diff options
author | David S. Miller <davem@davemloft.net> | 2012-11-14 22:06:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-14 22:06:57 -0500 |
commit | b092d92a68ac4f88c637cc7ca6074646ca120193 (patch) | |
tree | e2606a69dab1e3cb944512a53aa9733a788e4950 | |
parent | 0b3ba0553a9ef578dd289d9eed65cbd3b4823211 (diff) | |
parent | 5bdf502dd9c8fd60dddaabfb9a3dc1671302afd2 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says:
====================
Included is a Bluetooth pull -- Gustavo says:
"These are the Bluetooth bits for inclusion in 3.8, there is basically one big
thing here which is the High Speed patches from Andrei, he did a lot of work on
A2MP and management of AMP devices. The rest are mostly clean up and bug
fixes."
Also included is an NFC pull -- Samuel says:
"With this one we have:
- pn544 p2p support.
- pn544 physical and HCI layers separation. We are getting the pn544 driver
ready to support non i2c physical layers.
- LLCP SNL (Service Name Lookup). This is the NFC p2p service discovery
protocol.
- LLCP datagram sockets (connection less) support.
- IDR library usage for NFC devices indexes assignement.
- NFC netlink extension for setting and getting LLCP link characteristics.
- Various code style fixes and cleanups spread over the pn533, LLCP, HCI and
pn544 code."
There are a couple of mac80211 pulls as well -- Johannes says:
"Please pull my mac80211-next tree to get the first round of new features
for 3.8. We have:
* finally, the mac80211 multi-channel work
* scan improvements:
- bg scan
- scan flush
- forced AP scan
* cfg80211 tracing
* a bit of new code to allow implementing SAE (secure authentication of
equals) in managed mode
Along with a few random improvements, features and fixes."
and...
"Please pull from mac80211-next (per below pull request) to get a few
updates. Most important is probably the fix for the WDS regression that
my previous pull request introduced. Other than that, I have some
tracing code, two mesh updates and a change to allow drivers to
calculate the AES CMAC subkeys without having to implement the GF_mulx
operation themselves."
On top of that are the usual updates to iwlwifi, ath9k, rt2x00,
brcmfmac, mwifiex, and a few others here and there. Of note is the
addition of the ar5523 driver, ported from an original FreeBSD driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
233 files changed, 13900 insertions, 4289 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 4b062ff7441c..aedb604c83e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7509,6 +7509,12 @@ S: Maintained | |||
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> |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index d43ceff5be47..48a4c70b3842 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -43,8 +43,8 @@ static void early_nvram_init(void) | |||
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 |
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index e9f9ec8d443b..e80d585731aa 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c | |||
@@ -156,10 +156,10 @@ static int __init wgt634u_init(void) | |||
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)); |
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index a4c3ebcc4c86..ffd74e51f02d 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c | |||
@@ -22,12 +22,9 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, | |||
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) | |||
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); |
diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c index 9042781edec3..dbda91e4dff5 100644 --- a/drivers/bcma/driver_chipcommon_nflash.c +++ b/drivers/bcma/driver_chipcommon_nflash.c | |||
@@ -32,6 +32,9 @@ int bcma_nflash_init(struct bcma_drv_cc *cc) | |||
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. */ |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 201faf106b3f..a63ddd9c70eb 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -144,7 +144,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc) | |||
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) | |||
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); |
diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c index 2c4eec2ca5a0..63e688393825 100644 --- a/drivers/bcma/driver_chipcommon_sflash.c +++ b/drivers/bcma/driver_chipcommon_sflash.c | |||
@@ -12,7 +12,7 @@ | |||
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 { | |||
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) | |||
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) | |||
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; |
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index cc65b45b4368..170822ea51c7 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
@@ -181,47 +181,66 @@ EXPORT_SYMBOL(bcma_cpu_clock); | |||
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) | |||
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 | } |
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index 9baf886e82df..e56449506695 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c | |||
@@ -35,11 +35,6 @@ bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) | |||
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) | |||
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) | |||
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) | |||
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, |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index b6b4b5ebd4c2..98fdc3e014e7 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -238,7 +238,7 @@ static void __devexit bcma_host_pci_remove(struct pci_dev *dev) | |||
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, | |||
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) }, |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index d865470bc951..a9718893000b 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -81,6 +81,18 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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"); |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 0d546b64be34..4adf9ef9a113 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -595,8 +595,11 @@ int bcma_sprom_get(struct bcma_bus *bus) | |||
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 | ||
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 3f4bfc814dc7..9959d4cb23dc 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -492,7 +492,7 @@ done: | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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; |
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 961c8321451f..72b775fd49c8 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | |||
@@ -452,7 +452,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf, | |||
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, | |||
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) { |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 3cd05a7173f6..57f7db1ac31b 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -7433,7 +7433,7 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
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 && |
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 09602241901b..c25dcf192fec 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -26,5 +26,6 @@ source "drivers/net/wireless/ath/ath5k/Kconfig" | |||
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 |
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index d716b748e574..1e18621326dc 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile | |||
@@ -2,6 +2,7 @@ obj-$(CONFIG_ATH5K) += ath5k/ | |||
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 | ||
diff --git a/drivers/net/wireless/ath/ar5523/Kconfig b/drivers/net/wireless/ath/ar5523/Kconfig new file mode 100644 index 000000000000..11d99ee8de51 --- /dev/null +++ b/drivers/net/wireless/ath/ar5523/Kconfig | |||
@@ -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. | ||
diff --git a/drivers/net/wireless/ath/ar5523/Makefile b/drivers/net/wireless/ath/ar5523/Makefile new file mode 100644 index 000000000000..ebf7f3bf0a33 --- /dev/null +++ b/drivers/net/wireless/ath/ar5523/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_AR5523) := ar5523.o | |||
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c new file mode 100644 index 000000000000..f782b6e502bf --- /dev/null +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -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); | ||
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.h b/drivers/net/wireless/ath/ar5523/ar5523.h new file mode 100644 index 000000000000..00c6fd346d48 --- /dev/null +++ b/drivers/net/wireless/ath/ar5523/ar5523.h | |||
@@ -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) | ||
diff --git a/drivers/net/wireless/ath/ar5523/ar5523_hw.h b/drivers/net/wireless/ath/ar5523/ar5523_hw.h new file mode 100644 index 000000000000..a0e8bf460316 --- /dev/null +++ b/drivers/net/wireless/ath/ar5523/ar5523_hw.h | |||
@@ -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) | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7089f8160ad5..277089963eb4 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -301,7 +301,7 @@ static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif) | |||
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) | |||
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 | |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 84b558d126ca..162401f22f8c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -276,6 +276,11 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
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); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 5bbe5057ba18..c86cb6400040 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -18,6 +18,7 @@ | |||
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 @@ | |||
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, | |||
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) | |||
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, | |||
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; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 1a36fa262639..0693cd95b746 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -219,10 +219,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
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) | |||
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); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 44c202ce6c66..42b4412d6794 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -750,6 +750,9 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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); | |||
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) | |||
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) | |||
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 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 2a2d01889613..66d7ab9f920d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h | |||
@@ -18,6 +18,7 @@ | |||
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 { | |||
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 { | |||
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); | |||
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) | |||
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 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 9a48e3d2f231..8f585233a788 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -32,6 +32,7 @@ | |||
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 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h index 843e79f67ff2..0c2ac0c6dc89 100644 --- a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h | |||
@@ -768,9 +768,9 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = { | |||
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 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index dfe6a4707fd2..4e125d8904a0 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -437,6 +437,7 @@ void ath9k_set_beacon(struct ath_softc *sc); | |||
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 { | |||
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); | |||
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, | |||
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 { | |||
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 | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 419e9a3f2fed..c90e9bc4b026 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -195,7 +195,7 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah) | |||
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, | |||
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, | |||
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); | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 385197ad79b0..2f84ab273d0c 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -39,6 +39,9 @@ | |||
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 { | |||
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 { | |||
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, | |||
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 |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index e5cceb077574..f3448a032e6f 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -410,6 +410,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, | |||
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++) { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 6727b566d294..a8be94b2a53a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -1586,6 +1586,35 @@ static const struct file_operations fops_samps = { | |||
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) | |||
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 | } |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index d9ed141a053e..a8ea57b9f49c 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -187,6 +187,24 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index d98255eb1b9a..5ecf1287dddd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -694,6 +694,20 @@ err_hw: | |||
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, | |||
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 | |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ca78e33ca23e..66f6a74c508e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1036,26 +1036,6 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
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); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8e1559aba495..71cd9f0c96af 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2153,9 +2153,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
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) | |||
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; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dbc1b7a4cbfd..3e73bfe2315e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -401,6 +401,7 @@ enum ath9k_int { | |||
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 { | |||
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; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index fad3ccd5cd91..546bae93647b 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -687,6 +687,7 @@ static const struct ieee80211_iface_combination if_comb = { | |||
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) |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 7b88b9c39ccd..223b9693527e 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -350,8 +350,18 @@ void ath_ani_calibrate(unsigned long data) | |||
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 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index dd45edfa6bae..578a7234aa56 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -131,7 +131,8 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
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, | |||
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, | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index ec2d7c807567..0dd2cbb52d65 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -43,6 +43,7 @@ static bool ath_mci_add_profile(struct ath_common *common, | |||
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, | |||
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) | |||
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) | |||
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, | |||
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, | |||
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) | |||
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 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index fc14eea034eb..06958837620c 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h | |||
@@ -32,6 +32,27 @@ | |||
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 @@ | |||
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 @@ | |||
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 { | |||
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); | |||
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*/ |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 83d16e7ed272..a04028bce28b 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1105,7 +1105,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
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 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 4e6760f8596d..ad3c82c09177 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -907,10 +907,6 @@ | |||
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 { | |||
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 { | |||
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 |
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index a483d518758c..9f8563091bea 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -118,7 +118,7 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) | |||
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); |
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index e3b1b6e87760..24d75ab94f0d 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c | |||
@@ -343,7 +343,24 @@ int carl9170_set_operating_mode(struct ar9170 *ar) | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index a0b723078547..6d22382875bc 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -164,9 +164,6 @@ void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
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, | |||
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, | |||
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) | |||
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, | |||
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) | |||
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) |
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 888152ce3eca..307bc0ddff99 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
@@ -295,6 +295,13 @@ static void carl9170_usb_rx_irq_complete(struct urb *urb) | |||
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 | ||
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index 19befb331073..39e8a590d7fc 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c | |||
@@ -20,8 +20,8 @@ | |||
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) | |||
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) | |||
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) | |||
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; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c5a99c8c8168..ddd6a4f78097 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4652,7 +4652,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
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 |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 9d5170b6df50..fe80b637c519 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -24,6 +24,7 @@ ccflags-y += -D__CHECK_ENDIAN__ | |||
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 |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 17e7ae73e008..8704daa2758f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -318,6 +318,12 @@ struct brcmf_event { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 9b8ee19ea55d..265580f5b270 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -111,9 +111,6 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, | |||
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); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index a5c15cac5e7d..b9d8a5adfd43 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | |||
@@ -458,35 +458,6 @@ void brcmf_proto_detach(struct brcmf_pub *drvr) | |||
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 */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 15c5db5752d1..866b66995bb0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -28,12 +28,17 @@ | |||
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) | |||
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, | |||
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, | |||
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) | |||
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) | |||
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: | |||
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 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 7f89540b56da..862d2acb7a16 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | |||
@@ -16,8 +16,10 @@ | |||
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> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index fb508c2256dd..eefa6c2560cc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -31,6 +31,7 @@ | |||
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 { \ | |||
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 { \ | |||
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 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index d7c76ce9d8cb..297652339fda 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -52,16 +52,6 @@ MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); | |||
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) | |||
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, | |||
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 = { | |||
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) | |||
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) | |||
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) | |||
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) | |||
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: | |||
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) | |||
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) | |||
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(); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 6bc4425a8b0f..7fe6779b90cf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | |||
@@ -27,11 +27,6 @@ extern int brcmf_proto_attach(struct brcmf_pub *drvr); | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3564686add9a..415f2be36375 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -614,6 +614,12 @@ static const uint max_roundup = 512; | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c new file mode 100644 index 000000000000..4b272c3d237c --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c | |||
@@ -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 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h new file mode 100644 index 000000000000..16eb8202fb1e --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h | |||
@@ -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_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 7a6dfdc67b6c..484a6e4f23a2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -42,7 +42,6 @@ | |||
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 { | |||
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 { | |||
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) | |||
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, | |||
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, | |||
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) | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index a6f1e8166008..cb30feaa565b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -35,6 +35,7 @@ | |||
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 @@ | |||
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 @@ | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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: | |||
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) | |||
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; |
@@ -658,30 +547,6 @@ static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, | |||
658 | } | 547 | } |
659 | 548 | ||
660 | static s32 | 549 | 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 | ||
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) |
687 | { | 552 | { |
@@ -703,8 +568,8 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, | |||
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) | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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: | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | |||
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) | |||
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, | |||
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, | |||
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, | |||
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 | |||
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, | |||
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, | |||
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) | |||
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 | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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: | |||
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 | |||
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, | |||
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 | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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 | |||
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, | |||
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, | |||
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) | |||
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,85 +3008,53 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, | |||
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 | 3057 | 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 | ||
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) |
3263 | { | 3060 | { |
@@ -3275,8 +3072,8 @@ brcmf_update_pmklist(struct net_device *ndev, | |||
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, | |||
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, | |||
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 | |||
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, | |||
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: | |||
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) | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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 | |||
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, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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: | |||
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) | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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: | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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) | |||
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: | |||
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) | |||
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) | |||
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) | |||
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 | |||
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, | |||
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, | |||
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: | |||
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) | |||
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: | |||
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) | |||
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) | |||
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 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 71ced174748a..1dd96f148ef7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -127,15 +127,15 @@ do { \ | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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) | |||
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) | |||
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) | |||
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 */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index b89f1272b93f..de96290f5ccd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | |||
@@ -692,7 +692,7 @@ void ai_pci_up(struct si_pub *sih) | |||
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) | |||
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 */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 75086b37c817..565c15abbed5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -5077,7 +5077,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) | |||
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 | /* |
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index df7050abe717..d39e3e24077b 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c | |||
@@ -415,7 +415,7 @@ static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb, | |||
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) { |
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 02e057923236..95a1ca1e895c 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -1108,7 +1108,7 @@ static const char *get_info_element_string(u16 id) | |||
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 | |||
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)) |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f1430678..475df45c8320 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv) | |||
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) | |||
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, | |||
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) | |||
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) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 59a5f78402fc..678717bf62eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -25,6 +25,39 @@ | |||
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> |
@@ -235,6 +268,48 @@ TRACE_EVENT(iwlwifi_dbg, | |||
235 | ); | 268 | ); |
236 | 269 | ||
237 | #undef TRACE_SYSTEM | 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 | |||
312 | #undef TRACE_SYSTEM | ||
238 | #define TRACE_SYSTEM iwlwifi | 313 | #define TRACE_SYSTEM iwlwifi |
239 | 314 | ||
240 | TRACE_EVENT(iwlwifi_dev_hcmd, | 315 | TRACE_EVENT(iwlwifi_dev_hcmd, |
@@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd, | |||
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, | |||
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], |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 3dfebfb8434f..54c41b44bffe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -327,11 +327,11 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) | |||
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))) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 50d3819739d1..e1aa69f66de6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -87,7 +87,7 @@ void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | |||
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); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 9253ef1dba72..c3a4bb41e533 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -213,6 +213,9 @@ | |||
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 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ff1154232885..f75ea6d73ffc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -444,6 +444,10 @@ enum iwl_trans_state { | |||
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 { | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 17c8e5d82681..137af4c46a6c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -411,7 +411,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
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. |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index fe0fffd04304..f95d88df7772 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -300,7 +300,7 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af3c621..db3efbb84d92 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -480,21 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
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) | |||
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); |
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 97807751ebcf..3e81264db81e 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -101,7 +101,7 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
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; |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 9402b93b9a36..4a97acd170f7 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -58,8 +58,7 @@ mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 780d3e168297..fdb1eb861021 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -471,13 +471,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
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) | |||
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, | |||
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, | |||
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) | |||
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); |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8d465107f52b..da6c49177fcc 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -917,21 +917,24 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
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); |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index b5d37a8caa09..482faace7900 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -84,18 +84,19 @@ static void scan_delay_timer_fn(unsigned long data) | |||
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 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index eb22dd248d54..1df767bc8b6e 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -472,6 +472,14 @@ mwifiex_open(struct net_device *dev) | |||
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 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index c2d0ab146af5..81f8772dcb07 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -115,8 +115,6 @@ enum { | |||
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 { | |||
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); | |||
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, | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 9171aaedbccd..9189a32b7844 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -153,7 +153,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 09e6a267f566..65c12eb3e5e7 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -85,10 +85,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
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: |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 0c9f70b2cbe6..552d72ed055a 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -713,7 +713,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 07d32b73783e..b5c109504393 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c | |||
@@ -38,14 +38,10 @@ | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 2af263992e83..5cb3f7af8749 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -48,13 +48,19 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, | |||
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 | ||
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index d95a2d558fcf..8dd72240f162 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c | |||
@@ -188,10 +188,19 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, | |||
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 | } |
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 0966ac24b3b4..a018e42d117e 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c | |||
@@ -146,7 +146,7 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, | |||
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, | |||
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, | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index ae88f80cf86b..0982375ba3b1 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c | |||
@@ -146,20 +146,16 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, | |||
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, | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h index 4dadf9880a97..5a8fec26136e 100644 --- a/drivers/net/wireless/orinoco/main.h +++ b/drivers/net/wireless/orinoco/main.h | |||
@@ -39,7 +39,7 @@ static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len) | |||
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; |
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index 7f53cea2f205..01624dcaf73e 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c | |||
@@ -865,7 +865,7 @@ static int ezusb_firmware_download(struct ezusb_priv *upriv, | |||
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, | |||
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, | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 59474ae0aec0..c0441a715c96 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -2520,20 +2520,37 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 5b4b4d4eaf9e..ca69e35e50f1 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c | |||
@@ -52,11 +52,8 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, | |||
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; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 1ca4e25c143b..1cdf5a271c9f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -43,8 +43,8 @@ | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index cdcad7d9f15e..1d5d3604e3e0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
@@ -34,9 +34,6 @@ | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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, | |||
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: |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 2925094b2d91..3cfa1bb0f476 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h | |||
@@ -116,6 +116,9 @@ | |||
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 |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 27b3af880d96..74f9c083b80d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | |||
@@ -41,7 +41,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) | |||
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) | |||
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) | |||
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"); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 86d73b32d995..d1f34f6ffbdf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 88deae67cc14..73262ca3864b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -82,6 +82,8 @@ bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 54c7614958a8..a9c406f33d0a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | |||
@@ -97,15 +97,12 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index ea2e1bd847c8..60451eea4d82 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -162,12 +162,10 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | |||
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); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 390d6d4fcaa0..d7e1f0a7e48f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -127,11 +127,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index 6fd39eaf361e..16a0b9e59acf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | |||
@@ -39,7 +39,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) | |||
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) | |||
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) | |||
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"); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 4bbb711a36c5..b1ccff474c79 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -152,9 +152,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 7e91c76582ec..32ff959a0251 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | |||
@@ -46,7 +46,7 @@ | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 506b9a078ed1..953f1a0f8532 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | |||
@@ -115,15 +115,11 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index ed868c396c25..fd8df233ff22 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c | |||
@@ -35,7 +35,7 @@ | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index db0086062d05..33041bd4da81 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c | |||
@@ -298,13 +298,13 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 3066a7fb0b57..20144e0b4142 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c | |||
@@ -106,11 +106,11 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 4686f340b9d6..35bb9da6196a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
@@ -132,8 +132,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 465f58157101..bf79a52c8a52 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c | |||
@@ -267,13 +267,12 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 4542e6952b97..1d72779434ba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -1697,7 +1697,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
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) | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index b917a2a3caf7..67404975e00b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
@@ -139,17 +139,17 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 08c2f5625129..5061f1db3f02 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c | |||
@@ -192,8 +192,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index e3cf4c02122a..1ad51e711a32 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -129,8 +129,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 | } |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index f1b6bc693b0a..6794b688dd7d 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -198,15 +198,15 @@ struct bb_reg_def { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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; |
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index bf05831fdf09..36c359043f54 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile | |||
@@ -2,7 +2,7 @@ | |||
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 | ||
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 97c440a8cd61..18e279d3e836 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -84,6 +84,10 @@ MODULE_DEVICE_TABLE(usb, pn533_table); | |||
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, | |||
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) | |||
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, | |||
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, | |||
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 || |
diff --git a/drivers/nfc/pn544/Makefile b/drivers/nfc/pn544/Makefile new file mode 100644 index 000000000000..725733881eb3 --- /dev/null +++ b/drivers/nfc/pn544/Makefile | |||
@@ -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 | ||
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c new file mode 100644 index 000000000000..fb430d882352 --- /dev/null +++ b/drivers/nfc/pn544/i2c.c | |||
@@ -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); | ||
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544/pn544.c index c9c8570273ab..cc666de3b8e5 100644 --- a/drivers/nfc/pn544_hci.c +++ b/drivers/nfc/pn544/pn544.c | |||
@@ -18,47 +18,21 @@ | |||
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 { | |||
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 { | |||
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[] = { | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 = { | |||
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, | |||
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, | |||
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); | ||
diff --git a/drivers/nfc/pn544/pn544.h b/drivers/nfc/pn544/pn544.h new file mode 100644 index 000000000000..f47c6454914b --- /dev/null +++ b/drivers/nfc/pn544/pn544.h | |||
@@ -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_ */ | ||
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index 266aa1648a02..19396dc4ee47 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c | |||
@@ -37,6 +37,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { | |||
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); |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index b58fef780ea0..d7d58044b4bc 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -346,6 +346,8 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) | |||
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) | |||
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 |
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index c6250867a95d..b918ba922306 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c | |||
@@ -192,9 +192,10 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) | |||
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) | |||
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 | } |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 4180eb78d575..fd15d9829705 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -251,7 +251,7 @@ struct bcma_bus { | |||
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 | ||
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 1cf1749440ac..145f3c56227f 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -510,6 +510,7 @@ struct bcma_chipcommon_pmu { | |||
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; | |||
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 { | |||
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 { | |||
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); | |||
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); |
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h index c0043645cdcb..0baf8a56b794 100644 --- a/include/linux/bcma/bcma_driver_mips.h +++ b/include/linux/bcma/bcma_driver_mips.h | |||
@@ -35,13 +35,16 @@ struct bcma_device; | |||
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); |
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 6c9cb93ae3de..7e8104bb7a7e 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h | |||
@@ -85,6 +85,9 @@ | |||
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_ */ |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 2385119f8bb0..85764a900731 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -1107,20 +1107,6 @@ struct ieee80211_ht_operation { | |||
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 { | |||
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 { | |||
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 | ||
diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h index 5f44e9740cd2..07a9c7a2e088 100644 --- a/include/linux/ssb/ssb_driver_mips.h +++ b/include/linux/ssb/ssb_driver_mips.h | |||
@@ -13,6 +13,12 @@ struct ssb_serial_port { | |||
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 { | |||
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); |
diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 6a76e0a0705e..42f21766c538 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h | |||
@@ -19,13 +19,25 @@ | |||
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 { | |||
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 */ |
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h new file mode 100644 index 000000000000..2e7c79ea0463 --- /dev/null +++ b/include/net/bluetooth/amp.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 */ | ||
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index ede036977ae8..2554b3f5222a 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -180,7 +180,6 @@ static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) | |||
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 | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 76b2b6bdcf36..88cbbda61027 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -33,6 +33,8 @@ | |||
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 { | |||
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 { | |||
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 { | |||
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; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e7d454609881..9fe8e2dec870 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -73,6 +73,7 @@ struct discovery_state { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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) | |||
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) | |||
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) | |||
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); | |||
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) | |||
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) | |||
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) | |||
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; |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7ed8e356425a..6e23afdf65c1 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -32,13 +32,14 @@ | |||
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 { | |||
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 { | |||
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) | |||
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); | |||
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 */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7d5b6000378b..c6964572890f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -498,6 +498,7 @@ enum station_parameters_apply_mask { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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); | |||
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 { | |||
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 | /** |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 82558c8decf8..00b7204708bd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -144,6 +144,41 @@ struct ieee80211_low_level_stats { | |||
144 | }; | 144 | }; |
145 | 145 | ||
146 | /** | 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 | |||
181 | /** | ||
147 | * enum ieee80211_bss_change - BSS change notification flags | 182 | * enum ieee80211_bss_change - BSS change notification flags |
148 | * | 183 | * |
149 | * These flags are used with the bss_info_changed() callback | 184 | * These flags are used with the bss_info_changed() callback |
@@ -223,6 +258,7 @@ enum ieee80211_rssi_event { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 | /** |
@@ -3145,6 +3223,19 @@ 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 | ||
3147 | /** | 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 | |||
3238 | /** | ||
3148 | * struct ieee80211_key_seq - key sequence counter | 3239 | * struct ieee80211_key_seq - key sequence counter |
3149 | * | 3240 | * |
3150 | * @tkip: TKIP data, containing IV32 and IV16 in host byte order | 3241 | * @tkip: TKIP data, containing IV32 and IV16 in host byte order |
@@ -3524,6 +3615,27 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
3524 | void *iter_data); | 3615 | void *iter_data); |
3525 | 3616 | ||
3526 | /** | 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 | |||
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(). |
3529 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | 3641 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. |
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index e900072950cb..639f50af42df 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h | |||
@@ -24,6 +24,12 @@ | |||
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 { | |||
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 { | |||
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, | |||
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 */ |
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index f05b10682c9d..fce80b2f9be7 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
@@ -95,7 +95,7 @@ struct nfc_genl_data { | |||
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; |
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h index d908d17da56d..0e63cee8d810 100644 --- a/include/uapi/linux/nfc.h +++ b/include/uapi/linux/nfc.h | |||
@@ -60,6 +60,13 @@ | |||
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 { | |||
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 { | |||
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 { | |||
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 | }; |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 7df9b500c804..617d0fbfc96f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -1273,6 +1273,14 @@ enum nl80211_commands { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 { | |||
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 */ |
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 3537d385035e..1c11d0dcd863 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
@@ -11,6 +11,7 @@ menuconfig BT | |||
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 |
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index fa6d94a4602a..dea6a287daca 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -10,4 +10,4 @@ obj-$(CONFIG_BT_HIDP) += hidp/ | |||
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 |
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 0760d1fed6f0..d5136cfb57e2 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -16,6 +16,11 @@ | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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: | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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 = { | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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 | } | ||
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ba033f09196e..5355df63d39b 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -569,7 +569,6 @@ static int bt_seq_show(struct seq_file *seq, void *v) | |||
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) | |||
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) { |
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c new file mode 100644 index 000000000000..231d7ef53ecb --- /dev/null +++ b/net/bluetooth/amp.c | |||
@@ -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 | } | ||
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 4a6620bc1570..a5b639702637 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -182,8 +182,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) | |||
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); |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 6c9c1fd601ca..e0a6ebf2baa6 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -353,7 +353,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
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; |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b9196a44f759..fe646211c61f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -130,6 +130,20 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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) | |||
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 | } | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8a0ce706aebd..5a3f941b610f 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -405,7 +405,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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, | |||
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) | |||
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, | |||
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, | |||
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) | |||
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, | |||
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) | |||
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) | |||
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) { |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2022b43c7353..0383635f91fb 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -30,6 +30,8 @@ | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index a20e61c3653d..55cceee02a84 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -38,7 +38,7 @@ static ssize_t show_link_address(struct device *dev, | |||
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, | |||
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) | |||
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) | |||
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 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index ccd985da6518..0c0028463fa3 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -932,8 +932,12 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
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; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a91239dcda41..08efc256c931 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -48,19 +48,20 @@ static LIST_HEAD(chan_list); | |||
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 | |||
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 | |||
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 | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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, | |||
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, | |||
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) | |||
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) | |||
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, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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: | |||
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) | |||
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) | |||
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) | |||
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: | |||
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: | |||
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: | |||
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: | |||
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: | |||
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: | |||
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) | |||
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: | |||
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: | |||
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: | |||
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: | |||
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: | |||
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: | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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) | |||
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) | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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: | |||
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: | |||
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 | |||
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 | |||
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) | |||
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 | |||
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 | |||
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 | |||
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 | |||
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: | |||
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 | |||
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 | |||
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 | |||
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: | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 083f2bf065d4..89f1472939ec 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -40,7 +40,8 @@ static struct bt_sock_list l2cap_sk_list = { | |||
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: | |||
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 | |||
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: | |||
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: | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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) | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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) | |||
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) | |||
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) | |||
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) | |||
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 = { | |||
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) | |||
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 = { | |||
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, | |||
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) | |||
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); |
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index e1c97527e16c..b3fbc73516c4 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c | |||
@@ -41,20 +41,6 @@ void baswap(bdaddr_t *dst, bdaddr_t *src) | |||
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 | { |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index aa2ea0a8142c..399e5024b5bd 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -3125,6 +3125,9 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
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, | |||
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 | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index c75107ef8920..201fdf737209 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -377,8 +377,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, | |||
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, | |||
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, | |||
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) | |||
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) | |||
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 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index b3226f3658cf..4ddef57d03a7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -334,7 +334,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr | |||
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) | |||
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); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index ccc248791d50..bd6fd0f43d2b 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -166,7 +166,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | |||
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) | |||
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) { |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index dc42b917aaaf..450cdcd88e5c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -172,7 +172,7 @@ static int sco_connect(struct sock *sk) | |||
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 | |||
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) | |||
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) | |||
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) | |||
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); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2ac8d50861e0..9176bc17595c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -167,7 +167,7 @@ static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, | |||
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 | ||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 63af25458fda..b4ecf267a34b 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -248,7 +248,7 @@ config MAC80211_MHWMP_DEBUG | |||
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--- |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index a7dd110faafa..4911202334d9 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -8,6 +8,7 @@ mac80211-y := \ | |||
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 \ |
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index a04752e91023..493353534a0f 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c | |||
@@ -126,3 +126,20 @@ void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) | |||
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); | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 05f3a313db88..5eab1325a0f6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -372,10 +372,11 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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) | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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, | |||
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 * | |||
3042 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, | 3063 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, |
3043 | enum nl80211_channel_type *type) | 3064 | enum nl80211_channel_type *type) |
3044 | { | 3065 | { |
3045 | struct ieee80211_local *local = wiphy_priv(wiphy); | 3066 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
3067 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
3068 | struct ieee80211_channel *chan = NULL; | ||
3069 | |||
3070 | rcu_read_lock(); | ||
3071 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
3072 | if (chanctx_conf) { | ||
3073 | *type = chanctx_conf->channel_type; | ||
3074 | chan = chanctx_conf->channel; | ||
3075 | } | ||
3076 | rcu_read_unlock(); | ||
3046 | 3077 | ||
3047 | *type = local->_oper_channel_type; | 3078 | return chan; |
3048 | return local->oper_channel; | ||
3049 | } | 3079 | } |
3050 | 3080 | ||
3051 | #ifdef CONFIG_PM | 3081 | #ifdef CONFIG_PM |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 0bfc914ddd15..f84b86028a9c 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -3,108 +3,10 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/nl80211.h> | 5 | #include <linux/nl80211.h> |
6 | #include <linux/export.h> | ||
6 | #include <net/cfg80211.h> | 7 | #include <net/cfg80211.h> |
7 | #include "ieee80211_i.h" | 8 | #include "ieee80211_i.h" |
8 | 9 | #include "driver-ops.h" | |
9 | static enum ieee80211_chan_mode | ||
10 | __ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
11 | struct ieee80211_sub_if_data *ignore) | ||
12 | { | ||
13 | struct ieee80211_sub_if_data *sdata; | ||
14 | |||
15 | lockdep_assert_held(&local->iflist_mtx); | ||
16 | |||
17 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
18 | if (sdata == ignore) | ||
19 | continue; | ||
20 | |||
21 | if (!ieee80211_sdata_running(sdata)) | ||
22 | continue; | ||
23 | |||
24 | switch (sdata->vif.type) { | ||
25 | case NL80211_IFTYPE_MONITOR: | ||
26 | continue; | ||
27 | case NL80211_IFTYPE_STATION: | ||
28 | if (!sdata->u.mgd.associated) | ||
29 | continue; | ||
30 | break; | ||
31 | case NL80211_IFTYPE_ADHOC: | ||
32 | if (!sdata->u.ibss.ssid_len) | ||
33 | continue; | ||
34 | if (!sdata->u.ibss.fixed_channel) | ||
35 | return CHAN_MODE_HOPPING; | ||
36 | break; | ||
37 | case NL80211_IFTYPE_AP_VLAN: | ||
38 | /* will also have _AP interface */ | ||
39 | continue; | ||
40 | case NL80211_IFTYPE_AP: | ||
41 | if (!sdata->u.ap.beacon) | ||
42 | continue; | ||
43 | break; | ||
44 | case NL80211_IFTYPE_MESH_POINT: | ||
45 | if (!sdata->wdev.mesh_id_len) | ||
46 | continue; | ||
47 | break; | ||
48 | default: | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | return CHAN_MODE_FIXED; | ||
53 | } | ||
54 | |||
55 | return CHAN_MODE_UNDEFINED; | ||
56 | } | ||
57 | |||
58 | enum ieee80211_chan_mode | ||
59 | ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
60 | struct ieee80211_sub_if_data *ignore) | ||
61 | { | ||
62 | enum ieee80211_chan_mode mode; | ||
63 | |||
64 | mutex_lock(&local->iflist_mtx); | ||
65 | mode = __ieee80211_get_channel_mode(local, ignore); | ||
66 | mutex_unlock(&local->iflist_mtx); | ||
67 | |||
68 | return mode; | ||
69 | } | ||
70 | |||
71 | static enum nl80211_channel_type | ||
72 | ieee80211_get_superchan(struct ieee80211_local *local, | ||
73 | struct ieee80211_sub_if_data *sdata) | ||
74 | { | ||
75 | enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT; | ||
76 | struct ieee80211_sub_if_data *tmp; | ||
77 | |||
78 | mutex_lock(&local->iflist_mtx); | ||
79 | list_for_each_entry(tmp, &local->interfaces, list) { | ||
80 | if (tmp == sdata) | ||
81 | continue; | ||
82 | |||
83 | if (!ieee80211_sdata_running(tmp)) | ||
84 | continue; | ||
85 | |||
86 | switch (tmp->vif.bss_conf.channel_type) { | ||
87 | case NL80211_CHAN_NO_HT: | ||
88 | case NL80211_CHAN_HT20: | ||
89 | if (superchan > tmp->vif.bss_conf.channel_type) | ||
90 | break; | ||
91 | |||
92 | superchan = tmp->vif.bss_conf.channel_type; | ||
93 | break; | ||
94 | case NL80211_CHAN_HT40PLUS: | ||
95 | WARN_ON(superchan == NL80211_CHAN_HT40MINUS); | ||
96 | superchan = NL80211_CHAN_HT40PLUS; | ||
97 | break; | ||
98 | case NL80211_CHAN_HT40MINUS: | ||
99 | WARN_ON(superchan == NL80211_CHAN_HT40PLUS); | ||
100 | superchan = NL80211_CHAN_HT40MINUS; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | mutex_unlock(&local->iflist_mtx); | ||
105 | |||
106 | return superchan; | ||
107 | } | ||
108 | 10 | ||
109 | static bool | 11 | static bool |
110 | ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, | 12 | ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, |
@@ -148,23 +50,350 @@ ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, | |||
148 | return true; | 50 | return true; |
149 | } | 51 | } |
150 | 52 | ||
151 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | 53 | static void ieee80211_change_chantype(struct ieee80211_local *local, |
152 | struct ieee80211_sub_if_data *sdata, | 54 | struct ieee80211_chanctx *ctx, |
153 | enum nl80211_channel_type chantype) | 55 | enum nl80211_channel_type chantype) |
154 | { | 56 | { |
155 | enum nl80211_channel_type superchan; | 57 | if (chantype == ctx->conf.channel_type) |
156 | enum nl80211_channel_type compatchan; | 58 | return; |
157 | 59 | ||
158 | superchan = ieee80211_get_superchan(local, sdata); | 60 | ctx->conf.channel_type = chantype; |
159 | if (!ieee80211_channel_types_are_compatible(superchan, chantype, | 61 | drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE); |
160 | &compatchan)) | ||
161 | return false; | ||
162 | 62 | ||
163 | local->_oper_channel_type = compatchan; | 63 | if (!local->use_chanctx) { |
64 | local->_oper_channel_type = chantype; | ||
65 | ieee80211_hw_config(local, 0); | ||
66 | } | ||
67 | } | ||
164 | 68 | ||
165 | if (sdata) | 69 | static struct ieee80211_chanctx * |
166 | sdata->vif.bss_conf.channel_type = chantype; | 70 | ieee80211_find_chanctx(struct ieee80211_local *local, |
71 | struct ieee80211_channel *channel, | ||
72 | enum nl80211_channel_type channel_type, | ||
73 | enum ieee80211_chanctx_mode mode) | ||
74 | { | ||
75 | struct ieee80211_chanctx *ctx; | ||
76 | enum nl80211_channel_type compat_type; | ||
167 | 77 | ||
168 | return true; | 78 | lockdep_assert_held(&local->chanctx_mtx); |
79 | |||
80 | if (mode == IEEE80211_CHANCTX_EXCLUSIVE) | ||
81 | return NULL; | ||
82 | if (WARN_ON(!channel)) | ||
83 | return NULL; | ||
84 | |||
85 | list_for_each_entry(ctx, &local->chanctx_list, list) { | ||
86 | compat_type = ctx->conf.channel_type; | ||
87 | |||
88 | if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) | ||
89 | continue; | ||
90 | if (ctx->conf.channel != channel) | ||
91 | continue; | ||
92 | if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type, | ||
93 | channel_type, | ||
94 | &compat_type)) | ||
95 | continue; | ||
96 | |||
97 | ieee80211_change_chantype(local, ctx, compat_type); | ||
98 | |||
99 | return ctx; | ||
100 | } | ||
101 | |||
102 | return NULL; | ||
103 | } | ||
104 | |||
105 | static struct ieee80211_chanctx * | ||
106 | ieee80211_new_chanctx(struct ieee80211_local *local, | ||
107 | struct ieee80211_channel *channel, | ||
108 | enum nl80211_channel_type channel_type, | ||
109 | enum ieee80211_chanctx_mode mode) | ||
110 | { | ||
111 | struct ieee80211_chanctx *ctx; | ||
112 | int err; | ||
113 | |||
114 | lockdep_assert_held(&local->chanctx_mtx); | ||
115 | |||
116 | ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); | ||
117 | if (!ctx) | ||
118 | return ERR_PTR(-ENOMEM); | ||
119 | |||
120 | ctx->conf.channel = channel; | ||
121 | ctx->conf.channel_type = channel_type; | ||
122 | ctx->conf.rx_chains_static = 1; | ||
123 | ctx->conf.rx_chains_dynamic = 1; | ||
124 | ctx->mode = mode; | ||
125 | |||
126 | if (!local->use_chanctx) { | ||
127 | local->_oper_channel_type = channel_type; | ||
128 | local->_oper_channel = channel; | ||
129 | ieee80211_hw_config(local, 0); | ||
130 | } else { | ||
131 | err = drv_add_chanctx(local, ctx); | ||
132 | if (err) { | ||
133 | kfree(ctx); | ||
134 | return ERR_PTR(err); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | list_add_rcu(&ctx->list, &local->chanctx_list); | ||
139 | |||
140 | return ctx; | ||
141 | } | ||
142 | |||
143 | static void ieee80211_free_chanctx(struct ieee80211_local *local, | ||
144 | struct ieee80211_chanctx *ctx) | ||
145 | { | ||
146 | lockdep_assert_held(&local->chanctx_mtx); | ||
147 | |||
148 | WARN_ON_ONCE(ctx->refcount != 0); | ||
149 | |||
150 | if (!local->use_chanctx) { | ||
151 | local->_oper_channel_type = NL80211_CHAN_NO_HT; | ||
152 | ieee80211_hw_config(local, 0); | ||
153 | } else { | ||
154 | drv_remove_chanctx(local, ctx); | ||
155 | } | ||
156 | |||
157 | list_del_rcu(&ctx->list); | ||
158 | kfree_rcu(ctx, rcu_head); | ||
159 | } | ||
160 | |||
161 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | ||
162 | struct ieee80211_chanctx *ctx) | ||
163 | { | ||
164 | struct ieee80211_local *local = sdata->local; | ||
165 | int ret; | ||
166 | |||
167 | lockdep_assert_held(&local->chanctx_mtx); | ||
168 | |||
169 | ret = drv_assign_vif_chanctx(local, sdata, ctx); | ||
170 | if (ret) | ||
171 | return ret; | ||
172 | |||
173 | rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); | ||
174 | ctx->refcount++; | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static enum nl80211_channel_type | ||
180 | ieee80211_calc_chantype(struct ieee80211_local *local, | ||
181 | struct ieee80211_chanctx *ctx) | ||
182 | { | ||
183 | struct ieee80211_chanctx_conf *conf = &ctx->conf; | ||
184 | struct ieee80211_sub_if_data *sdata; | ||
185 | enum nl80211_channel_type result = NL80211_CHAN_NO_HT; | ||
186 | |||
187 | lockdep_assert_held(&local->chanctx_mtx); | ||
188 | |||
189 | rcu_read_lock(); | ||
190 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
191 | if (!ieee80211_sdata_running(sdata)) | ||
192 | continue; | ||
193 | if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) | ||
194 | continue; | ||
195 | |||
196 | WARN_ON_ONCE(!ieee80211_channel_types_are_compatible( | ||
197 | sdata->vif.bss_conf.channel_type, | ||
198 | result, &result)); | ||
199 | } | ||
200 | rcu_read_unlock(); | ||
201 | |||
202 | return result; | ||
203 | } | ||
204 | |||
205 | static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, | ||
206 | struct ieee80211_chanctx *ctx) | ||
207 | { | ||
208 | enum nl80211_channel_type chantype; | ||
209 | |||
210 | lockdep_assert_held(&local->chanctx_mtx); | ||
211 | |||
212 | chantype = ieee80211_calc_chantype(local, ctx); | ||
213 | ieee80211_change_chantype(local, ctx, chantype); | ||
214 | } | ||
215 | |||
216 | static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | ||
217 | struct ieee80211_chanctx *ctx) | ||
218 | { | ||
219 | struct ieee80211_local *local = sdata->local; | ||
220 | |||
221 | lockdep_assert_held(&local->chanctx_mtx); | ||
222 | |||
223 | ctx->refcount--; | ||
224 | rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); | ||
225 | |||
226 | drv_unassign_vif_chanctx(local, sdata, ctx); | ||
227 | |||
228 | if (ctx->refcount > 0) { | ||
229 | ieee80211_recalc_chanctx_chantype(sdata->local, ctx); | ||
230 | ieee80211_recalc_smps_chanctx(local, ctx); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | ||
235 | { | ||
236 | struct ieee80211_local *local = sdata->local; | ||
237 | struct ieee80211_chanctx_conf *conf; | ||
238 | struct ieee80211_chanctx *ctx; | ||
239 | |||
240 | lockdep_assert_held(&local->chanctx_mtx); | ||
241 | |||
242 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | ||
243 | lockdep_is_held(&local->chanctx_mtx)); | ||
244 | if (!conf) | ||
245 | return; | ||
246 | |||
247 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | ||
248 | |||
249 | ieee80211_unassign_vif_chanctx(sdata, ctx); | ||
250 | if (ctx->refcount == 0) | ||
251 | ieee80211_free_chanctx(local, ctx); | ||
252 | } | ||
253 | |||
254 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | ||
255 | struct ieee80211_chanctx *chanctx) | ||
256 | { | ||
257 | struct ieee80211_sub_if_data *sdata; | ||
258 | u8 rx_chains_static, rx_chains_dynamic; | ||
259 | |||
260 | lockdep_assert_held(&local->chanctx_mtx); | ||
261 | |||
262 | rx_chains_static = 1; | ||
263 | rx_chains_dynamic = 1; | ||
264 | |||
265 | rcu_read_lock(); | ||
266 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
267 | u8 needed_static, needed_dynamic; | ||
268 | |||
269 | if (!ieee80211_sdata_running(sdata)) | ||
270 | continue; | ||
271 | |||
272 | if (rcu_access_pointer(sdata->vif.chanctx_conf) != | ||
273 | &chanctx->conf) | ||
274 | continue; | ||
275 | |||
276 | switch (sdata->vif.type) { | ||
277 | case NL80211_IFTYPE_P2P_DEVICE: | ||
278 | continue; | ||
279 | case NL80211_IFTYPE_STATION: | ||
280 | if (!sdata->u.mgd.associated) | ||
281 | continue; | ||
282 | break; | ||
283 | case NL80211_IFTYPE_AP_VLAN: | ||
284 | continue; | ||
285 | case NL80211_IFTYPE_AP: | ||
286 | case NL80211_IFTYPE_ADHOC: | ||
287 | case NL80211_IFTYPE_WDS: | ||
288 | case NL80211_IFTYPE_MESH_POINT: | ||
289 | break; | ||
290 | default: | ||
291 | WARN_ON_ONCE(1); | ||
292 | } | ||
293 | |||
294 | switch (sdata->smps_mode) { | ||
295 | default: | ||
296 | WARN_ONCE(1, "Invalid SMPS mode %d\n", | ||
297 | sdata->smps_mode); | ||
298 | /* fall through */ | ||
299 | case IEEE80211_SMPS_OFF: | ||
300 | needed_static = sdata->needed_rx_chains; | ||
301 | needed_dynamic = sdata->needed_rx_chains; | ||
302 | break; | ||
303 | case IEEE80211_SMPS_DYNAMIC: | ||
304 | needed_static = 1; | ||
305 | needed_dynamic = sdata->needed_rx_chains; | ||
306 | break; | ||
307 | case IEEE80211_SMPS_STATIC: | ||
308 | needed_static = 1; | ||
309 | needed_dynamic = 1; | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | rx_chains_static = max(rx_chains_static, needed_static); | ||
314 | rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); | ||
315 | } | ||
316 | rcu_read_unlock(); | ||
317 | |||
318 | if (!local->use_chanctx) { | ||
319 | if (rx_chains_static > 1) | ||
320 | local->smps_mode = IEEE80211_SMPS_OFF; | ||
321 | else if (rx_chains_dynamic > 1) | ||
322 | local->smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
323 | else | ||
324 | local->smps_mode = IEEE80211_SMPS_STATIC; | ||
325 | ieee80211_hw_config(local, 0); | ||
326 | } | ||
327 | |||
328 | if (rx_chains_static == chanctx->conf.rx_chains_static && | ||
329 | rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) | ||
330 | return; | ||
331 | |||
332 | chanctx->conf.rx_chains_static = rx_chains_static; | ||
333 | chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; | ||
334 | drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); | ||
335 | } | ||
336 | |||
337 | int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | ||
338 | struct ieee80211_channel *channel, | ||
339 | enum nl80211_channel_type channel_type, | ||
340 | enum ieee80211_chanctx_mode mode) | ||
341 | { | ||
342 | struct ieee80211_local *local = sdata->local; | ||
343 | struct ieee80211_chanctx *ctx; | ||
344 | int ret; | ||
345 | |||
346 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | ||
347 | |||
348 | mutex_lock(&local->chanctx_mtx); | ||
349 | __ieee80211_vif_release_channel(sdata); | ||
350 | |||
351 | ctx = ieee80211_find_chanctx(local, channel, channel_type, mode); | ||
352 | if (!ctx) | ||
353 | ctx = ieee80211_new_chanctx(local, channel, channel_type, mode); | ||
354 | if (IS_ERR(ctx)) { | ||
355 | ret = PTR_ERR(ctx); | ||
356 | goto out; | ||
357 | } | ||
358 | |||
359 | sdata->vif.bss_conf.channel_type = channel_type; | ||
360 | |||
361 | ret = ieee80211_assign_vif_chanctx(sdata, ctx); | ||
362 | if (ret) { | ||
363 | /* if assign fails refcount stays the same */ | ||
364 | if (ctx->refcount == 0) | ||
365 | ieee80211_free_chanctx(local, ctx); | ||
366 | goto out; | ||
367 | } | ||
368 | |||
369 | ieee80211_recalc_smps_chanctx(local, ctx); | ||
370 | out: | ||
371 | mutex_unlock(&local->chanctx_mtx); | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | ||
376 | { | ||
377 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | ||
378 | |||
379 | mutex_lock(&sdata->local->chanctx_mtx); | ||
380 | __ieee80211_vif_release_channel(sdata); | ||
381 | mutex_unlock(&sdata->local->chanctx_mtx); | ||
382 | } | ||
383 | |||
384 | void ieee80211_iter_chan_contexts_atomic( | ||
385 | struct ieee80211_hw *hw, | ||
386 | void (*iter)(struct ieee80211_hw *hw, | ||
387 | struct ieee80211_chanctx_conf *chanctx_conf, | ||
388 | void *data), | ||
389 | void *iter_data) | ||
390 | { | ||
391 | struct ieee80211_local *local = hw_to_local(hw); | ||
392 | struct ieee80211_chanctx *ctx; | ||
169 | 393 | ||
394 | rcu_read_lock(); | ||
395 | list_for_each_entry_rcu(ctx, &local->chanctx_list, list) | ||
396 | iter(hw, &ctx->conf, iter_data); | ||
397 | rcu_read_unlock(); | ||
170 | } | 398 | } |
399 | EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); | ||
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h index 9be4e6d71d00..214ed4ecd739 100644 --- a/net/mac80211/debugfs.h +++ b/net/mac80211/debugfs.h | |||
@@ -2,9 +2,9 @@ | |||
2 | #define __MAC80211_DEBUGFS_H | 2 | #define __MAC80211_DEBUGFS_H |
3 | 3 | ||
4 | #ifdef CONFIG_MAC80211_DEBUGFS | 4 | #ifdef CONFIG_MAC80211_DEBUGFS |
5 | extern void debugfs_hw_add(struct ieee80211_local *local); | 5 | void debugfs_hw_add(struct ieee80211_local *local); |
6 | extern int mac80211_format_buffer(char __user *userbuf, size_t count, | 6 | int __printf(4, 5) mac80211_format_buffer(char __user *userbuf, size_t count, |
7 | loff_t *ppos, char *fmt, ...); | 7 | loff_t *ppos, char *fmt, ...); |
8 | #else | 8 | #else |
9 | static inline void debugfs_hw_add(struct ieee80211_local *local) | 9 | static inline void debugfs_hw_add(struct ieee80211_local *local) |
10 | { | 10 | { |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 6d5aec9418ee..3393ad5b8ab1 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -217,7 +217,7 @@ static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata, | |||
217 | 217 | ||
218 | return snprintf(buf, buflen, "request: %s\nused: %s\n", | 218 | return snprintf(buf, buflen, "request: %s\nused: %s\n", |
219 | smps_modes[sdata->u.mgd.req_smps], | 219 | smps_modes[sdata->u.mgd.req_smps], |
220 | smps_modes[sdata->u.mgd.ap_smps]); | 220 | smps_modes[sdata->smps_mode]); |
221 | } | 221 | } |
222 | 222 | ||
223 | static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, | 223 | static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, |
@@ -395,14 +395,14 @@ __IEEE80211_IF_FILE_W(uapsd_max_sp_len); | |||
395 | 395 | ||
396 | /* AP attributes */ | 396 | /* AP attributes */ |
397 | IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); | 397 | IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); |
398 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); | 398 | IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC); |
399 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); | 399 | IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC); |
400 | 400 | ||
401 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( | 401 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( |
402 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 402 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
403 | { | 403 | { |
404 | return scnprintf(buf, buflen, "%u\n", | 404 | return scnprintf(buf, buflen, "%u\n", |
405 | skb_queue_len(&sdata->u.ap.ps_bc_buf)); | 405 | skb_queue_len(&sdata->u.ap.ps.bc_buf)); |
406 | } | 406 | } |
407 | __IEEE80211_IF_FILE(num_buffered_multicast, NULL); | 407 | __IEEE80211_IF_FILE(num_buffered_multicast, NULL); |
408 | 408 | ||
@@ -471,7 +471,7 @@ IEEE80211_IF_FILE(dropped_frames_congestion, | |||
471 | u.mesh.mshstats.dropped_frames_congestion, DEC); | 471 | u.mesh.mshstats.dropped_frames_congestion, DEC); |
472 | IEEE80211_IF_FILE(dropped_frames_no_route, | 472 | IEEE80211_IF_FILE(dropped_frames_no_route, |
473 | u.mesh.mshstats.dropped_frames_no_route, DEC); | 473 | u.mesh.mshstats.dropped_frames_no_route, DEC); |
474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); | 474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC); |
475 | 475 | ||
476 | /* Mesh parameters */ | 476 | /* Mesh parameters */ |
477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, | 477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index da9003b20004..77407b31e1ff 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -871,4 +871,69 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | |||
871 | local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); | 871 | local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); |
872 | trace_drv_return_void(local); | 872 | trace_drv_return_void(local); |
873 | } | 873 | } |
874 | |||
875 | static inline int drv_add_chanctx(struct ieee80211_local *local, | ||
876 | struct ieee80211_chanctx *ctx) | ||
877 | { | ||
878 | int ret = -EOPNOTSUPP; | ||
879 | |||
880 | trace_drv_add_chanctx(local, ctx); | ||
881 | if (local->ops->add_chanctx) | ||
882 | ret = local->ops->add_chanctx(&local->hw, &ctx->conf); | ||
883 | trace_drv_return_int(local, ret); | ||
884 | |||
885 | return ret; | ||
886 | } | ||
887 | |||
888 | static inline void drv_remove_chanctx(struct ieee80211_local *local, | ||
889 | struct ieee80211_chanctx *ctx) | ||
890 | { | ||
891 | trace_drv_remove_chanctx(local, ctx); | ||
892 | if (local->ops->remove_chanctx) | ||
893 | local->ops->remove_chanctx(&local->hw, &ctx->conf); | ||
894 | trace_drv_return_void(local); | ||
895 | } | ||
896 | |||
897 | static inline void drv_change_chanctx(struct ieee80211_local *local, | ||
898 | struct ieee80211_chanctx *ctx, | ||
899 | u32 changed) | ||
900 | { | ||
901 | trace_drv_change_chanctx(local, ctx, changed); | ||
902 | if (local->ops->change_chanctx) | ||
903 | local->ops->change_chanctx(&local->hw, &ctx->conf, changed); | ||
904 | trace_drv_return_void(local); | ||
905 | } | ||
906 | |||
907 | static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, | ||
908 | struct ieee80211_sub_if_data *sdata, | ||
909 | struct ieee80211_chanctx *ctx) | ||
910 | { | ||
911 | int ret = 0; | ||
912 | |||
913 | check_sdata_in_driver(sdata); | ||
914 | |||
915 | trace_drv_assign_vif_chanctx(local, sdata, ctx); | ||
916 | if (local->ops->assign_vif_chanctx) | ||
917 | ret = local->ops->assign_vif_chanctx(&local->hw, | ||
918 | &sdata->vif, | ||
919 | &ctx->conf); | ||
920 | trace_drv_return_int(local, ret); | ||
921 | |||
922 | return ret; | ||
923 | } | ||
924 | |||
925 | static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, | ||
926 | struct ieee80211_sub_if_data *sdata, | ||
927 | struct ieee80211_chanctx *ctx) | ||
928 | { | ||
929 | check_sdata_in_driver(sdata); | ||
930 | |||
931 | trace_drv_unassign_vif_chanctx(local, sdata, ctx); | ||
932 | if (local->ops->unassign_vif_chanctx) | ||
933 | local->ops->unassign_vif_chanctx(&local->hw, | ||
934 | &sdata->vif, | ||
935 | &ctx->conf); | ||
936 | trace_drv_return_void(local); | ||
937 | } | ||
938 | |||
874 | #endif /* __MAC80211_DRIVER_OPS */ | 939 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bf87c70ac6c5..c7386b2b767e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "rate.h" | 26 | #include "rate.h" |
27 | 27 | ||
28 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) | 28 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) |
29 | #define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) | ||
30 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) | 29 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) |
31 | 30 | ||
32 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) | 31 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) |
@@ -39,7 +38,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
39 | const u8 *bssid, const int beacon_int, | 38 | const u8 *bssid, const int beacon_int, |
40 | struct ieee80211_channel *chan, | 39 | struct ieee80211_channel *chan, |
41 | const u32 basic_rates, | 40 | const u32 basic_rates, |
42 | const u16 capability, u64 tsf) | 41 | const u16 capability, u64 tsf, |
42 | bool creator) | ||
43 | { | 43 | { |
44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
45 | struct ieee80211_local *local = sdata->local; | 45 | struct ieee80211_local *local = sdata->local; |
@@ -72,25 +72,27 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
72 | /* if merging, indicate to driver that we leave the old IBSS */ | 72 | /* if merging, indicate to driver that we leave the old IBSS */ |
73 | if (sdata->vif.bss_conf.ibss_joined) { | 73 | if (sdata->vif.bss_conf.ibss_joined) { |
74 | sdata->vif.bss_conf.ibss_joined = false; | 74 | sdata->vif.bss_conf.ibss_joined = false; |
75 | sdata->vif.bss_conf.ibss_creator = false; | ||
75 | netif_carrier_off(sdata->dev); | 76 | netif_carrier_off(sdata->dev); |
76 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | 77 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); |
77 | } | 78 | } |
78 | 79 | ||
79 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
80 | |||
81 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 80 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
82 | 81 | ||
83 | local->oper_channel = chan; | ||
84 | channel_type = ifibss->channel_type; | 82 | channel_type = ifibss->channel_type; |
85 | if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) | 83 | if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) |
86 | channel_type = NL80211_CHAN_HT20; | 84 | channel_type = NL80211_CHAN_HT20; |
87 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 85 | |
88 | /* can only fail due to HT40+/- mismatch */ | 86 | ieee80211_vif_release_channel(sdata); |
89 | channel_type = NL80211_CHAN_HT20; | 87 | if (ieee80211_vif_use_channel(sdata, chan, channel_type, |
90 | WARN_ON(!ieee80211_set_channel_type(local, sdata, | 88 | ifibss->fixed_channel ? |
91 | NL80211_CHAN_HT20)); | 89 | IEEE80211_CHANCTX_SHARED : |
90 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
91 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
92 | return; | ||
92 | } | 93 | } |
93 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 94 | |
95 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
94 | 96 | ||
95 | sband = local->hw.wiphy->bands[chan->band]; | 97 | sband = local->hw.wiphy->bands[chan->band]; |
96 | 98 | ||
@@ -197,6 +199,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
197 | bss_change |= BSS_CHANGED_HT; | 199 | bss_change |= BSS_CHANGED_HT; |
198 | bss_change |= BSS_CHANGED_IBSS; | 200 | bss_change |= BSS_CHANGED_IBSS; |
199 | sdata->vif.bss_conf.ibss_joined = true; | 201 | sdata->vif.bss_conf.ibss_joined = true; |
202 | sdata->vif.bss_conf.ibss_creator = creator; | ||
200 | ieee80211_bss_info_change_notify(sdata, bss_change); | 203 | ieee80211_bss_info_change_notify(sdata, bss_change); |
201 | 204 | ||
202 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); | 205 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); |
@@ -249,7 +252,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
249 | cbss->channel, | 252 | cbss->channel, |
250 | basic_rates, | 253 | basic_rates, |
251 | cbss->capability, | 254 | cbss->capability, |
252 | cbss->tsf); | 255 | cbss->tsf, |
256 | false); | ||
253 | } | 257 | } |
254 | 258 | ||
255 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | 259 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, |
@@ -279,7 +283,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
279 | ibss_dbg(sdata, | 283 | ibss_dbg(sdata, |
280 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", | 284 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", |
281 | sdata->vif.addr, addr, sdata->u.ibss.bssid); | 285 | sdata->vif.addr, addr, sdata->u.ibss.bssid); |
282 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 286 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, |
283 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 287 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
284 | } | 288 | } |
285 | return sta; | 289 | return sta; |
@@ -294,7 +298,8 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
294 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 298 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
295 | struct ieee80211_local *local = sdata->local; | 299 | struct ieee80211_local *local = sdata->local; |
296 | struct sta_info *sta; | 300 | struct sta_info *sta; |
297 | int band = local->oper_channel->band; | 301 | struct ieee80211_chanctx_conf *chanctx_conf; |
302 | int band; | ||
298 | 303 | ||
299 | /* | 304 | /* |
300 | * XXX: Consider removing the least recently used entry and | 305 | * XXX: Consider removing the least recently used entry and |
@@ -317,6 +322,13 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
317 | return NULL; | 322 | return NULL; |
318 | } | 323 | } |
319 | 324 | ||
325 | rcu_read_lock(); | ||
326 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
327 | if (WARN_ON_ONCE(!chanctx_conf)) | ||
328 | return NULL; | ||
329 | band = chanctx_conf->channel->band; | ||
330 | rcu_read_unlock(); | ||
331 | |||
320 | sta = sta_info_alloc(sdata, addr, GFP_KERNEL); | 332 | sta = sta_info_alloc(sdata, addr, GFP_KERNEL); |
321 | if (!sta) { | 333 | if (!sta) { |
322 | rcu_read_lock(); | 334 | rcu_read_lock(); |
@@ -389,7 +401,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
389 | * However, try to reply to authentication attempts if someone | 401 | * However, try to reply to authentication attempts if someone |
390 | * has actually implemented this. | 402 | * has actually implemented this. |
391 | */ | 403 | */ |
392 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, | 404 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, 0, NULL, 0, |
393 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); | 405 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); |
394 | } | 406 | } |
395 | 407 | ||
@@ -517,7 +529,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
517 | goto put_bss; | 529 | goto put_bss; |
518 | 530 | ||
519 | /* different channel */ | 531 | /* different channel */ |
520 | if (cbss->channel != local->oper_channel) | 532 | if (sdata->u.ibss.fixed_channel && |
533 | sdata->u.ibss.channel != cbss->channel) | ||
521 | goto put_bss; | 534 | goto put_bss; |
522 | 535 | ||
523 | /* different SSID */ | 536 | /* different SSID */ |
@@ -592,7 +605,8 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
592 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 605 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
593 | struct ieee80211_local *local = sdata->local; | 606 | struct ieee80211_local *local = sdata->local; |
594 | struct sta_info *sta; | 607 | struct sta_info *sta; |
595 | int band = local->oper_channel->band; | 608 | struct ieee80211_chanctx_conf *chanctx_conf; |
609 | int band; | ||
596 | 610 | ||
597 | /* | 611 | /* |
598 | * XXX: Consider removing the least recently used entry and | 612 | * XXX: Consider removing the least recently used entry and |
@@ -610,6 +624,15 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
610 | if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) | 624 | if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) |
611 | return; | 625 | return; |
612 | 626 | ||
627 | rcu_read_lock(); | ||
628 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
629 | if (WARN_ON_ONCE(!chanctx_conf)) { | ||
630 | rcu_read_unlock(); | ||
631 | return; | ||
632 | } | ||
633 | band = chanctx_conf->channel->band; | ||
634 | rcu_read_unlock(); | ||
635 | |||
613 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 636 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
614 | if (!sta) | 637 | if (!sta) |
615 | return; | 638 | return; |
@@ -715,7 +738,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
715 | 738 | ||
716 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 739 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
717 | ifibss->channel, ifibss->basic_rates, | 740 | ifibss->channel, ifibss->basic_rates, |
718 | capability, 0); | 741 | capability, 0, true); |
719 | } | 742 | } |
720 | 743 | ||
721 | /* | 744 | /* |
@@ -784,18 +807,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
784 | int interval = IEEE80211_SCAN_INTERVAL; | 807 | int interval = IEEE80211_SCAN_INTERVAL; |
785 | 808 | ||
786 | if (time_after(jiffies, ifibss->ibss_join_req + | 809 | if (time_after(jiffies, ifibss->ibss_join_req + |
787 | IEEE80211_IBSS_JOIN_TIMEOUT)) { | 810 | IEEE80211_IBSS_JOIN_TIMEOUT)) |
788 | if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) { | 811 | ieee80211_sta_create_ibss(sdata); |
789 | ieee80211_sta_create_ibss(sdata); | ||
790 | return; | ||
791 | } | ||
792 | sdata_info(sdata, "IBSS not allowed on %d MHz\n", | ||
793 | local->oper_channel->center_freq); | ||
794 | |||
795 | /* No IBSS found - decrease scan interval and continue | ||
796 | * scanning. */ | ||
797 | interval = IEEE80211_SCAN_INTERVAL_SLOW; | ||
798 | } | ||
799 | 812 | ||
800 | mod_timer(&ifibss->timer, | 813 | mod_timer(&ifibss->timer, |
801 | round_jiffies(jiffies + interval)); | 814 | round_jiffies(jiffies + interval)); |
@@ -1086,17 +1099,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1086 | sdata->u.ibss.channel_type = params->channel_type; | 1099 | sdata->u.ibss.channel_type = params->channel_type; |
1087 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 1100 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
1088 | 1101 | ||
1089 | /* fix ourselves to that channel now already */ | ||
1090 | if (params->channel_fixed) { | ||
1091 | sdata->local->oper_channel = params->channel; | ||
1092 | if (!ieee80211_set_channel_type(sdata->local, sdata, | ||
1093 | params->channel_type)) { | ||
1094 | mutex_unlock(&sdata->u.ibss.mtx); | ||
1095 | kfree_skb(skb); | ||
1096 | return -EINVAL; | ||
1097 | } | ||
1098 | } | ||
1099 | |||
1100 | if (params->ie) { | 1102 | if (params->ie) { |
1101 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, | 1103 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, |
1102 | GFP_KERNEL); | 1104 | GFP_KERNEL); |
@@ -1134,6 +1136,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1134 | changed |= BSS_CHANGED_HT; | 1136 | changed |= BSS_CHANGED_HT; |
1135 | ieee80211_bss_info_change_notify(sdata, changed); | 1137 | ieee80211_bss_info_change_notify(sdata, changed); |
1136 | 1138 | ||
1139 | sdata->smps_mode = IEEE80211_SMPS_OFF; | ||
1140 | sdata->needed_rx_chains = sdata->local->rx_chains; | ||
1141 | |||
1137 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 1142 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
1138 | 1143 | ||
1139 | return 0; | 1144 | return 0; |
@@ -1197,6 +1202,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1197 | lockdep_is_held(&sdata->u.ibss.mtx)); | 1202 | lockdep_is_held(&sdata->u.ibss.mtx)); |
1198 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); | 1203 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); |
1199 | sdata->vif.bss_conf.ibss_joined = false; | 1204 | sdata->vif.bss_conf.ibss_joined = false; |
1205 | sdata->vif.bss_conf.ibss_creator = false; | ||
1200 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 1206 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
1201 | BSS_CHANGED_IBSS); | 1207 | BSS_CHANGED_IBSS); |
1202 | synchronize_rcu(); | 1208 | synchronize_rcu(); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c804550465b..3026519b236a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -280,23 +280,27 @@ struct probe_resp { | |||
280 | u8 data[0]; | 280 | u8 data[0]; |
281 | }; | 281 | }; |
282 | 282 | ||
283 | struct ieee80211_if_ap { | 283 | struct ps_data { |
284 | struct beacon_data __rcu *beacon; | ||
285 | struct probe_resp __rcu *probe_resp; | ||
286 | |||
287 | struct list_head vlans; | ||
288 | |||
289 | /* yes, this looks ugly, but guarantees that we can later use | 284 | /* yes, this looks ugly, but guarantees that we can later use |
290 | * bitmap_empty :) | 285 | * bitmap_empty :) |
291 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 286 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
292 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 287 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; |
293 | struct sk_buff_head ps_bc_buf; | 288 | struct sk_buff_head bc_buf; |
294 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 289 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
295 | atomic_t num_mcast_sta; /* number of stations receiving multicast */ | ||
296 | int dtim_count; | 290 | int dtim_count; |
297 | bool dtim_bc_mc; | 291 | bool dtim_bc_mc; |
298 | }; | 292 | }; |
299 | 293 | ||
294 | struct ieee80211_if_ap { | ||
295 | struct beacon_data __rcu *beacon; | ||
296 | struct probe_resp __rcu *probe_resp; | ||
297 | |||
298 | struct list_head vlans; | ||
299 | |||
300 | struct ps_data ps; | ||
301 | atomic_t num_mcast_sta; /* number of stations receiving multicast */ | ||
302 | }; | ||
303 | |||
300 | struct ieee80211_if_wds { | 304 | struct ieee80211_if_wds { |
301 | struct sta_info *sta; | 305 | struct sta_info *sta; |
302 | u8 remote_addr[ETH_ALEN]; | 306 | u8 remote_addr[ETH_ALEN]; |
@@ -316,7 +320,6 @@ struct mesh_stats { | |||
316 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ | 320 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ |
317 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ | 321 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ |
318 | __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ | 322 | __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ |
319 | atomic_t estab_plinks; | ||
320 | }; | 323 | }; |
321 | 324 | ||
322 | #define PREQ_Q_F_START 0x1 | 325 | #define PREQ_Q_F_START 0x1 |
@@ -378,8 +381,9 @@ struct ieee80211_mgd_auth_data { | |||
378 | u8 key_len, key_idx; | 381 | u8 key_len, key_idx; |
379 | bool done; | 382 | bool done; |
380 | 383 | ||
381 | size_t ie_len; | 384 | u16 sae_trans, sae_status; |
382 | u8 ie[]; | 385 | size_t data_len; |
386 | u8 data[]; | ||
383 | }; | 387 | }; |
384 | 388 | ||
385 | struct ieee80211_mgd_assoc_data { | 389 | struct ieee80211_mgd_assoc_data { |
@@ -433,7 +437,6 @@ struct ieee80211_if_managed { | |||
433 | bool powersave; /* powersave requested for this iface */ | 437 | bool powersave; /* powersave requested for this iface */ |
434 | bool broken_ap; /* AP is broken -- turn off powersave */ | 438 | bool broken_ap; /* AP is broken -- turn off powersave */ |
435 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | 439 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ |
436 | ap_smps, /* smps mode AP thinks we're in */ | ||
437 | driver_smps_mode; /* smps mode request */ | 440 | driver_smps_mode; /* smps mode request */ |
438 | 441 | ||
439 | struct work_struct request_smps_work; | 442 | struct work_struct request_smps_work; |
@@ -599,6 +602,7 @@ struct ieee80211_if_mesh { | |||
599 | int preq_queue_len; | 602 | int preq_queue_len; |
600 | struct mesh_stats mshstats; | 603 | struct mesh_stats mshstats; |
601 | struct mesh_config mshcfg; | 604 | struct mesh_config mshcfg; |
605 | atomic_t estab_plinks; | ||
602 | u32 mesh_seqnum; | 606 | u32 mesh_seqnum; |
603 | bool accepting_plinks; | 607 | bool accepting_plinks; |
604 | int num_gates; | 608 | int num_gates; |
@@ -610,7 +614,7 @@ struct ieee80211_if_mesh { | |||
610 | IEEE80211_MESH_SEC_SECURED = 0x2, | 614 | IEEE80211_MESH_SEC_SECURED = 0x2, |
611 | } security; | 615 | } security; |
612 | /* Extensible Synchronization Framework */ | 616 | /* Extensible Synchronization Framework */ |
613 | struct ieee80211_mesh_sync_ops *sync_ops; | 617 | const struct ieee80211_mesh_sync_ops *sync_ops; |
614 | s64 sync_offset_clockdrift_max; | 618 | s64 sync_offset_clockdrift_max; |
615 | spinlock_t sync_offset_lock; | 619 | spinlock_t sync_offset_lock; |
616 | bool adjusting_tbtt; | 620 | bool adjusting_tbtt; |
@@ -658,6 +662,30 @@ enum ieee80211_sdata_state_bits { | |||
658 | SDATA_STATE_OFFCHANNEL, | 662 | SDATA_STATE_OFFCHANNEL, |
659 | }; | 663 | }; |
660 | 664 | ||
665 | /** | ||
666 | * enum ieee80211_chanctx_mode - channel context configuration mode | ||
667 | * | ||
668 | * @IEEE80211_CHANCTX_SHARED: channel context may be used by | ||
669 | * multiple interfaces | ||
670 | * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used | ||
671 | * only by a single interface. This can be used for example for | ||
672 | * non-fixed channel IBSS. | ||
673 | */ | ||
674 | enum ieee80211_chanctx_mode { | ||
675 | IEEE80211_CHANCTX_SHARED, | ||
676 | IEEE80211_CHANCTX_EXCLUSIVE | ||
677 | }; | ||
678 | |||
679 | struct ieee80211_chanctx { | ||
680 | struct list_head list; | ||
681 | struct rcu_head rcu_head; | ||
682 | |||
683 | enum ieee80211_chanctx_mode mode; | ||
684 | int refcount; | ||
685 | |||
686 | struct ieee80211_chanctx_conf conf; | ||
687 | }; | ||
688 | |||
661 | struct ieee80211_sub_if_data { | 689 | struct ieee80211_sub_if_data { |
662 | struct list_head list; | 690 | struct list_head list; |
663 | 691 | ||
@@ -704,11 +732,17 @@ struct ieee80211_sub_if_data { | |||
704 | 732 | ||
705 | struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; | 733 | struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; |
706 | 734 | ||
735 | /* used to reconfigure hardware SM PS */ | ||
736 | struct work_struct recalc_smps; | ||
737 | |||
707 | struct work_struct work; | 738 | struct work_struct work; |
708 | struct sk_buff_head skb_queue; | 739 | struct sk_buff_head skb_queue; |
709 | 740 | ||
710 | bool arp_filter_state; | 741 | bool arp_filter_state; |
711 | 742 | ||
743 | u8 needed_rx_chains; | ||
744 | enum ieee80211_smps_mode smps_mode; | ||
745 | |||
712 | /* | 746 | /* |
713 | * AP this belongs to: self in AP mode and | 747 | * AP this belongs to: self in AP mode and |
714 | * corresponding AP in VLAN mode, NULL for | 748 | * corresponding AP in VLAN mode, NULL for |
@@ -749,6 +783,21 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | |||
749 | return container_of(p, struct ieee80211_sub_if_data, vif); | 783 | return container_of(p, struct ieee80211_sub_if_data, vif); |
750 | } | 784 | } |
751 | 785 | ||
786 | static inline enum ieee80211_band | ||
787 | ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) | ||
788 | { | ||
789 | enum ieee80211_band band = IEEE80211_BAND_2GHZ; | ||
790 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
791 | |||
792 | rcu_read_lock(); | ||
793 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
794 | if (!WARN_ON(!chanctx_conf)) | ||
795 | band = chanctx_conf->channel->band; | ||
796 | rcu_read_unlock(); | ||
797 | |||
798 | return band; | ||
799 | } | ||
800 | |||
752 | enum sdata_queue_type { | 801 | enum sdata_queue_type { |
753 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, | 802 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, |
754 | IEEE80211_SDATA_QUEUE_AGG_START = 1, | 803 | IEEE80211_SDATA_QUEUE_AGG_START = 1, |
@@ -821,6 +870,7 @@ enum { | |||
821 | * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to | 870 | * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to |
822 | * send out data | 871 | * send out data |
823 | * @SCAN_RESUME: Resume the scan and scan the next channel | 872 | * @SCAN_RESUME: Resume the scan and scan the next channel |
873 | * @SCAN_ABORT: Abort the scan and go back to operating channel | ||
824 | */ | 874 | */ |
825 | enum mac80211_scan_state { | 875 | enum mac80211_scan_state { |
826 | SCAN_DECISION, | 876 | SCAN_DECISION, |
@@ -828,6 +878,7 @@ enum mac80211_scan_state { | |||
828 | SCAN_SEND_PROBE, | 878 | SCAN_SEND_PROBE, |
829 | SCAN_SUSPEND, | 879 | SCAN_SUSPEND, |
830 | SCAN_RESUME, | 880 | SCAN_RESUME, |
881 | SCAN_ABORT, | ||
831 | }; | 882 | }; |
832 | 883 | ||
833 | struct ieee80211_local { | 884 | struct ieee80211_local { |
@@ -858,15 +909,14 @@ struct ieee80211_local { | |||
858 | 909 | ||
859 | bool wiphy_ciphers_allocated; | 910 | bool wiphy_ciphers_allocated; |
860 | 911 | ||
912 | bool use_chanctx; | ||
913 | |||
861 | /* protects the aggregated multicast list and filter calls */ | 914 | /* protects the aggregated multicast list and filter calls */ |
862 | spinlock_t filter_lock; | 915 | spinlock_t filter_lock; |
863 | 916 | ||
864 | /* used for uploading changed mc list */ | 917 | /* used for uploading changed mc list */ |
865 | struct work_struct reconfig_filter; | 918 | struct work_struct reconfig_filter; |
866 | 919 | ||
867 | /* used to reconfigure hardware SM PS */ | ||
868 | struct work_struct recalc_smps; | ||
869 | |||
870 | /* aggregated multicast list */ | 920 | /* aggregated multicast list */ |
871 | struct netdev_hw_addr_list mc_list; | 921 | struct netdev_hw_addr_list mc_list; |
872 | 922 | ||
@@ -903,6 +953,9 @@ struct ieee80211_local { | |||
903 | /* wowlan is enabled -- don't reconfig on resume */ | 953 | /* wowlan is enabled -- don't reconfig on resume */ |
904 | bool wowlan; | 954 | bool wowlan; |
905 | 955 | ||
956 | /* number of RX chains the hardware has */ | ||
957 | u8 rx_chains; | ||
958 | |||
906 | int tx_headroom; /* required headroom for hardware/radiotap */ | 959 | int tx_headroom; /* required headroom for hardware/radiotap */ |
907 | 960 | ||
908 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 961 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
@@ -980,13 +1033,19 @@ struct ieee80211_local { | |||
980 | enum mac80211_scan_state next_scan_state; | 1033 | enum mac80211_scan_state next_scan_state; |
981 | struct delayed_work scan_work; | 1034 | struct delayed_work scan_work; |
982 | struct ieee80211_sub_if_data __rcu *scan_sdata; | 1035 | struct ieee80211_sub_if_data __rcu *scan_sdata; |
1036 | struct ieee80211_channel *csa_channel; | ||
1037 | /* For backward compatibility only -- do not use */ | ||
1038 | struct ieee80211_channel *_oper_channel; | ||
983 | enum nl80211_channel_type _oper_channel_type; | 1039 | enum nl80211_channel_type _oper_channel_type; |
984 | struct ieee80211_channel *oper_channel, *csa_channel; | ||
985 | 1040 | ||
986 | /* Temporary remain-on-channel for off-channel operations */ | 1041 | /* Temporary remain-on-channel for off-channel operations */ |
987 | struct ieee80211_channel *tmp_channel; | 1042 | struct ieee80211_channel *tmp_channel; |
988 | enum nl80211_channel_type tmp_channel_type; | 1043 | enum nl80211_channel_type tmp_channel_type; |
989 | 1044 | ||
1045 | /* channel contexts */ | ||
1046 | struct list_head chanctx_list; | ||
1047 | struct mutex chanctx_mtx; | ||
1048 | |||
990 | /* SNMP counters */ | 1049 | /* SNMP counters */ |
991 | /* dot11CountersTable */ | 1050 | /* dot11CountersTable */ |
992 | u32 dot11TransmittedFragmentCount; | 1051 | u32 dot11TransmittedFragmentCount; |
@@ -1091,6 +1150,8 @@ struct ieee80211_local { | |||
1091 | 1150 | ||
1092 | /* virtual monitor interface */ | 1151 | /* virtual monitor interface */ |
1093 | struct ieee80211_sub_if_data __rcu *monitor_sdata; | 1152 | struct ieee80211_sub_if_data __rcu *monitor_sdata; |
1153 | struct ieee80211_channel *monitor_channel; | ||
1154 | enum nl80211_channel_type monitor_channel_type; | ||
1094 | }; | 1155 | }; |
1095 | 1156 | ||
1096 | static inline struct ieee80211_sub_if_data * | 1157 | static inline struct ieee80211_sub_if_data * |
@@ -1133,6 +1194,8 @@ struct ieee802_11_elems { | |||
1133 | u8 *wmm_param; | 1194 | u8 *wmm_param; |
1134 | struct ieee80211_ht_cap *ht_cap_elem; | 1195 | struct ieee80211_ht_cap *ht_cap_elem; |
1135 | struct ieee80211_ht_operation *ht_operation; | 1196 | struct ieee80211_ht_operation *ht_operation; |
1197 | struct ieee80211_vht_cap *vht_cap_elem; | ||
1198 | struct ieee80211_vht_operation *vht_operation; | ||
1136 | struct ieee80211_meshconf_ie *mesh_config; | 1199 | struct ieee80211_meshconf_ie *mesh_config; |
1137 | u8 *mesh_id; | 1200 | u8 *mesh_id; |
1138 | u8 *peering; | 1201 | u8 *peering; |
@@ -1359,6 +1422,13 @@ void ieee80211_ba_session_work(struct work_struct *work); | |||
1359 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); | 1422 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); |
1360 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); | 1423 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); |
1361 | 1424 | ||
1425 | u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs); | ||
1426 | |||
1427 | /* VHT */ | ||
1428 | void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | ||
1429 | struct ieee80211_supported_band *sband, | ||
1430 | struct ieee80211_vht_cap *vht_cap_ie, | ||
1431 | struct ieee80211_sta_vht_cap *vht_cap); | ||
1362 | /* Spectrum management */ | 1432 | /* Spectrum management */ |
1363 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1433 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
1364 | struct ieee80211_mgmt *mgmt, | 1434 | struct ieee80211_mgmt *mgmt, |
@@ -1393,11 +1463,42 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke | |||
1393 | gfp_t gfp); | 1463 | gfp_t gfp); |
1394 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | 1464 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
1395 | bool bss_notify); | 1465 | bool bss_notify); |
1396 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1466 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, |
1467 | enum ieee80211_band band); | ||
1468 | |||
1469 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | ||
1470 | struct sk_buff *skb, int tid, | ||
1471 | enum ieee80211_band band); | ||
1397 | 1472 | ||
1398 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | 1473 | static inline void |
1399 | struct sk_buff *skb, int tid); | 1474 | ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
1400 | static void inline ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | 1475 | struct sk_buff *skb, int tid, |
1476 | enum ieee80211_band band) | ||
1477 | { | ||
1478 | rcu_read_lock(); | ||
1479 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, band); | ||
1480 | rcu_read_unlock(); | ||
1481 | } | ||
1482 | |||
1483 | static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | ||
1484 | struct sk_buff *skb, int tid) | ||
1485 | { | ||
1486 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
1487 | |||
1488 | rcu_read_lock(); | ||
1489 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1490 | if (WARN_ON(!chanctx_conf)) { | ||
1491 | rcu_read_unlock(); | ||
1492 | kfree_skb(skb); | ||
1493 | return; | ||
1494 | } | ||
1495 | |||
1496 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, | ||
1497 | chanctx_conf->channel->band); | ||
1498 | rcu_read_unlock(); | ||
1499 | } | ||
1500 | |||
1501 | static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | ||
1401 | struct sk_buff *skb) | 1502 | struct sk_buff *skb) |
1402 | { | 1503 | { |
1403 | /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ | 1504 | /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ |
@@ -1444,7 +1545,7 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
1444 | } | 1545 | } |
1445 | 1546 | ||
1446 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1547 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1447 | u16 transaction, u16 auth_alg, | 1548 | u16 transaction, u16 auth_alg, u16 status, |
1448 | u8 *extra, size_t extra_len, const u8 *bssid, | 1549 | u8 *extra, size_t extra_len, const u8 *bssid, |
1449 | const u8 *da, const u8 *key, u8 key_len, u8 key_idx); | 1550 | const u8 *da, const u8 *key, u8 key_len, u8 key_idx); |
1450 | void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | 1551 | void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, |
@@ -1464,7 +1565,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1464 | const u8 *ssid, size_t ssid_len, | 1565 | const u8 *ssid, size_t ssid_len, |
1465 | const u8 *ie, size_t ie_len, | 1566 | const u8 *ie, size_t ie_len, |
1466 | u32 ratemask, bool directed, bool no_cck, | 1567 | u32 ratemask, bool directed, bool no_cck, |
1467 | struct ieee80211_channel *channel); | 1568 | struct ieee80211_channel *channel, bool scan); |
1468 | 1569 | ||
1469 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 1570 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
1470 | const size_t supp_rates_len, | 1571 | const size_t supp_rates_len, |
@@ -1474,7 +1575,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | |||
1474 | enum ieee80211_band band, u32 *basic_rates); | 1575 | enum ieee80211_band band, u32 *basic_rates); |
1475 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | 1576 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, |
1476 | enum ieee80211_smps_mode smps_mode); | 1577 | enum ieee80211_smps_mode smps_mode); |
1477 | void ieee80211_recalc_smps(struct ieee80211_local *local); | 1578 | void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); |
1478 | 1579 | ||
1479 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, | 1580 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, |
1480 | const u8 *ids, int n_ids, size_t offset); | 1581 | const u8 *ids, int n_ids, size_t offset); |
@@ -1495,21 +1596,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | |||
1495 | enum ieee80211_band band); | 1596 | enum ieee80211_band band); |
1496 | 1597 | ||
1497 | /* channel management */ | 1598 | /* channel management */ |
1498 | enum ieee80211_chan_mode { | ||
1499 | CHAN_MODE_UNDEFINED, | ||
1500 | CHAN_MODE_HOPPING, | ||
1501 | CHAN_MODE_FIXED, | ||
1502 | }; | ||
1503 | |||
1504 | enum ieee80211_chan_mode | ||
1505 | ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
1506 | struct ieee80211_sub_if_data *ignore); | ||
1507 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | ||
1508 | struct ieee80211_sub_if_data *sdata, | ||
1509 | enum nl80211_channel_type chantype); | ||
1510 | enum nl80211_channel_type | 1599 | enum nl80211_channel_type |
1511 | ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); | 1600 | ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); |
1512 | 1601 | ||
1602 | int __must_check | ||
1603 | ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | ||
1604 | struct ieee80211_channel *channel, | ||
1605 | enum nl80211_channel_type channel_type, | ||
1606 | enum ieee80211_chanctx_mode mode); | ||
1607 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); | ||
1608 | |||
1609 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | ||
1610 | struct ieee80211_chanctx *chanctx); | ||
1611 | |||
1513 | #ifdef CONFIG_MAC80211_NOINLINE | 1612 | #ifdef CONFIG_MAC80211_NOINLINE |
1514 | #define debug_noinline noinline | 1613 | #define debug_noinline noinline |
1515 | #else | 1614 | #else |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7de7717ad67d..bc3e3e1db093 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -380,6 +380,15 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
380 | goto out_unlock; | 380 | goto out_unlock; |
381 | } | 381 | } |
382 | 382 | ||
383 | ret = ieee80211_vif_use_channel(sdata, local->monitor_channel, | ||
384 | local->monitor_channel_type, | ||
385 | IEEE80211_CHANCTX_EXCLUSIVE); | ||
386 | if (ret) { | ||
387 | drv_remove_interface(local, sdata); | ||
388 | kfree(sdata); | ||
389 | goto out_unlock; | ||
390 | } | ||
391 | |||
383 | rcu_assign_pointer(local->monitor_sdata, sdata); | 392 | rcu_assign_pointer(local->monitor_sdata, sdata); |
384 | out_unlock: | 393 | out_unlock: |
385 | mutex_unlock(&local->iflist_mtx); | 394 | mutex_unlock(&local->iflist_mtx); |
@@ -403,6 +412,8 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
403 | rcu_assign_pointer(local->monitor_sdata, NULL); | 412 | rcu_assign_pointer(local->monitor_sdata, NULL); |
404 | synchronize_net(); | 413 | synchronize_net(); |
405 | 414 | ||
415 | ieee80211_vif_release_channel(sdata); | ||
416 | |||
406 | drv_remove_interface(local, sdata); | 417 | drv_remove_interface(local, sdata); |
407 | 418 | ||
408 | kfree(sdata); | 419 | kfree(sdata); |
@@ -665,7 +676,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
665 | struct sk_buff *skb, *tmp; | 676 | struct sk_buff *skb, *tmp; |
666 | u32 hw_reconf_flags = 0; | 677 | u32 hw_reconf_flags = 0; |
667 | int i; | 678 | int i; |
668 | enum nl80211_channel_type orig_ct; | ||
669 | 679 | ||
670 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | 680 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); |
671 | 681 | ||
@@ -729,6 +739,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
729 | del_timer_sync(&local->dynamic_ps_timer); | 739 | del_timer_sync(&local->dynamic_ps_timer); |
730 | cancel_work_sync(&local->dynamic_ps_enable_work); | 740 | cancel_work_sync(&local->dynamic_ps_enable_work); |
731 | 741 | ||
742 | cancel_work_sync(&sdata->recalc_smps); | ||
743 | |||
732 | /* APs need special treatment */ | 744 | /* APs need special treatment */ |
733 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 745 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
734 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 746 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
@@ -755,8 +767,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
755 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | 767 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); |
756 | 768 | ||
757 | /* free all potentially still buffered bcast frames */ | 769 | /* free all potentially still buffered bcast frames */ |
758 | local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); | 770 | local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); |
759 | skb_queue_purge(&sdata->u.ap.ps_bc_buf); | 771 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); |
760 | } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 772 | } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
761 | ieee80211_mgd_stop(sdata); | 773 | ieee80211_mgd_stop(sdata); |
762 | } | 774 | } |
@@ -837,14 +849,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
837 | hw_reconf_flags = 0; | 849 | hw_reconf_flags = 0; |
838 | } | 850 | } |
839 | 851 | ||
840 | /* Re-calculate channel-type, in case there are multiple vifs | ||
841 | * on different channel types. | ||
842 | */ | ||
843 | orig_ct = local->_oper_channel_type; | ||
844 | ieee80211_set_channel_type(local, NULL, NL80211_CHAN_NO_HT); | ||
845 | |||
846 | /* do after stop to avoid reconfiguring when we stop anyway */ | 852 | /* do after stop to avoid reconfiguring when we stop anyway */ |
847 | if (hw_reconf_flags || (orig_ct != local->_oper_channel_type)) | 853 | if (hw_reconf_flags) |
848 | ieee80211_hw_config(local, hw_reconf_flags); | 854 | ieee80211_hw_config(local, hw_reconf_flags); |
849 | 855 | ||
850 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 856 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
@@ -1121,6 +1127,13 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
1121 | } | 1127 | } |
1122 | } | 1128 | } |
1123 | 1129 | ||
1130 | static void ieee80211_recalc_smps_work(struct work_struct *work) | ||
1131 | { | ||
1132 | struct ieee80211_sub_if_data *sdata = | ||
1133 | container_of(work, struct ieee80211_sub_if_data, recalc_smps); | ||
1134 | |||
1135 | ieee80211_recalc_smps(sdata); | ||
1136 | } | ||
1124 | 1137 | ||
1125 | /* | 1138 | /* |
1126 | * Helper function to initialise an interface to a specific type. | 1139 | * Helper function to initialise an interface to a specific type. |
@@ -1149,6 +1162,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1149 | 1162 | ||
1150 | skb_queue_head_init(&sdata->skb_queue); | 1163 | skb_queue_head_init(&sdata->skb_queue); |
1151 | INIT_WORK(&sdata->work, ieee80211_iface_work); | 1164 | INIT_WORK(&sdata->work, ieee80211_iface_work); |
1165 | INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); | ||
1152 | 1166 | ||
1153 | switch (type) { | 1167 | switch (type) { |
1154 | case NL80211_IFTYPE_P2P_GO: | 1168 | case NL80211_IFTYPE_P2P_GO: |
@@ -1157,7 +1171,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1157 | sdata->vif.p2p = true; | 1171 | sdata->vif.p2p = true; |
1158 | /* fall through */ | 1172 | /* fall through */ |
1159 | case NL80211_IFTYPE_AP: | 1173 | case NL80211_IFTYPE_AP: |
1160 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 1174 | skb_queue_head_init(&sdata->u.ap.ps.bc_buf); |
1161 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 1175 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
1162 | break; | 1176 | break; |
1163 | case NL80211_IFTYPE_P2P_CLIENT: | 1177 | case NL80211_IFTYPE_P2P_CLIENT: |
@@ -1282,11 +1296,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1282 | if (type == ieee80211_vif_type_p2p(&sdata->vif)) | 1296 | if (type == ieee80211_vif_type_p2p(&sdata->vif)) |
1283 | return 0; | 1297 | return 0; |
1284 | 1298 | ||
1285 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | ||
1286 | if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS && | ||
1287 | type == NL80211_IFTYPE_ADHOC) | ||
1288 | return -EOPNOTSUPP; | ||
1289 | |||
1290 | if (ieee80211_sdata_running(sdata)) { | 1299 | if (ieee80211_sdata_running(sdata)) { |
1291 | ret = ieee80211_runtime_change_iftype(sdata, type); | 1300 | ret = ieee80211_runtime_change_iftype(sdata, type); |
1292 | if (ret) | 1301 | if (ret) |
@@ -1298,9 +1307,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1298 | } | 1307 | } |
1299 | 1308 | ||
1300 | /* reset some values that shouldn't be kept across type changes */ | 1309 | /* reset some values that shouldn't be kept across type changes */ |
1301 | sdata->vif.bss_conf.basic_rates = | ||
1302 | ieee80211_mandatory_rates(sdata->local, | ||
1303 | sdata->local->oper_channel->band); | ||
1304 | sdata->drop_unencrypted = 0; | 1310 | sdata->drop_unencrypted = 0; |
1305 | if (type == NL80211_IFTYPE_STATION) | 1311 | if (type == NL80211_IFTYPE_STATION) |
1306 | sdata->u.mgd.use_4addr = false; | 1312 | sdata->u.mgd.use_4addr = false; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c80c4490351c..fd8345c20051 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -93,23 +93,21 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
93 | ieee80211_configure_filter(local); | 93 | ieee80211_configure_filter(local); |
94 | } | 94 | } |
95 | 95 | ||
96 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 96 | static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) |
97 | { | 97 | { |
98 | struct ieee80211_channel *chan; | 98 | struct ieee80211_channel *chan; |
99 | int ret = 0; | 99 | u32 changed = 0; |
100 | int power; | 100 | int power; |
101 | enum nl80211_channel_type channel_type; | 101 | enum nl80211_channel_type channel_type; |
102 | u32 offchannel_flag; | 102 | u32 offchannel_flag; |
103 | 103 | ||
104 | might_sleep(); | ||
105 | |||
106 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 104 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
107 | if (local->scan_channel) { | 105 | if (local->scan_channel) { |
108 | chan = local->scan_channel; | 106 | chan = local->scan_channel; |
109 | /* If scanning on oper channel, use whatever channel-type | 107 | /* If scanning on oper channel, use whatever channel-type |
110 | * is currently in use. | 108 | * is currently in use. |
111 | */ | 109 | */ |
112 | if (chan == local->oper_channel) | 110 | if (chan == local->_oper_channel) |
113 | channel_type = local->_oper_channel_type; | 111 | channel_type = local->_oper_channel_type; |
114 | else | 112 | else |
115 | channel_type = NL80211_CHAN_NO_HT; | 113 | channel_type = NL80211_CHAN_NO_HT; |
@@ -117,11 +115,11 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
117 | chan = local->tmp_channel; | 115 | chan = local->tmp_channel; |
118 | channel_type = local->tmp_channel_type; | 116 | channel_type = local->tmp_channel_type; |
119 | } else { | 117 | } else { |
120 | chan = local->oper_channel; | 118 | chan = local->_oper_channel; |
121 | channel_type = local->_oper_channel_type; | 119 | channel_type = local->_oper_channel_type; |
122 | } | 120 | } |
123 | 121 | ||
124 | if (chan != local->oper_channel || | 122 | if (chan != local->_oper_channel || |
125 | channel_type != local->_oper_channel_type) | 123 | channel_type != local->_oper_channel_type) |
126 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 124 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
127 | else | 125 | else |
@@ -164,6 +162,21 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
164 | local->hw.conf.power_level = power; | 162 | local->hw.conf.power_level = power; |
165 | } | 163 | } |
166 | 164 | ||
165 | return changed; | ||
166 | } | ||
167 | |||
168 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | ||
169 | { | ||
170 | int ret = 0; | ||
171 | |||
172 | might_sleep(); | ||
173 | |||
174 | if (!local->use_chanctx) | ||
175 | changed |= ieee80211_hw_conf_chan(local); | ||
176 | else | ||
177 | changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL | | ||
178 | IEEE80211_CONF_CHANGE_POWER); | ||
179 | |||
167 | if (changed && local->open_count) { | 180 | if (changed && local->open_count) { |
168 | ret = drv_config(local, changed); | 181 | ret = drv_config(local, changed); |
169 | /* | 182 | /* |
@@ -359,14 +372,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
359 | } | 372 | } |
360 | EXPORT_SYMBOL(ieee80211_restart_hw); | 373 | EXPORT_SYMBOL(ieee80211_restart_hw); |
361 | 374 | ||
362 | static void ieee80211_recalc_smps_work(struct work_struct *work) | ||
363 | { | ||
364 | struct ieee80211_local *local = | ||
365 | container_of(work, struct ieee80211_local, recalc_smps); | ||
366 | |||
367 | ieee80211_recalc_smps(local); | ||
368 | } | ||
369 | |||
370 | #ifdef CONFIG_INET | 375 | #ifdef CONFIG_INET |
371 | static int ieee80211_ifa_changed(struct notifier_block *nb, | 376 | static int ieee80211_ifa_changed(struct notifier_block *nb, |
372 | unsigned long data, void *arg) | 377 | unsigned long data, void *arg) |
@@ -540,6 +545,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
540 | struct ieee80211_local *local; | 545 | struct ieee80211_local *local; |
541 | int priv_size, i; | 546 | int priv_size, i; |
542 | struct wiphy *wiphy; | 547 | struct wiphy *wiphy; |
548 | bool use_chanctx; | ||
543 | 549 | ||
544 | if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || | 550 | if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || |
545 | !ops->add_interface || !ops->remove_interface || | 551 | !ops->add_interface || !ops->remove_interface || |
@@ -549,6 +555,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
549 | if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) | 555 | if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) |
550 | return NULL; | 556 | return NULL; |
551 | 557 | ||
558 | /* check all or no channel context operations exist */ | ||
559 | i = !!ops->add_chanctx + !!ops->remove_chanctx + | ||
560 | !!ops->change_chanctx + !!ops->assign_vif_chanctx + | ||
561 | !!ops->unassign_vif_chanctx; | ||
562 | if (WARN_ON(i != 0 && i != 5)) | ||
563 | return NULL; | ||
564 | use_chanctx = i == 5; | ||
565 | |||
552 | /* Ensure 32-byte alignment of our private data and hw private data. | 566 | /* Ensure 32-byte alignment of our private data and hw private data. |
553 | * We use the wiphy priv data for both our ieee80211_local and for | 567 | * We use the wiphy priv data for both our ieee80211_local and for |
554 | * the driver's private data | 568 | * the driver's private data |
@@ -584,8 +598,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
584 | if (ops->remain_on_channel) | 598 | if (ops->remain_on_channel) |
585 | wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 599 | wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
586 | 600 | ||
587 | wiphy->features = NL80211_FEATURE_SK_TX_STATUS | | 601 | wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | |
588 | NL80211_FEATURE_HT_IBSS; | 602 | NL80211_FEATURE_SAE | |
603 | NL80211_FEATURE_HT_IBSS; | ||
604 | |||
605 | if (!ops->hw_scan) | ||
606 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | | ||
607 | NL80211_FEATURE_AP_SCAN; | ||
608 | |||
589 | 609 | ||
590 | if (!ops->set_key) | 610 | if (!ops->set_key) |
591 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 611 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
@@ -599,6 +619,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
599 | local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); | 619 | local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); |
600 | 620 | ||
601 | local->ops = ops; | 621 | local->ops = ops; |
622 | local->use_chanctx = use_chanctx; | ||
602 | 623 | ||
603 | /* set up some defaults */ | 624 | /* set up some defaults */ |
604 | local->hw.queues = 1; | 625 | local->hw.queues = 1; |
@@ -626,6 +647,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
626 | spin_lock_init(&local->filter_lock); | 647 | spin_lock_init(&local->filter_lock); |
627 | spin_lock_init(&local->queue_stop_reason_lock); | 648 | spin_lock_init(&local->queue_stop_reason_lock); |
628 | 649 | ||
650 | INIT_LIST_HEAD(&local->chanctx_list); | ||
651 | mutex_init(&local->chanctx_mtx); | ||
652 | |||
629 | /* | 653 | /* |
630 | * The rx_skb_queue is only accessed from tasklets, | 654 | * The rx_skb_queue is only accessed from tasklets, |
631 | * but other SKB queues are used from within IRQ | 655 | * but other SKB queues are used from within IRQ |
@@ -641,7 +665,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
641 | INIT_WORK(&local->restart_work, ieee80211_restart_work); | 665 | INIT_WORK(&local->restart_work, ieee80211_restart_work); |
642 | 666 | ||
643 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); | 667 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
644 | INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work); | ||
645 | local->smps_mode = IEEE80211_SMPS_OFF; | 668 | local->smps_mode = IEEE80211_SMPS_OFF; |
646 | 669 | ||
647 | INIT_WORK(&local->dynamic_ps_enable_work, | 670 | INIT_WORK(&local->dynamic_ps_enable_work, |
@@ -719,6 +742,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
719 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) | 742 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) |
720 | return -EINVAL; | 743 | return -EINVAL; |
721 | 744 | ||
745 | if (!local->use_chanctx) { | ||
746 | for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { | ||
747 | const struct ieee80211_iface_combination *comb; | ||
748 | |||
749 | comb = &local->hw.wiphy->iface_combinations[i]; | ||
750 | |||
751 | if (comb->num_different_channels > 1) | ||
752 | return -EINVAL; | ||
753 | } | ||
754 | } else { | ||
755 | /* | ||
756 | * WDS is currently prohibited when channel contexts are used | ||
757 | * because there's no clear definition of which channel WDS | ||
758 | * type interfaces use | ||
759 | */ | ||
760 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) | ||
761 | return -EINVAL; | ||
762 | } | ||
763 | |||
722 | /* Only HW csum features are currently compatible with mac80211 */ | 764 | /* Only HW csum features are currently compatible with mac80211 */ |
723 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 765 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
724 | NETIF_F_HW_CSUM; | 766 | NETIF_F_HW_CSUM; |
@@ -728,6 +770,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
728 | if (hw->max_report_rates == 0) | 770 | if (hw->max_report_rates == 0) |
729 | hw->max_report_rates = hw->max_rates; | 771 | hw->max_report_rates = hw->max_rates; |
730 | 772 | ||
773 | local->rx_chains = 1; | ||
774 | |||
731 | /* | 775 | /* |
732 | * generic code guarantees at least one band, | 776 | * generic code guarantees at least one band, |
733 | * set this very early because much code assumes | 777 | * set this very early because much code assumes |
@@ -743,18 +787,29 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
743 | sband = local->hw.wiphy->bands[band]; | 787 | sband = local->hw.wiphy->bands[band]; |
744 | if (!sband) | 788 | if (!sband) |
745 | continue; | 789 | continue; |
746 | if (!local->oper_channel) { | 790 | if (!local->use_chanctx && !local->_oper_channel) { |
747 | /* init channel we're on */ | 791 | /* init channel we're on */ |
748 | local->hw.conf.channel = | 792 | local->hw.conf.channel = |
749 | local->oper_channel = &sband->channels[0]; | 793 | local->_oper_channel = &sband->channels[0]; |
750 | local->hw.conf.channel_type = NL80211_CHAN_NO_HT; | 794 | local->hw.conf.channel_type = NL80211_CHAN_NO_HT; |
751 | } | 795 | } |
796 | if (!local->monitor_channel) { | ||
797 | local->monitor_channel = &sband->channels[0]; | ||
798 | local->monitor_channel_type = NL80211_CHAN_NO_HT; | ||
799 | } | ||
752 | channels += sband->n_channels; | 800 | channels += sband->n_channels; |
753 | 801 | ||
754 | if (max_bitrates < sband->n_bitrates) | 802 | if (max_bitrates < sband->n_bitrates) |
755 | max_bitrates = sband->n_bitrates; | 803 | max_bitrates = sband->n_bitrates; |
756 | supp_ht = supp_ht || sband->ht_cap.ht_supported; | 804 | supp_ht = supp_ht || sband->ht_cap.ht_supported; |
757 | supp_vht = supp_vht || sband->vht_cap.vht_supported; | 805 | supp_vht = supp_vht || sband->vht_cap.vht_supported; |
806 | |||
807 | if (sband->ht_cap.ht_supported) | ||
808 | local->rx_chains = | ||
809 | max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs), | ||
810 | local->rx_chains); | ||
811 | |||
812 | /* TODO: consider VHT for RX chains, hopefully it's the same */ | ||
758 | } | 813 | } |
759 | 814 | ||
760 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + | 815 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + |
@@ -778,19 +833,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
778 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | 833 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); |
779 | hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); | 834 | hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); |
780 | 835 | ||
781 | /* | 836 | /* mac80211 doesn't support more than one IBSS interface right now */ |
782 | * mac80211 doesn't support more than 1 channel, and also not more | ||
783 | * than one IBSS interface | ||
784 | */ | ||
785 | for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { | 837 | for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { |
786 | const struct ieee80211_iface_combination *c; | 838 | const struct ieee80211_iface_combination *c; |
787 | int j; | 839 | int j; |
788 | 840 | ||
789 | c = &hw->wiphy->iface_combinations[i]; | 841 | c = &hw->wiphy->iface_combinations[i]; |
790 | 842 | ||
791 | if (c->num_different_channels > 1) | ||
792 | return -EINVAL; | ||
793 | |||
794 | for (j = 0; j < c->n_limits; j++) | 843 | for (j = 0; j < c->n_limits; j++) |
795 | if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && | 844 | if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && |
796 | c->limits[j].max > 1) | 845 | c->limits[j].max > 1) |
@@ -832,7 +881,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
832 | 881 | ||
833 | if (supp_vht) | 882 | if (supp_vht) |
834 | local->scan_ies_len += | 883 | local->scan_ies_len += |
835 | 2 + sizeof(struct ieee80211_vht_capabilities); | 884 | 2 + sizeof(struct ieee80211_vht_cap); |
836 | 885 | ||
837 | if (!local->ops->hw_scan) { | 886 | if (!local->ops->hw_scan) { |
838 | /* For hw_scan, driver needs to set these up. */ | 887 | /* For hw_scan, driver needs to set these up. */ |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index ff0296c7bab8..a350cab4b339 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -97,7 +97,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, | |||
97 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) | 97 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) |
98 | goto mismatch; | 98 | goto mismatch; |
99 | 99 | ||
100 | ieee80211_sta_get_rates(local, ie, local->oper_channel->band, | 100 | ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), |
101 | &basic_rates); | 101 | &basic_rates); |
102 | 102 | ||
103 | if (sdata->vif.bss_conf.basic_rates != basic_rates) | 103 | if (sdata->vif.bss_conf.basic_rates != basic_rates) |
@@ -264,7 +264,7 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
264 | /* Authentication Protocol identifier */ | 264 | /* Authentication Protocol identifier */ |
265 | *pos++ = ifmsh->mesh_auth_id; | 265 | *pos++ = ifmsh->mesh_auth_id; |
266 | /* Mesh Formation Info - number of neighbors */ | 266 | /* Mesh Formation Info - number of neighbors */ |
267 | neighbors = atomic_read(&ifmsh->mshstats.estab_plinks); | 267 | neighbors = atomic_read(&ifmsh->estab_plinks); |
268 | /* Number of neighbor mesh STAs or 15 whichever is smaller */ | 268 | /* Number of neighbor mesh STAs or 15 whichever is smaller */ |
269 | neighbors = (neighbors > 15) ? 15 : neighbors; | 269 | neighbors = (neighbors > 15) ? 15 : neighbors; |
270 | *pos++ = neighbors << 1; | 270 | *pos++ = neighbors << 1; |
@@ -355,12 +355,22 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, | |||
355 | { | 355 | { |
356 | struct ieee80211_local *local = sdata->local; | 356 | struct ieee80211_local *local = sdata->local; |
357 | struct ieee80211_supported_band *sband; | 357 | struct ieee80211_supported_band *sband; |
358 | struct ieee80211_channel *chan = local->oper_channel; | 358 | struct ieee80211_chanctx_conf *chanctx_conf; |
359 | struct ieee80211_channel *chan; | ||
359 | u8 *pos; | 360 | u8 *pos; |
360 | 361 | ||
361 | if (skb_tailroom(skb) < 3) | 362 | if (skb_tailroom(skb) < 3) |
362 | return -ENOMEM; | 363 | return -ENOMEM; |
363 | 364 | ||
365 | rcu_read_lock(); | ||
366 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
367 | if (WARN_ON(!chanctx_conf)) { | ||
368 | rcu_read_unlock(); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | chan = chanctx_conf->channel; | ||
372 | rcu_read_unlock(); | ||
373 | |||
364 | sband = local->hw.wiphy->bands[chan->band]; | 374 | sband = local->hw.wiphy->bands[chan->band]; |
365 | if (sband->band == IEEE80211_BAND_2GHZ) { | 375 | if (sband->band == IEEE80211_BAND_2GHZ) { |
366 | pos = skb_put(skb, 2 + 1); | 376 | pos = skb_put(skb, 2 + 1); |
@@ -376,10 +386,11 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb, | |||
376 | struct ieee80211_sub_if_data *sdata) | 386 | struct ieee80211_sub_if_data *sdata) |
377 | { | 387 | { |
378 | struct ieee80211_local *local = sdata->local; | 388 | struct ieee80211_local *local = sdata->local; |
389 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
379 | struct ieee80211_supported_band *sband; | 390 | struct ieee80211_supported_band *sband; |
380 | u8 *pos; | 391 | u8 *pos; |
381 | 392 | ||
382 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 393 | sband = local->hw.wiphy->bands[band]; |
383 | if (!sband->ht_cap.ht_supported || | 394 | if (!sband->ht_cap.ht_supported || |
384 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) | 395 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) |
385 | return 0; | 396 | return 0; |
@@ -397,14 +408,26 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb, | |||
397 | struct ieee80211_sub_if_data *sdata) | 408 | struct ieee80211_sub_if_data *sdata) |
398 | { | 409 | { |
399 | struct ieee80211_local *local = sdata->local; | 410 | struct ieee80211_local *local = sdata->local; |
400 | struct ieee80211_channel *channel = local->oper_channel; | 411 | struct ieee80211_chanctx_conf *chanctx_conf; |
412 | struct ieee80211_channel *channel; | ||
401 | enum nl80211_channel_type channel_type = | 413 | enum nl80211_channel_type channel_type = |
402 | sdata->vif.bss_conf.channel_type; | 414 | sdata->vif.bss_conf.channel_type; |
403 | struct ieee80211_supported_band *sband = | 415 | struct ieee80211_supported_band *sband; |
404 | local->hw.wiphy->bands[channel->band]; | 416 | struct ieee80211_sta_ht_cap *ht_cap; |
405 | struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; | ||
406 | u8 *pos; | 417 | u8 *pos; |
407 | 418 | ||
419 | rcu_read_lock(); | ||
420 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
421 | if (WARN_ON(!chanctx_conf)) { | ||
422 | rcu_read_unlock(); | ||
423 | return -EINVAL; | ||
424 | } | ||
425 | channel = chanctx_conf->channel; | ||
426 | rcu_read_unlock(); | ||
427 | |||
428 | sband = local->hw.wiphy->bands[channel->band]; | ||
429 | ht_cap = &sband->ht_cap; | ||
430 | |||
408 | if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) | 431 | if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) |
409 | return 0; | 432 | return 0; |
410 | 433 | ||
@@ -610,7 +633,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
610 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; | 633 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; |
611 | sdata->vif.bss_conf.basic_rates = | 634 | sdata->vif.bss_conf.basic_rates = |
612 | ieee80211_mandatory_rates(sdata->local, | 635 | ieee80211_mandatory_rates(sdata->local, |
613 | sdata->local->oper_channel->band); | 636 | ieee80211_get_sdata_band(sdata)); |
614 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | | 637 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
615 | BSS_CHANGED_BEACON_ENABLED | | 638 | BSS_CHANGED_BEACON_ENABLED | |
616 | BSS_CHANGED_HT | | 639 | BSS_CHANGED_HT | |
@@ -680,8 +703,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
680 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 703 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
681 | &elems); | 704 | &elems); |
682 | 705 | ||
683 | /* ignore beacons from secure mesh peers if our security is off */ | 706 | /* ignore non-mesh or secure / unsecure mismatch */ |
684 | if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) | 707 | if ((!elems.mesh_id || !elems.mesh_config) || |
708 | (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || | ||
709 | (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) | ||
685 | return; | 710 | return; |
686 | 711 | ||
687 | if (elems.ds_params && elems.ds_params_len == 1) | 712 | if (elems.ds_params && elems.ds_params_len == 1) |
@@ -694,8 +719,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
694 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 719 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
695 | return; | 720 | return; |
696 | 721 | ||
697 | if (elems.mesh_id && elems.mesh_config && | 722 | if (mesh_matches_local(sdata, &elems)) |
698 | mesh_matches_local(sdata, &elems)) | ||
699 | mesh_neighbour_update(sdata, mgmt->sa, &elems); | 723 | mesh_neighbour_update(sdata, mgmt->sa, &elems); |
700 | 724 | ||
701 | if (ifmsh->sync_ops) | 725 | if (ifmsh->sync_ops) |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 25d0f17dec71..9285f3f67e66 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -256,7 +256,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | |||
256 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); | 256 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); |
257 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); | 257 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); |
258 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); | 258 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); |
259 | struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); | 259 | const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); |
260 | 260 | ||
261 | /* Mesh paths */ | 261 | /* Mesh paths */ |
262 | int mesh_nexthop_lookup(struct sk_buff *skb, | 262 | int mesh_nexthop_lookup(struct sk_buff *skb, |
@@ -324,7 +324,7 @@ extern int mesh_allocated; | |||
324 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) | 324 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) |
325 | { | 325 | { |
326 | return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks - | 326 | return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks - |
327 | atomic_read(&sdata->u.mesh.mshstats.estab_plinks); | 327 | atomic_read(&sdata->u.mesh.estab_plinks); |
328 | } | 328 | } |
329 | 329 | ||
330 | static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) | 330 | static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 3ab34d816897..234fe755968b 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -50,14 +50,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
50 | static inline | 50 | static inline |
51 | u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) | 51 | u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) |
52 | { | 52 | { |
53 | atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); | 53 | atomic_inc(&sdata->u.mesh.estab_plinks); |
54 | return mesh_accept_plinks_update(sdata); | 54 | return mesh_accept_plinks_update(sdata); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline | 57 | static inline |
58 | u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | 58 | u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) |
59 | { | 59 | { |
60 | atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); | 60 | atomic_dec(&sdata->u.mesh.estab_plinks); |
61 | return mesh_accept_plinks_update(sdata); | 61 | return mesh_accept_plinks_update(sdata); |
62 | } | 62 | } |
63 | 63 | ||
@@ -252,6 +252,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
252 | mgmt->u.action.u.self_prot.action_code = action; | 252 | mgmt->u.action.u.self_prot.action_code = action; |
253 | 253 | ||
254 | if (action != WLAN_SP_MESH_PEERING_CLOSE) { | 254 | if (action != WLAN_SP_MESH_PEERING_CLOSE) { |
255 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
256 | |||
255 | /* capability info */ | 257 | /* capability info */ |
256 | pos = skb_put(skb, 2); | 258 | pos = skb_put(skb, 2); |
257 | memset(pos, 0, 2); | 259 | memset(pos, 0, 2); |
@@ -260,10 +262,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
260 | pos = skb_put(skb, 2); | 262 | pos = skb_put(skb, 2); |
261 | memcpy(pos + 2, &plid, 2); | 263 | memcpy(pos + 2, &plid, 2); |
262 | } | 264 | } |
263 | if (ieee80211_add_srates_ie(sdata, skb, true, | 265 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || |
264 | local->oper_channel->band) || | 266 | ieee80211_add_ext_srates_ie(sdata, skb, true, band) || |
265 | ieee80211_add_ext_srates_ie(sdata, skb, true, | ||
266 | local->oper_channel->band) || | ||
267 | mesh_add_rsn_ie(skb, sdata) || | 267 | mesh_add_rsn_ie(skb, sdata) || |
268 | mesh_add_meshid_ie(skb, sdata) || | 268 | mesh_add_meshid_ie(skb, sdata) || |
269 | mesh_add_meshconf_ie(skb, sdata)) | 269 | mesh_add_meshconf_ie(skb, sdata)) |
@@ -343,7 +343,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata, | |||
343 | struct ieee802_11_elems *elems) | 343 | struct ieee802_11_elems *elems) |
344 | { | 344 | { |
345 | struct ieee80211_local *local = sdata->local; | 345 | struct ieee80211_local *local = sdata->local; |
346 | enum ieee80211_band band = local->oper_channel->band; | 346 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
347 | struct ieee80211_supported_band *sband; | 347 | struct ieee80211_supported_band *sband; |
348 | u32 rates, basic_rates = 0; | 348 | u32 rates, basic_rates = 0; |
349 | struct sta_info *sta; | 349 | struct sta_info *sta; |
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index a16b7b4b1e02..407c8705e10d 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c | |||
@@ -234,49 +234,7 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
234 | spin_unlock_bh(&ifmsh->sync_offset_lock); | 234 | spin_unlock_bh(&ifmsh->sync_offset_lock); |
235 | } | 235 | } |
236 | 236 | ||
237 | static const u8 *mesh_get_vendor_oui(struct ieee80211_sub_if_data *sdata) | 237 | static const struct sync_method sync_methods[] = { |
238 | { | ||
239 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
240 | u8 offset; | ||
241 | |||
242 | if (!ifmsh->ie || !ifmsh->ie_len) | ||
243 | return NULL; | ||
244 | |||
245 | offset = ieee80211_ie_split_vendor(ifmsh->ie, | ||
246 | ifmsh->ie_len, 0); | ||
247 | |||
248 | if (!offset) | ||
249 | return NULL; | ||
250 | |||
251 | return ifmsh->ie + offset + 2; | ||
252 | } | ||
253 | |||
254 | static void mesh_sync_vendor_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | ||
255 | u16 stype, | ||
256 | struct ieee80211_mgmt *mgmt, | ||
257 | struct ieee802_11_elems *elems, | ||
258 | struct ieee80211_rx_status *rx_status) | ||
259 | { | ||
260 | const u8 *oui; | ||
261 | |||
262 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); | ||
263 | msync_dbg(sdata, "called mesh_sync_vendor_rx_bcn_presp\n"); | ||
264 | oui = mesh_get_vendor_oui(sdata); | ||
265 | /* here you would implement the vendor offset tracking for this oui */ | ||
266 | } | ||
267 | |||
268 | static void mesh_sync_vendor_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | ||
269 | { | ||
270 | const u8 *oui; | ||
271 | |||
272 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); | ||
273 | msync_dbg(sdata, "called mesh_sync_vendor_adjust_tbtt\n"); | ||
274 | oui = mesh_get_vendor_oui(sdata); | ||
275 | /* here you would implement the vendor tsf adjustment for this oui */ | ||
276 | } | ||
277 | |||
278 | /* global variable */ | ||
279 | static struct sync_method sync_methods[] = { | ||
280 | { | 238 | { |
281 | .method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, | 239 | .method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, |
282 | .ops = { | 240 | .ops = { |
@@ -284,18 +242,11 @@ static struct sync_method sync_methods[] = { | |||
284 | .adjust_tbtt = &mesh_sync_offset_adjust_tbtt, | 242 | .adjust_tbtt = &mesh_sync_offset_adjust_tbtt, |
285 | } | 243 | } |
286 | }, | 244 | }, |
287 | { | ||
288 | .method = IEEE80211_SYNC_METHOD_VENDOR, | ||
289 | .ops = { | ||
290 | .rx_bcn_presp = &mesh_sync_vendor_rx_bcn_presp, | ||
291 | .adjust_tbtt = &mesh_sync_vendor_adjust_tbtt, | ||
292 | } | ||
293 | }, | ||
294 | }; | 245 | }; |
295 | 246 | ||
296 | struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) | 247 | const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) |
297 | { | 248 | { |
298 | struct ieee80211_mesh_sync_ops *ops = NULL; | 249 | const struct ieee80211_mesh_sync_ops *ops = NULL; |
299 | u8 i; | 250 | u8 i; |
300 | 251 | ||
301 | for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) { | 252 | for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1b7eed252fe9..1d1fdf0791f0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -178,20 +178,30 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata, | |||
178 | { | 178 | { |
179 | struct ieee80211_local *local = sdata->local; | 179 | struct ieee80211_local *local = sdata->local; |
180 | struct ieee80211_supported_band *sband; | 180 | struct ieee80211_supported_band *sband; |
181 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
182 | struct ieee80211_channel *chan; | ||
181 | struct sta_info *sta; | 183 | struct sta_info *sta; |
182 | u32 changed = 0; | 184 | u32 changed = 0; |
183 | u16 ht_opmode; | 185 | u16 ht_opmode; |
184 | bool disable_40 = false; | 186 | bool disable_40 = false; |
185 | 187 | ||
186 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 188 | rcu_read_lock(); |
189 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
190 | if (WARN_ON(!chanctx_conf)) { | ||
191 | rcu_read_unlock(); | ||
192 | return 0; | ||
193 | } | ||
194 | chan = chanctx_conf->channel; | ||
195 | rcu_read_unlock(); | ||
196 | sband = local->hw.wiphy->bands[chan->band]; | ||
187 | 197 | ||
188 | switch (sdata->vif.bss_conf.channel_type) { | 198 | switch (sdata->vif.bss_conf.channel_type) { |
189 | case NL80211_CHAN_HT40PLUS: | 199 | case NL80211_CHAN_HT40PLUS: |
190 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40PLUS) | 200 | if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) |
191 | disable_40 = true; | 201 | disable_40 = true; |
192 | break; | 202 | break; |
193 | case NL80211_CHAN_HT40MINUS: | 203 | case NL80211_CHAN_HT40MINUS: |
194 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40MINUS) | 204 | if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) |
195 | disable_40 = true; | 205 | disable_40 = true; |
196 | break; | 206 | break; |
197 | default: | 207 | default: |
@@ -343,7 +353,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, | |||
343 | cap = vht_cap.cap; | 353 | cap = vht_cap.cap; |
344 | 354 | ||
345 | /* reserve and fill IE */ | 355 | /* reserve and fill IE */ |
346 | pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2); | 356 | pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); |
347 | ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); | 357 | ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); |
348 | } | 358 | } |
349 | 359 | ||
@@ -359,11 +369,21 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
359 | int i, count, rates_len, supp_rates_len; | 369 | int i, count, rates_len, supp_rates_len; |
360 | u16 capab; | 370 | u16 capab; |
361 | struct ieee80211_supported_band *sband; | 371 | struct ieee80211_supported_band *sband; |
372 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
373 | struct ieee80211_channel *chan; | ||
362 | u32 rates = 0; | 374 | u32 rates = 0; |
363 | 375 | ||
364 | lockdep_assert_held(&ifmgd->mtx); | 376 | lockdep_assert_held(&ifmgd->mtx); |
365 | 377 | ||
366 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 378 | rcu_read_lock(); |
379 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
380 | if (WARN_ON(!chanctx_conf)) { | ||
381 | rcu_read_unlock(); | ||
382 | return; | ||
383 | } | ||
384 | chan = chanctx_conf->channel; | ||
385 | rcu_read_unlock(); | ||
386 | sband = local->hw.wiphy->bands[chan->band]; | ||
367 | 387 | ||
368 | if (assoc_data->supp_rates_len) { | 388 | if (assoc_data->supp_rates_len) { |
369 | /* | 389 | /* |
@@ -392,7 +412,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
392 | 4 + /* power capability */ | 412 | 4 + /* power capability */ |
393 | 2 + 2 * sband->n_channels + /* supported channels */ | 413 | 2 + 2 * sband->n_channels + /* supported channels */ |
394 | 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ | 414 | 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ |
395 | 2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */ | 415 | 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ |
396 | assoc_data->ie_len + /* extra IEs */ | 416 | assoc_data->ie_len + /* extra IEs */ |
397 | 9, /* WMM */ | 417 | 9, /* WMM */ |
398 | GFP_KERNEL); | 418 | GFP_KERNEL); |
@@ -485,7 +505,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
485 | *pos++ = WLAN_EID_PWR_CAPABILITY; | 505 | *pos++ = WLAN_EID_PWR_CAPABILITY; |
486 | *pos++ = 2; | 506 | *pos++ = 2; |
487 | *pos++ = 0; /* min tx power */ | 507 | *pos++ = 0; /* min tx power */ |
488 | *pos++ = local->oper_channel->max_power; /* max tx power */ | 508 | *pos++ = chan->max_power; /* max tx power */ |
489 | 509 | ||
490 | /* 2. supported channels */ | 510 | /* 2. supported channels */ |
491 | /* TODO: get this in reg domain format */ | 511 | /* TODO: get this in reg domain format */ |
@@ -523,7 +543,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
523 | 543 | ||
524 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 544 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
525 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, | 545 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, |
526 | sband, local->oper_channel, ifmgd->ap_smps); | 546 | sband, chan, sdata->smps_mode); |
527 | 547 | ||
528 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | 548 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) |
529 | ieee80211_add_vht_ie(sdata, skb, sband); | 549 | ieee80211_add_vht_ie(sdata, skb, sband); |
@@ -657,18 +677,18 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
657 | if (!ifmgd->associated) | 677 | if (!ifmgd->associated) |
658 | goto out; | 678 | goto out; |
659 | 679 | ||
660 | sdata->local->oper_channel = sdata->local->csa_channel; | 680 | sdata->local->_oper_channel = sdata->local->csa_channel; |
661 | if (!sdata->local->ops->channel_switch) { | 681 | if (!sdata->local->ops->channel_switch) { |
662 | /* call "hw_config" only if doing sw channel switch */ | 682 | /* call "hw_config" only if doing sw channel switch */ |
663 | ieee80211_hw_config(sdata->local, | 683 | ieee80211_hw_config(sdata->local, |
664 | IEEE80211_CONF_CHANGE_CHANNEL); | 684 | IEEE80211_CONF_CHANGE_CHANNEL); |
665 | } else { | 685 | } else { |
666 | /* update the device channel directly */ | 686 | /* update the device channel directly */ |
667 | sdata->local->hw.conf.channel = sdata->local->oper_channel; | 687 | sdata->local->hw.conf.channel = sdata->local->_oper_channel; |
668 | } | 688 | } |
669 | 689 | ||
670 | /* XXX: shouldn't really modify cfg80211-owned data! */ | 690 | /* XXX: shouldn't really modify cfg80211-owned data! */ |
671 | ifmgd->associated->channel = sdata->local->oper_channel; | 691 | ifmgd->associated->channel = sdata->local->_oper_channel; |
672 | 692 | ||
673 | /* XXX: wait for a beacon first? */ | 693 | /* XXX: wait for a beacon first? */ |
674 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 694 | ieee80211_wake_queues_by_reason(&sdata->local->hw, |
@@ -680,11 +700,8 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
680 | 700 | ||
681 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) | 701 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) |
682 | { | 702 | { |
683 | struct ieee80211_sub_if_data *sdata; | 703 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
684 | struct ieee80211_if_managed *ifmgd; | 704 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
685 | |||
686 | sdata = vif_to_sdata(vif); | ||
687 | ifmgd = &sdata->u.mgd; | ||
688 | 705 | ||
689 | trace_api_chswitch_done(sdata, success); | 706 | trace_api_chswitch_done(sdata, success); |
690 | if (!success) { | 707 | if (!success) { |
@@ -723,6 +740,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
723 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 740 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
724 | int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, | 741 | int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, |
725 | cbss->channel->band); | 742 | cbss->channel->band); |
743 | struct ieee80211_chanctx *chanctx; | ||
726 | 744 | ||
727 | ASSERT_MGD_MTX(ifmgd); | 745 | ASSERT_MGD_MTX(ifmgd); |
728 | 746 | ||
@@ -748,10 +766,34 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
748 | return; | 766 | return; |
749 | } | 767 | } |
750 | 768 | ||
751 | sdata->local->csa_channel = new_ch; | ||
752 | |||
753 | ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; | 769 | ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; |
754 | 770 | ||
771 | if (sdata->local->use_chanctx) { | ||
772 | sdata_info(sdata, | ||
773 | "not handling channel switch with channel contexts\n"); | ||
774 | ieee80211_queue_work(&sdata->local->hw, | ||
775 | &ifmgd->csa_connection_drop_work); | ||
776 | } | ||
777 | |||
778 | mutex_lock(&sdata->local->chanctx_mtx); | ||
779 | if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { | ||
780 | mutex_unlock(&sdata->local->chanctx_mtx); | ||
781 | return; | ||
782 | } | ||
783 | chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf), | ||
784 | struct ieee80211_chanctx, conf); | ||
785 | if (chanctx->refcount > 1) { | ||
786 | sdata_info(sdata, | ||
787 | "channel switch with multiple interfaces on the same channel, disconnecting\n"); | ||
788 | ieee80211_queue_work(&sdata->local->hw, | ||
789 | &ifmgd->csa_connection_drop_work); | ||
790 | mutex_unlock(&sdata->local->chanctx_mtx); | ||
791 | return; | ||
792 | } | ||
793 | mutex_unlock(&sdata->local->chanctx_mtx); | ||
794 | |||
795 | sdata->local->csa_channel = new_ch; | ||
796 | |||
755 | if (sw_elem->mode) | 797 | if (sw_elem->mode) |
756 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 798 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
757 | IEEE80211_QUEUE_STOP_REASON_CSA); | 799 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -1280,7 +1322,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | |||
1280 | } | 1322 | } |
1281 | 1323 | ||
1282 | use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); | 1324 | use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); |
1283 | if (sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) | 1325 | if (ieee80211_get_sdata_band(sdata) == IEEE80211_BAND_5GHZ) |
1284 | use_short_slot = true; | 1326 | use_short_slot = true; |
1285 | 1327 | ||
1286 | if (use_protection != bss_conf->use_cts_prot) { | 1328 | if (use_protection != bss_conf->use_cts_prot) { |
@@ -1350,7 +1392,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1350 | ieee80211_recalc_ps(local, -1); | 1392 | ieee80211_recalc_ps(local, -1); |
1351 | mutex_unlock(&local->iflist_mtx); | 1393 | mutex_unlock(&local->iflist_mtx); |
1352 | 1394 | ||
1353 | ieee80211_recalc_smps(local); | 1395 | ieee80211_recalc_smps(sdata); |
1354 | ieee80211_recalc_ps_vif(sdata); | 1396 | ieee80211_recalc_ps_vif(sdata); |
1355 | 1397 | ||
1356 | netif_tx_start_all_queues(sdata->dev); | 1398 | netif_tx_start_all_queues(sdata->dev); |
@@ -1465,9 +1507,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1465 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; | 1507 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
1466 | ieee80211_bss_info_change_notify(sdata, changed); | 1508 | ieee80211_bss_info_change_notify(sdata, changed); |
1467 | 1509 | ||
1468 | /* channel(_type) changes are handled by ieee80211_hw_config */ | 1510 | ieee80211_vif_release_channel(sdata); |
1469 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); | ||
1470 | ieee80211_hw_config(local, 0); | ||
1471 | 1511 | ||
1472 | /* disassociated - set to defaults now */ | 1512 | /* disassociated - set to defaults now */ |
1473 | ieee80211_set_wmm_default(sdata, false); | 1513 | ieee80211_set_wmm_default(sdata, false); |
@@ -1589,7 +1629,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1589 | 1629 | ||
1590 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, | 1630 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, |
1591 | 0, (u32) -1, true, false, | 1631 | 0, (u32) -1, true, false, |
1592 | ifmgd->associated->channel); | 1632 | ifmgd->associated->channel, false); |
1593 | } | 1633 | } |
1594 | 1634 | ||
1595 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); | 1635 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); |
@@ -1692,8 +1732,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
1692 | ssid_len = ssid[1]; | 1732 | ssid_len = ssid[1]; |
1693 | 1733 | ||
1694 | skb = ieee80211_build_probe_req(sdata, cbss->bssid, | 1734 | skb = ieee80211_build_probe_req(sdata, cbss->bssid, |
1695 | (u32) -1, | 1735 | (u32) -1, cbss->channel, |
1696 | sdata->local->oper_channel, | ||
1697 | ssid + 2, ssid_len, | 1736 | ssid + 2, ssid_len, |
1698 | NULL, 0, true); | 1737 | NULL, 0, true); |
1699 | 1738 | ||
@@ -1804,6 +1843,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
1804 | 1843 | ||
1805 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 1844 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
1806 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 1845 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
1846 | ieee80211_vif_release_channel(sdata); | ||
1807 | } | 1847 | } |
1808 | 1848 | ||
1809 | cfg80211_put_bss(auth_data->bss); | 1849 | cfg80211_put_bss(auth_data->bss); |
@@ -1824,7 +1864,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
1824 | return; | 1864 | return; |
1825 | auth_data->expected_transaction = 4; | 1865 | auth_data->expected_transaction = 4; |
1826 | drv_mgd_prepare_tx(sdata->local, sdata); | 1866 | drv_mgd_prepare_tx(sdata->local, sdata); |
1827 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, | 1867 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, |
1828 | elems.challenge - 2, elems.challenge_len + 2, | 1868 | elems.challenge - 2, elems.challenge_len + 2, |
1829 | auth_data->bss->bssid, auth_data->bss->bssid, | 1869 | auth_data->bss->bssid, auth_data->bss->bssid, |
1830 | auth_data->key, auth_data->key_len, | 1870 | auth_data->key, auth_data->key_len, |
@@ -1858,8 +1898,13 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1858 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | 1898 | status_code = le16_to_cpu(mgmt->u.auth.status_code); |
1859 | 1899 | ||
1860 | if (auth_alg != ifmgd->auth_data->algorithm || | 1900 | if (auth_alg != ifmgd->auth_data->algorithm || |
1861 | auth_transaction != ifmgd->auth_data->expected_transaction) | 1901 | auth_transaction != ifmgd->auth_data->expected_transaction) { |
1902 | sdata_info(sdata, "%pM unexpected authentication state: alg %d (expected %d) transact %d (expected %d)\n", | ||
1903 | mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, | ||
1904 | auth_transaction, | ||
1905 | ifmgd->auth_data->expected_transaction); | ||
1862 | return RX_MGMT_NONE; | 1906 | return RX_MGMT_NONE; |
1907 | } | ||
1863 | 1908 | ||
1864 | if (status_code != WLAN_STATUS_SUCCESS) { | 1909 | if (status_code != WLAN_STATUS_SUCCESS) { |
1865 | sdata_info(sdata, "%pM denied authentication (status %d)\n", | 1910 | sdata_info(sdata, "%pM denied authentication (status %d)\n", |
@@ -1872,6 +1917,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1872 | case WLAN_AUTH_OPEN: | 1917 | case WLAN_AUTH_OPEN: |
1873 | case WLAN_AUTH_LEAP: | 1918 | case WLAN_AUTH_LEAP: |
1874 | case WLAN_AUTH_FT: | 1919 | case WLAN_AUTH_FT: |
1920 | case WLAN_AUTH_SAE: | ||
1875 | break; | 1921 | break; |
1876 | case WLAN_AUTH_SHARED_KEY: | 1922 | case WLAN_AUTH_SHARED_KEY: |
1877 | if (ifmgd->auth_data->expected_transaction != 4) { | 1923 | if (ifmgd->auth_data->expected_transaction != 4) { |
@@ -1891,6 +1937,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1891 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 1937 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
1892 | run_again(ifmgd, ifmgd->auth_data->timeout); | 1938 | run_again(ifmgd, ifmgd->auth_data->timeout); |
1893 | 1939 | ||
1940 | if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && | ||
1941 | ifmgd->auth_data->expected_transaction != 2) { | ||
1942 | /* | ||
1943 | * Report auth frame to user space for processing since another | ||
1944 | * round of Authentication frames is still needed. | ||
1945 | */ | ||
1946 | return RX_MGMT_CFG80211_RX_AUTH; | ||
1947 | } | ||
1948 | |||
1894 | /* move station state to auth */ | 1949 | /* move station state to auth */ |
1895 | mutex_lock(&sdata->local->sta_mtx); | 1950 | mutex_lock(&sdata->local->sta_mtx); |
1896 | sta = sta_info_get(sdata, bssid); | 1951 | sta = sta_info_get(sdata, bssid); |
@@ -2030,6 +2085,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2030 | 2085 | ||
2031 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2086 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
2032 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 2087 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
2088 | ieee80211_vif_release_channel(sdata); | ||
2033 | } | 2089 | } |
2034 | 2090 | ||
2035 | kfree(assoc_data); | 2091 | kfree(assoc_data); |
@@ -2091,7 +2147,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2091 | return false; | 2147 | return false; |
2092 | } | 2148 | } |
2093 | 2149 | ||
2094 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 2150 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; |
2095 | 2151 | ||
2096 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 2152 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2097 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, | 2153 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
@@ -2100,6 +2156,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2100 | sta->supports_40mhz = | 2156 | sta->supports_40mhz = |
2101 | sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 2157 | sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
2102 | 2158 | ||
2159 | if (elems.vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | ||
2160 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | ||
2161 | elems.vht_cap_elem, | ||
2162 | &sta->sta.vht_cap); | ||
2163 | |||
2103 | rate_control_rate_init(sta); | 2164 | rate_control_rate_init(sta); |
2104 | 2165 | ||
2105 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) | 2166 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) |
@@ -2369,8 +2430,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2369 | size_t baselen; | 2430 | size_t baselen; |
2370 | struct ieee802_11_elems elems; | 2431 | struct ieee802_11_elems elems; |
2371 | struct ieee80211_local *local = sdata->local; | 2432 | struct ieee80211_local *local = sdata->local; |
2433 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
2434 | struct ieee80211_channel *chan; | ||
2372 | u32 changed = 0; | 2435 | u32 changed = 0; |
2373 | bool erp_valid, directed_tim = false; | 2436 | bool erp_valid; |
2374 | u8 erp_value = 0; | 2437 | u8 erp_value = 0; |
2375 | u32 ncrc; | 2438 | u32 ncrc; |
2376 | u8 *bssid; | 2439 | u8 *bssid; |
@@ -2382,8 +2445,19 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2382 | if (baselen > len) | 2445 | if (baselen > len) |
2383 | return; | 2446 | return; |
2384 | 2447 | ||
2385 | if (rx_status->freq != local->oper_channel->center_freq) | 2448 | rcu_read_lock(); |
2449 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
2450 | if (!chanctx_conf) { | ||
2451 | rcu_read_unlock(); | ||
2452 | return; | ||
2453 | } | ||
2454 | |||
2455 | if (rx_status->freq != chanctx_conf->channel->center_freq) { | ||
2456 | rcu_read_unlock(); | ||
2386 | return; | 2457 | return; |
2458 | } | ||
2459 | chan = chanctx_conf->channel; | ||
2460 | rcu_read_unlock(); | ||
2387 | 2461 | ||
2388 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && | 2462 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && |
2389 | ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { | 2463 | ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { |
@@ -2490,11 +2564,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2490 | len - baselen, &elems, | 2564 | len - baselen, &elems, |
2491 | care_about_ies, ncrc); | 2565 | care_about_ies, ncrc); |
2492 | 2566 | ||
2493 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) | ||
2494 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, | ||
2495 | ifmgd->aid); | ||
2496 | |||
2497 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { | 2567 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { |
2568 | bool directed_tim = ieee80211_check_tim(elems.tim, | ||
2569 | elems.tim_len, | ||
2570 | ifmgd->aid); | ||
2498 | if (directed_tim) { | 2571 | if (directed_tim) { |
2499 | if (local->hw.conf.dynamic_ps_timeout > 0) { | 2572 | if (local->hw.conf.dynamic_ps_timeout > 0) { |
2500 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 2573 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
@@ -2543,19 +2616,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2543 | 2616 | ||
2544 | 2617 | ||
2545 | if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && | 2618 | if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && |
2546 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) { | 2619 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2547 | struct ieee80211_supported_band *sband; | ||
2548 | |||
2549 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
2550 | |||
2551 | changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, | 2620 | changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, |
2552 | bssid, true); | 2621 | bssid, true); |
2553 | } | ||
2554 | 2622 | ||
2555 | if (elems.country_elem && elems.pwr_constr_elem && | 2623 | if (elems.country_elem && elems.pwr_constr_elem && |
2556 | mgmt->u.probe_resp.capab_info & | 2624 | mgmt->u.probe_resp.capab_info & |
2557 | cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) | 2625 | cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) |
2558 | ieee80211_handle_pwr_constr(sdata, local->oper_channel, | 2626 | ieee80211_handle_pwr_constr(sdata, chan, |
2559 | elems.country_elem, | 2627 | elems.country_elem, |
2560 | elems.country_elem_len, | 2628 | elems.country_elem_len, |
2561 | elems.pwr_constr_elem); | 2629 | elems.pwr_constr_elem); |
@@ -2703,13 +2771,23 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2703 | drv_mgd_prepare_tx(local, sdata); | 2771 | drv_mgd_prepare_tx(local, sdata); |
2704 | 2772 | ||
2705 | if (auth_data->bss->proberesp_ies) { | 2773 | if (auth_data->bss->proberesp_ies) { |
2774 | u16 trans = 1; | ||
2775 | u16 status = 0; | ||
2776 | |||
2706 | sdata_info(sdata, "send auth to %pM (try %d/%d)\n", | 2777 | sdata_info(sdata, "send auth to %pM (try %d/%d)\n", |
2707 | auth_data->bss->bssid, auth_data->tries, | 2778 | auth_data->bss->bssid, auth_data->tries, |
2708 | IEEE80211_AUTH_MAX_TRIES); | 2779 | IEEE80211_AUTH_MAX_TRIES); |
2709 | 2780 | ||
2710 | auth_data->expected_transaction = 2; | 2781 | auth_data->expected_transaction = 2; |
2711 | ieee80211_send_auth(sdata, 1, auth_data->algorithm, | 2782 | |
2712 | auth_data->ie, auth_data->ie_len, | 2783 | if (auth_data->algorithm == WLAN_AUTH_SAE) { |
2784 | trans = auth_data->sae_trans; | ||
2785 | status = auth_data->sae_status; | ||
2786 | auth_data->expected_transaction = trans; | ||
2787 | } | ||
2788 | |||
2789 | ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, | ||
2790 | auth_data->data, auth_data->data_len, | ||
2713 | auth_data->bss->bssid, | 2791 | auth_data->bss->bssid, |
2714 | auth_data->bss->bssid, NULL, 0, 0); | 2792 | auth_data->bss->bssid, NULL, 0, 0); |
2715 | } else { | 2793 | } else { |
@@ -2728,7 +2806,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2728 | */ | 2806 | */ |
2729 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], | 2807 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], |
2730 | NULL, 0, (u32) -1, true, false, | 2808 | NULL, 0, (u32) -1, true, false, |
2731 | auth_data->bss->channel); | 2809 | auth_data->bss->channel, false); |
2732 | } | 2810 | } |
2733 | 2811 | ||
2734 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 2812 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
@@ -3111,6 +3189,11 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3111 | * HT type, so do that here as well. If HT40 isn't allowed | 3189 | * HT type, so do that here as well. If HT40 isn't allowed |
3112 | * on this channel, disable 40 MHz operation. | 3190 | * on this channel, disable 40 MHz operation. |
3113 | */ | 3191 | */ |
3192 | const u8 *ht_cap_ie; | ||
3193 | const struct ieee80211_ht_cap *ht_cap; | ||
3194 | u8 chains = 1; | ||
3195 | |||
3196 | channel_type = NL80211_CHAN_HT20; | ||
3114 | 3197 | ||
3115 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 3198 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
3116 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 3199 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
@@ -3126,22 +3209,25 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3126 | channel_type = NL80211_CHAN_HT40MINUS; | 3209 | channel_type = NL80211_CHAN_HT40MINUS; |
3127 | break; | 3210 | break; |
3128 | } | 3211 | } |
3129 | } | ||
3130 | 3212 | ||
3131 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 3213 | ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, |
3132 | /* can only fail due to HT40+/- mismatch */ | 3214 | cbss->information_elements, |
3133 | channel_type = NL80211_CHAN_HT20; | 3215 | cbss->len_information_elements); |
3134 | sdata_info(sdata, | 3216 | if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) { |
3135 | "disabling 40 MHz due to multi-vif mismatch\n"); | 3217 | ht_cap = (void *)(ht_cap_ie + 2); |
3136 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; | 3218 | chains = ieee80211_mcs_to_chains(&ht_cap->mcs); |
3137 | WARN_ON(!ieee80211_set_channel_type(local, sdata, | 3219 | } |
3138 | channel_type)); | 3220 | sdata->needed_rx_chains = min(chains, local->rx_chains); |
3221 | } else { | ||
3222 | sdata->needed_rx_chains = 1; | ||
3139 | } | 3223 | } |
3140 | 3224 | ||
3141 | local->oper_channel = cbss->channel; | 3225 | /* will change later if needed */ |
3142 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 3226 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
3143 | 3227 | ||
3144 | return 0; | 3228 | ieee80211_vif_release_channel(sdata); |
3229 | return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type, | ||
3230 | IEEE80211_CHANCTX_SHARED); | ||
3145 | } | 3231 | } |
3146 | 3232 | ||
3147 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | 3233 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, |
@@ -3211,7 +3297,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3211 | sdata->vif.bss_conf.basic_rates = basic_rates; | 3297 | sdata->vif.bss_conf.basic_rates = basic_rates; |
3212 | 3298 | ||
3213 | /* cf. IEEE 802.11 9.2.12 */ | 3299 | /* cf. IEEE 802.11 9.2.12 */ |
3214 | if (local->oper_channel->band == IEEE80211_BAND_2GHZ && | 3300 | if (cbss->channel->band == IEEE80211_BAND_2GHZ && |
3215 | have_higher_than_11mbit) | 3301 | have_higher_than_11mbit) |
3216 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | 3302 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; |
3217 | else | 3303 | else |
@@ -3273,19 +3359,33 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3273 | case NL80211_AUTHTYPE_NETWORK_EAP: | 3359 | case NL80211_AUTHTYPE_NETWORK_EAP: |
3274 | auth_alg = WLAN_AUTH_LEAP; | 3360 | auth_alg = WLAN_AUTH_LEAP; |
3275 | break; | 3361 | break; |
3362 | case NL80211_AUTHTYPE_SAE: | ||
3363 | auth_alg = WLAN_AUTH_SAE; | ||
3364 | break; | ||
3276 | default: | 3365 | default: |
3277 | return -EOPNOTSUPP; | 3366 | return -EOPNOTSUPP; |
3278 | } | 3367 | } |
3279 | 3368 | ||
3280 | auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL); | 3369 | auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len + |
3370 | req->ie_len, GFP_KERNEL); | ||
3281 | if (!auth_data) | 3371 | if (!auth_data) |
3282 | return -ENOMEM; | 3372 | return -ENOMEM; |
3283 | 3373 | ||
3284 | auth_data->bss = req->bss; | 3374 | auth_data->bss = req->bss; |
3285 | 3375 | ||
3376 | if (req->sae_data_len >= 4) { | ||
3377 | __le16 *pos = (__le16 *) req->sae_data; | ||
3378 | auth_data->sae_trans = le16_to_cpu(pos[0]); | ||
3379 | auth_data->sae_status = le16_to_cpu(pos[1]); | ||
3380 | memcpy(auth_data->data, req->sae_data + 4, | ||
3381 | req->sae_data_len - 4); | ||
3382 | auth_data->data_len += req->sae_data_len - 4; | ||
3383 | } | ||
3384 | |||
3286 | if (req->ie && req->ie_len) { | 3385 | if (req->ie && req->ie_len) { |
3287 | memcpy(auth_data->ie, req->ie, req->ie_len); | 3386 | memcpy(&auth_data->data[auth_data->data_len], |
3288 | auth_data->ie_len = req->ie_len; | 3387 | req->ie, req->ie_len); |
3388 | auth_data->data_len += req->ie_len; | ||
3289 | } | 3389 | } |
3290 | 3390 | ||
3291 | if (req->key && req->key_len) { | 3391 | if (req->key && req->key_len) { |
@@ -3452,11 +3552,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3452 | 3552 | ||
3453 | if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { | 3553 | if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { |
3454 | if (ifmgd->powersave) | 3554 | if (ifmgd->powersave) |
3455 | ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC; | 3555 | sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; |
3456 | else | 3556 | else |
3457 | ifmgd->ap_smps = IEEE80211_SMPS_OFF; | 3557 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
3458 | } else | 3558 | } else |
3459 | ifmgd->ap_smps = ifmgd->req_smps; | 3559 | sdata->smps_mode = ifmgd->req_smps; |
3460 | 3560 | ||
3461 | assoc_data->capability = req->bss->capability; | 3561 | assoc_data->capability = req->bss->capability; |
3462 | assoc_data->wmm = bss->wmm_used && | 3562 | assoc_data->wmm = bss->wmm_used && |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 83608ac16780..c349f3aaf59e 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -107,6 +107,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
107 | { | 107 | { |
108 | struct ieee80211_sub_if_data *sdata; | 108 | struct ieee80211_sub_if_data *sdata; |
109 | 109 | ||
110 | if (WARN_ON(local->use_chanctx)) | ||
111 | return; | ||
112 | |||
110 | /* | 113 | /* |
111 | * notify the AP about us leaving the channel and stop all | 114 | * notify the AP about us leaving the channel and stop all |
112 | * STA interfaces. | 115 | * STA interfaces. |
@@ -145,6 +148,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
145 | { | 148 | { |
146 | struct ieee80211_sub_if_data *sdata; | 149 | struct ieee80211_sub_if_data *sdata; |
147 | 150 | ||
151 | if (WARN_ON(local->use_chanctx)) | ||
152 | return; | ||
153 | |||
148 | mutex_lock(&local->iflist_mtx); | 154 | mutex_lock(&local->iflist_mtx); |
149 | list_for_each_entry(sdata, &local->interfaces, list) { | 155 | list_for_each_entry(sdata, &local->interfaces, list) { |
150 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | 156 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) |
@@ -193,7 +199,8 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) | |||
193 | 199 | ||
194 | if (roc->mgmt_tx_cookie) { | 200 | if (roc->mgmt_tx_cookie) { |
195 | if (!WARN_ON(!roc->frame)) { | 201 | if (!WARN_ON(!roc->frame)) { |
196 | ieee80211_tx_skb(roc->sdata, roc->frame); | 202 | ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7, |
203 | roc->chan->band); | ||
197 | roc->frame = NULL; | 204 | roc->frame = NULL; |
198 | } | 205 | } |
199 | } else { | 206 | } else { |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 5c572e7a1a71..9f404ac901ab 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -135,6 +135,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
135 | ieee80211_bss_info_change_notify(sdata, | 135 | ieee80211_bss_info_change_notify(sdata, |
136 | BSS_CHANGED_BEACON_ENABLED); | 136 | BSS_CHANGED_BEACON_ENABLED); |
137 | 137 | ||
138 | /* the interface is leaving the channel and is removed */ | ||
139 | ieee80211_vif_release_channel(sdata); | ||
138 | drv_remove_interface(local, sdata); | 140 | drv_remove_interface(local, sdata); |
139 | } | 141 | } |
140 | 142 | ||
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 10de668eb9f6..ec198ef6aa8a 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -52,11 +52,21 @@ static inline void rate_control_rate_init(struct sta_info *sta) | |||
52 | struct ieee80211_sta *ista = &sta->sta; | 52 | struct ieee80211_sta *ista = &sta->sta; |
53 | void *priv_sta = sta->rate_ctrl_priv; | 53 | void *priv_sta = sta->rate_ctrl_priv; |
54 | struct ieee80211_supported_band *sband; | 54 | struct ieee80211_supported_band *sband; |
55 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
55 | 56 | ||
56 | if (!ref) | 57 | if (!ref) |
57 | return; | 58 | return; |
58 | 59 | ||
59 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 60 | rcu_read_lock(); |
61 | |||
62 | chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf); | ||
63 | if (WARN_ON(!chanctx_conf)) { | ||
64 | rcu_read_unlock(); | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | sband = local->hw.wiphy->bands[chanctx_conf->channel->band]; | ||
69 | rcu_read_unlock(); | ||
60 | 70 | ||
61 | ref->ops->rate_init(ref->priv, sband, ista, priv_sta); | 71 | ref->ops->rate_init(ref->priv, sband, ista, priv_sta); |
62 | set_sta_flag(sta, WLAN_STA_RATE_CONTROL); | 72 | set_sta_flag(sta, WLAN_STA_RATE_CONTROL); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 00ade7feb2e3..8c1f1527d671 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1148,12 +1148,19 @@ ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) | |||
1148 | return RX_CONTINUE; | 1148 | return RX_CONTINUE; |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | static void ap_sta_ps_start(struct sta_info *sta) | 1151 | static void sta_ps_start(struct sta_info *sta) |
1152 | { | 1152 | { |
1153 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1153 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
1154 | struct ieee80211_local *local = sdata->local; | 1154 | struct ieee80211_local *local = sdata->local; |
1155 | struct ps_data *ps; | ||
1155 | 1156 | ||
1156 | atomic_inc(&sdata->bss->num_sta_ps); | 1157 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
1158 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1159 | ps = &sdata->bss->ps; | ||
1160 | else | ||
1161 | return; | ||
1162 | |||
1163 | atomic_inc(&ps->num_sta_ps); | ||
1157 | set_sta_flag(sta, WLAN_STA_PS_STA); | 1164 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1158 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1165 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1159 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1166 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
@@ -1161,7 +1168,7 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1161 | sta->sta.addr, sta->sta.aid); | 1168 | sta->sta.addr, sta->sta.aid); |
1162 | } | 1169 | } |
1163 | 1170 | ||
1164 | static void ap_sta_ps_end(struct sta_info *sta) | 1171 | static void sta_ps_end(struct sta_info *sta) |
1165 | { | 1172 | { |
1166 | ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", | 1173 | ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", |
1167 | sta->sta.addr, sta->sta.aid); | 1174 | sta->sta.addr, sta->sta.aid); |
@@ -1188,9 +1195,9 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start) | |||
1188 | return -EINVAL; | 1195 | return -EINVAL; |
1189 | 1196 | ||
1190 | if (start) | 1197 | if (start) |
1191 | ap_sta_ps_start(sta_inf); | 1198 | sta_ps_start(sta_inf); |
1192 | else | 1199 | else |
1193 | ap_sta_ps_end(sta_inf); | 1200 | sta_ps_end(sta_inf); |
1194 | 1201 | ||
1195 | return 0; | 1202 | return 0; |
1196 | } | 1203 | } |
@@ -1342,10 +1349,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1342 | */ | 1349 | */ |
1343 | if (ieee80211_is_data(hdr->frame_control) && | 1350 | if (ieee80211_is_data(hdr->frame_control) && |
1344 | !ieee80211_has_pm(hdr->frame_control)) | 1351 | !ieee80211_has_pm(hdr->frame_control)) |
1345 | ap_sta_ps_end(sta); | 1352 | sta_ps_end(sta); |
1346 | } else { | 1353 | } else { |
1347 | if (ieee80211_has_pm(hdr->frame_control)) | 1354 | if (ieee80211_has_pm(hdr->frame_control)) |
1348 | ap_sta_ps_start(sta); | 1355 | sta_ps_start(sta); |
1349 | } | 1356 | } |
1350 | } | 1357 | } |
1351 | 1358 | ||
@@ -1391,9 +1398,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
1391 | struct sk_buff **skb) | 1398 | struct sk_buff **skb) |
1392 | { | 1399 | { |
1393 | struct ieee80211_fragment_entry *entry; | 1400 | struct ieee80211_fragment_entry *entry; |
1394 | int idx; | ||
1395 | 1401 | ||
1396 | idx = sdata->fragment_next; | ||
1397 | entry = &sdata->fragments[sdata->fragment_next++]; | 1402 | entry = &sdata->fragments[sdata->fragment_next++]; |
1398 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) | 1403 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |
1399 | sdata->fragment_next = 0; | 1404 | sdata->fragment_next = 0; |
@@ -3048,8 +3053,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3048 | 3053 | ||
3049 | WARN_ON_ONCE(softirq_count() == 0); | 3054 | WARN_ON_ONCE(softirq_count() == 0); |
3050 | 3055 | ||
3051 | if (WARN_ON(status->band < 0 || | 3056 | if (WARN_ON(status->band >= IEEE80211_NUM_BANDS)) |
3052 | status->band >= IEEE80211_NUM_BANDS)) | ||
3053 | goto drop; | 3057 | goto drop; |
3054 | 3058 | ||
3055 | sband = local->hw.wiphy->bands[status->band]; | 3059 | sband = local->hw.wiphy->bands[status->band]; |
@@ -3094,8 +3098,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3094 | * hardware error. The driver should catch hardware | 3098 | * hardware error. The driver should catch hardware |
3095 | * errors. | 3099 | * errors. |
3096 | */ | 3100 | */ |
3097 | if (WARN((status->rate_idx < 0 || | 3101 | if (WARN(status->rate_idx > 76, |
3098 | status->rate_idx > 76), | ||
3099 | "Rate marked as an HT rate but passed " | 3102 | "Rate marked as an HT rate but passed " |
3100 | "status->rate_idx is not " | 3103 | "status->rate_idx is not " |
3101 | "an MCS index [0-76]: %d (0x%02x)\n", | 3104 | "an MCS index [0-76]: %d (0x%02x)\n", |
@@ -3103,8 +3106,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3103 | status->rate_idx)) | 3106 | status->rate_idx)) |
3104 | goto drop; | 3107 | goto drop; |
3105 | } else { | 3108 | } else { |
3106 | if (WARN_ON(status->rate_idx < 0 || | 3109 | if (WARN_ON(status->rate_idx >= sband->n_bitrates)) |
3107 | status->rate_idx >= sband->n_bitrates)) | ||
3108 | goto drop; | 3110 | goto drop; |
3109 | rate = &sband->bitrates[status->rate_idx]; | 3111 | rate = &sband->bitrates[status->rate_idx]; |
3110 | } | 3112 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde24fd3..13d23299e696 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -336,6 +336,10 @@ EXPORT_SYMBOL(ieee80211_scan_completed); | |||
336 | 336 | ||
337 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) | 337 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) |
338 | { | 338 | { |
339 | /* Software scan is not supported in multi-channel cases */ | ||
340 | if (local->use_chanctx) | ||
341 | return -EOPNOTSUPP; | ||
342 | |||
339 | /* | 343 | /* |
340 | * Hardware/driver doesn't support hw_scan, so use software | 344 | * Hardware/driver doesn't support hw_scan, so use software |
341 | * scanning instead. First send a nullfunc frame with power save | 345 | * scanning instead. First send a nullfunc frame with power save |
@@ -417,7 +421,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
417 | local->scan_req->ie, local->scan_req->ie_len, | 421 | local->scan_req->ie, local->scan_req->ie_len, |
418 | local->scan_req->rates[band], false, | 422 | local->scan_req->rates[band], false, |
419 | local->scan_req->no_cck, | 423 | local->scan_req->no_cck, |
420 | local->hw.conf.channel); | 424 | local->hw.conf.channel, true); |
421 | 425 | ||
422 | /* | 426 | /* |
423 | * After sending probe requests, wait for probe responses | 427 | * After sending probe requests, wait for probe responses |
@@ -462,6 +466,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
462 | sizeof(*local->hw_scan_req) + | 466 | sizeof(*local->hw_scan_req) + |
463 | req->n_channels * sizeof(req->channels[0]); | 467 | req->n_channels * sizeof(req->channels[0]); |
464 | local->hw_scan_req->ie = ies; | 468 | local->hw_scan_req->ie = ies; |
469 | local->hw_scan_req->flags = req->flags; | ||
465 | 470 | ||
466 | local->hw_scan_band = 0; | 471 | local->hw_scan_band = 0; |
467 | 472 | ||
@@ -480,7 +485,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
480 | if (local->ops->hw_scan) { | 485 | if (local->ops->hw_scan) { |
481 | __set_bit(SCAN_HW_SCANNING, &local->scanning); | 486 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
482 | } else if ((req->n_channels == 1) && | 487 | } else if ((req->n_channels == 1) && |
483 | (req->channels[0] == local->oper_channel)) { | 488 | (req->channels[0] == local->_oper_channel)) { |
484 | /* | 489 | /* |
485 | * If we are scanning only on the operating channel | 490 | * If we are scanning only on the operating channel |
486 | * then we do not need to stop normal activities | 491 | * then we do not need to stop normal activities |
@@ -562,6 +567,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
562 | unsigned long min_beacon_int = 0; | 567 | unsigned long min_beacon_int = 0; |
563 | struct ieee80211_sub_if_data *sdata; | 568 | struct ieee80211_sub_if_data *sdata; |
564 | struct ieee80211_channel *next_chan; | 569 | struct ieee80211_channel *next_chan; |
570 | enum mac80211_scan_state next_scan_state; | ||
565 | 571 | ||
566 | /* | 572 | /* |
567 | * check if at least one STA interface is associated, | 573 | * check if at least one STA interface is associated, |
@@ -620,10 +626,18 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
620 | usecs_to_jiffies(min_beacon_int * 1024) * | 626 | usecs_to_jiffies(min_beacon_int * 1024) * |
621 | local->hw.conf.listen_interval); | 627 | local->hw.conf.listen_interval); |
622 | 628 | ||
623 | if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) | 629 | if (associated && !tx_empty) { |
624 | local->next_scan_state = SCAN_SUSPEND; | 630 | if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) |
625 | else | 631 | next_scan_state = SCAN_ABORT; |
626 | local->next_scan_state = SCAN_SET_CHANNEL; | 632 | else |
633 | next_scan_state = SCAN_SUSPEND; | ||
634 | } else if (associated && (bad_latency || listen_int_exceeded)) { | ||
635 | next_scan_state = SCAN_SUSPEND; | ||
636 | } else { | ||
637 | next_scan_state = SCAN_SET_CHANNEL; | ||
638 | } | ||
639 | |||
640 | local->next_scan_state = next_scan_state; | ||
627 | 641 | ||
628 | *next_delay = 0; | 642 | *next_delay = 0; |
629 | } | 643 | } |
@@ -794,6 +808,9 @@ void ieee80211_scan_work(struct work_struct *work) | |||
794 | case SCAN_RESUME: | 808 | case SCAN_RESUME: |
795 | ieee80211_scan_state_resume(local, &next_delay); | 809 | ieee80211_scan_state_resume(local, &next_delay); |
796 | break; | 810 | break; |
811 | case SCAN_ABORT: | ||
812 | aborted = true; | ||
813 | goto out_complete; | ||
797 | } | 814 | } |
798 | } while (next_delay == 0); | 815 | } while (next_delay == 0); |
799 | 816 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0a4e4c04db89..f7bb54f9ab72 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -98,6 +98,7 @@ static void free_sta_work(struct work_struct *wk) | |||
98 | struct tid_ampdu_tx *tid_tx; | 98 | struct tid_ampdu_tx *tid_tx; |
99 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 99 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
100 | struct ieee80211_local *local = sdata->local; | 100 | struct ieee80211_local *local = sdata->local; |
101 | struct ps_data *ps; | ||
101 | 102 | ||
102 | /* | 103 | /* |
103 | * At this point, when being called as call_rcu callback, | 104 | * At this point, when being called as call_rcu callback, |
@@ -107,11 +108,15 @@ static void free_sta_work(struct work_struct *wk) | |||
107 | */ | 108 | */ |
108 | 109 | ||
109 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { | 110 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { |
110 | BUG_ON(!sdata->bss); | 111 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
112 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
113 | ps = &sdata->bss->ps; | ||
114 | else | ||
115 | return; | ||
111 | 116 | ||
112 | clear_sta_flag(sta, WLAN_STA_PS_STA); | 117 | clear_sta_flag(sta, WLAN_STA_PS_STA); |
113 | 118 | ||
114 | atomic_dec(&sdata->bss->num_sta_ps); | 119 | atomic_dec(&ps->num_sta_ps); |
115 | sta_info_recalc_tim(sta); | 120 | sta_info_recalc_tim(sta); |
116 | } | 121 | } |
117 | 122 | ||
@@ -502,22 +507,22 @@ int sta_info_insert(struct sta_info *sta) | |||
502 | return err; | 507 | return err; |
503 | } | 508 | } |
504 | 509 | ||
505 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | 510 | static inline void __bss_tim_set(u8 *tim, u16 id) |
506 | { | 511 | { |
507 | /* | 512 | /* |
508 | * This format has been mandated by the IEEE specifications, | 513 | * This format has been mandated by the IEEE specifications, |
509 | * so this line may not be changed to use the __set_bit() format. | 514 | * so this line may not be changed to use the __set_bit() format. |
510 | */ | 515 | */ |
511 | bss->tim[aid / 8] |= (1 << (aid % 8)); | 516 | tim[id / 8] |= (1 << (id % 8)); |
512 | } | 517 | } |
513 | 518 | ||
514 | static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | 519 | static inline void __bss_tim_clear(u8 *tim, u16 id) |
515 | { | 520 | { |
516 | /* | 521 | /* |
517 | * This format has been mandated by the IEEE specifications, | 522 | * This format has been mandated by the IEEE specifications, |
518 | * so this line may not be changed to use the __clear_bit() format. | 523 | * so this line may not be changed to use the __clear_bit() format. |
519 | */ | 524 | */ |
520 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | 525 | tim[id / 8] &= ~(1 << (id % 8)); |
521 | } | 526 | } |
522 | 527 | ||
523 | static unsigned long ieee80211_tids_for_ac(int ac) | 528 | static unsigned long ieee80211_tids_for_ac(int ac) |
@@ -541,14 +546,23 @@ static unsigned long ieee80211_tids_for_ac(int ac) | |||
541 | void sta_info_recalc_tim(struct sta_info *sta) | 546 | void sta_info_recalc_tim(struct sta_info *sta) |
542 | { | 547 | { |
543 | struct ieee80211_local *local = sta->local; | 548 | struct ieee80211_local *local = sta->local; |
544 | struct ieee80211_if_ap *bss = sta->sdata->bss; | 549 | struct ps_data *ps; |
545 | unsigned long flags; | 550 | unsigned long flags; |
546 | bool indicate_tim = false; | 551 | bool indicate_tim = false; |
547 | u8 ignore_for_tim = sta->sta.uapsd_queues; | 552 | u8 ignore_for_tim = sta->sta.uapsd_queues; |
548 | int ac; | 553 | int ac; |
554 | u16 id; | ||
555 | |||
556 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | ||
557 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
558 | if (WARN_ON_ONCE(!sta->sdata->bss)) | ||
559 | return; | ||
549 | 560 | ||
550 | if (WARN_ON_ONCE(!sta->sdata->bss)) | 561 | ps = &sta->sdata->bss->ps; |
562 | id = sta->sta.aid; | ||
563 | } else { | ||
551 | return; | 564 | return; |
565 | } | ||
552 | 566 | ||
553 | /* No need to do anything if the driver does all */ | 567 | /* No need to do anything if the driver does all */ |
554 | if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) | 568 | if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) |
@@ -587,9 +601,9 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
587 | spin_lock_irqsave(&local->tim_lock, flags); | 601 | spin_lock_irqsave(&local->tim_lock, flags); |
588 | 602 | ||
589 | if (indicate_tim) | 603 | if (indicate_tim) |
590 | __bss_tim_set(bss, sta->sta.aid); | 604 | __bss_tim_set(ps->tim, id); |
591 | else | 605 | else |
592 | __bss_tim_clear(bss, sta->sta.aid); | 606 | __bss_tim_clear(ps->tim, id); |
593 | 607 | ||
594 | if (local->ops->set_tim) { | 608 | if (local->ops->set_tim) { |
595 | local->tim_in_locked_section = true; | 609 | local->tim_in_locked_section = true; |
@@ -893,8 +907,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
893 | continue; | 907 | continue; |
894 | 908 | ||
895 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 909 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
896 | ibss_dbg(sdata, "expiring inactive STA %pM\n", | 910 | sta_dbg(sta->sdata, "expiring inactive STA %pM\n", |
897 | sta->sta.addr); | 911 | sta->sta.addr); |
898 | WARN_ON(__sta_info_destroy(sta)); | 912 | WARN_ON(__sta_info_destroy(sta)); |
899 | } | 913 | } |
900 | } | 914 | } |
@@ -948,10 +962,17 @@ static void clear_sta_ps_flags(void *_sta) | |||
948 | { | 962 | { |
949 | struct sta_info *sta = _sta; | 963 | struct sta_info *sta = _sta; |
950 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 964 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
965 | struct ps_data *ps; | ||
966 | |||
967 | if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
968 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
969 | ps = &sdata->bss->ps; | ||
970 | else | ||
971 | return; | ||
951 | 972 | ||
952 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | 973 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
953 | if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) | 974 | if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) |
954 | atomic_dec(&sdata->bss->num_sta_ps); | 975 | atomic_dec(&ps->num_sta_ps); |
955 | } | 976 | } |
956 | 977 | ||
957 | /* powersave support code */ | 978 | /* powersave support code */ |
@@ -1008,6 +1029,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1008 | __le16 fc; | 1029 | __le16 fc; |
1009 | bool qos = test_sta_flag(sta, WLAN_STA_WME); | 1030 | bool qos = test_sta_flag(sta, WLAN_STA_WME); |
1010 | struct ieee80211_tx_info *info; | 1031 | struct ieee80211_tx_info *info; |
1032 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
1011 | 1033 | ||
1012 | if (qos) { | 1034 | if (qos) { |
1013 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | 1035 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | |
@@ -1057,7 +1079,16 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1057 | 1079 | ||
1058 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); | 1080 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); |
1059 | 1081 | ||
1060 | ieee80211_xmit(sdata, skb); | 1082 | rcu_read_lock(); |
1083 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1084 | if (WARN_ON(!chanctx_conf)) { | ||
1085 | rcu_read_unlock(); | ||
1086 | kfree_skb(skb); | ||
1087 | return; | ||
1088 | } | ||
1089 | |||
1090 | ieee80211_xmit(sdata, skb, chanctx_conf->channel->band); | ||
1091 | rcu_read_unlock(); | ||
1061 | } | 1092 | } |
1062 | 1093 | ||
1063 | static void | 1094 | static void |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3af0cc4130f1..21fa5c72ea14 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -189,30 +189,31 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | if (ieee80211_is_action(mgmt->frame_control) && | 191 | if (ieee80211_is_action(mgmt->frame_control) && |
192 | sdata->vif.type == NL80211_IFTYPE_STATION && | ||
193 | mgmt->u.action.category == WLAN_CATEGORY_HT && | 192 | mgmt->u.action.category == WLAN_CATEGORY_HT && |
194 | mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) { | 193 | mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS && |
194 | sdata->vif.type == NL80211_IFTYPE_STATION && | ||
195 | ieee80211_sdata_running(sdata)) { | ||
195 | /* | 196 | /* |
196 | * This update looks racy, but isn't -- if we come | 197 | * This update looks racy, but isn't -- if we come |
197 | * here we've definitely got a station that we're | 198 | * here we've definitely got a station that we're |
198 | * talking to, and on a managed interface that can | 199 | * talking to, and on a managed interface that can |
199 | * only be the AP. And the only other place updating | 200 | * only be the AP. And the only other place updating |
200 | * this variable is before we're associated. | 201 | * this variable in managed mode is before association. |
201 | */ | 202 | */ |
202 | switch (mgmt->u.action.u.ht_smps.smps_control) { | 203 | switch (mgmt->u.action.u.ht_smps.smps_control) { |
203 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: | 204 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: |
204 | sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC; | 205 | sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; |
205 | break; | 206 | break; |
206 | case WLAN_HT_SMPS_CONTROL_STATIC: | 207 | case WLAN_HT_SMPS_CONTROL_STATIC: |
207 | sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC; | 208 | sdata->smps_mode = IEEE80211_SMPS_STATIC; |
208 | break; | 209 | break; |
209 | case WLAN_HT_SMPS_CONTROL_DISABLED: | 210 | case WLAN_HT_SMPS_CONTROL_DISABLED: |
210 | default: /* shouldn't happen since we don't send that */ | 211 | default: /* shouldn't happen since we don't send that */ |
211 | sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF; | 212 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
212 | break; | 213 | break; |
213 | } | 214 | } |
214 | 215 | ||
215 | ieee80211_queue_work(&local->hw, &local->recalc_smps); | 216 | ieee80211_queue_work(&local->hw, &sdata->recalc_smps); |
216 | } | 217 | } |
217 | } | 218 | } |
218 | 219 | ||
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 18d9c8a52e9e..0638541b625f 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -28,6 +28,20 @@ | |||
28 | #define VIF_PR_FMT " vif:%s(%d%s)" | 28 | #define VIF_PR_FMT " vif:%s(%d%s)" |
29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" | 29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" |
30 | 30 | ||
31 | #define CHANCTX_ENTRY __field(int, freq) \ | ||
32 | __field(int, chantype) \ | ||
33 | __field(u8, rx_chains_static) \ | ||
34 | __field(u8, rx_chains_dynamic) | ||
35 | #define CHANCTX_ASSIGN __entry->freq = ctx->conf.channel->center_freq; \ | ||
36 | __entry->chantype = ctx->conf.channel_type; \ | ||
37 | __entry->rx_chains_static = ctx->conf.rx_chains_static; \ | ||
38 | __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic | ||
39 | #define CHANCTX_PR_FMT " freq:%d MHz chantype:%d chains:%d/%d" | ||
40 | #define CHANCTX_PR_ARG __entry->freq, __entry->chantype, \ | ||
41 | __entry->rx_chains_static, __entry->rx_chains_dynamic | ||
42 | |||
43 | |||
44 | |||
31 | /* | 45 | /* |
32 | * Tracing for driver callbacks. | 46 | * Tracing for driver callbacks. |
33 | */ | 47 | */ |
@@ -301,20 +315,33 @@ TRACE_EVENT(drv_bss_info_changed, | |||
301 | TP_STRUCT__entry( | 315 | TP_STRUCT__entry( |
302 | LOCAL_ENTRY | 316 | LOCAL_ENTRY |
303 | VIF_ENTRY | 317 | VIF_ENTRY |
318 | __field(u32, changed) | ||
304 | __field(bool, assoc) | 319 | __field(bool, assoc) |
320 | __field(bool, ibss_joined) | ||
321 | __field(bool, ibss_creator) | ||
305 | __field(u16, aid) | 322 | __field(u16, aid) |
306 | __field(bool, cts) | 323 | __field(bool, cts) |
307 | __field(bool, shortpre) | 324 | __field(bool, shortpre) |
308 | __field(bool, shortslot) | 325 | __field(bool, shortslot) |
326 | __field(bool, enable_beacon) | ||
309 | __field(u8, dtimper) | 327 | __field(u8, dtimper) |
310 | __field(u16, bcnint) | 328 | __field(u16, bcnint) |
311 | __field(u16, assoc_cap) | 329 | __field(u16, assoc_cap) |
312 | __field(u64, sync_tsf) | 330 | __field(u64, sync_tsf) |
313 | __field(u32, sync_device_ts) | 331 | __field(u32, sync_device_ts) |
314 | __field(u32, basic_rates) | 332 | __field(u32, basic_rates) |
315 | __field(u32, changed) | 333 | __array(int, mcast_rate, IEEE80211_NUM_BANDS) |
316 | __field(bool, enable_beacon) | ||
317 | __field(u16, ht_operation_mode) | 334 | __field(u16, ht_operation_mode) |
335 | __field(s32, cqm_rssi_thold); | ||
336 | __field(s32, cqm_rssi_hyst); | ||
337 | __field(u32, channel_type); | ||
338 | __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt); | ||
339 | __field(bool, arp_filter_enabled); | ||
340 | __field(bool, qos); | ||
341 | __field(bool, idle); | ||
342 | __field(bool, ps); | ||
343 | __dynamic_array(u8, ssid, info->ssid_len); | ||
344 | __field(bool, hidden_ssid); | ||
318 | ), | 345 | ), |
319 | 346 | ||
320 | TP_fast_assign( | 347 | TP_fast_assign( |
@@ -323,17 +350,32 @@ TRACE_EVENT(drv_bss_info_changed, | |||
323 | __entry->changed = changed; | 350 | __entry->changed = changed; |
324 | __entry->aid = info->aid; | 351 | __entry->aid = info->aid; |
325 | __entry->assoc = info->assoc; | 352 | __entry->assoc = info->assoc; |
353 | __entry->ibss_joined = info->ibss_joined; | ||
354 | __entry->ibss_creator = info->ibss_creator; | ||
326 | __entry->shortpre = info->use_short_preamble; | 355 | __entry->shortpre = info->use_short_preamble; |
327 | __entry->cts = info->use_cts_prot; | 356 | __entry->cts = info->use_cts_prot; |
328 | __entry->shortslot = info->use_short_slot; | 357 | __entry->shortslot = info->use_short_slot; |
358 | __entry->enable_beacon = info->enable_beacon; | ||
329 | __entry->dtimper = info->dtim_period; | 359 | __entry->dtimper = info->dtim_period; |
330 | __entry->bcnint = info->beacon_int; | 360 | __entry->bcnint = info->beacon_int; |
331 | __entry->assoc_cap = info->assoc_capability; | 361 | __entry->assoc_cap = info->assoc_capability; |
332 | __entry->sync_tsf = info->sync_tsf; | 362 | __entry->sync_tsf = info->sync_tsf; |
333 | __entry->sync_device_ts = info->sync_device_ts; | 363 | __entry->sync_device_ts = info->sync_device_ts; |
334 | __entry->basic_rates = info->basic_rates; | 364 | __entry->basic_rates = info->basic_rates; |
335 | __entry->enable_beacon = info->enable_beacon; | 365 | memcpy(__entry->mcast_rate, info->mcast_rate, |
366 | sizeof(__entry->mcast_rate)); | ||
336 | __entry->ht_operation_mode = info->ht_operation_mode; | 367 | __entry->ht_operation_mode = info->ht_operation_mode; |
368 | __entry->cqm_rssi_thold = info->cqm_rssi_thold; | ||
369 | __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; | ||
370 | __entry->channel_type = info->channel_type; | ||
371 | memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, | ||
372 | sizeof(u32) * info->arp_addr_cnt); | ||
373 | __entry->arp_filter_enabled = info->arp_filter_enabled; | ||
374 | __entry->qos = info->qos; | ||
375 | __entry->idle = info->idle; | ||
376 | __entry->ps = info->ps; | ||
377 | memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); | ||
378 | __entry->hidden_ssid = info->hidden_ssid; | ||
337 | ), | 379 | ), |
338 | 380 | ||
339 | TP_printk( | 381 | TP_printk( |
@@ -1256,6 +1298,104 @@ DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, | |||
1256 | TP_ARGS(local, sdata) | 1298 | TP_ARGS(local, sdata) |
1257 | ); | 1299 | ); |
1258 | 1300 | ||
1301 | DECLARE_EVENT_CLASS(local_chanctx, | ||
1302 | TP_PROTO(struct ieee80211_local *local, | ||
1303 | struct ieee80211_chanctx *ctx), | ||
1304 | |||
1305 | TP_ARGS(local, ctx), | ||
1306 | |||
1307 | TP_STRUCT__entry( | ||
1308 | LOCAL_ENTRY | ||
1309 | CHANCTX_ENTRY | ||
1310 | ), | ||
1311 | |||
1312 | TP_fast_assign( | ||
1313 | LOCAL_ASSIGN; | ||
1314 | CHANCTX_ASSIGN; | ||
1315 | ), | ||
1316 | |||
1317 | TP_printk( | ||
1318 | LOCAL_PR_FMT CHANCTX_PR_FMT, | ||
1319 | LOCAL_PR_ARG, CHANCTX_PR_ARG | ||
1320 | ) | ||
1321 | ); | ||
1322 | |||
1323 | DEFINE_EVENT(local_chanctx, drv_add_chanctx, | ||
1324 | TP_PROTO(struct ieee80211_local *local, | ||
1325 | struct ieee80211_chanctx *ctx), | ||
1326 | TP_ARGS(local, ctx) | ||
1327 | ); | ||
1328 | |||
1329 | DEFINE_EVENT(local_chanctx, drv_remove_chanctx, | ||
1330 | TP_PROTO(struct ieee80211_local *local, | ||
1331 | struct ieee80211_chanctx *ctx), | ||
1332 | TP_ARGS(local, ctx) | ||
1333 | ); | ||
1334 | |||
1335 | TRACE_EVENT(drv_change_chanctx, | ||
1336 | TP_PROTO(struct ieee80211_local *local, | ||
1337 | struct ieee80211_chanctx *ctx, | ||
1338 | u32 changed), | ||
1339 | |||
1340 | TP_ARGS(local, ctx, changed), | ||
1341 | |||
1342 | TP_STRUCT__entry( | ||
1343 | LOCAL_ENTRY | ||
1344 | CHANCTX_ENTRY | ||
1345 | __field(u32, changed) | ||
1346 | ), | ||
1347 | |||
1348 | TP_fast_assign( | ||
1349 | LOCAL_ASSIGN; | ||
1350 | CHANCTX_ASSIGN; | ||
1351 | __entry->changed = changed; | ||
1352 | ), | ||
1353 | |||
1354 | TP_printk( | ||
1355 | LOCAL_PR_FMT CHANCTX_PR_FMT " changed:%#x", | ||
1356 | LOCAL_PR_ARG, CHANCTX_PR_ARG, __entry->changed | ||
1357 | ) | ||
1358 | ); | ||
1359 | |||
1360 | DECLARE_EVENT_CLASS(local_sdata_chanctx, | ||
1361 | TP_PROTO(struct ieee80211_local *local, | ||
1362 | struct ieee80211_sub_if_data *sdata, | ||
1363 | struct ieee80211_chanctx *ctx), | ||
1364 | |||
1365 | TP_ARGS(local, sdata, ctx), | ||
1366 | |||
1367 | TP_STRUCT__entry( | ||
1368 | LOCAL_ENTRY | ||
1369 | VIF_ENTRY | ||
1370 | CHANCTX_ENTRY | ||
1371 | ), | ||
1372 | |||
1373 | TP_fast_assign( | ||
1374 | LOCAL_ASSIGN; | ||
1375 | VIF_ASSIGN; | ||
1376 | CHANCTX_ASSIGN; | ||
1377 | ), | ||
1378 | |||
1379 | TP_printk( | ||
1380 | LOCAL_PR_FMT VIF_PR_FMT CHANCTX_PR_FMT, | ||
1381 | LOCAL_PR_ARG, VIF_PR_ARG, CHANCTX_PR_ARG | ||
1382 | ) | ||
1383 | ); | ||
1384 | |||
1385 | DEFINE_EVENT(local_sdata_chanctx, drv_assign_vif_chanctx, | ||
1386 | TP_PROTO(struct ieee80211_local *local, | ||
1387 | struct ieee80211_sub_if_data *sdata, | ||
1388 | struct ieee80211_chanctx *ctx), | ||
1389 | TP_ARGS(local, sdata, ctx) | ||
1390 | ); | ||
1391 | |||
1392 | DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx, | ||
1393 | TP_PROTO(struct ieee80211_local *local, | ||
1394 | struct ieee80211_sub_if_data *sdata, | ||
1395 | struct ieee80211_chanctx *ctx), | ||
1396 | TP_ARGS(local, sdata, ctx) | ||
1397 | ); | ||
1398 | |||
1259 | /* | 1399 | /* |
1260 | * Tracing for API calls that drivers call. | 1400 | * Tracing for API calls that drivers call. |
1261 | */ | 1401 | */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9bf83f36657..065f81cb5618 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -324,22 +324,20 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
324 | struct ieee80211_sub_if_data *sdata; | 324 | struct ieee80211_sub_if_data *sdata; |
325 | struct sta_info *sta; | 325 | struct sta_info *sta; |
326 | 326 | ||
327 | /* | ||
328 | * virtual interfaces are protected by RCU | ||
329 | */ | ||
330 | rcu_read_lock(); | ||
331 | |||
332 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 327 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
333 | struct ieee80211_if_ap *ap; | 328 | struct ps_data *ps; |
334 | if (sdata->vif.type != NL80211_IFTYPE_AP) | 329 | |
330 | if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
331 | ps = &sdata->u.ap.ps; | ||
332 | else | ||
335 | continue; | 333 | continue; |
336 | ap = &sdata->u.ap; | 334 | |
337 | skb = skb_dequeue(&ap->ps_bc_buf); | 335 | skb = skb_dequeue(&ps->bc_buf); |
338 | if (skb) { | 336 | if (skb) { |
339 | purged++; | 337 | purged++; |
340 | dev_kfree_skb(skb); | 338 | dev_kfree_skb(skb); |
341 | } | 339 | } |
342 | total += skb_queue_len(&ap->ps_bc_buf); | 340 | total += skb_queue_len(&ps->bc_buf); |
343 | } | 341 | } |
344 | 342 | ||
345 | /* | 343 | /* |
@@ -360,8 +358,6 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
360 | } | 358 | } |
361 | } | 359 | } |
362 | 360 | ||
363 | rcu_read_unlock(); | ||
364 | |||
365 | local->total_ps_buffered = total; | 361 | local->total_ps_buffered = total; |
366 | ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); | 362 | ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); |
367 | } | 363 | } |
@@ -371,6 +367,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
371 | { | 367 | { |
372 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 368 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
373 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 369 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
370 | struct ps_data *ps; | ||
374 | 371 | ||
375 | /* | 372 | /* |
376 | * broadcast/multicast frame | 373 | * broadcast/multicast frame |
@@ -380,16 +377,24 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
380 | * This is done either by the hardware or us. | 377 | * This is done either by the hardware or us. |
381 | */ | 378 | */ |
382 | 379 | ||
383 | /* powersaving STAs only in AP/VLAN mode */ | 380 | /* powersaving STAs currently only in AP/VLAN mode */ |
384 | if (!tx->sdata->bss) | 381 | if (tx->sdata->vif.type == NL80211_IFTYPE_AP || |
382 | tx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
383 | if (!tx->sdata->bss) | ||
384 | return TX_CONTINUE; | ||
385 | |||
386 | ps = &tx->sdata->bss->ps; | ||
387 | } else { | ||
385 | return TX_CONTINUE; | 388 | return TX_CONTINUE; |
389 | } | ||
390 | |||
386 | 391 | ||
387 | /* no buffering for ordered frames */ | 392 | /* no buffering for ordered frames */ |
388 | if (ieee80211_has_order(hdr->frame_control)) | 393 | if (ieee80211_has_order(hdr->frame_control)) |
389 | return TX_CONTINUE; | 394 | return TX_CONTINUE; |
390 | 395 | ||
391 | /* no stations in PS mode */ | 396 | /* no stations in PS mode */ |
392 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) | 397 | if (!atomic_read(&ps->num_sta_ps)) |
393 | return TX_CONTINUE; | 398 | return TX_CONTINUE; |
394 | 399 | ||
395 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; | 400 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
@@ -404,14 +409,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
404 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 409 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
405 | purge_old_ps_buffers(tx->local); | 410 | purge_old_ps_buffers(tx->local); |
406 | 411 | ||
407 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { | 412 | if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) { |
408 | ps_dbg(tx->sdata, | 413 | ps_dbg(tx->sdata, |
409 | "BC TX buffer full - dropping the oldest frame\n"); | 414 | "BC TX buffer full - dropping the oldest frame\n"); |
410 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 415 | dev_kfree_skb(skb_dequeue(&ps->bc_buf)); |
411 | } else | 416 | } else |
412 | tx->local->total_ps_buffered++; | 417 | tx->local->total_ps_buffered++; |
413 | 418 | ||
414 | skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); | 419 | skb_queue_tail(&ps->bc_buf, tx->skb); |
415 | 420 | ||
416 | return TX_QUEUED; | 421 | return TX_QUEUED; |
417 | } | 422 | } |
@@ -951,7 +956,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
951 | fragnum = 0; | 956 | fragnum = 0; |
952 | 957 | ||
953 | skb_queue_walk(&tx->skbs, skb) { | 958 | skb_queue_walk(&tx->skbs, skb) { |
954 | int next_len; | ||
955 | const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); | 959 | const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); |
956 | 960 | ||
957 | hdr = (void *)skb->data; | 961 | hdr = (void *)skb->data; |
@@ -970,7 +974,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
970 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 974 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
971 | } else { | 975 | } else { |
972 | hdr->frame_control &= ~morefrags; | 976 | hdr->frame_control &= ~morefrags; |
973 | next_len = 0; | ||
974 | } | 977 | } |
975 | hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG); | 978 | hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG); |
976 | fragnum++; | 979 | fragnum++; |
@@ -1372,7 +1375,8 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1372 | * Returns false if the frame couldn't be transmitted but was queued instead. | 1375 | * Returns false if the frame couldn't be transmitted but was queued instead. |
1373 | */ | 1376 | */ |
1374 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | 1377 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, |
1375 | struct sk_buff *skb, bool txpending) | 1378 | struct sk_buff *skb, bool txpending, |
1379 | enum ieee80211_band band) | ||
1376 | { | 1380 | { |
1377 | struct ieee80211_local *local = sdata->local; | 1381 | struct ieee80211_local *local = sdata->local; |
1378 | struct ieee80211_tx_data tx; | 1382 | struct ieee80211_tx_data tx; |
@@ -1386,20 +1390,18 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1386 | return true; | 1390 | return true; |
1387 | } | 1391 | } |
1388 | 1392 | ||
1389 | rcu_read_lock(); | ||
1390 | |||
1391 | /* initialises tx */ | 1393 | /* initialises tx */ |
1392 | led_len = skb->len; | 1394 | led_len = skb->len; |
1393 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); | 1395 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); |
1394 | 1396 | ||
1395 | if (unlikely(res_prepare == TX_DROP)) { | 1397 | if (unlikely(res_prepare == TX_DROP)) { |
1396 | ieee80211_free_txskb(&local->hw, skb); | 1398 | ieee80211_free_txskb(&local->hw, skb); |
1397 | goto out; | 1399 | return true; |
1398 | } else if (unlikely(res_prepare == TX_QUEUED)) { | 1400 | } else if (unlikely(res_prepare == TX_QUEUED)) { |
1399 | goto out; | 1401 | return true; |
1400 | } | 1402 | } |
1401 | 1403 | ||
1402 | info->band = local->hw.conf.channel->band; | 1404 | info->band = band; |
1403 | 1405 | ||
1404 | /* set up hw_queue value early */ | 1406 | /* set up hw_queue value early */ |
1405 | if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || | 1407 | if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || |
@@ -1410,8 +1412,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1410 | if (!invoke_tx_handlers(&tx)) | 1412 | if (!invoke_tx_handlers(&tx)) |
1411 | result = __ieee80211_tx(local, &tx.skbs, led_len, | 1413 | result = __ieee80211_tx(local, &tx.skbs, led_len, |
1412 | tx.sta, txpending); | 1414 | tx.sta, txpending); |
1413 | out: | 1415 | |
1414 | rcu_read_unlock(); | ||
1415 | return result; | 1416 | return result; |
1416 | } | 1417 | } |
1417 | 1418 | ||
@@ -1446,7 +1447,8 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1446 | return 0; | 1447 | return 0; |
1447 | } | 1448 | } |
1448 | 1449 | ||
1449 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | 1450 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, |
1451 | enum ieee80211_band band) | ||
1450 | { | 1452 | { |
1451 | struct ieee80211_local *local = sdata->local; | 1453 | struct ieee80211_local *local = sdata->local; |
1452 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1454 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1454,8 +1456,6 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
1454 | int headroom; | 1456 | int headroom; |
1455 | bool may_encrypt; | 1457 | bool may_encrypt; |
1456 | 1458 | ||
1457 | rcu_read_lock(); | ||
1458 | |||
1459 | may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT); | 1459 | may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT); |
1460 | 1460 | ||
1461 | headroom = local->tx_headroom; | 1461 | headroom = local->tx_headroom; |
@@ -1466,7 +1466,6 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
1466 | 1466 | ||
1467 | if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { | 1467 | if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { |
1468 | ieee80211_free_txskb(&local->hw, skb); | 1468 | ieee80211_free_txskb(&local->hw, skb); |
1469 | rcu_read_unlock(); | ||
1470 | return; | 1469 | return; |
1471 | } | 1470 | } |
1472 | 1471 | ||
@@ -1478,13 +1477,11 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
1478 | !is_multicast_ether_addr(hdr->addr1) && | 1477 | !is_multicast_ether_addr(hdr->addr1) && |
1479 | mesh_nexthop_resolve(skb, sdata)) { | 1478 | mesh_nexthop_resolve(skb, sdata)) { |
1480 | /* skb queued: don't free */ | 1479 | /* skb queued: don't free */ |
1481 | rcu_read_unlock(); | ||
1482 | return; | 1480 | return; |
1483 | } | 1481 | } |
1484 | 1482 | ||
1485 | ieee80211_set_qos_hdr(sdata, skb); | 1483 | ieee80211_set_qos_hdr(sdata, skb); |
1486 | ieee80211_tx(sdata, skb, false); | 1484 | ieee80211_tx(sdata, skb, false, band); |
1487 | rcu_read_unlock(); | ||
1488 | } | 1485 | } |
1489 | 1486 | ||
1490 | static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) | 1487 | static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) |
@@ -1574,7 +1571,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1574 | struct net_device *dev) | 1571 | struct net_device *dev) |
1575 | { | 1572 | { |
1576 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1573 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1577 | struct ieee80211_channel *chan = local->hw.conf.channel; | 1574 | struct ieee80211_chanctx_conf *chanctx_conf; |
1575 | struct ieee80211_channel *chan; | ||
1578 | struct ieee80211_radiotap_header *prthdr = | 1576 | struct ieee80211_radiotap_header *prthdr = |
1579 | (struct ieee80211_radiotap_header *)skb->data; | 1577 | (struct ieee80211_radiotap_header *)skb->data; |
1580 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1578 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1583,26 +1581,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1583 | u16 len_rthdr; | 1581 | u16 len_rthdr; |
1584 | int hdrlen; | 1582 | int hdrlen; |
1585 | 1583 | ||
1586 | /* | ||
1587 | * Frame injection is not allowed if beaconing is not allowed | ||
1588 | * or if we need radar detection. Beaconing is usually not allowed when | ||
1589 | * the mode or operation (Adhoc, AP, Mesh) does not support DFS. | ||
1590 | * Passive scan is also used in world regulatory domains where | ||
1591 | * your country is not known and as such it should be treated as | ||
1592 | * NO TX unless the channel is explicitly allowed in which case | ||
1593 | * your current regulatory domain would not have the passive scan | ||
1594 | * flag. | ||
1595 | * | ||
1596 | * Since AP mode uses monitor interfaces to inject/TX management | ||
1597 | * frames we can make AP mode the exception to this rule once it | ||
1598 | * supports radar detection as its implementation can deal with | ||
1599 | * radar detection by itself. We can do that later by adding a | ||
1600 | * monitor flag interfaces used for AP support. | ||
1601 | */ | ||
1602 | if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | | ||
1603 | IEEE80211_CHAN_PASSIVE_SCAN))) | ||
1604 | goto fail; | ||
1605 | |||
1606 | /* check for not even having the fixed radiotap header part */ | 1584 | /* check for not even having the fixed radiotap header part */ |
1607 | if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) | 1585 | if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) |
1608 | goto fail; /* too short to be possibly valid */ | 1586 | goto fail; /* too short to be possibly valid */ |
@@ -1688,11 +1666,45 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1688 | } | 1666 | } |
1689 | } | 1667 | } |
1690 | 1668 | ||
1691 | ieee80211_xmit(sdata, skb); | 1669 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
1670 | if (!chanctx_conf) { | ||
1671 | tmp_sdata = rcu_dereference(local->monitor_sdata); | ||
1672 | if (tmp_sdata) | ||
1673 | chanctx_conf = | ||
1674 | rcu_dereference(tmp_sdata->vif.chanctx_conf); | ||
1675 | } | ||
1676 | if (!chanctx_conf) | ||
1677 | goto fail_rcu; | ||
1678 | |||
1679 | chan = chanctx_conf->channel; | ||
1680 | |||
1681 | /* | ||
1682 | * Frame injection is not allowed if beaconing is not allowed | ||
1683 | * or if we need radar detection. Beaconing is usually not allowed when | ||
1684 | * the mode or operation (Adhoc, AP, Mesh) does not support DFS. | ||
1685 | * Passive scan is also used in world regulatory domains where | ||
1686 | * your country is not known and as such it should be treated as | ||
1687 | * NO TX unless the channel is explicitly allowed in which case | ||
1688 | * your current regulatory domain would not have the passive scan | ||
1689 | * flag. | ||
1690 | * | ||
1691 | * Since AP mode uses monitor interfaces to inject/TX management | ||
1692 | * frames we can make AP mode the exception to this rule once it | ||
1693 | * supports radar detection as its implementation can deal with | ||
1694 | * radar detection by itself. We can do that later by adding a | ||
1695 | * monitor flag interfaces used for AP support. | ||
1696 | */ | ||
1697 | if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | | ||
1698 | IEEE80211_CHAN_PASSIVE_SCAN))) | ||
1699 | goto fail_rcu; | ||
1700 | |||
1701 | ieee80211_xmit(sdata, skb, chan->band); | ||
1692 | rcu_read_unlock(); | 1702 | rcu_read_unlock(); |
1693 | 1703 | ||
1694 | return NETDEV_TX_OK; | 1704 | return NETDEV_TX_OK; |
1695 | 1705 | ||
1706 | fail_rcu: | ||
1707 | rcu_read_unlock(); | ||
1696 | fail: | 1708 | fail: |
1697 | dev_kfree_skb(skb); | 1709 | dev_kfree_skb(skb); |
1698 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ | 1710 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ |
@@ -1734,6 +1746,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1734 | bool multicast; | 1746 | bool multicast; |
1735 | u32 info_flags = 0; | 1747 | u32 info_flags = 0; |
1736 | u16 info_id = 0; | 1748 | u16 info_id = 0; |
1749 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
1750 | struct ieee80211_sub_if_data *ap_sdata; | ||
1751 | enum ieee80211_band band; | ||
1737 | 1752 | ||
1738 | if (unlikely(skb->len < ETH_HLEN)) | 1753 | if (unlikely(skb->len < ETH_HLEN)) |
1739 | goto fail; | 1754 | goto fail; |
@@ -1743,9 +1758,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1743 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1758 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
1744 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); | 1759 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
1745 | 1760 | ||
1761 | rcu_read_lock(); | ||
1762 | |||
1746 | switch (sdata->vif.type) { | 1763 | switch (sdata->vif.type) { |
1747 | case NL80211_IFTYPE_AP_VLAN: | 1764 | case NL80211_IFTYPE_AP_VLAN: |
1748 | rcu_read_lock(); | ||
1749 | sta = rcu_dereference(sdata->u.vlan.sta); | 1765 | sta = rcu_dereference(sdata->u.vlan.sta); |
1750 | if (sta) { | 1766 | if (sta) { |
1751 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1767 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
@@ -1758,7 +1774,12 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1758 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | 1774 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1759 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | 1775 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); |
1760 | } | 1776 | } |
1761 | rcu_read_unlock(); | 1777 | ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, |
1778 | u.ap); | ||
1779 | chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); | ||
1780 | if (!chanctx_conf) | ||
1781 | goto fail_rcu; | ||
1782 | band = chanctx_conf->channel->band; | ||
1762 | if (sta) | 1783 | if (sta) |
1763 | break; | 1784 | break; |
1764 | /* fall through */ | 1785 | /* fall through */ |
@@ -1769,6 +1790,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1769 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | 1790 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
1770 | memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); | 1791 | memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); |
1771 | hdrlen = 24; | 1792 | hdrlen = 24; |
1793 | if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
1794 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1795 | if (!chanctx_conf) | ||
1796 | goto fail_rcu; | ||
1797 | band = chanctx_conf->channel->band; | ||
1772 | break; | 1798 | break; |
1773 | case NL80211_IFTYPE_WDS: | 1799 | case NL80211_IFTYPE_WDS: |
1774 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1800 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
@@ -1778,15 +1804,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1778 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1804 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1779 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1805 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
1780 | hdrlen = 30; | 1806 | hdrlen = 30; |
1807 | /* | ||
1808 | * This is the exception! WDS style interfaces are prohibited | ||
1809 | * when channel contexts are in used so this must be valid | ||
1810 | */ | ||
1811 | band = local->hw.conf.channel->band; | ||
1781 | break; | 1812 | break; |
1782 | #ifdef CONFIG_MAC80211_MESH | 1813 | #ifdef CONFIG_MAC80211_MESH |
1783 | case NL80211_IFTYPE_MESH_POINT: | 1814 | case NL80211_IFTYPE_MESH_POINT: |
1784 | if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { | 1815 | if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { |
1785 | /* Do not send frames with mesh_ttl == 0 */ | 1816 | /* Do not send frames with mesh_ttl == 0 */ |
1786 | sdata->u.mesh.mshstats.dropped_frames_ttl++; | 1817 | sdata->u.mesh.mshstats.dropped_frames_ttl++; |
1787 | goto fail; | 1818 | goto fail_rcu; |
1788 | } | 1819 | } |
1789 | rcu_read_lock(); | 1820 | |
1790 | if (!is_multicast_ether_addr(skb->data)) { | 1821 | if (!is_multicast_ether_addr(skb->data)) { |
1791 | mpath = mesh_path_lookup(skb->data, sdata); | 1822 | mpath = mesh_path_lookup(skb->data, sdata); |
1792 | if (!mpath) | 1823 | if (!mpath) |
@@ -1803,7 +1834,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1803 | !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { | 1834 | !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { |
1804 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1835 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1805 | skb->data, skb->data + ETH_ALEN); | 1836 | skb->data, skb->data + ETH_ALEN); |
1806 | rcu_read_unlock(); | ||
1807 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, | 1837 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, |
1808 | sdata, NULL, NULL); | 1838 | sdata, NULL, NULL); |
1809 | } else { | 1839 | } else { |
@@ -1819,7 +1849,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1819 | mesh_da = mppath->mpp; | 1849 | mesh_da = mppath->mpp; |
1820 | else if (mpath) | 1850 | else if (mpath) |
1821 | mesh_da = mpath->dst; | 1851 | mesh_da = mpath->dst; |
1822 | rcu_read_unlock(); | ||
1823 | 1852 | ||
1824 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1853 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1825 | mesh_da, sdata->vif.addr); | 1854 | mesh_da, sdata->vif.addr); |
@@ -1839,13 +1868,16 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1839 | skb->data + ETH_ALEN); | 1868 | skb->data + ETH_ALEN); |
1840 | 1869 | ||
1841 | } | 1870 | } |
1871 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1872 | if (!chanctx_conf) | ||
1873 | goto fail_rcu; | ||
1874 | band = chanctx_conf->channel->band; | ||
1842 | break; | 1875 | break; |
1843 | #endif | 1876 | #endif |
1844 | case NL80211_IFTYPE_STATION: | 1877 | case NL80211_IFTYPE_STATION: |
1845 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { | 1878 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { |
1846 | bool tdls_peer = false; | 1879 | bool tdls_peer = false; |
1847 | 1880 | ||
1848 | rcu_read_lock(); | ||
1849 | sta = sta_info_get(sdata, skb->data); | 1881 | sta = sta_info_get(sdata, skb->data); |
1850 | if (sta) { | 1882 | if (sta) { |
1851 | authorized = test_sta_flag(sta, | 1883 | authorized = test_sta_flag(sta, |
@@ -1856,7 +1888,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1856 | tdls_auth = test_sta_flag(sta, | 1888 | tdls_auth = test_sta_flag(sta, |
1857 | WLAN_STA_TDLS_PEER_AUTH); | 1889 | WLAN_STA_TDLS_PEER_AUTH); |
1858 | } | 1890 | } |
1859 | rcu_read_unlock(); | ||
1860 | 1891 | ||
1861 | /* | 1892 | /* |
1862 | * If the TDLS link is enabled, send everything | 1893 | * If the TDLS link is enabled, send everything |
@@ -1871,7 +1902,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1871 | if (tdls_direct) { | 1902 | if (tdls_direct) { |
1872 | /* link during setup - throw out frames to peer */ | 1903 | /* link during setup - throw out frames to peer */ |
1873 | if (!tdls_auth) | 1904 | if (!tdls_auth) |
1874 | goto fail; | 1905 | goto fail_rcu; |
1875 | 1906 | ||
1876 | /* DA SA BSSID */ | 1907 | /* DA SA BSSID */ |
1877 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1908 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -1896,6 +1927,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1896 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1927 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1897 | hdrlen = 24; | 1928 | hdrlen = 24; |
1898 | } | 1929 | } |
1930 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1931 | if (!chanctx_conf) | ||
1932 | goto fail_rcu; | ||
1933 | band = chanctx_conf->channel->band; | ||
1899 | break; | 1934 | break; |
1900 | case NL80211_IFTYPE_ADHOC: | 1935 | case NL80211_IFTYPE_ADHOC: |
1901 | /* DA SA BSSID */ | 1936 | /* DA SA BSSID */ |
@@ -1903,9 +1938,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1903 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1938 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
1904 | memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); | 1939 | memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); |
1905 | hdrlen = 24; | 1940 | hdrlen = 24; |
1941 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1942 | if (!chanctx_conf) | ||
1943 | goto fail_rcu; | ||
1944 | band = chanctx_conf->channel->band; | ||
1906 | break; | 1945 | break; |
1907 | default: | 1946 | default: |
1908 | goto fail; | 1947 | goto fail_rcu; |
1909 | } | 1948 | } |
1910 | 1949 | ||
1911 | /* | 1950 | /* |
@@ -1915,13 +1954,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1915 | */ | 1954 | */ |
1916 | multicast = is_multicast_ether_addr(hdr.addr1); | 1955 | multicast = is_multicast_ether_addr(hdr.addr1); |
1917 | if (!multicast) { | 1956 | if (!multicast) { |
1918 | rcu_read_lock(); | ||
1919 | sta = sta_info_get(sdata, hdr.addr1); | 1957 | sta = sta_info_get(sdata, hdr.addr1); |
1920 | if (sta) { | 1958 | if (sta) { |
1921 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | 1959 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1922 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | 1960 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); |
1923 | } | 1961 | } |
1924 | rcu_read_unlock(); | ||
1925 | } | 1962 | } |
1926 | 1963 | ||
1927 | /* For mesh, the use of the QoS header is mandatory */ | 1964 | /* For mesh, the use of the QoS header is mandatory */ |
@@ -1949,7 +1986,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1949 | 1986 | ||
1950 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); | 1987 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); |
1951 | 1988 | ||
1952 | goto fail; | 1989 | goto fail_rcu; |
1953 | } | 1990 | } |
1954 | 1991 | ||
1955 | if (unlikely(!multicast && skb->sk && | 1992 | if (unlikely(!multicast && skb->sk && |
@@ -2004,7 +2041,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2004 | kfree_skb(tmp_skb); | 2041 | kfree_skb(tmp_skb); |
2005 | 2042 | ||
2006 | if (!skb) | 2043 | if (!skb) |
2007 | goto fail; | 2044 | goto fail_rcu; |
2008 | } | 2045 | } |
2009 | 2046 | ||
2010 | hdr.frame_control = fc; | 2047 | hdr.frame_control = fc; |
@@ -2052,7 +2089,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2052 | head_need = max_t(int, 0, head_need); | 2089 | head_need = max_t(int, 0, head_need); |
2053 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) { | 2090 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) { |
2054 | ieee80211_free_txskb(&local->hw, skb); | 2091 | ieee80211_free_txskb(&local->hw, skb); |
2055 | return NETDEV_TX_OK; | 2092 | goto fail_rcu; |
2056 | } | 2093 | } |
2057 | } | 2094 | } |
2058 | 2095 | ||
@@ -2104,10 +2141,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2104 | info->flags = info_flags; | 2141 | info->flags = info_flags; |
2105 | info->ack_frame_id = info_id; | 2142 | info->ack_frame_id = info_id; |
2106 | 2143 | ||
2107 | ieee80211_xmit(sdata, skb); | 2144 | ieee80211_xmit(sdata, skb, band); |
2145 | rcu_read_unlock(); | ||
2108 | 2146 | ||
2109 | return NETDEV_TX_OK; | 2147 | return NETDEV_TX_OK; |
2110 | 2148 | ||
2149 | fail_rcu: | ||
2150 | rcu_read_unlock(); | ||
2111 | fail: | 2151 | fail: |
2112 | dev_kfree_skb(skb); | 2152 | dev_kfree_skb(skb); |
2113 | return NETDEV_TX_OK; | 2153 | return NETDEV_TX_OK; |
@@ -2139,11 +2179,18 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
2139 | struct sta_info *sta; | 2179 | struct sta_info *sta; |
2140 | struct ieee80211_hdr *hdr; | 2180 | struct ieee80211_hdr *hdr; |
2141 | bool result; | 2181 | bool result; |
2182 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
2142 | 2183 | ||
2143 | sdata = vif_to_sdata(info->control.vif); | 2184 | sdata = vif_to_sdata(info->control.vif); |
2144 | 2185 | ||
2145 | if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { | 2186 | if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { |
2146 | result = ieee80211_tx(sdata, skb, true); | 2187 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
2188 | if (unlikely(!chanctx_conf)) { | ||
2189 | dev_kfree_skb(skb); | ||
2190 | return true; | ||
2191 | } | ||
2192 | result = ieee80211_tx(sdata, skb, true, | ||
2193 | chanctx_conf->channel->band); | ||
2147 | } else { | 2194 | } else { |
2148 | struct sk_buff_head skbs; | 2195 | struct sk_buff_head skbs; |
2149 | 2196 | ||
@@ -2211,9 +2258,8 @@ void ieee80211_tx_pending(unsigned long data) | |||
2211 | /* functions for drivers to get certain frames */ | 2258 | /* functions for drivers to get certain frames */ |
2212 | 2259 | ||
2213 | static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | 2260 | static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, |
2214 | struct ieee80211_if_ap *bss, | 2261 | struct ps_data *ps, |
2215 | struct sk_buff *skb, | 2262 | struct sk_buff *skb) |
2216 | struct beacon_data *beacon) | ||
2217 | { | 2263 | { |
2218 | u8 *pos, *tim; | 2264 | u8 *pos, *tim; |
2219 | int aid0 = 0; | 2265 | int aid0 = 0; |
@@ -2221,27 +2267,27 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2221 | 2267 | ||
2222 | /* Generate bitmap for TIM only if there are any STAs in power save | 2268 | /* Generate bitmap for TIM only if there are any STAs in power save |
2223 | * mode. */ | 2269 | * mode. */ |
2224 | if (atomic_read(&bss->num_sta_ps) > 0) | 2270 | if (atomic_read(&ps->num_sta_ps) > 0) |
2225 | /* in the hope that this is faster than | 2271 | /* in the hope that this is faster than |
2226 | * checking byte-for-byte */ | 2272 | * checking byte-for-byte */ |
2227 | have_bits = !bitmap_empty((unsigned long*)bss->tim, | 2273 | have_bits = !bitmap_empty((unsigned long*)ps->tim, |
2228 | IEEE80211_MAX_AID+1); | 2274 | IEEE80211_MAX_AID+1); |
2229 | 2275 | ||
2230 | if (bss->dtim_count == 0) | 2276 | if (ps->dtim_count == 0) |
2231 | bss->dtim_count = sdata->vif.bss_conf.dtim_period - 1; | 2277 | ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; |
2232 | else | 2278 | else |
2233 | bss->dtim_count--; | 2279 | ps->dtim_count--; |
2234 | 2280 | ||
2235 | tim = pos = (u8 *) skb_put(skb, 6); | 2281 | tim = pos = (u8 *) skb_put(skb, 6); |
2236 | *pos++ = WLAN_EID_TIM; | 2282 | *pos++ = WLAN_EID_TIM; |
2237 | *pos++ = 4; | 2283 | *pos++ = 4; |
2238 | *pos++ = bss->dtim_count; | 2284 | *pos++ = ps->dtim_count; |
2239 | *pos++ = sdata->vif.bss_conf.dtim_period; | 2285 | *pos++ = sdata->vif.bss_conf.dtim_period; |
2240 | 2286 | ||
2241 | if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) | 2287 | if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf)) |
2242 | aid0 = 1; | 2288 | aid0 = 1; |
2243 | 2289 | ||
2244 | bss->dtim_bc_mc = aid0 == 1; | 2290 | ps->dtim_bc_mc = aid0 == 1; |
2245 | 2291 | ||
2246 | if (have_bits) { | 2292 | if (have_bits) { |
2247 | /* Find largest even number N1 so that bits numbered 1 through | 2293 | /* Find largest even number N1 so that bits numbered 1 through |
@@ -2249,14 +2295,14 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2249 | * (N2 + 1) x 8 through 2007 are 0. */ | 2295 | * (N2 + 1) x 8 through 2007 are 0. */ |
2250 | n1 = 0; | 2296 | n1 = 0; |
2251 | for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) { | 2297 | for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) { |
2252 | if (bss->tim[i]) { | 2298 | if (ps->tim[i]) { |
2253 | n1 = i & 0xfe; | 2299 | n1 = i & 0xfe; |
2254 | break; | 2300 | break; |
2255 | } | 2301 | } |
2256 | } | 2302 | } |
2257 | n2 = n1; | 2303 | n2 = n1; |
2258 | for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) { | 2304 | for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) { |
2259 | if (bss->tim[i]) { | 2305 | if (ps->tim[i]) { |
2260 | n2 = i; | 2306 | n2 = i; |
2261 | break; | 2307 | break; |
2262 | } | 2308 | } |
@@ -2266,7 +2312,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2266 | *pos++ = n1 | aid0; | 2312 | *pos++ = n1 | aid0; |
2267 | /* Part Virt Bitmap */ | 2313 | /* Part Virt Bitmap */ |
2268 | skb_put(skb, n2 - n1); | 2314 | skb_put(skb, n2 - n1); |
2269 | memcpy(pos, bss->tim + n1, n2 - n1 + 1); | 2315 | memcpy(pos, ps->tim + n1, n2 - n1 + 1); |
2270 | 2316 | ||
2271 | tim[1] = n2 - n1 + 4; | 2317 | tim[1] = n2 - n1 + 4; |
2272 | } else { | 2318 | } else { |
@@ -2283,16 +2329,16 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2283 | struct sk_buff *skb = NULL; | 2329 | struct sk_buff *skb = NULL; |
2284 | struct ieee80211_tx_info *info; | 2330 | struct ieee80211_tx_info *info; |
2285 | struct ieee80211_sub_if_data *sdata = NULL; | 2331 | struct ieee80211_sub_if_data *sdata = NULL; |
2286 | struct ieee80211_if_ap *ap = NULL; | 2332 | enum ieee80211_band band; |
2287 | struct beacon_data *beacon; | ||
2288 | enum ieee80211_band band = local->oper_channel->band; | ||
2289 | struct ieee80211_tx_rate_control txrc; | 2333 | struct ieee80211_tx_rate_control txrc; |
2334 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
2290 | 2335 | ||
2291 | rcu_read_lock(); | 2336 | rcu_read_lock(); |
2292 | 2337 | ||
2293 | sdata = vif_to_sdata(vif); | 2338 | sdata = vif_to_sdata(vif); |
2339 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
2294 | 2340 | ||
2295 | if (!ieee80211_sdata_running(sdata)) | 2341 | if (!ieee80211_sdata_running(sdata) || !chanctx_conf) |
2296 | goto out; | 2342 | goto out; |
2297 | 2343 | ||
2298 | if (tim_offset) | 2344 | if (tim_offset) |
@@ -2301,8 +2347,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2301 | *tim_length = 0; | 2347 | *tim_length = 0; |
2302 | 2348 | ||
2303 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 2349 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
2304 | ap = &sdata->u.ap; | 2350 | struct ieee80211_if_ap *ap = &sdata->u.ap; |
2305 | beacon = rcu_dereference(ap->beacon); | 2351 | struct beacon_data *beacon = rcu_dereference(ap->beacon); |
2352 | |||
2306 | if (beacon) { | 2353 | if (beacon) { |
2307 | /* | 2354 | /* |
2308 | * headroom, head length, | 2355 | * headroom, head length, |
@@ -2326,14 +2373,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2326 | * of the tim bitmap in mac80211 and the driver. | 2373 | * of the tim bitmap in mac80211 and the driver. |
2327 | */ | 2374 | */ |
2328 | if (local->tim_in_locked_section) { | 2375 | if (local->tim_in_locked_section) { |
2329 | ieee80211_beacon_add_tim(sdata, ap, skb, | 2376 | ieee80211_beacon_add_tim(sdata, &ap->ps, skb); |
2330 | beacon); | ||
2331 | } else { | 2377 | } else { |
2332 | unsigned long flags; | 2378 | unsigned long flags; |
2333 | 2379 | ||
2334 | spin_lock_irqsave(&local->tim_lock, flags); | 2380 | spin_lock_irqsave(&local->tim_lock, flags); |
2335 | ieee80211_beacon_add_tim(sdata, ap, skb, | 2381 | ieee80211_beacon_add_tim(sdata, &ap->ps, skb); |
2336 | beacon); | ||
2337 | spin_unlock_irqrestore(&local->tim_lock, flags); | 2382 | spin_unlock_irqrestore(&local->tim_lock, flags); |
2338 | } | 2383 | } |
2339 | 2384 | ||
@@ -2409,6 +2454,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2409 | *pos++ = WLAN_EID_SSID; | 2454 | *pos++ = WLAN_EID_SSID; |
2410 | *pos++ = 0x0; | 2455 | *pos++ = 0x0; |
2411 | 2456 | ||
2457 | band = chanctx_conf->channel->band; | ||
2458 | |||
2412 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || | 2459 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || |
2413 | mesh_add_ds_params_ie(skb, sdata) || | 2460 | mesh_add_ds_params_ie(skb, sdata) || |
2414 | ieee80211_add_ext_srates_ie(sdata, skb, true, band) || | 2461 | ieee80211_add_ext_srates_ie(sdata, skb, true, band) || |
@@ -2426,6 +2473,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2426 | goto out; | 2473 | goto out; |
2427 | } | 2474 | } |
2428 | 2475 | ||
2476 | band = chanctx_conf->channel->band; | ||
2477 | |||
2429 | info = IEEE80211_SKB_CB(skb); | 2478 | info = IEEE80211_SKB_CB(skb); |
2430 | 2479 | ||
2431 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 2480 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
@@ -2653,29 +2702,40 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2653 | struct sk_buff *skb = NULL; | 2702 | struct sk_buff *skb = NULL; |
2654 | struct ieee80211_tx_data tx; | 2703 | struct ieee80211_tx_data tx; |
2655 | struct ieee80211_sub_if_data *sdata; | 2704 | struct ieee80211_sub_if_data *sdata; |
2656 | struct ieee80211_if_ap *bss = NULL; | 2705 | struct ps_data *ps; |
2657 | struct beacon_data *beacon; | ||
2658 | struct ieee80211_tx_info *info; | 2706 | struct ieee80211_tx_info *info; |
2707 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
2659 | 2708 | ||
2660 | sdata = vif_to_sdata(vif); | 2709 | sdata = vif_to_sdata(vif); |
2661 | bss = &sdata->u.ap; | ||
2662 | 2710 | ||
2663 | rcu_read_lock(); | 2711 | rcu_read_lock(); |
2664 | beacon = rcu_dereference(bss->beacon); | 2712 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
2665 | 2713 | ||
2666 | if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head) | 2714 | if (!chanctx_conf) |
2667 | goto out; | 2715 | goto out; |
2668 | 2716 | ||
2669 | if (bss->dtim_count != 0 || !bss->dtim_bc_mc) | 2717 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
2718 | struct beacon_data *beacon = | ||
2719 | rcu_dereference(sdata->u.ap.beacon); | ||
2720 | |||
2721 | if (!beacon || !beacon->head) | ||
2722 | goto out; | ||
2723 | |||
2724 | ps = &sdata->u.ap.ps; | ||
2725 | } else { | ||
2726 | goto out; | ||
2727 | } | ||
2728 | |||
2729 | if (ps->dtim_count != 0 || !ps->dtim_bc_mc) | ||
2670 | goto out; /* send buffered bc/mc only after DTIM beacon */ | 2730 | goto out; /* send buffered bc/mc only after DTIM beacon */ |
2671 | 2731 | ||
2672 | while (1) { | 2732 | while (1) { |
2673 | skb = skb_dequeue(&bss->ps_bc_buf); | 2733 | skb = skb_dequeue(&ps->bc_buf); |
2674 | if (!skb) | 2734 | if (!skb) |
2675 | goto out; | 2735 | goto out; |
2676 | local->total_ps_buffered--; | 2736 | local->total_ps_buffered--; |
2677 | 2737 | ||
2678 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { | 2738 | if (!skb_queue_empty(&ps->bc_buf) && skb->len >= 2) { |
2679 | struct ieee80211_hdr *hdr = | 2739 | struct ieee80211_hdr *hdr = |
2680 | (struct ieee80211_hdr *) skb->data; | 2740 | (struct ieee80211_hdr *) skb->data; |
2681 | /* more buffered multicast/broadcast frames ==> set | 2741 | /* more buffered multicast/broadcast frames ==> set |
@@ -2693,7 +2753,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2693 | info = IEEE80211_SKB_CB(skb); | 2753 | info = IEEE80211_SKB_CB(skb); |
2694 | 2754 | ||
2695 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2755 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
2696 | info->band = local->oper_channel->band; | 2756 | info->band = chanctx_conf->channel->band; |
2697 | 2757 | ||
2698 | if (invoke_tx_handlers(&tx)) | 2758 | if (invoke_tx_handlers(&tx)) |
2699 | skb = NULL; | 2759 | skb = NULL; |
@@ -2704,8 +2764,9 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2704 | } | 2764 | } |
2705 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); | 2765 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); |
2706 | 2766 | ||
2707 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | 2767 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
2708 | struct sk_buff *skb, int tid) | 2768 | struct sk_buff *skb, int tid, |
2769 | enum ieee80211_band band) | ||
2709 | { | 2770 | { |
2710 | int ac = ieee802_1d_to_ac[tid & 7]; | 2771 | int ac = ieee802_1d_to_ac[tid & 7]; |
2711 | 2772 | ||
@@ -2722,6 +2783,6 @@ void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | |||
2722 | * requirements are that we do not come into tx with bhs on. | 2783 | * requirements are that we do not come into tx with bhs on. |
2723 | */ | 2784 | */ |
2724 | local_bh_disable(); | 2785 | local_bh_disable(); |
2725 | ieee80211_xmit(sdata, skb); | 2786 | ieee80211_xmit(sdata, skb, band); |
2726 | local_bh_enable(); | 2787 | local_bh_enable(); |
2727 | } | 2788 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 239391807ca9..9556391b05d7 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -769,6 +769,18 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
769 | else | 769 | else |
770 | elem_parse_failed = true; | 770 | elem_parse_failed = true; |
771 | break; | 771 | break; |
772 | case WLAN_EID_VHT_CAPABILITY: | ||
773 | if (elen >= sizeof(struct ieee80211_vht_cap)) | ||
774 | elems->vht_cap_elem = (void *)pos; | ||
775 | else | ||
776 | elem_parse_failed = true; | ||
777 | break; | ||
778 | case WLAN_EID_VHT_OPERATION: | ||
779 | if (elen >= sizeof(struct ieee80211_vht_operation)) | ||
780 | elems->vht_operation = (void *)pos; | ||
781 | else | ||
782 | elem_parse_failed = true; | ||
783 | break; | ||
772 | case WLAN_EID_MESH_ID: | 784 | case WLAN_EID_MESH_ID: |
773 | elems->mesh_id = pos; | 785 | elems->mesh_id = pos; |
774 | elems->mesh_id_len = elen; | 786 | elems->mesh_id_len = elen; |
@@ -837,7 +849,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
837 | if (elem_parse_failed) | 849 | if (elem_parse_failed) |
838 | elems->parse_error = true; | 850 | elems->parse_error = true; |
839 | else | 851 | else |
840 | set_bit(id, seen_elems); | 852 | __set_bit(id, seen_elems); |
841 | 853 | ||
842 | left -= elen; | 854 | left -= elen; |
843 | pos += elen; | 855 | pos += elen; |
@@ -860,6 +872,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
860 | { | 872 | { |
861 | struct ieee80211_local *local = sdata->local; | 873 | struct ieee80211_local *local = sdata->local; |
862 | struct ieee80211_tx_queue_params qparam; | 874 | struct ieee80211_tx_queue_params qparam; |
875 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
863 | int ac; | 876 | int ac; |
864 | bool use_11b, enable_qos; | 877 | bool use_11b, enable_qos; |
865 | int aCWmin, aCWmax; | 878 | int aCWmin, aCWmax; |
@@ -872,8 +885,12 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
872 | 885 | ||
873 | memset(&qparam, 0, sizeof(qparam)); | 886 | memset(&qparam, 0, sizeof(qparam)); |
874 | 887 | ||
875 | use_11b = (local->oper_channel->band == IEEE80211_BAND_2GHZ) && | 888 | rcu_read_lock(); |
889 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
890 | use_11b = (chanctx_conf && | ||
891 | chanctx_conf->channel->band == IEEE80211_BAND_2GHZ) && | ||
876 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); | 892 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); |
893 | rcu_read_unlock(); | ||
877 | 894 | ||
878 | /* | 895 | /* |
879 | * By default disable QoS in STA mode for old access points, which do | 896 | * By default disable QoS in STA mode for old access points, which do |
@@ -952,7 +969,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | |||
952 | const size_t supp_rates_len, | 969 | const size_t supp_rates_len, |
953 | const u8 *supp_rates) | 970 | const u8 *supp_rates) |
954 | { | 971 | { |
955 | struct ieee80211_local *local = sdata->local; | 972 | struct ieee80211_chanctx_conf *chanctx_conf; |
956 | int i, have_higher_than_11mbit = 0; | 973 | int i, have_higher_than_11mbit = 0; |
957 | 974 | ||
958 | /* cf. IEEE 802.11 9.2.12 */ | 975 | /* cf. IEEE 802.11 9.2.12 */ |
@@ -960,11 +977,16 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | |||
960 | if ((supp_rates[i] & 0x7f) * 5 > 110) | 977 | if ((supp_rates[i] & 0x7f) * 5 > 110) |
961 | have_higher_than_11mbit = 1; | 978 | have_higher_than_11mbit = 1; |
962 | 979 | ||
963 | if (local->oper_channel->band == IEEE80211_BAND_2GHZ && | 980 | rcu_read_lock(); |
981 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
982 | |||
983 | if (chanctx_conf && | ||
984 | chanctx_conf->channel->band == IEEE80211_BAND_2GHZ && | ||
964 | have_higher_than_11mbit) | 985 | have_higher_than_11mbit) |
965 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | 986 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; |
966 | else | 987 | else |
967 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 988 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
989 | rcu_read_unlock(); | ||
968 | 990 | ||
969 | ieee80211_set_wmm_default(sdata, true); | 991 | ieee80211_set_wmm_default(sdata, true); |
970 | } | 992 | } |
@@ -996,7 +1018,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | |||
996 | } | 1018 | } |
997 | 1019 | ||
998 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1020 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
999 | u16 transaction, u16 auth_alg, | 1021 | u16 transaction, u16 auth_alg, u16 status, |
1000 | u8 *extra, size_t extra_len, const u8 *da, | 1022 | u8 *extra, size_t extra_len, const u8 *da, |
1001 | const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx) | 1023 | const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx) |
1002 | { | 1024 | { |
@@ -1021,7 +1043,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1021 | memcpy(mgmt->bssid, bssid, ETH_ALEN); | 1043 | memcpy(mgmt->bssid, bssid, ETH_ALEN); |
1022 | mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); | 1044 | mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); |
1023 | mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); | 1045 | mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); |
1024 | mgmt->u.auth.status_code = cpu_to_le16(0); | 1046 | mgmt->u.auth.status_code = cpu_to_le16(status); |
1025 | if (extra) | 1047 | if (extra) |
1026 | memcpy(skb_put(skb, extra_len), extra, extra_len); | 1048 | memcpy(skb_put(skb, extra_len), extra, extra_len); |
1027 | 1049 | ||
@@ -1234,7 +1256,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1234 | const u8 *ssid, size_t ssid_len, | 1256 | const u8 *ssid, size_t ssid_len, |
1235 | const u8 *ie, size_t ie_len, | 1257 | const u8 *ie, size_t ie_len, |
1236 | u32 ratemask, bool directed, bool no_cck, | 1258 | u32 ratemask, bool directed, bool no_cck, |
1237 | struct ieee80211_channel *channel) | 1259 | struct ieee80211_channel *channel, bool scan) |
1238 | { | 1260 | { |
1239 | struct sk_buff *skb; | 1261 | struct sk_buff *skb; |
1240 | 1262 | ||
@@ -1245,7 +1267,10 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1245 | if (no_cck) | 1267 | if (no_cck) |
1246 | IEEE80211_SKB_CB(skb)->flags |= | 1268 | IEEE80211_SKB_CB(skb)->flags |= |
1247 | IEEE80211_TX_CTL_NO_CCK_RATE; | 1269 | IEEE80211_TX_CTL_NO_CCK_RATE; |
1248 | ieee80211_tx_skb(sdata, skb); | 1270 | if (scan) |
1271 | ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band); | ||
1272 | else | ||
1273 | ieee80211_tx_skb(sdata, skb); | ||
1249 | } | 1274 | } |
1250 | } | 1275 | } |
1251 | 1276 | ||
@@ -1308,6 +1333,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1308 | { | 1333 | { |
1309 | struct ieee80211_hw *hw = &local->hw; | 1334 | struct ieee80211_hw *hw = &local->hw; |
1310 | struct ieee80211_sub_if_data *sdata; | 1335 | struct ieee80211_sub_if_data *sdata; |
1336 | struct ieee80211_chanctx *ctx; | ||
1311 | struct sta_info *sta; | 1337 | struct sta_info *sta; |
1312 | int res, i; | 1338 | int res, i; |
1313 | 1339 | ||
@@ -1380,6 +1406,12 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1380 | res = drv_add_interface(local, sdata); | 1406 | res = drv_add_interface(local, sdata); |
1381 | } | 1407 | } |
1382 | 1408 | ||
1409 | /* add channel contexts */ | ||
1410 | mutex_lock(&local->chanctx_mtx); | ||
1411 | list_for_each_entry(ctx, &local->chanctx_list, list) | ||
1412 | WARN_ON(drv_add_chanctx(local, ctx)); | ||
1413 | mutex_unlock(&local->chanctx_mtx); | ||
1414 | |||
1383 | /* add STAs back */ | 1415 | /* add STAs back */ |
1384 | mutex_lock(&local->sta_mtx); | 1416 | mutex_lock(&local->sta_mtx); |
1385 | list_for_each_entry(sta, &local->sta_list, list) { | 1417 | list_for_each_entry(sta, &local->sta_list, list) { |
@@ -1420,11 +1452,22 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1420 | 1452 | ||
1421 | /* Finally also reconfigure all the BSS information */ | 1453 | /* Finally also reconfigure all the BSS information */ |
1422 | list_for_each_entry(sdata, &local->interfaces, list) { | 1454 | list_for_each_entry(sdata, &local->interfaces, list) { |
1455 | struct ieee80211_chanctx_conf *ctx_conf; | ||
1423 | u32 changed; | 1456 | u32 changed; |
1424 | 1457 | ||
1425 | if (!ieee80211_sdata_running(sdata)) | 1458 | if (!ieee80211_sdata_running(sdata)) |
1426 | continue; | 1459 | continue; |
1427 | 1460 | ||
1461 | mutex_lock(&local->chanctx_mtx); | ||
1462 | ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | ||
1463 | lockdep_is_held(&local->chanctx_mtx)); | ||
1464 | if (ctx_conf) { | ||
1465 | ctx = container_of(ctx_conf, struct ieee80211_chanctx, | ||
1466 | conf); | ||
1467 | drv_assign_vif_chanctx(local, sdata, ctx); | ||
1468 | } | ||
1469 | mutex_unlock(&local->chanctx_mtx); | ||
1470 | |||
1428 | /* common change flags for all interface types */ | 1471 | /* common change flags for all interface types */ |
1429 | changed = BSS_CHANGED_ERP_CTS_PROT | | 1472 | changed = BSS_CHANGED_ERP_CTS_PROT | |
1430 | BSS_CHANGED_ERP_PREAMBLE | | 1473 | BSS_CHANGED_ERP_PREAMBLE | |
@@ -1615,68 +1658,24 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif) | |||
1615 | } | 1658 | } |
1616 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); | 1659 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); |
1617 | 1660 | ||
1618 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | 1661 | void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata) |
1619 | enum ieee80211_smps_mode *smps_mode) | ||
1620 | { | ||
1621 | if (ifmgd->associated) { | ||
1622 | *smps_mode = ifmgd->ap_smps; | ||
1623 | |||
1624 | if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) { | ||
1625 | if (ifmgd->powersave) | ||
1626 | *smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
1627 | else | ||
1628 | *smps_mode = IEEE80211_SMPS_OFF; | ||
1629 | } | ||
1630 | |||
1631 | return 1; | ||
1632 | } | ||
1633 | |||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | void ieee80211_recalc_smps(struct ieee80211_local *local) | ||
1638 | { | 1662 | { |
1639 | struct ieee80211_sub_if_data *sdata; | 1663 | struct ieee80211_local *local = sdata->local; |
1640 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; | 1664 | struct ieee80211_chanctx_conf *chanctx_conf; |
1641 | int count = 0; | 1665 | struct ieee80211_chanctx *chanctx; |
1642 | |||
1643 | mutex_lock(&local->iflist_mtx); | ||
1644 | |||
1645 | /* | ||
1646 | * This function could be improved to handle multiple | ||
1647 | * interfaces better, but right now it makes any | ||
1648 | * non-station interfaces force SM PS to be turned | ||
1649 | * off. If there are multiple station interfaces it | ||
1650 | * could also use the best possible mode, e.g. if | ||
1651 | * one is in static and the other in dynamic then | ||
1652 | * dynamic is ok. | ||
1653 | */ | ||
1654 | |||
1655 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1656 | if (!ieee80211_sdata_running(sdata)) | ||
1657 | continue; | ||
1658 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
1659 | continue; | ||
1660 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
1661 | goto set; | ||
1662 | 1666 | ||
1663 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | 1667 | mutex_lock(&local->chanctx_mtx); |
1664 | 1668 | ||
1665 | if (count > 1) { | 1669 | chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
1666 | smps_mode = IEEE80211_SMPS_OFF; | 1670 | lockdep_is_held(&local->chanctx_mtx)); |
1667 | break; | ||
1668 | } | ||
1669 | } | ||
1670 | 1671 | ||
1671 | if (smps_mode == local->smps_mode) | 1672 | if (WARN_ON_ONCE(!chanctx_conf)) |
1672 | goto unlock; | 1673 | goto unlock; |
1673 | 1674 | ||
1674 | set: | 1675 | chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf); |
1675 | local->smps_mode = smps_mode; | 1676 | ieee80211_recalc_smps_chanctx(local, chanctx); |
1676 | /* changed flag is auto-detected for this */ | ||
1677 | ieee80211_hw_config(local, 0); | ||
1678 | unlock: | 1677 | unlock: |
1679 | mutex_unlock(&local->iflist_mtx); | 1678 | mutex_unlock(&local->chanctx_mtx); |
1680 | } | 1679 | } |
1681 | 1680 | ||
1682 | static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) | 1681 | static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) |
@@ -1816,8 +1815,8 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | |||
1816 | __le32 tmp; | 1815 | __le32 tmp; |
1817 | 1816 | ||
1818 | *pos++ = WLAN_EID_VHT_CAPABILITY; | 1817 | *pos++ = WLAN_EID_VHT_CAPABILITY; |
1819 | *pos++ = sizeof(struct ieee80211_vht_capabilities); | 1818 | *pos++ = sizeof(struct ieee80211_vht_cap); |
1820 | memset(pos, 0, sizeof(struct ieee80211_vht_capabilities)); | 1819 | memset(pos, 0, sizeof(struct ieee80211_vht_cap)); |
1821 | 1820 | ||
1822 | /* capability flags */ | 1821 | /* capability flags */ |
1823 | tmp = cpu_to_le32(cap); | 1822 | tmp = cpu_to_le32(cap); |
@@ -1975,3 +1974,19 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif) | |||
1975 | return ifmgd->ave_beacon_signal; | 1974 | return ifmgd->ave_beacon_signal; |
1976 | } | 1975 | } |
1977 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); | 1976 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); |
1977 | |||
1978 | u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs) | ||
1979 | { | ||
1980 | if (!mcs) | ||
1981 | return 1; | ||
1982 | |||
1983 | /* TODO: consider rx_highest */ | ||
1984 | |||
1985 | if (mcs->rx_mask[3]) | ||
1986 | return 4; | ||
1987 | if (mcs->rx_mask[2]) | ||
1988 | return 3; | ||
1989 | if (mcs->rx_mask[1]) | ||
1990 | return 2; | ||
1991 | return 1; | ||
1992 | } | ||
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c new file mode 100644 index 000000000000..f311388aeedf --- /dev/null +++ b/net/mac80211/vht.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * VHT handling | ||
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 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/ieee80211.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <net/mac80211.h> | ||
12 | #include "ieee80211_i.h" | ||
13 | |||
14 | |||
15 | void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | ||
16 | struct ieee80211_supported_band *sband, | ||
17 | struct ieee80211_vht_cap *vht_cap_ie, | ||
18 | struct ieee80211_sta_vht_cap *vht_cap) | ||
19 | { | ||
20 | if (WARN_ON_ONCE(!vht_cap)) | ||
21 | return; | ||
22 | |||
23 | memset(vht_cap, 0, sizeof(*vht_cap)); | ||
24 | |||
25 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) | ||
26 | return; | ||
27 | |||
28 | vht_cap->vht_supported = true; | ||
29 | |||
30 | vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info); | ||
31 | |||
32 | /* Copy peer MCS info, the driver might need them. */ | ||
33 | memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs, | ||
34 | sizeof(struct ieee80211_vht_mcs_info)); | ||
35 | } | ||
diff --git a/net/nfc/Kconfig b/net/nfc/Kconfig index 8d8d9bc4b6ff..60c3bbb63e8e 100644 --- a/net/nfc/Kconfig +++ b/net/nfc/Kconfig | |||
@@ -3,8 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig NFC | 5 | menuconfig NFC |
6 | depends on NET && EXPERIMENTAL | 6 | depends on NET |
7 | tristate "NFC subsystem support (EXPERIMENTAL)" | 7 | tristate "NFC subsystem support" |
8 | default n | 8 | default n |
9 | help | 9 | help |
10 | Say Y here if you want to build support for NFC (Near field | 10 | Say Y here if you want to build support for NFC (Near field |
diff --git a/net/nfc/core.c b/net/nfc/core.c index 479bee36dc3e..aa64ea441676 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -40,6 +40,9 @@ | |||
40 | int nfc_devlist_generation; | 40 | int nfc_devlist_generation; |
41 | DEFINE_MUTEX(nfc_devlist_mutex); | 41 | DEFINE_MUTEX(nfc_devlist_mutex); |
42 | 42 | ||
43 | /* NFC device ID bitmap */ | ||
44 | static DEFINE_IDA(nfc_index_ida); | ||
45 | |||
43 | /** | 46 | /** |
44 | * nfc_dev_up - turn on the NFC device | 47 | * nfc_dev_up - turn on the NFC device |
45 | * | 48 | * |
@@ -181,6 +184,7 @@ int nfc_stop_poll(struct nfc_dev *dev) | |||
181 | 184 | ||
182 | dev->ops->stop_poll(dev); | 185 | dev->ops->stop_poll(dev); |
183 | dev->polling = false; | 186 | dev->polling = false; |
187 | dev->rf_mode = NFC_RF_NONE; | ||
184 | 188 | ||
185 | error: | 189 | error: |
186 | device_unlock(&dev->dev); | 190 | device_unlock(&dev->dev); |
@@ -194,7 +198,7 @@ static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) | |||
194 | if (dev->n_targets == 0) | 198 | if (dev->n_targets == 0) |
195 | return NULL; | 199 | return NULL; |
196 | 200 | ||
197 | for (i = 0; i < dev->n_targets ; i++) { | 201 | for (i = 0; i < dev->n_targets; i++) { |
198 | if (dev->targets[i].idx == target_idx) | 202 | if (dev->targets[i].idx == target_idx) |
199 | return &dev->targets[i]; | 203 | return &dev->targets[i]; |
200 | } | 204 | } |
@@ -274,12 +278,14 @@ int nfc_dep_link_down(struct nfc_dev *dev) | |||
274 | if (!rc) { | 278 | if (!rc) { |
275 | dev->dep_link_up = false; | 279 | dev->dep_link_up = false; |
276 | dev->active_target = NULL; | 280 | dev->active_target = NULL; |
281 | dev->rf_mode = NFC_RF_NONE; | ||
277 | nfc_llcp_mac_is_down(dev); | 282 | nfc_llcp_mac_is_down(dev); |
278 | nfc_genl_dep_link_down_event(dev); | 283 | nfc_genl_dep_link_down_event(dev); |
279 | } | 284 | } |
280 | 285 | ||
281 | error: | 286 | error: |
282 | device_unlock(&dev->dev); | 287 | device_unlock(&dev->dev); |
288 | |||
283 | return rc; | 289 | return rc; |
284 | } | 290 | } |
285 | 291 | ||
@@ -503,6 +509,7 @@ EXPORT_SYMBOL(nfc_tm_activated); | |||
503 | int nfc_tm_deactivated(struct nfc_dev *dev) | 509 | int nfc_tm_deactivated(struct nfc_dev *dev) |
504 | { | 510 | { |
505 | dev->dep_link_up = false; | 511 | dev->dep_link_up = false; |
512 | dev->rf_mode = NFC_RF_NONE; | ||
506 | 513 | ||
507 | return nfc_genl_tm_deactivated(dev); | 514 | return nfc_genl_tm_deactivated(dev); |
508 | } | 515 | } |
@@ -697,6 +704,8 @@ static void nfc_check_pres_work(struct work_struct *work) | |||
697 | 704 | ||
698 | if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { | 705 | if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { |
699 | rc = dev->ops->check_presence(dev, dev->active_target); | 706 | rc = dev->ops->check_presence(dev, dev->active_target); |
707 | if (rc == -EOPNOTSUPP) | ||
708 | goto exit; | ||
700 | if (!rc) { | 709 | if (!rc) { |
701 | mod_timer(&dev->check_pres_timer, jiffies + | 710 | mod_timer(&dev->check_pres_timer, jiffies + |
702 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); | 711 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); |
@@ -708,6 +717,7 @@ static void nfc_check_pres_work(struct work_struct *work) | |||
708 | } | 717 | } |
709 | } | 718 | } |
710 | 719 | ||
720 | exit: | ||
711 | device_unlock(&dev->dev); | 721 | device_unlock(&dev->dev); |
712 | } | 722 | } |
713 | 723 | ||
@@ -753,7 +763,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | |||
753 | u32 supported_protocols, | 763 | u32 supported_protocols, |
754 | int tx_headroom, int tx_tailroom) | 764 | int tx_headroom, int tx_tailroom) |
755 | { | 765 | { |
756 | static atomic_t dev_no = ATOMIC_INIT(0); | ||
757 | struct nfc_dev *dev; | 766 | struct nfc_dev *dev; |
758 | 767 | ||
759 | if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || | 768 | if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || |
@@ -767,11 +776,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | |||
767 | if (!dev) | 776 | if (!dev) |
768 | return NULL; | 777 | return NULL; |
769 | 778 | ||
770 | dev->dev.class = &nfc_class; | ||
771 | dev->idx = atomic_inc_return(&dev_no) - 1; | ||
772 | dev_set_name(&dev->dev, "nfc%d", dev->idx); | ||
773 | device_initialize(&dev->dev); | ||
774 | |||
775 | dev->ops = ops; | 779 | dev->ops = ops; |
776 | dev->supported_protocols = supported_protocols; | 780 | dev->supported_protocols = supported_protocols; |
777 | dev->tx_headroom = tx_headroom; | 781 | dev->tx_headroom = tx_headroom; |
@@ -779,6 +783,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | |||
779 | 783 | ||
780 | nfc_genl_data_init(&dev->genl_data); | 784 | nfc_genl_data_init(&dev->genl_data); |
781 | 785 | ||
786 | dev->rf_mode = NFC_RF_NONE; | ||
782 | 787 | ||
783 | /* first generation must not be 0 */ | 788 | /* first generation must not be 0 */ |
784 | dev->targets_generation = 1; | 789 | dev->targets_generation = 1; |
@@ -806,6 +811,14 @@ int nfc_register_device(struct nfc_dev *dev) | |||
806 | 811 | ||
807 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); | 812 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); |
808 | 813 | ||
814 | dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); | ||
815 | if (dev->idx < 0) | ||
816 | return dev->idx; | ||
817 | |||
818 | dev->dev.class = &nfc_class; | ||
819 | dev_set_name(&dev->dev, "nfc%d", dev->idx); | ||
820 | device_initialize(&dev->dev); | ||
821 | |||
809 | mutex_lock(&nfc_devlist_mutex); | 822 | mutex_lock(&nfc_devlist_mutex); |
810 | nfc_devlist_generation++; | 823 | nfc_devlist_generation++; |
811 | rc = device_add(&dev->dev); | 824 | rc = device_add(&dev->dev); |
@@ -834,10 +847,12 @@ EXPORT_SYMBOL(nfc_register_device); | |||
834 | */ | 847 | */ |
835 | void nfc_unregister_device(struct nfc_dev *dev) | 848 | void nfc_unregister_device(struct nfc_dev *dev) |
836 | { | 849 | { |
837 | int rc; | 850 | int rc, id; |
838 | 851 | ||
839 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); | 852 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); |
840 | 853 | ||
854 | id = dev->idx; | ||
855 | |||
841 | mutex_lock(&nfc_devlist_mutex); | 856 | mutex_lock(&nfc_devlist_mutex); |
842 | nfc_devlist_generation++; | 857 | nfc_devlist_generation++; |
843 | 858 | ||
@@ -856,6 +871,8 @@ void nfc_unregister_device(struct nfc_dev *dev) | |||
856 | pr_debug("The userspace won't be notified that the device %s was removed\n", | 871 | pr_debug("The userspace won't be notified that the device %s was removed\n", |
857 | dev_name(&dev->dev)); | 872 | dev_name(&dev->dev)); |
858 | 873 | ||
874 | ida_simple_remove(&nfc_index_ida, id); | ||
875 | |||
859 | } | 876 | } |
860 | EXPORT_SYMBOL(nfc_unregister_device); | 877 | EXPORT_SYMBOL(nfc_unregister_device); |
861 | 878 | ||
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c index 71c6a7086b8f..07659cfd6d7b 100644 --- a/net/nfc/hci/command.c +++ b/net/nfc/hci/command.c | |||
@@ -257,16 +257,16 @@ static u8 nfc_hci_create_pipe(struct nfc_hci_dev *hdev, u8 dest_host, | |||
257 | *result = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, | 257 | *result = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, |
258 | NFC_HCI_ADM_CREATE_PIPE, | 258 | NFC_HCI_ADM_CREATE_PIPE, |
259 | (u8 *) ¶ms, sizeof(params), &skb); | 259 | (u8 *) ¶ms, sizeof(params), &skb); |
260 | if (*result == 0) { | 260 | if (*result < 0) |
261 | resp = (struct hci_create_pipe_resp *)skb->data; | 261 | return NFC_HCI_INVALID_PIPE; |
262 | pipe = resp->pipe; | ||
263 | kfree_skb(skb); | ||
264 | 262 | ||
265 | pr_debug("pipe created=%d\n", pipe); | 263 | resp = (struct hci_create_pipe_resp *)skb->data; |
264 | pipe = resp->pipe; | ||
265 | kfree_skb(skb); | ||
266 | 266 | ||
267 | return pipe; | 267 | pr_debug("pipe created=%d\n", pipe); |
268 | } else | 268 | |
269 | return NFC_HCI_INVALID_PIPE; | 269 | return pipe; |
270 | } | 270 | } |
271 | 271 | ||
272 | static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) | 272 | static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) |
@@ -279,8 +279,6 @@ static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) | |||
279 | 279 | ||
280 | static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) | 280 | static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) |
281 | { | 281 | { |
282 | int r; | ||
283 | |||
284 | u8 param[2]; | 282 | u8 param[2]; |
285 | 283 | ||
286 | /* TODO: Find out what the identity reference data is | 284 | /* TODO: Find out what the identity reference data is |
@@ -288,10 +286,8 @@ static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) | |||
288 | 286 | ||
289 | pr_debug("\n"); | 287 | pr_debug("\n"); |
290 | 288 | ||
291 | r = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, | 289 | return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, |
292 | NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); | 290 | NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); |
293 | |||
294 | return 0; | ||
295 | } | 291 | } |
296 | 292 | ||
297 | int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate) | 293 | int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate) |
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 5fbb6e40793e..bc571b0efb92 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c | |||
@@ -65,8 +65,9 @@ static void nfc_hci_msg_tx_work(struct work_struct *work) | |||
65 | -ETIME); | 65 | -ETIME); |
66 | kfree(hdev->cmd_pending_msg); | 66 | kfree(hdev->cmd_pending_msg); |
67 | hdev->cmd_pending_msg = NULL; | 67 | hdev->cmd_pending_msg = NULL; |
68 | } else | 68 | } else { |
69 | goto exit; | 69 | goto exit; |
70 | } | ||
70 | } | 71 | } |
71 | 72 | ||
72 | next_msg: | 73 | next_msg: |
@@ -182,7 +183,7 @@ static u32 nfc_hci_sak_to_protocol(u8 sak) | |||
182 | } | 183 | } |
183 | } | 184 | } |
184 | 185 | ||
185 | static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) | 186 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) |
186 | { | 187 | { |
187 | struct nfc_target *targets; | 188 | struct nfc_target *targets; |
188 | struct sk_buff *atqa_skb = NULL; | 189 | struct sk_buff *atqa_skb = NULL; |
@@ -263,7 +264,9 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) | |||
263 | break; | 264 | break; |
264 | } | 265 | } |
265 | 266 | ||
266 | targets->hci_reader_gate = gate; | 267 | /* if driver set the new gate, we will skip the old one */ |
268 | if (targets->hci_reader_gate == 0x00) | ||
269 | targets->hci_reader_gate = gate; | ||
267 | 270 | ||
268 | r = nfc_targets_found(hdev->ndev, targets, 1); | 271 | r = nfc_targets_found(hdev->ndev, targets, 1); |
269 | 272 | ||
@@ -275,6 +278,7 @@ exit: | |||
275 | 278 | ||
276 | return r; | 279 | return r; |
277 | } | 280 | } |
281 | EXPORT_SYMBOL(nfc_hci_target_discovered); | ||
278 | 282 | ||
279 | void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | 283 | void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, |
280 | struct sk_buff *skb) | 284 | struct sk_buff *skb) |
@@ -307,8 +311,13 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | |||
307 | nfc_hci_pipe2gate(hdev, pipe)); | 311 | nfc_hci_pipe2gate(hdev, pipe)); |
308 | break; | 312 | break; |
309 | default: | 313 | default: |
310 | /* TODO: Unknown events are hardware specific | 314 | if (hdev->ops->event_received) { |
311 | * pass them to the driver (needs a new hci_ops) */ | 315 | hdev->ops->event_received(hdev, |
316 | nfc_hci_pipe2gate(hdev, pipe), | ||
317 | event, skb); | ||
318 | return; | ||
319 | } | ||
320 | |||
312 | break; | 321 | break; |
313 | } | 322 | } |
314 | 323 | ||
@@ -527,7 +536,8 @@ static int hci_start_poll(struct nfc_dev *nfc_dev, | |||
527 | return hdev->ops->start_poll(hdev, im_protocols, tm_protocols); | 536 | return hdev->ops->start_poll(hdev, im_protocols, tm_protocols); |
528 | else | 537 | else |
529 | return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | 538 | return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, |
530 | NFC_HCI_EVT_READER_REQUESTED, NULL, 0); | 539 | NFC_HCI_EVT_READER_REQUESTED, |
540 | NULL, 0); | ||
531 | } | 541 | } |
532 | 542 | ||
533 | static void hci_stop_poll(struct nfc_dev *nfc_dev) | 543 | static void hci_stop_poll(struct nfc_dev *nfc_dev) |
@@ -538,6 +548,28 @@ static void hci_stop_poll(struct nfc_dev *nfc_dev) | |||
538 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | 548 | NFC_HCI_EVT_END_OPERATION, NULL, 0); |
539 | } | 549 | } |
540 | 550 | ||
551 | static int hci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, | ||
552 | __u8 comm_mode, __u8 *gb, size_t gb_len) | ||
553 | { | ||
554 | struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); | ||
555 | |||
556 | if (hdev->ops->dep_link_up) | ||
557 | return hdev->ops->dep_link_up(hdev, target, comm_mode, | ||
558 | gb, gb_len); | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static int hci_dep_link_down(struct nfc_dev *nfc_dev) | ||
564 | { | ||
565 | struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); | ||
566 | |||
567 | if (hdev->ops->dep_link_down) | ||
568 | return hdev->ops->dep_link_down(hdev); | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
541 | static int hci_activate_target(struct nfc_dev *nfc_dev, | 573 | static int hci_activate_target(struct nfc_dev *nfc_dev, |
542 | struct nfc_target *target, u32 protocol) | 574 | struct nfc_target *target, u32 protocol) |
543 | { | 575 | { |
@@ -586,8 +618,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
586 | switch (target->hci_reader_gate) { | 618 | switch (target->hci_reader_gate) { |
587 | case NFC_HCI_RF_READER_A_GATE: | 619 | case NFC_HCI_RF_READER_A_GATE: |
588 | case NFC_HCI_RF_READER_B_GATE: | 620 | case NFC_HCI_RF_READER_B_GATE: |
589 | if (hdev->ops->data_exchange) { | 621 | if (hdev->ops->im_transceive) { |
590 | r = hdev->ops->data_exchange(hdev, target, skb, cb, | 622 | r = hdev->ops->im_transceive(hdev, target, skb, cb, |
591 | cb_context); | 623 | cb_context); |
592 | if (r <= 0) /* handled */ | 624 | if (r <= 0) /* handled */ |
593 | break; | 625 | break; |
@@ -604,14 +636,14 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
604 | skb->len, hci_transceive_cb, hdev); | 636 | skb->len, hci_transceive_cb, hdev); |
605 | break; | 637 | break; |
606 | default: | 638 | default: |
607 | if (hdev->ops->data_exchange) { | 639 | if (hdev->ops->im_transceive) { |
608 | r = hdev->ops->data_exchange(hdev, target, skb, cb, | 640 | r = hdev->ops->im_transceive(hdev, target, skb, cb, |
609 | cb_context); | 641 | cb_context); |
610 | if (r == 1) | 642 | if (r == 1) |
611 | r = -ENOTSUPP; | 643 | r = -ENOTSUPP; |
612 | } | 644 | } else { |
613 | else | ||
614 | r = -ENOTSUPP; | 645 | r = -ENOTSUPP; |
646 | } | ||
615 | break; | 647 | break; |
616 | } | 648 | } |
617 | 649 | ||
@@ -620,6 +652,16 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
620 | return r; | 652 | return r; |
621 | } | 653 | } |
622 | 654 | ||
655 | static int hci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) | ||
656 | { | ||
657 | struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); | ||
658 | |||
659 | if (hdev->ops->tm_send) | ||
660 | return hdev->ops->tm_send(hdev, skb); | ||
661 | else | ||
662 | return -ENOTSUPP; | ||
663 | } | ||
664 | |||
623 | static int hci_check_presence(struct nfc_dev *nfc_dev, | 665 | static int hci_check_presence(struct nfc_dev *nfc_dev, |
624 | struct nfc_target *target) | 666 | struct nfc_target *target) |
625 | { | 667 | { |
@@ -723,9 +765,12 @@ static struct nfc_ops hci_nfc_ops = { | |||
723 | .dev_down = hci_dev_down, | 765 | .dev_down = hci_dev_down, |
724 | .start_poll = hci_start_poll, | 766 | .start_poll = hci_start_poll, |
725 | .stop_poll = hci_stop_poll, | 767 | .stop_poll = hci_stop_poll, |
768 | .dep_link_up = hci_dep_link_up, | ||
769 | .dep_link_down = hci_dep_link_down, | ||
726 | .activate_target = hci_activate_target, | 770 | .activate_target = hci_activate_target, |
727 | .deactivate_target = hci_deactivate_target, | 771 | .deactivate_target = hci_deactivate_target, |
728 | .im_transceive = hci_transceive, | 772 | .im_transceive = hci_transceive, |
773 | .tm_send = hci_tm_send, | ||
729 | .check_presence = hci_check_presence, | 774 | .check_presence = hci_check_presence, |
730 | }; | 775 | }; |
731 | 776 | ||
@@ -848,7 +893,7 @@ void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err) | |||
848 | } | 893 | } |
849 | EXPORT_SYMBOL(nfc_hci_driver_failure); | 894 | EXPORT_SYMBOL(nfc_hci_driver_failure); |
850 | 895 | ||
851 | void inline nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) | 896 | void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) |
852 | { | 897 | { |
853 | nfc_llc_rcv_from_drv(hdev->llc, skb); | 898 | nfc_llc_rcv_from_drv(hdev->llc, skb); |
854 | } | 899 | } |
diff --git a/net/nfc/hci/llc.c b/net/nfc/hci/llc.c index ae1205ded87f..fe5e966e5b88 100644 --- a/net/nfc/hci/llc.c +++ b/net/nfc/hci/llc.c | |||
@@ -72,7 +72,7 @@ int nfc_llc_register(const char *name, struct nfc_llc_ops *ops) | |||
72 | llc_engine->ops = ops; | 72 | llc_engine->ops = ops; |
73 | 73 | ||
74 | INIT_LIST_HEAD(&llc_engine->entry); | 74 | INIT_LIST_HEAD(&llc_engine->entry); |
75 | list_add_tail (&llc_engine->entry, &llc_engines); | 75 | list_add_tail(&llc_engine->entry, &llc_engines); |
76 | 76 | ||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c index 01cbc72943cd..27b313befc35 100644 --- a/net/nfc/hci/llc_shdlc.c +++ b/net/nfc/hci/llc_shdlc.c | |||
@@ -634,9 +634,9 @@ static void llc_shdlc_sm_work(struct work_struct *work) | |||
634 | r = llc_shdlc_connect_initiate(shdlc); | 634 | r = llc_shdlc_connect_initiate(shdlc); |
635 | else | 635 | else |
636 | r = -ETIME; | 636 | r = -ETIME; |
637 | if (r < 0) | 637 | if (r < 0) { |
638 | llc_shdlc_connect_complete(shdlc, r); | 638 | llc_shdlc_connect_complete(shdlc, r); |
639 | else { | 639 | } else { |
640 | mod_timer(&shdlc->connect_timer, jiffies + | 640 | mod_timer(&shdlc->connect_timer, jiffies + |
641 | msecs_to_jiffies(SHDLC_CONNECT_VALUE_MS)); | 641 | msecs_to_jiffies(SHDLC_CONNECT_VALUE_MS)); |
642 | 642 | ||
@@ -682,9 +682,8 @@ static void llc_shdlc_sm_work(struct work_struct *work) | |||
682 | llc_shdlc_handle_send_queue(shdlc); | 682 | llc_shdlc_handle_send_queue(shdlc); |
683 | } | 683 | } |
684 | 684 | ||
685 | if (shdlc->hard_fault) { | 685 | if (shdlc->hard_fault) |
686 | shdlc->llc_failure(shdlc->hdev, shdlc->hard_fault); | 686 | shdlc->llc_failure(shdlc->hdev, shdlc->hard_fault); |
687 | } | ||
688 | break; | 687 | break; |
689 | default: | 688 | default: |
690 | break; | 689 | break; |
diff --git a/net/nfc/llcp/Kconfig b/net/nfc/llcp/Kconfig index fbf5e8150908..a1a41cd68255 100644 --- a/net/nfc/llcp/Kconfig +++ b/net/nfc/llcp/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config NFC_LLCP | 1 | config NFC_LLCP |
2 | depends on NFC && EXPERIMENTAL | 2 | depends on NFC |
3 | bool "NFC LLCP support (EXPERIMENTAL)" | 3 | bool "NFC LLCP support" |
4 | default n | 4 | default n |
5 | help | 5 | help |
6 | Say Y here if you want to build support for a kernel NFC LLCP | 6 | Say Y here if you want to build support for a kernel NFC LLCP |
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index c45ccd6c094c..ed2d17312d61 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c | |||
@@ -261,7 +261,6 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock) | |||
261 | struct sk_buff *skb; | 261 | struct sk_buff *skb; |
262 | struct nfc_dev *dev; | 262 | struct nfc_dev *dev; |
263 | struct nfc_llcp_local *local; | 263 | struct nfc_llcp_local *local; |
264 | u16 size = 0; | ||
265 | 264 | ||
266 | pr_debug("Sending DISC\n"); | 265 | pr_debug("Sending DISC\n"); |
267 | 266 | ||
@@ -273,17 +272,10 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock) | |||
273 | if (dev == NULL) | 272 | if (dev == NULL) |
274 | return -ENODEV; | 273 | return -ENODEV; |
275 | 274 | ||
276 | size += LLCP_HEADER_SIZE; | 275 | skb = llcp_allocate_pdu(sock, LLCP_PDU_DISC, 0); |
277 | size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; | ||
278 | |||
279 | skb = alloc_skb(size, GFP_ATOMIC); | ||
280 | if (skb == NULL) | 276 | if (skb == NULL) |
281 | return -ENOMEM; | 277 | return -ENOMEM; |
282 | 278 | ||
283 | skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); | ||
284 | |||
285 | skb = llcp_add_header(skb, sock->dsap, sock->ssap, LLCP_PDU_DISC); | ||
286 | |||
287 | skb_queue_tail(&local->tx_queue, skb); | 279 | skb_queue_tail(&local->tx_queue, skb); |
288 | 280 | ||
289 | return 0; | 281 | return 0; |
@@ -324,8 +316,7 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
324 | struct sk_buff *skb; | 316 | struct sk_buff *skb; |
325 | u8 *service_name_tlv = NULL, service_name_tlv_length; | 317 | u8 *service_name_tlv = NULL, service_name_tlv_length; |
326 | u8 *miux_tlv = NULL, miux_tlv_length; | 318 | u8 *miux_tlv = NULL, miux_tlv_length; |
327 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | 319 | u8 *rw_tlv = NULL, rw_tlv_length; |
328 | __be16 miux; | ||
329 | int err; | 320 | int err; |
330 | u16 size = 0; | 321 | u16 size = 0; |
331 | 322 | ||
@@ -343,13 +334,11 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
343 | size += service_name_tlv_length; | 334 | size += service_name_tlv_length; |
344 | } | 335 | } |
345 | 336 | ||
346 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 337 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
347 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
348 | &miux_tlv_length); | 338 | &miux_tlv_length); |
349 | size += miux_tlv_length; | 339 | size += miux_tlv_length; |
350 | 340 | ||
351 | rw = LLCP_MAX_RW; | 341 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); |
352 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
353 | size += rw_tlv_length; | 342 | size += rw_tlv_length; |
354 | 343 | ||
355 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); | 344 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); |
@@ -386,8 +375,7 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
386 | struct nfc_llcp_local *local; | 375 | struct nfc_llcp_local *local; |
387 | struct sk_buff *skb; | 376 | struct sk_buff *skb; |
388 | u8 *miux_tlv = NULL, miux_tlv_length; | 377 | u8 *miux_tlv = NULL, miux_tlv_length; |
389 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | 378 | u8 *rw_tlv = NULL, rw_tlv_length; |
390 | __be16 miux; | ||
391 | int err; | 379 | int err; |
392 | u16 size = 0; | 380 | u16 size = 0; |
393 | 381 | ||
@@ -397,13 +385,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
397 | if (local == NULL) | 385 | if (local == NULL) |
398 | return -ENODEV; | 386 | return -ENODEV; |
399 | 387 | ||
400 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 388 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
401 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
402 | &miux_tlv_length); | 389 | &miux_tlv_length); |
403 | size += miux_tlv_length; | 390 | size += miux_tlv_length; |
404 | 391 | ||
405 | rw = LLCP_MAX_RW; | 392 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); |
406 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
407 | size += rw_tlv_length; | 393 | size += rw_tlv_length; |
408 | 394 | ||
409 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); | 395 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); |
@@ -428,6 +414,52 @@ error_tlv: | |||
428 | return err; | 414 | return err; |
429 | } | 415 | } |
430 | 416 | ||
417 | int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap) | ||
418 | { | ||
419 | struct sk_buff *skb; | ||
420 | struct nfc_dev *dev; | ||
421 | u8 *sdres_tlv = NULL, sdres_tlv_length, sdres[2]; | ||
422 | u16 size = 0; | ||
423 | |||
424 | pr_debug("Sending SNL tid 0x%x sap 0x%x\n", tid, sap); | ||
425 | |||
426 | if (local == NULL) | ||
427 | return -ENODEV; | ||
428 | |||
429 | dev = local->dev; | ||
430 | if (dev == NULL) | ||
431 | return -ENODEV; | ||
432 | |||
433 | sdres[0] = tid; | ||
434 | sdres[1] = sap; | ||
435 | sdres_tlv = nfc_llcp_build_tlv(LLCP_TLV_SDRES, sdres, 0, | ||
436 | &sdres_tlv_length); | ||
437 | if (sdres_tlv == NULL) | ||
438 | return -ENOMEM; | ||
439 | |||
440 | size += LLCP_HEADER_SIZE; | ||
441 | size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; | ||
442 | size += sdres_tlv_length; | ||
443 | |||
444 | skb = alloc_skb(size, GFP_KERNEL); | ||
445 | if (skb == NULL) { | ||
446 | kfree(sdres_tlv); | ||
447 | return -ENOMEM; | ||
448 | } | ||
449 | |||
450 | skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); | ||
451 | |||
452 | skb = llcp_add_header(skb, LLCP_SAP_SDP, LLCP_SAP_SDP, LLCP_PDU_SNL); | ||
453 | |||
454 | memcpy(skb_put(skb, sdres_tlv_length), sdres_tlv, sdres_tlv_length); | ||
455 | |||
456 | skb_queue_tail(&local->tx_queue, skb); | ||
457 | |||
458 | kfree(sdres_tlv); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
431 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) | 463 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) |
432 | { | 464 | { |
433 | struct sk_buff *skb; | 465 | struct sk_buff *skb; |
@@ -541,6 +573,52 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
541 | return len; | 573 | return len; |
542 | } | 574 | } |
543 | 575 | ||
576 | int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | ||
577 | struct msghdr *msg, size_t len) | ||
578 | { | ||
579 | struct sk_buff *pdu; | ||
580 | struct nfc_llcp_local *local; | ||
581 | size_t frag_len = 0, remaining_len; | ||
582 | u8 *msg_ptr; | ||
583 | int err; | ||
584 | |||
585 | pr_debug("Send UI frame len %zd\n", len); | ||
586 | |||
587 | local = sock->local; | ||
588 | if (local == NULL) | ||
589 | return -ENODEV; | ||
590 | |||
591 | remaining_len = len; | ||
592 | msg_ptr = (u8 *) msg->msg_iov; | ||
593 | |||
594 | while (remaining_len > 0) { | ||
595 | |||
596 | frag_len = min_t(size_t, sock->miu, remaining_len); | ||
597 | |||
598 | pr_debug("Fragment %zd bytes remaining %zd", | ||
599 | frag_len, remaining_len); | ||
600 | |||
601 | pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, | ||
602 | frag_len + LLCP_HEADER_SIZE, &err); | ||
603 | if (pdu == NULL) { | ||
604 | pr_err("Could not allocate PDU\n"); | ||
605 | continue; | ||
606 | } | ||
607 | |||
608 | pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); | ||
609 | |||
610 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | ||
611 | |||
612 | /* No need to check for the peer RW for UI frames */ | ||
613 | skb_queue_tail(&local->tx_queue, pdu); | ||
614 | |||
615 | remaining_len -= frag_len; | ||
616 | msg_ptr += frag_len; | ||
617 | } | ||
618 | |||
619 | return len; | ||
620 | } | ||
621 | |||
544 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) | 622 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) |
545 | { | 623 | { |
546 | struct sk_buff *skb; | 624 | struct sk_buff *skb; |
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index cc10d073c338..f6804532047a 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -45,12 +45,38 @@ void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *sk) | |||
45 | write_unlock(&l->lock); | 45 | write_unlock(&l->lock); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) | ||
49 | { | ||
50 | struct nfc_llcp_local *local = sock->local; | ||
51 | struct sk_buff *s, *tmp; | ||
52 | |||
53 | pr_debug("%p\n", &sock->sk); | ||
54 | |||
55 | skb_queue_purge(&sock->tx_queue); | ||
56 | skb_queue_purge(&sock->tx_pending_queue); | ||
57 | skb_queue_purge(&sock->tx_backlog_queue); | ||
58 | |||
59 | if (local == NULL) | ||
60 | return; | ||
61 | |||
62 | /* Search for local pending SKBs that are related to this socket */ | ||
63 | skb_queue_walk_safe(&local->tx_queue, s, tmp) { | ||
64 | if (s->sk != &sock->sk) | ||
65 | continue; | ||
66 | |||
67 | skb_unlink(s, &local->tx_queue); | ||
68 | kfree_skb(s); | ||
69 | } | ||
70 | } | ||
71 | |||
48 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | 72 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) |
49 | { | 73 | { |
50 | struct sock *sk; | 74 | struct sock *sk; |
51 | struct hlist_node *node, *tmp; | 75 | struct hlist_node *node, *tmp; |
52 | struct nfc_llcp_sock *llcp_sock; | 76 | struct nfc_llcp_sock *llcp_sock; |
53 | 77 | ||
78 | skb_queue_purge(&local->tx_queue); | ||
79 | |||
54 | write_lock(&local->sockets.lock); | 80 | write_lock(&local->sockets.lock); |
55 | 81 | ||
56 | sk_for_each_safe(sk, node, tmp, &local->sockets.head) { | 82 | sk_for_each_safe(sk, node, tmp, &local->sockets.head) { |
@@ -58,6 +84,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
58 | 84 | ||
59 | bh_lock_sock(sk); | 85 | bh_lock_sock(sk); |
60 | 86 | ||
87 | nfc_llcp_socket_purge(llcp_sock); | ||
88 | |||
61 | if (sk->sk_state == LLCP_CONNECTED) | 89 | if (sk->sk_state == LLCP_CONNECTED) |
62 | nfc_put_device(llcp_sock->dev); | 90 | nfc_put_device(llcp_sock->dev); |
63 | 91 | ||
@@ -65,7 +93,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
65 | struct nfc_llcp_sock *lsk, *n; | 93 | struct nfc_llcp_sock *lsk, *n; |
66 | struct sock *accept_sk; | 94 | struct sock *accept_sk; |
67 | 95 | ||
68 | list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, | 96 | list_for_each_entry_safe(lsk, n, |
97 | &llcp_sock->accept_queue, | ||
69 | accept_queue) { | 98 | accept_queue) { |
70 | accept_sk = &lsk->sk; | 99 | accept_sk = &lsk->sk; |
71 | bh_lock_sock(accept_sk); | 100 | bh_lock_sock(accept_sk); |
@@ -85,6 +114,16 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
85 | } | 114 | } |
86 | } | 115 | } |
87 | 116 | ||
117 | /* | ||
118 | * If we have a connection less socket bound, we keep it alive | ||
119 | * if the device is still present. | ||
120 | */ | ||
121 | if (sk->sk_state == LLCP_BOUND && sk->sk_type == SOCK_DGRAM && | ||
122 | listen == true) { | ||
123 | bh_unlock_sock(sk); | ||
124 | continue; | ||
125 | } | ||
126 | |||
88 | sk->sk_state = LLCP_CLOSED; | 127 | sk->sk_state = LLCP_CLOSED; |
89 | 128 | ||
90 | bh_unlock_sock(sk); | 129 | bh_unlock_sock(sk); |
@@ -134,7 +173,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, | |||
134 | { | 173 | { |
135 | struct sock *sk; | 174 | struct sock *sk; |
136 | struct hlist_node *node; | 175 | struct hlist_node *node; |
137 | struct nfc_llcp_sock *llcp_sock; | 176 | struct nfc_llcp_sock *llcp_sock, *tmp_sock; |
138 | 177 | ||
139 | pr_debug("ssap dsap %d %d\n", ssap, dsap); | 178 | pr_debug("ssap dsap %d %d\n", ssap, dsap); |
140 | 179 | ||
@@ -146,10 +185,12 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, | |||
146 | llcp_sock = NULL; | 185 | llcp_sock = NULL; |
147 | 186 | ||
148 | sk_for_each(sk, node, &local->sockets.head) { | 187 | sk_for_each(sk, node, &local->sockets.head) { |
149 | llcp_sock = nfc_llcp_sock(sk); | 188 | tmp_sock = nfc_llcp_sock(sk); |
150 | 189 | ||
151 | if (llcp_sock->ssap == ssap && llcp_sock->dsap == dsap) | 190 | if (tmp_sock->ssap == ssap && tmp_sock->dsap == dsap) { |
191 | llcp_sock = tmp_sock; | ||
152 | break; | 192 | break; |
193 | } | ||
153 | } | 194 | } |
154 | 195 | ||
155 | read_unlock(&local->sockets.lock); | 196 | read_unlock(&local->sockets.lock); |
@@ -249,7 +290,12 @@ struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local, | |||
249 | 290 | ||
250 | pr_debug("llcp sock %p\n", tmp_sock); | 291 | pr_debug("llcp sock %p\n", tmp_sock); |
251 | 292 | ||
252 | if (tmp_sock->sk.sk_state != LLCP_LISTEN) | 293 | if (tmp_sock->sk.sk_type == SOCK_STREAM && |
294 | tmp_sock->sk.sk_state != LLCP_LISTEN) | ||
295 | continue; | ||
296 | |||
297 | if (tmp_sock->sk.sk_type == SOCK_DGRAM && | ||
298 | tmp_sock->sk.sk_state != LLCP_BOUND) | ||
253 | continue; | 299 | continue; |
254 | 300 | ||
255 | if (tmp_sock->service_name == NULL || | 301 | if (tmp_sock->service_name == NULL || |
@@ -421,10 +467,9 @@ static u8 nfc_llcp_reserve_sdp_ssap(struct nfc_llcp_local *local) | |||
421 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | 467 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) |
422 | { | 468 | { |
423 | u8 *gb_cur, *version_tlv, version, version_length; | 469 | u8 *gb_cur, *version_tlv, version, version_length; |
424 | u8 *lto_tlv, lto, lto_length; | 470 | u8 *lto_tlv, lto_length; |
425 | u8 *wks_tlv, wks_length; | 471 | u8 *wks_tlv, wks_length; |
426 | u8 *miux_tlv, miux_length; | 472 | u8 *miux_tlv, miux_length; |
427 | __be16 miux; | ||
428 | u8 gb_len = 0; | 473 | u8 gb_len = 0; |
429 | int ret = 0; | 474 | int ret = 0; |
430 | 475 | ||
@@ -433,9 +478,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
433 | 1, &version_length); | 478 | 1, &version_length); |
434 | gb_len += version_length; | 479 | gb_len += version_length; |
435 | 480 | ||
436 | /* 1500 ms */ | 481 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, <o_length); |
437 | lto = 150; | ||
438 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, <o, 1, <o_length); | ||
439 | gb_len += lto_length; | 482 | gb_len += lto_length; |
440 | 483 | ||
441 | pr_debug("Local wks 0x%lx\n", local->local_wks); | 484 | pr_debug("Local wks 0x%lx\n", local->local_wks); |
@@ -443,8 +486,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
443 | &wks_length); | 486 | &wks_length); |
444 | gb_len += wks_length; | 487 | gb_len += wks_length; |
445 | 488 | ||
446 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 489 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
447 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
448 | &miux_length); | 490 | &miux_length); |
449 | gb_len += miux_length; | 491 | gb_len += miux_length; |
450 | 492 | ||
@@ -610,7 +652,10 @@ static void nfc_llcp_tx_work(struct work_struct *work) | |||
610 | if (skb != NULL) { | 652 | if (skb != NULL) { |
611 | sk = skb->sk; | 653 | sk = skb->sk; |
612 | llcp_sock = nfc_llcp_sock(sk); | 654 | llcp_sock = nfc_llcp_sock(sk); |
613 | if (llcp_sock != NULL) { | 655 | |
656 | if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) { | ||
657 | nfc_llcp_send_symm(local->dev); | ||
658 | } else { | ||
614 | int ret; | 659 | int ret; |
615 | 660 | ||
616 | pr_debug("Sending pending skb\n"); | 661 | pr_debug("Sending pending skb\n"); |
@@ -629,8 +674,6 @@ static void nfc_llcp_tx_work(struct work_struct *work) | |||
629 | skb_queue_tail(&llcp_sock->tx_pending_queue, | 674 | skb_queue_tail(&llcp_sock->tx_pending_queue, |
630 | skb); | 675 | skb); |
631 | } | 676 | } |
632 | } else { | ||
633 | nfc_llcp_send_symm(local->dev); | ||
634 | } | 677 | } |
635 | } else { | 678 | } else { |
636 | nfc_llcp_send_symm(local->dev); | 679 | nfc_llcp_send_symm(local->dev); |
@@ -704,6 +747,39 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len) | |||
704 | return NULL; | 747 | return NULL; |
705 | } | 748 | } |
706 | 749 | ||
750 | static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, | ||
751 | struct sk_buff *skb) | ||
752 | { | ||
753 | struct nfc_llcp_sock *llcp_sock; | ||
754 | struct nfc_llcp_ui_cb *ui_cb; | ||
755 | u8 dsap, ssap; | ||
756 | |||
757 | dsap = nfc_llcp_dsap(skb); | ||
758 | ssap = nfc_llcp_ssap(skb); | ||
759 | |||
760 | ui_cb = nfc_llcp_ui_skb_cb(skb); | ||
761 | ui_cb->dsap = dsap; | ||
762 | ui_cb->ssap = ssap; | ||
763 | |||
764 | printk("%s %d %d\n", __func__, dsap, ssap); | ||
765 | |||
766 | pr_debug("%d %d\n", dsap, ssap); | ||
767 | |||
768 | /* We're looking for a bound socket, not a client one */ | ||
769 | llcp_sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP); | ||
770 | if (llcp_sock == NULL || llcp_sock->sk.sk_type != SOCK_DGRAM) | ||
771 | return; | ||
772 | |||
773 | /* There is no sequence with UI frames */ | ||
774 | skb_pull(skb, LLCP_HEADER_SIZE); | ||
775 | if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) { | ||
776 | pr_err("receive queue is full\n"); | ||
777 | skb_queue_head(&llcp_sock->tx_backlog_queue, skb); | ||
778 | } | ||
779 | |||
780 | nfc_llcp_sock_put(llcp_sock); | ||
781 | } | ||
782 | |||
707 | static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | 783 | static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, |
708 | struct sk_buff *skb) | 784 | struct sk_buff *skb) |
709 | { | 785 | { |
@@ -823,9 +899,6 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | |||
823 | fail: | 899 | fail: |
824 | /* Send DM */ | 900 | /* Send DM */ |
825 | nfc_llcp_send_dm(local, dsap, ssap, reason); | 901 | nfc_llcp_send_dm(local, dsap, ssap, reason); |
826 | |||
827 | return; | ||
828 | |||
829 | } | 902 | } |
830 | 903 | ||
831 | int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) | 904 | int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) |
@@ -953,6 +1026,9 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, | |||
953 | 1026 | ||
954 | sk = &llcp_sock->sk; | 1027 | sk = &llcp_sock->sk; |
955 | lock_sock(sk); | 1028 | lock_sock(sk); |
1029 | |||
1030 | nfc_llcp_socket_purge(llcp_sock); | ||
1031 | |||
956 | if (sk->sk_state == LLCP_CLOSED) { | 1032 | if (sk->sk_state == LLCP_CLOSED) { |
957 | release_sock(sk); | 1033 | release_sock(sk); |
958 | nfc_llcp_sock_put(llcp_sock); | 1034 | nfc_llcp_sock_put(llcp_sock); |
@@ -1027,7 +1103,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) | |||
1027 | } | 1103 | } |
1028 | 1104 | ||
1029 | if (llcp_sock == NULL) { | 1105 | if (llcp_sock == NULL) { |
1030 | pr_err("Invalid DM\n"); | 1106 | pr_debug("Already closed\n"); |
1031 | return; | 1107 | return; |
1032 | } | 1108 | } |
1033 | 1109 | ||
@@ -1038,8 +1114,100 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) | |||
1038 | sk->sk_state_change(sk); | 1114 | sk->sk_state_change(sk); |
1039 | 1115 | ||
1040 | nfc_llcp_sock_put(llcp_sock); | 1116 | nfc_llcp_sock_put(llcp_sock); |
1117 | } | ||
1041 | 1118 | ||
1042 | return; | 1119 | static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, |
1120 | struct sk_buff *skb) | ||
1121 | { | ||
1122 | struct nfc_llcp_sock *llcp_sock; | ||
1123 | u8 dsap, ssap, *tlv, type, length, tid, sap; | ||
1124 | u16 tlv_len, offset; | ||
1125 | char *service_name; | ||
1126 | size_t service_name_len; | ||
1127 | |||
1128 | dsap = nfc_llcp_dsap(skb); | ||
1129 | ssap = nfc_llcp_ssap(skb); | ||
1130 | |||
1131 | pr_debug("%d %d\n", dsap, ssap); | ||
1132 | |||
1133 | if (dsap != LLCP_SAP_SDP || ssap != LLCP_SAP_SDP) { | ||
1134 | pr_err("Wrong SNL SAP\n"); | ||
1135 | return; | ||
1136 | } | ||
1137 | |||
1138 | tlv = &skb->data[LLCP_HEADER_SIZE]; | ||
1139 | tlv_len = skb->len - LLCP_HEADER_SIZE; | ||
1140 | offset = 0; | ||
1141 | |||
1142 | while (offset < tlv_len) { | ||
1143 | type = tlv[0]; | ||
1144 | length = tlv[1]; | ||
1145 | |||
1146 | switch (type) { | ||
1147 | case LLCP_TLV_SDREQ: | ||
1148 | tid = tlv[2]; | ||
1149 | service_name = (char *) &tlv[3]; | ||
1150 | service_name_len = length - 1; | ||
1151 | |||
1152 | pr_debug("Looking for %.16s\n", service_name); | ||
1153 | |||
1154 | if (service_name_len == strlen("urn:nfc:sn:sdp") && | ||
1155 | !strncmp(service_name, "urn:nfc:sn:sdp", | ||
1156 | service_name_len)) { | ||
1157 | sap = 1; | ||
1158 | goto send_snl; | ||
1159 | } | ||
1160 | |||
1161 | llcp_sock = nfc_llcp_sock_from_sn(local, service_name, | ||
1162 | service_name_len); | ||
1163 | if (!llcp_sock) { | ||
1164 | sap = 0; | ||
1165 | goto send_snl; | ||
1166 | } | ||
1167 | |||
1168 | /* | ||
1169 | * We found a socket but its ssap has not been reserved | ||
1170 | * yet. We need to assign it for good and send a reply. | ||
1171 | * The ssap will be freed when the socket is closed. | ||
1172 | */ | ||
1173 | if (llcp_sock->ssap == LLCP_SDP_UNBOUND) { | ||
1174 | atomic_t *client_count; | ||
1175 | |||
1176 | sap = nfc_llcp_reserve_sdp_ssap(local); | ||
1177 | |||
1178 | pr_debug("Reserving %d\n", sap); | ||
1179 | |||
1180 | if (sap == LLCP_SAP_MAX) { | ||
1181 | sap = 0; | ||
1182 | goto send_snl; | ||
1183 | } | ||
1184 | |||
1185 | client_count = | ||
1186 | &local->local_sdp_cnt[sap - | ||
1187 | LLCP_WKS_NUM_SAP]; | ||
1188 | |||
1189 | atomic_inc(client_count); | ||
1190 | |||
1191 | llcp_sock->ssap = sap; | ||
1192 | llcp_sock->reserved_ssap = sap; | ||
1193 | } else { | ||
1194 | sap = llcp_sock->ssap; | ||
1195 | } | ||
1196 | |||
1197 | pr_debug("%p %d\n", llcp_sock, sap); | ||
1198 | |||
1199 | send_snl: | ||
1200 | nfc_llcp_send_snl(local, tid, sap); | ||
1201 | break; | ||
1202 | |||
1203 | default: | ||
1204 | pr_err("Invalid SNL tlv value 0x%x\n", type); | ||
1205 | break; | ||
1206 | } | ||
1207 | |||
1208 | offset += length + 2; | ||
1209 | tlv += length + 2; | ||
1210 | } | ||
1043 | } | 1211 | } |
1044 | 1212 | ||
1045 | static void nfc_llcp_rx_work(struct work_struct *work) | 1213 | static void nfc_llcp_rx_work(struct work_struct *work) |
@@ -1072,6 +1240,11 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
1072 | pr_debug("SYMM\n"); | 1240 | pr_debug("SYMM\n"); |
1073 | break; | 1241 | break; |
1074 | 1242 | ||
1243 | case LLCP_PDU_UI: | ||
1244 | pr_debug("UI\n"); | ||
1245 | nfc_llcp_recv_ui(local, skb); | ||
1246 | break; | ||
1247 | |||
1075 | case LLCP_PDU_CONNECT: | 1248 | case LLCP_PDU_CONNECT: |
1076 | pr_debug("CONNECT\n"); | 1249 | pr_debug("CONNECT\n"); |
1077 | nfc_llcp_recv_connect(local, skb); | 1250 | nfc_llcp_recv_connect(local, skb); |
@@ -1092,6 +1265,11 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
1092 | nfc_llcp_recv_dm(local, skb); | 1265 | nfc_llcp_recv_dm(local, skb); |
1093 | break; | 1266 | break; |
1094 | 1267 | ||
1268 | case LLCP_PDU_SNL: | ||
1269 | pr_debug("SNL\n"); | ||
1270 | nfc_llcp_recv_snl(local, skb); | ||
1271 | break; | ||
1272 | |||
1095 | case LLCP_PDU_I: | 1273 | case LLCP_PDU_I: |
1096 | case LLCP_PDU_RR: | 1274 | case LLCP_PDU_RR: |
1097 | case LLCP_PDU_RNR: | 1275 | case LLCP_PDU_RNR: |
@@ -1104,8 +1282,6 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
1104 | schedule_work(&local->tx_work); | 1282 | schedule_work(&local->tx_work); |
1105 | kfree_skb(local->rx_pending); | 1283 | kfree_skb(local->rx_pending); |
1106 | local->rx_pending = NULL; | 1284 | local->rx_pending = NULL; |
1107 | |||
1108 | return; | ||
1109 | } | 1285 | } |
1110 | 1286 | ||
1111 | void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) | 1287 | void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) |
@@ -1121,8 +1297,6 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) | |||
1121 | local->rx_pending = skb_get(skb); | 1297 | local->rx_pending = skb_get(skb); |
1122 | del_timer(&local->link_timer); | 1298 | del_timer(&local->link_timer); |
1123 | schedule_work(&local->rx_work); | 1299 | schedule_work(&local->rx_work); |
1124 | |||
1125 | return; | ||
1126 | } | 1300 | } |
1127 | 1301 | ||
1128 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb) | 1302 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb) |
@@ -1205,6 +1379,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
1205 | rwlock_init(&local->connecting_sockets.lock); | 1379 | rwlock_init(&local->connecting_sockets.lock); |
1206 | rwlock_init(&local->raw_sockets.lock); | 1380 | rwlock_init(&local->raw_sockets.lock); |
1207 | 1381 | ||
1382 | local->lto = 150; /* 1500 ms */ | ||
1383 | local->rw = LLCP_MAX_RW; | ||
1384 | local->miux = cpu_to_be16(LLCP_MAX_MIUX); | ||
1385 | |||
1208 | nfc_llcp_build_gb(local); | 1386 | nfc_llcp_build_gb(local); |
1209 | 1387 | ||
1210 | local->remote_miu = LLCP_DEFAULT_MIU; | 1388 | local->remote_miu = LLCP_DEFAULT_MIU; |
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index fdb2d24e60bd..0d62366f8cc3 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h | |||
@@ -64,6 +64,9 @@ struct nfc_llcp_local { | |||
64 | u32 target_idx; | 64 | u32 target_idx; |
65 | u8 rf_mode; | 65 | u8 rf_mode; |
66 | u8 comm_mode; | 66 | u8 comm_mode; |
67 | u8 lto; | ||
68 | u8 rw; | ||
69 | __be16 miux; | ||
67 | unsigned long local_wks; /* Well known services */ | 70 | unsigned long local_wks; /* Well known services */ |
68 | unsigned long local_sdp; /* Local services */ | 71 | unsigned long local_sdp; /* Local services */ |
69 | unsigned long local_sap; /* Local SAPs, not available for discovery */ | 72 | unsigned long local_sap; /* Local SAPs, not available for discovery */ |
@@ -124,6 +127,13 @@ struct nfc_llcp_sock { | |||
124 | struct sock *parent; | 127 | struct sock *parent; |
125 | }; | 128 | }; |
126 | 129 | ||
130 | struct nfc_llcp_ui_cb { | ||
131 | __u8 dsap; | ||
132 | __u8 ssap; | ||
133 | }; | ||
134 | |||
135 | #define nfc_llcp_ui_skb_cb(__skb) ((struct nfc_llcp_ui_cb *)&((__skb)->cb[0])) | ||
136 | |||
127 | #define nfc_llcp_sock(sk) ((struct nfc_llcp_sock *) (sk)) | 137 | #define nfc_llcp_sock(sk) ((struct nfc_llcp_sock *) (sk)) |
128 | #define nfc_llcp_dev(sk) (nfc_llcp_sock((sk))->dev) | 138 | #define nfc_llcp_dev(sk) (nfc_llcp_sock((sk))->dev) |
129 | 139 | ||
@@ -209,10 +219,13 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock); | |||
209 | int nfc_llcp_send_symm(struct nfc_dev *dev); | 219 | int nfc_llcp_send_symm(struct nfc_dev *dev); |
210 | int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); | 220 | int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); |
211 | int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); | 221 | int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); |
222 | int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap); | ||
212 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); | 223 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); |
213 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); | 224 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
214 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | 225 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, |
215 | struct msghdr *msg, size_t len); | 226 | struct msghdr *msg, size_t len); |
227 | int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | ||
228 | struct msghdr *msg, size_t len); | ||
216 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); | 229 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); |
217 | 230 | ||
218 | /* Socket API */ | 231 | /* Socket API */ |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 63e4cdc92376..0fa1e92ceac8 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -205,8 +205,8 @@ static int llcp_sock_listen(struct socket *sock, int backlog) | |||
205 | 205 | ||
206 | lock_sock(sk); | 206 | lock_sock(sk); |
207 | 207 | ||
208 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | 208 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) || |
209 | || sk->sk_state != LLCP_BOUND) { | 209 | sk->sk_state != LLCP_BOUND) { |
210 | ret = -EBADFD; | 210 | ret = -EBADFD; |
211 | goto error; | 211 | goto error; |
212 | } | 212 | } |
@@ -608,6 +608,25 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
608 | 608 | ||
609 | lock_sock(sk); | 609 | lock_sock(sk); |
610 | 610 | ||
611 | if (sk->sk_type == SOCK_DGRAM) { | ||
612 | struct sockaddr_nfc_llcp *addr = | ||
613 | (struct sockaddr_nfc_llcp *)msg->msg_name; | ||
614 | |||
615 | if (msg->msg_namelen < sizeof(*addr)) { | ||
616 | release_sock(sk); | ||
617 | |||
618 | pr_err("Invalid socket address length %d\n", | ||
619 | msg->msg_namelen); | ||
620 | |||
621 | return -EINVAL; | ||
622 | } | ||
623 | |||
624 | release_sock(sk); | ||
625 | |||
626 | return nfc_llcp_send_ui_frame(llcp_sock, addr->dsap, addr->ssap, | ||
627 | msg, len); | ||
628 | } | ||
629 | |||
611 | if (sk->sk_state != LLCP_CONNECTED) { | 630 | if (sk->sk_state != LLCP_CONNECTED) { |
612 | release_sock(sk); | 631 | release_sock(sk); |
613 | return -ENOTCONN; | 632 | return -ENOTCONN; |
@@ -663,11 +682,28 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
663 | return -EFAULT; | 682 | return -EFAULT; |
664 | } | 683 | } |
665 | 684 | ||
685 | if (sk->sk_type == SOCK_DGRAM && msg->msg_name) { | ||
686 | struct nfc_llcp_ui_cb *ui_cb = nfc_llcp_ui_skb_cb(skb); | ||
687 | struct sockaddr_nfc_llcp sockaddr; | ||
688 | |||
689 | pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap); | ||
690 | |||
691 | sockaddr.sa_family = AF_NFC; | ||
692 | sockaddr.nfc_protocol = NFC_PROTO_NFC_DEP; | ||
693 | sockaddr.dsap = ui_cb->dsap; | ||
694 | sockaddr.ssap = ui_cb->ssap; | ||
695 | |||
696 | memcpy(msg->msg_name, &sockaddr, sizeof(sockaddr)); | ||
697 | msg->msg_namelen = sizeof(sockaddr); | ||
698 | } | ||
699 | |||
666 | /* Mark read part of skb as used */ | 700 | /* Mark read part of skb as used */ |
667 | if (!(flags & MSG_PEEK)) { | 701 | if (!(flags & MSG_PEEK)) { |
668 | 702 | ||
669 | /* SOCK_STREAM: re-queue skb if it contains unreceived data */ | 703 | /* SOCK_STREAM: re-queue skb if it contains unreceived data */ |
670 | if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_RAW) { | 704 | if (sk->sk_type == SOCK_STREAM || |
705 | sk->sk_type == SOCK_DGRAM || | ||
706 | sk->sk_type == SOCK_RAW) { | ||
671 | skb_pull(skb, copied); | 707 | skb_pull(skb, copied); |
672 | if (skb->len) { | 708 | if (skb->len) { |
673 | skb_queue_head(&sk->sk_receive_queue, skb); | 709 | skb_queue_head(&sk->sk_receive_queue, skb); |
diff --git a/net/nfc/nci/Kconfig b/net/nfc/nci/Kconfig index decdc49b26d8..6d69b5f0f19b 100644 --- a/net/nfc/nci/Kconfig +++ b/net/nfc/nci/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config NFC_NCI | 1 | config NFC_NCI |
2 | depends on NFC && EXPERIMENTAL | 2 | depends on NFC |
3 | tristate "NCI protocol support (EXPERIMENTAL)" | 3 | tristate "NCI protocol support" |
4 | default n | 4 | default n |
5 | help | 5 | help |
6 | NCI (NFC Controller Interface) is a communication protocol between | 6 | NCI (NFC Controller Interface) is a communication protocol between |
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index acf9abb7d99b..5f98dc1bf039 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -205,10 +205,10 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) | |||
205 | cmd.num_disc_configs = 0; | 205 | cmd.num_disc_configs = 0; |
206 | 206 | ||
207 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && | 207 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && |
208 | (protocols & NFC_PROTO_JEWEL_MASK | 208 | (protocols & NFC_PROTO_JEWEL_MASK || |
209 | || protocols & NFC_PROTO_MIFARE_MASK | 209 | protocols & NFC_PROTO_MIFARE_MASK || |
210 | || protocols & NFC_PROTO_ISO14443_MASK | 210 | protocols & NFC_PROTO_ISO14443_MASK || |
211 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { | 211 | protocols & NFC_PROTO_NFC_DEP_MASK)) { |
212 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = | 212 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = |
213 | NCI_NFC_A_PASSIVE_POLL_MODE; | 213 | NCI_NFC_A_PASSIVE_POLL_MODE; |
214 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; | 214 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; |
@@ -224,8 +224,8 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && | 226 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && |
227 | (protocols & NFC_PROTO_FELICA_MASK | 227 | (protocols & NFC_PROTO_FELICA_MASK || |
228 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { | 228 | protocols & NFC_PROTO_NFC_DEP_MASK)) { |
229 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = | 229 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = |
230 | NCI_NFC_F_PASSIVE_POLL_MODE; | 230 | NCI_NFC_F_PASSIVE_POLL_MODE; |
231 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; | 231 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; |
@@ -414,13 +414,13 @@ static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev) | |||
414 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 414 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
415 | struct nci_set_config_param param; | 415 | struct nci_set_config_param param; |
416 | __u8 local_gb[NFC_MAX_GT_LEN]; | 416 | __u8 local_gb[NFC_MAX_GT_LEN]; |
417 | int i, rc = 0; | 417 | int i; |
418 | 418 | ||
419 | param.val = nfc_get_local_general_bytes(nfc_dev, ¶m.len); | 419 | param.val = nfc_get_local_general_bytes(nfc_dev, ¶m.len); |
420 | if ((param.val == NULL) || (param.len == 0)) | 420 | if ((param.val == NULL) || (param.len == 0)) |
421 | return rc; | 421 | return 0; |
422 | 422 | ||
423 | if (param.len > NCI_MAX_PARAM_LEN) | 423 | if (param.len > NFC_MAX_GT_LEN) |
424 | return -EINVAL; | 424 | return -EINVAL; |
425 | 425 | ||
426 | for (i = 0; i < param.len; i++) | 426 | for (i = 0; i < param.len; i++) |
@@ -429,10 +429,8 @@ static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev) | |||
429 | param.id = NCI_PN_ATR_REQ_GEN_BYTES; | 429 | param.id = NCI_PN_ATR_REQ_GEN_BYTES; |
430 | param.val = local_gb; | 430 | param.val = local_gb; |
431 | 431 | ||
432 | rc = nci_request(ndev, nci_set_config_req, (unsigned long)¶m, | 432 | return nci_request(ndev, nci_set_config_req, (unsigned long)¶m, |
433 | msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT)); | 433 | msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT)); |
434 | |||
435 | return rc; | ||
436 | } | 434 | } |
437 | 435 | ||
438 | static int nci_start_poll(struct nfc_dev *nfc_dev, | 436 | static int nci_start_poll(struct nfc_dev *nfc_dev, |
@@ -579,7 +577,6 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, | |||
579 | } | 577 | } |
580 | } | 578 | } |
581 | 579 | ||
582 | |||
583 | static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, | 580 | static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, |
584 | __u8 comm_mode, __u8 *gb, size_t gb_len) | 581 | __u8 comm_mode, __u8 *gb, size_t gb_len) |
585 | { | 582 | { |
@@ -806,8 +803,8 @@ int nci_recv_frame(struct sk_buff *skb) | |||
806 | 803 | ||
807 | pr_debug("len %d\n", skb->len); | 804 | pr_debug("len %d\n", skb->len); |
808 | 805 | ||
809 | if (!ndev || (!test_bit(NCI_UP, &ndev->flags) | 806 | if (!ndev || (!test_bit(NCI_UP, &ndev->flags) && |
810 | && !test_bit(NCI_INIT, &ndev->flags))) { | 807 | !test_bit(NCI_INIT, &ndev->flags))) { |
811 | kfree_skb(skb); | 808 | kfree_skb(skb); |
812 | return -ENXIO; | 809 | return -ENXIO; |
813 | } | 810 | } |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index c1b5285cbde7..3568ae16786d 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -29,6 +29,8 @@ | |||
29 | 29 | ||
30 | #include "nfc.h" | 30 | #include "nfc.h" |
31 | 31 | ||
32 | #include "llcp/llcp.h" | ||
33 | |||
32 | static struct genl_multicast_group nfc_genl_event_mcgrp = { | 34 | static struct genl_multicast_group nfc_genl_event_mcgrp = { |
33 | .name = NFC_GENL_MCAST_EVENT_NAME, | 35 | .name = NFC_GENL_MCAST_EVENT_NAME, |
34 | }; | 36 | }; |
@@ -364,7 +366,8 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, | |||
364 | if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || | 366 | if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || |
365 | nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || | 367 | nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || |
366 | nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || | 368 | nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || |
367 | nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up)) | 369 | nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) || |
370 | nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode)) | ||
368 | goto nla_put_failure; | 371 | goto nla_put_failure; |
369 | 372 | ||
370 | return genlmsg_end(msg, hdr); | 373 | return genlmsg_end(msg, hdr); |
@@ -590,7 +593,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) | |||
590 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || | 593 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || |
591 | ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] && | 594 | ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] && |
592 | !info->attrs[NFC_ATTR_PROTOCOLS]) && | 595 | !info->attrs[NFC_ATTR_PROTOCOLS]) && |
593 | !info->attrs[NFC_ATTR_TM_PROTOCOLS])) | 596 | !info->attrs[NFC_ATTR_TM_PROTOCOLS])) |
594 | return -EINVAL; | 597 | return -EINVAL; |
595 | 598 | ||
596 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | 599 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); |
@@ -715,6 +718,146 @@ static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info) | |||
715 | return rc; | 718 | return rc; |
716 | } | 719 | } |
717 | 720 | ||
721 | static int nfc_genl_send_params(struct sk_buff *msg, | ||
722 | struct nfc_llcp_local *local, | ||
723 | u32 portid, u32 seq) | ||
724 | { | ||
725 | void *hdr; | ||
726 | |||
727 | hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0, | ||
728 | NFC_CMD_LLC_GET_PARAMS); | ||
729 | if (!hdr) | ||
730 | return -EMSGSIZE; | ||
731 | |||
732 | if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) || | ||
733 | nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) || | ||
734 | nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) || | ||
735 | nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux))) | ||
736 | goto nla_put_failure; | ||
737 | |||
738 | return genlmsg_end(msg, hdr); | ||
739 | |||
740 | nla_put_failure: | ||
741 | |||
742 | genlmsg_cancel(msg, hdr); | ||
743 | return -EMSGSIZE; | ||
744 | } | ||
745 | |||
746 | static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info) | ||
747 | { | ||
748 | struct nfc_dev *dev; | ||
749 | struct nfc_llcp_local *local; | ||
750 | int rc = 0; | ||
751 | struct sk_buff *msg = NULL; | ||
752 | u32 idx; | ||
753 | |||
754 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) | ||
755 | return -EINVAL; | ||
756 | |||
757 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | ||
758 | |||
759 | dev = nfc_get_device(idx); | ||
760 | if (!dev) | ||
761 | return -ENODEV; | ||
762 | |||
763 | device_lock(&dev->dev); | ||
764 | |||
765 | local = nfc_llcp_find_local(dev); | ||
766 | if (!local) { | ||
767 | rc = -ENODEV; | ||
768 | goto exit; | ||
769 | } | ||
770 | |||
771 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
772 | if (!msg) { | ||
773 | rc = -ENOMEM; | ||
774 | goto exit; | ||
775 | } | ||
776 | |||
777 | rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq); | ||
778 | |||
779 | exit: | ||
780 | device_unlock(&dev->dev); | ||
781 | |||
782 | nfc_put_device(dev); | ||
783 | |||
784 | if (rc < 0) { | ||
785 | if (msg) | ||
786 | nlmsg_free(msg); | ||
787 | |||
788 | return rc; | ||
789 | } | ||
790 | |||
791 | return genlmsg_reply(msg, info); | ||
792 | } | ||
793 | |||
794 | static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) | ||
795 | { | ||
796 | struct nfc_dev *dev; | ||
797 | struct nfc_llcp_local *local; | ||
798 | u8 rw = 0; | ||
799 | u16 miux = 0; | ||
800 | u32 idx; | ||
801 | int rc = 0; | ||
802 | |||
803 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || | ||
804 | (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] && | ||
805 | !info->attrs[NFC_ATTR_LLC_PARAM_RW] && | ||
806 | !info->attrs[NFC_ATTR_LLC_PARAM_MIUX])) | ||
807 | return -EINVAL; | ||
808 | |||
809 | if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) { | ||
810 | rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]); | ||
811 | |||
812 | if (rw > LLCP_MAX_RW) | ||
813 | return -EINVAL; | ||
814 | } | ||
815 | |||
816 | if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) { | ||
817 | miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]); | ||
818 | |||
819 | if (miux > LLCP_MAX_MIUX) | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | ||
824 | |||
825 | dev = nfc_get_device(idx); | ||
826 | if (!dev) | ||
827 | return -ENODEV; | ||
828 | |||
829 | device_lock(&dev->dev); | ||
830 | |||
831 | local = nfc_llcp_find_local(dev); | ||
832 | if (!local) { | ||
833 | nfc_put_device(dev); | ||
834 | rc = -ENODEV; | ||
835 | goto exit; | ||
836 | } | ||
837 | |||
838 | if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) { | ||
839 | if (dev->dep_link_up) { | ||
840 | rc = -EINPROGRESS; | ||
841 | goto exit; | ||
842 | } | ||
843 | |||
844 | local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]); | ||
845 | } | ||
846 | |||
847 | if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) | ||
848 | local->rw = rw; | ||
849 | |||
850 | if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) | ||
851 | local->miux = cpu_to_be16(miux); | ||
852 | |||
853 | exit: | ||
854 | device_unlock(&dev->dev); | ||
855 | |||
856 | nfc_put_device(dev); | ||
857 | |||
858 | return rc; | ||
859 | } | ||
860 | |||
718 | static struct genl_ops nfc_genl_ops[] = { | 861 | static struct genl_ops nfc_genl_ops[] = { |
719 | { | 862 | { |
720 | .cmd = NFC_CMD_GET_DEVICE, | 863 | .cmd = NFC_CMD_GET_DEVICE, |
@@ -759,6 +902,16 @@ static struct genl_ops nfc_genl_ops[] = { | |||
759 | .done = nfc_genl_dump_targets_done, | 902 | .done = nfc_genl_dump_targets_done, |
760 | .policy = nfc_genl_policy, | 903 | .policy = nfc_genl_policy, |
761 | }, | 904 | }, |
905 | { | ||
906 | .cmd = NFC_CMD_LLC_GET_PARAMS, | ||
907 | .doit = nfc_genl_llc_get_params, | ||
908 | .policy = nfc_genl_policy, | ||
909 | }, | ||
910 | { | ||
911 | .cmd = NFC_CMD_LLC_SET_PARAMS, | ||
912 | .doit = nfc_genl_llc_set_params, | ||
913 | .policy = nfc_genl_policy, | ||
914 | }, | ||
762 | }; | 915 | }; |
763 | 916 | ||
764 | 917 | ||
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index c5e42b79a418..87d914d2876a 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -56,6 +56,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev); | |||
56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); | 56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); |
57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); | 57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); |
58 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); | 58 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); |
59 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); | ||
59 | int __init nfc_llcp_init(void); | 60 | int __init nfc_llcp_init(void); |
60 | void nfc_llcp_exit(void); | 61 | void nfc_llcp_exit(void); |
61 | 62 | ||
@@ -97,6 +98,11 @@ static inline int nfc_llcp_data_received(struct nfc_dev *dev, | |||
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
99 | 100 | ||
101 | static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) | ||
102 | { | ||
103 | return NULL; | ||
104 | } | ||
105 | |||
100 | static inline int nfc_llcp_init(void) | 106 | static inline int nfc_llcp_init(void) |
101 | { | 107 | { |
102 | return 0; | 108 | return 0; |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 8b8a6a2b2bad..313bf1bc848a 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
@@ -256,7 +256,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
256 | return rc ? : copied; | 256 | return rc ? : copied; |
257 | } | 257 | } |
258 | 258 | ||
259 | |||
260 | static const struct proto_ops rawsock_ops = { | 259 | static const struct proto_ops rawsock_ops = { |
261 | .family = PF_NFC, | 260 | .family = PF_NFC, |
262 | .owner = THIS_MODULE, | 261 | .owner = THIS_MODULE, |
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 0f7e0d621ab0..a761670af31d 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -10,11 +10,13 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o | |||
10 | obj-$(CONFIG_WEXT_PRIV) += wext-priv.o | 10 | obj-$(CONFIG_WEXT_PRIV) += wext-priv.o |
11 | 11 | ||
12 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o | 12 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o |
13 | cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o | 13 | cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o |
14 | cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o | 14 | cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o |
15 | cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o | 15 | cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o |
16 | cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o | 16 | cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o |
17 | 17 | ||
18 | CFLAGS_trace.o := -I$(src) | ||
19 | |||
18 | ccflags-y += -D__CHECK_ENDIAN__ | 20 | ccflags-y += -D__CHECK_ENDIAN__ |
19 | 21 | ||
20 | $(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk | 22 | $(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk |
diff --git a/net/wireless/ap.c b/net/wireless/ap.c index fcc60d8dbefa..e143505f05bc 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <net/cfg80211.h> | 3 | #include <net/cfg80211.h> |
4 | #include "nl80211.h" | 4 | #include "nl80211.h" |
5 | #include "core.h" | 5 | #include "core.h" |
6 | #include "rdev-ops.h" | ||
6 | 7 | ||
7 | 8 | ||
8 | static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 9 | static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
@@ -23,7 +24,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | |||
23 | if (!wdev->beacon_interval) | 24 | if (!wdev->beacon_interval) |
24 | return -ENOENT; | 25 | return -ENOENT; |
25 | 26 | ||
26 | err = rdev->ops->stop_ap(&rdev->wiphy, dev); | 27 | err = rdev_stop_ap(rdev, dev); |
27 | if (!err) { | 28 | if (!err) { |
28 | wdev->beacon_interval = 0; | 29 | wdev->beacon_interval = 0; |
29 | wdev->channel = NULL; | 30 | wdev->channel = NULL; |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 2f876b9ee344..48febd2160ba 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <net/cfg80211.h> | 10 | #include <net/cfg80211.h> |
11 | #include "core.h" | 11 | #include "core.h" |
12 | #include "rdev-ops.h" | ||
12 | 13 | ||
13 | struct ieee80211_channel * | 14 | struct ieee80211_channel * |
14 | rdev_freq_to_chan(struct cfg80211_registered_device *rdev, | 15 | rdev_freq_to_chan(struct cfg80211_registered_device *rdev, |
@@ -52,6 +53,8 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | |||
52 | struct ieee80211_channel *sec_chan; | 53 | struct ieee80211_channel *sec_chan; |
53 | int diff; | 54 | int diff; |
54 | 55 | ||
56 | trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type); | ||
57 | |||
55 | switch (channel_type) { | 58 | switch (channel_type) { |
56 | case NL80211_CHAN_HT40PLUS: | 59 | case NL80211_CHAN_HT40PLUS: |
57 | diff = 20; | 60 | diff = 20; |
@@ -60,20 +63,25 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | |||
60 | diff = -20; | 63 | diff = -20; |
61 | break; | 64 | break; |
62 | default: | 65 | default: |
66 | trace_cfg80211_return_bool(true); | ||
63 | return true; | 67 | return true; |
64 | } | 68 | } |
65 | 69 | ||
66 | sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); | 70 | sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); |
67 | if (!sec_chan) | 71 | if (!sec_chan) { |
72 | trace_cfg80211_return_bool(false); | ||
68 | return false; | 73 | return false; |
74 | } | ||
69 | 75 | ||
70 | /* we'll need a DFS capability later */ | 76 | /* we'll need a DFS capability later */ |
71 | if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | | 77 | if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | |
72 | IEEE80211_CHAN_PASSIVE_SCAN | | 78 | IEEE80211_CHAN_PASSIVE_SCAN | |
73 | IEEE80211_CHAN_NO_IBSS | | 79 | IEEE80211_CHAN_NO_IBSS | |
74 | IEEE80211_CHAN_RADAR)) | 80 | IEEE80211_CHAN_RADAR)) { |
81 | trace_cfg80211_return_bool(false); | ||
75 | return false; | 82 | return false; |
76 | 83 | } | |
84 | trace_cfg80211_return_bool(true); | ||
77 | return true; | 85 | return true; |
78 | } | 86 | } |
79 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); | 87 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); |
@@ -92,7 +100,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, | |||
92 | if (!chan) | 100 | if (!chan) |
93 | return -EINVAL; | 101 | return -EINVAL; |
94 | 102 | ||
95 | return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); | 103 | return rdev_set_monitor_channel(rdev, chan, chantype); |
96 | } | 104 | } |
97 | 105 | ||
98 | void | 106 | void |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 3f7253052088..26711f46a3be 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "debugfs.h" | 26 | #include "debugfs.h" |
27 | #include "wext-compat.h" | 27 | #include "wext-compat.h" |
28 | #include "ethtool.h" | 28 | #include "ethtool.h" |
29 | #include "rdev-ops.h" | ||
29 | 30 | ||
30 | /* name for sysfs, %d is appended */ | 31 | /* name for sysfs, %d is appended */ |
31 | #define PHY_NAME "phy" | 32 | #define PHY_NAME "phy" |
@@ -216,7 +217,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) | |||
216 | { | 217 | { |
217 | struct cfg80211_registered_device *rdev = data; | 218 | struct cfg80211_registered_device *rdev = data; |
218 | 219 | ||
219 | rdev->ops->rfkill_poll(&rdev->wiphy); | 220 | rdev_rfkill_poll(rdev); |
220 | } | 221 | } |
221 | 222 | ||
222 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 223 | static int cfg80211_rfkill_set_block(void *data, bool blocked) |
@@ -240,7 +241,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
240 | case NL80211_IFTYPE_P2P_DEVICE: | 241 | case NL80211_IFTYPE_P2P_DEVICE: |
241 | if (!wdev->p2p_started) | 242 | if (!wdev->p2p_started) |
242 | break; | 243 | break; |
243 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | 244 | rdev_stop_p2p_device(rdev, wdev); |
244 | wdev->p2p_started = false; | 245 | wdev->p2p_started = false; |
245 | rdev->opencount--; | 246 | rdev->opencount--; |
246 | break; | 247 | break; |
@@ -370,6 +371,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
370 | rdev->wiphy.rts_threshold = (u32) -1; | 371 | rdev->wiphy.rts_threshold = (u32) -1; |
371 | rdev->wiphy.coverage_class = 0; | 372 | rdev->wiphy.coverage_class = 0; |
372 | 373 | ||
374 | rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; | ||
375 | |||
373 | return &rdev->wiphy; | 376 | return &rdev->wiphy; |
374 | } | 377 | } |
375 | EXPORT_SYMBOL(wiphy_new); | 378 | EXPORT_SYMBOL(wiphy_new); |
@@ -687,7 +690,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
687 | flush_work(&rdev->event_work); | 690 | flush_work(&rdev->event_work); |
688 | 691 | ||
689 | if (rdev->wowlan && rdev->ops->set_wakeup) | 692 | if (rdev->wowlan && rdev->ops->set_wakeup) |
690 | rdev->ops->set_wakeup(&rdev->wiphy, false); | 693 | rdev_set_wakeup(rdev, false); |
691 | cfg80211_rdev_free_wowlan(rdev); | 694 | cfg80211_rdev_free_wowlan(rdev); |
692 | } | 695 | } |
693 | EXPORT_SYMBOL(wiphy_unregister); | 696 | EXPORT_SYMBOL(wiphy_unregister); |
@@ -770,7 +773,7 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev) | |||
770 | case NL80211_IFTYPE_P2P_DEVICE: | 773 | case NL80211_IFTYPE_P2P_DEVICE: |
771 | if (!wdev->p2p_started) | 774 | if (!wdev->p2p_started) |
772 | break; | 775 | break; |
773 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | 776 | rdev_stop_p2p_device(rdev, wdev); |
774 | wdev->p2p_started = false; | 777 | wdev->p2p_started = false; |
775 | rdev->opencount--; | 778 | rdev->opencount--; |
776 | break; | 779 | break; |
@@ -961,9 +964,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
961 | if ((wdev->iftype == NL80211_IFTYPE_STATION || | 964 | if ((wdev->iftype == NL80211_IFTYPE_STATION || |
962 | wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && | 965 | wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && |
963 | rdev->ops->set_power_mgmt) | 966 | rdev->ops->set_power_mgmt) |
964 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, | 967 | if (rdev_set_power_mgmt(rdev, dev, wdev->ps, |
965 | wdev->ps, | 968 | wdev->ps_timeout)) { |
966 | wdev->ps_timeout)) { | ||
967 | /* assume this means it's off */ | 969 | /* assume this means it's off */ |
968 | wdev->ps = false; | 970 | wdev->ps = false; |
969 | } | 971 | } |
diff --git a/net/wireless/core.h b/net/wireless/core.h index a343be4a52bd..b8eb743fe7da 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -320,13 +320,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
320 | const u8 *bssid, | 320 | const u8 *bssid, |
321 | const u8 *ssid, int ssid_len, | 321 | const u8 *ssid, int ssid_len, |
322 | const u8 *ie, int ie_len, | 322 | const u8 *ie, int ie_len, |
323 | const u8 *key, int key_len, int key_idx); | 323 | const u8 *key, int key_len, int key_idx, |
324 | const u8 *sae_data, int sae_data_len); | ||
324 | int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | 325 | int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, |
325 | struct net_device *dev, struct ieee80211_channel *chan, | 326 | struct net_device *dev, struct ieee80211_channel *chan, |
326 | enum nl80211_auth_type auth_type, const u8 *bssid, | 327 | enum nl80211_auth_type auth_type, const u8 *bssid, |
327 | const u8 *ssid, int ssid_len, | 328 | const u8 *ssid, int ssid_len, |
328 | const u8 *ie, int ie_len, | 329 | const u8 *ie, int ie_len, |
329 | const u8 *key, int key_len, int key_idx); | 330 | const u8 *key, int key_len, int key_idx, |
331 | const u8 *sae_data, int sae_data_len); | ||
330 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 332 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
331 | struct net_device *dev, | 333 | struct net_device *dev, |
332 | struct ieee80211_channel *chan, | 334 | struct ieee80211_channel *chan, |
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c index 7eecdf40cf80..48c48ffafa1d 100644 --- a/net/wireless/ethtool.c +++ b/net/wireless/ethtool.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <net/cfg80211.h> | 2 | #include <net/cfg80211.h> |
3 | #include "core.h" | 3 | #include "core.h" |
4 | #include "ethtool.h" | 4 | #include "ethtool.h" |
5 | #include "rdev-ops.h" | ||
5 | 6 | ||
6 | static void cfg80211_get_drvinfo(struct net_device *dev, | 7 | static void cfg80211_get_drvinfo(struct net_device *dev, |
7 | struct ethtool_drvinfo *info) | 8 | struct ethtool_drvinfo *info) |
@@ -47,9 +48,8 @@ static void cfg80211_get_ringparam(struct net_device *dev, | |||
47 | memset(rp, 0, sizeof(*rp)); | 48 | memset(rp, 0, sizeof(*rp)); |
48 | 49 | ||
49 | if (rdev->ops->get_ringparam) | 50 | if (rdev->ops->get_ringparam) |
50 | rdev->ops->get_ringparam(wdev->wiphy, | 51 | rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending, |
51 | &rp->tx_pending, &rp->tx_max_pending, | 52 | &rp->rx_pending, &rp->rx_max_pending); |
52 | &rp->rx_pending, &rp->rx_max_pending); | ||
53 | } | 53 | } |
54 | 54 | ||
55 | static int cfg80211_set_ringparam(struct net_device *dev, | 55 | static int cfg80211_set_ringparam(struct net_device *dev, |
@@ -62,8 +62,7 @@ static int cfg80211_set_ringparam(struct net_device *dev, | |||
62 | return -EINVAL; | 62 | return -EINVAL; |
63 | 63 | ||
64 | if (rdev->ops->set_ringparam) | 64 | if (rdev->ops->set_ringparam) |
65 | return rdev->ops->set_ringparam(wdev->wiphy, | 65 | return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending); |
66 | rp->tx_pending, rp->rx_pending); | ||
67 | 66 | ||
68 | return -ENOTSUPP; | 67 | return -ENOTSUPP; |
69 | } | 68 | } |
@@ -73,7 +72,7 @@ static int cfg80211_get_sset_count(struct net_device *dev, int sset) | |||
73 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 72 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
74 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 73 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
75 | if (rdev->ops->get_et_sset_count) | 74 | if (rdev->ops->get_et_sset_count) |
76 | return rdev->ops->get_et_sset_count(wdev->wiphy, dev, sset); | 75 | return rdev_get_et_sset_count(rdev, dev, sset); |
77 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
78 | } | 77 | } |
79 | 78 | ||
@@ -83,7 +82,7 @@ static void cfg80211_get_stats(struct net_device *dev, | |||
83 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 82 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
84 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 83 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
85 | if (rdev->ops->get_et_stats) | 84 | if (rdev->ops->get_et_stats) |
86 | rdev->ops->get_et_stats(wdev->wiphy, dev, stats, data); | 85 | rdev_get_et_stats(rdev, dev, stats, data); |
87 | } | 86 | } |
88 | 87 | ||
89 | static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) | 88 | static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) |
@@ -91,7 +90,7 @@ static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) | |||
91 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 90 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
92 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 91 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
93 | if (rdev->ops->get_et_strings) | 92 | if (rdev->ops->get_et_strings) |
94 | rdev->ops->get_et_strings(wdev->wiphy, dev, sset, data); | 93 | rdev_get_et_strings(rdev, dev, sset, data); |
95 | } | 94 | } |
96 | 95 | ||
97 | const struct ethtool_ops cfg80211_ethtool_ops = { | 96 | const struct ethtool_ops cfg80211_ethtool_ops = { |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index ca5672f6ee2f..27941d5db72b 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <net/cfg80211.h> | 11 | #include <net/cfg80211.h> |
12 | #include "wext-compat.h" | 12 | #include "wext-compat.h" |
13 | #include "nl80211.h" | 13 | #include "nl80211.h" |
14 | #include "rdev-ops.h" | ||
14 | 15 | ||
15 | 16 | ||
16 | void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) | 17 | void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) |
@@ -61,6 +62,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) | |||
61 | struct cfg80211_event *ev; | 62 | struct cfg80211_event *ev; |
62 | unsigned long flags; | 63 | unsigned long flags; |
63 | 64 | ||
65 | trace_cfg80211_ibss_joined(dev, bssid); | ||
66 | |||
64 | CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); | 67 | CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); |
65 | 68 | ||
66 | ev = kzalloc(sizeof(*ev), gfp); | 69 | ev = kzalloc(sizeof(*ev), gfp); |
@@ -128,7 +131,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
128 | return err; | 131 | return err; |
129 | } | 132 | } |
130 | 133 | ||
131 | err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); | 134 | err = rdev_join_ibss(rdev, dev, params); |
132 | if (err) { | 135 | if (err) { |
133 | wdev->connect_keys = NULL; | 136 | wdev->connect_keys = NULL; |
134 | wdev->sme_state = CFG80211_SME_IDLE; | 137 | wdev->sme_state = CFG80211_SME_IDLE; |
@@ -175,7 +178,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
175 | */ | 178 | */ |
176 | if (rdev->ops->del_key) | 179 | if (rdev->ops->del_key) |
177 | for (i = 0; i < 6; i++) | 180 | for (i = 0; i < 6; i++) |
178 | rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); | 181 | rdev_del_key(rdev, dev, i, false, NULL); |
179 | 182 | ||
180 | if (wdev->current_bss) { | 183 | if (wdev->current_bss) { |
181 | cfg80211_unhold_bss(wdev->current_bss); | 184 | cfg80211_unhold_bss(wdev->current_bss); |
@@ -211,7 +214,7 @@ int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | |||
211 | if (!wdev->ssid_len) | 214 | if (!wdev->ssid_len) |
212 | return -ENOLINK; | 215 | return -ENOLINK; |
213 | 216 | ||
214 | err = rdev->ops->leave_ibss(&rdev->wiphy, dev); | 217 | err = rdev_leave_ibss(rdev, dev); |
215 | 218 | ||
216 | if (err) | 219 | if (err) |
217 | return err; | 220 | return err; |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index c384e77ff77a..966cfc4cd79d 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <net/cfg80211.h> | 3 | #include <net/cfg80211.h> |
4 | #include "nl80211.h" | 4 | #include "nl80211.h" |
5 | #include "core.h" | 5 | #include "core.h" |
6 | #include "rdev-ops.h" | ||
6 | 7 | ||
7 | /* Default values, timeouts in ms */ | 8 | /* Default values, timeouts in ms */ |
8 | #define MESH_TTL 31 | 9 | #define MESH_TTL 31 |
@@ -160,7 +161,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
160 | if (err) | 161 | if (err) |
161 | return err; | 162 | return err; |
162 | 163 | ||
163 | err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); | 164 | err = rdev_join_mesh(rdev, dev, conf, setup); |
164 | if (!err) { | 165 | if (!err) { |
165 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); | 166 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); |
166 | wdev->mesh_id_len = setup->mesh_id_len; | 167 | wdev->mesh_id_len = setup->mesh_id_len; |
@@ -220,9 +221,8 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | |||
220 | if (err) | 221 | if (err) |
221 | return err; | 222 | return err; |
222 | 223 | ||
223 | err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, | 224 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, |
224 | wdev->netdev, | 225 | channel); |
225 | channel); | ||
226 | if (!err) | 226 | if (!err) |
227 | wdev->channel = channel; | 227 | wdev->channel = channel; |
228 | 228 | ||
@@ -242,6 +242,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, | |||
242 | { | 242 | { |
243 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 243 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
244 | 244 | ||
245 | trace_cfg80211_notify_new_peer_candidate(dev, macaddr); | ||
245 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | 246 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) |
246 | return; | 247 | return; |
247 | 248 | ||
@@ -267,7 +268,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | |||
267 | if (!wdev->mesh_id_len) | 268 | if (!wdev->mesh_id_len) |
268 | return -ENOTCONN; | 269 | return -ENOTCONN; |
269 | 270 | ||
270 | err = rdev->ops->leave_mesh(&rdev->wiphy, dev); | 271 | err = rdev_leave_mesh(rdev, dev); |
271 | if (!err) { | 272 | if (!err) { |
272 | wdev->mesh_id_len = 0; | 273 | wdev->mesh_id_len = 0; |
273 | wdev->channel = NULL; | 274 | wdev->channel = NULL; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 904a7f368325..4bfd14f7c592 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <net/iw_handler.h> | 15 | #include <net/iw_handler.h> |
16 | #include "core.h" | 16 | #include "core.h" |
17 | #include "nl80211.h" | 17 | #include "nl80211.h" |
18 | #include "rdev-ops.h" | ||
19 | |||
18 | 20 | ||
19 | void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) | 21 | void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) |
20 | { | 22 | { |
@@ -22,6 +24,7 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) | |||
22 | struct wiphy *wiphy = wdev->wiphy; | 24 | struct wiphy *wiphy = wdev->wiphy; |
23 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 25 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
24 | 26 | ||
27 | trace_cfg80211_send_rx_auth(dev); | ||
25 | wdev_lock(wdev); | 28 | wdev_lock(wdev); |
26 | 29 | ||
27 | nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); | 30 | nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); |
@@ -42,6 +45,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, | |||
42 | u8 *ie = mgmt->u.assoc_resp.variable; | 45 | u8 *ie = mgmt->u.assoc_resp.variable; |
43 | int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | 46 | int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); |
44 | 47 | ||
48 | trace_cfg80211_send_rx_assoc(dev, bss); | ||
45 | wdev_lock(wdev); | 49 | wdev_lock(wdev); |
46 | 50 | ||
47 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 51 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
@@ -98,6 +102,7 @@ void __cfg80211_send_deauth(struct net_device *dev, | |||
98 | const u8 *bssid = mgmt->bssid; | 102 | const u8 *bssid = mgmt->bssid; |
99 | bool was_current = false; | 103 | bool was_current = false; |
100 | 104 | ||
105 | trace___cfg80211_send_deauth(dev); | ||
101 | ASSERT_WDEV_LOCK(wdev); | 106 | ASSERT_WDEV_LOCK(wdev); |
102 | 107 | ||
103 | if (wdev->current_bss && | 108 | if (wdev->current_bss && |
@@ -147,6 +152,7 @@ void __cfg80211_send_disassoc(struct net_device *dev, | |||
147 | u16 reason_code; | 152 | u16 reason_code; |
148 | bool from_ap; | 153 | bool from_ap; |
149 | 154 | ||
155 | trace___cfg80211_send_disassoc(dev); | ||
150 | ASSERT_WDEV_LOCK(wdev); | 156 | ASSERT_WDEV_LOCK(wdev); |
151 | 157 | ||
152 | nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); | 158 | nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); |
@@ -188,6 +194,7 @@ void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, | |||
188 | struct wiphy *wiphy = wdev->wiphy; | 194 | struct wiphy *wiphy = wdev->wiphy; |
189 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 195 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
190 | 196 | ||
197 | trace_cfg80211_send_unprot_deauth(dev); | ||
191 | nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC); | 198 | nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC); |
192 | } | 199 | } |
193 | EXPORT_SYMBOL(cfg80211_send_unprot_deauth); | 200 | EXPORT_SYMBOL(cfg80211_send_unprot_deauth); |
@@ -199,6 +206,7 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, | |||
199 | struct wiphy *wiphy = wdev->wiphy; | 206 | struct wiphy *wiphy = wdev->wiphy; |
200 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 207 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
201 | 208 | ||
209 | trace_cfg80211_send_unprot_disassoc(dev); | ||
202 | nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC); | 210 | nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC); |
203 | } | 211 | } |
204 | EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); | 212 | EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); |
@@ -209,6 +217,7 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | |||
209 | struct wiphy *wiphy = wdev->wiphy; | 217 | struct wiphy *wiphy = wdev->wiphy; |
210 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 218 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
211 | 219 | ||
220 | trace_cfg80211_send_auth_timeout(dev, addr); | ||
212 | wdev_lock(wdev); | 221 | wdev_lock(wdev); |
213 | 222 | ||
214 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); | 223 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); |
@@ -227,6 +236,7 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) | |||
227 | struct wiphy *wiphy = wdev->wiphy; | 236 | struct wiphy *wiphy = wdev->wiphy; |
228 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 237 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
229 | 238 | ||
239 | trace_cfg80211_send_assoc_timeout(dev, addr); | ||
230 | wdev_lock(wdev); | 240 | wdev_lock(wdev); |
231 | 241 | ||
232 | nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); | 242 | nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); |
@@ -261,6 +271,7 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, | |||
261 | } | 271 | } |
262 | #endif | 272 | #endif |
263 | 273 | ||
274 | trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc); | ||
264 | nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp); | 275 | nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp); |
265 | } | 276 | } |
266 | EXPORT_SYMBOL(cfg80211_michael_mic_failure); | 277 | EXPORT_SYMBOL(cfg80211_michael_mic_failure); |
@@ -273,7 +284,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
273 | const u8 *bssid, | 284 | const u8 *bssid, |
274 | const u8 *ssid, int ssid_len, | 285 | const u8 *ssid, int ssid_len, |
275 | const u8 *ie, int ie_len, | 286 | const u8 *ie, int ie_len, |
276 | const u8 *key, int key_len, int key_idx) | 287 | const u8 *key, int key_len, int key_idx, |
288 | const u8 *sae_data, int sae_data_len) | ||
277 | { | 289 | { |
278 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 290 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
279 | struct cfg80211_auth_request req; | 291 | struct cfg80211_auth_request req; |
@@ -293,6 +305,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
293 | 305 | ||
294 | req.ie = ie; | 306 | req.ie = ie; |
295 | req.ie_len = ie_len; | 307 | req.ie_len = ie_len; |
308 | req.sae_data = sae_data; | ||
309 | req.sae_data_len = sae_data_len; | ||
296 | req.auth_type = auth_type; | 310 | req.auth_type = auth_type; |
297 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 311 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
298 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 312 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
@@ -307,7 +321,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
307 | if (err) | 321 | if (err) |
308 | goto out; | 322 | goto out; |
309 | 323 | ||
310 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); | 324 | err = rdev_auth(rdev, dev, &req); |
311 | 325 | ||
312 | out: | 326 | out: |
313 | cfg80211_put_bss(req.bss); | 327 | cfg80211_put_bss(req.bss); |
@@ -319,7 +333,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
319 | enum nl80211_auth_type auth_type, const u8 *bssid, | 333 | enum nl80211_auth_type auth_type, const u8 *bssid, |
320 | const u8 *ssid, int ssid_len, | 334 | const u8 *ssid, int ssid_len, |
321 | const u8 *ie, int ie_len, | 335 | const u8 *ie, int ie_len, |
322 | const u8 *key, int key_len, int key_idx) | 336 | const u8 *key, int key_len, int key_idx, |
337 | const u8 *sae_data, int sae_data_len) | ||
323 | { | 338 | { |
324 | int err; | 339 | int err; |
325 | 340 | ||
@@ -327,7 +342,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
327 | wdev_lock(dev->ieee80211_ptr); | 342 | wdev_lock(dev->ieee80211_ptr); |
328 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 343 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
329 | ssid, ssid_len, ie, ie_len, | 344 | ssid, ssid_len, ie, ie_len, |
330 | key, key_len, key_idx); | 345 | key, key_len, key_idx, |
346 | sae_data, sae_data_len); | ||
331 | wdev_unlock(dev->ieee80211_ptr); | 347 | wdev_unlock(dev->ieee80211_ptr); |
332 | mutex_unlock(&rdev->devlist_mtx); | 348 | mutex_unlock(&rdev->devlist_mtx); |
333 | 349 | ||
@@ -410,7 +426,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
410 | if (err) | 426 | if (err) |
411 | goto out; | 427 | goto out; |
412 | 428 | ||
413 | err = rdev->ops->assoc(&rdev->wiphy, dev, &req); | 429 | err = rdev_assoc(rdev, dev, &req); |
414 | 430 | ||
415 | out: | 431 | out: |
416 | if (err) { | 432 | if (err) { |
@@ -466,7 +482,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
466 | !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) | 482 | !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) |
467 | return 0; | 483 | return 0; |
468 | 484 | ||
469 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); | 485 | return rdev_deauth(rdev, dev, &req); |
470 | } | 486 | } |
471 | 487 | ||
472 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 488 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
@@ -511,7 +527,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
511 | else | 527 | else |
512 | return -ENOTCONN; | 528 | return -ENOTCONN; |
513 | 529 | ||
514 | return rdev->ops->disassoc(&rdev->wiphy, dev, &req); | 530 | return rdev_disassoc(rdev, dev, &req); |
515 | } | 531 | } |
516 | 532 | ||
517 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 533 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
@@ -552,7 +568,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, | |||
552 | 568 | ||
553 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); | 569 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); |
554 | req.bssid = bssid; | 570 | req.bssid = bssid; |
555 | rdev->ops->deauth(&rdev->wiphy, dev, &req); | 571 | rdev_deauth(rdev, dev, &req); |
556 | 572 | ||
557 | if (wdev->current_bss) { | 573 | if (wdev->current_bss) { |
558 | cfg80211_unhold_bss(wdev->current_bss); | 574 | cfg80211_unhold_bss(wdev->current_bss); |
@@ -569,6 +585,8 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, | |||
569 | struct wiphy *wiphy = wdev->wiphy; | 585 | struct wiphy *wiphy = wdev->wiphy; |
570 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 586 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
571 | 587 | ||
588 | trace_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, | ||
589 | duration); | ||
572 | nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type, | 590 | nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type, |
573 | duration, gfp); | 591 | duration, gfp); |
574 | } | 592 | } |
@@ -582,6 +600,8 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, | |||
582 | struct wiphy *wiphy = wdev->wiphy; | 600 | struct wiphy *wiphy = wdev->wiphy; |
583 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 601 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
584 | 602 | ||
603 | trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan, | ||
604 | channel_type); | ||
585 | nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, | 605 | nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, |
586 | channel_type, gfp); | 606 | channel_type, gfp); |
587 | } | 607 | } |
@@ -593,6 +613,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
593 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 613 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
594 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 614 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
595 | 615 | ||
616 | trace_cfg80211_new_sta(dev, mac_addr, sinfo); | ||
596 | nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp); | 617 | nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp); |
597 | } | 618 | } |
598 | EXPORT_SYMBOL(cfg80211_new_sta); | 619 | EXPORT_SYMBOL(cfg80211_new_sta); |
@@ -602,6 +623,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | |||
602 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 623 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
603 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 624 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
604 | 625 | ||
626 | trace_cfg80211_del_sta(dev, mac_addr); | ||
605 | nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); | 627 | nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); |
606 | } | 628 | } |
607 | EXPORT_SYMBOL(cfg80211_del_sta); | 629 | EXPORT_SYMBOL(cfg80211_del_sta); |
@@ -682,7 +704,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, | |||
682 | list_add(&nreg->list, &wdev->mgmt_registrations); | 704 | list_add(&nreg->list, &wdev->mgmt_registrations); |
683 | 705 | ||
684 | if (rdev->ops->mgmt_frame_register) | 706 | if (rdev->ops->mgmt_frame_register) |
685 | rdev->ops->mgmt_frame_register(wiphy, wdev, frame_type, true); | 707 | rdev_mgmt_frame_register(rdev, wdev, frame_type, true); |
686 | 708 | ||
687 | out: | 709 | out: |
688 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 710 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
@@ -705,8 +727,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) | |||
705 | if (rdev->ops->mgmt_frame_register) { | 727 | if (rdev->ops->mgmt_frame_register) { |
706 | u16 frame_type = le16_to_cpu(reg->frame_type); | 728 | u16 frame_type = le16_to_cpu(reg->frame_type); |
707 | 729 | ||
708 | rdev->ops->mgmt_frame_register(wiphy, wdev, | 730 | rdev_mgmt_frame_register(rdev, wdev, |
709 | frame_type, false); | 731 | frame_type, false); |
710 | } | 732 | } |
711 | 733 | ||
712 | list_del(®->list); | 734 | list_del(®->list); |
@@ -832,10 +854,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
832 | return -EINVAL; | 854 | return -EINVAL; |
833 | 855 | ||
834 | /* Transmit the Action frame as requested by user space */ | 856 | /* Transmit the Action frame as requested by user space */ |
835 | return rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, | 857 | return rdev_mgmt_tx(rdev, wdev, chan, offchan, |
836 | channel_type, channel_type_valid, | 858 | channel_type, channel_type_valid, |
837 | wait, buf, len, no_cck, dont_wait_for_ack, | 859 | wait, buf, len, no_cck, dont_wait_for_ack, |
838 | cookie); | 860 | cookie); |
839 | } | 861 | } |
840 | 862 | ||
841 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | 863 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, |
@@ -854,10 +876,13 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
854 | cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); | 876 | cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); |
855 | u16 stype; | 877 | u16 stype; |
856 | 878 | ||
879 | trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm); | ||
857 | stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; | 880 | stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; |
858 | 881 | ||
859 | if (!(stypes->rx & BIT(stype))) | 882 | if (!(stypes->rx & BIT(stype))) { |
883 | trace_cfg80211_return_bool(false); | ||
860 | return false; | 884 | return false; |
885 | } | ||
861 | 886 | ||
862 | data = buf + ieee80211_hdrlen(mgmt->frame_control); | 887 | data = buf + ieee80211_hdrlen(mgmt->frame_control); |
863 | data_len = len - ieee80211_hdrlen(mgmt->frame_control); | 888 | data_len = len - ieee80211_hdrlen(mgmt->frame_control); |
@@ -888,6 +913,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
888 | 913 | ||
889 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 914 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
890 | 915 | ||
916 | trace_cfg80211_return_bool(result); | ||
891 | return result; | 917 | return result; |
892 | } | 918 | } |
893 | EXPORT_SYMBOL(cfg80211_rx_mgmt); | 919 | EXPORT_SYMBOL(cfg80211_rx_mgmt); |
@@ -898,6 +924,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
898 | struct wiphy *wiphy = wdev->wiphy; | 924 | struct wiphy *wiphy = wdev->wiphy; |
899 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 925 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
900 | 926 | ||
927 | trace_cfg80211_mgmt_tx_status(wdev, cookie, ack); | ||
928 | |||
901 | /* Indicate TX status of the Action frame to user space */ | 929 | /* Indicate TX status of the Action frame to user space */ |
902 | nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp); | 930 | nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp); |
903 | } | 931 | } |
@@ -911,6 +939,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, | |||
911 | struct wiphy *wiphy = wdev->wiphy; | 939 | struct wiphy *wiphy = wdev->wiphy; |
912 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 940 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
913 | 941 | ||
942 | trace_cfg80211_cqm_rssi_notify(dev, rssi_event); | ||
943 | |||
914 | /* Indicate roaming trigger event to user space */ | 944 | /* Indicate roaming trigger event to user space */ |
915 | nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); | 945 | nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); |
916 | } | 946 | } |
@@ -923,6 +953,8 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, | |||
923 | struct wiphy *wiphy = wdev->wiphy; | 953 | struct wiphy *wiphy = wdev->wiphy; |
924 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 954 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
925 | 955 | ||
956 | trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets); | ||
957 | |||
926 | /* Indicate roaming trigger event to user space */ | 958 | /* Indicate roaming trigger event to user space */ |
927 | nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); | 959 | nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); |
928 | } | 960 | } |
@@ -948,6 +980,7 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | |||
948 | struct wiphy *wiphy = wdev->wiphy; | 980 | struct wiphy *wiphy = wdev->wiphy; |
949 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 981 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
950 | 982 | ||
983 | trace_cfg80211_gtk_rekey_notify(dev, bssid); | ||
951 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); | 984 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); |
952 | } | 985 | } |
953 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); | 986 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); |
@@ -959,6 +992,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | |||
959 | struct wiphy *wiphy = wdev->wiphy; | 992 | struct wiphy *wiphy = wdev->wiphy; |
960 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 993 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
961 | 994 | ||
995 | trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth); | ||
962 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); | 996 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); |
963 | } | 997 | } |
964 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); | 998 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); |
@@ -971,6 +1005,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, | |||
971 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 1005 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
972 | struct ieee80211_channel *chan; | 1006 | struct ieee80211_channel *chan; |
973 | 1007 | ||
1008 | trace_cfg80211_ch_switch_notify(dev, freq, type); | ||
1009 | |||
974 | wdev_lock(wdev); | 1010 | wdev_lock(wdev); |
975 | 1011 | ||
976 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | 1012 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && |
@@ -993,12 +1029,18 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev, | |||
993 | const u8 *addr, gfp_t gfp) | 1029 | const u8 *addr, gfp_t gfp) |
994 | { | 1030 | { |
995 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1031 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1032 | bool ret; | ||
1033 | |||
1034 | trace_cfg80211_rx_spurious_frame(dev, addr); | ||
996 | 1035 | ||
997 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | 1036 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && |
998 | wdev->iftype != NL80211_IFTYPE_P2P_GO)) | 1037 | wdev->iftype != NL80211_IFTYPE_P2P_GO)) { |
1038 | trace_cfg80211_return_bool(false); | ||
999 | return false; | 1039 | return false; |
1000 | 1040 | } | |
1001 | return nl80211_unexpected_frame(dev, addr, gfp); | 1041 | ret = nl80211_unexpected_frame(dev, addr, gfp); |
1042 | trace_cfg80211_return_bool(ret); | ||
1043 | return ret; | ||
1002 | } | 1044 | } |
1003 | EXPORT_SYMBOL(cfg80211_rx_spurious_frame); | 1045 | EXPORT_SYMBOL(cfg80211_rx_spurious_frame); |
1004 | 1046 | ||
@@ -1006,12 +1048,18 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, | |||
1006 | const u8 *addr, gfp_t gfp) | 1048 | const u8 *addr, gfp_t gfp) |
1007 | { | 1049 | { |
1008 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1050 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1051 | bool ret; | ||
1052 | |||
1053 | trace_cfg80211_rx_unexpected_4addr_frame(dev, addr); | ||
1009 | 1054 | ||
1010 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | 1055 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && |
1011 | wdev->iftype != NL80211_IFTYPE_P2P_GO && | 1056 | wdev->iftype != NL80211_IFTYPE_P2P_GO && |
1012 | wdev->iftype != NL80211_IFTYPE_AP_VLAN)) | 1057 | wdev->iftype != NL80211_IFTYPE_AP_VLAN)) { |
1058 | trace_cfg80211_return_bool(false); | ||
1013 | return false; | 1059 | return false; |
1014 | 1060 | } | |
1015 | return nl80211_unexpected_4addr_frame(dev, addr, gfp); | 1061 | ret = nl80211_unexpected_4addr_frame(dev, addr, gfp); |
1062 | trace_cfg80211_return_bool(ret); | ||
1063 | return ret; | ||
1016 | } | 1064 | } |
1017 | EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); | 1065 | EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0418a6d5c1a6..8c0857815a90 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #include "core.h" | 22 | #include "core.h" |
23 | #include "nl80211.h" | 23 | #include "nl80211.h" |
24 | #include "reg.h" | 24 | #include "reg.h" |
25 | #include "rdev-ops.h" | ||
25 | 26 | ||
26 | static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type); | ||
27 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | 27 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, |
28 | struct genl_info *info, | 28 | struct genl_info *info, |
29 | struct cfg80211_crypto_settings *settings, | 29 | struct cfg80211_crypto_settings *settings, |
@@ -355,6 +355,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
355 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | 355 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, |
356 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, | 356 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, |
357 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, | 357 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, |
358 | [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, }, | ||
359 | [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, | ||
360 | [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, | ||
358 | }; | 361 | }; |
359 | 362 | ||
360 | /* policy for the key attributes */ | 363 | /* policy for the key attributes */ |
@@ -690,7 +693,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) | |||
690 | 693 | ||
691 | static struct cfg80211_cached_keys * | 694 | static struct cfg80211_cached_keys * |
692 | nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, | 695 | nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, |
693 | struct nlattr *keys) | 696 | struct nlattr *keys, bool *no_ht) |
694 | { | 697 | { |
695 | struct key_parse parse; | 698 | struct key_parse parse; |
696 | struct nlattr *key; | 699 | struct nlattr *key; |
@@ -733,6 +736,12 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, | |||
733 | result->params[parse.idx].key_len = parse.p.key_len; | 736 | result->params[parse.idx].key_len = parse.p.key_len; |
734 | result->params[parse.idx].key = result->data[parse.idx]; | 737 | result->params[parse.idx].key = result->data[parse.idx]; |
735 | memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); | 738 | memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); |
739 | |||
740 | if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
741 | parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) { | ||
742 | if (no_ht) | ||
743 | *no_ht = true; | ||
744 | } | ||
736 | } | 745 | } |
737 | 746 | ||
738 | return result; | 747 | return result; |
@@ -943,7 +952,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
943 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { | 952 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { |
944 | u32 tx_ant = 0, rx_ant = 0; | 953 | u32 tx_ant = 0, rx_ant = 0; |
945 | int res; | 954 | int res; |
946 | res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); | 955 | res = rdev_get_antenna(dev, &tx_ant, &rx_ant); |
947 | if (!res) { | 956 | if (!res) { |
948 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, | 957 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, |
949 | tx_ant) || | 958 | tx_ant) || |
@@ -1457,7 +1466,7 @@ static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) | |||
1457 | return -EOPNOTSUPP; | 1466 | return -EOPNOTSUPP; |
1458 | 1467 | ||
1459 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1468 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1460 | return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); | 1469 | return rdev_set_wds_peer(rdev, dev, bssid); |
1461 | } | 1470 | } |
1462 | 1471 | ||
1463 | 1472 | ||
@@ -1562,9 +1571,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1562 | if (result) | 1571 | if (result) |
1563 | goto bad_res; | 1572 | goto bad_res; |
1564 | 1573 | ||
1565 | result = rdev->ops->set_txq_params(&rdev->wiphy, | 1574 | result = rdev_set_txq_params(rdev, netdev, |
1566 | netdev, | 1575 | &txq_params); |
1567 | &txq_params); | ||
1568 | if (result) | 1576 | if (result) |
1569 | goto bad_res; | 1577 | goto bad_res; |
1570 | } | 1578 | } |
@@ -1599,7 +1607,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1599 | mbm = nla_get_u32(info->attrs[idx]); | 1607 | mbm = nla_get_u32(info->attrs[idx]); |
1600 | } | 1608 | } |
1601 | 1609 | ||
1602 | result = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); | 1610 | result = rdev_set_tx_power(rdev, type, mbm); |
1603 | if (result) | 1611 | if (result) |
1604 | goto bad_res; | 1612 | goto bad_res; |
1605 | } | 1613 | } |
@@ -1628,7 +1636,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1628 | tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; | 1636 | tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; |
1629 | rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; | 1637 | rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; |
1630 | 1638 | ||
1631 | result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); | 1639 | result = rdev_set_antenna(rdev, tx_ant, rx_ant); |
1632 | if (result) | 1640 | if (result) |
1633 | goto bad_res; | 1641 | goto bad_res; |
1634 | } | 1642 | } |
@@ -1713,7 +1721,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1713 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) | 1721 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) |
1714 | rdev->wiphy.coverage_class = coverage_class; | 1722 | rdev->wiphy.coverage_class = coverage_class; |
1715 | 1723 | ||
1716 | result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); | 1724 | result = rdev_set_wiphy_params(rdev, changed); |
1717 | if (result) { | 1725 | if (result) { |
1718 | rdev->wiphy.retry_short = old_retry_short; | 1726 | rdev->wiphy.retry_short = old_retry_short; |
1719 | rdev->wiphy.retry_long = old_retry_long; | 1727 | rdev->wiphy.retry_long = old_retry_long; |
@@ -1765,8 +1773,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1765 | struct ieee80211_channel *chan; | 1773 | struct ieee80211_channel *chan; |
1766 | enum nl80211_channel_type channel_type; | 1774 | enum nl80211_channel_type channel_type; |
1767 | 1775 | ||
1768 | chan = rdev->ops->get_channel(&rdev->wiphy, wdev, | 1776 | chan = rdev_get_channel(rdev, wdev, &channel_type); |
1769 | &channel_type); | ||
1770 | if (chan && | 1777 | if (chan && |
1771 | (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, | 1778 | (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, |
1772 | chan->center_freq) || | 1779 | chan->center_freq) || |
@@ -2014,9 +2021,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2014 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2021 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2015 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2022 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2016 | &flags); | 2023 | &flags); |
2017 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, | 2024 | wdev = rdev_add_virtual_intf(rdev, |
2018 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2025 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2019 | type, err ? NULL : &flags, ¶ms); | 2026 | type, err ? NULL : &flags, ¶ms); |
2020 | if (IS_ERR(wdev)) { | 2027 | if (IS_ERR(wdev)) { |
2021 | nlmsg_free(msg); | 2028 | nlmsg_free(msg); |
2022 | return PTR_ERR(wdev); | 2029 | return PTR_ERR(wdev); |
@@ -2083,7 +2090,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | |||
2083 | if (!wdev->netdev) | 2090 | if (!wdev->netdev) |
2084 | info->user_ptr[1] = NULL; | 2091 | info->user_ptr[1] = NULL; |
2085 | 2092 | ||
2086 | return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); | 2093 | return rdev_del_virtual_intf(rdev, wdev); |
2087 | } | 2094 | } |
2088 | 2095 | ||
2089 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | 2096 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) |
@@ -2100,7 +2107,7 @@ static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | |||
2100 | 2107 | ||
2101 | noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]); | 2108 | noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]); |
2102 | 2109 | ||
2103 | return rdev->ops->set_noack_map(&rdev->wiphy, dev, noack_map); | 2110 | return rdev_set_noack_map(rdev, dev, noack_map); |
2104 | } | 2111 | } |
2105 | 2112 | ||
2106 | struct get_key_cookie { | 2113 | struct get_key_cookie { |
@@ -2210,8 +2217,8 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
2210 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | 2217 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
2211 | return -ENOENT; | 2218 | return -ENOENT; |
2212 | 2219 | ||
2213 | err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise, | 2220 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, |
2214 | mac_addr, &cookie, get_key_callback); | 2221 | get_key_callback); |
2215 | 2222 | ||
2216 | if (err) | 2223 | if (err) |
2217 | goto free_msg; | 2224 | goto free_msg; |
@@ -2259,7 +2266,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) | |||
2259 | if (err) | 2266 | if (err) |
2260 | goto out; | 2267 | goto out; |
2261 | 2268 | ||
2262 | err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, | 2269 | err = rdev_set_default_key(rdev, dev, key.idx, |
2263 | key.def_uni, key.def_multi); | 2270 | key.def_uni, key.def_multi); |
2264 | 2271 | ||
2265 | if (err) | 2272 | if (err) |
@@ -2283,8 +2290,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) | |||
2283 | if (err) | 2290 | if (err) |
2284 | goto out; | 2291 | goto out; |
2285 | 2292 | ||
2286 | err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, | 2293 | err = rdev_set_default_mgmt_key(rdev, dev, key.idx); |
2287 | dev, key.idx); | ||
2288 | if (err) | 2294 | if (err) |
2289 | goto out; | 2295 | goto out; |
2290 | 2296 | ||
@@ -2340,9 +2346,9 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) | |||
2340 | wdev_lock(dev->ieee80211_ptr); | 2346 | wdev_lock(dev->ieee80211_ptr); |
2341 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 2347 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
2342 | if (!err) | 2348 | if (!err) |
2343 | err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, | 2349 | err = rdev_add_key(rdev, dev, key.idx, |
2344 | key.type == NL80211_KEYTYPE_PAIRWISE, | 2350 | key.type == NL80211_KEYTYPE_PAIRWISE, |
2345 | mac_addr, &key.p); | 2351 | mac_addr, &key.p); |
2346 | wdev_unlock(dev->ieee80211_ptr); | 2352 | wdev_unlock(dev->ieee80211_ptr); |
2347 | 2353 | ||
2348 | return err; | 2354 | return err; |
@@ -2386,9 +2392,9 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) | |||
2386 | err = -ENOENT; | 2392 | err = -ENOENT; |
2387 | 2393 | ||
2388 | if (!err) | 2394 | if (!err) |
2389 | err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, | 2395 | err = rdev_del_key(rdev, dev, key.idx, |
2390 | key.type == NL80211_KEYTYPE_PAIRWISE, | 2396 | key.type == NL80211_KEYTYPE_PAIRWISE, |
2391 | mac_addr); | 2397 | mac_addr); |
2392 | 2398 | ||
2393 | #ifdef CONFIG_CFG80211_WEXT | 2399 | #ifdef CONFIG_CFG80211_WEXT |
2394 | if (!err) { | 2400 | if (!err) { |
@@ -2490,6 +2496,30 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, | |||
2490 | return ret; | 2496 | return ret; |
2491 | } | 2497 | } |
2492 | 2498 | ||
2499 | static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, | ||
2500 | enum nl80211_auth_type auth_type, | ||
2501 | enum nl80211_commands cmd) | ||
2502 | { | ||
2503 | if (auth_type > NL80211_AUTHTYPE_MAX) | ||
2504 | return false; | ||
2505 | |||
2506 | switch (cmd) { | ||
2507 | case NL80211_CMD_AUTHENTICATE: | ||
2508 | if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) && | ||
2509 | auth_type == NL80211_AUTHTYPE_SAE) | ||
2510 | return false; | ||
2511 | return true; | ||
2512 | case NL80211_CMD_CONNECT: | ||
2513 | case NL80211_CMD_START_AP: | ||
2514 | /* SAE not supported yet */ | ||
2515 | if (auth_type == NL80211_AUTHTYPE_SAE) | ||
2516 | return false; | ||
2517 | return true; | ||
2518 | default: | ||
2519 | return false; | ||
2520 | } | ||
2521 | } | ||
2522 | |||
2493 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | 2523 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) |
2494 | { | 2524 | { |
2495 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2525 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -2559,7 +2589,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2559 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { | 2589 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { |
2560 | params.auth_type = nla_get_u32( | 2590 | params.auth_type = nla_get_u32( |
2561 | info->attrs[NL80211_ATTR_AUTH_TYPE]); | 2591 | info->attrs[NL80211_ATTR_AUTH_TYPE]); |
2562 | if (!nl80211_valid_auth_type(params.auth_type)) | 2592 | if (!nl80211_valid_auth_type(rdev, params.auth_type, |
2593 | NL80211_CMD_START_AP)) | ||
2563 | return -EINVAL; | 2594 | return -EINVAL; |
2564 | } else | 2595 | } else |
2565 | params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 2596 | params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
@@ -2607,7 +2638,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2607 | if (err) | 2638 | if (err) |
2608 | return err; | 2639 | return err; |
2609 | 2640 | ||
2610 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); | 2641 | err = rdev_start_ap(rdev, dev, ¶ms); |
2611 | if (!err) { | 2642 | if (!err) { |
2612 | wdev->preset_chan = params.channel; | 2643 | wdev->preset_chan = params.channel; |
2613 | wdev->preset_chantype = params.channel_type; | 2644 | wdev->preset_chantype = params.channel_type; |
@@ -2639,7 +2670,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) | |||
2639 | if (err) | 2670 | if (err) |
2640 | return err; | 2671 | return err; |
2641 | 2672 | ||
2642 | return rdev->ops->change_beacon(&rdev->wiphy, dev, ¶ms); | 2673 | return rdev_change_beacon(rdev, dev, ¶ms); |
2643 | } | 2674 | } |
2644 | 2675 | ||
2645 | static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) | 2676 | static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) |
@@ -2923,8 +2954,8 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
2923 | 2954 | ||
2924 | while (1) { | 2955 | while (1) { |
2925 | memset(&sinfo, 0, sizeof(sinfo)); | 2956 | memset(&sinfo, 0, sizeof(sinfo)); |
2926 | err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, | 2957 | err = rdev_dump_station(dev, netdev, sta_idx, |
2927 | mac_addr, &sinfo); | 2958 | mac_addr, &sinfo); |
2928 | if (err == -ENOENT) | 2959 | if (err == -ENOENT) |
2929 | break; | 2960 | break; |
2930 | if (err) | 2961 | if (err) |
@@ -2969,7 +3000,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | |||
2969 | if (!rdev->ops->get_station) | 3000 | if (!rdev->ops->get_station) |
2970 | return -EOPNOTSUPP; | 3001 | return -EOPNOTSUPP; |
2971 | 3002 | ||
2972 | err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); | 3003 | err = rdev_get_station(rdev, dev, mac_addr, &sinfo); |
2973 | if (err) | 3004 | if (err) |
2974 | return err; | 3005 | return err; |
2975 | 3006 | ||
@@ -3146,7 +3177,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3146 | 3177 | ||
3147 | /* be aware of params.vlan when changing code here */ | 3178 | /* be aware of params.vlan when changing code here */ |
3148 | 3179 | ||
3149 | err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, ¶ms); | 3180 | err = rdev_change_station(rdev, dev, mac_addr, ¶ms); |
3150 | 3181 | ||
3151 | if (params.vlan) | 3182 | if (params.vlan) |
3152 | dev_put(params.vlan); | 3183 | dev_put(params.vlan); |
@@ -3198,6 +3229,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
3198 | params.ht_capa = | 3229 | params.ht_capa = |
3199 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 3230 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
3200 | 3231 | ||
3232 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) | ||
3233 | params.vht_capa = | ||
3234 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); | ||
3235 | |||
3201 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 3236 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) |
3202 | params.plink_action = | 3237 | params.plink_action = |
3203 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 3238 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
@@ -3275,7 +3310,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
3275 | 3310 | ||
3276 | /* be aware of params.vlan when changing code here */ | 3311 | /* be aware of params.vlan when changing code here */ |
3277 | 3312 | ||
3278 | err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, ¶ms); | 3313 | err = rdev_add_station(rdev, dev, mac_addr, ¶ms); |
3279 | 3314 | ||
3280 | if (params.vlan) | 3315 | if (params.vlan) |
3281 | dev_put(params.vlan); | 3316 | dev_put(params.vlan); |
@@ -3300,7 +3335,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
3300 | if (!rdev->ops->del_station) | 3335 | if (!rdev->ops->del_station) |
3301 | return -EOPNOTSUPP; | 3336 | return -EOPNOTSUPP; |
3302 | 3337 | ||
3303 | return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); | 3338 | return rdev_del_station(rdev, dev, mac_addr); |
3304 | } | 3339 | } |
3305 | 3340 | ||
3306 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, | 3341 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, |
@@ -3382,8 +3417,8 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
3382 | } | 3417 | } |
3383 | 3418 | ||
3384 | while (1) { | 3419 | while (1) { |
3385 | err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx, | 3420 | err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop, |
3386 | dst, next_hop, &pinfo); | 3421 | &pinfo); |
3387 | if (err == -ENOENT) | 3422 | if (err == -ENOENT) |
3388 | break; | 3423 | break; |
3389 | if (err) | 3424 | if (err) |
@@ -3430,7 +3465,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) | |||
3430 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3465 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3431 | return -EOPNOTSUPP; | 3466 | return -EOPNOTSUPP; |
3432 | 3467 | ||
3433 | err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); | 3468 | err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo); |
3434 | if (err) | 3469 | if (err) |
3435 | return err; | 3470 | return err; |
3436 | 3471 | ||
@@ -3469,7 +3504,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) | |||
3469 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3504 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3470 | return -EOPNOTSUPP; | 3505 | return -EOPNOTSUPP; |
3471 | 3506 | ||
3472 | return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); | 3507 | return rdev_change_mpath(rdev, dev, dst, next_hop); |
3473 | } | 3508 | } |
3474 | 3509 | ||
3475 | static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) | 3510 | static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) |
@@ -3494,7 +3529,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) | |||
3494 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3529 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3495 | return -EOPNOTSUPP; | 3530 | return -EOPNOTSUPP; |
3496 | 3531 | ||
3497 | return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); | 3532 | return rdev_add_mpath(rdev, dev, dst, next_hop); |
3498 | } | 3533 | } |
3499 | 3534 | ||
3500 | static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | 3535 | static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) |
@@ -3509,7 +3544,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | |||
3509 | if (!rdev->ops->del_mpath) | 3544 | if (!rdev->ops->del_mpath) |
3510 | return -EOPNOTSUPP; | 3545 | return -EOPNOTSUPP; |
3511 | 3546 | ||
3512 | return rdev->ops->del_mpath(&rdev->wiphy, dev, dst); | 3547 | return rdev_del_mpath(rdev, dev, dst); |
3513 | } | 3548 | } |
3514 | 3549 | ||
3515 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | 3550 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) |
@@ -3554,7 +3589,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | |||
3554 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3589 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
3555 | return -EOPNOTSUPP; | 3590 | return -EOPNOTSUPP; |
3556 | 3591 | ||
3557 | return rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); | 3592 | return rdev_change_bss(rdev, dev, ¶ms); |
3558 | } | 3593 | } |
3559 | 3594 | ||
3560 | static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { | 3595 | static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { |
@@ -3668,8 +3703,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
3668 | if (!wdev->mesh_id_len) | 3703 | if (!wdev->mesh_id_len) |
3669 | memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); | 3704 | memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); |
3670 | else | 3705 | else |
3671 | err = rdev->ops->get_mesh_config(&rdev->wiphy, dev, | 3706 | err = rdev_get_mesh_config(rdev, dev, &cur_params); |
3672 | &cur_params); | ||
3673 | wdev_unlock(wdev); | 3707 | wdev_unlock(wdev); |
3674 | 3708 | ||
3675 | if (err) | 3709 | if (err) |
@@ -3971,8 +4005,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, | |||
3971 | err = -ENOLINK; | 4005 | err = -ENOLINK; |
3972 | 4006 | ||
3973 | if (!err) | 4007 | if (!err) |
3974 | err = rdev->ops->update_mesh_config(&rdev->wiphy, dev, | 4008 | err = rdev_update_mesh_config(rdev, dev, mask, &cfg); |
3975 | mask, &cfg); | ||
3976 | 4009 | ||
3977 | wdev_unlock(wdev); | 4010 | wdev_unlock(wdev); |
3978 | 4011 | ||
@@ -4337,14 +4370,27 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
4337 | } | 4370 | } |
4338 | } | 4371 | } |
4339 | 4372 | ||
4373 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { | ||
4374 | request->flags = nla_get_u32( | ||
4375 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); | ||
4376 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && | ||
4377 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || | ||
4378 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && | ||
4379 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { | ||
4380 | err = -EOPNOTSUPP; | ||
4381 | goto out_free; | ||
4382 | } | ||
4383 | } | ||
4384 | |||
4340 | request->no_cck = | 4385 | request->no_cck = |
4341 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | 4386 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); |
4342 | 4387 | ||
4343 | request->wdev = wdev; | 4388 | request->wdev = wdev; |
4344 | request->wiphy = &rdev->wiphy; | 4389 | request->wiphy = &rdev->wiphy; |
4390 | request->scan_start = jiffies; | ||
4345 | 4391 | ||
4346 | rdev->scan_req = request; | 4392 | rdev->scan_req = request; |
4347 | err = rdev->ops->scan(&rdev->wiphy, request); | 4393 | err = rdev_scan(rdev, request); |
4348 | 4394 | ||
4349 | if (!err) { | 4395 | if (!err) { |
4350 | nl80211_send_scan_start(rdev, wdev); | 4396 | nl80211_send_scan_start(rdev, wdev); |
@@ -4568,11 +4614,24 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
4568 | request->ie_len); | 4614 | request->ie_len); |
4569 | } | 4615 | } |
4570 | 4616 | ||
4617 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { | ||
4618 | request->flags = nla_get_u32( | ||
4619 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); | ||
4620 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && | ||
4621 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || | ||
4622 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && | ||
4623 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { | ||
4624 | err = -EOPNOTSUPP; | ||
4625 | goto out_free; | ||
4626 | } | ||
4627 | } | ||
4628 | |||
4571 | request->dev = dev; | 4629 | request->dev = dev; |
4572 | request->wiphy = &rdev->wiphy; | 4630 | request->wiphy = &rdev->wiphy; |
4573 | request->interval = interval; | 4631 | request->interval = interval; |
4632 | request->scan_start = jiffies; | ||
4574 | 4633 | ||
4575 | err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); | 4634 | err = rdev_sched_scan_start(rdev, dev, request); |
4576 | if (!err) { | 4635 | if (!err) { |
4577 | rdev->sched_scan_req = request; | 4636 | rdev->sched_scan_req = request; |
4578 | nl80211_send_sched_scan(rdev, dev, | 4637 | nl80211_send_sched_scan(rdev, dev, |
@@ -4815,8 +4874,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
4815 | while (1) { | 4874 | while (1) { |
4816 | struct ieee80211_channel *chan; | 4875 | struct ieee80211_channel *chan; |
4817 | 4876 | ||
4818 | res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, | 4877 | res = rdev_dump_survey(dev, netdev, survey_idx, &survey); |
4819 | &survey); | ||
4820 | if (res == -ENOENT) | 4878 | if (res == -ENOENT) |
4821 | break; | 4879 | break; |
4822 | if (res) | 4880 | if (res) |
@@ -4852,11 +4910,6 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
4852 | return res; | 4910 | return res; |
4853 | } | 4911 | } |
4854 | 4912 | ||
4855 | static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type) | ||
4856 | { | ||
4857 | return auth_type <= NL80211_AUTHTYPE_MAX; | ||
4858 | } | ||
4859 | |||
4860 | static bool nl80211_valid_wpa_versions(u32 wpa_versions) | 4913 | static bool nl80211_valid_wpa_versions(u32 wpa_versions) |
4861 | { | 4914 | { |
4862 | return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | | 4915 | return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | |
@@ -4868,8 +4921,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
4868 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4921 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4869 | struct net_device *dev = info->user_ptr[1]; | 4922 | struct net_device *dev = info->user_ptr[1]; |
4870 | struct ieee80211_channel *chan; | 4923 | struct ieee80211_channel *chan; |
4871 | const u8 *bssid, *ssid, *ie = NULL; | 4924 | const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL; |
4872 | int err, ssid_len, ie_len = 0; | 4925 | int err, ssid_len, ie_len = 0, sae_data_len = 0; |
4873 | enum nl80211_auth_type auth_type; | 4926 | enum nl80211_auth_type auth_type; |
4874 | struct key_parse key; | 4927 | struct key_parse key; |
4875 | bool local_state_change; | 4928 | bool local_state_change; |
@@ -4945,9 +4998,23 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
4945 | } | 4998 | } |
4946 | 4999 | ||
4947 | auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); | 5000 | auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); |
4948 | if (!nl80211_valid_auth_type(auth_type)) | 5001 | if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE)) |
4949 | return -EINVAL; | 5002 | return -EINVAL; |
4950 | 5003 | ||
5004 | if (auth_type == NL80211_AUTHTYPE_SAE && | ||
5005 | !info->attrs[NL80211_ATTR_SAE_DATA]) | ||
5006 | return -EINVAL; | ||
5007 | |||
5008 | if (info->attrs[NL80211_ATTR_SAE_DATA]) { | ||
5009 | if (auth_type != NL80211_AUTHTYPE_SAE) | ||
5010 | return -EINVAL; | ||
5011 | sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]); | ||
5012 | sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]); | ||
5013 | /* need to include at least Auth Transaction and Status Code */ | ||
5014 | if (sae_data_len < 4) | ||
5015 | return -EINVAL; | ||
5016 | } | ||
5017 | |||
4951 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | 5018 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
4952 | 5019 | ||
4953 | /* | 5020 | /* |
@@ -4959,7 +5026,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
4959 | 5026 | ||
4960 | return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 5027 | return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
4961 | ssid, ssid_len, ie, ie_len, | 5028 | ssid, ssid_len, ie, ie_len, |
4962 | key.p.key, key.p.key_len, key.idx); | 5029 | key.p.key, key.p.key_len, key.idx, |
5030 | sae_data, sae_data_len); | ||
4963 | } | 5031 | } |
4964 | 5032 | ||
4965 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | 5033 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, |
@@ -5339,10 +5407,18 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
5339 | return -EINVAL; | 5407 | return -EINVAL; |
5340 | 5408 | ||
5341 | if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { | 5409 | if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { |
5410 | bool no_ht = false; | ||
5411 | |||
5342 | connkeys = nl80211_parse_connkeys(rdev, | 5412 | connkeys = nl80211_parse_connkeys(rdev, |
5343 | info->attrs[NL80211_ATTR_KEYS]); | 5413 | info->attrs[NL80211_ATTR_KEYS], |
5414 | &no_ht); | ||
5344 | if (IS_ERR(connkeys)) | 5415 | if (IS_ERR(connkeys)) |
5345 | return PTR_ERR(connkeys); | 5416 | return PTR_ERR(connkeys); |
5417 | |||
5418 | if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { | ||
5419 | kfree(connkeys); | ||
5420 | return -EINVAL; | ||
5421 | } | ||
5346 | } | 5422 | } |
5347 | 5423 | ||
5348 | ibss.control_port = | 5424 | ibss.control_port = |
@@ -5384,7 +5460,7 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | |||
5384 | err = -EOPNOTSUPP; | 5460 | err = -EOPNOTSUPP; |
5385 | if (rdev->ops->testmode_cmd) { | 5461 | if (rdev->ops->testmode_cmd) { |
5386 | rdev->testmode_info = info; | 5462 | rdev->testmode_info = info; |
5387 | err = rdev->ops->testmode_cmd(&rdev->wiphy, | 5463 | err = rdev_testmode_cmd(rdev, |
5388 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), | 5464 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), |
5389 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); | 5465 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); |
5390 | rdev->testmode_info = NULL; | 5466 | rdev->testmode_info = NULL; |
@@ -5466,8 +5542,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb, | |||
5466 | genlmsg_cancel(skb, hdr); | 5542 | genlmsg_cancel(skb, hdr); |
5467 | break; | 5543 | break; |
5468 | } | 5544 | } |
5469 | err = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb, | 5545 | err = rdev_testmode_dump(rdev, skb, cb, data, data_len); |
5470 | data, data_len); | ||
5471 | nla_nest_end(skb, tmdata); | 5546 | nla_nest_end(skb, tmdata); |
5472 | 5547 | ||
5473 | if (err == -ENOBUFS || err == -ENOENT) { | 5548 | if (err == -ENOBUFS || err == -ENOENT) { |
@@ -5596,7 +5671,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
5596 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { | 5671 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { |
5597 | connect.auth_type = | 5672 | connect.auth_type = |
5598 | nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); | 5673 | nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); |
5599 | if (!nl80211_valid_auth_type(connect.auth_type)) | 5674 | if (!nl80211_valid_auth_type(rdev, connect.auth_type, |
5675 | NL80211_CMD_CONNECT)) | ||
5600 | return -EINVAL; | 5676 | return -EINVAL; |
5601 | } else | 5677 | } else |
5602 | connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 5678 | connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
@@ -5642,7 +5718,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
5642 | 5718 | ||
5643 | if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { | 5719 | if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { |
5644 | connkeys = nl80211_parse_connkeys(rdev, | 5720 | connkeys = nl80211_parse_connkeys(rdev, |
5645 | info->attrs[NL80211_ATTR_KEYS]); | 5721 | info->attrs[NL80211_ATTR_KEYS], NULL); |
5646 | if (IS_ERR(connkeys)) | 5722 | if (IS_ERR(connkeys)) |
5647 | return PTR_ERR(connkeys); | 5723 | return PTR_ERR(connkeys); |
5648 | } | 5724 | } |
@@ -5771,7 +5847,7 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) | |||
5771 | if (!rdev->ops->flush_pmksa) | 5847 | if (!rdev->ops->flush_pmksa) |
5772 | return -EOPNOTSUPP; | 5848 | return -EOPNOTSUPP; |
5773 | 5849 | ||
5774 | return rdev->ops->flush_pmksa(&rdev->wiphy, dev); | 5850 | return rdev_flush_pmksa(rdev, dev); |
5775 | } | 5851 | } |
5776 | 5852 | ||
5777 | static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | 5853 | static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) |
@@ -5798,10 +5874,10 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5798 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); | 5874 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); |
5799 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); | 5875 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); |
5800 | 5876 | ||
5801 | return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | 5877 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, |
5802 | dialog_token, status_code, | 5878 | dialog_token, status_code, |
5803 | nla_data(info->attrs[NL80211_ATTR_IE]), | 5879 | nla_data(info->attrs[NL80211_ATTR_IE]), |
5804 | nla_len(info->attrs[NL80211_ATTR_IE])); | 5880 | nla_len(info->attrs[NL80211_ATTR_IE])); |
5805 | } | 5881 | } |
5806 | 5882 | ||
5807 | static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) | 5883 | static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) |
@@ -5822,7 +5898,7 @@ static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) | |||
5822 | operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]); | 5898 | operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]); |
5823 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5899 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5824 | 5900 | ||
5825 | return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation); | 5901 | return rdev_tdls_oper(rdev, dev, peer, operation); |
5826 | } | 5902 | } |
5827 | 5903 | ||
5828 | static int nl80211_remain_on_channel(struct sk_buff *skb, | 5904 | static int nl80211_remain_on_channel(struct sk_buff *skb, |
@@ -5877,8 +5953,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, | |||
5877 | goto free_msg; | 5953 | goto free_msg; |
5878 | } | 5954 | } |
5879 | 5955 | ||
5880 | err = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, | 5956 | err = rdev_remain_on_channel(rdev, wdev, chan, channel_type, duration, |
5881 | channel_type, duration, &cookie); | 5957 | &cookie); |
5882 | 5958 | ||
5883 | if (err) | 5959 | if (err) |
5884 | goto free_msg; | 5960 | goto free_msg; |
@@ -5912,7 +5988,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, | |||
5912 | 5988 | ||
5913 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 5989 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
5914 | 5990 | ||
5915 | return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); | 5991 | return rdev_cancel_remain_on_channel(rdev, wdev, cookie); |
5916 | } | 5992 | } |
5917 | 5993 | ||
5918 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, | 5994 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, |
@@ -6055,7 +6131,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, | |||
6055 | } | 6131 | } |
6056 | } | 6132 | } |
6057 | 6133 | ||
6058 | return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); | 6134 | return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); |
6059 | } | 6135 | } |
6060 | 6136 | ||
6061 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | 6137 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) |
@@ -6230,7 +6306,7 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in | |||
6230 | 6306 | ||
6231 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 6307 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
6232 | 6308 | ||
6233 | return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); | 6309 | return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie); |
6234 | } | 6310 | } |
6235 | 6311 | ||
6236 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | 6312 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) |
@@ -6260,8 +6336,7 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | |||
6260 | if (state == wdev->ps) | 6336 | if (state == wdev->ps) |
6261 | return 0; | 6337 | return 0; |
6262 | 6338 | ||
6263 | err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state, | 6339 | err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout); |
6264 | wdev->ps_timeout); | ||
6265 | if (!err) | 6340 | if (!err) |
6266 | wdev->ps = state; | 6341 | wdev->ps = state; |
6267 | return err; | 6342 | return err; |
@@ -6341,8 +6416,7 @@ static int nl80211_set_cqm_txe(struct genl_info *info, | |||
6341 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6416 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) |
6342 | return -EOPNOTSUPP; | 6417 | return -EOPNOTSUPP; |
6343 | 6418 | ||
6344 | return rdev->ops->set_cqm_txe_config(wdev->wiphy, dev, | 6419 | return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl); |
6345 | rate, pkts, intvl); | ||
6346 | } | 6420 | } |
6347 | 6421 | ||
6348 | static int nl80211_set_cqm_rssi(struct genl_info *info, | 6422 | static int nl80211_set_cqm_rssi(struct genl_info *info, |
@@ -6364,8 +6438,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, | |||
6364 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6438 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) |
6365 | return -EOPNOTSUPP; | 6439 | return -EOPNOTSUPP; |
6366 | 6440 | ||
6367 | return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, | 6441 | return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis); |
6368 | threshold, hysteresis); | ||
6369 | } | 6442 | } |
6370 | 6443 | ||
6371 | static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | 6444 | static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) |
@@ -6690,7 +6763,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6690 | 6763 | ||
6691 | set_wakeup: | 6764 | set_wakeup: |
6692 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) | 6765 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) |
6693 | rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan); | 6766 | rdev_set_wakeup(rdev, rdev->wowlan); |
6694 | 6767 | ||
6695 | return 0; | 6768 | return 0; |
6696 | error: | 6769 | error: |
@@ -6746,7 +6819,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | |||
6746 | goto out; | 6819 | goto out; |
6747 | } | 6820 | } |
6748 | 6821 | ||
6749 | err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data); | 6822 | err = rdev_set_rekey_data(rdev, dev, &rekey_data); |
6750 | out: | 6823 | out: |
6751 | wdev_unlock(wdev); | 6824 | wdev_unlock(wdev); |
6752 | return err; | 6825 | return err; |
@@ -6805,7 +6878,7 @@ static int nl80211_probe_client(struct sk_buff *skb, | |||
6805 | 6878 | ||
6806 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 6879 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
6807 | 6880 | ||
6808 | err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie); | 6881 | err = rdev_probe_client(rdev, dev, addr, &cookie); |
6809 | if (err) | 6882 | if (err) |
6810 | goto free_msg; | 6883 | goto free_msg; |
6811 | 6884 | ||
@@ -6859,7 +6932,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) | |||
6859 | if (err) | 6932 | if (err) |
6860 | return err; | 6933 | return err; |
6861 | 6934 | ||
6862 | err = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); | 6935 | err = rdev_start_p2p_device(rdev, wdev); |
6863 | if (err) | 6936 | if (err) |
6864 | return err; | 6937 | return err; |
6865 | 6938 | ||
@@ -6885,7 +6958,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) | |||
6885 | if (!wdev->p2p_started) | 6958 | if (!wdev->p2p_started) |
6886 | return 0; | 6959 | return 0; |
6887 | 6960 | ||
6888 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | 6961 | rdev_stop_p2p_device(rdev, wdev); |
6889 | wdev->p2p_started = false; | 6962 | wdev->p2p_started = false; |
6890 | 6963 | ||
6891 | mutex_lock(&rdev->devlist_mtx); | 6964 | mutex_lock(&rdev->devlist_mtx); |
@@ -7622,6 +7695,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
7622 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) | 7695 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) |
7623 | goto nla_put_failure; | 7696 | goto nla_put_failure; |
7624 | 7697 | ||
7698 | if (req->flags) | ||
7699 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); | ||
7700 | |||
7625 | return 0; | 7701 | return 0; |
7626 | nla_put_failure: | 7702 | nla_put_failure: |
7627 | return -ENOBUFS; | 7703 | return -ENOBUFS; |
@@ -8800,7 +8876,10 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
8800 | void *hdr; | 8876 | void *hdr; |
8801 | int err; | 8877 | int err; |
8802 | 8878 | ||
8879 | trace_cfg80211_probe_status(dev, addr, cookie, acked); | ||
8880 | |||
8803 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8881 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8882 | |||
8804 | if (!msg) | 8883 | if (!msg) |
8805 | return; | 8884 | return; |
8806 | 8885 | ||
@@ -8842,6 +8921,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
8842 | void *hdr; | 8921 | void *hdr; |
8843 | u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid); | 8922 | u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid); |
8844 | 8923 | ||
8924 | trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm); | ||
8925 | |||
8845 | if (!nlportid) | 8926 | if (!nlportid) |
8846 | return; | 8927 | return; |
8847 | 8928 | ||
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h new file mode 100644 index 000000000000..eb5f8974e148 --- /dev/null +++ b/net/wireless/rdev-ops.h | |||
@@ -0,0 +1,879 @@ | |||
1 | #ifndef __CFG80211_RDEV_OPS | ||
2 | #define __CFG80211_RDEV_OPS | ||
3 | |||
4 | #include <linux/rtnetlink.h> | ||
5 | #include <net/cfg80211.h> | ||
6 | #include "core.h" | ||
7 | #include "trace.h" | ||
8 | |||
9 | static inline int rdev_suspend(struct cfg80211_registered_device *rdev) | ||
10 | { | ||
11 | int ret; | ||
12 | trace_rdev_suspend(&rdev->wiphy, rdev->wowlan); | ||
13 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | ||
14 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
15 | return ret; | ||
16 | } | ||
17 | |||
18 | static inline int rdev_resume(struct cfg80211_registered_device *rdev) | ||
19 | { | ||
20 | int ret; | ||
21 | trace_rdev_resume(&rdev->wiphy); | ||
22 | ret = rdev->ops->resume(&rdev->wiphy); | ||
23 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
24 | return ret; | ||
25 | } | ||
26 | |||
27 | static inline void rdev_set_wakeup(struct cfg80211_registered_device *rdev, | ||
28 | bool enabled) | ||
29 | { | ||
30 | trace_rdev_set_wakeup(&rdev->wiphy, enabled); | ||
31 | rdev->ops->set_wakeup(&rdev->wiphy, enabled); | ||
32 | trace_rdev_return_void(&rdev->wiphy); | ||
33 | } | ||
34 | |||
35 | static inline struct wireless_dev | ||
36 | *rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name, | ||
37 | enum nl80211_iftype type, u32 *flags, | ||
38 | struct vif_params *params) | ||
39 | { | ||
40 | struct wireless_dev *ret; | ||
41 | trace_rdev_add_virtual_intf(&rdev->wiphy, name, type); | ||
42 | ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, type, flags, | ||
43 | params); | ||
44 | trace_rdev_return_wdev(&rdev->wiphy, ret); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | static inline int | ||
49 | rdev_del_virtual_intf(struct cfg80211_registered_device *rdev, | ||
50 | struct wireless_dev *wdev) | ||
51 | { | ||
52 | int ret; | ||
53 | trace_rdev_del_virtual_intf(&rdev->wiphy, wdev); | ||
54 | ret = rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); | ||
55 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | static inline int | ||
60 | rdev_change_virtual_intf(struct cfg80211_registered_device *rdev, | ||
61 | struct net_device *dev, enum nl80211_iftype type, | ||
62 | u32 *flags, struct vif_params *params) | ||
63 | { | ||
64 | int ret; | ||
65 | trace_rdev_change_virtual_intf(&rdev->wiphy, dev, type); | ||
66 | ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, flags, | ||
67 | params); | ||
68 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | static inline int rdev_add_key(struct cfg80211_registered_device *rdev, | ||
73 | struct net_device *netdev, u8 key_index, | ||
74 | bool pairwise, const u8 *mac_addr, | ||
75 | struct key_params *params) | ||
76 | { | ||
77 | int ret; | ||
78 | trace_rdev_add_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); | ||
79 | ret = rdev->ops->add_key(&rdev->wiphy, netdev, key_index, pairwise, | ||
80 | mac_addr, params); | ||
81 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static inline int | ||
86 | rdev_get_key(struct cfg80211_registered_device *rdev, struct net_device *netdev, | ||
87 | u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, | ||
88 | void (*callback)(void *cookie, struct key_params*)) | ||
89 | { | ||
90 | int ret; | ||
91 | trace_rdev_get_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); | ||
92 | ret = rdev->ops->get_key(&rdev->wiphy, netdev, key_index, pairwise, | ||
93 | mac_addr, cookie, callback); | ||
94 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | static inline int rdev_del_key(struct cfg80211_registered_device *rdev, | ||
99 | struct net_device *netdev, u8 key_index, | ||
100 | bool pairwise, const u8 *mac_addr) | ||
101 | { | ||
102 | int ret; | ||
103 | trace_rdev_del_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); | ||
104 | ret = rdev->ops->del_key(&rdev->wiphy, netdev, key_index, pairwise, | ||
105 | mac_addr); | ||
106 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static inline int | ||
111 | rdev_set_default_key(struct cfg80211_registered_device *rdev, | ||
112 | struct net_device *netdev, u8 key_index, bool unicast, | ||
113 | bool multicast) | ||
114 | { | ||
115 | int ret; | ||
116 | trace_rdev_set_default_key(&rdev->wiphy, netdev, key_index, | ||
117 | unicast, multicast); | ||
118 | ret = rdev->ops->set_default_key(&rdev->wiphy, netdev, key_index, | ||
119 | unicast, multicast); | ||
120 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static inline int | ||
125 | rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev, | ||
126 | struct net_device *netdev, u8 key_index) | ||
127 | { | ||
128 | int ret; | ||
129 | trace_rdev_set_default_mgmt_key(&rdev->wiphy, netdev, key_index); | ||
130 | ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, netdev, | ||
131 | key_index); | ||
132 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static inline int rdev_start_ap(struct cfg80211_registered_device *rdev, | ||
137 | struct net_device *dev, | ||
138 | struct cfg80211_ap_settings *settings) | ||
139 | { | ||
140 | int ret; | ||
141 | trace_rdev_start_ap(&rdev->wiphy, dev, settings); | ||
142 | ret = rdev->ops->start_ap(&rdev->wiphy, dev, settings); | ||
143 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | static inline int rdev_change_beacon(struct cfg80211_registered_device *rdev, | ||
148 | struct net_device *dev, | ||
149 | struct cfg80211_beacon_data *info) | ||
150 | { | ||
151 | int ret; | ||
152 | trace_rdev_change_beacon(&rdev->wiphy, dev, info); | ||
153 | ret = rdev->ops->change_beacon(&rdev->wiphy, dev, info); | ||
154 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static inline int rdev_stop_ap(struct cfg80211_registered_device *rdev, | ||
159 | struct net_device *dev) | ||
160 | { | ||
161 | int ret; | ||
162 | trace_rdev_stop_ap(&rdev->wiphy, dev); | ||
163 | ret = rdev->ops->stop_ap(&rdev->wiphy, dev); | ||
164 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | static inline int rdev_add_station(struct cfg80211_registered_device *rdev, | ||
169 | struct net_device *dev, u8 *mac, | ||
170 | struct station_parameters *params) | ||
171 | { | ||
172 | int ret; | ||
173 | trace_rdev_add_station(&rdev->wiphy, dev, mac, params); | ||
174 | ret = rdev->ops->add_station(&rdev->wiphy, dev, mac, params); | ||
175 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static inline int rdev_del_station(struct cfg80211_registered_device *rdev, | ||
180 | struct net_device *dev, u8 *mac) | ||
181 | { | ||
182 | int ret; | ||
183 | trace_rdev_del_station(&rdev->wiphy, dev, mac); | ||
184 | ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); | ||
185 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | static inline int rdev_change_station(struct cfg80211_registered_device *rdev, | ||
190 | struct net_device *dev, u8 *mac, | ||
191 | struct station_parameters *params) | ||
192 | { | ||
193 | int ret; | ||
194 | trace_rdev_change_station(&rdev->wiphy, dev, mac, params); | ||
195 | ret = rdev->ops->change_station(&rdev->wiphy, dev, mac, params); | ||
196 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | static inline int rdev_get_station(struct cfg80211_registered_device *rdev, | ||
201 | struct net_device *dev, u8 *mac, | ||
202 | struct station_info *sinfo) | ||
203 | { | ||
204 | int ret; | ||
205 | trace_rdev_get_station(&rdev->wiphy, dev, mac); | ||
206 | ret = rdev->ops->get_station(&rdev->wiphy, dev, mac, sinfo); | ||
207 | trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static inline int rdev_dump_station(struct cfg80211_registered_device *rdev, | ||
212 | struct net_device *dev, int idx, u8 *mac, | ||
213 | struct station_info *sinfo) | ||
214 | { | ||
215 | int ret; | ||
216 | trace_rdev_dump_station(&rdev->wiphy, dev, idx, mac); | ||
217 | ret = rdev->ops->dump_station(&rdev->wiphy, dev, idx, mac, sinfo); | ||
218 | trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo); | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | static inline int rdev_add_mpath(struct cfg80211_registered_device *rdev, | ||
223 | struct net_device *dev, u8 *dst, u8 *next_hop) | ||
224 | { | ||
225 | int ret; | ||
226 | trace_rdev_add_mpath(&rdev->wiphy, dev, dst, next_hop); | ||
227 | ret = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); | ||
228 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static inline int rdev_del_mpath(struct cfg80211_registered_device *rdev, | ||
233 | struct net_device *dev, u8 *dst) | ||
234 | { | ||
235 | int ret; | ||
236 | trace_rdev_del_mpath(&rdev->wiphy, dev, dst); | ||
237 | ret = rdev->ops->del_mpath(&rdev->wiphy, dev, dst); | ||
238 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static inline int rdev_change_mpath(struct cfg80211_registered_device *rdev, | ||
243 | struct net_device *dev, u8 *dst, | ||
244 | u8 *next_hop) | ||
245 | { | ||
246 | int ret; | ||
247 | trace_rdev_change_mpath(&rdev->wiphy, dev, dst, next_hop); | ||
248 | ret = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); | ||
249 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, | ||
254 | struct net_device *dev, u8 *dst, u8 *next_hop, | ||
255 | struct mpath_info *pinfo) | ||
256 | { | ||
257 | int ret; | ||
258 | trace_rdev_get_mpath(&rdev->wiphy, dev, dst, next_hop); | ||
259 | ret = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, pinfo); | ||
260 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
261 | return ret; | ||
262 | |||
263 | } | ||
264 | |||
265 | static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, | ||
266 | struct net_device *dev, int idx, u8 *dst, | ||
267 | u8 *next_hop, struct mpath_info *pinfo) | ||
268 | |||
269 | { | ||
270 | int ret; | ||
271 | trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); | ||
272 | ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, | ||
273 | pinfo); | ||
274 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static inline int | ||
279 | rdev_get_mesh_config(struct cfg80211_registered_device *rdev, | ||
280 | struct net_device *dev, struct mesh_config *conf) | ||
281 | { | ||
282 | int ret; | ||
283 | trace_rdev_get_mesh_config(&rdev->wiphy, dev); | ||
284 | ret = rdev->ops->get_mesh_config(&rdev->wiphy, dev, conf); | ||
285 | trace_rdev_return_int_mesh_config(&rdev->wiphy, ret, conf); | ||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static inline int | ||
290 | rdev_update_mesh_config(struct cfg80211_registered_device *rdev, | ||
291 | struct net_device *dev, u32 mask, | ||
292 | const struct mesh_config *nconf) | ||
293 | { | ||
294 | int ret; | ||
295 | trace_rdev_update_mesh_config(&rdev->wiphy, dev, mask, nconf); | ||
296 | ret = rdev->ops->update_mesh_config(&rdev->wiphy, dev, mask, nconf); | ||
297 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | static inline int rdev_join_mesh(struct cfg80211_registered_device *rdev, | ||
302 | struct net_device *dev, | ||
303 | const struct mesh_config *conf, | ||
304 | const struct mesh_setup *setup) | ||
305 | { | ||
306 | int ret; | ||
307 | trace_rdev_join_mesh(&rdev->wiphy, dev, conf, setup); | ||
308 | ret = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); | ||
309 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | |||
314 | static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev, | ||
315 | struct net_device *dev) | ||
316 | { | ||
317 | int ret; | ||
318 | trace_rdev_leave_mesh(&rdev->wiphy, dev); | ||
319 | ret = rdev->ops->leave_mesh(&rdev->wiphy, dev); | ||
320 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, | ||
325 | struct net_device *dev, | ||
326 | struct bss_parameters *params) | ||
327 | |||
328 | { | ||
329 | int ret; | ||
330 | trace_rdev_change_bss(&rdev->wiphy, dev, params); | ||
331 | ret = rdev->ops->change_bss(&rdev->wiphy, dev, params); | ||
332 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | static inline int rdev_set_txq_params(struct cfg80211_registered_device *rdev, | ||
337 | struct net_device *dev, | ||
338 | struct ieee80211_txq_params *params) | ||
339 | |||
340 | { | ||
341 | int ret; | ||
342 | trace_rdev_set_txq_params(&rdev->wiphy, dev, params); | ||
343 | ret = rdev->ops->set_txq_params(&rdev->wiphy, dev, params); | ||
344 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | static inline int | ||
349 | rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev, | ||
350 | struct net_device *dev, | ||
351 | struct ieee80211_channel *chan) | ||
352 | { | ||
353 | int ret; | ||
354 | trace_rdev_libertas_set_mesh_channel(&rdev->wiphy, dev, chan); | ||
355 | ret = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, dev, chan); | ||
356 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | static inline int | ||
361 | rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, | ||
362 | struct ieee80211_channel *chan, | ||
363 | enum nl80211_channel_type channel_type) | ||
364 | { | ||
365 | int ret; | ||
366 | trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type); | ||
367 | ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type); | ||
368 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static inline int rdev_scan(struct cfg80211_registered_device *rdev, | ||
373 | struct cfg80211_scan_request *request) | ||
374 | { | ||
375 | int ret; | ||
376 | trace_rdev_scan(&rdev->wiphy, request); | ||
377 | ret = rdev->ops->scan(&rdev->wiphy, request); | ||
378 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | static inline int rdev_auth(struct cfg80211_registered_device *rdev, | ||
383 | struct net_device *dev, | ||
384 | struct cfg80211_auth_request *req) | ||
385 | { | ||
386 | int ret; | ||
387 | trace_rdev_auth(&rdev->wiphy, dev, req); | ||
388 | ret = rdev->ops->auth(&rdev->wiphy, dev, req); | ||
389 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | static inline int rdev_assoc(struct cfg80211_registered_device *rdev, | ||
394 | struct net_device *dev, | ||
395 | struct cfg80211_assoc_request *req) | ||
396 | { | ||
397 | int ret; | ||
398 | trace_rdev_assoc(&rdev->wiphy, dev, req); | ||
399 | ret = rdev->ops->assoc(&rdev->wiphy, dev, req); | ||
400 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | static inline int rdev_deauth(struct cfg80211_registered_device *rdev, | ||
405 | struct net_device *dev, | ||
406 | struct cfg80211_deauth_request *req) | ||
407 | { | ||
408 | int ret; | ||
409 | trace_rdev_deauth(&rdev->wiphy, dev, req); | ||
410 | ret = rdev->ops->deauth(&rdev->wiphy, dev, req); | ||
411 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | static inline int rdev_disassoc(struct cfg80211_registered_device *rdev, | ||
416 | struct net_device *dev, | ||
417 | struct cfg80211_disassoc_request *req) | ||
418 | { | ||
419 | int ret; | ||
420 | trace_rdev_disassoc(&rdev->wiphy, dev, req); | ||
421 | ret = rdev->ops->disassoc(&rdev->wiphy, dev, req); | ||
422 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | static inline int rdev_connect(struct cfg80211_registered_device *rdev, | ||
427 | struct net_device *dev, | ||
428 | struct cfg80211_connect_params *sme) | ||
429 | { | ||
430 | int ret; | ||
431 | trace_rdev_connect(&rdev->wiphy, dev, sme); | ||
432 | ret = rdev->ops->connect(&rdev->wiphy, dev, sme); | ||
433 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | static inline int rdev_disconnect(struct cfg80211_registered_device *rdev, | ||
438 | struct net_device *dev, u16 reason_code) | ||
439 | { | ||
440 | int ret; | ||
441 | trace_rdev_disconnect(&rdev->wiphy, dev, reason_code); | ||
442 | ret = rdev->ops->disconnect(&rdev->wiphy, dev, reason_code); | ||
443 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | static inline int rdev_join_ibss(struct cfg80211_registered_device *rdev, | ||
448 | struct net_device *dev, | ||
449 | struct cfg80211_ibss_params *params) | ||
450 | { | ||
451 | int ret; | ||
452 | trace_rdev_join_ibss(&rdev->wiphy, dev, params); | ||
453 | ret = rdev->ops->join_ibss(&rdev->wiphy, dev, params); | ||
454 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | static inline int rdev_leave_ibss(struct cfg80211_registered_device *rdev, | ||
459 | struct net_device *dev) | ||
460 | { | ||
461 | int ret; | ||
462 | trace_rdev_leave_ibss(&rdev->wiphy, dev); | ||
463 | ret = rdev->ops->leave_ibss(&rdev->wiphy, dev); | ||
464 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | static inline int | ||
469 | rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed) | ||
470 | { | ||
471 | int ret; | ||
472 | trace_rdev_set_wiphy_params(&rdev->wiphy, changed); | ||
473 | ret = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); | ||
474 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, | ||
479 | enum nl80211_tx_power_setting type, int mbm) | ||
480 | { | ||
481 | int ret; | ||
482 | trace_rdev_set_tx_power(&rdev->wiphy, type, mbm); | ||
483 | ret = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); | ||
484 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, | ||
489 | int *dbm) | ||
490 | { | ||
491 | int ret; | ||
492 | trace_rdev_get_tx_power(&rdev->wiphy); | ||
493 | ret = rdev->ops->get_tx_power(&rdev->wiphy, dbm); | ||
494 | trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); | ||
495 | return ret; | ||
496 | } | ||
497 | |||
498 | static inline int rdev_set_wds_peer(struct cfg80211_registered_device *rdev, | ||
499 | struct net_device *dev, const u8 *addr) | ||
500 | { | ||
501 | int ret; | ||
502 | trace_rdev_set_wds_peer(&rdev->wiphy, dev, addr); | ||
503 | ret = rdev->ops->set_wds_peer(&rdev->wiphy, dev, addr); | ||
504 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | static inline void rdev_rfkill_poll(struct cfg80211_registered_device *rdev) | ||
509 | { | ||
510 | trace_rdev_rfkill_poll(&rdev->wiphy); | ||
511 | rdev->ops->rfkill_poll(&rdev->wiphy); | ||
512 | trace_rdev_return_void(&rdev->wiphy); | ||
513 | } | ||
514 | |||
515 | |||
516 | #ifdef CONFIG_NL80211_TESTMODE | ||
517 | static inline int rdev_testmode_cmd(struct cfg80211_registered_device *rdev, | ||
518 | void *data, int len) | ||
519 | { | ||
520 | int ret; | ||
521 | trace_rdev_testmode_cmd(&rdev->wiphy); | ||
522 | ret = rdev->ops->testmode_cmd(&rdev->wiphy, data, len); | ||
523 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
524 | return ret; | ||
525 | } | ||
526 | |||
527 | static inline int rdev_testmode_dump(struct cfg80211_registered_device *rdev, | ||
528 | struct sk_buff *skb, | ||
529 | struct netlink_callback *cb, void *data, | ||
530 | int len) | ||
531 | { | ||
532 | int ret; | ||
533 | trace_rdev_testmode_dump(&rdev->wiphy); | ||
534 | ret = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb, data, len); | ||
535 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
536 | return ret; | ||
537 | } | ||
538 | #endif | ||
539 | |||
540 | static inline int | ||
541 | rdev_set_bitrate_mask(struct cfg80211_registered_device *rdev, | ||
542 | struct net_device *dev, const u8 *peer, | ||
543 | const struct cfg80211_bitrate_mask *mask) | ||
544 | { | ||
545 | int ret; | ||
546 | trace_rdev_set_bitrate_mask(&rdev->wiphy, dev, peer, mask); | ||
547 | ret = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, peer, mask); | ||
548 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
549 | return ret; | ||
550 | } | ||
551 | |||
552 | static inline int rdev_dump_survey(struct cfg80211_registered_device *rdev, | ||
553 | struct net_device *netdev, int idx, | ||
554 | struct survey_info *info) | ||
555 | { | ||
556 | int ret; | ||
557 | trace_rdev_dump_survey(&rdev->wiphy, netdev, idx); | ||
558 | ret = rdev->ops->dump_survey(&rdev->wiphy, netdev, idx, info); | ||
559 | if (ret < 0) | ||
560 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
561 | else | ||
562 | trace_rdev_return_int_survey_info(&rdev->wiphy, ret, info); | ||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | static inline int rdev_set_pmksa(struct cfg80211_registered_device *rdev, | ||
567 | struct net_device *netdev, | ||
568 | struct cfg80211_pmksa *pmksa) | ||
569 | { | ||
570 | int ret; | ||
571 | trace_rdev_set_pmksa(&rdev->wiphy, netdev, pmksa); | ||
572 | ret = rdev->ops->set_pmksa(&rdev->wiphy, netdev, pmksa); | ||
573 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
574 | return ret; | ||
575 | } | ||
576 | |||
577 | static inline int rdev_del_pmksa(struct cfg80211_registered_device *rdev, | ||
578 | struct net_device *netdev, | ||
579 | struct cfg80211_pmksa *pmksa) | ||
580 | { | ||
581 | int ret; | ||
582 | trace_rdev_del_pmksa(&rdev->wiphy, netdev, pmksa); | ||
583 | ret = rdev->ops->del_pmksa(&rdev->wiphy, netdev, pmksa); | ||
584 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | static inline int rdev_flush_pmksa(struct cfg80211_registered_device *rdev, | ||
589 | struct net_device *netdev) | ||
590 | { | ||
591 | int ret; | ||
592 | trace_rdev_flush_pmksa(&rdev->wiphy, netdev); | ||
593 | ret = rdev->ops->flush_pmksa(&rdev->wiphy, netdev); | ||
594 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | static inline int | ||
599 | rdev_remain_on_channel(struct cfg80211_registered_device *rdev, | ||
600 | struct wireless_dev *wdev, | ||
601 | struct ieee80211_channel *chan, | ||
602 | enum nl80211_channel_type channel_type, | ||
603 | unsigned int duration, u64 *cookie) | ||
604 | { | ||
605 | int ret; | ||
606 | trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, channel_type, | ||
607 | duration); | ||
608 | ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, | ||
609 | channel_type, duration, cookie); | ||
610 | trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | static inline int | ||
615 | rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev, | ||
616 | struct wireless_dev *wdev, u64 cookie) | ||
617 | { | ||
618 | int ret; | ||
619 | trace_rdev_cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); | ||
620 | ret = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); | ||
621 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
622 | return ret; | ||
623 | } | ||
624 | |||
625 | static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, | ||
626 | struct wireless_dev *wdev, | ||
627 | struct ieee80211_channel *chan, bool offchan, | ||
628 | enum nl80211_channel_type channel_type, | ||
629 | bool channel_type_valid, unsigned int wait, | ||
630 | const u8 *buf, size_t len, bool no_cck, | ||
631 | bool dont_wait_for_ack, u64 *cookie) | ||
632 | { | ||
633 | int ret; | ||
634 | trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, channel_type, | ||
635 | channel_type_valid, wait, no_cck, dont_wait_for_ack); | ||
636 | ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, | ||
637 | channel_type, channel_type_valid, wait, buf, | ||
638 | len, no_cck, dont_wait_for_ack, cookie); | ||
639 | trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); | ||
640 | return ret; | ||
641 | } | ||
642 | |||
643 | static inline int | ||
644 | rdev_mgmt_tx_cancel_wait(struct cfg80211_registered_device *rdev, | ||
645 | struct wireless_dev *wdev, u64 cookie) | ||
646 | { | ||
647 | int ret; | ||
648 | trace_rdev_mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); | ||
649 | ret = rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); | ||
650 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
651 | return ret; | ||
652 | } | ||
653 | |||
654 | static inline int rdev_set_power_mgmt(struct cfg80211_registered_device *rdev, | ||
655 | struct net_device *dev, bool enabled, | ||
656 | int timeout) | ||
657 | { | ||
658 | int ret; | ||
659 | trace_rdev_set_power_mgmt(&rdev->wiphy, dev, enabled, timeout); | ||
660 | ret = rdev->ops->set_power_mgmt(&rdev->wiphy, dev, enabled, timeout); | ||
661 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | static inline int | ||
666 | rdev_set_cqm_rssi_config(struct cfg80211_registered_device *rdev, | ||
667 | struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) | ||
668 | { | ||
669 | int ret; | ||
670 | trace_rdev_set_cqm_rssi_config(&rdev->wiphy, dev, rssi_thold, | ||
671 | rssi_hyst); | ||
672 | ret = rdev->ops->set_cqm_rssi_config(&rdev->wiphy, dev, rssi_thold, | ||
673 | rssi_hyst); | ||
674 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | static inline int | ||
679 | rdev_set_cqm_txe_config(struct cfg80211_registered_device *rdev, | ||
680 | struct net_device *dev, u32 rate, u32 pkts, u32 intvl) | ||
681 | { | ||
682 | int ret; | ||
683 | trace_rdev_set_cqm_txe_config(&rdev->wiphy, dev, rate, pkts, intvl); | ||
684 | ret = rdev->ops->set_cqm_txe_config(&rdev->wiphy, dev, rate, pkts, | ||
685 | intvl); | ||
686 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
687 | return ret; | ||
688 | } | ||
689 | |||
690 | static inline void | ||
691 | rdev_mgmt_frame_register(struct cfg80211_registered_device *rdev, | ||
692 | struct wireless_dev *wdev, u16 frame_type, bool reg) | ||
693 | { | ||
694 | trace_rdev_mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); | ||
695 | rdev->ops->mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); | ||
696 | trace_rdev_return_void(&rdev->wiphy); | ||
697 | } | ||
698 | |||
699 | static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev, | ||
700 | u32 tx_ant, u32 rx_ant) | ||
701 | { | ||
702 | int ret; | ||
703 | trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant); | ||
704 | ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); | ||
705 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev, | ||
710 | u32 *tx_ant, u32 *rx_ant) | ||
711 | { | ||
712 | int ret; | ||
713 | trace_rdev_get_antenna(&rdev->wiphy); | ||
714 | ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant); | ||
715 | if (ret) | ||
716 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
717 | else | ||
718 | trace_rdev_return_int_tx_rx(&rdev->wiphy, ret, *tx_ant, | ||
719 | *rx_ant); | ||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev, | ||
724 | u32 tx, u32 rx) | ||
725 | { | ||
726 | int ret; | ||
727 | trace_rdev_set_ringparam(&rdev->wiphy, tx, rx); | ||
728 | ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx); | ||
729 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
730 | return ret; | ||
731 | } | ||
732 | |||
733 | static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev, | ||
734 | u32 *tx, u32 *tx_max, u32 *rx, | ||
735 | u32 *rx_max) | ||
736 | { | ||
737 | trace_rdev_get_ringparam(&rdev->wiphy); | ||
738 | rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max); | ||
739 | trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max); | ||
740 | } | ||
741 | |||
742 | static inline int | ||
743 | rdev_sched_scan_start(struct cfg80211_registered_device *rdev, | ||
744 | struct net_device *dev, | ||
745 | struct cfg80211_sched_scan_request *request) | ||
746 | { | ||
747 | int ret; | ||
748 | trace_rdev_sched_scan_start(&rdev->wiphy, dev, request); | ||
749 | ret = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); | ||
750 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | static inline int rdev_sched_scan_stop(struct cfg80211_registered_device *rdev, | ||
755 | struct net_device *dev) | ||
756 | { | ||
757 | int ret; | ||
758 | trace_rdev_sched_scan_stop(&rdev->wiphy, dev); | ||
759 | ret = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); | ||
760 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
761 | return ret; | ||
762 | } | ||
763 | |||
764 | static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev, | ||
765 | struct net_device *dev, | ||
766 | struct cfg80211_gtk_rekey_data *data) | ||
767 | { | ||
768 | int ret; | ||
769 | trace_rdev_set_rekey_data(&rdev->wiphy, dev); | ||
770 | ret = rdev->ops->set_rekey_data(&rdev->wiphy, dev, data); | ||
771 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, | ||
776 | struct net_device *dev, u8 *peer, | ||
777 | u8 action_code, u8 dialog_token, | ||
778 | u16 status_code, const u8 *buf, size_t len) | ||
779 | { | ||
780 | int ret; | ||
781 | trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | ||
782 | dialog_token, status_code, buf, len); | ||
783 | ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | ||
784 | dialog_token, status_code, buf, len); | ||
785 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
786 | return ret; | ||
787 | } | ||
788 | |||
789 | static inline int rdev_tdls_oper(struct cfg80211_registered_device *rdev, | ||
790 | struct net_device *dev, u8 *peer, | ||
791 | enum nl80211_tdls_operation oper) | ||
792 | { | ||
793 | int ret; | ||
794 | trace_rdev_tdls_oper(&rdev->wiphy, dev, peer, oper); | ||
795 | ret = rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, oper); | ||
796 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
797 | return ret; | ||
798 | } | ||
799 | |||
800 | static inline int rdev_probe_client(struct cfg80211_registered_device *rdev, | ||
801 | struct net_device *dev, const u8 *peer, | ||
802 | u64 *cookie) | ||
803 | { | ||
804 | int ret; | ||
805 | trace_rdev_probe_client(&rdev->wiphy, dev, peer); | ||
806 | ret = rdev->ops->probe_client(&rdev->wiphy, dev, peer, cookie); | ||
807 | trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); | ||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | static inline int rdev_set_noack_map(struct cfg80211_registered_device *rdev, | ||
812 | struct net_device *dev, u16 noack_map) | ||
813 | { | ||
814 | int ret; | ||
815 | trace_rdev_set_noack_map(&rdev->wiphy, dev, noack_map); | ||
816 | ret = rdev->ops->set_noack_map(&rdev->wiphy, dev, noack_map); | ||
817 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
818 | return ret; | ||
819 | } | ||
820 | |||
821 | static inline int | ||
822 | rdev_get_et_sset_count(struct cfg80211_registered_device *rdev, | ||
823 | struct net_device *dev, int sset) | ||
824 | { | ||
825 | int ret; | ||
826 | trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset); | ||
827 | ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset); | ||
828 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
829 | return ret; | ||
830 | } | ||
831 | |||
832 | static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev, | ||
833 | struct net_device *dev, | ||
834 | struct ethtool_stats *stats, u64 *data) | ||
835 | { | ||
836 | trace_rdev_get_et_stats(&rdev->wiphy, dev); | ||
837 | rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data); | ||
838 | trace_rdev_return_void(&rdev->wiphy); | ||
839 | } | ||
840 | |||
841 | static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev, | ||
842 | struct net_device *dev, u32 sset, | ||
843 | u8 *data) | ||
844 | { | ||
845 | trace_rdev_get_et_strings(&rdev->wiphy, dev, sset); | ||
846 | rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data); | ||
847 | trace_rdev_return_void(&rdev->wiphy); | ||
848 | } | ||
849 | |||
850 | static inline struct ieee80211_channel | ||
851 | *rdev_get_channel(struct cfg80211_registered_device *rdev, | ||
852 | struct wireless_dev *wdev, enum nl80211_channel_type *type) | ||
853 | { | ||
854 | struct ieee80211_channel *ret; | ||
855 | trace_rdev_get_channel(&rdev->wiphy, wdev); | ||
856 | ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type); | ||
857 | trace_rdev_return_channel(&rdev->wiphy, ret, *type); | ||
858 | return ret; | ||
859 | } | ||
860 | |||
861 | static inline int rdev_start_p2p_device(struct cfg80211_registered_device *rdev, | ||
862 | struct wireless_dev *wdev) | ||
863 | { | ||
864 | int ret; | ||
865 | |||
866 | trace_rdev_start_p2p_device(&rdev->wiphy, wdev); | ||
867 | ret = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); | ||
868 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
869 | return ret; | ||
870 | } | ||
871 | |||
872 | static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev, | ||
873 | struct wireless_dev *wdev) | ||
874 | { | ||
875 | trace_rdev_stop_p2p_device(&rdev->wiphy, wdev); | ||
876 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
877 | trace_rdev_return_void(&rdev->wiphy); | ||
878 | } | ||
879 | #endif /* __CFG80211_RDEV_OPS */ | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 9730c9862bdc..7f97a087f452 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -17,9 +17,58 @@ | |||
17 | #include "core.h" | 17 | #include "core.h" |
18 | #include "nl80211.h" | 18 | #include "nl80211.h" |
19 | #include "wext-compat.h" | 19 | #include "wext-compat.h" |
20 | #include "rdev-ops.h" | ||
20 | 21 | ||
21 | #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) | 22 | #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) |
22 | 23 | ||
24 | static void bss_release(struct kref *ref) | ||
25 | { | ||
26 | struct cfg80211_internal_bss *bss; | ||
27 | |||
28 | bss = container_of(ref, struct cfg80211_internal_bss, ref); | ||
29 | if (bss->pub.free_priv) | ||
30 | bss->pub.free_priv(&bss->pub); | ||
31 | |||
32 | if (bss->beacon_ies_allocated) | ||
33 | kfree(bss->pub.beacon_ies); | ||
34 | if (bss->proberesp_ies_allocated) | ||
35 | kfree(bss->pub.proberesp_ies); | ||
36 | |||
37 | BUG_ON(atomic_read(&bss->hold)); | ||
38 | |||
39 | kfree(bss); | ||
40 | } | ||
41 | |||
42 | /* must hold dev->bss_lock! */ | ||
43 | static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, | ||
44 | struct cfg80211_internal_bss *bss) | ||
45 | { | ||
46 | list_del_init(&bss->list); | ||
47 | rb_erase(&bss->rbn, &dev->bss_tree); | ||
48 | kref_put(&bss->ref, bss_release); | ||
49 | } | ||
50 | |||
51 | /* must hold dev->bss_lock! */ | ||
52 | static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, | ||
53 | unsigned long expire_time) | ||
54 | { | ||
55 | struct cfg80211_internal_bss *bss, *tmp; | ||
56 | bool expired = false; | ||
57 | |||
58 | list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { | ||
59 | if (atomic_read(&bss->hold)) | ||
60 | continue; | ||
61 | if (!time_after(expire_time, bss->ts)) | ||
62 | continue; | ||
63 | |||
64 | __cfg80211_unlink_bss(dev, bss); | ||
65 | expired = true; | ||
66 | } | ||
67 | |||
68 | if (expired) | ||
69 | dev->bss_generation++; | ||
70 | } | ||
71 | |||
23 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) | 72 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) |
24 | { | 73 | { |
25 | struct cfg80211_scan_request *request; | 74 | struct cfg80211_scan_request *request; |
@@ -45,10 +94,17 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) | |||
45 | if (wdev->netdev) | 94 | if (wdev->netdev) |
46 | cfg80211_sme_scan_done(wdev->netdev); | 95 | cfg80211_sme_scan_done(wdev->netdev); |
47 | 96 | ||
48 | if (request->aborted) | 97 | if (request->aborted) { |
49 | nl80211_send_scan_aborted(rdev, wdev); | 98 | nl80211_send_scan_aborted(rdev, wdev); |
50 | else | 99 | } else { |
100 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { | ||
101 | /* flush entries from previous scans */ | ||
102 | spin_lock_bh(&rdev->bss_lock); | ||
103 | __cfg80211_bss_expire(rdev, request->scan_start); | ||
104 | spin_unlock_bh(&rdev->bss_lock); | ||
105 | } | ||
51 | nl80211_send_scan_done(rdev, wdev); | 106 | nl80211_send_scan_done(rdev, wdev); |
107 | } | ||
52 | 108 | ||
53 | #ifdef CONFIG_CFG80211_WEXT | 109 | #ifdef CONFIG_CFG80211_WEXT |
54 | if (wdev->netdev && !request->aborted) { | 110 | if (wdev->netdev && !request->aborted) { |
@@ -89,6 +145,7 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
89 | 145 | ||
90 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 146 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) |
91 | { | 147 | { |
148 | trace_cfg80211_scan_done(request, aborted); | ||
92 | WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); | 149 | WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); |
93 | 150 | ||
94 | request->aborted = aborted; | 151 | request->aborted = aborted; |
@@ -99,22 +156,34 @@ EXPORT_SYMBOL(cfg80211_scan_done); | |||
99 | void __cfg80211_sched_scan_results(struct work_struct *wk) | 156 | void __cfg80211_sched_scan_results(struct work_struct *wk) |
100 | { | 157 | { |
101 | struct cfg80211_registered_device *rdev; | 158 | struct cfg80211_registered_device *rdev; |
159 | struct cfg80211_sched_scan_request *request; | ||
102 | 160 | ||
103 | rdev = container_of(wk, struct cfg80211_registered_device, | 161 | rdev = container_of(wk, struct cfg80211_registered_device, |
104 | sched_scan_results_wk); | 162 | sched_scan_results_wk); |
105 | 163 | ||
164 | request = rdev->sched_scan_req; | ||
165 | |||
106 | mutex_lock(&rdev->sched_scan_mtx); | 166 | mutex_lock(&rdev->sched_scan_mtx); |
107 | 167 | ||
108 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 168 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
109 | if (rdev->sched_scan_req) | 169 | if (request) { |
110 | nl80211_send_sched_scan_results(rdev, | 170 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { |
111 | rdev->sched_scan_req->dev); | 171 | /* flush entries from previous scans */ |
172 | spin_lock_bh(&rdev->bss_lock); | ||
173 | __cfg80211_bss_expire(rdev, request->scan_start); | ||
174 | spin_unlock_bh(&rdev->bss_lock); | ||
175 | request->scan_start = | ||
176 | jiffies + msecs_to_jiffies(request->interval); | ||
177 | } | ||
178 | nl80211_send_sched_scan_results(rdev, request->dev); | ||
179 | } | ||
112 | 180 | ||
113 | mutex_unlock(&rdev->sched_scan_mtx); | 181 | mutex_unlock(&rdev->sched_scan_mtx); |
114 | } | 182 | } |
115 | 183 | ||
116 | void cfg80211_sched_scan_results(struct wiphy *wiphy) | 184 | void cfg80211_sched_scan_results(struct wiphy *wiphy) |
117 | { | 185 | { |
186 | trace_cfg80211_sched_scan_results(wiphy); | ||
118 | /* ignore if we're not scanning */ | 187 | /* ignore if we're not scanning */ |
119 | if (wiphy_to_dev(wiphy)->sched_scan_req) | 188 | if (wiphy_to_dev(wiphy)->sched_scan_req) |
120 | queue_work(cfg80211_wq, | 189 | queue_work(cfg80211_wq, |
@@ -126,6 +195,8 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | |||
126 | { | 195 | { |
127 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 196 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
128 | 197 | ||
198 | trace_cfg80211_sched_scan_stopped(wiphy); | ||
199 | |||
129 | mutex_lock(&rdev->sched_scan_mtx); | 200 | mutex_lock(&rdev->sched_scan_mtx); |
130 | __cfg80211_stop_sched_scan(rdev, true); | 201 | __cfg80211_stop_sched_scan(rdev, true); |
131 | mutex_unlock(&rdev->sched_scan_mtx); | 202 | mutex_unlock(&rdev->sched_scan_mtx); |
@@ -145,7 +216,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
145 | dev = rdev->sched_scan_req->dev; | 216 | dev = rdev->sched_scan_req->dev; |
146 | 217 | ||
147 | if (!driver_initiated) { | 218 | if (!driver_initiated) { |
148 | int err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); | 219 | int err = rdev_sched_scan_stop(rdev, dev); |
149 | if (err) | 220 | if (err) |
150 | return err; | 221 | return err; |
151 | } | 222 | } |
@@ -158,24 +229,6 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
158 | return 0; | 229 | return 0; |
159 | } | 230 | } |
160 | 231 | ||
161 | static void bss_release(struct kref *ref) | ||
162 | { | ||
163 | struct cfg80211_internal_bss *bss; | ||
164 | |||
165 | bss = container_of(ref, struct cfg80211_internal_bss, ref); | ||
166 | if (bss->pub.free_priv) | ||
167 | bss->pub.free_priv(&bss->pub); | ||
168 | |||
169 | if (bss->beacon_ies_allocated) | ||
170 | kfree(bss->pub.beacon_ies); | ||
171 | if (bss->proberesp_ies_allocated) | ||
172 | kfree(bss->pub.proberesp_ies); | ||
173 | |||
174 | BUG_ON(atomic_read(&bss->hold)); | ||
175 | |||
176 | kfree(bss); | ||
177 | } | ||
178 | |||
179 | /* must hold dev->bss_lock! */ | 232 | /* must hold dev->bss_lock! */ |
180 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | 233 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, |
181 | unsigned long age_secs) | 234 | unsigned long age_secs) |
@@ -188,32 +241,9 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, | |||
188 | } | 241 | } |
189 | } | 242 | } |
190 | 243 | ||
191 | /* must hold dev->bss_lock! */ | ||
192 | static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, | ||
193 | struct cfg80211_internal_bss *bss) | ||
194 | { | ||
195 | list_del_init(&bss->list); | ||
196 | rb_erase(&bss->rbn, &dev->bss_tree); | ||
197 | kref_put(&bss->ref, bss_release); | ||
198 | } | ||
199 | |||
200 | /* must hold dev->bss_lock! */ | ||
201 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev) | 244 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev) |
202 | { | 245 | { |
203 | struct cfg80211_internal_bss *bss, *tmp; | 246 | __cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); |
204 | bool expired = false; | ||
205 | |||
206 | list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { | ||
207 | if (atomic_read(&bss->hold)) | ||
208 | continue; | ||
209 | if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) | ||
210 | continue; | ||
211 | __cfg80211_unlink_bss(dev, bss); | ||
212 | expired = true; | ||
213 | } | ||
214 | |||
215 | if (expired) | ||
216 | dev->bss_generation++; | ||
217 | } | 247 | } |
218 | 248 | ||
219 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) | 249 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) |
@@ -459,6 +489,9 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | |||
459 | struct cfg80211_internal_bss *bss, *res = NULL; | 489 | struct cfg80211_internal_bss *bss, *res = NULL; |
460 | unsigned long now = jiffies; | 490 | unsigned long now = jiffies; |
461 | 491 | ||
492 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, | ||
493 | capa_val); | ||
494 | |||
462 | spin_lock_bh(&dev->bss_lock); | 495 | spin_lock_bh(&dev->bss_lock); |
463 | 496 | ||
464 | list_for_each_entry(bss, &dev->bss_list, list) { | 497 | list_for_each_entry(bss, &dev->bss_list, list) { |
@@ -480,6 +513,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | |||
480 | spin_unlock_bh(&dev->bss_lock); | 513 | spin_unlock_bh(&dev->bss_lock); |
481 | if (!res) | 514 | if (!res) |
482 | return NULL; | 515 | return NULL; |
516 | trace_cfg80211_return_bss(&res->pub); | ||
483 | return &res->pub; | 517 | return &res->pub; |
484 | } | 518 | } |
485 | EXPORT_SYMBOL(cfg80211_get_bss); | 519 | EXPORT_SYMBOL(cfg80211_get_bss); |
@@ -792,6 +826,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, | |||
792 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 826 | if (res->pub.capability & WLAN_CAPABILITY_ESS) |
793 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 827 | regulatory_hint_found_beacon(wiphy, channel, gfp); |
794 | 828 | ||
829 | trace_cfg80211_return_bss(&res->pub); | ||
795 | /* cfg80211_bss_update gives us a referenced result */ | 830 | /* cfg80211_bss_update gives us a referenced result */ |
796 | return &res->pub; | 831 | return &res->pub; |
797 | } | 832 | } |
@@ -804,10 +839,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
804 | s32 signal, gfp_t gfp) | 839 | s32 signal, gfp_t gfp) |
805 | { | 840 | { |
806 | struct cfg80211_internal_bss *res; | 841 | struct cfg80211_internal_bss *res; |
842 | |||
807 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 843 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
808 | u.probe_resp.variable); | 844 | u.probe_resp.variable); |
809 | size_t privsz; | 845 | size_t privsz; |
810 | 846 | ||
847 | trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); | ||
848 | |||
811 | if (WARN_ON(!mgmt)) | 849 | if (WARN_ON(!mgmt)) |
812 | return NULL; | 850 | return NULL; |
813 | 851 | ||
@@ -861,6 +899,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
861 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 899 | if (res->pub.capability & WLAN_CAPABILITY_ESS) |
862 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 900 | regulatory_hint_found_beacon(wiphy, channel, gfp); |
863 | 901 | ||
902 | trace_cfg80211_return_bss(&res->pub); | ||
864 | /* cfg80211_bss_update gives us a referenced result */ | 903 | /* cfg80211_bss_update gives us a referenced result */ |
865 | return &res->pub; | 904 | return &res->pub; |
866 | } | 905 | } |
@@ -962,6 +1001,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
962 | creq->ssids = (void *)&creq->channels[n_channels]; | 1001 | creq->ssids = (void *)&creq->channels[n_channels]; |
963 | creq->n_channels = n_channels; | 1002 | creq->n_channels = n_channels; |
964 | creq->n_ssids = 1; | 1003 | creq->n_ssids = 1; |
1004 | creq->scan_start = jiffies; | ||
965 | 1005 | ||
966 | /* translate "Scan on frequencies" request */ | 1006 | /* translate "Scan on frequencies" request */ |
967 | i = 0; | 1007 | i = 0; |
@@ -1026,7 +1066,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
1026 | creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; | 1066 | creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; |
1027 | 1067 | ||
1028 | rdev->scan_req = creq; | 1068 | rdev->scan_req = creq; |
1029 | err = rdev->ops->scan(wiphy, creq); | 1069 | err = rdev_scan(rdev, creq); |
1030 | if (err) { | 1070 | if (err) { |
1031 | rdev->scan_req = NULL; | 1071 | rdev->scan_req = NULL; |
1032 | /* creq will be freed below */ | 1072 | /* creq will be freed below */ |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 6f39cb808302..c7490027237d 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <net/rtnetlink.h> | 16 | #include <net/rtnetlink.h> |
17 | #include "nl80211.h" | 17 | #include "nl80211.h" |
18 | #include "reg.h" | 18 | #include "reg.h" |
19 | #include "rdev-ops.h" | ||
19 | 20 | ||
20 | struct cfg80211_conn { | 21 | struct cfg80211_conn { |
21 | struct cfg80211_connect_params params; | 22 | struct cfg80211_connect_params params; |
@@ -138,10 +139,11 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
138 | 139 | ||
139 | request->wdev = wdev; | 140 | request->wdev = wdev; |
140 | request->wiphy = &rdev->wiphy; | 141 | request->wiphy = &rdev->wiphy; |
142 | request->scan_start = jiffies; | ||
141 | 143 | ||
142 | rdev->scan_req = request; | 144 | rdev->scan_req = request; |
143 | 145 | ||
144 | err = rdev->ops->scan(wdev->wiphy, request); | 146 | err = rdev_scan(rdev, request); |
145 | if (!err) { | 147 | if (!err) { |
146 | wdev->conn->state = CFG80211_CONN_SCANNING; | 148 | wdev->conn->state = CFG80211_CONN_SCANNING; |
147 | nl80211_send_scan_start(rdev, wdev); | 149 | nl80211_send_scan_start(rdev, wdev); |
@@ -179,7 +181,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
179 | params->ssid, params->ssid_len, | 181 | params->ssid, params->ssid_len, |
180 | NULL, 0, | 182 | NULL, 0, |
181 | params->key, params->key_len, | 183 | params->key, params->key_len, |
182 | params->key_idx); | 184 | params->key_idx, NULL, 0); |
183 | case CFG80211_CONN_ASSOCIATE_NEXT: | 185 | case CFG80211_CONN_ASSOCIATE_NEXT: |
184 | BUG_ON(!rdev->ops->assoc); | 186 | BUG_ON(!rdev->ops->assoc); |
185 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; | 187 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; |
@@ -716,7 +718,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
716 | */ | 718 | */ |
717 | if (rdev->ops->del_key) | 719 | if (rdev->ops->del_key) |
718 | for (i = 0; i < 6; i++) | 720 | for (i = 0; i < 6; i++) |
719 | rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); | 721 | rdev_del_key(rdev, dev, i, false, NULL); |
720 | 722 | ||
721 | #ifdef CONFIG_CFG80211_WEXT | 723 | #ifdef CONFIG_CFG80211_WEXT |
722 | memset(&wrqu, 0, sizeof(wrqu)); | 724 | memset(&wrqu, 0, sizeof(wrqu)); |
@@ -892,7 +894,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
892 | } else { | 894 | } else { |
893 | wdev->sme_state = CFG80211_SME_CONNECTING; | 895 | wdev->sme_state = CFG80211_SME_CONNECTING; |
894 | wdev->connect_keys = connkeys; | 896 | wdev->connect_keys = connkeys; |
895 | err = rdev->ops->connect(&rdev->wiphy, dev, connect); | 897 | err = rdev_connect(rdev, dev, connect); |
896 | if (err) { | 898 | if (err) { |
897 | wdev->connect_keys = NULL; | 899 | wdev->connect_keys = NULL; |
898 | wdev->sme_state = CFG80211_SME_IDLE; | 900 | wdev->sme_state = CFG80211_SME_IDLE; |
@@ -964,7 +966,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
964 | if (err) | 966 | if (err) |
965 | return err; | 967 | return err; |
966 | } else { | 968 | } else { |
967 | err = rdev->ops->disconnect(&rdev->wiphy, dev, reason); | 969 | err = rdev_disconnect(rdev, dev, reason); |
968 | if (err) | 970 | if (err) |
969 | return err; | 971 | return err; |
970 | } | 972 | } |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index ff574597a854..9bf6d5e32166 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <net/cfg80211.h> | 16 | #include <net/cfg80211.h> |
17 | #include "sysfs.h" | 17 | #include "sysfs.h" |
18 | #include "core.h" | 18 | #include "core.h" |
19 | #include "rdev-ops.h" | ||
19 | 20 | ||
20 | static inline struct cfg80211_registered_device *dev_to_rdev( | 21 | static inline struct cfg80211_registered_device *dev_to_rdev( |
21 | struct device *dev) | 22 | struct device *dev) |
@@ -94,7 +95,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) | |||
94 | if (rdev->ops->suspend) { | 95 | if (rdev->ops->suspend) { |
95 | rtnl_lock(); | 96 | rtnl_lock(); |
96 | if (rdev->wiphy.registered) | 97 | if (rdev->wiphy.registered) |
97 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | 98 | ret = rdev_suspend(rdev); |
98 | rtnl_unlock(); | 99 | rtnl_unlock(); |
99 | } | 100 | } |
100 | 101 | ||
@@ -114,7 +115,7 @@ static int wiphy_resume(struct device *dev) | |||
114 | if (rdev->ops->resume) { | 115 | if (rdev->ops->resume) { |
115 | rtnl_lock(); | 116 | rtnl_lock(); |
116 | if (rdev->wiphy.registered) | 117 | if (rdev->wiphy.registered) |
117 | ret = rdev->ops->resume(&rdev->wiphy); | 118 | ret = rdev_resume(rdev); |
118 | rtnl_unlock(); | 119 | rtnl_unlock(); |
119 | } | 120 | } |
120 | 121 | ||
diff --git a/net/wireless/trace.c b/net/wireless/trace.c new file mode 100644 index 000000000000..95f997fad755 --- /dev/null +++ b/net/wireless/trace.c | |||
@@ -0,0 +1,7 @@ | |||
1 | #include <linux/module.h> | ||
2 | |||
3 | #ifndef __CHECKER__ | ||
4 | #define CREATE_TRACE_POINTS | ||
5 | #include "trace.h" | ||
6 | |||
7 | #endif | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h new file mode 100644 index 000000000000..0ca71caf85fb --- /dev/null +++ b/net/wireless/trace.h | |||
@@ -0,0 +1,2296 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM cfg80211 | ||
3 | |||
4 | #if !defined(__RDEV_OPS_TRACE) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define __RDEV_OPS_TRACE | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | |||
9 | #include <linux/rtnetlink.h> | ||
10 | #include <net/cfg80211.h> | ||
11 | #include "core.h" | ||
12 | |||
13 | #define MAC_ENTRY(entry_mac) __array(u8, entry_mac, ETH_ALEN) | ||
14 | #define MAC_ASSIGN(entry_mac, given_mac) do { \ | ||
15 | if (given_mac) \ | ||
16 | memcpy(__entry->entry_mac, given_mac, ETH_ALEN); \ | ||
17 | else \ | ||
18 | memset(__entry->entry_mac, 0, ETH_ALEN); \ | ||
19 | } while (0) | ||
20 | #define MAC_PR_FMT "%pM" | ||
21 | #define MAC_PR_ARG(entry_mac) (__entry->entry_mac) | ||
22 | |||
23 | #define WIPHY_ENTRY MAC_ENTRY(wiphy_mac) | ||
24 | #define WIPHY_ASSIGN MAC_ASSIGN(wiphy_mac, wiphy->perm_addr) | ||
25 | #define WIPHY_PR_FMT "wiphy " MAC_PR_FMT | ||
26 | #define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) | ||
27 | |||
28 | #define WDEV_ENTRY __field(u32, id) | ||
29 | #define WDEV_ASSIGN (__entry->id) = (wdev->identifier) | ||
30 | #define WDEV_PR_FMT ", wdev id: %u" | ||
31 | #define WDEV_PR_ARG (__entry->id) | ||
32 | |||
33 | #define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \ | ||
34 | MAC_ENTRY(netdev_addr) \ | ||
35 | __field(int, ifindex) | ||
36 | #define NETDEV_ASSIGN \ | ||
37 | do { \ | ||
38 | memcpy(__entry->name, netdev->name, IFNAMSIZ); \ | ||
39 | MAC_ASSIGN(netdev_addr, netdev->dev_addr); \ | ||
40 | (__entry->ifindex) = (netdev->ifindex); \ | ||
41 | } while (0) | ||
42 | #define NETDEV_PR_FMT ", netdev - name: %s, addr: " MAC_PR_FMT \ | ||
43 | ", intf index: %d" | ||
44 | #define NETDEV_PR_ARG (__entry->name), MAC_PR_ARG(netdev_addr), \ | ||
45 | (__entry->ifindex) | ||
46 | |||
47 | #define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \ | ||
48 | __field(u16, dot11MeshConfirmTimeout) \ | ||
49 | __field(u16, dot11MeshHoldingTimeout) \ | ||
50 | __field(u16, dot11MeshMaxPeerLinks) \ | ||
51 | __field(u8, dot11MeshMaxRetries) \ | ||
52 | __field(u8, dot11MeshTTL) \ | ||
53 | __field(u8, element_ttl) \ | ||
54 | __field(bool, auto_open_plinks) \ | ||
55 | __field(u32, dot11MeshNbrOffsetMaxNeighbor) \ | ||
56 | __field(u8, dot11MeshHWMPmaxPREQretries) \ | ||
57 | __field(u32, path_refresh_time) \ | ||
58 | __field(u32, dot11MeshHWMPactivePathTimeout) \ | ||
59 | __field(u16, min_discovery_timeout) \ | ||
60 | __field(u16, dot11MeshHWMPpreqMinInterval) \ | ||
61 | __field(u16, dot11MeshHWMPperrMinInterval) \ | ||
62 | __field(u16, dot11MeshHWMPnetDiameterTraversalTime) \ | ||
63 | __field(u8, dot11MeshHWMPRootMode) \ | ||
64 | __field(u16, dot11MeshHWMPRannInterval) \ | ||
65 | __field(bool, dot11MeshGateAnnouncementProtocol) \ | ||
66 | __field(bool, dot11MeshForwarding) \ | ||
67 | __field(s32, rssi_threshold) \ | ||
68 | __field(u16, ht_opmode) \ | ||
69 | __field(u32, dot11MeshHWMPactivePathToRootTimeout) \ | ||
70 | __field(u16, dot11MeshHWMProotInterval) \ | ||
71 | __field(u16, dot11MeshHWMPconfirmationInterval) | ||
72 | #define MESH_CFG_ASSIGN \ | ||
73 | do { \ | ||
74 | __entry->dot11MeshRetryTimeout = conf->dot11MeshRetryTimeout; \ | ||
75 | __entry->dot11MeshConfirmTimeout = \ | ||
76 | conf->dot11MeshConfirmTimeout; \ | ||
77 | __entry->dot11MeshHoldingTimeout = \ | ||
78 | conf->dot11MeshHoldingTimeout; \ | ||
79 | __entry->dot11MeshMaxPeerLinks = conf->dot11MeshMaxPeerLinks; \ | ||
80 | __entry->dot11MeshMaxRetries = conf->dot11MeshMaxRetries; \ | ||
81 | __entry->dot11MeshTTL = conf->dot11MeshTTL; \ | ||
82 | __entry->element_ttl = conf->element_ttl; \ | ||
83 | __entry->auto_open_plinks = conf->auto_open_plinks; \ | ||
84 | __entry->dot11MeshNbrOffsetMaxNeighbor = \ | ||
85 | conf->dot11MeshNbrOffsetMaxNeighbor; \ | ||
86 | __entry->dot11MeshHWMPmaxPREQretries = \ | ||
87 | conf->dot11MeshHWMPmaxPREQretries; \ | ||
88 | __entry->path_refresh_time = conf->path_refresh_time; \ | ||
89 | __entry->dot11MeshHWMPactivePathTimeout = \ | ||
90 | conf->dot11MeshHWMPactivePathTimeout; \ | ||
91 | __entry->min_discovery_timeout = conf->min_discovery_timeout; \ | ||
92 | __entry->dot11MeshHWMPpreqMinInterval = \ | ||
93 | conf->dot11MeshHWMPpreqMinInterval; \ | ||
94 | __entry->dot11MeshHWMPperrMinInterval = \ | ||
95 | conf->dot11MeshHWMPperrMinInterval; \ | ||
96 | __entry->dot11MeshHWMPnetDiameterTraversalTime = \ | ||
97 | conf->dot11MeshHWMPnetDiameterTraversalTime; \ | ||
98 | __entry->dot11MeshHWMPRootMode = conf->dot11MeshHWMPRootMode; \ | ||
99 | __entry->dot11MeshHWMPRannInterval = \ | ||
100 | conf->dot11MeshHWMPRannInterval; \ | ||
101 | __entry->dot11MeshGateAnnouncementProtocol = \ | ||
102 | conf->dot11MeshGateAnnouncementProtocol; \ | ||
103 | __entry->dot11MeshForwarding = conf->dot11MeshForwarding; \ | ||
104 | __entry->rssi_threshold = conf->rssi_threshold; \ | ||
105 | __entry->ht_opmode = conf->ht_opmode; \ | ||
106 | __entry->dot11MeshHWMPactivePathToRootTimeout = \ | ||
107 | conf->dot11MeshHWMPactivePathToRootTimeout; \ | ||
108 | __entry->dot11MeshHWMProotInterval = \ | ||
109 | conf->dot11MeshHWMProotInterval; \ | ||
110 | __entry->dot11MeshHWMPconfirmationInterval = \ | ||
111 | conf->dot11MeshHWMPconfirmationInterval; \ | ||
112 | } while (0) | ||
113 | |||
114 | #define CHAN_ENTRY __field(enum ieee80211_band, band) \ | ||
115 | __field(u16, center_freq) | ||
116 | #define CHAN_ASSIGN(chan) \ | ||
117 | do { \ | ||
118 | if (chan) { \ | ||
119 | __entry->band = chan->band; \ | ||
120 | __entry->center_freq = chan->center_freq; \ | ||
121 | } else { \ | ||
122 | __entry->band = 0; \ | ||
123 | __entry->center_freq = 0; \ | ||
124 | } \ | ||
125 | } while (0) | ||
126 | #define CHAN_PR_FMT ", band: %d, freq: %u" | ||
127 | #define CHAN_PR_ARG __entry->band, __entry->center_freq | ||
128 | |||
129 | #define SINFO_ENTRY __field(int, generation) \ | ||
130 | __field(u32, connected_time) \ | ||
131 | __field(u32, inactive_time) \ | ||
132 | __field(u32, rx_bytes) \ | ||
133 | __field(u32, tx_bytes) \ | ||
134 | __field(u32, rx_packets) \ | ||
135 | __field(u32, tx_packets) \ | ||
136 | __field(u32, tx_retries) \ | ||
137 | __field(u32, tx_failed) \ | ||
138 | __field(u32, rx_dropped_misc) \ | ||
139 | __field(u32, beacon_loss_count) \ | ||
140 | __field(u16, llid) \ | ||
141 | __field(u16, plid) \ | ||
142 | __field(u8, plink_state) | ||
143 | #define SINFO_ASSIGN \ | ||
144 | do { \ | ||
145 | __entry->generation = sinfo->generation; \ | ||
146 | __entry->connected_time = sinfo->connected_time; \ | ||
147 | __entry->inactive_time = sinfo->inactive_time; \ | ||
148 | __entry->rx_bytes = sinfo->rx_bytes; \ | ||
149 | __entry->tx_bytes = sinfo->tx_bytes; \ | ||
150 | __entry->rx_packets = sinfo->rx_packets; \ | ||
151 | __entry->tx_packets = sinfo->tx_packets; \ | ||
152 | __entry->tx_retries = sinfo->tx_retries; \ | ||
153 | __entry->tx_failed = sinfo->tx_failed; \ | ||
154 | __entry->rx_dropped_misc = sinfo->rx_dropped_misc; \ | ||
155 | __entry->beacon_loss_count = sinfo->beacon_loss_count; \ | ||
156 | __entry->llid = sinfo->llid; \ | ||
157 | __entry->plid = sinfo->plid; \ | ||
158 | __entry->plink_state = sinfo->plink_state; \ | ||
159 | } while (0) | ||
160 | |||
161 | #define BOOL_TO_STR(bo) (bo) ? "true" : "false" | ||
162 | |||
163 | /************************************************************* | ||
164 | * rdev->ops traces * | ||
165 | *************************************************************/ | ||
166 | |||
167 | TRACE_EVENT(rdev_suspend, | ||
168 | TP_PROTO(struct wiphy *wiphy, struct cfg80211_wowlan *wow), | ||
169 | TP_ARGS(wiphy, wow), | ||
170 | TP_STRUCT__entry( | ||
171 | WIPHY_ENTRY | ||
172 | __field(bool, any) | ||
173 | __field(bool, disconnect) | ||
174 | __field(bool, magic_pkt) | ||
175 | __field(bool, gtk_rekey_failure) | ||
176 | __field(bool, eap_identity_req) | ||
177 | __field(bool, four_way_handshake) | ||
178 | __field(bool, rfkill_release) | ||
179 | __field(bool, valid_wow) | ||
180 | ), | ||
181 | TP_fast_assign( | ||
182 | WIPHY_ASSIGN; | ||
183 | if (wow) { | ||
184 | __entry->any = wow->any; | ||
185 | __entry->disconnect = wow->disconnect; | ||
186 | __entry->magic_pkt = wow->magic_pkt; | ||
187 | __entry->gtk_rekey_failure = wow->gtk_rekey_failure; | ||
188 | __entry->eap_identity_req = wow->eap_identity_req; | ||
189 | __entry->four_way_handshake = wow->four_way_handshake; | ||
190 | __entry->rfkill_release = wow->rfkill_release; | ||
191 | __entry->valid_wow = true; | ||
192 | } else { | ||
193 | __entry->valid_wow = false; | ||
194 | } | ||
195 | ), | ||
196 | TP_printk(WIPHY_PR_FMT ", wow%s - any: %d, disconnect: %d, " | ||
197 | "magic pkt: %d, gtk rekey failure: %d, eap identify req: %d, " | ||
198 | "four way handshake: %d, rfkill release: %d.", | ||
199 | WIPHY_PR_ARG, __entry->valid_wow ? "" : "(Not configured!)", | ||
200 | __entry->any, __entry->disconnect, __entry->magic_pkt, | ||
201 | __entry->gtk_rekey_failure, __entry->eap_identity_req, | ||
202 | __entry->four_way_handshake, __entry->rfkill_release) | ||
203 | ); | ||
204 | |||
205 | TRACE_EVENT(rdev_return_int, | ||
206 | TP_PROTO(struct wiphy *wiphy, int ret), | ||
207 | TP_ARGS(wiphy, ret), | ||
208 | TP_STRUCT__entry( | ||
209 | WIPHY_ENTRY | ||
210 | __field(int, ret) | ||
211 | ), | ||
212 | TP_fast_assign( | ||
213 | WIPHY_ASSIGN; | ||
214 | __entry->ret = ret; | ||
215 | ), | ||
216 | TP_printk(WIPHY_PR_FMT ", returned: %d", WIPHY_PR_ARG, __entry->ret) | ||
217 | ); | ||
218 | |||
219 | TRACE_EVENT(rdev_scan, | ||
220 | TP_PROTO(struct wiphy *wiphy, struct cfg80211_scan_request *request), | ||
221 | TP_ARGS(wiphy, request), | ||
222 | TP_STRUCT__entry( | ||
223 | WIPHY_ENTRY | ||
224 | ), | ||
225 | TP_fast_assign( | ||
226 | WIPHY_ASSIGN; | ||
227 | ), | ||
228 | TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) | ||
229 | ); | ||
230 | |||
231 | DECLARE_EVENT_CLASS(wiphy_only_evt, | ||
232 | TP_PROTO(struct wiphy *wiphy), | ||
233 | TP_ARGS(wiphy), | ||
234 | TP_STRUCT__entry( | ||
235 | WIPHY_ENTRY | ||
236 | ), | ||
237 | TP_fast_assign( | ||
238 | WIPHY_ASSIGN; | ||
239 | ), | ||
240 | TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) | ||
241 | ); | ||
242 | |||
243 | DEFINE_EVENT(wiphy_only_evt, rdev_resume, | ||
244 | TP_PROTO(struct wiphy *wiphy), | ||
245 | TP_ARGS(wiphy) | ||
246 | ); | ||
247 | |||
248 | DEFINE_EVENT(wiphy_only_evt, rdev_return_void, | ||
249 | TP_PROTO(struct wiphy *wiphy), | ||
250 | TP_ARGS(wiphy) | ||
251 | ); | ||
252 | |||
253 | DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam, | ||
254 | TP_PROTO(struct wiphy *wiphy), | ||
255 | TP_ARGS(wiphy) | ||
256 | ); | ||
257 | |||
258 | DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, | ||
259 | TP_PROTO(struct wiphy *wiphy), | ||
260 | TP_ARGS(wiphy) | ||
261 | ); | ||
262 | |||
263 | DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power, | ||
264 | TP_PROTO(struct wiphy *wiphy), | ||
265 | TP_ARGS(wiphy) | ||
266 | ); | ||
267 | |||
268 | DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, | ||
269 | TP_PROTO(struct wiphy *wiphy), | ||
270 | TP_ARGS(wiphy) | ||
271 | ); | ||
272 | |||
273 | DECLARE_EVENT_CLASS(wiphy_enabled_evt, | ||
274 | TP_PROTO(struct wiphy *wiphy, bool enabled), | ||
275 | TP_ARGS(wiphy, enabled), | ||
276 | TP_STRUCT__entry( | ||
277 | WIPHY_ENTRY | ||
278 | __field(bool, enabled) | ||
279 | ), | ||
280 | TP_fast_assign( | ||
281 | WIPHY_ASSIGN; | ||
282 | __entry->enabled = enabled; | ||
283 | ), | ||
284 | TP_printk(WIPHY_PR_FMT ", %senabled ", | ||
285 | WIPHY_PR_ARG, __entry->enabled ? "" : "not ") | ||
286 | ); | ||
287 | |||
288 | DEFINE_EVENT(wiphy_enabled_evt, rdev_set_wakeup, | ||
289 | TP_PROTO(struct wiphy *wiphy, bool enabled), | ||
290 | TP_ARGS(wiphy, enabled) | ||
291 | ); | ||
292 | |||
293 | TRACE_EVENT(rdev_add_virtual_intf, | ||
294 | TP_PROTO(struct wiphy *wiphy, char *name, enum nl80211_iftype type), | ||
295 | TP_ARGS(wiphy, name, type), | ||
296 | TP_STRUCT__entry( | ||
297 | WIPHY_ENTRY | ||
298 | __string(vir_intf_name, name ? name : "<noname>") | ||
299 | __field(enum nl80211_iftype, type) | ||
300 | ), | ||
301 | TP_fast_assign( | ||
302 | WIPHY_ASSIGN; | ||
303 | __assign_str(vir_intf_name, name ? name : "<noname>"); | ||
304 | __entry->type = type; | ||
305 | ), | ||
306 | TP_printk(WIPHY_PR_FMT ", virtual intf name: %s, type: %d", | ||
307 | WIPHY_PR_ARG, __get_str(vir_intf_name), __entry->type) | ||
308 | ); | ||
309 | |||
310 | DECLARE_EVENT_CLASS(wiphy_wdev_evt, | ||
311 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
312 | TP_ARGS(wiphy, wdev), | ||
313 | TP_STRUCT__entry( | ||
314 | WIPHY_ENTRY | ||
315 | WDEV_ENTRY | ||
316 | ), | ||
317 | TP_fast_assign( | ||
318 | WIPHY_ASSIGN; | ||
319 | WDEV_ASSIGN; | ||
320 | ), | ||
321 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) | ||
322 | ); | ||
323 | |||
324 | DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, | ||
325 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
326 | TP_ARGS(wiphy, wdev) | ||
327 | ); | ||
328 | |||
329 | DEFINE_EVENT(wiphy_wdev_evt, rdev_del_virtual_intf, | ||
330 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
331 | TP_ARGS(wiphy, wdev) | ||
332 | ); | ||
333 | |||
334 | TRACE_EVENT(rdev_change_virtual_intf, | ||
335 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
336 | enum nl80211_iftype type), | ||
337 | TP_ARGS(wiphy, netdev, type), | ||
338 | TP_STRUCT__entry( | ||
339 | WIPHY_ENTRY | ||
340 | NETDEV_ENTRY | ||
341 | __field(enum nl80211_iftype, type) | ||
342 | ), | ||
343 | TP_fast_assign( | ||
344 | WIPHY_ASSIGN; | ||
345 | NETDEV_ASSIGN; | ||
346 | __entry->type = type; | ||
347 | ), | ||
348 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", type: %d", | ||
349 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type) | ||
350 | ); | ||
351 | |||
352 | DECLARE_EVENT_CLASS(key_handle, | ||
353 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, | ||
354 | bool pairwise, const u8 *mac_addr), | ||
355 | TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr), | ||
356 | TP_STRUCT__entry( | ||
357 | WIPHY_ENTRY | ||
358 | NETDEV_ENTRY | ||
359 | MAC_ENTRY(mac_addr) | ||
360 | __field(u8, key_index) | ||
361 | __field(bool, pairwise) | ||
362 | ), | ||
363 | TP_fast_assign( | ||
364 | WIPHY_ASSIGN; | ||
365 | NETDEV_ASSIGN; | ||
366 | MAC_ASSIGN(mac_addr, mac_addr); | ||
367 | __entry->key_index = key_index; | ||
368 | __entry->pairwise = pairwise; | ||
369 | ), | ||
370 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT, | ||
371 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, | ||
372 | BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr)) | ||
373 | ); | ||
374 | |||
375 | DEFINE_EVENT(key_handle, rdev_add_key, | ||
376 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, | ||
377 | bool pairwise, const u8 *mac_addr), | ||
378 | TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) | ||
379 | ); | ||
380 | |||
381 | DEFINE_EVENT(key_handle, rdev_get_key, | ||
382 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, | ||
383 | bool pairwise, const u8 *mac_addr), | ||
384 | TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) | ||
385 | ); | ||
386 | |||
387 | DEFINE_EVENT(key_handle, rdev_del_key, | ||
388 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, | ||
389 | bool pairwise, const u8 *mac_addr), | ||
390 | TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) | ||
391 | ); | ||
392 | |||
393 | TRACE_EVENT(rdev_set_default_key, | ||
394 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, | ||
395 | bool unicast, bool multicast), | ||
396 | TP_ARGS(wiphy, netdev, key_index, unicast, multicast), | ||
397 | TP_STRUCT__entry( | ||
398 | WIPHY_ENTRY | ||
399 | NETDEV_ENTRY | ||
400 | __field(u8, key_index) | ||
401 | __field(bool, unicast) | ||
402 | __field(bool, multicast) | ||
403 | ), | ||
404 | TP_fast_assign( | ||
405 | WIPHY_ASSIGN; | ||
406 | NETDEV_ASSIGN; | ||
407 | __entry->key_index = key_index; | ||
408 | __entry->unicast = unicast; | ||
409 | __entry->multicast = multicast; | ||
410 | ), | ||
411 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s", | ||
412 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, | ||
413 | BOOL_TO_STR(__entry->unicast), | ||
414 | BOOL_TO_STR(__entry->multicast)) | ||
415 | ); | ||
416 | |||
417 | TRACE_EVENT(rdev_set_default_mgmt_key, | ||
418 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index), | ||
419 | TP_ARGS(wiphy, netdev, key_index), | ||
420 | TP_STRUCT__entry( | ||
421 | WIPHY_ENTRY | ||
422 | NETDEV_ENTRY | ||
423 | __field(u8, key_index) | ||
424 | ), | ||
425 | TP_fast_assign( | ||
426 | WIPHY_ASSIGN; | ||
427 | NETDEV_ASSIGN; | ||
428 | __entry->key_index = key_index; | ||
429 | ), | ||
430 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u", | ||
431 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) | ||
432 | ); | ||
433 | |||
434 | TRACE_EVENT(rdev_start_ap, | ||
435 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
436 | struct cfg80211_ap_settings *settings), | ||
437 | TP_ARGS(wiphy, netdev, settings), | ||
438 | TP_STRUCT__entry( | ||
439 | WIPHY_ENTRY | ||
440 | NETDEV_ENTRY | ||
441 | CHAN_ENTRY | ||
442 | __field(int, beacon_interval) | ||
443 | __field(int, dtim_period) | ||
444 | __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) | ||
445 | __field(enum nl80211_hidden_ssid, hidden_ssid) | ||
446 | __field(u32, wpa_ver) | ||
447 | __field(bool, privacy) | ||
448 | __field(enum nl80211_auth_type, auth_type) | ||
449 | __field(int, inactivity_timeout) | ||
450 | ), | ||
451 | TP_fast_assign( | ||
452 | WIPHY_ASSIGN; | ||
453 | NETDEV_ASSIGN; | ||
454 | CHAN_ASSIGN(settings->channel); | ||
455 | __entry->beacon_interval = settings->beacon_interval; | ||
456 | __entry->dtim_period = settings->dtim_period; | ||
457 | __entry->hidden_ssid = settings->hidden_ssid; | ||
458 | __entry->wpa_ver = settings->crypto.wpa_versions; | ||
459 | __entry->privacy = settings->privacy; | ||
460 | __entry->auth_type = settings->auth_type; | ||
461 | __entry->inactivity_timeout = settings->inactivity_timeout; | ||
462 | memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); | ||
463 | memcpy(__entry->ssid, settings->ssid, settings->ssid_len); | ||
464 | ), | ||
465 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, " | ||
466 | CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, " | ||
467 | "hidden ssid: %d, wpa versions: %u, privacy: %s, " | ||
468 | "auth type: %d, inactivity timeout: %d", | ||
469 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG, | ||
470 | __entry->beacon_interval, __entry->dtim_period, | ||
471 | __entry->hidden_ssid, __entry->wpa_ver, | ||
472 | BOOL_TO_STR(__entry->privacy), __entry->auth_type, | ||
473 | __entry->inactivity_timeout) | ||
474 | ); | ||
475 | |||
476 | TRACE_EVENT(rdev_change_beacon, | ||
477 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
478 | struct cfg80211_beacon_data *info), | ||
479 | TP_ARGS(wiphy, netdev, info), | ||
480 | TP_STRUCT__entry( | ||
481 | WIPHY_ENTRY | ||
482 | NETDEV_ENTRY | ||
483 | __dynamic_array(u8, head, info ? info->head_len : 0) | ||
484 | __dynamic_array(u8, tail, info ? info->tail_len : 0) | ||
485 | __dynamic_array(u8, beacon_ies, info ? info->beacon_ies_len : 0) | ||
486 | __dynamic_array(u8, proberesp_ies, | ||
487 | info ? info->proberesp_ies_len : 0) | ||
488 | __dynamic_array(u8, assocresp_ies, | ||
489 | info ? info->assocresp_ies_len : 0) | ||
490 | __dynamic_array(u8, probe_resp, info ? info->probe_resp_len : 0) | ||
491 | ), | ||
492 | TP_fast_assign( | ||
493 | WIPHY_ASSIGN; | ||
494 | NETDEV_ASSIGN; | ||
495 | if (info) { | ||
496 | if (info->head) | ||
497 | memcpy(__get_dynamic_array(head), info->head, | ||
498 | info->head_len); | ||
499 | if (info->tail) | ||
500 | memcpy(__get_dynamic_array(tail), info->tail, | ||
501 | info->tail_len); | ||
502 | if (info->beacon_ies) | ||
503 | memcpy(__get_dynamic_array(beacon_ies), | ||
504 | info->beacon_ies, info->beacon_ies_len); | ||
505 | if (info->proberesp_ies) | ||
506 | memcpy(__get_dynamic_array(proberesp_ies), | ||
507 | info->proberesp_ies, | ||
508 | info->proberesp_ies_len); | ||
509 | if (info->assocresp_ies) | ||
510 | memcpy(__get_dynamic_array(assocresp_ies), | ||
511 | info->assocresp_ies, | ||
512 | info->assocresp_ies_len); | ||
513 | if (info->probe_resp) | ||
514 | memcpy(__get_dynamic_array(probe_resp), | ||
515 | info->probe_resp, info->probe_resp_len); | ||
516 | } | ||
517 | ), | ||
518 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) | ||
519 | ); | ||
520 | |||
521 | DECLARE_EVENT_CLASS(wiphy_netdev_evt, | ||
522 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
523 | TP_ARGS(wiphy, netdev), | ||
524 | TP_STRUCT__entry( | ||
525 | WIPHY_ENTRY | ||
526 | NETDEV_ENTRY | ||
527 | ), | ||
528 | TP_fast_assign( | ||
529 | WIPHY_ASSIGN; | ||
530 | NETDEV_ASSIGN; | ||
531 | ), | ||
532 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) | ||
533 | ); | ||
534 | |||
535 | DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, | ||
536 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
537 | TP_ARGS(wiphy, netdev) | ||
538 | ); | ||
539 | |||
540 | DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats, | ||
541 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
542 | TP_ARGS(wiphy, netdev) | ||
543 | ); | ||
544 | |||
545 | DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, | ||
546 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
547 | TP_ARGS(wiphy, netdev) | ||
548 | ); | ||
549 | |||
550 | DEFINE_EVENT(wiphy_netdev_evt, rdev_set_rekey_data, | ||
551 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
552 | TP_ARGS(wiphy, netdev) | ||
553 | ); | ||
554 | |||
555 | DEFINE_EVENT(wiphy_netdev_evt, rdev_get_mesh_config, | ||
556 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
557 | TP_ARGS(wiphy, netdev) | ||
558 | ); | ||
559 | |||
560 | DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_mesh, | ||
561 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
562 | TP_ARGS(wiphy, netdev) | ||
563 | ); | ||
564 | |||
565 | DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss, | ||
566 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
567 | TP_ARGS(wiphy, netdev) | ||
568 | ); | ||
569 | |||
570 | DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, | ||
571 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
572 | TP_ARGS(wiphy, netdev) | ||
573 | ); | ||
574 | |||
575 | DECLARE_EVENT_CLASS(station_add_change, | ||
576 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, | ||
577 | struct station_parameters *params), | ||
578 | TP_ARGS(wiphy, netdev, mac, params), | ||
579 | TP_STRUCT__entry( | ||
580 | WIPHY_ENTRY | ||
581 | NETDEV_ENTRY | ||
582 | MAC_ENTRY(sta_mac) | ||
583 | __field(u32, sta_flags_mask) | ||
584 | __field(u32, sta_flags_set) | ||
585 | __field(u32, sta_modify_mask) | ||
586 | __field(int, listen_interval) | ||
587 | __field(u16, aid) | ||
588 | __field(u8, plink_action) | ||
589 | __field(u8, plink_state) | ||
590 | __field(u8, uapsd_queues) | ||
591 | __array(u8, ht_capa, (int)sizeof(struct ieee80211_ht_cap)) | ||
592 | ), | ||
593 | TP_fast_assign( | ||
594 | WIPHY_ASSIGN; | ||
595 | NETDEV_ASSIGN; | ||
596 | MAC_ASSIGN(sta_mac, mac); | ||
597 | __entry->sta_flags_mask = params->sta_flags_mask; | ||
598 | __entry->sta_flags_set = params->sta_flags_set; | ||
599 | __entry->sta_modify_mask = params->sta_modify_mask; | ||
600 | __entry->listen_interval = params->listen_interval; | ||
601 | __entry->aid = params->aid; | ||
602 | __entry->plink_action = params->plink_action; | ||
603 | __entry->plink_state = params->plink_state; | ||
604 | __entry->uapsd_queues = params->uapsd_queues; | ||
605 | memset(__entry->ht_capa, 0, sizeof(struct ieee80211_ht_cap)); | ||
606 | if (params->ht_capa) | ||
607 | memcpy(__entry->ht_capa, params->ht_capa, | ||
608 | sizeof(struct ieee80211_ht_cap)); | ||
609 | ), | ||
610 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT | ||
611 | ", station flags mask: %u, station flags set: %u, " | ||
612 | "station modify mask: %u, listen interval: %d, aid: %u, " | ||
613 | "plink action: %u, plink state: %u, uapsd queues: %u", | ||
614 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), | ||
615 | __entry->sta_flags_mask, __entry->sta_flags_set, | ||
616 | __entry->sta_modify_mask, __entry->listen_interval, | ||
617 | __entry->aid, __entry->plink_action, __entry->plink_state, | ||
618 | __entry->uapsd_queues) | ||
619 | ); | ||
620 | |||
621 | DEFINE_EVENT(station_add_change, rdev_add_station, | ||
622 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, | ||
623 | struct station_parameters *params), | ||
624 | TP_ARGS(wiphy, netdev, mac, params) | ||
625 | ); | ||
626 | |||
627 | DEFINE_EVENT(station_add_change, rdev_change_station, | ||
628 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, | ||
629 | struct station_parameters *params), | ||
630 | TP_ARGS(wiphy, netdev, mac, params) | ||
631 | ); | ||
632 | |||
633 | DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt, | ||
634 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | ||
635 | TP_ARGS(wiphy, netdev, mac), | ||
636 | TP_STRUCT__entry( | ||
637 | WIPHY_ENTRY | ||
638 | NETDEV_ENTRY | ||
639 | MAC_ENTRY(sta_mac) | ||
640 | ), | ||
641 | TP_fast_assign( | ||
642 | WIPHY_ASSIGN; | ||
643 | NETDEV_ASSIGN; | ||
644 | MAC_ASSIGN(sta_mac, mac); | ||
645 | ), | ||
646 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mac: " MAC_PR_FMT, | ||
647 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) | ||
648 | ); | ||
649 | |||
650 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, | ||
651 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | ||
652 | TP_ARGS(wiphy, netdev, mac) | ||
653 | ); | ||
654 | |||
655 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, | ||
656 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | ||
657 | TP_ARGS(wiphy, netdev, mac) | ||
658 | ); | ||
659 | |||
660 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_mpath, | ||
661 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | ||
662 | TP_ARGS(wiphy, netdev, mac) | ||
663 | ); | ||
664 | |||
665 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_set_wds_peer, | ||
666 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | ||
667 | TP_ARGS(wiphy, netdev, mac) | ||
668 | ); | ||
669 | |||
670 | TRACE_EVENT(rdev_dump_station, | ||
671 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, | ||
672 | u8 *mac), | ||
673 | TP_ARGS(wiphy, netdev, idx, mac), | ||
674 | TP_STRUCT__entry( | ||
675 | WIPHY_ENTRY | ||
676 | NETDEV_ENTRY | ||
677 | MAC_ENTRY(sta_mac) | ||
678 | __field(int, idx) | ||
679 | ), | ||
680 | TP_fast_assign( | ||
681 | WIPHY_ASSIGN; | ||
682 | NETDEV_ASSIGN; | ||
683 | MAC_ASSIGN(sta_mac, mac); | ||
684 | __entry->idx = idx; | ||
685 | ), | ||
686 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d", | ||
687 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), | ||
688 | __entry->idx) | ||
689 | ); | ||
690 | |||
691 | TRACE_EVENT(rdev_return_int_station_info, | ||
692 | TP_PROTO(struct wiphy *wiphy, int ret, struct station_info *sinfo), | ||
693 | TP_ARGS(wiphy, ret, sinfo), | ||
694 | TP_STRUCT__entry( | ||
695 | WIPHY_ENTRY | ||
696 | __field(int, ret) | ||
697 | SINFO_ENTRY | ||
698 | ), | ||
699 | TP_fast_assign( | ||
700 | WIPHY_ASSIGN; | ||
701 | __entry->ret = ret; | ||
702 | SINFO_ASSIGN; | ||
703 | ), | ||
704 | TP_printk(WIPHY_PR_FMT ", returned %d" , | ||
705 | WIPHY_PR_ARG, __entry->ret) | ||
706 | ); | ||
707 | |||
708 | DECLARE_EVENT_CLASS(mpath_evt, | ||
709 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, | ||
710 | u8 *next_hop), | ||
711 | TP_ARGS(wiphy, netdev, dst, next_hop), | ||
712 | TP_STRUCT__entry( | ||
713 | WIPHY_ENTRY | ||
714 | NETDEV_ENTRY | ||
715 | MAC_ENTRY(dst) | ||
716 | MAC_ENTRY(next_hop) | ||
717 | ), | ||
718 | TP_fast_assign( | ||
719 | WIPHY_ASSIGN; | ||
720 | NETDEV_ASSIGN; | ||
721 | MAC_ASSIGN(dst, dst); | ||
722 | MAC_ASSIGN(next_hop, next_hop); | ||
723 | ), | ||
724 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT, | ||
725 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst), | ||
726 | MAC_PR_ARG(next_hop)) | ||
727 | ); | ||
728 | |||
729 | DEFINE_EVENT(mpath_evt, rdev_add_mpath, | ||
730 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, | ||
731 | u8 *next_hop), | ||
732 | TP_ARGS(wiphy, netdev, dst, next_hop) | ||
733 | ); | ||
734 | |||
735 | DEFINE_EVENT(mpath_evt, rdev_change_mpath, | ||
736 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, | ||
737 | u8 *next_hop), | ||
738 | TP_ARGS(wiphy, netdev, dst, next_hop) | ||
739 | ); | ||
740 | |||
741 | DEFINE_EVENT(mpath_evt, rdev_get_mpath, | ||
742 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, | ||
743 | u8 *next_hop), | ||
744 | TP_ARGS(wiphy, netdev, dst, next_hop) | ||
745 | ); | ||
746 | |||
747 | TRACE_EVENT(rdev_dump_mpath, | ||
748 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, | ||
749 | u8 *dst, u8 *next_hop), | ||
750 | TP_ARGS(wiphy, netdev, idx, dst, next_hop), | ||
751 | TP_STRUCT__entry( | ||
752 | WIPHY_ENTRY | ||
753 | NETDEV_ENTRY | ||
754 | MAC_ENTRY(dst) | ||
755 | MAC_ENTRY(next_hop) | ||
756 | __field(int, idx) | ||
757 | ), | ||
758 | TP_fast_assign( | ||
759 | WIPHY_ASSIGN; | ||
760 | NETDEV_ASSIGN; | ||
761 | MAC_ASSIGN(dst, dst); | ||
762 | MAC_ASSIGN(next_hop, next_hop); | ||
763 | __entry->idx = idx; | ||
764 | ), | ||
765 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d, destination: " | ||
766 | MAC_PR_FMT ", next hop: " MAC_PR_FMT, | ||
767 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), | ||
768 | MAC_PR_ARG(next_hop)) | ||
769 | ); | ||
770 | |||
771 | TRACE_EVENT(rdev_return_int_mpath_info, | ||
772 | TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), | ||
773 | TP_ARGS(wiphy, ret, pinfo), | ||
774 | TP_STRUCT__entry( | ||
775 | WIPHY_ENTRY | ||
776 | __field(int, ret) | ||
777 | __field(int, generation) | ||
778 | __field(u32, filled) | ||
779 | __field(u32, frame_qlen) | ||
780 | __field(u32, sn) | ||
781 | __field(u32, metric) | ||
782 | __field(u32, exptime) | ||
783 | __field(u32, discovery_timeout) | ||
784 | __field(u8, discovery_retries) | ||
785 | __field(u8, flags) | ||
786 | ), | ||
787 | TP_fast_assign( | ||
788 | WIPHY_ASSIGN; | ||
789 | __entry->ret = ret; | ||
790 | __entry->generation = pinfo->generation; | ||
791 | __entry->filled = pinfo->filled; | ||
792 | __entry->frame_qlen = pinfo->frame_qlen; | ||
793 | __entry->sn = pinfo->sn; | ||
794 | __entry->metric = pinfo->metric; | ||
795 | __entry->exptime = pinfo->exptime; | ||
796 | __entry->discovery_timeout = pinfo->discovery_timeout; | ||
797 | __entry->discovery_retries = pinfo->discovery_retries; | ||
798 | __entry->flags = pinfo->flags; | ||
799 | ), | ||
800 | TP_printk(WIPHY_PR_FMT ", returned %d. mpath info - generation: %d, " | ||
801 | "filled: %u, frame qlen: %u, sn: %u, metric: %u, exptime: %u," | ||
802 | " discovery timeout: %u, discovery retries: %u, flags: %u", | ||
803 | WIPHY_PR_ARG, __entry->ret, __entry->generation, | ||
804 | __entry->filled, __entry->frame_qlen, __entry->sn, | ||
805 | __entry->metric, __entry->exptime, __entry->discovery_timeout, | ||
806 | __entry->discovery_retries, __entry->flags) | ||
807 | ); | ||
808 | |||
809 | TRACE_EVENT(rdev_return_int_mesh_config, | ||
810 | TP_PROTO(struct wiphy *wiphy, int ret, struct mesh_config *conf), | ||
811 | TP_ARGS(wiphy, ret, conf), | ||
812 | TP_STRUCT__entry( | ||
813 | WIPHY_ENTRY | ||
814 | MESH_CFG_ENTRY | ||
815 | __field(int, ret) | ||
816 | ), | ||
817 | TP_fast_assign( | ||
818 | WIPHY_ASSIGN; | ||
819 | MESH_CFG_ASSIGN; | ||
820 | __entry->ret = ret; | ||
821 | ), | ||
822 | TP_printk(WIPHY_PR_FMT ", returned: %d", | ||
823 | WIPHY_PR_ARG, __entry->ret) | ||
824 | ); | ||
825 | |||
826 | TRACE_EVENT(rdev_update_mesh_config, | ||
827 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 mask, | ||
828 | const struct mesh_config *conf), | ||
829 | TP_ARGS(wiphy, netdev, mask, conf), | ||
830 | TP_STRUCT__entry( | ||
831 | WIPHY_ENTRY | ||
832 | NETDEV_ENTRY | ||
833 | MESH_CFG_ENTRY | ||
834 | __field(u32, mask) | ||
835 | ), | ||
836 | TP_fast_assign( | ||
837 | WIPHY_ASSIGN; | ||
838 | NETDEV_ASSIGN; | ||
839 | MESH_CFG_ASSIGN; | ||
840 | __entry->mask = mask; | ||
841 | ), | ||
842 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mask: %u", | ||
843 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask) | ||
844 | ); | ||
845 | |||
846 | TRACE_EVENT(rdev_join_mesh, | ||
847 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
848 | const struct mesh_config *conf, | ||
849 | const struct mesh_setup *setup), | ||
850 | TP_ARGS(wiphy, netdev, conf, setup), | ||
851 | TP_STRUCT__entry( | ||
852 | WIPHY_ENTRY | ||
853 | NETDEV_ENTRY | ||
854 | MESH_CFG_ENTRY | ||
855 | ), | ||
856 | TP_fast_assign( | ||
857 | WIPHY_ASSIGN; | ||
858 | NETDEV_ASSIGN; | ||
859 | MESH_CFG_ASSIGN; | ||
860 | ), | ||
861 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, | ||
862 | WIPHY_PR_ARG, NETDEV_PR_ARG) | ||
863 | ); | ||
864 | |||
865 | TRACE_EVENT(rdev_change_bss, | ||
866 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
867 | struct bss_parameters *params), | ||
868 | TP_ARGS(wiphy, netdev, params), | ||
869 | TP_STRUCT__entry( | ||
870 | WIPHY_ENTRY | ||
871 | NETDEV_ENTRY | ||
872 | __field(int, use_cts_prot) | ||
873 | __field(int, use_short_preamble) | ||
874 | __field(int, use_short_slot_time) | ||
875 | __field(int, ap_isolate) | ||
876 | __field(int, ht_opmode) | ||
877 | ), | ||
878 | TP_fast_assign( | ||
879 | WIPHY_ASSIGN; | ||
880 | NETDEV_ASSIGN; | ||
881 | __entry->use_cts_prot = params->use_cts_prot; | ||
882 | __entry->use_short_preamble = params->use_short_preamble; | ||
883 | __entry->use_short_slot_time = params->use_short_slot_time; | ||
884 | __entry->ap_isolate = params->ap_isolate; | ||
885 | __entry->ht_opmode = params->ht_opmode; | ||
886 | ), | ||
887 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", use cts prot: %d, " | ||
888 | "use short preamble: %d, use short slot time: %d, " | ||
889 | "ap isolate: %d, ht opmode: %d", | ||
890 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot, | ||
891 | __entry->use_short_preamble, __entry->use_short_slot_time, | ||
892 | __entry->ap_isolate, __entry->ht_opmode) | ||
893 | ); | ||
894 | |||
895 | TRACE_EVENT(rdev_set_txq_params, | ||
896 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
897 | struct ieee80211_txq_params *params), | ||
898 | TP_ARGS(wiphy, netdev, params), | ||
899 | TP_STRUCT__entry( | ||
900 | WIPHY_ENTRY | ||
901 | NETDEV_ENTRY | ||
902 | __field(enum nl80211_ac, ac) | ||
903 | __field(u16, txop) | ||
904 | __field(u16, cwmin) | ||
905 | __field(u16, cwmax) | ||
906 | __field(u8, aifs) | ||
907 | ), | ||
908 | TP_fast_assign( | ||
909 | WIPHY_ASSIGN; | ||
910 | NETDEV_ASSIGN; | ||
911 | __entry->ac = params->ac; | ||
912 | __entry->txop = params->txop; | ||
913 | __entry->cwmin = params->cwmin; | ||
914 | __entry->cwmax = params->cwmax; | ||
915 | __entry->aifs = params->aifs; | ||
916 | ), | ||
917 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u", | ||
918 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop, | ||
919 | __entry->cwmin, __entry->cwmax, __entry->aifs) | ||
920 | ); | ||
921 | |||
922 | TRACE_EVENT(rdev_libertas_set_mesh_channel, | ||
923 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
924 | struct ieee80211_channel *chan), | ||
925 | TP_ARGS(wiphy, netdev, chan), | ||
926 | TP_STRUCT__entry( | ||
927 | WIPHY_ENTRY | ||
928 | NETDEV_ENTRY | ||
929 | CHAN_ENTRY | ||
930 | ), | ||
931 | TP_fast_assign( | ||
932 | WIPHY_ASSIGN; | ||
933 | NETDEV_ASSIGN; | ||
934 | CHAN_ASSIGN(chan); | ||
935 | ), | ||
936 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT CHAN_PR_FMT, WIPHY_PR_ARG, | ||
937 | NETDEV_PR_ARG, CHAN_PR_ARG) | ||
938 | ); | ||
939 | |||
940 | TRACE_EVENT(rdev_set_monitor_channel, | ||
941 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, | ||
942 | enum nl80211_channel_type chan_type), | ||
943 | TP_ARGS(wiphy, chan, chan_type), | ||
944 | TP_STRUCT__entry( | ||
945 | WIPHY_ENTRY | ||
946 | CHAN_ENTRY | ||
947 | __field(enum nl80211_channel_type, chan_type) | ||
948 | ), | ||
949 | TP_fast_assign( | ||
950 | WIPHY_ASSIGN; | ||
951 | CHAN_ASSIGN(chan); | ||
952 | __entry->chan_type = chan_type; | ||
953 | ), | ||
954 | TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d", | ||
955 | WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type) | ||
956 | ); | ||
957 | |||
958 | TRACE_EVENT(rdev_auth, | ||
959 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
960 | struct cfg80211_auth_request *req), | ||
961 | TP_ARGS(wiphy, netdev, req), | ||
962 | TP_STRUCT__entry( | ||
963 | WIPHY_ENTRY | ||
964 | NETDEV_ENTRY | ||
965 | MAC_ENTRY(bssid) | ||
966 | __field(enum nl80211_auth_type, auth_type) | ||
967 | ), | ||
968 | TP_fast_assign( | ||
969 | WIPHY_ASSIGN; | ||
970 | NETDEV_ASSIGN; | ||
971 | if (req->bss) | ||
972 | MAC_ASSIGN(bssid, req->bss->bssid); | ||
973 | else | ||
974 | memset(__entry->bssid, 0, ETH_ALEN); | ||
975 | __entry->auth_type = req->auth_type; | ||
976 | ), | ||
977 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT, | ||
978 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type, | ||
979 | MAC_PR_ARG(bssid)) | ||
980 | ); | ||
981 | |||
982 | TRACE_EVENT(rdev_assoc, | ||
983 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
984 | struct cfg80211_assoc_request *req), | ||
985 | TP_ARGS(wiphy, netdev, req), | ||
986 | TP_STRUCT__entry( | ||
987 | WIPHY_ENTRY | ||
988 | NETDEV_ENTRY | ||
989 | MAC_ENTRY(bssid) | ||
990 | MAC_ENTRY(prev_bssid) | ||
991 | __field(bool, use_mfp) | ||
992 | __field(u32, flags) | ||
993 | ), | ||
994 | TP_fast_assign( | ||
995 | WIPHY_ASSIGN; | ||
996 | NETDEV_ASSIGN; | ||
997 | if (req->bss) | ||
998 | MAC_ASSIGN(bssid, req->bss->bssid); | ||
999 | else | ||
1000 | memset(__entry->bssid, 0, ETH_ALEN); | ||
1001 | MAC_ASSIGN(prev_bssid, req->prev_bssid); | ||
1002 | __entry->use_mfp = req->use_mfp; | ||
1003 | __entry->flags = req->flags; | ||
1004 | ), | ||
1005 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT | ||
1006 | ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u", | ||
1007 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), | ||
1008 | MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp), | ||
1009 | __entry->flags) | ||
1010 | ); | ||
1011 | |||
1012 | TRACE_EVENT(rdev_deauth, | ||
1013 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1014 | struct cfg80211_deauth_request *req), | ||
1015 | TP_ARGS(wiphy, netdev, req), | ||
1016 | TP_STRUCT__entry( | ||
1017 | WIPHY_ENTRY | ||
1018 | NETDEV_ENTRY | ||
1019 | MAC_ENTRY(bssid) | ||
1020 | __field(u16, reason_code) | ||
1021 | ), | ||
1022 | TP_fast_assign( | ||
1023 | WIPHY_ASSIGN; | ||
1024 | NETDEV_ASSIGN; | ||
1025 | MAC_ASSIGN(bssid, req->bssid); | ||
1026 | __entry->reason_code = req->reason_code; | ||
1027 | ), | ||
1028 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u", | ||
1029 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), | ||
1030 | __entry->reason_code) | ||
1031 | ); | ||
1032 | |||
1033 | TRACE_EVENT(rdev_disassoc, | ||
1034 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1035 | struct cfg80211_disassoc_request *req), | ||
1036 | TP_ARGS(wiphy, netdev, req), | ||
1037 | TP_STRUCT__entry( | ||
1038 | WIPHY_ENTRY | ||
1039 | NETDEV_ENTRY | ||
1040 | MAC_ENTRY(bssid) | ||
1041 | __field(u16, reason_code) | ||
1042 | __field(bool, local_state_change) | ||
1043 | ), | ||
1044 | TP_fast_assign( | ||
1045 | WIPHY_ASSIGN; | ||
1046 | NETDEV_ASSIGN; | ||
1047 | if (req->bss) | ||
1048 | MAC_ASSIGN(bssid, req->bss->bssid); | ||
1049 | else | ||
1050 | memset(__entry->bssid, 0, ETH_ALEN); | ||
1051 | __entry->reason_code = req->reason_code; | ||
1052 | __entry->local_state_change = req->local_state_change; | ||
1053 | ), | ||
1054 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT | ||
1055 | ", reason: %u, local state change: %s", | ||
1056 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), | ||
1057 | __entry->reason_code, | ||
1058 | BOOL_TO_STR(__entry->local_state_change)) | ||
1059 | ); | ||
1060 | |||
1061 | TRACE_EVENT(rdev_mgmt_tx_cancel_wait, | ||
1062 | TP_PROTO(struct wiphy *wiphy, | ||
1063 | struct wireless_dev *wdev, u64 cookie), | ||
1064 | TP_ARGS(wiphy, wdev, cookie), | ||
1065 | TP_STRUCT__entry( | ||
1066 | WIPHY_ENTRY | ||
1067 | WDEV_ENTRY | ||
1068 | __field(u64, cookie) | ||
1069 | ), | ||
1070 | TP_fast_assign( | ||
1071 | WIPHY_ASSIGN; | ||
1072 | WDEV_ASSIGN; | ||
1073 | __entry->cookie = cookie; | ||
1074 | ), | ||
1075 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu ", | ||
1076 | WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) | ||
1077 | ); | ||
1078 | |||
1079 | TRACE_EVENT(rdev_set_power_mgmt, | ||
1080 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1081 | bool enabled, int timeout), | ||
1082 | TP_ARGS(wiphy, netdev, enabled, timeout), | ||
1083 | TP_STRUCT__entry( | ||
1084 | WIPHY_ENTRY | ||
1085 | NETDEV_ENTRY | ||
1086 | __field(bool, enabled) | ||
1087 | __field(int, timeout) | ||
1088 | ), | ||
1089 | TP_fast_assign( | ||
1090 | WIPHY_ASSIGN; | ||
1091 | NETDEV_ASSIGN; | ||
1092 | __entry->enabled = enabled; | ||
1093 | __entry->timeout = timeout; | ||
1094 | ), | ||
1095 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", %senabled, timeout: %d ", | ||
1096 | WIPHY_PR_ARG, NETDEV_PR_ARG, | ||
1097 | __entry->enabled ? "" : "not ", __entry->timeout) | ||
1098 | ); | ||
1099 | |||
1100 | TRACE_EVENT(rdev_connect, | ||
1101 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1102 | struct cfg80211_connect_params *sme), | ||
1103 | TP_ARGS(wiphy, netdev, sme), | ||
1104 | TP_STRUCT__entry( | ||
1105 | WIPHY_ENTRY | ||
1106 | NETDEV_ENTRY | ||
1107 | MAC_ENTRY(bssid) | ||
1108 | __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) | ||
1109 | __field(enum nl80211_auth_type, auth_type) | ||
1110 | __field(bool, privacy) | ||
1111 | __field(u32, wpa_versions) | ||
1112 | __field(u32, flags) | ||
1113 | ), | ||
1114 | TP_fast_assign( | ||
1115 | WIPHY_ASSIGN; | ||
1116 | NETDEV_ASSIGN; | ||
1117 | MAC_ASSIGN(bssid, sme->bssid); | ||
1118 | memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); | ||
1119 | memcpy(__entry->ssid, sme->ssid, sme->ssid_len); | ||
1120 | __entry->auth_type = sme->auth_type; | ||
1121 | __entry->privacy = sme->privacy; | ||
1122 | __entry->wpa_versions = sme->crypto.wpa_versions; | ||
1123 | __entry->flags = sme->flags; | ||
1124 | ), | ||
1125 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT | ||
1126 | ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, " | ||
1127 | "flags: %u", | ||
1128 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid, | ||
1129 | __entry->auth_type, BOOL_TO_STR(__entry->privacy), | ||
1130 | __entry->wpa_versions, __entry->flags) | ||
1131 | ); | ||
1132 | |||
1133 | TRACE_EVENT(rdev_set_cqm_rssi_config, | ||
1134 | TP_PROTO(struct wiphy *wiphy, | ||
1135 | struct net_device *netdev, s32 rssi_thold, | ||
1136 | u32 rssi_hyst), | ||
1137 | TP_ARGS(wiphy, netdev, rssi_thold, rssi_hyst), | ||
1138 | TP_STRUCT__entry( | ||
1139 | WIPHY_ENTRY | ||
1140 | NETDEV_ENTRY | ||
1141 | __field(s32, rssi_thold) | ||
1142 | __field(u32, rssi_hyst) | ||
1143 | ), | ||
1144 | TP_fast_assign( | ||
1145 | WIPHY_ASSIGN; | ||
1146 | NETDEV_ASSIGN; | ||
1147 | __entry->rssi_thold = rssi_thold; | ||
1148 | __entry->rssi_hyst = rssi_hyst; | ||
1149 | ), | ||
1150 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT | ||
1151 | ", rssi_thold: %d, rssi_hyst: %u ", | ||
1152 | WIPHY_PR_ARG, NETDEV_PR_ARG, | ||
1153 | __entry->rssi_thold, __entry->rssi_hyst) | ||
1154 | ); | ||
1155 | |||
1156 | TRACE_EVENT(rdev_set_cqm_txe_config, | ||
1157 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 rate, | ||
1158 | u32 pkts, u32 intvl), | ||
1159 | TP_ARGS(wiphy, netdev, rate, pkts, intvl), | ||
1160 | TP_STRUCT__entry( | ||
1161 | WIPHY_ENTRY | ||
1162 | NETDEV_ENTRY | ||
1163 | __field(u32, rate) | ||
1164 | __field(u32, pkts) | ||
1165 | __field(u32, intvl) | ||
1166 | ), | ||
1167 | TP_fast_assign( | ||
1168 | WIPHY_ASSIGN; | ||
1169 | NETDEV_ASSIGN; | ||
1170 | __entry->rate = rate; | ||
1171 | __entry->pkts = pkts; | ||
1172 | __entry->intvl = intvl; | ||
1173 | ), | ||
1174 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u", | ||
1175 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts, | ||
1176 | __entry->intvl) | ||
1177 | ); | ||
1178 | |||
1179 | TRACE_EVENT(rdev_disconnect, | ||
1180 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1181 | u16 reason_code), | ||
1182 | TP_ARGS(wiphy, netdev, reason_code), | ||
1183 | TP_STRUCT__entry( | ||
1184 | WIPHY_ENTRY | ||
1185 | NETDEV_ENTRY | ||
1186 | __field(u16, reason_code) | ||
1187 | ), | ||
1188 | TP_fast_assign( | ||
1189 | WIPHY_ASSIGN; | ||
1190 | NETDEV_ASSIGN; | ||
1191 | __entry->reason_code = reason_code; | ||
1192 | ), | ||
1193 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG, | ||
1194 | NETDEV_PR_ARG, __entry->reason_code) | ||
1195 | ); | ||
1196 | |||
1197 | TRACE_EVENT(rdev_join_ibss, | ||
1198 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1199 | struct cfg80211_ibss_params *params), | ||
1200 | TP_ARGS(wiphy, netdev, params), | ||
1201 | TP_STRUCT__entry( | ||
1202 | WIPHY_ENTRY | ||
1203 | NETDEV_ENTRY | ||
1204 | MAC_ENTRY(bssid) | ||
1205 | __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) | ||
1206 | ), | ||
1207 | TP_fast_assign( | ||
1208 | WIPHY_ASSIGN; | ||
1209 | NETDEV_ASSIGN; | ||
1210 | MAC_ASSIGN(bssid, params->bssid); | ||
1211 | memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); | ||
1212 | memcpy(__entry->ssid, params->ssid, params->ssid_len); | ||
1213 | ), | ||
1214 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s", | ||
1215 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) | ||
1216 | ); | ||
1217 | |||
1218 | TRACE_EVENT(rdev_set_wiphy_params, | ||
1219 | TP_PROTO(struct wiphy *wiphy, u32 changed), | ||
1220 | TP_ARGS(wiphy, changed), | ||
1221 | TP_STRUCT__entry( | ||
1222 | WIPHY_ENTRY | ||
1223 | __field(u32, changed) | ||
1224 | ), | ||
1225 | TP_fast_assign( | ||
1226 | WIPHY_ASSIGN; | ||
1227 | __entry->changed = changed; | ||
1228 | ), | ||
1229 | TP_printk(WIPHY_PR_FMT ", changed: %u", | ||
1230 | WIPHY_PR_ARG, __entry->changed) | ||
1231 | ); | ||
1232 | |||
1233 | TRACE_EVENT(rdev_set_tx_power, | ||
1234 | TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_setting type, | ||
1235 | int mbm), | ||
1236 | TP_ARGS(wiphy, type, mbm), | ||
1237 | TP_STRUCT__entry( | ||
1238 | WIPHY_ENTRY | ||
1239 | __field(enum nl80211_tx_power_setting, type) | ||
1240 | __field(int, mbm) | ||
1241 | ), | ||
1242 | TP_fast_assign( | ||
1243 | WIPHY_ASSIGN; | ||
1244 | __entry->type = type; | ||
1245 | __entry->mbm = mbm; | ||
1246 | ), | ||
1247 | TP_printk(WIPHY_PR_FMT ", type: %d, mbm: %d", | ||
1248 | WIPHY_PR_ARG, __entry->type, __entry->mbm) | ||
1249 | ); | ||
1250 | |||
1251 | TRACE_EVENT(rdev_return_int_int, | ||
1252 | TP_PROTO(struct wiphy *wiphy, int func_ret, int func_fill), | ||
1253 | TP_ARGS(wiphy, func_ret, func_fill), | ||
1254 | TP_STRUCT__entry( | ||
1255 | WIPHY_ENTRY | ||
1256 | __field(int, func_ret) | ||
1257 | __field(int, func_fill) | ||
1258 | ), | ||
1259 | TP_fast_assign( | ||
1260 | WIPHY_ASSIGN; | ||
1261 | __entry->func_ret = func_ret; | ||
1262 | __entry->func_fill = func_fill; | ||
1263 | ), | ||
1264 | TP_printk(WIPHY_PR_FMT ", function returns: %d, function filled: %d", | ||
1265 | WIPHY_PR_ARG, __entry->func_ret, __entry->func_fill) | ||
1266 | ); | ||
1267 | |||
1268 | #ifdef CONFIG_NL80211_TESTMODE | ||
1269 | TRACE_EVENT(rdev_testmode_cmd, | ||
1270 | TP_PROTO(struct wiphy *wiphy), | ||
1271 | TP_ARGS(wiphy), | ||
1272 | TP_STRUCT__entry( | ||
1273 | WIPHY_ENTRY | ||
1274 | ), | ||
1275 | TP_fast_assign( | ||
1276 | WIPHY_ASSIGN; | ||
1277 | ), | ||
1278 | TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) | ||
1279 | ); | ||
1280 | |||
1281 | TRACE_EVENT(rdev_testmode_dump, | ||
1282 | TP_PROTO(struct wiphy *wiphy), | ||
1283 | TP_ARGS(wiphy), | ||
1284 | TP_STRUCT__entry( | ||
1285 | WIPHY_ENTRY | ||
1286 | ), | ||
1287 | TP_fast_assign( | ||
1288 | WIPHY_ASSIGN; | ||
1289 | ), | ||
1290 | TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) | ||
1291 | ); | ||
1292 | #endif /* CONFIG_NL80211_TESTMODE */ | ||
1293 | |||
1294 | TRACE_EVENT(rdev_set_bitrate_mask, | ||
1295 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1296 | const u8 *peer, const struct cfg80211_bitrate_mask *mask), | ||
1297 | TP_ARGS(wiphy, netdev, peer, mask), | ||
1298 | TP_STRUCT__entry( | ||
1299 | WIPHY_ENTRY | ||
1300 | NETDEV_ENTRY | ||
1301 | MAC_ENTRY(peer) | ||
1302 | ), | ||
1303 | TP_fast_assign( | ||
1304 | WIPHY_ASSIGN; | ||
1305 | NETDEV_ASSIGN; | ||
1306 | MAC_ASSIGN(peer, peer); | ||
1307 | ), | ||
1308 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", peer: " MAC_PR_FMT, | ||
1309 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) | ||
1310 | ); | ||
1311 | |||
1312 | TRACE_EVENT(rdev_mgmt_frame_register, | ||
1313 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
1314 | u16 frame_type, bool reg), | ||
1315 | TP_ARGS(wiphy, wdev, frame_type, reg), | ||
1316 | TP_STRUCT__entry( | ||
1317 | WIPHY_ENTRY | ||
1318 | WDEV_ENTRY | ||
1319 | __field(u16, frame_type) | ||
1320 | __field(bool, reg) | ||
1321 | ), | ||
1322 | TP_fast_assign( | ||
1323 | WIPHY_ASSIGN; | ||
1324 | WDEV_ASSIGN; | ||
1325 | __entry->frame_type = frame_type; | ||
1326 | __entry->reg = reg; | ||
1327 | ), | ||
1328 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", frame_type: %u, reg: %s ", | ||
1329 | WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type, | ||
1330 | __entry->reg ? "true" : "false") | ||
1331 | ); | ||
1332 | |||
1333 | TRACE_EVENT(rdev_return_int_tx_rx, | ||
1334 | TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx), | ||
1335 | TP_ARGS(wiphy, ret, tx, rx), | ||
1336 | TP_STRUCT__entry( | ||
1337 | WIPHY_ENTRY | ||
1338 | __field(int, ret) | ||
1339 | __field(u32, tx) | ||
1340 | __field(u32, rx) | ||
1341 | ), | ||
1342 | TP_fast_assign( | ||
1343 | WIPHY_ASSIGN; | ||
1344 | __entry->ret = ret; | ||
1345 | __entry->tx = tx; | ||
1346 | __entry->rx = rx; | ||
1347 | ), | ||
1348 | TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u", | ||
1349 | WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx) | ||
1350 | ); | ||
1351 | |||
1352 | TRACE_EVENT(rdev_return_void_tx_rx, | ||
1353 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 tx_max, | ||
1354 | u32 rx, u32 rx_max), | ||
1355 | TP_ARGS(wiphy, tx, tx_max, rx, rx_max), | ||
1356 | TP_STRUCT__entry( | ||
1357 | WIPHY_ENTRY | ||
1358 | __field(u32, tx) | ||
1359 | __field(u32, tx_max) | ||
1360 | __field(u32, rx) | ||
1361 | __field(u32, rx_max) | ||
1362 | ), | ||
1363 | TP_fast_assign( | ||
1364 | WIPHY_ASSIGN; | ||
1365 | __entry->tx = tx; | ||
1366 | __entry->tx_max = tx_max; | ||
1367 | __entry->rx = rx; | ||
1368 | __entry->rx_max = rx_max; | ||
1369 | ), | ||
1370 | TP_printk(WIPHY_PR_FMT ", tx: %u, tx_max: %u, rx: %u, rx_max: %u ", | ||
1371 | WIPHY_PR_ARG, __entry->tx, __entry->tx_max, __entry->rx, | ||
1372 | __entry->rx_max) | ||
1373 | ); | ||
1374 | |||
1375 | DECLARE_EVENT_CLASS(tx_rx_evt, | ||
1376 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), | ||
1377 | TP_ARGS(wiphy, rx, tx), | ||
1378 | TP_STRUCT__entry( | ||
1379 | WIPHY_ENTRY | ||
1380 | __field(u32, tx) | ||
1381 | __field(u32, rx) | ||
1382 | ), | ||
1383 | TP_fast_assign( | ||
1384 | WIPHY_ASSIGN; | ||
1385 | __entry->tx = tx; | ||
1386 | __entry->rx = rx; | ||
1387 | ), | ||
1388 | TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u ", | ||
1389 | WIPHY_PR_ARG, __entry->tx, __entry->rx) | ||
1390 | ); | ||
1391 | |||
1392 | DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam, | ||
1393 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), | ||
1394 | TP_ARGS(wiphy, rx, tx) | ||
1395 | ); | ||
1396 | |||
1397 | DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, | ||
1398 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), | ||
1399 | TP_ARGS(wiphy, rx, tx) | ||
1400 | ); | ||
1401 | |||
1402 | TRACE_EVENT(rdev_sched_scan_start, | ||
1403 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1404 | struct cfg80211_sched_scan_request *request), | ||
1405 | TP_ARGS(wiphy, netdev, request), | ||
1406 | TP_STRUCT__entry( | ||
1407 | WIPHY_ENTRY | ||
1408 | NETDEV_ENTRY | ||
1409 | ), | ||
1410 | TP_fast_assign( | ||
1411 | WIPHY_ASSIGN; | ||
1412 | NETDEV_ASSIGN; | ||
1413 | ), | ||
1414 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, | ||
1415 | WIPHY_PR_ARG, NETDEV_PR_ARG) | ||
1416 | ); | ||
1417 | |||
1418 | TRACE_EVENT(rdev_tdls_mgmt, | ||
1419 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1420 | u8 *peer, u8 action_code, u8 dialog_token, | ||
1421 | u16 status_code, const u8 *buf, size_t len), | ||
1422 | TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, | ||
1423 | buf, len), | ||
1424 | TP_STRUCT__entry( | ||
1425 | WIPHY_ENTRY | ||
1426 | NETDEV_ENTRY | ||
1427 | MAC_ENTRY(peer) | ||
1428 | __field(u8, action_code) | ||
1429 | __field(u8, dialog_token) | ||
1430 | __field(u16, status_code) | ||
1431 | __dynamic_array(u8, buf, len) | ||
1432 | ), | ||
1433 | TP_fast_assign( | ||
1434 | WIPHY_ASSIGN; | ||
1435 | NETDEV_ASSIGN; | ||
1436 | MAC_ASSIGN(peer, peer); | ||
1437 | __entry->action_code = action_code; | ||
1438 | __entry->dialog_token = dialog_token; | ||
1439 | __entry->status_code = status_code; | ||
1440 | memcpy(__get_dynamic_array(buf), buf, len); | ||
1441 | ), | ||
1442 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", action_code: %u, " | ||
1443 | "dialog_token: %u, status_code: %u, buf: %#.2x ", | ||
1444 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), | ||
1445 | __entry->action_code, __entry->dialog_token, | ||
1446 | __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) | ||
1447 | ); | ||
1448 | |||
1449 | TRACE_EVENT(rdev_dump_survey, | ||
1450 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx), | ||
1451 | TP_ARGS(wiphy, netdev, idx), | ||
1452 | TP_STRUCT__entry( | ||
1453 | WIPHY_ENTRY | ||
1454 | NETDEV_ENTRY | ||
1455 | __field(int, idx) | ||
1456 | ), | ||
1457 | TP_fast_assign( | ||
1458 | WIPHY_ASSIGN; | ||
1459 | NETDEV_ASSIGN; | ||
1460 | __entry->idx = idx; | ||
1461 | ), | ||
1462 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d", | ||
1463 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx) | ||
1464 | ); | ||
1465 | |||
1466 | TRACE_EVENT(rdev_return_int_survey_info, | ||
1467 | TP_PROTO(struct wiphy *wiphy, int ret, struct survey_info *info), | ||
1468 | TP_ARGS(wiphy, ret, info), | ||
1469 | TP_STRUCT__entry( | ||
1470 | WIPHY_ENTRY | ||
1471 | CHAN_ENTRY | ||
1472 | __field(int, ret) | ||
1473 | __field(u64, channel_time) | ||
1474 | __field(u64, channel_time_busy) | ||
1475 | __field(u64, channel_time_ext_busy) | ||
1476 | __field(u64, channel_time_rx) | ||
1477 | __field(u64, channel_time_tx) | ||
1478 | __field(u32, filled) | ||
1479 | __field(s8, noise) | ||
1480 | ), | ||
1481 | TP_fast_assign( | ||
1482 | WIPHY_ASSIGN; | ||
1483 | CHAN_ASSIGN(info->channel); | ||
1484 | __entry->ret = ret; | ||
1485 | __entry->channel_time = info->channel_time; | ||
1486 | __entry->channel_time_busy = info->channel_time_busy; | ||
1487 | __entry->channel_time_ext_busy = info->channel_time_ext_busy; | ||
1488 | __entry->channel_time_rx = info->channel_time_rx; | ||
1489 | __entry->channel_time_tx = info->channel_time_tx; | ||
1490 | __entry->filled = info->filled; | ||
1491 | __entry->noise = info->noise; | ||
1492 | ), | ||
1493 | TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT | ||
1494 | ", channel time: %llu, channel time busy: %llu, " | ||
1495 | "channel time extension busy: %llu, channel time rx: %llu, " | ||
1496 | "channel time tx: %llu, filled: %u, noise: %d", | ||
1497 | WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG, | ||
1498 | __entry->channel_time, __entry->channel_time_busy, | ||
1499 | __entry->channel_time_ext_busy, __entry->channel_time_rx, | ||
1500 | __entry->channel_time_tx, __entry->filled, __entry->noise) | ||
1501 | ); | ||
1502 | |||
1503 | TRACE_EVENT(rdev_tdls_oper, | ||
1504 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1505 | u8 *peer, enum nl80211_tdls_operation oper), | ||
1506 | TP_ARGS(wiphy, netdev, peer, oper), | ||
1507 | TP_STRUCT__entry( | ||
1508 | WIPHY_ENTRY | ||
1509 | NETDEV_ENTRY | ||
1510 | MAC_ENTRY(peer) | ||
1511 | __field(enum nl80211_tdls_operation, oper) | ||
1512 | ), | ||
1513 | TP_fast_assign( | ||
1514 | WIPHY_ASSIGN; | ||
1515 | NETDEV_ASSIGN; | ||
1516 | MAC_ASSIGN(peer, peer); | ||
1517 | __entry->oper = oper; | ||
1518 | ), | ||
1519 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", oper: %d", | ||
1520 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper) | ||
1521 | ); | ||
1522 | |||
1523 | DECLARE_EVENT_CLASS(rdev_pmksa, | ||
1524 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1525 | struct cfg80211_pmksa *pmksa), | ||
1526 | TP_ARGS(wiphy, netdev, pmksa), | ||
1527 | TP_STRUCT__entry( | ||
1528 | WIPHY_ENTRY | ||
1529 | NETDEV_ENTRY | ||
1530 | MAC_ENTRY(bssid) | ||
1531 | ), | ||
1532 | TP_fast_assign( | ||
1533 | WIPHY_ASSIGN; | ||
1534 | NETDEV_ASSIGN; | ||
1535 | MAC_ASSIGN(bssid, pmksa->bssid); | ||
1536 | ), | ||
1537 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT, | ||
1538 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid)) | ||
1539 | ); | ||
1540 | |||
1541 | TRACE_EVENT(rdev_probe_client, | ||
1542 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1543 | const u8 *peer), | ||
1544 | TP_ARGS(wiphy, netdev, peer), | ||
1545 | TP_STRUCT__entry( | ||
1546 | WIPHY_ENTRY | ||
1547 | NETDEV_ENTRY | ||
1548 | MAC_ENTRY(peer) | ||
1549 | ), | ||
1550 | TP_fast_assign( | ||
1551 | WIPHY_ASSIGN; | ||
1552 | NETDEV_ASSIGN; | ||
1553 | MAC_ASSIGN(peer, peer); | ||
1554 | ), | ||
1555 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT, | ||
1556 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) | ||
1557 | ); | ||
1558 | |||
1559 | DEFINE_EVENT(rdev_pmksa, rdev_set_pmksa, | ||
1560 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1561 | struct cfg80211_pmksa *pmksa), | ||
1562 | TP_ARGS(wiphy, netdev, pmksa) | ||
1563 | ); | ||
1564 | |||
1565 | DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa, | ||
1566 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1567 | struct cfg80211_pmksa *pmksa), | ||
1568 | TP_ARGS(wiphy, netdev, pmksa) | ||
1569 | ); | ||
1570 | |||
1571 | TRACE_EVENT(rdev_remain_on_channel, | ||
1572 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
1573 | struct ieee80211_channel *chan, | ||
1574 | enum nl80211_channel_type channel_type, unsigned int duration), | ||
1575 | TP_ARGS(wiphy, wdev, chan, channel_type, duration), | ||
1576 | TP_STRUCT__entry( | ||
1577 | WIPHY_ENTRY | ||
1578 | WDEV_ENTRY | ||
1579 | CHAN_ENTRY | ||
1580 | __field(enum nl80211_channel_type, channel_type) | ||
1581 | __field(unsigned int, duration) | ||
1582 | ), | ||
1583 | TP_fast_assign( | ||
1584 | WIPHY_ASSIGN; | ||
1585 | WDEV_ASSIGN; | ||
1586 | CHAN_ASSIGN(chan); | ||
1587 | __entry->channel_type = channel_type; | ||
1588 | __entry->duration = duration; | ||
1589 | ), | ||
1590 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", channel type: %d, duration: %u", | ||
1591 | WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->channel_type, | ||
1592 | __entry->duration) | ||
1593 | ); | ||
1594 | |||
1595 | TRACE_EVENT(rdev_return_int_cookie, | ||
1596 | TP_PROTO(struct wiphy *wiphy, int ret, u64 cookie), | ||
1597 | TP_ARGS(wiphy, ret, cookie), | ||
1598 | TP_STRUCT__entry( | ||
1599 | WIPHY_ENTRY | ||
1600 | __field(int, ret) | ||
1601 | __field(u64, cookie) | ||
1602 | ), | ||
1603 | TP_fast_assign( | ||
1604 | WIPHY_ASSIGN; | ||
1605 | __entry->ret = ret; | ||
1606 | __entry->cookie = cookie; | ||
1607 | ), | ||
1608 | TP_printk(WIPHY_PR_FMT ", returned %d, cookie: %llu", | ||
1609 | WIPHY_PR_ARG, __entry->ret, __entry->cookie) | ||
1610 | ); | ||
1611 | |||
1612 | TRACE_EVENT(rdev_cancel_remain_on_channel, | ||
1613 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie), | ||
1614 | TP_ARGS(wiphy, wdev, cookie), | ||
1615 | TP_STRUCT__entry( | ||
1616 | WIPHY_ENTRY | ||
1617 | WDEV_ENTRY | ||
1618 | __field(u64, cookie) | ||
1619 | ), | ||
1620 | TP_fast_assign( | ||
1621 | WIPHY_ASSIGN; | ||
1622 | WDEV_ASSIGN; | ||
1623 | __entry->cookie = cookie; | ||
1624 | ), | ||
1625 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu", | ||
1626 | WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) | ||
1627 | ); | ||
1628 | |||
1629 | TRACE_EVENT(rdev_mgmt_tx, | ||
1630 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
1631 | struct ieee80211_channel *chan, bool offchan, | ||
1632 | enum nl80211_channel_type channel_type, | ||
1633 | bool channel_type_valid, unsigned int wait, bool no_cck, | ||
1634 | bool dont_wait_for_ack), | ||
1635 | TP_ARGS(wiphy, wdev, chan, offchan, channel_type, channel_type_valid, | ||
1636 | wait, no_cck, dont_wait_for_ack), | ||
1637 | TP_STRUCT__entry( | ||
1638 | WIPHY_ENTRY | ||
1639 | WDEV_ENTRY | ||
1640 | CHAN_ENTRY | ||
1641 | __field(bool, offchan) | ||
1642 | __field(enum nl80211_channel_type, channel_type) | ||
1643 | __field(bool, channel_type_valid) | ||
1644 | __field(unsigned int, wait) | ||
1645 | __field(bool, no_cck) | ||
1646 | __field(bool, dont_wait_for_ack) | ||
1647 | ), | ||
1648 | TP_fast_assign( | ||
1649 | WIPHY_ASSIGN; | ||
1650 | WDEV_ASSIGN; | ||
1651 | CHAN_ASSIGN(chan); | ||
1652 | __entry->offchan = offchan; | ||
1653 | __entry->channel_type = channel_type; | ||
1654 | __entry->channel_type_valid = channel_type_valid; | ||
1655 | __entry->wait = wait; | ||
1656 | __entry->no_cck = no_cck; | ||
1657 | __entry->dont_wait_for_ack = dont_wait_for_ack; | ||
1658 | ), | ||
1659 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", offchan: %s, " | ||
1660 | "channel type: %d, channel type valid: %s, wait: %u, " | ||
1661 | "no cck: %s, dont wait for ack: %s", | ||
1662 | WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, | ||
1663 | BOOL_TO_STR(__entry->offchan), __entry->channel_type, | ||
1664 | BOOL_TO_STR(__entry->channel_type_valid), __entry->wait, | ||
1665 | BOOL_TO_STR(__entry->no_cck), | ||
1666 | BOOL_TO_STR(__entry->dont_wait_for_ack)) | ||
1667 | ); | ||
1668 | |||
1669 | TRACE_EVENT(rdev_set_noack_map, | ||
1670 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1671 | u16 noack_map), | ||
1672 | TP_ARGS(wiphy, netdev, noack_map), | ||
1673 | TP_STRUCT__entry( | ||
1674 | WIPHY_ENTRY | ||
1675 | NETDEV_ENTRY | ||
1676 | __field(u16, noack_map) | ||
1677 | ), | ||
1678 | TP_fast_assign( | ||
1679 | WIPHY_ASSIGN; | ||
1680 | NETDEV_ASSIGN; | ||
1681 | __entry->noack_map = noack_map; | ||
1682 | ), | ||
1683 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", noack_map: %u", | ||
1684 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) | ||
1685 | ); | ||
1686 | |||
1687 | TRACE_EVENT(rdev_get_et_sset_count, | ||
1688 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset), | ||
1689 | TP_ARGS(wiphy, netdev, sset), | ||
1690 | TP_STRUCT__entry( | ||
1691 | WIPHY_ENTRY | ||
1692 | NETDEV_ENTRY | ||
1693 | __field(int, sset) | ||
1694 | ), | ||
1695 | TP_fast_assign( | ||
1696 | WIPHY_ASSIGN; | ||
1697 | NETDEV_ASSIGN; | ||
1698 | __entry->sset = sset; | ||
1699 | ), | ||
1700 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %d", | ||
1701 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) | ||
1702 | ); | ||
1703 | |||
1704 | TRACE_EVENT(rdev_get_et_strings, | ||
1705 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset), | ||
1706 | TP_ARGS(wiphy, netdev, sset), | ||
1707 | TP_STRUCT__entry( | ||
1708 | WIPHY_ENTRY | ||
1709 | NETDEV_ENTRY | ||
1710 | __field(u32, sset) | ||
1711 | ), | ||
1712 | TP_fast_assign( | ||
1713 | WIPHY_ASSIGN; | ||
1714 | NETDEV_ASSIGN; | ||
1715 | __entry->sset = sset; | ||
1716 | ), | ||
1717 | TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %u", | ||
1718 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) | ||
1719 | ); | ||
1720 | |||
1721 | DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, | ||
1722 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
1723 | TP_ARGS(wiphy, wdev) | ||
1724 | ); | ||
1725 | |||
1726 | TRACE_EVENT(rdev_return_channel, | ||
1727 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, | ||
1728 | enum nl80211_channel_type type), | ||
1729 | TP_ARGS(wiphy, chan, type), | ||
1730 | TP_STRUCT__entry( | ||
1731 | WIPHY_ENTRY | ||
1732 | CHAN_ENTRY | ||
1733 | __field(enum nl80211_channel_type, type) | ||
1734 | ), | ||
1735 | TP_fast_assign( | ||
1736 | WIPHY_ASSIGN; | ||
1737 | CHAN_ASSIGN(chan); | ||
1738 | __entry->type = type; | ||
1739 | ), | ||
1740 | TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d", | ||
1741 | WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type) | ||
1742 | ); | ||
1743 | |||
1744 | DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, | ||
1745 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
1746 | TP_ARGS(wiphy, wdev) | ||
1747 | ); | ||
1748 | |||
1749 | DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device, | ||
1750 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
1751 | TP_ARGS(wiphy, wdev) | ||
1752 | ); | ||
1753 | |||
1754 | /************************************************************* | ||
1755 | * cfg80211 exported functions traces * | ||
1756 | *************************************************************/ | ||
1757 | |||
1758 | TRACE_EVENT(cfg80211_return_bool, | ||
1759 | TP_PROTO(bool ret), | ||
1760 | TP_ARGS(ret), | ||
1761 | TP_STRUCT__entry( | ||
1762 | __field(bool, ret) | ||
1763 | ), | ||
1764 | TP_fast_assign( | ||
1765 | __entry->ret = ret; | ||
1766 | ), | ||
1767 | TP_printk("returned %s", BOOL_TO_STR(__entry->ret)) | ||
1768 | ); | ||
1769 | |||
1770 | DECLARE_EVENT_CLASS(cfg80211_netdev_mac_evt, | ||
1771 | TP_PROTO(struct net_device *netdev, const u8 *macaddr), | ||
1772 | TP_ARGS(netdev, macaddr), | ||
1773 | TP_STRUCT__entry( | ||
1774 | NETDEV_ENTRY | ||
1775 | MAC_ENTRY(macaddr) | ||
1776 | ), | ||
1777 | TP_fast_assign( | ||
1778 | NETDEV_ASSIGN; | ||
1779 | MAC_ASSIGN(macaddr, macaddr); | ||
1780 | ), | ||
1781 | TP_printk(NETDEV_PR_FMT ", mac: " MAC_PR_FMT, | ||
1782 | NETDEV_PR_ARG, MAC_PR_ARG(macaddr)) | ||
1783 | ); | ||
1784 | |||
1785 | DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_notify_new_peer_candidate, | ||
1786 | TP_PROTO(struct net_device *netdev, const u8 *macaddr), | ||
1787 | TP_ARGS(netdev, macaddr) | ||
1788 | ); | ||
1789 | |||
1790 | DECLARE_EVENT_CLASS(netdev_evt_only, | ||
1791 | TP_PROTO(struct net_device *netdev), | ||
1792 | TP_ARGS(netdev), | ||
1793 | TP_STRUCT__entry( | ||
1794 | NETDEV_ENTRY | ||
1795 | ), | ||
1796 | TP_fast_assign( | ||
1797 | NETDEV_ASSIGN; | ||
1798 | ), | ||
1799 | TP_printk(NETDEV_PR_FMT , NETDEV_PR_ARG) | ||
1800 | ); | ||
1801 | |||
1802 | DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth, | ||
1803 | TP_PROTO(struct net_device *netdev), | ||
1804 | TP_ARGS(netdev) | ||
1805 | ); | ||
1806 | |||
1807 | TRACE_EVENT(cfg80211_send_rx_assoc, | ||
1808 | TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss), | ||
1809 | TP_ARGS(netdev, bss), | ||
1810 | TP_STRUCT__entry( | ||
1811 | NETDEV_ENTRY | ||
1812 | MAC_ENTRY(bssid) | ||
1813 | CHAN_ENTRY | ||
1814 | ), | ||
1815 | TP_fast_assign( | ||
1816 | NETDEV_ASSIGN; | ||
1817 | MAC_ASSIGN(bssid, bss->bssid); | ||
1818 | CHAN_ASSIGN(bss->channel); | ||
1819 | ), | ||
1820 | TP_printk(NETDEV_PR_FMT MAC_PR_FMT CHAN_PR_FMT, | ||
1821 | NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) | ||
1822 | ); | ||
1823 | |||
1824 | DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, | ||
1825 | TP_PROTO(struct net_device *netdev), | ||
1826 | TP_ARGS(netdev) | ||
1827 | ); | ||
1828 | |||
1829 | DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, | ||
1830 | TP_PROTO(struct net_device *netdev), | ||
1831 | TP_ARGS(netdev) | ||
1832 | ); | ||
1833 | |||
1834 | DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_deauth, | ||
1835 | TP_PROTO(struct net_device *netdev), | ||
1836 | TP_ARGS(netdev) | ||
1837 | ); | ||
1838 | |||
1839 | DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_disassoc, | ||
1840 | TP_PROTO(struct net_device *netdev), | ||
1841 | TP_ARGS(netdev) | ||
1842 | ); | ||
1843 | |||
1844 | DECLARE_EVENT_CLASS(netdev_mac_evt, | ||
1845 | TP_PROTO(struct net_device *netdev, const u8 *mac), | ||
1846 | TP_ARGS(netdev, mac), | ||
1847 | TP_STRUCT__entry( | ||
1848 | NETDEV_ENTRY | ||
1849 | MAC_ENTRY(mac) | ||
1850 | ), | ||
1851 | TP_fast_assign( | ||
1852 | NETDEV_ASSIGN; | ||
1853 | MAC_ASSIGN(mac, mac) | ||
1854 | ), | ||
1855 | TP_printk(NETDEV_PR_FMT ", mac: " MAC_PR_FMT, | ||
1856 | NETDEV_PR_ARG, MAC_PR_ARG(mac)) | ||
1857 | ); | ||
1858 | |||
1859 | DEFINE_EVENT(netdev_mac_evt, cfg80211_send_auth_timeout, | ||
1860 | TP_PROTO(struct net_device *netdev, const u8 *mac), | ||
1861 | TP_ARGS(netdev, mac) | ||
1862 | ); | ||
1863 | |||
1864 | DEFINE_EVENT(netdev_mac_evt, cfg80211_send_assoc_timeout, | ||
1865 | TP_PROTO(struct net_device *netdev, const u8 *mac), | ||
1866 | TP_ARGS(netdev, mac) | ||
1867 | ); | ||
1868 | |||
1869 | TRACE_EVENT(cfg80211_michael_mic_failure, | ||
1870 | TP_PROTO(struct net_device *netdev, const u8 *addr, | ||
1871 | enum nl80211_key_type key_type, int key_id, const u8 *tsc), | ||
1872 | TP_ARGS(netdev, addr, key_type, key_id, tsc), | ||
1873 | TP_STRUCT__entry( | ||
1874 | NETDEV_ENTRY | ||
1875 | MAC_ENTRY(addr) | ||
1876 | __field(enum nl80211_key_type, key_type) | ||
1877 | __field(int, key_id) | ||
1878 | __array(u8, tsc, 6) | ||
1879 | ), | ||
1880 | TP_fast_assign( | ||
1881 | NETDEV_ASSIGN; | ||
1882 | MAC_ASSIGN(addr, addr); | ||
1883 | __entry->key_type = key_type; | ||
1884 | __entry->key_id = key_id; | ||
1885 | memcpy(__entry->tsc, tsc, 6); | ||
1886 | ), | ||
1887 | TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", | ||
1888 | NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type, | ||
1889 | __entry->key_id, __entry->tsc) | ||
1890 | ); | ||
1891 | |||
1892 | TRACE_EVENT(cfg80211_ready_on_channel, | ||
1893 | TP_PROTO(struct wireless_dev *wdev, u64 cookie, | ||
1894 | struct ieee80211_channel *chan, | ||
1895 | enum nl80211_channel_type channel_type, unsigned int duration), | ||
1896 | TP_ARGS(wdev, cookie, chan, channel_type, duration), | ||
1897 | TP_STRUCT__entry( | ||
1898 | WDEV_ENTRY | ||
1899 | __field(u64, cookie) | ||
1900 | CHAN_ENTRY | ||
1901 | __field(enum nl80211_channel_type, channel_type) | ||
1902 | __field(unsigned int, duration) | ||
1903 | ), | ||
1904 | TP_fast_assign( | ||
1905 | WDEV_ASSIGN; | ||
1906 | __entry->cookie = cookie; | ||
1907 | CHAN_ASSIGN(chan); | ||
1908 | __entry->channel_type = channel_type; | ||
1909 | __entry->duration = duration; | ||
1910 | ), | ||
1911 | TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d, duration: %u", | ||
1912 | WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, | ||
1913 | __entry->channel_type, __entry->duration) | ||
1914 | ); | ||
1915 | |||
1916 | TRACE_EVENT(cfg80211_ready_on_channel_expired, | ||
1917 | TP_PROTO(struct wireless_dev *wdev, u64 cookie, | ||
1918 | struct ieee80211_channel *chan, | ||
1919 | enum nl80211_channel_type channel_type), | ||
1920 | TP_ARGS(wdev, cookie, chan, channel_type), | ||
1921 | TP_STRUCT__entry( | ||
1922 | WDEV_ENTRY | ||
1923 | __field(u64, cookie) | ||
1924 | CHAN_ENTRY | ||
1925 | __field(enum nl80211_channel_type, channel_type) | ||
1926 | ), | ||
1927 | TP_fast_assign( | ||
1928 | WDEV_ASSIGN; | ||
1929 | __entry->cookie = cookie; | ||
1930 | CHAN_ASSIGN(chan); | ||
1931 | __entry->channel_type = channel_type; | ||
1932 | ), | ||
1933 | TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d", | ||
1934 | WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, | ||
1935 | __entry->channel_type) | ||
1936 | ); | ||
1937 | |||
1938 | TRACE_EVENT(cfg80211_new_sta, | ||
1939 | TP_PROTO(struct net_device *netdev, const u8 *mac_addr, | ||
1940 | struct station_info *sinfo), | ||
1941 | TP_ARGS(netdev, mac_addr, sinfo), | ||
1942 | TP_STRUCT__entry( | ||
1943 | NETDEV_ENTRY | ||
1944 | MAC_ENTRY(mac_addr) | ||
1945 | SINFO_ENTRY | ||
1946 | ), | ||
1947 | TP_fast_assign( | ||
1948 | NETDEV_ASSIGN; | ||
1949 | MAC_ASSIGN(mac_addr, mac_addr); | ||
1950 | SINFO_ASSIGN; | ||
1951 | ), | ||
1952 | TP_printk(NETDEV_PR_FMT MAC_PR_FMT, | ||
1953 | NETDEV_PR_ARG, MAC_PR_ARG(mac_addr)) | ||
1954 | ); | ||
1955 | |||
1956 | DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_del_sta, | ||
1957 | TP_PROTO(struct net_device *netdev, const u8 *macaddr), | ||
1958 | TP_ARGS(netdev, macaddr) | ||
1959 | ); | ||
1960 | |||
1961 | TRACE_EVENT(cfg80211_rx_mgmt, | ||
1962 | TP_PROTO(struct wireless_dev *wdev, int freq, int sig_mbm), | ||
1963 | TP_ARGS(wdev, freq, sig_mbm), | ||
1964 | TP_STRUCT__entry( | ||
1965 | WDEV_ENTRY | ||
1966 | __field(int, freq) | ||
1967 | __field(int, sig_mbm) | ||
1968 | ), | ||
1969 | TP_fast_assign( | ||
1970 | WDEV_ASSIGN; | ||
1971 | __entry->freq = freq; | ||
1972 | __entry->sig_mbm = sig_mbm; | ||
1973 | ), | ||
1974 | TP_printk(WDEV_PR_FMT ", freq: %d, sig mbm: %d", | ||
1975 | WDEV_PR_ARG, __entry->freq, __entry->sig_mbm) | ||
1976 | ); | ||
1977 | |||
1978 | TRACE_EVENT(cfg80211_mgmt_tx_status, | ||
1979 | TP_PROTO(struct wireless_dev *wdev, u64 cookie, bool ack), | ||
1980 | TP_ARGS(wdev, cookie, ack), | ||
1981 | TP_STRUCT__entry( | ||
1982 | WDEV_ENTRY | ||
1983 | __field(u64, cookie) | ||
1984 | __field(bool, ack) | ||
1985 | ), | ||
1986 | TP_fast_assign( | ||
1987 | WDEV_ASSIGN; | ||
1988 | __entry->cookie = cookie; | ||
1989 | __entry->ack = ack; | ||
1990 | ), | ||
1991 | TP_printk(WDEV_PR_FMT", cookie: %llu, ack: %s", | ||
1992 | WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack)) | ||
1993 | ); | ||
1994 | |||
1995 | TRACE_EVENT(cfg80211_cqm_rssi_notify, | ||
1996 | TP_PROTO(struct net_device *netdev, | ||
1997 | enum nl80211_cqm_rssi_threshold_event rssi_event), | ||
1998 | TP_ARGS(netdev, rssi_event), | ||
1999 | TP_STRUCT__entry( | ||
2000 | NETDEV_ENTRY | ||
2001 | __field(enum nl80211_cqm_rssi_threshold_event, rssi_event) | ||
2002 | ), | ||
2003 | TP_fast_assign( | ||
2004 | NETDEV_ASSIGN; | ||
2005 | __entry->rssi_event = rssi_event; | ||
2006 | ), | ||
2007 | TP_printk(NETDEV_PR_FMT ", rssi event: %d", | ||
2008 | NETDEV_PR_ARG, __entry->rssi_event) | ||
2009 | ); | ||
2010 | |||
2011 | TRACE_EVENT(cfg80211_can_beacon_sec_chan, | ||
2012 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, | ||
2013 | enum nl80211_channel_type channel_type), | ||
2014 | TP_ARGS(wiphy, channel, channel_type), | ||
2015 | TP_STRUCT__entry( | ||
2016 | WIPHY_ENTRY | ||
2017 | CHAN_ENTRY | ||
2018 | __field(enum nl80211_channel_type, channel_type) | ||
2019 | ), | ||
2020 | TP_fast_assign( | ||
2021 | WIPHY_ASSIGN; | ||
2022 | CHAN_ASSIGN(channel); | ||
2023 | __entry->channel_type = channel_type; | ||
2024 | ), | ||
2025 | TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d", | ||
2026 | WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type) | ||
2027 | ); | ||
2028 | |||
2029 | TRACE_EVENT(cfg80211_ch_switch_notify, | ||
2030 | TP_PROTO(struct net_device *netdev, int freq, | ||
2031 | enum nl80211_channel_type type), | ||
2032 | TP_ARGS(netdev, freq, type), | ||
2033 | TP_STRUCT__entry( | ||
2034 | NETDEV_ENTRY | ||
2035 | __field(int, freq) | ||
2036 | __field(enum nl80211_channel_type, type) | ||
2037 | ), | ||
2038 | TP_fast_assign( | ||
2039 | NETDEV_ASSIGN; | ||
2040 | __entry->freq = freq; | ||
2041 | __entry->type = type; | ||
2042 | ), | ||
2043 | TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG, | ||
2044 | __entry->freq, __entry->type) | ||
2045 | ); | ||
2046 | |||
2047 | DECLARE_EVENT_CLASS(cfg80211_rx_evt, | ||
2048 | TP_PROTO(struct net_device *netdev, const u8 *addr), | ||
2049 | TP_ARGS(netdev, addr), | ||
2050 | TP_STRUCT__entry( | ||
2051 | NETDEV_ENTRY | ||
2052 | MAC_ENTRY(addr) | ||
2053 | ), | ||
2054 | TP_fast_assign( | ||
2055 | NETDEV_ASSIGN; | ||
2056 | MAC_ASSIGN(addr, addr); | ||
2057 | ), | ||
2058 | TP_printk(NETDEV_PR_FMT MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) | ||
2059 | ); | ||
2060 | |||
2061 | DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, | ||
2062 | TP_PROTO(struct net_device *netdev, const u8 *addr), | ||
2063 | TP_ARGS(netdev, addr) | ||
2064 | ); | ||
2065 | |||
2066 | DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame, | ||
2067 | TP_PROTO(struct net_device *netdev, const u8 *addr), | ||
2068 | TP_ARGS(netdev, addr) | ||
2069 | ); | ||
2070 | |||
2071 | DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_unexpected_4addr_frame, | ||
2072 | TP_PROTO(struct net_device *netdev, const u8 *addr), | ||
2073 | TP_ARGS(netdev, addr) | ||
2074 | ); | ||
2075 | |||
2076 | TRACE_EVENT(cfg80211_probe_status, | ||
2077 | TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie, | ||
2078 | bool acked), | ||
2079 | TP_ARGS(netdev, addr, cookie, acked), | ||
2080 | TP_STRUCT__entry( | ||
2081 | NETDEV_ENTRY | ||
2082 | MAC_ENTRY(addr) | ||
2083 | __field(u64, cookie) | ||
2084 | __field(bool, acked) | ||
2085 | ), | ||
2086 | TP_fast_assign( | ||
2087 | NETDEV_ASSIGN; | ||
2088 | MAC_ASSIGN(addr, addr); | ||
2089 | __entry->cookie = cookie; | ||
2090 | __entry->acked = acked; | ||
2091 | ), | ||
2092 | TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", cookie: %llu, acked: %s", | ||
2093 | NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie, | ||
2094 | BOOL_TO_STR(__entry->acked)) | ||
2095 | ); | ||
2096 | |||
2097 | TRACE_EVENT(cfg80211_cqm_pktloss_notify, | ||
2098 | TP_PROTO(struct net_device *netdev, const u8 *peer, u32 num_packets), | ||
2099 | TP_ARGS(netdev, peer, num_packets), | ||
2100 | TP_STRUCT__entry( | ||
2101 | NETDEV_ENTRY | ||
2102 | MAC_ENTRY(peer) | ||
2103 | __field(u32, num_packets) | ||
2104 | ), | ||
2105 | TP_fast_assign( | ||
2106 | NETDEV_ASSIGN; | ||
2107 | MAC_ASSIGN(peer, peer); | ||
2108 | __entry->num_packets = num_packets; | ||
2109 | ), | ||
2110 | TP_printk(NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", num of lost packets: %u", | ||
2111 | NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->num_packets) | ||
2112 | ); | ||
2113 | |||
2114 | DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_gtk_rekey_notify, | ||
2115 | TP_PROTO(struct net_device *netdev, const u8 *macaddr), | ||
2116 | TP_ARGS(netdev, macaddr) | ||
2117 | ); | ||
2118 | |||
2119 | TRACE_EVENT(cfg80211_pmksa_candidate_notify, | ||
2120 | TP_PROTO(struct net_device *netdev, int index, const u8 *bssid, | ||
2121 | bool preauth), | ||
2122 | TP_ARGS(netdev, index, bssid, preauth), | ||
2123 | TP_STRUCT__entry( | ||
2124 | NETDEV_ENTRY | ||
2125 | __field(int, index) | ||
2126 | MAC_ENTRY(bssid) | ||
2127 | __field(bool, preauth) | ||
2128 | ), | ||
2129 | TP_fast_assign( | ||
2130 | NETDEV_ASSIGN; | ||
2131 | __entry->index = index; | ||
2132 | MAC_ASSIGN(bssid, bssid); | ||
2133 | __entry->preauth = preauth; | ||
2134 | ), | ||
2135 | TP_printk(NETDEV_PR_FMT ", index:%d, bssid: " MAC_PR_FMT ", pre auth: %s", | ||
2136 | NETDEV_PR_ARG, __entry->index, MAC_PR_ARG(bssid), | ||
2137 | BOOL_TO_STR(__entry->preauth)) | ||
2138 | ); | ||
2139 | |||
2140 | TRACE_EVENT(cfg80211_report_obss_beacon, | ||
2141 | TP_PROTO(struct wiphy *wiphy, const u8 *frame, size_t len, | ||
2142 | int freq, int sig_dbm), | ||
2143 | TP_ARGS(wiphy, frame, len, freq, sig_dbm), | ||
2144 | TP_STRUCT__entry( | ||
2145 | WIPHY_ENTRY | ||
2146 | __field(int, freq) | ||
2147 | __field(int, sig_dbm) | ||
2148 | ), | ||
2149 | TP_fast_assign( | ||
2150 | WIPHY_ASSIGN; | ||
2151 | __entry->freq = freq; | ||
2152 | __entry->sig_dbm = sig_dbm; | ||
2153 | ), | ||
2154 | TP_printk(WIPHY_PR_FMT ", freq: %d, sig_dbm: %d", | ||
2155 | WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm) | ||
2156 | ); | ||
2157 | |||
2158 | TRACE_EVENT(cfg80211_scan_done, | ||
2159 | TP_PROTO(struct cfg80211_scan_request *request, bool aborted), | ||
2160 | TP_ARGS(request, aborted), | ||
2161 | TP_STRUCT__entry( | ||
2162 | __field(u32, n_channels) | ||
2163 | __dynamic_array(u8, ie, request ? request->ie_len : 0) | ||
2164 | __array(u32, rates, IEEE80211_NUM_BANDS) | ||
2165 | __field(u32, wdev_id) | ||
2166 | MAC_ENTRY(wiphy_mac) | ||
2167 | __field(bool, no_cck) | ||
2168 | __field(bool, aborted) | ||
2169 | ), | ||
2170 | TP_fast_assign( | ||
2171 | if (request) { | ||
2172 | memcpy(__get_dynamic_array(ie), request->ie, | ||
2173 | request->ie_len); | ||
2174 | memcpy(__entry->rates, request->rates, | ||
2175 | IEEE80211_NUM_BANDS); | ||
2176 | __entry->wdev_id = request->wdev ? | ||
2177 | request->wdev->identifier : 0; | ||
2178 | if (request->wiphy) | ||
2179 | MAC_ASSIGN(wiphy_mac, | ||
2180 | request->wiphy->perm_addr); | ||
2181 | __entry->no_cck = request->no_cck; | ||
2182 | } | ||
2183 | __entry->aborted = aborted; | ||
2184 | ), | ||
2185 | TP_printk("aborted: %s", BOOL_TO_STR(__entry->aborted)) | ||
2186 | ); | ||
2187 | |||
2188 | DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results, | ||
2189 | TP_PROTO(struct wiphy *wiphy), | ||
2190 | TP_ARGS(wiphy) | ||
2191 | ); | ||
2192 | |||
2193 | DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_stopped, | ||
2194 | TP_PROTO(struct wiphy *wiphy), | ||
2195 | TP_ARGS(wiphy) | ||
2196 | ); | ||
2197 | |||
2198 | TRACE_EVENT(cfg80211_get_bss, | ||
2199 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, | ||
2200 | const u8 *bssid, const u8 *ssid, size_t ssid_len, | ||
2201 | u16 capa_mask, u16 capa_val), | ||
2202 | TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, capa_mask, capa_val), | ||
2203 | TP_STRUCT__entry( | ||
2204 | WIPHY_ENTRY | ||
2205 | CHAN_ENTRY | ||
2206 | MAC_ENTRY(bssid) | ||
2207 | __dynamic_array(u8, ssid, ssid_len) | ||
2208 | __field(u16, capa_mask) | ||
2209 | __field(u16, capa_val) | ||
2210 | ), | ||
2211 | TP_fast_assign( | ||
2212 | WIPHY_ASSIGN; | ||
2213 | CHAN_ASSIGN(channel); | ||
2214 | MAC_ASSIGN(bssid, bssid); | ||
2215 | memcpy(__get_dynamic_array(ssid), ssid, ssid_len); | ||
2216 | __entry->capa_mask = capa_mask; | ||
2217 | __entry->capa_val = capa_val; | ||
2218 | ), | ||
2219 | TP_printk(WIPHY_PR_FMT CHAN_PR_FMT MAC_PR_FMT ", buf: %#.2x, " | ||
2220 | "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, | ||
2221 | MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], | ||
2222 | __entry->capa_mask, __entry->capa_val) | ||
2223 | ); | ||
2224 | |||
2225 | TRACE_EVENT(cfg80211_inform_bss_frame, | ||
2226 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, | ||
2227 | struct ieee80211_mgmt *mgmt, size_t len, | ||
2228 | s32 signal), | ||
2229 | TP_ARGS(wiphy, channel, mgmt, len, signal), | ||
2230 | TP_STRUCT__entry( | ||
2231 | WIPHY_ENTRY | ||
2232 | CHAN_ENTRY | ||
2233 | __dynamic_array(u8, mgmt, len) | ||
2234 | __field(s32, signal) | ||
2235 | ), | ||
2236 | TP_fast_assign( | ||
2237 | WIPHY_ASSIGN; | ||
2238 | CHAN_ASSIGN(channel); | ||
2239 | if (mgmt) | ||
2240 | memcpy(__get_dynamic_array(mgmt), mgmt, len); | ||
2241 | __entry->signal = signal; | ||
2242 | ), | ||
2243 | TP_printk(WIPHY_PR_FMT CHAN_PR_FMT "signal: %d", | ||
2244 | WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) | ||
2245 | ); | ||
2246 | |||
2247 | DECLARE_EVENT_CLASS(cfg80211_bss_evt, | ||
2248 | TP_PROTO(struct cfg80211_bss *pub), | ||
2249 | TP_ARGS(pub), | ||
2250 | TP_STRUCT__entry( | ||
2251 | MAC_ENTRY(bssid) | ||
2252 | CHAN_ENTRY | ||
2253 | ), | ||
2254 | TP_fast_assign( | ||
2255 | MAC_ASSIGN(bssid, pub->bssid); | ||
2256 | CHAN_ASSIGN(pub->channel); | ||
2257 | ), | ||
2258 | TP_printk(MAC_PR_FMT CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG) | ||
2259 | ); | ||
2260 | |||
2261 | DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss, | ||
2262 | TP_PROTO(struct cfg80211_bss *pub), | ||
2263 | TP_ARGS(pub) | ||
2264 | ); | ||
2265 | |||
2266 | TRACE_EVENT(cfg80211_return_uint, | ||
2267 | TP_PROTO(unsigned int ret), | ||
2268 | TP_ARGS(ret), | ||
2269 | TP_STRUCT__entry( | ||
2270 | __field(unsigned int, ret) | ||
2271 | ), | ||
2272 | TP_fast_assign( | ||
2273 | __entry->ret = ret; | ||
2274 | ), | ||
2275 | TP_printk("ret: %d", __entry->ret) | ||
2276 | ); | ||
2277 | |||
2278 | TRACE_EVENT(cfg80211_return_u32, | ||
2279 | TP_PROTO(u32 ret), | ||
2280 | TP_ARGS(ret), | ||
2281 | TP_STRUCT__entry( | ||
2282 | __field(u32, ret) | ||
2283 | ), | ||
2284 | TP_fast_assign( | ||
2285 | __entry->ret = ret; | ||
2286 | ), | ||
2287 | TP_printk("ret: %u", __entry->ret) | ||
2288 | ); | ||
2289 | |||
2290 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ | ||
2291 | |||
2292 | #undef TRACE_INCLUDE_PATH | ||
2293 | #define TRACE_INCLUDE_PATH . | ||
2294 | #undef TRACE_INCLUDE_FILE | ||
2295 | #define TRACE_INCLUDE_FILE trace | ||
2296 | #include <trace/define_trace.h> | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c index 2762e8329986..5b6c1df72f31 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <net/ip.h> | 11 | #include <net/ip.h> |
12 | #include <net/dsfield.h> | 12 | #include <net/dsfield.h> |
13 | #include "core.h" | 13 | #include "core.h" |
14 | #include "rdev-ops.h" | ||
15 | |||
14 | 16 | ||
15 | struct ieee80211_rate * | 17 | struct ieee80211_rate * |
16 | ieee80211_get_response_rate(struct ieee80211_supported_band *sband, | 18 | ieee80211_get_response_rate(struct ieee80211_supported_band *sband, |
@@ -705,19 +707,18 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
705 | for (i = 0; i < 6; i++) { | 707 | for (i = 0; i < 6; i++) { |
706 | if (!wdev->connect_keys->params[i].cipher) | 708 | if (!wdev->connect_keys->params[i].cipher) |
707 | continue; | 709 | continue; |
708 | if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, | 710 | if (rdev_add_key(rdev, dev, i, false, NULL, |
709 | &wdev->connect_keys->params[i])) { | 711 | &wdev->connect_keys->params[i])) { |
710 | netdev_err(dev, "failed to set key %d\n", i); | 712 | netdev_err(dev, "failed to set key %d\n", i); |
711 | continue; | 713 | continue; |
712 | } | 714 | } |
713 | if (wdev->connect_keys->def == i) | 715 | if (wdev->connect_keys->def == i) |
714 | if (rdev->ops->set_default_key(wdev->wiphy, dev, | 716 | if (rdev_set_default_key(rdev, dev, i, true, true)) { |
715 | i, true, true)) { | ||
716 | netdev_err(dev, "failed to set defkey %d\n", i); | 717 | netdev_err(dev, "failed to set defkey %d\n", i); |
717 | continue; | 718 | continue; |
718 | } | 719 | } |
719 | if (wdev->connect_keys->defmgmt == i) | 720 | if (wdev->connect_keys->defmgmt == i) |
720 | if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i)) | 721 | if (rdev_set_default_mgmt_key(rdev, dev, i)) |
721 | netdev_err(dev, "failed to set mgtdef %d\n", i); | 722 | netdev_err(dev, "failed to set mgtdef %d\n", i); |
722 | } | 723 | } |
723 | 724 | ||
@@ -850,8 +851,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
850 | cfg80211_process_rdev_events(rdev); | 851 | cfg80211_process_rdev_events(rdev); |
851 | } | 852 | } |
852 | 853 | ||
853 | err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, | 854 | err = rdev_change_virtual_intf(rdev, dev, ntype, flags, params); |
854 | ntype, flags, params); | ||
855 | 855 | ||
856 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); | 856 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); |
857 | 857 | ||
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 494379eb464f..6488d2dbc1d7 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <net/cfg80211-wext.h> | 19 | #include <net/cfg80211-wext.h> |
20 | #include "wext-compat.h" | 20 | #include "wext-compat.h" |
21 | #include "core.h" | 21 | #include "core.h" |
22 | #include "rdev-ops.h" | ||
22 | 23 | ||
23 | int cfg80211_wext_giwname(struct net_device *dev, | 24 | int cfg80211_wext_giwname(struct net_device *dev, |
24 | struct iw_request_info *info, | 25 | struct iw_request_info *info, |
@@ -301,8 +302,7 @@ int cfg80211_wext_siwrts(struct net_device *dev, | |||
301 | else | 302 | else |
302 | wdev->wiphy->rts_threshold = rts->value; | 303 | wdev->wiphy->rts_threshold = rts->value; |
303 | 304 | ||
304 | err = rdev->ops->set_wiphy_params(wdev->wiphy, | 305 | err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD); |
305 | WIPHY_PARAM_RTS_THRESHOLD); | ||
306 | if (err) | 306 | if (err) |
307 | wdev->wiphy->rts_threshold = orts; | 307 | wdev->wiphy->rts_threshold = orts; |
308 | 308 | ||
@@ -342,8 +342,7 @@ int cfg80211_wext_siwfrag(struct net_device *dev, | |||
342 | wdev->wiphy->frag_threshold = frag->value & ~0x1; | 342 | wdev->wiphy->frag_threshold = frag->value & ~0x1; |
343 | } | 343 | } |
344 | 344 | ||
345 | err = rdev->ops->set_wiphy_params(wdev->wiphy, | 345 | err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD); |
346 | WIPHY_PARAM_FRAG_THRESHOLD); | ||
347 | if (err) | 346 | if (err) |
348 | wdev->wiphy->frag_threshold = ofrag; | 347 | wdev->wiphy->frag_threshold = ofrag; |
349 | 348 | ||
@@ -396,7 +395,7 @@ static int cfg80211_wext_siwretry(struct net_device *dev, | |||
396 | if (!changed) | 395 | if (!changed) |
397 | return 0; | 396 | return 0; |
398 | 397 | ||
399 | err = rdev->ops->set_wiphy_params(wdev->wiphy, changed); | 398 | err = rdev_set_wiphy_params(rdev, changed); |
400 | if (err) { | 399 | if (err) { |
401 | wdev->wiphy->retry_short = oshort; | 400 | wdev->wiphy->retry_short = oshort; |
402 | wdev->wiphy->retry_long = olong; | 401 | wdev->wiphy->retry_long = olong; |
@@ -490,8 +489,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
490 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | 489 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
491 | err = -ENOENT; | 490 | err = -ENOENT; |
492 | else | 491 | else |
493 | err = rdev->ops->del_key(&rdev->wiphy, dev, idx, | 492 | err = rdev_del_key(rdev, dev, idx, pairwise, |
494 | pairwise, addr); | 493 | addr); |
495 | } | 494 | } |
496 | wdev->wext.connect.privacy = false; | 495 | wdev->wext.connect.privacy = false; |
497 | /* | 496 | /* |
@@ -525,8 +524,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
525 | 524 | ||
526 | err = 0; | 525 | err = 0; |
527 | if (wdev->current_bss) | 526 | if (wdev->current_bss) |
528 | err = rdev->ops->add_key(&rdev->wiphy, dev, idx, | 527 | err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); |
529 | pairwise, addr, params); | ||
530 | if (err) | 528 | if (err) |
531 | return err; | 529 | return err; |
532 | 530 | ||
@@ -552,8 +550,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
552 | __cfg80211_leave_ibss(rdev, wdev->netdev, true); | 550 | __cfg80211_leave_ibss(rdev, wdev->netdev, true); |
553 | rejoin = true; | 551 | rejoin = true; |
554 | } | 552 | } |
555 | err = rdev->ops->set_default_key(&rdev->wiphy, dev, | 553 | err = rdev_set_default_key(rdev, dev, idx, true, true); |
556 | idx, true, true); | ||
557 | } | 554 | } |
558 | if (!err) { | 555 | if (!err) { |
559 | wdev->wext.default_key = idx; | 556 | wdev->wext.default_key = idx; |
@@ -566,8 +563,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
566 | if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && | 563 | if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && |
567 | (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { | 564 | (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { |
568 | if (wdev->current_bss) | 565 | if (wdev->current_bss) |
569 | err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, | 566 | err = rdev_set_default_mgmt_key(rdev, dev, idx); |
570 | dev, idx); | ||
571 | if (!err) | 567 | if (!err) |
572 | wdev->wext.default_mgmt_key = idx; | 568 | wdev->wext.default_mgmt_key = idx; |
573 | return err; | 569 | return err; |
@@ -631,8 +627,8 @@ static int cfg80211_wext_siwencode(struct net_device *dev, | |||
631 | err = 0; | 627 | err = 0; |
632 | wdev_lock(wdev); | 628 | wdev_lock(wdev); |
633 | if (wdev->current_bss) | 629 | if (wdev->current_bss) |
634 | err = rdev->ops->set_default_key(&rdev->wiphy, dev, | 630 | err = rdev_set_default_key(rdev, dev, idx, true, |
635 | idx, true, true); | 631 | true); |
636 | if (!err) | 632 | if (!err) |
637 | wdev->wext.default_key = idx; | 633 | wdev->wext.default_key = idx; |
638 | wdev_unlock(wdev); | 634 | wdev_unlock(wdev); |
@@ -839,7 +835,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
839 | if (!rdev->ops->get_channel) | 835 | if (!rdev->ops->get_channel) |
840 | return -EINVAL; | 836 | return -EINVAL; |
841 | 837 | ||
842 | chan = rdev->ops->get_channel(wdev->wiphy, wdev, &channel_type); | 838 | chan = rdev_get_channel(rdev, wdev, &channel_type); |
843 | if (!chan) | 839 | if (!chan) |
844 | return -EINVAL; | 840 | return -EINVAL; |
845 | freq->m = chan->center_freq; | 841 | freq->m = chan->center_freq; |
@@ -899,7 +895,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev, | |||
899 | return 0; | 895 | return 0; |
900 | } | 896 | } |
901 | 897 | ||
902 | return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); | 898 | return rdev_set_tx_power(rdev, type, DBM_TO_MBM(dbm)); |
903 | } | 899 | } |
904 | 900 | ||
905 | static int cfg80211_wext_giwtxpower(struct net_device *dev, | 901 | static int cfg80211_wext_giwtxpower(struct net_device *dev, |
@@ -918,7 +914,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev, | |||
918 | if (!rdev->ops->get_tx_power) | 914 | if (!rdev->ops->get_tx_power) |
919 | return -EOPNOTSUPP; | 915 | return -EOPNOTSUPP; |
920 | 916 | ||
921 | err = rdev->ops->get_tx_power(wdev->wiphy, &val); | 917 | err = rdev_get_tx_power(rdev, &val); |
922 | if (err) | 918 | if (err) |
923 | return err; | 919 | return err; |
924 | 920 | ||
@@ -1158,7 +1154,7 @@ static int cfg80211_wext_siwpower(struct net_device *dev, | |||
1158 | timeout = wrq->value / 1000; | 1154 | timeout = wrq->value / 1000; |
1159 | } | 1155 | } |
1160 | 1156 | ||
1161 | err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout); | 1157 | err = rdev_set_power_mgmt(rdev, dev, ps, timeout); |
1162 | if (err) | 1158 | if (err) |
1163 | return err; | 1159 | return err; |
1164 | 1160 | ||
@@ -1200,7 +1196,7 @@ static int cfg80211_wds_wext_siwap(struct net_device *dev, | |||
1200 | if (!rdev->ops->set_wds_peer) | 1196 | if (!rdev->ops->set_wds_peer) |
1201 | return -EOPNOTSUPP; | 1197 | return -EOPNOTSUPP; |
1202 | 1198 | ||
1203 | err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data); | 1199 | err = rdev_set_wds_peer(rdev, dev, (u8 *)&addr->sa_data); |
1204 | if (err) | 1200 | if (err) |
1205 | return err; | 1201 | return err; |
1206 | 1202 | ||
@@ -1272,7 +1268,7 @@ static int cfg80211_wext_siwrate(struct net_device *dev, | |||
1272 | if (!match) | 1268 | if (!match) |
1273 | return -EINVAL; | 1269 | return -EINVAL; |
1274 | 1270 | ||
1275 | return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); | 1271 | return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); |
1276 | } | 1272 | } |
1277 | 1273 | ||
1278 | static int cfg80211_wext_giwrate(struct net_device *dev, | 1274 | static int cfg80211_wext_giwrate(struct net_device *dev, |
@@ -1302,7 +1298,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, | |||
1302 | if (err) | 1298 | if (err) |
1303 | return err; | 1299 | return err; |
1304 | 1300 | ||
1305 | err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo); | 1301 | err = rdev_get_station(rdev, dev, addr, &sinfo); |
1306 | if (err) | 1302 | if (err) |
1307 | return err; | 1303 | return err; |
1308 | 1304 | ||
@@ -1339,7 +1335,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | |||
1339 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); | 1335 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); |
1340 | wdev_unlock(wdev); | 1336 | wdev_unlock(wdev); |
1341 | 1337 | ||
1342 | if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo)) | 1338 | if (rdev_get_station(rdev, dev, bssid, &sinfo)) |
1343 | return NULL; | 1339 | return NULL; |
1344 | 1340 | ||
1345 | memset(&wstats, 0, sizeof(wstats)); | 1341 | memset(&wstats, 0, sizeof(wstats)); |
@@ -1474,19 +1470,19 @@ static int cfg80211_wext_siwpmksa(struct net_device *dev, | |||
1474 | if (!rdev->ops->set_pmksa) | 1470 | if (!rdev->ops->set_pmksa) |
1475 | return -EOPNOTSUPP; | 1471 | return -EOPNOTSUPP; |
1476 | 1472 | ||
1477 | return rdev->ops->set_pmksa(&rdev->wiphy, dev, &cfg_pmksa); | 1473 | return rdev_set_pmksa(rdev, dev, &cfg_pmksa); |
1478 | 1474 | ||
1479 | case IW_PMKSA_REMOVE: | 1475 | case IW_PMKSA_REMOVE: |
1480 | if (!rdev->ops->del_pmksa) | 1476 | if (!rdev->ops->del_pmksa) |
1481 | return -EOPNOTSUPP; | 1477 | return -EOPNOTSUPP; |
1482 | 1478 | ||
1483 | return rdev->ops->del_pmksa(&rdev->wiphy, dev, &cfg_pmksa); | 1479 | return rdev_del_pmksa(rdev, dev, &cfg_pmksa); |
1484 | 1480 | ||
1485 | case IW_PMKSA_FLUSH: | 1481 | case IW_PMKSA_FLUSH: |
1486 | if (!rdev->ops->flush_pmksa) | 1482 | if (!rdev->ops->flush_pmksa) |
1487 | return -EOPNOTSUPP; | 1483 | return -EOPNOTSUPP; |
1488 | 1484 | ||
1489 | return rdev->ops->flush_pmksa(&rdev->wiphy, dev); | 1485 | return rdev_flush_pmksa(rdev, dev); |
1490 | 1486 | ||
1491 | default: | 1487 | default: |
1492 | return -EOPNOTSUPP; | 1488 | return -EOPNOTSUPP; |