diff options
213 files changed, 8748 insertions, 4480 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index f01f54f27750..0b7007a9c8a4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -152,8 +152,8 @@ F: drivers/scsi/53c700* | |||
152 | 152 | ||
153 | 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) | 153 | 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) |
154 | M: Alexander Aring <alex.aring@gmail.com> | 154 | M: Alexander Aring <alex.aring@gmail.com> |
155 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) | ||
156 | L: linux-bluetooth@vger.kernel.org | 155 | L: linux-bluetooth@vger.kernel.org |
156 | L: linux-wpan@vger.kernel.org | ||
157 | S: Maintained | 157 | S: Maintained |
158 | F: net/6lowpan/ | 158 | F: net/6lowpan/ |
159 | F: include/net/6lowpan.h | 159 | F: include/net/6lowpan.h |
@@ -4580,13 +4580,14 @@ F: drivers/idle/i7300_idle.c | |||
4580 | 4580 | ||
4581 | IEEE 802.15.4 SUBSYSTEM | 4581 | IEEE 802.15.4 SUBSYSTEM |
4582 | M: Alexander Aring <alex.aring@gmail.com> | 4582 | M: Alexander Aring <alex.aring@gmail.com> |
4583 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) | 4583 | L: linux-wpan@vger.kernel.org |
4584 | W: http://apps.sourceforge.net/trac/linux-zigbee | 4584 | W: https://github.com/linux-wpan |
4585 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git | 4585 | T: git git://github.com/linux-wpan/linux-wpan-next.git |
4586 | S: Maintained | 4586 | S: Maintained |
4587 | F: net/ieee802154/ | 4587 | F: net/ieee802154/ |
4588 | F: net/mac802154/ | 4588 | F: net/mac802154/ |
4589 | F: drivers/net/ieee802154/ | 4589 | F: drivers/net/ieee802154/ |
4590 | F: Documentation/networking/ieee802154.txt | ||
4590 | 4591 | ||
4591 | IGUANAWORKS USB IR TRANSCEIVER | 4592 | IGUANAWORKS USB IR TRANSCEIVER |
4592 | M: Sean Young <sean@mess.org> | 4593 | M: Sean Young <sean@mess.org> |
@@ -6356,7 +6357,7 @@ M: Lauro Ramos Venancio <lauro.venancio@openbossa.org> | |||
6356 | M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org> | 6357 | M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org> |
6357 | M: Samuel Ortiz <sameo@linux.intel.com> | 6358 | M: Samuel Ortiz <sameo@linux.intel.com> |
6358 | L: linux-wireless@vger.kernel.org | 6359 | L: linux-wireless@vger.kernel.org |
6359 | L: linux-nfc@lists.01.org (moderated for non-subscribers) | 6360 | L: linux-nfc@lists.01.org (subscribers-only) |
6360 | S: Supported | 6361 | S: Supported |
6361 | F: net/nfc/ | 6362 | F: net/nfc/ |
6362 | F: include/net/nfc/ | 6363 | F: include/net/nfc/ |
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 11115bbe115c..004d6aa671ce 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
@@ -21,6 +21,14 @@ | |||
21 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | 23 | ||
24 | enum bcma_boot_dev { | ||
25 | BCMA_BOOT_DEV_UNK = 0, | ||
26 | BCMA_BOOT_DEV_ROM, | ||
27 | BCMA_BOOT_DEV_PARALLEL, | ||
28 | BCMA_BOOT_DEV_SERIAL, | ||
29 | BCMA_BOOT_DEV_NAND, | ||
30 | }; | ||
31 | |||
24 | static const char * const part_probes[] = { "bcm47xxpart", NULL }; | 32 | static const char * const part_probes[] = { "bcm47xxpart", NULL }; |
25 | 33 | ||
26 | static struct physmap_flash_data bcma_pflash_data = { | 34 | static struct physmap_flash_data bcma_pflash_data = { |
@@ -229,11 +237,51 @@ u32 bcma_cpu_clock(struct bcma_drv_mips *mcore) | |||
229 | } | 237 | } |
230 | EXPORT_SYMBOL(bcma_cpu_clock); | 238 | EXPORT_SYMBOL(bcma_cpu_clock); |
231 | 239 | ||
240 | static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus) | ||
241 | { | ||
242 | struct bcma_drv_cc *cc = &bus->drv_cc; | ||
243 | u8 cc_rev = cc->core->id.rev; | ||
244 | |||
245 | if (cc_rev == 42) { | ||
246 | struct bcma_device *core; | ||
247 | |||
248 | core = bcma_find_core(bus, BCMA_CORE_NS_ROM); | ||
249 | if (core) { | ||
250 | switch (bcma_aread32(core, BCMA_IOST) & | ||
251 | BCMA_NS_ROM_IOST_BOOT_DEV_MASK) { | ||
252 | case BCMA_NS_ROM_IOST_BOOT_DEV_NOR: | ||
253 | return BCMA_BOOT_DEV_SERIAL; | ||
254 | case BCMA_NS_ROM_IOST_BOOT_DEV_NAND: | ||
255 | return BCMA_BOOT_DEV_NAND; | ||
256 | case BCMA_NS_ROM_IOST_BOOT_DEV_ROM: | ||
257 | default: | ||
258 | return BCMA_BOOT_DEV_ROM; | ||
259 | } | ||
260 | } | ||
261 | } else { | ||
262 | if (cc_rev == 38) { | ||
263 | if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT) | ||
264 | return BCMA_BOOT_DEV_NAND; | ||
265 | else if (cc->status & BIT(5)) | ||
266 | return BCMA_BOOT_DEV_ROM; | ||
267 | } | ||
268 | |||
269 | if ((cc->capabilities & BCMA_CC_CAP_FLASHT) == | ||
270 | BCMA_CC_FLASHT_PARA) | ||
271 | return BCMA_BOOT_DEV_PARALLEL; | ||
272 | else | ||
273 | return BCMA_BOOT_DEV_SERIAL; | ||
274 | } | ||
275 | |||
276 | return BCMA_BOOT_DEV_SERIAL; | ||
277 | } | ||
278 | |||
232 | static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | 279 | static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) |
233 | { | 280 | { |
234 | struct bcma_bus *bus = mcore->core->bus; | 281 | struct bcma_bus *bus = mcore->core->bus; |
235 | struct bcma_drv_cc *cc = &bus->drv_cc; | 282 | struct bcma_drv_cc *cc = &bus->drv_cc; |
236 | struct bcma_pflash *pflash = &cc->pflash; | 283 | struct bcma_pflash *pflash = &cc->pflash; |
284 | enum bcma_boot_dev boot_dev; | ||
237 | 285 | ||
238 | switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { | 286 | switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { |
239 | case BCMA_CC_FLASHT_STSER: | 287 | case BCMA_CC_FLASHT_STSER: |
@@ -269,6 +317,20 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | |||
269 | bcma_nflash_init(cc); | 317 | bcma_nflash_init(cc); |
270 | } | 318 | } |
271 | } | 319 | } |
320 | |||
321 | /* Determine flash type this SoC boots from */ | ||
322 | boot_dev = bcma_boot_dev(bus); | ||
323 | switch (boot_dev) { | ||
324 | case BCMA_BOOT_DEV_PARALLEL: | ||
325 | case BCMA_BOOT_DEV_SERIAL: | ||
326 | /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */ | ||
327 | break; | ||
328 | case BCMA_BOOT_DEV_NAND: | ||
329 | /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */ | ||
330 | break; | ||
331 | default: | ||
332 | break; | ||
333 | } | ||
272 | } | 334 | } |
273 | 335 | ||
274 | void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) | 336 | void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) |
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c index 3475e600011a..1edd7e064621 100644 --- a/drivers/bcma/host_soc.c +++ b/drivers/bcma/host_soc.c | |||
@@ -134,12 +134,16 @@ static void bcma_host_soc_block_write(struct bcma_device *core, | |||
134 | 134 | ||
135 | static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset) | 135 | static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset) |
136 | { | 136 | { |
137 | if (WARN_ONCE(!core->io_wrap, "Accessed core has no wrapper/agent\n")) | ||
138 | return ~0; | ||
137 | return readl(core->io_wrap + offset); | 139 | return readl(core->io_wrap + offset); |
138 | } | 140 | } |
139 | 141 | ||
140 | static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset, | 142 | static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset, |
141 | u32 value) | 143 | u32 value) |
142 | { | 144 | { |
145 | if (WARN_ONCE(!core->io_wrap, "Accessed core has no wrapper/agent\n")) | ||
146 | return; | ||
143 | writel(value, core->io_wrap + offset); | 147 | writel(value, core->io_wrap + offset); |
144 | } | 148 | } |
145 | 149 | ||
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index b4764c6bcf17..e9bd77249a4c 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c | |||
@@ -421,10 +421,13 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
421 | core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE); | 421 | core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE); |
422 | if (!core->io_addr) | 422 | if (!core->io_addr) |
423 | return -ENOMEM; | 423 | return -ENOMEM; |
424 | core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE); | 424 | if (core->wrap) { |
425 | if (!core->io_wrap) { | 425 | core->io_wrap = ioremap_nocache(core->wrap, |
426 | iounmap(core->io_addr); | 426 | BCMA_CORE_SIZE); |
427 | return -ENOMEM; | 427 | if (!core->io_wrap) { |
428 | iounmap(core->io_addr); | ||
429 | return -ENOMEM; | ||
430 | } | ||
428 | } | 431 | } |
429 | } | 432 | } |
430 | return 0; | 433 | return 0; |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a0d7355ef127..d85ced27ebd5 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = { | |||
88 | { USB_DEVICE(0x04CA, 0x300b) }, | 88 | { USB_DEVICE(0x04CA, 0x300b) }, |
89 | { USB_DEVICE(0x0930, 0x0219) }, | 89 | { USB_DEVICE(0x0930, 0x0219) }, |
90 | { USB_DEVICE(0x0930, 0x0220) }, | 90 | { USB_DEVICE(0x0930, 0x0220) }, |
91 | { USB_DEVICE(0x0930, 0x0227) }, | ||
91 | { USB_DEVICE(0x0b05, 0x17d0) }, | 92 | { USB_DEVICE(0x0b05, 0x17d0) }, |
92 | { USB_DEVICE(0x0CF3, 0x0036) }, | 93 | { USB_DEVICE(0x0CF3, 0x0036) }, |
93 | { USB_DEVICE(0x0CF3, 0x3004) }, | 94 | { USB_DEVICE(0x0CF3, 0x3004) }, |
@@ -138,6 +139,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { | |||
138 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 139 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
139 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 140 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
140 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, | 141 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, |
142 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, | ||
141 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, | 143 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
142 | { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 144 | { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
143 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | 145 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index dfa5043e68ba..35e63aaa6f80 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -61,7 +61,7 @@ MODULE_LICENSE("GPL"); | |||
61 | /* ======================== Local structures ======================== */ | 61 | /* ======================== Local structures ======================== */ |
62 | 62 | ||
63 | 63 | ||
64 | typedef struct bluecard_info_t { | 64 | struct bluecard_info { |
65 | struct pcmcia_device *p_dev; | 65 | struct pcmcia_device *p_dev; |
66 | 66 | ||
67 | struct hci_dev *hdev; | 67 | struct hci_dev *hdev; |
@@ -78,7 +78,7 @@ typedef struct bluecard_info_t { | |||
78 | 78 | ||
79 | unsigned char ctrl_reg; | 79 | unsigned char ctrl_reg; |
80 | unsigned long hw_state; /* Status of the hardware and LED control */ | 80 | unsigned long hw_state; /* Status of the hardware and LED control */ |
81 | } bluecard_info_t; | 81 | }; |
82 | 82 | ||
83 | 83 | ||
84 | static int bluecard_config(struct pcmcia_device *link); | 84 | static int bluecard_config(struct pcmcia_device *link); |
@@ -157,7 +157,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev); | |||
157 | 157 | ||
158 | static void bluecard_activity_led_timeout(u_long arg) | 158 | static void bluecard_activity_led_timeout(u_long arg) |
159 | { | 159 | { |
160 | bluecard_info_t *info = (bluecard_info_t *)arg; | 160 | struct bluecard_info *info = (struct bluecard_info *)arg; |
161 | unsigned int iobase = info->p_dev->resource[0]->start; | 161 | unsigned int iobase = info->p_dev->resource[0]->start; |
162 | 162 | ||
163 | if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) | 163 | if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) |
@@ -173,7 +173,7 @@ static void bluecard_activity_led_timeout(u_long arg) | |||
173 | } | 173 | } |
174 | 174 | ||
175 | 175 | ||
176 | static void bluecard_enable_activity_led(bluecard_info_t *info) | 176 | static void bluecard_enable_activity_led(struct bluecard_info *info) |
177 | { | 177 | { |
178 | unsigned int iobase = info->p_dev->resource[0]->start; | 178 | unsigned int iobase = info->p_dev->resource[0]->start; |
179 | 179 | ||
@@ -215,7 +215,7 @@ static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, i | |||
215 | } | 215 | } |
216 | 216 | ||
217 | 217 | ||
218 | static void bluecard_write_wakeup(bluecard_info_t *info) | 218 | static void bluecard_write_wakeup(struct bluecard_info *info) |
219 | { | 219 | { |
220 | if (!info) { | 220 | if (!info) { |
221 | BT_ERR("Unknown device"); | 221 | BT_ERR("Unknown device"); |
@@ -368,7 +368,8 @@ static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, in | |||
368 | } | 368 | } |
369 | 369 | ||
370 | 370 | ||
371 | static void bluecard_receive(bluecard_info_t *info, unsigned int offset) | 371 | static void bluecard_receive(struct bluecard_info *info, |
372 | unsigned int offset) | ||
372 | { | 373 | { |
373 | unsigned int iobase; | 374 | unsigned int iobase; |
374 | unsigned char buf[31]; | 375 | unsigned char buf[31]; |
@@ -497,7 +498,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) | |||
497 | 498 | ||
498 | static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) | 499 | static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) |
499 | { | 500 | { |
500 | bluecard_info_t *info = dev_inst; | 501 | struct bluecard_info *info = dev_inst; |
501 | unsigned int iobase; | 502 | unsigned int iobase; |
502 | unsigned char reg; | 503 | unsigned char reg; |
503 | 504 | ||
@@ -562,7 +563,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) | |||
562 | 563 | ||
563 | static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) | 564 | static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) |
564 | { | 565 | { |
565 | bluecard_info_t *info = hci_get_drvdata(hdev); | 566 | struct bluecard_info *info = hci_get_drvdata(hdev); |
566 | struct sk_buff *skb; | 567 | struct sk_buff *skb; |
567 | 568 | ||
568 | /* Ericsson baud rate command */ | 569 | /* Ericsson baud rate command */ |
@@ -611,7 +612,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) | |||
611 | 612 | ||
612 | static int bluecard_hci_flush(struct hci_dev *hdev) | 613 | static int bluecard_hci_flush(struct hci_dev *hdev) |
613 | { | 614 | { |
614 | bluecard_info_t *info = hci_get_drvdata(hdev); | 615 | struct bluecard_info *info = hci_get_drvdata(hdev); |
615 | 616 | ||
616 | /* Drop TX queue */ | 617 | /* Drop TX queue */ |
617 | skb_queue_purge(&(info->txq)); | 618 | skb_queue_purge(&(info->txq)); |
@@ -622,7 +623,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev) | |||
622 | 623 | ||
623 | static int bluecard_hci_open(struct hci_dev *hdev) | 624 | static int bluecard_hci_open(struct hci_dev *hdev) |
624 | { | 625 | { |
625 | bluecard_info_t *info = hci_get_drvdata(hdev); | 626 | struct bluecard_info *info = hci_get_drvdata(hdev); |
626 | 627 | ||
627 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) | 628 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) |
628 | bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); | 629 | bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); |
@@ -643,7 +644,7 @@ static int bluecard_hci_open(struct hci_dev *hdev) | |||
643 | 644 | ||
644 | static int bluecard_hci_close(struct hci_dev *hdev) | 645 | static int bluecard_hci_close(struct hci_dev *hdev) |
645 | { | 646 | { |
646 | bluecard_info_t *info = hci_get_drvdata(hdev); | 647 | struct bluecard_info *info = hci_get_drvdata(hdev); |
647 | 648 | ||
648 | if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) | 649 | if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) |
649 | return 0; | 650 | return 0; |
@@ -663,7 +664,7 @@ static int bluecard_hci_close(struct hci_dev *hdev) | |||
663 | 664 | ||
664 | static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | 665 | static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
665 | { | 666 | { |
666 | bluecard_info_t *info = hci_get_drvdata(hdev); | 667 | struct bluecard_info *info = hci_get_drvdata(hdev); |
667 | 668 | ||
668 | switch (bt_cb(skb)->pkt_type) { | 669 | switch (bt_cb(skb)->pkt_type) { |
669 | case HCI_COMMAND_PKT: | 670 | case HCI_COMMAND_PKT: |
@@ -691,7 +692,7 @@ static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
691 | /* ======================== Card services HCI interaction ======================== */ | 692 | /* ======================== Card services HCI interaction ======================== */ |
692 | 693 | ||
693 | 694 | ||
694 | static int bluecard_open(bluecard_info_t *info) | 695 | static int bluecard_open(struct bluecard_info *info) |
695 | { | 696 | { |
696 | unsigned int iobase = info->p_dev->resource[0]->start; | 697 | unsigned int iobase = info->p_dev->resource[0]->start; |
697 | struct hci_dev *hdev; | 698 | struct hci_dev *hdev; |
@@ -806,7 +807,7 @@ static int bluecard_open(bluecard_info_t *info) | |||
806 | } | 807 | } |
807 | 808 | ||
808 | 809 | ||
809 | static int bluecard_close(bluecard_info_t *info) | 810 | static int bluecard_close(struct bluecard_info *info) |
810 | { | 811 | { |
811 | unsigned int iobase = info->p_dev->resource[0]->start; | 812 | unsigned int iobase = info->p_dev->resource[0]->start; |
812 | struct hci_dev *hdev = info->hdev; | 813 | struct hci_dev *hdev = info->hdev; |
@@ -833,7 +834,7 @@ static int bluecard_close(bluecard_info_t *info) | |||
833 | 834 | ||
834 | static int bluecard_probe(struct pcmcia_device *link) | 835 | static int bluecard_probe(struct pcmcia_device *link) |
835 | { | 836 | { |
836 | bluecard_info_t *info; | 837 | struct bluecard_info *info; |
837 | 838 | ||
838 | /* Create new info device */ | 839 | /* Create new info device */ |
839 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); | 840 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); |
@@ -857,7 +858,7 @@ static void bluecard_detach(struct pcmcia_device *link) | |||
857 | 858 | ||
858 | static int bluecard_config(struct pcmcia_device *link) | 859 | static int bluecard_config(struct pcmcia_device *link) |
859 | { | 860 | { |
860 | bluecard_info_t *info = link->priv; | 861 | struct bluecard_info *info = link->priv; |
861 | int i, n; | 862 | int i, n; |
862 | 863 | ||
863 | link->config_index = 0x20; | 864 | link->config_index = 0x20; |
@@ -897,7 +898,7 @@ failed: | |||
897 | 898 | ||
898 | static void bluecard_release(struct pcmcia_device *link) | 899 | static void bluecard_release(struct pcmcia_device *link) |
899 | { | 900 | { |
900 | bluecard_info_t *info = link->priv; | 901 | struct bluecard_info *info = link->priv; |
901 | 902 | ||
902 | bluecard_close(info); | 903 | bluecard_close(info); |
903 | 904 | ||
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 1d82721cf9c6..4f7e8d400bc0 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -67,7 +67,7 @@ MODULE_FIRMWARE("BT3CPCC.bin"); | |||
67 | /* ======================== Local structures ======================== */ | 67 | /* ======================== Local structures ======================== */ |
68 | 68 | ||
69 | 69 | ||
70 | typedef struct bt3c_info_t { | 70 | struct bt3c_info { |
71 | struct pcmcia_device *p_dev; | 71 | struct pcmcia_device *p_dev; |
72 | 72 | ||
73 | struct hci_dev *hdev; | 73 | struct hci_dev *hdev; |
@@ -80,7 +80,7 @@ typedef struct bt3c_info_t { | |||
80 | unsigned long rx_state; | 80 | unsigned long rx_state; |
81 | unsigned long rx_count; | 81 | unsigned long rx_count; |
82 | struct sk_buff *rx_skb; | 82 | struct sk_buff *rx_skb; |
83 | } bt3c_info_t; | 83 | }; |
84 | 84 | ||
85 | 85 | ||
86 | static int bt3c_config(struct pcmcia_device *link); | 86 | static int bt3c_config(struct pcmcia_device *link); |
@@ -175,7 +175,7 @@ static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) | |||
175 | } | 175 | } |
176 | 176 | ||
177 | 177 | ||
178 | static void bt3c_write_wakeup(bt3c_info_t *info) | 178 | static void bt3c_write_wakeup(struct bt3c_info *info) |
179 | { | 179 | { |
180 | if (!info) { | 180 | if (!info) { |
181 | BT_ERR("Unknown device"); | 181 | BT_ERR("Unknown device"); |
@@ -214,7 +214,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | 216 | ||
217 | static void bt3c_receive(bt3c_info_t *info) | 217 | static void bt3c_receive(struct bt3c_info *info) |
218 | { | 218 | { |
219 | unsigned int iobase; | 219 | unsigned int iobase; |
220 | int size = 0, avail; | 220 | int size = 0, avail; |
@@ -336,7 +336,7 @@ static void bt3c_receive(bt3c_info_t *info) | |||
336 | 336 | ||
337 | static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) | 337 | static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) |
338 | { | 338 | { |
339 | bt3c_info_t *info = dev_inst; | 339 | struct bt3c_info *info = dev_inst; |
340 | unsigned int iobase; | 340 | unsigned int iobase; |
341 | int iir; | 341 | int iir; |
342 | irqreturn_t r = IRQ_NONE; | 342 | irqreturn_t r = IRQ_NONE; |
@@ -388,7 +388,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) | |||
388 | 388 | ||
389 | static int bt3c_hci_flush(struct hci_dev *hdev) | 389 | static int bt3c_hci_flush(struct hci_dev *hdev) |
390 | { | 390 | { |
391 | bt3c_info_t *info = hci_get_drvdata(hdev); | 391 | struct bt3c_info *info = hci_get_drvdata(hdev); |
392 | 392 | ||
393 | /* Drop TX queue */ | 393 | /* Drop TX queue */ |
394 | skb_queue_purge(&(info->txq)); | 394 | skb_queue_purge(&(info->txq)); |
@@ -418,7 +418,7 @@ static int bt3c_hci_close(struct hci_dev *hdev) | |||
418 | 418 | ||
419 | static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | 419 | static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
420 | { | 420 | { |
421 | bt3c_info_t *info = hci_get_drvdata(hdev); | 421 | struct bt3c_info *info = hci_get_drvdata(hdev); |
422 | unsigned long flags; | 422 | unsigned long flags; |
423 | 423 | ||
424 | switch (bt_cb(skb)->pkt_type) { | 424 | switch (bt_cb(skb)->pkt_type) { |
@@ -451,7 +451,8 @@ static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
451 | /* ======================== Card services HCI interaction ======================== */ | 451 | /* ======================== Card services HCI interaction ======================== */ |
452 | 452 | ||
453 | 453 | ||
454 | static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware, | 454 | static int bt3c_load_firmware(struct bt3c_info *info, |
455 | const unsigned char *firmware, | ||
455 | int count) | 456 | int count) |
456 | { | 457 | { |
457 | char *ptr = (char *) firmware; | 458 | char *ptr = (char *) firmware; |
@@ -536,7 +537,7 @@ error: | |||
536 | } | 537 | } |
537 | 538 | ||
538 | 539 | ||
539 | static int bt3c_open(bt3c_info_t *info) | 540 | static int bt3c_open(struct bt3c_info *info) |
540 | { | 541 | { |
541 | const struct firmware *firmware; | 542 | const struct firmware *firmware; |
542 | struct hci_dev *hdev; | 543 | struct hci_dev *hdev; |
@@ -603,7 +604,7 @@ error: | |||
603 | } | 604 | } |
604 | 605 | ||
605 | 606 | ||
606 | static int bt3c_close(bt3c_info_t *info) | 607 | static int bt3c_close(struct bt3c_info *info) |
607 | { | 608 | { |
608 | struct hci_dev *hdev = info->hdev; | 609 | struct hci_dev *hdev = info->hdev; |
609 | 610 | ||
@@ -620,7 +621,7 @@ static int bt3c_close(bt3c_info_t *info) | |||
620 | 621 | ||
621 | static int bt3c_probe(struct pcmcia_device *link) | 622 | static int bt3c_probe(struct pcmcia_device *link) |
622 | { | 623 | { |
623 | bt3c_info_t *info; | 624 | struct bt3c_info *info; |
624 | 625 | ||
625 | /* Create new info device */ | 626 | /* Create new info device */ |
626 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); | 627 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); |
@@ -683,7 +684,7 @@ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, | |||
683 | 684 | ||
684 | static int bt3c_config(struct pcmcia_device *link) | 685 | static int bt3c_config(struct pcmcia_device *link) |
685 | { | 686 | { |
686 | bt3c_info_t *info = link->priv; | 687 | struct bt3c_info *info = link->priv; |
687 | int i; | 688 | int i; |
688 | unsigned long try; | 689 | unsigned long try; |
689 | 690 | ||
@@ -724,7 +725,7 @@ failed: | |||
724 | 725 | ||
725 | static void bt3c_release(struct pcmcia_device *link) | 726 | static void bt3c_release(struct pcmcia_device *link) |
726 | { | 727 | { |
727 | bt3c_info_t *info = link->priv; | 728 | struct bt3c_info *info = link->priv; |
728 | 729 | ||
729 | bt3c_close(info); | 730 | bt3c_close(info); |
730 | 731 | ||
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index fb948f02eda5..abb4d2106db4 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); | |||
62 | /* ======================== Local structures ======================== */ | 62 | /* ======================== Local structures ======================== */ |
63 | 63 | ||
64 | 64 | ||
65 | typedef struct btuart_info_t { | 65 | struct btuart_info { |
66 | struct pcmcia_device *p_dev; | 66 | struct pcmcia_device *p_dev; |
67 | 67 | ||
68 | struct hci_dev *hdev; | 68 | struct hci_dev *hdev; |
@@ -75,7 +75,7 @@ typedef struct btuart_info_t { | |||
75 | unsigned long rx_state; | 75 | unsigned long rx_state; |
76 | unsigned long rx_count; | 76 | unsigned long rx_count; |
77 | struct sk_buff *rx_skb; | 77 | struct sk_buff *rx_skb; |
78 | } btuart_info_t; | 78 | }; |
79 | 79 | ||
80 | 80 | ||
81 | static int btuart_config(struct pcmcia_device *link); | 81 | static int btuart_config(struct pcmcia_device *link); |
@@ -127,7 +127,7 @@ static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | 129 | ||
130 | static void btuart_write_wakeup(btuart_info_t *info) | 130 | static void btuart_write_wakeup(struct btuart_info *info) |
131 | { | 131 | { |
132 | if (!info) { | 132 | if (!info) { |
133 | BT_ERR("Unknown device"); | 133 | BT_ERR("Unknown device"); |
@@ -172,7 +172,7 @@ static void btuart_write_wakeup(btuart_info_t *info) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | 174 | ||
175 | static void btuart_receive(btuart_info_t *info) | 175 | static void btuart_receive(struct btuart_info *info) |
176 | { | 176 | { |
177 | unsigned int iobase; | 177 | unsigned int iobase; |
178 | int boguscount = 0; | 178 | int boguscount = 0; |
@@ -286,7 +286,7 @@ static void btuart_receive(btuart_info_t *info) | |||
286 | 286 | ||
287 | static irqreturn_t btuart_interrupt(int irq, void *dev_inst) | 287 | static irqreturn_t btuart_interrupt(int irq, void *dev_inst) |
288 | { | 288 | { |
289 | btuart_info_t *info = dev_inst; | 289 | struct btuart_info *info = dev_inst; |
290 | unsigned int iobase; | 290 | unsigned int iobase; |
291 | int boguscount = 0; | 291 | int boguscount = 0; |
292 | int iir, lsr; | 292 | int iir, lsr; |
@@ -340,7 +340,8 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | 342 | ||
343 | static void btuart_change_speed(btuart_info_t *info, unsigned int speed) | 343 | static void btuart_change_speed(struct btuart_info *info, |
344 | unsigned int speed) | ||
344 | { | 345 | { |
345 | unsigned long flags; | 346 | unsigned long flags; |
346 | unsigned int iobase; | 347 | unsigned int iobase; |
@@ -397,7 +398,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed) | |||
397 | 398 | ||
398 | static int btuart_hci_flush(struct hci_dev *hdev) | 399 | static int btuart_hci_flush(struct hci_dev *hdev) |
399 | { | 400 | { |
400 | btuart_info_t *info = hci_get_drvdata(hdev); | 401 | struct btuart_info *info = hci_get_drvdata(hdev); |
401 | 402 | ||
402 | /* Drop TX queue */ | 403 | /* Drop TX queue */ |
403 | skb_queue_purge(&(info->txq)); | 404 | skb_queue_purge(&(info->txq)); |
@@ -427,7 +428,7 @@ static int btuart_hci_close(struct hci_dev *hdev) | |||
427 | 428 | ||
428 | static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | 429 | static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
429 | { | 430 | { |
430 | btuart_info_t *info = hci_get_drvdata(hdev); | 431 | struct btuart_info *info = hci_get_drvdata(hdev); |
431 | 432 | ||
432 | switch (bt_cb(skb)->pkt_type) { | 433 | switch (bt_cb(skb)->pkt_type) { |
433 | case HCI_COMMAND_PKT: | 434 | case HCI_COMMAND_PKT: |
@@ -455,7 +456,7 @@ static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
455 | /* ======================== Card services HCI interaction ======================== */ | 456 | /* ======================== Card services HCI interaction ======================== */ |
456 | 457 | ||
457 | 458 | ||
458 | static int btuart_open(btuart_info_t *info) | 459 | static int btuart_open(struct btuart_info *info) |
459 | { | 460 | { |
460 | unsigned long flags; | 461 | unsigned long flags; |
461 | unsigned int iobase = info->p_dev->resource[0]->start; | 462 | unsigned int iobase = info->p_dev->resource[0]->start; |
@@ -521,7 +522,7 @@ static int btuart_open(btuart_info_t *info) | |||
521 | } | 522 | } |
522 | 523 | ||
523 | 524 | ||
524 | static int btuart_close(btuart_info_t *info) | 525 | static int btuart_close(struct btuart_info *info) |
525 | { | 526 | { |
526 | unsigned long flags; | 527 | unsigned long flags; |
527 | unsigned int iobase = info->p_dev->resource[0]->start; | 528 | unsigned int iobase = info->p_dev->resource[0]->start; |
@@ -550,7 +551,7 @@ static int btuart_close(btuart_info_t *info) | |||
550 | 551 | ||
551 | static int btuart_probe(struct pcmcia_device *link) | 552 | static int btuart_probe(struct pcmcia_device *link) |
552 | { | 553 | { |
553 | btuart_info_t *info; | 554 | struct btuart_info *info; |
554 | 555 | ||
555 | /* Create new info device */ | 556 | /* Create new info device */ |
556 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); | 557 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); |
@@ -613,7 +614,7 @@ static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, | |||
613 | 614 | ||
614 | static int btuart_config(struct pcmcia_device *link) | 615 | static int btuart_config(struct pcmcia_device *link) |
615 | { | 616 | { |
616 | btuart_info_t *info = link->priv; | 617 | struct btuart_info *info = link->priv; |
617 | int i; | 618 | int i; |
618 | int try; | 619 | int try; |
619 | 620 | ||
@@ -654,7 +655,7 @@ failed: | |||
654 | 655 | ||
655 | static void btuart_release(struct pcmcia_device *link) | 656 | static void btuart_release(struct pcmcia_device *link) |
656 | { | 657 | { |
657 | btuart_info_t *info = link->priv; | 658 | struct btuart_info *info = link->priv; |
658 | 659 | ||
659 | btuart_close(info); | 660 | btuart_close(info); |
660 | 661 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 292c38e8aa17..0527b29c3954 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -165,6 +165,7 @@ static const struct usb_device_id blacklist_table[] = { | |||
165 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 165 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
166 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 166 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
167 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, | 167 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, |
168 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, | ||
168 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, | 169 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
169 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 170 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
170 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | 171 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 2bd8fad17206..78e10f0c65b2 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); | |||
62 | /* ======================== Local structures ======================== */ | 62 | /* ======================== Local structures ======================== */ |
63 | 63 | ||
64 | 64 | ||
65 | typedef struct dtl1_info_t { | 65 | struct dtl1_info { |
66 | struct pcmcia_device *p_dev; | 66 | struct pcmcia_device *p_dev; |
67 | 67 | ||
68 | struct hci_dev *hdev; | 68 | struct hci_dev *hdev; |
@@ -78,7 +78,7 @@ typedef struct dtl1_info_t { | |||
78 | unsigned long rx_state; | 78 | unsigned long rx_state; |
79 | unsigned long rx_count; | 79 | unsigned long rx_count; |
80 | struct sk_buff *rx_skb; | 80 | struct sk_buff *rx_skb; |
81 | } dtl1_info_t; | 81 | }; |
82 | 82 | ||
83 | 83 | ||
84 | static int dtl1_config(struct pcmcia_device *link); | 84 | static int dtl1_config(struct pcmcia_device *link); |
@@ -94,11 +94,11 @@ static int dtl1_config(struct pcmcia_device *link); | |||
94 | #define RECV_WAIT_DATA 1 | 94 | #define RECV_WAIT_DATA 1 |
95 | 95 | ||
96 | 96 | ||
97 | typedef struct { | 97 | struct nsh { |
98 | u8 type; | 98 | u8 type; |
99 | u8 zero; | 99 | u8 zero; |
100 | u16 len; | 100 | u16 len; |
101 | } __packed nsh_t; /* Nokia Specific Header */ | 101 | } __packed; /* Nokia Specific Header */ |
102 | 102 | ||
103 | #define NSHL 4 /* Nokia Specific Header Length */ | 103 | #define NSHL 4 /* Nokia Specific Header Length */ |
104 | 104 | ||
@@ -126,7 +126,7 @@ static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | 128 | ||
129 | static void dtl1_write_wakeup(dtl1_info_t *info) | 129 | static void dtl1_write_wakeup(struct dtl1_info *info) |
130 | { | 130 | { |
131 | if (!info) { | 131 | if (!info) { |
132 | BT_ERR("Unknown device"); | 132 | BT_ERR("Unknown device"); |
@@ -176,7 +176,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info) | |||
176 | } | 176 | } |
177 | 177 | ||
178 | 178 | ||
179 | static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb) | 179 | static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb) |
180 | { | 180 | { |
181 | u8 flowmask = *(u8 *)skb->data; | 181 | u8 flowmask = *(u8 *)skb->data; |
182 | int i; | 182 | int i; |
@@ -199,10 +199,10 @@ static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | 201 | ||
202 | static void dtl1_receive(dtl1_info_t *info) | 202 | static void dtl1_receive(struct dtl1_info *info) |
203 | { | 203 | { |
204 | unsigned int iobase; | 204 | unsigned int iobase; |
205 | nsh_t *nsh; | 205 | struct nsh *nsh; |
206 | int boguscount = 0; | 206 | int boguscount = 0; |
207 | 207 | ||
208 | if (!info) { | 208 | if (!info) { |
@@ -227,7 +227,7 @@ static void dtl1_receive(dtl1_info_t *info) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); | 229 | *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); |
230 | nsh = (nsh_t *)info->rx_skb->data; | 230 | nsh = (struct nsh *)info->rx_skb->data; |
231 | 231 | ||
232 | info->rx_count--; | 232 | info->rx_count--; |
233 | 233 | ||
@@ -287,7 +287,7 @@ static void dtl1_receive(dtl1_info_t *info) | |||
287 | 287 | ||
288 | static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) | 288 | static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) |
289 | { | 289 | { |
290 | dtl1_info_t *info = dev_inst; | 290 | struct dtl1_info *info = dev_inst; |
291 | unsigned int iobase; | 291 | unsigned int iobase; |
292 | unsigned char msr; | 292 | unsigned char msr; |
293 | int boguscount = 0; | 293 | int boguscount = 0; |
@@ -365,7 +365,7 @@ static int dtl1_hci_open(struct hci_dev *hdev) | |||
365 | 365 | ||
366 | static int dtl1_hci_flush(struct hci_dev *hdev) | 366 | static int dtl1_hci_flush(struct hci_dev *hdev) |
367 | { | 367 | { |
368 | dtl1_info_t *info = hci_get_drvdata(hdev); | 368 | struct dtl1_info *info = hci_get_drvdata(hdev); |
369 | 369 | ||
370 | /* Drop TX queue */ | 370 | /* Drop TX queue */ |
371 | skb_queue_purge(&(info->txq)); | 371 | skb_queue_purge(&(info->txq)); |
@@ -387,9 +387,9 @@ static int dtl1_hci_close(struct hci_dev *hdev) | |||
387 | 387 | ||
388 | static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | 388 | static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
389 | { | 389 | { |
390 | dtl1_info_t *info = hci_get_drvdata(hdev); | 390 | struct dtl1_info *info = hci_get_drvdata(hdev); |
391 | struct sk_buff *s; | 391 | struct sk_buff *s; |
392 | nsh_t nsh; | 392 | struct nsh nsh; |
393 | 393 | ||
394 | switch (bt_cb(skb)->pkt_type) { | 394 | switch (bt_cb(skb)->pkt_type) { |
395 | case HCI_COMMAND_PKT: | 395 | case HCI_COMMAND_PKT: |
@@ -436,7 +436,7 @@ static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
436 | /* ======================== Card services HCI interaction ======================== */ | 436 | /* ======================== Card services HCI interaction ======================== */ |
437 | 437 | ||
438 | 438 | ||
439 | static int dtl1_open(dtl1_info_t *info) | 439 | static int dtl1_open(struct dtl1_info *info) |
440 | { | 440 | { |
441 | unsigned long flags; | 441 | unsigned long flags; |
442 | unsigned int iobase = info->p_dev->resource[0]->start; | 442 | unsigned int iobase = info->p_dev->resource[0]->start; |
@@ -505,7 +505,7 @@ static int dtl1_open(dtl1_info_t *info) | |||
505 | } | 505 | } |
506 | 506 | ||
507 | 507 | ||
508 | static int dtl1_close(dtl1_info_t *info) | 508 | static int dtl1_close(struct dtl1_info *info) |
509 | { | 509 | { |
510 | unsigned long flags; | 510 | unsigned long flags; |
511 | unsigned int iobase = info->p_dev->resource[0]->start; | 511 | unsigned int iobase = info->p_dev->resource[0]->start; |
@@ -534,7 +534,7 @@ static int dtl1_close(dtl1_info_t *info) | |||
534 | 534 | ||
535 | static int dtl1_probe(struct pcmcia_device *link) | 535 | static int dtl1_probe(struct pcmcia_device *link) |
536 | { | 536 | { |
537 | dtl1_info_t *info; | 537 | struct dtl1_info *info; |
538 | 538 | ||
539 | /* Create new info device */ | 539 | /* Create new info device */ |
540 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); | 540 | info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); |
@@ -552,7 +552,7 @@ static int dtl1_probe(struct pcmcia_device *link) | |||
552 | 552 | ||
553 | static void dtl1_detach(struct pcmcia_device *link) | 553 | static void dtl1_detach(struct pcmcia_device *link) |
554 | { | 554 | { |
555 | dtl1_info_t *info = link->priv; | 555 | struct dtl1_info *info = link->priv; |
556 | 556 | ||
557 | dtl1_close(info); | 557 | dtl1_close(info); |
558 | pcmcia_disable_device(link); | 558 | pcmcia_disable_device(link); |
@@ -571,7 +571,7 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) | |||
571 | 571 | ||
572 | static int dtl1_config(struct pcmcia_device *link) | 572 | static int dtl1_config(struct pcmcia_device *link) |
573 | { | 573 | { |
574 | dtl1_info_t *info = link->priv; | 574 | struct dtl1_info *info = link->priv; |
575 | int ret; | 575 | int ret; |
576 | 576 | ||
577 | /* Look for a generic full-sized window */ | 577 | /* Look for a generic full-sized window */ |
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index caacb422995d..a22838669b4e 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c | |||
@@ -237,7 +237,7 @@ static void h5_pkt_cull(struct h5 *h5) | |||
237 | break; | 237 | break; |
238 | 238 | ||
239 | to_remove--; | 239 | to_remove--; |
240 | seq = (seq - 1) % 8; | 240 | seq = (seq - 1) & 0x07; |
241 | } | 241 | } |
242 | 242 | ||
243 | if (seq != h5->rx_ack) | 243 | if (seq != h5->rx_ack) |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index fd9e5305e77f..c1a4ade32772 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -261,6 +261,7 @@ enum ATH_DEBUG { | |||
261 | ATH_DBG_MCI = 0x00008000, | 261 | ATH_DBG_MCI = 0x00008000, |
262 | ATH_DBG_DFS = 0x00010000, | 262 | ATH_DBG_DFS = 0x00010000, |
263 | ATH_DBG_WOW = 0x00020000, | 263 | ATH_DBG_WOW = 0x00020000, |
264 | ATH_DBG_CHAN_CTX = 0x00040000, | ||
264 | ATH_DBG_ANY = 0xffffffff | 265 | ATH_DBG_ANY = 0xffffffff |
265 | }; | 266 | }; |
266 | 267 | ||
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index a6f5285235af..1053bb5f2cdc 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig | |||
@@ -25,6 +25,7 @@ config ATH10K_DEBUG | |||
25 | config ATH10K_DEBUGFS | 25 | config ATH10K_DEBUGFS |
26 | bool "Atheros ath10k debugfs support" | 26 | bool "Atheros ath10k debugfs support" |
27 | depends on ATH10K | 27 | depends on ATH10K |
28 | select RELAY | ||
28 | ---help--- | 29 | ---help--- |
29 | Enabled debugfs support | 30 | Enabled debugfs support |
30 | 31 | ||
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index a4179f49ee1f..2cfb63ca9327 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile | |||
@@ -10,6 +10,7 @@ ath10k_core-y += mac.o \ | |||
10 | wmi.o \ | 10 | wmi.o \ |
11 | bmi.o | 11 | bmi.o |
12 | 12 | ||
13 | ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o | ||
13 | ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o | 14 | ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o |
14 | 15 | ||
15 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o | 16 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o |
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c index 17d221abd58c..3d29b0875b3e 100644 --- a/drivers/net/wireless/ath/ath10k/bmi.c +++ b/drivers/net/wireless/ath/ath10k/bmi.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | void ath10k_bmi_start(struct ath10k *ar) | 23 | void ath10k_bmi_start(struct ath10k *ar) |
24 | { | 24 | { |
25 | ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n"); | 25 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n"); |
26 | 26 | ||
27 | ar->bmi.done_sent = false; | 27 | ar->bmi.done_sent = false; |
28 | } | 28 | } |
@@ -33,10 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar) | |||
33 | u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); | 33 | u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); |
34 | int ret; | 34 | int ret; |
35 | 35 | ||
36 | ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n"); | 36 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi done\n"); |
37 | 37 | ||
38 | if (ar->bmi.done_sent) { | 38 | if (ar->bmi.done_sent) { |
39 | ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n"); | 39 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi skipped\n"); |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
@@ -45,7 +45,7 @@ int ath10k_bmi_done(struct ath10k *ar) | |||
45 | 45 | ||
46 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); | 46 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); |
47 | if (ret) { | 47 | if (ret) { |
48 | ath10k_warn("unable to write to the device: %d\n", ret); | 48 | ath10k_warn(ar, "unable to write to the device: %d\n", ret); |
49 | return ret; | 49 | return ret; |
50 | } | 50 | } |
51 | 51 | ||
@@ -61,10 +61,10 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, | |||
61 | u32 resplen = sizeof(resp.get_target_info); | 61 | u32 resplen = sizeof(resp.get_target_info); |
62 | int ret; | 62 | int ret; |
63 | 63 | ||
64 | ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n"); | 64 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info\n"); |
65 | 65 | ||
66 | if (ar->bmi.done_sent) { | 66 | if (ar->bmi.done_sent) { |
67 | ath10k_warn("BMI Get Target Info Command disallowed\n"); | 67 | ath10k_warn(ar, "BMI Get Target Info Command disallowed\n"); |
68 | return -EBUSY; | 68 | return -EBUSY; |
69 | } | 69 | } |
70 | 70 | ||
@@ -72,12 +72,12 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, | |||
72 | 72 | ||
73 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); | 73 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); |
74 | if (ret) { | 74 | if (ret) { |
75 | ath10k_warn("unable to get target info from device\n"); | 75 | ath10k_warn(ar, "unable to get target info from device\n"); |
76 | return ret; | 76 | return ret; |
77 | } | 77 | } |
78 | 78 | ||
79 | if (resplen < sizeof(resp.get_target_info)) { | 79 | if (resplen < sizeof(resp.get_target_info)) { |
80 | ath10k_warn("invalid get_target_info response length (%d)\n", | 80 | ath10k_warn(ar, "invalid get_target_info response length (%d)\n", |
81 | resplen); | 81 | resplen); |
82 | return -EIO; | 82 | return -EIO; |
83 | } | 83 | } |
@@ -97,11 +97,11 @@ int ath10k_bmi_read_memory(struct ath10k *ar, | |||
97 | u32 rxlen; | 97 | u32 rxlen; |
98 | int ret; | 98 | int ret; |
99 | 99 | ||
100 | ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", | 100 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", |
101 | address, length); | 101 | address, length); |
102 | 102 | ||
103 | if (ar->bmi.done_sent) { | 103 | if (ar->bmi.done_sent) { |
104 | ath10k_warn("command disallowed\n"); | 104 | ath10k_warn(ar, "command disallowed\n"); |
105 | return -EBUSY; | 105 | return -EBUSY; |
106 | } | 106 | } |
107 | 107 | ||
@@ -115,7 +115,7 @@ int ath10k_bmi_read_memory(struct ath10k *ar, | |||
115 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, | 115 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, |
116 | &resp, &rxlen); | 116 | &resp, &rxlen); |
117 | if (ret) { | 117 | if (ret) { |
118 | ath10k_warn("unable to read from the device (%d)\n", | 118 | ath10k_warn(ar, "unable to read from the device (%d)\n", |
119 | ret); | 119 | ret); |
120 | return ret; | 120 | return ret; |
121 | } | 121 | } |
@@ -137,11 +137,11 @@ int ath10k_bmi_write_memory(struct ath10k *ar, | |||
137 | u32 txlen; | 137 | u32 txlen; |
138 | int ret; | 138 | int ret; |
139 | 139 | ||
140 | ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", | 140 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", |
141 | address, length); | 141 | address, length); |
142 | 142 | ||
143 | if (ar->bmi.done_sent) { | 143 | if (ar->bmi.done_sent) { |
144 | ath10k_warn("command disallowed\n"); | 144 | ath10k_warn(ar, "command disallowed\n"); |
145 | return -EBUSY; | 145 | return -EBUSY; |
146 | } | 146 | } |
147 | 147 | ||
@@ -159,7 +159,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, | |||
159 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, | 159 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, |
160 | NULL, NULL); | 160 | NULL, NULL); |
161 | if (ret) { | 161 | if (ret) { |
162 | ath10k_warn("unable to write to the device (%d)\n", | 162 | ath10k_warn(ar, "unable to write to the device (%d)\n", |
163 | ret); | 163 | ret); |
164 | return ret; | 164 | return ret; |
165 | } | 165 | } |
@@ -183,11 +183,11 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result) | |||
183 | u32 resplen = sizeof(resp.execute); | 183 | u32 resplen = sizeof(resp.execute); |
184 | int ret; | 184 | int ret; |
185 | 185 | ||
186 | ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", | 186 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", |
187 | address, param); | 187 | address, param); |
188 | 188 | ||
189 | if (ar->bmi.done_sent) { | 189 | if (ar->bmi.done_sent) { |
190 | ath10k_warn("command disallowed\n"); | 190 | ath10k_warn(ar, "command disallowed\n"); |
191 | return -EBUSY; | 191 | return -EBUSY; |
192 | } | 192 | } |
193 | 193 | ||
@@ -197,19 +197,19 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result) | |||
197 | 197 | ||
198 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); | 198 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); |
199 | if (ret) { | 199 | if (ret) { |
200 | ath10k_warn("unable to read from the device\n"); | 200 | ath10k_warn(ar, "unable to read from the device\n"); |
201 | return ret; | 201 | return ret; |
202 | } | 202 | } |
203 | 203 | ||
204 | if (resplen < sizeof(resp.execute)) { | 204 | if (resplen < sizeof(resp.execute)) { |
205 | ath10k_warn("invalid execute response length (%d)\n", | 205 | ath10k_warn(ar, "invalid execute response length (%d)\n", |
206 | resplen); | 206 | resplen); |
207 | return -EIO; | 207 | return -EIO; |
208 | } | 208 | } |
209 | 209 | ||
210 | *result = __le32_to_cpu(resp.execute.result); | 210 | *result = __le32_to_cpu(resp.execute.result); |
211 | 211 | ||
212 | ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); | 212 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); |
213 | 213 | ||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
@@ -221,11 +221,11 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) | |||
221 | u32 txlen; | 221 | u32 txlen; |
222 | int ret; | 222 | int ret; |
223 | 223 | ||
224 | ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", | 224 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", |
225 | buffer, length); | 225 | buffer, length); |
226 | 226 | ||
227 | if (ar->bmi.done_sent) { | 227 | if (ar->bmi.done_sent) { |
228 | ath10k_warn("command disallowed\n"); | 228 | ath10k_warn(ar, "command disallowed\n"); |
229 | return -EBUSY; | 229 | return -EBUSY; |
230 | } | 230 | } |
231 | 231 | ||
@@ -241,7 +241,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) | |||
241 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, | 241 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, |
242 | NULL, NULL); | 242 | NULL, NULL); |
243 | if (ret) { | 243 | if (ret) { |
244 | ath10k_warn("unable to write to the device\n"); | 244 | ath10k_warn(ar, "unable to write to the device\n"); |
245 | return ret; | 245 | return ret; |
246 | } | 246 | } |
247 | 247 | ||
@@ -258,11 +258,11 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) | |||
258 | u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); | 258 | u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); |
259 | int ret; | 259 | int ret; |
260 | 260 | ||
261 | ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", | 261 | ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", |
262 | address); | 262 | address); |
263 | 263 | ||
264 | if (ar->bmi.done_sent) { | 264 | if (ar->bmi.done_sent) { |
265 | ath10k_warn("command disallowed\n"); | 265 | ath10k_warn(ar, "command disallowed\n"); |
266 | return -EBUSY; | 266 | return -EBUSY; |
267 | } | 267 | } |
268 | 268 | ||
@@ -271,7 +271,7 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) | |||
271 | 271 | ||
272 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); | 272 | ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); |
273 | if (ret) { | 273 | if (ret) { |
274 | ath10k_warn("unable to Start LZ Stream to the device\n"); | 274 | ath10k_warn(ar, "unable to Start LZ Stream to the device\n"); |
275 | return ret; | 275 | return ret; |
276 | } | 276 | } |
277 | 277 | ||
@@ -286,7 +286,7 @@ int ath10k_bmi_fast_download(struct ath10k *ar, | |||
286 | u32 trailer_len = length - head_len; | 286 | u32 trailer_len = length - head_len; |
287 | int ret; | 287 | int ret; |
288 | 288 | ||
289 | ath10k_dbg(ATH10K_DBG_BMI, | 289 | ath10k_dbg(ar, ATH10K_DBG_BMI, |
290 | "bmi fast download address 0x%x buffer 0x%p length %d\n", | 290 | "bmi fast download address 0x%x buffer 0x%p length %d\n", |
291 | address, buffer, length); | 291 | address, buffer, length); |
292 | 292 | ||
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 4333107ecf37..71eef233bd01 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c | |||
@@ -284,13 +284,9 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, | |||
284 | int ret = 0; | 284 | int ret = 0; |
285 | 285 | ||
286 | if (nbytes > ce_state->src_sz_max) | 286 | if (nbytes > ce_state->src_sz_max) |
287 | ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n", | 287 | ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n", |
288 | __func__, nbytes, ce_state->src_sz_max); | 288 | __func__, nbytes, ce_state->src_sz_max); |
289 | 289 | ||
290 | ret = ath10k_pci_wake(ar); | ||
291 | if (ret) | ||
292 | return ret; | ||
293 | |||
294 | if (unlikely(CE_RING_DELTA(nentries_mask, | 290 | if (unlikely(CE_RING_DELTA(nentries_mask, |
295 | write_index, sw_index - 1) <= 0)) { | 291 | write_index, sw_index - 1) <= 0)) { |
296 | ret = -ENOSR; | 292 | ret = -ENOSR; |
@@ -325,7 +321,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, | |||
325 | 321 | ||
326 | src_ring->write_index = write_index; | 322 | src_ring->write_index = write_index; |
327 | exit: | 323 | exit: |
328 | ath10k_pci_sleep(ar); | ||
329 | return ret; | 324 | return ret; |
330 | } | 325 | } |
331 | 326 | ||
@@ -390,49 +385,57 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) | |||
390 | return delta; | 385 | return delta; |
391 | } | 386 | } |
392 | 387 | ||
393 | int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, | 388 | |
394 | void *per_recv_context, | 389 | int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) |
395 | u32 buffer) | ||
396 | { | 390 | { |
397 | struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; | 391 | struct ath10k *ar = pipe->ar; |
398 | u32 ctrl_addr = ce_state->ctrl_addr; | ||
399 | struct ath10k *ar = ce_state->ar; | ||
400 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 392 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
393 | struct ath10k_ce_ring *dest_ring = pipe->dest_ring; | ||
401 | unsigned int nentries_mask = dest_ring->nentries_mask; | 394 | unsigned int nentries_mask = dest_ring->nentries_mask; |
402 | unsigned int write_index; | 395 | unsigned int write_index = dest_ring->write_index; |
403 | unsigned int sw_index; | 396 | unsigned int sw_index = dest_ring->sw_index; |
404 | int ret; | ||
405 | 397 | ||
406 | spin_lock_bh(&ar_pci->ce_lock); | 398 | lockdep_assert_held(&ar_pci->ce_lock); |
407 | write_index = dest_ring->write_index; | ||
408 | sw_index = dest_ring->sw_index; | ||
409 | 399 | ||
410 | ret = ath10k_pci_wake(ar); | 400 | return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); |
411 | if (ret) | 401 | } |
412 | goto out; | ||
413 | 402 | ||
414 | if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) { | 403 | int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) |
415 | struct ce_desc *base = dest_ring->base_addr_owner_space; | 404 | { |
416 | struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); | 405 | struct ath10k *ar = pipe->ar; |
406 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
407 | struct ath10k_ce_ring *dest_ring = pipe->dest_ring; | ||
408 | unsigned int nentries_mask = dest_ring->nentries_mask; | ||
409 | unsigned int write_index = dest_ring->write_index; | ||
410 | unsigned int sw_index = dest_ring->sw_index; | ||
411 | struct ce_desc *base = dest_ring->base_addr_owner_space; | ||
412 | struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); | ||
413 | u32 ctrl_addr = pipe->ctrl_addr; | ||
417 | 414 | ||
418 | /* Update destination descriptor */ | 415 | lockdep_assert_held(&ar_pci->ce_lock); |
419 | desc->addr = __cpu_to_le32(buffer); | ||
420 | desc->nbytes = 0; | ||
421 | 416 | ||
422 | dest_ring->per_transfer_context[write_index] = | 417 | if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0) |
423 | per_recv_context; | 418 | return -EIO; |
424 | 419 | ||
425 | /* Update Destination Ring Write Index */ | 420 | desc->addr = __cpu_to_le32(paddr); |
426 | write_index = CE_RING_IDX_INCR(nentries_mask, write_index); | 421 | desc->nbytes = 0; |
427 | ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index); | 422 | |
428 | dest_ring->write_index = write_index; | 423 | dest_ring->per_transfer_context[write_index] = ctx; |
429 | ret = 0; | 424 | write_index = CE_RING_IDX_INCR(nentries_mask, write_index); |
430 | } else { | 425 | ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index); |
431 | ret = -EIO; | 426 | dest_ring->write_index = write_index; |
432 | } | 427 | |
433 | ath10k_pci_sleep(ar); | 428 | return 0; |
429 | } | ||
430 | |||
431 | int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) | ||
432 | { | ||
433 | struct ath10k *ar = pipe->ar; | ||
434 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
435 | int ret; | ||
434 | 436 | ||
435 | out: | 437 | spin_lock_bh(&ar_pci->ce_lock); |
438 | ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr); | ||
436 | spin_unlock_bh(&ar_pci->ce_lock); | 439 | spin_unlock_bh(&ar_pci->ce_lock); |
437 | 440 | ||
438 | return ret; | 441 | return ret; |
@@ -588,7 +591,6 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, | |||
588 | unsigned int sw_index = src_ring->sw_index; | 591 | unsigned int sw_index = src_ring->sw_index; |
589 | struct ce_desc *sdesc, *sbase; | 592 | struct ce_desc *sdesc, *sbase; |
590 | unsigned int read_index; | 593 | unsigned int read_index; |
591 | int ret; | ||
592 | 594 | ||
593 | if (src_ring->hw_index == sw_index) { | 595 | if (src_ring->hw_index == sw_index) { |
594 | /* | 596 | /* |
@@ -599,18 +601,12 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, | |||
599 | * value of the HW index has become stale. | 601 | * value of the HW index has become stale. |
600 | */ | 602 | */ |
601 | 603 | ||
602 | ret = ath10k_pci_wake(ar); | ||
603 | if (ret) | ||
604 | return ret; | ||
605 | |||
606 | read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); | 604 | read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); |
607 | if (read_index == 0xffffffff) | 605 | if (read_index == 0xffffffff) |
608 | return -ENODEV; | 606 | return -ENODEV; |
609 | 607 | ||
610 | read_index &= nentries_mask; | 608 | read_index &= nentries_mask; |
611 | src_ring->hw_index = read_index; | 609 | src_ring->hw_index = read_index; |
612 | |||
613 | ath10k_pci_sleep(ar); | ||
614 | } | 610 | } |
615 | 611 | ||
616 | read_index = src_ring->hw_index; | 612 | read_index = src_ring->hw_index; |
@@ -731,11 +727,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) | |||
731 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 727 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
732 | struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; | 728 | struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; |
733 | u32 ctrl_addr = ce_state->ctrl_addr; | 729 | u32 ctrl_addr = ce_state->ctrl_addr; |
734 | int ret; | ||
735 | |||
736 | ret = ath10k_pci_wake(ar); | ||
737 | if (ret) | ||
738 | return; | ||
739 | 730 | ||
740 | spin_lock_bh(&ar_pci->ce_lock); | 731 | spin_lock_bh(&ar_pci->ce_lock); |
741 | 732 | ||
@@ -760,7 +751,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) | |||
760 | ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK); | 751 | ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK); |
761 | 752 | ||
762 | spin_unlock_bh(&ar_pci->ce_lock); | 753 | spin_unlock_bh(&ar_pci->ce_lock); |
763 | ath10k_pci_sleep(ar); | ||
764 | } | 754 | } |
765 | 755 | ||
766 | /* | 756 | /* |
@@ -771,13 +761,9 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) | |||
771 | 761 | ||
772 | void ath10k_ce_per_engine_service_any(struct ath10k *ar) | 762 | void ath10k_ce_per_engine_service_any(struct ath10k *ar) |
773 | { | 763 | { |
774 | int ce_id, ret; | 764 | int ce_id; |
775 | u32 intr_summary; | 765 | u32 intr_summary; |
776 | 766 | ||
777 | ret = ath10k_pci_wake(ar); | ||
778 | if (ret) | ||
779 | return; | ||
780 | |||
781 | intr_summary = CE_INTERRUPT_SUMMARY(ar); | 767 | intr_summary = CE_INTERRUPT_SUMMARY(ar); |
782 | 768 | ||
783 | for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { | 769 | for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { |
@@ -789,8 +775,6 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) | |||
789 | 775 | ||
790 | ath10k_ce_per_engine_service(ar, ce_id); | 776 | ath10k_ce_per_engine_service(ar, ce_id); |
791 | } | 777 | } |
792 | |||
793 | ath10k_pci_sleep(ar); | ||
794 | } | 778 | } |
795 | 779 | ||
796 | /* | 780 | /* |
@@ -800,16 +784,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) | |||
800 | * | 784 | * |
801 | * Called with ce_lock held. | 785 | * Called with ce_lock held. |
802 | */ | 786 | */ |
803 | static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, | 787 | static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state) |
804 | int disable_copy_compl_intr) | ||
805 | { | 788 | { |
806 | u32 ctrl_addr = ce_state->ctrl_addr; | 789 | u32 ctrl_addr = ce_state->ctrl_addr; |
807 | struct ath10k *ar = ce_state->ar; | 790 | struct ath10k *ar = ce_state->ar; |
808 | int ret; | 791 | bool disable_copy_compl_intr = ce_state->attr_flags & CE_ATTR_DIS_INTR; |
809 | |||
810 | ret = ath10k_pci_wake(ar); | ||
811 | if (ret) | ||
812 | return; | ||
813 | 792 | ||
814 | if ((!disable_copy_compl_intr) && | 793 | if ((!disable_copy_compl_intr) && |
815 | (ce_state->send_cb || ce_state->recv_cb)) | 794 | (ce_state->send_cb || ce_state->recv_cb)) |
@@ -818,17 +797,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, | |||
818 | ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); | 797 | ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); |
819 | 798 | ||
820 | ath10k_ce_watermark_intr_disable(ar, ctrl_addr); | 799 | ath10k_ce_watermark_intr_disable(ar, ctrl_addr); |
821 | |||
822 | ath10k_pci_sleep(ar); | ||
823 | } | 800 | } |
824 | 801 | ||
825 | int ath10k_ce_disable_interrupts(struct ath10k *ar) | 802 | int ath10k_ce_disable_interrupts(struct ath10k *ar) |
826 | { | 803 | { |
827 | int ce_id, ret; | 804 | int ce_id; |
828 | |||
829 | ret = ath10k_pci_wake(ar); | ||
830 | if (ret) | ||
831 | return ret; | ||
832 | 805 | ||
833 | for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { | 806 | for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { |
834 | u32 ctrl_addr = ath10k_ce_base_address(ce_id); | 807 | u32 ctrl_addr = ath10k_ce_base_address(ce_id); |
@@ -838,34 +811,16 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar) | |||
838 | ath10k_ce_watermark_intr_disable(ar, ctrl_addr); | 811 | ath10k_ce_watermark_intr_disable(ar, ctrl_addr); |
839 | } | 812 | } |
840 | 813 | ||
841 | ath10k_pci_sleep(ar); | ||
842 | |||
843 | return 0; | 814 | return 0; |
844 | } | 815 | } |
845 | 816 | ||
846 | void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, | 817 | void ath10k_ce_enable_interrupts(struct ath10k *ar) |
847 | void (*send_cb)(struct ath10k_ce_pipe *), | ||
848 | int disable_interrupts) | ||
849 | { | 818 | { |
850 | struct ath10k *ar = ce_state->ar; | ||
851 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 819 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
820 | int ce_id; | ||
852 | 821 | ||
853 | spin_lock_bh(&ar_pci->ce_lock); | 822 | for (ce_id = 0; ce_id < CE_COUNT; ce_id++) |
854 | ce_state->send_cb = send_cb; | 823 | ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]); |
855 | ath10k_ce_per_engine_handler_adjust(ce_state, disable_interrupts); | ||
856 | spin_unlock_bh(&ar_pci->ce_lock); | ||
857 | } | ||
858 | |||
859 | void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, | ||
860 | void (*recv_cb)(struct ath10k_ce_pipe *)) | ||
861 | { | ||
862 | struct ath10k *ar = ce_state->ar; | ||
863 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
864 | |||
865 | spin_lock_bh(&ar_pci->ce_lock); | ||
866 | ce_state->recv_cb = recv_cb; | ||
867 | ath10k_ce_per_engine_handler_adjust(ce_state, 0); | ||
868 | spin_unlock_bh(&ar_pci->ce_lock); | ||
869 | } | 824 | } |
870 | 825 | ||
871 | static int ath10k_ce_init_src_ring(struct ath10k *ar, | 826 | static int ath10k_ce_init_src_ring(struct ath10k *ar, |
@@ -898,7 +853,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, | |||
898 | ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); | 853 | ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); |
899 | ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); | 854 | ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); |
900 | 855 | ||
901 | ath10k_dbg(ATH10K_DBG_BOOT, | 856 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
902 | "boot init ce src ring id %d entries %d base_addr %p\n", | 857 | "boot init ce src ring id %d entries %d base_addr %p\n", |
903 | ce_id, nentries, src_ring->base_addr_owner_space); | 858 | ce_id, nentries, src_ring->base_addr_owner_space); |
904 | 859 | ||
@@ -932,7 +887,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, | |||
932 | ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); | 887 | ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); |
933 | ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); | 888 | ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); |
934 | 889 | ||
935 | ath10k_dbg(ATH10K_DBG_BOOT, | 890 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
936 | "boot ce dest ring id %d entries %d base_addr %p\n", | 891 | "boot ce dest ring id %d entries %d base_addr %p\n", |
937 | ce_id, nentries, dest_ring->base_addr_owner_space); | 892 | ce_id, nentries, dest_ring->base_addr_owner_space); |
938 | 893 | ||
@@ -1067,7 +1022,9 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, | |||
1067 | * initialized by software/firmware. | 1022 | * initialized by software/firmware. |
1068 | */ | 1023 | */ |
1069 | int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, | 1024 | int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, |
1070 | const struct ce_attr *attr) | 1025 | const struct ce_attr *attr, |
1026 | void (*send_cb)(struct ath10k_ce_pipe *), | ||
1027 | void (*recv_cb)(struct ath10k_ce_pipe *)) | ||
1071 | { | 1028 | { |
1072 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1029 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
1073 | struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; | 1030 | struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; |
@@ -1084,39 +1041,37 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, | |||
1084 | BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > | 1041 | BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > |
1085 | (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); | 1042 | (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); |
1086 | 1043 | ||
1087 | ret = ath10k_pci_wake(ar); | ||
1088 | if (ret) | ||
1089 | return ret; | ||
1090 | |||
1091 | spin_lock_bh(&ar_pci->ce_lock); | 1044 | spin_lock_bh(&ar_pci->ce_lock); |
1092 | ce_state->ar = ar; | 1045 | ce_state->ar = ar; |
1093 | ce_state->id = ce_id; | 1046 | ce_state->id = ce_id; |
1094 | ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); | 1047 | ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); |
1095 | ce_state->attr_flags = attr->flags; | 1048 | ce_state->attr_flags = attr->flags; |
1096 | ce_state->src_sz_max = attr->src_sz_max; | 1049 | ce_state->src_sz_max = attr->src_sz_max; |
1050 | if (attr->src_nentries) | ||
1051 | ce_state->send_cb = send_cb; | ||
1052 | if (attr->dest_nentries) | ||
1053 | ce_state->recv_cb = recv_cb; | ||
1097 | spin_unlock_bh(&ar_pci->ce_lock); | 1054 | spin_unlock_bh(&ar_pci->ce_lock); |
1098 | 1055 | ||
1099 | if (attr->src_nentries) { | 1056 | if (attr->src_nentries) { |
1100 | ret = ath10k_ce_init_src_ring(ar, ce_id, attr); | 1057 | ret = ath10k_ce_init_src_ring(ar, ce_id, attr); |
1101 | if (ret) { | 1058 | if (ret) { |
1102 | ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", | 1059 | ath10k_err(ar, "Failed to initialize CE src ring for ID: %d (%d)\n", |
1103 | ce_id, ret); | 1060 | ce_id, ret); |
1104 | goto out; | 1061 | return ret; |
1105 | } | 1062 | } |
1106 | } | 1063 | } |
1107 | 1064 | ||
1108 | if (attr->dest_nentries) { | 1065 | if (attr->dest_nentries) { |
1109 | ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); | 1066 | ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); |
1110 | if (ret) { | 1067 | if (ret) { |
1111 | ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", | 1068 | ath10k_err(ar, "Failed to initialize CE dest ring for ID: %d (%d)\n", |
1112 | ce_id, ret); | 1069 | ce_id, ret); |
1113 | goto out; | 1070 | return ret; |
1114 | } | 1071 | } |
1115 | } | 1072 | } |
1116 | 1073 | ||
1117 | out: | 1074 | return 0; |
1118 | ath10k_pci_sleep(ar); | ||
1119 | return ret; | ||
1120 | } | 1075 | } |
1121 | 1076 | ||
1122 | static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) | 1077 | static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) |
@@ -1140,16 +1095,8 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) | |||
1140 | 1095 | ||
1141 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) | 1096 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) |
1142 | { | 1097 | { |
1143 | int ret; | ||
1144 | |||
1145 | ret = ath10k_pci_wake(ar); | ||
1146 | if (ret) | ||
1147 | return; | ||
1148 | |||
1149 | ath10k_ce_deinit_src_ring(ar, ce_id); | 1098 | ath10k_ce_deinit_src_ring(ar, ce_id); |
1150 | ath10k_ce_deinit_dest_ring(ar, ce_id); | 1099 | ath10k_ce_deinit_dest_ring(ar, ce_id); |
1151 | |||
1152 | ath10k_pci_sleep(ar); | ||
1153 | } | 1100 | } |
1154 | 1101 | ||
1155 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, | 1102 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, |
@@ -1163,7 +1110,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, | |||
1163 | ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); | 1110 | ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); |
1164 | if (IS_ERR(ce_state->src_ring)) { | 1111 | if (IS_ERR(ce_state->src_ring)) { |
1165 | ret = PTR_ERR(ce_state->src_ring); | 1112 | ret = PTR_ERR(ce_state->src_ring); |
1166 | ath10k_err("failed to allocate copy engine source ring %d: %d\n", | 1113 | ath10k_err(ar, "failed to allocate copy engine source ring %d: %d\n", |
1167 | ce_id, ret); | 1114 | ce_id, ret); |
1168 | ce_state->src_ring = NULL; | 1115 | ce_state->src_ring = NULL; |
1169 | return ret; | 1116 | return ret; |
@@ -1175,7 +1122,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, | |||
1175 | attr); | 1122 | attr); |
1176 | if (IS_ERR(ce_state->dest_ring)) { | 1123 | if (IS_ERR(ce_state->dest_ring)) { |
1177 | ret = PTR_ERR(ce_state->dest_ring); | 1124 | ret = PTR_ERR(ce_state->dest_ring); |
1178 | ath10k_err("failed to allocate copy engine destination ring %d: %d\n", | 1125 | ath10k_err(ar, "failed to allocate copy engine destination ring %d: %d\n", |
1179 | ce_id, ret); | 1126 | ce_id, ret); |
1180 | ce_state->dest_ring = NULL; | 1127 | ce_state->dest_ring = NULL; |
1181 | return ret; | 1128 | return ret; |
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 7a5a36fc59c1..82d1f23546b9 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h | |||
@@ -162,30 +162,13 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, | |||
162 | 162 | ||
163 | void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); | 163 | void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); |
164 | 164 | ||
165 | void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, | ||
166 | void (*send_cb)(struct ath10k_ce_pipe *), | ||
167 | int disable_interrupts); | ||
168 | |||
169 | int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); | 165 | int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); |
170 | 166 | ||
171 | /*==================Recv=======================*/ | 167 | /*==================Recv=======================*/ |
172 | 168 | ||
173 | /* | 169 | int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe); |
174 | * Make a buffer available to receive. The buffer must be at least of a | 170 | int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr); |
175 | * minimal size appropriate for this copy engine (src_sz_max attribute). | 171 | int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr); |
176 | * ce - which copy engine to use | ||
177 | * per_transfer_recv_context - context passed back to caller's recv_cb | ||
178 | * buffer - address of buffer in CE space | ||
179 | * Returns 0 on success; otherwise an error status. | ||
180 | * | ||
181 | * Implemenation note: Pushes a buffer to Dest ring. | ||
182 | */ | ||
183 | int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, | ||
184 | void *per_transfer_recv_context, | ||
185 | u32 buffer); | ||
186 | |||
187 | void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, | ||
188 | void (*recv_cb)(struct ath10k_ce_pipe *)); | ||
189 | 172 | ||
190 | /* recv flags */ | 173 | /* recv flags */ |
191 | /* Data is byte-swapped */ | 174 | /* Data is byte-swapped */ |
@@ -214,7 +197,9 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, | |||
214 | /*==================CE Engine Initialization=======================*/ | 197 | /*==================CE Engine Initialization=======================*/ |
215 | 198 | ||
216 | int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, | 199 | int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, |
217 | const struct ce_attr *attr); | 200 | const struct ce_attr *attr, |
201 | void (*send_cb)(struct ath10k_ce_pipe *), | ||
202 | void (*recv_cb)(struct ath10k_ce_pipe *)); | ||
218 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); | 203 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); |
219 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, | 204 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, |
220 | const struct ce_attr *attr); | 205 | const struct ce_attr *attr); |
@@ -245,6 +230,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, | |||
245 | void ath10k_ce_per_engine_service_any(struct ath10k *ar); | 230 | void ath10k_ce_per_engine_service_any(struct ath10k *ar); |
246 | void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); | 231 | void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); |
247 | int ath10k_ce_disable_interrupts(struct ath10k *ar); | 232 | int ath10k_ce_disable_interrupts(struct ath10k *ar); |
233 | void ath10k_ce_enable_interrupts(struct ath10k *ar); | ||
248 | 234 | ||
249 | /* ce_attr.flags values */ | 235 | /* ce_attr.flags values */ |
250 | /* Use NonSnooping PCIe accesses? */ | 236 | /* Use NonSnooping PCIe accesses? */ |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 93adb8c58969..651a6da8adf5 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -53,7 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
53 | 53 | ||
54 | static void ath10k_send_suspend_complete(struct ath10k *ar) | 54 | static void ath10k_send_suspend_complete(struct ath10k *ar) |
55 | { | 55 | { |
56 | ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); | 56 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n"); |
57 | 57 | ||
58 | complete(&ar->target_suspend); | 58 | complete(&ar->target_suspend); |
59 | } | 59 | } |
@@ -67,14 +67,14 @@ static int ath10k_init_configure_target(struct ath10k *ar) | |||
67 | ret = ath10k_bmi_write32(ar, hi_app_host_interest, | 67 | ret = ath10k_bmi_write32(ar, hi_app_host_interest, |
68 | HTC_PROTOCOL_VERSION); | 68 | HTC_PROTOCOL_VERSION); |
69 | if (ret) { | 69 | if (ret) { |
70 | ath10k_err("settings HTC version failed\n"); | 70 | ath10k_err(ar, "settings HTC version failed\n"); |
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | /* set the firmware mode to STA/IBSS/AP */ | 74 | /* set the firmware mode to STA/IBSS/AP */ |
75 | ret = ath10k_bmi_read32(ar, hi_option_flag, ¶m_host); | 75 | ret = ath10k_bmi_read32(ar, hi_option_flag, ¶m_host); |
76 | if (ret) { | 76 | if (ret) { |
77 | ath10k_err("setting firmware mode (1/2) failed\n"); | 77 | ath10k_err(ar, "setting firmware mode (1/2) failed\n"); |
78 | return ret; | 78 | return ret; |
79 | } | 79 | } |
80 | 80 | ||
@@ -93,14 +93,14 @@ static int ath10k_init_configure_target(struct ath10k *ar) | |||
93 | 93 | ||
94 | ret = ath10k_bmi_write32(ar, hi_option_flag, param_host); | 94 | ret = ath10k_bmi_write32(ar, hi_option_flag, param_host); |
95 | if (ret) { | 95 | if (ret) { |
96 | ath10k_err("setting firmware mode (2/2) failed\n"); | 96 | ath10k_err(ar, "setting firmware mode (2/2) failed\n"); |
97 | return ret; | 97 | return ret; |
98 | } | 98 | } |
99 | 99 | ||
100 | /* We do all byte-swapping on the host */ | 100 | /* We do all byte-swapping on the host */ |
101 | ret = ath10k_bmi_write32(ar, hi_be, 0); | 101 | ret = ath10k_bmi_write32(ar, hi_be, 0); |
102 | if (ret) { | 102 | if (ret) { |
103 | ath10k_err("setting host CPU BE mode failed\n"); | 103 | ath10k_err(ar, "setting host CPU BE mode failed\n"); |
104 | return ret; | 104 | return ret; |
105 | } | 105 | } |
106 | 106 | ||
@@ -108,7 +108,7 @@ static int ath10k_init_configure_target(struct ath10k *ar) | |||
108 | ret = ath10k_bmi_write32(ar, hi_fw_swap, 0); | 108 | ret = ath10k_bmi_write32(ar, hi_fw_swap, 0); |
109 | 109 | ||
110 | if (ret) { | 110 | if (ret) { |
111 | ath10k_err("setting FW data/desc swap flags failed\n"); | 111 | ath10k_err(ar, "setting FW data/desc swap flags failed\n"); |
112 | return ret; | 112 | return ret; |
113 | } | 113 | } |
114 | 114 | ||
@@ -146,11 +146,12 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) | |||
146 | 146 | ||
147 | ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr); | 147 | ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr); |
148 | if (ret) { | 148 | if (ret) { |
149 | ath10k_err("could not read board ext data addr (%d)\n", ret); | 149 | ath10k_err(ar, "could not read board ext data addr (%d)\n", |
150 | ret); | ||
150 | return ret; | 151 | return ret; |
151 | } | 152 | } |
152 | 153 | ||
153 | ath10k_dbg(ATH10K_DBG_BOOT, | 154 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
154 | "boot push board extended data addr 0x%x\n", | 155 | "boot push board extended data addr 0x%x\n", |
155 | board_ext_data_addr); | 156 | board_ext_data_addr); |
156 | 157 | ||
@@ -158,7 +159,7 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) | |||
158 | return 0; | 159 | return 0; |
159 | 160 | ||
160 | if (ar->board_len != (board_data_size + board_ext_data_size)) { | 161 | if (ar->board_len != (board_data_size + board_ext_data_size)) { |
161 | ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n", | 162 | ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n", |
162 | ar->board_len, board_data_size, board_ext_data_size); | 163 | ar->board_len, board_data_size, board_ext_data_size); |
163 | return -EINVAL; | 164 | return -EINVAL; |
164 | } | 165 | } |
@@ -167,14 +168,15 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) | |||
167 | ar->board_data + board_data_size, | 168 | ar->board_data + board_data_size, |
168 | board_ext_data_size); | 169 | board_ext_data_size); |
169 | if (ret) { | 170 | if (ret) { |
170 | ath10k_err("could not write board ext data (%d)\n", ret); | 171 | ath10k_err(ar, "could not write board ext data (%d)\n", ret); |
171 | return ret; | 172 | return ret; |
172 | } | 173 | } |
173 | 174 | ||
174 | ret = ath10k_bmi_write32(ar, hi_board_ext_data_config, | 175 | ret = ath10k_bmi_write32(ar, hi_board_ext_data_config, |
175 | (board_ext_data_size << 16) | 1); | 176 | (board_ext_data_size << 16) | 1); |
176 | if (ret) { | 177 | if (ret) { |
177 | ath10k_err("could not write board ext data bit (%d)\n", ret); | 178 | ath10k_err(ar, "could not write board ext data bit (%d)\n", |
179 | ret); | ||
178 | return ret; | 180 | return ret; |
179 | } | 181 | } |
180 | 182 | ||
@@ -189,13 +191,13 @@ static int ath10k_download_board_data(struct ath10k *ar) | |||
189 | 191 | ||
190 | ret = ath10k_push_board_ext_data(ar); | 192 | ret = ath10k_push_board_ext_data(ar); |
191 | if (ret) { | 193 | if (ret) { |
192 | ath10k_err("could not push board ext data (%d)\n", ret); | 194 | ath10k_err(ar, "could not push board ext data (%d)\n", ret); |
193 | goto exit; | 195 | goto exit; |
194 | } | 196 | } |
195 | 197 | ||
196 | ret = ath10k_bmi_read32(ar, hi_board_data, &address); | 198 | ret = ath10k_bmi_read32(ar, hi_board_data, &address); |
197 | if (ret) { | 199 | if (ret) { |
198 | ath10k_err("could not read board data addr (%d)\n", ret); | 200 | ath10k_err(ar, "could not read board data addr (%d)\n", ret); |
199 | goto exit; | 201 | goto exit; |
200 | } | 202 | } |
201 | 203 | ||
@@ -203,13 +205,13 @@ static int ath10k_download_board_data(struct ath10k *ar) | |||
203 | min_t(u32, board_data_size, | 205 | min_t(u32, board_data_size, |
204 | ar->board_len)); | 206 | ar->board_len)); |
205 | if (ret) { | 207 | if (ret) { |
206 | ath10k_err("could not write board data (%d)\n", ret); | 208 | ath10k_err(ar, "could not write board data (%d)\n", ret); |
207 | goto exit; | 209 | goto exit; |
208 | } | 210 | } |
209 | 211 | ||
210 | ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1); | 212 | ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1); |
211 | if (ret) { | 213 | if (ret) { |
212 | ath10k_err("could not write board data bit (%d)\n", ret); | 214 | ath10k_err(ar, "could not write board data bit (%d)\n", ret); |
213 | goto exit; | 215 | goto exit; |
214 | } | 216 | } |
215 | 217 | ||
@@ -225,30 +227,30 @@ static int ath10k_download_and_run_otp(struct ath10k *ar) | |||
225 | /* OTP is optional */ | 227 | /* OTP is optional */ |
226 | 228 | ||
227 | if (!ar->otp_data || !ar->otp_len) { | 229 | if (!ar->otp_data || !ar->otp_len) { |
228 | ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", | 230 | ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", |
229 | ar->otp_data, ar->otp_len); | 231 | ar->otp_data, ar->otp_len); |
230 | return 0; | 232 | return 0; |
231 | } | 233 | } |
232 | 234 | ||
233 | ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", | 235 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", |
234 | address, ar->otp_len); | 236 | address, ar->otp_len); |
235 | 237 | ||
236 | ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); | 238 | ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); |
237 | if (ret) { | 239 | if (ret) { |
238 | ath10k_err("could not write otp (%d)\n", ret); | 240 | ath10k_err(ar, "could not write otp (%d)\n", ret); |
239 | return ret; | 241 | return ret; |
240 | } | 242 | } |
241 | 243 | ||
242 | ret = ath10k_bmi_execute(ar, address, 0, &result); | 244 | ret = ath10k_bmi_execute(ar, address, 0, &result); |
243 | if (ret) { | 245 | if (ret) { |
244 | ath10k_err("could not execute otp (%d)\n", ret); | 246 | ath10k_err(ar, "could not execute otp (%d)\n", ret); |
245 | return ret; | 247 | return ret; |
246 | } | 248 | } |
247 | 249 | ||
248 | ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); | 250 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); |
249 | 251 | ||
250 | if (result != 0) { | 252 | if (result != 0) { |
251 | ath10k_err("otp calibration failed: %d", result); | 253 | ath10k_err(ar, "otp calibration failed: %d", result); |
252 | return -EINVAL; | 254 | return -EINVAL; |
253 | } | 255 | } |
254 | 256 | ||
@@ -265,7 +267,7 @@ static int ath10k_download_fw(struct ath10k *ar) | |||
265 | ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data, | 267 | ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data, |
266 | ar->firmware_len); | 268 | ar->firmware_len); |
267 | if (ret) { | 269 | if (ret) { |
268 | ath10k_err("could not write fw (%d)\n", ret); | 270 | ath10k_err(ar, "could not write fw (%d)\n", ret); |
269 | goto exit; | 271 | goto exit; |
270 | } | 272 | } |
271 | 273 | ||
@@ -302,12 +304,12 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) | |||
302 | int ret = 0; | 304 | int ret = 0; |
303 | 305 | ||
304 | if (ar->hw_params.fw.fw == NULL) { | 306 | if (ar->hw_params.fw.fw == NULL) { |
305 | ath10k_err("firmware file not defined\n"); | 307 | ath10k_err(ar, "firmware file not defined\n"); |
306 | return -EINVAL; | 308 | return -EINVAL; |
307 | } | 309 | } |
308 | 310 | ||
309 | if (ar->hw_params.fw.board == NULL) { | 311 | if (ar->hw_params.fw.board == NULL) { |
310 | ath10k_err("board data file not defined"); | 312 | ath10k_err(ar, "board data file not defined"); |
311 | return -EINVAL; | 313 | return -EINVAL; |
312 | } | 314 | } |
313 | 315 | ||
@@ -316,7 +318,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) | |||
316 | ar->hw_params.fw.board); | 318 | ar->hw_params.fw.board); |
317 | if (IS_ERR(ar->board)) { | 319 | if (IS_ERR(ar->board)) { |
318 | ret = PTR_ERR(ar->board); | 320 | ret = PTR_ERR(ar->board); |
319 | ath10k_err("could not fetch board data (%d)\n", ret); | 321 | ath10k_err(ar, "could not fetch board data (%d)\n", ret); |
320 | goto err; | 322 | goto err; |
321 | } | 323 | } |
322 | 324 | ||
@@ -328,7 +330,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) | |||
328 | ar->hw_params.fw.fw); | 330 | ar->hw_params.fw.fw); |
329 | if (IS_ERR(ar->firmware)) { | 331 | if (IS_ERR(ar->firmware)) { |
330 | ret = PTR_ERR(ar->firmware); | 332 | ret = PTR_ERR(ar->firmware); |
331 | ath10k_err("could not fetch firmware (%d)\n", ret); | 333 | ath10k_err(ar, "could not fetch firmware (%d)\n", ret); |
332 | goto err; | 334 | goto err; |
333 | } | 335 | } |
334 | 336 | ||
@@ -344,7 +346,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) | |||
344 | ar->hw_params.fw.otp); | 346 | ar->hw_params.fw.otp); |
345 | if (IS_ERR(ar->otp)) { | 347 | if (IS_ERR(ar->otp)) { |
346 | ret = PTR_ERR(ar->otp); | 348 | ret = PTR_ERR(ar->otp); |
347 | ath10k_err("could not fetch otp (%d)\n", ret); | 349 | ath10k_err(ar, "could not fetch otp (%d)\n", ret); |
348 | goto err; | 350 | goto err; |
349 | } | 351 | } |
350 | 352 | ||
@@ -369,7 +371,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
369 | /* first fetch the firmware file (firmware-*.bin) */ | 371 | /* first fetch the firmware file (firmware-*.bin) */ |
370 | ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); | 372 | ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); |
371 | if (IS_ERR(ar->firmware)) { | 373 | if (IS_ERR(ar->firmware)) { |
372 | ath10k_err("could not fetch firmware file '%s/%s': %ld\n", | 374 | ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n", |
373 | ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware)); | 375 | ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware)); |
374 | return PTR_ERR(ar->firmware); | 376 | return PTR_ERR(ar->firmware); |
375 | } | 377 | } |
@@ -381,14 +383,14 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
381 | magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; | 383 | magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; |
382 | 384 | ||
383 | if (len < magic_len) { | 385 | if (len < magic_len) { |
384 | ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n", | 386 | ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n", |
385 | ar->hw_params.fw.dir, name, len); | 387 | ar->hw_params.fw.dir, name, len); |
386 | ret = -EINVAL; | 388 | ret = -EINVAL; |
387 | goto err; | 389 | goto err; |
388 | } | 390 | } |
389 | 391 | ||
390 | if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { | 392 | if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { |
391 | ath10k_err("invalid firmware magic\n"); | 393 | ath10k_err(ar, "invalid firmware magic\n"); |
392 | ret = -EINVAL; | 394 | ret = -EINVAL; |
393 | goto err; | 395 | goto err; |
394 | } | 396 | } |
@@ -410,7 +412,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
410 | data += sizeof(*hdr); | 412 | data += sizeof(*hdr); |
411 | 413 | ||
412 | if (len < ie_len) { | 414 | if (len < ie_len) { |
413 | ath10k_err("invalid length for FW IE %d (%zu < %zu)\n", | 415 | ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n", |
414 | ie_id, len, ie_len); | 416 | ie_id, len, ie_len); |
415 | ret = -EINVAL; | 417 | ret = -EINVAL; |
416 | goto err; | 418 | goto err; |
@@ -424,7 +426,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
424 | memcpy(ar->hw->wiphy->fw_version, data, ie_len); | 426 | memcpy(ar->hw->wiphy->fw_version, data, ie_len); |
425 | ar->hw->wiphy->fw_version[ie_len] = '\0'; | 427 | ar->hw->wiphy->fw_version[ie_len] = '\0'; |
426 | 428 | ||
427 | ath10k_dbg(ATH10K_DBG_BOOT, | 429 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
428 | "found fw version %s\n", | 430 | "found fw version %s\n", |
429 | ar->hw->wiphy->fw_version); | 431 | ar->hw->wiphy->fw_version); |
430 | break; | 432 | break; |
@@ -434,11 +436,11 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
434 | 436 | ||
435 | timestamp = (__le32 *)data; | 437 | timestamp = (__le32 *)data; |
436 | 438 | ||
437 | ath10k_dbg(ATH10K_DBG_BOOT, "found fw timestamp %d\n", | 439 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n", |
438 | le32_to_cpup(timestamp)); | 440 | le32_to_cpup(timestamp)); |
439 | break; | 441 | break; |
440 | case ATH10K_FW_IE_FEATURES: | 442 | case ATH10K_FW_IE_FEATURES: |
441 | ath10k_dbg(ATH10K_DBG_BOOT, | 443 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
442 | "found firmware features ie (%zd B)\n", | 444 | "found firmware features ie (%zd B)\n", |
443 | ie_len); | 445 | ie_len); |
444 | 446 | ||
@@ -450,19 +452,19 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
450 | break; | 452 | break; |
451 | 453 | ||
452 | if (data[index] & (1 << bit)) { | 454 | if (data[index] & (1 << bit)) { |
453 | ath10k_dbg(ATH10K_DBG_BOOT, | 455 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
454 | "Enabling feature bit: %i\n", | 456 | "Enabling feature bit: %i\n", |
455 | i); | 457 | i); |
456 | __set_bit(i, ar->fw_features); | 458 | __set_bit(i, ar->fw_features); |
457 | } | 459 | } |
458 | } | 460 | } |
459 | 461 | ||
460 | ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "", | 462 | ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "", |
461 | ar->fw_features, | 463 | ar->fw_features, |
462 | sizeof(ar->fw_features)); | 464 | sizeof(ar->fw_features)); |
463 | break; | 465 | break; |
464 | case ATH10K_FW_IE_FW_IMAGE: | 466 | case ATH10K_FW_IE_FW_IMAGE: |
465 | ath10k_dbg(ATH10K_DBG_BOOT, | 467 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
466 | "found fw image ie (%zd B)\n", | 468 | "found fw image ie (%zd B)\n", |
467 | ie_len); | 469 | ie_len); |
468 | 470 | ||
@@ -471,7 +473,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
471 | 473 | ||
472 | break; | 474 | break; |
473 | case ATH10K_FW_IE_OTP_IMAGE: | 475 | case ATH10K_FW_IE_OTP_IMAGE: |
474 | ath10k_dbg(ATH10K_DBG_BOOT, | 476 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
475 | "found otp image ie (%zd B)\n", | 477 | "found otp image ie (%zd B)\n", |
476 | ie_len); | 478 | ie_len); |
477 | 479 | ||
@@ -480,7 +482,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
480 | 482 | ||
481 | break; | 483 | break; |
482 | default: | 484 | default: |
483 | ath10k_warn("Unknown FW IE: %u\n", | 485 | ath10k_warn(ar, "Unknown FW IE: %u\n", |
484 | le32_to_cpu(hdr->id)); | 486 | le32_to_cpu(hdr->id)); |
485 | break; | 487 | break; |
486 | } | 488 | } |
@@ -493,15 +495,22 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
493 | } | 495 | } |
494 | 496 | ||
495 | if (!ar->firmware_data || !ar->firmware_len) { | 497 | if (!ar->firmware_data || !ar->firmware_len) { |
496 | ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", | 498 | ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", |
497 | ar->hw_params.fw.dir, name); | 499 | ar->hw_params.fw.dir, name); |
498 | ret = -ENOMEDIUM; | 500 | ret = -ENOMEDIUM; |
499 | goto err; | 501 | goto err; |
500 | } | 502 | } |
501 | 503 | ||
504 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) && | ||
505 | !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | ||
506 | ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well"); | ||
507 | ret = -EINVAL; | ||
508 | goto err; | ||
509 | } | ||
510 | |||
502 | /* now fetch the board file */ | 511 | /* now fetch the board file */ |
503 | if (ar->hw_params.fw.board == NULL) { | 512 | if (ar->hw_params.fw.board == NULL) { |
504 | ath10k_err("board data file not defined"); | 513 | ath10k_err(ar, "board data file not defined"); |
505 | ret = -EINVAL; | 514 | ret = -EINVAL; |
506 | goto err; | 515 | goto err; |
507 | } | 516 | } |
@@ -511,7 +520,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) | |||
511 | ar->hw_params.fw.board); | 520 | ar->hw_params.fw.board); |
512 | if (IS_ERR(ar->board)) { | 521 | if (IS_ERR(ar->board)) { |
513 | ret = PTR_ERR(ar->board); | 522 | ret = PTR_ERR(ar->board); |
514 | ath10k_err("could not fetch board data '%s/%s' (%d)\n", | 523 | ath10k_err(ar, "could not fetch board data '%s/%s' (%d)\n", |
515 | ar->hw_params.fw.dir, ar->hw_params.fw.board, | 524 | ar->hw_params.fw.dir, ar->hw_params.fw.board, |
516 | ret); | 525 | ret); |
517 | goto err; | 526 | goto err; |
@@ -531,22 +540,29 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) | |||
531 | { | 540 | { |
532 | int ret; | 541 | int ret; |
533 | 542 | ||
543 | ar->fw_api = 3; | ||
544 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); | ||
545 | |||
546 | ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE); | ||
547 | if (ret == 0) | ||
548 | goto success; | ||
549 | |||
534 | ar->fw_api = 2; | 550 | ar->fw_api = 2; |
535 | ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); | 551 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); |
536 | 552 | ||
537 | ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); | 553 | ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); |
538 | if (ret == 0) | 554 | if (ret == 0) |
539 | goto success; | 555 | goto success; |
540 | 556 | ||
541 | ar->fw_api = 1; | 557 | ar->fw_api = 1; |
542 | ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); | 558 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); |
543 | 559 | ||
544 | ret = ath10k_core_fetch_firmware_api_1(ar); | 560 | ret = ath10k_core_fetch_firmware_api_1(ar); |
545 | if (ret) | 561 | if (ret) |
546 | return ret; | 562 | return ret; |
547 | 563 | ||
548 | success: | 564 | success: |
549 | ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); | 565 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); |
550 | 566 | ||
551 | return 0; | 567 | return 0; |
552 | } | 568 | } |
@@ -557,19 +573,19 @@ static int ath10k_init_download_firmware(struct ath10k *ar) | |||
557 | 573 | ||
558 | ret = ath10k_download_board_data(ar); | 574 | ret = ath10k_download_board_data(ar); |
559 | if (ret) { | 575 | if (ret) { |
560 | ath10k_err("failed to download board data: %d\n", ret); | 576 | ath10k_err(ar, "failed to download board data: %d\n", ret); |
561 | return ret; | 577 | return ret; |
562 | } | 578 | } |
563 | 579 | ||
564 | ret = ath10k_download_and_run_otp(ar); | 580 | ret = ath10k_download_and_run_otp(ar); |
565 | if (ret) { | 581 | if (ret) { |
566 | ath10k_err("failed to run otp: %d\n", ret); | 582 | ath10k_err(ar, "failed to run otp: %d\n", ret); |
567 | return ret; | 583 | return ret; |
568 | } | 584 | } |
569 | 585 | ||
570 | ret = ath10k_download_fw(ar); | 586 | ret = ath10k_download_fw(ar); |
571 | if (ret) { | 587 | if (ret) { |
572 | ath10k_err("failed to download firmware: %d\n", ret); | 588 | ath10k_err(ar, "failed to download firmware: %d\n", ret); |
573 | return ret; | 589 | return ret; |
574 | } | 590 | } |
575 | 591 | ||
@@ -586,7 +602,7 @@ static int ath10k_init_uart(struct ath10k *ar) | |||
586 | */ | 602 | */ |
587 | ret = ath10k_bmi_write32(ar, hi_serial_enable, 0); | 603 | ret = ath10k_bmi_write32(ar, hi_serial_enable, 0); |
588 | if (ret) { | 604 | if (ret) { |
589 | ath10k_warn("could not disable UART prints (%d)\n", ret); | 605 | ath10k_warn(ar, "could not disable UART prints (%d)\n", ret); |
590 | return ret; | 606 | return ret; |
591 | } | 607 | } |
592 | 608 | ||
@@ -595,24 +611,24 @@ static int ath10k_init_uart(struct ath10k *ar) | |||
595 | 611 | ||
596 | ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); | 612 | ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); |
597 | if (ret) { | 613 | if (ret) { |
598 | ath10k_warn("could not enable UART prints (%d)\n", ret); | 614 | ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); |
599 | return ret; | 615 | return ret; |
600 | } | 616 | } |
601 | 617 | ||
602 | ret = ath10k_bmi_write32(ar, hi_serial_enable, 1); | 618 | ret = ath10k_bmi_write32(ar, hi_serial_enable, 1); |
603 | if (ret) { | 619 | if (ret) { |
604 | ath10k_warn("could not enable UART prints (%d)\n", ret); | 620 | ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); |
605 | return ret; | 621 | return ret; |
606 | } | 622 | } |
607 | 623 | ||
608 | /* Set the UART baud rate to 19200. */ | 624 | /* Set the UART baud rate to 19200. */ |
609 | ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); | 625 | ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); |
610 | if (ret) { | 626 | if (ret) { |
611 | ath10k_warn("could not set the baud rate (%d)\n", ret); | 627 | ath10k_warn(ar, "could not set the baud rate (%d)\n", ret); |
612 | return ret; | 628 | return ret; |
613 | } | 629 | } |
614 | 630 | ||
615 | ath10k_info("UART prints enabled\n"); | 631 | ath10k_info(ar, "UART prints enabled\n"); |
616 | return 0; | 632 | return 0; |
617 | } | 633 | } |
618 | 634 | ||
@@ -629,14 +645,14 @@ static int ath10k_init_hw_params(struct ath10k *ar) | |||
629 | } | 645 | } |
630 | 646 | ||
631 | if (i == ARRAY_SIZE(ath10k_hw_params_list)) { | 647 | if (i == ARRAY_SIZE(ath10k_hw_params_list)) { |
632 | ath10k_err("Unsupported hardware version: 0x%x\n", | 648 | ath10k_err(ar, "Unsupported hardware version: 0x%x\n", |
633 | ar->target_version); | 649 | ar->target_version); |
634 | return -EINVAL; | 650 | return -EINVAL; |
635 | } | 651 | } |
636 | 652 | ||
637 | ar->hw_params = *hw_params; | 653 | ar->hw_params = *hw_params; |
638 | 654 | ||
639 | ath10k_dbg(ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n", | 655 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n", |
640 | ar->hw_params.name, ar->target_version); | 656 | ar->hw_params.name, ar->target_version); |
641 | 657 | ||
642 | return 0; | 658 | return 0; |
@@ -651,14 +667,14 @@ static void ath10k_core_restart(struct work_struct *work) | |||
651 | switch (ar->state) { | 667 | switch (ar->state) { |
652 | case ATH10K_STATE_ON: | 668 | case ATH10K_STATE_ON: |
653 | ar->state = ATH10K_STATE_RESTARTING; | 669 | ar->state = ATH10K_STATE_RESTARTING; |
654 | del_timer_sync(&ar->scan.timeout); | 670 | ath10k_hif_stop(ar); |
655 | ath10k_reset_scan((unsigned long)ar); | 671 | ath10k_scan_finish(ar); |
656 | ieee80211_restart_hw(ar->hw); | 672 | ieee80211_restart_hw(ar->hw); |
657 | break; | 673 | break; |
658 | case ATH10K_STATE_OFF: | 674 | case ATH10K_STATE_OFF: |
659 | /* this can happen if driver is being unloaded | 675 | /* this can happen if driver is being unloaded |
660 | * or if the crash happens during FW probing */ | 676 | * or if the crash happens during FW probing */ |
661 | ath10k_warn("cannot restart a device that hasn't been started\n"); | 677 | ath10k_warn(ar, "cannot restart a device that hasn't been started\n"); |
662 | break; | 678 | break; |
663 | case ATH10K_STATE_RESTARTING: | 679 | case ATH10K_STATE_RESTARTING: |
664 | /* hw restart might be requested from multiple places */ | 680 | /* hw restart might be requested from multiple places */ |
@@ -667,7 +683,7 @@ static void ath10k_core_restart(struct work_struct *work) | |||
667 | ar->state = ATH10K_STATE_WEDGED; | 683 | ar->state = ATH10K_STATE_WEDGED; |
668 | /* fall through */ | 684 | /* fall through */ |
669 | case ATH10K_STATE_WEDGED: | 685 | case ATH10K_STATE_WEDGED: |
670 | ath10k_warn("device is wedged, will not restart\n"); | 686 | ath10k_warn(ar, "device is wedged, will not restart\n"); |
671 | break; | 687 | break; |
672 | } | 688 | } |
673 | 689 | ||
@@ -700,7 +716,7 @@ int ath10k_core_start(struct ath10k *ar) | |||
700 | 716 | ||
701 | status = ath10k_htc_init(ar); | 717 | status = ath10k_htc_init(ar); |
702 | if (status) { | 718 | if (status) { |
703 | ath10k_err("could not init HTC (%d)\n", status); | 719 | ath10k_err(ar, "could not init HTC (%d)\n", status); |
704 | goto err; | 720 | goto err; |
705 | } | 721 | } |
706 | 722 | ||
@@ -710,90 +726,91 @@ int ath10k_core_start(struct ath10k *ar) | |||
710 | 726 | ||
711 | status = ath10k_wmi_attach(ar); | 727 | status = ath10k_wmi_attach(ar); |
712 | if (status) { | 728 | if (status) { |
713 | ath10k_err("WMI attach failed: %d\n", status); | 729 | ath10k_err(ar, "WMI attach failed: %d\n", status); |
714 | goto err; | 730 | goto err; |
715 | } | 731 | } |
716 | 732 | ||
717 | status = ath10k_htt_init(ar); | 733 | status = ath10k_htt_init(ar); |
718 | if (status) { | 734 | if (status) { |
719 | ath10k_err("failed to init htt: %d\n", status); | 735 | ath10k_err(ar, "failed to init htt: %d\n", status); |
720 | goto err_wmi_detach; | 736 | goto err_wmi_detach; |
721 | } | 737 | } |
722 | 738 | ||
723 | status = ath10k_htt_tx_alloc(&ar->htt); | 739 | status = ath10k_htt_tx_alloc(&ar->htt); |
724 | if (status) { | 740 | if (status) { |
725 | ath10k_err("failed to alloc htt tx: %d\n", status); | 741 | ath10k_err(ar, "failed to alloc htt tx: %d\n", status); |
726 | goto err_wmi_detach; | 742 | goto err_wmi_detach; |
727 | } | 743 | } |
728 | 744 | ||
729 | status = ath10k_htt_rx_alloc(&ar->htt); | 745 | status = ath10k_htt_rx_alloc(&ar->htt); |
730 | if (status) { | 746 | if (status) { |
731 | ath10k_err("failed to alloc htt rx: %d\n", status); | 747 | ath10k_err(ar, "failed to alloc htt rx: %d\n", status); |
732 | goto err_htt_tx_detach; | 748 | goto err_htt_tx_detach; |
733 | } | 749 | } |
734 | 750 | ||
735 | status = ath10k_hif_start(ar); | 751 | status = ath10k_hif_start(ar); |
736 | if (status) { | 752 | if (status) { |
737 | ath10k_err("could not start HIF: %d\n", status); | 753 | ath10k_err(ar, "could not start HIF: %d\n", status); |
738 | goto err_htt_rx_detach; | 754 | goto err_htt_rx_detach; |
739 | } | 755 | } |
740 | 756 | ||
741 | status = ath10k_htc_wait_target(&ar->htc); | 757 | status = ath10k_htc_wait_target(&ar->htc); |
742 | if (status) { | 758 | if (status) { |
743 | ath10k_err("failed to connect to HTC: %d\n", status); | 759 | ath10k_err(ar, "failed to connect to HTC: %d\n", status); |
744 | goto err_hif_stop; | 760 | goto err_hif_stop; |
745 | } | 761 | } |
746 | 762 | ||
747 | status = ath10k_htt_connect(&ar->htt); | 763 | status = ath10k_htt_connect(&ar->htt); |
748 | if (status) { | 764 | if (status) { |
749 | ath10k_err("failed to connect htt (%d)\n", status); | 765 | ath10k_err(ar, "failed to connect htt (%d)\n", status); |
750 | goto err_hif_stop; | 766 | goto err_hif_stop; |
751 | } | 767 | } |
752 | 768 | ||
753 | status = ath10k_wmi_connect(ar); | 769 | status = ath10k_wmi_connect(ar); |
754 | if (status) { | 770 | if (status) { |
755 | ath10k_err("could not connect wmi: %d\n", status); | 771 | ath10k_err(ar, "could not connect wmi: %d\n", status); |
756 | goto err_hif_stop; | 772 | goto err_hif_stop; |
757 | } | 773 | } |
758 | 774 | ||
759 | status = ath10k_htc_start(&ar->htc); | 775 | status = ath10k_htc_start(&ar->htc); |
760 | if (status) { | 776 | if (status) { |
761 | ath10k_err("failed to start htc: %d\n", status); | 777 | ath10k_err(ar, "failed to start htc: %d\n", status); |
762 | goto err_hif_stop; | 778 | goto err_hif_stop; |
763 | } | 779 | } |
764 | 780 | ||
765 | status = ath10k_wmi_wait_for_service_ready(ar); | 781 | status = ath10k_wmi_wait_for_service_ready(ar); |
766 | if (status <= 0) { | 782 | if (status <= 0) { |
767 | ath10k_warn("wmi service ready event not received"); | 783 | ath10k_warn(ar, "wmi service ready event not received"); |
768 | status = -ETIMEDOUT; | 784 | status = -ETIMEDOUT; |
769 | goto err_htc_stop; | 785 | goto err_hif_stop; |
770 | } | 786 | } |
771 | 787 | ||
772 | ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", | 788 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n", |
773 | ar->hw->wiphy->fw_version); | 789 | ar->hw->wiphy->fw_version); |
774 | 790 | ||
775 | status = ath10k_wmi_cmd_init(ar); | 791 | status = ath10k_wmi_cmd_init(ar); |
776 | if (status) { | 792 | if (status) { |
777 | ath10k_err("could not send WMI init command (%d)\n", status); | 793 | ath10k_err(ar, "could not send WMI init command (%d)\n", |
778 | goto err_htc_stop; | 794 | status); |
795 | goto err_hif_stop; | ||
779 | } | 796 | } |
780 | 797 | ||
781 | status = ath10k_wmi_wait_for_unified_ready(ar); | 798 | status = ath10k_wmi_wait_for_unified_ready(ar); |
782 | if (status <= 0) { | 799 | if (status <= 0) { |
783 | ath10k_err("wmi unified ready event not received\n"); | 800 | ath10k_err(ar, "wmi unified ready event not received\n"); |
784 | status = -ETIMEDOUT; | 801 | status = -ETIMEDOUT; |
785 | goto err_htc_stop; | 802 | goto err_hif_stop; |
786 | } | 803 | } |
787 | 804 | ||
788 | status = ath10k_htt_setup(&ar->htt); | 805 | status = ath10k_htt_setup(&ar->htt); |
789 | if (status) { | 806 | if (status) { |
790 | ath10k_err("failed to setup htt: %d\n", status); | 807 | ath10k_err(ar, "failed to setup htt: %d\n", status); |
791 | goto err_htc_stop; | 808 | goto err_hif_stop; |
792 | } | 809 | } |
793 | 810 | ||
794 | status = ath10k_debug_start(ar); | 811 | status = ath10k_debug_start(ar); |
795 | if (status) | 812 | if (status) |
796 | goto err_htc_stop; | 813 | goto err_hif_stop; |
797 | 814 | ||
798 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) | 815 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) |
799 | ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1; | 816 | ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1; |
@@ -802,28 +819,8 @@ int ath10k_core_start(struct ath10k *ar) | |||
802 | 819 | ||
803 | INIT_LIST_HEAD(&ar->arvifs); | 820 | INIT_LIST_HEAD(&ar->arvifs); |
804 | 821 | ||
805 | if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) { | ||
806 | ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", | ||
807 | ar->hw_params.name, | ||
808 | ar->target_version, | ||
809 | ar->chip_id, | ||
810 | ar->hw->wiphy->fw_version, | ||
811 | ar->fw_api, | ||
812 | ar->htt.target_version_major, | ||
813 | ar->htt.target_version_minor); | ||
814 | ath10k_info("debug %d debugfs %d tracing %d dfs %d\n", | ||
815 | config_enabled(CONFIG_ATH10K_DEBUG), | ||
816 | config_enabled(CONFIG_ATH10K_DEBUGFS), | ||
817 | config_enabled(CONFIG_ATH10K_TRACING), | ||
818 | config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)); | ||
819 | } | ||
820 | |||
821 | __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags); | ||
822 | |||
823 | return 0; | 822 | return 0; |
824 | 823 | ||
825 | err_htc_stop: | ||
826 | ath10k_htc_stop(&ar->htc); | ||
827 | err_hif_stop: | 824 | err_hif_stop: |
828 | ath10k_hif_stop(ar); | 825 | ath10k_hif_stop(ar); |
829 | err_htt_rx_detach: | 826 | err_htt_rx_detach: |
@@ -845,14 +842,14 @@ int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt) | |||
845 | 842 | ||
846 | ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt); | 843 | ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt); |
847 | if (ret) { | 844 | if (ret) { |
848 | ath10k_warn("could not suspend target (%d)\n", ret); | 845 | ath10k_warn(ar, "could not suspend target (%d)\n", ret); |
849 | return ret; | 846 | return ret; |
850 | } | 847 | } |
851 | 848 | ||
852 | ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ); | 849 | ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ); |
853 | 850 | ||
854 | if (ret == 0) { | 851 | if (ret == 0) { |
855 | ath10k_warn("suspend timed out - target pause event never came\n"); | 852 | ath10k_warn(ar, "suspend timed out - target pause event never came\n"); |
856 | return -ETIMEDOUT; | 853 | return -ETIMEDOUT; |
857 | } | 854 | } |
858 | 855 | ||
@@ -868,7 +865,6 @@ void ath10k_core_stop(struct ath10k *ar) | |||
868 | ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); | 865 | ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); |
869 | 866 | ||
870 | ath10k_debug_stop(ar); | 867 | ath10k_debug_stop(ar); |
871 | ath10k_htc_stop(&ar->htc); | ||
872 | ath10k_hif_stop(ar); | 868 | ath10k_hif_stop(ar); |
873 | ath10k_htt_tx_free(&ar->htt); | 869 | ath10k_htt_tx_free(&ar->htt); |
874 | ath10k_htt_rx_free(&ar->htt); | 870 | ath10k_htt_rx_free(&ar->htt); |
@@ -887,14 +883,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar) | |||
887 | 883 | ||
888 | ret = ath10k_hif_power_up(ar); | 884 | ret = ath10k_hif_power_up(ar); |
889 | if (ret) { | 885 | if (ret) { |
890 | ath10k_err("could not start pci hif (%d)\n", ret); | 886 | ath10k_err(ar, "could not start pci hif (%d)\n", ret); |
891 | return ret; | 887 | return ret; |
892 | } | 888 | } |
893 | 889 | ||
894 | memset(&target_info, 0, sizeof(target_info)); | 890 | memset(&target_info, 0, sizeof(target_info)); |
895 | ret = ath10k_bmi_get_target_info(ar, &target_info); | 891 | ret = ath10k_bmi_get_target_info(ar, &target_info); |
896 | if (ret) { | 892 | if (ret) { |
897 | ath10k_err("could not get target info (%d)\n", ret); | 893 | ath10k_err(ar, "could not get target info (%d)\n", ret); |
898 | ath10k_hif_power_down(ar); | 894 | ath10k_hif_power_down(ar); |
899 | return ret; | 895 | return ret; |
900 | } | 896 | } |
@@ -904,14 +900,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar) | |||
904 | 900 | ||
905 | ret = ath10k_init_hw_params(ar); | 901 | ret = ath10k_init_hw_params(ar); |
906 | if (ret) { | 902 | if (ret) { |
907 | ath10k_err("could not get hw params (%d)\n", ret); | 903 | ath10k_err(ar, "could not get hw params (%d)\n", ret); |
908 | ath10k_hif_power_down(ar); | 904 | ath10k_hif_power_down(ar); |
909 | return ret; | 905 | return ret; |
910 | } | 906 | } |
911 | 907 | ||
912 | ret = ath10k_core_fetch_firmware_files(ar); | 908 | ret = ath10k_core_fetch_firmware_files(ar); |
913 | if (ret) { | 909 | if (ret) { |
914 | ath10k_err("could not fetch firmware files (%d)\n", ret); | 910 | ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); |
915 | ath10k_hif_power_down(ar); | 911 | ath10k_hif_power_down(ar); |
916 | return ret; | 912 | return ret; |
917 | } | 913 | } |
@@ -920,13 +916,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar) | |||
920 | 916 | ||
921 | ret = ath10k_core_start(ar); | 917 | ret = ath10k_core_start(ar); |
922 | if (ret) { | 918 | if (ret) { |
923 | ath10k_err("could not init core (%d)\n", ret); | 919 | ath10k_err(ar, "could not init core (%d)\n", ret); |
924 | ath10k_core_free_firmware_files(ar); | 920 | ath10k_core_free_firmware_files(ar); |
925 | ath10k_hif_power_down(ar); | 921 | ath10k_hif_power_down(ar); |
926 | mutex_unlock(&ar->conf_mutex); | 922 | mutex_unlock(&ar->conf_mutex); |
927 | return ret; | 923 | return ret; |
928 | } | 924 | } |
929 | 925 | ||
926 | ath10k_print_driver_info(ar); | ||
930 | ath10k_core_stop(ar); | 927 | ath10k_core_stop(ar); |
931 | 928 | ||
932 | mutex_unlock(&ar->conf_mutex); | 929 | mutex_unlock(&ar->conf_mutex); |
@@ -939,7 +936,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) | |||
939 | { | 936 | { |
940 | u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); | 937 | u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); |
941 | 938 | ||
942 | ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", | 939 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", |
943 | ar->chip_id, hw_revision); | 940 | ar->chip_id, hw_revision); |
944 | 941 | ||
945 | /* Check that we are not using hw1.0 (some of them have same pci id | 942 | /* Check that we are not using hw1.0 (some of them have same pci id |
@@ -947,7 +944,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) | |||
947 | * due to missing hw1.0 workarounds. */ | 944 | * due to missing hw1.0 workarounds. */ |
948 | switch (hw_revision) { | 945 | switch (hw_revision) { |
949 | case QCA988X_HW_1_0_CHIP_ID_REV: | 946 | case QCA988X_HW_1_0_CHIP_ID_REV: |
950 | ath10k_err("ERROR: qca988x hw1.0 is not supported\n"); | 947 | ath10k_err(ar, "ERROR: qca988x hw1.0 is not supported\n"); |
951 | return -EOPNOTSUPP; | 948 | return -EOPNOTSUPP; |
952 | 949 | ||
953 | case QCA988X_HW_2_0_CHIP_ID_REV: | 950 | case QCA988X_HW_2_0_CHIP_ID_REV: |
@@ -955,7 +952,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) | |||
955 | return 0; | 952 | return 0; |
956 | 953 | ||
957 | default: | 954 | default: |
958 | ath10k_warn("Warning: hardware revision unknown (0x%x), expect problems\n", | 955 | ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n", |
959 | ar->chip_id); | 956 | ar->chip_id); |
960 | return 0; | 957 | return 0; |
961 | } | 958 | } |
@@ -970,25 +967,33 @@ static void ath10k_core_register_work(struct work_struct *work) | |||
970 | 967 | ||
971 | status = ath10k_core_probe_fw(ar); | 968 | status = ath10k_core_probe_fw(ar); |
972 | if (status) { | 969 | if (status) { |
973 | ath10k_err("could not probe fw (%d)\n", status); | 970 | ath10k_err(ar, "could not probe fw (%d)\n", status); |
974 | goto err; | 971 | goto err; |
975 | } | 972 | } |
976 | 973 | ||
977 | status = ath10k_mac_register(ar); | 974 | status = ath10k_mac_register(ar); |
978 | if (status) { | 975 | if (status) { |
979 | ath10k_err("could not register to mac80211 (%d)\n", status); | 976 | ath10k_err(ar, "could not register to mac80211 (%d)\n", status); |
980 | goto err_release_fw; | 977 | goto err_release_fw; |
981 | } | 978 | } |
982 | 979 | ||
983 | status = ath10k_debug_create(ar); | 980 | status = ath10k_debug_create(ar); |
984 | if (status) { | 981 | if (status) { |
985 | ath10k_err("unable to initialize debugfs\n"); | 982 | ath10k_err(ar, "unable to initialize debugfs\n"); |
986 | goto err_unregister_mac; | 983 | goto err_unregister_mac; |
987 | } | 984 | } |
988 | 985 | ||
986 | status = ath10k_spectral_create(ar); | ||
987 | if (status) { | ||
988 | ath10k_err(ar, "failed to initialize spectral\n"); | ||
989 | goto err_debug_destroy; | ||
990 | } | ||
991 | |||
989 | set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); | 992 | set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); |
990 | return; | 993 | return; |
991 | 994 | ||
995 | err_debug_destroy: | ||
996 | ath10k_debug_destroy(ar); | ||
992 | err_unregister_mac: | 997 | err_unregister_mac: |
993 | ath10k_mac_unregister(ar); | 998 | ath10k_mac_unregister(ar); |
994 | err_release_fw: | 999 | err_release_fw: |
@@ -1008,7 +1013,7 @@ int ath10k_core_register(struct ath10k *ar, u32 chip_id) | |||
1008 | 1013 | ||
1009 | status = ath10k_core_check_chip_id(ar); | 1014 | status = ath10k_core_check_chip_id(ar); |
1010 | if (status) { | 1015 | if (status) { |
1011 | ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); | 1016 | ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id); |
1012 | return status; | 1017 | return status; |
1013 | } | 1018 | } |
1014 | 1019 | ||
@@ -1025,6 +1030,12 @@ void ath10k_core_unregister(struct ath10k *ar) | |||
1025 | if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) | 1030 | if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) |
1026 | return; | 1031 | return; |
1027 | 1032 | ||
1033 | /* Stop spectral before unregistering from mac80211 to remove the | ||
1034 | * relayfs debugfs file cleanly. Otherwise the parent debugfs tree | ||
1035 | * would be already be free'd recursively, leading to a double free. | ||
1036 | */ | ||
1037 | ath10k_spectral_destroy(ar); | ||
1038 | |||
1028 | /* We must unregister from mac80211 before we stop HTC and HIF. | 1039 | /* We must unregister from mac80211 before we stop HTC and HIF. |
1029 | * Otherwise we will fail to submit commands to FW and mac80211 will be | 1040 | * Otherwise we will fail to submit commands to FW and mac80211 will be |
1030 | * unhappy about callback failures. */ | 1041 | * unhappy about callback failures. */ |
@@ -1036,12 +1047,12 @@ void ath10k_core_unregister(struct ath10k *ar) | |||
1036 | } | 1047 | } |
1037 | EXPORT_SYMBOL(ath10k_core_unregister); | 1048 | EXPORT_SYMBOL(ath10k_core_unregister); |
1038 | 1049 | ||
1039 | struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | 1050 | struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, |
1040 | const struct ath10k_hif_ops *hif_ops) | 1051 | const struct ath10k_hif_ops *hif_ops) |
1041 | { | 1052 | { |
1042 | struct ath10k *ar; | 1053 | struct ath10k *ar; |
1043 | 1054 | ||
1044 | ar = ath10k_mac_create(); | 1055 | ar = ath10k_mac_create(priv_size); |
1045 | if (!ar) | 1056 | if (!ar) |
1046 | return NULL; | 1057 | return NULL; |
1047 | 1058 | ||
@@ -1051,7 +1062,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | |||
1051 | ar->p2p = !!ath10k_p2p; | 1062 | ar->p2p = !!ath10k_p2p; |
1052 | ar->dev = dev; | 1063 | ar->dev = dev; |
1053 | 1064 | ||
1054 | ar->hif.priv = hif_priv; | ||
1055 | ar->hif.ops = hif_ops; | 1065 | ar->hif.ops = hif_ops; |
1056 | 1066 | ||
1057 | init_completion(&ar->scan.started); | 1067 | init_completion(&ar->scan.started); |
@@ -1062,7 +1072,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | |||
1062 | init_completion(&ar->install_key_done); | 1072 | init_completion(&ar->install_key_done); |
1063 | init_completion(&ar->vdev_setup_done); | 1073 | init_completion(&ar->vdev_setup_done); |
1064 | 1074 | ||
1065 | setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); | 1075 | INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); |
1066 | 1076 | ||
1067 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); | 1077 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); |
1068 | if (!ar->workqueue) | 1078 | if (!ar->workqueue) |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 83a5fa91531d..4ef476099225 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/if_ether.h> | 22 | #include <linux/if_ether.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/uuid.h> | ||
26 | #include <linux/time.h> | ||
25 | 27 | ||
26 | #include "htt.h" | 28 | #include "htt.h" |
27 | #include "htc.h" | 29 | #include "htc.h" |
@@ -31,6 +33,7 @@ | |||
31 | #include "../ath.h" | 33 | #include "../ath.h" |
32 | #include "../regd.h" | 34 | #include "../regd.h" |
33 | #include "../dfs_pattern_detector.h" | 35 | #include "../dfs_pattern_detector.h" |
36 | #include "spectral.h" | ||
34 | 37 | ||
35 | #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) | 38 | #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) |
36 | #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) | 39 | #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) |
@@ -237,6 +240,7 @@ struct ath10k_vif { | |||
237 | 240 | ||
238 | bool is_started; | 241 | bool is_started; |
239 | bool is_up; | 242 | bool is_up; |
243 | bool spectral_enabled; | ||
240 | u32 aid; | 244 | u32 aid; |
241 | u8 bssid[ETH_ALEN]; | 245 | u8 bssid[ETH_ALEN]; |
242 | 246 | ||
@@ -276,11 +280,20 @@ struct ath10k_vif_iter { | |||
276 | struct ath10k_vif *arvif; | 280 | struct ath10k_vif *arvif; |
277 | }; | 281 | }; |
278 | 282 | ||
283 | /* used for crash-dump storage, protected by data-lock */ | ||
284 | struct ath10k_fw_crash_data { | ||
285 | bool crashed_since_read; | ||
286 | |||
287 | uuid_le uuid; | ||
288 | struct timespec timestamp; | ||
289 | __le32 registers[REG_DUMP_COUNT_QCA988X]; | ||
290 | }; | ||
291 | |||
279 | struct ath10k_debug { | 292 | struct ath10k_debug { |
280 | struct dentry *debugfs_phy; | 293 | struct dentry *debugfs_phy; |
281 | 294 | ||
282 | struct ath10k_target_stats target_stats; | 295 | struct ath10k_target_stats target_stats; |
283 | u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; | 296 | DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_BM_SIZE); |
284 | 297 | ||
285 | struct completion event_stats_compl; | 298 | struct completion event_stats_compl; |
286 | 299 | ||
@@ -293,6 +306,8 @@ struct ath10k_debug { | |||
293 | 306 | ||
294 | u8 htt_max_amsdu; | 307 | u8 htt_max_amsdu; |
295 | u8 htt_max_ampdu; | 308 | u8 htt_max_ampdu; |
309 | |||
310 | struct ath10k_fw_crash_data *fw_crash_data; | ||
296 | }; | 311 | }; |
297 | 312 | ||
298 | enum ath10k_state { | 313 | enum ath10k_state { |
@@ -330,6 +345,11 @@ enum ath10k_fw_features { | |||
330 | /* Firmware does not support P2P */ | 345 | /* Firmware does not support P2P */ |
331 | ATH10K_FW_FEATURE_NO_P2P = 3, | 346 | ATH10K_FW_FEATURE_NO_P2P = 3, |
332 | 347 | ||
348 | /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit | ||
349 | * is required to be set as well. | ||
350 | */ | ||
351 | ATH10K_FW_FEATURE_WMI_10_2 = 4, | ||
352 | |||
333 | /* keep last */ | 353 | /* keep last */ |
334 | ATH10K_FW_FEATURE_COUNT, | 354 | ATH10K_FW_FEATURE_COUNT, |
335 | }; | 355 | }; |
@@ -337,10 +357,32 @@ enum ath10k_fw_features { | |||
337 | enum ath10k_dev_flags { | 357 | enum ath10k_dev_flags { |
338 | /* Indicates that ath10k device is during CAC phase of DFS */ | 358 | /* Indicates that ath10k device is during CAC phase of DFS */ |
339 | ATH10K_CAC_RUNNING, | 359 | ATH10K_CAC_RUNNING, |
340 | ATH10K_FLAG_FIRST_BOOT_DONE, | ||
341 | ATH10K_FLAG_CORE_REGISTERED, | 360 | ATH10K_FLAG_CORE_REGISTERED, |
342 | }; | 361 | }; |
343 | 362 | ||
363 | enum ath10k_scan_state { | ||
364 | ATH10K_SCAN_IDLE, | ||
365 | ATH10K_SCAN_STARTING, | ||
366 | ATH10K_SCAN_RUNNING, | ||
367 | ATH10K_SCAN_ABORTING, | ||
368 | }; | ||
369 | |||
370 | static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state) | ||
371 | { | ||
372 | switch (state) { | ||
373 | case ATH10K_SCAN_IDLE: | ||
374 | return "idle"; | ||
375 | case ATH10K_SCAN_STARTING: | ||
376 | return "starting"; | ||
377 | case ATH10K_SCAN_RUNNING: | ||
378 | return "running"; | ||
379 | case ATH10K_SCAN_ABORTING: | ||
380 | return "aborting"; | ||
381 | } | ||
382 | |||
383 | return "unknown"; | ||
384 | } | ||
385 | |||
344 | struct ath10k { | 386 | struct ath10k { |
345 | struct ath_common ath_common; | 387 | struct ath_common ath_common; |
346 | struct ieee80211_hw *hw; | 388 | struct ieee80211_hw *hw; |
@@ -368,7 +410,6 @@ struct ath10k { | |||
368 | bool p2p; | 410 | bool p2p; |
369 | 411 | ||
370 | struct { | 412 | struct { |
371 | void *priv; | ||
372 | const struct ath10k_hif_ops *ops; | 413 | const struct ath10k_hif_ops *ops; |
373 | } hif; | 414 | } hif; |
374 | 415 | ||
@@ -410,10 +451,9 @@ struct ath10k { | |||
410 | struct completion started; | 451 | struct completion started; |
411 | struct completion completed; | 452 | struct completion completed; |
412 | struct completion on_channel; | 453 | struct completion on_channel; |
413 | struct timer_list timeout; | 454 | struct delayed_work timeout; |
455 | enum ath10k_scan_state state; | ||
414 | bool is_roc; | 456 | bool is_roc; |
415 | bool in_progress; | ||
416 | bool aborting; | ||
417 | int vdev_id; | 457 | int vdev_id; |
418 | int roc_freq; | 458 | int roc_freq; |
419 | } scan; | 459 | } scan; |
@@ -494,9 +534,21 @@ struct ath10k { | |||
494 | #ifdef CONFIG_ATH10K_DEBUGFS | 534 | #ifdef CONFIG_ATH10K_DEBUGFS |
495 | struct ath10k_debug debug; | 535 | struct ath10k_debug debug; |
496 | #endif | 536 | #endif |
537 | |||
538 | struct { | ||
539 | /* relay(fs) channel for spectral scan */ | ||
540 | struct rchan *rfs_chan_spec_scan; | ||
541 | |||
542 | /* spectral_mode and spec_config are protected by conf_mutex */ | ||
543 | enum ath10k_spectral_mode mode; | ||
544 | struct ath10k_spec_scan config; | ||
545 | } spectral; | ||
546 | |||
547 | /* must be last */ | ||
548 | u8 drv_priv[0] __aligned(sizeof(void *)); | ||
497 | }; | 549 | }; |
498 | 550 | ||
499 | struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | 551 | struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, |
500 | const struct ath10k_hif_ops *hif_ops); | 552 | const struct ath10k_hif_ops *hif_ops); |
501 | void ath10k_core_destroy(struct ath10k *ar); | 553 | void ath10k_core_destroy(struct ath10k *ar); |
502 | 554 | ||
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 3030158c478e..f3f0a80f8bab 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -17,6 +17,9 @@ | |||
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/debugfs.h> | 19 | #include <linux/debugfs.h> |
20 | #include <linux/version.h> | ||
21 | #include <linux/vermagic.h> | ||
22 | #include <linux/vmalloc.h> | ||
20 | 23 | ||
21 | #include "core.h" | 24 | #include "core.h" |
22 | #include "debug.h" | 25 | #include "debug.h" |
@@ -24,25 +27,86 @@ | |||
24 | /* ms */ | 27 | /* ms */ |
25 | #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 | 28 | #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 |
26 | 29 | ||
27 | static int ath10k_printk(const char *level, const char *fmt, ...) | 30 | #define ATH10K_FW_CRASH_DUMP_VERSION 1 |
28 | { | ||
29 | struct va_format vaf; | ||
30 | va_list args; | ||
31 | int rtn; | ||
32 | 31 | ||
33 | va_start(args, fmt); | 32 | /** |
33 | * enum ath10k_fw_crash_dump_type - types of data in the dump file | ||
34 | * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format | ||
35 | */ | ||
36 | enum ath10k_fw_crash_dump_type { | ||
37 | ATH10K_FW_CRASH_DUMP_REGISTERS = 0, | ||
34 | 38 | ||
35 | vaf.fmt = fmt; | 39 | ATH10K_FW_CRASH_DUMP_MAX, |
36 | vaf.va = &args; | 40 | }; |
37 | 41 | ||
38 | rtn = printk("%sath10k: %pV", level, &vaf); | 42 | struct ath10k_tlv_dump_data { |
43 | /* see ath10k_fw_crash_dump_type above */ | ||
44 | __le32 type; | ||
39 | 45 | ||
40 | va_end(args); | 46 | /* in bytes */ |
47 | __le32 tlv_len; | ||
41 | 48 | ||
42 | return rtn; | 49 | /* pad to 32-bit boundaries as needed */ |
43 | } | 50 | u8 tlv_data[]; |
51 | } __packed; | ||
52 | |||
53 | struct ath10k_dump_file_data { | ||
54 | /* dump file information */ | ||
55 | |||
56 | /* "ATH10K-FW-DUMP" */ | ||
57 | char df_magic[16]; | ||
58 | |||
59 | __le32 len; | ||
60 | |||
61 | /* file dump version */ | ||
62 | __le32 version; | ||
63 | |||
64 | /* some info we can get from ath10k struct that might help */ | ||
65 | |||
66 | u8 uuid[16]; | ||
67 | |||
68 | __le32 chip_id; | ||
69 | |||
70 | /* 0 for now, in place for later hardware */ | ||
71 | __le32 bus_type; | ||
72 | |||
73 | __le32 target_version; | ||
74 | __le32 fw_version_major; | ||
75 | __le32 fw_version_minor; | ||
76 | __le32 fw_version_release; | ||
77 | __le32 fw_version_build; | ||
78 | __le32 phy_capability; | ||
79 | __le32 hw_min_tx_power; | ||
80 | __le32 hw_max_tx_power; | ||
81 | __le32 ht_cap_info; | ||
82 | __le32 vht_cap_info; | ||
83 | __le32 num_rf_chains; | ||
84 | |||
85 | /* firmware version string */ | ||
86 | char fw_ver[ETHTOOL_FWVERS_LEN]; | ||
87 | |||
88 | /* Kernel related information */ | ||
89 | |||
90 | /* time-of-day stamp */ | ||
91 | __le64 tv_sec; | ||
44 | 92 | ||
45 | int ath10k_info(const char *fmt, ...) | 93 | /* time-of-day stamp, nano-seconds */ |
94 | __le64 tv_nsec; | ||
95 | |||
96 | /* LINUX_VERSION_CODE */ | ||
97 | __le32 kernel_ver_code; | ||
98 | |||
99 | /* VERMAGIC_STRING */ | ||
100 | char kernel_ver[64]; | ||
101 | |||
102 | /* room for growth w/out changing binary format */ | ||
103 | u8 unused[128]; | ||
104 | |||
105 | /* struct ath10k_tlv_dump_data + more */ | ||
106 | u8 data[0]; | ||
107 | } __packed; | ||
108 | |||
109 | int ath10k_info(struct ath10k *ar, const char *fmt, ...) | ||
46 | { | 110 | { |
47 | struct va_format vaf = { | 111 | struct va_format vaf = { |
48 | .fmt = fmt, | 112 | .fmt = fmt, |
@@ -52,7 +116,7 @@ int ath10k_info(const char *fmt, ...) | |||
52 | 116 | ||
53 | va_start(args, fmt); | 117 | va_start(args, fmt); |
54 | vaf.va = &args; | 118 | vaf.va = &args; |
55 | ret = ath10k_printk(KERN_INFO, "%pV", &vaf); | 119 | ret = dev_info(ar->dev, "%pV", &vaf); |
56 | trace_ath10k_log_info(&vaf); | 120 | trace_ath10k_log_info(&vaf); |
57 | va_end(args); | 121 | va_end(args); |
58 | 122 | ||
@@ -60,7 +124,25 @@ int ath10k_info(const char *fmt, ...) | |||
60 | } | 124 | } |
61 | EXPORT_SYMBOL(ath10k_info); | 125 | EXPORT_SYMBOL(ath10k_info); |
62 | 126 | ||
63 | int ath10k_err(const char *fmt, ...) | 127 | void ath10k_print_driver_info(struct ath10k *ar) |
128 | { | ||
129 | ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", | ||
130 | ar->hw_params.name, | ||
131 | ar->target_version, | ||
132 | ar->chip_id, | ||
133 | ar->hw->wiphy->fw_version, | ||
134 | ar->fw_api, | ||
135 | ar->htt.target_version_major, | ||
136 | ar->htt.target_version_minor); | ||
137 | ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d\n", | ||
138 | config_enabled(CONFIG_ATH10K_DEBUG), | ||
139 | config_enabled(CONFIG_ATH10K_DEBUGFS), | ||
140 | config_enabled(CONFIG_ATH10K_TRACING), | ||
141 | config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)); | ||
142 | } | ||
143 | EXPORT_SYMBOL(ath10k_print_driver_info); | ||
144 | |||
145 | int ath10k_err(struct ath10k *ar, const char *fmt, ...) | ||
64 | { | 146 | { |
65 | struct va_format vaf = { | 147 | struct va_format vaf = { |
66 | .fmt = fmt, | 148 | .fmt = fmt, |
@@ -70,7 +152,7 @@ int ath10k_err(const char *fmt, ...) | |||
70 | 152 | ||
71 | va_start(args, fmt); | 153 | va_start(args, fmt); |
72 | vaf.va = &args; | 154 | vaf.va = &args; |
73 | ret = ath10k_printk(KERN_ERR, "%pV", &vaf); | 155 | ret = dev_err(ar->dev, "%pV", &vaf); |
74 | trace_ath10k_log_err(&vaf); | 156 | trace_ath10k_log_err(&vaf); |
75 | va_end(args); | 157 | va_end(args); |
76 | 158 | ||
@@ -78,25 +160,21 @@ int ath10k_err(const char *fmt, ...) | |||
78 | } | 160 | } |
79 | EXPORT_SYMBOL(ath10k_err); | 161 | EXPORT_SYMBOL(ath10k_err); |
80 | 162 | ||
81 | int ath10k_warn(const char *fmt, ...) | 163 | int ath10k_warn(struct ath10k *ar, const char *fmt, ...) |
82 | { | 164 | { |
83 | struct va_format vaf = { | 165 | struct va_format vaf = { |
84 | .fmt = fmt, | 166 | .fmt = fmt, |
85 | }; | 167 | }; |
86 | va_list args; | 168 | va_list args; |
87 | int ret = 0; | ||
88 | 169 | ||
89 | va_start(args, fmt); | 170 | va_start(args, fmt); |
90 | vaf.va = &args; | 171 | vaf.va = &args; |
91 | 172 | dev_warn_ratelimited(ar->dev, "%pV", &vaf); | |
92 | if (net_ratelimit()) | ||
93 | ret = ath10k_printk(KERN_WARNING, "%pV", &vaf); | ||
94 | |||
95 | trace_ath10k_log_warn(&vaf); | 173 | trace_ath10k_log_warn(&vaf); |
96 | 174 | ||
97 | va_end(args); | 175 | va_end(args); |
98 | 176 | ||
99 | return ret; | 177 | return 0; |
100 | } | 178 | } |
101 | EXPORT_SYMBOL(ath10k_warn); | 179 | EXPORT_SYMBOL(ath10k_warn); |
102 | 180 | ||
@@ -115,9 +193,10 @@ static ssize_t ath10k_read_wmi_services(struct file *file, | |||
115 | { | 193 | { |
116 | struct ath10k *ar = file->private_data; | 194 | struct ath10k *ar = file->private_data; |
117 | char *buf; | 195 | char *buf; |
118 | unsigned int len = 0, buf_len = 1500; | 196 | unsigned int len = 0, buf_len = 4096; |
119 | const char *status; | 197 | const char *name; |
120 | ssize_t ret_cnt; | 198 | ssize_t ret_cnt; |
199 | bool enabled; | ||
121 | int i; | 200 | int i; |
122 | 201 | ||
123 | buf = kzalloc(buf_len, GFP_KERNEL); | 202 | buf = kzalloc(buf_len, GFP_KERNEL); |
@@ -129,15 +208,22 @@ static ssize_t ath10k_read_wmi_services(struct file *file, | |||
129 | if (len > buf_len) | 208 | if (len > buf_len) |
130 | len = buf_len; | 209 | len = buf_len; |
131 | 210 | ||
132 | for (i = 0; i < WMI_SERVICE_LAST; i++) { | 211 | for (i = 0; i < WMI_MAX_SERVICE; i++) { |
133 | if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i)) | 212 | enabled = test_bit(i, ar->debug.wmi_service_bitmap); |
134 | status = "enabled"; | 213 | name = wmi_service_name(i); |
135 | else | 214 | |
136 | status = "disabled"; | 215 | if (!name) { |
216 | if (enabled) | ||
217 | len += scnprintf(buf + len, buf_len - len, | ||
218 | "%-40s %s (bit %d)\n", | ||
219 | "unknown", "enabled", i); | ||
220 | |||
221 | continue; | ||
222 | } | ||
137 | 223 | ||
138 | len += scnprintf(buf + len, buf_len - len, | 224 | len += scnprintf(buf + len, buf_len - len, |
139 | "0x%02x - %20s - %s\n", | 225 | "%-40s %s\n", |
140 | i, wmi_service_name(i), status); | 226 | name, enabled ? "enabled" : "-"); |
141 | } | 227 | } |
142 | 228 | ||
143 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); | 229 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
@@ -309,7 +395,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, | |||
309 | 395 | ||
310 | ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); | 396 | ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); |
311 | if (ret) { | 397 | if (ret) { |
312 | ath10k_warn("could not request stats (%d)\n", ret); | 398 | ath10k_warn(ar, "could not request stats (%d)\n", ret); |
313 | goto exit; | 399 | goto exit; |
314 | } | 400 | } |
315 | 401 | ||
@@ -527,11 +613,14 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, | |||
527 | } | 613 | } |
528 | 614 | ||
529 | if (!strcmp(buf, "soft")) { | 615 | if (!strcmp(buf, "soft")) { |
530 | ath10k_info("simulating soft firmware crash\n"); | 616 | ath10k_info(ar, "simulating soft firmware crash\n"); |
531 | ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); | 617 | ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); |
532 | } else if (!strcmp(buf, "hard")) { | 618 | } else if (!strcmp(buf, "hard")) { |
533 | ath10k_info("simulating hard firmware crash\n"); | 619 | ath10k_info(ar, "simulating hard firmware crash\n"); |
534 | ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1, | 620 | /* 0x7fff is vdev id, and it is always out of range for all |
621 | * firmware variants in order to force a firmware crash. | ||
622 | */ | ||
623 | ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, | ||
535 | ar->wmi.vdev_param->rts_threshold, 0); | 624 | ar->wmi.vdev_param->rts_threshold, 0); |
536 | } else { | 625 | } else { |
537 | ret = -EINVAL; | 626 | ret = -EINVAL; |
@@ -539,7 +628,7 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, | |||
539 | } | 628 | } |
540 | 629 | ||
541 | if (ret) { | 630 | if (ret) { |
542 | ath10k_warn("failed to simulate firmware crash: %d\n", ret); | 631 | ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret); |
543 | goto exit; | 632 | goto exit; |
544 | } | 633 | } |
545 | 634 | ||
@@ -577,6 +666,138 @@ static const struct file_operations fops_chip_id = { | |||
577 | .llseek = default_llseek, | 666 | .llseek = default_llseek, |
578 | }; | 667 | }; |
579 | 668 | ||
669 | struct ath10k_fw_crash_data * | ||
670 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | ||
671 | { | ||
672 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
673 | |||
674 | lockdep_assert_held(&ar->data_lock); | ||
675 | |||
676 | crash_data->crashed_since_read = true; | ||
677 | uuid_le_gen(&crash_data->uuid); | ||
678 | getnstimeofday(&crash_data->timestamp); | ||
679 | |||
680 | return crash_data; | ||
681 | } | ||
682 | EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data); | ||
683 | |||
684 | static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) | ||
685 | { | ||
686 | struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; | ||
687 | struct ath10k_dump_file_data *dump_data; | ||
688 | struct ath10k_tlv_dump_data *dump_tlv; | ||
689 | int hdr_len = sizeof(*dump_data); | ||
690 | unsigned int len, sofar = 0; | ||
691 | unsigned char *buf; | ||
692 | |||
693 | len = hdr_len; | ||
694 | len += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
695 | |||
696 | sofar += hdr_len; | ||
697 | |||
698 | /* This is going to get big when we start dumping FW RAM and such, | ||
699 | * so go ahead and use vmalloc. | ||
700 | */ | ||
701 | buf = vzalloc(len); | ||
702 | if (!buf) | ||
703 | return NULL; | ||
704 | |||
705 | spin_lock_bh(&ar->data_lock); | ||
706 | |||
707 | if (!crash_data->crashed_since_read) { | ||
708 | spin_unlock_bh(&ar->data_lock); | ||
709 | vfree(buf); | ||
710 | return NULL; | ||
711 | } | ||
712 | |||
713 | dump_data = (struct ath10k_dump_file_data *)(buf); | ||
714 | strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", | ||
715 | sizeof(dump_data->df_magic)); | ||
716 | dump_data->len = cpu_to_le32(len); | ||
717 | |||
718 | dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); | ||
719 | |||
720 | memcpy(dump_data->uuid, &crash_data->uuid, sizeof(dump_data->uuid)); | ||
721 | dump_data->chip_id = cpu_to_le32(ar->chip_id); | ||
722 | dump_data->bus_type = cpu_to_le32(0); | ||
723 | dump_data->target_version = cpu_to_le32(ar->target_version); | ||
724 | dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); | ||
725 | dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor); | ||
726 | dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release); | ||
727 | dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build); | ||
728 | dump_data->phy_capability = cpu_to_le32(ar->phy_capability); | ||
729 | dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power); | ||
730 | dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power); | ||
731 | dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info); | ||
732 | dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info); | ||
733 | dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); | ||
734 | |||
735 | strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, | ||
736 | sizeof(dump_data->fw_ver)); | ||
737 | |||
738 | dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE); | ||
739 | strlcpy(dump_data->kernel_ver, VERMAGIC_STRING, | ||
740 | sizeof(dump_data->kernel_ver)); | ||
741 | |||
742 | dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); | ||
743 | dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec); | ||
744 | |||
745 | /* Gather crash-dump */ | ||
746 | dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); | ||
747 | dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS); | ||
748 | dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers)); | ||
749 | memcpy(dump_tlv->tlv_data, &crash_data->registers, | ||
750 | sizeof(crash_data->registers)); | ||
751 | sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers); | ||
752 | |||
753 | ar->debug.fw_crash_data->crashed_since_read = false; | ||
754 | |||
755 | spin_unlock_bh(&ar->data_lock); | ||
756 | |||
757 | return dump_data; | ||
758 | } | ||
759 | |||
760 | static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file) | ||
761 | { | ||
762 | struct ath10k *ar = inode->i_private; | ||
763 | struct ath10k_dump_file_data *dump; | ||
764 | |||
765 | dump = ath10k_build_dump_file(ar); | ||
766 | if (!dump) | ||
767 | return -ENODATA; | ||
768 | |||
769 | file->private_data = dump; | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static ssize_t ath10k_fw_crash_dump_read(struct file *file, | ||
775 | char __user *user_buf, | ||
776 | size_t count, loff_t *ppos) | ||
777 | { | ||
778 | struct ath10k_dump_file_data *dump_file = file->private_data; | ||
779 | |||
780 | return simple_read_from_buffer(user_buf, count, ppos, | ||
781 | dump_file, | ||
782 | le32_to_cpu(dump_file->len)); | ||
783 | } | ||
784 | |||
785 | static int ath10k_fw_crash_dump_release(struct inode *inode, | ||
786 | struct file *file) | ||
787 | { | ||
788 | vfree(file->private_data); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static const struct file_operations fops_fw_crash_dump = { | ||
794 | .open = ath10k_fw_crash_dump_open, | ||
795 | .read = ath10k_fw_crash_dump_read, | ||
796 | .release = ath10k_fw_crash_dump_release, | ||
797 | .owner = THIS_MODULE, | ||
798 | .llseek = default_llseek, | ||
799 | }; | ||
800 | |||
580 | static int ath10k_debug_htt_stats_req(struct ath10k *ar) | 801 | static int ath10k_debug_htt_stats_req(struct ath10k *ar) |
581 | { | 802 | { |
582 | u64 cookie; | 803 | u64 cookie; |
@@ -596,7 +817,7 @@ static int ath10k_debug_htt_stats_req(struct ath10k *ar) | |||
596 | ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, | 817 | ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, |
597 | cookie); | 818 | cookie); |
598 | if (ret) { | 819 | if (ret) { |
599 | ath10k_warn("failed to send htt stats request: %d\n", ret); | 820 | ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); |
600 | return ret; | 821 | return ret; |
601 | } | 822 | } |
602 | 823 | ||
@@ -770,7 +991,7 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file, | |||
770 | if (ar->state == ATH10K_STATE_ON) { | 991 | if (ar->state == ATH10K_STATE_ON) { |
771 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); | 992 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); |
772 | if (ret) { | 993 | if (ret) { |
773 | ath10k_warn("dbglog cfg failed from debugfs: %d\n", | 994 | ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n", |
774 | ret); | 995 | ret); |
775 | goto exit; | 996 | goto exit; |
776 | } | 997 | } |
@@ -801,13 +1022,14 @@ int ath10k_debug_start(struct ath10k *ar) | |||
801 | ret = ath10k_debug_htt_stats_req(ar); | 1022 | ret = ath10k_debug_htt_stats_req(ar); |
802 | if (ret) | 1023 | if (ret) |
803 | /* continue normally anyway, this isn't serious */ | 1024 | /* continue normally anyway, this isn't serious */ |
804 | ath10k_warn("failed to start htt stats workqueue: %d\n", ret); | 1025 | ath10k_warn(ar, "failed to start htt stats workqueue: %d\n", |
1026 | ret); | ||
805 | 1027 | ||
806 | if (ar->debug.fw_dbglog_mask) { | 1028 | if (ar->debug.fw_dbglog_mask) { |
807 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); | 1029 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); |
808 | if (ret) | 1030 | if (ret) |
809 | /* not serious */ | 1031 | /* not serious */ |
810 | ath10k_warn("failed to enable dbglog during start: %d", | 1032 | ath10k_warn(ar, "failed to enable dbglog during start: %d", |
811 | ret); | 1033 | ret); |
812 | } | 1034 | } |
813 | 1035 | ||
@@ -910,11 +1132,20 @@ static const struct file_operations fops_dfs_stats = { | |||
910 | 1132 | ||
911 | int ath10k_debug_create(struct ath10k *ar) | 1133 | int ath10k_debug_create(struct ath10k *ar) |
912 | { | 1134 | { |
1135 | int ret; | ||
1136 | |||
1137 | ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); | ||
1138 | if (!ar->debug.fw_crash_data) { | ||
1139 | ret = -ENOMEM; | ||
1140 | goto err; | ||
1141 | } | ||
1142 | |||
913 | ar->debug.debugfs_phy = debugfs_create_dir("ath10k", | 1143 | ar->debug.debugfs_phy = debugfs_create_dir("ath10k", |
914 | ar->hw->wiphy->debugfsdir); | 1144 | ar->hw->wiphy->debugfsdir); |
915 | 1145 | if (!ar->debug.debugfs_phy) { | |
916 | if (!ar->debug.debugfs_phy) | 1146 | ret = -ENOMEM; |
917 | return -ENOMEM; | 1147 | goto err_free_fw_crash_data; |
1148 | } | ||
918 | 1149 | ||
919 | INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, | 1150 | INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, |
920 | ath10k_debug_htt_stats_dwork); | 1151 | ath10k_debug_htt_stats_dwork); |
@@ -930,6 +1161,9 @@ int ath10k_debug_create(struct ath10k *ar) | |||
930 | debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, | 1161 | debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, |
931 | ar, &fops_simulate_fw_crash); | 1162 | ar, &fops_simulate_fw_crash); |
932 | 1163 | ||
1164 | debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, | ||
1165 | ar, &fops_fw_crash_dump); | ||
1166 | |||
933 | debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, | 1167 | debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, |
934 | ar, &fops_chip_id); | 1168 | ar, &fops_chip_id); |
935 | 1169 | ||
@@ -958,17 +1192,25 @@ int ath10k_debug_create(struct ath10k *ar) | |||
958 | } | 1192 | } |
959 | 1193 | ||
960 | return 0; | 1194 | return 0; |
1195 | |||
1196 | err_free_fw_crash_data: | ||
1197 | vfree(ar->debug.fw_crash_data); | ||
1198 | |||
1199 | err: | ||
1200 | return ret; | ||
961 | } | 1201 | } |
962 | 1202 | ||
963 | void ath10k_debug_destroy(struct ath10k *ar) | 1203 | void ath10k_debug_destroy(struct ath10k *ar) |
964 | { | 1204 | { |
1205 | vfree(ar->debug.fw_crash_data); | ||
965 | cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); | 1206 | cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); |
966 | } | 1207 | } |
967 | 1208 | ||
968 | #endif /* CONFIG_ATH10K_DEBUGFS */ | 1209 | #endif /* CONFIG_ATH10K_DEBUGFS */ |
969 | 1210 | ||
970 | #ifdef CONFIG_ATH10K_DEBUG | 1211 | #ifdef CONFIG_ATH10K_DEBUG |
971 | void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...) | 1212 | void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, |
1213 | const char *fmt, ...) | ||
972 | { | 1214 | { |
973 | struct va_format vaf; | 1215 | struct va_format vaf; |
974 | va_list args; | 1216 | va_list args; |
@@ -979,7 +1221,7 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...) | |||
979 | vaf.va = &args; | 1221 | vaf.va = &args; |
980 | 1222 | ||
981 | if (ath10k_debug_mask & mask) | 1223 | if (ath10k_debug_mask & mask) |
982 | ath10k_printk(KERN_DEBUG, "%pV", &vaf); | 1224 | dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); |
983 | 1225 | ||
984 | trace_ath10k_log_dbg(mask, &vaf); | 1226 | trace_ath10k_log_dbg(mask, &vaf); |
985 | 1227 | ||
@@ -987,13 +1229,14 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...) | |||
987 | } | 1229 | } |
988 | EXPORT_SYMBOL(ath10k_dbg); | 1230 | EXPORT_SYMBOL(ath10k_dbg); |
989 | 1231 | ||
990 | void ath10k_dbg_dump(enum ath10k_debug_mask mask, | 1232 | void ath10k_dbg_dump(struct ath10k *ar, |
1233 | enum ath10k_debug_mask mask, | ||
991 | const char *msg, const char *prefix, | 1234 | const char *msg, const char *prefix, |
992 | const void *buf, size_t len) | 1235 | const void *buf, size_t len) |
993 | { | 1236 | { |
994 | if (ath10k_debug_mask & mask) { | 1237 | if (ath10k_debug_mask & mask) { |
995 | if (msg) | 1238 | if (msg) |
996 | ath10k_dbg(mask, "%s\n", msg); | 1239 | ath10k_dbg(ar, mask, "%s\n", msg); |
997 | 1240 | ||
998 | print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); | 1241 | print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); |
999 | } | 1242 | } |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index a5824990bd2a..56746539bea2 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -39,9 +39,10 @@ enum ath10k_debug_mask { | |||
39 | 39 | ||
40 | extern unsigned int ath10k_debug_mask; | 40 | extern unsigned int ath10k_debug_mask; |
41 | 41 | ||
42 | __printf(1, 2) int ath10k_info(const char *fmt, ...); | 42 | __printf(2, 3) int ath10k_info(struct ath10k *ar, const char *fmt, ...); |
43 | __printf(1, 2) int ath10k_err(const char *fmt, ...); | 43 | __printf(2, 3) int ath10k_err(struct ath10k *ar, const char *fmt, ...); |
44 | __printf(1, 2) int ath10k_warn(const char *fmt, ...); | 44 | __printf(2, 3) int ath10k_warn(struct ath10k *ar, const char *fmt, ...); |
45 | void ath10k_print_driver_info(struct ath10k *ar); | ||
45 | 46 | ||
46 | #ifdef CONFIG_ATH10K_DEBUGFS | 47 | #ifdef CONFIG_ATH10K_DEBUGFS |
47 | int ath10k_debug_start(struct ath10k *ar); | 48 | int ath10k_debug_start(struct ath10k *ar); |
@@ -53,6 +54,10 @@ void ath10k_debug_read_service_map(struct ath10k *ar, | |||
53 | size_t map_size); | 54 | size_t map_size); |
54 | void ath10k_debug_read_target_stats(struct ath10k *ar, | 55 | void ath10k_debug_read_target_stats(struct ath10k *ar, |
55 | struct wmi_stats_event *ev); | 56 | struct wmi_stats_event *ev); |
57 | struct ath10k_fw_crash_data * | ||
58 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); | ||
59 | |||
60 | void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); | ||
56 | 61 | ||
57 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) | 62 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) |
58 | 63 | ||
@@ -86,25 +91,40 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar, | |||
86 | { | 91 | { |
87 | } | 92 | } |
88 | 93 | ||
94 | static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, | ||
95 | int len) | ||
96 | { | ||
97 | } | ||
98 | |||
99 | static inline struct ath10k_fw_crash_data * | ||
100 | ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | ||
101 | { | ||
102 | return NULL; | ||
103 | } | ||
104 | |||
89 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) | 105 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) |
90 | 106 | ||
91 | #endif /* CONFIG_ATH10K_DEBUGFS */ | 107 | #endif /* CONFIG_ATH10K_DEBUGFS */ |
92 | 108 | ||
93 | #ifdef CONFIG_ATH10K_DEBUG | 109 | #ifdef CONFIG_ATH10K_DEBUG |
94 | __printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, | 110 | __printf(3, 4) void ath10k_dbg(struct ath10k *ar, |
111 | enum ath10k_debug_mask mask, | ||
95 | const char *fmt, ...); | 112 | const char *fmt, ...); |
96 | void ath10k_dbg_dump(enum ath10k_debug_mask mask, | 113 | void ath10k_dbg_dump(struct ath10k *ar, |
114 | enum ath10k_debug_mask mask, | ||
97 | const char *msg, const char *prefix, | 115 | const char *msg, const char *prefix, |
98 | const void *buf, size_t len); | 116 | const void *buf, size_t len); |
99 | #else /* CONFIG_ATH10K_DEBUG */ | 117 | #else /* CONFIG_ATH10K_DEBUG */ |
100 | 118 | ||
101 | static inline int ath10k_dbg(enum ath10k_debug_mask dbg_mask, | 119 | static inline int ath10k_dbg(struct ath10k *ar, |
120 | enum ath10k_debug_mask dbg_mask, | ||
102 | const char *fmt, ...) | 121 | const char *fmt, ...) |
103 | { | 122 | { |
104 | return 0; | 123 | return 0; |
105 | } | 124 | } |
106 | 125 | ||
107 | static inline void ath10k_dbg_dump(enum ath10k_debug_mask mask, | 126 | static inline void ath10k_dbg_dump(struct ath10k *ar, |
127 | enum ath10k_debug_mask mask, | ||
108 | const char *msg, const char *prefix, | 128 | const char *msg, const char *prefix, |
109 | const void *buf, size_t len) | 129 | const void *buf, size_t len) |
110 | { | 130 | { |
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index 5fdc40d3b378..fd9a251f0659 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c | |||
@@ -46,7 +46,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar) | |||
46 | 46 | ||
47 | skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); | 47 | skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); |
48 | if (!skb) { | 48 | if (!skb) { |
49 | ath10k_warn("Unable to allocate ctrl skb\n"); | 49 | ath10k_warn(ar, "Unable to allocate ctrl skb\n"); |
50 | return NULL; | 50 | return NULL; |
51 | } | 51 | } |
52 | 52 | ||
@@ -56,7 +56,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar) | |||
56 | skb_cb = ATH10K_SKB_CB(skb); | 56 | skb_cb = ATH10K_SKB_CB(skb); |
57 | memset(skb_cb, 0, sizeof(*skb_cb)); | 57 | memset(skb_cb, 0, sizeof(*skb_cb)); |
58 | 58 | ||
59 | ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); | 59 | ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); |
60 | return skb; | 60 | return skb; |
61 | } | 61 | } |
62 | 62 | ||
@@ -72,13 +72,15 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc, | |||
72 | static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep, | 72 | static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep, |
73 | struct sk_buff *skb) | 73 | struct sk_buff *skb) |
74 | { | 74 | { |
75 | ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, | 75 | struct ath10k *ar = ep->htc->ar; |
76 | |||
77 | ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, | ||
76 | ep->eid, skb); | 78 | ep->eid, skb); |
77 | 79 | ||
78 | ath10k_htc_restore_tx_skb(ep->htc, skb); | 80 | ath10k_htc_restore_tx_skb(ep->htc, skb); |
79 | 81 | ||
80 | if (!ep->ep_ops.ep_tx_complete) { | 82 | if (!ep->ep_ops.ep_tx_complete) { |
81 | ath10k_warn("no tx handler for eid %d\n", ep->eid); | 83 | ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid); |
82 | dev_kfree_skb_any(skb); | 84 | dev_kfree_skb_any(skb); |
83 | return; | 85 | return; |
84 | } | 86 | } |
@@ -89,12 +91,14 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep, | |||
89 | /* assumes tx_lock is held */ | 91 | /* assumes tx_lock is held */ |
90 | static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep) | 92 | static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep) |
91 | { | 93 | { |
94 | struct ath10k *ar = ep->htc->ar; | ||
95 | |||
92 | if (!ep->tx_credit_flow_enabled) | 96 | if (!ep->tx_credit_flow_enabled) |
93 | return false; | 97 | return false; |
94 | if (ep->tx_credits >= ep->tx_credits_per_max_message) | 98 | if (ep->tx_credits >= ep->tx_credits_per_max_message) |
95 | return false; | 99 | return false; |
96 | 100 | ||
97 | ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n", | 101 | ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n", |
98 | ep->eid); | 102 | ep->eid); |
99 | return true; | 103 | return true; |
100 | } | 104 | } |
@@ -123,6 +127,7 @@ int ath10k_htc_send(struct ath10k_htc *htc, | |||
123 | enum ath10k_htc_ep_id eid, | 127 | enum ath10k_htc_ep_id eid, |
124 | struct sk_buff *skb) | 128 | struct sk_buff *skb) |
125 | { | 129 | { |
130 | struct ath10k *ar = htc->ar; | ||
126 | struct ath10k_htc_ep *ep = &htc->endpoint[eid]; | 131 | struct ath10k_htc_ep *ep = &htc->endpoint[eid]; |
127 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); | 132 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); |
128 | struct ath10k_hif_sg_item sg_item; | 133 | struct ath10k_hif_sg_item sg_item; |
@@ -134,18 +139,10 @@ int ath10k_htc_send(struct ath10k_htc *htc, | |||
134 | return -ECOMM; | 139 | return -ECOMM; |
135 | 140 | ||
136 | if (eid >= ATH10K_HTC_EP_COUNT) { | 141 | if (eid >= ATH10K_HTC_EP_COUNT) { |
137 | ath10k_warn("Invalid endpoint id: %d\n", eid); | 142 | ath10k_warn(ar, "Invalid endpoint id: %d\n", eid); |
138 | return -ENOENT; | 143 | return -ENOENT; |
139 | } | 144 | } |
140 | 145 | ||
141 | /* FIXME: This looks ugly, can we fix it? */ | ||
142 | spin_lock_bh(&htc->tx_lock); | ||
143 | if (htc->stopped) { | ||
144 | spin_unlock_bh(&htc->tx_lock); | ||
145 | return -ESHUTDOWN; | ||
146 | } | ||
147 | spin_unlock_bh(&htc->tx_lock); | ||
148 | |||
149 | skb_push(skb, sizeof(struct ath10k_htc_hdr)); | 146 | skb_push(skb, sizeof(struct ath10k_htc_hdr)); |
150 | 147 | ||
151 | if (ep->tx_credit_flow_enabled) { | 148 | if (ep->tx_credit_flow_enabled) { |
@@ -157,7 +154,7 @@ int ath10k_htc_send(struct ath10k_htc *htc, | |||
157 | goto err_pull; | 154 | goto err_pull; |
158 | } | 155 | } |
159 | ep->tx_credits -= credits; | 156 | ep->tx_credits -= credits; |
160 | ath10k_dbg(ATH10K_DBG_HTC, | 157 | ath10k_dbg(ar, ATH10K_DBG_HTC, |
161 | "htc ep %d consumed %d credits (total %d)\n", | 158 | "htc ep %d consumed %d credits (total %d)\n", |
162 | eid, credits, ep->tx_credits); | 159 | eid, credits, ep->tx_credits); |
163 | spin_unlock_bh(&htc->tx_lock); | 160 | spin_unlock_bh(&htc->tx_lock); |
@@ -188,7 +185,7 @@ err_credits: | |||
188 | if (ep->tx_credit_flow_enabled) { | 185 | if (ep->tx_credit_flow_enabled) { |
189 | spin_lock_bh(&htc->tx_lock); | 186 | spin_lock_bh(&htc->tx_lock); |
190 | ep->tx_credits += credits; | 187 | ep->tx_credits += credits; |
191 | ath10k_dbg(ATH10K_DBG_HTC, | 188 | ath10k_dbg(ar, ATH10K_DBG_HTC, |
192 | "htc ep %d reverted %d credits back (total %d)\n", | 189 | "htc ep %d reverted %d credits back (total %d)\n", |
193 | eid, credits, ep->tx_credits); | 190 | eid, credits, ep->tx_credits); |
194 | spin_unlock_bh(&htc->tx_lock); | 191 | spin_unlock_bh(&htc->tx_lock); |
@@ -227,11 +224,12 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc, | |||
227 | int len, | 224 | int len, |
228 | enum ath10k_htc_ep_id eid) | 225 | enum ath10k_htc_ep_id eid) |
229 | { | 226 | { |
227 | struct ath10k *ar = htc->ar; | ||
230 | struct ath10k_htc_ep *ep; | 228 | struct ath10k_htc_ep *ep; |
231 | int i, n_reports; | 229 | int i, n_reports; |
232 | 230 | ||
233 | if (len % sizeof(*report)) | 231 | if (len % sizeof(*report)) |
234 | ath10k_warn("Uneven credit report len %d", len); | 232 | ath10k_warn(ar, "Uneven credit report len %d", len); |
235 | 233 | ||
236 | n_reports = len / sizeof(*report); | 234 | n_reports = len / sizeof(*report); |
237 | 235 | ||
@@ -243,7 +241,7 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc, | |||
243 | ep = &htc->endpoint[report->eid]; | 241 | ep = &htc->endpoint[report->eid]; |
244 | ep->tx_credits += report->credits; | 242 | ep->tx_credits += report->credits; |
245 | 243 | ||
246 | ath10k_dbg(ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n", | 244 | ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n", |
247 | report->eid, report->credits, ep->tx_credits); | 245 | report->eid, report->credits, ep->tx_credits); |
248 | 246 | ||
249 | if (ep->ep_ops.ep_tx_credits) { | 247 | if (ep->ep_ops.ep_tx_credits) { |
@@ -260,6 +258,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc, | |||
260 | int length, | 258 | int length, |
261 | enum ath10k_htc_ep_id src_eid) | 259 | enum ath10k_htc_ep_id src_eid) |
262 | { | 260 | { |
261 | struct ath10k *ar = htc->ar; | ||
263 | int status = 0; | 262 | int status = 0; |
264 | struct ath10k_htc_record *record; | 263 | struct ath10k_htc_record *record; |
265 | u8 *orig_buffer; | 264 | u8 *orig_buffer; |
@@ -279,7 +278,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc, | |||
279 | 278 | ||
280 | if (record->hdr.len > length) { | 279 | if (record->hdr.len > length) { |
281 | /* no room left in buffer for record */ | 280 | /* no room left in buffer for record */ |
282 | ath10k_warn("Invalid record length: %d\n", | 281 | ath10k_warn(ar, "Invalid record length: %d\n", |
283 | record->hdr.len); | 282 | record->hdr.len); |
284 | status = -EINVAL; | 283 | status = -EINVAL; |
285 | break; | 284 | break; |
@@ -289,7 +288,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc, | |||
289 | case ATH10K_HTC_RECORD_CREDITS: | 288 | case ATH10K_HTC_RECORD_CREDITS: |
290 | len = sizeof(struct ath10k_htc_credit_report); | 289 | len = sizeof(struct ath10k_htc_credit_report); |
291 | if (record->hdr.len < len) { | 290 | if (record->hdr.len < len) { |
292 | ath10k_warn("Credit report too long\n"); | 291 | ath10k_warn(ar, "Credit report too long\n"); |
293 | status = -EINVAL; | 292 | status = -EINVAL; |
294 | break; | 293 | break; |
295 | } | 294 | } |
@@ -299,7 +298,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc, | |||
299 | src_eid); | 298 | src_eid); |
300 | break; | 299 | break; |
301 | default: | 300 | default: |
302 | ath10k_warn("Unhandled record: id:%d length:%d\n", | 301 | ath10k_warn(ar, "Unhandled record: id:%d length:%d\n", |
303 | record->hdr.id, record->hdr.len); | 302 | record->hdr.id, record->hdr.len); |
304 | break; | 303 | break; |
305 | } | 304 | } |
@@ -313,7 +312,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc, | |||
313 | } | 312 | } |
314 | 313 | ||
315 | if (status) | 314 | if (status) |
316 | ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "", | 315 | ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "", |
317 | orig_buffer, orig_length); | 316 | orig_buffer, orig_length); |
318 | 317 | ||
319 | return status; | 318 | return status; |
@@ -339,8 +338,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, | |||
339 | eid = hdr->eid; | 338 | eid = hdr->eid; |
340 | 339 | ||
341 | if (eid >= ATH10K_HTC_EP_COUNT) { | 340 | if (eid >= ATH10K_HTC_EP_COUNT) { |
342 | ath10k_warn("HTC Rx: invalid eid %d\n", eid); | 341 | ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid); |
343 | ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "", | 342 | ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "", |
344 | hdr, sizeof(*hdr)); | 343 | hdr, sizeof(*hdr)); |
345 | status = -EINVAL; | 344 | status = -EINVAL; |
346 | goto out; | 345 | goto out; |
@@ -360,19 +359,19 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, | |||
360 | payload_len = __le16_to_cpu(hdr->len); | 359 | payload_len = __le16_to_cpu(hdr->len); |
361 | 360 | ||
362 | if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) { | 361 | if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) { |
363 | ath10k_warn("HTC rx frame too long, len: %zu\n", | 362 | ath10k_warn(ar, "HTC rx frame too long, len: %zu\n", |
364 | payload_len + sizeof(*hdr)); | 363 | payload_len + sizeof(*hdr)); |
365 | ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "", | 364 | ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "", |
366 | hdr, sizeof(*hdr)); | 365 | hdr, sizeof(*hdr)); |
367 | status = -EINVAL; | 366 | status = -EINVAL; |
368 | goto out; | 367 | goto out; |
369 | } | 368 | } |
370 | 369 | ||
371 | if (skb->len < payload_len) { | 370 | if (skb->len < payload_len) { |
372 | ath10k_dbg(ATH10K_DBG_HTC, | 371 | ath10k_dbg(ar, ATH10K_DBG_HTC, |
373 | "HTC Rx: insufficient length, got %d, expected %d\n", | 372 | "HTC Rx: insufficient length, got %d, expected %d\n", |
374 | skb->len, payload_len); | 373 | skb->len, payload_len); |
375 | ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", | 374 | ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", |
376 | "", hdr, sizeof(*hdr)); | 375 | "", hdr, sizeof(*hdr)); |
377 | status = -EINVAL; | 376 | status = -EINVAL; |
378 | goto out; | 377 | goto out; |
@@ -388,7 +387,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, | |||
388 | 387 | ||
389 | if ((trailer_len < min_len) || | 388 | if ((trailer_len < min_len) || |
390 | (trailer_len > payload_len)) { | 389 | (trailer_len > payload_len)) { |
391 | ath10k_warn("Invalid trailer length: %d\n", | 390 | ath10k_warn(ar, "Invalid trailer length: %d\n", |
392 | trailer_len); | 391 | trailer_len); |
393 | status = -EPROTO; | 392 | status = -EPROTO; |
394 | goto out; | 393 | goto out; |
@@ -421,7 +420,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, | |||
421 | * this is a fatal error, target should not be | 420 | * this is a fatal error, target should not be |
422 | * sending unsolicited messages on the ep 0 | 421 | * sending unsolicited messages on the ep 0 |
423 | */ | 422 | */ |
424 | ath10k_warn("HTC rx ctrl still processing\n"); | 423 | ath10k_warn(ar, "HTC rx ctrl still processing\n"); |
425 | status = -EINVAL; | 424 | status = -EINVAL; |
426 | complete(&htc->ctl_resp); | 425 | complete(&htc->ctl_resp); |
427 | goto out; | 426 | goto out; |
@@ -442,7 +441,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, | |||
442 | goto out; | 441 | goto out; |
443 | } | 442 | } |
444 | 443 | ||
445 | ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", | 444 | ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", |
446 | eid, skb); | 445 | eid, skb); |
447 | ep->ep_ops.ep_rx_complete(ar, skb); | 446 | ep->ep_ops.ep_rx_complete(ar, skb); |
448 | 447 | ||
@@ -459,7 +458,7 @@ static void ath10k_htc_control_rx_complete(struct ath10k *ar, | |||
459 | { | 458 | { |
460 | /* This is unexpected. FW is not supposed to send regular rx on this | 459 | /* This is unexpected. FW is not supposed to send regular rx on this |
461 | * endpoint. */ | 460 | * endpoint. */ |
462 | ath10k_warn("unexpected htc rx\n"); | 461 | ath10k_warn(ar, "unexpected htc rx\n"); |
463 | kfree_skb(skb); | 462 | kfree_skb(skb); |
464 | } | 463 | } |
465 | 464 | ||
@@ -546,6 +545,7 @@ static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc, | |||
546 | 545 | ||
547 | int ath10k_htc_wait_target(struct ath10k_htc *htc) | 546 | int ath10k_htc_wait_target(struct ath10k_htc *htc) |
548 | { | 547 | { |
548 | struct ath10k *ar = htc->ar; | ||
549 | int i, status = 0; | 549 | int i, status = 0; |
550 | struct ath10k_htc_svc_conn_req conn_req; | 550 | struct ath10k_htc_svc_conn_req conn_req; |
551 | struct ath10k_htc_svc_conn_resp conn_resp; | 551 | struct ath10k_htc_svc_conn_resp conn_resp; |
@@ -563,7 +563,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) | |||
563 | * iomap writes unmasking PCI CE irqs aren't propagated | 563 | * iomap writes unmasking PCI CE irqs aren't propagated |
564 | * properly in KVM PCI-passthrough sometimes. | 564 | * properly in KVM PCI-passthrough sometimes. |
565 | */ | 565 | */ |
566 | ath10k_warn("failed to receive control response completion, polling..\n"); | 566 | ath10k_warn(ar, "failed to receive control response completion, polling..\n"); |
567 | 567 | ||
568 | for (i = 0; i < CE_COUNT; i++) | 568 | for (i = 0; i < CE_COUNT; i++) |
569 | ath10k_hif_send_complete_check(htc->ar, i, 1); | 569 | ath10k_hif_send_complete_check(htc->ar, i, 1); |
@@ -576,12 +576,12 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | if (status < 0) { | 578 | if (status < 0) { |
579 | ath10k_err("ctl_resp never came in (%d)\n", status); | 579 | ath10k_err(ar, "ctl_resp never came in (%d)\n", status); |
580 | return status; | 580 | return status; |
581 | } | 581 | } |
582 | 582 | ||
583 | if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { | 583 | if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { |
584 | ath10k_err("Invalid HTC ready msg len:%d\n", | 584 | ath10k_err(ar, "Invalid HTC ready msg len:%d\n", |
585 | htc->control_resp_len); | 585 | htc->control_resp_len); |
586 | return -ECOMM; | 586 | return -ECOMM; |
587 | } | 587 | } |
@@ -592,21 +592,21 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) | |||
592 | credit_size = __le16_to_cpu(msg->ready.credit_size); | 592 | credit_size = __le16_to_cpu(msg->ready.credit_size); |
593 | 593 | ||
594 | if (message_id != ATH10K_HTC_MSG_READY_ID) { | 594 | if (message_id != ATH10K_HTC_MSG_READY_ID) { |
595 | ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id); | 595 | ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id); |
596 | return -ECOMM; | 596 | return -ECOMM; |
597 | } | 597 | } |
598 | 598 | ||
599 | htc->total_transmit_credits = credit_count; | 599 | htc->total_transmit_credits = credit_count; |
600 | htc->target_credit_size = credit_size; | 600 | htc->target_credit_size = credit_size; |
601 | 601 | ||
602 | ath10k_dbg(ATH10K_DBG_HTC, | 602 | ath10k_dbg(ar, ATH10K_DBG_HTC, |
603 | "Target ready! transmit resources: %d size:%d\n", | 603 | "Target ready! transmit resources: %d size:%d\n", |
604 | htc->total_transmit_credits, | 604 | htc->total_transmit_credits, |
605 | htc->target_credit_size); | 605 | htc->target_credit_size); |
606 | 606 | ||
607 | if ((htc->total_transmit_credits == 0) || | 607 | if ((htc->total_transmit_credits == 0) || |
608 | (htc->target_credit_size == 0)) { | 608 | (htc->target_credit_size == 0)) { |
609 | ath10k_err("Invalid credit size received\n"); | 609 | ath10k_err(ar, "Invalid credit size received\n"); |
610 | return -ECOMM; | 610 | return -ECOMM; |
611 | } | 611 | } |
612 | 612 | ||
@@ -623,7 +623,8 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) | |||
623 | /* connect fake service */ | 623 | /* connect fake service */ |
624 | status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); | 624 | status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); |
625 | if (status) { | 625 | if (status) { |
626 | ath10k_err("could not connect to htc service (%d)\n", status); | 626 | ath10k_err(ar, "could not connect to htc service (%d)\n", |
627 | status); | ||
627 | return status; | 628 | return status; |
628 | } | 629 | } |
629 | 630 | ||
@@ -634,6 +635,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
634 | struct ath10k_htc_svc_conn_req *conn_req, | 635 | struct ath10k_htc_svc_conn_req *conn_req, |
635 | struct ath10k_htc_svc_conn_resp *conn_resp) | 636 | struct ath10k_htc_svc_conn_resp *conn_resp) |
636 | { | 637 | { |
638 | struct ath10k *ar = htc->ar; | ||
637 | struct ath10k_htc_msg *msg; | 639 | struct ath10k_htc_msg *msg; |
638 | struct ath10k_htc_conn_svc *req_msg; | 640 | struct ath10k_htc_conn_svc *req_msg; |
639 | struct ath10k_htc_conn_svc_response resp_msg_dummy; | 641 | struct ath10k_htc_conn_svc_response resp_msg_dummy; |
@@ -659,13 +661,13 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
659 | tx_alloc = ath10k_htc_get_credit_allocation(htc, | 661 | tx_alloc = ath10k_htc_get_credit_allocation(htc, |
660 | conn_req->service_id); | 662 | conn_req->service_id); |
661 | if (!tx_alloc) | 663 | if (!tx_alloc) |
662 | ath10k_dbg(ATH10K_DBG_BOOT, | 664 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
663 | "boot htc service %s does not allocate target credits\n", | 665 | "boot htc service %s does not allocate target credits\n", |
664 | htc_service_name(conn_req->service_id)); | 666 | htc_service_name(conn_req->service_id)); |
665 | 667 | ||
666 | skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); | 668 | skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); |
667 | if (!skb) { | 669 | if (!skb) { |
668 | ath10k_err("Failed to allocate HTC packet\n"); | 670 | ath10k_err(ar, "Failed to allocate HTC packet\n"); |
669 | return -ENOMEM; | 671 | return -ENOMEM; |
670 | } | 672 | } |
671 | 673 | ||
@@ -703,7 +705,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
703 | if (status <= 0) { | 705 | if (status <= 0) { |
704 | if (status == 0) | 706 | if (status == 0) |
705 | status = -ETIMEDOUT; | 707 | status = -ETIMEDOUT; |
706 | ath10k_err("Service connect timeout: %d\n", status); | 708 | ath10k_err(ar, "Service connect timeout: %d\n", status); |
707 | return status; | 709 | return status; |
708 | } | 710 | } |
709 | 711 | ||
@@ -716,11 +718,11 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
716 | if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) || | 718 | if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) || |
717 | (htc->control_resp_len < sizeof(msg->hdr) + | 719 | (htc->control_resp_len < sizeof(msg->hdr) + |
718 | sizeof(msg->connect_service_response))) { | 720 | sizeof(msg->connect_service_response))) { |
719 | ath10k_err("Invalid resp message ID 0x%x", message_id); | 721 | ath10k_err(ar, "Invalid resp message ID 0x%x", message_id); |
720 | return -EPROTO; | 722 | return -EPROTO; |
721 | } | 723 | } |
722 | 724 | ||
723 | ath10k_dbg(ATH10K_DBG_HTC, | 725 | ath10k_dbg(ar, ATH10K_DBG_HTC, |
724 | "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n", | 726 | "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n", |
725 | htc_service_name(service_id), | 727 | htc_service_name(service_id), |
726 | resp_msg->status, resp_msg->eid); | 728 | resp_msg->status, resp_msg->eid); |
@@ -729,7 +731,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
729 | 731 | ||
730 | /* check response status */ | 732 | /* check response status */ |
731 | if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) { | 733 | if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) { |
732 | ath10k_err("HTC Service %s connect request failed: 0x%x)\n", | 734 | ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n", |
733 | htc_service_name(service_id), | 735 | htc_service_name(service_id), |
734 | resp_msg->status); | 736 | resp_msg->status); |
735 | return -EPROTO; | 737 | return -EPROTO; |
@@ -780,18 +782,18 @@ setup: | |||
780 | if (status) | 782 | if (status) |
781 | return status; | 783 | return status; |
782 | 784 | ||
783 | ath10k_dbg(ATH10K_DBG_BOOT, | 785 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
784 | "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n", | 786 | "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n", |
785 | htc_service_name(ep->service_id), ep->ul_pipe_id, | 787 | htc_service_name(ep->service_id), ep->ul_pipe_id, |
786 | ep->dl_pipe_id, ep->eid); | 788 | ep->dl_pipe_id, ep->eid); |
787 | 789 | ||
788 | ath10k_dbg(ATH10K_DBG_BOOT, | 790 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
789 | "boot htc ep %d ul polled %d dl polled %d\n", | 791 | "boot htc ep %d ul polled %d dl polled %d\n", |
790 | ep->eid, ep->ul_is_polled, ep->dl_is_polled); | 792 | ep->eid, ep->ul_is_polled, ep->dl_is_polled); |
791 | 793 | ||
792 | if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { | 794 | if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { |
793 | ep->tx_credit_flow_enabled = false; | 795 | ep->tx_credit_flow_enabled = false; |
794 | ath10k_dbg(ATH10K_DBG_BOOT, | 796 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
795 | "boot htc service '%s' eid %d TX flow control disabled\n", | 797 | "boot htc service '%s' eid %d TX flow control disabled\n", |
796 | htc_service_name(ep->service_id), assigned_eid); | 798 | htc_service_name(ep->service_id), assigned_eid); |
797 | } | 799 | } |
@@ -799,13 +801,13 @@ setup: | |||
799 | return status; | 801 | return status; |
800 | } | 802 | } |
801 | 803 | ||
802 | struct sk_buff *ath10k_htc_alloc_skb(int size) | 804 | struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size) |
803 | { | 805 | { |
804 | struct sk_buff *skb; | 806 | struct sk_buff *skb; |
805 | 807 | ||
806 | skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); | 808 | skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); |
807 | if (!skb) { | 809 | if (!skb) { |
808 | ath10k_warn("could not allocate HTC tx skb\n"); | 810 | ath10k_warn(ar, "could not allocate HTC tx skb\n"); |
809 | return NULL; | 811 | return NULL; |
810 | } | 812 | } |
811 | 813 | ||
@@ -813,13 +815,14 @@ struct sk_buff *ath10k_htc_alloc_skb(int size) | |||
813 | 815 | ||
814 | /* FW/HTC requires 4-byte aligned streams */ | 816 | /* FW/HTC requires 4-byte aligned streams */ |
815 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) | 817 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) |
816 | ath10k_warn("Unaligned HTC tx skb\n"); | 818 | ath10k_warn(ar, "Unaligned HTC tx skb\n"); |
817 | 819 | ||
818 | return skb; | 820 | return skb; |
819 | } | 821 | } |
820 | 822 | ||
821 | int ath10k_htc_start(struct ath10k_htc *htc) | 823 | int ath10k_htc_start(struct ath10k_htc *htc) |
822 | { | 824 | { |
825 | struct ath10k *ar = htc->ar; | ||
823 | struct sk_buff *skb; | 826 | struct sk_buff *skb; |
824 | int status = 0; | 827 | int status = 0; |
825 | struct ath10k_htc_msg *msg; | 828 | struct ath10k_htc_msg *msg; |
@@ -835,7 +838,7 @@ int ath10k_htc_start(struct ath10k_htc *htc) | |||
835 | msg->hdr.message_id = | 838 | msg->hdr.message_id = |
836 | __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID); | 839 | __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID); |
837 | 840 | ||
838 | ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); | 841 | ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); |
839 | 842 | ||
840 | status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); | 843 | status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); |
841 | if (status) { | 844 | if (status) { |
@@ -846,13 +849,6 @@ int ath10k_htc_start(struct ath10k_htc *htc) | |||
846 | return 0; | 849 | return 0; |
847 | } | 850 | } |
848 | 851 | ||
849 | void ath10k_htc_stop(struct ath10k_htc *htc) | ||
850 | { | ||
851 | spin_lock_bh(&htc->tx_lock); | ||
852 | htc->stopped = true; | ||
853 | spin_unlock_bh(&htc->tx_lock); | ||
854 | } | ||
855 | |||
856 | /* registered target arrival callback from the HIF layer */ | 852 | /* registered target arrival callback from the HIF layer */ |
857 | int ath10k_htc_init(struct ath10k *ar) | 853 | int ath10k_htc_init(struct ath10k *ar) |
858 | { | 854 | { |
@@ -862,7 +858,6 @@ int ath10k_htc_init(struct ath10k *ar) | |||
862 | 858 | ||
863 | spin_lock_init(&htc->tx_lock); | 859 | spin_lock_init(&htc->tx_lock); |
864 | 860 | ||
865 | htc->stopped = false; | ||
866 | ath10k_htc_reset_endpoint_states(htc); | 861 | ath10k_htc_reset_endpoint_states(htc); |
867 | 862 | ||
868 | /* setup HIF layer callbacks */ | 863 | /* setup HIF layer callbacks */ |
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h index 4716d331e6b6..bf532f671189 100644 --- a/drivers/net/wireless/ath/ath10k/htc.h +++ b/drivers/net/wireless/ath/ath10k/htc.h | |||
@@ -332,7 +332,7 @@ struct ath10k_htc { | |||
332 | struct ath10k *ar; | 332 | struct ath10k *ar; |
333 | struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT]; | 333 | struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT]; |
334 | 334 | ||
335 | /* protects endpoint and stopped fields */ | 335 | /* protects endpoints */ |
336 | spinlock_t tx_lock; | 336 | spinlock_t tx_lock; |
337 | 337 | ||
338 | struct ath10k_htc_ops htc_ops; | 338 | struct ath10k_htc_ops htc_ops; |
@@ -345,8 +345,6 @@ struct ath10k_htc { | |||
345 | int total_transmit_credits; | 345 | int total_transmit_credits; |
346 | struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT]; | 346 | struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT]; |
347 | int target_credit_size; | 347 | int target_credit_size; |
348 | |||
349 | bool stopped; | ||
350 | }; | 348 | }; |
351 | 349 | ||
352 | int ath10k_htc_init(struct ath10k *ar); | 350 | int ath10k_htc_init(struct ath10k *ar); |
@@ -357,7 +355,6 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, | |||
357 | struct ath10k_htc_svc_conn_resp *conn_resp); | 355 | struct ath10k_htc_svc_conn_resp *conn_resp); |
358 | int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, | 356 | int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, |
359 | struct sk_buff *packet); | 357 | struct sk_buff *packet); |
360 | void ath10k_htc_stop(struct ath10k_htc *htc); | 358 | struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size); |
361 | struct sk_buff *ath10k_htc_alloc_skb(int size); | ||
362 | 359 | ||
363 | #endif | 360 | #endif |
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 19c12cc8d663..87daae11f116 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c | |||
@@ -74,12 +74,14 @@ int ath10k_htt_init(struct ath10k *ar) | |||
74 | 74 | ||
75 | static int ath10k_htt_verify_version(struct ath10k_htt *htt) | 75 | static int ath10k_htt_verify_version(struct ath10k_htt *htt) |
76 | { | 76 | { |
77 | ath10k_dbg(ATH10K_DBG_BOOT, "htt target version %d.%d\n", | 77 | struct ath10k *ar = htt->ar; |
78 | |||
79 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt target version %d.%d\n", | ||
78 | htt->target_version_major, htt->target_version_minor); | 80 | htt->target_version_major, htt->target_version_minor); |
79 | 81 | ||
80 | if (htt->target_version_major != 2 && | 82 | if (htt->target_version_major != 2 && |
81 | htt->target_version_major != 3) { | 83 | htt->target_version_major != 3) { |
82 | ath10k_err("unsupported htt major version %d. supported versions are 2 and 3\n", | 84 | ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n", |
83 | htt->target_version_major); | 85 | htt->target_version_major); |
84 | return -ENOTSUPP; | 86 | return -ENOTSUPP; |
85 | } | 87 | } |
@@ -89,6 +91,7 @@ static int ath10k_htt_verify_version(struct ath10k_htt *htt) | |||
89 | 91 | ||
90 | int ath10k_htt_setup(struct ath10k_htt *htt) | 92 | int ath10k_htt_setup(struct ath10k_htt *htt) |
91 | { | 93 | { |
94 | struct ath10k *ar = htt->ar; | ||
92 | int status; | 95 | int status; |
93 | 96 | ||
94 | init_completion(&htt->target_version_received); | 97 | init_completion(&htt->target_version_received); |
@@ -100,7 +103,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt) | |||
100 | status = wait_for_completion_timeout(&htt->target_version_received, | 103 | status = wait_for_completion_timeout(&htt->target_version_received, |
101 | HTT_TARGET_VERSION_TIMEOUT_HZ); | 104 | HTT_TARGET_VERSION_TIMEOUT_HZ); |
102 | if (status <= 0) { | 105 | if (status <= 0) { |
103 | ath10k_warn("htt version request timed out\n"); | 106 | ath10k_warn(ar, "htt version request timed out\n"); |
104 | return -ETIMEDOUT; | 107 | return -ETIMEDOUT; |
105 | } | 108 | } |
106 | 109 | ||
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 80cdac15588a..30927b1d7109 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -271,13 +271,14 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt) | |||
271 | 271 | ||
272 | static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) | 272 | static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) |
273 | { | 273 | { |
274 | struct ath10k *ar = htt->ar; | ||
274 | int idx; | 275 | int idx; |
275 | struct sk_buff *msdu; | 276 | struct sk_buff *msdu; |
276 | 277 | ||
277 | lockdep_assert_held(&htt->rx_ring.lock); | 278 | lockdep_assert_held(&htt->rx_ring.lock); |
278 | 279 | ||
279 | if (htt->rx_ring.fill_cnt == 0) { | 280 | if (htt->rx_ring.fill_cnt == 0) { |
280 | ath10k_warn("tried to pop sk_buff from an empty rx ring\n"); | 281 | ath10k_warn(ar, "tried to pop sk_buff from an empty rx ring\n"); |
281 | return NULL; | 282 | return NULL; |
282 | } | 283 | } |
283 | 284 | ||
@@ -311,6 +312,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
311 | struct sk_buff **tail_msdu, | 312 | struct sk_buff **tail_msdu, |
312 | u32 *attention) | 313 | u32 *attention) |
313 | { | 314 | { |
315 | struct ath10k *ar = htt->ar; | ||
314 | int msdu_len, msdu_chaining = 0; | 316 | int msdu_len, msdu_chaining = 0; |
315 | struct sk_buff *msdu; | 317 | struct sk_buff *msdu; |
316 | struct htt_rx_desc *rx_desc; | 318 | struct htt_rx_desc *rx_desc; |
@@ -318,7 +320,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
318 | lockdep_assert_held(&htt->rx_ring.lock); | 320 | lockdep_assert_held(&htt->rx_ring.lock); |
319 | 321 | ||
320 | if (htt->rx_confused) { | 322 | if (htt->rx_confused) { |
321 | ath10k_warn("htt is confused. refusing rx\n"); | 323 | ath10k_warn(ar, "htt is confused. refusing rx\n"); |
322 | return -1; | 324 | return -1; |
323 | } | 325 | } |
324 | 326 | ||
@@ -331,7 +333,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
331 | msdu->len + skb_tailroom(msdu), | 333 | msdu->len + skb_tailroom(msdu), |
332 | DMA_FROM_DEVICE); | 334 | DMA_FROM_DEVICE); |
333 | 335 | ||
334 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ", | 336 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ", |
335 | msdu->data, msdu->len + skb_tailroom(msdu)); | 337 | msdu->data, msdu->len + skb_tailroom(msdu)); |
336 | 338 | ||
337 | rx_desc = (struct htt_rx_desc *)msdu->data; | 339 | rx_desc = (struct htt_rx_desc *)msdu->data; |
@@ -354,7 +356,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
354 | ath10k_htt_rx_free_msdu_chain(*head_msdu); | 356 | ath10k_htt_rx_free_msdu_chain(*head_msdu); |
355 | *head_msdu = NULL; | 357 | *head_msdu = NULL; |
356 | msdu = NULL; | 358 | msdu = NULL; |
357 | ath10k_err("htt rx stopped. cannot recover\n"); | 359 | ath10k_err(ar, "htt rx stopped. cannot recover\n"); |
358 | htt->rx_confused = true; | 360 | htt->rx_confused = true; |
359 | break; | 361 | break; |
360 | } | 362 | } |
@@ -429,7 +431,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
429 | next->len + skb_tailroom(next), | 431 | next->len + skb_tailroom(next), |
430 | DMA_FROM_DEVICE); | 432 | DMA_FROM_DEVICE); |
431 | 433 | ||
432 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, | 434 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, |
433 | "htt rx chained: ", next->data, | 435 | "htt rx chained: ", next->data, |
434 | next->len + skb_tailroom(next)); | 436 | next->len + skb_tailroom(next)); |
435 | 437 | ||
@@ -483,13 +485,14 @@ static void ath10k_htt_rx_replenish_task(unsigned long ptr) | |||
483 | 485 | ||
484 | int ath10k_htt_rx_alloc(struct ath10k_htt *htt) | 486 | int ath10k_htt_rx_alloc(struct ath10k_htt *htt) |
485 | { | 487 | { |
488 | struct ath10k *ar = htt->ar; | ||
486 | dma_addr_t paddr; | 489 | dma_addr_t paddr; |
487 | void *vaddr; | 490 | void *vaddr; |
488 | struct timer_list *timer = &htt->rx_ring.refill_retry_timer; | 491 | struct timer_list *timer = &htt->rx_ring.refill_retry_timer; |
489 | 492 | ||
490 | htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); | 493 | htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); |
491 | if (!is_power_of_2(htt->rx_ring.size)) { | 494 | if (!is_power_of_2(htt->rx_ring.size)) { |
492 | ath10k_warn("htt rx ring size is not power of 2\n"); | 495 | ath10k_warn(ar, "htt rx ring size is not power of 2\n"); |
493 | return -EINVAL; | 496 | return -EINVAL; |
494 | } | 497 | } |
495 | 498 | ||
@@ -550,7 +553,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) | |||
550 | tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task, | 553 | tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task, |
551 | (unsigned long)htt); | 554 | (unsigned long)htt); |
552 | 555 | ||
553 | ath10k_dbg(ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", | 556 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", |
554 | htt->rx_ring.size, htt->rx_ring.fill_level); | 557 | htt->rx_ring.size, htt->rx_ring.fill_level); |
555 | return 0; | 558 | return 0; |
556 | 559 | ||
@@ -572,7 +575,8 @@ err_netbuf: | |||
572 | return -ENOMEM; | 575 | return -ENOMEM; |
573 | } | 576 | } |
574 | 577 | ||
575 | static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type) | 578 | static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar, |
579 | enum htt_rx_mpdu_encrypt_type type) | ||
576 | { | 580 | { |
577 | switch (type) { | 581 | switch (type) { |
578 | case HTT_RX_MPDU_ENCRYPT_WEP40: | 582 | case HTT_RX_MPDU_ENCRYPT_WEP40: |
@@ -588,11 +592,12 @@ static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type) | |||
588 | return 0; | 592 | return 0; |
589 | } | 593 | } |
590 | 594 | ||
591 | ath10k_warn("unknown encryption type %d\n", type); | 595 | ath10k_warn(ar, "unknown encryption type %d\n", type); |
592 | return 0; | 596 | return 0; |
593 | } | 597 | } |
594 | 598 | ||
595 | static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type) | 599 | static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar, |
600 | enum htt_rx_mpdu_encrypt_type type) | ||
596 | { | 601 | { |
597 | switch (type) { | 602 | switch (type) { |
598 | case HTT_RX_MPDU_ENCRYPT_NONE: | 603 | case HTT_RX_MPDU_ENCRYPT_NONE: |
@@ -608,7 +613,7 @@ static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type) | |||
608 | return 8; | 613 | return 8; |
609 | } | 614 | } |
610 | 615 | ||
611 | ath10k_warn("unknown encryption type %d\n", type); | 616 | ath10k_warn(ar, "unknown encryption type %d\n", type); |
612 | return 0; | 617 | return 0; |
613 | } | 618 | } |
614 | 619 | ||
@@ -819,19 +824,55 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, | |||
819 | return true; | 824 | return true; |
820 | } | 825 | } |
821 | 826 | ||
827 | static const char * const tid_to_ac[] = { | ||
828 | "BE", | ||
829 | "BK", | ||
830 | "BK", | ||
831 | "BE", | ||
832 | "VI", | ||
833 | "VI", | ||
834 | "VO", | ||
835 | "VO", | ||
836 | }; | ||
837 | |||
838 | static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size) | ||
839 | { | ||
840 | u8 *qc; | ||
841 | int tid; | ||
842 | |||
843 | if (!ieee80211_is_data_qos(hdr->frame_control)) | ||
844 | return ""; | ||
845 | |||
846 | qc = ieee80211_get_qos_ctl(hdr); | ||
847 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
848 | if (tid < 8) | ||
849 | snprintf(out, size, "tid %d (%s)", tid, tid_to_ac[tid]); | ||
850 | else | ||
851 | snprintf(out, size, "tid %d", tid); | ||
852 | |||
853 | return out; | ||
854 | } | ||
855 | |||
822 | static void ath10k_process_rx(struct ath10k *ar, | 856 | static void ath10k_process_rx(struct ath10k *ar, |
823 | struct ieee80211_rx_status *rx_status, | 857 | struct ieee80211_rx_status *rx_status, |
824 | struct sk_buff *skb) | 858 | struct sk_buff *skb) |
825 | { | 859 | { |
826 | struct ieee80211_rx_status *status; | 860 | struct ieee80211_rx_status *status; |
861 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
862 | char tid[32]; | ||
827 | 863 | ||
828 | status = IEEE80211_SKB_RXCB(skb); | 864 | status = IEEE80211_SKB_RXCB(skb); |
829 | *status = *rx_status; | 865 | *status = *rx_status; |
830 | 866 | ||
831 | ath10k_dbg(ATH10K_DBG_DATA, | 867 | ath10k_dbg(ar, ATH10K_DBG_DATA, |
832 | "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n", | 868 | "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", |
833 | skb, | 869 | skb, |
834 | skb->len, | 870 | skb->len, |
871 | ieee80211_get_SA(hdr), | ||
872 | ath10k_get_tid(hdr, tid, sizeof(tid)), | ||
873 | is_multicast_ether_addr(ieee80211_get_DA(hdr)) ? | ||
874 | "mcast" : "ucast", | ||
875 | (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4, | ||
835 | status->flag == 0 ? "legacy" : "", | 876 | status->flag == 0 ? "legacy" : "", |
836 | status->flag & RX_FLAG_HT ? "ht" : "", | 877 | status->flag & RX_FLAG_HT ? "ht" : "", |
837 | status->flag & RX_FLAG_VHT ? "vht" : "", | 878 | status->flag & RX_FLAG_VHT ? "vht" : "", |
@@ -843,8 +884,9 @@ static void ath10k_process_rx(struct ath10k *ar, | |||
843 | status->freq, | 884 | status->freq, |
844 | status->band, status->flag, | 885 | status->band, status->flag, |
845 | !!(status->flag & RX_FLAG_FAILED_FCS_CRC), | 886 | !!(status->flag & RX_FLAG_FAILED_FCS_CRC), |
846 | !!(status->flag & RX_FLAG_MMIC_ERROR)); | 887 | !!(status->flag & RX_FLAG_MMIC_ERROR), |
847 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", | 888 | !!(status->flag & RX_FLAG_AMSDU_MORE)); |
889 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", | ||
848 | skb->data, skb->len); | 890 | skb->data, skb->len); |
849 | 891 | ||
850 | ieee80211_rx(ar->hw, skb); | 892 | ieee80211_rx(ar->hw, skb); |
@@ -860,13 +902,14 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
860 | struct ieee80211_rx_status *rx_status, | 902 | struct ieee80211_rx_status *rx_status, |
861 | struct sk_buff *skb_in) | 903 | struct sk_buff *skb_in) |
862 | { | 904 | { |
905 | struct ath10k *ar = htt->ar; | ||
863 | struct htt_rx_desc *rxd; | 906 | struct htt_rx_desc *rxd; |
864 | struct sk_buff *skb = skb_in; | 907 | struct sk_buff *skb = skb_in; |
865 | struct sk_buff *first; | 908 | struct sk_buff *first; |
866 | enum rx_msdu_decap_format fmt; | 909 | enum rx_msdu_decap_format fmt; |
867 | enum htt_rx_mpdu_encrypt_type enctype; | 910 | enum htt_rx_mpdu_encrypt_type enctype; |
868 | struct ieee80211_hdr *hdr; | 911 | struct ieee80211_hdr *hdr; |
869 | u8 hdr_buf[64], addr[ETH_ALEN], *qos; | 912 | u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos; |
870 | unsigned int hdr_len; | 913 | unsigned int hdr_len; |
871 | 914 | ||
872 | rxd = (void *)skb->data - sizeof(*rxd); | 915 | rxd = (void *)skb->data - sizeof(*rxd); |
@@ -893,8 +936,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
893 | /* First frame in an A-MSDU chain has more decapped data. */ | 936 | /* First frame in an A-MSDU chain has more decapped data. */ |
894 | if (skb == first) { | 937 | if (skb == first) { |
895 | len = round_up(ieee80211_hdrlen(hdr->frame_control), 4); | 938 | len = round_up(ieee80211_hdrlen(hdr->frame_control), 4); |
896 | len += round_up(ath10k_htt_rx_crypto_param_len(enctype), | 939 | len += round_up(ath10k_htt_rx_crypto_param_len(ar, |
897 | 4); | 940 | enctype), 4); |
898 | decap_hdr += len; | 941 | decap_hdr += len; |
899 | } | 942 | } |
900 | 943 | ||
@@ -904,10 +947,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
904 | skb_trim(skb, skb->len - FCS_LEN); | 947 | skb_trim(skb, skb->len - FCS_LEN); |
905 | break; | 948 | break; |
906 | case RX_MSDU_DECAP_NATIVE_WIFI: | 949 | case RX_MSDU_DECAP_NATIVE_WIFI: |
907 | /* pull decapped header and copy DA */ | 950 | /* pull decapped header and copy SA & DA */ |
908 | hdr = (struct ieee80211_hdr *)skb->data; | 951 | hdr = (struct ieee80211_hdr *)skb->data; |
909 | hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); | 952 | hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); |
910 | memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN); | 953 | memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN); |
954 | memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN); | ||
911 | skb_pull(skb, hdr_len); | 955 | skb_pull(skb, hdr_len); |
912 | 956 | ||
913 | /* push original 802.11 header */ | 957 | /* push original 802.11 header */ |
@@ -921,8 +965,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
921 | qos = ieee80211_get_qos_ctl(hdr); | 965 | qos = ieee80211_get_qos_ctl(hdr); |
922 | qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; | 966 | qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; |
923 | 967 | ||
924 | /* original 802.11 header has a different DA */ | 968 | /* original 802.11 header has a different DA and in |
925 | memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN); | 969 | * case of 4addr it may also have different SA |
970 | */ | ||
971 | memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN); | ||
972 | memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN); | ||
926 | break; | 973 | break; |
927 | case RX_MSDU_DECAP_ETHERNET2_DIX: | 974 | case RX_MSDU_DECAP_ETHERNET2_DIX: |
928 | /* strip ethernet header and insert decapped 802.11 | 975 | /* strip ethernet header and insert decapped 802.11 |
@@ -965,6 +1012,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, | |||
965 | struct ieee80211_rx_status *rx_status, | 1012 | struct ieee80211_rx_status *rx_status, |
966 | struct sk_buff *skb) | 1013 | struct sk_buff *skb) |
967 | { | 1014 | { |
1015 | struct ath10k *ar = htt->ar; | ||
968 | struct htt_rx_desc *rxd; | 1016 | struct htt_rx_desc *rxd; |
969 | struct ieee80211_hdr *hdr; | 1017 | struct ieee80211_hdr *hdr; |
970 | enum rx_msdu_decap_format fmt; | 1018 | enum rx_msdu_decap_format fmt; |
@@ -974,7 +1022,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, | |||
974 | 1022 | ||
975 | /* This shouldn't happen. If it does than it may be a FW bug. */ | 1023 | /* This shouldn't happen. If it does than it may be a FW bug. */ |
976 | if (skb->next) { | 1024 | if (skb->next) { |
977 | ath10k_warn("htt rx received chained non A-MSDU frame\n"); | 1025 | ath10k_warn(ar, "htt rx received chained non A-MSDU frame\n"); |
978 | ath10k_htt_rx_free_msdu_chain(skb->next); | 1026 | ath10k_htt_rx_free_msdu_chain(skb->next); |
979 | skb->next = NULL; | 1027 | skb->next = NULL; |
980 | } | 1028 | } |
@@ -1011,7 +1059,8 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, | |||
1011 | 1059 | ||
1012 | rfc1042 = hdr; | 1060 | rfc1042 = hdr; |
1013 | rfc1042 += roundup(hdr_len, 4); | 1061 | rfc1042 += roundup(hdr_len, 4); |
1014 | rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4); | 1062 | rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(ar, |
1063 | enctype), 4); | ||
1015 | 1064 | ||
1016 | skb_pull(skb, sizeof(struct ethhdr)); | 1065 | skb_pull(skb, sizeof(struct ethhdr)); |
1017 | memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)), | 1066 | memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)), |
@@ -1120,27 +1169,29 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, | |||
1120 | bool channel_set, | 1169 | bool channel_set, |
1121 | u32 attention) | 1170 | u32 attention) |
1122 | { | 1171 | { |
1172 | struct ath10k *ar = htt->ar; | ||
1173 | |||
1123 | if (head->len == 0) { | 1174 | if (head->len == 0) { |
1124 | ath10k_dbg(ATH10K_DBG_HTT, | 1175 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1125 | "htt rx dropping due to zero-len\n"); | 1176 | "htt rx dropping due to zero-len\n"); |
1126 | return false; | 1177 | return false; |
1127 | } | 1178 | } |
1128 | 1179 | ||
1129 | if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) { | 1180 | if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) { |
1130 | ath10k_dbg(ATH10K_DBG_HTT, | 1181 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1131 | "htt rx dropping due to decrypt-err\n"); | 1182 | "htt rx dropping due to decrypt-err\n"); |
1132 | return false; | 1183 | return false; |
1133 | } | 1184 | } |
1134 | 1185 | ||
1135 | if (!channel_set) { | 1186 | if (!channel_set) { |
1136 | ath10k_warn("no channel configured; ignoring frame!\n"); | 1187 | ath10k_warn(ar, "no channel configured; ignoring frame!\n"); |
1137 | return false; | 1188 | return false; |
1138 | } | 1189 | } |
1139 | 1190 | ||
1140 | /* Skip mgmt frames while we handle this in WMI */ | 1191 | /* Skip mgmt frames while we handle this in WMI */ |
1141 | if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL || | 1192 | if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL || |
1142 | attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { | 1193 | attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { |
1143 | ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); | 1194 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); |
1144 | return false; | 1195 | return false; |
1145 | } | 1196 | } |
1146 | 1197 | ||
@@ -1148,14 +1199,14 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, | |||
1148 | status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && | 1199 | status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && |
1149 | status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && | 1200 | status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && |
1150 | !htt->ar->monitor_started) { | 1201 | !htt->ar->monitor_started) { |
1151 | ath10k_dbg(ATH10K_DBG_HTT, | 1202 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1152 | "htt rx ignoring frame w/ status %d\n", | 1203 | "htt rx ignoring frame w/ status %d\n", |
1153 | status); | 1204 | status); |
1154 | return false; | 1205 | return false; |
1155 | } | 1206 | } |
1156 | 1207 | ||
1157 | if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { | 1208 | if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { |
1158 | ath10k_dbg(ATH10K_DBG_HTT, | 1209 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1159 | "htt rx CAC running\n"); | 1210 | "htt rx CAC running\n"); |
1160 | return false; | 1211 | return false; |
1161 | } | 1212 | } |
@@ -1166,6 +1217,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, | |||
1166 | static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | 1217 | static void ath10k_htt_rx_handler(struct ath10k_htt *htt, |
1167 | struct htt_rx_indication *rx) | 1218 | struct htt_rx_indication *rx) |
1168 | { | 1219 | { |
1220 | struct ath10k *ar = htt->ar; | ||
1169 | struct ieee80211_rx_status *rx_status = &htt->rx_status; | 1221 | struct ieee80211_rx_status *rx_status = &htt->rx_status; |
1170 | struct htt_rx_indication_mpdu_range *mpdu_ranges; | 1222 | struct htt_rx_indication_mpdu_range *mpdu_ranges; |
1171 | struct htt_rx_desc *rxd; | 1223 | struct htt_rx_desc *rxd; |
@@ -1211,7 +1263,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | |||
1211 | rx_status); | 1263 | rx_status); |
1212 | } | 1264 | } |
1213 | 1265 | ||
1214 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", | 1266 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", |
1215 | rx, sizeof(*rx) + | 1267 | rx, sizeof(*rx) + |
1216 | (sizeof(struct htt_rx_indication_mpdu_range) * | 1268 | (sizeof(struct htt_rx_indication_mpdu_range) * |
1217 | num_mpdu_ranges)); | 1269 | num_mpdu_ranges)); |
@@ -1233,7 +1285,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | |||
1233 | &attention); | 1285 | &attention); |
1234 | 1286 | ||
1235 | if (ret < 0) { | 1287 | if (ret < 0) { |
1236 | ath10k_warn("failed to pop amsdu from htt rx ring %d\n", | 1288 | ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n", |
1237 | ret); | 1289 | ret); |
1238 | ath10k_htt_rx_free_msdu_chain(msdu_head); | 1290 | ath10k_htt_rx_free_msdu_chain(msdu_head); |
1239 | continue; | 1291 | continue; |
@@ -1282,6 +1334,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | |||
1282 | static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | 1334 | static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, |
1283 | struct htt_rx_fragment_indication *frag) | 1335 | struct htt_rx_fragment_indication *frag) |
1284 | { | 1336 | { |
1337 | struct ath10k *ar = htt->ar; | ||
1285 | struct sk_buff *msdu_head, *msdu_tail; | 1338 | struct sk_buff *msdu_head, *msdu_tail; |
1286 | enum htt_rx_mpdu_encrypt_type enctype; | 1339 | enum htt_rx_mpdu_encrypt_type enctype; |
1287 | struct htt_rx_desc *rxd; | 1340 | struct htt_rx_desc *rxd; |
@@ -1308,10 +1361,10 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1308 | &attention); | 1361 | &attention); |
1309 | spin_unlock_bh(&htt->rx_ring.lock); | 1362 | spin_unlock_bh(&htt->rx_ring.lock); |
1310 | 1363 | ||
1311 | ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); | 1364 | ath10k_dbg(ar, ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); |
1312 | 1365 | ||
1313 | if (ret) { | 1366 | if (ret) { |
1314 | ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n", | 1367 | ath10k_warn(ar, "failed to pop amsdu from httr rx ring for fragmented rx %d\n", |
1315 | ret); | 1368 | ret); |
1316 | ath10k_htt_rx_free_msdu_chain(msdu_head); | 1369 | ath10k_htt_rx_free_msdu_chain(msdu_head); |
1317 | return; | 1370 | return; |
@@ -1328,7 +1381,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1328 | RX_MSDU_START_INFO1_DECAP_FORMAT); | 1381 | RX_MSDU_START_INFO1_DECAP_FORMAT); |
1329 | 1382 | ||
1330 | if (fmt != RX_MSDU_DECAP_RAW) { | 1383 | if (fmt != RX_MSDU_DECAP_RAW) { |
1331 | ath10k_warn("we dont support non-raw fragmented rx yet\n"); | 1384 | ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n"); |
1332 | dev_kfree_skb_any(msdu_head); | 1385 | dev_kfree_skb_any(msdu_head); |
1333 | goto end; | 1386 | goto end; |
1334 | } | 1387 | } |
@@ -1340,17 +1393,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1340 | msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); | 1393 | msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); |
1341 | 1394 | ||
1342 | if (tkip_mic_err) | 1395 | if (tkip_mic_err) |
1343 | ath10k_warn("tkip mic error\n"); | 1396 | ath10k_warn(ar, "tkip mic error\n"); |
1344 | 1397 | ||
1345 | if (decrypt_err) { | 1398 | if (decrypt_err) { |
1346 | ath10k_warn("decryption err in fragmented rx\n"); | 1399 | ath10k_warn(ar, "decryption err in fragmented rx\n"); |
1347 | dev_kfree_skb_any(msdu_head); | 1400 | dev_kfree_skb_any(msdu_head); |
1348 | goto end; | 1401 | goto end; |
1349 | } | 1402 | } |
1350 | 1403 | ||
1351 | if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) { | 1404 | if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) { |
1352 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1405 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1353 | paramlen = ath10k_htt_rx_crypto_param_len(enctype); | 1406 | paramlen = ath10k_htt_rx_crypto_param_len(ar, enctype); |
1354 | 1407 | ||
1355 | /* It is more efficient to move the header than the payload */ | 1408 | /* It is more efficient to move the header than the payload */ |
1356 | memmove((void *)msdu_head->data + paramlen, | 1409 | memmove((void *)msdu_head->data + paramlen, |
@@ -1364,7 +1417,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1364 | trim = 4; | 1417 | trim = 4; |
1365 | 1418 | ||
1366 | /* remove crypto trailer */ | 1419 | /* remove crypto trailer */ |
1367 | trim += ath10k_htt_rx_crypto_tail_len(enctype); | 1420 | trim += ath10k_htt_rx_crypto_tail_len(ar, enctype); |
1368 | 1421 | ||
1369 | /* last fragment of TKIP frags has MIC */ | 1422 | /* last fragment of TKIP frags has MIC */ |
1370 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 1423 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
@@ -1372,20 +1425,20 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1372 | trim += 8; | 1425 | trim += 8; |
1373 | 1426 | ||
1374 | if (trim > msdu_head->len) { | 1427 | if (trim > msdu_head->len) { |
1375 | ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n"); | 1428 | ath10k_warn(ar, "htt rx fragment: trailer longer than the frame itself? drop\n"); |
1376 | dev_kfree_skb_any(msdu_head); | 1429 | dev_kfree_skb_any(msdu_head); |
1377 | goto end; | 1430 | goto end; |
1378 | } | 1431 | } |
1379 | 1432 | ||
1380 | skb_trim(msdu_head, msdu_head->len - trim); | 1433 | skb_trim(msdu_head, msdu_head->len - trim); |
1381 | 1434 | ||
1382 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ", | 1435 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ", |
1383 | msdu_head->data, msdu_head->len); | 1436 | msdu_head->data, msdu_head->len); |
1384 | ath10k_process_rx(htt->ar, rx_status, msdu_head); | 1437 | ath10k_process_rx(htt->ar, rx_status, msdu_head); |
1385 | 1438 | ||
1386 | end: | 1439 | end: |
1387 | if (fw_desc_len > 0) { | 1440 | if (fw_desc_len > 0) { |
1388 | ath10k_dbg(ATH10K_DBG_HTT, | 1441 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1389 | "expecting more fragmented rx in one indication %d\n", | 1442 | "expecting more fragmented rx in one indication %d\n", |
1390 | fw_desc_len); | 1443 | fw_desc_len); |
1391 | } | 1444 | } |
@@ -1415,12 +1468,12 @@ static void ath10k_htt_rx_frm_tx_compl(struct ath10k *ar, | |||
1415 | tx_done.discard = true; | 1468 | tx_done.discard = true; |
1416 | break; | 1469 | break; |
1417 | default: | 1470 | default: |
1418 | ath10k_warn("unhandled tx completion status %d\n", status); | 1471 | ath10k_warn(ar, "unhandled tx completion status %d\n", status); |
1419 | tx_done.discard = true; | 1472 | tx_done.discard = true; |
1420 | break; | 1473 | break; |
1421 | } | 1474 | } |
1422 | 1475 | ||
1423 | ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n", | 1476 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n", |
1424 | resp->data_tx_completion.num_msdus); | 1477 | resp->data_tx_completion.num_msdus); |
1425 | 1478 | ||
1426 | for (i = 0; i < resp->data_tx_completion.num_msdus; i++) { | 1479 | for (i = 0; i < resp->data_tx_completion.num_msdus; i++) { |
@@ -1441,14 +1494,14 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp) | |||
1441 | tid = MS(info0, HTT_RX_BA_INFO0_TID); | 1494 | tid = MS(info0, HTT_RX_BA_INFO0_TID); |
1442 | peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); | 1495 | peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); |
1443 | 1496 | ||
1444 | ath10k_dbg(ATH10K_DBG_HTT, | 1497 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1445 | "htt rx addba tid %hu peer_id %hu size %hhu\n", | 1498 | "htt rx addba tid %hu peer_id %hu size %hhu\n", |
1446 | tid, peer_id, ev->window_size); | 1499 | tid, peer_id, ev->window_size); |
1447 | 1500 | ||
1448 | spin_lock_bh(&ar->data_lock); | 1501 | spin_lock_bh(&ar->data_lock); |
1449 | peer = ath10k_peer_find_by_id(ar, peer_id); | 1502 | peer = ath10k_peer_find_by_id(ar, peer_id); |
1450 | if (!peer) { | 1503 | if (!peer) { |
1451 | ath10k_warn("received addba event for invalid peer_id: %hu\n", | 1504 | ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n", |
1452 | peer_id); | 1505 | peer_id); |
1453 | spin_unlock_bh(&ar->data_lock); | 1506 | spin_unlock_bh(&ar->data_lock); |
1454 | return; | 1507 | return; |
@@ -1456,13 +1509,13 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp) | |||
1456 | 1509 | ||
1457 | arvif = ath10k_get_arvif(ar, peer->vdev_id); | 1510 | arvif = ath10k_get_arvif(ar, peer->vdev_id); |
1458 | if (!arvif) { | 1511 | if (!arvif) { |
1459 | ath10k_warn("received addba event for invalid vdev_id: %u\n", | 1512 | ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n", |
1460 | peer->vdev_id); | 1513 | peer->vdev_id); |
1461 | spin_unlock_bh(&ar->data_lock); | 1514 | spin_unlock_bh(&ar->data_lock); |
1462 | return; | 1515 | return; |
1463 | } | 1516 | } |
1464 | 1517 | ||
1465 | ath10k_dbg(ATH10K_DBG_HTT, | 1518 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1466 | "htt rx start rx ba session sta %pM tid %hu size %hhu\n", | 1519 | "htt rx start rx ba session sta %pM tid %hu size %hhu\n", |
1467 | peer->addr, tid, ev->window_size); | 1520 | peer->addr, tid, ev->window_size); |
1468 | 1521 | ||
@@ -1481,14 +1534,14 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp) | |||
1481 | tid = MS(info0, HTT_RX_BA_INFO0_TID); | 1534 | tid = MS(info0, HTT_RX_BA_INFO0_TID); |
1482 | peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); | 1535 | peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); |
1483 | 1536 | ||
1484 | ath10k_dbg(ATH10K_DBG_HTT, | 1537 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1485 | "htt rx delba tid %hu peer_id %hu\n", | 1538 | "htt rx delba tid %hu peer_id %hu\n", |
1486 | tid, peer_id); | 1539 | tid, peer_id); |
1487 | 1540 | ||
1488 | spin_lock_bh(&ar->data_lock); | 1541 | spin_lock_bh(&ar->data_lock); |
1489 | peer = ath10k_peer_find_by_id(ar, peer_id); | 1542 | peer = ath10k_peer_find_by_id(ar, peer_id); |
1490 | if (!peer) { | 1543 | if (!peer) { |
1491 | ath10k_warn("received addba event for invalid peer_id: %hu\n", | 1544 | ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n", |
1492 | peer_id); | 1545 | peer_id); |
1493 | spin_unlock_bh(&ar->data_lock); | 1546 | spin_unlock_bh(&ar->data_lock); |
1494 | return; | 1547 | return; |
@@ -1496,13 +1549,13 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp) | |||
1496 | 1549 | ||
1497 | arvif = ath10k_get_arvif(ar, peer->vdev_id); | 1550 | arvif = ath10k_get_arvif(ar, peer->vdev_id); |
1498 | if (!arvif) { | 1551 | if (!arvif) { |
1499 | ath10k_warn("received addba event for invalid vdev_id: %u\n", | 1552 | ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n", |
1500 | peer->vdev_id); | 1553 | peer->vdev_id); |
1501 | spin_unlock_bh(&ar->data_lock); | 1554 | spin_unlock_bh(&ar->data_lock); |
1502 | return; | 1555 | return; |
1503 | } | 1556 | } |
1504 | 1557 | ||
1505 | ath10k_dbg(ATH10K_DBG_HTT, | 1558 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1506 | "htt rx stop rx ba session sta %pM tid %hu\n", | 1559 | "htt rx stop rx ba session sta %pM tid %hu\n", |
1507 | peer->addr, tid); | 1560 | peer->addr, tid); |
1508 | 1561 | ||
@@ -1517,9 +1570,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1517 | 1570 | ||
1518 | /* confirm alignment */ | 1571 | /* confirm alignment */ |
1519 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) | 1572 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) |
1520 | ath10k_warn("unaligned htt message, expect trouble\n"); | 1573 | ath10k_warn(ar, "unaligned htt message, expect trouble\n"); |
1521 | 1574 | ||
1522 | ath10k_dbg(ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n", | 1575 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n", |
1523 | resp->hdr.msg_type); | 1576 | resp->hdr.msg_type); |
1524 | switch (resp->hdr.msg_type) { | 1577 | switch (resp->hdr.msg_type) { |
1525 | case HTT_T2H_MSG_TYPE_VERSION_CONF: { | 1578 | case HTT_T2H_MSG_TYPE_VERSION_CONF: { |
@@ -1583,7 +1636,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1583 | struct ath10k *ar = htt->ar; | 1636 | struct ath10k *ar = htt->ar; |
1584 | struct htt_security_indication *ev = &resp->security_indication; | 1637 | struct htt_security_indication *ev = &resp->security_indication; |
1585 | 1638 | ||
1586 | ath10k_dbg(ATH10K_DBG_HTT, | 1639 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
1587 | "sec ind peer_id %d unicast %d type %d\n", | 1640 | "sec ind peer_id %d unicast %d type %d\n", |
1588 | __le16_to_cpu(ev->peer_id), | 1641 | __le16_to_cpu(ev->peer_id), |
1589 | !!(ev->flags & HTT_SECURITY_IS_UNICAST), | 1642 | !!(ev->flags & HTT_SECURITY_IS_UNICAST), |
@@ -1592,7 +1645,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1592 | break; | 1645 | break; |
1593 | } | 1646 | } |
1594 | case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { | 1647 | case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { |
1595 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", | 1648 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", |
1596 | skb->data, skb->len); | 1649 | skb->data, skb->len); |
1597 | ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind); | 1650 | ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind); |
1598 | break; | 1651 | break; |
@@ -1609,7 +1662,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1609 | * sends all tx frames as already inspected so this shouldn't | 1662 | * sends all tx frames as already inspected so this shouldn't |
1610 | * happen unless fw has a bug. | 1663 | * happen unless fw has a bug. |
1611 | */ | 1664 | */ |
1612 | ath10k_warn("received an unexpected htt tx inspect event\n"); | 1665 | ath10k_warn(ar, "received an unexpected htt tx inspect event\n"); |
1613 | break; | 1666 | break; |
1614 | case HTT_T2H_MSG_TYPE_RX_ADDBA: | 1667 | case HTT_T2H_MSG_TYPE_RX_ADDBA: |
1615 | ath10k_htt_rx_addba(ar, resp); | 1668 | ath10k_htt_rx_addba(ar, resp); |
@@ -1624,9 +1677,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1624 | break; | 1677 | break; |
1625 | } | 1678 | } |
1626 | default: | 1679 | default: |
1627 | ath10k_dbg(ATH10K_DBG_HTT, "htt event (%d) not handled\n", | 1680 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt event (%d) not handled\n", |
1628 | resp->hdr.msg_type); | 1681 | resp->hdr.msg_type); |
1629 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", | 1682 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", |
1630 | skb->data, skb->len); | 1683 | skb->data, skb->len); |
1631 | break; | 1684 | break; |
1632 | }; | 1685 | }; |
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 8b27bfcc1de3..eaa73aa99c20 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c | |||
@@ -58,6 +58,7 @@ exit: | |||
58 | 58 | ||
59 | int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt) | 59 | int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt) |
60 | { | 60 | { |
61 | struct ath10k *ar = htt->ar; | ||
61 | int msdu_id; | 62 | int msdu_id; |
62 | 63 | ||
63 | lockdep_assert_held(&htt->tx_lock); | 64 | lockdep_assert_held(&htt->tx_lock); |
@@ -67,24 +68,29 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt) | |||
67 | if (msdu_id == htt->max_num_pending_tx) | 68 | if (msdu_id == htt->max_num_pending_tx) |
68 | return -ENOBUFS; | 69 | return -ENOBUFS; |
69 | 70 | ||
70 | ath10k_dbg(ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id); | 71 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id); |
71 | __set_bit(msdu_id, htt->used_msdu_ids); | 72 | __set_bit(msdu_id, htt->used_msdu_ids); |
72 | return msdu_id; | 73 | return msdu_id; |
73 | } | 74 | } |
74 | 75 | ||
75 | void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) | 76 | void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) |
76 | { | 77 | { |
78 | struct ath10k *ar = htt->ar; | ||
79 | |||
77 | lockdep_assert_held(&htt->tx_lock); | 80 | lockdep_assert_held(&htt->tx_lock); |
78 | 81 | ||
79 | if (!test_bit(msdu_id, htt->used_msdu_ids)) | 82 | if (!test_bit(msdu_id, htt->used_msdu_ids)) |
80 | ath10k_warn("trying to free unallocated msdu_id %d\n", msdu_id); | 83 | ath10k_warn(ar, "trying to free unallocated msdu_id %d\n", |
84 | msdu_id); | ||
81 | 85 | ||
82 | ath10k_dbg(ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id); | 86 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id); |
83 | __clear_bit(msdu_id, htt->used_msdu_ids); | 87 | __clear_bit(msdu_id, htt->used_msdu_ids); |
84 | } | 88 | } |
85 | 89 | ||
86 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | 90 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt) |
87 | { | 91 | { |
92 | struct ath10k *ar = htt->ar; | ||
93 | |||
88 | spin_lock_init(&htt->tx_lock); | 94 | spin_lock_init(&htt->tx_lock); |
89 | init_waitqueue_head(&htt->empty_tx_wq); | 95 | init_waitqueue_head(&htt->empty_tx_wq); |
90 | 96 | ||
@@ -93,7 +99,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | |||
93 | else | 99 | else |
94 | htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC; | 100 | htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC; |
95 | 101 | ||
96 | ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", | 102 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", |
97 | htt->max_num_pending_tx); | 103 | htt->max_num_pending_tx); |
98 | 104 | ||
99 | htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) * | 105 | htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) * |
@@ -122,6 +128,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | |||
122 | 128 | ||
123 | static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt) | 129 | static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt) |
124 | { | 130 | { |
131 | struct ath10k *ar = htt->ar; | ||
125 | struct htt_tx_done tx_done = {0}; | 132 | struct htt_tx_done tx_done = {0}; |
126 | int msdu_id; | 133 | int msdu_id; |
127 | 134 | ||
@@ -130,7 +137,7 @@ static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt) | |||
130 | if (!test_bit(msdu_id, htt->used_msdu_ids)) | 137 | if (!test_bit(msdu_id, htt->used_msdu_ids)) |
131 | continue; | 138 | continue; |
132 | 139 | ||
133 | ath10k_dbg(ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", | 140 | ath10k_dbg(ar, ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", |
134 | msdu_id); | 141 | msdu_id); |
135 | 142 | ||
136 | tx_done.discard = 1; | 143 | tx_done.discard = 1; |
@@ -157,6 +164,7 @@ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) | |||
157 | 164 | ||
158 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) | 165 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) |
159 | { | 166 | { |
167 | struct ath10k *ar = htt->ar; | ||
160 | struct sk_buff *skb; | 168 | struct sk_buff *skb; |
161 | struct htt_cmd *cmd; | 169 | struct htt_cmd *cmd; |
162 | int len = 0; | 170 | int len = 0; |
@@ -165,7 +173,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) | |||
165 | len += sizeof(cmd->hdr); | 173 | len += sizeof(cmd->hdr); |
166 | len += sizeof(cmd->ver_req); | 174 | len += sizeof(cmd->ver_req); |
167 | 175 | ||
168 | skb = ath10k_htc_alloc_skb(len); | 176 | skb = ath10k_htc_alloc_skb(ar, len); |
169 | if (!skb) | 177 | if (!skb) |
170 | return -ENOMEM; | 178 | return -ENOMEM; |
171 | 179 | ||
@@ -184,6 +192,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) | |||
184 | 192 | ||
185 | int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) | 193 | int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) |
186 | { | 194 | { |
195 | struct ath10k *ar = htt->ar; | ||
187 | struct htt_stats_req *req; | 196 | struct htt_stats_req *req; |
188 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
189 | struct htt_cmd *cmd; | 198 | struct htt_cmd *cmd; |
@@ -192,7 +201,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) | |||
192 | len += sizeof(cmd->hdr); | 201 | len += sizeof(cmd->hdr); |
193 | len += sizeof(cmd->stats_req); | 202 | len += sizeof(cmd->stats_req); |
194 | 203 | ||
195 | skb = ath10k_htc_alloc_skb(len); | 204 | skb = ath10k_htc_alloc_skb(ar, len); |
196 | if (!skb) | 205 | if (!skb) |
197 | return -ENOMEM; | 206 | return -ENOMEM; |
198 | 207 | ||
@@ -214,7 +223,8 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) | |||
214 | 223 | ||
215 | ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); | 224 | ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); |
216 | if (ret) { | 225 | if (ret) { |
217 | ath10k_warn("failed to send htt type stats request: %d", ret); | 226 | ath10k_warn(ar, "failed to send htt type stats request: %d", |
227 | ret); | ||
218 | dev_kfree_skb_any(skb); | 228 | dev_kfree_skb_any(skb); |
219 | return ret; | 229 | return ret; |
220 | } | 230 | } |
@@ -224,6 +234,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) | |||
224 | 234 | ||
225 | int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) | 235 | int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) |
226 | { | 236 | { |
237 | struct ath10k *ar = htt->ar; | ||
227 | struct sk_buff *skb; | 238 | struct sk_buff *skb; |
228 | struct htt_cmd *cmd; | 239 | struct htt_cmd *cmd; |
229 | struct htt_rx_ring_setup_ring *ring; | 240 | struct htt_rx_ring_setup_ring *ring; |
@@ -242,7 +253,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) | |||
242 | 253 | ||
243 | len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr) | 254 | len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr) |
244 | + (sizeof(*ring) * num_rx_ring); | 255 | + (sizeof(*ring) * num_rx_ring); |
245 | skb = ath10k_htc_alloc_skb(len); | 256 | skb = ath10k_htc_alloc_skb(ar, len); |
246 | if (!skb) | 257 | if (!skb) |
247 | return -ENOMEM; | 258 | return -ENOMEM; |
248 | 259 | ||
@@ -311,6 +322,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, | |||
311 | u8 max_subfrms_ampdu, | 322 | u8 max_subfrms_ampdu, |
312 | u8 max_subfrms_amsdu) | 323 | u8 max_subfrms_amsdu) |
313 | { | 324 | { |
325 | struct ath10k *ar = htt->ar; | ||
314 | struct htt_aggr_conf *aggr_conf; | 326 | struct htt_aggr_conf *aggr_conf; |
315 | struct sk_buff *skb; | 327 | struct sk_buff *skb; |
316 | struct htt_cmd *cmd; | 328 | struct htt_cmd *cmd; |
@@ -328,7 +340,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, | |||
328 | len = sizeof(cmd->hdr); | 340 | len = sizeof(cmd->hdr); |
329 | len += sizeof(cmd->aggr_conf); | 341 | len += sizeof(cmd->aggr_conf); |
330 | 342 | ||
331 | skb = ath10k_htc_alloc_skb(len); | 343 | skb = ath10k_htc_alloc_skb(ar, len); |
332 | if (!skb) | 344 | if (!skb) |
333 | return -ENOMEM; | 345 | return -ENOMEM; |
334 | 346 | ||
@@ -340,7 +352,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, | |||
340 | aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu; | 352 | aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu; |
341 | aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu; | 353 | aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu; |
342 | 354 | ||
343 | ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d", | 355 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d", |
344 | aggr_conf->max_num_amsdu_subframes, | 356 | aggr_conf->max_num_amsdu_subframes, |
345 | aggr_conf->max_num_ampdu_subframes); | 357 | aggr_conf->max_num_ampdu_subframes); |
346 | 358 | ||
@@ -355,7 +367,8 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, | |||
355 | 367 | ||
356 | int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | 368 | int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) |
357 | { | 369 | { |
358 | struct device *dev = htt->ar->dev; | 370 | struct ath10k *ar = htt->ar; |
371 | struct device *dev = ar->dev; | ||
359 | struct sk_buff *txdesc = NULL; | 372 | struct sk_buff *txdesc = NULL; |
360 | struct htt_cmd *cmd; | 373 | struct htt_cmd *cmd; |
361 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); | 374 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); |
@@ -382,7 +395,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | |||
382 | htt->pending_tx[msdu_id] = msdu; | 395 | htt->pending_tx[msdu_id] = msdu; |
383 | spin_unlock_bh(&htt->tx_lock); | 396 | spin_unlock_bh(&htt->tx_lock); |
384 | 397 | ||
385 | txdesc = ath10k_htc_alloc_skb(len); | 398 | txdesc = ath10k_htc_alloc_skb(ar, len); |
386 | if (!txdesc) { | 399 | if (!txdesc) { |
387 | res = -ENOMEM; | 400 | res = -ENOMEM; |
388 | goto err_free_msdu_id; | 401 | goto err_free_msdu_id; |
@@ -429,7 +442,8 @@ err: | |||
429 | 442 | ||
430 | int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | 443 | int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) |
431 | { | 444 | { |
432 | struct device *dev = htt->ar->dev; | 445 | struct ath10k *ar = htt->ar; |
446 | struct device *dev = ar->dev; | ||
433 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; | 447 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; |
434 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); | 448 | struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); |
435 | struct ath10k_hif_sg_item sg_items[2]; | 449 | struct ath10k_hif_sg_item sg_items[2]; |
@@ -545,11 +559,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | |||
545 | skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); | 559 | skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); |
546 | skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); | 560 | skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); |
547 | 561 | ||
548 | ath10k_dbg(ATH10K_DBG_HTT, | 562 | ath10k_dbg(ar, ATH10K_DBG_HTT, |
549 | "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", | 563 | "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", |
550 | flags0, flags1, msdu->len, msdu_id, frags_paddr, | 564 | flags0, flags1, msdu->len, msdu_id, frags_paddr, |
551 | (u32)skb_cb->paddr, vdev_id, tid); | 565 | (u32)skb_cb->paddr, vdev_id, tid); |
552 | ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", | 566 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", |
553 | msdu->data, msdu->len); | 567 | msdu->data, msdu->len); |
554 | 568 | ||
555 | sg_items[0].transfer_id = 0; | 569 | sg_items[0].transfer_id = 0; |
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 007e855f4ba9..13568b01de9f 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
@@ -28,16 +28,19 @@ | |||
28 | #define QCA988X_HW_2_0_CHIP_ID_REV 0x2 | 28 | #define QCA988X_HW_2_0_CHIP_ID_REV 0x2 |
29 | #define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" | 29 | #define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" |
30 | #define QCA988X_HW_2_0_FW_FILE "firmware.bin" | 30 | #define QCA988X_HW_2_0_FW_FILE "firmware.bin" |
31 | #define QCA988X_HW_2_0_FW_2_FILE "firmware-2.bin" | 31 | #define QCA988X_HW_2_0_FW_3_FILE "firmware-3.bin" |
32 | #define QCA988X_HW_2_0_OTP_FILE "otp.bin" | 32 | #define QCA988X_HW_2_0_OTP_FILE "otp.bin" |
33 | #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" | 33 | #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" |
34 | #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 | 34 | #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 |
35 | 35 | ||
36 | #define ATH10K_FW_API2_FILE "firmware-2.bin" | 36 | #define ATH10K_FW_API2_FILE "firmware-2.bin" |
37 | #define ATH10K_FW_API3_FILE "firmware-3.bin" | ||
37 | 38 | ||
38 | /* includes also the null byte */ | 39 | /* includes also the null byte */ |
39 | #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" | 40 | #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" |
40 | 41 | ||
42 | #define REG_DUMP_COUNT_QCA988X 60 | ||
43 | |||
41 | struct ath10k_fw_ie { | 44 | struct ath10k_fw_ie { |
42 | __le32 id; | 45 | __le32 id; |
43 | __le32 len; | 46 | __le32 len; |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 9d61bb157189..b858c8288196 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -36,6 +36,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
36 | enum set_key_cmd cmd, | 36 | enum set_key_cmd cmd, |
37 | const u8 *macaddr) | 37 | const u8 *macaddr) |
38 | { | 38 | { |
39 | struct ath10k *ar = arvif->ar; | ||
39 | struct wmi_vdev_install_key_arg arg = { | 40 | struct wmi_vdev_install_key_arg arg = { |
40 | .vdev_id = arvif->vdev_id, | 41 | .vdev_id = arvif->vdev_id, |
41 | .key_idx = key->keyidx, | 42 | .key_idx = key->keyidx, |
@@ -73,7 +74,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
73 | arg.key_flags = WMI_KEY_PAIRWISE; | 74 | arg.key_flags = WMI_KEY_PAIRWISE; |
74 | break; | 75 | break; |
75 | default: | 76 | default: |
76 | ath10k_warn("cipher %d is not supported\n", key->cipher); | 77 | ath10k_warn(ar, "cipher %d is not supported\n", key->cipher); |
77 | return -EOPNOTSUPP; | 78 | return -EOPNOTSUPP; |
78 | } | 79 | } |
79 | 80 | ||
@@ -168,7 +169,7 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, | |||
168 | first_errno = ret; | 169 | first_errno = ret; |
169 | 170 | ||
170 | if (ret) | 171 | if (ret) |
171 | ath10k_warn("failed to remove peer wep key %d: %d\n", | 172 | ath10k_warn(ar, "failed to remove peer wep key %d: %d\n", |
172 | i, ret); | 173 | i, ret); |
173 | 174 | ||
174 | peer->keys[i] = NULL; | 175 | peer->keys[i] = NULL; |
@@ -216,7 +217,7 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, | |||
216 | first_errno = ret; | 217 | first_errno = ret; |
217 | 218 | ||
218 | if (ret) | 219 | if (ret) |
219 | ath10k_warn("failed to remove key for %pM: %d\n", | 220 | ath10k_warn(ar, "failed to remove key for %pM: %d\n", |
220 | addr, ret); | 221 | addr, ret); |
221 | } | 222 | } |
222 | 223 | ||
@@ -327,14 +328,14 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) | |||
327 | 328 | ||
328 | ret = ath10k_wmi_peer_create(ar, vdev_id, addr); | 329 | ret = ath10k_wmi_peer_create(ar, vdev_id, addr); |
329 | if (ret) { | 330 | if (ret) { |
330 | ath10k_warn("failed to create wmi peer %pM on vdev %i: %i\n", | 331 | ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n", |
331 | addr, vdev_id, ret); | 332 | addr, vdev_id, ret); |
332 | return ret; | 333 | return ret; |
333 | } | 334 | } |
334 | 335 | ||
335 | ret = ath10k_wait_for_peer_created(ar, vdev_id, addr); | 336 | ret = ath10k_wait_for_peer_created(ar, vdev_id, addr); |
336 | if (ret) { | 337 | if (ret) { |
337 | ath10k_warn("failed to wait for created wmi peer %pM on vdev %i: %i\n", | 338 | ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n", |
338 | addr, vdev_id, ret); | 339 | addr, vdev_id, ret); |
339 | return ret; | 340 | return ret; |
340 | } | 341 | } |
@@ -355,7 +356,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif) | |||
355 | ret = ath10k_wmi_pdev_set_param(ar, param, | 356 | ret = ath10k_wmi_pdev_set_param(ar, param, |
356 | ATH10K_KICKOUT_THRESHOLD); | 357 | ATH10K_KICKOUT_THRESHOLD); |
357 | if (ret) { | 358 | if (ret) { |
358 | ath10k_warn("failed to set kickout threshold on vdev %i: %d\n", | 359 | ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n", |
359 | arvif->vdev_id, ret); | 360 | arvif->vdev_id, ret); |
360 | return ret; | 361 | return ret; |
361 | } | 362 | } |
@@ -364,7 +365,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif) | |||
364 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, | 365 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, |
365 | ATH10K_KEEPALIVE_MIN_IDLE); | 366 | ATH10K_KEEPALIVE_MIN_IDLE); |
366 | if (ret) { | 367 | if (ret) { |
367 | ath10k_warn("failed to set keepalive minimum idle time on vdev %i: %d\n", | 368 | ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n", |
368 | arvif->vdev_id, ret); | 369 | arvif->vdev_id, ret); |
369 | return ret; | 370 | return ret; |
370 | } | 371 | } |
@@ -373,7 +374,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif) | |||
373 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, | 374 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, |
374 | ATH10K_KEEPALIVE_MAX_IDLE); | 375 | ATH10K_KEEPALIVE_MAX_IDLE); |
375 | if (ret) { | 376 | if (ret) { |
376 | ath10k_warn("failed to set keepalive maximum idle time on vdev %i: %d\n", | 377 | ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n", |
377 | arvif->vdev_id, ret); | 378 | arvif->vdev_id, ret); |
378 | return ret; | 379 | return ret; |
379 | } | 380 | } |
@@ -382,7 +383,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif) | |||
382 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, | 383 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, |
383 | ATH10K_KEEPALIVE_MAX_UNRESPONSIVE); | 384 | ATH10K_KEEPALIVE_MAX_UNRESPONSIVE); |
384 | if (ret) { | 385 | if (ret) { |
385 | ath10k_warn("failed to set keepalive maximum unresponsive time on vdev %i: %d\n", | 386 | ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n", |
386 | arvif->vdev_id, ret); | 387 | arvif->vdev_id, ret); |
387 | return ret; | 388 | return ret; |
388 | } | 389 | } |
@@ -449,7 +450,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
449 | if (peer->vdev_id != vdev_id) | 450 | if (peer->vdev_id != vdev_id) |
450 | continue; | 451 | continue; |
451 | 452 | ||
452 | ath10k_warn("removing stale peer %pM from vdev_id %d\n", | 453 | ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n", |
453 | peer->addr, vdev_id); | 454 | peer->addr, vdev_id); |
454 | 455 | ||
455 | list_del(&peer->list); | 456 | list_del(&peer->list); |
@@ -496,7 +497,7 @@ static bool ath10k_monitor_is_enabled(struct ath10k *ar) | |||
496 | { | 497 | { |
497 | lockdep_assert_held(&ar->conf_mutex); | 498 | lockdep_assert_held(&ar->conf_mutex); |
498 | 499 | ||
499 | ath10k_dbg(ATH10K_DBG_MAC, | 500 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
500 | "mac monitor refs: promisc %d monitor %d cac %d\n", | 501 | "mac monitor refs: promisc %d monitor %d cac %d\n", |
501 | ar->promisc, ar->monitor, | 502 | ar->promisc, ar->monitor, |
502 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); | 503 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); |
@@ -531,35 +532,35 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) | |||
531 | 532 | ||
532 | ret = ath10k_wmi_vdev_start(ar, &arg); | 533 | ret = ath10k_wmi_vdev_start(ar, &arg); |
533 | if (ret) { | 534 | if (ret) { |
534 | ath10k_warn("failed to request monitor vdev %i start: %d\n", | 535 | ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n", |
535 | vdev_id, ret); | 536 | vdev_id, ret); |
536 | return ret; | 537 | return ret; |
537 | } | 538 | } |
538 | 539 | ||
539 | ret = ath10k_vdev_setup_sync(ar); | 540 | ret = ath10k_vdev_setup_sync(ar); |
540 | if (ret) { | 541 | if (ret) { |
541 | ath10k_warn("failed to synchronize setup for monitor vdev %i: %d\n", | 542 | ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n", |
542 | vdev_id, ret); | 543 | vdev_id, ret); |
543 | return ret; | 544 | return ret; |
544 | } | 545 | } |
545 | 546 | ||
546 | ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); | 547 | ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); |
547 | if (ret) { | 548 | if (ret) { |
548 | ath10k_warn("failed to put up monitor vdev %i: %d\n", | 549 | ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n", |
549 | vdev_id, ret); | 550 | vdev_id, ret); |
550 | goto vdev_stop; | 551 | goto vdev_stop; |
551 | } | 552 | } |
552 | 553 | ||
553 | ar->monitor_vdev_id = vdev_id; | 554 | ar->monitor_vdev_id = vdev_id; |
554 | 555 | ||
555 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i started\n", | 556 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n", |
556 | ar->monitor_vdev_id); | 557 | ar->monitor_vdev_id); |
557 | return 0; | 558 | return 0; |
558 | 559 | ||
559 | vdev_stop: | 560 | vdev_stop: |
560 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); | 561 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); |
561 | if (ret) | 562 | if (ret) |
562 | ath10k_warn("failed to stop monitor vdev %i after start failure: %d\n", | 563 | ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n", |
563 | ar->monitor_vdev_id, ret); | 564 | ar->monitor_vdev_id, ret); |
564 | 565 | ||
565 | return ret; | 566 | return ret; |
@@ -573,20 +574,20 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar) | |||
573 | 574 | ||
574 | ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); | 575 | ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); |
575 | if (ret) | 576 | if (ret) |
576 | ath10k_warn("failed to put down monitor vdev %i: %d\n", | 577 | ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n", |
577 | ar->monitor_vdev_id, ret); | 578 | ar->monitor_vdev_id, ret); |
578 | 579 | ||
579 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); | 580 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); |
580 | if (ret) | 581 | if (ret) |
581 | ath10k_warn("failed to to request monitor vdev %i stop: %d\n", | 582 | ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n", |
582 | ar->monitor_vdev_id, ret); | 583 | ar->monitor_vdev_id, ret); |
583 | 584 | ||
584 | ret = ath10k_vdev_setup_sync(ar); | 585 | ret = ath10k_vdev_setup_sync(ar); |
585 | if (ret) | 586 | if (ret) |
586 | ath10k_warn("failed to synchronise monitor vdev %i: %d\n", | 587 | ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n", |
587 | ar->monitor_vdev_id, ret); | 588 | ar->monitor_vdev_id, ret); |
588 | 589 | ||
589 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", | 590 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", |
590 | ar->monitor_vdev_id); | 591 | ar->monitor_vdev_id); |
591 | return ret; | 592 | return ret; |
592 | } | 593 | } |
@@ -597,35 +598,29 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar) | |||
597 | 598 | ||
598 | lockdep_assert_held(&ar->conf_mutex); | 599 | lockdep_assert_held(&ar->conf_mutex); |
599 | 600 | ||
600 | bit = ffs(ar->free_vdev_map); | 601 | if (ar->free_vdev_map == 0) { |
601 | if (bit == 0) { | 602 | ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n"); |
602 | ath10k_warn("failed to find free vdev id for monitor vdev\n"); | ||
603 | return -ENOMEM; | 603 | return -ENOMEM; |
604 | } | 604 | } |
605 | 605 | ||
606 | bit = ffs(ar->free_vdev_map); | ||
607 | |||
606 | ar->monitor_vdev_id = bit - 1; | 608 | ar->monitor_vdev_id = bit - 1; |
607 | ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); | ||
608 | 609 | ||
609 | ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id, | 610 | ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id, |
610 | WMI_VDEV_TYPE_MONITOR, | 611 | WMI_VDEV_TYPE_MONITOR, |
611 | 0, ar->mac_addr); | 612 | 0, ar->mac_addr); |
612 | if (ret) { | 613 | if (ret) { |
613 | ath10k_warn("failed to request monitor vdev %i creation: %d\n", | 614 | ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n", |
614 | ar->monitor_vdev_id, ret); | 615 | ar->monitor_vdev_id, ret); |
615 | goto vdev_fail; | 616 | return ret; |
616 | } | 617 | } |
617 | 618 | ||
618 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", | 619 | ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); |
620 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n", | ||
619 | ar->monitor_vdev_id); | 621 | ar->monitor_vdev_id); |
620 | 622 | ||
621 | return 0; | 623 | return 0; |
622 | |||
623 | vdev_fail: | ||
624 | /* | ||
625 | * Restore the ID to the global map. | ||
626 | */ | ||
627 | ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); | ||
628 | return ret; | ||
629 | } | 624 | } |
630 | 625 | ||
631 | static int ath10k_monitor_vdev_delete(struct ath10k *ar) | 626 | static int ath10k_monitor_vdev_delete(struct ath10k *ar) |
@@ -636,14 +631,14 @@ static int ath10k_monitor_vdev_delete(struct ath10k *ar) | |||
636 | 631 | ||
637 | ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id); | 632 | ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id); |
638 | if (ret) { | 633 | if (ret) { |
639 | ath10k_warn("failed to request wmi monitor vdev %i removal: %d\n", | 634 | ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n", |
640 | ar->monitor_vdev_id, ret); | 635 | ar->monitor_vdev_id, ret); |
641 | return ret; | 636 | return ret; |
642 | } | 637 | } |
643 | 638 | ||
644 | ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); | 639 | ar->free_vdev_map |= 1 << ar->monitor_vdev_id; |
645 | 640 | ||
646 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", | 641 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", |
647 | ar->monitor_vdev_id); | 642 | ar->monitor_vdev_id); |
648 | return ret; | 643 | return ret; |
649 | } | 644 | } |
@@ -655,30 +650,30 @@ static int ath10k_monitor_start(struct ath10k *ar) | |||
655 | lockdep_assert_held(&ar->conf_mutex); | 650 | lockdep_assert_held(&ar->conf_mutex); |
656 | 651 | ||
657 | if (!ath10k_monitor_is_enabled(ar)) { | 652 | if (!ath10k_monitor_is_enabled(ar)) { |
658 | ath10k_warn("trying to start monitor with no references\n"); | 653 | ath10k_warn(ar, "trying to start monitor with no references\n"); |
659 | return 0; | 654 | return 0; |
660 | } | 655 | } |
661 | 656 | ||
662 | if (ar->monitor_started) { | 657 | if (ar->monitor_started) { |
663 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor already started\n"); | 658 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor already started\n"); |
664 | return 0; | 659 | return 0; |
665 | } | 660 | } |
666 | 661 | ||
667 | ret = ath10k_monitor_vdev_create(ar); | 662 | ret = ath10k_monitor_vdev_create(ar); |
668 | if (ret) { | 663 | if (ret) { |
669 | ath10k_warn("failed to create monitor vdev: %d\n", ret); | 664 | ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); |
670 | return ret; | 665 | return ret; |
671 | } | 666 | } |
672 | 667 | ||
673 | ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); | 668 | ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); |
674 | if (ret) { | 669 | if (ret) { |
675 | ath10k_warn("failed to start monitor vdev: %d\n", ret); | 670 | ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret); |
676 | ath10k_monitor_vdev_delete(ar); | 671 | ath10k_monitor_vdev_delete(ar); |
677 | return ret; | 672 | return ret; |
678 | } | 673 | } |
679 | 674 | ||
680 | ar->monitor_started = true; | 675 | ar->monitor_started = true; |
681 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor started\n"); | 676 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n"); |
682 | 677 | ||
683 | return 0; | 678 | return 0; |
684 | } | 679 | } |
@@ -690,27 +685,27 @@ static void ath10k_monitor_stop(struct ath10k *ar) | |||
690 | lockdep_assert_held(&ar->conf_mutex); | 685 | lockdep_assert_held(&ar->conf_mutex); |
691 | 686 | ||
692 | if (ath10k_monitor_is_enabled(ar)) { | 687 | if (ath10k_monitor_is_enabled(ar)) { |
693 | ath10k_dbg(ATH10K_DBG_MAC, | 688 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
694 | "mac monitor will be stopped later\n"); | 689 | "mac monitor will be stopped later\n"); |
695 | return; | 690 | return; |
696 | } | 691 | } |
697 | 692 | ||
698 | if (!ar->monitor_started) { | 693 | if (!ar->monitor_started) { |
699 | ath10k_dbg(ATH10K_DBG_MAC, | 694 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
700 | "mac monitor probably failed to start earlier\n"); | 695 | "mac monitor probably failed to start earlier\n"); |
701 | return; | 696 | return; |
702 | } | 697 | } |
703 | 698 | ||
704 | ret = ath10k_monitor_vdev_stop(ar); | 699 | ret = ath10k_monitor_vdev_stop(ar); |
705 | if (ret) | 700 | if (ret) |
706 | ath10k_warn("failed to stop monitor vdev: %d\n", ret); | 701 | ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); |
707 | 702 | ||
708 | ret = ath10k_monitor_vdev_delete(ar); | 703 | ret = ath10k_monitor_vdev_delete(ar); |
709 | if (ret) | 704 | if (ret) |
710 | ath10k_warn("failed to delete monitor vdev: %d\n", ret); | 705 | ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); |
711 | 706 | ||
712 | ar->monitor_started = false; | 707 | ar->monitor_started = false; |
713 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor stopped\n"); | 708 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); |
714 | } | 709 | } |
715 | 710 | ||
716 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) | 711 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) |
@@ -743,12 +738,12 @@ static int ath10k_start_cac(struct ath10k *ar) | |||
743 | 738 | ||
744 | ret = ath10k_monitor_start(ar); | 739 | ret = ath10k_monitor_start(ar); |
745 | if (ret) { | 740 | if (ret) { |
746 | ath10k_warn("failed to start monitor (cac): %d\n", ret); | 741 | ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); |
747 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 742 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
748 | return ret; | 743 | return ret; |
749 | } | 744 | } |
750 | 745 | ||
751 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", | 746 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", |
752 | ar->monitor_vdev_id); | 747 | ar->monitor_vdev_id); |
753 | 748 | ||
754 | return 0; | 749 | return 0; |
@@ -765,7 +760,7 @@ static int ath10k_stop_cac(struct ath10k *ar) | |||
765 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 760 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
766 | ath10k_monitor_stop(ar); | 761 | ath10k_monitor_stop(ar); |
767 | 762 | ||
768 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n"); | 763 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n"); |
769 | 764 | ||
770 | return 0; | 765 | return 0; |
771 | } | 766 | } |
@@ -791,12 +786,12 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar) | |||
791 | * radiation is not allowed, make this channel DFS_UNAVAILABLE | 786 | * radiation is not allowed, make this channel DFS_UNAVAILABLE |
792 | * by indicating that radar was detected. | 787 | * by indicating that radar was detected. |
793 | */ | 788 | */ |
794 | ath10k_warn("failed to start CAC: %d\n", ret); | 789 | ath10k_warn(ar, "failed to start CAC: %d\n", ret); |
795 | ieee80211_radar_detected(ar->hw); | 790 | ieee80211_radar_detected(ar->hw); |
796 | } | 791 | } |
797 | } | 792 | } |
798 | 793 | ||
799 | static int ath10k_vdev_start(struct ath10k_vif *arvif) | 794 | static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart) |
800 | { | 795 | { |
801 | struct ath10k *ar = arvif->ar; | 796 | struct ath10k *ar = arvif->ar; |
802 | struct cfg80211_chan_def *chandef = &ar->chandef; | 797 | struct cfg80211_chan_def *chandef = &ar->chandef; |
@@ -833,21 +828,25 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) | |||
833 | arg.ssid_len = arvif->vif->bss_conf.ssid_len; | 828 | arg.ssid_len = arvif->vif->bss_conf.ssid_len; |
834 | } | 829 | } |
835 | 830 | ||
836 | ath10k_dbg(ATH10K_DBG_MAC, | 831 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
837 | "mac vdev %d start center_freq %d phymode %s\n", | 832 | "mac vdev %d start center_freq %d phymode %s\n", |
838 | arg.vdev_id, arg.channel.freq, | 833 | arg.vdev_id, arg.channel.freq, |
839 | ath10k_wmi_phymode_str(arg.channel.mode)); | 834 | ath10k_wmi_phymode_str(arg.channel.mode)); |
840 | 835 | ||
841 | ret = ath10k_wmi_vdev_start(ar, &arg); | 836 | if (restart) |
837 | ret = ath10k_wmi_vdev_restart(ar, &arg); | ||
838 | else | ||
839 | ret = ath10k_wmi_vdev_start(ar, &arg); | ||
840 | |||
842 | if (ret) { | 841 | if (ret) { |
843 | ath10k_warn("failed to start WMI vdev %i: %d\n", | 842 | ath10k_warn(ar, "failed to start WMI vdev %i: %d\n", |
844 | arg.vdev_id, ret); | 843 | arg.vdev_id, ret); |
845 | return ret; | 844 | return ret; |
846 | } | 845 | } |
847 | 846 | ||
848 | ret = ath10k_vdev_setup_sync(ar); | 847 | ret = ath10k_vdev_setup_sync(ar); |
849 | if (ret) { | 848 | if (ret) { |
850 | ath10k_warn("failed to synchronise setup for vdev %i: %d\n", | 849 | ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n", |
851 | arg.vdev_id, ret); | 850 | arg.vdev_id, ret); |
852 | return ret; | 851 | return ret; |
853 | } | 852 | } |
@@ -858,6 +857,16 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) | |||
858 | return ret; | 857 | return ret; |
859 | } | 858 | } |
860 | 859 | ||
860 | static int ath10k_vdev_start(struct ath10k_vif *arvif) | ||
861 | { | ||
862 | return ath10k_vdev_start_restart(arvif, false); | ||
863 | } | ||
864 | |||
865 | static int ath10k_vdev_restart(struct ath10k_vif *arvif) | ||
866 | { | ||
867 | return ath10k_vdev_start_restart(arvif, true); | ||
868 | } | ||
869 | |||
861 | static int ath10k_vdev_stop(struct ath10k_vif *arvif) | 870 | static int ath10k_vdev_stop(struct ath10k_vif *arvif) |
862 | { | 871 | { |
863 | struct ath10k *ar = arvif->ar; | 872 | struct ath10k *ar = arvif->ar; |
@@ -869,14 +878,14 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) | |||
869 | 878 | ||
870 | ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); | 879 | ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); |
871 | if (ret) { | 880 | if (ret) { |
872 | ath10k_warn("failed to stop WMI vdev %i: %d\n", | 881 | ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n", |
873 | arvif->vdev_id, ret); | 882 | arvif->vdev_id, ret); |
874 | return ret; | 883 | return ret; |
875 | } | 884 | } |
876 | 885 | ||
877 | ret = ath10k_vdev_setup_sync(ar); | 886 | ret = ath10k_vdev_setup_sync(ar); |
878 | if (ret) { | 887 | if (ret) { |
879 | ath10k_warn("failed to syncronise setup for vdev %i: %d\n", | 888 | ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n", |
880 | arvif->vdev_id, ret); | 889 | arvif->vdev_id, ret); |
881 | return ret; | 890 | return ret; |
882 | } | 891 | } |
@@ -894,6 +903,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) | |||
894 | static void ath10k_control_beaconing(struct ath10k_vif *arvif, | 903 | static void ath10k_control_beaconing(struct ath10k_vif *arvif, |
895 | struct ieee80211_bss_conf *info) | 904 | struct ieee80211_bss_conf *info) |
896 | { | 905 | { |
906 | struct ath10k *ar = arvif->ar; | ||
897 | int ret = 0; | 907 | int ret = 0; |
898 | 908 | ||
899 | lockdep_assert_held(&arvif->ar->conf_mutex); | 909 | lockdep_assert_held(&arvif->ar->conf_mutex); |
@@ -931,7 +941,7 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, | |||
931 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, | 941 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, |
932 | arvif->bssid); | 942 | arvif->bssid); |
933 | if (ret) { | 943 | if (ret) { |
934 | ath10k_warn("failed to bring up vdev %d: %i\n", | 944 | ath10k_warn(ar, "failed to bring up vdev %d: %i\n", |
935 | arvif->vdev_id, ret); | 945 | arvif->vdev_id, ret); |
936 | ath10k_vdev_stop(arvif); | 946 | ath10k_vdev_stop(arvif); |
937 | return; | 947 | return; |
@@ -940,13 +950,14 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, | |||
940 | arvif->is_started = true; | 950 | arvif->is_started = true; |
941 | arvif->is_up = true; | 951 | arvif->is_up = true; |
942 | 952 | ||
943 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); | 953 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); |
944 | } | 954 | } |
945 | 955 | ||
946 | static void ath10k_control_ibss(struct ath10k_vif *arvif, | 956 | static void ath10k_control_ibss(struct ath10k_vif *arvif, |
947 | struct ieee80211_bss_conf *info, | 957 | struct ieee80211_bss_conf *info, |
948 | const u8 self_peer[ETH_ALEN]) | 958 | const u8 self_peer[ETH_ALEN]) |
949 | { | 959 | { |
960 | struct ath10k *ar = arvif->ar; | ||
950 | u32 vdev_param; | 961 | u32 vdev_param; |
951 | int ret = 0; | 962 | int ret = 0; |
952 | 963 | ||
@@ -955,7 +966,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, | |||
955 | if (!info->ibss_joined) { | 966 | if (!info->ibss_joined) { |
956 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); | 967 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); |
957 | if (ret) | 968 | if (ret) |
958 | ath10k_warn("failed to delete IBSS self peer %pM for vdev %d: %d\n", | 969 | ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n", |
959 | self_peer, arvif->vdev_id, ret); | 970 | self_peer, arvif->vdev_id, ret); |
960 | 971 | ||
961 | if (is_zero_ether_addr(arvif->bssid)) | 972 | if (is_zero_ether_addr(arvif->bssid)) |
@@ -964,7 +975,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, | |||
964 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, | 975 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, |
965 | arvif->bssid); | 976 | arvif->bssid); |
966 | if (ret) { | 977 | if (ret) { |
967 | ath10k_warn("failed to delete IBSS BSSID peer %pM for vdev %d: %d\n", | 978 | ath10k_warn(ar, "failed to delete IBSS BSSID peer %pM for vdev %d: %d\n", |
968 | arvif->bssid, arvif->vdev_id, ret); | 979 | arvif->bssid, arvif->vdev_id, ret); |
969 | return; | 980 | return; |
970 | } | 981 | } |
@@ -976,7 +987,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, | |||
976 | 987 | ||
977 | ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer); | 988 | ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer); |
978 | if (ret) { | 989 | if (ret) { |
979 | ath10k_warn("failed to create IBSS self peer %pM for vdev %d: %d\n", | 990 | ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n", |
980 | self_peer, arvif->vdev_id, ret); | 991 | self_peer, arvif->vdev_id, ret); |
981 | return; | 992 | return; |
982 | } | 993 | } |
@@ -985,7 +996,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, | |||
985 | ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param, | 996 | ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param, |
986 | ATH10K_DEFAULT_ATIM); | 997 | ATH10K_DEFAULT_ATIM); |
987 | if (ret) | 998 | if (ret) |
988 | ath10k_warn("failed to set IBSS ATIM for vdev %d: %d\n", | 999 | ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n", |
989 | arvif->vdev_id, ret); | 1000 | arvif->vdev_id, ret); |
990 | } | 1001 | } |
991 | 1002 | ||
@@ -1012,7 +1023,7 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) | |||
1012 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, | 1023 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, |
1013 | conf->dynamic_ps_timeout); | 1024 | conf->dynamic_ps_timeout); |
1014 | if (ret) { | 1025 | if (ret) { |
1015 | ath10k_warn("failed to set inactivity time for vdev %d: %i\n", | 1026 | ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n", |
1016 | arvif->vdev_id, ret); | 1027 | arvif->vdev_id, ret); |
1017 | return ret; | 1028 | return ret; |
1018 | } | 1029 | } |
@@ -1020,12 +1031,12 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) | |||
1020 | psmode = WMI_STA_PS_MODE_DISABLED; | 1031 | psmode = WMI_STA_PS_MODE_DISABLED; |
1021 | } | 1032 | } |
1022 | 1033 | ||
1023 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d psmode %s\n", | 1034 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n", |
1024 | arvif->vdev_id, psmode ? "enable" : "disable"); | 1035 | arvif->vdev_id, psmode ? "enable" : "disable"); |
1025 | 1036 | ||
1026 | ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode); | 1037 | ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode); |
1027 | if (ret) { | 1038 | if (ret) { |
1028 | ath10k_warn("failed to set PS Mode %d for vdev %d: %d\n", | 1039 | ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n", |
1029 | psmode, arvif->vdev_id, ret); | 1040 | psmode, arvif->vdev_id, ret); |
1030 | return ret; | 1041 | return ret; |
1031 | } | 1042 | } |
@@ -1109,12 +1120,12 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, | |||
1109 | 1120 | ||
1110 | /* FIXME: base on RSN IE/WPA IE is a correct idea? */ | 1121 | /* FIXME: base on RSN IE/WPA IE is a correct idea? */ |
1111 | if (rsnie || wpaie) { | 1122 | if (rsnie || wpaie) { |
1112 | ath10k_dbg(ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__); | 1123 | ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__); |
1113 | arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; | 1124 | arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; |
1114 | } | 1125 | } |
1115 | 1126 | ||
1116 | if (wpaie) { | 1127 | if (wpaie) { |
1117 | ath10k_dbg(ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__); | 1128 | ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__); |
1118 | arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; | 1129 | arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; |
1119 | } | 1130 | } |
1120 | } | 1131 | } |
@@ -1223,7 +1234,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, | |||
1223 | arg->peer_num_spatial_streams = sta->rx_nss; | 1234 | arg->peer_num_spatial_streams = sta->rx_nss; |
1224 | } | 1235 | } |
1225 | 1236 | ||
1226 | ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", | 1237 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", |
1227 | arg->addr, | 1238 | arg->addr, |
1228 | arg->peer_ht_rates.num_rates, | 1239 | arg->peer_ht_rates.num_rates, |
1229 | arg->peer_num_spatial_streams); | 1240 | arg->peer_num_spatial_streams); |
@@ -1240,7 +1251,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1240 | lockdep_assert_held(&ar->conf_mutex); | 1251 | lockdep_assert_held(&ar->conf_mutex); |
1241 | 1252 | ||
1242 | if (sta->wme && sta->uapsd_queues) { | 1253 | if (sta->wme && sta->uapsd_queues) { |
1243 | ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", | 1254 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", |
1244 | sta->uapsd_queues, sta->max_sp); | 1255 | sta->uapsd_queues, sta->max_sp); |
1245 | 1256 | ||
1246 | if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) | 1257 | if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) |
@@ -1265,7 +1276,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1265 | WMI_AP_PS_PEER_PARAM_UAPSD, | 1276 | WMI_AP_PS_PEER_PARAM_UAPSD, |
1266 | uapsd); | 1277 | uapsd); |
1267 | if (ret) { | 1278 | if (ret) { |
1268 | ath10k_warn("failed to set ap ps peer param uapsd for vdev %i: %d\n", | 1279 | ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n", |
1269 | arvif->vdev_id, ret); | 1280 | arvif->vdev_id, ret); |
1270 | return ret; | 1281 | return ret; |
1271 | } | 1282 | } |
@@ -1275,7 +1286,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1275 | WMI_AP_PS_PEER_PARAM_MAX_SP, | 1286 | WMI_AP_PS_PEER_PARAM_MAX_SP, |
1276 | max_sp); | 1287 | max_sp); |
1277 | if (ret) { | 1288 | if (ret) { |
1278 | ath10k_warn("failed to set ap ps peer param max sp for vdev %i: %d\n", | 1289 | ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n", |
1279 | arvif->vdev_id, ret); | 1290 | arvif->vdev_id, ret); |
1280 | return ret; | 1291 | return ret; |
1281 | } | 1292 | } |
@@ -1287,7 +1298,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1287 | ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr, | 1298 | ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr, |
1288 | WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10); | 1299 | WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10); |
1289 | if (ret) { | 1300 | if (ret) { |
1290 | ath10k_warn("failed to set ap ps peer param ageout time for vdev %i: %d\n", | 1301 | ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n", |
1291 | arvif->vdev_id, ret); | 1302 | arvif->vdev_id, ret); |
1292 | return ret; | 1303 | return ret; |
1293 | } | 1304 | } |
@@ -1334,7 +1345,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, | |||
1334 | arg->peer_vht_rates.tx_mcs_set = | 1345 | arg->peer_vht_rates.tx_mcs_set = |
1335 | __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); | 1346 | __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); |
1336 | 1347 | ||
1337 | ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", | 1348 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", |
1338 | sta->addr, arg->peer_max_mpdu, arg->peer_flags); | 1349 | sta->addr, arg->peer_max_mpdu, arg->peer_flags); |
1339 | } | 1350 | } |
1340 | 1351 | ||
@@ -1407,7 +1418,7 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, | |||
1407 | break; | 1418 | break; |
1408 | } | 1419 | } |
1409 | 1420 | ||
1410 | ath10k_dbg(ATH10K_DBG_MAC, "mac peer %pM phymode %s\n", | 1421 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n", |
1411 | sta->addr, ath10k_wmi_phymode_str(phymode)); | 1422 | sta->addr, ath10k_wmi_phymode_str(phymode)); |
1412 | 1423 | ||
1413 | arg->peer_phymode = phymode; | 1424 | arg->peer_phymode = phymode; |
@@ -1480,7 +1491,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1480 | 1491 | ||
1481 | ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); | 1492 | ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); |
1482 | if (!ap_sta) { | 1493 | if (!ap_sta) { |
1483 | ath10k_warn("failed to find station entry for bss %pM vdev %i\n", | 1494 | ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n", |
1484 | bss_conf->bssid, arvif->vdev_id); | 1495 | bss_conf->bssid, arvif->vdev_id); |
1485 | rcu_read_unlock(); | 1496 | rcu_read_unlock(); |
1486 | return; | 1497 | return; |
@@ -1493,7 +1504,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1493 | ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, | 1504 | ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, |
1494 | bss_conf, &peer_arg); | 1505 | bss_conf, &peer_arg); |
1495 | if (ret) { | 1506 | if (ret) { |
1496 | ath10k_warn("failed to prepare peer assoc for %pM vdev %i: %d\n", | 1507 | ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n", |
1497 | bss_conf->bssid, arvif->vdev_id, ret); | 1508 | bss_conf->bssid, arvif->vdev_id, ret); |
1498 | rcu_read_unlock(); | 1509 | rcu_read_unlock(); |
1499 | return; | 1510 | return; |
@@ -1503,19 +1514,19 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1503 | 1514 | ||
1504 | ret = ath10k_wmi_peer_assoc(ar, &peer_arg); | 1515 | ret = ath10k_wmi_peer_assoc(ar, &peer_arg); |
1505 | if (ret) { | 1516 | if (ret) { |
1506 | ath10k_warn("failed to run peer assoc for %pM vdev %i: %d\n", | 1517 | ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n", |
1507 | bss_conf->bssid, arvif->vdev_id, ret); | 1518 | bss_conf->bssid, arvif->vdev_id, ret); |
1508 | return; | 1519 | return; |
1509 | } | 1520 | } |
1510 | 1521 | ||
1511 | ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap); | 1522 | ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap); |
1512 | if (ret) { | 1523 | if (ret) { |
1513 | ath10k_warn("failed to setup peer SMPS for vdev %i: %d\n", | 1524 | ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n", |
1514 | arvif->vdev_id, ret); | 1525 | arvif->vdev_id, ret); |
1515 | return; | 1526 | return; |
1516 | } | 1527 | } |
1517 | 1528 | ||
1518 | ath10k_dbg(ATH10K_DBG_MAC, | 1529 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
1519 | "mac vdev %d up (associated) bssid %pM aid %d\n", | 1530 | "mac vdev %d up (associated) bssid %pM aid %d\n", |
1520 | arvif->vdev_id, bss_conf->bssid, bss_conf->aid); | 1531 | arvif->vdev_id, bss_conf->bssid, bss_conf->aid); |
1521 | 1532 | ||
@@ -1524,7 +1535,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1524 | 1535 | ||
1525 | ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); | 1536 | ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); |
1526 | if (ret) { | 1537 | if (ret) { |
1527 | ath10k_warn("failed to set vdev %d up: %d\n", | 1538 | ath10k_warn(ar, "failed to set vdev %d up: %d\n", |
1528 | arvif->vdev_id, ret); | 1539 | arvif->vdev_id, ret); |
1529 | return; | 1540 | return; |
1530 | } | 1541 | } |
@@ -1550,7 +1561,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, | |||
1550 | * No idea why this happens, even though VDEV-DOWN is supposed | 1561 | * No idea why this happens, even though VDEV-DOWN is supposed |
1551 | * to be analogous to link down, so just stop the VDEV. | 1562 | * to be analogous to link down, so just stop the VDEV. |
1552 | */ | 1563 | */ |
1553 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n", | 1564 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n", |
1554 | arvif->vdev_id); | 1565 | arvif->vdev_id); |
1555 | 1566 | ||
1556 | /* FIXME: check return value */ | 1567 | /* FIXME: check return value */ |
@@ -1563,7 +1574,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, | |||
1563 | * interfaces as it expects there is no rx when no interface is | 1574 | * interfaces as it expects there is no rx when no interface is |
1564 | * running. | 1575 | * running. |
1565 | */ | 1576 | */ |
1566 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id); | 1577 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id); |
1567 | 1578 | ||
1568 | /* FIXME: why don't we print error if wmi call fails? */ | 1579 | /* FIXME: why don't we print error if wmi call fails? */ |
1569 | ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); | 1580 | ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); |
@@ -1584,7 +1595,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1584 | 1595 | ||
1585 | ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg); | 1596 | ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg); |
1586 | if (ret) { | 1597 | if (ret) { |
1587 | ath10k_warn("failed to prepare WMI peer assoc for %pM vdev %i: %i\n", | 1598 | ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n", |
1588 | sta->addr, arvif->vdev_id, ret); | 1599 | sta->addr, arvif->vdev_id, ret); |
1589 | return ret; | 1600 | return ret; |
1590 | } | 1601 | } |
@@ -1592,14 +1603,14 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1592 | peer_arg.peer_reassoc = reassoc; | 1603 | peer_arg.peer_reassoc = reassoc; |
1593 | ret = ath10k_wmi_peer_assoc(ar, &peer_arg); | 1604 | ret = ath10k_wmi_peer_assoc(ar, &peer_arg); |
1594 | if (ret) { | 1605 | if (ret) { |
1595 | ath10k_warn("failed to run peer assoc for STA %pM vdev %i: %d\n", | 1606 | ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n", |
1596 | sta->addr, arvif->vdev_id, ret); | 1607 | sta->addr, arvif->vdev_id, ret); |
1597 | return ret; | 1608 | return ret; |
1598 | } | 1609 | } |
1599 | 1610 | ||
1600 | ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap); | 1611 | ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap); |
1601 | if (ret) { | 1612 | if (ret) { |
1602 | ath10k_warn("failed to setup peer SMPS for vdev %d: %d\n", | 1613 | ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n", |
1603 | arvif->vdev_id, ret); | 1614 | arvif->vdev_id, ret); |
1604 | return ret; | 1615 | return ret; |
1605 | } | 1616 | } |
@@ -1608,7 +1619,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1608 | arvif->num_legacy_stations++; | 1619 | arvif->num_legacy_stations++; |
1609 | ret = ath10k_recalc_rtscts_prot(arvif); | 1620 | ret = ath10k_recalc_rtscts_prot(arvif); |
1610 | if (ret) { | 1621 | if (ret) { |
1611 | ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", | 1622 | ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", |
1612 | arvif->vdev_id, ret); | 1623 | arvif->vdev_id, ret); |
1613 | return ret; | 1624 | return ret; |
1614 | } | 1625 | } |
@@ -1616,14 +1627,14 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1616 | 1627 | ||
1617 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); | 1628 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); |
1618 | if (ret) { | 1629 | if (ret) { |
1619 | ath10k_warn("failed to install peer wep keys for vdev %i: %d\n", | 1630 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", |
1620 | arvif->vdev_id, ret); | 1631 | arvif->vdev_id, ret); |
1621 | return ret; | 1632 | return ret; |
1622 | } | 1633 | } |
1623 | 1634 | ||
1624 | ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); | 1635 | ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); |
1625 | if (ret) { | 1636 | if (ret) { |
1626 | ath10k_warn("failed to set qos params for STA %pM for vdev %i: %d\n", | 1637 | ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n", |
1627 | sta->addr, arvif->vdev_id, ret); | 1638 | sta->addr, arvif->vdev_id, ret); |
1628 | return ret; | 1639 | return ret; |
1629 | } | 1640 | } |
@@ -1642,7 +1653,7 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1642 | arvif->num_legacy_stations--; | 1653 | arvif->num_legacy_stations--; |
1643 | ret = ath10k_recalc_rtscts_prot(arvif); | 1654 | ret = ath10k_recalc_rtscts_prot(arvif); |
1644 | if (ret) { | 1655 | if (ret) { |
1645 | ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", | 1656 | ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", |
1646 | arvif->vdev_id, ret); | 1657 | arvif->vdev_id, ret); |
1647 | return ret; | 1658 | return ret; |
1648 | } | 1659 | } |
@@ -1650,7 +1661,7 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1650 | 1661 | ||
1651 | ret = ath10k_clear_peer_keys(arvif, sta->addr); | 1662 | ret = ath10k_clear_peer_keys(arvif, sta->addr); |
1652 | if (ret) { | 1663 | if (ret) { |
1653 | ath10k_warn("failed to clear all peer wep keys for vdev %i: %d\n", | 1664 | ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n", |
1654 | arvif->vdev_id, ret); | 1665 | arvif->vdev_id, ret); |
1655 | return ret; | 1666 | return ret; |
1656 | } | 1667 | } |
@@ -1742,7 +1753,7 @@ static int ath10k_update_channel_list(struct ath10k *ar) | |||
1742 | if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN)) | 1753 | if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN)) |
1743 | continue; | 1754 | continue; |
1744 | 1755 | ||
1745 | ath10k_dbg(ATH10K_DBG_WMI, | 1756 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
1746 | "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", | 1757 | "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", |
1747 | ch - arg.channels, arg.n_channels, | 1758 | ch - arg.channels, arg.n_channels, |
1748 | ch->freq, ch->max_power, ch->max_reg_power, | 1759 | ch->freq, ch->max_power, ch->max_reg_power, |
@@ -1785,7 +1796,7 @@ static void ath10k_regd_update(struct ath10k *ar) | |||
1785 | 1796 | ||
1786 | ret = ath10k_update_channel_list(ar); | 1797 | ret = ath10k_update_channel_list(ar); |
1787 | if (ret) | 1798 | if (ret) |
1788 | ath10k_warn("failed to update channel list: %d\n", ret); | 1799 | ath10k_warn(ar, "failed to update channel list: %d\n", ret); |
1789 | 1800 | ||
1790 | regpair = ar->ath_common.regulatory.regpair; | 1801 | regpair = ar->ath_common.regulatory.regpair; |
1791 | 1802 | ||
@@ -1806,7 +1817,7 @@ static void ath10k_regd_update(struct ath10k *ar) | |||
1806 | regpair->reg_5ghz_ctl, | 1817 | regpair->reg_5ghz_ctl, |
1807 | wmi_dfs_reg); | 1818 | wmi_dfs_reg); |
1808 | if (ret) | 1819 | if (ret) |
1809 | ath10k_warn("failed to set pdev regdomain: %d\n", ret); | 1820 | ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret); |
1810 | } | 1821 | } |
1811 | 1822 | ||
1812 | static void ath10k_reg_notifier(struct wiphy *wiphy, | 1823 | static void ath10k_reg_notifier(struct wiphy *wiphy, |
@@ -1819,12 +1830,12 @@ static void ath10k_reg_notifier(struct wiphy *wiphy, | |||
1819 | ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); | 1830 | ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); |
1820 | 1831 | ||
1821 | if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) { | 1832 | if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) { |
1822 | ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs region 0x%x\n", | 1833 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n", |
1823 | request->dfs_region); | 1834 | request->dfs_region); |
1824 | result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector, | 1835 | result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector, |
1825 | request->dfs_region); | 1836 | request->dfs_region); |
1826 | if (!result) | 1837 | if (!result) |
1827 | ath10k_warn("DFS region 0x%X not supported, will trigger radar for every pulse\n", | 1838 | ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n", |
1828 | request->dfs_region); | 1839 | request->dfs_region); |
1829 | } | 1840 | } |
1830 | 1841 | ||
@@ -1861,7 +1872,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, | |||
1861 | if (ar->monitor_started) | 1872 | if (ar->monitor_started) |
1862 | return ar->monitor_vdev_id; | 1873 | return ar->monitor_vdev_id; |
1863 | 1874 | ||
1864 | ath10k_warn("failed to resolve vdev id\n"); | 1875 | ath10k_warn(ar, "failed to resolve vdev id\n"); |
1865 | return 0; | 1876 | return 0; |
1866 | } | 1877 | } |
1867 | 1878 | ||
@@ -1897,6 +1908,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work) | |||
1897 | { | 1908 | { |
1898 | struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, | 1909 | struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, |
1899 | wep_key_work); | 1910 | wep_key_work); |
1911 | struct ath10k *ar = arvif->ar; | ||
1900 | int ret, keyidx = arvif->def_wep_key_newidx; | 1912 | int ret, keyidx = arvif->def_wep_key_newidx; |
1901 | 1913 | ||
1902 | mutex_lock(&arvif->ar->conf_mutex); | 1914 | mutex_lock(&arvif->ar->conf_mutex); |
@@ -1907,7 +1919,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work) | |||
1907 | if (arvif->def_wep_key_idx == keyidx) | 1919 | if (arvif->def_wep_key_idx == keyidx) |
1908 | goto unlock; | 1920 | goto unlock; |
1909 | 1921 | ||
1910 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", | 1922 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", |
1911 | arvif->vdev_id, keyidx); | 1923 | arvif->vdev_id, keyidx); |
1912 | 1924 | ||
1913 | ret = ath10k_wmi_vdev_set_param(arvif->ar, | 1925 | ret = ath10k_wmi_vdev_set_param(arvif->ar, |
@@ -1915,7 +1927,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work) | |||
1915 | arvif->ar->wmi.vdev_param->def_keyid, | 1927 | arvif->ar->wmi.vdev_param->def_keyid, |
1916 | keyidx); | 1928 | keyidx); |
1917 | if (ret) { | 1929 | if (ret) { |
1918 | ath10k_warn("failed to update wep key index for vdev %d: %d\n", | 1930 | ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n", |
1919 | arvif->vdev_id, | 1931 | arvif->vdev_id, |
1920 | ret); | 1932 | ret); |
1921 | goto unlock; | 1933 | goto unlock; |
@@ -1995,7 +2007,7 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) | |||
1995 | ar->fw_features)) { | 2007 | ar->fw_features)) { |
1996 | if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >= | 2008 | if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >= |
1997 | ATH10K_MAX_NUM_MGMT_PENDING) { | 2009 | ATH10K_MAX_NUM_MGMT_PENDING) { |
1998 | ath10k_warn("reached WMI management tranmist queue limit\n"); | 2010 | ath10k_warn(ar, "reached WMI management transmit queue limit\n"); |
1999 | ret = -EBUSY; | 2011 | ret = -EBUSY; |
2000 | goto exit; | 2012 | goto exit; |
2001 | } | 2013 | } |
@@ -2019,7 +2031,8 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) | |||
2019 | 2031 | ||
2020 | exit: | 2032 | exit: |
2021 | if (ret) { | 2033 | if (ret) { |
2022 | ath10k_warn("failed to transmit packet, dropping: %d\n", ret); | 2034 | ath10k_warn(ar, "failed to transmit packet, dropping: %d\n", |
2035 | ret); | ||
2023 | ieee80211_free_txskb(ar->hw, skb); | 2036 | ieee80211_free_txskb(ar->hw, skb); |
2024 | } | 2037 | } |
2025 | } | 2038 | } |
@@ -2061,7 +2074,7 @@ void ath10k_offchan_tx_work(struct work_struct *work) | |||
2061 | 2074 | ||
2062 | mutex_lock(&ar->conf_mutex); | 2075 | mutex_lock(&ar->conf_mutex); |
2063 | 2076 | ||
2064 | ath10k_dbg(ATH10K_DBG_MAC, "mac offchannel skb %p\n", | 2077 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n", |
2065 | skb); | 2078 | skb); |
2066 | 2079 | ||
2067 | hdr = (struct ieee80211_hdr *)skb->data; | 2080 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -2074,13 +2087,13 @@ void ath10k_offchan_tx_work(struct work_struct *work) | |||
2074 | 2087 | ||
2075 | if (peer) | 2088 | if (peer) |
2076 | /* FIXME: should this use ath10k_warn()? */ | 2089 | /* FIXME: should this use ath10k_warn()? */ |
2077 | ath10k_dbg(ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n", | 2090 | ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n", |
2078 | peer_addr, vdev_id); | 2091 | peer_addr, vdev_id); |
2079 | 2092 | ||
2080 | if (!peer) { | 2093 | if (!peer) { |
2081 | ret = ath10k_peer_create(ar, vdev_id, peer_addr); | 2094 | ret = ath10k_peer_create(ar, vdev_id, peer_addr); |
2082 | if (ret) | 2095 | if (ret) |
2083 | ath10k_warn("failed to create peer %pM on vdev %d: %d\n", | 2096 | ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n", |
2084 | peer_addr, vdev_id, ret); | 2097 | peer_addr, vdev_id, ret); |
2085 | } | 2098 | } |
2086 | 2099 | ||
@@ -2094,13 +2107,13 @@ void ath10k_offchan_tx_work(struct work_struct *work) | |||
2094 | ret = wait_for_completion_timeout(&ar->offchan_tx_completed, | 2107 | ret = wait_for_completion_timeout(&ar->offchan_tx_completed, |
2095 | 3 * HZ); | 2108 | 3 * HZ); |
2096 | if (ret <= 0) | 2109 | if (ret <= 0) |
2097 | ath10k_warn("timed out waiting for offchannel skb %p\n", | 2110 | ath10k_warn(ar, "timed out waiting for offchannel skb %p\n", |
2098 | skb); | 2111 | skb); |
2099 | 2112 | ||
2100 | if (!peer) { | 2113 | if (!peer) { |
2101 | ret = ath10k_peer_delete(ar, vdev_id, peer_addr); | 2114 | ret = ath10k_peer_delete(ar, vdev_id, peer_addr); |
2102 | if (ret) | 2115 | if (ret) |
2103 | ath10k_warn("failed to delete peer %pM on vdev %d: %d\n", | 2116 | ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n", |
2104 | peer_addr, vdev_id, ret); | 2117 | peer_addr, vdev_id, ret); |
2105 | } | 2118 | } |
2106 | 2119 | ||
@@ -2134,7 +2147,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) | |||
2134 | 2147 | ||
2135 | ret = ath10k_wmi_mgmt_tx(ar, skb); | 2148 | ret = ath10k_wmi_mgmt_tx(ar, skb); |
2136 | if (ret) { | 2149 | if (ret) { |
2137 | ath10k_warn("failed to transmit management frame via WMI: %d\n", | 2150 | ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n", |
2138 | ret); | 2151 | ret); |
2139 | ieee80211_free_txskb(ar->hw, skb); | 2152 | ieee80211_free_txskb(ar->hw, skb); |
2140 | } | 2153 | } |
@@ -2145,34 +2158,40 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) | |||
2145 | /* Scanning */ | 2158 | /* Scanning */ |
2146 | /************/ | 2159 | /************/ |
2147 | 2160 | ||
2148 | /* | 2161 | void __ath10k_scan_finish(struct ath10k *ar) |
2149 | * This gets called if we dont get a heart-beat during scan. | ||
2150 | * This may indicate the FW has hung and we need to abort the | ||
2151 | * scan manually to prevent cancel_hw_scan() from deadlocking | ||
2152 | */ | ||
2153 | void ath10k_reset_scan(unsigned long ptr) | ||
2154 | { | 2162 | { |
2155 | struct ath10k *ar = (struct ath10k *)ptr; | 2163 | lockdep_assert_held(&ar->data_lock); |
2156 | 2164 | ||
2157 | spin_lock_bh(&ar->data_lock); | 2165 | switch (ar->scan.state) { |
2158 | if (!ar->scan.in_progress) { | 2166 | case ATH10K_SCAN_IDLE: |
2159 | spin_unlock_bh(&ar->data_lock); | 2167 | break; |
2160 | return; | 2168 | case ATH10K_SCAN_RUNNING: |
2169 | case ATH10K_SCAN_ABORTING: | ||
2170 | if (ar->scan.is_roc) | ||
2171 | ieee80211_remain_on_channel_expired(ar->hw); | ||
2172 | else | ||
2173 | ieee80211_scan_completed(ar->hw, | ||
2174 | (ar->scan.state == | ||
2175 | ATH10K_SCAN_ABORTING)); | ||
2176 | /* fall through */ | ||
2177 | case ATH10K_SCAN_STARTING: | ||
2178 | ar->scan.state = ATH10K_SCAN_IDLE; | ||
2179 | ar->scan_channel = NULL; | ||
2180 | ath10k_offchan_tx_purge(ar); | ||
2181 | cancel_delayed_work(&ar->scan.timeout); | ||
2182 | complete_all(&ar->scan.completed); | ||
2183 | break; | ||
2161 | } | 2184 | } |
2185 | } | ||
2162 | 2186 | ||
2163 | ath10k_warn("scan timed out, firmware problem?\n"); | 2187 | void ath10k_scan_finish(struct ath10k *ar) |
2164 | 2188 | { | |
2165 | if (ar->scan.is_roc) | 2189 | spin_lock_bh(&ar->data_lock); |
2166 | ieee80211_remain_on_channel_expired(ar->hw); | 2190 | __ath10k_scan_finish(ar); |
2167 | else | ||
2168 | ieee80211_scan_completed(ar->hw, 1 /* aborted */); | ||
2169 | |||
2170 | ar->scan.in_progress = false; | ||
2171 | complete_all(&ar->scan.completed); | ||
2172 | spin_unlock_bh(&ar->data_lock); | 2191 | spin_unlock_bh(&ar->data_lock); |
2173 | } | 2192 | } |
2174 | 2193 | ||
2175 | static int ath10k_abort_scan(struct ath10k *ar) | 2194 | static int ath10k_scan_stop(struct ath10k *ar) |
2176 | { | 2195 | { |
2177 | struct wmi_stop_scan_arg arg = { | 2196 | struct wmi_stop_scan_arg arg = { |
2178 | .req_id = 1, /* FIXME */ | 2197 | .req_id = 1, /* FIXME */ |
@@ -2183,47 +2202,79 @@ static int ath10k_abort_scan(struct ath10k *ar) | |||
2183 | 2202 | ||
2184 | lockdep_assert_held(&ar->conf_mutex); | 2203 | lockdep_assert_held(&ar->conf_mutex); |
2185 | 2204 | ||
2186 | del_timer_sync(&ar->scan.timeout); | 2205 | ret = ath10k_wmi_stop_scan(ar, &arg); |
2206 | if (ret) { | ||
2207 | ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret); | ||
2208 | goto out; | ||
2209 | } | ||
2187 | 2210 | ||
2188 | spin_lock_bh(&ar->data_lock); | 2211 | ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); |
2189 | if (!ar->scan.in_progress) { | 2212 | if (ret == 0) { |
2190 | spin_unlock_bh(&ar->data_lock); | 2213 | ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n"); |
2191 | return 0; | 2214 | ret = -ETIMEDOUT; |
2215 | } else if (ret > 0) { | ||
2216 | ret = 0; | ||
2192 | } | 2217 | } |
2193 | 2218 | ||
2194 | ar->scan.aborting = true; | 2219 | out: |
2220 | /* Scan state should be updated upon scan completion but in case | ||
2221 | * firmware fails to deliver the event (for whatever reason) it is | ||
2222 | * desired to clean up scan state anyway. Firmware may have just | ||
2223 | * dropped the scan completion event delivery due to transport pipe | ||
2224 | * being overflown with data and/or it can recover on its own before | ||
2225 | * next scan request is submitted. | ||
2226 | */ | ||
2227 | spin_lock_bh(&ar->data_lock); | ||
2228 | if (ar->scan.state != ATH10K_SCAN_IDLE) | ||
2229 | __ath10k_scan_finish(ar); | ||
2195 | spin_unlock_bh(&ar->data_lock); | 2230 | spin_unlock_bh(&ar->data_lock); |
2196 | 2231 | ||
2197 | ret = ath10k_wmi_stop_scan(ar, &arg); | 2232 | return ret; |
2198 | if (ret) { | 2233 | } |
2199 | ath10k_warn("failed to stop wmi scan: %d\n", ret); | ||
2200 | spin_lock_bh(&ar->data_lock); | ||
2201 | ar->scan.in_progress = false; | ||
2202 | ath10k_offchan_tx_purge(ar); | ||
2203 | spin_unlock_bh(&ar->data_lock); | ||
2204 | return -EIO; | ||
2205 | } | ||
2206 | 2234 | ||
2207 | ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); | 2235 | static void ath10k_scan_abort(struct ath10k *ar) |
2208 | if (ret == 0) | 2236 | { |
2209 | ath10k_warn("timed out while waiting for scan to stop\n"); | 2237 | int ret; |
2210 | 2238 | ||
2211 | /* scan completion may be done right after we timeout here, so let's | 2239 | lockdep_assert_held(&ar->conf_mutex); |
2212 | * check the in_progress and tell mac80211 scan is completed. if we | ||
2213 | * don't do that and FW fails to send us scan completion indication | ||
2214 | * then userspace won't be able to scan anymore */ | ||
2215 | ret = 0; | ||
2216 | 2240 | ||
2217 | spin_lock_bh(&ar->data_lock); | 2241 | spin_lock_bh(&ar->data_lock); |
2218 | if (ar->scan.in_progress) { | 2242 | |
2219 | ath10k_warn("failed to stop scan, it's still in progress\n"); | 2243 | switch (ar->scan.state) { |
2220 | ar->scan.in_progress = false; | 2244 | case ATH10K_SCAN_IDLE: |
2221 | ath10k_offchan_tx_purge(ar); | 2245 | /* This can happen if timeout worker kicked in and called |
2222 | ret = -ETIMEDOUT; | 2246 | * abortion while scan completion was being processed. |
2247 | */ | ||
2248 | break; | ||
2249 | case ATH10K_SCAN_STARTING: | ||
2250 | case ATH10K_SCAN_ABORTING: | ||
2251 | ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n", | ||
2252 | ath10k_scan_state_str(ar->scan.state), | ||
2253 | ar->scan.state); | ||
2254 | break; | ||
2255 | case ATH10K_SCAN_RUNNING: | ||
2256 | ar->scan.state = ATH10K_SCAN_ABORTING; | ||
2257 | spin_unlock_bh(&ar->data_lock); | ||
2258 | |||
2259 | ret = ath10k_scan_stop(ar); | ||
2260 | if (ret) | ||
2261 | ath10k_warn(ar, "failed to abort scan: %d\n", ret); | ||
2262 | |||
2263 | spin_lock_bh(&ar->data_lock); | ||
2264 | break; | ||
2223 | } | 2265 | } |
2266 | |||
2224 | spin_unlock_bh(&ar->data_lock); | 2267 | spin_unlock_bh(&ar->data_lock); |
2268 | } | ||
2225 | 2269 | ||
2226 | return ret; | 2270 | void ath10k_scan_timeout_work(struct work_struct *work) |
2271 | { | ||
2272 | struct ath10k *ar = container_of(work, struct ath10k, | ||
2273 | scan.timeout.work); | ||
2274 | |||
2275 | mutex_lock(&ar->conf_mutex); | ||
2276 | ath10k_scan_abort(ar); | ||
2277 | mutex_unlock(&ar->conf_mutex); | ||
2227 | } | 2278 | } |
2228 | 2279 | ||
2229 | static int ath10k_start_scan(struct ath10k *ar, | 2280 | static int ath10k_start_scan(struct ath10k *ar, |
@@ -2239,17 +2290,16 @@ static int ath10k_start_scan(struct ath10k *ar, | |||
2239 | 2290 | ||
2240 | ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ); | 2291 | ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ); |
2241 | if (ret == 0) { | 2292 | if (ret == 0) { |
2242 | ath10k_abort_scan(ar); | 2293 | ret = ath10k_scan_stop(ar); |
2243 | return ret; | 2294 | if (ret) |
2295 | ath10k_warn(ar, "failed to stop scan: %d\n", ret); | ||
2296 | |||
2297 | return -ETIMEDOUT; | ||
2244 | } | 2298 | } |
2245 | 2299 | ||
2246 | /* the scan can complete earlier, before we even | 2300 | /* Add a 200ms margin to account for event/command processing */ |
2247 | * start the timer. in that case the timer handler | 2301 | ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, |
2248 | * checks ar->scan.in_progress and bails out if its | 2302 | msecs_to_jiffies(arg->max_scan_time+200)); |
2249 | * false. Add a 200ms margin to account event/command | ||
2250 | * processing. */ | ||
2251 | mod_timer(&ar->scan.timeout, jiffies + | ||
2252 | msecs_to_jiffies(arg->max_scan_time+200)); | ||
2253 | return 0; | 2303 | return 0; |
2254 | } | 2304 | } |
2255 | 2305 | ||
@@ -2269,7 +2319,7 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2269 | 2319 | ||
2270 | /* We should disable CCK RATE due to P2P */ | 2320 | /* We should disable CCK RATE due to P2P */ |
2271 | if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE) | 2321 | if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE) |
2272 | ath10k_dbg(ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n"); | 2322 | ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n"); |
2273 | 2323 | ||
2274 | ATH10K_SKB_CB(skb)->htt.is_offchan = false; | 2324 | ATH10K_SKB_CB(skb)->htt.is_offchan = false; |
2275 | ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr); | 2325 | ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr); |
@@ -2289,7 +2339,8 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2289 | ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id; | 2339 | ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id; |
2290 | spin_unlock_bh(&ar->data_lock); | 2340 | spin_unlock_bh(&ar->data_lock); |
2291 | 2341 | ||
2292 | ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb); | 2342 | ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n", |
2343 | skb); | ||
2293 | 2344 | ||
2294 | skb_queue_tail(&ar->offchan_tx_queue, skb); | 2345 | skb_queue_tail(&ar->offchan_tx_queue, skb); |
2295 | ieee80211_queue_work(hw, &ar->offchan_tx_work); | 2346 | ieee80211_queue_work(hw, &ar->offchan_tx_work); |
@@ -2325,8 +2376,7 @@ void ath10k_halt(struct ath10k *ar) | |||
2325 | ath10k_monitor_stop(ar); | 2376 | ath10k_monitor_stop(ar); |
2326 | } | 2377 | } |
2327 | 2378 | ||
2328 | del_timer_sync(&ar->scan.timeout); | 2379 | ath10k_scan_finish(ar); |
2329 | ath10k_reset_scan((unsigned long)ar); | ||
2330 | ath10k_peer_cleanup_all(ar); | 2380 | ath10k_peer_cleanup_all(ar); |
2331 | ath10k_core_stop(ar); | 2381 | ath10k_core_stop(ar); |
2332 | ath10k_hif_power_down(ar); | 2382 | ath10k_hif_power_down(ar); |
@@ -2380,7 +2430,7 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) | |||
2380 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask, | 2430 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask, |
2381 | tx_ant); | 2431 | tx_ant); |
2382 | if (ret) { | 2432 | if (ret) { |
2383 | ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n", | 2433 | ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n", |
2384 | ret, tx_ant); | 2434 | ret, tx_ant); |
2385 | return ret; | 2435 | return ret; |
2386 | } | 2436 | } |
@@ -2388,7 +2438,7 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) | |||
2388 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask, | 2438 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask, |
2389 | rx_ant); | 2439 | rx_ant); |
2390 | if (ret) { | 2440 | if (ret) { |
2391 | ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n", | 2441 | ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n", |
2392 | ret, rx_ant); | 2442 | ret, rx_ant); |
2393 | return ret; | 2443 | return ret; |
2394 | } | 2444 | } |
@@ -2439,25 +2489,25 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2439 | 2489 | ||
2440 | ret = ath10k_hif_power_up(ar); | 2490 | ret = ath10k_hif_power_up(ar); |
2441 | if (ret) { | 2491 | if (ret) { |
2442 | ath10k_err("Could not init hif: %d\n", ret); | 2492 | ath10k_err(ar, "Could not init hif: %d\n", ret); |
2443 | goto err_off; | 2493 | goto err_off; |
2444 | } | 2494 | } |
2445 | 2495 | ||
2446 | ret = ath10k_core_start(ar); | 2496 | ret = ath10k_core_start(ar); |
2447 | if (ret) { | 2497 | if (ret) { |
2448 | ath10k_err("Could not init core: %d\n", ret); | 2498 | ath10k_err(ar, "Could not init core: %d\n", ret); |
2449 | goto err_power_down; | 2499 | goto err_power_down; |
2450 | } | 2500 | } |
2451 | 2501 | ||
2452 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); | 2502 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); |
2453 | if (ret) { | 2503 | if (ret) { |
2454 | ath10k_warn("failed to enable PMF QOS: %d\n", ret); | 2504 | ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret); |
2455 | goto err_core_stop; | 2505 | goto err_core_stop; |
2456 | } | 2506 | } |
2457 | 2507 | ||
2458 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); | 2508 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); |
2459 | if (ret) { | 2509 | if (ret) { |
2460 | ath10k_warn("failed to enable dynamic BW: %d\n", ret); | 2510 | ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret); |
2461 | goto err_core_stop; | 2511 | goto err_core_stop; |
2462 | } | 2512 | } |
2463 | 2513 | ||
@@ -2477,7 +2527,7 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2477 | ret = ath10k_wmi_pdev_set_param(ar, | 2527 | ret = ath10k_wmi_pdev_set_param(ar, |
2478 | ar->wmi.pdev_param->arp_ac_override, 0); | 2528 | ar->wmi.pdev_param->arp_ac_override, 0); |
2479 | if (ret) { | 2529 | if (ret) { |
2480 | ath10k_warn("failed to set arp ac override parameter: %d\n", | 2530 | ath10k_warn(ar, "failed to set arp ac override parameter: %d\n", |
2481 | ret); | 2531 | ret); |
2482 | goto err_core_stop; | 2532 | goto err_core_stop; |
2483 | } | 2533 | } |
@@ -2485,6 +2535,8 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2485 | ar->num_started_vdevs = 0; | 2535 | ar->num_started_vdevs = 0; |
2486 | ath10k_regd_update(ar); | 2536 | ath10k_regd_update(ar); |
2487 | 2537 | ||
2538 | ath10k_spectral_start(ar); | ||
2539 | |||
2488 | mutex_unlock(&ar->conf_mutex); | 2540 | mutex_unlock(&ar->conf_mutex); |
2489 | return 0; | 2541 | return 0; |
2490 | 2542 | ||
@@ -2515,6 +2567,7 @@ static void ath10k_stop(struct ieee80211_hw *hw) | |||
2515 | } | 2567 | } |
2516 | mutex_unlock(&ar->conf_mutex); | 2568 | mutex_unlock(&ar->conf_mutex); |
2517 | 2569 | ||
2570 | cancel_delayed_work_sync(&ar->scan.timeout); | ||
2518 | cancel_work_sync(&ar->restart_work); | 2571 | cancel_work_sync(&ar->restart_work); |
2519 | } | 2572 | } |
2520 | 2573 | ||
@@ -2528,7 +2581,7 @@ static int ath10k_config_ps(struct ath10k *ar) | |||
2528 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2581 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2529 | ret = ath10k_mac_vif_setup_ps(arvif); | 2582 | ret = ath10k_mac_vif_setup_ps(arvif); |
2530 | if (ret) { | 2583 | if (ret) { |
2531 | ath10k_warn("failed to setup powersave: %d\n", ret); | 2584 | ath10k_warn(ar, "failed to setup powersave: %d\n", ret); |
2532 | break; | 2585 | break; |
2533 | } | 2586 | } |
2534 | } | 2587 | } |
@@ -2566,7 +2619,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2566 | 2619 | ||
2567 | lockdep_assert_held(&ar->conf_mutex); | 2620 | lockdep_assert_held(&ar->conf_mutex); |
2568 | 2621 | ||
2569 | ath10k_dbg(ATH10K_DBG_MAC, | 2622 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
2570 | "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n", | 2623 | "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n", |
2571 | ar->chandef.chan->center_freq, | 2624 | ar->chandef.chan->center_freq, |
2572 | ar->chandef.center_freq1, | 2625 | ar->chandef.center_freq1, |
@@ -2582,18 +2635,21 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2582 | if (!arvif->is_started) | 2635 | if (!arvif->is_started) |
2583 | continue; | 2636 | continue; |
2584 | 2637 | ||
2638 | if (!arvif->is_up) | ||
2639 | continue; | ||
2640 | |||
2585 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) | 2641 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) |
2586 | continue; | 2642 | continue; |
2587 | 2643 | ||
2588 | ret = ath10k_vdev_stop(arvif); | 2644 | ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); |
2589 | if (ret) { | 2645 | if (ret) { |
2590 | ath10k_warn("failed to stop vdev %d: %d\n", | 2646 | ath10k_warn(ar, "failed to down vdev %d: %d\n", |
2591 | arvif->vdev_id, ret); | 2647 | arvif->vdev_id, ret); |
2592 | continue; | 2648 | continue; |
2593 | } | 2649 | } |
2594 | } | 2650 | } |
2595 | 2651 | ||
2596 | /* all vdevs are now stopped - now attempt to restart them */ | 2652 | /* all vdevs are downed now - attempt to restart and re-up them */ |
2597 | 2653 | ||
2598 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2654 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2599 | if (!arvif->is_started) | 2655 | if (!arvif->is_started) |
@@ -2602,9 +2658,9 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2602 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) | 2658 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) |
2603 | continue; | 2659 | continue; |
2604 | 2660 | ||
2605 | ret = ath10k_vdev_start(arvif); | 2661 | ret = ath10k_vdev_restart(arvif); |
2606 | if (ret) { | 2662 | if (ret) { |
2607 | ath10k_warn("failed to start vdev %d: %d\n", | 2663 | ath10k_warn(ar, "failed to restart vdev %d: %d\n", |
2608 | arvif->vdev_id, ret); | 2664 | arvif->vdev_id, ret); |
2609 | continue; | 2665 | continue; |
2610 | } | 2666 | } |
@@ -2615,7 +2671,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2615 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, | 2671 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, |
2616 | arvif->bssid); | 2672 | arvif->bssid); |
2617 | if (ret) { | 2673 | if (ret) { |
2618 | ath10k_warn("failed to bring vdev up %d: %d\n", | 2674 | ath10k_warn(ar, "failed to bring vdev up %d: %d\n", |
2619 | arvif->vdev_id, ret); | 2675 | arvif->vdev_id, ret); |
2620 | continue; | 2676 | continue; |
2621 | } | 2677 | } |
@@ -2635,7 +2691,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2635 | mutex_lock(&ar->conf_mutex); | 2691 | mutex_lock(&ar->conf_mutex); |
2636 | 2692 | ||
2637 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 2693 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2638 | ath10k_dbg(ATH10K_DBG_MAC, | 2694 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
2639 | "mac config channel %dMHz flags 0x%x radar %d\n", | 2695 | "mac config channel %dMHz flags 0x%x radar %d\n", |
2640 | conf->chandef.chan->center_freq, | 2696 | conf->chandef.chan->center_freq, |
2641 | conf->chandef.chan->flags, | 2697 | conf->chandef.chan->flags, |
@@ -2655,21 +2711,21 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2655 | } | 2711 | } |
2656 | 2712 | ||
2657 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 2713 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
2658 | ath10k_dbg(ATH10K_DBG_MAC, "mac config power %d\n", | 2714 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac config power %d\n", |
2659 | hw->conf.power_level); | 2715 | hw->conf.power_level); |
2660 | 2716 | ||
2661 | param = ar->wmi.pdev_param->txpower_limit2g; | 2717 | param = ar->wmi.pdev_param->txpower_limit2g; |
2662 | ret = ath10k_wmi_pdev_set_param(ar, param, | 2718 | ret = ath10k_wmi_pdev_set_param(ar, param, |
2663 | hw->conf.power_level * 2); | 2719 | hw->conf.power_level * 2); |
2664 | if (ret) | 2720 | if (ret) |
2665 | ath10k_warn("failed to set 2g txpower %d: %d\n", | 2721 | ath10k_warn(ar, "failed to set 2g txpower %d: %d\n", |
2666 | hw->conf.power_level, ret); | 2722 | hw->conf.power_level, ret); |
2667 | 2723 | ||
2668 | param = ar->wmi.pdev_param->txpower_limit5g; | 2724 | param = ar->wmi.pdev_param->txpower_limit5g; |
2669 | ret = ath10k_wmi_pdev_set_param(ar, param, | 2725 | ret = ath10k_wmi_pdev_set_param(ar, param, |
2670 | hw->conf.power_level * 2); | 2726 | hw->conf.power_level * 2); |
2671 | if (ret) | 2727 | if (ret) |
2672 | ath10k_warn("failed to set 5g txpower %d: %d\n", | 2728 | ath10k_warn(ar, "failed to set 5g txpower %d: %d\n", |
2673 | hw->conf.power_level, ret); | 2729 | hw->conf.power_level, ret); |
2674 | } | 2730 | } |
2675 | 2731 | ||
@@ -2681,7 +2737,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2681 | ar->monitor = true; | 2737 | ar->monitor = true; |
2682 | ret = ath10k_monitor_start(ar); | 2738 | ret = ath10k_monitor_start(ar); |
2683 | if (ret) { | 2739 | if (ret) { |
2684 | ath10k_warn("failed to start monitor (config): %d\n", | 2740 | ath10k_warn(ar, "failed to start monitor (config): %d\n", |
2685 | ret); | 2741 | ret); |
2686 | ar->monitor = false; | 2742 | ar->monitor = false; |
2687 | } | 2743 | } |
@@ -2724,11 +2780,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2724 | INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); | 2780 | INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); |
2725 | INIT_LIST_HEAD(&arvif->list); | 2781 | INIT_LIST_HEAD(&arvif->list); |
2726 | 2782 | ||
2727 | bit = ffs(ar->free_vdev_map); | 2783 | if (ar->free_vdev_map == 0) { |
2728 | if (bit == 0) { | 2784 | ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n"); |
2729 | ret = -EBUSY; | 2785 | ret = -EBUSY; |
2730 | goto err; | 2786 | goto err; |
2731 | } | 2787 | } |
2788 | bit = ffs(ar->free_vdev_map); | ||
2732 | 2789 | ||
2733 | arvif->vdev_id = bit - 1; | 2790 | arvif->vdev_id = bit - 1; |
2734 | arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; | 2791 | arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; |
@@ -2760,25 +2817,25 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2760 | break; | 2817 | break; |
2761 | } | 2818 | } |
2762 | 2819 | ||
2763 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n", | 2820 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n", |
2764 | arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype); | 2821 | arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype); |
2765 | 2822 | ||
2766 | ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type, | 2823 | ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type, |
2767 | arvif->vdev_subtype, vif->addr); | 2824 | arvif->vdev_subtype, vif->addr); |
2768 | if (ret) { | 2825 | if (ret) { |
2769 | ath10k_warn("failed to create WMI vdev %i: %d\n", | 2826 | ath10k_warn(ar, "failed to create WMI vdev %i: %d\n", |
2770 | arvif->vdev_id, ret); | 2827 | arvif->vdev_id, ret); |
2771 | goto err; | 2828 | goto err; |
2772 | } | 2829 | } |
2773 | 2830 | ||
2774 | ar->free_vdev_map &= ~BIT(arvif->vdev_id); | 2831 | ar->free_vdev_map &= ~(1 << arvif->vdev_id); |
2775 | list_add(&arvif->list, &ar->arvifs); | 2832 | list_add(&arvif->list, &ar->arvifs); |
2776 | 2833 | ||
2777 | vdev_param = ar->wmi.vdev_param->def_keyid; | 2834 | vdev_param = ar->wmi.vdev_param->def_keyid; |
2778 | ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, | 2835 | ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, |
2779 | arvif->def_wep_key_idx); | 2836 | arvif->def_wep_key_idx); |
2780 | if (ret) { | 2837 | if (ret) { |
2781 | ath10k_warn("failed to set vdev %i default key id: %d\n", | 2838 | ath10k_warn(ar, "failed to set vdev %i default key id: %d\n", |
2782 | arvif->vdev_id, ret); | 2839 | arvif->vdev_id, ret); |
2783 | goto err_vdev_delete; | 2840 | goto err_vdev_delete; |
2784 | } | 2841 | } |
@@ -2788,7 +2845,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2788 | ATH10K_HW_TXRX_NATIVE_WIFI); | 2845 | ATH10K_HW_TXRX_NATIVE_WIFI); |
2789 | /* 10.X firmware does not support this VDEV parameter. Do not warn */ | 2846 | /* 10.X firmware does not support this VDEV parameter. Do not warn */ |
2790 | if (ret && ret != -EOPNOTSUPP) { | 2847 | if (ret && ret != -EOPNOTSUPP) { |
2791 | ath10k_warn("failed to set vdev %i TX encapsulation: %d\n", | 2848 | ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", |
2792 | arvif->vdev_id, ret); | 2849 | arvif->vdev_id, ret); |
2793 | goto err_vdev_delete; | 2850 | goto err_vdev_delete; |
2794 | } | 2851 | } |
@@ -2796,14 +2853,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2796 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { | 2853 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { |
2797 | ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr); | 2854 | ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr); |
2798 | if (ret) { | 2855 | if (ret) { |
2799 | ath10k_warn("failed to create vdev %i peer for AP: %d\n", | 2856 | ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n", |
2800 | arvif->vdev_id, ret); | 2857 | arvif->vdev_id, ret); |
2801 | goto err_vdev_delete; | 2858 | goto err_vdev_delete; |
2802 | } | 2859 | } |
2803 | 2860 | ||
2804 | ret = ath10k_mac_set_kickout(arvif); | 2861 | ret = ath10k_mac_set_kickout(arvif); |
2805 | if (ret) { | 2862 | if (ret) { |
2806 | ath10k_warn("failed to set vdev %i kickout parameters: %d\n", | 2863 | ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n", |
2807 | arvif->vdev_id, ret); | 2864 | arvif->vdev_id, ret); |
2808 | goto err_peer_delete; | 2865 | goto err_peer_delete; |
2809 | } | 2866 | } |
@@ -2815,7 +2872,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2815 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, | 2872 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, |
2816 | param, value); | 2873 | param, value); |
2817 | if (ret) { | 2874 | if (ret) { |
2818 | ath10k_warn("failed to set vdev %i RX wake policy: %d\n", | 2875 | ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n", |
2819 | arvif->vdev_id, ret); | 2876 | arvif->vdev_id, ret); |
2820 | goto err_peer_delete; | 2877 | goto err_peer_delete; |
2821 | } | 2878 | } |
@@ -2825,7 +2882,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2825 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, | 2882 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, |
2826 | param, value); | 2883 | param, value); |
2827 | if (ret) { | 2884 | if (ret) { |
2828 | ath10k_warn("failed to set vdev %i TX wake thresh: %d\n", | 2885 | ath10k_warn(ar, "failed to set vdev %i TX wake thresh: %d\n", |
2829 | arvif->vdev_id, ret); | 2886 | arvif->vdev_id, ret); |
2830 | goto err_peer_delete; | 2887 | goto err_peer_delete; |
2831 | } | 2888 | } |
@@ -2835,7 +2892,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2835 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, | 2892 | ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, |
2836 | param, value); | 2893 | param, value); |
2837 | if (ret) { | 2894 | if (ret) { |
2838 | ath10k_warn("failed to set vdev %i PSPOLL count: %d\n", | 2895 | ath10k_warn(ar, "failed to set vdev %i PSPOLL count: %d\n", |
2839 | arvif->vdev_id, ret); | 2896 | arvif->vdev_id, ret); |
2840 | goto err_peer_delete; | 2897 | goto err_peer_delete; |
2841 | } | 2898 | } |
@@ -2843,14 +2900,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2843 | 2900 | ||
2844 | ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold); | 2901 | ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold); |
2845 | if (ret) { | 2902 | if (ret) { |
2846 | ath10k_warn("failed to set rts threshold for vdev %d: %d\n", | 2903 | ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n", |
2847 | arvif->vdev_id, ret); | 2904 | arvif->vdev_id, ret); |
2848 | goto err_peer_delete; | 2905 | goto err_peer_delete; |
2849 | } | 2906 | } |
2850 | 2907 | ||
2851 | ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); | 2908 | ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); |
2852 | if (ret) { | 2909 | if (ret) { |
2853 | ath10k_warn("failed to set frag threshold for vdev %d: %d\n", | 2910 | ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n", |
2854 | arvif->vdev_id, ret); | 2911 | arvif->vdev_id, ret); |
2855 | goto err_peer_delete; | 2912 | goto err_peer_delete; |
2856 | } | 2913 | } |
@@ -2864,7 +2921,7 @@ err_peer_delete: | |||
2864 | 2921 | ||
2865 | err_vdev_delete: | 2922 | err_vdev_delete: |
2866 | ath10k_wmi_vdev_delete(ar, arvif->vdev_id); | 2923 | ath10k_wmi_vdev_delete(ar, arvif->vdev_id); |
2867 | ar->free_vdev_map &= ~BIT(arvif->vdev_id); | 2924 | ar->free_vdev_map |= 1 << arvif->vdev_id; |
2868 | list_del(&arvif->list); | 2925 | list_del(&arvif->list); |
2869 | 2926 | ||
2870 | err: | 2927 | err: |
@@ -2892,26 +2949,32 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, | |||
2892 | dev_kfree_skb_any(arvif->beacon); | 2949 | dev_kfree_skb_any(arvif->beacon); |
2893 | arvif->beacon = NULL; | 2950 | arvif->beacon = NULL; |
2894 | } | 2951 | } |
2952 | |||
2895 | spin_unlock_bh(&ar->data_lock); | 2953 | spin_unlock_bh(&ar->data_lock); |
2896 | 2954 | ||
2897 | ar->free_vdev_map |= 1 << (arvif->vdev_id); | 2955 | ret = ath10k_spectral_vif_stop(arvif); |
2956 | if (ret) | ||
2957 | ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n", | ||
2958 | arvif->vdev_id, ret); | ||
2959 | |||
2960 | ar->free_vdev_map |= 1 << arvif->vdev_id; | ||
2898 | list_del(&arvif->list); | 2961 | list_del(&arvif->list); |
2899 | 2962 | ||
2900 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { | 2963 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { |
2901 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); | 2964 | ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); |
2902 | if (ret) | 2965 | if (ret) |
2903 | ath10k_warn("failed to remove peer for AP vdev %i: %d\n", | 2966 | ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n", |
2904 | arvif->vdev_id, ret); | 2967 | arvif->vdev_id, ret); |
2905 | 2968 | ||
2906 | kfree(arvif->u.ap.noa_data); | 2969 | kfree(arvif->u.ap.noa_data); |
2907 | } | 2970 | } |
2908 | 2971 | ||
2909 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n", | 2972 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n", |
2910 | arvif->vdev_id); | 2973 | arvif->vdev_id); |
2911 | 2974 | ||
2912 | ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id); | 2975 | ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id); |
2913 | if (ret) | 2976 | if (ret) |
2914 | ath10k_warn("failed to delete WMI vdev %i: %d\n", | 2977 | ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", |
2915 | arvif->vdev_id, ret); | 2978 | arvif->vdev_id, ret); |
2916 | 2979 | ||
2917 | ath10k_peer_cleanup(ar, arvif->vdev_id); | 2980 | ath10k_peer_cleanup(ar, arvif->vdev_id); |
@@ -2950,7 +3013,7 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw, | |||
2950 | ar->promisc = true; | 3013 | ar->promisc = true; |
2951 | ret = ath10k_monitor_start(ar); | 3014 | ret = ath10k_monitor_start(ar); |
2952 | if (ret) { | 3015 | if (ret) { |
2953 | ath10k_warn("failed to start monitor (promisc): %d\n", | 3016 | ath10k_warn(ar, "failed to start monitor (promisc): %d\n", |
2954 | ret); | 3017 | ret); |
2955 | ar->promisc = false; | 3018 | ar->promisc = false; |
2956 | } | 3019 | } |
@@ -2982,17 +3045,17 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
2982 | vdev_param = ar->wmi.vdev_param->beacon_interval; | 3045 | vdev_param = ar->wmi.vdev_param->beacon_interval; |
2983 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3046 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
2984 | arvif->beacon_interval); | 3047 | arvif->beacon_interval); |
2985 | ath10k_dbg(ATH10K_DBG_MAC, | 3048 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
2986 | "mac vdev %d beacon_interval %d\n", | 3049 | "mac vdev %d beacon_interval %d\n", |
2987 | arvif->vdev_id, arvif->beacon_interval); | 3050 | arvif->vdev_id, arvif->beacon_interval); |
2988 | 3051 | ||
2989 | if (ret) | 3052 | if (ret) |
2990 | ath10k_warn("failed to set beacon interval for vdev %d: %i\n", | 3053 | ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n", |
2991 | arvif->vdev_id, ret); | 3054 | arvif->vdev_id, ret); |
2992 | } | 3055 | } |
2993 | 3056 | ||
2994 | if (changed & BSS_CHANGED_BEACON) { | 3057 | if (changed & BSS_CHANGED_BEACON) { |
2995 | ath10k_dbg(ATH10K_DBG_MAC, | 3058 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
2996 | "vdev %d set beacon tx mode to staggered\n", | 3059 | "vdev %d set beacon tx mode to staggered\n", |
2997 | arvif->vdev_id); | 3060 | arvif->vdev_id); |
2998 | 3061 | ||
@@ -3000,14 +3063,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3000 | ret = ath10k_wmi_pdev_set_param(ar, pdev_param, | 3063 | ret = ath10k_wmi_pdev_set_param(ar, pdev_param, |
3001 | WMI_BEACON_STAGGERED_MODE); | 3064 | WMI_BEACON_STAGGERED_MODE); |
3002 | if (ret) | 3065 | if (ret) |
3003 | ath10k_warn("failed to set beacon mode for vdev %d: %i\n", | 3066 | ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n", |
3004 | arvif->vdev_id, ret); | 3067 | arvif->vdev_id, ret); |
3005 | } | 3068 | } |
3006 | 3069 | ||
3007 | if (changed & BSS_CHANGED_BEACON_INFO) { | 3070 | if (changed & BSS_CHANGED_BEACON_INFO) { |
3008 | arvif->dtim_period = info->dtim_period; | 3071 | arvif->dtim_period = info->dtim_period; |
3009 | 3072 | ||
3010 | ath10k_dbg(ATH10K_DBG_MAC, | 3073 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3011 | "mac vdev %d dtim_period %d\n", | 3074 | "mac vdev %d dtim_period %d\n", |
3012 | arvif->vdev_id, arvif->dtim_period); | 3075 | arvif->vdev_id, arvif->dtim_period); |
3013 | 3076 | ||
@@ -3015,7 +3078,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3015 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3078 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
3016 | arvif->dtim_period); | 3079 | arvif->dtim_period); |
3017 | if (ret) | 3080 | if (ret) |
3018 | ath10k_warn("failed to set dtim period for vdev %d: %i\n", | 3081 | ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n", |
3019 | arvif->vdev_id, ret); | 3082 | arvif->vdev_id, ret); |
3020 | } | 3083 | } |
3021 | 3084 | ||
@@ -3034,14 +3097,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3034 | if (changed & BSS_CHANGED_BSSID && | 3097 | if (changed & BSS_CHANGED_BSSID && |
3035 | vif->type != NL80211_IFTYPE_AP) { | 3098 | vif->type != NL80211_IFTYPE_AP) { |
3036 | if (!is_zero_ether_addr(info->bssid)) { | 3099 | if (!is_zero_ether_addr(info->bssid)) { |
3037 | ath10k_dbg(ATH10K_DBG_MAC, | 3100 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3038 | "mac vdev %d create peer %pM\n", | 3101 | "mac vdev %d create peer %pM\n", |
3039 | arvif->vdev_id, info->bssid); | 3102 | arvif->vdev_id, info->bssid); |
3040 | 3103 | ||
3041 | ret = ath10k_peer_create(ar, arvif->vdev_id, | 3104 | ret = ath10k_peer_create(ar, arvif->vdev_id, |
3042 | info->bssid); | 3105 | info->bssid); |
3043 | if (ret) | 3106 | if (ret) |
3044 | ath10k_warn("failed to add peer %pM for vdev %d when changing bssid: %i\n", | 3107 | ath10k_warn(ar, "failed to add peer %pM for vdev %d when changing bssid: %i\n", |
3045 | info->bssid, arvif->vdev_id, ret); | 3108 | info->bssid, arvif->vdev_id, ret); |
3046 | 3109 | ||
3047 | if (vif->type == NL80211_IFTYPE_STATION) { | 3110 | if (vif->type == NL80211_IFTYPE_STATION) { |
@@ -3051,13 +3114,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3051 | */ | 3114 | */ |
3052 | memcpy(arvif->bssid, info->bssid, ETH_ALEN); | 3115 | memcpy(arvif->bssid, info->bssid, ETH_ALEN); |
3053 | 3116 | ||
3054 | ath10k_dbg(ATH10K_DBG_MAC, | 3117 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3055 | "mac vdev %d start %pM\n", | 3118 | "mac vdev %d start %pM\n", |
3056 | arvif->vdev_id, info->bssid); | 3119 | arvif->vdev_id, info->bssid); |
3057 | 3120 | ||
3058 | ret = ath10k_vdev_start(arvif); | 3121 | ret = ath10k_vdev_start(arvif); |
3059 | if (ret) { | 3122 | if (ret) { |
3060 | ath10k_warn("failed to start vdev %i: %d\n", | 3123 | ath10k_warn(ar, "failed to start vdev %i: %d\n", |
3061 | arvif->vdev_id, ret); | 3124 | arvif->vdev_id, ret); |
3062 | goto exit; | 3125 | goto exit; |
3063 | } | 3126 | } |
@@ -3081,12 +3144,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3081 | 3144 | ||
3082 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 3145 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
3083 | arvif->use_cts_prot = info->use_cts_prot; | 3146 | arvif->use_cts_prot = info->use_cts_prot; |
3084 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n", | 3147 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n", |
3085 | arvif->vdev_id, info->use_cts_prot); | 3148 | arvif->vdev_id, info->use_cts_prot); |
3086 | 3149 | ||
3087 | ret = ath10k_recalc_rtscts_prot(arvif); | 3150 | ret = ath10k_recalc_rtscts_prot(arvif); |
3088 | if (ret) | 3151 | if (ret) |
3089 | ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", | 3152 | ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", |
3090 | arvif->vdev_id, ret); | 3153 | arvif->vdev_id, ret); |
3091 | } | 3154 | } |
3092 | 3155 | ||
@@ -3098,14 +3161,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3098 | else | 3161 | else |
3099 | slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */ | 3162 | slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */ |
3100 | 3163 | ||
3101 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n", | 3164 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n", |
3102 | arvif->vdev_id, slottime); | 3165 | arvif->vdev_id, slottime); |
3103 | 3166 | ||
3104 | vdev_param = ar->wmi.vdev_param->slot_time; | 3167 | vdev_param = ar->wmi.vdev_param->slot_time; |
3105 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3168 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
3106 | slottime); | 3169 | slottime); |
3107 | if (ret) | 3170 | if (ret) |
3108 | ath10k_warn("failed to set erp slot for vdev %d: %i\n", | 3171 | ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n", |
3109 | arvif->vdev_id, ret); | 3172 | arvif->vdev_id, ret); |
3110 | } | 3173 | } |
3111 | 3174 | ||
@@ -3116,7 +3179,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3116 | else | 3179 | else |
3117 | preamble = WMI_VDEV_PREAMBLE_LONG; | 3180 | preamble = WMI_VDEV_PREAMBLE_LONG; |
3118 | 3181 | ||
3119 | ath10k_dbg(ATH10K_DBG_MAC, | 3182 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3120 | "mac vdev %d preamble %dn", | 3183 | "mac vdev %d preamble %dn", |
3121 | arvif->vdev_id, preamble); | 3184 | arvif->vdev_id, preamble); |
3122 | 3185 | ||
@@ -3124,7 +3187,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3124 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3187 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
3125 | preamble); | 3188 | preamble); |
3126 | if (ret) | 3189 | if (ret) |
3127 | ath10k_warn("failed to set preamble for vdev %d: %i\n", | 3190 | ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n", |
3128 | arvif->vdev_id, ret); | 3191 | arvif->vdev_id, ret); |
3129 | } | 3192 | } |
3130 | 3193 | ||
@@ -3151,20 +3214,26 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, | |||
3151 | mutex_lock(&ar->conf_mutex); | 3214 | mutex_lock(&ar->conf_mutex); |
3152 | 3215 | ||
3153 | spin_lock_bh(&ar->data_lock); | 3216 | spin_lock_bh(&ar->data_lock); |
3154 | if (ar->scan.in_progress) { | 3217 | switch (ar->scan.state) { |
3155 | spin_unlock_bh(&ar->data_lock); | 3218 | case ATH10K_SCAN_IDLE: |
3219 | reinit_completion(&ar->scan.started); | ||
3220 | reinit_completion(&ar->scan.completed); | ||
3221 | ar->scan.state = ATH10K_SCAN_STARTING; | ||
3222 | ar->scan.is_roc = false; | ||
3223 | ar->scan.vdev_id = arvif->vdev_id; | ||
3224 | ret = 0; | ||
3225 | break; | ||
3226 | case ATH10K_SCAN_STARTING: | ||
3227 | case ATH10K_SCAN_RUNNING: | ||
3228 | case ATH10K_SCAN_ABORTING: | ||
3156 | ret = -EBUSY; | 3229 | ret = -EBUSY; |
3157 | goto exit; | 3230 | break; |
3158 | } | 3231 | } |
3159 | |||
3160 | reinit_completion(&ar->scan.started); | ||
3161 | reinit_completion(&ar->scan.completed); | ||
3162 | ar->scan.in_progress = true; | ||
3163 | ar->scan.aborting = false; | ||
3164 | ar->scan.is_roc = false; | ||
3165 | ar->scan.vdev_id = arvif->vdev_id; | ||
3166 | spin_unlock_bh(&ar->data_lock); | 3232 | spin_unlock_bh(&ar->data_lock); |
3167 | 3233 | ||
3234 | if (ret) | ||
3235 | goto exit; | ||
3236 | |||
3168 | memset(&arg, 0, sizeof(arg)); | 3237 | memset(&arg, 0, sizeof(arg)); |
3169 | ath10k_wmi_start_scan_init(ar, &arg); | 3238 | ath10k_wmi_start_scan_init(ar, &arg); |
3170 | arg.vdev_id = arvif->vdev_id; | 3239 | arg.vdev_id = arvif->vdev_id; |
@@ -3196,9 +3265,9 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, | |||
3196 | 3265 | ||
3197 | ret = ath10k_start_scan(ar, &arg); | 3266 | ret = ath10k_start_scan(ar, &arg); |
3198 | if (ret) { | 3267 | if (ret) { |
3199 | ath10k_warn("failed to start hw scan: %d\n", ret); | 3268 | ath10k_warn(ar, "failed to start hw scan: %d\n", ret); |
3200 | spin_lock_bh(&ar->data_lock); | 3269 | spin_lock_bh(&ar->data_lock); |
3201 | ar->scan.in_progress = false; | 3270 | ar->scan.state = ATH10K_SCAN_IDLE; |
3202 | spin_unlock_bh(&ar->data_lock); | 3271 | spin_unlock_bh(&ar->data_lock); |
3203 | } | 3272 | } |
3204 | 3273 | ||
@@ -3211,14 +3280,10 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw, | |||
3211 | struct ieee80211_vif *vif) | 3280 | struct ieee80211_vif *vif) |
3212 | { | 3281 | { |
3213 | struct ath10k *ar = hw->priv; | 3282 | struct ath10k *ar = hw->priv; |
3214 | int ret; | ||
3215 | 3283 | ||
3216 | mutex_lock(&ar->conf_mutex); | 3284 | mutex_lock(&ar->conf_mutex); |
3217 | ret = ath10k_abort_scan(ar); | 3285 | cancel_delayed_work_sync(&ar->scan.timeout); |
3218 | if (ret) { | 3286 | ath10k_scan_abort(ar); |
3219 | ath10k_warn("failed to abort scan: %d\n", ret); | ||
3220 | ieee80211_scan_completed(hw, 1 /* aborted */); | ||
3221 | } | ||
3222 | mutex_unlock(&ar->conf_mutex); | 3287 | mutex_unlock(&ar->conf_mutex); |
3223 | } | 3288 | } |
3224 | 3289 | ||
@@ -3256,7 +3321,7 @@ static void ath10k_set_key_h_def_keyidx(struct ath10k *ar, | |||
3256 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3321 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
3257 | key->keyidx); | 3322 | key->keyidx); |
3258 | if (ret) | 3323 | if (ret) |
3259 | ath10k_warn("failed to set vdev %i group key as default key: %d\n", | 3324 | ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n", |
3260 | arvif->vdev_id, ret); | 3325 | arvif->vdev_id, ret); |
3261 | } | 3326 | } |
3262 | 3327 | ||
@@ -3294,7 +3359,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3294 | 3359 | ||
3295 | if (!peer) { | 3360 | if (!peer) { |
3296 | if (cmd == SET_KEY) { | 3361 | if (cmd == SET_KEY) { |
3297 | ath10k_warn("failed to install key for non-existent peer %pM\n", | 3362 | ath10k_warn(ar, "failed to install key for non-existent peer %pM\n", |
3298 | peer_addr); | 3363 | peer_addr); |
3299 | ret = -EOPNOTSUPP; | 3364 | ret = -EOPNOTSUPP; |
3300 | goto exit; | 3365 | goto exit; |
@@ -3317,7 +3382,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3317 | 3382 | ||
3318 | ret = ath10k_install_key(arvif, key, cmd, peer_addr); | 3383 | ret = ath10k_install_key(arvif, key, cmd, peer_addr); |
3319 | if (ret) { | 3384 | if (ret) { |
3320 | ath10k_warn("failed to install key for vdev %i peer %pM: %d\n", | 3385 | ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", |
3321 | arvif->vdev_id, peer_addr, ret); | 3386 | arvif->vdev_id, peer_addr, ret); |
3322 | goto exit; | 3387 | goto exit; |
3323 | } | 3388 | } |
@@ -3332,7 +3397,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3332 | peer->keys[key->keyidx] = NULL; | 3397 | peer->keys[key->keyidx] = NULL; |
3333 | else if (peer == NULL) | 3398 | else if (peer == NULL) |
3334 | /* impossible unless FW goes crazy */ | 3399 | /* impossible unless FW goes crazy */ |
3335 | ath10k_warn("Peer %pM disappeared!\n", peer_addr); | 3400 | ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); |
3336 | spin_unlock_bh(&ar->data_lock); | 3401 | spin_unlock_bh(&ar->data_lock); |
3337 | 3402 | ||
3338 | exit: | 3403 | exit: |
@@ -3368,45 +3433,45 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) | |||
3368 | mutex_lock(&ar->conf_mutex); | 3433 | mutex_lock(&ar->conf_mutex); |
3369 | 3434 | ||
3370 | if (changed & IEEE80211_RC_BW_CHANGED) { | 3435 | if (changed & IEEE80211_RC_BW_CHANGED) { |
3371 | ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n", | 3436 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n", |
3372 | sta->addr, bw); | 3437 | sta->addr, bw); |
3373 | 3438 | ||
3374 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, | 3439 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, |
3375 | WMI_PEER_CHAN_WIDTH, bw); | 3440 | WMI_PEER_CHAN_WIDTH, bw); |
3376 | if (err) | 3441 | if (err) |
3377 | ath10k_warn("failed to update STA %pM peer bw %d: %d\n", | 3442 | ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n", |
3378 | sta->addr, bw, err); | 3443 | sta->addr, bw, err); |
3379 | } | 3444 | } |
3380 | 3445 | ||
3381 | if (changed & IEEE80211_RC_NSS_CHANGED) { | 3446 | if (changed & IEEE80211_RC_NSS_CHANGED) { |
3382 | ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM nss %d\n", | 3447 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n", |
3383 | sta->addr, nss); | 3448 | sta->addr, nss); |
3384 | 3449 | ||
3385 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, | 3450 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, |
3386 | WMI_PEER_NSS, nss); | 3451 | WMI_PEER_NSS, nss); |
3387 | if (err) | 3452 | if (err) |
3388 | ath10k_warn("failed to update STA %pM nss %d: %d\n", | 3453 | ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n", |
3389 | sta->addr, nss, err); | 3454 | sta->addr, nss, err); |
3390 | } | 3455 | } |
3391 | 3456 | ||
3392 | if (changed & IEEE80211_RC_SMPS_CHANGED) { | 3457 | if (changed & IEEE80211_RC_SMPS_CHANGED) { |
3393 | ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM smps %d\n", | 3458 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n", |
3394 | sta->addr, smps); | 3459 | sta->addr, smps); |
3395 | 3460 | ||
3396 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, | 3461 | err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, |
3397 | WMI_PEER_SMPS_STATE, smps); | 3462 | WMI_PEER_SMPS_STATE, smps); |
3398 | if (err) | 3463 | if (err) |
3399 | ath10k_warn("failed to update STA %pM smps %d: %d\n", | 3464 | ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n", |
3400 | sta->addr, smps, err); | 3465 | sta->addr, smps, err); |
3401 | } | 3466 | } |
3402 | 3467 | ||
3403 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { | 3468 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { |
3404 | ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", | 3469 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", |
3405 | sta->addr); | 3470 | sta->addr); |
3406 | 3471 | ||
3407 | err = ath10k_station_assoc(ar, arvif, sta, true); | 3472 | err = ath10k_station_assoc(ar, arvif, sta, true); |
3408 | if (err) | 3473 | if (err) |
3409 | ath10k_warn("failed to reassociate station: %pM\n", | 3474 | ath10k_warn(ar, "failed to reassociate station: %pM\n", |
3410 | sta->addr); | 3475 | sta->addr); |
3411 | } | 3476 | } |
3412 | 3477 | ||
@@ -3451,31 +3516,31 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
3451 | max_num_peers = TARGET_NUM_PEERS; | 3516 | max_num_peers = TARGET_NUM_PEERS; |
3452 | 3517 | ||
3453 | if (ar->num_peers >= max_num_peers) { | 3518 | if (ar->num_peers >= max_num_peers) { |
3454 | ath10k_warn("number of peers exceeded: peers number %d (max peers %d)\n", | 3519 | ath10k_warn(ar, "number of peers exceeded: peers number %d (max peers %d)\n", |
3455 | ar->num_peers, max_num_peers); | 3520 | ar->num_peers, max_num_peers); |
3456 | ret = -ENOBUFS; | 3521 | ret = -ENOBUFS; |
3457 | goto exit; | 3522 | goto exit; |
3458 | } | 3523 | } |
3459 | 3524 | ||
3460 | ath10k_dbg(ATH10K_DBG_MAC, | 3525 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3461 | "mac vdev %d peer create %pM (new sta) num_peers %d\n", | 3526 | "mac vdev %d peer create %pM (new sta) num_peers %d\n", |
3462 | arvif->vdev_id, sta->addr, ar->num_peers); | 3527 | arvif->vdev_id, sta->addr, ar->num_peers); |
3463 | 3528 | ||
3464 | ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); | 3529 | ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); |
3465 | if (ret) | 3530 | if (ret) |
3466 | ath10k_warn("failed to add peer %pM for vdev %d when adding a new sta: %i\n", | 3531 | ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n", |
3467 | sta->addr, arvif->vdev_id, ret); | 3532 | sta->addr, arvif->vdev_id, ret); |
3468 | } else if ((old_state == IEEE80211_STA_NONE && | 3533 | } else if ((old_state == IEEE80211_STA_NONE && |
3469 | new_state == IEEE80211_STA_NOTEXIST)) { | 3534 | new_state == IEEE80211_STA_NOTEXIST)) { |
3470 | /* | 3535 | /* |
3471 | * Existing station deletion. | 3536 | * Existing station deletion. |
3472 | */ | 3537 | */ |
3473 | ath10k_dbg(ATH10K_DBG_MAC, | 3538 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3474 | "mac vdev %d peer delete %pM (sta gone)\n", | 3539 | "mac vdev %d peer delete %pM (sta gone)\n", |
3475 | arvif->vdev_id, sta->addr); | 3540 | arvif->vdev_id, sta->addr); |
3476 | ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); | 3541 | ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); |
3477 | if (ret) | 3542 | if (ret) |
3478 | ath10k_warn("failed to delete peer %pM for vdev %d: %i\n", | 3543 | ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", |
3479 | sta->addr, arvif->vdev_id, ret); | 3544 | sta->addr, arvif->vdev_id, ret); |
3480 | 3545 | ||
3481 | if (vif->type == NL80211_IFTYPE_STATION) | 3546 | if (vif->type == NL80211_IFTYPE_STATION) |
@@ -3487,12 +3552,12 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
3487 | /* | 3552 | /* |
3488 | * New association. | 3553 | * New association. |
3489 | */ | 3554 | */ |
3490 | ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM associated\n", | 3555 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n", |
3491 | sta->addr); | 3556 | sta->addr); |
3492 | 3557 | ||
3493 | ret = ath10k_station_assoc(ar, arvif, sta, false); | 3558 | ret = ath10k_station_assoc(ar, arvif, sta, false); |
3494 | if (ret) | 3559 | if (ret) |
3495 | ath10k_warn("failed to associate station %pM for vdev %i: %i\n", | 3560 | ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n", |
3496 | sta->addr, arvif->vdev_id, ret); | 3561 | sta->addr, arvif->vdev_id, ret); |
3497 | } else if (old_state == IEEE80211_STA_ASSOC && | 3562 | } else if (old_state == IEEE80211_STA_ASSOC && |
3498 | new_state == IEEE80211_STA_AUTH && | 3563 | new_state == IEEE80211_STA_AUTH && |
@@ -3501,12 +3566,12 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
3501 | /* | 3566 | /* |
3502 | * Disassociation. | 3567 | * Disassociation. |
3503 | */ | 3568 | */ |
3504 | ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM disassociated\n", | 3569 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n", |
3505 | sta->addr); | 3570 | sta->addr); |
3506 | 3571 | ||
3507 | ret = ath10k_station_disassoc(ar, arvif, sta); | 3572 | ret = ath10k_station_disassoc(ar, arvif, sta); |
3508 | if (ret) | 3573 | if (ret) |
3509 | ath10k_warn("failed to disassociate station: %pM vdev %i: %i\n", | 3574 | ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n", |
3510 | sta->addr, arvif->vdev_id, ret); | 3575 | sta->addr, arvif->vdev_id, ret); |
3511 | } | 3576 | } |
3512 | exit: | 3577 | exit: |
@@ -3554,7 +3619,7 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, | |||
3554 | WMI_STA_PS_PARAM_UAPSD, | 3619 | WMI_STA_PS_PARAM_UAPSD, |
3555 | arvif->u.sta.uapsd); | 3620 | arvif->u.sta.uapsd); |
3556 | if (ret) { | 3621 | if (ret) { |
3557 | ath10k_warn("failed to set uapsd params: %d\n", ret); | 3622 | ath10k_warn(ar, "failed to set uapsd params: %d\n", ret); |
3558 | goto exit; | 3623 | goto exit; |
3559 | } | 3624 | } |
3560 | 3625 | ||
@@ -3567,7 +3632,7 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, | |||
3567 | WMI_STA_PS_PARAM_RX_WAKE_POLICY, | 3632 | WMI_STA_PS_PARAM_RX_WAKE_POLICY, |
3568 | value); | 3633 | value); |
3569 | if (ret) | 3634 | if (ret) |
3570 | ath10k_warn("failed to set rx wake param: %d\n", ret); | 3635 | ath10k_warn(ar, "failed to set rx wake param: %d\n", ret); |
3571 | 3636 | ||
3572 | exit: | 3637 | exit: |
3573 | return ret; | 3638 | return ret; |
@@ -3617,13 +3682,13 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw, | |||
3617 | /* FIXME: FW accepts wmm params per hw, not per vif */ | 3682 | /* FIXME: FW accepts wmm params per hw, not per vif */ |
3618 | ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params); | 3683 | ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params); |
3619 | if (ret) { | 3684 | if (ret) { |
3620 | ath10k_warn("failed to set wmm params: %d\n", ret); | 3685 | ath10k_warn(ar, "failed to set wmm params: %d\n", ret); |
3621 | goto exit; | 3686 | goto exit; |
3622 | } | 3687 | } |
3623 | 3688 | ||
3624 | ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd); | 3689 | ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd); |
3625 | if (ret) | 3690 | if (ret) |
3626 | ath10k_warn("failed to set sta uapsd: %d\n", ret); | 3691 | ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret); |
3627 | 3692 | ||
3628 | exit: | 3693 | exit: |
3629 | mutex_unlock(&ar->conf_mutex); | 3694 | mutex_unlock(&ar->conf_mutex); |
@@ -3641,27 +3706,33 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, | |||
3641 | struct ath10k *ar = hw->priv; | 3706 | struct ath10k *ar = hw->priv; |
3642 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 3707 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
3643 | struct wmi_start_scan_arg arg; | 3708 | struct wmi_start_scan_arg arg; |
3644 | int ret; | 3709 | int ret = 0; |
3645 | 3710 | ||
3646 | mutex_lock(&ar->conf_mutex); | 3711 | mutex_lock(&ar->conf_mutex); |
3647 | 3712 | ||
3648 | spin_lock_bh(&ar->data_lock); | 3713 | spin_lock_bh(&ar->data_lock); |
3649 | if (ar->scan.in_progress) { | 3714 | switch (ar->scan.state) { |
3650 | spin_unlock_bh(&ar->data_lock); | 3715 | case ATH10K_SCAN_IDLE: |
3716 | reinit_completion(&ar->scan.started); | ||
3717 | reinit_completion(&ar->scan.completed); | ||
3718 | reinit_completion(&ar->scan.on_channel); | ||
3719 | ar->scan.state = ATH10K_SCAN_STARTING; | ||
3720 | ar->scan.is_roc = true; | ||
3721 | ar->scan.vdev_id = arvif->vdev_id; | ||
3722 | ar->scan.roc_freq = chan->center_freq; | ||
3723 | ret = 0; | ||
3724 | break; | ||
3725 | case ATH10K_SCAN_STARTING: | ||
3726 | case ATH10K_SCAN_RUNNING: | ||
3727 | case ATH10K_SCAN_ABORTING: | ||
3651 | ret = -EBUSY; | 3728 | ret = -EBUSY; |
3652 | goto exit; | 3729 | break; |
3653 | } | 3730 | } |
3654 | |||
3655 | reinit_completion(&ar->scan.started); | ||
3656 | reinit_completion(&ar->scan.completed); | ||
3657 | reinit_completion(&ar->scan.on_channel); | ||
3658 | ar->scan.in_progress = true; | ||
3659 | ar->scan.aborting = false; | ||
3660 | ar->scan.is_roc = true; | ||
3661 | ar->scan.vdev_id = arvif->vdev_id; | ||
3662 | ar->scan.roc_freq = chan->center_freq; | ||
3663 | spin_unlock_bh(&ar->data_lock); | 3731 | spin_unlock_bh(&ar->data_lock); |
3664 | 3732 | ||
3733 | if (ret) | ||
3734 | goto exit; | ||
3735 | |||
3665 | memset(&arg, 0, sizeof(arg)); | 3736 | memset(&arg, 0, sizeof(arg)); |
3666 | ath10k_wmi_start_scan_init(ar, &arg); | 3737 | ath10k_wmi_start_scan_init(ar, &arg); |
3667 | arg.vdev_id = arvif->vdev_id; | 3738 | arg.vdev_id = arvif->vdev_id; |
@@ -3676,17 +3747,21 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, | |||
3676 | 3747 | ||
3677 | ret = ath10k_start_scan(ar, &arg); | 3748 | ret = ath10k_start_scan(ar, &arg); |
3678 | if (ret) { | 3749 | if (ret) { |
3679 | ath10k_warn("failed to start roc scan: %d\n", ret); | 3750 | ath10k_warn(ar, "failed to start roc scan: %d\n", ret); |
3680 | spin_lock_bh(&ar->data_lock); | 3751 | spin_lock_bh(&ar->data_lock); |
3681 | ar->scan.in_progress = false; | 3752 | ar->scan.state = ATH10K_SCAN_IDLE; |
3682 | spin_unlock_bh(&ar->data_lock); | 3753 | spin_unlock_bh(&ar->data_lock); |
3683 | goto exit; | 3754 | goto exit; |
3684 | } | 3755 | } |
3685 | 3756 | ||
3686 | ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ); | 3757 | ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ); |
3687 | if (ret == 0) { | 3758 | if (ret == 0) { |
3688 | ath10k_warn("failed to switch to channel for roc scan\n"); | 3759 | ath10k_warn(ar, "failed to switch to channel for roc scan\n"); |
3689 | ath10k_abort_scan(ar); | 3760 | |
3761 | ret = ath10k_scan_stop(ar); | ||
3762 | if (ret) | ||
3763 | ath10k_warn(ar, "failed to stop scan: %d\n", ret); | ||
3764 | |||
3690 | ret = -ETIMEDOUT; | 3765 | ret = -ETIMEDOUT; |
3691 | goto exit; | 3766 | goto exit; |
3692 | } | 3767 | } |
@@ -3702,7 +3777,8 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
3702 | struct ath10k *ar = hw->priv; | 3777 | struct ath10k *ar = hw->priv; |
3703 | 3778 | ||
3704 | mutex_lock(&ar->conf_mutex); | 3779 | mutex_lock(&ar->conf_mutex); |
3705 | ath10k_abort_scan(ar); | 3780 | cancel_delayed_work_sync(&ar->scan.timeout); |
3781 | ath10k_scan_abort(ar); | ||
3706 | mutex_unlock(&ar->conf_mutex); | 3782 | mutex_unlock(&ar->conf_mutex); |
3707 | 3783 | ||
3708 | return 0; | 3784 | return 0; |
@@ -3721,12 +3797,12 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
3721 | 3797 | ||
3722 | mutex_lock(&ar->conf_mutex); | 3798 | mutex_lock(&ar->conf_mutex); |
3723 | list_for_each_entry(arvif, &ar->arvifs, list) { | 3799 | list_for_each_entry(arvif, &ar->arvifs, list) { |
3724 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n", | 3800 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n", |
3725 | arvif->vdev_id, value); | 3801 | arvif->vdev_id, value); |
3726 | 3802 | ||
3727 | ret = ath10k_mac_set_rts(arvif, value); | 3803 | ret = ath10k_mac_set_rts(arvif, value); |
3728 | if (ret) { | 3804 | if (ret) { |
3729 | ath10k_warn("failed to set rts threshold for vdev %d: %d\n", | 3805 | ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n", |
3730 | arvif->vdev_id, ret); | 3806 | arvif->vdev_id, ret); |
3731 | break; | 3807 | break; |
3732 | } | 3808 | } |
@@ -3744,12 +3820,12 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | |||
3744 | 3820 | ||
3745 | mutex_lock(&ar->conf_mutex); | 3821 | mutex_lock(&ar->conf_mutex); |
3746 | list_for_each_entry(arvif, &ar->arvifs, list) { | 3822 | list_for_each_entry(arvif, &ar->arvifs, list) { |
3747 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n", | 3823 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n", |
3748 | arvif->vdev_id, value); | 3824 | arvif->vdev_id, value); |
3749 | 3825 | ||
3750 | ret = ath10k_mac_set_rts(arvif, value); | 3826 | ret = ath10k_mac_set_rts(arvif, value); |
3751 | if (ret) { | 3827 | if (ret) { |
3752 | ath10k_warn("failed to set fragmentation threshold for vdev %d: %d\n", | 3828 | ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n", |
3753 | arvif->vdev_id, ret); | 3829 | arvif->vdev_id, ret); |
3754 | break; | 3830 | break; |
3755 | } | 3831 | } |
@@ -3789,7 +3865,7 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3789 | }), ATH10K_FLUSH_TIMEOUT_HZ); | 3865 | }), ATH10K_FLUSH_TIMEOUT_HZ); |
3790 | 3866 | ||
3791 | if (ret <= 0 || skip) | 3867 | if (ret <= 0 || skip) |
3792 | ath10k_warn("failed to flush transmit queue (skip %i ar-state %i): %i\n", | 3868 | ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n", |
3793 | skip, ar->state, ret); | 3869 | skip, ar->state, ret); |
3794 | 3870 | ||
3795 | skip: | 3871 | skip: |
@@ -3824,7 +3900,7 @@ static int ath10k_suspend(struct ieee80211_hw *hw, | |||
3824 | 3900 | ||
3825 | ret = ath10k_hif_suspend(ar); | 3901 | ret = ath10k_hif_suspend(ar); |
3826 | if (ret) { | 3902 | if (ret) { |
3827 | ath10k_warn("failed to suspend hif: %d\n", ret); | 3903 | ath10k_warn(ar, "failed to suspend hif: %d\n", ret); |
3828 | goto resume; | 3904 | goto resume; |
3829 | } | 3905 | } |
3830 | 3906 | ||
@@ -3833,7 +3909,7 @@ static int ath10k_suspend(struct ieee80211_hw *hw, | |||
3833 | resume: | 3909 | resume: |
3834 | ret = ath10k_wmi_pdev_resume_target(ar); | 3910 | ret = ath10k_wmi_pdev_resume_target(ar); |
3835 | if (ret) | 3911 | if (ret) |
3836 | ath10k_warn("failed to resume target: %d\n", ret); | 3912 | ath10k_warn(ar, "failed to resume target: %d\n", ret); |
3837 | 3913 | ||
3838 | ret = 1; | 3914 | ret = 1; |
3839 | exit: | 3915 | exit: |
@@ -3850,14 +3926,14 @@ static int ath10k_resume(struct ieee80211_hw *hw) | |||
3850 | 3926 | ||
3851 | ret = ath10k_hif_resume(ar); | 3927 | ret = ath10k_hif_resume(ar); |
3852 | if (ret) { | 3928 | if (ret) { |
3853 | ath10k_warn("failed to resume hif: %d\n", ret); | 3929 | ath10k_warn(ar, "failed to resume hif: %d\n", ret); |
3854 | ret = 1; | 3930 | ret = 1; |
3855 | goto exit; | 3931 | goto exit; |
3856 | } | 3932 | } |
3857 | 3933 | ||
3858 | ret = ath10k_wmi_pdev_resume_target(ar); | 3934 | ret = ath10k_wmi_pdev_resume_target(ar); |
3859 | if (ret) { | 3935 | if (ret) { |
3860 | ath10k_warn("failed to resume target: %d\n", ret); | 3936 | ath10k_warn(ar, "failed to resume target: %d\n", ret); |
3861 | ret = 1; | 3937 | ret = 1; |
3862 | goto exit; | 3938 | goto exit; |
3863 | } | 3939 | } |
@@ -3878,7 +3954,7 @@ static void ath10k_restart_complete(struct ieee80211_hw *hw) | |||
3878 | /* If device failed to restart it will be in a different state, e.g. | 3954 | /* If device failed to restart it will be in a different state, e.g. |
3879 | * ATH10K_STATE_WEDGED */ | 3955 | * ATH10K_STATE_WEDGED */ |
3880 | if (ar->state == ATH10K_STATE_RESTARTED) { | 3956 | if (ar->state == ATH10K_STATE_RESTARTED) { |
3881 | ath10k_info("device successfully recovered\n"); | 3957 | ath10k_info(ar, "device successfully recovered\n"); |
3882 | ar->state = ATH10K_STATE_ON; | 3958 | ar->state = ATH10K_STATE_ON; |
3883 | } | 3959 | } |
3884 | 3960 | ||
@@ -4075,7 +4151,8 @@ ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask, | |||
4075 | } | 4151 | } |
4076 | 4152 | ||
4077 | static bool | 4153 | static bool |
4078 | ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask, | 4154 | ath10k_bitrate_mask_rate(struct ath10k *ar, |
4155 | const struct cfg80211_bitrate_mask *mask, | ||
4079 | enum ieee80211_band band, | 4156 | enum ieee80211_band band, |
4080 | u8 *fixed_rate, | 4157 | u8 *fixed_rate, |
4081 | u8 *fixed_nss) | 4158 | u8 *fixed_nss) |
@@ -4133,7 +4210,7 @@ ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask, | |||
4133 | nss <<= 4; | 4210 | nss <<= 4; |
4134 | pream <<= 6; | 4211 | pream <<= 6; |
4135 | 4212 | ||
4136 | ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n", | 4213 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n", |
4137 | pream, nss, rate); | 4214 | pream, nss, rate); |
4138 | 4215 | ||
4139 | *fixed_rate = pream | nss | rate; | 4216 | *fixed_rate = pream | nss | rate; |
@@ -4141,7 +4218,8 @@ ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask, | |||
4141 | return true; | 4218 | return true; |
4142 | } | 4219 | } |
4143 | 4220 | ||
4144 | static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask, | 4221 | static bool ath10k_get_fixed_rate_nss(struct ath10k *ar, |
4222 | const struct cfg80211_bitrate_mask *mask, | ||
4145 | enum ieee80211_band band, | 4223 | enum ieee80211_band band, |
4146 | u8 *fixed_rate, | 4224 | u8 *fixed_rate, |
4147 | u8 *fixed_nss) | 4225 | u8 *fixed_nss) |
@@ -4151,7 +4229,7 @@ static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask, | |||
4151 | return true; | 4229 | return true; |
4152 | 4230 | ||
4153 | /* Next Check single rate is set */ | 4231 | /* Next Check single rate is set */ |
4154 | return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss); | 4232 | return ath10k_bitrate_mask_rate(ar, mask, band, fixed_rate, fixed_nss); |
4155 | } | 4233 | } |
4156 | 4234 | ||
4157 | static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, | 4235 | static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, |
@@ -4171,16 +4249,16 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, | |||
4171 | goto exit; | 4249 | goto exit; |
4172 | 4250 | ||
4173 | if (fixed_rate == WMI_FIXED_RATE_NONE) | 4251 | if (fixed_rate == WMI_FIXED_RATE_NONE) |
4174 | ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n"); | 4252 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n"); |
4175 | 4253 | ||
4176 | if (force_sgi) | 4254 | if (force_sgi) |
4177 | ath10k_dbg(ATH10K_DBG_MAC, "mac force sgi\n"); | 4255 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac force sgi\n"); |
4178 | 4256 | ||
4179 | vdev_param = ar->wmi.vdev_param->fixed_rate; | 4257 | vdev_param = ar->wmi.vdev_param->fixed_rate; |
4180 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, | 4258 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, |
4181 | vdev_param, fixed_rate); | 4259 | vdev_param, fixed_rate); |
4182 | if (ret) { | 4260 | if (ret) { |
4183 | ath10k_warn("failed to set fixed rate param 0x%02x: %d\n", | 4261 | ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n", |
4184 | fixed_rate, ret); | 4262 | fixed_rate, ret); |
4185 | ret = -EINVAL; | 4263 | ret = -EINVAL; |
4186 | goto exit; | 4264 | goto exit; |
@@ -4193,7 +4271,7 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, | |||
4193 | vdev_param, fixed_nss); | 4271 | vdev_param, fixed_nss); |
4194 | 4272 | ||
4195 | if (ret) { | 4273 | if (ret) { |
4196 | ath10k_warn("failed to set fixed nss param %d: %d\n", | 4274 | ath10k_warn(ar, "failed to set fixed nss param %d: %d\n", |
4197 | fixed_nss, ret); | 4275 | fixed_nss, ret); |
4198 | ret = -EINVAL; | 4276 | ret = -EINVAL; |
4199 | goto exit; | 4277 | goto exit; |
@@ -4206,7 +4284,7 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, | |||
4206 | force_sgi); | 4284 | force_sgi); |
4207 | 4285 | ||
4208 | if (ret) { | 4286 | if (ret) { |
4209 | ath10k_warn("failed to set sgi param %d: %d\n", | 4287 | ath10k_warn(ar, "failed to set sgi param %d: %d\n", |
4210 | force_sgi, ret); | 4288 | force_sgi, ret); |
4211 | ret = -EINVAL; | 4289 | ret = -EINVAL; |
4212 | goto exit; | 4290 | goto exit; |
@@ -4235,14 +4313,14 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw, | |||
4235 | return -EINVAL; | 4313 | return -EINVAL; |
4236 | 4314 | ||
4237 | if (!ath10k_default_bitrate_mask(ar, band, mask)) { | 4315 | if (!ath10k_default_bitrate_mask(ar, band, mask)) { |
4238 | if (!ath10k_get_fixed_rate_nss(mask, band, | 4316 | if (!ath10k_get_fixed_rate_nss(ar, mask, band, |
4239 | &fixed_rate, | 4317 | &fixed_rate, |
4240 | &fixed_nss)) | 4318 | &fixed_nss)) |
4241 | return -EINVAL; | 4319 | return -EINVAL; |
4242 | } | 4320 | } |
4243 | 4321 | ||
4244 | if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) { | 4322 | if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) { |
4245 | ath10k_warn("failed to force SGI usage for default rate settings\n"); | 4323 | ath10k_warn(ar, "failed to force SGI usage for default rate settings\n"); |
4246 | return -EINVAL; | 4324 | return -EINVAL; |
4247 | } | 4325 | } |
4248 | 4326 | ||
@@ -4261,7 +4339,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, | |||
4261 | 4339 | ||
4262 | spin_lock_bh(&ar->data_lock); | 4340 | spin_lock_bh(&ar->data_lock); |
4263 | 4341 | ||
4264 | ath10k_dbg(ATH10K_DBG_MAC, | 4342 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
4265 | "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", | 4343 | "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", |
4266 | sta->addr, changed, sta->bandwidth, sta->rx_nss, | 4344 | sta->addr, changed, sta->bandwidth, sta->rx_nss, |
4267 | sta->smps_mode); | 4345 | sta->smps_mode); |
@@ -4280,7 +4358,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, | |||
4280 | bw = WMI_PEER_CHWIDTH_80MHZ; | 4358 | bw = WMI_PEER_CHWIDTH_80MHZ; |
4281 | break; | 4359 | break; |
4282 | case IEEE80211_STA_RX_BW_160: | 4360 | case IEEE80211_STA_RX_BW_160: |
4283 | ath10k_warn("Invalid bandwith %d in rc update for %pM\n", | 4361 | ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n", |
4284 | sta->bandwidth, sta->addr); | 4362 | sta->bandwidth, sta->addr); |
4285 | bw = WMI_PEER_CHWIDTH_20MHZ; | 4363 | bw = WMI_PEER_CHWIDTH_20MHZ; |
4286 | break; | 4364 | break; |
@@ -4307,7 +4385,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, | |||
4307 | smps = WMI_PEER_SMPS_DYNAMIC; | 4385 | smps = WMI_PEER_SMPS_DYNAMIC; |
4308 | break; | 4386 | break; |
4309 | case IEEE80211_SMPS_NUM_MODES: | 4387 | case IEEE80211_SMPS_NUM_MODES: |
4310 | ath10k_warn("Invalid smps %d in sta rc update for %pM\n", | 4388 | ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n", |
4311 | sta->smps_mode, sta->addr); | 4389 | sta->smps_mode, sta->addr); |
4312 | smps = WMI_PEER_SMPS_PS_NONE; | 4390 | smps = WMI_PEER_SMPS_PS_NONE; |
4313 | break; | 4391 | break; |
@@ -4339,9 +4417,10 @@ static int ath10k_ampdu_action(struct ieee80211_hw *hw, | |||
4339 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | 4417 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
4340 | u8 buf_size) | 4418 | u8 buf_size) |
4341 | { | 4419 | { |
4420 | struct ath10k *ar = hw->priv; | ||
4342 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 4421 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
4343 | 4422 | ||
4344 | ath10k_dbg(ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n", | 4423 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n", |
4345 | arvif->vdev_id, sta->addr, tid, action); | 4424 | arvif->vdev_id, sta->addr, tid, action); |
4346 | 4425 | ||
4347 | switch (action) { | 4426 | switch (action) { |
@@ -4489,12 +4568,12 @@ static struct ieee80211_rate ath10k_rates[] = { | |||
4489 | #define ath10k_g_rates (ath10k_rates + 0) | 4568 | #define ath10k_g_rates (ath10k_rates + 0) |
4490 | #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates)) | 4569 | #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates)) |
4491 | 4570 | ||
4492 | struct ath10k *ath10k_mac_create(void) | 4571 | struct ath10k *ath10k_mac_create(size_t priv_size) |
4493 | { | 4572 | { |
4494 | struct ieee80211_hw *hw; | 4573 | struct ieee80211_hw *hw; |
4495 | struct ath10k *ar; | 4574 | struct ath10k *ar; |
4496 | 4575 | ||
4497 | hw = ieee80211_alloc_hw(sizeof(struct ath10k), &ath10k_ops); | 4576 | hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops); |
4498 | if (!hw) | 4577 | if (!hw) |
4499 | return NULL; | 4578 | return NULL; |
4500 | 4579 | ||
@@ -4669,7 +4748,7 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id) | |||
4669 | ath10k_get_arvif_iter, | 4748 | ath10k_get_arvif_iter, |
4670 | &arvif_iter); | 4749 | &arvif_iter); |
4671 | if (!arvif_iter.arvif) { | 4750 | if (!arvif_iter.arvif) { |
4672 | ath10k_warn("No VIF found for vdev %d\n", vdev_id); | 4751 | ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id); |
4673 | return NULL; | 4752 | return NULL; |
4674 | } | 4753 | } |
4675 | 4754 | ||
@@ -4815,19 +4894,19 @@ int ath10k_mac_register(struct ath10k *ar) | |||
4815 | NL80211_DFS_UNSET); | 4894 | NL80211_DFS_UNSET); |
4816 | 4895 | ||
4817 | if (!ar->dfs_detector) | 4896 | if (!ar->dfs_detector) |
4818 | ath10k_warn("failed to initialise DFS pattern detector\n"); | 4897 | ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); |
4819 | } | 4898 | } |
4820 | 4899 | ||
4821 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, | 4900 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, |
4822 | ath10k_reg_notifier); | 4901 | ath10k_reg_notifier); |
4823 | if (ret) { | 4902 | if (ret) { |
4824 | ath10k_err("failed to initialise regulatory: %i\n", ret); | 4903 | ath10k_err(ar, "failed to initialise regulatory: %i\n", ret); |
4825 | goto err_free; | 4904 | goto err_free; |
4826 | } | 4905 | } |
4827 | 4906 | ||
4828 | ret = ieee80211_register_hw(ar->hw); | 4907 | ret = ieee80211_register_hw(ar->hw); |
4829 | if (ret) { | 4908 | if (ret) { |
4830 | ath10k_err("failed to register ieee80211: %d\n", ret); | 4909 | ath10k_err(ar, "failed to register ieee80211: %d\n", ret); |
4831 | goto err_free; | 4910 | goto err_free; |
4832 | } | 4911 | } |
4833 | 4912 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index ef4f84376d7c..6c80eeada3e2 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h | |||
@@ -26,12 +26,14 @@ struct ath10k_generic_iter { | |||
26 | int ret; | 26 | int ret; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct ath10k *ath10k_mac_create(void); | 29 | struct ath10k *ath10k_mac_create(size_t priv_size); |
30 | void ath10k_mac_destroy(struct ath10k *ar); | 30 | void ath10k_mac_destroy(struct ath10k *ar); |
31 | int ath10k_mac_register(struct ath10k *ar); | 31 | int ath10k_mac_register(struct ath10k *ar); |
32 | void ath10k_mac_unregister(struct ath10k *ar); | 32 | void ath10k_mac_unregister(struct ath10k *ar); |
33 | struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id); | 33 | struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id); |
34 | void ath10k_reset_scan(unsigned long ptr); | 34 | void __ath10k_scan_finish(struct ath10k *ar); |
35 | void ath10k_scan_finish(struct ath10k *ar); | ||
36 | void ath10k_scan_timeout_work(struct work_struct *work); | ||
35 | void ath10k_offchan_tx_purge(struct ath10k *ar); | 37 | void ath10k_offchan_tx_purge(struct ath10k *ar); |
36 | void ath10k_offchan_tx_work(struct work_struct *work); | 38 | void ath10k_offchan_tx_work(struct work_struct *work); |
37 | void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); | 39 | void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 3376963a4862..056a35a77133 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -44,13 +44,9 @@ enum ath10k_pci_reset_mode { | |||
44 | ATH10K_PCI_RESET_WARM_ONLY = 1, | 44 | ATH10K_PCI_RESET_WARM_ONLY = 1, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static unsigned int ath10k_pci_target_ps; | ||
48 | static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO; | 47 | static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO; |
49 | static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO; | 48 | static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO; |
50 | 49 | ||
51 | module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644); | ||
52 | MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option"); | ||
53 | |||
54 | module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644); | 50 | module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644); |
55 | MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)"); | 51 | MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)"); |
56 | 52 | ||
@@ -71,10 +67,7 @@ static const struct pci_device_id ath10k_pci_id_table[] = { | |||
71 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, | 67 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, |
72 | u32 *data); | 68 | u32 *data); |
73 | 69 | ||
74 | static int ath10k_pci_post_rx(struct ath10k *ar); | 70 | static void ath10k_pci_buffer_cleanup(struct ath10k *ar); |
75 | static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, | ||
76 | int num); | ||
77 | static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); | ||
78 | static int ath10k_pci_cold_reset(struct ath10k *ar); | 71 | static int ath10k_pci_cold_reset(struct ath10k *ar); |
79 | static int ath10k_pci_warm_reset(struct ath10k *ar); | 72 | static int ath10k_pci_warm_reset(struct ath10k *ar); |
80 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar); | 73 | static int ath10k_pci_wait_for_target_init(struct ath10k *ar); |
@@ -156,79 +149,175 @@ static const struct ce_attr host_ce_config_wlan[] = { | |||
156 | static const struct ce_pipe_config target_ce_config_wlan[] = { | 149 | static const struct ce_pipe_config target_ce_config_wlan[] = { |
157 | /* CE0: host->target HTC control and raw streams */ | 150 | /* CE0: host->target HTC control and raw streams */ |
158 | { | 151 | { |
159 | .pipenum = 0, | 152 | .pipenum = __cpu_to_le32(0), |
160 | .pipedir = PIPEDIR_OUT, | 153 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), |
161 | .nentries = 32, | 154 | .nentries = __cpu_to_le32(32), |
162 | .nbytes_max = 256, | 155 | .nbytes_max = __cpu_to_le32(256), |
163 | .flags = CE_ATTR_FLAGS, | 156 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
164 | .reserved = 0, | 157 | .reserved = __cpu_to_le32(0), |
165 | }, | 158 | }, |
166 | 159 | ||
167 | /* CE1: target->host HTT + HTC control */ | 160 | /* CE1: target->host HTT + HTC control */ |
168 | { | 161 | { |
169 | .pipenum = 1, | 162 | .pipenum = __cpu_to_le32(1), |
170 | .pipedir = PIPEDIR_IN, | 163 | .pipedir = __cpu_to_le32(PIPEDIR_IN), |
171 | .nentries = 32, | 164 | .nentries = __cpu_to_le32(32), |
172 | .nbytes_max = 512, | 165 | .nbytes_max = __cpu_to_le32(512), |
173 | .flags = CE_ATTR_FLAGS, | 166 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
174 | .reserved = 0, | 167 | .reserved = __cpu_to_le32(0), |
175 | }, | 168 | }, |
176 | 169 | ||
177 | /* CE2: target->host WMI */ | 170 | /* CE2: target->host WMI */ |
178 | { | 171 | { |
179 | .pipenum = 2, | 172 | .pipenum = __cpu_to_le32(2), |
180 | .pipedir = PIPEDIR_IN, | 173 | .pipedir = __cpu_to_le32(PIPEDIR_IN), |
181 | .nentries = 32, | 174 | .nentries = __cpu_to_le32(32), |
182 | .nbytes_max = 2048, | 175 | .nbytes_max = __cpu_to_le32(2048), |
183 | .flags = CE_ATTR_FLAGS, | 176 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
184 | .reserved = 0, | 177 | .reserved = __cpu_to_le32(0), |
185 | }, | 178 | }, |
186 | 179 | ||
187 | /* CE3: host->target WMI */ | 180 | /* CE3: host->target WMI */ |
188 | { | 181 | { |
189 | .pipenum = 3, | 182 | .pipenum = __cpu_to_le32(3), |
190 | .pipedir = PIPEDIR_OUT, | 183 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), |
191 | .nentries = 32, | 184 | .nentries = __cpu_to_le32(32), |
192 | .nbytes_max = 2048, | 185 | .nbytes_max = __cpu_to_le32(2048), |
193 | .flags = CE_ATTR_FLAGS, | 186 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
194 | .reserved = 0, | 187 | .reserved = __cpu_to_le32(0), |
195 | }, | 188 | }, |
196 | 189 | ||
197 | /* CE4: host->target HTT */ | 190 | /* CE4: host->target HTT */ |
198 | { | 191 | { |
199 | .pipenum = 4, | 192 | .pipenum = __cpu_to_le32(4), |
200 | .pipedir = PIPEDIR_OUT, | 193 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), |
201 | .nentries = 256, | 194 | .nentries = __cpu_to_le32(256), |
202 | .nbytes_max = 256, | 195 | .nbytes_max = __cpu_to_le32(256), |
203 | .flags = CE_ATTR_FLAGS, | 196 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
204 | .reserved = 0, | 197 | .reserved = __cpu_to_le32(0), |
205 | }, | 198 | }, |
206 | 199 | ||
207 | /* NB: 50% of src nentries, since tx has 2 frags */ | 200 | /* NB: 50% of src nentries, since tx has 2 frags */ |
208 | 201 | ||
209 | /* CE5: unused */ | 202 | /* CE5: unused */ |
210 | { | 203 | { |
211 | .pipenum = 5, | 204 | .pipenum = __cpu_to_le32(5), |
212 | .pipedir = PIPEDIR_OUT, | 205 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), |
213 | .nentries = 32, | 206 | .nentries = __cpu_to_le32(32), |
214 | .nbytes_max = 2048, | 207 | .nbytes_max = __cpu_to_le32(2048), |
215 | .flags = CE_ATTR_FLAGS, | 208 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
216 | .reserved = 0, | 209 | .reserved = __cpu_to_le32(0), |
217 | }, | 210 | }, |
218 | 211 | ||
219 | /* CE6: Reserved for target autonomous hif_memcpy */ | 212 | /* CE6: Reserved for target autonomous hif_memcpy */ |
220 | { | 213 | { |
221 | .pipenum = 6, | 214 | .pipenum = __cpu_to_le32(6), |
222 | .pipedir = PIPEDIR_INOUT, | 215 | .pipedir = __cpu_to_le32(PIPEDIR_INOUT), |
223 | .nentries = 32, | 216 | .nentries = __cpu_to_le32(32), |
224 | .nbytes_max = 4096, | 217 | .nbytes_max = __cpu_to_le32(4096), |
225 | .flags = CE_ATTR_FLAGS, | 218 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), |
226 | .reserved = 0, | 219 | .reserved = __cpu_to_le32(0), |
227 | }, | 220 | }, |
228 | 221 | ||
229 | /* CE7 used only by Host */ | 222 | /* CE7 used only by Host */ |
230 | }; | 223 | }; |
231 | 224 | ||
225 | /* | ||
226 | * Map from service/endpoint to Copy Engine. | ||
227 | * This table is derived from the CE_PCI TABLE, above. | ||
228 | * It is passed to the Target at startup for use by firmware. | ||
229 | */ | ||
230 | static const struct service_to_pipe target_service_to_ce_map_wlan[] = { | ||
231 | { | ||
232 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), | ||
233 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
234 | __cpu_to_le32(3), | ||
235 | }, | ||
236 | { | ||
237 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), | ||
238 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
239 | __cpu_to_le32(2), | ||
240 | }, | ||
241 | { | ||
242 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK), | ||
243 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
244 | __cpu_to_le32(3), | ||
245 | }, | ||
246 | { | ||
247 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK), | ||
248 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
249 | __cpu_to_le32(2), | ||
250 | }, | ||
251 | { | ||
252 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE), | ||
253 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
254 | __cpu_to_le32(3), | ||
255 | }, | ||
256 | { | ||
257 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE), | ||
258 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
259 | __cpu_to_le32(2), | ||
260 | }, | ||
261 | { | ||
262 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI), | ||
263 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
264 | __cpu_to_le32(3), | ||
265 | }, | ||
266 | { | ||
267 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI), | ||
268 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
269 | __cpu_to_le32(2), | ||
270 | }, | ||
271 | { | ||
272 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL), | ||
273 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
274 | __cpu_to_le32(3), | ||
275 | }, | ||
276 | { | ||
277 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL), | ||
278 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
279 | __cpu_to_le32(2), | ||
280 | }, | ||
281 | { | ||
282 | __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL), | ||
283 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
284 | __cpu_to_le32(0), | ||
285 | }, | ||
286 | { | ||
287 | __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL), | ||
288 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
289 | __cpu_to_le32(1), | ||
290 | }, | ||
291 | { /* not used */ | ||
292 | __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS), | ||
293 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
294 | __cpu_to_le32(0), | ||
295 | }, | ||
296 | { /* not used */ | ||
297 | __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS), | ||
298 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
299 | __cpu_to_le32(1), | ||
300 | }, | ||
301 | { | ||
302 | __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG), | ||
303 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ | ||
304 | __cpu_to_le32(4), | ||
305 | }, | ||
306 | { | ||
307 | __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG), | ||
308 | __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ | ||
309 | __cpu_to_le32(1), | ||
310 | }, | ||
311 | |||
312 | /* (Additions here) */ | ||
313 | |||
314 | { /* must be last */ | ||
315 | __cpu_to_le32(0), | ||
316 | __cpu_to_le32(0), | ||
317 | __cpu_to_le32(0), | ||
318 | }, | ||
319 | }; | ||
320 | |||
232 | static bool ath10k_pci_irq_pending(struct ath10k *ar) | 321 | static bool ath10k_pci_irq_pending(struct ath10k *ar) |
233 | { | 322 | { |
234 | u32 cause; | 323 | u32 cause; |
@@ -270,44 +359,111 @@ static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) | |||
270 | PCIE_INTR_ENABLE_ADDRESS); | 359 | PCIE_INTR_ENABLE_ADDRESS); |
271 | } | 360 | } |
272 | 361 | ||
273 | static irqreturn_t ath10k_pci_early_irq_handler(int irq, void *arg) | 362 | static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar) |
274 | { | 363 | { |
275 | struct ath10k *ar = arg; | ||
276 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 364 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
277 | 365 | ||
278 | if (ar_pci->num_msi_intrs == 0) { | 366 | if (ar_pci->num_msi_intrs > 1) |
279 | if (!ath10k_pci_irq_pending(ar)) | 367 | return "msi-x"; |
280 | return IRQ_NONE; | 368 | else if (ar_pci->num_msi_intrs == 1) |
281 | 369 | return "msi"; | |
282 | ath10k_pci_disable_and_clear_legacy_irq(ar); | 370 | else |
283 | } | 371 | return "legacy"; |
284 | |||
285 | tasklet_schedule(&ar_pci->early_irq_tasklet); | ||
286 | |||
287 | return IRQ_HANDLED; | ||
288 | } | 372 | } |
289 | 373 | ||
290 | static int ath10k_pci_request_early_irq(struct ath10k *ar) | 374 | static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe) |
291 | { | 375 | { |
376 | struct ath10k *ar = pipe->hif_ce_state; | ||
292 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 377 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
378 | struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl; | ||
379 | struct sk_buff *skb; | ||
380 | dma_addr_t paddr; | ||
293 | int ret; | 381 | int ret; |
294 | 382 | ||
295 | /* Regardless whether MSI-X/MSI/legacy irqs have been set up the first | 383 | lockdep_assert_held(&ar_pci->ce_lock); |
296 | * interrupt from irq vector is triggered in all cases for FW | 384 | |
297 | * indication/errors */ | 385 | skb = dev_alloc_skb(pipe->buf_sz); |
298 | ret = request_irq(ar_pci->pdev->irq, ath10k_pci_early_irq_handler, | 386 | if (!skb) |
299 | IRQF_SHARED, "ath10k_pci (early)", ar); | 387 | return -ENOMEM; |
388 | |||
389 | WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); | ||
390 | |||
391 | paddr = dma_map_single(ar->dev, skb->data, | ||
392 | skb->len + skb_tailroom(skb), | ||
393 | DMA_FROM_DEVICE); | ||
394 | if (unlikely(dma_mapping_error(ar->dev, paddr))) { | ||
395 | ath10k_warn(ar, "failed to dma map pci rx buf\n"); | ||
396 | dev_kfree_skb_any(skb); | ||
397 | return -EIO; | ||
398 | } | ||
399 | |||
400 | ATH10K_SKB_CB(skb)->paddr = paddr; | ||
401 | |||
402 | ret = __ath10k_ce_rx_post_buf(ce_pipe, skb, paddr); | ||
300 | if (ret) { | 403 | if (ret) { |
301 | ath10k_warn("failed to request early irq: %d\n", ret); | 404 | ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret); |
405 | dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb), | ||
406 | DMA_FROM_DEVICE); | ||
407 | dev_kfree_skb_any(skb); | ||
302 | return ret; | 408 | return ret; |
303 | } | 409 | } |
304 | 410 | ||
305 | return 0; | 411 | return 0; |
306 | } | 412 | } |
307 | 413 | ||
308 | static void ath10k_pci_free_early_irq(struct ath10k *ar) | 414 | static void __ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe) |
415 | { | ||
416 | struct ath10k *ar = pipe->hif_ce_state; | ||
417 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
418 | struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl; | ||
419 | int ret, num; | ||
420 | |||
421 | lockdep_assert_held(&ar_pci->ce_lock); | ||
422 | |||
423 | if (pipe->buf_sz == 0) | ||
424 | return; | ||
425 | |||
426 | if (!ce_pipe->dest_ring) | ||
427 | return; | ||
428 | |||
429 | num = __ath10k_ce_rx_num_free_bufs(ce_pipe); | ||
430 | while (num--) { | ||
431 | ret = __ath10k_pci_rx_post_buf(pipe); | ||
432 | if (ret) { | ||
433 | ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret); | ||
434 | mod_timer(&ar_pci->rx_post_retry, jiffies + | ||
435 | ATH10K_PCI_RX_POST_RETRY_MS); | ||
436 | break; | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | static void ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe) | ||
442 | { | ||
443 | struct ath10k *ar = pipe->hif_ce_state; | ||
444 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
445 | |||
446 | spin_lock_bh(&ar_pci->ce_lock); | ||
447 | __ath10k_pci_rx_post_pipe(pipe); | ||
448 | spin_unlock_bh(&ar_pci->ce_lock); | ||
449 | } | ||
450 | |||
451 | static void ath10k_pci_rx_post(struct ath10k *ar) | ||
452 | { | ||
453 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
454 | int i; | ||
455 | |||
456 | spin_lock_bh(&ar_pci->ce_lock); | ||
457 | for (i = 0; i < CE_COUNT; i++) | ||
458 | __ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]); | ||
459 | spin_unlock_bh(&ar_pci->ce_lock); | ||
460 | } | ||
461 | |||
462 | static void ath10k_pci_rx_replenish_retry(unsigned long ptr) | ||
309 | { | 463 | { |
310 | free_irq(ath10k_pci_priv(ar)->pdev->irq, ar); | 464 | struct ath10k *ar = (void *)ptr; |
465 | |||
466 | ath10k_pci_rx_post(ar); | ||
311 | } | 467 | } |
312 | 468 | ||
313 | /* | 469 | /* |
@@ -376,7 +532,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
376 | nbytes = min_t(unsigned int, remaining_bytes, | 532 | nbytes = min_t(unsigned int, remaining_bytes, |
377 | DIAG_TRANSFER_LIMIT); | 533 | DIAG_TRANSFER_LIMIT); |
378 | 534 | ||
379 | ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, ce_data); | 535 | ret = ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data); |
380 | if (ret != 0) | 536 | if (ret != 0) |
381 | goto done; | 537 | goto done; |
382 | 538 | ||
@@ -389,10 +545,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
389 | * convert it from Target CPU virtual address space | 545 | * convert it from Target CPU virtual address space |
390 | * to CE address space | 546 | * to CE address space |
391 | */ | 547 | */ |
392 | ath10k_pci_wake(ar); | ||
393 | address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, | 548 | address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, |
394 | address); | 549 | address); |
395 | ath10k_pci_sleep(ar); | ||
396 | 550 | ||
397 | ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, | 551 | ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, |
398 | 0); | 552 | 0); |
@@ -448,15 +602,10 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
448 | } | 602 | } |
449 | 603 | ||
450 | done: | 604 | done: |
451 | if (ret == 0) { | 605 | if (ret == 0) |
452 | /* Copy data from allocated DMA buf to caller's buf */ | 606 | memcpy(data, data_buf, orig_nbytes); |
453 | WARN_ON_ONCE(orig_nbytes & 3); | 607 | else |
454 | for (i = 0; i < orig_nbytes / sizeof(__le32); i++) { | 608 | ath10k_warn(ar, "failed to read diag value at 0x%x: %d\n", |
455 | ((u32 *)data)[i] = | ||
456 | __le32_to_cpu(((__le32 *)data_buf)[i]); | ||
457 | } | ||
458 | } else | ||
459 | ath10k_warn("failed to read diag value at 0x%x: %d\n", | ||
460 | address, ret); | 609 | address, ret); |
461 | 610 | ||
462 | if (data_buf) | 611 | if (data_buf) |
@@ -466,17 +615,54 @@ done: | |||
466 | return ret; | 615 | return ret; |
467 | } | 616 | } |
468 | 617 | ||
618 | static int ath10k_pci_diag_read32(struct ath10k *ar, u32 address, u32 *value) | ||
619 | { | ||
620 | __le32 val = 0; | ||
621 | int ret; | ||
622 | |||
623 | ret = ath10k_pci_diag_read_mem(ar, address, &val, sizeof(val)); | ||
624 | *value = __le32_to_cpu(val); | ||
625 | |||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | static int __ath10k_pci_diag_read_hi(struct ath10k *ar, void *dest, | ||
630 | u32 src, u32 len) | ||
631 | { | ||
632 | u32 host_addr, addr; | ||
633 | int ret; | ||
634 | |||
635 | host_addr = host_interest_item_address(src); | ||
636 | |||
637 | ret = ath10k_pci_diag_read32(ar, host_addr, &addr); | ||
638 | if (ret != 0) { | ||
639 | ath10k_warn(ar, "failed to get memcpy hi address for firmware address %d: %d\n", | ||
640 | src, ret); | ||
641 | return ret; | ||
642 | } | ||
643 | |||
644 | ret = ath10k_pci_diag_read_mem(ar, addr, dest, len); | ||
645 | if (ret != 0) { | ||
646 | ath10k_warn(ar, "failed to memcpy firmware memory from %d (%d B): %d\n", | ||
647 | addr, len, ret); | ||
648 | return ret; | ||
649 | } | ||
650 | |||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | #define ath10k_pci_diag_read_hi(ar, dest, src, len) \ | ||
655 | __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len); | ||
656 | |||
469 | /* Read 4-byte aligned data from Target memory or register */ | 657 | /* Read 4-byte aligned data from Target memory or register */ |
470 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, | 658 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, |
471 | u32 *data) | 659 | u32 *data) |
472 | { | 660 | { |
473 | /* Assume range doesn't cross this boundary */ | 661 | /* Assume range doesn't cross this boundary */ |
474 | if (address >= DRAM_BASE_ADDRESS) | 662 | if (address >= DRAM_BASE_ADDRESS) |
475 | return ath10k_pci_diag_read_mem(ar, address, data, sizeof(u32)); | 663 | return ath10k_pci_diag_read32(ar, address, data); |
476 | 664 | ||
477 | ath10k_pci_wake(ar); | ||
478 | *data = ath10k_pci_read32(ar, address); | 665 | *data = ath10k_pci_read32(ar, address); |
479 | ath10k_pci_sleep(ar); | ||
480 | return 0; | 666 | return 0; |
481 | } | 667 | } |
482 | 668 | ||
@@ -514,9 +700,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
514 | } | 700 | } |
515 | 701 | ||
516 | /* Copy caller's data to allocated DMA buf */ | 702 | /* Copy caller's data to allocated DMA buf */ |
517 | WARN_ON_ONCE(orig_nbytes & 3); | 703 | memcpy(data_buf, data, orig_nbytes); |
518 | for (i = 0; i < orig_nbytes / sizeof(__le32); i++) | ||
519 | ((__le32 *)data_buf)[i] = __cpu_to_le32(((u32 *)data)[i]); | ||
520 | 704 | ||
521 | /* | 705 | /* |
522 | * The address supplied by the caller is in the | 706 | * The address supplied by the caller is in the |
@@ -528,9 +712,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
528 | * to | 712 | * to |
529 | * CE address space | 713 | * CE address space |
530 | */ | 714 | */ |
531 | ath10k_pci_wake(ar); | ||
532 | address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); | 715 | address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); |
533 | ath10k_pci_sleep(ar); | ||
534 | 716 | ||
535 | remaining_bytes = orig_nbytes; | 717 | remaining_bytes = orig_nbytes; |
536 | ce_data = ce_data_base; | 718 | ce_data = ce_data_base; |
@@ -539,7 +721,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
539 | nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); | 721 | nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); |
540 | 722 | ||
541 | /* Set up to receive directly into Target(!) address */ | 723 | /* Set up to receive directly into Target(!) address */ |
542 | ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, address); | 724 | ret = ath10k_ce_rx_post_buf(ce_diag, NULL, address); |
543 | if (ret != 0) | 725 | if (ret != 0) |
544 | goto done; | 726 | goto done; |
545 | 727 | ||
@@ -608,66 +790,46 @@ done: | |||
608 | } | 790 | } |
609 | 791 | ||
610 | if (ret != 0) | 792 | if (ret != 0) |
611 | ath10k_warn("failed to write diag value at 0x%x: %d\n", | 793 | ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", |
612 | address, ret); | 794 | address, ret); |
613 | 795 | ||
614 | return ret; | 796 | return ret; |
615 | } | 797 | } |
616 | 798 | ||
799 | static int ath10k_pci_diag_write32(struct ath10k *ar, u32 address, u32 value) | ||
800 | { | ||
801 | __le32 val = __cpu_to_le32(value); | ||
802 | |||
803 | return ath10k_pci_diag_write_mem(ar, address, &val, sizeof(val)); | ||
804 | } | ||
805 | |||
617 | /* Write 4B data to Target memory or register */ | 806 | /* Write 4B data to Target memory or register */ |
618 | static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address, | 807 | static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address, |
619 | u32 data) | 808 | u32 data) |
620 | { | 809 | { |
621 | /* Assume range doesn't cross this boundary */ | 810 | /* Assume range doesn't cross this boundary */ |
622 | if (address >= DRAM_BASE_ADDRESS) | 811 | if (address >= DRAM_BASE_ADDRESS) |
623 | return ath10k_pci_diag_write_mem(ar, address, &data, | 812 | return ath10k_pci_diag_write32(ar, address, data); |
624 | sizeof(u32)); | ||
625 | 813 | ||
626 | ath10k_pci_wake(ar); | ||
627 | ath10k_pci_write32(ar, address, data); | 814 | ath10k_pci_write32(ar, address, data); |
628 | ath10k_pci_sleep(ar); | ||
629 | return 0; | 815 | return 0; |
630 | } | 816 | } |
631 | 817 | ||
632 | static bool ath10k_pci_target_is_awake(struct ath10k *ar) | 818 | static bool ath10k_pci_is_awake(struct ath10k *ar) |
633 | { | 819 | { |
634 | void __iomem *mem = ath10k_pci_priv(ar)->mem; | 820 | u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS); |
635 | u32 val; | 821 | |
636 | val = ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + | 822 | return RTC_STATE_V_GET(val) == RTC_STATE_V_ON; |
637 | RTC_STATE_ADDRESS); | ||
638 | return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON); | ||
639 | } | 823 | } |
640 | 824 | ||
641 | int ath10k_do_pci_wake(struct ath10k *ar) | 825 | static int ath10k_pci_wake_wait(struct ath10k *ar) |
642 | { | 826 | { |
643 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
644 | void __iomem *pci_addr = ar_pci->mem; | ||
645 | int tot_delay = 0; | 827 | int tot_delay = 0; |
646 | int curr_delay = 5; | 828 | int curr_delay = 5; |
647 | 829 | ||
648 | if (atomic_read(&ar_pci->keep_awake_count) == 0) { | 830 | while (tot_delay < PCIE_WAKE_TIMEOUT) { |
649 | /* Force AWAKE */ | 831 | if (ath10k_pci_is_awake(ar)) |
650 | iowrite32(PCIE_SOC_WAKE_V_MASK, | ||
651 | pci_addr + PCIE_LOCAL_BASE_ADDRESS + | ||
652 | PCIE_SOC_WAKE_ADDRESS); | ||
653 | } | ||
654 | atomic_inc(&ar_pci->keep_awake_count); | ||
655 | |||
656 | if (ar_pci->verified_awake) | ||
657 | return 0; | ||
658 | |||
659 | for (;;) { | ||
660 | if (ath10k_pci_target_is_awake(ar)) { | ||
661 | ar_pci->verified_awake = true; | ||
662 | return 0; | 832 | return 0; |
663 | } | ||
664 | |||
665 | if (tot_delay > PCIE_WAKE_TIMEOUT) { | ||
666 | ath10k_warn("target took longer %d us to wake up (awake count %d)\n", | ||
667 | PCIE_WAKE_TIMEOUT, | ||
668 | atomic_read(&ar_pci->keep_awake_count)); | ||
669 | return -ETIMEDOUT; | ||
670 | } | ||
671 | 833 | ||
672 | udelay(curr_delay); | 834 | udelay(curr_delay); |
673 | tot_delay += curr_delay; | 835 | tot_delay += curr_delay; |
@@ -675,20 +837,21 @@ int ath10k_do_pci_wake(struct ath10k *ar) | |||
675 | if (curr_delay < 50) | 837 | if (curr_delay < 50) |
676 | curr_delay += 5; | 838 | curr_delay += 5; |
677 | } | 839 | } |
840 | |||
841 | return -ETIMEDOUT; | ||
678 | } | 842 | } |
679 | 843 | ||
680 | void ath10k_do_pci_sleep(struct ath10k *ar) | 844 | static int ath10k_pci_wake(struct ath10k *ar) |
681 | { | 845 | { |
682 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 846 | ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, |
683 | void __iomem *pci_addr = ar_pci->mem; | 847 | PCIE_SOC_WAKE_V_MASK); |
848 | return ath10k_pci_wake_wait(ar); | ||
849 | } | ||
684 | 850 | ||
685 | if (atomic_dec_and_test(&ar_pci->keep_awake_count)) { | 851 | static void ath10k_pci_sleep(struct ath10k *ar) |
686 | /* Allow sleep */ | 852 | { |
687 | ar_pci->verified_awake = false; | 853 | ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, |
688 | iowrite32(PCIE_SOC_WAKE_RESET, | 854 | PCIE_SOC_WAKE_RESET); |
689 | pci_addr + PCIE_LOCAL_BASE_ADDRESS + | ||
690 | PCIE_SOC_WAKE_ADDRESS); | ||
691 | } | ||
692 | } | 855 | } |
693 | 856 | ||
694 | /* Called by lower (CE) layer when a send to Target completes. */ | 857 | /* Called by lower (CE) layer when a send to Target completes. */ |
@@ -726,19 +889,17 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state) | |||
726 | unsigned int nbytes, max_nbytes; | 889 | unsigned int nbytes, max_nbytes; |
727 | unsigned int transfer_id; | 890 | unsigned int transfer_id; |
728 | unsigned int flags; | 891 | unsigned int flags; |
729 | int err, num_replenish = 0; | ||
730 | 892 | ||
731 | while (ath10k_ce_completed_recv_next(ce_state, &transfer_context, | 893 | while (ath10k_ce_completed_recv_next(ce_state, &transfer_context, |
732 | &ce_data, &nbytes, &transfer_id, | 894 | &ce_data, &nbytes, &transfer_id, |
733 | &flags) == 0) { | 895 | &flags) == 0) { |
734 | num_replenish++; | ||
735 | skb = transfer_context; | 896 | skb = transfer_context; |
736 | max_nbytes = skb->len + skb_tailroom(skb); | 897 | max_nbytes = skb->len + skb_tailroom(skb); |
737 | dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, | 898 | dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, |
738 | max_nbytes, DMA_FROM_DEVICE); | 899 | max_nbytes, DMA_FROM_DEVICE); |
739 | 900 | ||
740 | if (unlikely(max_nbytes < nbytes)) { | 901 | if (unlikely(max_nbytes < nbytes)) { |
741 | ath10k_warn("rxed more than expected (nbytes %d, max %d)", | 902 | ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)", |
742 | nbytes, max_nbytes); | 903 | nbytes, max_nbytes); |
743 | dev_kfree_skb_any(skb); | 904 | dev_kfree_skb_any(skb); |
744 | continue; | 905 | continue; |
@@ -748,12 +909,7 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state) | |||
748 | cb->rx_completion(ar, skb, pipe_info->pipe_num); | 909 | cb->rx_completion(ar, skb, pipe_info->pipe_num); |
749 | } | 910 | } |
750 | 911 | ||
751 | err = ath10k_pci_post_rx_pipe(pipe_info, num_replenish); | 912 | ath10k_pci_rx_post_pipe(pipe_info); |
752 | if (unlikely(err)) { | ||
753 | /* FIXME: retry */ | ||
754 | ath10k_warn("failed to replenish CE rx ring %d (%d bufs): %d\n", | ||
755 | pipe_info->pipe_num, num_replenish, err); | ||
756 | } | ||
757 | } | 913 | } |
758 | 914 | ||
759 | static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | 915 | static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, |
@@ -781,10 +937,10 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | |||
781 | } | 937 | } |
782 | 938 | ||
783 | for (i = 0; i < n_items - 1; i++) { | 939 | for (i = 0; i < n_items - 1; i++) { |
784 | ath10k_dbg(ATH10K_DBG_PCI, | 940 | ath10k_dbg(ar, ATH10K_DBG_PCI, |
785 | "pci tx item %d paddr 0x%08x len %d n_items %d\n", | 941 | "pci tx item %d paddr 0x%08x len %d n_items %d\n", |
786 | i, items[i].paddr, items[i].len, n_items); | 942 | i, items[i].paddr, items[i].len, n_items); |
787 | ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL, "item data: ", | 943 | ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ", |
788 | items[i].vaddr, items[i].len); | 944 | items[i].vaddr, items[i].len); |
789 | 945 | ||
790 | err = ath10k_ce_send_nolock(ce_pipe, | 946 | err = ath10k_ce_send_nolock(ce_pipe, |
@@ -799,10 +955,10 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | |||
799 | 955 | ||
800 | /* `i` is equal to `n_items -1` after for() */ | 956 | /* `i` is equal to `n_items -1` after for() */ |
801 | 957 | ||
802 | ath10k_dbg(ATH10K_DBG_PCI, | 958 | ath10k_dbg(ar, ATH10K_DBG_PCI, |
803 | "pci tx item %d paddr 0x%08x len %d n_items %d\n", | 959 | "pci tx item %d paddr 0x%08x len %d n_items %d\n", |
804 | i, items[i].paddr, items[i].len, n_items); | 960 | i, items[i].paddr, items[i].len, n_items); |
805 | ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL, "item data: ", | 961 | ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ", |
806 | items[i].vaddr, items[i].len); | 962 | items[i].vaddr, items[i].len); |
807 | 963 | ||
808 | err = ath10k_ce_send_nolock(ce_pipe, | 964 | err = ath10k_ce_send_nolock(ce_pipe, |
@@ -829,52 +985,64 @@ static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) | |||
829 | { | 985 | { |
830 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 986 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
831 | 987 | ||
832 | ath10k_dbg(ATH10K_DBG_PCI, "pci hif get free queue number\n"); | 988 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get free queue number\n"); |
833 | 989 | ||
834 | return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); | 990 | return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); |
835 | } | 991 | } |
836 | 992 | ||
837 | static void ath10k_pci_hif_dump_area(struct ath10k *ar) | 993 | static void ath10k_pci_dump_registers(struct ath10k *ar, |
994 | struct ath10k_fw_crash_data *crash_data) | ||
838 | { | 995 | { |
839 | u32 reg_dump_area = 0; | 996 | __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; |
840 | u32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; | 997 | int i, ret; |
841 | u32 host_addr; | ||
842 | int ret; | ||
843 | u32 i; | ||
844 | 998 | ||
845 | ath10k_err("firmware crashed!\n"); | 999 | lockdep_assert_held(&ar->data_lock); |
846 | ath10k_err("hardware name %s version 0x%x\n", | ||
847 | ar->hw_params.name, ar->target_version); | ||
848 | ath10k_err("firmware version: %s\n", ar->hw->wiphy->fw_version); | ||
849 | 1000 | ||
850 | host_addr = host_interest_item_address(HI_ITEM(hi_failure_state)); | 1001 | ret = ath10k_pci_diag_read_hi(ar, ®_dump_values[0], |
851 | ret = ath10k_pci_diag_read_mem(ar, host_addr, | 1002 | hi_failure_state, |
852 | ®_dump_area, sizeof(u32)); | 1003 | REG_DUMP_COUNT_QCA988X * sizeof(__le32)); |
853 | if (ret) { | 1004 | if (ret) { |
854 | ath10k_err("failed to read FW dump area address: %d\n", ret); | 1005 | ath10k_err(ar, "failed to read firmware dump area: %d\n", ret); |
855 | return; | ||
856 | } | ||
857 | |||
858 | ath10k_err("target register Dump Location: 0x%08X\n", reg_dump_area); | ||
859 | |||
860 | ret = ath10k_pci_diag_read_mem(ar, reg_dump_area, | ||
861 | ®_dump_values[0], | ||
862 | REG_DUMP_COUNT_QCA988X * sizeof(u32)); | ||
863 | if (ret != 0) { | ||
864 | ath10k_err("failed to read FW dump area: %d\n", ret); | ||
865 | return; | 1006 | return; |
866 | } | 1007 | } |
867 | 1008 | ||
868 | BUILD_BUG_ON(REG_DUMP_COUNT_QCA988X % 4); | 1009 | BUILD_BUG_ON(REG_DUMP_COUNT_QCA988X % 4); |
869 | 1010 | ||
870 | ath10k_err("target Register Dump\n"); | 1011 | ath10k_err(ar, "firmware register dump:\n"); |
871 | for (i = 0; i < REG_DUMP_COUNT_QCA988X; i += 4) | 1012 | for (i = 0; i < REG_DUMP_COUNT_QCA988X; i += 4) |
872 | ath10k_err("[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n", | 1013 | ath10k_err(ar, "[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n", |
873 | i, | 1014 | i, |
874 | reg_dump_values[i], | 1015 | __le32_to_cpu(reg_dump_values[i]), |
875 | reg_dump_values[i + 1], | 1016 | __le32_to_cpu(reg_dump_values[i + 1]), |
876 | reg_dump_values[i + 2], | 1017 | __le32_to_cpu(reg_dump_values[i + 2]), |
877 | reg_dump_values[i + 3]); | 1018 | __le32_to_cpu(reg_dump_values[i + 3])); |
1019 | |||
1020 | if (!crash_data) | ||
1021 | return; | ||
1022 | |||
1023 | for (i = 0; i < REG_DUMP_COUNT_QCA988X; i++) | ||
1024 | crash_data->registers[i] = reg_dump_values[i]; | ||
1025 | } | ||
1026 | |||
1027 | static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) | ||
1028 | { | ||
1029 | struct ath10k_fw_crash_data *crash_data; | ||
1030 | char uuid[50]; | ||
1031 | |||
1032 | spin_lock_bh(&ar->data_lock); | ||
1033 | |||
1034 | crash_data = ath10k_debug_get_new_fw_crash_data(ar); | ||
1035 | |||
1036 | if (crash_data) | ||
1037 | scnprintf(uuid, sizeof(uuid), "%pUl", &crash_data->uuid); | ||
1038 | else | ||
1039 | scnprintf(uuid, sizeof(uuid), "n/a"); | ||
1040 | |||
1041 | ath10k_err(ar, "firmware crashed! (uuid %s)\n", uuid); | ||
1042 | ath10k_print_driver_info(ar); | ||
1043 | ath10k_pci_dump_registers(ar, crash_data); | ||
1044 | |||
1045 | spin_unlock_bh(&ar->data_lock); | ||
878 | 1046 | ||
879 | queue_work(ar->workqueue, &ar->restart_work); | 1047 | queue_work(ar->workqueue, &ar->restart_work); |
880 | } | 1048 | } |
@@ -882,7 +1050,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar) | |||
882 | static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, | 1050 | static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, |
883 | int force) | 1051 | int force) |
884 | { | 1052 | { |
885 | ath10k_dbg(ATH10K_DBG_PCI, "pci hif send complete check\n"); | 1053 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif send complete check\n"); |
886 | 1054 | ||
887 | if (!force) { | 1055 | if (!force) { |
888 | int resources; | 1056 | int resources; |
@@ -910,43 +1078,12 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar, | |||
910 | { | 1078 | { |
911 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1079 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
912 | 1080 | ||
913 | ath10k_dbg(ATH10K_DBG_PCI, "pci hif set callbacks\n"); | 1081 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif set callbacks\n"); |
914 | 1082 | ||
915 | memcpy(&ar_pci->msg_callbacks_current, callbacks, | 1083 | memcpy(&ar_pci->msg_callbacks_current, callbacks, |
916 | sizeof(ar_pci->msg_callbacks_current)); | 1084 | sizeof(ar_pci->msg_callbacks_current)); |
917 | } | 1085 | } |
918 | 1086 | ||
919 | static int ath10k_pci_setup_ce_irq(struct ath10k *ar) | ||
920 | { | ||
921 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
922 | const struct ce_attr *attr; | ||
923 | struct ath10k_pci_pipe *pipe_info; | ||
924 | int pipe_num, disable_interrupts; | ||
925 | |||
926 | for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { | ||
927 | pipe_info = &ar_pci->pipe_info[pipe_num]; | ||
928 | |||
929 | /* Handle Diagnostic CE specially */ | ||
930 | if (pipe_info->ce_hdl == ar_pci->ce_diag) | ||
931 | continue; | ||
932 | |||
933 | attr = &host_ce_config_wlan[pipe_num]; | ||
934 | |||
935 | if (attr->src_nentries) { | ||
936 | disable_interrupts = attr->flags & CE_ATTR_DIS_INTR; | ||
937 | ath10k_ce_send_cb_register(pipe_info->ce_hdl, | ||
938 | ath10k_pci_ce_send_done, | ||
939 | disable_interrupts); | ||
940 | } | ||
941 | |||
942 | if (attr->dest_nentries) | ||
943 | ath10k_ce_recv_cb_register(pipe_info->ce_hdl, | ||
944 | ath10k_pci_ce_recv_data); | ||
945 | } | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static void ath10k_pci_kill_tasklet(struct ath10k *ar) | 1087 | static void ath10k_pci_kill_tasklet(struct ath10k *ar) |
951 | { | 1088 | { |
952 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1089 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
@@ -954,74 +1091,64 @@ static void ath10k_pci_kill_tasklet(struct ath10k *ar) | |||
954 | 1091 | ||
955 | tasklet_kill(&ar_pci->intr_tq); | 1092 | tasklet_kill(&ar_pci->intr_tq); |
956 | tasklet_kill(&ar_pci->msi_fw_err); | 1093 | tasklet_kill(&ar_pci->msi_fw_err); |
957 | tasklet_kill(&ar_pci->early_irq_tasklet); | ||
958 | 1094 | ||
959 | for (i = 0; i < CE_COUNT; i++) | 1095 | for (i = 0; i < CE_COUNT; i++) |
960 | tasklet_kill(&ar_pci->pipe_info[i].intr); | 1096 | tasklet_kill(&ar_pci->pipe_info[i].intr); |
1097 | |||
1098 | del_timer_sync(&ar_pci->rx_post_retry); | ||
961 | } | 1099 | } |
962 | 1100 | ||
963 | /* TODO - temporary mapping while we have too few CE's */ | ||
964 | static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, | 1101 | static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, |
965 | u16 service_id, u8 *ul_pipe, | 1102 | u16 service_id, u8 *ul_pipe, |
966 | u8 *dl_pipe, int *ul_is_polled, | 1103 | u8 *dl_pipe, int *ul_is_polled, |
967 | int *dl_is_polled) | 1104 | int *dl_is_polled) |
968 | { | 1105 | { |
969 | int ret = 0; | 1106 | const struct service_to_pipe *entry; |
1107 | bool ul_set = false, dl_set = false; | ||
1108 | int i; | ||
970 | 1109 | ||
971 | ath10k_dbg(ATH10K_DBG_PCI, "pci hif map service\n"); | 1110 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif map service\n"); |
972 | 1111 | ||
973 | /* polling for received messages not supported */ | 1112 | /* polling for received messages not supported */ |
974 | *dl_is_polled = 0; | 1113 | *dl_is_polled = 0; |
975 | 1114 | ||
976 | switch (service_id) { | 1115 | for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) { |
977 | case ATH10K_HTC_SVC_ID_HTT_DATA_MSG: | 1116 | entry = &target_service_to_ce_map_wlan[i]; |
978 | /* | ||
979 | * Host->target HTT gets its own pipe, so it can be polled | ||
980 | * while other pipes are interrupt driven. | ||
981 | */ | ||
982 | *ul_pipe = 4; | ||
983 | /* | ||
984 | * Use the same target->host pipe for HTC ctrl, HTC raw | ||
985 | * streams, and HTT. | ||
986 | */ | ||
987 | *dl_pipe = 1; | ||
988 | break; | ||
989 | 1117 | ||
990 | case ATH10K_HTC_SVC_ID_RSVD_CTRL: | 1118 | if (__le32_to_cpu(entry->service_id) != service_id) |
991 | case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS: | 1119 | continue; |
992 | /* | ||
993 | * Note: HTC_RAW_STREAMS_SVC is currently unused, and | ||
994 | * HTC_CTRL_RSVD_SVC could share the same pipe as the | ||
995 | * WMI services. So, if another CE is needed, change | ||
996 | * this to *ul_pipe = 3, which frees up CE 0. | ||
997 | */ | ||
998 | /* *ul_pipe = 3; */ | ||
999 | *ul_pipe = 0; | ||
1000 | *dl_pipe = 1; | ||
1001 | break; | ||
1002 | |||
1003 | case ATH10K_HTC_SVC_ID_WMI_DATA_BK: | ||
1004 | case ATH10K_HTC_SVC_ID_WMI_DATA_BE: | ||
1005 | case ATH10K_HTC_SVC_ID_WMI_DATA_VI: | ||
1006 | case ATH10K_HTC_SVC_ID_WMI_DATA_VO: | ||
1007 | 1120 | ||
1008 | case ATH10K_HTC_SVC_ID_WMI_CONTROL: | 1121 | switch (__le32_to_cpu(entry->pipedir)) { |
1009 | *ul_pipe = 3; | 1122 | case PIPEDIR_NONE: |
1010 | *dl_pipe = 2; | 1123 | break; |
1011 | break; | 1124 | case PIPEDIR_IN: |
1125 | WARN_ON(dl_set); | ||
1126 | *dl_pipe = __le32_to_cpu(entry->pipenum); | ||
1127 | dl_set = true; | ||
1128 | break; | ||
1129 | case PIPEDIR_OUT: | ||
1130 | WARN_ON(ul_set); | ||
1131 | *ul_pipe = __le32_to_cpu(entry->pipenum); | ||
1132 | ul_set = true; | ||
1133 | break; | ||
1134 | case PIPEDIR_INOUT: | ||
1135 | WARN_ON(dl_set); | ||
1136 | WARN_ON(ul_set); | ||
1137 | *dl_pipe = __le32_to_cpu(entry->pipenum); | ||
1138 | *ul_pipe = __le32_to_cpu(entry->pipenum); | ||
1139 | dl_set = true; | ||
1140 | ul_set = true; | ||
1141 | break; | ||
1142 | } | ||
1143 | } | ||
1012 | 1144 | ||
1013 | /* pipe 5 unused */ | 1145 | if (WARN_ON(!ul_set || !dl_set)) |
1014 | /* pipe 6 reserved */ | 1146 | return -ENOENT; |
1015 | /* pipe 7 reserved */ | ||
1016 | 1147 | ||
1017 | default: | ||
1018 | ret = -1; | ||
1019 | break; | ||
1020 | } | ||
1021 | *ul_is_polled = | 1148 | *ul_is_polled = |
1022 | (host_ce_config_wlan[*ul_pipe].flags & CE_ATTR_DIS_INTR) != 0; | 1149 | (host_ce_config_wlan[*ul_pipe].flags & CE_ATTR_DIS_INTR) != 0; |
1023 | 1150 | ||
1024 | return ret; | 1151 | return 0; |
1025 | } | 1152 | } |
1026 | 1153 | ||
1027 | static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, | 1154 | static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, |
@@ -1029,7 +1156,7 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, | |||
1029 | { | 1156 | { |
1030 | int ul_is_polled, dl_is_polled; | 1157 | int ul_is_polled, dl_is_polled; |
1031 | 1158 | ||
1032 | ath10k_dbg(ATH10K_DBG_PCI, "pci hif get default pipe\n"); | 1159 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get default pipe\n"); |
1033 | 1160 | ||
1034 | (void)ath10k_pci_hif_map_service_to_pipe(ar, | 1161 | (void)ath10k_pci_hif_map_service_to_pipe(ar, |
1035 | ATH10K_HTC_SVC_ID_RSVD_CTRL, | 1162 | ATH10K_HTC_SVC_ID_RSVD_CTRL, |
@@ -1039,141 +1166,48 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, | |||
1039 | &dl_is_polled); | 1166 | &dl_is_polled); |
1040 | } | 1167 | } |
1041 | 1168 | ||
1042 | static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, | 1169 | static void ath10k_pci_irq_disable(struct ath10k *ar) |
1043 | int num) | ||
1044 | { | 1170 | { |
1045 | struct ath10k *ar = pipe_info->hif_ce_state; | ||
1046 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1171 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
1047 | struct ath10k_ce_pipe *ce_state = pipe_info->ce_hdl; | 1172 | int i; |
1048 | struct sk_buff *skb; | ||
1049 | dma_addr_t ce_data; | ||
1050 | int i, ret = 0; | ||
1051 | |||
1052 | if (pipe_info->buf_sz == 0) | ||
1053 | return 0; | ||
1054 | |||
1055 | for (i = 0; i < num; i++) { | ||
1056 | skb = dev_alloc_skb(pipe_info->buf_sz); | ||
1057 | if (!skb) { | ||
1058 | ath10k_warn("failed to allocate skbuff for pipe %d\n", | ||
1059 | num); | ||
1060 | ret = -ENOMEM; | ||
1061 | goto err; | ||
1062 | } | ||
1063 | |||
1064 | WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); | ||
1065 | |||
1066 | ce_data = dma_map_single(ar->dev, skb->data, | ||
1067 | skb->len + skb_tailroom(skb), | ||
1068 | DMA_FROM_DEVICE); | ||
1069 | |||
1070 | if (unlikely(dma_mapping_error(ar->dev, ce_data))) { | ||
1071 | ath10k_warn("failed to DMA map sk_buff\n"); | ||
1072 | dev_kfree_skb_any(skb); | ||
1073 | ret = -EIO; | ||
1074 | goto err; | ||
1075 | } | ||
1076 | |||
1077 | ATH10K_SKB_CB(skb)->paddr = ce_data; | ||
1078 | |||
1079 | pci_dma_sync_single_for_device(ar_pci->pdev, ce_data, | ||
1080 | pipe_info->buf_sz, | ||
1081 | PCI_DMA_FROMDEVICE); | ||
1082 | 1173 | ||
1083 | ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb, | 1174 | ath10k_ce_disable_interrupts(ar); |
1084 | ce_data); | ||
1085 | if (ret) { | ||
1086 | ath10k_warn("failed to enqueue to pipe %d: %d\n", | ||
1087 | num, ret); | ||
1088 | goto err; | ||
1089 | } | ||
1090 | } | ||
1091 | 1175 | ||
1092 | return ret; | 1176 | /* Regardless how many interrupts were assigned for MSI the first one |
1177 | * is always used for firmware indications (crashes). There's no way to | ||
1178 | * mask the irq in the device so call disable_irq(). Legacy (shared) | ||
1179 | * interrupts can be masked on the device though. | ||
1180 | */ | ||
1181 | if (ar_pci->num_msi_intrs > 0) | ||
1182 | disable_irq(ar_pci->pdev->irq); | ||
1183 | else | ||
1184 | ath10k_pci_disable_and_clear_legacy_irq(ar); | ||
1093 | 1185 | ||
1094 | err: | 1186 | for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) |
1095 | ath10k_pci_rx_pipe_cleanup(pipe_info); | 1187 | synchronize_irq(ar_pci->pdev->irq + i); |
1096 | return ret; | ||
1097 | } | 1188 | } |
1098 | 1189 | ||
1099 | static int ath10k_pci_post_rx(struct ath10k *ar) | 1190 | static void ath10k_pci_irq_enable(struct ath10k *ar) |
1100 | { | 1191 | { |
1101 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1192 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
1102 | struct ath10k_pci_pipe *pipe_info; | ||
1103 | const struct ce_attr *attr; | ||
1104 | int pipe_num, ret = 0; | ||
1105 | 1193 | ||
1106 | for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { | 1194 | ath10k_ce_enable_interrupts(ar); |
1107 | pipe_info = &ar_pci->pipe_info[pipe_num]; | ||
1108 | attr = &host_ce_config_wlan[pipe_num]; | ||
1109 | |||
1110 | if (attr->dest_nentries == 0) | ||
1111 | continue; | ||
1112 | |||
1113 | ret = ath10k_pci_post_rx_pipe(pipe_info, | ||
1114 | attr->dest_nentries - 1); | ||
1115 | if (ret) { | ||
1116 | ath10k_warn("failed to post RX buffer for pipe %d: %d\n", | ||
1117 | pipe_num, ret); | ||
1118 | |||
1119 | for (; pipe_num >= 0; pipe_num--) { | ||
1120 | pipe_info = &ar_pci->pipe_info[pipe_num]; | ||
1121 | ath10k_pci_rx_pipe_cleanup(pipe_info); | ||
1122 | } | ||
1123 | return ret; | ||
1124 | } | ||
1125 | } | ||
1126 | 1195 | ||
1127 | return 0; | 1196 | /* See comment in ath10k_pci_irq_disable() */ |
1197 | if (ar_pci->num_msi_intrs > 0) | ||
1198 | enable_irq(ar_pci->pdev->irq); | ||
1199 | else | ||
1200 | ath10k_pci_enable_legacy_irq(ar); | ||
1128 | } | 1201 | } |
1129 | 1202 | ||
1130 | static int ath10k_pci_hif_start(struct ath10k *ar) | 1203 | static int ath10k_pci_hif_start(struct ath10k *ar) |
1131 | { | 1204 | { |
1132 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1205 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n"); |
1133 | int ret, ret_early; | ||
1134 | |||
1135 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif start\n"); | ||
1136 | |||
1137 | ath10k_pci_free_early_irq(ar); | ||
1138 | ath10k_pci_kill_tasklet(ar); | ||
1139 | |||
1140 | ret = ath10k_pci_request_irq(ar); | ||
1141 | if (ret) { | ||
1142 | ath10k_warn("failed to post RX buffers for all pipes: %d\n", | ||
1143 | ret); | ||
1144 | goto err_early_irq; | ||
1145 | } | ||
1146 | |||
1147 | ret = ath10k_pci_setup_ce_irq(ar); | ||
1148 | if (ret) { | ||
1149 | ath10k_warn("failed to setup CE interrupts: %d\n", ret); | ||
1150 | goto err_stop; | ||
1151 | } | ||
1152 | 1206 | ||
1153 | /* Post buffers once to start things off. */ | 1207 | ath10k_pci_irq_enable(ar); |
1154 | ret = ath10k_pci_post_rx(ar); | 1208 | ath10k_pci_rx_post(ar); |
1155 | if (ret) { | ||
1156 | ath10k_warn("failed to post RX buffers for all pipes: %d\n", | ||
1157 | ret); | ||
1158 | goto err_stop; | ||
1159 | } | ||
1160 | 1209 | ||
1161 | ar_pci->started = 1; | ||
1162 | return 0; | 1210 | return 0; |
1163 | |||
1164 | err_stop: | ||
1165 | ath10k_ce_disable_interrupts(ar); | ||
1166 | ath10k_pci_free_irq(ar); | ||
1167 | ath10k_pci_kill_tasklet(ar); | ||
1168 | err_early_irq: | ||
1169 | /* Though there should be no interrupts (device was reset) | ||
1170 | * power_down() expects the early IRQ to be installed as per the | ||
1171 | * driver lifecycle. */ | ||
1172 | ret_early = ath10k_pci_request_early_irq(ar); | ||
1173 | if (ret_early) | ||
1174 | ath10k_warn("failed to re-enable early irq: %d\n", ret_early); | ||
1175 | |||
1176 | return ret; | ||
1177 | } | 1211 | } |
1178 | 1212 | ||
1179 | static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) | 1213 | static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) |
@@ -1193,10 +1227,6 @@ static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) | |||
1193 | 1227 | ||
1194 | ar = pipe_info->hif_ce_state; | 1228 | ar = pipe_info->hif_ce_state; |
1195 | ar_pci = ath10k_pci_priv(ar); | 1229 | ar_pci = ath10k_pci_priv(ar); |
1196 | |||
1197 | if (!ar_pci->started) | ||
1198 | return; | ||
1199 | |||
1200 | ce_hdl = pipe_info->ce_hdl; | 1230 | ce_hdl = pipe_info->ce_hdl; |
1201 | 1231 | ||
1202 | while (ath10k_ce_revoke_recv_next(ce_hdl, (void **)&netbuf, | 1232 | while (ath10k_ce_revoke_recv_next(ce_hdl, (void **)&netbuf, |
@@ -1227,10 +1257,6 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) | |||
1227 | 1257 | ||
1228 | ar = pipe_info->hif_ce_state; | 1258 | ar = pipe_info->hif_ce_state; |
1229 | ar_pci = ath10k_pci_priv(ar); | 1259 | ar_pci = ath10k_pci_priv(ar); |
1230 | |||
1231 | if (!ar_pci->started) | ||
1232 | return; | ||
1233 | |||
1234 | ce_hdl = pipe_info->ce_hdl; | 1260 | ce_hdl = pipe_info->ce_hdl; |
1235 | 1261 | ||
1236 | while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf, | 1262 | while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf, |
@@ -1275,41 +1301,24 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar) | |||
1275 | ath10k_ce_deinit_pipe(ar, i); | 1301 | ath10k_ce_deinit_pipe(ar, i); |
1276 | } | 1302 | } |
1277 | 1303 | ||
1278 | static void ath10k_pci_hif_stop(struct ath10k *ar) | 1304 | static void ath10k_pci_flush(struct ath10k *ar) |
1279 | { | 1305 | { |
1280 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1281 | int ret; | ||
1282 | |||
1283 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n"); | ||
1284 | |||
1285 | if (WARN_ON(!ar_pci->started)) | ||
1286 | return; | ||
1287 | |||
1288 | ret = ath10k_ce_disable_interrupts(ar); | ||
1289 | if (ret) | ||
1290 | ath10k_warn("failed to disable CE interrupts: %d\n", ret); | ||
1291 | |||
1292 | ath10k_pci_free_irq(ar); | ||
1293 | ath10k_pci_kill_tasklet(ar); | 1306 | ath10k_pci_kill_tasklet(ar); |
1307 | ath10k_pci_buffer_cleanup(ar); | ||
1308 | } | ||
1294 | 1309 | ||
1295 | ret = ath10k_pci_request_early_irq(ar); | 1310 | static void ath10k_pci_hif_stop(struct ath10k *ar) |
1296 | if (ret) | 1311 | { |
1297 | ath10k_warn("failed to re-enable early irq: %d\n", ret); | 1312 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n"); |
1298 | |||
1299 | /* At this point, asynchronous threads are stopped, the target should | ||
1300 | * not DMA nor interrupt. We process the leftovers and then free | ||
1301 | * everything else up. */ | ||
1302 | 1313 | ||
1303 | ath10k_pci_buffer_cleanup(ar); | 1314 | ath10k_pci_irq_disable(ar); |
1315 | ath10k_pci_flush(ar); | ||
1304 | 1316 | ||
1305 | /* Make the sure the device won't access any structures on the host by | 1317 | /* Most likely the device has HTT Rx ring configured. The only way to |
1306 | * resetting it. The device was fed with PCI CE ringbuffer | 1318 | * prevent the device from accessing (and possible corrupting) host |
1307 | * configuration during init. If ringbuffers are freed and the device | 1319 | * memory is to reset the chip now. |
1308 | * were to access them this could lead to memory corruption on the | 1320 | */ |
1309 | * host. */ | ||
1310 | ath10k_pci_warm_reset(ar); | 1321 | ath10k_pci_warm_reset(ar); |
1311 | |||
1312 | ar_pci->started = 0; | ||
1313 | } | 1322 | } |
1314 | 1323 | ||
1315 | static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, | 1324 | static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, |
@@ -1360,7 +1369,7 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, | |||
1360 | xfer.wait_for_resp = true; | 1369 | xfer.wait_for_resp = true; |
1361 | xfer.resp_len = 0; | 1370 | xfer.resp_len = 0; |
1362 | 1371 | ||
1363 | ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr); | 1372 | ath10k_ce_rx_post_buf(ce_rx, &xfer, resp_paddr); |
1364 | } | 1373 | } |
1365 | 1374 | ||
1366 | ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0); | 1375 | ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0); |
@@ -1418,6 +1427,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state) | |||
1418 | 1427 | ||
1419 | static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) | 1428 | static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) |
1420 | { | 1429 | { |
1430 | struct ath10k *ar = ce_state->ar; | ||
1421 | struct bmi_xfer *xfer; | 1431 | struct bmi_xfer *xfer; |
1422 | u32 ce_data; | 1432 | u32 ce_data; |
1423 | unsigned int nbytes; | 1433 | unsigned int nbytes; |
@@ -1429,7 +1439,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) | |||
1429 | return; | 1439 | return; |
1430 | 1440 | ||
1431 | if (!xfer->wait_for_resp) { | 1441 | if (!xfer->wait_for_resp) { |
1432 | ath10k_warn("unexpected: BMI data received; ignoring\n"); | 1442 | ath10k_warn(ar, "unexpected: BMI data received; ignoring\n"); |
1433 | return; | 1443 | return; |
1434 | } | 1444 | } |
1435 | 1445 | ||
@@ -1457,102 +1467,6 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe, | |||
1457 | } | 1467 | } |
1458 | 1468 | ||
1459 | /* | 1469 | /* |
1460 | * Map from service/endpoint to Copy Engine. | ||
1461 | * This table is derived from the CE_PCI TABLE, above. | ||
1462 | * It is passed to the Target at startup for use by firmware. | ||
1463 | */ | ||
1464 | static const struct service_to_pipe target_service_to_ce_map_wlan[] = { | ||
1465 | { | ||
1466 | ATH10K_HTC_SVC_ID_WMI_DATA_VO, | ||
1467 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1468 | 3, | ||
1469 | }, | ||
1470 | { | ||
1471 | ATH10K_HTC_SVC_ID_WMI_DATA_VO, | ||
1472 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1473 | 2, | ||
1474 | }, | ||
1475 | { | ||
1476 | ATH10K_HTC_SVC_ID_WMI_DATA_BK, | ||
1477 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1478 | 3, | ||
1479 | }, | ||
1480 | { | ||
1481 | ATH10K_HTC_SVC_ID_WMI_DATA_BK, | ||
1482 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1483 | 2, | ||
1484 | }, | ||
1485 | { | ||
1486 | ATH10K_HTC_SVC_ID_WMI_DATA_BE, | ||
1487 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1488 | 3, | ||
1489 | }, | ||
1490 | { | ||
1491 | ATH10K_HTC_SVC_ID_WMI_DATA_BE, | ||
1492 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1493 | 2, | ||
1494 | }, | ||
1495 | { | ||
1496 | ATH10K_HTC_SVC_ID_WMI_DATA_VI, | ||
1497 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1498 | 3, | ||
1499 | }, | ||
1500 | { | ||
1501 | ATH10K_HTC_SVC_ID_WMI_DATA_VI, | ||
1502 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1503 | 2, | ||
1504 | }, | ||
1505 | { | ||
1506 | ATH10K_HTC_SVC_ID_WMI_CONTROL, | ||
1507 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1508 | 3, | ||
1509 | }, | ||
1510 | { | ||
1511 | ATH10K_HTC_SVC_ID_WMI_CONTROL, | ||
1512 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1513 | 2, | ||
1514 | }, | ||
1515 | { | ||
1516 | ATH10K_HTC_SVC_ID_RSVD_CTRL, | ||
1517 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1518 | 0, /* could be moved to 3 (share with WMI) */ | ||
1519 | }, | ||
1520 | { | ||
1521 | ATH10K_HTC_SVC_ID_RSVD_CTRL, | ||
1522 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1523 | 1, | ||
1524 | }, | ||
1525 | { | ||
1526 | ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS, /* not currently used */ | ||
1527 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1528 | 0, | ||
1529 | }, | ||
1530 | { | ||
1531 | ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS, /* not currently used */ | ||
1532 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1533 | 1, | ||
1534 | }, | ||
1535 | { | ||
1536 | ATH10K_HTC_SVC_ID_HTT_DATA_MSG, | ||
1537 | PIPEDIR_OUT, /* out = UL = host -> target */ | ||
1538 | 4, | ||
1539 | }, | ||
1540 | { | ||
1541 | ATH10K_HTC_SVC_ID_HTT_DATA_MSG, | ||
1542 | PIPEDIR_IN, /* in = DL = target -> host */ | ||
1543 | 1, | ||
1544 | }, | ||
1545 | |||
1546 | /* (Additions here) */ | ||
1547 | |||
1548 | { /* Must be last */ | ||
1549 | 0, | ||
1550 | 0, | ||
1551 | 0, | ||
1552 | }, | ||
1553 | }; | ||
1554 | |||
1555 | /* | ||
1556 | * Send an interrupt to the device to wake up the Target CPU | 1470 | * Send an interrupt to the device to wake up the Target CPU |
1557 | * so it has an opportunity to notice any changed state. | 1471 | * so it has an opportunity to notice any changed state. |
1558 | */ | 1472 | */ |
@@ -1565,7 +1479,7 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar) | |||
1565 | CORE_CTRL_ADDRESS, | 1479 | CORE_CTRL_ADDRESS, |
1566 | &core_ctrl); | 1480 | &core_ctrl); |
1567 | if (ret) { | 1481 | if (ret) { |
1568 | ath10k_warn("failed to read core_ctrl: %d\n", ret); | 1482 | ath10k_warn(ar, "failed to read core_ctrl: %d\n", ret); |
1569 | return ret; | 1483 | return ret; |
1570 | } | 1484 | } |
1571 | 1485 | ||
@@ -1576,7 +1490,7 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar) | |||
1576 | CORE_CTRL_ADDRESS, | 1490 | CORE_CTRL_ADDRESS, |
1577 | core_ctrl); | 1491 | core_ctrl); |
1578 | if (ret) { | 1492 | if (ret) { |
1579 | ath10k_warn("failed to set target CPU interrupt mask: %d\n", | 1493 | ath10k_warn(ar, "failed to set target CPU interrupt mask: %d\n", |
1580 | ret); | 1494 | ret); |
1581 | return ret; | 1495 | return ret; |
1582 | } | 1496 | } |
@@ -1605,13 +1519,13 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1605 | ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr, | 1519 | ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr, |
1606 | &pcie_state_targ_addr); | 1520 | &pcie_state_targ_addr); |
1607 | if (ret != 0) { | 1521 | if (ret != 0) { |
1608 | ath10k_err("Failed to get pcie state addr: %d\n", ret); | 1522 | ath10k_err(ar, "Failed to get pcie state addr: %d\n", ret); |
1609 | return ret; | 1523 | return ret; |
1610 | } | 1524 | } |
1611 | 1525 | ||
1612 | if (pcie_state_targ_addr == 0) { | 1526 | if (pcie_state_targ_addr == 0) { |
1613 | ret = -EIO; | 1527 | ret = -EIO; |
1614 | ath10k_err("Invalid pcie state addr\n"); | 1528 | ath10k_err(ar, "Invalid pcie state addr\n"); |
1615 | return ret; | 1529 | return ret; |
1616 | } | 1530 | } |
1617 | 1531 | ||
@@ -1620,13 +1534,13 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1620 | pipe_cfg_addr), | 1534 | pipe_cfg_addr), |
1621 | &pipe_cfg_targ_addr); | 1535 | &pipe_cfg_targ_addr); |
1622 | if (ret != 0) { | 1536 | if (ret != 0) { |
1623 | ath10k_err("Failed to get pipe cfg addr: %d\n", ret); | 1537 | ath10k_err(ar, "Failed to get pipe cfg addr: %d\n", ret); |
1624 | return ret; | 1538 | return ret; |
1625 | } | 1539 | } |
1626 | 1540 | ||
1627 | if (pipe_cfg_targ_addr == 0) { | 1541 | if (pipe_cfg_targ_addr == 0) { |
1628 | ret = -EIO; | 1542 | ret = -EIO; |
1629 | ath10k_err("Invalid pipe cfg addr\n"); | 1543 | ath10k_err(ar, "Invalid pipe cfg addr\n"); |
1630 | return ret; | 1544 | return ret; |
1631 | } | 1545 | } |
1632 | 1546 | ||
@@ -1635,7 +1549,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1635 | sizeof(target_ce_config_wlan)); | 1549 | sizeof(target_ce_config_wlan)); |
1636 | 1550 | ||
1637 | if (ret != 0) { | 1551 | if (ret != 0) { |
1638 | ath10k_err("Failed to write pipe cfg: %d\n", ret); | 1552 | ath10k_err(ar, "Failed to write pipe cfg: %d\n", ret); |
1639 | return ret; | 1553 | return ret; |
1640 | } | 1554 | } |
1641 | 1555 | ||
@@ -1644,13 +1558,13 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1644 | svc_to_pipe_map), | 1558 | svc_to_pipe_map), |
1645 | &svc_to_pipe_map); | 1559 | &svc_to_pipe_map); |
1646 | if (ret != 0) { | 1560 | if (ret != 0) { |
1647 | ath10k_err("Failed to get svc/pipe map: %d\n", ret); | 1561 | ath10k_err(ar, "Failed to get svc/pipe map: %d\n", ret); |
1648 | return ret; | 1562 | return ret; |
1649 | } | 1563 | } |
1650 | 1564 | ||
1651 | if (svc_to_pipe_map == 0) { | 1565 | if (svc_to_pipe_map == 0) { |
1652 | ret = -EIO; | 1566 | ret = -EIO; |
1653 | ath10k_err("Invalid svc_to_pipe map\n"); | 1567 | ath10k_err(ar, "Invalid svc_to_pipe map\n"); |
1654 | return ret; | 1568 | return ret; |
1655 | } | 1569 | } |
1656 | 1570 | ||
@@ -1658,7 +1572,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1658 | target_service_to_ce_map_wlan, | 1572 | target_service_to_ce_map_wlan, |
1659 | sizeof(target_service_to_ce_map_wlan)); | 1573 | sizeof(target_service_to_ce_map_wlan)); |
1660 | if (ret != 0) { | 1574 | if (ret != 0) { |
1661 | ath10k_err("Failed to write svc/pipe map: %d\n", ret); | 1575 | ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret); |
1662 | return ret; | 1576 | return ret; |
1663 | } | 1577 | } |
1664 | 1578 | ||
@@ -1667,18 +1581,17 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1667 | config_flags), | 1581 | config_flags), |
1668 | &pcie_config_flags); | 1582 | &pcie_config_flags); |
1669 | if (ret != 0) { | 1583 | if (ret != 0) { |
1670 | ath10k_err("Failed to get pcie config_flags: %d\n", ret); | 1584 | ath10k_err(ar, "Failed to get pcie config_flags: %d\n", ret); |
1671 | return ret; | 1585 | return ret; |
1672 | } | 1586 | } |
1673 | 1587 | ||
1674 | pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; | 1588 | pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; |
1675 | 1589 | ||
1676 | ret = ath10k_pci_diag_write_mem(ar, pcie_state_targ_addr + | 1590 | ret = ath10k_pci_diag_write_access(ar, pcie_state_targ_addr + |
1677 | offsetof(struct pcie_state, config_flags), | 1591 | offsetof(struct pcie_state, config_flags), |
1678 | &pcie_config_flags, | 1592 | pcie_config_flags); |
1679 | sizeof(pcie_config_flags)); | ||
1680 | if (ret != 0) { | 1593 | if (ret != 0) { |
1681 | ath10k_err("Failed to write pcie config_flags: %d\n", ret); | 1594 | ath10k_err(ar, "Failed to write pcie config_flags: %d\n", ret); |
1682 | return ret; | 1595 | return ret; |
1683 | } | 1596 | } |
1684 | 1597 | ||
@@ -1687,7 +1600,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1687 | 1600 | ||
1688 | ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value); | 1601 | ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value); |
1689 | if (ret != 0) { | 1602 | if (ret != 0) { |
1690 | ath10k_err("Faile to get early alloc val: %d\n", ret); | 1603 | ath10k_err(ar, "Faile to get early alloc val: %d\n", ret); |
1691 | return ret; | 1604 | return ret; |
1692 | } | 1605 | } |
1693 | 1606 | ||
@@ -1699,7 +1612,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1699 | 1612 | ||
1700 | ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value); | 1613 | ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value); |
1701 | if (ret != 0) { | 1614 | if (ret != 0) { |
1702 | ath10k_err("Failed to set early alloc val: %d\n", ret); | 1615 | ath10k_err(ar, "Failed to set early alloc val: %d\n", ret); |
1703 | return ret; | 1616 | return ret; |
1704 | } | 1617 | } |
1705 | 1618 | ||
@@ -1708,7 +1621,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1708 | 1621 | ||
1709 | ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value); | 1622 | ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value); |
1710 | if (ret != 0) { | 1623 | if (ret != 0) { |
1711 | ath10k_err("Failed to get option val: %d\n", ret); | 1624 | ath10k_err(ar, "Failed to get option val: %d\n", ret); |
1712 | return ret; | 1625 | return ret; |
1713 | } | 1626 | } |
1714 | 1627 | ||
@@ -1716,7 +1629,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1716 | 1629 | ||
1717 | ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value); | 1630 | ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value); |
1718 | if (ret != 0) { | 1631 | if (ret != 0) { |
1719 | ath10k_err("Failed to set option val: %d\n", ret); | 1632 | ath10k_err(ar, "Failed to set option val: %d\n", ret); |
1720 | return ret; | 1633 | return ret; |
1721 | } | 1634 | } |
1722 | 1635 | ||
@@ -1730,7 +1643,7 @@ static int ath10k_pci_alloc_ce(struct ath10k *ar) | |||
1730 | for (i = 0; i < CE_COUNT; i++) { | 1643 | for (i = 0; i < CE_COUNT; i++) { |
1731 | ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]); | 1644 | ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]); |
1732 | if (ret) { | 1645 | if (ret) { |
1733 | ath10k_err("failed to allocate copy engine pipe %d: %d\n", | 1646 | ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n", |
1734 | i, ret); | 1647 | i, ret); |
1735 | return ret; | 1648 | return ret; |
1736 | } | 1649 | } |
@@ -1761,9 +1674,11 @@ static int ath10k_pci_ce_init(struct ath10k *ar) | |||
1761 | pipe_info->hif_ce_state = ar; | 1674 | pipe_info->hif_ce_state = ar; |
1762 | attr = &host_ce_config_wlan[pipe_num]; | 1675 | attr = &host_ce_config_wlan[pipe_num]; |
1763 | 1676 | ||
1764 | ret = ath10k_ce_init_pipe(ar, pipe_num, attr); | 1677 | ret = ath10k_ce_init_pipe(ar, pipe_num, attr, |
1678 | ath10k_pci_ce_send_done, | ||
1679 | ath10k_pci_ce_recv_data); | ||
1765 | if (ret) { | 1680 | if (ret) { |
1766 | ath10k_err("failed to initialize copy engine pipe %d: %d\n", | 1681 | ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n", |
1767 | pipe_num, ret); | 1682 | pipe_num, ret); |
1768 | return ret; | 1683 | return ret; |
1769 | } | 1684 | } |
@@ -1783,32 +1698,19 @@ static int ath10k_pci_ce_init(struct ath10k *ar) | |||
1783 | return 0; | 1698 | return 0; |
1784 | } | 1699 | } |
1785 | 1700 | ||
1786 | static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar) | 1701 | static bool ath10k_pci_has_fw_crashed(struct ath10k *ar) |
1787 | { | 1702 | { |
1788 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1703 | return ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS) & |
1789 | u32 fw_indicator; | 1704 | FW_IND_EVENT_PENDING; |
1790 | 1705 | } | |
1791 | ath10k_pci_wake(ar); | ||
1792 | |||
1793 | fw_indicator = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); | ||
1794 | |||
1795 | if (fw_indicator & FW_IND_EVENT_PENDING) { | ||
1796 | /* ACK: clear Target-side pending event */ | ||
1797 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, | ||
1798 | fw_indicator & ~FW_IND_EVENT_PENDING); | ||
1799 | 1706 | ||
1800 | if (ar_pci->started) { | 1707 | static void ath10k_pci_fw_crashed_clear(struct ath10k *ar) |
1801 | ath10k_pci_hif_dump_area(ar); | 1708 | { |
1802 | } else { | 1709 | u32 val; |
1803 | /* | ||
1804 | * Probable Target failure before we're prepared | ||
1805 | * to handle it. Generally unexpected. | ||
1806 | */ | ||
1807 | ath10k_warn("early firmware event indicated\n"); | ||
1808 | } | ||
1809 | } | ||
1810 | 1710 | ||
1811 | ath10k_pci_sleep(ar); | 1711 | val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); |
1712 | val &= ~FW_IND_EVENT_PENDING; | ||
1713 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val); | ||
1812 | } | 1714 | } |
1813 | 1715 | ||
1814 | /* this function effectively clears target memory controller assert line */ | 1716 | /* this function effectively clears target memory controller assert line */ |
@@ -1833,25 +1735,19 @@ static void ath10k_pci_warm_reset_si0(struct ath10k *ar) | |||
1833 | 1735 | ||
1834 | static int ath10k_pci_warm_reset(struct ath10k *ar) | 1736 | static int ath10k_pci_warm_reset(struct ath10k *ar) |
1835 | { | 1737 | { |
1836 | int ret = 0; | ||
1837 | u32 val; | 1738 | u32 val; |
1838 | 1739 | ||
1839 | ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset\n"); | 1740 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset\n"); |
1840 | |||
1841 | ret = ath10k_do_pci_wake(ar); | ||
1842 | if (ret) { | ||
1843 | ath10k_err("failed to wake up target: %d\n", ret); | ||
1844 | return ret; | ||
1845 | } | ||
1846 | 1741 | ||
1847 | /* debug */ | 1742 | /* debug */ |
1848 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 1743 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
1849 | PCIE_INTR_CAUSE_ADDRESS); | 1744 | PCIE_INTR_CAUSE_ADDRESS); |
1850 | ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val); | 1745 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", |
1746 | val); | ||
1851 | 1747 | ||
1852 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 1748 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
1853 | CPU_INTR_ADDRESS); | 1749 | CPU_INTR_ADDRESS); |
1854 | ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", | 1750 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", |
1855 | val); | 1751 | val); |
1856 | 1752 | ||
1857 | /* disable pending irqs */ | 1753 | /* disable pending irqs */ |
@@ -1894,11 +1790,12 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) | |||
1894 | /* debug */ | 1790 | /* debug */ |
1895 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 1791 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
1896 | PCIE_INTR_CAUSE_ADDRESS); | 1792 | PCIE_INTR_CAUSE_ADDRESS); |
1897 | ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val); | 1793 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", |
1794 | val); | ||
1898 | 1795 | ||
1899 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 1796 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
1900 | CPU_INTR_ADDRESS); | 1797 | CPU_INTR_ADDRESS); |
1901 | ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", | 1798 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", |
1902 | val); | 1799 | val); |
1903 | 1800 | ||
1904 | /* CPU warm reset */ | 1801 | /* CPU warm reset */ |
@@ -1909,20 +1806,18 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) | |||
1909 | 1806 | ||
1910 | val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + | 1807 | val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + |
1911 | SOC_RESET_CONTROL_ADDRESS); | 1808 | SOC_RESET_CONTROL_ADDRESS); |
1912 | ath10k_dbg(ATH10K_DBG_BOOT, "boot target reset state: 0x%08x\n", val); | 1809 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target reset state: 0x%08x\n", |
1810 | val); | ||
1913 | 1811 | ||
1914 | msleep(100); | 1812 | msleep(100); |
1915 | 1813 | ||
1916 | ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset complete\n"); | 1814 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset complete\n"); |
1917 | 1815 | ||
1918 | ath10k_do_pci_sleep(ar); | 1816 | return 0; |
1919 | return ret; | ||
1920 | } | 1817 | } |
1921 | 1818 | ||
1922 | static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) | 1819 | static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) |
1923 | { | 1820 | { |
1924 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1925 | const char *irq_mode; | ||
1926 | int ret; | 1821 | int ret; |
1927 | 1822 | ||
1928 | /* | 1823 | /* |
@@ -1941,80 +1836,39 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) | |||
1941 | ret = ath10k_pci_warm_reset(ar); | 1836 | ret = ath10k_pci_warm_reset(ar); |
1942 | 1837 | ||
1943 | if (ret) { | 1838 | if (ret) { |
1944 | ath10k_err("failed to reset target: %d\n", ret); | 1839 | ath10k_err(ar, "failed to reset target: %d\n", ret); |
1945 | goto err; | 1840 | goto err; |
1946 | } | 1841 | } |
1947 | 1842 | ||
1948 | if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) | ||
1949 | /* Force AWAKE forever */ | ||
1950 | ath10k_do_pci_wake(ar); | ||
1951 | |||
1952 | ret = ath10k_pci_ce_init(ar); | 1843 | ret = ath10k_pci_ce_init(ar); |
1953 | if (ret) { | 1844 | if (ret) { |
1954 | ath10k_err("failed to initialize CE: %d\n", ret); | 1845 | ath10k_err(ar, "failed to initialize CE: %d\n", ret); |
1955 | goto err_ps; | 1846 | goto err; |
1956 | } | ||
1957 | |||
1958 | ret = ath10k_ce_disable_interrupts(ar); | ||
1959 | if (ret) { | ||
1960 | ath10k_err("failed to disable CE interrupts: %d\n", ret); | ||
1961 | goto err_ce; | ||
1962 | } | ||
1963 | |||
1964 | ret = ath10k_pci_init_irq(ar); | ||
1965 | if (ret) { | ||
1966 | ath10k_err("failed to init irqs: %d\n", ret); | ||
1967 | goto err_ce; | ||
1968 | } | ||
1969 | |||
1970 | ret = ath10k_pci_request_early_irq(ar); | ||
1971 | if (ret) { | ||
1972 | ath10k_err("failed to request early irq: %d\n", ret); | ||
1973 | goto err_deinit_irq; | ||
1974 | } | 1847 | } |
1975 | 1848 | ||
1976 | ret = ath10k_pci_wait_for_target_init(ar); | 1849 | ret = ath10k_pci_wait_for_target_init(ar); |
1977 | if (ret) { | 1850 | if (ret) { |
1978 | ath10k_err("failed to wait for target to init: %d\n", ret); | 1851 | ath10k_err(ar, "failed to wait for target to init: %d\n", ret); |
1979 | goto err_free_early_irq; | 1852 | goto err_ce; |
1980 | } | 1853 | } |
1981 | 1854 | ||
1982 | ret = ath10k_pci_init_config(ar); | 1855 | ret = ath10k_pci_init_config(ar); |
1983 | if (ret) { | 1856 | if (ret) { |
1984 | ath10k_err("failed to setup init config: %d\n", ret); | 1857 | ath10k_err(ar, "failed to setup init config: %d\n", ret); |
1985 | goto err_free_early_irq; | 1858 | goto err_ce; |
1986 | } | 1859 | } |
1987 | 1860 | ||
1988 | ret = ath10k_pci_wake_target_cpu(ar); | 1861 | ret = ath10k_pci_wake_target_cpu(ar); |
1989 | if (ret) { | 1862 | if (ret) { |
1990 | ath10k_err("could not wake up target CPU: %d\n", ret); | 1863 | ath10k_err(ar, "could not wake up target CPU: %d\n", ret); |
1991 | goto err_free_early_irq; | 1864 | goto err_ce; |
1992 | } | 1865 | } |
1993 | 1866 | ||
1994 | if (ar_pci->num_msi_intrs > 1) | ||
1995 | irq_mode = "MSI-X"; | ||
1996 | else if (ar_pci->num_msi_intrs == 1) | ||
1997 | irq_mode = "MSI"; | ||
1998 | else | ||
1999 | irq_mode = "legacy"; | ||
2000 | |||
2001 | if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) | ||
2002 | ath10k_info("pci irq %s irq_mode %d reset_mode %d\n", | ||
2003 | irq_mode, ath10k_pci_irq_mode, | ||
2004 | ath10k_pci_reset_mode); | ||
2005 | |||
2006 | return 0; | 1867 | return 0; |
2007 | 1868 | ||
2008 | err_free_early_irq: | ||
2009 | ath10k_pci_free_early_irq(ar); | ||
2010 | err_deinit_irq: | ||
2011 | ath10k_pci_deinit_irq(ar); | ||
2012 | err_ce: | 1869 | err_ce: |
2013 | ath10k_pci_ce_deinit(ar); | 1870 | ath10k_pci_ce_deinit(ar); |
2014 | ath10k_pci_warm_reset(ar); | 1871 | ath10k_pci_warm_reset(ar); |
2015 | err_ps: | ||
2016 | if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) | ||
2017 | ath10k_do_pci_sleep(ar); | ||
2018 | err: | 1872 | err: |
2019 | return ret; | 1873 | return ret; |
2020 | } | 1874 | } |
@@ -2034,7 +1888,7 @@ static int ath10k_pci_hif_power_up_warm(struct ath10k *ar) | |||
2034 | if (ret == 0) | 1888 | if (ret == 0) |
2035 | break; | 1889 | break; |
2036 | 1890 | ||
2037 | ath10k_warn("failed to warm reset (attempt %d out of %d): %d\n", | 1891 | ath10k_warn(ar, "failed to warm reset (attempt %d out of %d): %d\n", |
2038 | i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, ret); | 1892 | i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, ret); |
2039 | } | 1893 | } |
2040 | 1894 | ||
@@ -2045,7 +1899,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
2045 | { | 1899 | { |
2046 | int ret; | 1900 | int ret; |
2047 | 1901 | ||
2048 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power up\n"); | 1902 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); |
2049 | 1903 | ||
2050 | /* | 1904 | /* |
2051 | * Hardware CUS232 version 2 has some issues with cold reset and the | 1905 | * Hardware CUS232 version 2 has some issues with cold reset and the |
@@ -2057,17 +1911,17 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
2057 | */ | 1911 | */ |
2058 | ret = ath10k_pci_hif_power_up_warm(ar); | 1912 | ret = ath10k_pci_hif_power_up_warm(ar); |
2059 | if (ret) { | 1913 | if (ret) { |
2060 | ath10k_warn("failed to power up target using warm reset: %d\n", | 1914 | ath10k_warn(ar, "failed to power up target using warm reset: %d\n", |
2061 | ret); | 1915 | ret); |
2062 | 1916 | ||
2063 | if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) | 1917 | if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) |
2064 | return ret; | 1918 | return ret; |
2065 | 1919 | ||
2066 | ath10k_warn("trying cold reset\n"); | 1920 | ath10k_warn(ar, "trying cold reset\n"); |
2067 | 1921 | ||
2068 | ret = __ath10k_pci_hif_power_up(ar, true); | 1922 | ret = __ath10k_pci_hif_power_up(ar, true); |
2069 | if (ret) { | 1923 | if (ret) { |
2070 | ath10k_err("failed to power up target using cold reset too (%d)\n", | 1924 | ath10k_err(ar, "failed to power up target using cold reset too (%d)\n", |
2071 | ret); | 1925 | ret); |
2072 | return ret; | 1926 | return ret; |
2073 | } | 1927 | } |
@@ -2078,18 +1932,9 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
2078 | 1932 | ||
2079 | static void ath10k_pci_hif_power_down(struct ath10k *ar) | 1933 | static void ath10k_pci_hif_power_down(struct ath10k *ar) |
2080 | { | 1934 | { |
2081 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 1935 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); |
2082 | |||
2083 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power down\n"); | ||
2084 | 1936 | ||
2085 | ath10k_pci_free_early_irq(ar); | ||
2086 | ath10k_pci_kill_tasklet(ar); | ||
2087 | ath10k_pci_deinit_irq(ar); | ||
2088 | ath10k_pci_ce_deinit(ar); | ||
2089 | ath10k_pci_warm_reset(ar); | 1937 | ath10k_pci_warm_reset(ar); |
2090 | |||
2091 | if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) | ||
2092 | ath10k_do_pci_sleep(ar); | ||
2093 | } | 1938 | } |
2094 | 1939 | ||
2095 | #ifdef CONFIG_PM | 1940 | #ifdef CONFIG_PM |
@@ -2171,7 +2016,13 @@ static void ath10k_msi_err_tasklet(unsigned long data) | |||
2171 | { | 2016 | { |
2172 | struct ath10k *ar = (struct ath10k *)data; | 2017 | struct ath10k *ar = (struct ath10k *)data; |
2173 | 2018 | ||
2174 | ath10k_pci_fw_interrupt_handler(ar); | 2019 | if (!ath10k_pci_has_fw_crashed(ar)) { |
2020 | ath10k_warn(ar, "received unsolicited fw crash interrupt\n"); | ||
2021 | return; | ||
2022 | } | ||
2023 | |||
2024 | ath10k_pci_fw_crashed_clear(ar); | ||
2025 | ath10k_pci_fw_crashed_dump(ar); | ||
2175 | } | 2026 | } |
2176 | 2027 | ||
2177 | /* | 2028 | /* |
@@ -2185,7 +2036,8 @@ static irqreturn_t ath10k_pci_per_engine_handler(int irq, void *arg) | |||
2185 | int ce_id = irq - ar_pci->pdev->irq - MSI_ASSIGN_CE_INITIAL; | 2036 | int ce_id = irq - ar_pci->pdev->irq - MSI_ASSIGN_CE_INITIAL; |
2186 | 2037 | ||
2187 | if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_pci->pipe_info)) { | 2038 | if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_pci->pipe_info)) { |
2188 | ath10k_warn("unexpected/invalid irq %d ce_id %d\n", irq, ce_id); | 2039 | ath10k_warn(ar, "unexpected/invalid irq %d ce_id %d\n", irq, |
2040 | ce_id); | ||
2189 | return IRQ_HANDLED; | 2041 | return IRQ_HANDLED; |
2190 | } | 2042 | } |
2191 | 2043 | ||
@@ -2232,36 +2084,17 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg) | |||
2232 | return IRQ_HANDLED; | 2084 | return IRQ_HANDLED; |
2233 | } | 2085 | } |
2234 | 2086 | ||
2235 | static void ath10k_pci_early_irq_tasklet(unsigned long data) | 2087 | static void ath10k_pci_tasklet(unsigned long data) |
2236 | { | 2088 | { |
2237 | struct ath10k *ar = (struct ath10k *)data; | 2089 | struct ath10k *ar = (struct ath10k *)data; |
2238 | u32 fw_ind; | 2090 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2239 | int ret; | ||
2240 | 2091 | ||
2241 | ret = ath10k_pci_wake(ar); | 2092 | if (ath10k_pci_has_fw_crashed(ar)) { |
2242 | if (ret) { | 2093 | ath10k_pci_fw_crashed_clear(ar); |
2243 | ath10k_warn("failed to wake target in early irq tasklet: %d\n", | 2094 | ath10k_pci_fw_crashed_dump(ar); |
2244 | ret); | ||
2245 | return; | 2095 | return; |
2246 | } | 2096 | } |
2247 | 2097 | ||
2248 | fw_ind = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); | ||
2249 | if (fw_ind & FW_IND_EVENT_PENDING) { | ||
2250 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, | ||
2251 | fw_ind & ~FW_IND_EVENT_PENDING); | ||
2252 | ath10k_pci_hif_dump_area(ar); | ||
2253 | } | ||
2254 | |||
2255 | ath10k_pci_sleep(ar); | ||
2256 | ath10k_pci_enable_legacy_irq(ar); | ||
2257 | } | ||
2258 | |||
2259 | static void ath10k_pci_tasklet(unsigned long data) | ||
2260 | { | ||
2261 | struct ath10k *ar = (struct ath10k *)data; | ||
2262 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
2263 | |||
2264 | ath10k_pci_fw_interrupt_handler(ar); /* FIXME: Handle FW error */ | ||
2265 | ath10k_ce_per_engine_service_any(ar); | 2098 | ath10k_ce_per_engine_service_any(ar); |
2266 | 2099 | ||
2267 | /* Re-enable legacy irq that was disabled in the irq handler */ | 2100 | /* Re-enable legacy irq that was disabled in the irq handler */ |
@@ -2278,7 +2111,7 @@ static int ath10k_pci_request_irq_msix(struct ath10k *ar) | |||
2278 | ath10k_pci_msi_fw_handler, | 2111 | ath10k_pci_msi_fw_handler, |
2279 | IRQF_SHARED, "ath10k_pci", ar); | 2112 | IRQF_SHARED, "ath10k_pci", ar); |
2280 | if (ret) { | 2113 | if (ret) { |
2281 | ath10k_warn("failed to request MSI-X fw irq %d: %d\n", | 2114 | ath10k_warn(ar, "failed to request MSI-X fw irq %d: %d\n", |
2282 | ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); | 2115 | ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); |
2283 | return ret; | 2116 | return ret; |
2284 | } | 2117 | } |
@@ -2288,7 +2121,7 @@ static int ath10k_pci_request_irq_msix(struct ath10k *ar) | |||
2288 | ath10k_pci_per_engine_handler, | 2121 | ath10k_pci_per_engine_handler, |
2289 | IRQF_SHARED, "ath10k_pci", ar); | 2122 | IRQF_SHARED, "ath10k_pci", ar); |
2290 | if (ret) { | 2123 | if (ret) { |
2291 | ath10k_warn("failed to request MSI-X ce irq %d: %d\n", | 2124 | ath10k_warn(ar, "failed to request MSI-X ce irq %d: %d\n", |
2292 | ar_pci->pdev->irq + i, ret); | 2125 | ar_pci->pdev->irq + i, ret); |
2293 | 2126 | ||
2294 | for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) | 2127 | for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) |
@@ -2311,7 +2144,7 @@ static int ath10k_pci_request_irq_msi(struct ath10k *ar) | |||
2311 | ath10k_pci_interrupt_handler, | 2144 | ath10k_pci_interrupt_handler, |
2312 | IRQF_SHARED, "ath10k_pci", ar); | 2145 | IRQF_SHARED, "ath10k_pci", ar); |
2313 | if (ret) { | 2146 | if (ret) { |
2314 | ath10k_warn("failed to request MSI irq %d: %d\n", | 2147 | ath10k_warn(ar, "failed to request MSI irq %d: %d\n", |
2315 | ar_pci->pdev->irq, ret); | 2148 | ar_pci->pdev->irq, ret); |
2316 | return ret; | 2149 | return ret; |
2317 | } | 2150 | } |
@@ -2328,7 +2161,7 @@ static int ath10k_pci_request_irq_legacy(struct ath10k *ar) | |||
2328 | ath10k_pci_interrupt_handler, | 2161 | ath10k_pci_interrupt_handler, |
2329 | IRQF_SHARED, "ath10k_pci", ar); | 2162 | IRQF_SHARED, "ath10k_pci", ar); |
2330 | if (ret) { | 2163 | if (ret) { |
2331 | ath10k_warn("failed to request legacy irq %d: %d\n", | 2164 | ath10k_warn(ar, "failed to request legacy irq %d: %d\n", |
2332 | ar_pci->pdev->irq, ret); | 2165 | ar_pci->pdev->irq, ret); |
2333 | return ret; | 2166 | return ret; |
2334 | } | 2167 | } |
@@ -2349,7 +2182,7 @@ static int ath10k_pci_request_irq(struct ath10k *ar) | |||
2349 | return ath10k_pci_request_irq_msix(ar); | 2182 | return ath10k_pci_request_irq_msix(ar); |
2350 | } | 2183 | } |
2351 | 2184 | ||
2352 | ath10k_warn("unknown irq configuration upon request\n"); | 2185 | ath10k_warn(ar, "unknown irq configuration upon request\n"); |
2353 | return -EINVAL; | 2186 | return -EINVAL; |
2354 | } | 2187 | } |
2355 | 2188 | ||
@@ -2372,8 +2205,6 @@ static void ath10k_pci_init_irq_tasklets(struct ath10k *ar) | |||
2372 | tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar); | 2205 | tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar); |
2373 | tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, | 2206 | tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, |
2374 | (unsigned long)ar); | 2207 | (unsigned long)ar); |
2375 | tasklet_init(&ar_pci->early_irq_tasklet, ath10k_pci_early_irq_tasklet, | ||
2376 | (unsigned long)ar); | ||
2377 | 2208 | ||
2378 | for (i = 0; i < CE_COUNT; i++) { | 2209 | for (i = 0; i < CE_COUNT; i++) { |
2379 | ar_pci->pipe_info[i].ar_pci = ar_pci; | 2210 | ar_pci->pipe_info[i].ar_pci = ar_pci; |
@@ -2385,18 +2216,16 @@ static void ath10k_pci_init_irq_tasklets(struct ath10k *ar) | |||
2385 | static int ath10k_pci_init_irq(struct ath10k *ar) | 2216 | static int ath10k_pci_init_irq(struct ath10k *ar) |
2386 | { | 2217 | { |
2387 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2218 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2388 | bool msix_supported = test_bit(ATH10K_PCI_FEATURE_MSI_X, | ||
2389 | ar_pci->features); | ||
2390 | int ret; | 2219 | int ret; |
2391 | 2220 | ||
2392 | ath10k_pci_init_irq_tasklets(ar); | 2221 | ath10k_pci_init_irq_tasklets(ar); |
2393 | 2222 | ||
2394 | if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO && | 2223 | if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO) |
2395 | !test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) | 2224 | ath10k_info(ar, "limiting irq mode to: %d\n", |
2396 | ath10k_info("limiting irq mode to: %d\n", ath10k_pci_irq_mode); | 2225 | ath10k_pci_irq_mode); |
2397 | 2226 | ||
2398 | /* Try MSI-X */ | 2227 | /* Try MSI-X */ |
2399 | if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) { | 2228 | if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) { |
2400 | ar_pci->num_msi_intrs = MSI_NUM_REQUEST; | 2229 | ar_pci->num_msi_intrs = MSI_NUM_REQUEST; |
2401 | ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, | 2230 | ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, |
2402 | ar_pci->num_msi_intrs); | 2231 | ar_pci->num_msi_intrs); |
@@ -2426,34 +2255,16 @@ static int ath10k_pci_init_irq(struct ath10k *ar) | |||
2426 | * synchronization checking. */ | 2255 | * synchronization checking. */ |
2427 | ar_pci->num_msi_intrs = 0; | 2256 | ar_pci->num_msi_intrs = 0; |
2428 | 2257 | ||
2429 | ret = ath10k_pci_wake(ar); | ||
2430 | if (ret) { | ||
2431 | ath10k_warn("failed to wake target: %d\n", ret); | ||
2432 | return ret; | ||
2433 | } | ||
2434 | |||
2435 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, | 2258 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, |
2436 | PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); | 2259 | PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); |
2437 | ath10k_pci_sleep(ar); | ||
2438 | 2260 | ||
2439 | return 0; | 2261 | return 0; |
2440 | } | 2262 | } |
2441 | 2263 | ||
2442 | static int ath10k_pci_deinit_irq_legacy(struct ath10k *ar) | 2264 | static void ath10k_pci_deinit_irq_legacy(struct ath10k *ar) |
2443 | { | 2265 | { |
2444 | int ret; | ||
2445 | |||
2446 | ret = ath10k_pci_wake(ar); | ||
2447 | if (ret) { | ||
2448 | ath10k_warn("failed to wake target: %d\n", ret); | ||
2449 | return ret; | ||
2450 | } | ||
2451 | |||
2452 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, | 2266 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, |
2453 | 0); | 2267 | 0); |
2454 | ath10k_pci_sleep(ar); | ||
2455 | |||
2456 | return 0; | ||
2457 | } | 2268 | } |
2458 | 2269 | ||
2459 | static int ath10k_pci_deinit_irq(struct ath10k *ar) | 2270 | static int ath10k_pci_deinit_irq(struct ath10k *ar) |
@@ -2462,7 +2273,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar) | |||
2462 | 2273 | ||
2463 | switch (ar_pci->num_msi_intrs) { | 2274 | switch (ar_pci->num_msi_intrs) { |
2464 | case 0: | 2275 | case 0: |
2465 | return ath10k_pci_deinit_irq_legacy(ar); | 2276 | ath10k_pci_deinit_irq_legacy(ar); |
2277 | return 0; | ||
2466 | case 1: | 2278 | case 1: |
2467 | /* fall-through */ | 2279 | /* fall-through */ |
2468 | case MSI_NUM_REQUEST: | 2280 | case MSI_NUM_REQUEST: |
@@ -2472,7 +2284,7 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar) | |||
2472 | pci_disable_msi(ar_pci->pdev); | 2284 | pci_disable_msi(ar_pci->pdev); |
2473 | } | 2285 | } |
2474 | 2286 | ||
2475 | ath10k_warn("unknown irq configuration upon deinit\n"); | 2287 | ath10k_warn(ar, "unknown irq configuration upon deinit\n"); |
2476 | return -EINVAL; | 2288 | return -EINVAL; |
2477 | } | 2289 | } |
2478 | 2290 | ||
@@ -2480,23 +2292,17 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) | |||
2480 | { | 2292 | { |
2481 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2293 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2482 | unsigned long timeout; | 2294 | unsigned long timeout; |
2483 | int ret; | ||
2484 | u32 val; | 2295 | u32 val; |
2485 | 2296 | ||
2486 | ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n"); | 2297 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot waiting target to initialise\n"); |
2487 | |||
2488 | ret = ath10k_pci_wake(ar); | ||
2489 | if (ret) { | ||
2490 | ath10k_err("failed to wake up target for init: %d\n", ret); | ||
2491 | return ret; | ||
2492 | } | ||
2493 | 2298 | ||
2494 | timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT); | 2299 | timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT); |
2495 | 2300 | ||
2496 | do { | 2301 | do { |
2497 | val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); | 2302 | val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); |
2498 | 2303 | ||
2499 | ath10k_dbg(ATH10K_DBG_BOOT, "boot target indicator %x\n", val); | 2304 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target indicator %x\n", |
2305 | val); | ||
2500 | 2306 | ||
2501 | /* target should never return this */ | 2307 | /* target should never return this */ |
2502 | if (val == 0xffffffff) | 2308 | if (val == 0xffffffff) |
@@ -2511,55 +2317,42 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) | |||
2511 | 2317 | ||
2512 | if (ar_pci->num_msi_intrs == 0) | 2318 | if (ar_pci->num_msi_intrs == 0) |
2513 | /* Fix potential race by repeating CORE_BASE writes */ | 2319 | /* Fix potential race by repeating CORE_BASE writes */ |
2514 | ath10k_pci_soc_write32(ar, PCIE_INTR_ENABLE_ADDRESS, | 2320 | ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + |
2515 | PCIE_INTR_FIRMWARE_MASK | | 2321 | PCIE_INTR_ENABLE_ADDRESS, |
2516 | PCIE_INTR_CE_MASK_ALL); | 2322 | PCIE_INTR_FIRMWARE_MASK | |
2323 | PCIE_INTR_CE_MASK_ALL); | ||
2517 | 2324 | ||
2518 | mdelay(10); | 2325 | mdelay(10); |
2519 | } while (time_before(jiffies, timeout)); | 2326 | } while (time_before(jiffies, timeout)); |
2520 | 2327 | ||
2521 | if (val == 0xffffffff) { | 2328 | if (val == 0xffffffff) { |
2522 | ath10k_err("failed to read device register, device is gone\n"); | 2329 | ath10k_err(ar, "failed to read device register, device is gone\n"); |
2523 | ret = -EIO; | 2330 | return -EIO; |
2524 | goto out; | ||
2525 | } | 2331 | } |
2526 | 2332 | ||
2527 | if (val & FW_IND_EVENT_PENDING) { | 2333 | if (val & FW_IND_EVENT_PENDING) { |
2528 | ath10k_warn("device has crashed during init\n"); | 2334 | ath10k_warn(ar, "device has crashed during init\n"); |
2529 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, | 2335 | ath10k_pci_fw_crashed_clear(ar); |
2530 | val & ~FW_IND_EVENT_PENDING); | 2336 | ath10k_pci_fw_crashed_dump(ar); |
2531 | ath10k_pci_hif_dump_area(ar); | 2337 | return -ECOMM; |
2532 | ret = -ECOMM; | ||
2533 | goto out; | ||
2534 | } | 2338 | } |
2535 | 2339 | ||
2536 | if (!(val & FW_IND_INITIALIZED)) { | 2340 | if (!(val & FW_IND_INITIALIZED)) { |
2537 | ath10k_err("failed to receive initialized event from target: %08x\n", | 2341 | ath10k_err(ar, "failed to receive initialized event from target: %08x\n", |
2538 | val); | 2342 | val); |
2539 | ret = -ETIMEDOUT; | 2343 | return -ETIMEDOUT; |
2540 | goto out; | ||
2541 | } | 2344 | } |
2542 | 2345 | ||
2543 | ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n"); | 2346 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target initialised\n"); |
2544 | 2347 | return 0; | |
2545 | out: | ||
2546 | ath10k_pci_sleep(ar); | ||
2547 | return ret; | ||
2548 | } | 2348 | } |
2549 | 2349 | ||
2550 | static int ath10k_pci_cold_reset(struct ath10k *ar) | 2350 | static int ath10k_pci_cold_reset(struct ath10k *ar) |
2551 | { | 2351 | { |
2552 | int i, ret; | 2352 | int i; |
2553 | u32 val; | 2353 | u32 val; |
2554 | 2354 | ||
2555 | ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n"); | 2355 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n"); |
2556 | |||
2557 | ret = ath10k_do_pci_wake(ar); | ||
2558 | if (ret) { | ||
2559 | ath10k_err("failed to wake up target: %d\n", | ||
2560 | ret); | ||
2561 | return ret; | ||
2562 | } | ||
2563 | 2356 | ||
2564 | /* Put Target, including PCIe, into RESET. */ | 2357 | /* Put Target, including PCIe, into RESET. */ |
2565 | val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); | 2358 | val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); |
@@ -2584,169 +2377,198 @@ static int ath10k_pci_cold_reset(struct ath10k *ar) | |||
2584 | msleep(1); | 2377 | msleep(1); |
2585 | } | 2378 | } |
2586 | 2379 | ||
2587 | ath10k_do_pci_sleep(ar); | 2380 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n"); |
2588 | |||
2589 | ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n"); | ||
2590 | 2381 | ||
2591 | return 0; | 2382 | return 0; |
2592 | } | 2383 | } |
2593 | 2384 | ||
2594 | static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) | 2385 | static int ath10k_pci_claim(struct ath10k *ar) |
2595 | { | ||
2596 | int i; | ||
2597 | |||
2598 | for (i = 0; i < ATH10K_PCI_FEATURE_COUNT; i++) { | ||
2599 | if (!test_bit(i, ar_pci->features)) | ||
2600 | continue; | ||
2601 | |||
2602 | switch (i) { | ||
2603 | case ATH10K_PCI_FEATURE_MSI_X: | ||
2604 | ath10k_dbg(ATH10K_DBG_BOOT, "device supports MSI-X\n"); | ||
2605 | break; | ||
2606 | case ATH10K_PCI_FEATURE_SOC_POWER_SAVE: | ||
2607 | ath10k_dbg(ATH10K_DBG_BOOT, "QCA98XX SoC power save enabled\n"); | ||
2608 | break; | ||
2609 | } | ||
2610 | } | ||
2611 | } | ||
2612 | |||
2613 | static int ath10k_pci_probe(struct pci_dev *pdev, | ||
2614 | const struct pci_device_id *pci_dev) | ||
2615 | { | 2386 | { |
2616 | void __iomem *mem; | 2387 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2617 | int ret = 0; | 2388 | struct pci_dev *pdev = ar_pci->pdev; |
2618 | struct ath10k *ar; | 2389 | u32 lcr_val; |
2619 | struct ath10k_pci *ar_pci; | 2390 | int ret; |
2620 | u32 lcr_val, chip_id; | ||
2621 | |||
2622 | ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n"); | ||
2623 | |||
2624 | ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL); | ||
2625 | if (ar_pci == NULL) | ||
2626 | return -ENOMEM; | ||
2627 | |||
2628 | ar_pci->pdev = pdev; | ||
2629 | ar_pci->dev = &pdev->dev; | ||
2630 | |||
2631 | switch (pci_dev->device) { | ||
2632 | case QCA988X_2_0_DEVICE_ID: | ||
2633 | set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features); | ||
2634 | break; | ||
2635 | default: | ||
2636 | ret = -ENODEV; | ||
2637 | ath10k_err("Unknown device ID: %d\n", pci_dev->device); | ||
2638 | goto err_ar_pci; | ||
2639 | } | ||
2640 | |||
2641 | if (ath10k_pci_target_ps) | ||
2642 | set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features); | ||
2643 | |||
2644 | ath10k_pci_dump_features(ar_pci); | ||
2645 | |||
2646 | ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops); | ||
2647 | if (!ar) { | ||
2648 | ath10k_err("failed to create driver core\n"); | ||
2649 | ret = -EINVAL; | ||
2650 | goto err_ar_pci; | ||
2651 | } | ||
2652 | |||
2653 | ar_pci->ar = ar; | ||
2654 | atomic_set(&ar_pci->keep_awake_count, 0); | ||
2655 | 2391 | ||
2656 | pci_set_drvdata(pdev, ar); | 2392 | pci_set_drvdata(pdev, ar); |
2657 | 2393 | ||
2658 | ret = pci_enable_device(pdev); | 2394 | ret = pci_enable_device(pdev); |
2659 | if (ret) { | 2395 | if (ret) { |
2660 | ath10k_err("failed to enable PCI device: %d\n", ret); | 2396 | ath10k_err(ar, "failed to enable pci device: %d\n", ret); |
2661 | goto err_ar; | 2397 | return ret; |
2662 | } | 2398 | } |
2663 | 2399 | ||
2664 | /* Request MMIO resources */ | ||
2665 | ret = pci_request_region(pdev, BAR_NUM, "ath"); | 2400 | ret = pci_request_region(pdev, BAR_NUM, "ath"); |
2666 | if (ret) { | 2401 | if (ret) { |
2667 | ath10k_err("failed to request MMIO region: %d\n", ret); | 2402 | ath10k_err(ar, "failed to request region BAR%d: %d\n", BAR_NUM, |
2403 | ret); | ||
2668 | goto err_device; | 2404 | goto err_device; |
2669 | } | 2405 | } |
2670 | 2406 | ||
2671 | /* | 2407 | /* Target expects 32 bit DMA. Enforce it. */ |
2672 | * Target structures have a limit of 32 bit DMA pointers. | ||
2673 | * DMA pointers can be wider than 32 bits by default on some systems. | ||
2674 | */ | ||
2675 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2408 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
2676 | if (ret) { | 2409 | if (ret) { |
2677 | ath10k_err("failed to set DMA mask to 32-bit: %d\n", ret); | 2410 | ath10k_err(ar, "failed to set dma mask to 32-bit: %d\n", ret); |
2678 | goto err_region; | 2411 | goto err_region; |
2679 | } | 2412 | } |
2680 | 2413 | ||
2681 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 2414 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
2682 | if (ret) { | 2415 | if (ret) { |
2683 | ath10k_err("failed to set consistent DMA mask to 32-bit\n"); | 2416 | ath10k_err(ar, "failed to set consistent dma mask to 32-bit: %d\n", |
2417 | ret); | ||
2684 | goto err_region; | 2418 | goto err_region; |
2685 | } | 2419 | } |
2686 | 2420 | ||
2687 | /* Set bus master bit in PCI_COMMAND to enable DMA */ | ||
2688 | pci_set_master(pdev); | 2421 | pci_set_master(pdev); |
2689 | 2422 | ||
2690 | /* | 2423 | /* Workaround: Disable ASPM */ |
2691 | * Temporary FIX: disable ASPM | ||
2692 | * Will be removed after the OTP is programmed | ||
2693 | */ | ||
2694 | pci_read_config_dword(pdev, 0x80, &lcr_val); | 2424 | pci_read_config_dword(pdev, 0x80, &lcr_val); |
2695 | pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); | 2425 | pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); |
2696 | 2426 | ||
2697 | /* Arrange for access to Target SoC registers. */ | 2427 | /* Arrange for access to Target SoC registers. */ |
2698 | mem = pci_iomap(pdev, BAR_NUM, 0); | 2428 | ar_pci->mem = pci_iomap(pdev, BAR_NUM, 0); |
2699 | if (!mem) { | 2429 | if (!ar_pci->mem) { |
2700 | ath10k_err("failed to perform IOMAP for BAR%d\n", BAR_NUM); | 2430 | ath10k_err(ar, "failed to iomap BAR%d\n", BAR_NUM); |
2701 | ret = -EIO; | 2431 | ret = -EIO; |
2702 | goto err_master; | 2432 | goto err_master; |
2703 | } | 2433 | } |
2704 | 2434 | ||
2705 | ar_pci->mem = mem; | 2435 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); |
2436 | return 0; | ||
2437 | |||
2438 | err_master: | ||
2439 | pci_clear_master(pdev); | ||
2440 | |||
2441 | err_region: | ||
2442 | pci_release_region(pdev, BAR_NUM); | ||
2443 | |||
2444 | err_device: | ||
2445 | pci_disable_device(pdev); | ||
2446 | |||
2447 | return ret; | ||
2448 | } | ||
2449 | |||
2450 | static void ath10k_pci_release(struct ath10k *ar) | ||
2451 | { | ||
2452 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
2453 | struct pci_dev *pdev = ar_pci->pdev; | ||
2454 | |||
2455 | pci_iounmap(pdev, ar_pci->mem); | ||
2456 | pci_release_region(pdev, BAR_NUM); | ||
2457 | pci_clear_master(pdev); | ||
2458 | pci_disable_device(pdev); | ||
2459 | } | ||
2460 | |||
2461 | static int ath10k_pci_probe(struct pci_dev *pdev, | ||
2462 | const struct pci_device_id *pci_dev) | ||
2463 | { | ||
2464 | int ret = 0; | ||
2465 | struct ath10k *ar; | ||
2466 | struct ath10k_pci *ar_pci; | ||
2467 | u32 chip_id; | ||
2468 | |||
2469 | ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, | ||
2470 | &ath10k_pci_hif_ops); | ||
2471 | if (!ar) { | ||
2472 | dev_err(&pdev->dev, "failed to allocate core\n"); | ||
2473 | return -ENOMEM; | ||
2474 | } | ||
2475 | |||
2476 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci probe\n"); | ||
2477 | |||
2478 | ar_pci = ath10k_pci_priv(ar); | ||
2479 | ar_pci->pdev = pdev; | ||
2480 | ar_pci->dev = &pdev->dev; | ||
2481 | ar_pci->ar = ar; | ||
2706 | 2482 | ||
2707 | spin_lock_init(&ar_pci->ce_lock); | 2483 | spin_lock_init(&ar_pci->ce_lock); |
2484 | setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, | ||
2485 | (unsigned long)ar); | ||
2708 | 2486 | ||
2709 | ret = ath10k_do_pci_wake(ar); | 2487 | ret = ath10k_pci_claim(ar); |
2710 | if (ret) { | 2488 | if (ret) { |
2711 | ath10k_err("Failed to get chip id: %d\n", ret); | 2489 | ath10k_err(ar, "failed to claim device: %d\n", ret); |
2712 | goto err_iomap; | 2490 | goto err_core_destroy; |
2713 | } | 2491 | } |
2714 | 2492 | ||
2715 | chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); | 2493 | ret = ath10k_pci_wake(ar); |
2494 | if (ret) { | ||
2495 | ath10k_err(ar, "failed to wake up: %d\n", ret); | ||
2496 | goto err_release; | ||
2497 | } | ||
2716 | 2498 | ||
2717 | ath10k_do_pci_sleep(ar); | 2499 | chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); |
2500 | if (chip_id == 0xffffffff) { | ||
2501 | ath10k_err(ar, "failed to get chip id\n"); | ||
2502 | goto err_sleep; | ||
2503 | } | ||
2718 | 2504 | ||
2719 | ret = ath10k_pci_alloc_ce(ar); | 2505 | ret = ath10k_pci_alloc_ce(ar); |
2720 | if (ret) { | 2506 | if (ret) { |
2721 | ath10k_err("failed to allocate copy engine pipes: %d\n", ret); | 2507 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", |
2722 | goto err_iomap; | 2508 | ret); |
2509 | goto err_sleep; | ||
2723 | } | 2510 | } |
2724 | 2511 | ||
2725 | ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); | 2512 | ath10k_pci_ce_deinit(ar); |
2726 | 2513 | ||
2727 | ret = ath10k_core_register(ar, chip_id); | 2514 | ret = ath10k_ce_disable_interrupts(ar); |
2515 | if (ret) { | ||
2516 | ath10k_err(ar, "failed to disable copy engine interrupts: %d\n", | ||
2517 | ret); | ||
2518 | goto err_free_ce; | ||
2519 | } | ||
2520 | |||
2521 | /* Workaround: There's no known way to mask all possible interrupts via | ||
2522 | * device CSR. The only way to make sure device doesn't assert | ||
2523 | * interrupts is to reset it. Interrupts are then disabled on host | ||
2524 | * after handlers are registered. | ||
2525 | */ | ||
2526 | ath10k_pci_warm_reset(ar); | ||
2527 | |||
2528 | ret = ath10k_pci_init_irq(ar); | ||
2728 | if (ret) { | 2529 | if (ret) { |
2729 | ath10k_err("failed to register driver core: %d\n", ret); | 2530 | ath10k_err(ar, "failed to init irqs: %d\n", ret); |
2730 | goto err_free_ce; | 2531 | goto err_free_ce; |
2731 | } | 2532 | } |
2732 | 2533 | ||
2534 | ath10k_info(ar, "pci irq %s interrupts %d irq_mode %d reset_mode %d\n", | ||
2535 | ath10k_pci_get_irq_method(ar), ar_pci->num_msi_intrs, | ||
2536 | ath10k_pci_irq_mode, ath10k_pci_reset_mode); | ||
2537 | |||
2538 | ret = ath10k_pci_request_irq(ar); | ||
2539 | if (ret) { | ||
2540 | ath10k_warn(ar, "failed to request irqs: %d\n", ret); | ||
2541 | goto err_deinit_irq; | ||
2542 | } | ||
2543 | |||
2544 | /* This shouldn't race as the device has been reset above. */ | ||
2545 | ath10k_pci_irq_disable(ar); | ||
2546 | |||
2547 | ret = ath10k_core_register(ar, chip_id); | ||
2548 | if (ret) { | ||
2549 | ath10k_err(ar, "failed to register driver core: %d\n", ret); | ||
2550 | goto err_free_irq; | ||
2551 | } | ||
2552 | |||
2733 | return 0; | 2553 | return 0; |
2734 | 2554 | ||
2555 | err_free_irq: | ||
2556 | ath10k_pci_free_irq(ar); | ||
2557 | |||
2558 | err_deinit_irq: | ||
2559 | ath10k_pci_deinit_irq(ar); | ||
2560 | |||
2735 | err_free_ce: | 2561 | err_free_ce: |
2736 | ath10k_pci_free_ce(ar); | 2562 | ath10k_pci_free_ce(ar); |
2737 | err_iomap: | 2563 | |
2738 | pci_iounmap(pdev, mem); | 2564 | err_sleep: |
2739 | err_master: | 2565 | ath10k_pci_sleep(ar); |
2740 | pci_clear_master(pdev); | 2566 | |
2741 | err_region: | 2567 | err_release: |
2742 | pci_release_region(pdev, BAR_NUM); | 2568 | ath10k_pci_release(ar); |
2743 | err_device: | 2569 | |
2744 | pci_disable_device(pdev); | 2570 | err_core_destroy: |
2745 | err_ar: | ||
2746 | ath10k_core_destroy(ar); | 2571 | ath10k_core_destroy(ar); |
2747 | err_ar_pci: | ||
2748 | /* call HIF PCI free here */ | ||
2749 | kfree(ar_pci); | ||
2750 | 2572 | ||
2751 | return ret; | 2573 | return ret; |
2752 | } | 2574 | } |
@@ -2756,7 +2578,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) | |||
2756 | struct ath10k *ar = pci_get_drvdata(pdev); | 2578 | struct ath10k *ar = pci_get_drvdata(pdev); |
2757 | struct ath10k_pci *ar_pci; | 2579 | struct ath10k_pci *ar_pci; |
2758 | 2580 | ||
2759 | ath10k_dbg(ATH10K_DBG_PCI, "pci remove\n"); | 2581 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci remove\n"); |
2760 | 2582 | ||
2761 | if (!ar) | 2583 | if (!ar) |
2762 | return; | 2584 | return; |
@@ -2767,15 +2589,13 @@ static void ath10k_pci_remove(struct pci_dev *pdev) | |||
2767 | return; | 2589 | return; |
2768 | 2590 | ||
2769 | ath10k_core_unregister(ar); | 2591 | ath10k_core_unregister(ar); |
2592 | ath10k_pci_free_irq(ar); | ||
2593 | ath10k_pci_deinit_irq(ar); | ||
2594 | ath10k_pci_ce_deinit(ar); | ||
2770 | ath10k_pci_free_ce(ar); | 2595 | ath10k_pci_free_ce(ar); |
2771 | 2596 | ath10k_pci_sleep(ar); | |
2772 | pci_iounmap(pdev, ar_pci->mem); | 2597 | ath10k_pci_release(ar); |
2773 | pci_release_region(pdev, BAR_NUM); | ||
2774 | pci_clear_master(pdev); | ||
2775 | pci_disable_device(pdev); | ||
2776 | |||
2777 | ath10k_core_destroy(ar); | 2598 | ath10k_core_destroy(ar); |
2778 | kfree(ar_pci); | ||
2779 | } | 2599 | } |
2780 | 2600 | ||
2781 | MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); | 2601 | MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); |
@@ -2793,7 +2613,8 @@ static int __init ath10k_pci_init(void) | |||
2793 | 2613 | ||
2794 | ret = pci_register_driver(&ath10k_pci_driver); | 2614 | ret = pci_register_driver(&ath10k_pci_driver); |
2795 | if (ret) | 2615 | if (ret) |
2796 | ath10k_err("failed to register PCI driver: %d\n", ret); | 2616 | printk(KERN_ERR "failed to register ath10k pci driver: %d\n", |
2617 | ret); | ||
2797 | 2618 | ||
2798 | return ret; | 2619 | return ret; |
2799 | } | 2620 | } |
@@ -2809,5 +2630,5 @@ module_exit(ath10k_pci_exit); | |||
2809 | MODULE_AUTHOR("Qualcomm Atheros"); | 2630 | MODULE_AUTHOR("Qualcomm Atheros"); |
2810 | MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); | 2631 | MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); |
2811 | MODULE_LICENSE("Dual BSD/GPL"); | 2632 | MODULE_LICENSE("Dual BSD/GPL"); |
2812 | MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_2_FILE); | 2633 | MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_3_FILE); |
2813 | MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE); | 2634 | MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE); |
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 940129209990..cf36511c7f4d 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h | |||
@@ -23,9 +23,6 @@ | |||
23 | #include "hw.h" | 23 | #include "hw.h" |
24 | #include "ce.h" | 24 | #include "ce.h" |
25 | 25 | ||
26 | /* FW dump area */ | ||
27 | #define REG_DUMP_COUNT_QCA988X 60 | ||
28 | |||
29 | /* | 26 | /* |
30 | * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite | 27 | * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite |
31 | */ | 28 | */ |
@@ -103,12 +100,12 @@ struct pcie_state { | |||
103 | * NOTE: Structure is shared between Host software and Target firmware! | 100 | * NOTE: Structure is shared between Host software and Target firmware! |
104 | */ | 101 | */ |
105 | struct ce_pipe_config { | 102 | struct ce_pipe_config { |
106 | u32 pipenum; | 103 | __le32 pipenum; |
107 | u32 pipedir; | 104 | __le32 pipedir; |
108 | u32 nentries; | 105 | __le32 nentries; |
109 | u32 nbytes_max; | 106 | __le32 nbytes_max; |
110 | u32 flags; | 107 | __le32 flags; |
111 | u32 reserved; | 108 | __le32 reserved; |
112 | }; | 109 | }; |
113 | 110 | ||
114 | /* | 111 | /* |
@@ -130,17 +127,9 @@ struct ce_pipe_config { | |||
130 | 127 | ||
131 | /* Establish a mapping between a service/direction and a pipe. */ | 128 | /* Establish a mapping between a service/direction and a pipe. */ |
132 | struct service_to_pipe { | 129 | struct service_to_pipe { |
133 | u32 service_id; | 130 | __le32 service_id; |
134 | u32 pipedir; | 131 | __le32 pipedir; |
135 | u32 pipenum; | 132 | __le32 pipenum; |
136 | }; | ||
137 | |||
138 | enum ath10k_pci_features { | ||
139 | ATH10K_PCI_FEATURE_MSI_X = 0, | ||
140 | ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 1, | ||
141 | |||
142 | /* keep last */ | ||
143 | ATH10K_PCI_FEATURE_COUNT | ||
144 | }; | 133 | }; |
145 | 134 | ||
146 | /* Per-pipe state. */ | 135 | /* Per-pipe state. */ |
@@ -169,8 +158,6 @@ struct ath10k_pci { | |||
169 | struct ath10k *ar; | 158 | struct ath10k *ar; |
170 | void __iomem *mem; | 159 | void __iomem *mem; |
171 | 160 | ||
172 | DECLARE_BITMAP(features, ATH10K_PCI_FEATURE_COUNT); | ||
173 | |||
174 | /* | 161 | /* |
175 | * Number of MSI interrupts granted, 0 --> using legacy PCI line | 162 | * Number of MSI interrupts granted, 0 --> using legacy PCI line |
176 | * interrupts. | 163 | * interrupts. |
@@ -179,12 +166,6 @@ struct ath10k_pci { | |||
179 | 166 | ||
180 | struct tasklet_struct intr_tq; | 167 | struct tasklet_struct intr_tq; |
181 | struct tasklet_struct msi_fw_err; | 168 | struct tasklet_struct msi_fw_err; |
182 | struct tasklet_struct early_irq_tasklet; | ||
183 | |||
184 | int started; | ||
185 | |||
186 | atomic_t keep_awake_count; | ||
187 | bool verified_awake; | ||
188 | 169 | ||
189 | struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; | 170 | struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; |
190 | 171 | ||
@@ -198,27 +179,15 @@ struct ath10k_pci { | |||
198 | 179 | ||
199 | /* Map CE id to ce_state */ | 180 | /* Map CE id to ce_state */ |
200 | struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; | 181 | struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; |
182 | struct timer_list rx_post_retry; | ||
201 | }; | 183 | }; |
202 | 184 | ||
203 | static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) | 185 | static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) |
204 | { | 186 | { |
205 | return ar->hif.priv; | 187 | return (struct ath10k_pci *)ar->drv_priv; |
206 | } | ||
207 | |||
208 | static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) | ||
209 | { | ||
210 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
211 | |||
212 | return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); | ||
213 | } | ||
214 | |||
215 | static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) | ||
216 | { | ||
217 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
218 | |||
219 | iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); | ||
220 | } | 188 | } |
221 | 189 | ||
190 | #define ATH10K_PCI_RX_POST_RETRY_MS 50 | ||
222 | #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ | 191 | #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ |
223 | #define PCIE_WAKE_TIMEOUT 5000 /* 5ms */ | 192 | #define PCIE_WAKE_TIMEOUT 5000 /* 5ms */ |
224 | 193 | ||
@@ -242,35 +211,17 @@ static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) | |||
242 | /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ | 211 | /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ |
243 | #define DIAG_ACCESS_CE_TIMEOUT_MS 10 | 212 | #define DIAG_ACCESS_CE_TIMEOUT_MS 10 |
244 | 213 | ||
245 | /* | 214 | /* Target exposes its registers for direct access. However before host can |
246 | * This API allows the Host to access Target registers directly | 215 | * access them it needs to make sure the target is awake (ath10k_pci_wake, |
247 | * and relatively efficiently over PCIe. | 216 | * ath10k_pci_wake_wait, ath10k_pci_is_awake). Once target is awake it won't go |
248 | * This allows the Host to avoid extra overhead associated with | 217 | * to sleep unless host tells it to (ath10k_pci_sleep). |
249 | * sending a message to firmware and waiting for a response message | ||
250 | * from firmware, as is done on other interconnects. | ||
251 | * | ||
252 | * Yet there is some complexity with direct accesses because the | ||
253 | * Target's power state is not known a priori. The Host must issue | ||
254 | * special PCIe reads/writes in order to explicitly wake the Target | ||
255 | * and to verify that it is awake and will remain awake. | ||
256 | * | ||
257 | * Usage: | ||
258 | * | 218 | * |
259 | * Use ath10k_pci_read32 and ath10k_pci_write32 to access Target space. | 219 | * If host tries to access target registers without waking it up it can |
260 | * These calls must be bracketed by ath10k_pci_wake and | 220 | * scribble over host memory. |
261 | * ath10k_pci_sleep. A single BEGIN/END pair is adequate for | ||
262 | * multiple READ/WRITE operations. | ||
263 | * | 221 | * |
264 | * Use ath10k_pci_wake to put the Target in a state in | 222 | * If target is asleep waking it up may take up to even 2ms. |
265 | * which it is legal for the Host to directly access it. This | ||
266 | * may involve waking the Target from a low power state, which | ||
267 | * may take up to 2Ms! | ||
268 | * | ||
269 | * Use ath10k_pci_sleep to tell the Target that as far as | ||
270 | * this code path is concerned, it no longer needs to remain | ||
271 | * directly accessible. BEGIN/END is under a reference counter; | ||
272 | * multiple code paths may issue BEGIN/END on a single targid. | ||
273 | */ | 223 | */ |
224 | |||
274 | static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, | 225 | static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, |
275 | u32 value) | 226 | u32 value) |
276 | { | 227 | { |
@@ -296,25 +247,18 @@ static inline void ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val) | |||
296 | ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + addr, val); | 247 | ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + addr, val); |
297 | } | 248 | } |
298 | 249 | ||
299 | int ath10k_do_pci_wake(struct ath10k *ar); | 250 | static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) |
300 | void ath10k_do_pci_sleep(struct ath10k *ar); | ||
301 | |||
302 | static inline int ath10k_pci_wake(struct ath10k *ar) | ||
303 | { | 251 | { |
304 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 252 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
305 | 253 | ||
306 | if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) | 254 | return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); |
307 | return ath10k_do_pci_wake(ar); | ||
308 | |||
309 | return 0; | ||
310 | } | 255 | } |
311 | 256 | ||
312 | static inline void ath10k_pci_sleep(struct ath10k *ar) | 257 | static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) |
313 | { | 258 | { |
314 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 259 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
315 | 260 | ||
316 | if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) | 261 | iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); |
317 | ath10k_do_pci_sleep(ar); | ||
318 | } | 262 | } |
319 | 263 | ||
320 | #endif /* _PCI_H_ */ | 264 | #endif /* _PCI_H_ */ |
diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c new file mode 100644 index 000000000000..3e1454b74e00 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/spectral.c | |||
@@ -0,0 +1,561 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Qualcomm Atheros, Inc. | ||
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 | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/relay.h> | ||
18 | #include "core.h" | ||
19 | #include "debug.h" | ||
20 | |||
21 | static void send_fft_sample(struct ath10k *ar, | ||
22 | const struct fft_sample_tlv *fft_sample_tlv) | ||
23 | { | ||
24 | int length; | ||
25 | |||
26 | if (!ar->spectral.rfs_chan_spec_scan) | ||
27 | return; | ||
28 | |||
29 | length = __be16_to_cpu(fft_sample_tlv->length) + | ||
30 | sizeof(*fft_sample_tlv); | ||
31 | relay_write(ar->spectral.rfs_chan_spec_scan, fft_sample_tlv, length); | ||
32 | } | ||
33 | |||
34 | static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len, | ||
35 | u8 *data) | ||
36 | { | ||
37 | int dc_pos; | ||
38 | u8 max_exp; | ||
39 | |||
40 | dc_pos = bin_len / 2; | ||
41 | |||
42 | /* peak index outside of bins */ | ||
43 | if (dc_pos < max_index || -dc_pos >= max_index) | ||
44 | return 0; | ||
45 | |||
46 | for (max_exp = 0; max_exp < 8; max_exp++) { | ||
47 | if (data[dc_pos + max_index] == (max_magnitude >> max_exp)) | ||
48 | break; | ||
49 | } | ||
50 | |||
51 | /* max_exp not found */ | ||
52 | if (data[dc_pos + max_index] != (max_magnitude >> max_exp)) | ||
53 | return 0; | ||
54 | |||
55 | return max_exp; | ||
56 | } | ||
57 | |||
58 | int ath10k_spectral_process_fft(struct ath10k *ar, | ||
59 | struct wmi_single_phyerr_rx_event *event, | ||
60 | struct phyerr_fft_report *fftr, | ||
61 | size_t bin_len, u64 tsf) | ||
62 | { | ||
63 | struct fft_sample_ath10k *fft_sample; | ||
64 | u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS]; | ||
65 | u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag; | ||
66 | u32 reg0, reg1, nf_list1, nf_list2; | ||
67 | u8 chain_idx, *bins; | ||
68 | int dc_pos; | ||
69 | |||
70 | fft_sample = (struct fft_sample_ath10k *)&buf; | ||
71 | |||
72 | if (bin_len < 64 || bin_len > SPECTRAL_ATH10K_MAX_NUM_BINS) | ||
73 | return -EINVAL; | ||
74 | |||
75 | reg0 = __le32_to_cpu(fftr->reg0); | ||
76 | reg1 = __le32_to_cpu(fftr->reg1); | ||
77 | |||
78 | length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + bin_len; | ||
79 | fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH10K; | ||
80 | fft_sample->tlv.length = __cpu_to_be16(length); | ||
81 | |||
82 | /* TODO: there might be a reason why the hardware reports 20/40/80 MHz, | ||
83 | * but the results/plots suggest that its actually 22/44/88 MHz. | ||
84 | */ | ||
85 | switch (event->hdr.chan_width_mhz) { | ||
86 | case 20: | ||
87 | fft_sample->chan_width_mhz = 22; | ||
88 | break; | ||
89 | case 40: | ||
90 | fft_sample->chan_width_mhz = 44; | ||
91 | break; | ||
92 | case 80: | ||
93 | /* TODO: As experiments with an analogue sender and various | ||
94 | * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) | ||
95 | * show, the particular configuration of 80 MHz/64 bins does | ||
96 | * not match with the other smaples at all. Until the reason | ||
97 | * for that is found, don't report these samples. | ||
98 | */ | ||
99 | if (bin_len == 64) | ||
100 | return -EINVAL; | ||
101 | fft_sample->chan_width_mhz = 88; | ||
102 | break; | ||
103 | default: | ||
104 | fft_sample->chan_width_mhz = event->hdr.chan_width_mhz; | ||
105 | } | ||
106 | |||
107 | fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB); | ||
108 | fft_sample->avgpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB); | ||
109 | |||
110 | peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); | ||
111 | fft_sample->max_magnitude = __cpu_to_be16(peak_mag); | ||
112 | fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX); | ||
113 | fft_sample->rssi = event->hdr.rssi_combined; | ||
114 | |||
115 | total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB); | ||
116 | base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB); | ||
117 | fft_sample->total_gain_db = __cpu_to_be16(total_gain_db); | ||
118 | fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db); | ||
119 | |||
120 | freq1 = __le16_to_cpu(event->hdr.freq1); | ||
121 | freq2 = __le16_to_cpu(event->hdr.freq2); | ||
122 | fft_sample->freq1 = __cpu_to_be16(freq1); | ||
123 | fft_sample->freq2 = __cpu_to_be16(freq2); | ||
124 | |||
125 | nf_list1 = __le32_to_cpu(event->hdr.nf_list_1); | ||
126 | nf_list2 = __le32_to_cpu(event->hdr.nf_list_2); | ||
127 | chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX); | ||
128 | |||
129 | switch (chain_idx) { | ||
130 | case 0: | ||
131 | fft_sample->noise = __cpu_to_be16(nf_list1 & 0xffffu); | ||
132 | break; | ||
133 | case 1: | ||
134 | fft_sample->noise = __cpu_to_be16((nf_list1 >> 16) & 0xffffu); | ||
135 | break; | ||
136 | case 2: | ||
137 | fft_sample->noise = __cpu_to_be16(nf_list2 & 0xffffu); | ||
138 | break; | ||
139 | case 3: | ||
140 | fft_sample->noise = __cpu_to_be16((nf_list2 >> 16) & 0xffffu); | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | bins = (u8 *)fftr; | ||
145 | bins += sizeof(*fftr); | ||
146 | |||
147 | fft_sample->tsf = __cpu_to_be64(tsf); | ||
148 | |||
149 | /* max_exp has been directly reported by previous hardware (ath9k), | ||
150 | * maybe its possible to get it by other means? | ||
151 | */ | ||
152 | fft_sample->max_exp = get_max_exp(fft_sample->max_index, peak_mag, | ||
153 | bin_len, bins); | ||
154 | |||
155 | memcpy(fft_sample->data, bins, bin_len); | ||
156 | |||
157 | /* DC value (value in the middle) is the blind spot of the spectral | ||
158 | * sample and invalid, interpolate it. | ||
159 | */ | ||
160 | dc_pos = bin_len / 2; | ||
161 | fft_sample->data[dc_pos] = (fft_sample->data[dc_pos + 1] + | ||
162 | fft_sample->data[dc_pos - 1]) / 2; | ||
163 | |||
164 | send_fft_sample(ar, &fft_sample->tlv); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static struct ath10k_vif *ath10k_get_spectral_vdev(struct ath10k *ar) | ||
170 | { | ||
171 | struct ath10k_vif *arvif; | ||
172 | |||
173 | lockdep_assert_held(&ar->conf_mutex); | ||
174 | |||
175 | if (list_empty(&ar->arvifs)) | ||
176 | return NULL; | ||
177 | |||
178 | /* if there already is a vif doing spectral, return that. */ | ||
179 | list_for_each_entry(arvif, &ar->arvifs, list) | ||
180 | if (arvif->spectral_enabled) | ||
181 | return arvif; | ||
182 | |||
183 | /* otherwise, return the first vif. */ | ||
184 | return list_first_entry(&ar->arvifs, typeof(*arvif), list); | ||
185 | } | ||
186 | |||
187 | static int ath10k_spectral_scan_trigger(struct ath10k *ar) | ||
188 | { | ||
189 | struct ath10k_vif *arvif; | ||
190 | int res; | ||
191 | int vdev_id; | ||
192 | |||
193 | lockdep_assert_held(&ar->conf_mutex); | ||
194 | |||
195 | arvif = ath10k_get_spectral_vdev(ar); | ||
196 | if (!arvif) | ||
197 | return -ENODEV; | ||
198 | vdev_id = arvif->vdev_id; | ||
199 | |||
200 | if (ar->spectral.mode == SPECTRAL_DISABLED) | ||
201 | return 0; | ||
202 | |||
203 | res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, | ||
204 | WMI_SPECTRAL_TRIGGER_CMD_CLEAR, | ||
205 | WMI_SPECTRAL_ENABLE_CMD_ENABLE); | ||
206 | if (res < 0) | ||
207 | return res; | ||
208 | |||
209 | res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, | ||
210 | WMI_SPECTRAL_TRIGGER_CMD_TRIGGER, | ||
211 | WMI_SPECTRAL_ENABLE_CMD_ENABLE); | ||
212 | if (res < 0) | ||
213 | return res; | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int ath10k_spectral_scan_config(struct ath10k *ar, | ||
219 | enum ath10k_spectral_mode mode) | ||
220 | { | ||
221 | struct wmi_vdev_spectral_conf_arg arg; | ||
222 | struct ath10k_vif *arvif; | ||
223 | int vdev_id, count, res = 0; | ||
224 | |||
225 | lockdep_assert_held(&ar->conf_mutex); | ||
226 | |||
227 | arvif = ath10k_get_spectral_vdev(ar); | ||
228 | if (!arvif) | ||
229 | return -ENODEV; | ||
230 | |||
231 | vdev_id = arvif->vdev_id; | ||
232 | |||
233 | arvif->spectral_enabled = (mode != SPECTRAL_DISABLED); | ||
234 | ar->spectral.mode = mode; | ||
235 | |||
236 | res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, | ||
237 | WMI_SPECTRAL_TRIGGER_CMD_CLEAR, | ||
238 | WMI_SPECTRAL_ENABLE_CMD_DISABLE); | ||
239 | if (res < 0) { | ||
240 | ath10k_warn(ar, "failed to enable spectral scan: %d\n", res); | ||
241 | return res; | ||
242 | } | ||
243 | |||
244 | if (mode == SPECTRAL_DISABLED) | ||
245 | return 0; | ||
246 | |||
247 | if (mode == SPECTRAL_BACKGROUND) | ||
248 | count = WMI_SPECTRAL_COUNT_DEFAULT; | ||
249 | else | ||
250 | count = max_t(u8, 1, ar->spectral.config.count); | ||
251 | |||
252 | arg.vdev_id = vdev_id; | ||
253 | arg.scan_count = count; | ||
254 | arg.scan_period = WMI_SPECTRAL_PERIOD_DEFAULT; | ||
255 | arg.scan_priority = WMI_SPECTRAL_PRIORITY_DEFAULT; | ||
256 | arg.scan_fft_size = ar->spectral.config.fft_size; | ||
257 | arg.scan_gc_ena = WMI_SPECTRAL_GC_ENA_DEFAULT; | ||
258 | arg.scan_restart_ena = WMI_SPECTRAL_RESTART_ENA_DEFAULT; | ||
259 | arg.scan_noise_floor_ref = WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT; | ||
260 | arg.scan_init_delay = WMI_SPECTRAL_INIT_DELAY_DEFAULT; | ||
261 | arg.scan_nb_tone_thr = WMI_SPECTRAL_NB_TONE_THR_DEFAULT; | ||
262 | arg.scan_str_bin_thr = WMI_SPECTRAL_STR_BIN_THR_DEFAULT; | ||
263 | arg.scan_wb_rpt_mode = WMI_SPECTRAL_WB_RPT_MODE_DEFAULT; | ||
264 | arg.scan_rssi_rpt_mode = WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT; | ||
265 | arg.scan_rssi_thr = WMI_SPECTRAL_RSSI_THR_DEFAULT; | ||
266 | arg.scan_pwr_format = WMI_SPECTRAL_PWR_FORMAT_DEFAULT; | ||
267 | arg.scan_rpt_mode = WMI_SPECTRAL_RPT_MODE_DEFAULT; | ||
268 | arg.scan_bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; | ||
269 | arg.scan_dbm_adj = WMI_SPECTRAL_DBM_ADJ_DEFAULT; | ||
270 | arg.scan_chn_mask = WMI_SPECTRAL_CHN_MASK_DEFAULT; | ||
271 | |||
272 | res = ath10k_wmi_vdev_spectral_conf(ar, &arg); | ||
273 | if (res < 0) { | ||
274 | ath10k_warn(ar, "failed to configure spectral scan: %d\n", res); | ||
275 | return res; | ||
276 | } | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, | ||
282 | size_t count, loff_t *ppos) | ||
283 | { | ||
284 | struct ath10k *ar = file->private_data; | ||
285 | char *mode = ""; | ||
286 | unsigned int len; | ||
287 | enum ath10k_spectral_mode spectral_mode; | ||
288 | |||
289 | mutex_lock(&ar->conf_mutex); | ||
290 | spectral_mode = ar->spectral.mode; | ||
291 | mutex_unlock(&ar->conf_mutex); | ||
292 | |||
293 | switch (spectral_mode) { | ||
294 | case SPECTRAL_DISABLED: | ||
295 | mode = "disable"; | ||
296 | break; | ||
297 | case SPECTRAL_BACKGROUND: | ||
298 | mode = "background"; | ||
299 | break; | ||
300 | case SPECTRAL_MANUAL: | ||
301 | mode = "manual"; | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | len = strlen(mode); | ||
306 | return simple_read_from_buffer(user_buf, count, ppos, mode, len); | ||
307 | } | ||
308 | |||
309 | static ssize_t write_file_spec_scan_ctl(struct file *file, | ||
310 | const char __user *user_buf, | ||
311 | size_t count, loff_t *ppos) | ||
312 | { | ||
313 | struct ath10k *ar = file->private_data; | ||
314 | char buf[32]; | ||
315 | ssize_t len; | ||
316 | int res; | ||
317 | |||
318 | len = min(count, sizeof(buf) - 1); | ||
319 | if (copy_from_user(buf, user_buf, len)) | ||
320 | return -EFAULT; | ||
321 | |||
322 | buf[len] = '\0'; | ||
323 | |||
324 | mutex_lock(&ar->conf_mutex); | ||
325 | |||
326 | if (strncmp("trigger", buf, 7) == 0) { | ||
327 | if (ar->spectral.mode == SPECTRAL_MANUAL || | ||
328 | ar->spectral.mode == SPECTRAL_BACKGROUND) { | ||
329 | /* reset the configuration to adopt possibly changed | ||
330 | * debugfs parameters | ||
331 | */ | ||
332 | res = ath10k_spectral_scan_config(ar, | ||
333 | ar->spectral.mode); | ||
334 | if (res < 0) { | ||
335 | ath10k_warn(ar, "failed to reconfigure spectral scan: %d\n", | ||
336 | res); | ||
337 | } | ||
338 | res = ath10k_spectral_scan_trigger(ar); | ||
339 | if (res < 0) { | ||
340 | ath10k_warn(ar, "failed to trigger spectral scan: %d\n", | ||
341 | res); | ||
342 | } | ||
343 | } else { | ||
344 | res = -EINVAL; | ||
345 | } | ||
346 | } else if (strncmp("background", buf, 9) == 0) { | ||
347 | res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND); | ||
348 | } else if (strncmp("manual", buf, 6) == 0) { | ||
349 | res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL); | ||
350 | } else if (strncmp("disable", buf, 7) == 0) { | ||
351 | res = ath10k_spectral_scan_config(ar, SPECTRAL_DISABLED); | ||
352 | } else { | ||
353 | res = -EINVAL; | ||
354 | } | ||
355 | |||
356 | mutex_unlock(&ar->conf_mutex); | ||
357 | |||
358 | if (res < 0) | ||
359 | return res; | ||
360 | |||
361 | return count; | ||
362 | } | ||
363 | |||
364 | static const struct file_operations fops_spec_scan_ctl = { | ||
365 | .read = read_file_spec_scan_ctl, | ||
366 | .write = write_file_spec_scan_ctl, | ||
367 | .open = simple_open, | ||
368 | .owner = THIS_MODULE, | ||
369 | .llseek = default_llseek, | ||
370 | }; | ||
371 | |||
372 | static ssize_t read_file_spectral_count(struct file *file, | ||
373 | char __user *user_buf, | ||
374 | size_t count, loff_t *ppos) | ||
375 | { | ||
376 | struct ath10k *ar = file->private_data; | ||
377 | char buf[32]; | ||
378 | unsigned int len; | ||
379 | u8 spectral_count; | ||
380 | |||
381 | mutex_lock(&ar->conf_mutex); | ||
382 | spectral_count = ar->spectral.config.count; | ||
383 | mutex_unlock(&ar->conf_mutex); | ||
384 | |||
385 | len = sprintf(buf, "%d\n", spectral_count); | ||
386 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
387 | } | ||
388 | |||
389 | static ssize_t write_file_spectral_count(struct file *file, | ||
390 | const char __user *user_buf, | ||
391 | size_t count, loff_t *ppos) | ||
392 | { | ||
393 | struct ath10k *ar = file->private_data; | ||
394 | unsigned long val; | ||
395 | char buf[32]; | ||
396 | ssize_t len; | ||
397 | |||
398 | len = min(count, sizeof(buf) - 1); | ||
399 | if (copy_from_user(buf, user_buf, len)) | ||
400 | return -EFAULT; | ||
401 | |||
402 | buf[len] = '\0'; | ||
403 | if (kstrtoul(buf, 0, &val)) | ||
404 | return -EINVAL; | ||
405 | |||
406 | if (val < 0 || val > 255) | ||
407 | return -EINVAL; | ||
408 | |||
409 | mutex_lock(&ar->conf_mutex); | ||
410 | ar->spectral.config.count = val; | ||
411 | mutex_unlock(&ar->conf_mutex); | ||
412 | |||
413 | return count; | ||
414 | } | ||
415 | |||
416 | static const struct file_operations fops_spectral_count = { | ||
417 | .read = read_file_spectral_count, | ||
418 | .write = write_file_spectral_count, | ||
419 | .open = simple_open, | ||
420 | .owner = THIS_MODULE, | ||
421 | .llseek = default_llseek, | ||
422 | }; | ||
423 | |||
424 | static ssize_t read_file_spectral_bins(struct file *file, | ||
425 | char __user *user_buf, | ||
426 | size_t count, loff_t *ppos) | ||
427 | { | ||
428 | struct ath10k *ar = file->private_data; | ||
429 | char buf[32]; | ||
430 | unsigned int len, bins, fft_size, bin_scale; | ||
431 | |||
432 | mutex_lock(&ar->conf_mutex); | ||
433 | |||
434 | fft_size = ar->spectral.config.fft_size; | ||
435 | bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; | ||
436 | bins = 1 << (fft_size - bin_scale); | ||
437 | |||
438 | mutex_unlock(&ar->conf_mutex); | ||
439 | |||
440 | len = sprintf(buf, "%d\n", bins); | ||
441 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
442 | } | ||
443 | |||
444 | static ssize_t write_file_spectral_bins(struct file *file, | ||
445 | const char __user *user_buf, | ||
446 | size_t count, loff_t *ppos) | ||
447 | { | ||
448 | struct ath10k *ar = file->private_data; | ||
449 | unsigned long val; | ||
450 | char buf[32]; | ||
451 | ssize_t len; | ||
452 | |||
453 | len = min(count, sizeof(buf) - 1); | ||
454 | if (copy_from_user(buf, user_buf, len)) | ||
455 | return -EFAULT; | ||
456 | |||
457 | buf[len] = '\0'; | ||
458 | if (kstrtoul(buf, 0, &val)) | ||
459 | return -EINVAL; | ||
460 | |||
461 | if (val < 64 || val > SPECTRAL_ATH10K_MAX_NUM_BINS) | ||
462 | return -EINVAL; | ||
463 | |||
464 | if (!is_power_of_2(val)) | ||
465 | return -EINVAL; | ||
466 | |||
467 | mutex_lock(&ar->conf_mutex); | ||
468 | ar->spectral.config.fft_size = ilog2(val); | ||
469 | ar->spectral.config.fft_size += WMI_SPECTRAL_BIN_SCALE_DEFAULT; | ||
470 | mutex_unlock(&ar->conf_mutex); | ||
471 | |||
472 | return count; | ||
473 | } | ||
474 | |||
475 | static const struct file_operations fops_spectral_bins = { | ||
476 | .read = read_file_spectral_bins, | ||
477 | .write = write_file_spectral_bins, | ||
478 | .open = simple_open, | ||
479 | .owner = THIS_MODULE, | ||
480 | .llseek = default_llseek, | ||
481 | }; | ||
482 | |||
483 | static struct dentry *create_buf_file_handler(const char *filename, | ||
484 | struct dentry *parent, | ||
485 | umode_t mode, | ||
486 | struct rchan_buf *buf, | ||
487 | int *is_global) | ||
488 | { | ||
489 | struct dentry *buf_file; | ||
490 | |||
491 | buf_file = debugfs_create_file(filename, mode, parent, buf, | ||
492 | &relay_file_operations); | ||
493 | *is_global = 1; | ||
494 | return buf_file; | ||
495 | } | ||
496 | |||
497 | static int remove_buf_file_handler(struct dentry *dentry) | ||
498 | { | ||
499 | debugfs_remove(dentry); | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static struct rchan_callbacks rfs_spec_scan_cb = { | ||
505 | .create_buf_file = create_buf_file_handler, | ||
506 | .remove_buf_file = remove_buf_file_handler, | ||
507 | }; | ||
508 | |||
509 | int ath10k_spectral_start(struct ath10k *ar) | ||
510 | { | ||
511 | struct ath10k_vif *arvif; | ||
512 | |||
513 | lockdep_assert_held(&ar->conf_mutex); | ||
514 | |||
515 | list_for_each_entry(arvif, &ar->arvifs, list) | ||
516 | arvif->spectral_enabled = 0; | ||
517 | |||
518 | ar->spectral.mode = SPECTRAL_DISABLED; | ||
519 | ar->spectral.config.count = WMI_SPECTRAL_COUNT_DEFAULT; | ||
520 | ar->spectral.config.fft_size = WMI_SPECTRAL_FFT_SIZE_DEFAULT; | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) | ||
526 | { | ||
527 | if (!arvif->spectral_enabled) | ||
528 | return 0; | ||
529 | |||
530 | return ath10k_spectral_scan_config(arvif->ar, SPECTRAL_DISABLED); | ||
531 | } | ||
532 | |||
533 | int ath10k_spectral_create(struct ath10k *ar) | ||
534 | { | ||
535 | ar->spectral.rfs_chan_spec_scan = relay_open("spectral_scan", | ||
536 | ar->debug.debugfs_phy, | ||
537 | 1024, 256, | ||
538 | &rfs_spec_scan_cb, NULL); | ||
539 | debugfs_create_file("spectral_scan_ctl", | ||
540 | S_IRUSR | S_IWUSR, | ||
541 | ar->debug.debugfs_phy, ar, | ||
542 | &fops_spec_scan_ctl); | ||
543 | debugfs_create_file("spectral_count", | ||
544 | S_IRUSR | S_IWUSR, | ||
545 | ar->debug.debugfs_phy, ar, | ||
546 | &fops_spectral_count); | ||
547 | debugfs_create_file("spectral_bins", | ||
548 | S_IRUSR | S_IWUSR, | ||
549 | ar->debug.debugfs_phy, ar, | ||
550 | &fops_spectral_bins); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | void ath10k_spectral_destroy(struct ath10k *ar) | ||
556 | { | ||
557 | if (ar->spectral.rfs_chan_spec_scan) { | ||
558 | relay_close(ar->spectral.rfs_chan_spec_scan); | ||
559 | ar->spectral.rfs_chan_spec_scan = NULL; | ||
560 | } | ||
561 | } | ||
diff --git a/drivers/net/wireless/ath/ath10k/spectral.h b/drivers/net/wireless/ath/ath10k/spectral.h new file mode 100644 index 000000000000..ddc57c557272 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/spectral.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Qualcomm Atheros, Inc. | ||
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 | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef SPECTRAL_H | ||
18 | #define SPECTRAL_H | ||
19 | |||
20 | #include "../spectral_common.h" | ||
21 | |||
22 | /** | ||
23 | * struct ath10k_spec_scan - parameters for Atheros spectral scan | ||
24 | * | ||
25 | * @count: number of scan results requested for manual mode | ||
26 | * @fft_size: number of bins to be requested = 2^(fft_size - bin_scale) | ||
27 | */ | ||
28 | struct ath10k_spec_scan { | ||
29 | u8 count; | ||
30 | u8 fft_size; | ||
31 | }; | ||
32 | |||
33 | /* enum ath10k_spectral_mode: | ||
34 | * | ||
35 | * @SPECTRAL_DISABLED: spectral mode is disabled | ||
36 | * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with | ||
37 | * something else. | ||
38 | * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples | ||
39 | * is performed manually. | ||
40 | */ | ||
41 | enum ath10k_spectral_mode { | ||
42 | SPECTRAL_DISABLED = 0, | ||
43 | SPECTRAL_BACKGROUND, | ||
44 | SPECTRAL_MANUAL, | ||
45 | }; | ||
46 | |||
47 | #ifdef CONFIG_ATH10K_DEBUGFS | ||
48 | |||
49 | int ath10k_spectral_process_fft(struct ath10k *ar, | ||
50 | struct wmi_single_phyerr_rx_event *event, | ||
51 | struct phyerr_fft_report *fftr, | ||
52 | size_t bin_len, u64 tsf); | ||
53 | int ath10k_spectral_start(struct ath10k *ar); | ||
54 | int ath10k_spectral_vif_stop(struct ath10k_vif *arvif); | ||
55 | int ath10k_spectral_create(struct ath10k *ar); | ||
56 | void ath10k_spectral_destroy(struct ath10k *ar); | ||
57 | |||
58 | #else | ||
59 | |||
60 | static inline int | ||
61 | ath10k_spectral_process_fft(struct ath10k *ar, | ||
62 | struct wmi_single_phyerr_rx_event *event, | ||
63 | struct phyerr_fft_report *fftr, | ||
64 | size_t bin_len, u64 tsf) | ||
65 | { | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static inline int ath10k_spectral_start(struct ath10k *ar) | ||
70 | { | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static inline int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static inline int ath10k_spectral_create(struct ath10k *ar) | ||
80 | { | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static inline void ath10k_spectral_destroy(struct ath10k *ar) | ||
85 | { | ||
86 | } | ||
87 | |||
88 | #endif /* CONFIG_ATH10K_DEBUGFS */ | ||
89 | |||
90 | #endif /* SPECTRAL_H */ | ||
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index f4fa22d1d591..2eeec8a63d5c 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c | |||
@@ -32,14 +32,14 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb) | |||
32 | * offchan_tx_skb. */ | 32 | * offchan_tx_skb. */ |
33 | spin_lock_bh(&ar->data_lock); | 33 | spin_lock_bh(&ar->data_lock); |
34 | if (ar->offchan_tx_skb != skb) { | 34 | if (ar->offchan_tx_skb != skb) { |
35 | ath10k_warn("completed old offchannel frame\n"); | 35 | ath10k_warn(ar, "completed old offchannel frame\n"); |
36 | goto out; | 36 | goto out; |
37 | } | 37 | } |
38 | 38 | ||
39 | complete(&ar->offchan_tx_completed); | 39 | complete(&ar->offchan_tx_completed); |
40 | ar->offchan_tx_skb = NULL; /* just for sanity */ | 40 | ar->offchan_tx_skb = NULL; /* just for sanity */ |
41 | 41 | ||
42 | ath10k_dbg(ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb); | 42 | ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb); |
43 | out: | 43 | out: |
44 | spin_unlock_bh(&ar->data_lock); | 44 | spin_unlock_bh(&ar->data_lock); |
45 | } | 45 | } |
@@ -47,18 +47,19 @@ out: | |||
47 | void ath10k_txrx_tx_unref(struct ath10k_htt *htt, | 47 | void ath10k_txrx_tx_unref(struct ath10k_htt *htt, |
48 | const struct htt_tx_done *tx_done) | 48 | const struct htt_tx_done *tx_done) |
49 | { | 49 | { |
50 | struct device *dev = htt->ar->dev; | 50 | struct ath10k *ar = htt->ar; |
51 | struct device *dev = ar->dev; | ||
51 | struct ieee80211_tx_info *info; | 52 | struct ieee80211_tx_info *info; |
52 | struct ath10k_skb_cb *skb_cb; | 53 | struct ath10k_skb_cb *skb_cb; |
53 | struct sk_buff *msdu; | 54 | struct sk_buff *msdu; |
54 | 55 | ||
55 | lockdep_assert_held(&htt->tx_lock); | 56 | lockdep_assert_held(&htt->tx_lock); |
56 | 57 | ||
57 | ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", | 58 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", |
58 | tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack); | 59 | tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack); |
59 | 60 | ||
60 | if (tx_done->msdu_id >= htt->max_num_pending_tx) { | 61 | if (tx_done->msdu_id >= htt->max_num_pending_tx) { |
61 | ath10k_warn("warning: msdu_id %d too big, ignoring\n", | 62 | ath10k_warn(ar, "warning: msdu_id %d too big, ignoring\n", |
62 | tx_done->msdu_id); | 63 | tx_done->msdu_id); |
63 | return; | 64 | return; |
64 | } | 65 | } |
@@ -182,7 +183,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt, | |||
182 | wake_up(&ar->peer_mapping_wq); | 183 | wake_up(&ar->peer_mapping_wq); |
183 | } | 184 | } |
184 | 185 | ||
185 | ath10k_dbg(ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", | 186 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", |
186 | ev->vdev_id, ev->addr, ev->peer_id); | 187 | ev->vdev_id, ev->addr, ev->peer_id); |
187 | 188 | ||
188 | set_bit(ev->peer_id, peer->peer_ids); | 189 | set_bit(ev->peer_id, peer->peer_ids); |
@@ -199,12 +200,12 @@ void ath10k_peer_unmap_event(struct ath10k_htt *htt, | |||
199 | spin_lock_bh(&ar->data_lock); | 200 | spin_lock_bh(&ar->data_lock); |
200 | peer = ath10k_peer_find_by_id(ar, ev->peer_id); | 201 | peer = ath10k_peer_find_by_id(ar, ev->peer_id); |
201 | if (!peer) { | 202 | if (!peer) { |
202 | ath10k_warn("peer-unmap-event: unknown peer id %d\n", | 203 | ath10k_warn(ar, "peer-unmap-event: unknown peer id %d\n", |
203 | ev->peer_id); | 204 | ev->peer_id); |
204 | goto exit; | 205 | goto exit; |
205 | } | 206 | } |
206 | 207 | ||
207 | ath10k_dbg(ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n", | 208 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n", |
208 | peer->vdev_id, peer->addr, ev->peer_id); | 209 | peer->vdev_id, peer->addr, ev->peer_id); |
209 | 210 | ||
210 | clear_bit(ev->peer_id, peer->peer_ids); | 211 | clear_bit(ev->peer_id, peer->peer_ids); |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c2c87c916b5a..e500a3cc905e 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -487,6 +487,127 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { | |||
487 | .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, | 487 | .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, |
488 | }; | 488 | }; |
489 | 489 | ||
490 | /* firmware 10.2 specific mappings */ | ||
491 | static struct wmi_cmd_map wmi_10_2_cmd_map = { | ||
492 | .init_cmdid = WMI_10_2_INIT_CMDID, | ||
493 | .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, | ||
494 | .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, | ||
495 | .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, | ||
496 | .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, | ||
497 | .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, | ||
498 | .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, | ||
499 | .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, | ||
500 | .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, | ||
501 | .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, | ||
502 | .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, | ||
503 | .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, | ||
504 | .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, | ||
505 | .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, | ||
506 | .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, | ||
507 | .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, | ||
508 | .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, | ||
509 | .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, | ||
510 | .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, | ||
511 | .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, | ||
512 | .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, | ||
513 | .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, | ||
514 | .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, | ||
515 | .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, | ||
516 | .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, | ||
517 | .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, | ||
518 | .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, | ||
519 | .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, | ||
520 | .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, | ||
521 | .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, | ||
522 | .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, | ||
523 | .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, | ||
524 | .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, | ||
525 | .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, | ||
526 | .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, | ||
527 | .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, | ||
528 | .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, | ||
529 | .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, | ||
530 | .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, | ||
531 | .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, | ||
532 | .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, | ||
533 | .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, | ||
534 | .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, | ||
535 | .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, | ||
536 | .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, | ||
537 | .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, | ||
538 | .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, | ||
539 | .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, | ||
540 | .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, | ||
541 | .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, | ||
542 | .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, | ||
543 | .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, | ||
544 | .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, | ||
545 | .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, | ||
546 | .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, | ||
547 | .roam_scan_rssi_change_threshold = | ||
548 | WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, | ||
549 | .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, | ||
550 | .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, | ||
551 | .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, | ||
552 | .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, | ||
553 | .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, | ||
554 | .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, | ||
555 | .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, | ||
556 | .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, | ||
557 | .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, | ||
558 | .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, | ||
559 | .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, | ||
560 | .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, | ||
561 | .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, | ||
562 | .wlan_profile_set_hist_intvl_cmdid = | ||
563 | WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, | ||
564 | .wlan_profile_get_profile_data_cmdid = | ||
565 | WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, | ||
566 | .wlan_profile_enable_profile_id_cmdid = | ||
567 | WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, | ||
568 | .wlan_profile_list_profile_id_cmdid = | ||
569 | WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, | ||
570 | .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, | ||
571 | .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, | ||
572 | .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, | ||
573 | .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, | ||
574 | .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, | ||
575 | .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, | ||
576 | .wow_enable_disable_wake_event_cmdid = | ||
577 | WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, | ||
578 | .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, | ||
579 | .wow_hostwakeup_from_sleep_cmdid = | ||
580 | WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, | ||
581 | .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, | ||
582 | .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, | ||
583 | .vdev_spectral_scan_configure_cmdid = | ||
584 | WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, | ||
585 | .vdev_spectral_scan_enable_cmdid = | ||
586 | WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, | ||
587 | .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, | ||
588 | .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, | ||
589 | .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, | ||
590 | .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, | ||
591 | .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, | ||
592 | .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, | ||
593 | .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, | ||
594 | .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, | ||
595 | .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, | ||
596 | .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, | ||
597 | .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, | ||
598 | .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, | ||
599 | .echo_cmdid = WMI_10_2_ECHO_CMDID, | ||
600 | .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, | ||
601 | .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, | ||
602 | .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, | ||
603 | .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, | ||
604 | .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, | ||
605 | .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, | ||
606 | .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, | ||
607 | .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, | ||
608 | .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, | ||
609 | }; | ||
610 | |||
490 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) | 611 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) |
491 | { | 612 | { |
492 | int ret; | 613 | int ret; |
@@ -503,18 +624,18 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) | |||
503 | return ret; | 624 | return ret; |
504 | } | 625 | } |
505 | 626 | ||
506 | static struct sk_buff *ath10k_wmi_alloc_skb(u32 len) | 627 | static struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) |
507 | { | 628 | { |
508 | struct sk_buff *skb; | 629 | struct sk_buff *skb; |
509 | u32 round_len = roundup(len, 4); | 630 | u32 round_len = roundup(len, 4); |
510 | 631 | ||
511 | skb = ath10k_htc_alloc_skb(WMI_SKB_HEADROOM + round_len); | 632 | skb = ath10k_htc_alloc_skb(ar, WMI_SKB_HEADROOM + round_len); |
512 | if (!skb) | 633 | if (!skb) |
513 | return NULL; | 634 | return NULL; |
514 | 635 | ||
515 | skb_reserve(skb, WMI_SKB_HEADROOM); | 636 | skb_reserve(skb, WMI_SKB_HEADROOM); |
516 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) | 637 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) |
517 | ath10k_warn("Unaligned WMI skb\n"); | 638 | ath10k_warn(ar, "Unaligned WMI skb\n"); |
518 | 639 | ||
519 | skb_put(skb, round_len); | 640 | skb_put(skb, round_len); |
520 | memset(skb->data, 0, round_len); | 641 | memset(skb->data, 0, round_len); |
@@ -612,7 +733,7 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, | |||
612 | might_sleep(); | 733 | might_sleep(); |
613 | 734 | ||
614 | if (cmd_id == WMI_CMD_UNSUPPORTED) { | 735 | if (cmd_id == WMI_CMD_UNSUPPORTED) { |
615 | ath10k_warn("wmi command %d is not supported by firmware\n", | 736 | ath10k_warn(ar, "wmi command %d is not supported by firmware\n", |
616 | cmd_id); | 737 | cmd_id); |
617 | return ret; | 738 | return ret; |
618 | } | 739 | } |
@@ -660,7 +781,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
660 | 781 | ||
661 | len = round_up(len, 4); | 782 | len = round_up(len, 4); |
662 | 783 | ||
663 | wmi_skb = ath10k_wmi_alloc_skb(len); | 784 | wmi_skb = ath10k_wmi_alloc_skb(ar, len); |
664 | if (!wmi_skb) | 785 | if (!wmi_skb) |
665 | return -ENOMEM; | 786 | return -ENOMEM; |
666 | 787 | ||
@@ -674,7 +795,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
674 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); | 795 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); |
675 | memcpy(cmd->buf, skb->data, skb->len); | 796 | memcpy(cmd->buf, skb->data, skb->len); |
676 | 797 | ||
677 | ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", | 798 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", |
678 | wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, | 799 | wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, |
679 | fc & IEEE80211_FCTL_STYPE); | 800 | fc & IEEE80211_FCTL_STYPE); |
680 | 801 | ||
@@ -690,6 +811,130 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
690 | return ret; | 811 | return ret; |
691 | } | 812 | } |
692 | 813 | ||
814 | static void ath10k_wmi_event_scan_started(struct ath10k *ar) | ||
815 | { | ||
816 | lockdep_assert_held(&ar->data_lock); | ||
817 | |||
818 | switch (ar->scan.state) { | ||
819 | case ATH10K_SCAN_IDLE: | ||
820 | case ATH10K_SCAN_RUNNING: | ||
821 | case ATH10K_SCAN_ABORTING: | ||
822 | ath10k_warn(ar, "received scan started event in an invalid scan state: %s (%d)\n", | ||
823 | ath10k_scan_state_str(ar->scan.state), | ||
824 | ar->scan.state); | ||
825 | break; | ||
826 | case ATH10K_SCAN_STARTING: | ||
827 | ar->scan.state = ATH10K_SCAN_RUNNING; | ||
828 | |||
829 | if (ar->scan.is_roc) | ||
830 | ieee80211_ready_on_channel(ar->hw); | ||
831 | |||
832 | complete(&ar->scan.started); | ||
833 | break; | ||
834 | } | ||
835 | } | ||
836 | |||
837 | static void ath10k_wmi_event_scan_completed(struct ath10k *ar) | ||
838 | { | ||
839 | lockdep_assert_held(&ar->data_lock); | ||
840 | |||
841 | switch (ar->scan.state) { | ||
842 | case ATH10K_SCAN_IDLE: | ||
843 | case ATH10K_SCAN_STARTING: | ||
844 | /* One suspected reason scan can be completed while starting is | ||
845 | * if firmware fails to deliver all scan events to the host, | ||
846 | * e.g. when transport pipe is full. This has been observed | ||
847 | * with spectral scan phyerr events starving wmi transport | ||
848 | * pipe. In such case the "scan completed" event should be (and | ||
849 | * is) ignored by the host as it may be just firmware's scan | ||
850 | * state machine recovering. | ||
851 | */ | ||
852 | ath10k_warn(ar, "received scan completed event in an invalid scan state: %s (%d)\n", | ||
853 | ath10k_scan_state_str(ar->scan.state), | ||
854 | ar->scan.state); | ||
855 | break; | ||
856 | case ATH10K_SCAN_RUNNING: | ||
857 | case ATH10K_SCAN_ABORTING: | ||
858 | __ath10k_scan_finish(ar); | ||
859 | break; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | static void ath10k_wmi_event_scan_bss_chan(struct ath10k *ar) | ||
864 | { | ||
865 | lockdep_assert_held(&ar->data_lock); | ||
866 | |||
867 | switch (ar->scan.state) { | ||
868 | case ATH10K_SCAN_IDLE: | ||
869 | case ATH10K_SCAN_STARTING: | ||
870 | ath10k_warn(ar, "received scan bss chan event in an invalid scan state: %s (%d)\n", | ||
871 | ath10k_scan_state_str(ar->scan.state), | ||
872 | ar->scan.state); | ||
873 | break; | ||
874 | case ATH10K_SCAN_RUNNING: | ||
875 | case ATH10K_SCAN_ABORTING: | ||
876 | ar->scan_channel = NULL; | ||
877 | break; | ||
878 | } | ||
879 | } | ||
880 | |||
881 | static void ath10k_wmi_event_scan_foreign_chan(struct ath10k *ar, u32 freq) | ||
882 | { | ||
883 | lockdep_assert_held(&ar->data_lock); | ||
884 | |||
885 | switch (ar->scan.state) { | ||
886 | case ATH10K_SCAN_IDLE: | ||
887 | case ATH10K_SCAN_STARTING: | ||
888 | ath10k_warn(ar, "received scan foreign chan event in an invalid scan state: %s (%d)\n", | ||
889 | ath10k_scan_state_str(ar->scan.state), | ||
890 | ar->scan.state); | ||
891 | break; | ||
892 | case ATH10K_SCAN_RUNNING: | ||
893 | case ATH10K_SCAN_ABORTING: | ||
894 | ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); | ||
895 | |||
896 | if (ar->scan.is_roc && ar->scan.roc_freq == freq) | ||
897 | complete(&ar->scan.on_channel); | ||
898 | break; | ||
899 | } | ||
900 | } | ||
901 | |||
902 | static const char * | ||
903 | ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, | ||
904 | enum wmi_scan_completion_reason reason) | ||
905 | { | ||
906 | switch (type) { | ||
907 | case WMI_SCAN_EVENT_STARTED: | ||
908 | return "started"; | ||
909 | case WMI_SCAN_EVENT_COMPLETED: | ||
910 | switch (reason) { | ||
911 | case WMI_SCAN_REASON_COMPLETED: | ||
912 | return "completed"; | ||
913 | case WMI_SCAN_REASON_CANCELLED: | ||
914 | return "completed [cancelled]"; | ||
915 | case WMI_SCAN_REASON_PREEMPTED: | ||
916 | return "completed [preempted]"; | ||
917 | case WMI_SCAN_REASON_TIMEDOUT: | ||
918 | return "completed [timedout]"; | ||
919 | case WMI_SCAN_REASON_MAX: | ||
920 | break; | ||
921 | } | ||
922 | return "completed [unknown]"; | ||
923 | case WMI_SCAN_EVENT_BSS_CHANNEL: | ||
924 | return "bss channel"; | ||
925 | case WMI_SCAN_EVENT_FOREIGN_CHANNEL: | ||
926 | return "foreign channel"; | ||
927 | case WMI_SCAN_EVENT_DEQUEUED: | ||
928 | return "dequeued"; | ||
929 | case WMI_SCAN_EVENT_PREEMPTED: | ||
930 | return "preempted"; | ||
931 | case WMI_SCAN_EVENT_START_FAILED: | ||
932 | return "start failed"; | ||
933 | default: | ||
934 | return "unknown"; | ||
935 | } | ||
936 | } | ||
937 | |||
693 | static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) | 938 | static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) |
694 | { | 939 | { |
695 | struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; | 940 | struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; |
@@ -707,81 +952,32 @@ static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) | |||
707 | scan_id = __le32_to_cpu(event->scan_id); | 952 | scan_id = __le32_to_cpu(event->scan_id); |
708 | vdev_id = __le32_to_cpu(event->vdev_id); | 953 | vdev_id = __le32_to_cpu(event->vdev_id); |
709 | 954 | ||
710 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENTID\n"); | ||
711 | ath10k_dbg(ATH10K_DBG_WMI, | ||
712 | "scan event type %d reason %d freq %d req_id %d " | ||
713 | "scan_id %d vdev_id %d\n", | ||
714 | event_type, reason, freq, req_id, scan_id, vdev_id); | ||
715 | |||
716 | spin_lock_bh(&ar->data_lock); | 955 | spin_lock_bh(&ar->data_lock); |
717 | 956 | ||
957 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
958 | "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n", | ||
959 | ath10k_wmi_event_scan_type_str(event_type, reason), | ||
960 | event_type, reason, freq, req_id, scan_id, vdev_id, | ||
961 | ath10k_scan_state_str(ar->scan.state), ar->scan.state); | ||
962 | |||
718 | switch (event_type) { | 963 | switch (event_type) { |
719 | case WMI_SCAN_EVENT_STARTED: | 964 | case WMI_SCAN_EVENT_STARTED: |
720 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_STARTED\n"); | 965 | ath10k_wmi_event_scan_started(ar); |
721 | if (ar->scan.in_progress && ar->scan.is_roc) | ||
722 | ieee80211_ready_on_channel(ar->hw); | ||
723 | |||
724 | complete(&ar->scan.started); | ||
725 | break; | 966 | break; |
726 | case WMI_SCAN_EVENT_COMPLETED: | 967 | case WMI_SCAN_EVENT_COMPLETED: |
727 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_COMPLETED\n"); | 968 | ath10k_wmi_event_scan_completed(ar); |
728 | switch (reason) { | ||
729 | case WMI_SCAN_REASON_COMPLETED: | ||
730 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_COMPLETED\n"); | ||
731 | break; | ||
732 | case WMI_SCAN_REASON_CANCELLED: | ||
733 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_CANCELED\n"); | ||
734 | break; | ||
735 | case WMI_SCAN_REASON_PREEMPTED: | ||
736 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_PREEMPTED\n"); | ||
737 | break; | ||
738 | case WMI_SCAN_REASON_TIMEDOUT: | ||
739 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_TIMEDOUT\n"); | ||
740 | break; | ||
741 | default: | ||
742 | break; | ||
743 | } | ||
744 | |||
745 | ar->scan_channel = NULL; | ||
746 | if (!ar->scan.in_progress) { | ||
747 | ath10k_warn("no scan requested, ignoring\n"); | ||
748 | break; | ||
749 | } | ||
750 | |||
751 | if (ar->scan.is_roc) { | ||
752 | ath10k_offchan_tx_purge(ar); | ||
753 | |||
754 | if (!ar->scan.aborting) | ||
755 | ieee80211_remain_on_channel_expired(ar->hw); | ||
756 | } else { | ||
757 | ieee80211_scan_completed(ar->hw, ar->scan.aborting); | ||
758 | } | ||
759 | |||
760 | del_timer(&ar->scan.timeout); | ||
761 | complete_all(&ar->scan.completed); | ||
762 | ar->scan.in_progress = false; | ||
763 | break; | 969 | break; |
764 | case WMI_SCAN_EVENT_BSS_CHANNEL: | 970 | case WMI_SCAN_EVENT_BSS_CHANNEL: |
765 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_BSS_CHANNEL\n"); | 971 | ath10k_wmi_event_scan_bss_chan(ar); |
766 | ar->scan_channel = NULL; | ||
767 | break; | 972 | break; |
768 | case WMI_SCAN_EVENT_FOREIGN_CHANNEL: | 973 | case WMI_SCAN_EVENT_FOREIGN_CHANNEL: |
769 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_FOREIGN_CHANNEL\n"); | 974 | ath10k_wmi_event_scan_foreign_chan(ar, freq); |
770 | ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); | ||
771 | if (ar->scan.in_progress && ar->scan.is_roc && | ||
772 | ar->scan.roc_freq == freq) { | ||
773 | complete(&ar->scan.on_channel); | ||
774 | } | ||
775 | break; | ||
776 | case WMI_SCAN_EVENT_DEQUEUED: | ||
777 | ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_DEQUEUED\n"); | ||
778 | break; | ||
779 | case WMI_SCAN_EVENT_PREEMPTED: | ||
780 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_PREEMPTED\n"); | ||
781 | break; | 975 | break; |
782 | case WMI_SCAN_EVENT_START_FAILED: | 976 | case WMI_SCAN_EVENT_START_FAILED: |
783 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_START_FAILED\n"); | 977 | ath10k_warn(ar, "received scan start failure event\n"); |
784 | break; | 978 | break; |
979 | case WMI_SCAN_EVENT_DEQUEUED: | ||
980 | case WMI_SCAN_EVENT_PREEMPTED: | ||
785 | default: | 981 | default: |
786 | break; | 982 | break; |
787 | } | 983 | } |
@@ -911,7 +1107,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
911 | 1107 | ||
912 | memset(status, 0, sizeof(*status)); | 1108 | memset(status, 0, sizeof(*status)); |
913 | 1109 | ||
914 | ath10k_dbg(ATH10K_DBG_MGMT, | 1110 | ath10k_dbg(ar, ATH10K_DBG_MGMT, |
915 | "event mgmt rx status %08x\n", rx_status); | 1111 | "event mgmt rx status %08x\n", rx_status); |
916 | 1112 | ||
917 | if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { | 1113 | if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { |
@@ -947,9 +1143,9 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
947 | 1143 | ||
948 | if (phy_mode == MODE_11B && | 1144 | if (phy_mode == MODE_11B && |
949 | status->band == IEEE80211_BAND_5GHZ) | 1145 | status->band == IEEE80211_BAND_5GHZ) |
950 | ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); | 1146 | ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); |
951 | } else { | 1147 | } else { |
952 | ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n"); | 1148 | ath10k_warn(ar, "using (unreliable) phy_mode to extract band for mgmt rx\n"); |
953 | status->band = phy_mode_to_band(phy_mode); | 1149 | status->band = phy_mode_to_band(phy_mode); |
954 | } | 1150 | } |
955 | 1151 | ||
@@ -979,12 +1175,12 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
979 | } | 1175 | } |
980 | } | 1176 | } |
981 | 1177 | ||
982 | ath10k_dbg(ATH10K_DBG_MGMT, | 1178 | ath10k_dbg(ar, ATH10K_DBG_MGMT, |
983 | "event mgmt rx skb %p len %d ftype %02x stype %02x\n", | 1179 | "event mgmt rx skb %p len %d ftype %02x stype %02x\n", |
984 | skb, skb->len, | 1180 | skb, skb->len, |
985 | fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); | 1181 | fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); |
986 | 1182 | ||
987 | ath10k_dbg(ATH10K_DBG_MGMT, | 1183 | ath10k_dbg(ar, ATH10K_DBG_MGMT, |
988 | "event mgmt rx freq %d band %d snr %d, rate_idx %d\n", | 1184 | "event mgmt rx freq %d band %d snr %d, rate_idx %d\n", |
989 | status->freq, status->band, status->signal, | 1185 | status->freq, status->band, status->signal, |
990 | status->rate_idx); | 1186 | status->rate_idx); |
@@ -1034,21 +1230,26 @@ static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) | |||
1034 | rx_clear_count = __le32_to_cpu(ev->rx_clear_count); | 1230 | rx_clear_count = __le32_to_cpu(ev->rx_clear_count); |
1035 | cycle_count = __le32_to_cpu(ev->cycle_count); | 1231 | cycle_count = __le32_to_cpu(ev->cycle_count); |
1036 | 1232 | ||
1037 | ath10k_dbg(ATH10K_DBG_WMI, | 1233 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
1038 | "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n", | 1234 | "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n", |
1039 | err_code, freq, cmd_flags, noise_floor, rx_clear_count, | 1235 | err_code, freq, cmd_flags, noise_floor, rx_clear_count, |
1040 | cycle_count); | 1236 | cycle_count); |
1041 | 1237 | ||
1042 | spin_lock_bh(&ar->data_lock); | 1238 | spin_lock_bh(&ar->data_lock); |
1043 | 1239 | ||
1044 | if (!ar->scan.in_progress) { | 1240 | switch (ar->scan.state) { |
1045 | ath10k_warn("chan info event without a scan request?\n"); | 1241 | case ATH10K_SCAN_IDLE: |
1242 | case ATH10K_SCAN_STARTING: | ||
1243 | ath10k_warn(ar, "received chan info event without a scan request, ignoring\n"); | ||
1046 | goto exit; | 1244 | goto exit; |
1245 | case ATH10K_SCAN_RUNNING: | ||
1246 | case ATH10K_SCAN_ABORTING: | ||
1247 | break; | ||
1047 | } | 1248 | } |
1048 | 1249 | ||
1049 | idx = freq_to_idx(ar, freq); | 1250 | idx = freq_to_idx(ar, freq); |
1050 | if (idx >= ARRAY_SIZE(ar->survey)) { | 1251 | if (idx >= ARRAY_SIZE(ar->survey)) { |
1051 | ath10k_warn("chan info: invalid frequency %d (idx %d out of bounds)\n", | 1252 | ath10k_warn(ar, "chan info: invalid frequency %d (idx %d out of bounds)\n", |
1052 | freq, idx); | 1253 | freq, idx); |
1053 | goto exit; | 1254 | goto exit; |
1054 | } | 1255 | } |
@@ -1079,12 +1280,12 @@ exit: | |||
1079 | 1280 | ||
1080 | static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) | 1281 | static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) |
1081 | { | 1282 | { |
1082 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); | 1283 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); |
1083 | } | 1284 | } |
1084 | 1285 | ||
1085 | static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) | 1286 | static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) |
1086 | { | 1287 | { |
1087 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", | 1288 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", |
1088 | skb->len); | 1289 | skb->len); |
1089 | 1290 | ||
1090 | trace_ath10k_wmi_dbglog(skb->data, skb->len); | 1291 | trace_ath10k_wmi_dbglog(skb->data, skb->len); |
@@ -1097,7 +1298,7 @@ static void ath10k_wmi_event_update_stats(struct ath10k *ar, | |||
1097 | { | 1298 | { |
1098 | struct wmi_stats_event *ev = (struct wmi_stats_event *)skb->data; | 1299 | struct wmi_stats_event *ev = (struct wmi_stats_event *)skb->data; |
1099 | 1300 | ||
1100 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); | 1301 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); |
1101 | 1302 | ||
1102 | ath10k_debug_read_target_stats(ar, ev); | 1303 | ath10k_debug_read_target_stats(ar, ev); |
1103 | } | 1304 | } |
@@ -1107,7 +1308,7 @@ static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, | |||
1107 | { | 1308 | { |
1108 | struct wmi_vdev_start_response_event *ev; | 1309 | struct wmi_vdev_start_response_event *ev; |
1109 | 1310 | ||
1110 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); | 1311 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); |
1111 | 1312 | ||
1112 | ev = (struct wmi_vdev_start_response_event *)skb->data; | 1313 | ev = (struct wmi_vdev_start_response_event *)skb->data; |
1113 | 1314 | ||
@@ -1120,7 +1321,7 @@ static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, | |||
1120 | static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, | 1321 | static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, |
1121 | struct sk_buff *skb) | 1322 | struct sk_buff *skb) |
1122 | { | 1323 | { |
1123 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); | 1324 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); |
1124 | complete(&ar->vdev_setup_done); | 1325 | complete(&ar->vdev_setup_done); |
1125 | } | 1326 | } |
1126 | 1327 | ||
@@ -1132,14 +1333,14 @@ static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, | |||
1132 | 1333 | ||
1133 | ev = (struct wmi_peer_sta_kickout_event *)skb->data; | 1334 | ev = (struct wmi_peer_sta_kickout_event *)skb->data; |
1134 | 1335 | ||
1135 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", | 1336 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", |
1136 | ev->peer_macaddr.addr); | 1337 | ev->peer_macaddr.addr); |
1137 | 1338 | ||
1138 | rcu_read_lock(); | 1339 | rcu_read_lock(); |
1139 | 1340 | ||
1140 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); | 1341 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); |
1141 | if (!sta) { | 1342 | if (!sta) { |
1142 | ath10k_warn("Spurious quick kickout for STA %pM\n", | 1343 | ath10k_warn(ar, "Spurious quick kickout for STA %pM\n", |
1143 | ev->peer_macaddr.addr); | 1344 | ev->peer_macaddr.addr); |
1144 | goto exit; | 1345 | goto exit; |
1145 | } | 1346 | } |
@@ -1216,7 +1417,7 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, | |||
1216 | (u8 *)skb_tail_pointer(bcn) - ies); | 1417 | (u8 *)skb_tail_pointer(bcn) - ies); |
1217 | if (!ie) { | 1418 | if (!ie) { |
1218 | if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS) | 1419 | if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS) |
1219 | ath10k_warn("no tim ie found;\n"); | 1420 | ath10k_warn(ar, "no tim ie found;\n"); |
1220 | return; | 1421 | return; |
1221 | } | 1422 | } |
1222 | 1423 | ||
@@ -1236,12 +1437,12 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, | |||
1236 | ie_len += expand_size; | 1437 | ie_len += expand_size; |
1237 | pvm_len += expand_size; | 1438 | pvm_len += expand_size; |
1238 | } else { | 1439 | } else { |
1239 | ath10k_warn("tim expansion failed\n"); | 1440 | ath10k_warn(ar, "tim expansion failed\n"); |
1240 | } | 1441 | } |
1241 | } | 1442 | } |
1242 | 1443 | ||
1243 | if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) { | 1444 | if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) { |
1244 | ath10k_warn("tim pvm length is too great (%d)\n", pvm_len); | 1445 | ath10k_warn(ar, "tim pvm length is too great (%d)\n", pvm_len); |
1245 | return; | 1446 | return; |
1246 | } | 1447 | } |
1247 | 1448 | ||
@@ -1255,7 +1456,7 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, | |||
1255 | ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; | 1456 | ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; |
1256 | } | 1457 | } |
1257 | 1458 | ||
1258 | ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", | 1459 | ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", |
1259 | tim->dtim_count, tim->dtim_period, | 1460 | tim->dtim_count, tim->dtim_period, |
1260 | tim->bitmap_ctrl, pvm_len); | 1461 | tim->bitmap_ctrl, pvm_len); |
1261 | } | 1462 | } |
@@ -1333,7 +1534,7 @@ static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1333 | if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) | 1534 | if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) |
1334 | return; | 1535 | return; |
1335 | 1536 | ||
1336 | ath10k_dbg(ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); | 1537 | ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); |
1337 | if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) { | 1538 | if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) { |
1338 | new_len = ath10k_p2p_calc_noa_ie_len(noa); | 1539 | new_len = ath10k_p2p_calc_noa_ie_len(noa); |
1339 | if (!new_len) | 1540 | if (!new_len) |
@@ -1381,7 +1582,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1381 | ev = (struct wmi_host_swba_event *)skb->data; | 1582 | ev = (struct wmi_host_swba_event *)skb->data; |
1382 | map = __le32_to_cpu(ev->vdev_map); | 1583 | map = __le32_to_cpu(ev->vdev_map); |
1383 | 1584 | ||
1384 | ath10k_dbg(ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", | 1585 | ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", |
1385 | ev->vdev_map); | 1586 | ev->vdev_map); |
1386 | 1587 | ||
1387 | for (; map; map >>= 1, vdev_id++) { | 1588 | for (; map; map >>= 1, vdev_id++) { |
@@ -1391,13 +1592,13 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1391 | i++; | 1592 | i++; |
1392 | 1593 | ||
1393 | if (i >= WMI_MAX_AP_VDEV) { | 1594 | if (i >= WMI_MAX_AP_VDEV) { |
1394 | ath10k_warn("swba has corrupted vdev map\n"); | 1595 | ath10k_warn(ar, "swba has corrupted vdev map\n"); |
1395 | break; | 1596 | break; |
1396 | } | 1597 | } |
1397 | 1598 | ||
1398 | bcn_info = &ev->bcn_info[i]; | 1599 | bcn_info = &ev->bcn_info[i]; |
1399 | 1600 | ||
1400 | ath10k_dbg(ATH10K_DBG_MGMT, | 1601 | ath10k_dbg(ar, ATH10K_DBG_MGMT, |
1401 | "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n", | 1602 | "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n", |
1402 | i, | 1603 | i, |
1403 | __le32_to_cpu(bcn_info->tim_info.tim_len), | 1604 | __le32_to_cpu(bcn_info->tim_info.tim_len), |
@@ -1411,7 +1612,8 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1411 | 1612 | ||
1412 | arvif = ath10k_get_arvif(ar, vdev_id); | 1613 | arvif = ath10k_get_arvif(ar, vdev_id); |
1413 | if (arvif == NULL) { | 1614 | if (arvif == NULL) { |
1414 | ath10k_warn("no vif for vdev_id %d found\n", vdev_id); | 1615 | ath10k_warn(ar, "no vif for vdev_id %d found\n", |
1616 | vdev_id); | ||
1415 | continue; | 1617 | continue; |
1416 | } | 1618 | } |
1417 | 1619 | ||
@@ -1428,7 +1630,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1428 | 1630 | ||
1429 | bcn = ieee80211_beacon_get(ar->hw, arvif->vif); | 1631 | bcn = ieee80211_beacon_get(ar->hw, arvif->vif); |
1430 | if (!bcn) { | 1632 | if (!bcn) { |
1431 | ath10k_warn("could not get mac80211 beacon\n"); | 1633 | ath10k_warn(ar, "could not get mac80211 beacon\n"); |
1432 | continue; | 1634 | continue; |
1433 | } | 1635 | } |
1434 | 1636 | ||
@@ -1440,7 +1642,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1440 | 1642 | ||
1441 | if (arvif->beacon) { | 1643 | if (arvif->beacon) { |
1442 | if (!arvif->beacon_sent) | 1644 | if (!arvif->beacon_sent) |
1443 | ath10k_warn("SWBA overrun on vdev %d\n", | 1645 | ath10k_warn(ar, "SWBA overrun on vdev %d\n", |
1444 | arvif->vdev_id); | 1646 | arvif->vdev_id); |
1445 | 1647 | ||
1446 | dma_unmap_single(arvif->ar->dev, | 1648 | dma_unmap_single(arvif->ar->dev, |
@@ -1456,7 +1658,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | |||
1456 | ret = dma_mapping_error(arvif->ar->dev, | 1658 | ret = dma_mapping_error(arvif->ar->dev, |
1457 | ATH10K_SKB_CB(bcn)->paddr); | 1659 | ATH10K_SKB_CB(bcn)->paddr); |
1458 | if (ret) { | 1660 | if (ret) { |
1459 | ath10k_warn("failed to map beacon: %d\n", ret); | 1661 | ath10k_warn(ar, "failed to map beacon: %d\n", ret); |
1460 | dev_kfree_skb_any(bcn); | 1662 | dev_kfree_skb_any(bcn); |
1461 | goto skip; | 1663 | goto skip; |
1462 | } | 1664 | } |
@@ -1473,7 +1675,7 @@ skip: | |||
1473 | static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, | 1675 | static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, |
1474 | struct sk_buff *skb) | 1676 | struct sk_buff *skb) |
1475 | { | 1677 | { |
1476 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); | 1678 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); |
1477 | } | 1679 | } |
1478 | 1680 | ||
1479 | static void ath10k_dfs_radar_report(struct ath10k *ar, | 1681 | static void ath10k_dfs_radar_report(struct ath10k *ar, |
@@ -1489,20 +1691,20 @@ static void ath10k_dfs_radar_report(struct ath10k *ar, | |||
1489 | reg0 = __le32_to_cpu(rr->reg0); | 1691 | reg0 = __le32_to_cpu(rr->reg0); |
1490 | reg1 = __le32_to_cpu(rr->reg1); | 1692 | reg1 = __le32_to_cpu(rr->reg1); |
1491 | 1693 | ||
1492 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1694 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1493 | "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n", | 1695 | "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n", |
1494 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP), | 1696 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP), |
1495 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH), | 1697 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH), |
1496 | MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN), | 1698 | MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN), |
1497 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF)); | 1699 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF)); |
1498 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1700 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1499 | "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n", | 1701 | "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n", |
1500 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK), | 1702 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK), |
1501 | MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX), | 1703 | MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX), |
1502 | MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID), | 1704 | MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID), |
1503 | MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN), | 1705 | MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN), |
1504 | MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK)); | 1706 | MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK)); |
1505 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1707 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1506 | "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n", | 1708 | "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n", |
1507 | MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET), | 1709 | MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET), |
1508 | MS(reg1, RADAR_REPORT_REG1_PULSE_DUR)); | 1710 | MS(reg1, RADAR_REPORT_REG1_PULSE_DUR)); |
@@ -1529,25 +1731,25 @@ static void ath10k_dfs_radar_report(struct ath10k *ar, | |||
1529 | pe.width = width; | 1731 | pe.width = width; |
1530 | pe.rssi = rssi; | 1732 | pe.rssi = rssi; |
1531 | 1733 | ||
1532 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1734 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1533 | "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", | 1735 | "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", |
1534 | pe.freq, pe.width, pe.rssi, pe.ts); | 1736 | pe.freq, pe.width, pe.rssi, pe.ts); |
1535 | 1737 | ||
1536 | ATH10K_DFS_STAT_INC(ar, pulses_detected); | 1738 | ATH10K_DFS_STAT_INC(ar, pulses_detected); |
1537 | 1739 | ||
1538 | if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) { | 1740 | if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) { |
1539 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1741 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1540 | "dfs no pulse pattern detected, yet\n"); | 1742 | "dfs no pulse pattern detected, yet\n"); |
1541 | return; | 1743 | return; |
1542 | } | 1744 | } |
1543 | 1745 | ||
1544 | ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs radar detected\n"); | 1746 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n"); |
1545 | ATH10K_DFS_STAT_INC(ar, radar_detected); | 1747 | ATH10K_DFS_STAT_INC(ar, radar_detected); |
1546 | 1748 | ||
1547 | /* Control radar events reporting in debugfs file | 1749 | /* Control radar events reporting in debugfs file |
1548 | dfs_block_radar_events */ | 1750 | dfs_block_radar_events */ |
1549 | if (ar->dfs_block_radar_events) { | 1751 | if (ar->dfs_block_radar_events) { |
1550 | ath10k_info("DFS Radar detected, but ignored as requested\n"); | 1752 | ath10k_info(ar, "DFS Radar detected, but ignored as requested\n"); |
1551 | return; | 1753 | return; |
1552 | } | 1754 | } |
1553 | 1755 | ||
@@ -1566,13 +1768,13 @@ static int ath10k_dfs_fft_report(struct ath10k *ar, | |||
1566 | reg1 = __le32_to_cpu(fftr->reg1); | 1768 | reg1 = __le32_to_cpu(fftr->reg1); |
1567 | rssi = event->hdr.rssi_combined; | 1769 | rssi = event->hdr.rssi_combined; |
1568 | 1770 | ||
1569 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1771 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1570 | "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", | 1772 | "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", |
1571 | MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB), | 1773 | MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB), |
1572 | MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB), | 1774 | MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB), |
1573 | MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX), | 1775 | MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX), |
1574 | MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX)); | 1776 | MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX)); |
1575 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1777 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1576 | "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n", | 1778 | "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n", |
1577 | MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB), | 1779 | MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB), |
1578 | MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB), | 1780 | MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB), |
@@ -1584,7 +1786,7 @@ static int ath10k_dfs_fft_report(struct ath10k *ar, | |||
1584 | /* false event detection */ | 1786 | /* false event detection */ |
1585 | if (rssi == DFS_RSSI_POSSIBLY_FALSE && | 1787 | if (rssi == DFS_RSSI_POSSIBLY_FALSE && |
1586 | peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) { | 1788 | peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) { |
1587 | ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); | 1789 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); |
1588 | ATH10K_DFS_STAT_INC(ar, pulses_discarded); | 1790 | ATH10K_DFS_STAT_INC(ar, pulses_discarded); |
1589 | return -EINVAL; | 1791 | return -EINVAL; |
1590 | } | 1792 | } |
@@ -1603,7 +1805,7 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, | |||
1603 | u8 *tlv_buf; | 1805 | u8 *tlv_buf; |
1604 | 1806 | ||
1605 | buf_len = __le32_to_cpu(event->hdr.buf_len); | 1807 | buf_len = __le32_to_cpu(event->hdr.buf_len); |
1606 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1808 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1607 | "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", | 1809 | "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", |
1608 | event->hdr.phy_err_code, event->hdr.rssi_combined, | 1810 | event->hdr.phy_err_code, event->hdr.rssi_combined, |
1609 | __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len); | 1811 | __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len); |
@@ -1616,21 +1818,22 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, | |||
1616 | 1818 | ||
1617 | while (i < buf_len) { | 1819 | while (i < buf_len) { |
1618 | if (i + sizeof(*tlv) > buf_len) { | 1820 | if (i + sizeof(*tlv) > buf_len) { |
1619 | ath10k_warn("too short buf for tlv header (%d)\n", i); | 1821 | ath10k_warn(ar, "too short buf for tlv header (%d)\n", |
1822 | i); | ||
1620 | return; | 1823 | return; |
1621 | } | 1824 | } |
1622 | 1825 | ||
1623 | tlv = (struct phyerr_tlv *)&event->bufp[i]; | 1826 | tlv = (struct phyerr_tlv *)&event->bufp[i]; |
1624 | tlv_len = __le16_to_cpu(tlv->len); | 1827 | tlv_len = __le16_to_cpu(tlv->len); |
1625 | tlv_buf = &event->bufp[i + sizeof(*tlv)]; | 1828 | tlv_buf = &event->bufp[i + sizeof(*tlv)]; |
1626 | ath10k_dbg(ATH10K_DBG_REGULATORY, | 1829 | ath10k_dbg(ar, ATH10K_DBG_REGULATORY, |
1627 | "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", | 1830 | "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", |
1628 | tlv_len, tlv->tag, tlv->sig); | 1831 | tlv_len, tlv->tag, tlv->sig); |
1629 | 1832 | ||
1630 | switch (tlv->tag) { | 1833 | switch (tlv->tag) { |
1631 | case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY: | 1834 | case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY: |
1632 | if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) { | 1835 | if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) { |
1633 | ath10k_warn("too short radar pulse summary (%d)\n", | 1836 | ath10k_warn(ar, "too short radar pulse summary (%d)\n", |
1634 | i); | 1837 | i); |
1635 | return; | 1838 | return; |
1636 | } | 1839 | } |
@@ -1640,7 +1843,8 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, | |||
1640 | break; | 1843 | break; |
1641 | case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: | 1844 | case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: |
1642 | if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { | 1845 | if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { |
1643 | ath10k_warn("too short fft report (%d)\n", i); | 1846 | ath10k_warn(ar, "too short fft report (%d)\n", |
1847 | i); | ||
1644 | return; | 1848 | return; |
1645 | } | 1849 | } |
1646 | 1850 | ||
@@ -1659,7 +1863,54 @@ static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, | |||
1659 | struct wmi_single_phyerr_rx_event *event, | 1863 | struct wmi_single_phyerr_rx_event *event, |
1660 | u64 tsf) | 1864 | u64 tsf) |
1661 | { | 1865 | { |
1662 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event spectral scan\n"); | 1866 | int buf_len, tlv_len, res, i = 0; |
1867 | struct phyerr_tlv *tlv; | ||
1868 | u8 *tlv_buf; | ||
1869 | struct phyerr_fft_report *fftr; | ||
1870 | size_t fftr_len; | ||
1871 | |||
1872 | buf_len = __le32_to_cpu(event->hdr.buf_len); | ||
1873 | |||
1874 | while (i < buf_len) { | ||
1875 | if (i + sizeof(*tlv) > buf_len) { | ||
1876 | ath10k_warn(ar, "failed to parse phyerr tlv header at byte %d\n", | ||
1877 | i); | ||
1878 | return; | ||
1879 | } | ||
1880 | |||
1881 | tlv = (struct phyerr_tlv *)&event->bufp[i]; | ||
1882 | tlv_len = __le16_to_cpu(tlv->len); | ||
1883 | tlv_buf = &event->bufp[i + sizeof(*tlv)]; | ||
1884 | |||
1885 | if (i + sizeof(*tlv) + tlv_len > buf_len) { | ||
1886 | ath10k_warn(ar, "failed to parse phyerr tlv payload at byte %d\n", | ||
1887 | i); | ||
1888 | return; | ||
1889 | } | ||
1890 | |||
1891 | switch (tlv->tag) { | ||
1892 | case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: | ||
1893 | if (sizeof(*fftr) > tlv_len) { | ||
1894 | ath10k_warn(ar, "failed to parse fft report at byte %d\n", | ||
1895 | i); | ||
1896 | return; | ||
1897 | } | ||
1898 | |||
1899 | fftr_len = tlv_len - sizeof(*fftr); | ||
1900 | fftr = (struct phyerr_fft_report *)tlv_buf; | ||
1901 | res = ath10k_spectral_process_fft(ar, event, | ||
1902 | fftr, fftr_len, | ||
1903 | tsf); | ||
1904 | if (res < 0) { | ||
1905 | ath10k_warn(ar, "failed to process fft report: %d\n", | ||
1906 | res); | ||
1907 | return; | ||
1908 | } | ||
1909 | break; | ||
1910 | } | ||
1911 | |||
1912 | i += sizeof(*tlv) + tlv_len; | ||
1913 | } | ||
1663 | } | 1914 | } |
1664 | 1915 | ||
1665 | static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | 1916 | static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) |
@@ -1674,7 +1925,7 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | |||
1674 | 1925 | ||
1675 | /* Check if combined event available */ | 1926 | /* Check if combined event available */ |
1676 | if (left_len < sizeof(*comb_event)) { | 1927 | if (left_len < sizeof(*comb_event)) { |
1677 | ath10k_warn("wmi phyerr combined event wrong len\n"); | 1928 | ath10k_warn(ar, "wmi phyerr combined event wrong len\n"); |
1678 | return; | 1929 | return; |
1679 | } | 1930 | } |
1680 | 1931 | ||
@@ -1688,7 +1939,7 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | |||
1688 | tsf <<= 32; | 1939 | tsf <<= 32; |
1689 | tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32); | 1940 | tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32); |
1690 | 1941 | ||
1691 | ath10k_dbg(ATH10K_DBG_WMI, | 1942 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
1692 | "wmi event phyerr count %d tsf64 0x%llX\n", | 1943 | "wmi event phyerr count %d tsf64 0x%llX\n", |
1693 | count, tsf); | 1944 | count, tsf); |
1694 | 1945 | ||
@@ -1696,7 +1947,8 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | |||
1696 | for (i = 0; i < count; i++) { | 1947 | for (i = 0; i < count; i++) { |
1697 | /* Check if we can read event header */ | 1948 | /* Check if we can read event header */ |
1698 | if (left_len < sizeof(*event)) { | 1949 | if (left_len < sizeof(*event)) { |
1699 | ath10k_warn("single event (%d) wrong head len\n", i); | 1950 | ath10k_warn(ar, "single event (%d) wrong head len\n", |
1951 | i); | ||
1700 | return; | 1952 | return; |
1701 | } | 1953 | } |
1702 | 1954 | ||
@@ -1706,7 +1958,7 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | |||
1706 | phy_err_code = event->hdr.phy_err_code; | 1958 | phy_err_code = event->hdr.phy_err_code; |
1707 | 1959 | ||
1708 | if (left_len < buf_len) { | 1960 | if (left_len < buf_len) { |
1709 | ath10k_warn("single event (%d) wrong buf len\n", i); | 1961 | ath10k_warn(ar, "single event (%d) wrong buf len\n", i); |
1710 | return; | 1962 | return; |
1711 | } | 1963 | } |
1712 | 1964 | ||
@@ -1733,13 +1985,13 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | |||
1733 | 1985 | ||
1734 | static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) | 1986 | static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) |
1735 | { | 1987 | { |
1736 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); | 1988 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); |
1737 | } | 1989 | } |
1738 | 1990 | ||
1739 | static void ath10k_wmi_event_profile_match(struct ath10k *ar, | 1991 | static void ath10k_wmi_event_profile_match(struct ath10k *ar, |
1740 | struct sk_buff *skb) | 1992 | struct sk_buff *skb) |
1741 | { | 1993 | { |
1742 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); | 1994 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); |
1743 | } | 1995 | } |
1744 | 1996 | ||
1745 | static void ath10k_wmi_event_debug_print(struct ath10k *ar, | 1997 | static void ath10k_wmi_event_debug_print(struct ath10k *ar, |
@@ -1764,7 +2016,7 @@ static void ath10k_wmi_event_debug_print(struct ath10k *ar, | |||
1764 | } | 2016 | } |
1765 | 2017 | ||
1766 | if (i == sizeof(buf) - 1) | 2018 | if (i == sizeof(buf) - 1) |
1767 | ath10k_warn("wmi debug print truncated: %d\n", skb->len); | 2019 | ath10k_warn(ar, "wmi debug print truncated: %d\n", skb->len); |
1768 | 2020 | ||
1769 | /* for some reason the debug prints end with \n, remove that */ | 2021 | /* for some reason the debug prints end with \n, remove that */ |
1770 | if (skb->data[i - 1] == '\n') | 2022 | if (skb->data[i - 1] == '\n') |
@@ -1773,108 +2025,108 @@ static void ath10k_wmi_event_debug_print(struct ath10k *ar, | |||
1773 | /* the last byte is always reserved for the null character */ | 2025 | /* the last byte is always reserved for the null character */ |
1774 | buf[i] = '\0'; | 2026 | buf[i] = '\0'; |
1775 | 2027 | ||
1776 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf); | 2028 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf); |
1777 | } | 2029 | } |
1778 | 2030 | ||
1779 | static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) | 2031 | static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) |
1780 | { | 2032 | { |
1781 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); | 2033 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); |
1782 | } | 2034 | } |
1783 | 2035 | ||
1784 | static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, | 2036 | static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, |
1785 | struct sk_buff *skb) | 2037 | struct sk_buff *skb) |
1786 | { | 2038 | { |
1787 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); | 2039 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); |
1788 | } | 2040 | } |
1789 | 2041 | ||
1790 | static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, | 2042 | static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, |
1791 | struct sk_buff *skb) | 2043 | struct sk_buff *skb) |
1792 | { | 2044 | { |
1793 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); | 2045 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); |
1794 | } | 2046 | } |
1795 | 2047 | ||
1796 | static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, | 2048 | static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, |
1797 | struct sk_buff *skb) | 2049 | struct sk_buff *skb) |
1798 | { | 2050 | { |
1799 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); | 2051 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); |
1800 | } | 2052 | } |
1801 | 2053 | ||
1802 | static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, | 2054 | static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, |
1803 | struct sk_buff *skb) | 2055 | struct sk_buff *skb) |
1804 | { | 2056 | { |
1805 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); | 2057 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); |
1806 | } | 2058 | } |
1807 | 2059 | ||
1808 | static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, | 2060 | static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, |
1809 | struct sk_buff *skb) | 2061 | struct sk_buff *skb) |
1810 | { | 2062 | { |
1811 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); | 2063 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); |
1812 | } | 2064 | } |
1813 | 2065 | ||
1814 | static void ath10k_wmi_event_dcs_interference(struct ath10k *ar, | 2066 | static void ath10k_wmi_event_dcs_interference(struct ath10k *ar, |
1815 | struct sk_buff *skb) | 2067 | struct sk_buff *skb) |
1816 | { | 2068 | { |
1817 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); | 2069 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); |
1818 | } | 2070 | } |
1819 | 2071 | ||
1820 | static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, | 2072 | static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, |
1821 | struct sk_buff *skb) | 2073 | struct sk_buff *skb) |
1822 | { | 2074 | { |
1823 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); | 2075 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); |
1824 | } | 2076 | } |
1825 | 2077 | ||
1826 | static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, | 2078 | static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, |
1827 | struct sk_buff *skb) | 2079 | struct sk_buff *skb) |
1828 | { | 2080 | { |
1829 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); | 2081 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); |
1830 | } | 2082 | } |
1831 | 2083 | ||
1832 | static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, | 2084 | static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, |
1833 | struct sk_buff *skb) | 2085 | struct sk_buff *skb) |
1834 | { | 2086 | { |
1835 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); | 2087 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); |
1836 | } | 2088 | } |
1837 | 2089 | ||
1838 | static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, | 2090 | static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, |
1839 | struct sk_buff *skb) | 2091 | struct sk_buff *skb) |
1840 | { | 2092 | { |
1841 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); | 2093 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); |
1842 | } | 2094 | } |
1843 | 2095 | ||
1844 | static void ath10k_wmi_event_delba_complete(struct ath10k *ar, | 2096 | static void ath10k_wmi_event_delba_complete(struct ath10k *ar, |
1845 | struct sk_buff *skb) | 2097 | struct sk_buff *skb) |
1846 | { | 2098 | { |
1847 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); | 2099 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); |
1848 | } | 2100 | } |
1849 | 2101 | ||
1850 | static void ath10k_wmi_event_addba_complete(struct ath10k *ar, | 2102 | static void ath10k_wmi_event_addba_complete(struct ath10k *ar, |
1851 | struct sk_buff *skb) | 2103 | struct sk_buff *skb) |
1852 | { | 2104 | { |
1853 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); | 2105 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); |
1854 | } | 2106 | } |
1855 | 2107 | ||
1856 | static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, | 2108 | static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, |
1857 | struct sk_buff *skb) | 2109 | struct sk_buff *skb) |
1858 | { | 2110 | { |
1859 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); | 2111 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); |
1860 | } | 2112 | } |
1861 | 2113 | ||
1862 | static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, | 2114 | static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, |
1863 | struct sk_buff *skb) | 2115 | struct sk_buff *skb) |
1864 | { | 2116 | { |
1865 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); | 2117 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); |
1866 | } | 2118 | } |
1867 | 2119 | ||
1868 | static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, | 2120 | static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, |
1869 | struct sk_buff *skb) | 2121 | struct sk_buff *skb) |
1870 | { | 2122 | { |
1871 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); | 2123 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); |
1872 | } | 2124 | } |
1873 | 2125 | ||
1874 | static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, | 2126 | static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, |
1875 | struct sk_buff *skb) | 2127 | struct sk_buff *skb) |
1876 | { | 2128 | { |
1877 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); | 2129 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); |
1878 | } | 2130 | } |
1879 | 2131 | ||
1880 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, | 2132 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, |
@@ -1894,7 +2146,7 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, | |||
1894 | &paddr, | 2146 | &paddr, |
1895 | GFP_ATOMIC); | 2147 | GFP_ATOMIC); |
1896 | if (!ar->wmi.mem_chunks[idx].vaddr) { | 2148 | if (!ar->wmi.mem_chunks[idx].vaddr) { |
1897 | ath10k_warn("failed to allocate memory chunk\n"); | 2149 | ath10k_warn(ar, "failed to allocate memory chunk\n"); |
1898 | return -ENOMEM; | 2150 | return -ENOMEM; |
1899 | } | 2151 | } |
1900 | 2152 | ||
@@ -1912,9 +2164,10 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, | |||
1912 | struct sk_buff *skb) | 2164 | struct sk_buff *skb) |
1913 | { | 2165 | { |
1914 | struct wmi_service_ready_event *ev = (void *)skb->data; | 2166 | struct wmi_service_ready_event *ev = (void *)skb->data; |
2167 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {}; | ||
1915 | 2168 | ||
1916 | if (skb->len < sizeof(*ev)) { | 2169 | if (skb->len < sizeof(*ev)) { |
1917 | ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", | 2170 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", |
1918 | skb->len, sizeof(*ev)); | 2171 | skb->len, sizeof(*ev)); |
1919 | return; | 2172 | return; |
1920 | } | 2173 | } |
@@ -1937,7 +2190,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, | |||
1937 | set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); | 2190 | set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); |
1938 | 2191 | ||
1939 | if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { | 2192 | if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { |
1940 | ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", | 2193 | ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", |
1941 | ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); | 2194 | ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); |
1942 | ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; | 2195 | ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; |
1943 | } | 2196 | } |
@@ -1945,8 +2198,10 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, | |||
1945 | ar->ath_common.regulatory.current_rd = | 2198 | ar->ath_common.regulatory.current_rd = |
1946 | __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); | 2199 | __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); |
1947 | 2200 | ||
1948 | ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, | 2201 | wmi_main_svc_map(ev->wmi_service_bitmap, svc_bmap); |
1949 | sizeof(ev->wmi_service_bitmap)); | 2202 | ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); |
2203 | ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", | ||
2204 | ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap)); | ||
1950 | 2205 | ||
1951 | if (strlen(ar->hw->wiphy->fw_version) == 0) { | 2206 | if (strlen(ar->hw->wiphy->fw_version) == 0) { |
1952 | snprintf(ar->hw->wiphy->fw_version, | 2207 | snprintf(ar->hw->wiphy->fw_version, |
@@ -1960,11 +2215,11 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, | |||
1960 | 2215 | ||
1961 | /* FIXME: it probably should be better to support this */ | 2216 | /* FIXME: it probably should be better to support this */ |
1962 | if (__le32_to_cpu(ev->num_mem_reqs) > 0) { | 2217 | if (__le32_to_cpu(ev->num_mem_reqs) > 0) { |
1963 | ath10k_warn("target requested %d memory chunks; ignoring\n", | 2218 | ath10k_warn(ar, "target requested %d memory chunks; ignoring\n", |
1964 | __le32_to_cpu(ev->num_mem_reqs)); | 2219 | __le32_to_cpu(ev->num_mem_reqs)); |
1965 | } | 2220 | } |
1966 | 2221 | ||
1967 | ath10k_dbg(ATH10K_DBG_WMI, | 2222 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
1968 | "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", | 2223 | "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", |
1969 | __le32_to_cpu(ev->sw_version), | 2224 | __le32_to_cpu(ev->sw_version), |
1970 | __le32_to_cpu(ev->sw_version_1), | 2225 | __le32_to_cpu(ev->sw_version_1), |
@@ -1986,9 +2241,10 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
1986 | u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; | 2241 | u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; |
1987 | int ret; | 2242 | int ret; |
1988 | struct wmi_service_ready_event_10x *ev = (void *)skb->data; | 2243 | struct wmi_service_ready_event_10x *ev = (void *)skb->data; |
2244 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {}; | ||
1989 | 2245 | ||
1990 | if (skb->len < sizeof(*ev)) { | 2246 | if (skb->len < sizeof(*ev)) { |
1991 | ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", | 2247 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", |
1992 | skb->len, sizeof(*ev)); | 2248 | skb->len, sizeof(*ev)); |
1993 | return; | 2249 | return; |
1994 | } | 2250 | } |
@@ -2004,7 +2260,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2004 | ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); | 2260 | ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); |
2005 | 2261 | ||
2006 | if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { | 2262 | if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { |
2007 | ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", | 2263 | ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", |
2008 | ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); | 2264 | ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); |
2009 | ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; | 2265 | ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; |
2010 | } | 2266 | } |
@@ -2012,8 +2268,10 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2012 | ar->ath_common.regulatory.current_rd = | 2268 | ar->ath_common.regulatory.current_rd = |
2013 | __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); | 2269 | __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); |
2014 | 2270 | ||
2015 | ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, | 2271 | wmi_10x_svc_map(ev->wmi_service_bitmap, svc_bmap); |
2016 | sizeof(ev->wmi_service_bitmap)); | 2272 | ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); |
2273 | ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", | ||
2274 | ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap)); | ||
2017 | 2275 | ||
2018 | if (strlen(ar->hw->wiphy->fw_version) == 0) { | 2276 | if (strlen(ar->hw->wiphy->fw_version) == 0) { |
2019 | snprintf(ar->hw->wiphy->fw_version, | 2277 | snprintf(ar->hw->wiphy->fw_version, |
@@ -2026,7 +2284,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2026 | num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); | 2284 | num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); |
2027 | 2285 | ||
2028 | if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { | 2286 | if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { |
2029 | ath10k_warn("requested memory chunks number (%d) exceeds the limit\n", | 2287 | ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n", |
2030 | num_mem_reqs); | 2288 | num_mem_reqs); |
2031 | return; | 2289 | return; |
2032 | } | 2290 | } |
@@ -2034,7 +2292,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2034 | if (!num_mem_reqs) | 2292 | if (!num_mem_reqs) |
2035 | goto exit; | 2293 | goto exit; |
2036 | 2294 | ||
2037 | ath10k_dbg(ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", | 2295 | ath10k_dbg(ar, ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", |
2038 | num_mem_reqs); | 2296 | num_mem_reqs); |
2039 | 2297 | ||
2040 | for (i = 0; i < num_mem_reqs; ++i) { | 2298 | for (i = 0; i < num_mem_reqs; ++i) { |
@@ -2052,7 +2310,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2052 | else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) | 2310 | else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) |
2053 | num_units = TARGET_10X_NUM_VDEVS + 1; | 2311 | num_units = TARGET_10X_NUM_VDEVS + 1; |
2054 | 2312 | ||
2055 | ath10k_dbg(ATH10K_DBG_WMI, | 2313 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2056 | "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", | 2314 | "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", |
2057 | req_id, | 2315 | req_id, |
2058 | __le32_to_cpu(ev->mem_reqs[i].num_units), | 2316 | __le32_to_cpu(ev->mem_reqs[i].num_units), |
@@ -2067,7 +2325,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2067 | } | 2325 | } |
2068 | 2326 | ||
2069 | exit: | 2327 | exit: |
2070 | ath10k_dbg(ATH10K_DBG_WMI, | 2328 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2071 | "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", | 2329 | "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", |
2072 | __le32_to_cpu(ev->sw_version), | 2330 | __le32_to_cpu(ev->sw_version), |
2073 | __le32_to_cpu(ev->abi_version), | 2331 | __le32_to_cpu(ev->abi_version), |
@@ -2091,7 +2349,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2091 | 2349 | ||
2092 | memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); | 2350 | memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); |
2093 | 2351 | ||
2094 | ath10k_dbg(ATH10K_DBG_WMI, | 2352 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2095 | "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", | 2353 | "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", |
2096 | __le32_to_cpu(ev->sw_version), | 2354 | __le32_to_cpu(ev->sw_version), |
2097 | __le32_to_cpu(ev->abi_version), | 2355 | __le32_to_cpu(ev->abi_version), |
@@ -2211,7 +2469,7 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2211 | ath10k_wmi_ready_event_rx(ar, skb); | 2469 | ath10k_wmi_ready_event_rx(ar, skb); |
2212 | break; | 2470 | break; |
2213 | default: | 2471 | default: |
2214 | ath10k_warn("Unknown eventid: %d\n", id); | 2472 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
2215 | break; | 2473 | break; |
2216 | } | 2474 | } |
2217 | 2475 | ||
@@ -2318,27 +2576,151 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2318 | ath10k_wmi_ready_event_rx(ar, skb); | 2576 | ath10k_wmi_ready_event_rx(ar, skb); |
2319 | break; | 2577 | break; |
2320 | default: | 2578 | default: |
2321 | ath10k_warn("Unknown eventid: %d\n", id); | 2579 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
2322 | break; | 2580 | break; |
2323 | } | 2581 | } |
2324 | 2582 | ||
2325 | dev_kfree_skb(skb); | 2583 | dev_kfree_skb(skb); |
2326 | } | 2584 | } |
2327 | 2585 | ||
2586 | static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) | ||
2587 | { | ||
2588 | struct wmi_cmd_hdr *cmd_hdr; | ||
2589 | enum wmi_10_2_event_id id; | ||
2590 | |||
2591 | cmd_hdr = (struct wmi_cmd_hdr *)skb->data; | ||
2592 | id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); | ||
2593 | |||
2594 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) | ||
2595 | return; | ||
2596 | |||
2597 | trace_ath10k_wmi_event(id, skb->data, skb->len); | ||
2598 | |||
2599 | switch (id) { | ||
2600 | case WMI_10_2_MGMT_RX_EVENTID: | ||
2601 | ath10k_wmi_event_mgmt_rx(ar, skb); | ||
2602 | /* mgmt_rx() owns the skb now! */ | ||
2603 | return; | ||
2604 | case WMI_10_2_SCAN_EVENTID: | ||
2605 | ath10k_wmi_event_scan(ar, skb); | ||
2606 | break; | ||
2607 | case WMI_10_2_CHAN_INFO_EVENTID: | ||
2608 | ath10k_wmi_event_chan_info(ar, skb); | ||
2609 | break; | ||
2610 | case WMI_10_2_ECHO_EVENTID: | ||
2611 | ath10k_wmi_event_echo(ar, skb); | ||
2612 | break; | ||
2613 | case WMI_10_2_DEBUG_MESG_EVENTID: | ||
2614 | ath10k_wmi_event_debug_mesg(ar, skb); | ||
2615 | break; | ||
2616 | case WMI_10_2_UPDATE_STATS_EVENTID: | ||
2617 | ath10k_wmi_event_update_stats(ar, skb); | ||
2618 | break; | ||
2619 | case WMI_10_2_VDEV_START_RESP_EVENTID: | ||
2620 | ath10k_wmi_event_vdev_start_resp(ar, skb); | ||
2621 | break; | ||
2622 | case WMI_10_2_VDEV_STOPPED_EVENTID: | ||
2623 | ath10k_wmi_event_vdev_stopped(ar, skb); | ||
2624 | break; | ||
2625 | case WMI_10_2_PEER_STA_KICKOUT_EVENTID: | ||
2626 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | ||
2627 | break; | ||
2628 | case WMI_10_2_HOST_SWBA_EVENTID: | ||
2629 | ath10k_wmi_event_host_swba(ar, skb); | ||
2630 | break; | ||
2631 | case WMI_10_2_TBTTOFFSET_UPDATE_EVENTID: | ||
2632 | ath10k_wmi_event_tbttoffset_update(ar, skb); | ||
2633 | break; | ||
2634 | case WMI_10_2_PHYERR_EVENTID: | ||
2635 | ath10k_wmi_event_phyerr(ar, skb); | ||
2636 | break; | ||
2637 | case WMI_10_2_ROAM_EVENTID: | ||
2638 | ath10k_wmi_event_roam(ar, skb); | ||
2639 | break; | ||
2640 | case WMI_10_2_PROFILE_MATCH: | ||
2641 | ath10k_wmi_event_profile_match(ar, skb); | ||
2642 | break; | ||
2643 | case WMI_10_2_DEBUG_PRINT_EVENTID: | ||
2644 | ath10k_wmi_event_debug_print(ar, skb); | ||
2645 | break; | ||
2646 | case WMI_10_2_PDEV_QVIT_EVENTID: | ||
2647 | ath10k_wmi_event_pdev_qvit(ar, skb); | ||
2648 | break; | ||
2649 | case WMI_10_2_WLAN_PROFILE_DATA_EVENTID: | ||
2650 | ath10k_wmi_event_wlan_profile_data(ar, skb); | ||
2651 | break; | ||
2652 | case WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID: | ||
2653 | ath10k_wmi_event_rtt_measurement_report(ar, skb); | ||
2654 | break; | ||
2655 | case WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID: | ||
2656 | ath10k_wmi_event_tsf_measurement_report(ar, skb); | ||
2657 | break; | ||
2658 | case WMI_10_2_RTT_ERROR_REPORT_EVENTID: | ||
2659 | ath10k_wmi_event_rtt_error_report(ar, skb); | ||
2660 | break; | ||
2661 | case WMI_10_2_WOW_WAKEUP_HOST_EVENTID: | ||
2662 | ath10k_wmi_event_wow_wakeup_host(ar, skb); | ||
2663 | break; | ||
2664 | case WMI_10_2_DCS_INTERFERENCE_EVENTID: | ||
2665 | ath10k_wmi_event_dcs_interference(ar, skb); | ||
2666 | break; | ||
2667 | case WMI_10_2_PDEV_TPC_CONFIG_EVENTID: | ||
2668 | ath10k_wmi_event_pdev_tpc_config(ar, skb); | ||
2669 | break; | ||
2670 | case WMI_10_2_INST_RSSI_STATS_EVENTID: | ||
2671 | ath10k_wmi_event_inst_rssi_stats(ar, skb); | ||
2672 | break; | ||
2673 | case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: | ||
2674 | ath10k_wmi_event_vdev_standby_req(ar, skb); | ||
2675 | break; | ||
2676 | case WMI_10_2_VDEV_RESUME_REQ_EVENTID: | ||
2677 | ath10k_wmi_event_vdev_resume_req(ar, skb); | ||
2678 | break; | ||
2679 | case WMI_10_2_SERVICE_READY_EVENTID: | ||
2680 | ath10k_wmi_10x_service_ready_event_rx(ar, skb); | ||
2681 | break; | ||
2682 | case WMI_10_2_READY_EVENTID: | ||
2683 | ath10k_wmi_ready_event_rx(ar, skb); | ||
2684 | break; | ||
2685 | case WMI_10_2_RTT_KEEPALIVE_EVENTID: | ||
2686 | case WMI_10_2_GPIO_INPUT_EVENTID: | ||
2687 | case WMI_10_2_PEER_RATECODE_LIST_EVENTID: | ||
2688 | case WMI_10_2_GENERIC_BUFFER_EVENTID: | ||
2689 | case WMI_10_2_MCAST_BUF_RELEASE_EVENTID: | ||
2690 | case WMI_10_2_MCAST_LIST_AGEOUT_EVENTID: | ||
2691 | case WMI_10_2_WDS_PEER_EVENTID: | ||
2692 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
2693 | "received event id %d not implemented\n", id); | ||
2694 | break; | ||
2695 | default: | ||
2696 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | ||
2697 | break; | ||
2698 | } | ||
2699 | |||
2700 | dev_kfree_skb(skb); | ||
2701 | } | ||
2328 | 2702 | ||
2329 | static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) | 2703 | static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) |
2330 | { | 2704 | { |
2331 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) | 2705 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
2332 | ath10k_wmi_10x_process_rx(ar, skb); | 2706 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) |
2333 | else | 2707 | ath10k_wmi_10_2_process_rx(ar, skb); |
2708 | else | ||
2709 | ath10k_wmi_10x_process_rx(ar, skb); | ||
2710 | } else { | ||
2334 | ath10k_wmi_main_process_rx(ar, skb); | 2711 | ath10k_wmi_main_process_rx(ar, skb); |
2712 | } | ||
2335 | } | 2713 | } |
2336 | 2714 | ||
2337 | /* WMI Initialization functions */ | 2715 | /* WMI Initialization functions */ |
2338 | int ath10k_wmi_attach(struct ath10k *ar) | 2716 | int ath10k_wmi_attach(struct ath10k *ar) |
2339 | { | 2717 | { |
2340 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | 2718 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
2341 | ar->wmi.cmd = &wmi_10x_cmd_map; | 2719 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) |
2720 | ar->wmi.cmd = &wmi_10_2_cmd_map; | ||
2721 | else | ||
2722 | ar->wmi.cmd = &wmi_10x_cmd_map; | ||
2723 | |||
2342 | ar->wmi.vdev_param = &wmi_10x_vdev_param_map; | 2724 | ar->wmi.vdev_param = &wmi_10x_vdev_param_map; |
2343 | ar->wmi.pdev_param = &wmi_10x_pdev_param_map; | 2725 | ar->wmi.pdev_param = &wmi_10x_pdev_param_map; |
2344 | } else { | 2726 | } else { |
@@ -2388,7 +2770,7 @@ int ath10k_wmi_connect(struct ath10k *ar) | |||
2388 | 2770 | ||
2389 | status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp); | 2771 | status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp); |
2390 | if (status) { | 2772 | if (status) { |
2391 | ath10k_warn("failed to connect to WMI CONTROL service status: %d\n", | 2773 | ath10k_warn(ar, "failed to connect to WMI CONTROL service status: %d\n", |
2392 | status); | 2774 | status); |
2393 | return status; | 2775 | return status; |
2394 | } | 2776 | } |
@@ -2404,7 +2786,7 @@ static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd, | |||
2404 | struct wmi_pdev_set_regdomain_cmd *cmd; | 2786 | struct wmi_pdev_set_regdomain_cmd *cmd; |
2405 | struct sk_buff *skb; | 2787 | struct sk_buff *skb; |
2406 | 2788 | ||
2407 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 2789 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2408 | if (!skb) | 2790 | if (!skb) |
2409 | return -ENOMEM; | 2791 | return -ENOMEM; |
2410 | 2792 | ||
@@ -2415,7 +2797,7 @@ static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd, | |||
2415 | cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g); | 2797 | cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g); |
2416 | cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); | 2798 | cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); |
2417 | 2799 | ||
2418 | ath10k_dbg(ATH10K_DBG_WMI, | 2800 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2419 | "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", | 2801 | "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", |
2420 | rd, rd2g, rd5g, ctl2g, ctl5g); | 2802 | rd, rd2g, rd5g, ctl2g, ctl5g); |
2421 | 2803 | ||
@@ -2431,7 +2813,7 @@ static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd, | |||
2431 | struct wmi_pdev_set_regdomain_cmd_10x *cmd; | 2813 | struct wmi_pdev_set_regdomain_cmd_10x *cmd; |
2432 | struct sk_buff *skb; | 2814 | struct sk_buff *skb; |
2433 | 2815 | ||
2434 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 2816 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2435 | if (!skb) | 2817 | if (!skb) |
2436 | return -ENOMEM; | 2818 | return -ENOMEM; |
2437 | 2819 | ||
@@ -2443,7 +2825,7 @@ static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd, | |||
2443 | cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); | 2825 | cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); |
2444 | cmd->dfs_domain = __cpu_to_le32(dfs_reg); | 2826 | cmd->dfs_domain = __cpu_to_le32(dfs_reg); |
2445 | 2827 | ||
2446 | ath10k_dbg(ATH10K_DBG_WMI, | 2828 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2447 | "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", | 2829 | "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", |
2448 | rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg); | 2830 | rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg); |
2449 | 2831 | ||
@@ -2473,7 +2855,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | |||
2473 | if (arg->passive) | 2855 | if (arg->passive) |
2474 | return -EINVAL; | 2856 | return -EINVAL; |
2475 | 2857 | ||
2476 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 2858 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2477 | if (!skb) | 2859 | if (!skb) |
2478 | return -ENOMEM; | 2860 | return -ENOMEM; |
2479 | 2861 | ||
@@ -2491,7 +2873,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | |||
2491 | cmd->chan.reg_classid = arg->reg_class_id; | 2873 | cmd->chan.reg_classid = arg->reg_class_id; |
2492 | cmd->chan.antenna_max = arg->max_antenna_gain; | 2874 | cmd->chan.antenna_max = arg->max_antenna_gain; |
2493 | 2875 | ||
2494 | ath10k_dbg(ATH10K_DBG_WMI, | 2876 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2495 | "wmi set channel mode %d freq %d\n", | 2877 | "wmi set channel mode %d freq %d\n", |
2496 | arg->mode, arg->freq); | 2878 | arg->mode, arg->freq); |
2497 | 2879 | ||
@@ -2504,7 +2886,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) | |||
2504 | struct wmi_pdev_suspend_cmd *cmd; | 2886 | struct wmi_pdev_suspend_cmd *cmd; |
2505 | struct sk_buff *skb; | 2887 | struct sk_buff *skb; |
2506 | 2888 | ||
2507 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 2889 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2508 | if (!skb) | 2890 | if (!skb) |
2509 | return -ENOMEM; | 2891 | return -ENOMEM; |
2510 | 2892 | ||
@@ -2518,7 +2900,7 @@ int ath10k_wmi_pdev_resume_target(struct ath10k *ar) | |||
2518 | { | 2900 | { |
2519 | struct sk_buff *skb; | 2901 | struct sk_buff *skb; |
2520 | 2902 | ||
2521 | skb = ath10k_wmi_alloc_skb(0); | 2903 | skb = ath10k_wmi_alloc_skb(ar, 0); |
2522 | if (skb == NULL) | 2904 | if (skb == NULL) |
2523 | return -ENOMEM; | 2905 | return -ENOMEM; |
2524 | 2906 | ||
@@ -2531,11 +2913,12 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) | |||
2531 | struct sk_buff *skb; | 2913 | struct sk_buff *skb; |
2532 | 2914 | ||
2533 | if (id == WMI_PDEV_PARAM_UNSUPPORTED) { | 2915 | if (id == WMI_PDEV_PARAM_UNSUPPORTED) { |
2534 | ath10k_warn("pdev param %d not supported by firmware\n", id); | 2916 | ath10k_warn(ar, "pdev param %d not supported by firmware\n", |
2917 | id); | ||
2535 | return -EOPNOTSUPP; | 2918 | return -EOPNOTSUPP; |
2536 | } | 2919 | } |
2537 | 2920 | ||
2538 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 2921 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2539 | if (!skb) | 2922 | if (!skb) |
2540 | return -ENOMEM; | 2923 | return -ENOMEM; |
2541 | 2924 | ||
@@ -2543,7 +2926,7 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) | |||
2543 | cmd->param_id = __cpu_to_le32(id); | 2926 | cmd->param_id = __cpu_to_le32(id); |
2544 | cmd->param_value = __cpu_to_le32(value); | 2927 | cmd->param_value = __cpu_to_le32(value); |
2545 | 2928 | ||
2546 | ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", | 2929 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", |
2547 | id, value); | 2930 | id, value); |
2548 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); | 2931 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); |
2549 | } | 2932 | } |
@@ -2610,7 +2993,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2610 | len = sizeof(*cmd) + | 2993 | len = sizeof(*cmd) + |
2611 | (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); | 2994 | (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); |
2612 | 2995 | ||
2613 | buf = ath10k_wmi_alloc_skb(len); | 2996 | buf = ath10k_wmi_alloc_skb(ar, len); |
2614 | if (!buf) | 2997 | if (!buf) |
2615 | return -ENOMEM; | 2998 | return -ENOMEM; |
2616 | 2999 | ||
@@ -2621,7 +3004,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2621 | goto out; | 3004 | goto out; |
2622 | } | 3005 | } |
2623 | 3006 | ||
2624 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", | 3007 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", |
2625 | ar->wmi.num_mem_chunks); | 3008 | ar->wmi.num_mem_chunks); |
2626 | 3009 | ||
2627 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); | 3010 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); |
@@ -2634,7 +3017,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2634 | cmd->host_mem_chunks[i].req_id = | 3017 | cmd->host_mem_chunks[i].req_id = |
2635 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); | 3018 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); |
2636 | 3019 | ||
2637 | ath10k_dbg(ATH10K_DBG_WMI, | 3020 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2638 | "wmi chunk %d len %d requested, addr 0x%llx\n", | 3021 | "wmi chunk %d len %d requested, addr 0x%llx\n", |
2639 | i, | 3022 | i, |
2640 | ar->wmi.mem_chunks[i].len, | 3023 | ar->wmi.mem_chunks[i].len, |
@@ -2643,7 +3026,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2643 | out: | 3026 | out: |
2644 | memcpy(&cmd->resource_config, &config, sizeof(config)); | 3027 | memcpy(&cmd->resource_config, &config, sizeof(config)); |
2645 | 3028 | ||
2646 | ath10k_dbg(ATH10K_DBG_WMI, "wmi init\n"); | 3029 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); |
2647 | return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); | 3030 | return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); |
2648 | } | 3031 | } |
2649 | 3032 | ||
@@ -2701,7 +3084,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2701 | len = sizeof(*cmd) + | 3084 | len = sizeof(*cmd) + |
2702 | (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); | 3085 | (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); |
2703 | 3086 | ||
2704 | buf = ath10k_wmi_alloc_skb(len); | 3087 | buf = ath10k_wmi_alloc_skb(ar, len); |
2705 | if (!buf) | 3088 | if (!buf) |
2706 | return -ENOMEM; | 3089 | return -ENOMEM; |
2707 | 3090 | ||
@@ -2712,7 +3095,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2712 | goto out; | 3095 | goto out; |
2713 | } | 3096 | } |
2714 | 3097 | ||
2715 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", | 3098 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", |
2716 | ar->wmi.num_mem_chunks); | 3099 | ar->wmi.num_mem_chunks); |
2717 | 3100 | ||
2718 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); | 3101 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); |
@@ -2725,7 +3108,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2725 | cmd->host_mem_chunks[i].req_id = | 3108 | cmd->host_mem_chunks[i].req_id = |
2726 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); | 3109 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); |
2727 | 3110 | ||
2728 | ath10k_dbg(ATH10K_DBG_WMI, | 3111 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2729 | "wmi chunk %d len %d requested, addr 0x%llx\n", | 3112 | "wmi chunk %d len %d requested, addr 0x%llx\n", |
2730 | i, | 3113 | i, |
2731 | ar->wmi.mem_chunks[i].len, | 3114 | ar->wmi.mem_chunks[i].len, |
@@ -2734,7 +3117,98 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2734 | out: | 3117 | out: |
2735 | memcpy(&cmd->resource_config, &config, sizeof(config)); | 3118 | memcpy(&cmd->resource_config, &config, sizeof(config)); |
2736 | 3119 | ||
2737 | ath10k_dbg(ATH10K_DBG_WMI, "wmi init 10x\n"); | 3120 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); |
3121 | return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); | ||
3122 | } | ||
3123 | |||
3124 | static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) | ||
3125 | { | ||
3126 | struct wmi_init_cmd_10_2 *cmd; | ||
3127 | struct sk_buff *buf; | ||
3128 | struct wmi_resource_config_10x config = {}; | ||
3129 | u32 len, val; | ||
3130 | int i; | ||
3131 | |||
3132 | config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); | ||
3133 | config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); | ||
3134 | config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); | ||
3135 | config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); | ||
3136 | config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); | ||
3137 | config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); | ||
3138 | config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); | ||
3139 | config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); | ||
3140 | config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); | ||
3141 | config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); | ||
3142 | config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); | ||
3143 | config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); | ||
3144 | |||
3145 | config.scan_max_pending_reqs = | ||
3146 | __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); | ||
3147 | |||
3148 | config.bmiss_offload_max_vdev = | ||
3149 | __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); | ||
3150 | |||
3151 | config.roam_offload_max_vdev = | ||
3152 | __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); | ||
3153 | |||
3154 | config.roam_offload_max_ap_profiles = | ||
3155 | __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); | ||
3156 | |||
3157 | config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); | ||
3158 | config.num_mcast_table_elems = | ||
3159 | __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); | ||
3160 | |||
3161 | config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); | ||
3162 | config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); | ||
3163 | config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); | ||
3164 | config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); | ||
3165 | config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); | ||
3166 | |||
3167 | val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; | ||
3168 | config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); | ||
3169 | |||
3170 | config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); | ||
3171 | |||
3172 | config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); | ||
3173 | config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); | ||
3174 | |||
3175 | len = sizeof(*cmd) + | ||
3176 | (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); | ||
3177 | |||
3178 | buf = ath10k_wmi_alloc_skb(ar, len); | ||
3179 | if (!buf) | ||
3180 | return -ENOMEM; | ||
3181 | |||
3182 | cmd = (struct wmi_init_cmd_10_2 *)buf->data; | ||
3183 | |||
3184 | if (ar->wmi.num_mem_chunks == 0) { | ||
3185 | cmd->num_host_mem_chunks = 0; | ||
3186 | goto out; | ||
3187 | } | ||
3188 | |||
3189 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", | ||
3190 | ar->wmi.num_mem_chunks); | ||
3191 | |||
3192 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); | ||
3193 | |||
3194 | for (i = 0; i < ar->wmi.num_mem_chunks; i++) { | ||
3195 | cmd->host_mem_chunks[i].ptr = | ||
3196 | __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); | ||
3197 | cmd->host_mem_chunks[i].size = | ||
3198 | __cpu_to_le32(ar->wmi.mem_chunks[i].len); | ||
3199 | cmd->host_mem_chunks[i].req_id = | ||
3200 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); | ||
3201 | |||
3202 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
3203 | "wmi chunk %d len %d requested, addr 0x%llx\n", | ||
3204 | i, | ||
3205 | ar->wmi.mem_chunks[i].len, | ||
3206 | (unsigned long long)ar->wmi.mem_chunks[i].paddr); | ||
3207 | } | ||
3208 | out: | ||
3209 | memcpy(&cmd->resource_config.common, &config, sizeof(config)); | ||
3210 | |||
3211 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); | ||
2738 | return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); | 3212 | return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); |
2739 | } | 3213 | } |
2740 | 3214 | ||
@@ -2742,10 +3216,14 @@ int ath10k_wmi_cmd_init(struct ath10k *ar) | |||
2742 | { | 3216 | { |
2743 | int ret; | 3217 | int ret; |
2744 | 3218 | ||
2745 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) | 3219 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
2746 | ret = ath10k_wmi_10x_cmd_init(ar); | 3220 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) |
2747 | else | 3221 | ret = ath10k_wmi_10_2_cmd_init(ar); |
3222 | else | ||
3223 | ret = ath10k_wmi_10x_cmd_init(ar); | ||
3224 | } else { | ||
2748 | ret = ath10k_wmi_main_cmd_init(ar); | 3225 | ret = ath10k_wmi_main_cmd_init(ar); |
3226 | } | ||
2749 | 3227 | ||
2750 | return ret; | 3228 | return ret; |
2751 | } | 3229 | } |
@@ -2822,7 +3300,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, | |||
2822 | if (len < 0) | 3300 | if (len < 0) |
2823 | return len; /* len contains error code here */ | 3301 | return len; /* len contains error code here */ |
2824 | 3302 | ||
2825 | skb = ath10k_wmi_alloc_skb(len); | 3303 | skb = ath10k_wmi_alloc_skb(ar, len); |
2826 | if (!skb) | 3304 | if (!skb) |
2827 | return -ENOMEM; | 3305 | return -ENOMEM; |
2828 | 3306 | ||
@@ -2865,8 +3343,8 @@ int ath10k_wmi_start_scan(struct ath10k *ar, | |||
2865 | channels->num_chan = __cpu_to_le32(arg->n_channels); | 3343 | channels->num_chan = __cpu_to_le32(arg->n_channels); |
2866 | 3344 | ||
2867 | for (i = 0; i < arg->n_channels; i++) | 3345 | for (i = 0; i < arg->n_channels; i++) |
2868 | channels->channel_list[i] = | 3346 | channels->channel_list[i].freq = |
2869 | __cpu_to_le32(arg->channels[i]); | 3347 | __cpu_to_le16(arg->channels[i]); |
2870 | 3348 | ||
2871 | off += sizeof(*channels); | 3349 | off += sizeof(*channels); |
2872 | off += sizeof(__le32) * arg->n_channels; | 3350 | off += sizeof(__le32) * arg->n_channels; |
@@ -2918,7 +3396,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, | |||
2918 | return -EINVAL; | 3396 | return -EINVAL; |
2919 | } | 3397 | } |
2920 | 3398 | ||
2921 | ath10k_dbg(ATH10K_DBG_WMI, "wmi start scan\n"); | 3399 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); |
2922 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); | 3400 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); |
2923 | } | 3401 | } |
2924 | 3402 | ||
@@ -2960,7 +3438,7 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) | |||
2960 | if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) | 3438 | if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) |
2961 | return -EINVAL; | 3439 | return -EINVAL; |
2962 | 3440 | ||
2963 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3441 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2964 | if (!skb) | 3442 | if (!skb) |
2965 | return -ENOMEM; | 3443 | return -ENOMEM; |
2966 | 3444 | ||
@@ -2976,7 +3454,7 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) | |||
2976 | cmd->scan_id = __cpu_to_le32(scan_id); | 3454 | cmd->scan_id = __cpu_to_le32(scan_id); |
2977 | cmd->scan_req_id = __cpu_to_le32(req_id); | 3455 | cmd->scan_req_id = __cpu_to_le32(req_id); |
2978 | 3456 | ||
2979 | ath10k_dbg(ATH10K_DBG_WMI, | 3457 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2980 | "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", | 3458 | "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", |
2981 | arg->req_id, arg->req_type, arg->u.scan_id); | 3459 | arg->req_id, arg->req_type, arg->u.scan_id); |
2982 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); | 3460 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); |
@@ -2990,7 +3468,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, | |||
2990 | struct wmi_vdev_create_cmd *cmd; | 3468 | struct wmi_vdev_create_cmd *cmd; |
2991 | struct sk_buff *skb; | 3469 | struct sk_buff *skb; |
2992 | 3470 | ||
2993 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3471 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
2994 | if (!skb) | 3472 | if (!skb) |
2995 | return -ENOMEM; | 3473 | return -ENOMEM; |
2996 | 3474 | ||
@@ -3000,7 +3478,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, | |||
3000 | cmd->vdev_subtype = __cpu_to_le32(subtype); | 3478 | cmd->vdev_subtype = __cpu_to_le32(subtype); |
3001 | memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN); | 3479 | memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN); |
3002 | 3480 | ||
3003 | ath10k_dbg(ATH10K_DBG_WMI, | 3481 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3004 | "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", | 3482 | "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", |
3005 | vdev_id, type, subtype, macaddr); | 3483 | vdev_id, type, subtype, macaddr); |
3006 | 3484 | ||
@@ -3012,14 +3490,14 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) | |||
3012 | struct wmi_vdev_delete_cmd *cmd; | 3490 | struct wmi_vdev_delete_cmd *cmd; |
3013 | struct sk_buff *skb; | 3491 | struct sk_buff *skb; |
3014 | 3492 | ||
3015 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3493 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3016 | if (!skb) | 3494 | if (!skb) |
3017 | return -ENOMEM; | 3495 | return -ENOMEM; |
3018 | 3496 | ||
3019 | cmd = (struct wmi_vdev_delete_cmd *)skb->data; | 3497 | cmd = (struct wmi_vdev_delete_cmd *)skb->data; |
3020 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3498 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3021 | 3499 | ||
3022 | ath10k_dbg(ATH10K_DBG_WMI, | 3500 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3023 | "WMI vdev delete id %d\n", vdev_id); | 3501 | "WMI vdev delete id %d\n", vdev_id); |
3024 | 3502 | ||
3025 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); | 3503 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); |
@@ -3052,7 +3530,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
3052 | else | 3530 | else |
3053 | return -EINVAL; /* should not happen, we already check cmd_id */ | 3531 | return -EINVAL; /* should not happen, we already check cmd_id */ |
3054 | 3532 | ||
3055 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3533 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3056 | if (!skb) | 3534 | if (!skb) |
3057 | return -ENOMEM; | 3535 | return -ENOMEM; |
3058 | 3536 | ||
@@ -3090,7 +3568,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
3090 | cmd->chan.reg_classid = arg->channel.reg_class_id; | 3568 | cmd->chan.reg_classid = arg->channel.reg_class_id; |
3091 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; | 3569 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; |
3092 | 3570 | ||
3093 | ath10k_dbg(ATH10K_DBG_WMI, | 3571 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3094 | "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, " | 3572 | "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, " |
3095 | "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id, | 3573 | "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id, |
3096 | flags, arg->channel.freq, arg->channel.mode, | 3574 | flags, arg->channel.freq, arg->channel.mode, |
@@ -3120,14 +3598,14 @@ int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) | |||
3120 | struct wmi_vdev_stop_cmd *cmd; | 3598 | struct wmi_vdev_stop_cmd *cmd; |
3121 | struct sk_buff *skb; | 3599 | struct sk_buff *skb; |
3122 | 3600 | ||
3123 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3601 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3124 | if (!skb) | 3602 | if (!skb) |
3125 | return -ENOMEM; | 3603 | return -ENOMEM; |
3126 | 3604 | ||
3127 | cmd = (struct wmi_vdev_stop_cmd *)skb->data; | 3605 | cmd = (struct wmi_vdev_stop_cmd *)skb->data; |
3128 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3606 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3129 | 3607 | ||
3130 | ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); | 3608 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); |
3131 | 3609 | ||
3132 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); | 3610 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); |
3133 | } | 3611 | } |
@@ -3137,7 +3615,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) | |||
3137 | struct wmi_vdev_up_cmd *cmd; | 3615 | struct wmi_vdev_up_cmd *cmd; |
3138 | struct sk_buff *skb; | 3616 | struct sk_buff *skb; |
3139 | 3617 | ||
3140 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3618 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3141 | if (!skb) | 3619 | if (!skb) |
3142 | return -ENOMEM; | 3620 | return -ENOMEM; |
3143 | 3621 | ||
@@ -3146,7 +3624,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) | |||
3146 | cmd->vdev_assoc_id = __cpu_to_le32(aid); | 3624 | cmd->vdev_assoc_id = __cpu_to_le32(aid); |
3147 | memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); | 3625 | memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); |
3148 | 3626 | ||
3149 | ath10k_dbg(ATH10K_DBG_WMI, | 3627 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3150 | "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", | 3628 | "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", |
3151 | vdev_id, aid, bssid); | 3629 | vdev_id, aid, bssid); |
3152 | 3630 | ||
@@ -3158,14 +3636,14 @@ int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) | |||
3158 | struct wmi_vdev_down_cmd *cmd; | 3636 | struct wmi_vdev_down_cmd *cmd; |
3159 | struct sk_buff *skb; | 3637 | struct sk_buff *skb; |
3160 | 3638 | ||
3161 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3639 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3162 | if (!skb) | 3640 | if (!skb) |
3163 | return -ENOMEM; | 3641 | return -ENOMEM; |
3164 | 3642 | ||
3165 | cmd = (struct wmi_vdev_down_cmd *)skb->data; | 3643 | cmd = (struct wmi_vdev_down_cmd *)skb->data; |
3166 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3644 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3167 | 3645 | ||
3168 | ath10k_dbg(ATH10K_DBG_WMI, | 3646 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3169 | "wmi mgmt vdev down id 0x%x\n", vdev_id); | 3647 | "wmi mgmt vdev down id 0x%x\n", vdev_id); |
3170 | 3648 | ||
3171 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); | 3649 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); |
@@ -3178,13 +3656,13 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, | |||
3178 | struct sk_buff *skb; | 3656 | struct sk_buff *skb; |
3179 | 3657 | ||
3180 | if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { | 3658 | if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { |
3181 | ath10k_dbg(ATH10K_DBG_WMI, | 3659 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3182 | "vdev param %d not supported by firmware\n", | 3660 | "vdev param %d not supported by firmware\n", |
3183 | param_id); | 3661 | param_id); |
3184 | return -EOPNOTSUPP; | 3662 | return -EOPNOTSUPP; |
3185 | } | 3663 | } |
3186 | 3664 | ||
3187 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3665 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3188 | if (!skb) | 3666 | if (!skb) |
3189 | return -ENOMEM; | 3667 | return -ENOMEM; |
3190 | 3668 | ||
@@ -3193,7 +3671,7 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, | |||
3193 | cmd->param_id = __cpu_to_le32(param_id); | 3671 | cmd->param_id = __cpu_to_le32(param_id); |
3194 | cmd->param_value = __cpu_to_le32(param_value); | 3672 | cmd->param_value = __cpu_to_le32(param_value); |
3195 | 3673 | ||
3196 | ath10k_dbg(ATH10K_DBG_WMI, | 3674 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3197 | "wmi vdev id 0x%x set param %d value %d\n", | 3675 | "wmi vdev id 0x%x set param %d value %d\n", |
3198 | vdev_id, param_id, param_value); | 3676 | vdev_id, param_id, param_value); |
3199 | 3677 | ||
@@ -3211,7 +3689,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, | |||
3211 | if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) | 3689 | if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) |
3212 | return -EINVAL; | 3690 | return -EINVAL; |
3213 | 3691 | ||
3214 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->key_len); | 3692 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len); |
3215 | if (!skb) | 3693 | if (!skb) |
3216 | return -ENOMEM; | 3694 | return -ENOMEM; |
3217 | 3695 | ||
@@ -3229,20 +3707,76 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, | |||
3229 | if (arg->key_data) | 3707 | if (arg->key_data) |
3230 | memcpy(cmd->key_data, arg->key_data, arg->key_len); | 3708 | memcpy(cmd->key_data, arg->key_data, arg->key_len); |
3231 | 3709 | ||
3232 | ath10k_dbg(ATH10K_DBG_WMI, | 3710 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3233 | "wmi vdev install key idx %d cipher %d len %d\n", | 3711 | "wmi vdev install key idx %d cipher %d len %d\n", |
3234 | arg->key_idx, arg->key_cipher, arg->key_len); | 3712 | arg->key_idx, arg->key_cipher, arg->key_len); |
3235 | return ath10k_wmi_cmd_send(ar, skb, | 3713 | return ath10k_wmi_cmd_send(ar, skb, |
3236 | ar->wmi.cmd->vdev_install_key_cmdid); | 3714 | ar->wmi.cmd->vdev_install_key_cmdid); |
3237 | } | 3715 | } |
3238 | 3716 | ||
3717 | int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, | ||
3718 | const struct wmi_vdev_spectral_conf_arg *arg) | ||
3719 | { | ||
3720 | struct wmi_vdev_spectral_conf_cmd *cmd; | ||
3721 | struct sk_buff *skb; | ||
3722 | u32 cmdid; | ||
3723 | |||
3724 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); | ||
3725 | if (!skb) | ||
3726 | return -ENOMEM; | ||
3727 | |||
3728 | cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; | ||
3729 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); | ||
3730 | cmd->scan_count = __cpu_to_le32(arg->scan_count); | ||
3731 | cmd->scan_period = __cpu_to_le32(arg->scan_period); | ||
3732 | cmd->scan_priority = __cpu_to_le32(arg->scan_priority); | ||
3733 | cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); | ||
3734 | cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); | ||
3735 | cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); | ||
3736 | cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); | ||
3737 | cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); | ||
3738 | cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); | ||
3739 | cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); | ||
3740 | cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); | ||
3741 | cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); | ||
3742 | cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); | ||
3743 | cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); | ||
3744 | cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); | ||
3745 | cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); | ||
3746 | cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); | ||
3747 | cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); | ||
3748 | |||
3749 | cmdid = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid; | ||
3750 | return ath10k_wmi_cmd_send(ar, skb, cmdid); | ||
3751 | } | ||
3752 | |||
3753 | int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, | ||
3754 | u32 enable) | ||
3755 | { | ||
3756 | struct wmi_vdev_spectral_enable_cmd *cmd; | ||
3757 | struct sk_buff *skb; | ||
3758 | u32 cmdid; | ||
3759 | |||
3760 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); | ||
3761 | if (!skb) | ||
3762 | return -ENOMEM; | ||
3763 | |||
3764 | cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; | ||
3765 | cmd->vdev_id = __cpu_to_le32(vdev_id); | ||
3766 | cmd->trigger_cmd = __cpu_to_le32(trigger); | ||
3767 | cmd->enable_cmd = __cpu_to_le32(enable); | ||
3768 | |||
3769 | cmdid = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid; | ||
3770 | return ath10k_wmi_cmd_send(ar, skb, cmdid); | ||
3771 | } | ||
3772 | |||
3239 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | 3773 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, |
3240 | const u8 peer_addr[ETH_ALEN]) | 3774 | const u8 peer_addr[ETH_ALEN]) |
3241 | { | 3775 | { |
3242 | struct wmi_peer_create_cmd *cmd; | 3776 | struct wmi_peer_create_cmd *cmd; |
3243 | struct sk_buff *skb; | 3777 | struct sk_buff *skb; |
3244 | 3778 | ||
3245 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3779 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3246 | if (!skb) | 3780 | if (!skb) |
3247 | return -ENOMEM; | 3781 | return -ENOMEM; |
3248 | 3782 | ||
@@ -3250,7 +3784,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | |||
3250 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3784 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3251 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3785 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); |
3252 | 3786 | ||
3253 | ath10k_dbg(ATH10K_DBG_WMI, | 3787 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3254 | "wmi peer create vdev_id %d peer_addr %pM\n", | 3788 | "wmi peer create vdev_id %d peer_addr %pM\n", |
3255 | vdev_id, peer_addr); | 3789 | vdev_id, peer_addr); |
3256 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); | 3790 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); |
@@ -3262,7 +3796,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, | |||
3262 | struct wmi_peer_delete_cmd *cmd; | 3796 | struct wmi_peer_delete_cmd *cmd; |
3263 | struct sk_buff *skb; | 3797 | struct sk_buff *skb; |
3264 | 3798 | ||
3265 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3799 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3266 | if (!skb) | 3800 | if (!skb) |
3267 | return -ENOMEM; | 3801 | return -ENOMEM; |
3268 | 3802 | ||
@@ -3270,7 +3804,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, | |||
3270 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3804 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3271 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3805 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); |
3272 | 3806 | ||
3273 | ath10k_dbg(ATH10K_DBG_WMI, | 3807 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3274 | "wmi peer delete vdev_id %d peer_addr %pM\n", | 3808 | "wmi peer delete vdev_id %d peer_addr %pM\n", |
3275 | vdev_id, peer_addr); | 3809 | vdev_id, peer_addr); |
3276 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); | 3810 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); |
@@ -3282,7 +3816,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, | |||
3282 | struct wmi_peer_flush_tids_cmd *cmd; | 3816 | struct wmi_peer_flush_tids_cmd *cmd; |
3283 | struct sk_buff *skb; | 3817 | struct sk_buff *skb; |
3284 | 3818 | ||
3285 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3819 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3286 | if (!skb) | 3820 | if (!skb) |
3287 | return -ENOMEM; | 3821 | return -ENOMEM; |
3288 | 3822 | ||
@@ -3291,7 +3825,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, | |||
3291 | cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); | 3825 | cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); |
3292 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3826 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); |
3293 | 3827 | ||
3294 | ath10k_dbg(ATH10K_DBG_WMI, | 3828 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3295 | "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", | 3829 | "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", |
3296 | vdev_id, peer_addr, tid_bitmap); | 3830 | vdev_id, peer_addr, tid_bitmap); |
3297 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); | 3831 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); |
@@ -3304,7 +3838,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, | |||
3304 | struct wmi_peer_set_param_cmd *cmd; | 3838 | struct wmi_peer_set_param_cmd *cmd; |
3305 | struct sk_buff *skb; | 3839 | struct sk_buff *skb; |
3306 | 3840 | ||
3307 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3841 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3308 | if (!skb) | 3842 | if (!skb) |
3309 | return -ENOMEM; | 3843 | return -ENOMEM; |
3310 | 3844 | ||
@@ -3314,7 +3848,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, | |||
3314 | cmd->param_value = __cpu_to_le32(param_value); | 3848 | cmd->param_value = __cpu_to_le32(param_value); |
3315 | memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3849 | memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); |
3316 | 3850 | ||
3317 | ath10k_dbg(ATH10K_DBG_WMI, | 3851 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3318 | "wmi vdev %d peer 0x%pM set param %d value %d\n", | 3852 | "wmi vdev %d peer 0x%pM set param %d value %d\n", |
3319 | vdev_id, peer_addr, param_id, param_value); | 3853 | vdev_id, peer_addr, param_id, param_value); |
3320 | 3854 | ||
@@ -3327,7 +3861,7 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, | |||
3327 | struct wmi_sta_powersave_mode_cmd *cmd; | 3861 | struct wmi_sta_powersave_mode_cmd *cmd; |
3328 | struct sk_buff *skb; | 3862 | struct sk_buff *skb; |
3329 | 3863 | ||
3330 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3864 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3331 | if (!skb) | 3865 | if (!skb) |
3332 | return -ENOMEM; | 3866 | return -ENOMEM; |
3333 | 3867 | ||
@@ -3335,7 +3869,7 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, | |||
3335 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3869 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3336 | cmd->sta_ps_mode = __cpu_to_le32(psmode); | 3870 | cmd->sta_ps_mode = __cpu_to_le32(psmode); |
3337 | 3871 | ||
3338 | ath10k_dbg(ATH10K_DBG_WMI, | 3872 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3339 | "wmi set powersave id 0x%x mode %d\n", | 3873 | "wmi set powersave id 0x%x mode %d\n", |
3340 | vdev_id, psmode); | 3874 | vdev_id, psmode); |
3341 | 3875 | ||
@@ -3350,7 +3884,7 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, | |||
3350 | struct wmi_sta_powersave_param_cmd *cmd; | 3884 | struct wmi_sta_powersave_param_cmd *cmd; |
3351 | struct sk_buff *skb; | 3885 | struct sk_buff *skb; |
3352 | 3886 | ||
3353 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3887 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3354 | if (!skb) | 3888 | if (!skb) |
3355 | return -ENOMEM; | 3889 | return -ENOMEM; |
3356 | 3890 | ||
@@ -3359,7 +3893,7 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, | |||
3359 | cmd->param_id = __cpu_to_le32(param_id); | 3893 | cmd->param_id = __cpu_to_le32(param_id); |
3360 | cmd->param_value = __cpu_to_le32(value); | 3894 | cmd->param_value = __cpu_to_le32(value); |
3361 | 3895 | ||
3362 | ath10k_dbg(ATH10K_DBG_WMI, | 3896 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3363 | "wmi sta ps param vdev_id 0x%x param %d value %d\n", | 3897 | "wmi sta ps param vdev_id 0x%x param %d value %d\n", |
3364 | vdev_id, param_id, value); | 3898 | vdev_id, param_id, value); |
3365 | return ath10k_wmi_cmd_send(ar, skb, | 3899 | return ath10k_wmi_cmd_send(ar, skb, |
@@ -3375,7 +3909,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, | |||
3375 | if (!mac) | 3909 | if (!mac) |
3376 | return -EINVAL; | 3910 | return -EINVAL; |
3377 | 3911 | ||
3378 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 3912 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3379 | if (!skb) | 3913 | if (!skb) |
3380 | return -ENOMEM; | 3914 | return -ENOMEM; |
3381 | 3915 | ||
@@ -3385,7 +3919,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, | |||
3385 | cmd->param_value = __cpu_to_le32(value); | 3919 | cmd->param_value = __cpu_to_le32(value); |
3386 | memcpy(&cmd->peer_macaddr, mac, ETH_ALEN); | 3920 | memcpy(&cmd->peer_macaddr, mac, ETH_ALEN); |
3387 | 3921 | ||
3388 | ath10k_dbg(ATH10K_DBG_WMI, | 3922 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3389 | "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", | 3923 | "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", |
3390 | vdev_id, param_id, value, mac); | 3924 | vdev_id, param_id, value, mac); |
3391 | 3925 | ||
@@ -3405,7 +3939,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, | |||
3405 | 3939 | ||
3406 | len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel); | 3940 | len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel); |
3407 | 3941 | ||
3408 | skb = ath10k_wmi_alloc_skb(len); | 3942 | skb = ath10k_wmi_alloc_skb(ar, len); |
3409 | if (!skb) | 3943 | if (!skb) |
3410 | return -EINVAL; | 3944 | return -EINVAL; |
3411 | 3945 | ||
@@ -3447,24 +3981,12 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, | |||
3447 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); | 3981 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); |
3448 | } | 3982 | } |
3449 | 3983 | ||
3450 | int ath10k_wmi_peer_assoc(struct ath10k *ar, | 3984 | static void |
3451 | const struct wmi_peer_assoc_complete_arg *arg) | 3985 | ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf, |
3986 | const struct wmi_peer_assoc_complete_arg *arg) | ||
3452 | { | 3987 | { |
3453 | struct wmi_peer_assoc_complete_cmd *cmd; | 3988 | struct wmi_common_peer_assoc_complete_cmd *cmd = buf; |
3454 | struct sk_buff *skb; | ||
3455 | 3989 | ||
3456 | if (arg->peer_mpdu_density > 16) | ||
3457 | return -EINVAL; | ||
3458 | if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) | ||
3459 | return -EINVAL; | ||
3460 | if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) | ||
3461 | return -EINVAL; | ||
3462 | |||
3463 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | ||
3464 | if (!skb) | ||
3465 | return -ENOMEM; | ||
3466 | |||
3467 | cmd = (struct wmi_peer_assoc_complete_cmd *)skb->data; | ||
3468 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); | 3990 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); |
3469 | cmd->peer_new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); | 3991 | cmd->peer_new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); |
3470 | cmd->peer_associd = __cpu_to_le32(arg->peer_aid); | 3992 | cmd->peer_associd = __cpu_to_le32(arg->peer_aid); |
@@ -3499,8 +4021,80 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar, | |||
3499 | __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); | 4021 | __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); |
3500 | cmd->peer_vht_rates.tx_mcs_set = | 4022 | cmd->peer_vht_rates.tx_mcs_set = |
3501 | __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); | 4023 | __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); |
4024 | } | ||
4025 | |||
4026 | static void | ||
4027 | ath10k_wmi_peer_assoc_fill_main(struct ath10k *ar, void *buf, | ||
4028 | const struct wmi_peer_assoc_complete_arg *arg) | ||
4029 | { | ||
4030 | struct wmi_main_peer_assoc_complete_cmd *cmd = buf; | ||
4031 | |||
4032 | ath10k_wmi_peer_assoc_fill(ar, buf, arg); | ||
4033 | memset(cmd->peer_ht_info, 0, sizeof(cmd->peer_ht_info)); | ||
4034 | } | ||
4035 | |||
4036 | static void | ||
4037 | ath10k_wmi_peer_assoc_fill_10_1(struct ath10k *ar, void *buf, | ||
4038 | const struct wmi_peer_assoc_complete_arg *arg) | ||
4039 | { | ||
4040 | ath10k_wmi_peer_assoc_fill(ar, buf, arg); | ||
4041 | } | ||
4042 | |||
4043 | static void | ||
4044 | ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf, | ||
4045 | const struct wmi_peer_assoc_complete_arg *arg) | ||
4046 | { | ||
4047 | struct wmi_10_2_peer_assoc_complete_cmd *cmd = buf; | ||
4048 | int max_mcs, max_nss; | ||
4049 | u32 info0; | ||
4050 | |||
4051 | /* TODO: Is using max values okay with firmware? */ | ||
4052 | max_mcs = 0xf; | ||
4053 | max_nss = 0xf; | ||
4054 | |||
4055 | info0 = SM(max_mcs, WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX) | | ||
4056 | SM(max_nss, WMI_PEER_ASSOC_INFO0_MAX_NSS); | ||
4057 | |||
4058 | ath10k_wmi_peer_assoc_fill(ar, buf, arg); | ||
4059 | cmd->info0 = __cpu_to_le32(info0); | ||
4060 | } | ||
4061 | |||
4062 | int ath10k_wmi_peer_assoc(struct ath10k *ar, | ||
4063 | const struct wmi_peer_assoc_complete_arg *arg) | ||
4064 | { | ||
4065 | struct sk_buff *skb; | ||
4066 | int len; | ||
4067 | |||
4068 | if (arg->peer_mpdu_density > 16) | ||
4069 | return -EINVAL; | ||
4070 | if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) | ||
4071 | return -EINVAL; | ||
4072 | if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) | ||
4073 | return -EINVAL; | ||
4074 | |||
4075 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | ||
4076 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) | ||
4077 | len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); | ||
4078 | else | ||
4079 | len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); | ||
4080 | } else { | ||
4081 | len = sizeof(struct wmi_main_peer_assoc_complete_cmd); | ||
4082 | } | ||
4083 | |||
4084 | skb = ath10k_wmi_alloc_skb(ar, len); | ||
4085 | if (!skb) | ||
4086 | return -ENOMEM; | ||
4087 | |||
4088 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | ||
4089 | if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) | ||
4090 | ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); | ||
4091 | else | ||
4092 | ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); | ||
4093 | } else { | ||
4094 | ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); | ||
4095 | } | ||
3502 | 4096 | ||
3503 | ath10k_dbg(ATH10K_DBG_WMI, | 4097 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3504 | "wmi peer assoc vdev %d addr %pM (%s)\n", | 4098 | "wmi peer assoc vdev %d addr %pM (%s)\n", |
3505 | arg->vdev_id, arg->addr, | 4099 | arg->vdev_id, arg->addr, |
3506 | arg->peer_reassoc ? "reassociate" : "new"); | 4100 | arg->peer_reassoc ? "reassociate" : "new"); |
@@ -3518,7 +4112,7 @@ int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) | |||
3518 | int ret; | 4112 | int ret; |
3519 | u16 fc; | 4113 | u16 fc; |
3520 | 4114 | ||
3521 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 4115 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3522 | if (!skb) | 4116 | if (!skb) |
3523 | return -ENOMEM; | 4117 | return -ENOMEM; |
3524 | 4118 | ||
@@ -3532,6 +4126,7 @@ int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) | |||
3532 | cmd->msdu_id = 0; | 4126 | cmd->msdu_id = 0; |
3533 | cmd->frame_control = __cpu_to_le32(fc); | 4127 | cmd->frame_control = __cpu_to_le32(fc); |
3534 | cmd->flags = 0; | 4128 | cmd->flags = 0; |
4129 | cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA); | ||
3535 | 4130 | ||
3536 | if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) | 4131 | if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) |
3537 | cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); | 4132 | cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); |
@@ -3565,7 +4160,7 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, | |||
3565 | struct wmi_pdev_set_wmm_params *cmd; | 4160 | struct wmi_pdev_set_wmm_params *cmd; |
3566 | struct sk_buff *skb; | 4161 | struct sk_buff *skb; |
3567 | 4162 | ||
3568 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 4163 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3569 | if (!skb) | 4164 | if (!skb) |
3570 | return -ENOMEM; | 4165 | return -ENOMEM; |
3571 | 4166 | ||
@@ -3575,7 +4170,7 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, | |||
3575 | ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); | 4170 | ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); |
3576 | ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); | 4171 | ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); |
3577 | 4172 | ||
3578 | ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); | 4173 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); |
3579 | return ath10k_wmi_cmd_send(ar, skb, | 4174 | return ath10k_wmi_cmd_send(ar, skb, |
3580 | ar->wmi.cmd->pdev_set_wmm_params_cmdid); | 4175 | ar->wmi.cmd->pdev_set_wmm_params_cmdid); |
3581 | } | 4176 | } |
@@ -3585,14 +4180,14 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) | |||
3585 | struct wmi_request_stats_cmd *cmd; | 4180 | struct wmi_request_stats_cmd *cmd; |
3586 | struct sk_buff *skb; | 4181 | struct sk_buff *skb; |
3587 | 4182 | ||
3588 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 4183 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3589 | if (!skb) | 4184 | if (!skb) |
3590 | return -ENOMEM; | 4185 | return -ENOMEM; |
3591 | 4186 | ||
3592 | cmd = (struct wmi_request_stats_cmd *)skb->data; | 4187 | cmd = (struct wmi_request_stats_cmd *)skb->data; |
3593 | cmd->stats_id = __cpu_to_le32(stats_id); | 4188 | cmd->stats_id = __cpu_to_le32(stats_id); |
3594 | 4189 | ||
3595 | ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); | 4190 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); |
3596 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); | 4191 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); |
3597 | } | 4192 | } |
3598 | 4193 | ||
@@ -3602,7 +4197,7 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, | |||
3602 | struct wmi_force_fw_hang_cmd *cmd; | 4197 | struct wmi_force_fw_hang_cmd *cmd; |
3603 | struct sk_buff *skb; | 4198 | struct sk_buff *skb; |
3604 | 4199 | ||
3605 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 4200 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3606 | if (!skb) | 4201 | if (!skb) |
3607 | return -ENOMEM; | 4202 | return -ENOMEM; |
3608 | 4203 | ||
@@ -3610,7 +4205,7 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, | |||
3610 | cmd->type = __cpu_to_le32(type); | 4205 | cmd->type = __cpu_to_le32(type); |
3611 | cmd->delay_ms = __cpu_to_le32(delay_ms); | 4206 | cmd->delay_ms = __cpu_to_le32(delay_ms); |
3612 | 4207 | ||
3613 | ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", | 4208 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", |
3614 | type, delay_ms); | 4209 | type, delay_ms); |
3615 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); | 4210 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); |
3616 | } | 4211 | } |
@@ -3621,7 +4216,7 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) | |||
3621 | struct sk_buff *skb; | 4216 | struct sk_buff *skb; |
3622 | u32 cfg; | 4217 | u32 cfg; |
3623 | 4218 | ||
3624 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | 4219 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); |
3625 | if (!skb) | 4220 | if (!skb) |
3626 | return -ENOMEM; | 4221 | return -ENOMEM; |
3627 | 4222 | ||
@@ -3642,7 +4237,7 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) | |||
3642 | cmd->config_enable = __cpu_to_le32(cfg); | 4237 | cmd->config_enable = __cpu_to_le32(cfg); |
3643 | cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK); | 4238 | cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK); |
3644 | 4239 | ||
3645 | ath10k_dbg(ATH10K_DBG_WMI, | 4240 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3646 | "wmi dbglog cfg modules %08x %08x config %08x %08x\n", | 4241 | "wmi dbglog cfg modules %08x %08x config %08x %08x\n", |
3647 | __le32_to_cpu(cmd->module_enable), | 4242 | __le32_to_cpu(cmd->module_enable), |
3648 | __le32_to_cpu(cmd->module_valid), | 4243 | __le32_to_cpu(cmd->module_valid), |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index e93df2c10413..e70836586756 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -73,116 +73,279 @@ struct wmi_cmd_hdr { | |||
73 | #define HTC_PROTOCOL_VERSION 0x0002 | 73 | #define HTC_PROTOCOL_VERSION 0x0002 |
74 | #define WMI_PROTOCOL_VERSION 0x0002 | 74 | #define WMI_PROTOCOL_VERSION 0x0002 |
75 | 75 | ||
76 | enum wmi_service_id { | 76 | enum wmi_service { |
77 | WMI_SERVICE_BEACON_OFFLOAD = 0, /* beacon offload */ | 77 | WMI_SERVICE_BEACON_OFFLOAD = 0, |
78 | WMI_SERVICE_SCAN_OFFLOAD, /* scan offload */ | 78 | WMI_SERVICE_SCAN_OFFLOAD, |
79 | WMI_SERVICE_ROAM_OFFLOAD, /* roam offload */ | 79 | WMI_SERVICE_ROAM_OFFLOAD, |
80 | WMI_SERVICE_BCN_MISS_OFFLOAD, /* beacon miss offload */ | 80 | WMI_SERVICE_BCN_MISS_OFFLOAD, |
81 | WMI_SERVICE_STA_PWRSAVE, /* fake sleep + basic power save */ | 81 | WMI_SERVICE_STA_PWRSAVE, |
82 | WMI_SERVICE_STA_ADVANCED_PWRSAVE, /* uapsd, pspoll, force sleep */ | 82 | WMI_SERVICE_STA_ADVANCED_PWRSAVE, |
83 | WMI_SERVICE_AP_UAPSD, /* uapsd on AP */ | 83 | WMI_SERVICE_AP_UAPSD, |
84 | WMI_SERVICE_AP_DFS, /* DFS on AP */ | 84 | WMI_SERVICE_AP_DFS, |
85 | WMI_SERVICE_11AC, /* supports 11ac */ | 85 | WMI_SERVICE_11AC, |
86 | WMI_SERVICE_BLOCKACK, /* Supports triggering ADDBA/DELBA from host*/ | 86 | WMI_SERVICE_BLOCKACK, |
87 | WMI_SERVICE_PHYERR, /* PHY error */ | 87 | WMI_SERVICE_PHYERR, |
88 | WMI_SERVICE_BCN_FILTER, /* Beacon filter support */ | 88 | WMI_SERVICE_BCN_FILTER, |
89 | WMI_SERVICE_RTT, /* RTT (round trip time) support */ | 89 | WMI_SERVICE_RTT, |
90 | WMI_SERVICE_RATECTRL, /* Rate-control */ | 90 | WMI_SERVICE_RATECTRL, |
91 | WMI_SERVICE_WOW, /* WOW Support */ | 91 | WMI_SERVICE_WOW, |
92 | WMI_SERVICE_RATECTRL_CACHE, /* Rate-control caching */ | 92 | WMI_SERVICE_RATECTRL_CACHE, |
93 | WMI_SERVICE_IRAM_TIDS, /* TIDs in IRAM */ | 93 | WMI_SERVICE_IRAM_TIDS, |
94 | WMI_SERVICE_ARPNS_OFFLOAD, /* ARP NS Offload support */ | 94 | WMI_SERVICE_ARPNS_OFFLOAD, |
95 | WMI_SERVICE_NLO, /* Network list offload service */ | 95 | WMI_SERVICE_NLO, |
96 | WMI_SERVICE_GTK_OFFLOAD, /* GTK offload */ | 96 | WMI_SERVICE_GTK_OFFLOAD, |
97 | WMI_SERVICE_SCAN_SCH, /* Scan Scheduler Service */ | 97 | WMI_SERVICE_SCAN_SCH, |
98 | WMI_SERVICE_CSA_OFFLOAD, /* CSA offload service */ | 98 | WMI_SERVICE_CSA_OFFLOAD, |
99 | WMI_SERVICE_CHATTER, /* Chatter service */ | 99 | WMI_SERVICE_CHATTER, |
100 | WMI_SERVICE_COEX_FREQAVOID, /* FW report freq range to avoid */ | 100 | WMI_SERVICE_COEX_FREQAVOID, |
101 | WMI_SERVICE_PACKET_POWER_SAVE, /* packet power save service */ | 101 | WMI_SERVICE_PACKET_POWER_SAVE, |
102 | WMI_SERVICE_FORCE_FW_HANG, /* To test fw recovery mechanism */ | 102 | WMI_SERVICE_FORCE_FW_HANG, |
103 | WMI_SERVICE_GPIO, /* GPIO service */ | 103 | WMI_SERVICE_GPIO, |
104 | WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, /* Modulated DTIM support */ | 104 | WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, |
105 | WMI_STA_UAPSD_BASIC_AUTO_TRIG, /* UAPSD AC Trigger Generation */ | 105 | WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, |
106 | WMI_STA_UAPSD_VAR_AUTO_TRIG, /* -do- */ | 106 | WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, |
107 | WMI_SERVICE_STA_KEEP_ALIVE, /* STA keep alive mechanism support */ | 107 | WMI_SERVICE_STA_KEEP_ALIVE, |
108 | WMI_SERVICE_TX_ENCAP, /* Packet type for TX encapsulation */ | 108 | WMI_SERVICE_TX_ENCAP, |
109 | 109 | WMI_SERVICE_BURST, | |
110 | WMI_SERVICE_LAST, | 110 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, |
111 | WMI_MAX_SERVICE = 64 /* max service */ | 111 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, |
112 | }; | ||
113 | |||
114 | enum wmi_10x_service { | ||
115 | WMI_10X_SERVICE_BEACON_OFFLOAD = 0, | ||
116 | WMI_10X_SERVICE_SCAN_OFFLOAD, | ||
117 | WMI_10X_SERVICE_ROAM_OFFLOAD, | ||
118 | WMI_10X_SERVICE_BCN_MISS_OFFLOAD, | ||
119 | WMI_10X_SERVICE_STA_PWRSAVE, | ||
120 | WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, | ||
121 | WMI_10X_SERVICE_AP_UAPSD, | ||
122 | WMI_10X_SERVICE_AP_DFS, | ||
123 | WMI_10X_SERVICE_11AC, | ||
124 | WMI_10X_SERVICE_BLOCKACK, | ||
125 | WMI_10X_SERVICE_PHYERR, | ||
126 | WMI_10X_SERVICE_BCN_FILTER, | ||
127 | WMI_10X_SERVICE_RTT, | ||
128 | WMI_10X_SERVICE_RATECTRL, | ||
129 | WMI_10X_SERVICE_WOW, | ||
130 | WMI_10X_SERVICE_RATECTRL_CACHE, | ||
131 | WMI_10X_SERVICE_IRAM_TIDS, | ||
132 | WMI_10X_SERVICE_BURST, | ||
133 | |||
134 | /* introduced in 10.2 */ | ||
135 | WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, | ||
136 | WMI_10X_SERVICE_FORCE_FW_HANG, | ||
137 | WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, | ||
138 | }; | ||
139 | |||
140 | enum wmi_main_service { | ||
141 | WMI_MAIN_SERVICE_BEACON_OFFLOAD = 0, | ||
142 | WMI_MAIN_SERVICE_SCAN_OFFLOAD, | ||
143 | WMI_MAIN_SERVICE_ROAM_OFFLOAD, | ||
144 | WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, | ||
145 | WMI_MAIN_SERVICE_STA_PWRSAVE, | ||
146 | WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, | ||
147 | WMI_MAIN_SERVICE_AP_UAPSD, | ||
148 | WMI_MAIN_SERVICE_AP_DFS, | ||
149 | WMI_MAIN_SERVICE_11AC, | ||
150 | WMI_MAIN_SERVICE_BLOCKACK, | ||
151 | WMI_MAIN_SERVICE_PHYERR, | ||
152 | WMI_MAIN_SERVICE_BCN_FILTER, | ||
153 | WMI_MAIN_SERVICE_RTT, | ||
154 | WMI_MAIN_SERVICE_RATECTRL, | ||
155 | WMI_MAIN_SERVICE_WOW, | ||
156 | WMI_MAIN_SERVICE_RATECTRL_CACHE, | ||
157 | WMI_MAIN_SERVICE_IRAM_TIDS, | ||
158 | WMI_MAIN_SERVICE_ARPNS_OFFLOAD, | ||
159 | WMI_MAIN_SERVICE_NLO, | ||
160 | WMI_MAIN_SERVICE_GTK_OFFLOAD, | ||
161 | WMI_MAIN_SERVICE_SCAN_SCH, | ||
162 | WMI_MAIN_SERVICE_CSA_OFFLOAD, | ||
163 | WMI_MAIN_SERVICE_CHATTER, | ||
164 | WMI_MAIN_SERVICE_COEX_FREQAVOID, | ||
165 | WMI_MAIN_SERVICE_PACKET_POWER_SAVE, | ||
166 | WMI_MAIN_SERVICE_FORCE_FW_HANG, | ||
167 | WMI_MAIN_SERVICE_GPIO, | ||
168 | WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, | ||
169 | WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, | ||
170 | WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, | ||
171 | WMI_MAIN_SERVICE_STA_KEEP_ALIVE, | ||
172 | WMI_MAIN_SERVICE_TX_ENCAP, | ||
112 | }; | 173 | }; |
113 | 174 | ||
114 | static inline char *wmi_service_name(int service_id) | 175 | static inline char *wmi_service_name(int service_id) |
115 | { | 176 | { |
177 | #define SVCSTR(x) case x: return #x | ||
178 | |||
116 | switch (service_id) { | 179 | switch (service_id) { |
117 | case WMI_SERVICE_BEACON_OFFLOAD: | 180 | SVCSTR(WMI_SERVICE_BEACON_OFFLOAD); |
118 | return "BEACON_OFFLOAD"; | 181 | SVCSTR(WMI_SERVICE_SCAN_OFFLOAD); |
119 | case WMI_SERVICE_SCAN_OFFLOAD: | 182 | SVCSTR(WMI_SERVICE_ROAM_OFFLOAD); |
120 | return "SCAN_OFFLOAD"; | 183 | SVCSTR(WMI_SERVICE_BCN_MISS_OFFLOAD); |
121 | case WMI_SERVICE_ROAM_OFFLOAD: | 184 | SVCSTR(WMI_SERVICE_STA_PWRSAVE); |
122 | return "ROAM_OFFLOAD"; | 185 | SVCSTR(WMI_SERVICE_STA_ADVANCED_PWRSAVE); |
123 | case WMI_SERVICE_BCN_MISS_OFFLOAD: | 186 | SVCSTR(WMI_SERVICE_AP_UAPSD); |
124 | return "BCN_MISS_OFFLOAD"; | 187 | SVCSTR(WMI_SERVICE_AP_DFS); |
125 | case WMI_SERVICE_STA_PWRSAVE: | 188 | SVCSTR(WMI_SERVICE_11AC); |
126 | return "STA_PWRSAVE"; | 189 | SVCSTR(WMI_SERVICE_BLOCKACK); |
127 | case WMI_SERVICE_STA_ADVANCED_PWRSAVE: | 190 | SVCSTR(WMI_SERVICE_PHYERR); |
128 | return "STA_ADVANCED_PWRSAVE"; | 191 | SVCSTR(WMI_SERVICE_BCN_FILTER); |
129 | case WMI_SERVICE_AP_UAPSD: | 192 | SVCSTR(WMI_SERVICE_RTT); |
130 | return "AP_UAPSD"; | 193 | SVCSTR(WMI_SERVICE_RATECTRL); |
131 | case WMI_SERVICE_AP_DFS: | 194 | SVCSTR(WMI_SERVICE_WOW); |
132 | return "AP_DFS"; | 195 | SVCSTR(WMI_SERVICE_RATECTRL_CACHE); |
133 | case WMI_SERVICE_11AC: | 196 | SVCSTR(WMI_SERVICE_IRAM_TIDS); |
134 | return "11AC"; | 197 | SVCSTR(WMI_SERVICE_ARPNS_OFFLOAD); |
135 | case WMI_SERVICE_BLOCKACK: | 198 | SVCSTR(WMI_SERVICE_NLO); |
136 | return "BLOCKACK"; | 199 | SVCSTR(WMI_SERVICE_GTK_OFFLOAD); |
137 | case WMI_SERVICE_PHYERR: | 200 | SVCSTR(WMI_SERVICE_SCAN_SCH); |
138 | return "PHYERR"; | 201 | SVCSTR(WMI_SERVICE_CSA_OFFLOAD); |
139 | case WMI_SERVICE_BCN_FILTER: | 202 | SVCSTR(WMI_SERVICE_CHATTER); |
140 | return "BCN_FILTER"; | 203 | SVCSTR(WMI_SERVICE_COEX_FREQAVOID); |
141 | case WMI_SERVICE_RTT: | 204 | SVCSTR(WMI_SERVICE_PACKET_POWER_SAVE); |
142 | return "RTT"; | 205 | SVCSTR(WMI_SERVICE_FORCE_FW_HANG); |
143 | case WMI_SERVICE_RATECTRL: | 206 | SVCSTR(WMI_SERVICE_GPIO); |
144 | return "RATECTRL"; | 207 | SVCSTR(WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); |
145 | case WMI_SERVICE_WOW: | 208 | SVCSTR(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); |
146 | return "WOW"; | 209 | SVCSTR(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); |
147 | case WMI_SERVICE_RATECTRL_CACHE: | 210 | SVCSTR(WMI_SERVICE_STA_KEEP_ALIVE); |
148 | return "RATECTRL CACHE"; | 211 | SVCSTR(WMI_SERVICE_TX_ENCAP); |
149 | case WMI_SERVICE_IRAM_TIDS: | 212 | SVCSTR(WMI_SERVICE_BURST); |
150 | return "IRAM TIDS"; | 213 | SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); |
151 | case WMI_SERVICE_ARPNS_OFFLOAD: | 214 | SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); |
152 | return "ARPNS_OFFLOAD"; | ||
153 | case WMI_SERVICE_NLO: | ||
154 | return "NLO"; | ||
155 | case WMI_SERVICE_GTK_OFFLOAD: | ||
156 | return "GTK_OFFLOAD"; | ||
157 | case WMI_SERVICE_SCAN_SCH: | ||
158 | return "SCAN_SCH"; | ||
159 | case WMI_SERVICE_CSA_OFFLOAD: | ||
160 | return "CSA_OFFLOAD"; | ||
161 | case WMI_SERVICE_CHATTER: | ||
162 | return "CHATTER"; | ||
163 | case WMI_SERVICE_COEX_FREQAVOID: | ||
164 | return "COEX_FREQAVOID"; | ||
165 | case WMI_SERVICE_PACKET_POWER_SAVE: | ||
166 | return "PACKET_POWER_SAVE"; | ||
167 | case WMI_SERVICE_FORCE_FW_HANG: | ||
168 | return "FORCE FW HANG"; | ||
169 | case WMI_SERVICE_GPIO: | ||
170 | return "GPIO"; | ||
171 | case WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM: | ||
172 | return "MODULATED DTIM"; | ||
173 | case WMI_STA_UAPSD_BASIC_AUTO_TRIG: | ||
174 | return "BASIC UAPSD"; | ||
175 | case WMI_STA_UAPSD_VAR_AUTO_TRIG: | ||
176 | return "VAR UAPSD"; | ||
177 | case WMI_SERVICE_STA_KEEP_ALIVE: | ||
178 | return "STA KEEP ALIVE"; | ||
179 | case WMI_SERVICE_TX_ENCAP: | ||
180 | return "TX ENCAP"; | ||
181 | default: | 215 | default: |
182 | return "UNKNOWN SERVICE\n"; | 216 | return NULL; |
183 | } | 217 | } |
218 | |||
219 | #undef SVCSTR | ||
220 | } | ||
221 | |||
222 | #define WMI_MAX_SERVICE 64 | ||
223 | |||
224 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ | ||
225 | (__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ | ||
226 | BIT((svc_id)%(sizeof(u32)))) | ||
227 | |||
228 | #define SVCMAP(x, y) \ | ||
229 | do { \ | ||
230 | if (WMI_SERVICE_IS_ENABLED((in), (x))) \ | ||
231 | __set_bit(y, out); \ | ||
232 | } while (0) | ||
233 | |||
234 | static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out) | ||
235 | { | ||
236 | SVCMAP(WMI_10X_SERVICE_BEACON_OFFLOAD, | ||
237 | WMI_SERVICE_BEACON_OFFLOAD); | ||
238 | SVCMAP(WMI_10X_SERVICE_SCAN_OFFLOAD, | ||
239 | WMI_SERVICE_SCAN_OFFLOAD); | ||
240 | SVCMAP(WMI_10X_SERVICE_ROAM_OFFLOAD, | ||
241 | WMI_SERVICE_ROAM_OFFLOAD); | ||
242 | SVCMAP(WMI_10X_SERVICE_BCN_MISS_OFFLOAD, | ||
243 | WMI_SERVICE_BCN_MISS_OFFLOAD); | ||
244 | SVCMAP(WMI_10X_SERVICE_STA_PWRSAVE, | ||
245 | WMI_SERVICE_STA_PWRSAVE); | ||
246 | SVCMAP(WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, | ||
247 | WMI_SERVICE_STA_ADVANCED_PWRSAVE); | ||
248 | SVCMAP(WMI_10X_SERVICE_AP_UAPSD, | ||
249 | WMI_SERVICE_AP_UAPSD); | ||
250 | SVCMAP(WMI_10X_SERVICE_AP_DFS, | ||
251 | WMI_SERVICE_AP_DFS); | ||
252 | SVCMAP(WMI_10X_SERVICE_11AC, | ||
253 | WMI_SERVICE_11AC); | ||
254 | SVCMAP(WMI_10X_SERVICE_BLOCKACK, | ||
255 | WMI_SERVICE_BLOCKACK); | ||
256 | SVCMAP(WMI_10X_SERVICE_PHYERR, | ||
257 | WMI_SERVICE_PHYERR); | ||
258 | SVCMAP(WMI_10X_SERVICE_BCN_FILTER, | ||
259 | WMI_SERVICE_BCN_FILTER); | ||
260 | SVCMAP(WMI_10X_SERVICE_RTT, | ||
261 | WMI_SERVICE_RTT); | ||
262 | SVCMAP(WMI_10X_SERVICE_RATECTRL, | ||
263 | WMI_SERVICE_RATECTRL); | ||
264 | SVCMAP(WMI_10X_SERVICE_WOW, | ||
265 | WMI_SERVICE_WOW); | ||
266 | SVCMAP(WMI_10X_SERVICE_RATECTRL_CACHE, | ||
267 | WMI_SERVICE_RATECTRL_CACHE); | ||
268 | SVCMAP(WMI_10X_SERVICE_IRAM_TIDS, | ||
269 | WMI_SERVICE_IRAM_TIDS); | ||
270 | SVCMAP(WMI_10X_SERVICE_BURST, | ||
271 | WMI_SERVICE_BURST); | ||
272 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, | ||
273 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); | ||
274 | SVCMAP(WMI_10X_SERVICE_FORCE_FW_HANG, | ||
275 | WMI_SERVICE_FORCE_FW_HANG); | ||
276 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, | ||
277 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); | ||
278 | } | ||
279 | |||
280 | static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out) | ||
281 | { | ||
282 | SVCMAP(WMI_MAIN_SERVICE_BEACON_OFFLOAD, | ||
283 | WMI_SERVICE_BEACON_OFFLOAD); | ||
284 | SVCMAP(WMI_MAIN_SERVICE_SCAN_OFFLOAD, | ||
285 | WMI_SERVICE_SCAN_OFFLOAD); | ||
286 | SVCMAP(WMI_MAIN_SERVICE_ROAM_OFFLOAD, | ||
287 | WMI_SERVICE_ROAM_OFFLOAD); | ||
288 | SVCMAP(WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, | ||
289 | WMI_SERVICE_BCN_MISS_OFFLOAD); | ||
290 | SVCMAP(WMI_MAIN_SERVICE_STA_PWRSAVE, | ||
291 | WMI_SERVICE_STA_PWRSAVE); | ||
292 | SVCMAP(WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, | ||
293 | WMI_SERVICE_STA_ADVANCED_PWRSAVE); | ||
294 | SVCMAP(WMI_MAIN_SERVICE_AP_UAPSD, | ||
295 | WMI_SERVICE_AP_UAPSD); | ||
296 | SVCMAP(WMI_MAIN_SERVICE_AP_DFS, | ||
297 | WMI_SERVICE_AP_DFS); | ||
298 | SVCMAP(WMI_MAIN_SERVICE_11AC, | ||
299 | WMI_SERVICE_11AC); | ||
300 | SVCMAP(WMI_MAIN_SERVICE_BLOCKACK, | ||
301 | WMI_SERVICE_BLOCKACK); | ||
302 | SVCMAP(WMI_MAIN_SERVICE_PHYERR, | ||
303 | WMI_SERVICE_PHYERR); | ||
304 | SVCMAP(WMI_MAIN_SERVICE_BCN_FILTER, | ||
305 | WMI_SERVICE_BCN_FILTER); | ||
306 | SVCMAP(WMI_MAIN_SERVICE_RTT, | ||
307 | WMI_SERVICE_RTT); | ||
308 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL, | ||
309 | WMI_SERVICE_RATECTRL); | ||
310 | SVCMAP(WMI_MAIN_SERVICE_WOW, | ||
311 | WMI_SERVICE_WOW); | ||
312 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL_CACHE, | ||
313 | WMI_SERVICE_RATECTRL_CACHE); | ||
314 | SVCMAP(WMI_MAIN_SERVICE_IRAM_TIDS, | ||
315 | WMI_SERVICE_IRAM_TIDS); | ||
316 | SVCMAP(WMI_MAIN_SERVICE_ARPNS_OFFLOAD, | ||
317 | WMI_SERVICE_ARPNS_OFFLOAD); | ||
318 | SVCMAP(WMI_MAIN_SERVICE_NLO, | ||
319 | WMI_SERVICE_NLO); | ||
320 | SVCMAP(WMI_MAIN_SERVICE_GTK_OFFLOAD, | ||
321 | WMI_SERVICE_GTK_OFFLOAD); | ||
322 | SVCMAP(WMI_MAIN_SERVICE_SCAN_SCH, | ||
323 | WMI_SERVICE_SCAN_SCH); | ||
324 | SVCMAP(WMI_MAIN_SERVICE_CSA_OFFLOAD, | ||
325 | WMI_SERVICE_CSA_OFFLOAD); | ||
326 | SVCMAP(WMI_MAIN_SERVICE_CHATTER, | ||
327 | WMI_SERVICE_CHATTER); | ||
328 | SVCMAP(WMI_MAIN_SERVICE_COEX_FREQAVOID, | ||
329 | WMI_SERVICE_COEX_FREQAVOID); | ||
330 | SVCMAP(WMI_MAIN_SERVICE_PACKET_POWER_SAVE, | ||
331 | WMI_SERVICE_PACKET_POWER_SAVE); | ||
332 | SVCMAP(WMI_MAIN_SERVICE_FORCE_FW_HANG, | ||
333 | WMI_SERVICE_FORCE_FW_HANG); | ||
334 | SVCMAP(WMI_MAIN_SERVICE_GPIO, | ||
335 | WMI_SERVICE_GPIO); | ||
336 | SVCMAP(WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, | ||
337 | WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); | ||
338 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, | ||
339 | WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); | ||
340 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, | ||
341 | WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); | ||
342 | SVCMAP(WMI_MAIN_SERVICE_STA_KEEP_ALIVE, | ||
343 | WMI_SERVICE_STA_KEEP_ALIVE); | ||
344 | SVCMAP(WMI_MAIN_SERVICE_TX_ENCAP, | ||
345 | WMI_SERVICE_TX_ENCAP); | ||
184 | } | 346 | } |
185 | 347 | ||
348 | #undef SVCMAP | ||
186 | 349 | ||
187 | #define WMI_SERVICE_BM_SIZE \ | 350 | #define WMI_SERVICE_BM_SIZE \ |
188 | ((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32)) | 351 | ((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32)) |
@@ -803,6 +966,159 @@ enum wmi_10x_event_id { | |||
803 | WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID-1, | 966 | WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID-1, |
804 | }; | 967 | }; |
805 | 968 | ||
969 | enum wmi_10_2_cmd_id { | ||
970 | WMI_10_2_START_CMDID = 0x9000, | ||
971 | WMI_10_2_END_CMDID = 0x9FFF, | ||
972 | WMI_10_2_INIT_CMDID, | ||
973 | WMI_10_2_START_SCAN_CMDID = WMI_10_2_START_CMDID, | ||
974 | WMI_10_2_STOP_SCAN_CMDID, | ||
975 | WMI_10_2_SCAN_CHAN_LIST_CMDID, | ||
976 | WMI_10_2_ECHO_CMDID, | ||
977 | WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, | ||
978 | WMI_10_2_PDEV_SET_CHANNEL_CMDID, | ||
979 | WMI_10_2_PDEV_SET_PARAM_CMDID, | ||
980 | WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, | ||
981 | WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, | ||
982 | WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, | ||
983 | WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, | ||
984 | WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, | ||
985 | WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, | ||
986 | WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, | ||
987 | WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, | ||
988 | WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, | ||
989 | WMI_10_2_VDEV_CREATE_CMDID, | ||
990 | WMI_10_2_VDEV_DELETE_CMDID, | ||
991 | WMI_10_2_VDEV_START_REQUEST_CMDID, | ||
992 | WMI_10_2_VDEV_RESTART_REQUEST_CMDID, | ||
993 | WMI_10_2_VDEV_UP_CMDID, | ||
994 | WMI_10_2_VDEV_STOP_CMDID, | ||
995 | WMI_10_2_VDEV_DOWN_CMDID, | ||
996 | WMI_10_2_VDEV_STANDBY_RESPONSE_CMDID, | ||
997 | WMI_10_2_VDEV_RESUME_RESPONSE_CMDID, | ||
998 | WMI_10_2_VDEV_SET_PARAM_CMDID, | ||
999 | WMI_10_2_VDEV_INSTALL_KEY_CMDID, | ||
1000 | WMI_10_2_VDEV_SET_DSCP_TID_MAP_CMDID, | ||
1001 | WMI_10_2_PEER_CREATE_CMDID, | ||
1002 | WMI_10_2_PEER_DELETE_CMDID, | ||
1003 | WMI_10_2_PEER_FLUSH_TIDS_CMDID, | ||
1004 | WMI_10_2_PEER_SET_PARAM_CMDID, | ||
1005 | WMI_10_2_PEER_ASSOC_CMDID, | ||
1006 | WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, | ||
1007 | WMI_10_2_PEER_UPDATE_WDS_ENTRY_CMDID, | ||
1008 | WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, | ||
1009 | WMI_10_2_PEER_MCAST_GROUP_CMDID, | ||
1010 | WMI_10_2_BCN_TX_CMDID, | ||
1011 | WMI_10_2_BCN_PRB_TMPL_CMDID, | ||
1012 | WMI_10_2_BCN_FILTER_RX_CMDID, | ||
1013 | WMI_10_2_PRB_REQ_FILTER_RX_CMDID, | ||
1014 | WMI_10_2_MGMT_TX_CMDID, | ||
1015 | WMI_10_2_ADDBA_CLEAR_RESP_CMDID, | ||
1016 | WMI_10_2_ADDBA_SEND_CMDID, | ||
1017 | WMI_10_2_ADDBA_STATUS_CMDID, | ||
1018 | WMI_10_2_DELBA_SEND_CMDID, | ||
1019 | WMI_10_2_ADDBA_SET_RESP_CMDID, | ||
1020 | WMI_10_2_SEND_SINGLEAMSDU_CMDID, | ||
1021 | WMI_10_2_STA_POWERSAVE_MODE_CMDID, | ||
1022 | WMI_10_2_STA_POWERSAVE_PARAM_CMDID, | ||
1023 | WMI_10_2_STA_MIMO_PS_MODE_CMDID, | ||
1024 | WMI_10_2_DBGLOG_CFG_CMDID, | ||
1025 | WMI_10_2_PDEV_DFS_ENABLE_CMDID, | ||
1026 | WMI_10_2_PDEV_DFS_DISABLE_CMDID, | ||
1027 | WMI_10_2_PDEV_QVIT_CMDID, | ||
1028 | WMI_10_2_ROAM_SCAN_MODE, | ||
1029 | WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, | ||
1030 | WMI_10_2_ROAM_SCAN_PERIOD, | ||
1031 | WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, | ||
1032 | WMI_10_2_ROAM_AP_PROFILE, | ||
1033 | WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, | ||
1034 | WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, | ||
1035 | WMI_10_2_OFL_SCAN_PERIOD, | ||
1036 | WMI_10_2_P2P_DEV_SET_DEVICE_INFO, | ||
1037 | WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, | ||
1038 | WMI_10_2_P2P_GO_SET_BEACON_IE, | ||
1039 | WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, | ||
1040 | WMI_10_2_AP_PS_PEER_PARAM_CMDID, | ||
1041 | WMI_10_2_AP_PS_PEER_UAPSD_COEX_CMDID, | ||
1042 | WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, | ||
1043 | WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, | ||
1044 | WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, | ||
1045 | WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, | ||
1046 | WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, | ||
1047 | WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, | ||
1048 | WMI_10_2_PDEV_SUSPEND_CMDID, | ||
1049 | WMI_10_2_PDEV_RESUME_CMDID, | ||
1050 | WMI_10_2_ADD_BCN_FILTER_CMDID, | ||
1051 | WMI_10_2_RMV_BCN_FILTER_CMDID, | ||
1052 | WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, | ||
1053 | WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, | ||
1054 | WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, | ||
1055 | WMI_10_2_WOW_ENABLE_CMDID, | ||
1056 | WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, | ||
1057 | WMI_10_2_RTT_MEASREQ_CMDID, | ||
1058 | WMI_10_2_RTT_TSF_CMDID, | ||
1059 | WMI_10_2_RTT_KEEPALIVE_CMDID, | ||
1060 | WMI_10_2_PDEV_SEND_BCN_CMDID, | ||
1061 | WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, | ||
1062 | WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, | ||
1063 | WMI_10_2_REQUEST_STATS_CMDID, | ||
1064 | WMI_10_2_GPIO_CONFIG_CMDID, | ||
1065 | WMI_10_2_GPIO_OUTPUT_CMDID, | ||
1066 | WMI_10_2_VDEV_RATEMASK_CMDID, | ||
1067 | WMI_10_2_PDEV_SMART_ANT_ENABLE_CMDID, | ||
1068 | WMI_10_2_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, | ||
1069 | WMI_10_2_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, | ||
1070 | WMI_10_2_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, | ||
1071 | WMI_10_2_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID, | ||
1072 | WMI_10_2_FORCE_FW_HANG_CMDID, | ||
1073 | WMI_10_2_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, | ||
1074 | WMI_10_2_PDEV_SET_CTL_TABLE_CMDID, | ||
1075 | WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID, | ||
1076 | WMI_10_2_PDEV_RATEPWR_TABLE_CMDID, | ||
1077 | WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID, | ||
1078 | WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1, | ||
1079 | }; | ||
1080 | |||
1081 | enum wmi_10_2_event_id { | ||
1082 | WMI_10_2_SERVICE_READY_EVENTID = 0x8000, | ||
1083 | WMI_10_2_READY_EVENTID, | ||
1084 | WMI_10_2_DEBUG_MESG_EVENTID, | ||
1085 | WMI_10_2_START_EVENTID = 0x9000, | ||
1086 | WMI_10_2_END_EVENTID = 0x9FFF, | ||
1087 | WMI_10_2_SCAN_EVENTID = WMI_10_2_START_EVENTID, | ||
1088 | WMI_10_2_ECHO_EVENTID, | ||
1089 | WMI_10_2_UPDATE_STATS_EVENTID, | ||
1090 | WMI_10_2_INST_RSSI_STATS_EVENTID, | ||
1091 | WMI_10_2_VDEV_START_RESP_EVENTID, | ||
1092 | WMI_10_2_VDEV_STANDBY_REQ_EVENTID, | ||
1093 | WMI_10_2_VDEV_RESUME_REQ_EVENTID, | ||
1094 | WMI_10_2_VDEV_STOPPED_EVENTID, | ||
1095 | WMI_10_2_PEER_STA_KICKOUT_EVENTID, | ||
1096 | WMI_10_2_HOST_SWBA_EVENTID, | ||
1097 | WMI_10_2_TBTTOFFSET_UPDATE_EVENTID, | ||
1098 | WMI_10_2_MGMT_RX_EVENTID, | ||
1099 | WMI_10_2_CHAN_INFO_EVENTID, | ||
1100 | WMI_10_2_PHYERR_EVENTID, | ||
1101 | WMI_10_2_ROAM_EVENTID, | ||
1102 | WMI_10_2_PROFILE_MATCH, | ||
1103 | WMI_10_2_DEBUG_PRINT_EVENTID, | ||
1104 | WMI_10_2_PDEV_QVIT_EVENTID, | ||
1105 | WMI_10_2_WLAN_PROFILE_DATA_EVENTID, | ||
1106 | WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID, | ||
1107 | WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID, | ||
1108 | WMI_10_2_RTT_ERROR_REPORT_EVENTID, | ||
1109 | WMI_10_2_RTT_KEEPALIVE_EVENTID, | ||
1110 | WMI_10_2_WOW_WAKEUP_HOST_EVENTID, | ||
1111 | WMI_10_2_DCS_INTERFERENCE_EVENTID, | ||
1112 | WMI_10_2_PDEV_TPC_CONFIG_EVENTID, | ||
1113 | WMI_10_2_GPIO_INPUT_EVENTID, | ||
1114 | WMI_10_2_PEER_RATECODE_LIST_EVENTID, | ||
1115 | WMI_10_2_GENERIC_BUFFER_EVENTID, | ||
1116 | WMI_10_2_MCAST_BUF_RELEASE_EVENTID, | ||
1117 | WMI_10_2_MCAST_LIST_AGEOUT_EVENTID, | ||
1118 | WMI_10_2_WDS_PEER_EVENTID, | ||
1119 | WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1, | ||
1120 | }; | ||
1121 | |||
806 | enum wmi_phy_mode { | 1122 | enum wmi_phy_mode { |
807 | MODE_11A = 0, /* 11a Mode */ | 1123 | MODE_11A = 0, /* 11a Mode */ |
808 | MODE_11G = 1, /* 11b/g Mode */ | 1124 | MODE_11G = 1, /* 11b/g Mode */ |
@@ -1076,10 +1392,6 @@ struct wlan_host_mem_req { | |||
1076 | __le32 num_units; | 1392 | __le32 num_units; |
1077 | } __packed; | 1393 | } __packed; |
1078 | 1394 | ||
1079 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ | ||
1080 | ((((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ | ||
1081 | (1 << ((svc_id)%(sizeof(u32))))) != 0) | ||
1082 | |||
1083 | /* | 1395 | /* |
1084 | * The following struct holds optional payload for | 1396 | * The following struct holds optional payload for |
1085 | * wmi_service_ready_event,e.g., 11ac pass some of the | 1397 | * wmi_service_ready_event,e.g., 11ac pass some of the |
@@ -1551,6 +1863,16 @@ struct wmi_resource_config_10x { | |||
1551 | __le32 max_frag_entries; | 1863 | __le32 max_frag_entries; |
1552 | } __packed; | 1864 | } __packed; |
1553 | 1865 | ||
1866 | struct wmi_resource_config_10_2 { | ||
1867 | struct wmi_resource_config_10x common; | ||
1868 | __le32 max_peer_ext_stats; | ||
1869 | __le32 smart_ant_cap; /* 0-disable, 1-enable */ | ||
1870 | __le32 bk_min_free; | ||
1871 | __le32 be_min_free; | ||
1872 | __le32 vi_min_free; | ||
1873 | __le32 vo_min_free; | ||
1874 | __le32 rx_batchmode; /* 0-disable, 1-enable */ | ||
1875 | } __packed; | ||
1554 | 1876 | ||
1555 | #define NUM_UNITS_IS_NUM_VDEVS 0x1 | 1877 | #define NUM_UNITS_IS_NUM_VDEVS 0x1 |
1556 | #define NUM_UNITS_IS_NUM_PEERS 0x2 | 1878 | #define NUM_UNITS_IS_NUM_PEERS 0x2 |
@@ -1588,11 +1910,28 @@ struct wmi_init_cmd_10x { | |||
1588 | struct host_memory_chunk host_mem_chunks[1]; | 1910 | struct host_memory_chunk host_mem_chunks[1]; |
1589 | } __packed; | 1911 | } __packed; |
1590 | 1912 | ||
1913 | struct wmi_init_cmd_10_2 { | ||
1914 | struct wmi_resource_config_10_2 resource_config; | ||
1915 | __le32 num_host_mem_chunks; | ||
1916 | |||
1917 | /* | ||
1918 | * variable number of host memory chunks. | ||
1919 | * This should be the last element in the structure | ||
1920 | */ | ||
1921 | struct host_memory_chunk host_mem_chunks[1]; | ||
1922 | } __packed; | ||
1923 | |||
1924 | struct wmi_chan_list_entry { | ||
1925 | __le16 freq; | ||
1926 | u8 phy_mode; /* valid for 10.2 only */ | ||
1927 | u8 reserved; | ||
1928 | } __packed; | ||
1929 | |||
1591 | /* TLV for channel list */ | 1930 | /* TLV for channel list */ |
1592 | struct wmi_chan_list { | 1931 | struct wmi_chan_list { |
1593 | __le32 tag; /* WMI_CHAN_LIST_TAG */ | 1932 | __le32 tag; /* WMI_CHAN_LIST_TAG */ |
1594 | __le32 num_chan; | 1933 | __le32 num_chan; |
1595 | __le32 channel_list[0]; | 1934 | struct wmi_chan_list_entry channel_list[0]; |
1596 | } __packed; | 1935 | } __packed; |
1597 | 1936 | ||
1598 | struct wmi_bssid_list { | 1937 | struct wmi_bssid_list { |
@@ -1821,7 +2160,7 @@ struct wmi_start_scan_arg { | |||
1821 | u32 n_bssids; | 2160 | u32 n_bssids; |
1822 | 2161 | ||
1823 | u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; | 2162 | u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; |
1824 | u32 channels[64]; | 2163 | u16 channels[64]; |
1825 | struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; | 2164 | struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; |
1826 | struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; | 2165 | struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; |
1827 | }; | 2166 | }; |
@@ -2067,6 +2406,7 @@ struct wmi_comb_phyerr_rx_event { | |||
2067 | #define PHYERR_TLV_SIG 0xBB | 2406 | #define PHYERR_TLV_SIG 0xBB |
2068 | #define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB | 2407 | #define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB |
2069 | #define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8 | 2408 | #define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8 |
2409 | #define PHYERR_TLV_TAG_SPECTRAL_SUMMARY_REPORT 0xF9 | ||
2070 | 2410 | ||
2071 | struct phyerr_radar_report { | 2411 | struct phyerr_radar_report { |
2072 | __le32 reg0; /* RADAR_REPORT_REG0_* */ | 2412 | __le32 reg0; /* RADAR_REPORT_REG0_* */ |
@@ -2515,6 +2855,19 @@ enum wmi_10x_pdev_param { | |||
2515 | WMI_10X_PDEV_PARAM_BURST_DUR, | 2855 | WMI_10X_PDEV_PARAM_BURST_DUR, |
2516 | /* Set Bursting Enable*/ | 2856 | /* Set Bursting Enable*/ |
2517 | WMI_10X_PDEV_PARAM_BURST_ENABLE, | 2857 | WMI_10X_PDEV_PARAM_BURST_ENABLE, |
2858 | |||
2859 | /* following are available as of firmware 10.2 */ | ||
2860 | WMI_10X_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, | ||
2861 | WMI_10X_PDEV_PARAM_IGMPMLD_OVERRIDE, | ||
2862 | WMI_10X_PDEV_PARAM_IGMPMLD_TID, | ||
2863 | WMI_10X_PDEV_PARAM_ANTENNA_GAIN, | ||
2864 | WMI_10X_PDEV_PARAM_RX_DECAP_MODE, | ||
2865 | WMI_10X_PDEV_PARAM_RX_FILTER, | ||
2866 | WMI_10X_PDEV_PARAM_SET_MCAST_TO_UCAST_TID, | ||
2867 | WMI_10X_PDEV_PARAM_PROXY_STA_MODE, | ||
2868 | WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE, | ||
2869 | WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, | ||
2870 | WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, | ||
2518 | }; | 2871 | }; |
2519 | 2872 | ||
2520 | struct wmi_pdev_set_param_cmd { | 2873 | struct wmi_pdev_set_param_cmd { |
@@ -3387,6 +3740,14 @@ enum wmi_10x_vdev_param { | |||
3387 | WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, | 3740 | WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, |
3388 | 3741 | ||
3389 | WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, | 3742 | WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, |
3743 | |||
3744 | /* following are available as of firmware 10.2 */ | ||
3745 | WMI_10X_VDEV_PARAM_TX_ENCAP_TYPE, | ||
3746 | WMI_10X_VDEV_PARAM_CABQ_MAXDUR, | ||
3747 | WMI_10X_VDEV_PARAM_MFPTEST_SET, | ||
3748 | WMI_10X_VDEV_PARAM_RTS_FIXED_RATE, | ||
3749 | WMI_10X_VDEV_PARAM_VHT_SGIMASK, | ||
3750 | WMI_10X_VDEV_PARAM_VHT80_RATEMASK, | ||
3390 | }; | 3751 | }; |
3391 | 3752 | ||
3392 | /* slot time long */ | 3753 | /* slot time long */ |
@@ -3444,6 +3805,98 @@ struct wmi_vdev_simple_event { | |||
3444 | /* unsupported VDEV combination */ | 3805 | /* unsupported VDEV combination */ |
3445 | #define WMI_INIFIED_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 | 3806 | #define WMI_INIFIED_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 |
3446 | 3807 | ||
3808 | /* TODO: please add more comments if you have in-depth information */ | ||
3809 | struct wmi_vdev_spectral_conf_cmd { | ||
3810 | __le32 vdev_id; | ||
3811 | |||
3812 | /* number of fft samples to send (0 for infinite) */ | ||
3813 | __le32 scan_count; | ||
3814 | __le32 scan_period; | ||
3815 | __le32 scan_priority; | ||
3816 | |||
3817 | /* number of bins in the FFT: 2^(fft_size - bin_scale) */ | ||
3818 | __le32 scan_fft_size; | ||
3819 | __le32 scan_gc_ena; | ||
3820 | __le32 scan_restart_ena; | ||
3821 | __le32 scan_noise_floor_ref; | ||
3822 | __le32 scan_init_delay; | ||
3823 | __le32 scan_nb_tone_thr; | ||
3824 | __le32 scan_str_bin_thr; | ||
3825 | __le32 scan_wb_rpt_mode; | ||
3826 | __le32 scan_rssi_rpt_mode; | ||
3827 | __le32 scan_rssi_thr; | ||
3828 | __le32 scan_pwr_format; | ||
3829 | |||
3830 | /* rpt_mode: Format of FFT report to software for spectral scan | ||
3831 | * triggered FFTs: | ||
3832 | * 0: No FFT report (only spectral scan summary report) | ||
3833 | * 1: 2-dword summary of metrics for each completed FFT + spectral | ||
3834 | * scan summary report | ||
3835 | * 2: 2-dword summary of metrics for each completed FFT + | ||
3836 | * 1x- oversampled bins(in-band) per FFT + spectral scan summary | ||
3837 | * report | ||
3838 | * 3: 2-dword summary of metrics for each completed FFT + | ||
3839 | * 2x- oversampled bins (all) per FFT + spectral scan summary | ||
3840 | */ | ||
3841 | __le32 scan_rpt_mode; | ||
3842 | __le32 scan_bin_scale; | ||
3843 | __le32 scan_dbm_adj; | ||
3844 | __le32 scan_chn_mask; | ||
3845 | } __packed; | ||
3846 | |||
3847 | struct wmi_vdev_spectral_conf_arg { | ||
3848 | u32 vdev_id; | ||
3849 | u32 scan_count; | ||
3850 | u32 scan_period; | ||
3851 | u32 scan_priority; | ||
3852 | u32 scan_fft_size; | ||
3853 | u32 scan_gc_ena; | ||
3854 | u32 scan_restart_ena; | ||
3855 | u32 scan_noise_floor_ref; | ||
3856 | u32 scan_init_delay; | ||
3857 | u32 scan_nb_tone_thr; | ||
3858 | u32 scan_str_bin_thr; | ||
3859 | u32 scan_wb_rpt_mode; | ||
3860 | u32 scan_rssi_rpt_mode; | ||
3861 | u32 scan_rssi_thr; | ||
3862 | u32 scan_pwr_format; | ||
3863 | u32 scan_rpt_mode; | ||
3864 | u32 scan_bin_scale; | ||
3865 | u32 scan_dbm_adj; | ||
3866 | u32 scan_chn_mask; | ||
3867 | }; | ||
3868 | |||
3869 | #define WMI_SPECTRAL_ENABLE_DEFAULT 0 | ||
3870 | #define WMI_SPECTRAL_COUNT_DEFAULT 0 | ||
3871 | #define WMI_SPECTRAL_PERIOD_DEFAULT 35 | ||
3872 | #define WMI_SPECTRAL_PRIORITY_DEFAULT 1 | ||
3873 | #define WMI_SPECTRAL_FFT_SIZE_DEFAULT 7 | ||
3874 | #define WMI_SPECTRAL_GC_ENA_DEFAULT 1 | ||
3875 | #define WMI_SPECTRAL_RESTART_ENA_DEFAULT 0 | ||
3876 | #define WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96 | ||
3877 | #define WMI_SPECTRAL_INIT_DELAY_DEFAULT 80 | ||
3878 | #define WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12 | ||
3879 | #define WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8 | ||
3880 | #define WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0 | ||
3881 | #define WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0 | ||
3882 | #define WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0 | ||
3883 | #define WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0 | ||
3884 | #define WMI_SPECTRAL_RPT_MODE_DEFAULT 2 | ||
3885 | #define WMI_SPECTRAL_BIN_SCALE_DEFAULT 1 | ||
3886 | #define WMI_SPECTRAL_DBM_ADJ_DEFAULT 1 | ||
3887 | #define WMI_SPECTRAL_CHN_MASK_DEFAULT 1 | ||
3888 | |||
3889 | struct wmi_vdev_spectral_enable_cmd { | ||
3890 | __le32 vdev_id; | ||
3891 | __le32 trigger_cmd; | ||
3892 | __le32 enable_cmd; | ||
3893 | } __packed; | ||
3894 | |||
3895 | #define WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1 | ||
3896 | #define WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2 | ||
3897 | #define WMI_SPECTRAL_ENABLE_CMD_ENABLE 1 | ||
3898 | #define WMI_SPECTRAL_ENABLE_CMD_DISABLE 2 | ||
3899 | |||
3447 | /* Beacon processing related command and event structures */ | 3900 | /* Beacon processing related command and event structures */ |
3448 | struct wmi_bcn_tx_hdr { | 3901 | struct wmi_bcn_tx_hdr { |
3449 | __le32 vdev_id; | 3902 | __le32 vdev_id; |
@@ -3470,6 +3923,11 @@ enum wmi_bcn_tx_ref_flags { | |||
3470 | WMI_BCN_TX_REF_FLAG_DELIVER_CAB = 0x2, | 3923 | WMI_BCN_TX_REF_FLAG_DELIVER_CAB = 0x2, |
3471 | }; | 3924 | }; |
3472 | 3925 | ||
3926 | /* TODO: It is unclear why "no antenna" works while any other seemingly valid | ||
3927 | * chainmask yields no beacons on the air at all. | ||
3928 | */ | ||
3929 | #define WMI_BCN_TX_REF_DEF_ANTENNA 0 | ||
3930 | |||
3473 | struct wmi_bcn_tx_ref_cmd { | 3931 | struct wmi_bcn_tx_ref_cmd { |
3474 | __le32 vdev_id; | 3932 | __le32 vdev_id; |
3475 | __le32 data_len; | 3933 | __le32 data_len; |
@@ -3481,6 +3939,8 @@ struct wmi_bcn_tx_ref_cmd { | |||
3481 | __le32 frame_control; | 3939 | __le32 frame_control; |
3482 | /* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */ | 3940 | /* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */ |
3483 | __le32 flags; | 3941 | __le32 flags; |
3942 | /* introduced in 10.2 */ | ||
3943 | __le32 antenna_mask; | ||
3484 | } __packed; | 3944 | } __packed; |
3485 | 3945 | ||
3486 | /* Beacon filter */ | 3946 | /* Beacon filter */ |
@@ -4053,7 +4513,7 @@ struct wmi_peer_set_q_empty_callback_cmd { | |||
4053 | /* Maximum listen interval supported by hw in units of beacon interval */ | 4513 | /* Maximum listen interval supported by hw in units of beacon interval */ |
4054 | #define ATH10K_MAX_HW_LISTEN_INTERVAL 5 | 4514 | #define ATH10K_MAX_HW_LISTEN_INTERVAL 5 |
4055 | 4515 | ||
4056 | struct wmi_peer_assoc_complete_cmd { | 4516 | struct wmi_common_peer_assoc_complete_cmd { |
4057 | struct wmi_mac_addr peer_macaddr; | 4517 | struct wmi_mac_addr peer_macaddr; |
4058 | __le32 vdev_id; | 4518 | __le32 vdev_id; |
4059 | __le32 peer_new_assoc; /* 1=assoc, 0=reassoc */ | 4519 | __le32 peer_new_assoc; /* 1=assoc, 0=reassoc */ |
@@ -4071,11 +4531,30 @@ struct wmi_peer_assoc_complete_cmd { | |||
4071 | __le32 peer_vht_caps; | 4531 | __le32 peer_vht_caps; |
4072 | __le32 peer_phymode; | 4532 | __le32 peer_phymode; |
4073 | struct wmi_vht_rate_set peer_vht_rates; | 4533 | struct wmi_vht_rate_set peer_vht_rates; |
4534 | }; | ||
4535 | |||
4536 | struct wmi_main_peer_assoc_complete_cmd { | ||
4537 | struct wmi_common_peer_assoc_complete_cmd cmd; | ||
4538 | |||
4074 | /* HT Operation Element of the peer. Five bytes packed in 2 | 4539 | /* HT Operation Element of the peer. Five bytes packed in 2 |
4075 | * INT32 array and filled from lsb to msb. */ | 4540 | * INT32 array and filled from lsb to msb. */ |
4076 | __le32 peer_ht_info[2]; | 4541 | __le32 peer_ht_info[2]; |
4077 | } __packed; | 4542 | } __packed; |
4078 | 4543 | ||
4544 | struct wmi_10_1_peer_assoc_complete_cmd { | ||
4545 | struct wmi_common_peer_assoc_complete_cmd cmd; | ||
4546 | } __packed; | ||
4547 | |||
4548 | #define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_LSB 0 | ||
4549 | #define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_MASK 0x0f | ||
4550 | #define WMI_PEER_ASSOC_INFO0_MAX_NSS_LSB 4 | ||
4551 | #define WMI_PEER_ASSOC_INFO0_MAX_NSS_MASK 0xf0 | ||
4552 | |||
4553 | struct wmi_10_2_peer_assoc_complete_cmd { | ||
4554 | struct wmi_common_peer_assoc_complete_cmd cmd; | ||
4555 | __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ | ||
4556 | } __packed; | ||
4557 | |||
4079 | struct wmi_peer_assoc_complete_arg { | 4558 | struct wmi_peer_assoc_complete_arg { |
4080 | u8 addr[ETH_ALEN]; | 4559 | u8 addr[ETH_ALEN]; |
4081 | u32 vdev_id; | 4560 | u32 vdev_id; |
@@ -4290,6 +4769,10 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, | |||
4290 | u32 param_id, u32 param_value); | 4769 | u32 param_id, u32 param_value); |
4291 | int ath10k_wmi_vdev_install_key(struct ath10k *ar, | 4770 | int ath10k_wmi_vdev_install_key(struct ath10k *ar, |
4292 | const struct wmi_vdev_install_key_arg *arg); | 4771 | const struct wmi_vdev_install_key_arg *arg); |
4772 | int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, | ||
4773 | const struct wmi_vdev_spectral_conf_arg *arg); | ||
4774 | int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, | ||
4775 | u32 enable); | ||
4293 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | 4776 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, |
4294 | const u8 peer_addr[ETH_ALEN]); | 4777 | const u8 peer_addr[ETH_ALEN]); |
4295 | int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, | 4778 | int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 7106547a14dd..66b6366158b9 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -351,8 +351,7 @@ void ath5k_hw_deinit(struct ath5k_hw *ah) | |||
351 | { | 351 | { |
352 | __set_bit(ATH_STAT_INVALID, ah->status); | 352 | __set_bit(ATH_STAT_INVALID, ah->status); |
353 | 353 | ||
354 | if (ah->ah_rf_banks != NULL) | 354 | kfree(ah->ah_rf_banks); |
355 | kfree(ah->ah_rf_banks); | ||
356 | 355 | ||
357 | ath5k_eeprom_detach(ah); | 356 | ath5k_eeprom_detach(ah); |
358 | 357 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8ad2550bce7f..59a87247aac4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1423,7 +1423,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1423 | break; | 1423 | break; |
1424 | } | 1424 | } |
1425 | 1425 | ||
1426 | if (rxs->rate_idx >= 0 && rs->rs_rate == | 1426 | if (rs->rs_rate == |
1427 | ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short) | 1427 | ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short) |
1428 | rxs->flag |= RX_FLAG_SHORTPRE; | 1428 | rxs->flag |= RX_FLAG_SHORTPRE; |
1429 | 1429 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index b8d031ae63c2..30e4e1fd4b04 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -894,6 +894,100 @@ static const struct file_operations fops_queue = { | |||
894 | .llseek = default_llseek, | 894 | .llseek = default_llseek, |
895 | }; | 895 | }; |
896 | 896 | ||
897 | /* debugfs: eeprom */ | ||
898 | |||
899 | struct eeprom_private { | ||
900 | u16 *buf; | ||
901 | int len; | ||
902 | }; | ||
903 | |||
904 | static int open_file_eeprom(struct inode *inode, struct file *file) | ||
905 | { | ||
906 | struct eeprom_private *ep; | ||
907 | struct ath5k_hw *ah = inode->i_private; | ||
908 | bool res; | ||
909 | int i, ret; | ||
910 | u32 eesize; | ||
911 | u16 val, *buf; | ||
912 | |||
913 | /* Get eeprom size */ | ||
914 | |||
915 | res = ath5k_hw_nvram_read(ah, AR5K_EEPROM_SIZE_UPPER, &val); | ||
916 | if (!res) | ||
917 | return -EACCES; | ||
918 | |||
919 | if (val == 0) { | ||
920 | eesize = AR5K_EEPROM_INFO_MAX + AR5K_EEPROM_INFO_BASE; | ||
921 | } else { | ||
922 | eesize = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << | ||
923 | AR5K_EEPROM_SIZE_ENDLOC_SHIFT; | ||
924 | ath5k_hw_nvram_read(ah, AR5K_EEPROM_SIZE_LOWER, &val); | ||
925 | eesize = eesize | val; | ||
926 | } | ||
927 | |||
928 | if (eesize > 4096) | ||
929 | return -EINVAL; | ||
930 | |||
931 | /* Create buffer and read in eeprom */ | ||
932 | |||
933 | buf = vmalloc(eesize); | ||
934 | if (!buf) { | ||
935 | ret = -ENOMEM; | ||
936 | goto err; | ||
937 | } | ||
938 | |||
939 | for (i = 0; i < eesize; ++i) { | ||
940 | AR5K_EEPROM_READ(i, val); | ||
941 | buf[i] = val; | ||
942 | } | ||
943 | |||
944 | /* Create private struct and assign to file */ | ||
945 | |||
946 | ep = kmalloc(sizeof(*ep), GFP_KERNEL); | ||
947 | if (!ep) { | ||
948 | ret = -ENOMEM; | ||
949 | goto freebuf; | ||
950 | } | ||
951 | |||
952 | ep->buf = buf; | ||
953 | ep->len = i; | ||
954 | |||
955 | file->private_data = (void *)ep; | ||
956 | |||
957 | return 0; | ||
958 | |||
959 | freebuf: | ||
960 | vfree(buf); | ||
961 | err: | ||
962 | return ret; | ||
963 | |||
964 | } | ||
965 | |||
966 | static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, | ||
967 | size_t count, loff_t *ppos) | ||
968 | { | ||
969 | struct eeprom_private *ep = file->private_data; | ||
970 | |||
971 | return simple_read_from_buffer(user_buf, count, ppos, ep->buf, ep->len); | ||
972 | } | ||
973 | |||
974 | static int release_file_eeprom(struct inode *inode, struct file *file) | ||
975 | { | ||
976 | struct eeprom_private *ep = file->private_data; | ||
977 | |||
978 | vfree(ep->buf); | ||
979 | kfree(ep); | ||
980 | |||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static const struct file_operations fops_eeprom = { | ||
985 | .open = open_file_eeprom, | ||
986 | .read = read_file_eeprom, | ||
987 | .release = release_file_eeprom, | ||
988 | .owner = THIS_MODULE, | ||
989 | }; | ||
990 | |||
897 | 991 | ||
898 | void | 992 | void |
899 | ath5k_debug_init_device(struct ath5k_hw *ah) | 993 | ath5k_debug_init_device(struct ath5k_hw *ah) |
@@ -921,6 +1015,8 @@ ath5k_debug_init_device(struct ath5k_hw *ah) | |||
921 | 1015 | ||
922 | debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc); | 1016 | debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc); |
923 | 1017 | ||
1018 | debugfs_create_file("eeprom", S_IRUSR, phydir, ah, &fops_eeprom); | ||
1019 | |||
924 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah, | 1020 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah, |
925 | &fops_frameerrors); | 1021 | &fops_frameerrors); |
926 | 1022 | ||
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 48a6a69b57bc..2062d1190556 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
@@ -130,6 +130,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, | |||
130 | 130 | ||
131 | led->ah = ah; | 131 | led->ah = ah; |
132 | strncpy(led->name, name, sizeof(led->name)); | 132 | strncpy(led->name, name, sizeof(led->name)); |
133 | led->name[sizeof(led->name)-1] = 0; | ||
133 | led->led_dev.name = led->name; | 134 | led->led_dev.name = led->name; |
134 | led->led_dev.default_trigger = trigger; | 135 | led->led_dev.default_trigger = trigger; |
135 | led->led_dev.brightness_set = ath5k_led_brightness_set; | 136 | led->led_dev.brightness_set = ath5k_led_brightness_set; |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index e535807c3d89..ba60e37213eb 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -717,6 +717,7 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, | |||
717 | memcpy(ie + 2, vif->ssid, vif->ssid_len); | 717 | memcpy(ie + 2, vif->ssid, vif->ssid_len); |
718 | memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len); | 718 | memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len); |
719 | bss = cfg80211_inform_bss(ar->wiphy, chan, | 719 | bss = cfg80211_inform_bss(ar->wiphy, chan, |
720 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
720 | bssid, 0, cap_val, 100, | 721 | bssid, 0, cap_val, 100, |
721 | ie, 2 + vif->ssid_len + beacon_ie_len, | 722 | ie, 2 + vif->ssid_len + beacon_ie_len, |
722 | 0, GFP_KERNEL); | 723 | 0, GFP_KERNEL); |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index fffd52355123..6e473fa4b13c 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -1049,7 +1049,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
1049 | ar->hw.reserved_ram_size = le32_to_cpup(val); | 1049 | ar->hw.reserved_ram_size = le32_to_cpup(val); |
1050 | 1050 | ||
1051 | ath6kl_dbg(ATH6KL_DBG_BOOT, | 1051 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
1052 | "found reserved ram size ie 0x%d\n", | 1052 | "found reserved ram size ie %d\n", |
1053 | ar->hw.reserved_ram_size); | 1053 | ar->hw.reserved_ram_size); |
1054 | break; | 1054 | break; |
1055 | case ATH6KL_FW_IE_CAPABILITIES: | 1055 | case ATH6KL_FW_IE_CAPABILITIES: |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 21516bc65785..933aef025698 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -225,7 +225,7 @@ int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value) | |||
225 | ret = ath6kl_hif_diag_write32(ar, address, value); | 225 | ret = ath6kl_hif_diag_write32(ar, address, value); |
226 | 226 | ||
227 | if (ret) { | 227 | if (ret) { |
228 | ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n", | 228 | ath6kl_err("failed to write 0x%x during diagnose window to 0x%x\n", |
229 | address, value); | 229 | address, value); |
230 | return ret; | 230 | return ret; |
231 | } | 231 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 339d89f14d32..eab0ab976af2 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -1400,6 +1400,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { | |||
1400 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, | 1400 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, |
1401 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))}, | 1401 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))}, |
1402 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))}, | 1402 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))}, |
1403 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x2))}, | ||
1403 | {}, | 1404 | {}, |
1404 | }; | 1405 | }; |
1405 | 1406 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index c44325856b81..a6a5e40b3e98 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -1229,26 +1229,7 @@ static struct usb_driver ath6kl_usb_driver = { | |||
1229 | .disable_hub_initiated_lpm = 1, | 1229 | .disable_hub_initiated_lpm = 1, |
1230 | }; | 1230 | }; |
1231 | 1231 | ||
1232 | static int ath6kl_usb_init(void) | 1232 | module_usb_driver(ath6kl_usb_driver); |
1233 | { | ||
1234 | int ret; | ||
1235 | |||
1236 | ret = usb_register(&ath6kl_usb_driver); | ||
1237 | if (ret) { | ||
1238 | ath6kl_err("usb registration failed: %d\n", ret); | ||
1239 | return ret; | ||
1240 | } | ||
1241 | |||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | static void ath6kl_usb_exit(void) | ||
1246 | { | ||
1247 | usb_deregister(&ath6kl_usb_driver); | ||
1248 | } | ||
1249 | |||
1250 | module_init(ath6kl_usb_init); | ||
1251 | module_exit(ath6kl_usb_exit); | ||
1252 | 1233 | ||
1253 | MODULE_AUTHOR("Atheros Communications, Inc."); | 1234 | MODULE_AUTHOR("Atheros Communications, Inc."); |
1254 | MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); | 1235 | MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 94df345d08c2..b921005ad7ee 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -619,8 +619,7 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
619 | dlen, freq, vif->probe_req_report); | 619 | dlen, freq, vif->probe_req_report); |
620 | 620 | ||
621 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 621 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
622 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0, | 622 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0); |
623 | GFP_ATOMIC); | ||
624 | 623 | ||
625 | return 0; | 624 | return 0; |
626 | } | 625 | } |
@@ -659,7 +658,7 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
659 | return -EINVAL; | 658 | return -EINVAL; |
660 | } | 659 | } |
661 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 660 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
662 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0, GFP_ATOMIC); | 661 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0); |
663 | 662 | ||
664 | return 0; | 663 | return 0; |
665 | } | 664 | } |
@@ -1093,7 +1092,6 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1093 | u8 *buf; | 1092 | u8 *buf; |
1094 | struct ieee80211_channel *channel; | 1093 | struct ieee80211_channel *channel; |
1095 | struct ath6kl *ar = wmi->parent_dev; | 1094 | struct ath6kl *ar = wmi->parent_dev; |
1096 | struct ieee80211_mgmt *mgmt; | ||
1097 | struct cfg80211_bss *bss; | 1095 | struct cfg80211_bss *bss; |
1098 | 1096 | ||
1099 | if (len <= sizeof(struct wmi_bss_info_hdr2)) | 1097 | if (len <= sizeof(struct wmi_bss_info_hdr2)) |
@@ -1139,39 +1137,15 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1139 | } | 1137 | } |
1140 | } | 1138 | } |
1141 | 1139 | ||
1142 | /* | 1140 | bss = cfg80211_inform_bss(ar->wiphy, channel, |
1143 | * In theory, use of cfg80211_inform_bss() would be more natural here | 1141 | bih->frame_type == BEACON_FTYPE ? |
1144 | * since we do not have the full frame. However, at least for now, | 1142 | CFG80211_BSS_FTYPE_BEACON : |
1145 | * cfg80211 can only distinguish Beacon and Probe Response frames from | 1143 | CFG80211_BSS_FTYPE_PRESP, |
1146 | * each other when using cfg80211_inform_bss_frame(), so let's build a | 1144 | bih->bssid, get_unaligned_le64((__le64 *)buf), |
1147 | * fake IEEE 802.11 header to be able to take benefit of this. | 1145 | get_unaligned_le16(((__le16 *)buf) + 5), |
1148 | */ | 1146 | get_unaligned_le16(((__le16 *)buf) + 4), |
1149 | mgmt = kmalloc(24 + len, GFP_ATOMIC); | 1147 | buf + 8 + 2 + 2, len - 8 - 2 - 2, |
1150 | if (mgmt == NULL) | 1148 | (bih->snr - 95) * 100, GFP_ATOMIC); |
1151 | return -EINVAL; | ||
1152 | |||
1153 | if (bih->frame_type == BEACON_FTYPE) { | ||
1154 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1155 | IEEE80211_STYPE_BEACON); | ||
1156 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
1157 | } else { | ||
1158 | struct net_device *dev = vif->ndev; | ||
1159 | |||
1160 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1161 | IEEE80211_STYPE_PROBE_RESP); | ||
1162 | memcpy(mgmt->da, dev->dev_addr, ETH_ALEN); | ||
1163 | } | ||
1164 | mgmt->duration = cpu_to_le16(0); | ||
1165 | memcpy(mgmt->sa, bih->bssid, ETH_ALEN); | ||
1166 | memcpy(mgmt->bssid, bih->bssid, ETH_ALEN); | ||
1167 | mgmt->seq_ctrl = cpu_to_le16(0); | ||
1168 | |||
1169 | memcpy(&mgmt->u.beacon, buf, len); | ||
1170 | |||
1171 | bss = cfg80211_inform_bss_frame(ar->wiphy, channel, mgmt, | ||
1172 | 24 + len, (bih->snr - 95) * 100, | ||
1173 | GFP_ATOMIC); | ||
1174 | kfree(mgmt); | ||
1175 | if (bss == NULL) | 1149 | if (bss == NULL) |
1176 | return -ENOMEM; | 1150 | return -ENOMEM; |
1177 | cfg80211_put_bss(ar->wiphy, bss); | 1151 | cfg80211_put_bss(ar->wiphy, bss); |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 8fcc029a76a6..b8f570ed39ad 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -130,6 +130,15 @@ config ATH9K_RFKILL | |||
130 | seconds. Turn off to save power, but enable it if you have | 130 | seconds. Turn off to save power, but enable it if you have |
131 | a platform that can toggle the RF-Kill GPIO. | 131 | a platform that can toggle the RF-Kill GPIO. |
132 | 132 | ||
133 | config ATH9K_CHANNEL_CONTEXT | ||
134 | bool "Channel Context support" | ||
135 | depends on ATH9K | ||
136 | default n | ||
137 | ---help--- | ||
138 | This option enables channel context support in ath9k, which is needed | ||
139 | for multi-channel concurrency. Enable this if P2P PowerSave support | ||
140 | is required. | ||
141 | |||
133 | config ATH9K_HTC | 142 | config ATH9K_HTC |
134 | tristate "Atheros HTC based wireless cards support" | 143 | tristate "Atheros HTC based wireless cards support" |
135 | depends on USB && MAC80211 | 144 | depends on USB && MAC80211 |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7fc13a8da675..c690601f7276 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "spectral.h" | 31 | #include "spectral.h" |
32 | 32 | ||
33 | struct ath_node; | 33 | struct ath_node; |
34 | struct ath_vif; | ||
34 | 35 | ||
35 | extern struct ieee80211_ops ath9k_ops; | 36 | extern struct ieee80211_ops ath9k_ops; |
36 | extern int ath9k_modparam_nohwcrypt; | 37 | extern int ath9k_modparam_nohwcrypt; |
@@ -324,6 +325,10 @@ struct ath_rx { | |||
324 | u32 ampdu_ref; | 325 | u32 ampdu_ref; |
325 | }; | 326 | }; |
326 | 327 | ||
328 | /*******************/ | ||
329 | /* Channel Context */ | ||
330 | /*******************/ | ||
331 | |||
327 | struct ath_chanctx { | 332 | struct ath_chanctx { |
328 | struct cfg80211_chan_def chandef; | 333 | struct cfg80211_chan_def chandef; |
329 | struct list_head vifs; | 334 | struct list_head vifs; |
@@ -354,7 +359,9 @@ enum ath_chanctx_event { | |||
354 | ATH_CHANCTX_EVENT_BEACON_RECEIVED, | 359 | ATH_CHANCTX_EVENT_BEACON_RECEIVED, |
355 | ATH_CHANCTX_EVENT_ASSOC, | 360 | ATH_CHANCTX_EVENT_ASSOC, |
356 | ATH_CHANCTX_EVENT_SWITCH, | 361 | ATH_CHANCTX_EVENT_SWITCH, |
362 | ATH_CHANCTX_EVENT_ASSIGN, | ||
357 | ATH_CHANCTX_EVENT_UNASSIGN, | 363 | ATH_CHANCTX_EVENT_UNASSIGN, |
364 | ATH_CHANCTX_EVENT_CHANGE, | ||
358 | ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL, | 365 | ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL, |
359 | }; | 366 | }; |
360 | 367 | ||
@@ -403,35 +410,121 @@ struct ath_offchannel { | |||
403 | int roc_duration; | 410 | int roc_duration; |
404 | int duration; | 411 | int duration; |
405 | }; | 412 | }; |
413 | |||
414 | #define case_rtn_string(val) case val: return #val | ||
415 | |||
406 | #define ath_for_each_chanctx(_sc, _ctx) \ | 416 | #define ath_for_each_chanctx(_sc, _ctx) \ |
407 | for (ctx = &sc->chanctx[0]; \ | 417 | for (ctx = &sc->chanctx[0]; \ |
408 | ctx <= &sc->chanctx[ARRAY_SIZE(sc->chanctx) - 1]; \ | 418 | ctx <= &sc->chanctx[ARRAY_SIZE(sc->chanctx) - 1]; \ |
409 | ctx++) | 419 | ctx++) |
410 | 420 | ||
411 | void ath9k_fill_chanctx_ops(void); | 421 | void ath_chanctx_init(struct ath_softc *sc); |
412 | void ath9k_chanctx_force_active(struct ieee80211_hw *hw, | 422 | void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, |
413 | struct ieee80211_vif *vif); | 423 | struct cfg80211_chan_def *chandef); |
424 | |||
425 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
426 | |||
414 | static inline struct ath_chanctx * | 427 | static inline struct ath_chanctx * |
415 | ath_chanctx_get(struct ieee80211_chanctx_conf *ctx) | 428 | ath_chanctx_get(struct ieee80211_chanctx_conf *ctx) |
416 | { | 429 | { |
417 | struct ath_chanctx **ptr = (void *) ctx->drv_priv; | 430 | struct ath_chanctx **ptr = (void *) ctx->drv_priv; |
418 | return *ptr; | 431 | return *ptr; |
419 | } | 432 | } |
420 | void ath_chanctx_init(struct ath_softc *sc); | 433 | |
421 | void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, | 434 | bool ath9k_is_chanctx_enabled(void); |
422 | struct cfg80211_chan_def *chandef); | 435 | void ath9k_fill_chanctx_ops(void); |
423 | void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, | 436 | void ath9k_init_channel_context(struct ath_softc *sc); |
424 | struct cfg80211_chan_def *chandef); | 437 | void ath9k_offchannel_init(struct ath_softc *sc); |
438 | void ath9k_deinit_channel_context(struct ath_softc *sc); | ||
439 | int ath9k_init_p2p(struct ath_softc *sc); | ||
440 | void ath9k_deinit_p2p(struct ath_softc *sc); | ||
441 | void ath9k_p2p_remove_vif(struct ath_softc *sc, | ||
442 | struct ieee80211_vif *vif); | ||
443 | void ath9k_p2p_beacon_sync(struct ath_softc *sc); | ||
444 | void ath9k_p2p_bss_info_changed(struct ath_softc *sc, | ||
445 | struct ieee80211_vif *vif); | ||
446 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | ||
447 | struct sk_buff *skb); | ||
448 | void ath9k_p2p_ps_timer(void *priv); | ||
449 | void ath9k_chanctx_wake_queues(struct ath_softc *sc); | ||
425 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); | 450 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); |
426 | void ath_offchannel_timer(unsigned long data); | 451 | |
427 | void ath_offchannel_channel_change(struct ath_softc *sc); | 452 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, |
428 | void ath_chanctx_offchan_switch(struct ath_softc *sc, | 453 | enum ath_chanctx_event ev); |
429 | struct ieee80211_channel *chan); | 454 | void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, |
430 | struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, | 455 | enum ath_chanctx_event ev); |
431 | bool active); | ||
432 | void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | 456 | void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, |
433 | enum ath_chanctx_event ev); | 457 | enum ath_chanctx_event ev); |
434 | void ath_chanctx_timer(unsigned long data); | 458 | void ath_chanctx_set_next(struct ath_softc *sc, bool force); |
459 | void ath_offchannel_next(struct ath_softc *sc); | ||
460 | void ath_scan_complete(struct ath_softc *sc, bool abort); | ||
461 | void ath_roc_complete(struct ath_softc *sc, bool abort); | ||
462 | |||
463 | #else | ||
464 | |||
465 | static inline bool ath9k_is_chanctx_enabled(void) | ||
466 | { | ||
467 | return false; | ||
468 | } | ||
469 | static inline void ath9k_fill_chanctx_ops(void) | ||
470 | { | ||
471 | } | ||
472 | static inline void ath9k_init_channel_context(struct ath_softc *sc) | ||
473 | { | ||
474 | } | ||
475 | static inline void ath9k_offchannel_init(struct ath_softc *sc) | ||
476 | { | ||
477 | } | ||
478 | static inline void ath9k_deinit_channel_context(struct ath_softc *sc) | ||
479 | { | ||
480 | } | ||
481 | static inline void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, | ||
482 | enum ath_chanctx_event ev) | ||
483 | { | ||
484 | } | ||
485 | static inline void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, | ||
486 | enum ath_chanctx_event ev) | ||
487 | { | ||
488 | } | ||
489 | static inline void ath_chanctx_event(struct ath_softc *sc, | ||
490 | struct ieee80211_vif *vif, | ||
491 | enum ath_chanctx_event ev) | ||
492 | { | ||
493 | } | ||
494 | static inline int ath9k_init_p2p(struct ath_softc *sc) | ||
495 | { | ||
496 | return 0; | ||
497 | } | ||
498 | static inline void ath9k_deinit_p2p(struct ath_softc *sc) | ||
499 | { | ||
500 | } | ||
501 | static inline void ath9k_p2p_remove_vif(struct ath_softc *sc, | ||
502 | struct ieee80211_vif *vif) | ||
503 | { | ||
504 | } | ||
505 | static inline void ath9k_p2p_beacon_sync(struct ath_softc *sc) | ||
506 | { | ||
507 | } | ||
508 | static inline void ath9k_p2p_bss_info_changed(struct ath_softc *sc, | ||
509 | struct ieee80211_vif *vif) | ||
510 | { | ||
511 | } | ||
512 | static inline void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | ||
513 | struct sk_buff *skb) | ||
514 | { | ||
515 | } | ||
516 | static inline void ath9k_p2p_ps_timer(struct ath_softc *sc) | ||
517 | { | ||
518 | } | ||
519 | static inline void ath9k_chanctx_wake_queues(struct ath_softc *sc) | ||
520 | { | ||
521 | } | ||
522 | static inline void ath_chanctx_check_active(struct ath_softc *sc, | ||
523 | struct ath_chanctx *ctx) | ||
524 | { | ||
525 | } | ||
526 | |||
527 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
435 | 528 | ||
436 | int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); | 529 | int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); |
437 | int ath_startrecv(struct ath_softc *sc); | 530 | int ath_startrecv(struct ath_softc *sc); |
@@ -583,7 +676,6 @@ void ath9k_csa_update(struct ath_softc *sc); | |||
583 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 676 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
584 | #define ATH_PLL_WORK_INTERVAL 100 | 677 | #define ATH_PLL_WORK_INTERVAL 100 |
585 | 678 | ||
586 | void ath_chanctx_work(struct work_struct *work); | ||
587 | void ath_tx_complete_poll_work(struct work_struct *work); | 679 | void ath_tx_complete_poll_work(struct work_struct *work); |
588 | void ath_reset_work(struct work_struct *work); | 680 | void ath_reset_work(struct work_struct *work); |
589 | bool ath_hw_check(struct ath_softc *sc); | 681 | bool ath_hw_check(struct ath_softc *sc); |
@@ -597,8 +689,6 @@ int ath_update_survey_stats(struct ath_softc *sc); | |||
597 | void ath_update_survey_nf(struct ath_softc *sc, int channel); | 689 | void ath_update_survey_nf(struct ath_softc *sc, int channel); |
598 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); | 690 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); |
599 | void ath_ps_full_sleep(unsigned long data); | 691 | void ath_ps_full_sleep(unsigned long data); |
600 | void ath9k_p2p_ps_timer(void *priv); | ||
601 | void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif); | ||
602 | void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop); | 692 | void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop); |
603 | 693 | ||
604 | /**********/ | 694 | /**********/ |
@@ -849,12 +939,17 @@ struct ath_softc { | |||
849 | struct mutex mutex; | 939 | struct mutex mutex; |
850 | struct work_struct paprd_work; | 940 | struct work_struct paprd_work; |
851 | struct work_struct hw_reset_work; | 941 | struct work_struct hw_reset_work; |
852 | struct work_struct chanctx_work; | ||
853 | struct completion paprd_complete; | 942 | struct completion paprd_complete; |
854 | wait_queue_head_t tx_wait; | 943 | wait_queue_head_t tx_wait; |
855 | 944 | ||
945 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
946 | struct work_struct chanctx_work; | ||
856 | struct ath_gen_timer *p2p_ps_timer; | 947 | struct ath_gen_timer *p2p_ps_timer; |
857 | struct ath_vif *p2p_ps_vif; | 948 | struct ath_vif *p2p_ps_vif; |
949 | struct ath_chanctx_sched sched; | ||
950 | struct ath_offchannel offchannel; | ||
951 | struct ath_chanctx *next_chan; | ||
952 | #endif | ||
858 | 953 | ||
859 | unsigned long driver_data; | 954 | unsigned long driver_data; |
860 | 955 | ||
@@ -875,10 +970,7 @@ struct ath_softc { | |||
875 | struct cfg80211_chan_def cur_chandef; | 970 | struct cfg80211_chan_def cur_chandef; |
876 | struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX]; | 971 | struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX]; |
877 | struct ath_chanctx *cur_chan; | 972 | struct ath_chanctx *cur_chan; |
878 | struct ath_chanctx *next_chan; | ||
879 | spinlock_t chan_lock; | 973 | spinlock_t chan_lock; |
880 | struct ath_offchannel offchannel; | ||
881 | struct ath_chanctx_sched sched; | ||
882 | 974 | ||
883 | #ifdef CONFIG_MAC80211_LEDS | 975 | #ifdef CONFIG_MAC80211_LEDS |
884 | bool led_registered; | 976 | bool led_registered; |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eaf8f058c151..b2f56d8b9043 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -108,55 +108,6 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
108 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); | 108 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); |
109 | } | 109 | } |
110 | 110 | ||
111 | static void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | ||
112 | struct sk_buff *skb) | ||
113 | { | ||
114 | static const u8 noa_ie_hdr[] = { | ||
115 | WLAN_EID_VENDOR_SPECIFIC, /* type */ | ||
116 | 0, /* length */ | ||
117 | 0x50, 0x6f, 0x9a, /* WFA OUI */ | ||
118 | 0x09, /* P2P subtype */ | ||
119 | 0x0c, /* Notice of Absence */ | ||
120 | 0x00, /* LSB of little-endian len */ | ||
121 | 0x00, /* MSB of little-endian len */ | ||
122 | }; | ||
123 | |||
124 | struct ieee80211_p2p_noa_attr *noa; | ||
125 | int noa_len, noa_desc, i = 0; | ||
126 | u8 *hdr; | ||
127 | |||
128 | if (!avp->offchannel_duration && !avp->periodic_noa_duration) | ||
129 | return; | ||
130 | |||
131 | noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration; | ||
132 | noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc; | ||
133 | |||
134 | hdr = skb_put(skb, sizeof(noa_ie_hdr)); | ||
135 | memcpy(hdr, noa_ie_hdr, sizeof(noa_ie_hdr)); | ||
136 | hdr[1] = sizeof(noa_ie_hdr) + noa_len - 2; | ||
137 | hdr[7] = noa_len; | ||
138 | |||
139 | noa = (void *) skb_put(skb, noa_len); | ||
140 | memset(noa, 0, noa_len); | ||
141 | |||
142 | noa->index = avp->noa_index; | ||
143 | if (avp->periodic_noa_duration) { | ||
144 | u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval); | ||
145 | |||
146 | noa->desc[i].count = 255; | ||
147 | noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start); | ||
148 | noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration); | ||
149 | noa->desc[i].interval = cpu_to_le32(interval); | ||
150 | i++; | ||
151 | } | ||
152 | |||
153 | if (avp->offchannel_duration) { | ||
154 | noa->desc[i].count = 1; | ||
155 | noa->desc[i].start_time = cpu_to_le32(avp->offchannel_start); | ||
156 | noa->desc[i].duration = cpu_to_le32(avp->offchannel_duration); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | 111 | static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, |
161 | struct ieee80211_vif *vif) | 112 | struct ieee80211_vif *vif) |
162 | { | 113 | { |
@@ -427,9 +378,10 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
427 | 378 | ||
428 | /* EDMA devices check that in the tx completion function. */ | 379 | /* EDMA devices check that in the tx completion function. */ |
429 | if (!edma) { | 380 | if (!edma) { |
430 | if (sc->sched.beacon_pending) | 381 | if (ath9k_is_chanctx_enabled()) { |
431 | ath_chanctx_event(sc, NULL, | 382 | ath_chanctx_beacon_sent_ev(sc, |
432 | ATH_CHANCTX_EVENT_BEACON_SENT); | 383 | ATH_CHANCTX_EVENT_BEACON_SENT); |
384 | } | ||
433 | 385 | ||
434 | if (ath9k_csa_is_finished(sc, vif)) | 386 | if (ath9k_csa_is_finished(sc, vif)) |
435 | return; | 387 | return; |
@@ -438,7 +390,10 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
438 | if (!vif || !vif->bss_conf.enable_beacon) | 390 | if (!vif || !vif->bss_conf.enable_beacon) |
439 | return; | 391 | return; |
440 | 392 | ||
441 | ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_BEACON_PREPARE); | 393 | if (ath9k_is_chanctx_enabled()) { |
394 | ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_BEACON_PREPARE); | ||
395 | } | ||
396 | |||
442 | bf = ath9k_beacon_generate(sc->hw, vif); | 397 | bf = ath9k_beacon_generate(sc->hw, vif); |
443 | 398 | ||
444 | if (sc->beacon.bmisscnt != 0) { | 399 | if (sc->beacon.bmisscnt != 0) { |
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index ba214ebdcd16..409f912a67c7 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c | |||
@@ -101,202 +101,6 @@ static int ath_set_channel(struct ath_softc *sc) | |||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static bool | ||
105 | ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, | ||
106 | bool powersave) | ||
107 | { | ||
108 | struct ieee80211_vif *vif = avp->vif; | ||
109 | struct ieee80211_sta *sta = NULL; | ||
110 | struct ieee80211_hdr_3addr *nullfunc; | ||
111 | struct ath_tx_control txctl; | ||
112 | struct sk_buff *skb; | ||
113 | int band = sc->cur_chan->chandef.chan->band; | ||
114 | |||
115 | switch (vif->type) { | ||
116 | case NL80211_IFTYPE_STATION: | ||
117 | if (!vif->bss_conf.assoc) | ||
118 | return false; | ||
119 | |||
120 | skb = ieee80211_nullfunc_get(sc->hw, vif); | ||
121 | if (!skb) | ||
122 | return false; | ||
123 | |||
124 | nullfunc = (struct ieee80211_hdr_3addr *) skb->data; | ||
125 | if (powersave) | ||
126 | nullfunc->frame_control |= | ||
127 | cpu_to_le16(IEEE80211_FCTL_PM); | ||
128 | |||
129 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
130 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) { | ||
131 | dev_kfree_skb_any(skb); | ||
132 | return false; | ||
133 | } | ||
134 | break; | ||
135 | default: | ||
136 | return false; | ||
137 | } | ||
138 | |||
139 | memset(&txctl, 0, sizeof(txctl)); | ||
140 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | ||
141 | txctl.sta = sta; | ||
142 | txctl.force_channel = true; | ||
143 | if (ath_tx_start(sc->hw, skb, &txctl)) { | ||
144 | ieee80211_free_txskb(sc->hw, skb); | ||
145 | return false; | ||
146 | } | ||
147 | |||
148 | return true; | ||
149 | } | ||
150 | |||
151 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) | ||
152 | { | ||
153 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
154 | struct ath_vif *avp; | ||
155 | bool active = false; | ||
156 | u8 n_active = 0; | ||
157 | |||
158 | if (!ctx) | ||
159 | return; | ||
160 | |||
161 | list_for_each_entry(avp, &ctx->vifs, list) { | ||
162 | struct ieee80211_vif *vif = avp->vif; | ||
163 | |||
164 | switch (vif->type) { | ||
165 | case NL80211_IFTYPE_P2P_CLIENT: | ||
166 | case NL80211_IFTYPE_STATION: | ||
167 | if (vif->bss_conf.assoc) | ||
168 | active = true; | ||
169 | break; | ||
170 | default: | ||
171 | active = true; | ||
172 | break; | ||
173 | } | ||
174 | } | ||
175 | ctx->active = active; | ||
176 | |||
177 | ath_for_each_chanctx(sc, ctx) { | ||
178 | if (!ctx->assigned || list_empty(&ctx->vifs)) | ||
179 | continue; | ||
180 | n_active++; | ||
181 | } | ||
182 | |||
183 | if (n_active <= 1) { | ||
184 | clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags); | ||
185 | return; | ||
186 | } | ||
187 | if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) | ||
188 | return; | ||
189 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL); | ||
190 | } | ||
191 | |||
192 | static bool | ||
193 | ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave) | ||
194 | { | ||
195 | struct ath_vif *avp; | ||
196 | bool sent = false; | ||
197 | |||
198 | rcu_read_lock(); | ||
199 | list_for_each_entry(avp, &sc->cur_chan->vifs, list) { | ||
200 | if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave)) | ||
201 | sent = true; | ||
202 | } | ||
203 | rcu_read_unlock(); | ||
204 | |||
205 | return sent; | ||
206 | } | ||
207 | |||
208 | static bool ath_chanctx_defer_switch(struct ath_softc *sc) | ||
209 | { | ||
210 | if (sc->cur_chan == &sc->offchannel.chan) | ||
211 | return false; | ||
212 | |||
213 | switch (sc->sched.state) { | ||
214 | case ATH_CHANCTX_STATE_SWITCH: | ||
215 | return false; | ||
216 | case ATH_CHANCTX_STATE_IDLE: | ||
217 | if (!sc->cur_chan->switch_after_beacon) | ||
218 | return false; | ||
219 | |||
220 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | ||
221 | break; | ||
222 | default: | ||
223 | break; | ||
224 | } | ||
225 | |||
226 | return true; | ||
227 | } | ||
228 | |||
229 | static void ath_chanctx_set_next(struct ath_softc *sc, bool force) | ||
230 | { | ||
231 | struct timespec ts; | ||
232 | bool measure_time = false; | ||
233 | bool send_ps = false; | ||
234 | |||
235 | spin_lock_bh(&sc->chan_lock); | ||
236 | if (!sc->next_chan) { | ||
237 | spin_unlock_bh(&sc->chan_lock); | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | if (!force && ath_chanctx_defer_switch(sc)) { | ||
242 | spin_unlock_bh(&sc->chan_lock); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | if (sc->cur_chan != sc->next_chan) { | ||
247 | sc->cur_chan->stopped = true; | ||
248 | spin_unlock_bh(&sc->chan_lock); | ||
249 | |||
250 | if (sc->next_chan == &sc->offchannel.chan) { | ||
251 | getrawmonotonic(&ts); | ||
252 | measure_time = true; | ||
253 | } | ||
254 | __ath9k_flush(sc->hw, ~0, true); | ||
255 | |||
256 | if (ath_chanctx_send_ps_frame(sc, true)) | ||
257 | __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false); | ||
258 | |||
259 | send_ps = true; | ||
260 | spin_lock_bh(&sc->chan_lock); | ||
261 | |||
262 | if (sc->cur_chan != &sc->offchannel.chan) { | ||
263 | getrawmonotonic(&sc->cur_chan->tsf_ts); | ||
264 | sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah); | ||
265 | } | ||
266 | } | ||
267 | sc->cur_chan = sc->next_chan; | ||
268 | sc->cur_chan->stopped = false; | ||
269 | sc->next_chan = NULL; | ||
270 | sc->sched.offchannel_duration = 0; | ||
271 | if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE) | ||
272 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; | ||
273 | |||
274 | spin_unlock_bh(&sc->chan_lock); | ||
275 | |||
276 | if (sc->sc_ah->chip_fullsleep || | ||
277 | memcmp(&sc->cur_chandef, &sc->cur_chan->chandef, | ||
278 | sizeof(sc->cur_chandef))) { | ||
279 | ath_set_channel(sc); | ||
280 | if (measure_time) | ||
281 | sc->sched.channel_switch_time = | ||
282 | ath9k_hw_get_tsf_offset(&ts, NULL); | ||
283 | } | ||
284 | if (send_ps) | ||
285 | ath_chanctx_send_ps_frame(sc, false); | ||
286 | |||
287 | ath_offchannel_channel_change(sc); | ||
288 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH); | ||
289 | } | ||
290 | |||
291 | void ath_chanctx_work(struct work_struct *work) | ||
292 | { | ||
293 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
294 | chanctx_work); | ||
295 | mutex_lock(&sc->mutex); | ||
296 | ath_chanctx_set_next(sc, false); | ||
297 | mutex_unlock(&sc->mutex); | ||
298 | } | ||
299 | |||
300 | void ath_chanctx_init(struct ath_softc *sc) | 104 | void ath_chanctx_init(struct ath_softc *sc) |
301 | { | 105 | { |
302 | struct ath_chanctx *ctx; | 106 | struct ath_chanctx *ctx; |
@@ -318,115 +122,124 @@ void ath_chanctx_init(struct ath_softc *sc) | |||
318 | for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) | 122 | for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) |
319 | INIT_LIST_HEAD(&ctx->acq[j]); | 123 | INIT_LIST_HEAD(&ctx->acq[j]); |
320 | } | 124 | } |
321 | ctx = &sc->offchannel.chan; | ||
322 | cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20); | ||
323 | INIT_LIST_HEAD(&ctx->vifs); | ||
324 | ctx->txpower = ATH_TXPOWER_MAX; | ||
325 | for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) | ||
326 | INIT_LIST_HEAD(&ctx->acq[j]); | ||
327 | sc->offchannel.chan.offchannel = true; | ||
328 | |||
329 | } | 125 | } |
330 | 126 | ||
331 | void ath9k_chanctx_force_active(struct ieee80211_hw *hw, | 127 | void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, |
332 | struct ieee80211_vif *vif) | 128 | struct cfg80211_chan_def *chandef) |
333 | { | 129 | { |
334 | struct ath_softc *sc = hw->priv; | ||
335 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 130 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
336 | struct ath_vif *avp = (struct ath_vif *) vif->drv_priv; | 131 | bool cur_chan; |
337 | bool changed = false; | ||
338 | |||
339 | if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) | ||
340 | return; | ||
341 | |||
342 | if (!avp->chanctx) | ||
343 | return; | ||
344 | |||
345 | mutex_lock(&sc->mutex); | ||
346 | 132 | ||
347 | spin_lock_bh(&sc->chan_lock); | 133 | spin_lock_bh(&sc->chan_lock); |
348 | if (sc->next_chan || (sc->cur_chan != avp->chanctx)) { | 134 | if (chandef) |
349 | sc->next_chan = avp->chanctx; | 135 | memcpy(&ctx->chandef, chandef, sizeof(*chandef)); |
350 | changed = true; | 136 | cur_chan = sc->cur_chan == ctx; |
351 | } | ||
352 | sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE; | ||
353 | spin_unlock_bh(&sc->chan_lock); | 137 | spin_unlock_bh(&sc->chan_lock); |
354 | 138 | ||
355 | if (changed) | 139 | if (!cur_chan) { |
356 | ath_chanctx_set_next(sc, true); | 140 | ath_dbg(common, CHAN_CTX, |
141 | "Current context differs from the new context\n"); | ||
142 | return; | ||
143 | } | ||
357 | 144 | ||
358 | mutex_unlock(&sc->mutex); | 145 | ath_set_channel(sc); |
359 | } | 146 | } |
360 | 147 | ||
361 | void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, | 148 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT |
362 | struct cfg80211_chan_def *chandef) | ||
363 | { | ||
364 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
365 | 149 | ||
366 | spin_lock_bh(&sc->chan_lock); | 150 | /**********************************************************/ |
151 | /* Functions to handle the channel context state machine. */ | ||
152 | /**********************************************************/ | ||
367 | 153 | ||
368 | if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && | 154 | static const char *offchannel_state_string(enum ath_offchannel_state state) |
369 | (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { | 155 | { |
370 | sc->sched.offchannel_pending = true; | 156 | switch (state) { |
371 | spin_unlock_bh(&sc->chan_lock); | 157 | case_rtn_string(ATH_OFFCHANNEL_IDLE); |
372 | return; | 158 | case_rtn_string(ATH_OFFCHANNEL_PROBE_SEND); |
159 | case_rtn_string(ATH_OFFCHANNEL_PROBE_WAIT); | ||
160 | case_rtn_string(ATH_OFFCHANNEL_SUSPEND); | ||
161 | case_rtn_string(ATH_OFFCHANNEL_ROC_START); | ||
162 | case_rtn_string(ATH_OFFCHANNEL_ROC_WAIT); | ||
163 | case_rtn_string(ATH_OFFCHANNEL_ROC_DONE); | ||
164 | default: | ||
165 | return "unknown"; | ||
373 | } | 166 | } |
167 | } | ||
374 | 168 | ||
375 | sc->next_chan = ctx; | 169 | static const char *chanctx_event_string(enum ath_chanctx_event ev) |
376 | if (chandef) | 170 | { |
377 | ctx->chandef = *chandef; | 171 | switch (ev) { |
378 | 172 | case_rtn_string(ATH_CHANCTX_EVENT_BEACON_PREPARE); | |
379 | if (sc->next_chan == &sc->offchannel.chan) { | 173 | case_rtn_string(ATH_CHANCTX_EVENT_BEACON_SENT); |
380 | sc->sched.offchannel_duration = | 174 | case_rtn_string(ATH_CHANCTX_EVENT_TSF_TIMER); |
381 | TU_TO_USEC(sc->offchannel.duration) + | 175 | case_rtn_string(ATH_CHANCTX_EVENT_BEACON_RECEIVED); |
382 | sc->sched.channel_switch_time; | 176 | case_rtn_string(ATH_CHANCTX_EVENT_ASSOC); |
177 | case_rtn_string(ATH_CHANCTX_EVENT_SWITCH); | ||
178 | case_rtn_string(ATH_CHANCTX_EVENT_ASSIGN); | ||
179 | case_rtn_string(ATH_CHANCTX_EVENT_UNASSIGN); | ||
180 | case_rtn_string(ATH_CHANCTX_EVENT_CHANGE); | ||
181 | case_rtn_string(ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL); | ||
182 | default: | ||
183 | return "unknown"; | ||
383 | } | 184 | } |
384 | spin_unlock_bh(&sc->chan_lock); | ||
385 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); | ||
386 | } | 185 | } |
387 | 186 | ||
388 | void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, | 187 | static const char *chanctx_state_string(enum ath_chanctx_state state) |
389 | struct cfg80211_chan_def *chandef) | ||
390 | { | 188 | { |
391 | bool cur_chan; | 189 | switch (state) { |
190 | case_rtn_string(ATH_CHANCTX_STATE_IDLE); | ||
191 | case_rtn_string(ATH_CHANCTX_STATE_WAIT_FOR_BEACON); | ||
192 | case_rtn_string(ATH_CHANCTX_STATE_WAIT_FOR_TIMER); | ||
193 | case_rtn_string(ATH_CHANCTX_STATE_SWITCH); | ||
194 | case_rtn_string(ATH_CHANCTX_STATE_FORCE_ACTIVE); | ||
195 | default: | ||
196 | return "unknown"; | ||
197 | } | ||
198 | } | ||
392 | 199 | ||
393 | spin_lock_bh(&sc->chan_lock); | 200 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) |
394 | if (chandef) | 201 | { |
395 | memcpy(&ctx->chandef, chandef, sizeof(*chandef)); | 202 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
396 | cur_chan = sc->cur_chan == ctx; | 203 | struct ath_vif *avp; |
397 | spin_unlock_bh(&sc->chan_lock); | 204 | bool active = false; |
205 | u8 n_active = 0; | ||
398 | 206 | ||
399 | if (!cur_chan) | 207 | if (!ctx) |
400 | return; | 208 | return; |
401 | 209 | ||
402 | ath_set_channel(sc); | 210 | list_for_each_entry(avp, &ctx->vifs, list) { |
403 | } | 211 | struct ieee80211_vif *vif = avp->vif; |
404 | 212 | ||
405 | struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active) | 213 | switch (vif->type) { |
406 | { | 214 | case NL80211_IFTYPE_P2P_CLIENT: |
407 | struct ath_chanctx *ctx; | 215 | case NL80211_IFTYPE_STATION: |
216 | if (vif->bss_conf.assoc) | ||
217 | active = true; | ||
218 | break; | ||
219 | default: | ||
220 | active = true; | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | ctx->active = active; | ||
408 | 225 | ||
409 | ath_for_each_chanctx(sc, ctx) { | 226 | ath_for_each_chanctx(sc, ctx) { |
410 | if (!ctx->assigned || list_empty(&ctx->vifs)) | 227 | if (!ctx->assigned || list_empty(&ctx->vifs)) |
411 | continue; | 228 | continue; |
412 | if (active && !ctx->active) | 229 | n_active++; |
413 | continue; | ||
414 | |||
415 | if (ctx->switch_after_beacon) | ||
416 | return ctx; | ||
417 | } | 230 | } |
418 | 231 | ||
419 | return &sc->chanctx[0]; | 232 | if (n_active <= 1) { |
420 | } | 233 | clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags); |
421 | 234 | return; | |
422 | void ath_chanctx_offchan_switch(struct ath_softc *sc, | 235 | } |
423 | struct ieee80211_channel *chan) | 236 | if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) |
424 | { | 237 | return; |
425 | struct cfg80211_chan_def chandef; | ||
426 | |||
427 | cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); | ||
428 | 238 | ||
429 | ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef); | 239 | if (ath9k_is_chanctx_enabled()) { |
240 | ath_chanctx_event(sc, NULL, | ||
241 | ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL); | ||
242 | } | ||
430 | } | 243 | } |
431 | 244 | ||
432 | static struct ath_chanctx * | 245 | static struct ath_chanctx * |
@@ -469,25 +282,22 @@ static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc) | |||
469 | prev->tsf_val += offset; | 282 | prev->tsf_val += offset; |
470 | } | 283 | } |
471 | 284 | ||
472 | void ath_chanctx_timer(unsigned long data) | ||
473 | { | ||
474 | struct ath_softc *sc = (struct ath_softc *) data; | ||
475 | |||
476 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER); | ||
477 | } | ||
478 | |||
479 | /* Configure the TSF based hardware timer for a channel switch. | 285 | /* Configure the TSF based hardware timer for a channel switch. |
480 | * Also set up backup software timer, in case the gen timer fails. | 286 | * Also set up backup software timer, in case the gen timer fails. |
481 | * This could be caused by a hardware reset. | 287 | * This could be caused by a hardware reset. |
482 | */ | 288 | */ |
483 | static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time) | 289 | static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time) |
484 | { | 290 | { |
291 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
485 | struct ath_hw *ah = sc->sc_ah; | 292 | struct ath_hw *ah = sc->sc_ah; |
486 | 293 | ||
487 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000); | 294 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000); |
488 | tsf_time -= ath9k_hw_gettsf32(ah); | 295 | tsf_time -= ath9k_hw_gettsf32(ah); |
489 | tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1; | 296 | tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1; |
490 | mod_timer(&sc->sched.timer, tsf_time); | 297 | mod_timer(&sc->sched.timer, jiffies + tsf_time); |
298 | |||
299 | ath_dbg(common, CHAN_CTX, | ||
300 | "Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time)); | ||
491 | } | 301 | } |
492 | 302 | ||
493 | void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | 303 | void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, |
@@ -507,33 +317,50 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
507 | 317 | ||
508 | spin_lock_bh(&sc->chan_lock); | 318 | spin_lock_bh(&sc->chan_lock); |
509 | 319 | ||
320 | ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s\n", | ||
321 | sc->cur_chan->chandef.center_freq1, | ||
322 | chanctx_event_string(ev), | ||
323 | chanctx_state_string(sc->sched.state)); | ||
324 | |||
510 | switch (ev) { | 325 | switch (ev) { |
511 | case ATH_CHANCTX_EVENT_BEACON_PREPARE: | 326 | case ATH_CHANCTX_EVENT_BEACON_PREPARE: |
512 | if (avp->offchannel_duration) | 327 | if (avp->offchannel_duration) |
513 | avp->offchannel_duration = 0; | 328 | avp->offchannel_duration = 0; |
514 | 329 | ||
515 | if (avp->chanctx != sc->cur_chan) | 330 | if (avp->chanctx != sc->cur_chan) { |
331 | ath_dbg(common, CHAN_CTX, | ||
332 | "Contexts differ, not preparing beacon\n"); | ||
516 | break; | 333 | break; |
334 | } | ||
517 | 335 | ||
518 | if (sc->sched.offchannel_pending) { | 336 | if (sc->sched.offchannel_pending) { |
519 | sc->sched.offchannel_pending = false; | 337 | sc->sched.offchannel_pending = false; |
520 | sc->next_chan = &sc->offchannel.chan; | 338 | sc->next_chan = &sc->offchannel.chan; |
521 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | 339 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; |
340 | ath_dbg(common, CHAN_CTX, | ||
341 | "Setting offchannel_pending to false\n"); | ||
522 | } | 342 | } |
523 | 343 | ||
524 | ctx = ath_chanctx_get_next(sc, sc->cur_chan); | 344 | ctx = ath_chanctx_get_next(sc, sc->cur_chan); |
525 | if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) { | 345 | if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) { |
526 | sc->next_chan = ctx; | 346 | sc->next_chan = ctx; |
527 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | 347 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; |
348 | ath_dbg(common, CHAN_CTX, | ||
349 | "Set next context, move chanctx state to WAIT_FOR_BEACON\n"); | ||
528 | } | 350 | } |
529 | 351 | ||
530 | /* if the timer missed its window, use the next interval */ | 352 | /* if the timer missed its window, use the next interval */ |
531 | if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER) | 353 | if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER) { |
532 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | 354 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; |
355 | ath_dbg(common, CHAN_CTX, | ||
356 | "Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n"); | ||
357 | } | ||
533 | 358 | ||
534 | if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) | 359 | if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) |
535 | break; | 360 | break; |
536 | 361 | ||
362 | ath_dbg(common, CHAN_CTX, "Preparing beacon for vif: %pM\n", vif->addr); | ||
363 | |||
537 | sc->sched.beacon_pending = true; | 364 | sc->sched.beacon_pending = true; |
538 | sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER); | 365 | sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER); |
539 | 366 | ||
@@ -577,15 +404,28 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
577 | 404 | ||
578 | if (noa_changed) | 405 | if (noa_changed) |
579 | avp->noa_index++; | 406 | avp->noa_index++; |
407 | |||
408 | ath_dbg(common, CHAN_CTX, | ||
409 | "periodic_noa_duration: %d, periodic_noa_start: %d, noa_index: %d\n", | ||
410 | avp->periodic_noa_duration, | ||
411 | avp->periodic_noa_start, | ||
412 | avp->noa_index); | ||
413 | |||
580 | break; | 414 | break; |
581 | case ATH_CHANCTX_EVENT_BEACON_SENT: | 415 | case ATH_CHANCTX_EVENT_BEACON_SENT: |
582 | if (!sc->sched.beacon_pending) | 416 | if (!sc->sched.beacon_pending) { |
417 | ath_dbg(common, CHAN_CTX, | ||
418 | "No pending beacon\n"); | ||
583 | break; | 419 | break; |
420 | } | ||
584 | 421 | ||
585 | sc->sched.beacon_pending = false; | 422 | sc->sched.beacon_pending = false; |
586 | if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) | 423 | if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) |
587 | break; | 424 | break; |
588 | 425 | ||
426 | ath_dbg(common, CHAN_CTX, | ||
427 | "Move chanctx state to WAIT_FOR_TIMER\n"); | ||
428 | |||
589 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; | 429 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; |
590 | ath_chanctx_setup_timer(sc, sc->sched.switch_start_time); | 430 | ath_chanctx_setup_timer(sc, sc->sched.switch_start_time); |
591 | break; | 431 | break; |
@@ -597,6 +437,9 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
597 | sc->sched.beacon_pending) | 437 | sc->sched.beacon_pending) |
598 | sc->sched.beacon_miss++; | 438 | sc->sched.beacon_miss++; |
599 | 439 | ||
440 | ath_dbg(common, CHAN_CTX, | ||
441 | "Move chanctx state to SWITCH\n"); | ||
442 | |||
600 | sc->sched.state = ATH_CHANCTX_STATE_SWITCH; | 443 | sc->sched.state = ATH_CHANCTX_STATE_SWITCH; |
601 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); | 444 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); |
602 | break; | 445 | break; |
@@ -625,6 +468,9 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
625 | avp->chanctx != sc->cur_chan) | 468 | avp->chanctx != sc->cur_chan) |
626 | break; | 469 | break; |
627 | 470 | ||
471 | ath_dbg(common, CHAN_CTX, | ||
472 | "Move chanctx state from FORCE_ACTIVE to IDLE\n"); | ||
473 | |||
628 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; | 474 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; |
629 | /* fall through */ | 475 | /* fall through */ |
630 | case ATH_CHANCTX_EVENT_SWITCH: | 476 | case ATH_CHANCTX_EVENT_SWITCH: |
@@ -640,6 +486,9 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
640 | sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan); | 486 | sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan); |
641 | cur_conf = &sc->cur_chan->beacon; | 487 | cur_conf = &sc->cur_chan->beacon; |
642 | 488 | ||
489 | ath_dbg(common, CHAN_CTX, | ||
490 | "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n"); | ||
491 | |||
643 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; | 492 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; |
644 | 493 | ||
645 | tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; | 494 | tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; |
@@ -679,7 +528,785 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
679 | sc->next_chan = ctx; | 528 | sc->next_chan = ctx; |
680 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); | 529 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); |
681 | break; | 530 | break; |
531 | case ATH_CHANCTX_EVENT_ASSIGN: | ||
532 | /* | ||
533 | * When adding a new channel context, check if a scan | ||
534 | * is in progress and abort it since the addition of | ||
535 | * a new channel context is usually followed by VIF | ||
536 | * assignment, in which case we have to start multi-channel | ||
537 | * operation. | ||
538 | */ | ||
539 | if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { | ||
540 | ath_dbg(common, CHAN_CTX, | ||
541 | "Aborting HW scan to add new context\n"); | ||
542 | |||
543 | spin_unlock_bh(&sc->chan_lock); | ||
544 | del_timer_sync(&sc->offchannel.timer); | ||
545 | ath_scan_complete(sc, true); | ||
546 | spin_lock_bh(&sc->chan_lock); | ||
547 | } | ||
548 | break; | ||
549 | case ATH_CHANCTX_EVENT_CHANGE: | ||
550 | break; | ||
551 | } | ||
552 | |||
553 | spin_unlock_bh(&sc->chan_lock); | ||
554 | } | ||
555 | |||
556 | void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, | ||
557 | enum ath_chanctx_event ev) | ||
558 | { | ||
559 | if (sc->sched.beacon_pending) | ||
560 | ath_chanctx_event(sc, NULL, ev); | ||
561 | } | ||
562 | |||
563 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, | ||
564 | enum ath_chanctx_event ev) | ||
565 | { | ||
566 | sc->sched.next_tbtt = ts; | ||
567 | ath_chanctx_event(sc, NULL, ev); | ||
568 | } | ||
569 | |||
570 | static int ath_scan_channel_duration(struct ath_softc *sc, | ||
571 | struct ieee80211_channel *chan) | ||
572 | { | ||
573 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
574 | |||
575 | if (!req->n_ssids || (chan->flags & IEEE80211_CHAN_NO_IR)) | ||
576 | return (HZ / 9); /* ~110 ms */ | ||
577 | |||
578 | return (HZ / 16); /* ~60 ms */ | ||
579 | } | ||
580 | |||
581 | static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, | ||
582 | struct cfg80211_chan_def *chandef) | ||
583 | { | ||
584 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
585 | |||
586 | spin_lock_bh(&sc->chan_lock); | ||
587 | |||
588 | if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && | ||
589 | (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { | ||
590 | sc->sched.offchannel_pending = true; | ||
591 | spin_unlock_bh(&sc->chan_lock); | ||
592 | return; | ||
593 | } | ||
594 | |||
595 | sc->next_chan = ctx; | ||
596 | if (chandef) { | ||
597 | ctx->chandef = *chandef; | ||
598 | ath_dbg(common, CHAN_CTX, | ||
599 | "Assigned next_chan to %d MHz\n", chandef->center_freq1); | ||
600 | } | ||
601 | |||
602 | if (sc->next_chan == &sc->offchannel.chan) { | ||
603 | sc->sched.offchannel_duration = | ||
604 | TU_TO_USEC(sc->offchannel.duration) + | ||
605 | sc->sched.channel_switch_time; | ||
606 | |||
607 | if (chandef) { | ||
608 | ath_dbg(common, CHAN_CTX, | ||
609 | "Offchannel duration for chan %d MHz : %u\n", | ||
610 | chandef->center_freq1, | ||
611 | sc->sched.offchannel_duration); | ||
612 | } | ||
613 | } | ||
614 | spin_unlock_bh(&sc->chan_lock); | ||
615 | ieee80211_queue_work(sc->hw, &sc->chanctx_work); | ||
616 | } | ||
617 | |||
618 | static void ath_chanctx_offchan_switch(struct ath_softc *sc, | ||
619 | struct ieee80211_channel *chan) | ||
620 | { | ||
621 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
622 | struct cfg80211_chan_def chandef; | ||
623 | |||
624 | cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); | ||
625 | ath_dbg(common, CHAN_CTX, | ||
626 | "Channel definition created: %d MHz\n", chandef.center_freq1); | ||
627 | |||
628 | ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef); | ||
629 | } | ||
630 | |||
631 | static struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, | ||
632 | bool active) | ||
633 | { | ||
634 | struct ath_chanctx *ctx; | ||
635 | |||
636 | ath_for_each_chanctx(sc, ctx) { | ||
637 | if (!ctx->assigned || list_empty(&ctx->vifs)) | ||
638 | continue; | ||
639 | if (active && !ctx->active) | ||
640 | continue; | ||
641 | |||
642 | if (ctx->switch_after_beacon) | ||
643 | return ctx; | ||
644 | } | ||
645 | |||
646 | return &sc->chanctx[0]; | ||
647 | } | ||
648 | |||
649 | static void | ||
650 | ath_scan_next_channel(struct ath_softc *sc) | ||
651 | { | ||
652 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
653 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
654 | struct ieee80211_channel *chan; | ||
655 | |||
656 | if (sc->offchannel.scan_idx >= req->n_channels) { | ||
657 | ath_dbg(common, CHAN_CTX, | ||
658 | "Moving offchannel state to ATH_OFFCHANNEL_IDLE, " | ||
659 | "scan_idx: %d, n_channels: %d\n", | ||
660 | sc->offchannel.scan_idx, | ||
661 | req->n_channels); | ||
662 | |||
663 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
664 | ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false), | ||
665 | NULL); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | ath_dbg(common, CHAN_CTX, | ||
670 | "Moving offchannel state to ATH_OFFCHANNEL_PROBE_SEND, scan_idx: %d\n", | ||
671 | sc->offchannel.scan_idx); | ||
672 | |||
673 | chan = req->channels[sc->offchannel.scan_idx++]; | ||
674 | sc->offchannel.duration = ath_scan_channel_duration(sc, chan); | ||
675 | sc->offchannel.state = ATH_OFFCHANNEL_PROBE_SEND; | ||
676 | |||
677 | ath_chanctx_offchan_switch(sc, chan); | ||
678 | } | ||
679 | |||
680 | void ath_offchannel_next(struct ath_softc *sc) | ||
681 | { | ||
682 | struct ieee80211_vif *vif; | ||
683 | |||
684 | if (sc->offchannel.scan_req) { | ||
685 | vif = sc->offchannel.scan_vif; | ||
686 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; | ||
687 | ath_scan_next_channel(sc); | ||
688 | } else if (sc->offchannel.roc_vif) { | ||
689 | vif = sc->offchannel.roc_vif; | ||
690 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; | ||
691 | sc->offchannel.duration = sc->offchannel.roc_duration; | ||
692 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; | ||
693 | ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); | ||
694 | } else { | ||
695 | ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false), | ||
696 | NULL); | ||
697 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
698 | if (sc->ps_idle) | ||
699 | ath_cancel_work(sc); | ||
700 | } | ||
701 | } | ||
702 | |||
703 | void ath_roc_complete(struct ath_softc *sc, bool abort) | ||
704 | { | ||
705 | sc->offchannel.roc_vif = NULL; | ||
706 | sc->offchannel.roc_chan = NULL; | ||
707 | if (!abort) | ||
708 | ieee80211_remain_on_channel_expired(sc->hw); | ||
709 | ath_offchannel_next(sc); | ||
710 | ath9k_ps_restore(sc); | ||
711 | } | ||
712 | |||
713 | void ath_scan_complete(struct ath_softc *sc, bool abort) | ||
714 | { | ||
715 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
716 | |||
717 | if (abort) | ||
718 | ath_dbg(common, CHAN_CTX, "HW scan aborted\n"); | ||
719 | else | ||
720 | ath_dbg(common, CHAN_CTX, "HW scan complete\n"); | ||
721 | |||
722 | sc->offchannel.scan_req = NULL; | ||
723 | sc->offchannel.scan_vif = NULL; | ||
724 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
725 | ieee80211_scan_completed(sc->hw, abort); | ||
726 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | ||
727 | ath_offchannel_next(sc); | ||
728 | ath9k_ps_restore(sc); | ||
729 | } | ||
730 | |||
731 | static void ath_scan_send_probe(struct ath_softc *sc, | ||
732 | struct cfg80211_ssid *ssid) | ||
733 | { | ||
734 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
735 | struct ieee80211_vif *vif = sc->offchannel.scan_vif; | ||
736 | struct ath_tx_control txctl = {}; | ||
737 | struct sk_buff *skb; | ||
738 | struct ieee80211_tx_info *info; | ||
739 | int band = sc->offchannel.chan.chandef.chan->band; | ||
740 | |||
741 | skb = ieee80211_probereq_get(sc->hw, vif, | ||
742 | ssid->ssid, ssid->ssid_len, req->ie_len); | ||
743 | if (!skb) | ||
744 | return; | ||
745 | |||
746 | info = IEEE80211_SKB_CB(skb); | ||
747 | if (req->no_cck) | ||
748 | info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | ||
749 | |||
750 | if (req->ie_len) | ||
751 | memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len); | ||
752 | |||
753 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
754 | |||
755 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL)) | ||
756 | goto error; | ||
757 | |||
758 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | ||
759 | txctl.force_channel = true; | ||
760 | if (ath_tx_start(sc->hw, skb, &txctl)) | ||
761 | goto error; | ||
762 | |||
763 | return; | ||
764 | |||
765 | error: | ||
766 | ieee80211_free_txskb(sc->hw, skb); | ||
767 | } | ||
768 | |||
769 | static void ath_scan_channel_start(struct ath_softc *sc) | ||
770 | { | ||
771 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
772 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
773 | int i; | ||
774 | |||
775 | if (!(sc->cur_chan->chandef.chan->flags & IEEE80211_CHAN_NO_IR) && | ||
776 | req->n_ssids) { | ||
777 | for (i = 0; i < req->n_ssids; i++) | ||
778 | ath_scan_send_probe(sc, &req->ssids[i]); | ||
779 | |||
780 | } | ||
781 | |||
782 | ath_dbg(common, CHAN_CTX, | ||
783 | "Moving offchannel state to ATH_OFFCHANNEL_PROBE_WAIT\n"); | ||
784 | |||
785 | sc->offchannel.state = ATH_OFFCHANNEL_PROBE_WAIT; | ||
786 | mod_timer(&sc->offchannel.timer, jiffies + sc->offchannel.duration); | ||
787 | } | ||
788 | |||
789 | static void ath_chanctx_timer(unsigned long data) | ||
790 | { | ||
791 | struct ath_softc *sc = (struct ath_softc *) data; | ||
792 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
793 | |||
794 | ath_dbg(common, CHAN_CTX, | ||
795 | "Channel context timer invoked\n"); | ||
796 | |||
797 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER); | ||
798 | } | ||
799 | |||
800 | static void ath_offchannel_timer(unsigned long data) | ||
801 | { | ||
802 | struct ath_softc *sc = (struct ath_softc *)data; | ||
803 | struct ath_chanctx *ctx; | ||
804 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
805 | |||
806 | ath_dbg(common, CHAN_CTX, "%s: offchannel state: %s\n", | ||
807 | __func__, offchannel_state_string(sc->offchannel.state)); | ||
808 | |||
809 | switch (sc->offchannel.state) { | ||
810 | case ATH_OFFCHANNEL_PROBE_WAIT: | ||
811 | if (!sc->offchannel.scan_req) | ||
812 | return; | ||
813 | |||
814 | /* get first active channel context */ | ||
815 | ctx = ath_chanctx_get_oper_chan(sc, true); | ||
816 | if (ctx->active) { | ||
817 | ath_dbg(common, CHAN_CTX, | ||
818 | "Switch to oper/active context, " | ||
819 | "move offchannel state to ATH_OFFCHANNEL_SUSPEND\n"); | ||
820 | |||
821 | sc->offchannel.state = ATH_OFFCHANNEL_SUSPEND; | ||
822 | ath_chanctx_switch(sc, ctx, NULL); | ||
823 | mod_timer(&sc->offchannel.timer, jiffies + HZ / 10); | ||
824 | break; | ||
825 | } | ||
826 | /* fall through */ | ||
827 | case ATH_OFFCHANNEL_SUSPEND: | ||
828 | if (!sc->offchannel.scan_req) | ||
829 | return; | ||
830 | |||
831 | ath_scan_next_channel(sc); | ||
832 | break; | ||
833 | case ATH_OFFCHANNEL_ROC_START: | ||
834 | case ATH_OFFCHANNEL_ROC_WAIT: | ||
835 | ctx = ath_chanctx_get_oper_chan(sc, false); | ||
836 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE; | ||
837 | ath_chanctx_switch(sc, ctx, NULL); | ||
838 | break; | ||
839 | default: | ||
840 | break; | ||
841 | } | ||
842 | } | ||
843 | |||
844 | static bool | ||
845 | ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, | ||
846 | bool powersave) | ||
847 | { | ||
848 | struct ieee80211_vif *vif = avp->vif; | ||
849 | struct ieee80211_sta *sta = NULL; | ||
850 | struct ieee80211_hdr_3addr *nullfunc; | ||
851 | struct ath_tx_control txctl; | ||
852 | struct sk_buff *skb; | ||
853 | int band = sc->cur_chan->chandef.chan->band; | ||
854 | |||
855 | switch (vif->type) { | ||
856 | case NL80211_IFTYPE_STATION: | ||
857 | if (!vif->bss_conf.assoc) | ||
858 | return false; | ||
859 | |||
860 | skb = ieee80211_nullfunc_get(sc->hw, vif); | ||
861 | if (!skb) | ||
862 | return false; | ||
863 | |||
864 | nullfunc = (struct ieee80211_hdr_3addr *) skb->data; | ||
865 | if (powersave) | ||
866 | nullfunc->frame_control |= | ||
867 | cpu_to_le16(IEEE80211_FCTL_PM); | ||
868 | |||
869 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
870 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) { | ||
871 | dev_kfree_skb_any(skb); | ||
872 | return false; | ||
873 | } | ||
874 | break; | ||
875 | default: | ||
876 | return false; | ||
877 | } | ||
878 | |||
879 | memset(&txctl, 0, sizeof(txctl)); | ||
880 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | ||
881 | txctl.sta = sta; | ||
882 | txctl.force_channel = true; | ||
883 | if (ath_tx_start(sc->hw, skb, &txctl)) { | ||
884 | ieee80211_free_txskb(sc->hw, skb); | ||
885 | return false; | ||
886 | } | ||
887 | |||
888 | return true; | ||
889 | } | ||
890 | |||
891 | static bool | ||
892 | ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave) | ||
893 | { | ||
894 | struct ath_vif *avp; | ||
895 | bool sent = false; | ||
896 | |||
897 | rcu_read_lock(); | ||
898 | list_for_each_entry(avp, &sc->cur_chan->vifs, list) { | ||
899 | if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave)) | ||
900 | sent = true; | ||
901 | } | ||
902 | rcu_read_unlock(); | ||
903 | |||
904 | return sent; | ||
905 | } | ||
906 | |||
907 | static bool ath_chanctx_defer_switch(struct ath_softc *sc) | ||
908 | { | ||
909 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
910 | |||
911 | if (sc->cur_chan == &sc->offchannel.chan) | ||
912 | return false; | ||
913 | |||
914 | switch (sc->sched.state) { | ||
915 | case ATH_CHANCTX_STATE_SWITCH: | ||
916 | return false; | ||
917 | case ATH_CHANCTX_STATE_IDLE: | ||
918 | if (!sc->cur_chan->switch_after_beacon) | ||
919 | return false; | ||
920 | |||
921 | ath_dbg(common, CHAN_CTX, | ||
922 | "Defer switch, set chanctx state to WAIT_FOR_BEACON\n"); | ||
923 | |||
924 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | ||
925 | break; | ||
926 | default: | ||
927 | break; | ||
928 | } | ||
929 | |||
930 | return true; | ||
931 | } | ||
932 | |||
933 | static void ath_offchannel_channel_change(struct ath_softc *sc) | ||
934 | { | ||
935 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
936 | |||
937 | ath_dbg(common, CHAN_CTX, "%s: offchannel state: %s\n", | ||
938 | __func__, offchannel_state_string(sc->offchannel.state)); | ||
939 | |||
940 | switch (sc->offchannel.state) { | ||
941 | case ATH_OFFCHANNEL_PROBE_SEND: | ||
942 | if (!sc->offchannel.scan_req) | ||
943 | return; | ||
944 | |||
945 | if (sc->cur_chan->chandef.chan != | ||
946 | sc->offchannel.chan.chandef.chan) | ||
947 | return; | ||
948 | |||
949 | ath_scan_channel_start(sc); | ||
950 | break; | ||
951 | case ATH_OFFCHANNEL_IDLE: | ||
952 | if (!sc->offchannel.scan_req) | ||
953 | return; | ||
954 | |||
955 | ath_scan_complete(sc, false); | ||
956 | break; | ||
957 | case ATH_OFFCHANNEL_ROC_START: | ||
958 | if (sc->cur_chan != &sc->offchannel.chan) | ||
959 | break; | ||
960 | |||
961 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT; | ||
962 | mod_timer(&sc->offchannel.timer, jiffies + | ||
963 | msecs_to_jiffies(sc->offchannel.duration)); | ||
964 | ieee80211_ready_on_channel(sc->hw); | ||
965 | break; | ||
966 | case ATH_OFFCHANNEL_ROC_DONE: | ||
967 | ath_roc_complete(sc, false); | ||
968 | break; | ||
969 | default: | ||
970 | break; | ||
971 | } | ||
972 | } | ||
973 | |||
974 | void ath_chanctx_set_next(struct ath_softc *sc, bool force) | ||
975 | { | ||
976 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
977 | struct timespec ts; | ||
978 | bool measure_time = false; | ||
979 | bool send_ps = false; | ||
980 | |||
981 | spin_lock_bh(&sc->chan_lock); | ||
982 | if (!sc->next_chan) { | ||
983 | spin_unlock_bh(&sc->chan_lock); | ||
984 | return; | ||
682 | } | 985 | } |
683 | 986 | ||
987 | if (!force && ath_chanctx_defer_switch(sc)) { | ||
988 | spin_unlock_bh(&sc->chan_lock); | ||
989 | return; | ||
990 | } | ||
991 | |||
992 | ath_dbg(common, CHAN_CTX, | ||
993 | "%s: current: %d MHz, next: %d MHz\n", | ||
994 | __func__, | ||
995 | sc->cur_chan->chandef.center_freq1, | ||
996 | sc->next_chan->chandef.center_freq1); | ||
997 | |||
998 | if (sc->cur_chan != sc->next_chan) { | ||
999 | ath_dbg(common, CHAN_CTX, | ||
1000 | "Stopping current chanctx: %d\n", | ||
1001 | sc->cur_chan->chandef.center_freq1); | ||
1002 | sc->cur_chan->stopped = true; | ||
1003 | spin_unlock_bh(&sc->chan_lock); | ||
1004 | |||
1005 | if (sc->next_chan == &sc->offchannel.chan) { | ||
1006 | getrawmonotonic(&ts); | ||
1007 | measure_time = true; | ||
1008 | } | ||
1009 | __ath9k_flush(sc->hw, ~0, true); | ||
1010 | |||
1011 | if (ath_chanctx_send_ps_frame(sc, true)) | ||
1012 | __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false); | ||
1013 | |||
1014 | send_ps = true; | ||
1015 | spin_lock_bh(&sc->chan_lock); | ||
1016 | |||
1017 | if (sc->cur_chan != &sc->offchannel.chan) { | ||
1018 | getrawmonotonic(&sc->cur_chan->tsf_ts); | ||
1019 | sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah); | ||
1020 | } | ||
1021 | } | ||
1022 | sc->cur_chan = sc->next_chan; | ||
1023 | sc->cur_chan->stopped = false; | ||
1024 | sc->next_chan = NULL; | ||
1025 | sc->sched.offchannel_duration = 0; | ||
1026 | if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE) | ||
1027 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; | ||
1028 | |||
684 | spin_unlock_bh(&sc->chan_lock); | 1029 | spin_unlock_bh(&sc->chan_lock); |
1030 | |||
1031 | if (sc->sc_ah->chip_fullsleep || | ||
1032 | memcmp(&sc->cur_chandef, &sc->cur_chan->chandef, | ||
1033 | sizeof(sc->cur_chandef))) { | ||
1034 | ath_dbg(common, CHAN_CTX, | ||
1035 | "%s: Set channel %d MHz\n", | ||
1036 | __func__, sc->cur_chan->chandef.center_freq1); | ||
1037 | ath_set_channel(sc); | ||
1038 | if (measure_time) | ||
1039 | sc->sched.channel_switch_time = | ||
1040 | ath9k_hw_get_tsf_offset(&ts, NULL); | ||
1041 | } | ||
1042 | if (send_ps) | ||
1043 | ath_chanctx_send_ps_frame(sc, false); | ||
1044 | |||
1045 | ath_offchannel_channel_change(sc); | ||
1046 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH); | ||
1047 | } | ||
1048 | |||
1049 | static void ath_chanctx_work(struct work_struct *work) | ||
1050 | { | ||
1051 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
1052 | chanctx_work); | ||
1053 | mutex_lock(&sc->mutex); | ||
1054 | ath_chanctx_set_next(sc, false); | ||
1055 | mutex_unlock(&sc->mutex); | ||
1056 | } | ||
1057 | |||
1058 | void ath9k_offchannel_init(struct ath_softc *sc) | ||
1059 | { | ||
1060 | struct ath_chanctx *ctx; | ||
1061 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1062 | struct ieee80211_supported_band *sband; | ||
1063 | struct ieee80211_channel *chan; | ||
1064 | int i; | ||
1065 | |||
1066 | sband = &common->sbands[IEEE80211_BAND_2GHZ]; | ||
1067 | if (!sband->n_channels) | ||
1068 | sband = &common->sbands[IEEE80211_BAND_5GHZ]; | ||
1069 | |||
1070 | chan = &sband->channels[0]; | ||
1071 | |||
1072 | ctx = &sc->offchannel.chan; | ||
1073 | INIT_LIST_HEAD(&ctx->vifs); | ||
1074 | ctx->txpower = ATH_TXPOWER_MAX; | ||
1075 | cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20); | ||
1076 | |||
1077 | for (i = 0; i < ARRAY_SIZE(ctx->acq); i++) | ||
1078 | INIT_LIST_HEAD(&ctx->acq[i]); | ||
1079 | |||
1080 | sc->offchannel.chan.offchannel = true; | ||
1081 | } | ||
1082 | |||
1083 | void ath9k_init_channel_context(struct ath_softc *sc) | ||
1084 | { | ||
1085 | INIT_WORK(&sc->chanctx_work, ath_chanctx_work); | ||
1086 | |||
1087 | setup_timer(&sc->offchannel.timer, ath_offchannel_timer, | ||
1088 | (unsigned long)sc); | ||
1089 | setup_timer(&sc->sched.timer, ath_chanctx_timer, | ||
1090 | (unsigned long)sc); | ||
1091 | } | ||
1092 | |||
1093 | void ath9k_deinit_channel_context(struct ath_softc *sc) | ||
1094 | { | ||
1095 | cancel_work_sync(&sc->chanctx_work); | ||
1096 | } | ||
1097 | |||
1098 | bool ath9k_is_chanctx_enabled(void) | ||
1099 | { | ||
1100 | return (ath9k_use_chanctx == 1); | ||
1101 | } | ||
1102 | |||
1103 | /********************/ | ||
1104 | /* Queue management */ | ||
1105 | /********************/ | ||
1106 | |||
1107 | void ath9k_chanctx_wake_queues(struct ath_softc *sc) | ||
1108 | { | ||
1109 | struct ath_hw *ah = sc->sc_ah; | ||
1110 | int i; | ||
1111 | |||
1112 | if (sc->cur_chan == &sc->offchannel.chan) { | ||
1113 | ieee80211_wake_queue(sc->hw, | ||
1114 | sc->hw->offchannel_tx_hw_queue); | ||
1115 | } else { | ||
1116 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | ||
1117 | ieee80211_wake_queue(sc->hw, | ||
1118 | sc->cur_chan->hw_queue_base + i); | ||
1119 | } | ||
1120 | |||
1121 | if (ah->opmode == NL80211_IFTYPE_AP) | ||
1122 | ieee80211_wake_queue(sc->hw, sc->hw->queues - 2); | ||
685 | } | 1123 | } |
1124 | |||
1125 | /*****************/ | ||
1126 | /* P2P Powersave */ | ||
1127 | /*****************/ | ||
1128 | |||
1129 | static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) | ||
1130 | { | ||
1131 | struct ath_hw *ah = sc->sc_ah; | ||
1132 | s32 tsf, target_tsf; | ||
1133 | |||
1134 | if (!avp || !avp->noa.has_next_tsf) | ||
1135 | return; | ||
1136 | |||
1137 | ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer); | ||
1138 | |||
1139 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1140 | |||
1141 | target_tsf = avp->noa.next_tsf; | ||
1142 | if (!avp->noa.absent) | ||
1143 | target_tsf -= ATH_P2P_PS_STOP_TIME; | ||
1144 | |||
1145 | if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) | ||
1146 | target_tsf = tsf + ATH_P2P_PS_STOP_TIME; | ||
1147 | |||
1148 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); | ||
1149 | } | ||
1150 | |||
1151 | static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
1152 | { | ||
1153 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1154 | u32 tsf; | ||
1155 | |||
1156 | if (!sc->p2p_ps_timer) | ||
1157 | return; | ||
1158 | |||
1159 | if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) | ||
1160 | return; | ||
1161 | |||
1162 | sc->p2p_ps_vif = avp; | ||
1163 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1164 | ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); | ||
1165 | ath9k_update_p2p_ps_timer(sc, avp); | ||
1166 | } | ||
1167 | |||
1168 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | ||
1169 | struct sk_buff *skb) | ||
1170 | { | ||
1171 | static const u8 noa_ie_hdr[] = { | ||
1172 | WLAN_EID_VENDOR_SPECIFIC, /* type */ | ||
1173 | 0, /* length */ | ||
1174 | 0x50, 0x6f, 0x9a, /* WFA OUI */ | ||
1175 | 0x09, /* P2P subtype */ | ||
1176 | 0x0c, /* Notice of Absence */ | ||
1177 | 0x00, /* LSB of little-endian len */ | ||
1178 | 0x00, /* MSB of little-endian len */ | ||
1179 | }; | ||
1180 | |||
1181 | struct ieee80211_p2p_noa_attr *noa; | ||
1182 | int noa_len, noa_desc, i = 0; | ||
1183 | u8 *hdr; | ||
1184 | |||
1185 | if (!avp->offchannel_duration && !avp->periodic_noa_duration) | ||
1186 | return; | ||
1187 | |||
1188 | noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration; | ||
1189 | noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc; | ||
1190 | |||
1191 | hdr = skb_put(skb, sizeof(noa_ie_hdr)); | ||
1192 | memcpy(hdr, noa_ie_hdr, sizeof(noa_ie_hdr)); | ||
1193 | hdr[1] = sizeof(noa_ie_hdr) + noa_len - 2; | ||
1194 | hdr[7] = noa_len; | ||
1195 | |||
1196 | noa = (void *) skb_put(skb, noa_len); | ||
1197 | memset(noa, 0, noa_len); | ||
1198 | |||
1199 | noa->index = avp->noa_index; | ||
1200 | if (avp->periodic_noa_duration) { | ||
1201 | u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval); | ||
1202 | |||
1203 | noa->desc[i].count = 255; | ||
1204 | noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start); | ||
1205 | noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration); | ||
1206 | noa->desc[i].interval = cpu_to_le32(interval); | ||
1207 | i++; | ||
1208 | } | ||
1209 | |||
1210 | if (avp->offchannel_duration) { | ||
1211 | noa->desc[i].count = 1; | ||
1212 | noa->desc[i].start_time = cpu_to_le32(avp->offchannel_start); | ||
1213 | noa->desc[i].duration = cpu_to_le32(avp->offchannel_duration); | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | void ath9k_p2p_ps_timer(void *priv) | ||
1218 | { | ||
1219 | struct ath_softc *sc = priv; | ||
1220 | struct ath_vif *avp = sc->p2p_ps_vif; | ||
1221 | struct ieee80211_vif *vif; | ||
1222 | struct ieee80211_sta *sta; | ||
1223 | struct ath_node *an; | ||
1224 | u32 tsf; | ||
1225 | |||
1226 | del_timer_sync(&sc->sched.timer); | ||
1227 | ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer); | ||
1228 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER); | ||
1229 | |||
1230 | if (!avp || avp->chanctx != sc->cur_chan) | ||
1231 | return; | ||
1232 | |||
1233 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1234 | if (!avp->noa.absent) | ||
1235 | tsf += ATH_P2P_PS_STOP_TIME; | ||
1236 | |||
1237 | if (!avp->noa.has_next_tsf || | ||
1238 | avp->noa.next_tsf - tsf > BIT(31)) | ||
1239 | ieee80211_update_p2p_noa(&avp->noa, tsf); | ||
1240 | |||
1241 | ath9k_update_p2p_ps_timer(sc, avp); | ||
1242 | |||
1243 | rcu_read_lock(); | ||
1244 | |||
1245 | vif = avp->vif; | ||
1246 | sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); | ||
1247 | if (!sta) | ||
1248 | goto out; | ||
1249 | |||
1250 | an = (void *) sta->drv_priv; | ||
1251 | if (an->sleeping == !!avp->noa.absent) | ||
1252 | goto out; | ||
1253 | |||
1254 | an->sleeping = avp->noa.absent; | ||
1255 | if (an->sleeping) | ||
1256 | ath_tx_aggr_sleep(sta, sc, an); | ||
1257 | else | ||
1258 | ath_tx_aggr_wakeup(sc, an); | ||
1259 | |||
1260 | out: | ||
1261 | rcu_read_unlock(); | ||
1262 | } | ||
1263 | |||
1264 | void ath9k_p2p_bss_info_changed(struct ath_softc *sc, | ||
1265 | struct ieee80211_vif *vif) | ||
1266 | { | ||
1267 | unsigned long flags; | ||
1268 | |||
1269 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1270 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1271 | if (!(sc->ps_flags & PS_BEACON_SYNC)) | ||
1272 | ath9k_update_p2p_ps(sc, vif); | ||
1273 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1274 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1275 | } | ||
1276 | |||
1277 | void ath9k_p2p_beacon_sync(struct ath_softc *sc) | ||
1278 | { | ||
1279 | if (sc->p2p_ps_vif) | ||
1280 | ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); | ||
1281 | } | ||
1282 | |||
1283 | void ath9k_p2p_remove_vif(struct ath_softc *sc, | ||
1284 | struct ieee80211_vif *vif) | ||
1285 | { | ||
1286 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1287 | |||
1288 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1289 | if (avp == sc->p2p_ps_vif) { | ||
1290 | sc->p2p_ps_vif = NULL; | ||
1291 | ath9k_update_p2p_ps_timer(sc, NULL); | ||
1292 | } | ||
1293 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1294 | } | ||
1295 | |||
1296 | int ath9k_init_p2p(struct ath_softc *sc) | ||
1297 | { | ||
1298 | sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, | ||
1299 | NULL, sc, AR_FIRST_NDP_TIMER); | ||
1300 | if (!sc->p2p_ps_timer) | ||
1301 | return -ENOMEM; | ||
1302 | |||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1306 | void ath9k_deinit_p2p(struct ath_softc *sc) | ||
1307 | { | ||
1308 | if (sc->p2p_ps_timer) | ||
1309 | ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer); | ||
1310 | } | ||
1311 | |||
1312 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8a3bd5fe3a54..d779f4fa50e3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -592,6 +592,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
592 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | | 592 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | |
593 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 593 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
594 | 594 | ||
595 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | ||
596 | |||
595 | hw->queues = 4; | 597 | hw->queues = 4; |
596 | hw->max_listen_interval = 1; | 598 | hw->max_listen_interval = 1; |
597 | 599 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 39419ea845cc..ca10a8b3a381 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -61,10 +61,14 @@ static int ath9k_ps_enable; | |||
61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | 61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); |
62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | 62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); |
63 | 63 | ||
64 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
65 | |||
64 | int ath9k_use_chanctx; | 66 | int ath9k_use_chanctx; |
65 | module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444); | 67 | module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444); |
66 | MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency"); | 68 | MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency"); |
67 | 69 | ||
70 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
71 | |||
68 | bool is_ath9k_unloaded; | 72 | bool is_ath9k_unloaded; |
69 | 73 | ||
70 | #ifdef CONFIG_MAC80211_LEDS | 74 | #ifdef CONFIG_MAC80211_LEDS |
@@ -511,7 +515,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
511 | sc->tx99_power = MAX_RATE_POWER + 1; | 515 | sc->tx99_power = MAX_RATE_POWER + 1; |
512 | init_waitqueue_head(&sc->tx_wait); | 516 | init_waitqueue_head(&sc->tx_wait); |
513 | sc->cur_chan = &sc->chanctx[0]; | 517 | sc->cur_chan = &sc->chanctx[0]; |
514 | if (!ath9k_use_chanctx) | 518 | if (!ath9k_is_chanctx_enabled()) |
515 | sc->cur_chan->hw_queue_base = 0; | 519 | sc->cur_chan->hw_queue_base = 0; |
516 | 520 | ||
517 | if (!pdata || pdata->use_eeprom) { | 521 | if (!pdata || pdata->use_eeprom) { |
@@ -567,11 +571,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
567 | setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); | 571 | setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); |
568 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | 572 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); |
569 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 573 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
570 | INIT_WORK(&sc->chanctx_work, ath_chanctx_work); | ||
571 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | 574 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); |
572 | setup_timer(&sc->offchannel.timer, ath_offchannel_timer, | 575 | |
573 | (unsigned long)sc); | 576 | ath9k_init_channel_context(sc); |
574 | setup_timer(&sc->sched.timer, ath_chanctx_timer, (unsigned long)sc); | ||
575 | 577 | ||
576 | /* | 578 | /* |
577 | * Cache line size is used to size and align various | 579 | * Cache line size is used to size and align various |
@@ -600,13 +602,15 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
600 | if (ret) | 602 | if (ret) |
601 | goto err_btcoex; | 603 | goto err_btcoex; |
602 | 604 | ||
603 | sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, | 605 | ret = ath9k_init_p2p(sc); |
604 | NULL, sc, AR_FIRST_NDP_TIMER); | 606 | if (ret) |
607 | goto err_btcoex; | ||
605 | 608 | ||
606 | ath9k_cmn_init_crypto(sc->sc_ah); | 609 | ath9k_cmn_init_crypto(sc->sc_ah); |
607 | ath9k_init_misc(sc); | 610 | ath9k_init_misc(sc); |
608 | ath_fill_led_pin(sc); | 611 | ath_fill_led_pin(sc); |
609 | ath_chanctx_init(sc); | 612 | ath_chanctx_init(sc); |
613 | ath9k_offchannel_init(sc); | ||
610 | 614 | ||
611 | if (common->bus_ops->aspm_init) | 615 | if (common->bus_ops->aspm_init) |
612 | common->bus_ops->aspm_init(common); | 616 | common->bus_ops->aspm_init(common); |
@@ -672,18 +676,14 @@ static const struct ieee80211_iface_limit wds_limits[] = { | |||
672 | { .max = 2048, .types = BIT(NL80211_IFTYPE_WDS) }, | 676 | { .max = 2048, .types = BIT(NL80211_IFTYPE_WDS) }, |
673 | }; | 677 | }; |
674 | 678 | ||
679 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
680 | |||
675 | static const struct ieee80211_iface_limit if_limits_multi[] = { | 681 | static const struct ieee80211_iface_limit if_limits_multi[] = { |
676 | { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) }, | 682 | { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | |
677 | { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | | 683 | BIT(NL80211_IFTYPE_AP) | |
684 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
678 | BIT(NL80211_IFTYPE_P2P_GO) }, | 685 | BIT(NL80211_IFTYPE_P2P_GO) }, |
679 | }; | 686 | { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, |
680 | |||
681 | static const struct ieee80211_iface_limit if_dfs_limits[] = { | ||
682 | { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | | ||
683 | #ifdef CONFIG_MAC80211_MESH | ||
684 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
685 | #endif | ||
686 | BIT(NL80211_IFTYPE_ADHOC) }, | ||
687 | }; | 687 | }; |
688 | 688 | ||
689 | static const struct ieee80211_iface_combination if_comb_multi[] = { | 689 | static const struct ieee80211_iface_combination if_comb_multi[] = { |
@@ -696,6 +696,16 @@ static const struct ieee80211_iface_combination if_comb_multi[] = { | |||
696 | }, | 696 | }, |
697 | }; | 697 | }; |
698 | 698 | ||
699 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
700 | |||
701 | static const struct ieee80211_iface_limit if_dfs_limits[] = { | ||
702 | { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | | ||
703 | #ifdef CONFIG_MAC80211_MESH | ||
704 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
705 | #endif | ||
706 | BIT(NL80211_IFTYPE_ADHOC) }, | ||
707 | }; | ||
708 | |||
699 | static const struct ieee80211_iface_combination if_comb[] = { | 709 | static const struct ieee80211_iface_combination if_comb[] = { |
700 | { | 710 | { |
701 | .limits = if_limits, | 711 | .limits = if_limits, |
@@ -763,24 +773,31 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
763 | BIT(NL80211_IFTYPE_AP) | | 773 | BIT(NL80211_IFTYPE_AP) | |
764 | BIT(NL80211_IFTYPE_STATION) | | 774 | BIT(NL80211_IFTYPE_STATION) | |
765 | BIT(NL80211_IFTYPE_ADHOC) | | 775 | BIT(NL80211_IFTYPE_ADHOC) | |
766 | BIT(NL80211_IFTYPE_MESH_POINT); | 776 | BIT(NL80211_IFTYPE_MESH_POINT) | |
767 | if (!ath9k_use_chanctx) { | 777 | BIT(NL80211_IFTYPE_WDS); |
778 | |||
768 | hw->wiphy->iface_combinations = if_comb; | 779 | hw->wiphy->iface_combinations = if_comb; |
769 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); | 780 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); |
770 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_WDS); | ||
771 | } else { | ||
772 | hw->wiphy->iface_combinations = if_comb_multi; | ||
773 | hw->wiphy->n_iface_combinations = | ||
774 | ARRAY_SIZE(if_comb_multi); | ||
775 | hw->wiphy->max_scan_ssids = 255; | ||
776 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | ||
777 | hw->wiphy->max_remain_on_channel_duration = 10000; | ||
778 | hw->chanctx_data_size = sizeof(void *); | ||
779 | hw->extra_beacon_tailroom = | ||
780 | sizeof(struct ieee80211_p2p_noa_attr) + 9; | ||
781 | } | ||
782 | } | 781 | } |
783 | 782 | ||
783 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
784 | |||
785 | if (ath9k_is_chanctx_enabled()) { | ||
786 | hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS); | ||
787 | hw->wiphy->iface_combinations = if_comb_multi; | ||
788 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi); | ||
789 | hw->wiphy->max_scan_ssids = 255; | ||
790 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | ||
791 | hw->wiphy->max_remain_on_channel_duration = 10000; | ||
792 | hw->chanctx_data_size = sizeof(void *); | ||
793 | hw->extra_beacon_tailroom = | ||
794 | sizeof(struct ieee80211_p2p_noa_attr) + 9; | ||
795 | |||
796 | ath_dbg(common, CHAN_CTX, "Use channel contexts\n"); | ||
797 | } | ||
798 | |||
799 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
800 | |||
784 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 801 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
785 | 802 | ||
786 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 803 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
@@ -915,9 +932,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
915 | { | 932 | { |
916 | int i = 0; | 933 | int i = 0; |
917 | 934 | ||
918 | if (sc->p2p_ps_timer) | 935 | ath9k_deinit_p2p(sc); |
919 | ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer); | ||
920 | |||
921 | ath9k_deinit_btcoex(sc); | 936 | ath9k_deinit_btcoex(sc); |
922 | 937 | ||
923 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 938 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e6ac8d2e610c..d9be83158a82 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -223,7 +223,6 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
223 | struct ath_hw *ah = sc->sc_ah; | 223 | struct ath_hw *ah = sc->sc_ah; |
224 | struct ath_common *common = ath9k_hw_common(ah); | 224 | struct ath_common *common = ath9k_hw_common(ah); |
225 | unsigned long flags; | 225 | unsigned long flags; |
226 | int i; | ||
227 | 226 | ||
228 | if (ath_startrecv(sc) != 0) { | 227 | if (ath_startrecv(sc) != 0) { |
229 | ath_err(common, "Unable to restart recv logic\n"); | 228 | ath_err(common, "Unable to restart recv logic\n"); |
@@ -268,20 +267,10 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
268 | ath9k_hw_set_interrupts(ah); | 267 | ath9k_hw_set_interrupts(ah); |
269 | ath9k_hw_enable_interrupts(ah); | 268 | ath9k_hw_enable_interrupts(ah); |
270 | 269 | ||
271 | if (!ath9k_use_chanctx) | 270 | if (!ath9k_is_chanctx_enabled()) |
272 | ieee80211_wake_queues(sc->hw); | 271 | ieee80211_wake_queues(sc->hw); |
273 | else { | 272 | else |
274 | if (sc->cur_chan == &sc->offchannel.chan) | 273 | ath9k_chanctx_wake_queues(sc); |
275 | ieee80211_wake_queue(sc->hw, | ||
276 | sc->hw->offchannel_tx_hw_queue); | ||
277 | else { | ||
278 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | ||
279 | ieee80211_wake_queue(sc->hw, | ||
280 | sc->cur_chan->hw_queue_base + i); | ||
281 | } | ||
282 | if (ah->opmode == NL80211_IFTYPE_AP) | ||
283 | ieee80211_wake_queue(sc->hw, sc->hw->queues - 2); | ||
284 | } | ||
285 | 274 | ||
286 | ath9k_p2p_ps_timer(sc); | 275 | ath9k_p2p_ps_timer(sc); |
287 | 276 | ||
@@ -314,6 +303,9 @@ int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
314 | if (!ath_prepare_reset(sc)) | 303 | if (!ath_prepare_reset(sc)) |
315 | fastcc = false; | 304 | fastcc = false; |
316 | 305 | ||
306 | if (ath9k_is_chanctx_enabled()) | ||
307 | fastcc = false; | ||
308 | |||
317 | spin_lock_bh(&sc->chan_lock); | 309 | spin_lock_bh(&sc->chan_lock); |
318 | sc->cur_chandef = sc->cur_chan->chandef; | 310 | sc->cur_chandef = sc->cur_chan->chandef; |
319 | spin_unlock_bh(&sc->chan_lock); | 311 | spin_unlock_bh(&sc->chan_lock); |
@@ -822,7 +814,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
822 | struct ath_common *common = ath9k_hw_common(ah); | 814 | struct ath_common *common = ath9k_hw_common(ah); |
823 | bool prev_idle; | 815 | bool prev_idle; |
824 | 816 | ||
825 | cancel_work_sync(&sc->chanctx_work); | 817 | ath9k_deinit_channel_context(sc); |
818 | |||
826 | mutex_lock(&sc->mutex); | 819 | mutex_lock(&sc->mutex); |
827 | 820 | ||
828 | ath_cancel_work(sc); | 821 | ath_cancel_work(sc); |
@@ -903,9 +896,9 @@ static bool ath9k_uses_beacons(int type) | |||
903 | } | 896 | } |
904 | } | 897 | } |
905 | 898 | ||
906 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 899 | static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, |
900 | u8 *mac, struct ieee80211_vif *vif) | ||
907 | { | 901 | { |
908 | struct ath9k_vif_iter_data *iter_data = data; | ||
909 | int i; | 902 | int i; |
910 | 903 | ||
911 | if (iter_data->has_hw_macaddr) { | 904 | if (iter_data->has_hw_macaddr) { |
@@ -968,6 +961,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
968 | list_for_each_entry(avp, &ctx->vifs, list) | 961 | list_for_each_entry(avp, &ctx->vifs, list) |
969 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); | 962 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); |
970 | 963 | ||
964 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
971 | if (ctx == &sc->offchannel.chan) { | 965 | if (ctx == &sc->offchannel.chan) { |
972 | struct ieee80211_vif *vif; | 966 | struct ieee80211_vif *vif; |
973 | 967 | ||
@@ -980,6 +974,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
980 | ath9k_vif_iter(iter_data, vif->addr, vif); | 974 | ath9k_vif_iter(iter_data, vif->addr, vif); |
981 | iter_data->beacons = false; | 975 | iter_data->beacons = false; |
982 | } | 976 | } |
977 | #endif | ||
983 | } | 978 | } |
984 | 979 | ||
985 | static void ath9k_set_assoc_state(struct ath_softc *sc, | 980 | static void ath9k_set_assoc_state(struct ath_softc *sc, |
@@ -1139,7 +1134,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1139 | ath9k_beacon_assign_slot(sc, vif); | 1134 | ath9k_beacon_assign_slot(sc, vif); |
1140 | 1135 | ||
1141 | avp->vif = vif; | 1136 | avp->vif = vif; |
1142 | if (!ath9k_use_chanctx) { | 1137 | if (!ath9k_is_chanctx_enabled()) { |
1143 | avp->chanctx = sc->cur_chan; | 1138 | avp->chanctx = sc->cur_chan; |
1144 | list_add_tail(&avp->list, &avp->chanctx->vifs); | 1139 | list_add_tail(&avp->list, &avp->chanctx->vifs); |
1145 | } | 1140 | } |
@@ -1202,29 +1197,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1202 | return 0; | 1197 | return 0; |
1203 | } | 1198 | } |
1204 | 1199 | ||
1205 | static void | ||
1206 | ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) | ||
1207 | { | ||
1208 | struct ath_hw *ah = sc->sc_ah; | ||
1209 | s32 tsf, target_tsf; | ||
1210 | |||
1211 | if (!avp || !avp->noa.has_next_tsf) | ||
1212 | return; | ||
1213 | |||
1214 | ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer); | ||
1215 | |||
1216 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1217 | |||
1218 | target_tsf = avp->noa.next_tsf; | ||
1219 | if (!avp->noa.absent) | ||
1220 | target_tsf -= ATH_P2P_PS_STOP_TIME; | ||
1221 | |||
1222 | if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) | ||
1223 | target_tsf = tsf + ATH_P2P_PS_STOP_TIME; | ||
1224 | |||
1225 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); | ||
1226 | } | ||
1227 | |||
1228 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1200 | static void ath9k_remove_interface(struct ieee80211_hw *hw, |
1229 | struct ieee80211_vif *vif) | 1201 | struct ieee80211_vif *vif) |
1230 | { | 1202 | { |
@@ -1236,16 +1208,11 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1236 | 1208 | ||
1237 | mutex_lock(&sc->mutex); | 1209 | mutex_lock(&sc->mutex); |
1238 | 1210 | ||
1239 | spin_lock_bh(&sc->sc_pcu_lock); | 1211 | ath9k_p2p_remove_vif(sc, vif); |
1240 | if (avp == sc->p2p_ps_vif) { | ||
1241 | sc->p2p_ps_vif = NULL; | ||
1242 | ath9k_update_p2p_ps_timer(sc, NULL); | ||
1243 | } | ||
1244 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1245 | 1212 | ||
1246 | sc->nvifs--; | 1213 | sc->nvifs--; |
1247 | sc->tx99_vif = NULL; | 1214 | sc->tx99_vif = NULL; |
1248 | if (!ath9k_use_chanctx) | 1215 | if (!ath9k_is_chanctx_enabled()) |
1249 | list_del(&avp->list); | 1216 | list_del(&avp->list); |
1250 | 1217 | ||
1251 | if (ath9k_uses_beacons(vif->type)) | 1218 | if (ath9k_uses_beacons(vif->type)) |
@@ -1423,7 +1390,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1423 | } | 1390 | } |
1424 | } | 1391 | } |
1425 | 1392 | ||
1426 | if (!ath9k_use_chanctx && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { | 1393 | if (!ath9k_is_chanctx_enabled() && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { |
1427 | ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL); | 1394 | ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL); |
1428 | ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); | 1395 | ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); |
1429 | } | 1396 | } |
@@ -1687,70 +1654,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1687 | return ret; | 1654 | return ret; |
1688 | } | 1655 | } |
1689 | 1656 | ||
1690 | void ath9k_p2p_ps_timer(void *priv) | ||
1691 | { | ||
1692 | struct ath_softc *sc = priv; | ||
1693 | struct ath_vif *avp = sc->p2p_ps_vif; | ||
1694 | struct ieee80211_vif *vif; | ||
1695 | struct ieee80211_sta *sta; | ||
1696 | struct ath_node *an; | ||
1697 | u32 tsf; | ||
1698 | |||
1699 | del_timer_sync(&sc->sched.timer); | ||
1700 | ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer); | ||
1701 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER); | ||
1702 | |||
1703 | if (!avp || avp->chanctx != sc->cur_chan) | ||
1704 | return; | ||
1705 | |||
1706 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1707 | if (!avp->noa.absent) | ||
1708 | tsf += ATH_P2P_PS_STOP_TIME; | ||
1709 | |||
1710 | if (!avp->noa.has_next_tsf || | ||
1711 | avp->noa.next_tsf - tsf > BIT(31)) | ||
1712 | ieee80211_update_p2p_noa(&avp->noa, tsf); | ||
1713 | |||
1714 | ath9k_update_p2p_ps_timer(sc, avp); | ||
1715 | |||
1716 | rcu_read_lock(); | ||
1717 | |||
1718 | vif = avp->vif; | ||
1719 | sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); | ||
1720 | if (!sta) | ||
1721 | goto out; | ||
1722 | |||
1723 | an = (void *) sta->drv_priv; | ||
1724 | if (an->sleeping == !!avp->noa.absent) | ||
1725 | goto out; | ||
1726 | |||
1727 | an->sleeping = avp->noa.absent; | ||
1728 | if (an->sleeping) | ||
1729 | ath_tx_aggr_sleep(sta, sc, an); | ||
1730 | else | ||
1731 | ath_tx_aggr_wakeup(sc, an); | ||
1732 | |||
1733 | out: | ||
1734 | rcu_read_unlock(); | ||
1735 | } | ||
1736 | |||
1737 | void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
1738 | { | ||
1739 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1740 | u32 tsf; | ||
1741 | |||
1742 | if (!sc->p2p_ps_timer) | ||
1743 | return; | ||
1744 | |||
1745 | if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) | ||
1746 | return; | ||
1747 | |||
1748 | sc->p2p_ps_vif = avp; | ||
1749 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | ||
1750 | ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); | ||
1751 | ath9k_update_p2p_ps_timer(sc, avp); | ||
1752 | } | ||
1753 | |||
1754 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | 1657 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, |
1755 | struct ieee80211_vif *vif, | 1658 | struct ieee80211_vif *vif, |
1756 | struct ieee80211_bss_conf *bss_conf, | 1659 | struct ieee80211_bss_conf *bss_conf, |
@@ -1765,7 +1668,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1765 | struct ath_hw *ah = sc->sc_ah; | 1668 | struct ath_hw *ah = sc->sc_ah; |
1766 | struct ath_common *common = ath9k_hw_common(ah); | 1669 | struct ath_common *common = ath9k_hw_common(ah); |
1767 | struct ath_vif *avp = (void *)vif->drv_priv; | 1670 | struct ath_vif *avp = (void *)vif->drv_priv; |
1768 | unsigned long flags; | ||
1769 | int slottime; | 1671 | int slottime; |
1770 | 1672 | ||
1771 | ath9k_ps_wakeup(sc); | 1673 | ath9k_ps_wakeup(sc); |
@@ -1776,8 +1678,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1776 | bss_conf->bssid, bss_conf->assoc); | 1678 | bss_conf->bssid, bss_conf->assoc); |
1777 | 1679 | ||
1778 | ath9k_calculate_summary_state(sc, avp->chanctx); | 1680 | ath9k_calculate_summary_state(sc, avp->chanctx); |
1779 | if (bss_conf->assoc) | 1681 | |
1780 | ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_ASSOC); | 1682 | if (ath9k_is_chanctx_enabled()) { |
1683 | if (bss_conf->assoc) | ||
1684 | ath_chanctx_event(sc, vif, | ||
1685 | ATH_CHANCTX_EVENT_ASSOC); | ||
1686 | } | ||
1781 | } | 1687 | } |
1782 | 1688 | ||
1783 | if (changed & BSS_CHANGED_IBSS) { | 1689 | if (changed & BSS_CHANGED_IBSS) { |
@@ -1814,14 +1720,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1814 | } | 1720 | } |
1815 | } | 1721 | } |
1816 | 1722 | ||
1817 | if (changed & BSS_CHANGED_P2P_PS) { | 1723 | if (changed & BSS_CHANGED_P2P_PS) |
1818 | spin_lock_bh(&sc->sc_pcu_lock); | 1724 | ath9k_p2p_bss_info_changed(sc, vif); |
1819 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1820 | if (!(sc->ps_flags & PS_BEACON_SYNC)) | ||
1821 | ath9k_update_p2p_ps(sc, vif); | ||
1822 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1823 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1824 | } | ||
1825 | 1725 | ||
1826 | if (changed & CHECK_ANI) | 1726 | if (changed & CHECK_ANI) |
1827 | ath_check_ani(sc); | 1727 | ath_check_ani(sc); |
@@ -2207,207 +2107,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2207 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | 2107 | clear_bit(ATH_OP_SCANNING, &common->op_flags); |
2208 | } | 2108 | } |
2209 | 2109 | ||
2210 | static int ath_scan_channel_duration(struct ath_softc *sc, | 2110 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT |
2211 | struct ieee80211_channel *chan) | ||
2212 | { | ||
2213 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
2214 | |||
2215 | if (!req->n_ssids || (chan->flags & IEEE80211_CHAN_NO_IR)) | ||
2216 | return (HZ / 9); /* ~110 ms */ | ||
2217 | |||
2218 | return (HZ / 16); /* ~60 ms */ | ||
2219 | } | ||
2220 | |||
2221 | static void | ||
2222 | ath_scan_next_channel(struct ath_softc *sc) | ||
2223 | { | ||
2224 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
2225 | struct ieee80211_channel *chan; | ||
2226 | |||
2227 | if (sc->offchannel.scan_idx >= req->n_channels) { | ||
2228 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
2229 | ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false), | ||
2230 | NULL); | ||
2231 | return; | ||
2232 | } | ||
2233 | |||
2234 | chan = req->channels[sc->offchannel.scan_idx++]; | ||
2235 | sc->offchannel.duration = ath_scan_channel_duration(sc, chan); | ||
2236 | sc->offchannel.state = ATH_OFFCHANNEL_PROBE_SEND; | ||
2237 | ath_chanctx_offchan_switch(sc, chan); | ||
2238 | } | ||
2239 | |||
2240 | static void ath_offchannel_next(struct ath_softc *sc) | ||
2241 | { | ||
2242 | struct ieee80211_vif *vif; | ||
2243 | |||
2244 | if (sc->offchannel.scan_req) { | ||
2245 | vif = sc->offchannel.scan_vif; | ||
2246 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; | ||
2247 | ath_scan_next_channel(sc); | ||
2248 | } else if (sc->offchannel.roc_vif) { | ||
2249 | vif = sc->offchannel.roc_vif; | ||
2250 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; | ||
2251 | sc->offchannel.duration = sc->offchannel.roc_duration; | ||
2252 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; | ||
2253 | ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); | ||
2254 | } else { | ||
2255 | ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false), | ||
2256 | NULL); | ||
2257 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
2258 | if (sc->ps_idle) | ||
2259 | ath_cancel_work(sc); | ||
2260 | } | ||
2261 | } | ||
2262 | |||
2263 | static void ath_roc_complete(struct ath_softc *sc, bool abort) | ||
2264 | { | ||
2265 | sc->offchannel.roc_vif = NULL; | ||
2266 | sc->offchannel.roc_chan = NULL; | ||
2267 | if (!abort) | ||
2268 | ieee80211_remain_on_channel_expired(sc->hw); | ||
2269 | ath_offchannel_next(sc); | ||
2270 | ath9k_ps_restore(sc); | ||
2271 | } | ||
2272 | |||
2273 | static void ath_scan_complete(struct ath_softc *sc, bool abort) | ||
2274 | { | ||
2275 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2276 | |||
2277 | sc->offchannel.scan_req = NULL; | ||
2278 | sc->offchannel.scan_vif = NULL; | ||
2279 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | ||
2280 | ieee80211_scan_completed(sc->hw, abort); | ||
2281 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | ||
2282 | ath_offchannel_next(sc); | ||
2283 | ath9k_ps_restore(sc); | ||
2284 | } | ||
2285 | |||
2286 | static void ath_scan_send_probe(struct ath_softc *sc, | ||
2287 | struct cfg80211_ssid *ssid) | ||
2288 | { | ||
2289 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
2290 | struct ieee80211_vif *vif = sc->offchannel.scan_vif; | ||
2291 | struct ath_tx_control txctl = {}; | ||
2292 | struct sk_buff *skb; | ||
2293 | struct ieee80211_tx_info *info; | ||
2294 | int band = sc->offchannel.chan.chandef.chan->band; | ||
2295 | |||
2296 | skb = ieee80211_probereq_get(sc->hw, vif, | ||
2297 | ssid->ssid, ssid->ssid_len, req->ie_len); | ||
2298 | if (!skb) | ||
2299 | return; | ||
2300 | |||
2301 | info = IEEE80211_SKB_CB(skb); | ||
2302 | if (req->no_cck) | ||
2303 | info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | ||
2304 | |||
2305 | if (req->ie_len) | ||
2306 | memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len); | ||
2307 | |||
2308 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
2309 | |||
2310 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL)) | ||
2311 | goto error; | ||
2312 | |||
2313 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | ||
2314 | txctl.force_channel = true; | ||
2315 | if (ath_tx_start(sc->hw, skb, &txctl)) | ||
2316 | goto error; | ||
2317 | |||
2318 | return; | ||
2319 | |||
2320 | error: | ||
2321 | ieee80211_free_txskb(sc->hw, skb); | ||
2322 | } | ||
2323 | |||
2324 | static void ath_scan_channel_start(struct ath_softc *sc) | ||
2325 | { | ||
2326 | struct cfg80211_scan_request *req = sc->offchannel.scan_req; | ||
2327 | int i; | ||
2328 | |||
2329 | if (!(sc->cur_chan->chandef.chan->flags & IEEE80211_CHAN_NO_IR) && | ||
2330 | req->n_ssids) { | ||
2331 | for (i = 0; i < req->n_ssids; i++) | ||
2332 | ath_scan_send_probe(sc, &req->ssids[i]); | ||
2333 | |||
2334 | } | ||
2335 | |||
2336 | sc->offchannel.state = ATH_OFFCHANNEL_PROBE_WAIT; | ||
2337 | mod_timer(&sc->offchannel.timer, jiffies + sc->offchannel.duration); | ||
2338 | } | ||
2339 | |||
2340 | void ath_offchannel_channel_change(struct ath_softc *sc) | ||
2341 | { | ||
2342 | switch (sc->offchannel.state) { | ||
2343 | case ATH_OFFCHANNEL_PROBE_SEND: | ||
2344 | if (!sc->offchannel.scan_req) | ||
2345 | return; | ||
2346 | |||
2347 | if (sc->cur_chan->chandef.chan != | ||
2348 | sc->offchannel.chan.chandef.chan) | ||
2349 | return; | ||
2350 | |||
2351 | ath_scan_channel_start(sc); | ||
2352 | break; | ||
2353 | case ATH_OFFCHANNEL_IDLE: | ||
2354 | if (!sc->offchannel.scan_req) | ||
2355 | return; | ||
2356 | |||
2357 | ath_scan_complete(sc, false); | ||
2358 | break; | ||
2359 | case ATH_OFFCHANNEL_ROC_START: | ||
2360 | if (sc->cur_chan != &sc->offchannel.chan) | ||
2361 | break; | ||
2362 | |||
2363 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT; | ||
2364 | mod_timer(&sc->offchannel.timer, jiffies + | ||
2365 | msecs_to_jiffies(sc->offchannel.duration)); | ||
2366 | ieee80211_ready_on_channel(sc->hw); | ||
2367 | break; | ||
2368 | case ATH_OFFCHANNEL_ROC_DONE: | ||
2369 | ath_roc_complete(sc, false); | ||
2370 | break; | ||
2371 | default: | ||
2372 | break; | ||
2373 | } | ||
2374 | } | ||
2375 | |||
2376 | void ath_offchannel_timer(unsigned long data) | ||
2377 | { | ||
2378 | struct ath_softc *sc = (struct ath_softc *)data; | ||
2379 | struct ath_chanctx *ctx; | ||
2380 | |||
2381 | switch (sc->offchannel.state) { | ||
2382 | case ATH_OFFCHANNEL_PROBE_WAIT: | ||
2383 | if (!sc->offchannel.scan_req) | ||
2384 | return; | ||
2385 | |||
2386 | /* get first active channel context */ | ||
2387 | ctx = ath_chanctx_get_oper_chan(sc, true); | ||
2388 | if (ctx->active) { | ||
2389 | sc->offchannel.state = ATH_OFFCHANNEL_SUSPEND; | ||
2390 | ath_chanctx_switch(sc, ctx, NULL); | ||
2391 | mod_timer(&sc->offchannel.timer, jiffies + HZ / 10); | ||
2392 | break; | ||
2393 | } | ||
2394 | /* fall through */ | ||
2395 | case ATH_OFFCHANNEL_SUSPEND: | ||
2396 | if (!sc->offchannel.scan_req) | ||
2397 | return; | ||
2398 | |||
2399 | ath_scan_next_channel(sc); | ||
2400 | break; | ||
2401 | case ATH_OFFCHANNEL_ROC_START: | ||
2402 | case ATH_OFFCHANNEL_ROC_WAIT: | ||
2403 | ctx = ath_chanctx_get_oper_chan(sc, false); | ||
2404 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE; | ||
2405 | ath_chanctx_switch(sc, ctx, NULL); | ||
2406 | break; | ||
2407 | default: | ||
2408 | break; | ||
2409 | } | ||
2410 | } | ||
2411 | 2111 | ||
2412 | static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2112 | static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2413 | struct ieee80211_scan_request *hw_req) | 2113 | struct ieee80211_scan_request *hw_req) |
@@ -2430,8 +2130,13 @@ static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2430 | sc->offchannel.scan_req = req; | 2130 | sc->offchannel.scan_req = req; |
2431 | sc->offchannel.scan_idx = 0; | 2131 | sc->offchannel.scan_idx = 0; |
2432 | 2132 | ||
2433 | if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) | 2133 | ath_dbg(common, CHAN_CTX, "HW scan request received on vif: %pM\n", |
2134 | vif->addr); | ||
2135 | |||
2136 | if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) { | ||
2137 | ath_dbg(common, CHAN_CTX, "Starting HW scan\n"); | ||
2434 | ath_offchannel_next(sc); | 2138 | ath_offchannel_next(sc); |
2139 | } | ||
2435 | 2140 | ||
2436 | out: | 2141 | out: |
2437 | mutex_unlock(&sc->mutex); | 2142 | mutex_unlock(&sc->mutex); |
@@ -2443,6 +2148,9 @@ static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw, | |||
2443 | struct ieee80211_vif *vif) | 2148 | struct ieee80211_vif *vif) |
2444 | { | 2149 | { |
2445 | struct ath_softc *sc = hw->priv; | 2150 | struct ath_softc *sc = hw->priv; |
2151 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2152 | |||
2153 | ath_dbg(common, CHAN_CTX, "Cancel HW scan on vif: %pM\n", vif->addr); | ||
2446 | 2154 | ||
2447 | mutex_lock(&sc->mutex); | 2155 | mutex_lock(&sc->mutex); |
2448 | del_timer_sync(&sc->offchannel.timer); | 2156 | del_timer_sync(&sc->offchannel.timer); |
@@ -2456,6 +2164,7 @@ static int ath9k_remain_on_channel(struct ieee80211_hw *hw, | |||
2456 | enum ieee80211_roc_type type) | 2164 | enum ieee80211_roc_type type) |
2457 | { | 2165 | { |
2458 | struct ath_softc *sc = hw->priv; | 2166 | struct ath_softc *sc = hw->priv; |
2167 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2459 | int ret = 0; | 2168 | int ret = 0; |
2460 | 2169 | ||
2461 | mutex_lock(&sc->mutex); | 2170 | mutex_lock(&sc->mutex); |
@@ -2470,8 +2179,14 @@ static int ath9k_remain_on_channel(struct ieee80211_hw *hw, | |||
2470 | sc->offchannel.roc_chan = chan; | 2179 | sc->offchannel.roc_chan = chan; |
2471 | sc->offchannel.roc_duration = duration; | 2180 | sc->offchannel.roc_duration = duration; |
2472 | 2181 | ||
2473 | if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) | 2182 | ath_dbg(common, CHAN_CTX, |
2183 | "RoC request on vif: %pM, type: %d duration: %d\n", | ||
2184 | vif->addr, type, duration); | ||
2185 | |||
2186 | if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) { | ||
2187 | ath_dbg(common, CHAN_CTX, "Starting RoC period\n"); | ||
2474 | ath_offchannel_next(sc); | 2188 | ath_offchannel_next(sc); |
2189 | } | ||
2475 | 2190 | ||
2476 | out: | 2191 | out: |
2477 | mutex_unlock(&sc->mutex); | 2192 | mutex_unlock(&sc->mutex); |
@@ -2482,9 +2197,11 @@ out: | |||
2482 | static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw) | 2197 | static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw) |
2483 | { | 2198 | { |
2484 | struct ath_softc *sc = hw->priv; | 2199 | struct ath_softc *sc = hw->priv; |
2200 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2485 | 2201 | ||
2486 | mutex_lock(&sc->mutex); | 2202 | mutex_lock(&sc->mutex); |
2487 | 2203 | ||
2204 | ath_dbg(common, CHAN_CTX, "Cancel RoC\n"); | ||
2488 | del_timer_sync(&sc->offchannel.timer); | 2205 | del_timer_sync(&sc->offchannel.timer); |
2489 | 2206 | ||
2490 | if (sc->offchannel.roc_vif) { | 2207 | if (sc->offchannel.roc_vif) { |
@@ -2501,6 +2218,7 @@ static int ath9k_add_chanctx(struct ieee80211_hw *hw, | |||
2501 | struct ieee80211_chanctx_conf *conf) | 2218 | struct ieee80211_chanctx_conf *conf) |
2502 | { | 2219 | { |
2503 | struct ath_softc *sc = hw->priv; | 2220 | struct ath_softc *sc = hw->priv; |
2221 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2504 | struct ath_chanctx *ctx, **ptr; | 2222 | struct ath_chanctx *ctx, **ptr; |
2505 | int pos; | 2223 | int pos; |
2506 | 2224 | ||
@@ -2515,10 +2233,18 @@ static int ath9k_add_chanctx(struct ieee80211_hw *hw, | |||
2515 | ctx->assigned = true; | 2233 | ctx->assigned = true; |
2516 | pos = ctx - &sc->chanctx[0]; | 2234 | pos = ctx - &sc->chanctx[0]; |
2517 | ctx->hw_queue_base = pos * IEEE80211_NUM_ACS; | 2235 | ctx->hw_queue_base = pos * IEEE80211_NUM_ACS; |
2236 | |||
2237 | ath_dbg(common, CHAN_CTX, | ||
2238 | "Add channel context: %d MHz\n", | ||
2239 | conf->def.chan->center_freq); | ||
2240 | |||
2518 | ath_chanctx_set_channel(sc, ctx, &conf->def); | 2241 | ath_chanctx_set_channel(sc, ctx, &conf->def); |
2242 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ASSIGN); | ||
2243 | |||
2519 | mutex_unlock(&sc->mutex); | 2244 | mutex_unlock(&sc->mutex); |
2520 | return 0; | 2245 | return 0; |
2521 | } | 2246 | } |
2247 | |||
2522 | mutex_unlock(&sc->mutex); | 2248 | mutex_unlock(&sc->mutex); |
2523 | return -ENOSPC; | 2249 | return -ENOSPC; |
2524 | } | 2250 | } |
@@ -2528,12 +2254,19 @@ static void ath9k_remove_chanctx(struct ieee80211_hw *hw, | |||
2528 | struct ieee80211_chanctx_conf *conf) | 2254 | struct ieee80211_chanctx_conf *conf) |
2529 | { | 2255 | { |
2530 | struct ath_softc *sc = hw->priv; | 2256 | struct ath_softc *sc = hw->priv; |
2257 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2531 | struct ath_chanctx *ctx = ath_chanctx_get(conf); | 2258 | struct ath_chanctx *ctx = ath_chanctx_get(conf); |
2532 | 2259 | ||
2533 | mutex_lock(&sc->mutex); | 2260 | mutex_lock(&sc->mutex); |
2261 | |||
2262 | ath_dbg(common, CHAN_CTX, | ||
2263 | "Remove channel context: %d MHz\n", | ||
2264 | conf->def.chan->center_freq); | ||
2265 | |||
2534 | ctx->assigned = false; | 2266 | ctx->assigned = false; |
2535 | ctx->hw_queue_base = -1; | 2267 | ctx->hw_queue_base = -1; |
2536 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN); | 2268 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN); |
2269 | |||
2537 | mutex_unlock(&sc->mutex); | 2270 | mutex_unlock(&sc->mutex); |
2538 | } | 2271 | } |
2539 | 2272 | ||
@@ -2542,9 +2275,13 @@ static void ath9k_change_chanctx(struct ieee80211_hw *hw, | |||
2542 | u32 changed) | 2275 | u32 changed) |
2543 | { | 2276 | { |
2544 | struct ath_softc *sc = hw->priv; | 2277 | struct ath_softc *sc = hw->priv; |
2278 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2545 | struct ath_chanctx *ctx = ath_chanctx_get(conf); | 2279 | struct ath_chanctx *ctx = ath_chanctx_get(conf); |
2546 | 2280 | ||
2547 | mutex_lock(&sc->mutex); | 2281 | mutex_lock(&sc->mutex); |
2282 | ath_dbg(common, CHAN_CTX, | ||
2283 | "Change channel context: %d MHz\n", | ||
2284 | conf->def.chan->center_freq); | ||
2548 | ath_chanctx_set_channel(sc, ctx, &conf->def); | 2285 | ath_chanctx_set_channel(sc, ctx, &conf->def); |
2549 | mutex_unlock(&sc->mutex); | 2286 | mutex_unlock(&sc->mutex); |
2550 | } | 2287 | } |
@@ -2554,16 +2291,24 @@ static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw, | |||
2554 | struct ieee80211_chanctx_conf *conf) | 2291 | struct ieee80211_chanctx_conf *conf) |
2555 | { | 2292 | { |
2556 | struct ath_softc *sc = hw->priv; | 2293 | struct ath_softc *sc = hw->priv; |
2294 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2557 | struct ath_vif *avp = (void *)vif->drv_priv; | 2295 | struct ath_vif *avp = (void *)vif->drv_priv; |
2558 | struct ath_chanctx *ctx = ath_chanctx_get(conf); | 2296 | struct ath_chanctx *ctx = ath_chanctx_get(conf); |
2559 | int i; | 2297 | int i; |
2560 | 2298 | ||
2561 | mutex_lock(&sc->mutex); | 2299 | mutex_lock(&sc->mutex); |
2300 | |||
2301 | ath_dbg(common, CHAN_CTX, | ||
2302 | "Assign VIF (addr: %pM, type: %d, p2p: %d) to channel context: %d MHz\n", | ||
2303 | vif->addr, vif->type, vif->p2p, | ||
2304 | conf->def.chan->center_freq); | ||
2305 | |||
2562 | avp->chanctx = ctx; | 2306 | avp->chanctx = ctx; |
2563 | list_add_tail(&avp->list, &ctx->vifs); | 2307 | list_add_tail(&avp->list, &ctx->vifs); |
2564 | ath9k_calculate_summary_state(sc, ctx); | 2308 | ath9k_calculate_summary_state(sc, ctx); |
2565 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 2309 | for (i = 0; i < IEEE80211_NUM_ACS; i++) |
2566 | vif->hw_queue[i] = ctx->hw_queue_base + i; | 2310 | vif->hw_queue[i] = ctx->hw_queue_base + i; |
2311 | |||
2567 | mutex_unlock(&sc->mutex); | 2312 | mutex_unlock(&sc->mutex); |
2568 | 2313 | ||
2569 | return 0; | 2314 | return 0; |
@@ -2574,36 +2319,79 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw, | |||
2574 | struct ieee80211_chanctx_conf *conf) | 2319 | struct ieee80211_chanctx_conf *conf) |
2575 | { | 2320 | { |
2576 | struct ath_softc *sc = hw->priv; | 2321 | struct ath_softc *sc = hw->priv; |
2322 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2577 | struct ath_vif *avp = (void *)vif->drv_priv; | 2323 | struct ath_vif *avp = (void *)vif->drv_priv; |
2578 | struct ath_chanctx *ctx = ath_chanctx_get(conf); | 2324 | struct ath_chanctx *ctx = ath_chanctx_get(conf); |
2579 | int ac; | 2325 | int ac; |
2580 | 2326 | ||
2581 | mutex_lock(&sc->mutex); | 2327 | mutex_lock(&sc->mutex); |
2328 | |||
2329 | ath_dbg(common, CHAN_CTX, | ||
2330 | "Remove VIF (addr: %pM, type: %d, p2p: %d) from channel context: %d MHz\n", | ||
2331 | vif->addr, vif->type, vif->p2p, | ||
2332 | conf->def.chan->center_freq); | ||
2333 | |||
2582 | avp->chanctx = NULL; | 2334 | avp->chanctx = NULL; |
2583 | list_del(&avp->list); | 2335 | list_del(&avp->list); |
2584 | ath9k_calculate_summary_state(sc, ctx); | 2336 | ath9k_calculate_summary_state(sc, ctx); |
2585 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 2337 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
2586 | vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE; | 2338 | vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE; |
2339 | |||
2340 | mutex_unlock(&sc->mutex); | ||
2341 | } | ||
2342 | |||
2343 | static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, | ||
2344 | struct ieee80211_vif *vif) | ||
2345 | { | ||
2346 | struct ath_softc *sc = hw->priv; | ||
2347 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2348 | struct ath_vif *avp = (struct ath_vif *) vif->drv_priv; | ||
2349 | bool changed = false; | ||
2350 | |||
2351 | if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) | ||
2352 | return; | ||
2353 | |||
2354 | if (!avp->chanctx) | ||
2355 | return; | ||
2356 | |||
2357 | mutex_lock(&sc->mutex); | ||
2358 | |||
2359 | spin_lock_bh(&sc->chan_lock); | ||
2360 | if (sc->next_chan || (sc->cur_chan != avp->chanctx)) { | ||
2361 | sc->next_chan = avp->chanctx; | ||
2362 | changed = true; | ||
2363 | } | ||
2364 | ath_dbg(common, CHAN_CTX, | ||
2365 | "%s: Set chanctx state to FORCE_ACTIVE, changed: %d\n", | ||
2366 | __func__, changed); | ||
2367 | sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE; | ||
2368 | spin_unlock_bh(&sc->chan_lock); | ||
2369 | |||
2370 | if (changed) | ||
2371 | ath_chanctx_set_next(sc, true); | ||
2372 | |||
2587 | mutex_unlock(&sc->mutex); | 2373 | mutex_unlock(&sc->mutex); |
2588 | } | 2374 | } |
2589 | 2375 | ||
2590 | void ath9k_fill_chanctx_ops(void) | 2376 | void ath9k_fill_chanctx_ops(void) |
2591 | { | 2377 | { |
2592 | if (!ath9k_use_chanctx) | 2378 | if (!ath9k_is_chanctx_enabled()) |
2593 | return; | 2379 | return; |
2594 | 2380 | ||
2595 | ath9k_ops.hw_scan = ath9k_hw_scan; | 2381 | ath9k_ops.hw_scan = ath9k_hw_scan; |
2596 | ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan; | 2382 | ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan; |
2597 | ath9k_ops.remain_on_channel = ath9k_remain_on_channel; | 2383 | ath9k_ops.remain_on_channel = ath9k_remain_on_channel; |
2598 | ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel; | 2384 | ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel; |
2599 | ath9k_ops.add_chanctx = ath9k_add_chanctx; | 2385 | ath9k_ops.add_chanctx = ath9k_add_chanctx; |
2600 | ath9k_ops.remove_chanctx = ath9k_remove_chanctx; | 2386 | ath9k_ops.remove_chanctx = ath9k_remove_chanctx; |
2601 | ath9k_ops.change_chanctx = ath9k_change_chanctx; | 2387 | ath9k_ops.change_chanctx = ath9k_change_chanctx; |
2602 | ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx; | 2388 | ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx; |
2603 | ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; | 2389 | ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; |
2604 | ath9k_ops.mgd_prepare_tx = ath9k_chanctx_force_active; | 2390 | ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx; |
2605 | } | 2391 | } |
2606 | 2392 | ||
2393 | #endif | ||
2394 | |||
2607 | struct ieee80211_ops ath9k_ops = { | 2395 | struct ieee80211_ops ath9k_ops = { |
2608 | .tx = ath9k_tx, | 2396 | .tx = ath9k_tx, |
2609 | .start = ath9k_start, | 2397 | .start = ath9k_start, |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 74ab1d02013b..2aaf233ee5d6 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -425,7 +425,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
425 | if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah)) | 425 | if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah)) |
426 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; | 426 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; |
427 | 427 | ||
428 | if (ath9k_use_chanctx && | 428 | if (ath9k_is_chanctx_enabled() && |
429 | test_bit(ATH_OP_SCANNING, &common->op_flags)) | 429 | test_bit(ATH_OP_SCANNING, &common->op_flags)) |
430 | rfilt |= ATH9K_RX_FILTER_BEACON; | 430 | rfilt |= ATH9K_RX_FILTER_BEACON; |
431 | 431 | ||
@@ -547,8 +547,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
547 | "Reconfigure beacon timers based on synchronized timestamp\n"); | 547 | "Reconfigure beacon timers based on synchronized timestamp\n"); |
548 | if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) | 548 | if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) |
549 | ath9k_set_beacon(sc); | 549 | ath9k_set_beacon(sc); |
550 | if (sc->p2p_ps_vif) | 550 | |
551 | ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); | 551 | ath9k_p2p_beacon_sync(sc); |
552 | } | 552 | } |
553 | 553 | ||
554 | if (ath_beacon_dtim_pending_cab(skb)) { | 554 | if (ath_beacon_dtim_pending_cab(skb)) { |
@@ -892,9 +892,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
892 | return -EINVAL; | 892 | return -EINVAL; |
893 | } | 893 | } |
894 | 894 | ||
895 | if (rx_stats->is_mybeacon) { | 895 | if (ath9k_is_chanctx_enabled()) { |
896 | sc->sched.next_tbtt = rx_stats->rs_tstamp; | 896 | if (rx_stats->is_mybeacon) |
897 | ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_BEACON_RECEIVED); | 897 | ath_chanctx_beacon_recv_ev(sc, rx_stats->rs_tstamp, |
898 | ATH_CHANCTX_EVENT_BEACON_RECEIVED); | ||
898 | } | 899 | } |
899 | 900 | ||
900 | ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status); | 901 | ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status); |
diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index ead63412ee1a..7b410c6858b0 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h | |||
@@ -17,6 +17,8 @@ | |||
17 | #ifndef SPECTRAL_H | 17 | #ifndef SPECTRAL_H |
18 | #define SPECTRAL_H | 18 | #define SPECTRAL_H |
19 | 19 | ||
20 | #include "../spectral_common.h" | ||
21 | |||
20 | /* enum spectral_mode: | 22 | /* enum spectral_mode: |
21 | * | 23 | * |
22 | * @SPECTRAL_DISABLED: spectral mode is disabled | 24 | * @SPECTRAL_DISABLED: spectral mode is disabled |
@@ -54,8 +56,6 @@ struct ath_ht20_mag_info { | |||
54 | u8 max_exp; | 56 | u8 max_exp; |
55 | } __packed; | 57 | } __packed; |
56 | 58 | ||
57 | #define SPECTRAL_HT20_NUM_BINS 56 | ||
58 | |||
59 | /* WARNING: don't actually use this struct! MAC may vary the amount of | 59 | /* WARNING: don't actually use this struct! MAC may vary the amount of |
60 | * data by -1/+2. This struct is for reference only. | 60 | * data by -1/+2. This struct is for reference only. |
61 | */ | 61 | */ |
@@ -83,8 +83,6 @@ struct ath_ht20_40_mag_info { | |||
83 | u8 max_exp; | 83 | u8 max_exp; |
84 | } __packed; | 84 | } __packed; |
85 | 85 | ||
86 | #define SPECTRAL_HT20_40_NUM_BINS 128 | ||
87 | |||
88 | /* WARNING: don't actually use this struct! MAC may vary the amount of | 86 | /* WARNING: don't actually use this struct! MAC may vary the amount of |
89 | * data. This struct is for reference only. | 87 | * data. This struct is for reference only. |
90 | */ | 88 | */ |
@@ -125,71 +123,6 @@ static inline u8 spectral_bitmap_weight(u8 *bins) | |||
125 | return bins[0] & 0x3f; | 123 | return bins[0] & 0x3f; |
126 | } | 124 | } |
127 | 125 | ||
128 | /* FFT sample format given to userspace via debugfs. | ||
129 | * | ||
130 | * Please keep the type/length at the front position and change | ||
131 | * other fields after adding another sample type | ||
132 | * | ||
133 | * TODO: this might need rework when switching to nl80211-based | ||
134 | * interface. | ||
135 | */ | ||
136 | enum ath_fft_sample_type { | ||
137 | ATH_FFT_SAMPLE_HT20 = 1, | ||
138 | ATH_FFT_SAMPLE_HT20_40, | ||
139 | }; | ||
140 | |||
141 | struct fft_sample_tlv { | ||
142 | u8 type; /* see ath_fft_sample */ | ||
143 | __be16 length; | ||
144 | /* type dependent data follows */ | ||
145 | } __packed; | ||
146 | |||
147 | struct fft_sample_ht20 { | ||
148 | struct fft_sample_tlv tlv; | ||
149 | |||
150 | u8 max_exp; | ||
151 | |||
152 | __be16 freq; | ||
153 | s8 rssi; | ||
154 | s8 noise; | ||
155 | |||
156 | __be16 max_magnitude; | ||
157 | u8 max_index; | ||
158 | u8 bitmap_weight; | ||
159 | |||
160 | __be64 tsf; | ||
161 | |||
162 | u8 data[SPECTRAL_HT20_NUM_BINS]; | ||
163 | } __packed; | ||
164 | |||
165 | struct fft_sample_ht20_40 { | ||
166 | struct fft_sample_tlv tlv; | ||
167 | |||
168 | u8 channel_type; | ||
169 | __be16 freq; | ||
170 | |||
171 | s8 lower_rssi; | ||
172 | s8 upper_rssi; | ||
173 | |||
174 | __be64 tsf; | ||
175 | |||
176 | s8 lower_noise; | ||
177 | s8 upper_noise; | ||
178 | |||
179 | __be16 lower_max_magnitude; | ||
180 | __be16 upper_max_magnitude; | ||
181 | |||
182 | u8 lower_max_index; | ||
183 | u8 upper_max_index; | ||
184 | |||
185 | u8 lower_bitmap_weight; | ||
186 | u8 upper_bitmap_weight; | ||
187 | |||
188 | u8 max_exp; | ||
189 | |||
190 | u8 data[SPECTRAL_HT20_40_NUM_BINS]; | ||
191 | } __packed; | ||
192 | |||
193 | void ath9k_spectral_init_debug(struct ath_softc *sc); | 126 | void ath9k_spectral_init_debug(struct ath_softc *sc); |
194 | void ath9k_spectral_deinit_debug(struct ath_softc *sc); | 127 | void ath9k_spectral_deinit_debug(struct ath_softc *sc); |
195 | 128 | ||
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index a4f4f0da81f6..33531d9a4d50 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -193,7 +193,8 @@ int ath9k_suspend(struct ieee80211_hw *hw, | |||
193 | u32 wow_triggers_enabled = 0; | 193 | u32 wow_triggers_enabled = 0; |
194 | int ret = 0; | 194 | int ret = 0; |
195 | 195 | ||
196 | cancel_work_sync(&sc->chanctx_work); | 196 | ath9k_deinit_channel_context(sc); |
197 | |||
197 | mutex_lock(&sc->mutex); | 198 | mutex_lock(&sc->mutex); |
198 | 199 | ||
199 | ath_cancel_work(sc); | 200 | ath_cancel_work(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 704fcbcbe20b..281986613fb2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2632,8 +2632,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2632 | sc->beacon.tx_processed = true; | 2632 | sc->beacon.tx_processed = true; |
2633 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | 2633 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); |
2634 | 2634 | ||
2635 | ath_chanctx_event(sc, NULL, | 2635 | if (ath9k_is_chanctx_enabled()) { |
2636 | ATH_CHANCTX_EVENT_BEACON_SENT); | 2636 | ath_chanctx_event(sc, NULL, |
2637 | ATH_CHANCTX_EVENT_BEACON_SENT); | ||
2638 | } | ||
2639 | |||
2637 | ath9k_csa_update(sc); | 2640 | ath9k_csa_update(sc); |
2638 | continue; | 2641 | continue; |
2639 | } | 2642 | } |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index f8ded84b7be8..ef5b6dc7b7f1 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1430,18 +1430,10 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, | |||
1430 | if (!sta_info->ht_sta) | 1430 | if (!sta_info->ht_sta) |
1431 | return -EOPNOTSUPP; | 1431 | return -EOPNOTSUPP; |
1432 | 1432 | ||
1433 | rcu_read_lock(); | ||
1434 | if (rcu_dereference(sta_info->agg[tid])) { | ||
1435 | rcu_read_unlock(); | ||
1436 | return -EBUSY; | ||
1437 | } | ||
1438 | |||
1439 | tid_info = kzalloc(sizeof(struct carl9170_sta_tid), | 1433 | tid_info = kzalloc(sizeof(struct carl9170_sta_tid), |
1440 | GFP_ATOMIC); | 1434 | GFP_ATOMIC); |
1441 | if (!tid_info) { | 1435 | if (!tid_info) |
1442 | rcu_read_unlock(); | ||
1443 | return -ENOMEM; | 1436 | return -ENOMEM; |
1444 | } | ||
1445 | 1437 | ||
1446 | tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); | 1438 | tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); |
1447 | tid_info->state = CARL9170_TID_STATE_PROGRESS; | 1439 | tid_info->state = CARL9170_TID_STATE_PROGRESS; |
@@ -1460,7 +1452,6 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, | |||
1460 | list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); | 1452 | list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); |
1461 | rcu_assign_pointer(sta_info->agg[tid], tid_info); | 1453 | rcu_assign_pointer(sta_info->agg[tid], tid_info); |
1462 | spin_unlock_bh(&ar->tx_ampdu_list_lock); | 1454 | spin_unlock_bh(&ar->tx_ampdu_list_lock); |
1463 | rcu_read_unlock(); | ||
1464 | 1455 | ||
1465 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1456 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1466 | break; | 1457 | break; |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 4cadfd48ffdf..ae86a600d920 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -1557,7 +1557,7 @@ static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar) | |||
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | out: | 1559 | out: |
1560 | rcu_assign_pointer(ar->beacon_iter, cvif); | 1560 | RCU_INIT_POINTER(ar->beacon_iter, cvif); |
1561 | return cvif; | 1561 | return cvif; |
1562 | } | 1562 | } |
1563 | 1563 | ||
diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h new file mode 100644 index 000000000000..0d742acb1599 --- /dev/null +++ b/drivers/net/wireless/ath/spectral_common.h | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Qualcomm Atheros, Inc. | ||
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 | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef SPECTRAL_COMMON_H | ||
18 | #define SPECTRAL_COMMON_H | ||
19 | |||
20 | #define SPECTRAL_HT20_NUM_BINS 56 | ||
21 | #define SPECTRAL_HT20_40_NUM_BINS 128 | ||
22 | |||
23 | /* TODO: could possibly be 512, but no samples this large | ||
24 | * could be acquired so far. | ||
25 | */ | ||
26 | #define SPECTRAL_ATH10K_MAX_NUM_BINS 256 | ||
27 | |||
28 | /* FFT sample format given to userspace via debugfs. | ||
29 | * | ||
30 | * Please keep the type/length at the front position and change | ||
31 | * other fields after adding another sample type | ||
32 | * | ||
33 | * TODO: this might need rework when switching to nl80211-based | ||
34 | * interface. | ||
35 | */ | ||
36 | enum ath_fft_sample_type { | ||
37 | ATH_FFT_SAMPLE_HT20 = 1, | ||
38 | ATH_FFT_SAMPLE_HT20_40, | ||
39 | ATH_FFT_SAMPLE_ATH10K, | ||
40 | }; | ||
41 | |||
42 | struct fft_sample_tlv { | ||
43 | u8 type; /* see ath_fft_sample */ | ||
44 | __be16 length; | ||
45 | /* type dependent data follows */ | ||
46 | } __packed; | ||
47 | |||
48 | struct fft_sample_ht20 { | ||
49 | struct fft_sample_tlv tlv; | ||
50 | |||
51 | u8 max_exp; | ||
52 | |||
53 | __be16 freq; | ||
54 | s8 rssi; | ||
55 | s8 noise; | ||
56 | |||
57 | __be16 max_magnitude; | ||
58 | u8 max_index; | ||
59 | u8 bitmap_weight; | ||
60 | |||
61 | __be64 tsf; | ||
62 | |||
63 | u8 data[SPECTRAL_HT20_NUM_BINS]; | ||
64 | } __packed; | ||
65 | |||
66 | struct fft_sample_ht20_40 { | ||
67 | struct fft_sample_tlv tlv; | ||
68 | |||
69 | u8 channel_type; | ||
70 | __be16 freq; | ||
71 | |||
72 | s8 lower_rssi; | ||
73 | s8 upper_rssi; | ||
74 | |||
75 | __be64 tsf; | ||
76 | |||
77 | s8 lower_noise; | ||
78 | s8 upper_noise; | ||
79 | |||
80 | __be16 lower_max_magnitude; | ||
81 | __be16 upper_max_magnitude; | ||
82 | |||
83 | u8 lower_max_index; | ||
84 | u8 upper_max_index; | ||
85 | |||
86 | u8 lower_bitmap_weight; | ||
87 | u8 upper_bitmap_weight; | ||
88 | |||
89 | u8 max_exp; | ||
90 | |||
91 | u8 data[SPECTRAL_HT20_40_NUM_BINS]; | ||
92 | } __packed; | ||
93 | |||
94 | struct fft_sample_ath10k { | ||
95 | struct fft_sample_tlv tlv; | ||
96 | u8 chan_width_mhz; | ||
97 | __be16 freq1; | ||
98 | __be16 freq2; | ||
99 | __be16 noise; | ||
100 | __be16 max_magnitude; | ||
101 | __be16 total_gain_db; | ||
102 | __be16 base_pwr_db; | ||
103 | __be64 tsf; | ||
104 | s8 max_index; | ||
105 | u8 rssi; | ||
106 | u8 relpwr_db; | ||
107 | u8 avgpwr_db; | ||
108 | u8 max_exp; | ||
109 | |||
110 | u8 data[0]; | ||
111 | } __packed; | ||
112 | |||
113 | #endif /* SPECTRAL_COMMON_H */ | ||
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 4ac2c208c9ba..a00f31881df9 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -311,8 +311,10 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
311 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + | 311 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + |
312 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); | 312 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); |
313 | 313 | ||
314 | if (rc) | 314 | if (rc) { |
315 | del_timer_sync(&wil->scan_timer); | ||
315 | wil->scan_request = NULL; | 316 | wil->scan_request = NULL; |
317 | } | ||
316 | 318 | ||
317 | return rc; | 319 | return rc; |
318 | } | 320 | } |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 8f66186adb8c..b1c6a7293390 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/power_supply.h> | 22 | #include <linux/power_supply.h> |
23 | 23 | ||
24 | #include "wil6210.h" | 24 | #include "wil6210.h" |
25 | #include "wmi.h" | ||
25 | #include "txrx.h" | 26 | #include "txrx.h" |
26 | 27 | ||
27 | /* Nasty hack. Better have per device instances */ | 28 | /* Nasty hack. Better have per device instances */ |
@@ -29,6 +30,21 @@ static u32 mem_addr; | |||
29 | static u32 dbg_txdesc_index; | 30 | static u32 dbg_txdesc_index; |
30 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ | 31 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ |
31 | 32 | ||
33 | enum dbg_off_type { | ||
34 | doff_u32 = 0, | ||
35 | doff_x32 = 1, | ||
36 | doff_ulong = 2, | ||
37 | doff_io32 = 3, | ||
38 | }; | ||
39 | |||
40 | /* offset to "wil" */ | ||
41 | struct dbg_off { | ||
42 | const char *name; | ||
43 | umode_t mode; | ||
44 | ulong off; | ||
45 | enum dbg_off_type type; | ||
46 | }; | ||
47 | |||
32 | static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, | 48 | static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, |
33 | const char *name, struct vring *vring, | 49 | const char *name, struct vring *vring, |
34 | char _s, char _h) | 50 | char _s, char _h) |
@@ -244,9 +260,9 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, | |||
244 | static struct dentry *wil_debugfs_create_iomem_x32(const char *name, | 260 | static struct dentry *wil_debugfs_create_iomem_x32(const char *name, |
245 | umode_t mode, | 261 | umode_t mode, |
246 | struct dentry *parent, | 262 | struct dentry *parent, |
247 | void __iomem *value) | 263 | void *value) |
248 | { | 264 | { |
249 | return debugfs_create_file(name, mode, parent, (void * __force)value, | 265 | return debugfs_create_file(name, mode, parent, value, |
250 | &fops_iomem_x32); | 266 | &fops_iomem_x32); |
251 | } | 267 | } |
252 | 268 | ||
@@ -270,6 +286,59 @@ static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode, | |||
270 | return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong); | 286 | return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong); |
271 | } | 287 | } |
272 | 288 | ||
289 | /** | ||
290 | * wil6210_debugfs_init_offset - create set of debugfs files | ||
291 | * @wil - driver's context, used for printing | ||
292 | * @dbg - directory on the debugfs, where files will be created | ||
293 | * @base - base address used in address calculation | ||
294 | * @tbl - table with file descriptions. Should be terminated with empty element. | ||
295 | * | ||
296 | * Creates files accordingly to the @tbl. | ||
297 | */ | ||
298 | static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, | ||
299 | struct dentry *dbg, void *base, | ||
300 | const struct dbg_off * const tbl) | ||
301 | { | ||
302 | int i; | ||
303 | |||
304 | for (i = 0; tbl[i].name; i++) { | ||
305 | struct dentry *f = NULL; | ||
306 | |||
307 | switch (tbl[i].type) { | ||
308 | case doff_u32: | ||
309 | f = debugfs_create_u32(tbl[i].name, tbl[i].mode, dbg, | ||
310 | base + tbl[i].off); | ||
311 | break; | ||
312 | case doff_x32: | ||
313 | f = debugfs_create_x32(tbl[i].name, tbl[i].mode, dbg, | ||
314 | base + tbl[i].off); | ||
315 | break; | ||
316 | case doff_ulong: | ||
317 | f = wil_debugfs_create_ulong(tbl[i].name, tbl[i].mode, | ||
318 | dbg, base + tbl[i].off); | ||
319 | break; | ||
320 | case doff_io32: | ||
321 | f = wil_debugfs_create_iomem_x32(tbl[i].name, | ||
322 | tbl[i].mode, dbg, | ||
323 | base + tbl[i].off); | ||
324 | break; | ||
325 | } | ||
326 | if (IS_ERR_OR_NULL(f)) | ||
327 | wil_err(wil, "Create file \"%s\": err %ld\n", | ||
328 | tbl[i].name, PTR_ERR(f)); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static const struct dbg_off isr_off[] = { | ||
333 | {"ICC", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICC), doff_io32}, | ||
334 | {"ICR", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICR), doff_io32}, | ||
335 | {"ICM", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICM), doff_io32}, | ||
336 | {"ICS", S_IWUSR, offsetof(struct RGF_ICR, ICS), doff_io32}, | ||
337 | {"IMV", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, IMV), doff_io32}, | ||
338 | {"IMS", S_IWUSR, offsetof(struct RGF_ICR, IMS), doff_io32}, | ||
339 | {"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32}, | ||
340 | {}, | ||
341 | }; | ||
273 | static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, | 342 | static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, |
274 | const char *name, | 343 | const char *name, |
275 | struct dentry *parent, u32 off) | 344 | struct dentry *parent, u32 off) |
@@ -279,24 +348,19 @@ static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, | |||
279 | if (IS_ERR_OR_NULL(d)) | 348 | if (IS_ERR_OR_NULL(d)) |
280 | return -ENODEV; | 349 | return -ENODEV; |
281 | 350 | ||
282 | wil_debugfs_create_iomem_x32("ICC", S_IRUGO | S_IWUSR, d, | 351 | wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr + off, |
283 | wil->csr + off); | 352 | isr_off); |
284 | wil_debugfs_create_iomem_x32("ICR", S_IRUGO | S_IWUSR, d, | ||
285 | wil->csr + off + 4); | ||
286 | wil_debugfs_create_iomem_x32("ICM", S_IRUGO | S_IWUSR, d, | ||
287 | wil->csr + off + 8); | ||
288 | wil_debugfs_create_iomem_x32("ICS", S_IWUSR, d, | ||
289 | wil->csr + off + 12); | ||
290 | wil_debugfs_create_iomem_x32("IMV", S_IRUGO | S_IWUSR, d, | ||
291 | wil->csr + off + 16); | ||
292 | wil_debugfs_create_iomem_x32("IMS", S_IWUSR, d, | ||
293 | wil->csr + off + 20); | ||
294 | wil_debugfs_create_iomem_x32("IMC", S_IWUSR, d, | ||
295 | wil->csr + off + 24); | ||
296 | 353 | ||
297 | return 0; | 354 | return 0; |
298 | } | 355 | } |
299 | 356 | ||
357 | static const struct dbg_off pseudo_isr_off[] = { | ||
358 | {"CAUSE", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE), doff_io32}, | ||
359 | {"MASK_SW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW), doff_io32}, | ||
360 | {"MASK_FW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW), doff_io32}, | ||
361 | {}, | ||
362 | }; | ||
363 | |||
300 | static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, | 364 | static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, |
301 | struct dentry *parent) | 365 | struct dentry *parent) |
302 | { | 366 | { |
@@ -305,16 +369,19 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, | |||
305 | if (IS_ERR_OR_NULL(d)) | 369 | if (IS_ERR_OR_NULL(d)) |
306 | return -ENODEV; | 370 | return -ENODEV; |
307 | 371 | ||
308 | wil_debugfs_create_iomem_x32("CAUSE", S_IRUGO, d, wil->csr + | 372 | wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr, |
309 | HOSTADDR(RGF_DMA_PSEUDO_CAUSE)); | 373 | pseudo_isr_off); |
310 | wil_debugfs_create_iomem_x32("MASK_SW", S_IRUGO, d, wil->csr + | ||
311 | HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); | ||
312 | wil_debugfs_create_iomem_x32("MASK_FW", S_IRUGO, d, wil->csr + | ||
313 | HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW)); | ||
314 | 374 | ||
315 | return 0; | 375 | return 0; |
316 | } | 376 | } |
317 | 377 | ||
378 | static const struct dbg_off itr_cnt_off[] = { | ||
379 | {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32}, | ||
380 | {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32}, | ||
381 | {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32}, | ||
382 | {}, | ||
383 | }; | ||
384 | |||
318 | static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, | 385 | static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, |
319 | struct dentry *parent) | 386 | struct dentry *parent) |
320 | { | 387 | { |
@@ -323,12 +390,8 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, | |||
323 | if (IS_ERR_OR_NULL(d)) | 390 | if (IS_ERR_OR_NULL(d)) |
324 | return -ENODEV; | 391 | return -ENODEV; |
325 | 392 | ||
326 | wil_debugfs_create_iomem_x32("TRSH", S_IRUGO | S_IWUSR, d, wil->csr + | 393 | wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr, |
327 | HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); | 394 | itr_cnt_off); |
328 | wil_debugfs_create_iomem_x32("DATA", S_IRUGO | S_IWUSR, d, wil->csr + | ||
329 | HOSTADDR(RGF_DMA_ITR_CNT_DATA)); | ||
330 | wil_debugfs_create_iomem_x32("CTL", S_IRUGO | S_IWUSR, d, wil->csr + | ||
331 | HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
332 | 395 | ||
333 | return 0; | 396 | return 0; |
334 | } | 397 | } |
@@ -666,16 +729,79 @@ static const struct file_operations fops_txdesc = { | |||
666 | }; | 729 | }; |
667 | 730 | ||
668 | /*---------beamforming------------*/ | 731 | /*---------beamforming------------*/ |
732 | static char *wil_bfstatus_str(u32 status) | ||
733 | { | ||
734 | switch (status) { | ||
735 | case 0: | ||
736 | return "Failed"; | ||
737 | case 1: | ||
738 | return "OK"; | ||
739 | case 2: | ||
740 | return "Retrying"; | ||
741 | default: | ||
742 | return "??"; | ||
743 | } | ||
744 | } | ||
745 | |||
746 | static bool is_all_zeros(void * const x_, size_t sz) | ||
747 | { | ||
748 | /* if reply is all-0, ignore this CID */ | ||
749 | u32 *x = x_; | ||
750 | int n; | ||
751 | |||
752 | for (n = 0; n < sz / sizeof(*x); n++) | ||
753 | if (x[n]) | ||
754 | return false; | ||
755 | |||
756 | return true; | ||
757 | } | ||
758 | |||
669 | static int wil_bf_debugfs_show(struct seq_file *s, void *data) | 759 | static int wil_bf_debugfs_show(struct seq_file *s, void *data) |
670 | { | 760 | { |
761 | int rc; | ||
762 | int i; | ||
671 | struct wil6210_priv *wil = s->private; | 763 | struct wil6210_priv *wil = s->private; |
672 | seq_printf(s, | 764 | struct wmi_notify_req_cmd cmd = { |
673 | "TSF : 0x%016llx\n" | 765 | .interval_usec = 0, |
674 | "TxMCS : %d\n" | 766 | }; |
675 | "Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n", | 767 | struct { |
676 | wil->stats.tsf, wil->stats.bf_mcs, | 768 | struct wil6210_mbox_hdr_wmi wmi; |
677 | wil->stats.my_rx_sector, wil->stats.my_tx_sector, | 769 | struct wmi_notify_req_done_event evt; |
678 | wil->stats.peer_rx_sector, wil->stats.peer_tx_sector); | 770 | } __packed reply; |
771 | |||
772 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | ||
773 | u32 status; | ||
774 | |||
775 | cmd.cid = i; | ||
776 | rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), | ||
777 | WMI_NOTIFY_REQ_DONE_EVENTID, &reply, | ||
778 | sizeof(reply), 20); | ||
779 | /* if reply is all-0, ignore this CID */ | ||
780 | if (rc || is_all_zeros(&reply.evt, sizeof(reply.evt))) | ||
781 | continue; | ||
782 | |||
783 | status = le32_to_cpu(reply.evt.status); | ||
784 | seq_printf(s, "CID %d {\n" | ||
785 | " TSF = 0x%016llx\n" | ||
786 | " TxMCS = %2d TxTpt = %4d\n" | ||
787 | " SQI = %4d\n" | ||
788 | " Status = 0x%08x %s\n" | ||
789 | " Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n" | ||
790 | " Goodput(rx:tx) %4d:%4d\n" | ||
791 | "}\n", | ||
792 | i, | ||
793 | le64_to_cpu(reply.evt.tsf), | ||
794 | le16_to_cpu(reply.evt.bf_mcs), | ||
795 | le32_to_cpu(reply.evt.tx_tpt), | ||
796 | reply.evt.sqi, | ||
797 | status, wil_bfstatus_str(status), | ||
798 | le16_to_cpu(reply.evt.my_rx_sector), | ||
799 | le16_to_cpu(reply.evt.my_tx_sector), | ||
800 | le16_to_cpu(reply.evt.other_rx_sector), | ||
801 | le16_to_cpu(reply.evt.other_tx_sector), | ||
802 | le32_to_cpu(reply.evt.rx_goodput), | ||
803 | le32_to_cpu(reply.evt.tx_goodput)); | ||
804 | } | ||
679 | return 0; | 805 | return 0; |
680 | } | 806 | } |
681 | 807 | ||
@@ -985,6 +1111,87 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, | |||
985 | } | 1111 | } |
986 | } | 1112 | } |
987 | 1113 | ||
1114 | /* misc files */ | ||
1115 | static const struct { | ||
1116 | const char *name; | ||
1117 | umode_t mode; | ||
1118 | const struct file_operations *fops; | ||
1119 | } dbg_files[] = { | ||
1120 | {"mbox", S_IRUGO, &fops_mbox}, | ||
1121 | {"vrings", S_IRUGO, &fops_vring}, | ||
1122 | {"stations", S_IRUGO, &fops_sta}, | ||
1123 | {"desc", S_IRUGO, &fops_txdesc}, | ||
1124 | {"bf", S_IRUGO, &fops_bf}, | ||
1125 | {"ssid", S_IRUGO | S_IWUSR, &fops_ssid}, | ||
1126 | {"mem_val", S_IRUGO, &fops_memread}, | ||
1127 | {"reset", S_IWUSR, &fops_reset}, | ||
1128 | {"rxon", S_IWUSR, &fops_rxon}, | ||
1129 | {"tx_mgmt", S_IWUSR, &fops_txmgmt}, | ||
1130 | {"wmi_send", S_IWUSR, &fops_wmi}, | ||
1131 | {"temp", S_IRUGO, &fops_temp}, | ||
1132 | {"freq", S_IRUGO, &fops_freq}, | ||
1133 | {"link", S_IRUGO, &fops_link}, | ||
1134 | {"info", S_IRUGO, &fops_info}, | ||
1135 | }; | ||
1136 | |||
1137 | static void wil6210_debugfs_init_files(struct wil6210_priv *wil, | ||
1138 | struct dentry *dbg) | ||
1139 | { | ||
1140 | int i; | ||
1141 | |||
1142 | for (i = 0; i < ARRAY_SIZE(dbg_files); i++) | ||
1143 | debugfs_create_file(dbg_files[i].name, dbg_files[i].mode, dbg, | ||
1144 | wil, dbg_files[i].fops); | ||
1145 | } | ||
1146 | |||
1147 | /* interrupt control blocks */ | ||
1148 | static const struct { | ||
1149 | const char *name; | ||
1150 | u32 icr_off; | ||
1151 | } dbg_icr[] = { | ||
1152 | {"USER_ICR", HOSTADDR(RGF_USER_USER_ICR)}, | ||
1153 | {"DMA_EP_TX_ICR", HOSTADDR(RGF_DMA_EP_TX_ICR)}, | ||
1154 | {"DMA_EP_RX_ICR", HOSTADDR(RGF_DMA_EP_RX_ICR)}, | ||
1155 | {"DMA_EP_MISC_ICR", HOSTADDR(RGF_DMA_EP_MISC_ICR)}, | ||
1156 | }; | ||
1157 | |||
1158 | static void wil6210_debugfs_init_isr(struct wil6210_priv *wil, | ||
1159 | struct dentry *dbg) | ||
1160 | { | ||
1161 | int i; | ||
1162 | |||
1163 | for (i = 0; i < ARRAY_SIZE(dbg_icr); i++) | ||
1164 | wil6210_debugfs_create_ISR(wil, dbg_icr[i].name, dbg, | ||
1165 | dbg_icr[i].icr_off); | ||
1166 | } | ||
1167 | |||
1168 | #define WIL_FIELD(name, mode, type) { __stringify(name), mode, \ | ||
1169 | offsetof(struct wil6210_priv, name), type} | ||
1170 | |||
1171 | /* fields in struct wil6210_priv */ | ||
1172 | static const struct dbg_off dbg_wil_off[] = { | ||
1173 | WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), | ||
1174 | WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), | ||
1175 | WIL_FIELD(fw_version, S_IRUGO, doff_u32), | ||
1176 | WIL_FIELD(hw_version, S_IRUGO, doff_x32), | ||
1177 | {}, | ||
1178 | }; | ||
1179 | |||
1180 | static const struct dbg_off dbg_wil_regs[] = { | ||
1181 | {"RGF_MAC_MTRL_COUNTER_0", S_IRUGO, HOSTADDR(RGF_MAC_MTRL_COUNTER_0), | ||
1182 | doff_io32}, | ||
1183 | {"RGF_USER_USAGE_1", S_IRUGO, HOSTADDR(RGF_USER_USAGE_1), doff_io32}, | ||
1184 | {}, | ||
1185 | }; | ||
1186 | |||
1187 | /* static parameters */ | ||
1188 | static const struct dbg_off dbg_statics[] = { | ||
1189 | {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32}, | ||
1190 | {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32}, | ||
1191 | {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, | ||
1192 | {}, | ||
1193 | }; | ||
1194 | |||
988 | int wil6210_debugfs_init(struct wil6210_priv *wil) | 1195 | int wil6210_debugfs_init(struct wil6210_priv *wil) |
989 | { | 1196 | { |
990 | struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, | 1197 | struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, |
@@ -993,51 +1200,17 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) | |||
993 | if (IS_ERR_OR_NULL(dbg)) | 1200 | if (IS_ERR_OR_NULL(dbg)) |
994 | return -ENODEV; | 1201 | return -ENODEV; |
995 | 1202 | ||
996 | debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox); | 1203 | wil6210_debugfs_init_files(wil, dbg); |
997 | debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring); | 1204 | wil6210_debugfs_init_isr(wil, dbg); |
998 | debugfs_create_file("stations", S_IRUGO, dbg, wil, &fops_sta); | 1205 | wil6210_debugfs_init_blobs(wil, dbg); |
999 | debugfs_create_file("desc", S_IRUGO, dbg, wil, &fops_txdesc); | 1206 | wil6210_debugfs_init_offset(wil, dbg, wil, dbg_wil_off); |
1000 | debugfs_create_u32("desc_index", S_IRUGO | S_IWUSR, dbg, | 1207 | wil6210_debugfs_init_offset(wil, dbg, (void * __force)wil->csr, |
1001 | &dbg_txdesc_index); | 1208 | dbg_wil_regs); |
1002 | debugfs_create_u32("vring_index", S_IRUGO | S_IWUSR, dbg, | 1209 | wil6210_debugfs_init_offset(wil, dbg, NULL, dbg_statics); |
1003 | &dbg_vring_index); | ||
1004 | |||
1005 | debugfs_create_file("bf", S_IRUGO, dbg, wil, &fops_bf); | ||
1006 | debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid); | ||
1007 | debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg, | ||
1008 | &wil->secure_pcp); | ||
1009 | wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg, | ||
1010 | &wil->status); | ||
1011 | debugfs_create_u32("fw_version", S_IRUGO, dbg, &wil->fw_version); | ||
1012 | debugfs_create_x32("hw_version", S_IRUGO, dbg, &wil->hw_version); | ||
1013 | |||
1014 | wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg, | ||
1015 | HOSTADDR(RGF_USER_USER_ICR)); | ||
1016 | wil6210_debugfs_create_ISR(wil, "DMA_EP_TX_ICR", dbg, | ||
1017 | HOSTADDR(RGF_DMA_EP_TX_ICR)); | ||
1018 | wil6210_debugfs_create_ISR(wil, "DMA_EP_RX_ICR", dbg, | ||
1019 | HOSTADDR(RGF_DMA_EP_RX_ICR)); | ||
1020 | wil6210_debugfs_create_ISR(wil, "DMA_EP_MISC_ICR", dbg, | ||
1021 | HOSTADDR(RGF_DMA_EP_MISC_ICR)); | ||
1022 | wil6210_debugfs_create_pseudo_ISR(wil, dbg); | ||
1023 | wil6210_debugfs_create_ITR_CNT(wil, dbg); | ||
1024 | 1210 | ||
1025 | wil_debugfs_create_iomem_x32("RGF_USER_USAGE_1", S_IRUGO, dbg, | 1211 | wil6210_debugfs_create_pseudo_ISR(wil, dbg); |
1026 | wil->csr + | ||
1027 | HOSTADDR(RGF_USER_USAGE_1)); | ||
1028 | debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr); | ||
1029 | debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); | ||
1030 | |||
1031 | debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset); | ||
1032 | debugfs_create_file("rxon", S_IWUSR, dbg, wil, &fops_rxon); | ||
1033 | debugfs_create_file("tx_mgmt", S_IWUSR, dbg, wil, &fops_txmgmt); | ||
1034 | debugfs_create_file("wmi_send", S_IWUSR, dbg, wil, &fops_wmi); | ||
1035 | debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp); | ||
1036 | debugfs_create_file("freq", S_IRUGO, dbg, wil, &fops_freq); | ||
1037 | debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link); | ||
1038 | debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info); | ||
1039 | 1212 | ||
1040 | wil6210_debugfs_init_blobs(wil, dbg); | 1213 | wil6210_debugfs_create_ITR_CNT(wil, dbg); |
1041 | 1214 | ||
1042 | return 0; | 1215 | return 0; |
1043 | } | 1216 | } |
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 67f1002a03a1..98bfbb6390b7 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 3704d2a434f3..b69d90f0716f 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -25,6 +25,9 @@ static bool no_fw_recovery; | |||
25 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); | 25 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); |
26 | MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); | 26 | MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); |
27 | 27 | ||
28 | #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ | ||
29 | #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ | ||
30 | |||
28 | /* | 31 | /* |
29 | * Due to a hardware issue, | 32 | * Due to a hardware issue, |
30 | * one has to read/write to/from NIC in 32-bit chunks; | 33 | * one has to read/write to/from NIC in 32-bit chunks; |
@@ -309,7 +312,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) | |||
309 | destroy_workqueue(wil->wmi_wq); | 312 | destroy_workqueue(wil->wmi_wq); |
310 | } | 313 | } |
311 | 314 | ||
312 | static void wil_target_reset(struct wil6210_priv *wil) | 315 | static int wil_target_reset(struct wil6210_priv *wil) |
313 | { | 316 | { |
314 | int delay = 0; | 317 | int delay = 0; |
315 | u32 hw_state; | 318 | u32 hw_state; |
@@ -327,6 +330,8 @@ static void wil_target_reset(struct wil6210_priv *wil) | |||
327 | /* register clear = read, AND with inverted, write */ | 330 | /* register clear = read, AND with inverted, write */ |
328 | #define C(a, v) W(a, R(a) & ~v) | 331 | #define C(a, v) W(a, R(a) & ~v) |
329 | 332 | ||
333 | wmb(); /* If host reorder writes here -> race in NIC */ | ||
334 | W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ | ||
330 | wil->hw_version = R(RGF_USER_FW_REV_ID); | 335 | wil->hw_version = R(RGF_USER_FW_REV_ID); |
331 | rev_id = wil->hw_version & 0xff; | 336 | rev_id = wil->hw_version & 0xff; |
332 | 337 | ||
@@ -343,8 +348,9 @@ static void wil_target_reset(struct wil6210_priv *wil) | |||
343 | wmb(); /* order is important here */ | 348 | wmb(); /* order is important here */ |
344 | } | 349 | } |
345 | 350 | ||
346 | W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ | ||
347 | W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ | 351 | W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ |
352 | wmb(); /* If host reorder writes here -> race in NIC */ | ||
353 | W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ | ||
348 | wmb(); /* order is important here */ | 354 | wmb(); /* order is important here */ |
349 | 355 | ||
350 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); | 356 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); |
@@ -385,14 +391,14 @@ static void wil_target_reset(struct wil6210_priv *wil) | |||
385 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); | 391 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); |
386 | wmb(); /* order is important here */ | 392 | wmb(); /* order is important here */ |
387 | 393 | ||
388 | /* wait until device ready */ | 394 | /* wait until device ready. typical time is 200..250 msec */ |
389 | do { | 395 | do { |
390 | msleep(1); | 396 | msleep(RST_DELAY); |
391 | hw_state = R(RGF_USER_HW_MACHINE_STATE); | 397 | hw_state = R(RGF_USER_HW_MACHINE_STATE); |
392 | if (delay++ > 100) { | 398 | if (delay++ > RST_COUNT) { |
393 | wil_err(wil, "Reset not completed, hw_state 0x%08x\n", | 399 | wil_err(wil, "Reset not completed, hw_state 0x%08x\n", |
394 | hw_state); | 400 | hw_state); |
395 | return; | 401 | return -ETIME; |
396 | } | 402 | } |
397 | } while (hw_state != HW_MACHINE_BOOT_DONE); | 403 | } while (hw_state != HW_MACHINE_BOOT_DONE); |
398 | 404 | ||
@@ -403,7 +409,8 @@ static void wil_target_reset(struct wil6210_priv *wil) | |||
403 | C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); | 409 | C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); |
404 | wmb(); /* order is important here */ | 410 | wmb(); /* order is important here */ |
405 | 411 | ||
406 | wil_dbg_misc(wil, "Reset completed in %d ms\n", delay); | 412 | wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); |
413 | return 0; | ||
407 | 414 | ||
408 | #undef R | 415 | #undef R |
409 | #undef W | 416 | #undef W |
@@ -468,10 +475,11 @@ int wil_reset(struct wil6210_priv *wil) | |||
468 | flush_workqueue(wil->wmi_wq_conn); | 475 | flush_workqueue(wil->wmi_wq_conn); |
469 | flush_workqueue(wil->wmi_wq); | 476 | flush_workqueue(wil->wmi_wq); |
470 | 477 | ||
471 | /* TODO: put MAC in reset */ | 478 | rc = wil_target_reset(wil); |
472 | wil_target_reset(wil); | ||
473 | |||
474 | wil_rx_fini(wil); | 479 | wil_rx_fini(wil); |
480 | if (rc) | ||
481 | return rc; | ||
482 | |||
475 | 483 | ||
476 | /* init after reset */ | 484 | /* init after reset */ |
477 | wil->pending_connect_cid = -1; | 485 | wil->pending_connect_cid = -1; |
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 7afce6e8c507..a44c2b61be08 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -168,11 +168,15 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr) | |||
168 | void wil_if_free(struct wil6210_priv *wil) | 168 | void wil_if_free(struct wil6210_priv *wil) |
169 | { | 169 | { |
170 | struct net_device *ndev = wil_to_ndev(wil); | 170 | struct net_device *ndev = wil_to_ndev(wil); |
171 | |||
171 | if (!ndev) | 172 | if (!ndev) |
172 | return; | 173 | return; |
173 | 174 | ||
174 | free_netdev(ndev); | ||
175 | wil_priv_deinit(wil); | 175 | wil_priv_deinit(wil); |
176 | |||
177 | wil_to_ndev(wil) = NULL; | ||
178 | free_netdev(ndev); | ||
179 | |||
176 | wil_wdev_free(wil); | 180 | wil_wdev_free(wil); |
177 | } | 181 | } |
178 | 182 | ||
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index d3fbfa28db62..38dcbea49d44 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -218,12 +218,13 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
218 | static void wil_pcie_remove(struct pci_dev *pdev) | 218 | static void wil_pcie_remove(struct pci_dev *pdev) |
219 | { | 219 | { |
220 | struct wil6210_priv *wil = pci_get_drvdata(pdev); | 220 | struct wil6210_priv *wil = pci_get_drvdata(pdev); |
221 | void __iomem *csr = wil->csr; | ||
221 | 222 | ||
222 | wil6210_debugfs_remove(wil); | 223 | wil6210_debugfs_remove(wil); |
223 | wil_if_pcie_disable(wil); | 224 | wil_if_pcie_disable(wil); |
224 | wil_if_remove(wil); | 225 | wil_if_remove(wil); |
225 | wil_if_free(wil); | 226 | wil_if_free(wil); |
226 | pci_iounmap(pdev, wil->csr); | 227 | pci_iounmap(pdev, csr); |
227 | pci_release_region(pdev, 0); | 228 | pci_release_region(pdev, 0); |
228 | pci_disable_device(pdev); | 229 | pci_disable_device(pdev); |
229 | } | 230 | } |
@@ -243,6 +244,8 @@ static const struct pci_device_id wil6210_pcie_ids[] = { | |||
243 | .driver_data = (kernel_ulong_t)&wil_board_marlon }, | 244 | .driver_data = (kernel_ulong_t)&wil_board_marlon }, |
244 | { PCI_DEVICE(0x1ae9, 0x0310), | 245 | { PCI_DEVICE(0x1ae9, 0x0310), |
245 | .driver_data = (kernel_ulong_t)&wil_board_sparrow }, | 246 | .driver_data = (kernel_ulong_t)&wil_board_sparrow }, |
247 | { PCI_DEVICE(0x1ae9, 0x0302), /* same as above, firmware broken */ | ||
248 | .driver_data = (kernel_ulong_t)&wil_board_sparrow }, | ||
246 | { /* end: all zeroes */ }, | 249 | { /* end: all zeroes */ }, |
247 | }; | 250 | }; |
248 | MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); | 251 | MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); |
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c index 180ca4793904..97c6a24716a1 100644 --- a/drivers/net/wireless/ath/wil6210/rx_reorder.c +++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c | |||
@@ -1,3 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
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 | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
1 | #include "wil6210.h" | 17 | #include "wil6210.h" |
2 | #include "txrx.h" | 18 | #include "txrx.h" |
3 | 19 | ||
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index d3467943d39d..9bd920d272bb 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -414,7 +414,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
414 | cid = wil_rxdesc_cid(d); | 414 | cid = wil_rxdesc_cid(d); |
415 | stats = &wil->sta[cid].stats; | 415 | stats = &wil->sta[cid].stats; |
416 | stats->last_mcs_rx = wil_rxdesc_mcs(d); | 416 | stats->last_mcs_rx = wil_rxdesc_mcs(d); |
417 | wil->stats.last_mcs_rx = stats->last_mcs_rx; | ||
418 | 417 | ||
419 | /* use radiotap header only if required */ | 418 | /* use radiotap header only if required */ |
420 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) | 419 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index bc5706a4f007..a1ac4f87d47b 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 67e9624f7111..f8718fe547c4 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -133,6 +133,9 @@ struct RGF_ICR { | |||
133 | #define RGF_HP_CTRL (0x88265c) | 133 | #define RGF_HP_CTRL (0x88265c) |
134 | #define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4) | 134 | #define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4) |
135 | 135 | ||
136 | /* MAC timer, usec, for packet lifetime */ | ||
137 | #define RGF_MAC_MTRL_COUNTER_0 (0x886aa8) | ||
138 | |||
136 | /* popular locations */ | 139 | /* popular locations */ |
137 | #define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) | 140 | #define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) |
138 | #define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ | 141 | #define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ |
@@ -327,17 +330,6 @@ struct wil_tid_ampdu_rx { | |||
327 | bool first_time; /* is it 1-st time this buffer used? */ | 330 | bool first_time; /* is it 1-st time this buffer used? */ |
328 | }; | 331 | }; |
329 | 332 | ||
330 | struct wil6210_stats { | ||
331 | u64 tsf; | ||
332 | u32 snr; | ||
333 | u16 last_mcs_rx; | ||
334 | u16 bf_mcs; /* last BF, used for Tx */ | ||
335 | u16 my_rx_sector; | ||
336 | u16 my_tx_sector; | ||
337 | u16 peer_rx_sector; | ||
338 | u16 peer_tx_sector; | ||
339 | }; | ||
340 | |||
341 | enum wil_sta_status { | 333 | enum wil_sta_status { |
342 | wil_sta_unused = 0, | 334 | wil_sta_unused = 0, |
343 | wil_sta_conn_pending = 1, | 335 | wil_sta_conn_pending = 1, |
@@ -430,7 +422,6 @@ struct wil6210_priv { | |||
430 | 422 | ||
431 | struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ | 423 | struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ |
432 | /* statistics */ | 424 | /* statistics */ |
433 | struct wil6210_stats stats; | ||
434 | atomic_t isr_count_rx, isr_count_tx; | 425 | atomic_t isr_count_rx, isr_count_tx; |
435 | /* debugfs */ | 426 | /* debugfs */ |
436 | struct dentry *debug; | 427 | struct dentry *debug; |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 1d1d0afdd2e1..b1aaaee997d5 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 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 | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -14,6 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/moduleparam.h> | ||
17 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
18 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
19 | 20 | ||
@@ -22,6 +23,10 @@ | |||
22 | #include "wmi.h" | 23 | #include "wmi.h" |
23 | #include "trace.h" | 24 | #include "trace.h" |
24 | 25 | ||
26 | static uint max_assoc_sta = 1; | ||
27 | module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR); | ||
28 | MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP"); | ||
29 | |||
25 | /** | 30 | /** |
26 | * WMI event receiving - theory of operations | 31 | * WMI event receiving - theory of operations |
27 | * | 32 | * |
@@ -346,11 +351,11 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) | |||
346 | rx_mgmt_frame->bssid); | 351 | rx_mgmt_frame->bssid); |
347 | cfg80211_put_bss(wiphy, bss); | 352 | cfg80211_put_bss(wiphy, bss); |
348 | } else { | 353 | } else { |
349 | wil_err(wil, "cfg80211_inform_bss() failed\n"); | 354 | wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); |
350 | } | 355 | } |
351 | } else { | 356 | } else { |
352 | cfg80211_rx_mgmt(wil->wdev, freq, signal, | 357 | cfg80211_rx_mgmt(wil->wdev, freq, signal, |
353 | (void *)rx_mgmt_frame, d_len, 0, GFP_KERNEL); | 358 | (void *)rx_mgmt_frame, d_len, 0); |
354 | } | 359 | } |
355 | } | 360 | } |
356 | 361 | ||
@@ -482,33 +487,6 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, | |||
482 | mutex_unlock(&wil->mutex); | 487 | mutex_unlock(&wil->mutex); |
483 | } | 488 | } |
484 | 489 | ||
485 | static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len) | ||
486 | { | ||
487 | struct wmi_notify_req_done_event *evt = d; | ||
488 | |||
489 | if (len < sizeof(*evt)) { | ||
490 | wil_err(wil, "Short NOTIFY event\n"); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | wil->stats.tsf = le64_to_cpu(evt->tsf); | ||
495 | wil->stats.snr = le32_to_cpu(evt->snr_val); | ||
496 | wil->stats.bf_mcs = le16_to_cpu(evt->bf_mcs); | ||
497 | wil->stats.my_rx_sector = le16_to_cpu(evt->my_rx_sector); | ||
498 | wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector); | ||
499 | wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector); | ||
500 | wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector); | ||
501 | wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n" | ||
502 | "BF status 0x%08x SNR 0x%08x SQI %d%%\n" | ||
503 | "Tx Tpt %d goodput %d Rx goodput %d\n" | ||
504 | "Sectors(rx:tx) my %d:%d peer %d:%d\n", | ||
505 | wil->stats.bf_mcs, wil->stats.tsf, evt->status, | ||
506 | wil->stats.snr, evt->sqi, le32_to_cpu(evt->tx_tpt), | ||
507 | le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput), | ||
508 | wil->stats.my_rx_sector, wil->stats.my_tx_sector, | ||
509 | wil->stats.peer_rx_sector, wil->stats.peer_tx_sector); | ||
510 | } | ||
511 | |||
512 | /* | 490 | /* |
513 | * Firmware reports EAPOL frame using WME event. | 491 | * Firmware reports EAPOL frame using WME event. |
514 | * Reconstruct Ethernet frame and deliver it via normal Rx | 492 | * Reconstruct Ethernet frame and deliver it via normal Rx |
@@ -651,7 +629,6 @@ static const struct { | |||
651 | {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete}, | 629 | {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete}, |
652 | {WMI_CONNECT_EVENTID, wmi_evt_connect}, | 630 | {WMI_CONNECT_EVENTID, wmi_evt_connect}, |
653 | {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, | 631 | {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, |
654 | {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify}, | ||
655 | {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, | 632 | {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, |
656 | {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, | 633 | {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, |
657 | {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, | 634 | {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, |
@@ -822,7 +799,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) | |||
822 | .network_type = wmi_nettype, | 799 | .network_type = wmi_nettype, |
823 | .disable_sec_offload = 1, | 800 | .disable_sec_offload = 1, |
824 | .channel = chan - 1, | 801 | .channel = chan - 1, |
825 | .pcp_max_assoc_sta = WIL6210_MAX_CID, | 802 | .pcp_max_assoc_sta = max_assoc_sta, |
826 | }; | 803 | }; |
827 | struct { | 804 | struct { |
828 | struct wil6210_mbox_hdr_wmi wmi; | 805 | struct wil6210_mbox_hdr_wmi wmi; |
@@ -832,6 +809,14 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) | |||
832 | if (!wil->secure_pcp) | 809 | if (!wil->secure_pcp) |
833 | cmd.disable_sec = 1; | 810 | cmd.disable_sec = 1; |
834 | 811 | ||
812 | if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || | ||
813 | (cmd.pcp_max_assoc_sta <= 0)) { | ||
814 | wil_info(wil, | ||
815 | "Requested connection limit %u, valid values are 1 - %d. Setting to %d\n", | ||
816 | max_assoc_sta, WIL6210_MAX_CID, WIL6210_MAX_CID); | ||
817 | cmd.pcp_max_assoc_sta = WIL6210_MAX_CID; | ||
818 | } | ||
819 | |||
835 | /* | 820 | /* |
836 | * Processing time may be huge, in case of secure AP it takes about | 821 | * Processing time may be huge, in case of secure AP it takes about |
837 | * 3500ms for FW to start AP | 822 | * 3500ms for FW to start AP |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 17334c852866..061618cee9f6 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2006-2012 Wilocity . | 3 | * Copyright (c) 2006-2012 Wilocity . |
4 | * | 4 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
@@ -980,7 +980,7 @@ struct wmi_ready_event { | |||
980 | * WMI_NOTIFY_REQ_DONE_EVENTID | 980 | * WMI_NOTIFY_REQ_DONE_EVENTID |
981 | */ | 981 | */ |
982 | struct wmi_notify_req_done_event { | 982 | struct wmi_notify_req_done_event { |
983 | __le32 status; | 983 | __le32 status; /* beamforming status, 0: fail; 1: OK; 2: retrying */ |
984 | __le64 tsf; | 984 | __le64 tsf; |
985 | __le32 snr_val; | 985 | __le32 snr_val; |
986 | __le32 tx_tpt; | 986 | __le32 tx_tpt; |
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 4cfb4d99ced0..7afc9c5329fb 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -66,18 +66,18 @@ static void atmel_release(struct pcmcia_device *link); | |||
66 | 66 | ||
67 | static void atmel_detach(struct pcmcia_device *p_dev); | 67 | static void atmel_detach(struct pcmcia_device *p_dev); |
68 | 68 | ||
69 | typedef struct local_info_t { | 69 | struct local_info { |
70 | struct net_device *eth_dev; | 70 | struct net_device *eth_dev; |
71 | } local_info_t; | 71 | }; |
72 | 72 | ||
73 | static int atmel_probe(struct pcmcia_device *p_dev) | 73 | static int atmel_probe(struct pcmcia_device *p_dev) |
74 | { | 74 | { |
75 | local_info_t *local; | 75 | struct local_info *local; |
76 | 76 | ||
77 | dev_dbg(&p_dev->dev, "atmel_attach()\n"); | 77 | dev_dbg(&p_dev->dev, "atmel_attach()\n"); |
78 | 78 | ||
79 | /* Allocate space for private device-specific data */ | 79 | /* Allocate space for private device-specific data */ |
80 | local = kzalloc(sizeof(local_info_t), GFP_KERNEL); | 80 | local = kzalloc(sizeof(*local), GFP_KERNEL); |
81 | if (!local) | 81 | if (!local) |
82 | return -ENOMEM; | 82 | return -ENOMEM; |
83 | 83 | ||
@@ -117,7 +117,7 @@ static int atmel_config_check(struct pcmcia_device *p_dev, void *priv_data) | |||
117 | 117 | ||
118 | static int atmel_config(struct pcmcia_device *link) | 118 | static int atmel_config(struct pcmcia_device *link) |
119 | { | 119 | { |
120 | local_info_t *dev; | 120 | struct local_info *dev; |
121 | int ret; | 121 | int ret; |
122 | const struct pcmcia_device_id *did; | 122 | const struct pcmcia_device_id *did; |
123 | 123 | ||
@@ -141,14 +141,14 @@ static int atmel_config(struct pcmcia_device *link) | |||
141 | if (ret) | 141 | if (ret) |
142 | goto failed; | 142 | goto failed; |
143 | 143 | ||
144 | ((local_info_t*)link->priv)->eth_dev = | 144 | ((struct local_info *)link->priv)->eth_dev = |
145 | init_atmel_card(link->irq, | 145 | init_atmel_card(link->irq, |
146 | link->resource[0]->start, | 146 | link->resource[0]->start, |
147 | did ? did->driver_info : ATMEL_FW_TYPE_NONE, | 147 | did ? did->driver_info : ATMEL_FW_TYPE_NONE, |
148 | &link->dev, | 148 | &link->dev, |
149 | card_present, | 149 | card_present, |
150 | link); | 150 | link); |
151 | if (!((local_info_t*)link->priv)->eth_dev) | 151 | if (!((struct local_info *)link->priv)->eth_dev) |
152 | goto failed; | 152 | goto failed; |
153 | 153 | ||
154 | 154 | ||
@@ -161,20 +161,20 @@ static int atmel_config(struct pcmcia_device *link) | |||
161 | 161 | ||
162 | static void atmel_release(struct pcmcia_device *link) | 162 | static void atmel_release(struct pcmcia_device *link) |
163 | { | 163 | { |
164 | struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; | 164 | struct net_device *dev = ((struct local_info *)link->priv)->eth_dev; |
165 | 165 | ||
166 | dev_dbg(&link->dev, "atmel_release\n"); | 166 | dev_dbg(&link->dev, "atmel_release\n"); |
167 | 167 | ||
168 | if (dev) | 168 | if (dev) |
169 | stop_atmel_card(dev); | 169 | stop_atmel_card(dev); |
170 | ((local_info_t*)link->priv)->eth_dev = NULL; | 170 | ((struct local_info *)link->priv)->eth_dev = NULL; |
171 | 171 | ||
172 | pcmcia_disable_device(link); | 172 | pcmcia_disable_device(link); |
173 | } | 173 | } |
174 | 174 | ||
175 | static int atmel_suspend(struct pcmcia_device *link) | 175 | static int atmel_suspend(struct pcmcia_device *link) |
176 | { | 176 | { |
177 | local_info_t *local = link->priv; | 177 | struct local_info *local = link->priv; |
178 | 178 | ||
179 | netif_device_detach(local->eth_dev); | 179 | netif_device_detach(local->eth_dev); |
180 | 180 | ||
@@ -183,7 +183,7 @@ static int atmel_suspend(struct pcmcia_device *link) | |||
183 | 183 | ||
184 | static int atmel_resume(struct pcmcia_device *link) | 184 | static int atmel_resume(struct pcmcia_device *link) |
185 | { | 185 | { |
186 | local_info_t *local = link->priv; | 186 | struct local_info *local = link->priv; |
187 | 187 | ||
188 | atmel_open(local->eth_dev); | 188 | atmel_open(local->eth_dev); |
189 | netif_device_attach(local->eth_dev); | 189 | netif_device_attach(local->eth_dev); |
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 6e00b8804ada..9f7965aae93d 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -18,6 +18,7 @@ b43-y += xmit.o | |||
18 | b43-y += dma.o | 18 | b43-y += dma.o |
19 | b43-y += pio.o | 19 | b43-y += pio.o |
20 | b43-y += rfkill.o | 20 | b43-y += rfkill.o |
21 | b43-y += ppr.o | ||
21 | b43-$(CONFIG_B43_LEDS) += leds.o | 22 | b43-$(CONFIG_B43_LEDS) += leds.o |
22 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o | 23 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o |
23 | b43-$(CONFIG_B43_SDIO) += sdio.o | 24 | b43-$(CONFIG_B43_SDIO) += sdio.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 4113b6934764..95a943326420 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -457,6 +457,7 @@ enum { | |||
457 | #define B43_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */ | 457 | #define B43_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */ |
458 | #define B43_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */ | 458 | #define B43_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */ |
459 | #define B43_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep frames with bad PLCP */ | 459 | #define B43_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep frames with bad PLCP */ |
460 | #define B43_MACCTL_PHY_LOCK 0x00200000 | ||
460 | #define B43_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */ | 461 | #define B43_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */ |
461 | #define B43_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */ | 462 | #define B43_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */ |
462 | #define B43_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */ | 463 | #define B43_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */ |
@@ -791,6 +792,13 @@ struct b43_firmware { | |||
791 | bool pcm_request_failed; | 792 | bool pcm_request_failed; |
792 | }; | 793 | }; |
793 | 794 | ||
795 | enum b43_band { | ||
796 | B43_BAND_2G = 0, | ||
797 | B43_BAND_5G_LO = 1, | ||
798 | B43_BAND_5G_MI = 2, | ||
799 | B43_BAND_5G_HI = 3, | ||
800 | }; | ||
801 | |||
794 | /* Device (802.11 core) initialization status. */ | 802 | /* Device (802.11 core) initialization status. */ |
795 | enum { | 803 | enum { |
796 | B43_STAT_UNINIT = 0, /* Uninitialized. */ | 804 | B43_STAT_UNINIT = 0, /* Uninitialized. */ |
@@ -1012,6 +1020,16 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) | |||
1012 | dev->dev->write16(dev->dev, offset, value); | 1020 | dev->dev->write16(dev->dev, offset, value); |
1013 | } | 1021 | } |
1014 | 1022 | ||
1023 | /* To optimize this check for flush_writes on BCM47XX_BCMA only. */ | ||
1024 | static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value) | ||
1025 | { | ||
1026 | b43_write16(dev, offset, value); | ||
1027 | #if defined(CONFIG_BCM47XX_BCMA) | ||
1028 | if (dev->dev->flush_writes) | ||
1029 | b43_read16(dev, offset); | ||
1030 | #endif | ||
1031 | } | ||
1032 | |||
1015 | static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask, | 1033 | static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask, |
1016 | u16 set) | 1034 | u16 set) |
1017 | { | 1035 | { |
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 565fdbdd6915..17d16a391fe6 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c | |||
@@ -22,6 +22,10 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifdef CONFIG_BCM47XX_BCMA | ||
26 | #include <asm/mach-bcm47xx/bcm47xx.h> | ||
27 | #endif | ||
28 | |||
25 | #include "b43.h" | 29 | #include "b43.h" |
26 | #include "bus.h" | 30 | #include "bus.h" |
27 | 31 | ||
@@ -102,6 +106,12 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core) | |||
102 | dev->write32 = b43_bus_bcma_write32; | 106 | dev->write32 = b43_bus_bcma_write32; |
103 | dev->block_read = b43_bus_bcma_block_read; | 107 | dev->block_read = b43_bus_bcma_block_read; |
104 | dev->block_write = b43_bus_bcma_block_write; | 108 | dev->block_write = b43_bus_bcma_block_write; |
109 | #ifdef CONFIG_BCM47XX_BCMA | ||
110 | if (b43_bus_host_is_pci(dev) && | ||
111 | bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA && | ||
112 | bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716) | ||
113 | dev->flush_writes = true; | ||
114 | #endif | ||
105 | 115 | ||
106 | dev->dev = &core->dev; | 116 | dev->dev = &core->dev; |
107 | dev->dma_dev = core->dma_dev; | 117 | dev->dma_dev = core->dma_dev; |
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index f3205c6988bc..256c2c17939a 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h | |||
@@ -33,6 +33,7 @@ struct b43_bus_dev { | |||
33 | size_t count, u16 offset, u8 reg_width); | 33 | size_t count, u16 offset, u8 reg_width); |
34 | void (*block_write)(struct b43_bus_dev *dev, const void *buffer, | 34 | void (*block_write)(struct b43_bus_dev *dev, const void *buffer, |
35 | size_t count, u16 offset, u8 reg_width); | 35 | size_t count, u16 offset, u8 reg_width); |
36 | bool flush_writes; | ||
36 | 37 | ||
37 | struct device *dev; | 38 | struct device *dev; |
38 | struct device *dma_dev; | 39 | struct device *dma_dev; |
@@ -60,7 +61,21 @@ static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev) | |||
60 | #else | 61 | #else |
61 | return false; | 62 | return false; |
62 | #endif | 63 | #endif |
64 | }; | ||
65 | |||
66 | static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev) | ||
67 | { | ||
68 | #ifdef CONFIG_B43_BCMA | ||
69 | if (dev->bus_type == B43_BUS_BCMA) | ||
70 | return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI); | ||
71 | #endif | ||
72 | #ifdef CONFIG_B43_SSB | ||
73 | if (dev->bus_type == B43_BUS_SSB) | ||
74 | return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI); | ||
75 | #endif | ||
76 | return false; | ||
63 | } | 77 | } |
78 | |||
64 | static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) | 79 | static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) |
65 | { | 80 | { |
66 | #ifdef CONFIG_B43_SSB | 81 | #ifdef CONFIG_B43_SSB |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 2af1ac396eb4..66ff718cc412 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4466 | if (core_rev == 40 || core_rev == 42) { | 4466 | if (core_rev == 40 || core_rev == 42) { |
4467 | radio_manuf = 0x17F; | 4467 | radio_manuf = 0x17F; |
4468 | 4468 | ||
4469 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0); | 4469 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0); |
4470 | radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA); | 4470 | radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA); |
4471 | 4471 | ||
4472 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1); | 4472 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1); |
4473 | radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA); | 4473 | radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA); |
4474 | 4474 | ||
4475 | radio_ver = 0; /* Is there version somewhere? */ | 4475 | radio_ver = 0; /* Is there version somewhere? */ |
@@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4477 | u16 radio24[3]; | 4477 | u16 radio24[3]; |
4478 | 4478 | ||
4479 | for (tmp = 0; tmp < 3; tmp++) { | 4479 | for (tmp = 0; tmp < 3; tmp++) { |
4480 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp); | 4480 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp); |
4481 | radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); | 4481 | radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); |
4482 | } | 4482 | } |
4483 | 4483 | ||
@@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4494 | else | 4494 | else |
4495 | tmp = 0x5205017F; | 4495 | tmp = 0x5205017F; |
4496 | } else { | 4496 | } else { |
4497 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, | 4497 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, |
4498 | B43_RADIOCTL_ID); | 4498 | B43_RADIOCTL_ID); |
4499 | tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | 4499 | tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); |
4500 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, | 4500 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, |
4501 | B43_RADIOCTL_ID); | 4501 | B43_RADIOCTL_ID); |
4502 | tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) | 4502 | tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; |
4503 | << 16; | ||
4504 | } | 4503 | } |
4505 | radio_manuf = (tmp & 0x00000FFF); | 4504 | radio_manuf = (tmp & 0x00000FFF); |
4506 | radio_id = (tmp & 0x0FFFF000) >> 12; | 4505 | radio_id = (tmp & 0x0FFFF000) >> 12; |
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index 25e40432d68b..99c036f5ecb7 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c | |||
@@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset) | |||
444 | static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg) | 444 | static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg) |
445 | { | 445 | { |
446 | reg = adjust_phyreg(dev, reg); | 446 | reg = adjust_phyreg(dev, reg); |
447 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 447 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
448 | return b43_read16(dev, B43_MMIO_PHY_DATA); | 448 | return b43_read16(dev, B43_MMIO_PHY_DATA); |
449 | } | 449 | } |
450 | 450 | ||
451 | static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) | 451 | static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) |
452 | { | 452 | { |
453 | reg = adjust_phyreg(dev, reg); | 453 | reg = adjust_phyreg(dev, reg); |
454 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 454 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
455 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | 455 | b43_write16(dev, B43_MMIO_PHY_DATA, value); |
456 | } | 456 | } |
457 | 457 | ||
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 3cbef21b4726..1dfc682a8055 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -222,12 +222,18 @@ static inline void assert_mac_suspended(struct b43_wldev *dev) | |||
222 | u16 b43_radio_read(struct b43_wldev *dev, u16 reg) | 222 | u16 b43_radio_read(struct b43_wldev *dev, u16 reg) |
223 | { | 223 | { |
224 | assert_mac_suspended(dev); | 224 | assert_mac_suspended(dev); |
225 | dev->phy.writes_counter = 0; | ||
225 | return dev->phy.ops->radio_read(dev, reg); | 226 | return dev->phy.ops->radio_read(dev, reg); |
226 | } | 227 | } |
227 | 228 | ||
228 | void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | 229 | void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value) |
229 | { | 230 | { |
230 | assert_mac_suspended(dev); | 231 | assert_mac_suspended(dev); |
232 | if (b43_bus_host_is_pci(dev->dev) && | ||
233 | ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) { | ||
234 | b43_read32(dev, B43_MMIO_MACCTL); | ||
235 | dev->phy.writes_counter = 1; | ||
236 | } | ||
231 | dev->phy.ops->radio_write(dev, reg, value); | 237 | dev->phy.ops->radio_write(dev, reg, value); |
232 | } | 238 | } |
233 | 239 | ||
@@ -268,17 +274,28 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg) | |||
268 | { | 274 | { |
269 | assert_mac_suspended(dev); | 275 | assert_mac_suspended(dev); |
270 | dev->phy.writes_counter = 0; | 276 | dev->phy.writes_counter = 0; |
271 | return dev->phy.ops->phy_read(dev, reg); | 277 | |
278 | if (dev->phy.ops->phy_read) | ||
279 | return dev->phy.ops->phy_read(dev, reg); | ||
280 | |||
281 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); | ||
282 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
272 | } | 283 | } |
273 | 284 | ||
274 | void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) | 285 | void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) |
275 | { | 286 | { |
276 | assert_mac_suspended(dev); | 287 | assert_mac_suspended(dev); |
277 | dev->phy.ops->phy_write(dev, reg, value); | 288 | if (b43_bus_host_is_pci(dev->dev) && |
278 | if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) { | 289 | ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) { |
279 | b43_read16(dev, B43_MMIO_PHY_VER); | 290 | b43_read16(dev, B43_MMIO_PHY_VER); |
280 | dev->phy.writes_counter = 0; | 291 | dev->phy.writes_counter = 1; |
281 | } | 292 | } |
293 | |||
294 | if (dev->phy.ops->phy_write) | ||
295 | return dev->phy.ops->phy_write(dev, reg, value); | ||
296 | |||
297 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); | ||
298 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
282 | } | 299 | } |
283 | 300 | ||
284 | void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) | 301 | void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 8f5c14bc10e6..727ce6edb4b3 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev) | |||
2555 | 2555 | ||
2556 | static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg) | 2556 | static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg) |
2557 | { | 2557 | { |
2558 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 2558 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
2559 | return b43_read16(dev, B43_MMIO_PHY_DATA); | 2559 | return b43_read16(dev, B43_MMIO_PHY_DATA); |
2560 | } | 2560 | } |
2561 | 2561 | ||
2562 | static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) | 2562 | static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) |
2563 | { | 2563 | { |
2564 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 2564 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
2565 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | 2565 | b43_write16(dev, B43_MMIO_PHY_DATA, value); |
2566 | } | 2566 | } |
2567 | 2567 | ||
@@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg) | |||
2572 | /* G-PHY needs 0x80 for read access. */ | 2572 | /* G-PHY needs 0x80 for read access. */ |
2573 | reg |= 0x80; | 2573 | reg |= 0x80; |
2574 | 2574 | ||
2575 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 2575 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
2576 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | 2576 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); |
2577 | } | 2577 | } |
2578 | 2578 | ||
@@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
2581 | /* Register 1 is a 32-bit register. */ | 2581 | /* Register 1 is a 32-bit register. */ |
2582 | B43_WARN_ON(reg == 1); | 2582 | B43_WARN_ON(reg == 1); |
2583 | 2583 | ||
2584 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 2584 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
2585 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); | 2585 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); |
2586 | } | 2586 | } |
2587 | 2587 | ||
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index f2974c6b1c01..c4dc8b020f60 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c | |||
@@ -1071,22 +1071,10 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) | |||
1071 | * R/W ops. | 1071 | * R/W ops. |
1072 | **************************************************/ | 1072 | **************************************************/ |
1073 | 1073 | ||
1074 | static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg) | ||
1075 | { | ||
1076 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
1077 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
1078 | } | ||
1079 | |||
1080 | static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value) | ||
1081 | { | ||
1082 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
1083 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
1084 | } | ||
1085 | |||
1086 | static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, | 1074 | static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, |
1087 | u16 set) | 1075 | u16 set) |
1088 | { | 1076 | { |
1089 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 1077 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
1090 | b43_write16(dev, B43_MMIO_PHY_DATA, | 1078 | b43_write16(dev, B43_MMIO_PHY_DATA, |
1091 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); | 1079 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); |
1092 | } | 1080 | } |
@@ -1096,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg) | |||
1096 | /* HT-PHY needs 0x200 for read access */ | 1084 | /* HT-PHY needs 0x200 for read access */ |
1097 | reg |= 0x200; | 1085 | reg |= 0x200; |
1098 | 1086 | ||
1099 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | 1087 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg); |
1100 | return b43_read16(dev, B43_MMIO_RADIO24_DATA); | 1088 | return b43_read16(dev, B43_MMIO_RADIO24_DATA); |
1101 | } | 1089 | } |
1102 | 1090 | ||
1103 | static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, | 1091 | static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, |
1104 | u16 value) | 1092 | u16 value) |
1105 | { | 1093 | { |
1106 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | 1094 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg); |
1107 | b43_write16(dev, B43_MMIO_RADIO24_DATA, value); | 1095 | b43_write16(dev, B43_MMIO_RADIO24_DATA, value); |
1108 | } | 1096 | } |
1109 | 1097 | ||
@@ -1126,8 +1114,6 @@ const struct b43_phy_operations b43_phyops_ht = { | |||
1126 | .free = b43_phy_ht_op_free, | 1114 | .free = b43_phy_ht_op_free, |
1127 | .prepare_structs = b43_phy_ht_op_prepare_structs, | 1115 | .prepare_structs = b43_phy_ht_op_prepare_structs, |
1128 | .init = b43_phy_ht_op_init, | 1116 | .init = b43_phy_ht_op_init, |
1129 | .phy_read = b43_phy_ht_op_read, | ||
1130 | .phy_write = b43_phy_ht_op_write, | ||
1131 | .phy_maskset = b43_phy_ht_op_maskset, | 1117 | .phy_maskset = b43_phy_ht_op_maskset, |
1132 | .radio_read = b43_phy_ht_op_radio_read, | 1118 | .radio_read = b43_phy_ht_op_radio_read, |
1133 | .radio_write = b43_phy_ht_op_radio_write, | 1119 | .radio_write = b43_phy_ht_op_radio_write, |
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index e76bbdf3247e..97461ccf3e1e 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c | |||
@@ -810,22 +810,10 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev) | |||
810 | * R/W ops. | 810 | * R/W ops. |
811 | **************************************************/ | 811 | **************************************************/ |
812 | 812 | ||
813 | static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg) | ||
814 | { | ||
815 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
816 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
817 | } | ||
818 | |||
819 | static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value) | ||
820 | { | ||
821 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
822 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
823 | } | ||
824 | |||
825 | static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, | 813 | static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, |
826 | u16 set) | 814 | u16 set) |
827 | { | 815 | { |
828 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 816 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
829 | b43_write16(dev, B43_MMIO_PHY_DATA, | 817 | b43_write16(dev, B43_MMIO_PHY_DATA, |
830 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); | 818 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); |
831 | } | 819 | } |
@@ -835,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg) | |||
835 | /* LCN-PHY needs 0x200 for read access */ | 823 | /* LCN-PHY needs 0x200 for read access */ |
836 | reg |= 0x200; | 824 | reg |= 0x200; |
837 | 825 | ||
838 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | 826 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg); |
839 | return b43_read16(dev, B43_MMIO_RADIO24_DATA); | 827 | return b43_read16(dev, B43_MMIO_RADIO24_DATA); |
840 | } | 828 | } |
841 | 829 | ||
842 | static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg, | 830 | static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg, |
843 | u16 value) | 831 | u16 value) |
844 | { | 832 | { |
845 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | 833 | b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg); |
846 | b43_write16(dev, B43_MMIO_RADIO24_DATA, value); | 834 | b43_write16(dev, B43_MMIO_RADIO24_DATA, value); |
847 | } | 835 | } |
848 | 836 | ||
@@ -855,8 +843,6 @@ const struct b43_phy_operations b43_phyops_lcn = { | |||
855 | .free = b43_phy_lcn_op_free, | 843 | .free = b43_phy_lcn_op_free, |
856 | .prepare_structs = b43_phy_lcn_op_prepare_structs, | 844 | .prepare_structs = b43_phy_lcn_op_prepare_structs, |
857 | .init = b43_phy_lcn_op_init, | 845 | .init = b43_phy_lcn_op_init, |
858 | .phy_read = b43_phy_lcn_op_read, | ||
859 | .phy_write = b43_phy_lcn_op_write, | ||
860 | .phy_maskset = b43_phy_lcn_op_maskset, | 846 | .phy_maskset = b43_phy_lcn_op_maskset, |
861 | .radio_read = b43_phy_lcn_op_radio_read, | 847 | .radio_read = b43_phy_lcn_op_radio_read, |
862 | .radio_write = b43_phy_lcn_op_radio_write, | 848 | .radio_write = b43_phy_lcn_op_radio_write, |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 92190dacf689..058a9f232050 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
@@ -1985,22 +1985,10 @@ static void lpphy_calibration(struct b43_wldev *dev) | |||
1985 | b43_mac_enable(dev); | 1985 | b43_mac_enable(dev); |
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) | ||
1989 | { | ||
1990 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
1991 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
1992 | } | ||
1993 | |||
1994 | static void b43_lpphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) | ||
1995 | { | ||
1996 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
1997 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
1998 | } | ||
1999 | |||
2000 | static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, | 1988 | static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, |
2001 | u16 set) | 1989 | u16 set) |
2002 | { | 1990 | { |
2003 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 1991 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
2004 | b43_write16(dev, B43_MMIO_PHY_DATA, | 1992 | b43_write16(dev, B43_MMIO_PHY_DATA, |
2005 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); | 1993 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); |
2006 | } | 1994 | } |
@@ -2016,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg) | |||
2016 | } else | 2004 | } else |
2017 | reg |= 0x200; | 2005 | reg |= 0x200; |
2018 | 2006 | ||
2019 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 2007 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
2020 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | 2008 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); |
2021 | } | 2009 | } |
2022 | 2010 | ||
@@ -2025,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
2025 | /* Register 1 is a 32-bit register. */ | 2013 | /* Register 1 is a 32-bit register. */ |
2026 | B43_WARN_ON(reg == 1); | 2014 | B43_WARN_ON(reg == 1); |
2027 | 2015 | ||
2028 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 2016 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
2029 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); | 2017 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); |
2030 | } | 2018 | } |
2031 | 2019 | ||
@@ -2713,8 +2701,6 @@ const struct b43_phy_operations b43_phyops_lp = { | |||
2713 | .free = b43_lpphy_op_free, | 2701 | .free = b43_lpphy_op_free, |
2714 | .prepare_structs = b43_lpphy_op_prepare_structs, | 2702 | .prepare_structs = b43_lpphy_op_prepare_structs, |
2715 | .init = b43_lpphy_op_init, | 2703 | .init = b43_lpphy_op_init, |
2716 | .phy_read = b43_lpphy_op_read, | ||
2717 | .phy_write = b43_lpphy_op_write, | ||
2718 | .phy_maskset = b43_lpphy_op_maskset, | 2704 | .phy_maskset = b43_lpphy_op_maskset, |
2719 | .radio_read = b43_lpphy_op_radio_read, | 2705 | .radio_read = b43_lpphy_op_radio_read, |
2720 | .radio_write = b43_lpphy_op_radio_write, | 2706 | .radio_write = b43_lpphy_op_radio_write, |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e2a3f0d5bcc2..cf625d8732a7 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "radio_2056.h" | 34 | #include "radio_2056.h" |
35 | #include "radio_2057.h" | 35 | #include "radio_2057.h" |
36 | #include "main.h" | 36 | #include "main.h" |
37 | #include "ppr.h" | ||
37 | 38 | ||
38 | struct nphy_txgains { | 39 | struct nphy_txgains { |
39 | u16 tx_lpf[2]; | 40 | u16 tx_lpf[2]; |
@@ -3606,16 +3607,6 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core, | |||
3606 | * Tx and Rx | 3607 | * Tx and Rx |
3607 | **************************************************/ | 3608 | **************************************************/ |
3608 | 3609 | ||
3609 | static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev) | ||
3610 | {//TODO | ||
3611 | } | ||
3612 | |||
3613 | static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, | ||
3614 | bool ignore_tssi) | ||
3615 | {//TODO | ||
3616 | return B43_TXPWR_RES_DONE; | ||
3617 | } | ||
3618 | |||
3619 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ | 3610 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ |
3620 | static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) | 3611 | static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) |
3621 | { | 3612 | { |
@@ -4069,6 +4060,7 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) | |||
4069 | 4060 | ||
4070 | s16 a1[2], b0[2], b1[2]; | 4061 | s16 a1[2], b0[2], b1[2]; |
4071 | u8 idle[2]; | 4062 | u8 idle[2]; |
4063 | u8 ppr_max; | ||
4072 | s8 target[2]; | 4064 | s8 target[2]; |
4073 | s32 num, den, pwr; | 4065 | s32 num, den, pwr; |
4074 | u32 regval[64]; | 4066 | u32 regval[64]; |
@@ -4147,7 +4139,12 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) | |||
4147 | b1[0] = b1[1] = -1393; | 4139 | b1[0] = b1[1] = -1393; |
4148 | } | 4140 | } |
4149 | } | 4141 | } |
4150 | /* target[0] = target[1] = nphy->tx_power_max; */ | 4142 | |
4143 | ppr_max = b43_ppr_get_max(dev, &nphy->tx_pwr_max_ppr); | ||
4144 | if (ppr_max) { | ||
4145 | target[0] = ppr_max; | ||
4146 | target[1] = ppr_max; | ||
4147 | } | ||
4151 | 4148 | ||
4152 | if (dev->phy.rev >= 3) { | 4149 | if (dev->phy.rev >= 3) { |
4153 | if (sprom->fem.ghz2.tssipos) | 4150 | if (sprom->fem.ghz2.tssipos) |
@@ -4235,8 +4232,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) | |||
4235 | 4232 | ||
4236 | const u32 *table = NULL; | 4233 | const u32 *table = NULL; |
4237 | u32 rfpwr_offset; | 4234 | u32 rfpwr_offset; |
4238 | u8 pga_gain; | 4235 | u8 pga_gain, pad_gain; |
4239 | int i; | 4236 | int i; |
4237 | const s16 *uninitialized_var(rf_pwr_offset_table); | ||
4240 | 4238 | ||
4241 | table = b43_nphy_get_tx_gain_table(dev); | 4239 | table = b43_nphy_get_tx_gain_table(dev); |
4242 | if (!table) | 4240 | if (!table) |
@@ -4252,13 +4250,27 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) | |||
4252 | nphy->gmval = (table[0] >> 16) & 0x7000; | 4250 | nphy->gmval = (table[0] >> 16) & 0x7000; |
4253 | #endif | 4251 | #endif |
4254 | 4252 | ||
4253 | if (phy->rev >= 19) { | ||
4254 | return; | ||
4255 | } else if (phy->rev >= 7) { | ||
4256 | rf_pwr_offset_table = b43_ntab_get_rf_pwr_offset_table(dev); | ||
4257 | if (!rf_pwr_offset_table) | ||
4258 | return; | ||
4259 | /* TODO: Enable this once we have gains configured */ | ||
4260 | return; | ||
4261 | } | ||
4262 | |||
4255 | for (i = 0; i < 128; i++) { | 4263 | for (i = 0; i < 128; i++) { |
4256 | if (phy->rev >= 19) { | 4264 | if (phy->rev >= 19) { |
4257 | /* TODO */ | 4265 | /* TODO */ |
4258 | return; | 4266 | return; |
4259 | } else if (phy->rev >= 7) { | 4267 | } else if (phy->rev >= 7) { |
4260 | /* TODO */ | 4268 | pga_gain = (table[i] >> 24) & 0xf; |
4261 | return; | 4269 | pad_gain = (table[i] >> 19) & 0x1f; |
4270 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
4271 | rfpwr_offset = rf_pwr_offset_table[pad_gain]; | ||
4272 | else | ||
4273 | rfpwr_offset = rf_pwr_offset_table[pga_gain]; | ||
4262 | } else { | 4274 | } else { |
4263 | pga_gain = (table[i] >> 24) & 0xF; | 4275 | pga_gain = (table[i] >> 24) & 0xF; |
4264 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 4276 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
@@ -5874,6 +5886,69 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) | |||
5874 | b43_mac_enable(dev); | 5886 | b43_mac_enable(dev); |
5875 | } | 5887 | } |
5876 | 5888 | ||
5889 | static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, | ||
5890 | bool ignore_tssi) | ||
5891 | { | ||
5892 | struct b43_phy *phy = &dev->phy; | ||
5893 | struct b43_phy_n *nphy = dev->phy.n; | ||
5894 | struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; | ||
5895 | struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr; | ||
5896 | u8 max; /* qdBm */ | ||
5897 | bool tx_pwr_state; | ||
5898 | |||
5899 | if (nphy->tx_pwr_last_recalc_freq == channel->center_freq && | ||
5900 | nphy->tx_pwr_last_recalc_limit == phy->desired_txpower) | ||
5901 | return B43_TXPWR_RES_DONE; | ||
5902 | |||
5903 | /* Make sure we have a clean PPR */ | ||
5904 | b43_ppr_clear(dev, ppr); | ||
5905 | |||
5906 | /* HW limitations */ | ||
5907 | b43_ppr_load_max_from_sprom(dev, ppr, B43_BAND_2G); | ||
5908 | |||
5909 | /* Regulatory & user settings */ | ||
5910 | max = INT_TO_Q52(phy->chandef->chan->max_power); | ||
5911 | if (phy->desired_txpower) | ||
5912 | max = min_t(u8, max, INT_TO_Q52(phy->desired_txpower)); | ||
5913 | b43_ppr_apply_max(dev, ppr, max); | ||
5914 | if (b43_debug(dev, B43_DBG_XMITPOWER)) | ||
5915 | b43dbg(dev->wl, "Calculated TX power: " Q52_FMT "\n", | ||
5916 | Q52_ARG(b43_ppr_get_max(dev, ppr))); | ||
5917 | |||
5918 | /* TODO: Enable this once we get gains working */ | ||
5919 | #if 0 | ||
5920 | /* Some extra gains */ | ||
5921 | hw_gain = 6; /* N-PHY specific */ | ||
5922 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
5923 | hw_gain += sprom->antenna_gain.a0; | ||
5924 | else | ||
5925 | hw_gain += sprom->antenna_gain.a1; | ||
5926 | b43_ppr_add(dev, ppr, -hw_gain); | ||
5927 | #endif | ||
5928 | |||
5929 | /* Make sure we didn't go too low */ | ||
5930 | b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8)); | ||
5931 | |||
5932 | /* Apply */ | ||
5933 | tx_pwr_state = nphy->txpwrctrl; | ||
5934 | b43_mac_suspend(dev); | ||
5935 | b43_nphy_tx_power_ctl_setup(dev); | ||
5936 | if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { | ||
5937 | b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_PHY_LOCK); | ||
5938 | b43_read32(dev, B43_MMIO_MACCTL); | ||
5939 | udelay(1); | ||
5940 | } | ||
5941 | b43_nphy_tx_power_ctrl(dev, nphy->txpwrctrl); | ||
5942 | if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) | ||
5943 | b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PHY_LOCK, 0); | ||
5944 | b43_mac_enable(dev); | ||
5945 | |||
5946 | nphy->tx_pwr_last_recalc_freq = channel->center_freq; | ||
5947 | nphy->tx_pwr_last_recalc_limit = phy->desired_txpower; | ||
5948 | |||
5949 | return B43_TXPWR_RES_DONE; | ||
5950 | } | ||
5951 | |||
5877 | /************************************************** | 5952 | /************************************************** |
5878 | * N-PHY init | 5953 | * N-PHY init |
5879 | **************************************************/ | 5954 | **************************************************/ |
@@ -6407,6 +6482,7 @@ static int b43_nphy_op_allocate(struct b43_wldev *dev) | |||
6407 | nphy = kzalloc(sizeof(*nphy), GFP_KERNEL); | 6482 | nphy = kzalloc(sizeof(*nphy), GFP_KERNEL); |
6408 | if (!nphy) | 6483 | if (!nphy) |
6409 | return -ENOMEM; | 6484 | return -ENOMEM; |
6485 | |||
6410 | dev->phy.n = nphy; | 6486 | dev->phy.n = nphy; |
6411 | 6487 | ||
6412 | return 0; | 6488 | return 0; |
@@ -6497,26 +6573,13 @@ static inline void check_phyreg(struct b43_wldev *dev, u16 offset) | |||
6497 | #endif /* B43_DEBUG */ | 6573 | #endif /* B43_DEBUG */ |
6498 | } | 6574 | } |
6499 | 6575 | ||
6500 | static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) | ||
6501 | { | ||
6502 | check_phyreg(dev, reg); | ||
6503 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
6504 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
6505 | } | ||
6506 | |||
6507 | static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) | ||
6508 | { | ||
6509 | check_phyreg(dev, reg); | ||
6510 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
6511 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
6512 | } | ||
6513 | |||
6514 | static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, | 6576 | static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, |
6515 | u16 set) | 6577 | u16 set) |
6516 | { | 6578 | { |
6517 | check_phyreg(dev, reg); | 6579 | check_phyreg(dev, reg); |
6518 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 6580 | b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); |
6519 | b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); | 6581 | b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); |
6582 | dev->phy.writes_counter = 1; | ||
6520 | } | 6583 | } |
6521 | 6584 | ||
6522 | static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) | 6585 | static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) |
@@ -6529,7 +6592,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) | |||
6529 | else | 6592 | else |
6530 | reg |= 0x100; | 6593 | reg |= 0x100; |
6531 | 6594 | ||
6532 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 6595 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
6533 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | 6596 | return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); |
6534 | } | 6597 | } |
6535 | 6598 | ||
@@ -6538,7 +6601,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
6538 | /* Register 1 is a 32-bit register. */ | 6601 | /* Register 1 is a 32-bit register. */ |
6539 | B43_WARN_ON(dev->phy.rev < 7 && reg == 1); | 6602 | B43_WARN_ON(dev->phy.rev < 7 && reg == 1); |
6540 | 6603 | ||
6541 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); | 6604 | b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg); |
6542 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); | 6605 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); |
6543 | } | 6606 | } |
6544 | 6607 | ||
@@ -6652,8 +6715,6 @@ const struct b43_phy_operations b43_phyops_n = { | |||
6652 | .free = b43_nphy_op_free, | 6715 | .free = b43_nphy_op_free, |
6653 | .prepare_structs = b43_nphy_op_prepare_structs, | 6716 | .prepare_structs = b43_nphy_op_prepare_structs, |
6654 | .init = b43_nphy_op_init, | 6717 | .init = b43_nphy_op_init, |
6655 | .phy_read = b43_nphy_op_read, | ||
6656 | .phy_write = b43_nphy_op_write, | ||
6657 | .phy_maskset = b43_nphy_op_maskset, | 6718 | .phy_maskset = b43_nphy_op_maskset, |
6658 | .radio_read = b43_nphy_op_radio_read, | 6719 | .radio_read = b43_nphy_op_radio_read, |
6659 | .radio_write = b43_nphy_op_radio_write, | 6720 | .radio_write = b43_nphy_op_radio_write, |
@@ -6662,5 +6723,4 @@ const struct b43_phy_operations b43_phyops_n = { | |||
6662 | .switch_channel = b43_nphy_op_switch_channel, | 6723 | .switch_channel = b43_nphy_op_switch_channel, |
6663 | .get_default_chan = b43_nphy_op_get_default_chan, | 6724 | .get_default_chan = b43_nphy_op_get_default_chan, |
6664 | .recalc_txpower = b43_nphy_op_recalc_txpower, | 6725 | .recalc_txpower = b43_nphy_op_recalc_txpower, |
6665 | .adjust_txpower = b43_nphy_op_adjust_txpower, | ||
6666 | }; | 6726 | }; |
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 30bec815b969..a6da2c31a99c 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define B43_NPHY_H_ | 2 | #define B43_NPHY_H_ |
3 | 3 | ||
4 | #include "phy_common.h" | 4 | #include "phy_common.h" |
5 | #include "ppr.h" | ||
5 | 6 | ||
6 | 7 | ||
7 | /* N-PHY registers. */ | 8 | /* N-PHY registers. */ |
@@ -967,6 +968,9 @@ struct b43_phy_n { | |||
967 | struct b43_phy_n_txpwrindex txpwrindex[2]; | 968 | struct b43_phy_n_txpwrindex txpwrindex[2]; |
968 | struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2]; | 969 | struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2]; |
969 | struct b43_chanspec txiqlocal_chanspec; | 970 | struct b43_chanspec txiqlocal_chanspec; |
971 | struct b43_ppr tx_pwr_max_ppr; | ||
972 | u16 tx_pwr_last_recalc_freq; | ||
973 | int tx_pwr_last_recalc_limit; | ||
970 | 974 | ||
971 | u8 txrx_chain; | 975 | u8 txrx_chain; |
972 | u16 tx_rx_cal_phy_saveregs[11]; | 976 | u16 tx_rx_cal_phy_saveregs[11]; |
diff --git a/drivers/net/wireless/b43/ppr.c b/drivers/net/wireless/b43/ppr.c new file mode 100644 index 000000000000..9a770279c415 --- /dev/null +++ b/drivers/net/wireless/b43/ppr.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Broadcom B43 wireless driver | ||
3 | * PPR (Power Per Rate) management | ||
4 | * | ||
5 | * Copyright (c) 2014 Rafał Miłecki <zajec5@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include "ppr.h" | ||
19 | #include "b43.h" | ||
20 | |||
21 | #define ppr_for_each_entry(ppr, i, entry) \ | ||
22 | for (i = 0, entry = &(ppr)->__all_rates[i]; \ | ||
23 | i < B43_PPR_RATES_NUM; \ | ||
24 | i++, entry++) | ||
25 | |||
26 | void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr) | ||
27 | { | ||
28 | memset(ppr, 0, sizeof(*ppr)); | ||
29 | |||
30 | /* Compile-time PPR check */ | ||
31 | BUILD_BUG_ON(sizeof(struct b43_ppr) != B43_PPR_RATES_NUM * sizeof(u8)); | ||
32 | } | ||
33 | |||
34 | void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff) | ||
35 | { | ||
36 | int i; | ||
37 | u8 *rate; | ||
38 | |||
39 | ppr_for_each_entry(ppr, i, rate) { | ||
40 | *rate = clamp_val(*rate + diff, 0, 127); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max) | ||
45 | { | ||
46 | int i; | ||
47 | u8 *rate; | ||
48 | |||
49 | ppr_for_each_entry(ppr, i, rate) { | ||
50 | *rate = min(*rate, max); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min) | ||
55 | { | ||
56 | int i; | ||
57 | u8 *rate; | ||
58 | |||
59 | ppr_for_each_entry(ppr, i, rate) { | ||
60 | *rate = max(*rate, min); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr) | ||
65 | { | ||
66 | u8 res = 0; | ||
67 | int i; | ||
68 | u8 *rate; | ||
69 | |||
70 | ppr_for_each_entry(ppr, i, rate) { | ||
71 | res = max(*rate, res); | ||
72 | } | ||
73 | |||
74 | return res; | ||
75 | } | ||
76 | |||
77 | bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr, | ||
78 | enum b43_band band) | ||
79 | { | ||
80 | struct b43_ppr_rates *rates = &ppr->rates; | ||
81 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
82 | struct b43_phy *phy = &dev->phy; | ||
83 | u8 maxpwr, off; | ||
84 | u32 sprom_ofdm_po; | ||
85 | u16 *sprom_mcs_po; | ||
86 | u8 extra_cdd_po, extra_stbc_po; | ||
87 | int i; | ||
88 | |||
89 | switch (band) { | ||
90 | case B43_BAND_2G: | ||
91 | maxpwr = min(sprom->core_pwr_info[0].maxpwr_2g, | ||
92 | sprom->core_pwr_info[1].maxpwr_2g); | ||
93 | sprom_ofdm_po = sprom->ofdm2gpo; | ||
94 | sprom_mcs_po = sprom->mcs2gpo; | ||
95 | extra_cdd_po = (sprom->cddpo >> 0) & 0xf; | ||
96 | extra_stbc_po = (sprom->stbcpo >> 0) & 0xf; | ||
97 | break; | ||
98 | case B43_BAND_5G_LO: | ||
99 | maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gl, | ||
100 | sprom->core_pwr_info[1].maxpwr_5gl); | ||
101 | sprom_ofdm_po = sprom->ofdm5glpo; | ||
102 | sprom_mcs_po = sprom->mcs5glpo; | ||
103 | extra_cdd_po = (sprom->cddpo >> 8) & 0xf; | ||
104 | extra_stbc_po = (sprom->stbcpo >> 8) & 0xf; | ||
105 | break; | ||
106 | case B43_BAND_5G_MI: | ||
107 | maxpwr = min(sprom->core_pwr_info[0].maxpwr_5g, | ||
108 | sprom->core_pwr_info[1].maxpwr_5g); | ||
109 | sprom_ofdm_po = sprom->ofdm5gpo; | ||
110 | sprom_mcs_po = sprom->mcs5gpo; | ||
111 | extra_cdd_po = (sprom->cddpo >> 4) & 0xf; | ||
112 | extra_stbc_po = (sprom->stbcpo >> 4) & 0xf; | ||
113 | break; | ||
114 | case B43_BAND_5G_HI: | ||
115 | maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gh, | ||
116 | sprom->core_pwr_info[1].maxpwr_5gh); | ||
117 | sprom_ofdm_po = sprom->ofdm5ghpo; | ||
118 | sprom_mcs_po = sprom->mcs5ghpo; | ||
119 | extra_cdd_po = (sprom->cddpo >> 12) & 0xf; | ||
120 | extra_stbc_po = (sprom->stbcpo >> 12) & 0xf; | ||
121 | break; | ||
122 | default: | ||
123 | WARN_ON_ONCE(1); | ||
124 | return false; | ||
125 | } | ||
126 | |||
127 | if (band == B43_BAND_2G) { | ||
128 | for (i = 0; i < 4; i++) { | ||
129 | off = ((sprom->cck2gpo >> (i * 4)) & 0xf) * 2; | ||
130 | rates->cck[i] = maxpwr - off; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /* OFDM */ | ||
135 | for (i = 0; i < 8; i++) { | ||
136 | off = ((sprom_ofdm_po >> (i * 4)) & 0xf) * 2; | ||
137 | rates->ofdm[i] = maxpwr - off; | ||
138 | } | ||
139 | |||
140 | /* MCS 20 SISO */ | ||
141 | rates->mcs_20[0] = rates->ofdm[0]; | ||
142 | rates->mcs_20[1] = rates->ofdm[2]; | ||
143 | rates->mcs_20[2] = rates->ofdm[3]; | ||
144 | rates->mcs_20[3] = rates->ofdm[4]; | ||
145 | rates->mcs_20[4] = rates->ofdm[5]; | ||
146 | rates->mcs_20[5] = rates->ofdm[6]; | ||
147 | rates->mcs_20[6] = rates->ofdm[7]; | ||
148 | rates->mcs_20[7] = rates->ofdm[7]; | ||
149 | |||
150 | /* MCS 20 CDD */ | ||
151 | for (i = 0; i < 4; i++) { | ||
152 | off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2; | ||
153 | rates->mcs_20_cdd[i] = maxpwr - off; | ||
154 | if (phy->type == B43_PHYTYPE_N && phy->rev >= 3) | ||
155 | rates->mcs_20_cdd[i] -= extra_cdd_po; | ||
156 | } | ||
157 | for (i = 0; i < 4; i++) { | ||
158 | off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2; | ||
159 | rates->mcs_20_cdd[4 + i] = maxpwr - off; | ||
160 | if (phy->type == B43_PHYTYPE_N && phy->rev >= 3) | ||
161 | rates->mcs_20_cdd[4 + i] -= extra_cdd_po; | ||
162 | } | ||
163 | |||
164 | /* OFDM 20 CDD */ | ||
165 | rates->ofdm_20_cdd[0] = rates->mcs_20_cdd[0]; | ||
166 | rates->ofdm_20_cdd[1] = rates->mcs_20_cdd[0]; | ||
167 | rates->ofdm_20_cdd[2] = rates->mcs_20_cdd[1]; | ||
168 | rates->ofdm_20_cdd[3] = rates->mcs_20_cdd[2]; | ||
169 | rates->ofdm_20_cdd[4] = rates->mcs_20_cdd[3]; | ||
170 | rates->ofdm_20_cdd[5] = rates->mcs_20_cdd[4]; | ||
171 | rates->ofdm_20_cdd[6] = rates->mcs_20_cdd[5]; | ||
172 | rates->ofdm_20_cdd[7] = rates->mcs_20_cdd[6]; | ||
173 | |||
174 | /* MCS 20 STBC */ | ||
175 | for (i = 0; i < 4; i++) { | ||
176 | off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2; | ||
177 | rates->mcs_20_stbc[i] = maxpwr - off; | ||
178 | if (phy->type == B43_PHYTYPE_N && phy->rev >= 3) | ||
179 | rates->mcs_20_stbc[i] -= extra_stbc_po; | ||
180 | } | ||
181 | for (i = 0; i < 4; i++) { | ||
182 | off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2; | ||
183 | rates->mcs_20_stbc[4 + i] = maxpwr - off; | ||
184 | if (phy->type == B43_PHYTYPE_N && phy->rev >= 3) | ||
185 | rates->mcs_20_stbc[4 + i] -= extra_stbc_po; | ||
186 | } | ||
187 | |||
188 | /* MCS 20 SDM */ | ||
189 | for (i = 0; i < 4; i++) { | ||
190 | off = ((sprom_mcs_po[2] >> (i * 4)) & 0xf) * 2; | ||
191 | rates->mcs_20_sdm[i] = maxpwr - off; | ||
192 | } | ||
193 | for (i = 0; i < 4; i++) { | ||
194 | off = ((sprom_mcs_po[3] >> (i * 4)) & 0xf) * 2; | ||
195 | rates->mcs_20_sdm[4 + i] = maxpwr - off; | ||
196 | } | ||
197 | |||
198 | return true; | ||
199 | } | ||
diff --git a/drivers/net/wireless/b43/ppr.h b/drivers/net/wireless/b43/ppr.h new file mode 100644 index 000000000000..24d7447e9f01 --- /dev/null +++ b/drivers/net/wireless/b43/ppr.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef LINUX_B43_PPR_H_ | ||
2 | #define LINUX_B43_PPR_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #define B43_PPR_CCK_RATES_NUM 4 | ||
7 | #define B43_PPR_OFDM_RATES_NUM 8 | ||
8 | #define B43_PPR_MCS_RATES_NUM 8 | ||
9 | |||
10 | #define B43_PPR_RATES_NUM (B43_PPR_CCK_RATES_NUM + \ | ||
11 | B43_PPR_OFDM_RATES_NUM * 2 + \ | ||
12 | B43_PPR_MCS_RATES_NUM * 4) | ||
13 | |||
14 | struct b43_ppr_rates { | ||
15 | u8 cck[B43_PPR_CCK_RATES_NUM]; | ||
16 | u8 ofdm[B43_PPR_OFDM_RATES_NUM]; | ||
17 | u8 ofdm_20_cdd[B43_PPR_OFDM_RATES_NUM]; | ||
18 | u8 mcs_20[B43_PPR_MCS_RATES_NUM]; /* SISO */ | ||
19 | u8 mcs_20_cdd[B43_PPR_MCS_RATES_NUM]; | ||
20 | u8 mcs_20_stbc[B43_PPR_MCS_RATES_NUM]; | ||
21 | u8 mcs_20_sdm[B43_PPR_MCS_RATES_NUM]; | ||
22 | }; | ||
23 | |||
24 | struct b43_ppr { | ||
25 | /* All powers are in qdbm (Q5.2) */ | ||
26 | union { | ||
27 | u8 __all_rates[B43_PPR_RATES_NUM]; | ||
28 | struct b43_ppr_rates rates; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | struct b43_wldev; | ||
33 | enum b43_band; | ||
34 | |||
35 | void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr); | ||
36 | |||
37 | void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff); | ||
38 | void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max); | ||
39 | void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min); | ||
40 | u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr); | ||
41 | |||
42 | bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr, | ||
43 | enum b43_band band); | ||
44 | |||
45 | #endif /* LINUX_B43_PPR_H_ */ | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 4b5885077b01..25d1cbd34306 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -2878,6 +2878,40 @@ const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = { | |||
2878 | -54, -46, -39, -31, -23, -15, -8, 0 | 2878 | -54, -46, -39, -31, -23, -15, -8, 0 |
2879 | }; | 2879 | }; |
2880 | 2880 | ||
2881 | /* Extracted from MMIO dump of 6.30.223.248 | ||
2882 | * Entries: 0, 15, 17, 21, 24, 26, 27, 29, 30 were guessed | ||
2883 | */ | ||
2884 | static const s16 b43_ntab_rf_pwr_offset_2057_rev9_2g[] = { | ||
2885 | -133, -133, -107, -92, -81, | ||
2886 | -73, -66, -61, -56, -52, | ||
2887 | -48, -44, -41, -37, -34, | ||
2888 | -31, -28, -25, -22, -19, | ||
2889 | -17, -14, -12, -10, -9, | ||
2890 | -7, -5, -4, -3, -2, | ||
2891 | -1, 0, | ||
2892 | }; | ||
2893 | |||
2894 | /* Extracted from MMIO dump of 6.30.223.248 */ | ||
2895 | static const s16 b43_ntab_rf_pwr_offset_2057_rev9_5g[] = { | ||
2896 | -101, -94, -86, -79, -72, | ||
2897 | -65, -57, -50, -42, -35, | ||
2898 | -28, -21, -16, -9, -4, | ||
2899 | 0, | ||
2900 | }; | ||
2901 | |||
2902 | /* Extracted from MMIO dump of 6.30.223.248 | ||
2903 | * Entries: 0, 26, 28, 29, 30, 31 were guessed | ||
2904 | */ | ||
2905 | static const s16 b43_ntab_rf_pwr_offset_2057_rev14_2g[] = { | ||
2906 | -111, -111, -111, -84, -70, | ||
2907 | -59, -52, -45, -40, -36, | ||
2908 | -32, -29, -26, -23, -21, | ||
2909 | -18, -16, -15, -13, -11, | ||
2910 | -10, -8, -7, -6, -5, | ||
2911 | -4, -4, -3, -3, -2, | ||
2912 | -2, -1, | ||
2913 | }; | ||
2914 | |||
2881 | const u16 tbl_iqcal_gainparams[2][9][8] = { | 2915 | const u16 tbl_iqcal_gainparams[2][9][8] = { |
2882 | { | 2916 | { |
2883 | { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, | 2917 | { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, |
@@ -3197,7 +3231,7 @@ static struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = { | |||
3197 | { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | 3231 | { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, |
3198 | 0x527E, /* invalid for external LNA! */ | 3232 | 0x527E, /* invalid for external LNA! */ |
3199 | { 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */ | 3233 | { 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */ |
3200 | 0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */ | 3234 | 0x007E, 0x0066, 0x0000, /* low is invalid (the last one) */ |
3201 | 0x18, 0x18, 0x18, | 3235 | 0x18, 0x18, 0x18, |
3202 | 0x01D0, 0x5, | 3236 | 0x01D0, 0x5, |
3203 | }, | 3237 | }, |
@@ -3708,9 +3742,43 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev) | |||
3708 | } | 3742 | } |
3709 | } | 3743 | } |
3710 | 3744 | ||
3745 | const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev) | ||
3746 | { | ||
3747 | struct b43_phy *phy = &dev->phy; | ||
3748 | |||
3749 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
3750 | switch (phy->rev) { | ||
3751 | case 17: | ||
3752 | if (phy->radio_rev == 14) | ||
3753 | return b43_ntab_rf_pwr_offset_2057_rev14_2g; | ||
3754 | break; | ||
3755 | case 16: | ||
3756 | if (phy->radio_rev == 9) | ||
3757 | return b43_ntab_rf_pwr_offset_2057_rev9_2g; | ||
3758 | break; | ||
3759 | } | ||
3760 | |||
3761 | b43err(dev->wl, | ||
3762 | "No 2GHz RF power table available for this device\n"); | ||
3763 | return NULL; | ||
3764 | } else { | ||
3765 | switch (phy->rev) { | ||
3766 | case 16: | ||
3767 | if (phy->radio_rev == 9) | ||
3768 | return b43_ntab_rf_pwr_offset_2057_rev9_5g; | ||
3769 | break; | ||
3770 | } | ||
3771 | |||
3772 | b43err(dev->wl, | ||
3773 | "No 5GHz RF power table available for this device\n"); | ||
3774 | return NULL; | ||
3775 | } | ||
3776 | } | ||
3777 | |||
3711 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | 3778 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( |
3712 | struct b43_wldev *dev, bool ghz5, bool ext_lna) | 3779 | struct b43_wldev *dev, bool ghz5, bool ext_lna) |
3713 | { | 3780 | { |
3781 | struct b43_phy *phy = &dev->phy; | ||
3714 | struct nphy_gain_ctl_workaround_entry *e; | 3782 | struct nphy_gain_ctl_workaround_entry *e; |
3715 | u8 phy_idx; | 3783 | u8 phy_idx; |
3716 | 3784 | ||
@@ -3729,37 +3797,49 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
3729 | e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; | 3797 | e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; |
3730 | 3798 | ||
3731 | /* Some workarounds to the workarounds... */ | 3799 | /* Some workarounds to the workarounds... */ |
3732 | if (ghz5 && dev->phy.rev >= 6) { | 3800 | if (!ghz5) { |
3733 | if (dev->phy.radio_rev == 11 && | ||
3734 | !b43_is_40mhz(dev)) | ||
3735 | e->cliplo_gain = 0x2d; | ||
3736 | } else if (!ghz5 && dev->phy.rev >= 5) { | ||
3737 | static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a, | ||
3738 | 0x106c, 0x1074, 0x107c, 0x207c}; | ||
3739 | u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso; | 3801 | u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso; |
3740 | 3802 | ||
3741 | if (ext_lna) { | 3803 | if (tr_iso > 7) |
3804 | tr_iso = 3; | ||
3805 | |||
3806 | if (phy->rev >= 6) { | ||
3807 | static const int gain_data[] = { 0x106a, 0x106c, 0x1074, | ||
3808 | 0x107c, 0x007e, 0x107e, | ||
3809 | 0x207e, 0x307e, }; | ||
3810 | |||
3811 | e->cliplo_gain = gain_data[tr_iso]; | ||
3812 | } else if (phy->rev == 5) { | ||
3813 | static const int gain_data[] = { 0x0062, 0x0064, 0x006a, | ||
3814 | 0x106a, 0x106c, 0x1074, | ||
3815 | 0x107c, 0x207c, }; | ||
3816 | |||
3817 | e->cliplo_gain = gain_data[tr_iso]; | ||
3818 | } | ||
3819 | |||
3820 | if (phy->rev >= 5 && ext_lna) { | ||
3742 | e->rfseq_init[0] &= ~0x4000; | 3821 | e->rfseq_init[0] &= ~0x4000; |
3743 | e->rfseq_init[1] &= ~0x4000; | 3822 | e->rfseq_init[1] &= ~0x4000; |
3744 | e->rfseq_init[2] &= ~0x4000; | 3823 | e->rfseq_init[2] &= ~0x4000; |
3745 | e->rfseq_init[3] &= ~0x4000; | 3824 | e->rfseq_init[3] &= ~0x4000; |
3746 | e->init_gain &= ~0x4000; | 3825 | e->init_gain &= ~0x4000; |
3747 | } | 3826 | } |
3748 | if (tr_iso > 7) | 3827 | } else { |
3749 | tr_iso = 3; | 3828 | if (phy->rev >= 6) { |
3750 | e->cliplo_gain = gain_data[tr_iso]; | 3829 | if (phy->radio_rev == 11 && !b43_is_40mhz(dev)) |
3751 | 3830 | e->crsminu = 0x2d; | |
3752 | } else if (ghz5 && dev->phy.rev == 4 && ext_lna) { | 3831 | } else if (phy->rev == 4 && ext_lna) { |
3753 | e->rfseq_init[0] &= ~0x4000; | 3832 | e->rfseq_init[0] &= ~0x4000; |
3754 | e->rfseq_init[1] &= ~0x4000; | 3833 | e->rfseq_init[1] &= ~0x4000; |
3755 | e->rfseq_init[2] &= ~0x4000; | 3834 | e->rfseq_init[2] &= ~0x4000; |
3756 | e->rfseq_init[3] &= ~0x4000; | 3835 | e->rfseq_init[3] &= ~0x4000; |
3757 | e->init_gain &= ~0x4000; | 3836 | e->init_gain &= ~0x4000; |
3758 | e->rfseq_init[0] |= 0x1000; | 3837 | e->rfseq_init[0] |= 0x1000; |
3759 | e->rfseq_init[1] |= 0x1000; | 3838 | e->rfseq_init[1] |= 0x1000; |
3760 | e->rfseq_init[2] |= 0x1000; | 3839 | e->rfseq_init[2] |= 0x1000; |
3761 | e->rfseq_init[3] |= 0x1000; | 3840 | e->rfseq_init[3] |= 0x1000; |
3762 | e->init_gain |= 0x1000; | 3841 | e->init_gain |= 0x1000; |
3842 | } | ||
3763 | } | 3843 | } |
3764 | 3844 | ||
3765 | return e; | 3845 | return e; |
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 3ce2e6f3a278..b51f386db02f 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -191,6 +191,8 @@ void b43_nphy_tables_init(struct b43_wldev *dev); | |||
191 | 191 | ||
192 | const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); | 192 | const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); |
193 | 193 | ||
194 | const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev); | ||
195 | |||
194 | extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[]; | 196 | extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[]; |
195 | 197 | ||
196 | extern const u16 tbl_iqcal_gainparams[2][9][8]; | 198 | extern const u16 tbl_iqcal_gainparams[2][9][8]; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index 057b982ea8b3..1d78a91db594 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c | |||
@@ -1431,8 +1431,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |||
1431 | IEEE80211_BAND_5GHZ); | 1431 | IEEE80211_BAND_5GHZ); |
1432 | 1432 | ||
1433 | wdev = &ifp->vif->wdev; | 1433 | wdev = &ifp->vif->wdev; |
1434 | cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, 0, | 1434 | cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, 0); |
1435 | GFP_ATOMIC); | ||
1436 | 1435 | ||
1437 | kfree(mgmt_frame); | 1436 | kfree(mgmt_frame); |
1438 | return 0; | 1437 | return 0; |
@@ -1896,8 +1895,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |||
1896 | IEEE80211_BAND_2GHZ : | 1895 | IEEE80211_BAND_2GHZ : |
1897 | IEEE80211_BAND_5GHZ); | 1896 | IEEE80211_BAND_5GHZ); |
1898 | 1897 | ||
1899 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0, | 1898 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0); |
1900 | GFP_ATOMIC); | ||
1901 | 1899 | ||
1902 | brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n", | 1900 | brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n", |
1903 | mgmt_frame_len, e->datalen, chanspec, freq); | 1901 | mgmt_frame_len, e->datalen, chanspec, freq); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 02fe706fc9ec..12a60ca1462a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -2394,9 +2394,13 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, | |||
2394 | brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); | 2394 | brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); |
2395 | brcmf_dbg(CONN, "Signal: %d\n", notify_signal); | 2395 | brcmf_dbg(CONN, "Signal: %d\n", notify_signal); |
2396 | 2396 | ||
2397 | bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, | 2397 | bss = cfg80211_inform_bss(wiphy, notify_channel, |
2398 | 0, notify_capability, notify_interval, notify_ie, | 2398 | CFG80211_BSS_FTYPE_UNKNOWN, |
2399 | notify_ielen, notify_signal, GFP_KERNEL); | 2399 | (const u8 *)bi->BSSID, |
2400 | 0, notify_capability, | ||
2401 | notify_interval, notify_ie, | ||
2402 | notify_ielen, notify_signal, | ||
2403 | GFP_KERNEL); | ||
2400 | 2404 | ||
2401 | if (!bss) | 2405 | if (!bss) |
2402 | return -ENOMEM; | 2406 | return -ENOMEM; |
@@ -2498,9 +2502,11 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, | |||
2498 | brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); | 2502 | brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); |
2499 | brcmf_dbg(CONN, "signal: %d\n", notify_signal); | 2503 | brcmf_dbg(CONN, "signal: %d\n", notify_signal); |
2500 | 2504 | ||
2501 | bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, | 2505 | bss = cfg80211_inform_bss(wiphy, notify_channel, |
2502 | 0, notify_capability, notify_interval, | 2506 | CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0, |
2503 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); | 2507 | notify_capability, notify_interval, |
2508 | notify_ie, notify_ielen, notify_signal, | ||
2509 | GFP_KERNEL); | ||
2504 | 2510 | ||
2505 | if (!bss) { | 2511 | if (!bss) { |
2506 | err = -ENOMEM; | 2512 | err = -ENOMEM; |
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index 40078f5f932e..964b64ab7fe3 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c | |||
@@ -398,7 +398,7 @@ static int cw1200_spi_probe(struct spi_device *func) | |||
398 | return -1; | 398 | return -1; |
399 | } | 399 | } |
400 | 400 | ||
401 | self = kzalloc(sizeof(*self), GFP_KERNEL); | 401 | self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); |
402 | if (!self) { | 402 | if (!self) { |
403 | pr_err("Can't allocate SPI hwbus_priv."); | 403 | pr_err("Can't allocate SPI hwbus_priv."); |
404 | return -ENOMEM; | 404 | return -ENOMEM; |
@@ -424,7 +424,6 @@ static int cw1200_spi_probe(struct spi_device *func) | |||
424 | if (status) { | 424 | if (status) { |
425 | cw1200_spi_irq_unsubscribe(self); | 425 | cw1200_spi_irq_unsubscribe(self); |
426 | cw1200_spi_off(plat_data); | 426 | cw1200_spi_off(plat_data); |
427 | kfree(self); | ||
428 | } | 427 | } |
429 | 428 | ||
430 | return status; | 429 | return status; |
@@ -441,7 +440,6 @@ static int cw1200_spi_disconnect(struct spi_device *func) | |||
441 | cw1200_core_release(self->core); | 440 | cw1200_core_release(self->core); |
442 | self->core = NULL; | 441 | self->core = NULL; |
443 | } | 442 | } |
444 | kfree(self); | ||
445 | } | 443 | } |
446 | cw1200_spi_off(dev_get_platdata(&func->dev)); | 444 | cw1200_spi_off(dev_get_platdata(&func->dev)); |
447 | 445 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index a42f9c335090..f0c3c77a48d3 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -5552,7 +5552,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5552 | min(network->ssid_len, priv->essid_len)))) { | 5552 | min(network->ssid_len, priv->essid_len)))) { |
5553 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5553 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
5554 | 5554 | ||
5555 | strncpy(escaped, | 5555 | strlcpy(escaped, |
5556 | print_ssid(ssid, network->ssid, | 5556 | print_ssid(ssid, network->ssid, |
5557 | network->ssid_len), | 5557 | network->ssid_len), |
5558 | sizeof(escaped)); | 5558 | sizeof(escaped)); |
@@ -5765,7 +5765,7 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5765 | memcmp(network->ssid, priv->essid, | 5765 | memcmp(network->ssid, priv->essid, |
5766 | min(network->ssid_len, priv->essid_len)))) { | 5766 | min(network->ssid_len, priv->essid_len)))) { |
5767 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5767 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
5768 | strncpy(escaped, | 5768 | strlcpy(escaped, |
5769 | print_ssid(ssid, network->ssid, | 5769 | print_ssid(ssid, network->ssid, |
5770 | network->ssid_len), | 5770 | network->ssid_len), |
5771 | sizeof(escaped)); | 5771 | sizeof(escaped)); |
@@ -5782,7 +5782,7 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5782 | * testing everything else. */ | 5782 | * testing everything else. */ |
5783 | if (match->network && match->network->stats.rssi > network->stats.rssi) { | 5783 | if (match->network && match->network->stats.rssi > network->stats.rssi) { |
5784 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5784 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
5785 | strncpy(escaped, | 5785 | strlcpy(escaped, |
5786 | print_ssid(ssid, network->ssid, network->ssid_len), | 5786 | print_ssid(ssid, network->ssid, network->ssid_len), |
5787 | sizeof(escaped)); | 5787 | sizeof(escaped)); |
5788 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because " | 5788 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because " |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 824f5e287783..267e48a2915e 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -85,6 +85,16 @@ config IWLWIFI_BCAST_FILTERING | |||
85 | If unsure, don't enable this option, as some programs might | 85 | If unsure, don't enable this option, as some programs might |
86 | expect incoming broadcasts for their normal operations. | 86 | expect incoming broadcasts for their normal operations. |
87 | 87 | ||
88 | config IWLWIFI_UAPSD | ||
89 | bool "enable U-APSD by default" | ||
90 | depends on IWLMVM | ||
91 | help | ||
92 | Say Y here to enable U-APSD by default. This may cause | ||
93 | interoperability problems with some APs, manifesting in lower than | ||
94 | expected throughput due to those APs not enabling aggregation | ||
95 | |||
96 | If unsure, say N. | ||
97 | |||
88 | menu "Debugging Options" | 98 | menu "Debugging Options" |
89 | 99 | ||
90 | config IWLWIFI_DEBUG | 100 | config IWLWIFI_DEBUG |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 3255a1723d17..d1ce3ce13591 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -580,7 +580,7 @@ turn_off: | |||
580 | * time, or we hadn't time to drain the AC queues. | 580 | * time, or we hadn't time to drain the AC queues. |
581 | */ | 581 | */ |
582 | if (agg_state == IWL_AGG_ON) | 582 | if (agg_state == IWL_AGG_ON) |
583 | iwl_trans_txq_disable(priv->trans, txq_id); | 583 | iwl_trans_txq_disable(priv->trans, txq_id, true); |
584 | else | 584 | else |
585 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 585 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
586 | agg_state); | 586 | agg_state); |
@@ -686,7 +686,7 @@ int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
686 | * time, or we hadn't time to drain the AC queues. | 686 | * time, or we hadn't time to drain the AC queues. |
687 | */ | 687 | */ |
688 | if (agg_state == IWL_AGG_ON) | 688 | if (agg_state == IWL_AGG_ON) |
689 | iwl_trans_txq_disable(priv->trans, txq_id); | 689 | iwl_trans_txq_disable(priv->trans, txq_id, true); |
690 | else | 690 | else |
691 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 691 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
692 | agg_state); | 692 | agg_state); |
@@ -781,7 +781,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
781 | "Can continue DELBA flow ssn = next_recl = %d\n", | 781 | "Can continue DELBA flow ssn = next_recl = %d\n", |
782 | tid_data->next_reclaimed); | 782 | tid_data->next_reclaimed); |
783 | iwl_trans_txq_disable(priv->trans, | 783 | iwl_trans_txq_disable(priv->trans, |
784 | tid_data->agg.txq_id); | 784 | tid_data->agg.txq_id, true); |
785 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); | 785 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); |
786 | tid_data->agg.state = IWL_AGG_OFF; | 786 | tid_data->agg.state = IWL_AGG_OFF; |
787 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | 787 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index d67a37a786aa..7e26d0dbfcf7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index e93c6972290b..23a67bfc086f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index fe129c94ae3e..23d059af6476 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 295083510e72..0a70bcd241f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -145,6 +145,7 @@ do { \ | |||
145 | #define IWL_DL_HCMD 0x00000004 | 145 | #define IWL_DL_HCMD 0x00000004 |
146 | #define IWL_DL_STATE 0x00000008 | 146 | #define IWL_DL_STATE 0x00000008 |
147 | /* 0x000000F0 - 0x00000010 */ | 147 | /* 0x000000F0 - 0x00000010 */ |
148 | #define IWL_DL_QUOTA 0x00000010 | ||
148 | #define IWL_DL_TE 0x00000020 | 149 | #define IWL_DL_TE 0x00000020 |
149 | #define IWL_DL_EEPROM 0x00000040 | 150 | #define IWL_DL_EEPROM 0x00000040 |
150 | #define IWL_DL_RADIO 0x00000080 | 151 | #define IWL_DL_RADIO 0x00000080 |
@@ -189,6 +190,7 @@ do { \ | |||
189 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) | 190 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) |
190 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) | 191 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) |
191 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) | 192 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) |
193 | #define IWL_DEBUG_QUOTA(p, f, a...) IWL_DEBUG(p, IWL_DL_QUOTA, f, ## a) | ||
192 | #define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a) | 194 | #define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a) |
193 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) | 195 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) |
194 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) | 196 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 23e7351e02de..90987d6f348e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -36,15 +36,8 @@ | |||
36 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); | 36 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); |
37 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); | 37 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); |
38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); | 38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); |
39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); | ||
40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx); | ||
41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); | 39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); |
42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); | 40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); |
43 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); | 41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); |
44 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); | 42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); |
45 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info); | ||
46 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn); | ||
47 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit); | ||
48 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err); | ||
49 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg); | ||
50 | #endif | 43 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 77e3178040b2..aefd94cb6e91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -1254,7 +1256,9 @@ struct iwl_mod_params iwlwifi_mod_params = { | |||
1254 | .bt_coex_active = true, | 1256 | .bt_coex_active = true, |
1255 | .power_level = IWL_POWER_INDEX_1, | 1257 | .power_level = IWL_POWER_INDEX_1, |
1256 | .wd_disable = true, | 1258 | .wd_disable = true, |
1257 | .uapsd_disable = false, | 1259 | #ifndef CONFIG_IWLWIFI_UAPSD |
1260 | .uapsd_disable = true, | ||
1261 | #endif /* CONFIG_IWLWIFI_UAPSD */ | ||
1258 | /* the rest are 0 by default */ | 1262 | /* the rest are 0 by default */ |
1259 | }; | 1263 | }; |
1260 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); | 1264 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); |
@@ -1370,7 +1374,11 @@ MODULE_PARM_DESC(nvm_file, "NVM file name"); | |||
1370 | 1374 | ||
1371 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, | 1375 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, |
1372 | bool, S_IRUGO); | 1376 | bool, S_IRUGO); |
1377 | #ifdef CONFIG_IWLWIFI_UAPSD | ||
1373 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); | 1378 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); |
1379 | #else | ||
1380 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: Y)"); | ||
1381 | #endif | ||
1374 | 1382 | ||
1375 | /* | 1383 | /* |
1376 | * set bt_coex_active to true, uCode will do kill/defer | 1384 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 3c72cb710b0c..be4f8972241a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index de5994a776c7..e30a41d04c8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 929a8063354c..401f7be36b93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 1bb5193c5b1b..f68cba4e0444 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -125,6 +127,8 @@ enum iwl_ucode_tlv_flag { | |||
125 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. | 127 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. |
126 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. | 128 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. |
127 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. | 129 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. |
130 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time | ||
131 | * longer than the passive one, which is essential for fragmented scan. | ||
128 | */ | 132 | */ |
129 | enum iwl_ucode_tlv_api { | 133 | enum iwl_ucode_tlv_api { |
130 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), | 134 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
@@ -133,6 +137,7 @@ enum iwl_ucode_tlv_api { | |||
133 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), | 137 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), |
134 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), | 138 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), |
135 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), | 139 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), |
140 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | ||
136 | }; | 141 | }; |
137 | 142 | ||
138 | /** | 143 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 018af2957d3b..8e7af798abd1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 99785c892f96..b6d666ee8359 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 47033a35a402..1560f4576c7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -281,6 +283,7 @@ | |||
281 | #define SCD_CHAINEXT_EN (SCD_BASE + 0x244) | 283 | #define SCD_CHAINEXT_EN (SCD_BASE + 0x244) |
282 | #define SCD_AGGR_SEL (SCD_BASE + 0x248) | 284 | #define SCD_AGGR_SEL (SCD_BASE + 0x248) |
283 | #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) | 285 | #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) |
286 | #define SCD_EN_CTRL (SCD_BASE + 0x254) | ||
284 | 287 | ||
285 | static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) | 288 | static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) |
286 | { | 289 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scd.h b/drivers/net/wireless/iwlwifi/iwl-scd.h new file mode 100644 index 000000000000..6c622b21bba7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-scd.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | |||
64 | #ifndef __iwl_scd_h__ | ||
65 | #define __iwl_scd_h__ | ||
66 | |||
67 | #include "iwl-trans.h" | ||
68 | #include "iwl-io.h" | ||
69 | #include "iwl-prph.h" | ||
70 | |||
71 | |||
72 | static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans, | ||
73 | u16 txq_id) | ||
74 | { | ||
75 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | ||
76 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
77 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
78 | } | ||
79 | |||
80 | static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans, | ||
81 | u16 txq_id) | ||
82 | { | ||
83 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | ||
84 | } | ||
85 | |||
86 | static inline void iwl_scd_txq_enable_agg(struct iwl_trans *trans, | ||
87 | u16 txq_id) | ||
88 | { | ||
89 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | ||
90 | } | ||
91 | |||
92 | static inline void iwl_scd_txq_disable_agg(struct iwl_trans *trans, | ||
93 | u16 txq_id) | ||
94 | { | ||
95 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | ||
96 | } | ||
97 | |||
98 | static inline void iwl_scd_disable_agg(struct iwl_trans *trans) | ||
99 | { | ||
100 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, 0); | ||
101 | } | ||
102 | |||
103 | static inline void iwl_scd_activate_fifos(struct iwl_trans *trans) | ||
104 | { | ||
105 | iwl_write_prph(trans, SCD_TXFACT, IWL_MASK(0, 7)); | ||
106 | } | ||
107 | |||
108 | static inline void iwl_scd_deactivate_fifos(struct iwl_trans *trans) | ||
109 | { | ||
110 | iwl_write_prph(trans, SCD_TXFACT, 0); | ||
111 | } | ||
112 | |||
113 | static inline void iwl_scd_enable_set_active(struct iwl_trans *trans, | ||
114 | u32 value) | ||
115 | { | ||
116 | iwl_write_prph(trans, SCD_EN_CTRL, value); | ||
117 | } | ||
118 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 656371a668da..c89985a58803 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -401,6 +403,14 @@ struct iwl_trans_dump_data { | |||
401 | 403 | ||
402 | struct iwl_trans; | 404 | struct iwl_trans; |
403 | 405 | ||
406 | struct iwl_trans_txq_scd_cfg { | ||
407 | u8 fifo; | ||
408 | s8 sta_id; | ||
409 | u8 tid; | ||
410 | bool aggregate; | ||
411 | int frame_limit; | ||
412 | }; | ||
413 | |||
404 | /** | 414 | /** |
405 | * struct iwl_trans_ops - transport specific operations | 415 | * struct iwl_trans_ops - transport specific operations |
406 | * | 416 | * |
@@ -437,7 +447,9 @@ struct iwl_trans; | |||
437 | * Must be atomic | 447 | * Must be atomic |
438 | * @txq_enable: setup a queue. To setup an AC queue, use the | 448 | * @txq_enable: setup a queue. To setup an AC queue, use the |
439 | * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before | 449 | * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before |
440 | * this one. The op_mode must not configure the HCMD queue. May sleep. | 450 | * this one. The op_mode must not configure the HCMD queue. The scheduler |
451 | * configuration may be %NULL, in which case the hardware will not be | ||
452 | * configured. May sleep. | ||
441 | * @txq_disable: de-configure a Tx queue to send AMPDUs | 453 | * @txq_disable: de-configure a Tx queue to send AMPDUs |
442 | * Must be atomic | 454 | * Must be atomic |
443 | * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. | 455 | * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. |
@@ -492,9 +504,10 @@ struct iwl_trans_ops { | |||
492 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, | 504 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, |
493 | struct sk_buff_head *skbs); | 505 | struct sk_buff_head *skbs); |
494 | 506 | ||
495 | void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, | 507 | void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, |
496 | int sta_id, int tid, int frame_limit, u16 ssn); | 508 | const struct iwl_trans_txq_scd_cfg *cfg); |
497 | void (*txq_disable)(struct iwl_trans *trans, int queue); | 509 | void (*txq_disable)(struct iwl_trans *trans, int queue, |
510 | bool configure_scd); | ||
498 | 511 | ||
499 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 512 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
500 | int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); | 513 | int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); |
@@ -766,29 +779,57 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | |||
766 | trans->ops->reclaim(trans, queue, ssn, skbs); | 779 | trans->ops->reclaim(trans, queue, ssn, skbs); |
767 | } | 780 | } |
768 | 781 | ||
769 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) | 782 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue, |
783 | bool configure_scd) | ||
770 | { | 784 | { |
771 | trans->ops->txq_disable(trans, queue); | 785 | trans->ops->txq_disable(trans, queue, configure_scd); |
772 | } | 786 | } |
773 | 787 | ||
774 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | 788 | static inline void |
775 | int fifo, int sta_id, int tid, | 789 | iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn, |
776 | int frame_limit, u16 ssn) | 790 | const struct iwl_trans_txq_scd_cfg *cfg) |
777 | { | 791 | { |
778 | might_sleep(); | 792 | might_sleep(); |
779 | 793 | ||
780 | if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) | 794 | if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) |
781 | IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); | 795 | IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); |
782 | 796 | ||
783 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, | 797 | trans->ops->txq_enable(trans, queue, ssn, cfg); |
784 | frame_limit, ssn); | 798 | } |
799 | |||
800 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | ||
801 | int fifo, int sta_id, int tid, | ||
802 | int frame_limit, u16 ssn) | ||
803 | { | ||
804 | struct iwl_trans_txq_scd_cfg cfg = { | ||
805 | .fifo = fifo, | ||
806 | .sta_id = sta_id, | ||
807 | .tid = tid, | ||
808 | .frame_limit = frame_limit, | ||
809 | .aggregate = sta_id >= 0, | ||
810 | }; | ||
811 | |||
812 | iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg); | ||
785 | } | 813 | } |
786 | 814 | ||
787 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | 815 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, |
788 | int fifo) | 816 | int fifo) |
789 | { | 817 | { |
790 | iwl_trans_txq_enable(trans, queue, fifo, -1, | 818 | struct iwl_trans_txq_scd_cfg cfg = { |
791 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); | 819 | .fifo = fifo, |
820 | .sta_id = -1, | ||
821 | .tid = IWL_MAX_TID_COUNT, | ||
822 | .frame_limit = IWL_FRAME_LIMIT, | ||
823 | .aggregate = false, | ||
824 | }; | ||
825 | |||
826 | iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); | ||
827 | } | ||
828 | |||
829 | static inline void | ||
830 | iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn) | ||
831 | { | ||
832 | iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL); | ||
792 | } | 833 | } |
793 | 834 | ||
794 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, | 835 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 2291bbcaaeab..2262d6dc61ae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index a3be33359927..585c0ab4a3ec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index ca79f7160573..dd00e8f7f765 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 645b3cfc29a5..c17be0fb7283 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -700,7 +702,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
700 | return ret; | 702 | return ret; |
701 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); | 703 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); |
702 | 704 | ||
703 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 705 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
704 | if (ret) | 706 | if (ret) |
705 | return ret; | 707 | return ret; |
706 | 708 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c index 2e90ff795c13..d919b4ebc83c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -119,6 +121,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, | |||
119 | IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val); | 121 | IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val); |
120 | dbgfs_pm->uapsd_misbehaving = val; | 122 | dbgfs_pm->uapsd_misbehaving = val; |
121 | break; | 123 | break; |
124 | case MVM_DEBUGFS_PM_USE_PS_POLL: | ||
125 | IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val); | ||
126 | dbgfs_pm->use_ps_poll = val; | ||
127 | break; | ||
122 | } | 128 | } |
123 | } | 129 | } |
124 | 130 | ||
@@ -169,6 +175,10 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf, | |||
169 | if (sscanf(buf + 18, "%d", &val) != 1) | 175 | if (sscanf(buf + 18, "%d", &val) != 1) |
170 | return -EINVAL; | 176 | return -EINVAL; |
171 | param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING; | 177 | param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING; |
178 | } else if (!strncmp("use_ps_poll=", buf, 12)) { | ||
179 | if (sscanf(buf + 12, "%d", &val) != 1) | ||
180 | return -EINVAL; | ||
181 | param = MVM_DEBUGFS_PM_USE_PS_POLL; | ||
172 | } else { | 182 | } else { |
173 | return -EINVAL; | 183 | return -EINVAL; |
174 | } | 184 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 7d18f466fbb3..d98ee109c5e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -257,6 +259,70 @@ static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, | |||
257 | return count; | 259 | return count; |
258 | } | 260 | } |
259 | 261 | ||
262 | static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file, | ||
263 | char __user *user_buf, | ||
264 | size_t count, loff_t *ppos) | ||
265 | { | ||
266 | struct iwl_mvm *mvm = file->private_data; | ||
267 | char buf[16]; | ||
268 | int pos; | ||
269 | |||
270 | if (!mvm->temperature_test) | ||
271 | pos = scnprintf(buf , sizeof(buf), "disabled\n"); | ||
272 | else | ||
273 | pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature); | ||
274 | |||
275 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * Set NIC Temperature | ||
280 | * Cause the driver to ignore the actual NIC temperature reported by the FW | ||
281 | * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN - | ||
282 | * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX | ||
283 | * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE | ||
284 | */ | ||
285 | static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm, | ||
286 | char *buf, size_t count, | ||
287 | loff_t *ppos) | ||
288 | { | ||
289 | int temperature; | ||
290 | |||
291 | if (kstrtoint(buf, 10, &temperature)) | ||
292 | return -EINVAL; | ||
293 | /* not a legal temperature */ | ||
294 | if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX && | ||
295 | temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) || | ||
296 | temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN) | ||
297 | return -EINVAL; | ||
298 | |||
299 | mutex_lock(&mvm->mutex); | ||
300 | if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) { | ||
301 | if (!mvm->temperature_test) | ||
302 | goto out; | ||
303 | |||
304 | mvm->temperature_test = false; | ||
305 | /* Since we can't read the temp while awake, just set | ||
306 | * it to zero until we get the next RX stats from the | ||
307 | * firmware. | ||
308 | */ | ||
309 | mvm->temperature = 0; | ||
310 | } else { | ||
311 | mvm->temperature_test = true; | ||
312 | mvm->temperature = temperature; | ||
313 | } | ||
314 | IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n", | ||
315 | mvm->temperature_test ? "En" : "Dis" , | ||
316 | mvm->temperature); | ||
317 | /* handle the temperature change */ | ||
318 | iwl_mvm_tt_handler(mvm); | ||
319 | |||
320 | out: | ||
321 | mutex_unlock(&mvm->mutex); | ||
322 | |||
323 | return count; | ||
324 | } | ||
325 | |||
260 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 326 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
261 | size_t count, loff_t *ppos) | 327 | size_t count, loff_t *ppos) |
262 | { | 328 | { |
@@ -1296,6 +1362,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); | |||
1296 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); | 1362 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); |
1297 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); | 1363 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); |
1298 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); | 1364 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); |
1365 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64); | ||
1299 | MVM_DEBUGFS_READ_FILE_OPS(stations); | 1366 | MVM_DEBUGFS_READ_FILE_OPS(stations); |
1300 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); | 1367 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); |
1301 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); | 1368 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); |
@@ -1336,6 +1403,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1336 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); | 1403 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); |
1337 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); | 1404 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); |
1338 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); | 1405 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); |
1406 | MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, | ||
1407 | S_IWUSR | S_IRUSR); | ||
1339 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); | 1408 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); |
1340 | MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); | 1409 | MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); |
1341 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); | 1410 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); |
@@ -1380,6 +1449,13 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1380 | goto err; | 1449 | goto err; |
1381 | #endif | 1450 | #endif |
1382 | 1451 | ||
1452 | if (!debugfs_create_u8("low_latency_agg_frame_limit", S_IRUSR | S_IWUSR, | ||
1453 | mvm->debugfs_dir, | ||
1454 | &mvm->low_latency_agg_frame_limit)) | ||
1455 | goto err; | ||
1456 | if (!debugfs_create_u8("ps_disabled", S_IRUSR, | ||
1457 | mvm->debugfs_dir, &mvm->ps_disabled)) | ||
1458 | goto err; | ||
1383 | if (!debugfs_create_blob("nvm_hw", S_IRUSR, | 1459 | if (!debugfs_create_blob("nvm_hw", S_IRUSR, |
1384 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) | 1460 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) |
1385 | goto err; | 1461 | goto err; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h index e3a9774af495..8c4190e7e027 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.h +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h index 69875716dcdb..816883f9ff94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 13696fe419b7..e74cdf2132f8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index c3a8c86b550d..27dd86395b39 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index c02a9e45ec5e..8f2216694004 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 47bd0406355d..21dd5b771660 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 95f5b3274efb..9c975f9ecfcb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -73,16 +75,20 @@ | |||
73 | #include "fw-api-coex.h" | 75 | #include "fw-api-coex.h" |
74 | #include "fw-api-scan.h" | 76 | #include "fw-api-scan.h" |
75 | 77 | ||
76 | /* maximal number of Tx queues in any platform */ | ||
77 | #define IWL_MVM_MAX_QUEUES 20 | ||
78 | |||
79 | /* Tx queue numbers */ | 78 | /* Tx queue numbers */ |
80 | enum { | 79 | enum { |
81 | IWL_MVM_OFFCHANNEL_QUEUE = 8, | 80 | IWL_MVM_OFFCHANNEL_QUEUE = 8, |
82 | IWL_MVM_CMD_QUEUE = 9, | 81 | IWL_MVM_CMD_QUEUE = 9, |
83 | }; | 82 | }; |
84 | 83 | ||
85 | #define IWL_MVM_CMD_FIFO 7 | 84 | enum iwl_mvm_tx_fifo { |
85 | IWL_MVM_TX_FIFO_BK = 0, | ||
86 | IWL_MVM_TX_FIFO_BE, | ||
87 | IWL_MVM_TX_FIFO_VI, | ||
88 | IWL_MVM_TX_FIFO_VO, | ||
89 | IWL_MVM_TX_FIFO_MCAST = 5, | ||
90 | IWL_MVM_TX_FIFO_CMD = 7, | ||
91 | }; | ||
86 | 92 | ||
87 | #define IWL_MVM_STATION_COUNT 16 | 93 | #define IWL_MVM_STATION_COUNT 16 |
88 | 94 | ||
@@ -184,6 +190,8 @@ enum { | |||
184 | REPLY_RX_MPDU_CMD = 0xc1, | 190 | REPLY_RX_MPDU_CMD = 0xc1, |
185 | BA_NOTIF = 0xc5, | 191 | BA_NOTIF = 0xc5, |
186 | 192 | ||
193 | MARKER_CMD = 0xcb, | ||
194 | |||
187 | /* BT Coex */ | 195 | /* BT Coex */ |
188 | BT_COEX_PRIO_TABLE = 0xcc, | 196 | BT_COEX_PRIO_TABLE = 0xcc, |
189 | BT_COEX_PROT_ENV = 0xcd, | 197 | BT_COEX_PROT_ENV = 0xcd, |
@@ -1307,6 +1315,38 @@ struct iwl_bcast_filter_cmd { | |||
1307 | struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER]; | 1315 | struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER]; |
1308 | } __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */ | 1316 | } __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */ |
1309 | 1317 | ||
1318 | /* | ||
1319 | * enum iwl_mvm_marker_id - maker ids | ||
1320 | * | ||
1321 | * The ids for different type of markers to insert into the usniffer logs | ||
1322 | */ | ||
1323 | enum iwl_mvm_marker_id { | ||
1324 | MARKER_ID_TX_FRAME_LATENCY = 1, | ||
1325 | }; /* MARKER_ID_API_E_VER_1 */ | ||
1326 | |||
1327 | /** | ||
1328 | * struct iwl_mvm_marker - mark info into the usniffer logs | ||
1329 | * | ||
1330 | * (MARKER_CMD = 0xcb) | ||
1331 | * | ||
1332 | * Mark the UTC time stamp into the usniffer logs together with additional | ||
1333 | * metadata, so the usniffer output can be parsed. | ||
1334 | * In the command response the ucode will return the GP2 time. | ||
1335 | * | ||
1336 | * @dw_len: The amount of dwords following this byte including this byte. | ||
1337 | * @marker_id: A unique marker id (iwl_mvm_marker_id). | ||
1338 | * @reserved: reserved. | ||
1339 | * @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC | ||
1340 | * @metadata: additional meta data that will be written to the unsiffer log | ||
1341 | */ | ||
1342 | struct iwl_mvm_marker { | ||
1343 | u8 dwLen; | ||
1344 | u8 markerId; | ||
1345 | __le16 reserved; | ||
1346 | __le64 timestamp; | ||
1347 | __le32 metadata[0]; | ||
1348 | } __packed; /* MARKER_API_S_VER_1 */ | ||
1349 | |||
1310 | struct mvm_statistics_dbg { | 1350 | struct mvm_statistics_dbg { |
1311 | __le32 burst_check; | 1351 | __le32 burst_check; |
1312 | __le32 burst_count; | 1352 | __le32 burst_count; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 883e702152d5..21d606028ca6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -242,10 +244,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, | |||
242 | mvm->queue_to_mac80211[i] = i; | 244 | mvm->queue_to_mac80211[i] = i; |
243 | else | 245 | else |
244 | mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; | 246 | mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; |
245 | atomic_set(&mvm->queue_stop_count[i], 0); | ||
246 | } | 247 | } |
247 | 248 | ||
248 | mvm->transport_queue_stop = 0; | 249 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) |
250 | atomic_set(&mvm->mac80211_queue_stop_count[i], 0); | ||
249 | 251 | ||
250 | mvm->ucode_loaded = true; | 252 | mvm->ucode_loaded = true; |
251 | 253 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 0e523e28cabf..9cbb192f680e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -81,7 +83,7 @@ struct iwl_mvm_mac_iface_iterator_data { | |||
81 | struct ieee80211_vif *vif; | 83 | struct ieee80211_vif *vif; |
82 | unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; | 84 | unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; |
83 | unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; | 85 | unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; |
84 | unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)]; | 86 | u32 used_hw_queues; |
85 | enum iwl_tsf_id preferred_tsf; | 87 | enum iwl_tsf_id preferred_tsf; |
86 | bool found_vif; | 88 | bool found_vif; |
87 | }; | 89 | }; |
@@ -192,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, | |||
192 | data->preferred_tsf = NUM_TSF_IDS; | 194 | data->preferred_tsf = NUM_TSF_IDS; |
193 | } | 195 | } |
194 | 196 | ||
197 | /* | ||
198 | * Get the mask of the queues used by the vif | ||
199 | */ | ||
200 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | ||
201 | struct ieee80211_vif *vif) | ||
202 | { | ||
203 | u32 qmask = 0, ac; | ||
204 | |||
205 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) | ||
206 | return BIT(IWL_MVM_OFFCHANNEL_QUEUE); | ||
207 | |||
208 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
209 | qmask |= BIT(vif->hw_queue[ac]); | ||
210 | |||
211 | if (vif->type == NL80211_IFTYPE_AP) | ||
212 | qmask |= BIT(vif->cab_queue); | ||
213 | |||
214 | return qmask; | ||
215 | } | ||
216 | |||
195 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | 217 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, |
196 | struct ieee80211_vif *vif) | 218 | struct ieee80211_vif *vif) |
197 | { | 219 | { |
198 | struct iwl_mvm_mac_iface_iterator_data *data = _data; | 220 | struct iwl_mvm_mac_iface_iterator_data *data = _data; |
199 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 221 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
200 | u32 ac; | ||
201 | 222 | ||
202 | /* Iterator may already find the interface being added -- skip it */ | 223 | /* Iterator may already find the interface being added -- skip it */ |
203 | if (vif == data->vif) { | 224 | if (vif == data->vif) { |
@@ -206,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
206 | } | 227 | } |
207 | 228 | ||
208 | /* Mark the queues used by the vif */ | 229 | /* Mark the queues used by the vif */ |
209 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 230 | data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif); |
210 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
211 | __set_bit(vif->hw_queue[ac], data->used_hw_queues); | ||
212 | |||
213 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
214 | __set_bit(vif->cab_queue, data->used_hw_queues); | ||
215 | 231 | ||
216 | /* Mark MAC IDs as used by clearing the available bit, and | 232 | /* Mark MAC IDs as used by clearing the available bit, and |
217 | * (below) mark TSFs as used if their existing use is not | 233 | * (below) mark TSFs as used if their existing use is not |
@@ -225,24 +241,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
225 | iwl_mvm_mac_tsf_id_iter(_data, mac, vif); | 241 | iwl_mvm_mac_tsf_id_iter(_data, mac, vif); |
226 | } | 242 | } |
227 | 243 | ||
228 | /* | ||
229 | * Get the mask of the queus used by the vif | ||
230 | */ | ||
231 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | ||
232 | struct ieee80211_vif *vif) | ||
233 | { | ||
234 | u32 qmask = 0, ac; | ||
235 | |||
236 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) | ||
237 | return BIT(IWL_MVM_OFFCHANNEL_QUEUE); | ||
238 | |||
239 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
240 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
241 | qmask |= BIT(vif->hw_queue[ac]); | ||
242 | |||
243 | return qmask; | ||
244 | } | ||
245 | |||
246 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, | 244 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, |
247 | struct ieee80211_vif *vif) | 245 | struct ieee80211_vif *vif) |
248 | { | 246 | { |
@@ -277,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
277 | .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, | 275 | .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, |
278 | /* no preference yet */ | 276 | /* no preference yet */ |
279 | .preferred_tsf = NUM_TSF_IDS, | 277 | .preferred_tsf = NUM_TSF_IDS, |
280 | .used_hw_queues = { | 278 | .used_hw_queues = |
281 | BIT(IWL_MVM_OFFCHANNEL_QUEUE) | | 279 | BIT(IWL_MVM_OFFCHANNEL_QUEUE) | |
282 | BIT(mvm->aux_queue) | | 280 | BIT(mvm->aux_queue) | |
283 | BIT(IWL_MVM_CMD_QUEUE) | 281 | BIT(IWL_MVM_CMD_QUEUE), |
284 | }, | ||
285 | .found_vif = false, | 282 | .found_vif = false, |
286 | }; | 283 | }; |
287 | u32 ac; | 284 | u32 ac; |
288 | int ret, i; | 285 | int ret, i; |
286 | unsigned long used_hw_queues; | ||
289 | 287 | ||
290 | /* | 288 | /* |
291 | * Allocate a MAC ID and a TSF for this MAC, along with the queues | 289 | * Allocate a MAC ID and a TSF for this MAC, along with the queues |
@@ -368,9 +366,11 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
368 | return 0; | 366 | return 0; |
369 | } | 367 | } |
370 | 368 | ||
369 | used_hw_queues = data.used_hw_queues; | ||
370 | |||
371 | /* Find available queues, and allocate them to the ACs */ | 371 | /* Find available queues, and allocate them to the ACs */ |
372 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 372 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
373 | u8 queue = find_first_zero_bit(data.used_hw_queues, | 373 | u8 queue = find_first_zero_bit(&used_hw_queues, |
374 | mvm->first_agg_queue); | 374 | mvm->first_agg_queue); |
375 | 375 | ||
376 | if (queue >= mvm->first_agg_queue) { | 376 | if (queue >= mvm->first_agg_queue) { |
@@ -379,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
379 | goto exit_fail; | 379 | goto exit_fail; |
380 | } | 380 | } |
381 | 381 | ||
382 | __set_bit(queue, data.used_hw_queues); | 382 | __set_bit(queue, &used_hw_queues); |
383 | vif->hw_queue[ac] = queue; | 383 | vif->hw_queue[ac] = queue; |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Allocate the CAB queue for softAP and GO interfaces */ | 386 | /* Allocate the CAB queue for softAP and GO interfaces */ |
387 | if (vif->type == NL80211_IFTYPE_AP) { | 387 | if (vif->type == NL80211_IFTYPE_AP) { |
388 | u8 queue = find_first_zero_bit(data.used_hw_queues, | 388 | u8 queue = find_first_zero_bit(&used_hw_queues, |
389 | mvm->first_agg_queue); | 389 | mvm->first_agg_queue); |
390 | 390 | ||
391 | if (queue >= mvm->first_agg_queue) { | 391 | if (queue >= mvm->first_agg_queue) { |
@@ -452,14 +452,16 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
452 | 452 | ||
453 | switch (vif->type) { | 453 | switch (vif->type) { |
454 | case NL80211_IFTYPE_P2P_DEVICE: | 454 | case NL80211_IFTYPE_P2P_DEVICE: |
455 | iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE); | 455 | iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE, |
456 | true); | ||
456 | break; | 457 | break; |
457 | case NL80211_IFTYPE_AP: | 458 | case NL80211_IFTYPE_AP: |
458 | iwl_trans_txq_disable(mvm->trans, vif->cab_queue); | 459 | iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true); |
459 | /* fall through */ | 460 | /* fall through */ |
460 | default: | 461 | default: |
461 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 462 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
462 | iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]); | 463 | iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac], |
464 | true); | ||
463 | } | 465 | } |
464 | } | 466 | } |
465 | 467 | ||
@@ -586,6 +588,7 @@ static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm, | |||
586 | static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | 588 | static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, |
587 | struct ieee80211_vif *vif, | 589 | struct ieee80211_vif *vif, |
588 | struct iwl_mac_ctx_cmd *cmd, | 590 | struct iwl_mac_ctx_cmd *cmd, |
591 | const u8 *bssid_override, | ||
589 | u32 action) | 592 | u32 action) |
590 | { | 593 | { |
591 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 594 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
@@ -593,6 +596,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
593 | bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & | 596 | bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & |
594 | IEEE80211_HT_OP_MODE_PROTECTION); | 597 | IEEE80211_HT_OP_MODE_PROTECTION); |
595 | u8 cck_ack_rates, ofdm_ack_rates; | 598 | u8 cck_ack_rates, ofdm_ack_rates; |
599 | const u8 *bssid = bssid_override ?: vif->bss_conf.bssid; | ||
596 | int i; | 600 | int i; |
597 | 601 | ||
598 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 602 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, |
@@ -625,8 +629,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
625 | cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); | 629 | cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); |
626 | 630 | ||
627 | memcpy(cmd->node_addr, vif->addr, ETH_ALEN); | 631 | memcpy(cmd->node_addr, vif->addr, ETH_ALEN); |
628 | if (vif->bss_conf.bssid) | 632 | |
629 | memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN); | 633 | if (bssid) |
634 | memcpy(cmd->bssid_addr, bssid, ETH_ALEN); | ||
630 | else | 635 | else |
631 | eth_broadcast_addr(cmd->bssid_addr); | 636 | eth_broadcast_addr(cmd->bssid_addr); |
632 | 637 | ||
@@ -695,7 +700,8 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm, | |||
695 | 700 | ||
696 | static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, | 701 | static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, |
697 | struct ieee80211_vif *vif, | 702 | struct ieee80211_vif *vif, |
698 | u32 action, bool force_assoc_off) | 703 | u32 action, bool force_assoc_off, |
704 | const u8 *bssid_override) | ||
699 | { | 705 | { |
700 | struct iwl_mac_ctx_cmd cmd = {}; | 706 | struct iwl_mac_ctx_cmd cmd = {}; |
701 | struct iwl_mac_data_sta *ctxt_sta; | 707 | struct iwl_mac_data_sta *ctxt_sta; |
@@ -703,7 +709,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, | |||
703 | WARN_ON(vif->type != NL80211_IFTYPE_STATION); | 709 | WARN_ON(vif->type != NL80211_IFTYPE_STATION); |
704 | 710 | ||
705 | /* Fill the common data for all mac context types */ | 711 | /* Fill the common data for all mac context types */ |
706 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 712 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, bssid_override, action); |
707 | 713 | ||
708 | if (vif->p2p) { | 714 | if (vif->p2p) { |
709 | struct ieee80211_p2p_noa_attr *noa = | 715 | struct ieee80211_p2p_noa_attr *noa = |
@@ -784,7 +790,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, | |||
784 | 790 | ||
785 | WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); | 791 | WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); |
786 | 792 | ||
787 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 793 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
788 | 794 | ||
789 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | | 795 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | |
790 | MAC_FILTER_IN_CONTROL_AND_MGMT | | 796 | MAC_FILTER_IN_CONTROL_AND_MGMT | |
@@ -805,7 +811,7 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm, | |||
805 | 811 | ||
806 | WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); | 812 | WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); |
807 | 813 | ||
808 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 814 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
809 | 815 | ||
810 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | | 816 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | |
811 | MAC_FILTER_IN_PROBE_REQUEST); | 817 | MAC_FILTER_IN_PROBE_REQUEST); |
@@ -844,7 +850,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, | |||
844 | 850 | ||
845 | WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); | 851 | WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); |
846 | 852 | ||
847 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 853 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
848 | 854 | ||
849 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); | 855 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); |
850 | 856 | ||
@@ -1072,7 +1078,7 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, | |||
1072 | WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p); | 1078 | WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p); |
1073 | 1079 | ||
1074 | /* Fill the common data for all mac context types */ | 1080 | /* Fill the common data for all mac context types */ |
1075 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1081 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
1076 | 1082 | ||
1077 | /* | 1083 | /* |
1078 | * pass probe requests and beacons from other APs (needed | 1084 | * pass probe requests and beacons from other APs (needed |
@@ -1098,7 +1104,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
1098 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); | 1104 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); |
1099 | 1105 | ||
1100 | /* Fill the common data for all mac context types */ | 1106 | /* Fill the common data for all mac context types */ |
1101 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1107 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
1102 | 1108 | ||
1103 | /* | 1109 | /* |
1104 | * pass probe requests and beacons from other APs (needed | 1110 | * pass probe requests and beacons from other APs (needed |
@@ -1121,12 +1127,14 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
1121 | } | 1127 | } |
1122 | 1128 | ||
1123 | static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1129 | static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1124 | u32 action, bool force_assoc_off) | 1130 | u32 action, bool force_assoc_off, |
1131 | const u8 *bssid_override) | ||
1125 | { | 1132 | { |
1126 | switch (vif->type) { | 1133 | switch (vif->type) { |
1127 | case NL80211_IFTYPE_STATION: | 1134 | case NL80211_IFTYPE_STATION: |
1128 | return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action, | 1135 | return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action, |
1129 | force_assoc_off); | 1136 | force_assoc_off, |
1137 | bssid_override); | ||
1130 | break; | 1138 | break; |
1131 | case NL80211_IFTYPE_AP: | 1139 | case NL80211_IFTYPE_AP: |
1132 | if (!vif->p2p) | 1140 | if (!vif->p2p) |
@@ -1157,7 +1165,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
1157 | return -EIO; | 1165 | return -EIO; |
1158 | 1166 | ||
1159 | ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, | 1167 | ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, |
1160 | true); | 1168 | true, NULL); |
1161 | if (ret) | 1169 | if (ret) |
1162 | return ret; | 1170 | return ret; |
1163 | 1171 | ||
@@ -1169,7 +1177,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
1169 | } | 1177 | } |
1170 | 1178 | ||
1171 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1179 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1172 | bool force_assoc_off) | 1180 | bool force_assoc_off, const u8 *bssid_override) |
1173 | { | 1181 | { |
1174 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1182 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1175 | 1183 | ||
@@ -1178,7 +1186,7 @@ int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1178 | return -EIO; | 1186 | return -EIO; |
1179 | 1187 | ||
1180 | return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, | 1188 | return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, |
1181 | force_assoc_off); | 1189 | force_assoc_off, bssid_override); |
1182 | } | 1190 | } |
1183 | 1191 | ||
1184 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 1192 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7c8796584c25..8d1d4b40b0a3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -776,6 +778,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
776 | iwl_trans_stop_device(mvm->trans); | 778 | iwl_trans_stop_device(mvm->trans); |
777 | 779 | ||
778 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 780 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
781 | mvm->ps_disabled = false; | ||
779 | 782 | ||
780 | /* just in case one was running */ | 783 | /* just in case one was running */ |
781 | ieee80211_remain_on_channel_expired(mvm->hw); | 784 | ieee80211_remain_on_channel_expired(mvm->hw); |
@@ -803,6 +806,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
803 | * ucode_down ref until reconfig is complete */ | 806 | * ucode_down ref until reconfig is complete */ |
804 | iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); | 807 | iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); |
805 | 808 | ||
809 | /* clear any stale d0i3 state */ | ||
810 | clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); | ||
811 | |||
806 | mvm->vif_count = 0; | 812 | mvm->vif_count = 0; |
807 | mvm->rx_ba_sessions = 0; | 813 | mvm->rx_ba_sessions = 0; |
808 | } | 814 | } |
@@ -880,7 +886,7 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | |||
880 | /* async_handlers_list is empty and will stay empty: HW is stopped */ | 886 | /* async_handlers_list is empty and will stay empty: HW is stopped */ |
881 | 887 | ||
882 | /* the fw is stopped, the aux sta is dead: clean up driver state */ | 888 | /* the fw is stopped, the aux sta is dead: clean up driver state */ |
883 | iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); | 889 | iwl_mvm_del_aux_sta(mvm); |
884 | 890 | ||
885 | mutex_unlock(&mvm->mutex); | 891 | mutex_unlock(&mvm->mutex); |
886 | 892 | ||
@@ -965,10 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
965 | */ | 971 | */ |
966 | if (vif->type == NL80211_IFTYPE_AP || | 972 | if (vif->type == NL80211_IFTYPE_AP || |
967 | vif->type == NL80211_IFTYPE_ADHOC) { | 973 | vif->type == NL80211_IFTYPE_ADHOC) { |
968 | u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 974 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
969 | ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, | ||
970 | qmask, | ||
971 | ieee80211_vif_type_p2p(vif)); | ||
972 | if (ret) { | 975 | if (ret) { |
973 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); | 976 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); |
974 | goto out_release; | 977 | goto out_release; |
@@ -1016,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1016 | if (ret) | 1019 | if (ret) |
1017 | goto out_unref_phy; | 1020 | goto out_unref_phy; |
1018 | 1021 | ||
1019 | ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1022 | ret = iwl_mvm_add_bcast_sta(mvm, vif); |
1020 | if (ret) | 1023 | if (ret) |
1021 | goto out_unbind; | 1024 | goto out_unbind; |
1022 | 1025 | ||
@@ -1057,14 +1060,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1057 | static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, | 1060 | static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, |
1058 | struct ieee80211_vif *vif) | 1061 | struct ieee80211_vif *vif) |
1059 | { | 1062 | { |
1060 | u32 tfd_msk = 0, ac; | 1063 | u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif); |
1061 | |||
1062 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
1063 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
1064 | tfd_msk |= BIT(vif->hw_queue[ac]); | ||
1065 | |||
1066 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
1067 | tfd_msk |= BIT(vif->cab_queue); | ||
1068 | 1064 | ||
1069 | if (tfd_msk) { | 1065 | if (tfd_msk) { |
1070 | mutex_lock(&mvm->mutex); | 1066 | mutex_lock(&mvm->mutex); |
@@ -1120,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
1120 | mvm->noa_duration = 0; | 1116 | mvm->noa_duration = 0; |
1121 | } | 1117 | } |
1122 | #endif | 1118 | #endif |
1123 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | 1119 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
1124 | goto out_release; | 1120 | goto out_release; |
1125 | } | 1121 | } |
1126 | 1122 | ||
1127 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 1123 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
1128 | mvm->p2p_device_vif = NULL; | 1124 | mvm->p2p_device_vif = NULL; |
1129 | iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1125 | iwl_mvm_rm_bcast_sta(mvm, vif); |
1130 | iwl_mvm_binding_remove_vif(mvm, vif); | 1126 | iwl_mvm_binding_remove_vif(mvm, vif); |
1131 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); | 1127 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); |
1132 | mvmvif->phy_ctxt = NULL; | 1128 | mvmvif->phy_ctxt = NULL; |
@@ -1445,10 +1441,23 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1445 | if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) | 1441 | if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) |
1446 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); | 1442 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); |
1447 | 1443 | ||
1448 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 1444 | /* |
1445 | * If we're not associated yet, take the (new) BSSID before associating | ||
1446 | * so the firmware knows. If we're already associated, then use the old | ||
1447 | * BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC | ||
1448 | * branch for disassociation below. | ||
1449 | */ | ||
1450 | if (changes & BSS_CHANGED_BSSID && !mvmvif->associated) | ||
1451 | memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN); | ||
1452 | |||
1453 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid); | ||
1449 | if (ret) | 1454 | if (ret) |
1450 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 1455 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
1451 | 1456 | ||
1457 | /* after sending it once, adopt mac80211 data */ | ||
1458 | memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN); | ||
1459 | mvmvif->associated = bss_conf->assoc; | ||
1460 | |||
1452 | if (changes & BSS_CHANGED_ASSOC) { | 1461 | if (changes & BSS_CHANGED_ASSOC) { |
1453 | if (bss_conf->assoc) { | 1462 | if (bss_conf->assoc) { |
1454 | /* add quota for this interface */ | 1463 | /* add quota for this interface */ |
@@ -1476,13 +1485,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1476 | */ | 1485 | */ |
1477 | u32 dur = (11 * vif->bss_conf.beacon_int) / 10; | 1486 | u32 dur = (11 * vif->bss_conf.beacon_int) / 10; |
1478 | iwl_mvm_protect_session(mvm, vif, dur, dur, | 1487 | iwl_mvm_protect_session(mvm, vif, dur, dur, |
1479 | 5 * dur); | 1488 | 5 * dur, false); |
1480 | } | 1489 | } |
1481 | 1490 | ||
1482 | iwl_mvm_sf_update(mvm, vif, false); | 1491 | iwl_mvm_sf_update(mvm, vif, false); |
1483 | iwl_mvm_power_vif_assoc(mvm, vif); | 1492 | iwl_mvm_power_vif_assoc(mvm, vif); |
1484 | if (vif->p2p) | 1493 | if (vif->p2p) { |
1485 | iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); | 1494 | iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); |
1495 | iwl_mvm_update_smps(mvm, vif, | ||
1496 | IWL_MVM_SMPS_REQ_PROT, | ||
1497 | IEEE80211_SMPS_DYNAMIC); | ||
1498 | } | ||
1486 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 1499 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
1487 | /* | 1500 | /* |
1488 | * If update fails - SF might be running in associated | 1501 | * If update fails - SF might be running in associated |
@@ -1506,6 +1519,13 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1506 | 1519 | ||
1507 | if (vif->p2p) | 1520 | if (vif->p2p) |
1508 | iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); | 1521 | iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); |
1522 | |||
1523 | /* this will take the cleared BSSID from bss_conf */ | ||
1524 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); | ||
1525 | if (ret) | ||
1526 | IWL_ERR(mvm, | ||
1527 | "failed to update MAC %pM (clear after unassoc)\n", | ||
1528 | vif->addr); | ||
1509 | } | 1529 | } |
1510 | 1530 | ||
1511 | iwl_mvm_recalc_multicast(mvm); | 1531 | iwl_mvm_recalc_multicast(mvm); |
@@ -1601,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1601 | 1621 | ||
1602 | /* Send the bcast station. At this stage the TBTT and DTIM time events | 1622 | /* Send the bcast station. At this stage the TBTT and DTIM time events |
1603 | * are added and applied to the scheduler */ | 1623 | * are added and applied to the scheduler */ |
1604 | ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1624 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
1605 | if (ret) | 1625 | if (ret) |
1606 | goto out_unbind; | 1626 | goto out_unbind; |
1607 | 1627 | ||
@@ -1617,7 +1637,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1617 | 1637 | ||
1618 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ | 1638 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ |
1619 | if (vif->p2p && mvm->p2p_device_vif) | 1639 | if (vif->p2p && mvm->p2p_device_vif) |
1620 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); | 1640 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); |
1621 | 1641 | ||
1622 | iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); | 1642 | iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); |
1623 | 1643 | ||
@@ -1633,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1633 | out_quota_failed: | 1653 | out_quota_failed: |
1634 | iwl_mvm_power_update_mac(mvm); | 1654 | iwl_mvm_power_update_mac(mvm); |
1635 | mvmvif->ap_ibss_active = false; | 1655 | mvmvif->ap_ibss_active = false; |
1636 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1656 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1637 | out_unbind: | 1657 | out_unbind: |
1638 | iwl_mvm_binding_remove_vif(mvm, vif); | 1658 | iwl_mvm_binding_remove_vif(mvm, vif); |
1639 | out_remove: | 1659 | out_remove: |
@@ -1675,10 +1695,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, | |||
1675 | 1695 | ||
1676 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ | 1696 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ |
1677 | if (vif->p2p && mvm->p2p_device_vif) | 1697 | if (vif->p2p && mvm->p2p_device_vif) |
1678 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); | 1698 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); |
1679 | 1699 | ||
1680 | iwl_mvm_update_quotas(mvm, NULL); | 1700 | iwl_mvm_update_quotas(mvm, NULL); |
1681 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1701 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1682 | iwl_mvm_binding_remove_vif(mvm, vif); | 1702 | iwl_mvm_binding_remove_vif(mvm, vif); |
1683 | 1703 | ||
1684 | iwl_mvm_power_update_mac(mvm); | 1704 | iwl_mvm_power_update_mac(mvm); |
@@ -1702,7 +1722,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, | |||
1702 | 1722 | ||
1703 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | | 1723 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | |
1704 | BSS_CHANGED_BANDWIDTH) && | 1724 | BSS_CHANGED_BANDWIDTH) && |
1705 | iwl_mvm_mac_ctxt_changed(mvm, vif, false)) | 1725 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL)) |
1706 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 1726 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
1707 | 1727 | ||
1708 | /* Need to send a new beacon template to the FW */ | 1728 | /* Need to send a new beacon template to the FW */ |
@@ -2113,7 +2133,7 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw, | |||
2113 | int ret; | 2133 | int ret; |
2114 | 2134 | ||
2115 | mutex_lock(&mvm->mutex); | 2135 | mutex_lock(&mvm->mutex); |
2116 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 2136 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
2117 | mutex_unlock(&mvm->mutex); | 2137 | mutex_unlock(&mvm->mutex); |
2118 | return ret; | 2138 | return ret; |
2119 | } | 2139 | } |
@@ -2141,7 +2161,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, | |||
2141 | 2161 | ||
2142 | mutex_lock(&mvm->mutex); | 2162 | mutex_lock(&mvm->mutex); |
2143 | /* Try really hard to protect the session and hear a beacon */ | 2163 | /* Try really hard to protect the session and hear a beacon */ |
2144 | iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500); | 2164 | iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false); |
2145 | mutex_unlock(&mvm->mutex); | 2165 | mutex_unlock(&mvm->mutex); |
2146 | 2166 | ||
2147 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); | 2167 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); |
@@ -2162,7 +2182,7 @@ static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, | |||
2162 | 2182 | ||
2163 | mutex_lock(&mvm->mutex); | 2183 | mutex_lock(&mvm->mutex); |
2164 | /* Protect the session to hear the TDLS setup response on the channel */ | 2184 | /* Protect the session to hear the TDLS setup response on the channel */ |
2165 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100); | 2185 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); |
2166 | mutex_unlock(&mvm->mutex); | 2186 | mutex_unlock(&mvm->mutex); |
2167 | 2187 | ||
2168 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); | 2188 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); |
@@ -2700,7 +2720,10 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
2700 | ret = 0; | 2720 | ret = 0; |
2701 | goto out; | 2721 | goto out; |
2702 | case NL80211_IFTYPE_STATION: | 2722 | case NL80211_IFTYPE_STATION: |
2723 | break; | ||
2703 | case NL80211_IFTYPE_MONITOR: | 2724 | case NL80211_IFTYPE_MONITOR: |
2725 | /* always disable PS when a monitor interface is active */ | ||
2726 | mvmvif->ps_disabled = true; | ||
2704 | break; | 2727 | break; |
2705 | default: | 2728 | default: |
2706 | ret = -EINVAL; | 2729 | ret = -EINVAL; |
@@ -2732,7 +2755,20 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
2732 | if ((vif->type == NL80211_IFTYPE_AP) || | 2755 | if ((vif->type == NL80211_IFTYPE_AP) || |
2733 | (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { | 2756 | (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { |
2734 | iwl_mvm_update_quotas(mvm, NULL); | 2757 | iwl_mvm_update_quotas(mvm, NULL); |
2735 | iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 2758 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
2759 | } | ||
2760 | |||
2761 | if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) { | ||
2762 | struct iwl_mvm_sta *mvmsta; | ||
2763 | |||
2764 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, | ||
2765 | mvmvif->ap_sta_id); | ||
2766 | |||
2767 | if (WARN_ON(!mvmsta)) | ||
2768 | goto out; | ||
2769 | |||
2770 | /* TODO: only re-enable after the first beacon */ | ||
2771 | iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); | ||
2736 | } | 2772 | } |
2737 | 2773 | ||
2738 | goto out; | 2774 | goto out; |
@@ -2766,6 +2802,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2766 | { | 2802 | { |
2767 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 2803 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
2768 | struct ieee80211_vif *disabled_vif = NULL; | 2804 | struct ieee80211_vif *disabled_vif = NULL; |
2805 | struct iwl_mvm_sta *mvmsta; | ||
2769 | 2806 | ||
2770 | lockdep_assert_held(&mvm->mutex); | 2807 | lockdep_assert_held(&mvm->mutex); |
2771 | 2808 | ||
@@ -2776,6 +2813,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2776 | goto out; | 2813 | goto out; |
2777 | case NL80211_IFTYPE_MONITOR: | 2814 | case NL80211_IFTYPE_MONITOR: |
2778 | mvmvif->monitor_active = false; | 2815 | mvmvif->monitor_active = false; |
2816 | mvmvif->ps_disabled = false; | ||
2779 | break; | 2817 | break; |
2780 | case NL80211_IFTYPE_AP: | 2818 | case NL80211_IFTYPE_AP: |
2781 | /* This part is triggered only during CSA */ | 2819 | /* This part is triggered only during CSA */ |
@@ -2796,7 +2834,13 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2796 | 2834 | ||
2797 | disabled_vif = vif; | 2835 | disabled_vif = vif; |
2798 | 2836 | ||
2799 | iwl_mvm_mac_ctxt_changed(mvm, vif, true); | 2837 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, |
2838 | mvmvif->ap_sta_id); | ||
2839 | |||
2840 | if (!WARN_ON(!mvmsta)) | ||
2841 | iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true); | ||
2842 | |||
2843 | iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL); | ||
2800 | break; | 2844 | break; |
2801 | default: | 2845 | default: |
2802 | break; | 2846 | break; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2e73d3bd7757..e292de96e09a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -103,14 +105,6 @@ | |||
103 | */ | 105 | */ |
104 | #define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3 | 106 | #define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3 |
105 | 107 | ||
106 | enum iwl_mvm_tx_fifo { | ||
107 | IWL_MVM_TX_FIFO_BK = 0, | ||
108 | IWL_MVM_TX_FIFO_BE, | ||
109 | IWL_MVM_TX_FIFO_VI, | ||
110 | IWL_MVM_TX_FIFO_VO, | ||
111 | IWL_MVM_TX_FIFO_MCAST = 5, | ||
112 | }; | ||
113 | |||
114 | extern const struct ieee80211_ops iwl_mvm_hw_ops; | 108 | extern const struct ieee80211_ops iwl_mvm_hw_ops; |
115 | 109 | ||
116 | /** | 110 | /** |
@@ -203,6 +197,7 @@ enum iwl_dbgfs_pm_mask { | |||
203 | MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), | 197 | MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), |
204 | MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), | 198 | MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), |
205 | MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9), | 199 | MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9), |
200 | MVM_DEBUGFS_PM_USE_PS_POLL = BIT(10), | ||
206 | }; | 201 | }; |
207 | 202 | ||
208 | struct iwl_dbgfs_pm { | 203 | struct iwl_dbgfs_pm { |
@@ -215,6 +210,7 @@ struct iwl_dbgfs_pm { | |||
215 | u32 lprx_rssi_threshold; | 210 | u32 lprx_rssi_threshold; |
216 | bool snooze_ena; | 211 | bool snooze_ena; |
217 | bool uapsd_misbehaving; | 212 | bool uapsd_misbehaving; |
213 | bool use_ps_poll; | ||
218 | int mask; | 214 | int mask; |
219 | }; | 215 | }; |
220 | 216 | ||
@@ -253,6 +249,7 @@ struct iwl_dbgfs_bf { | |||
253 | enum iwl_mvm_smps_type_request { | 249 | enum iwl_mvm_smps_type_request { |
254 | IWL_MVM_SMPS_REQ_BT_COEX, | 250 | IWL_MVM_SMPS_REQ_BT_COEX, |
255 | IWL_MVM_SMPS_REQ_TT, | 251 | IWL_MVM_SMPS_REQ_TT, |
252 | IWL_MVM_SMPS_REQ_PROT, | ||
256 | NUM_IWL_MVM_SMPS_REQ, | 253 | NUM_IWL_MVM_SMPS_REQ, |
257 | }; | 254 | }; |
258 | 255 | ||
@@ -315,6 +312,9 @@ struct iwl_mvm_vif_bf_data { | |||
315 | * @id: between 0 and 3 | 312 | * @id: between 0 and 3 |
316 | * @color: to solve races upon MAC addition and removal | 313 | * @color: to solve races upon MAC addition and removal |
317 | * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA | 314 | * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA |
315 | * @bssid: BSSID for this (client) interface | ||
316 | * @associated: indicates that we're currently associated, used only for | ||
317 | * managing the firmware state in iwl_mvm_bss_info_changed_station() | ||
318 | * @uploaded: indicates the MAC context has been added to the device | 318 | * @uploaded: indicates the MAC context has been added to the device |
319 | * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface | 319 | * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface |
320 | * should get quota etc. | 320 | * should get quota etc. |
@@ -323,6 +323,7 @@ struct iwl_mvm_vif_bf_data { | |||
323 | * interface should get quota etc. | 323 | * interface should get quota etc. |
324 | * @low_latency: indicates that this interface is in low-latency mode | 324 | * @low_latency: indicates that this interface is in low-latency mode |
325 | * (VMACLowLatencyMode) | 325 | * (VMACLowLatencyMode) |
326 | * @ps_disabled: indicates that this interface requires PS to be disabled | ||
326 | * @queue_params: QoS params for this MAC | 327 | * @queue_params: QoS params for this MAC |
327 | * @bcast_sta: station used for broadcast packets. Used by the following | 328 | * @bcast_sta: station used for broadcast packets. Used by the following |
328 | * vifs: P2P_DEVICE, GO and AP. | 329 | * vifs: P2P_DEVICE, GO and AP. |
@@ -335,11 +336,15 @@ struct iwl_mvm_vif { | |||
335 | u16 color; | 336 | u16 color; |
336 | u8 ap_sta_id; | 337 | u8 ap_sta_id; |
337 | 338 | ||
339 | u8 bssid[ETH_ALEN]; | ||
340 | bool associated; | ||
341 | |||
338 | bool uploaded; | 342 | bool uploaded; |
339 | bool ap_ibss_active; | 343 | bool ap_ibss_active; |
340 | bool pm_enabled; | 344 | bool pm_enabled; |
341 | bool monitor_active; | 345 | bool monitor_active; |
342 | bool low_latency; | 346 | bool low_latency; |
347 | bool ps_disabled; | ||
343 | struct iwl_mvm_vif_bf_data bf_data; | 348 | struct iwl_mvm_vif_bf_data bf_data; |
344 | 349 | ||
345 | u32 ap_beacon_time; | 350 | u32 ap_beacon_time; |
@@ -512,6 +517,10 @@ enum { | |||
512 | D0I3_PENDING_WAKEUP, | 517 | D0I3_PENDING_WAKEUP, |
513 | }; | 518 | }; |
514 | 519 | ||
520 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff | ||
521 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100 | ||
522 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200 | ||
523 | |||
515 | struct iwl_mvm { | 524 | struct iwl_mvm { |
516 | /* for logger access */ | 525 | /* for logger access */ |
517 | struct device *dev; | 526 | struct device *dev; |
@@ -553,9 +562,8 @@ struct iwl_mvm { | |||
553 | 562 | ||
554 | struct mvm_statistics_rx rx_stats; | 563 | struct mvm_statistics_rx rx_stats; |
555 | 564 | ||
556 | unsigned long transport_queue_stop; | ||
557 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; | 565 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; |
558 | atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; | 566 | atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES]; |
559 | 567 | ||
560 | const char *nvm_file_name; | 568 | const char *nvm_file_name; |
561 | struct iwl_nvm_data *nvm_data; | 569 | struct iwl_nvm_data *nvm_data; |
@@ -694,6 +702,12 @@ struct iwl_mvm { | |||
694 | /* Thermal Throttling and CTkill */ | 702 | /* Thermal Throttling and CTkill */ |
695 | struct iwl_mvm_tt_mgmt thermal_throttle; | 703 | struct iwl_mvm_tt_mgmt thermal_throttle; |
696 | s32 temperature; /* Celsius */ | 704 | s32 temperature; /* Celsius */ |
705 | /* | ||
706 | * Debug option to set the NIC temperature. This option makes the | ||
707 | * driver think this is the actual NIC temperature, and ignore the | ||
708 | * real temperature that is received from the fw | ||
709 | */ | ||
710 | bool temperature_test; /* Debug test temperature is enabled */ | ||
697 | 711 | ||
698 | #ifdef CONFIG_NL80211_TESTMODE | 712 | #ifdef CONFIG_NL80211_TESTMODE |
699 | u32 noa_duration; | 713 | u32 noa_duration; |
@@ -706,7 +720,7 @@ struct iwl_mvm { | |||
706 | u8 last_agg_queue; | 720 | u8 last_agg_queue; |
707 | 721 | ||
708 | /* Indicate if device power save is allowed */ | 722 | /* Indicate if device power save is allowed */ |
709 | bool ps_disabled; | 723 | u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */ |
710 | 724 | ||
711 | struct ieee80211_vif __rcu *csa_vif; | 725 | struct ieee80211_vif __rcu *csa_vif; |
712 | struct ieee80211_vif __rcu *csa_tx_blocked_vif; | 726 | struct ieee80211_vif __rcu *csa_tx_blocked_vif; |
@@ -714,6 +728,8 @@ struct iwl_mvm { | |||
714 | 728 | ||
715 | /* system time of last beacon (for AP/GO interface) */ | 729 | /* system time of last beacon (for AP/GO interface) */ |
716 | u32 ap_last_beacon_gp2; | 730 | u32 ap_last_beacon_gp2; |
731 | |||
732 | u8 low_latency_agg_frame_limit; | ||
717 | }; | 733 | }; |
718 | 734 | ||
719 | /* Extract MVM priv from op_mode and _hw */ | 735 | /* Extract MVM priv from op_mode and _hw */ |
@@ -878,7 +894,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | |||
878 | void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 894 | void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
879 | int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 895 | int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
880 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 896 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
881 | bool force_assoc_off); | 897 | bool force_assoc_off, const u8 *bssid_override); |
882 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 898 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
883 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | 899 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, |
884 | struct ieee80211_vif *vif); | 900 | struct ieee80211_vif *vif); |
@@ -968,6 +984,7 @@ int rs_pretty_print_rate(char *buf, const u32 rate); | |||
968 | /* power management */ | 984 | /* power management */ |
969 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm); | 985 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm); |
970 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm); | 986 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm); |
987 | int iwl_mvm_power_update_ps(struct iwl_mvm *mvm); | ||
971 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 988 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
972 | char *buf, int bufsz); | 989 | char *buf, int bufsz); |
973 | 990 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index cfdd314fdd5d..4fafd4bd89f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/offloading.c b/drivers/net/wireless/iwlwifi/mvm/offloading.c index 9bfb95e89cfb..adcbf4c8edd8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/offloading.c +++ b/drivers/net/wireless/iwlwifi/mvm/offloading.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 610dbcb0dc27..87f278cc9b2c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -415,6 +417,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
415 | mvm->first_agg_queue = 12; | 417 | mvm->first_agg_queue = 12; |
416 | } | 418 | } |
417 | mvm->sf_state = SF_UNINIT; | 419 | mvm->sf_state = SF_UNINIT; |
420 | mvm->low_latency_agg_frame_limit = 1; | ||
418 | 421 | ||
419 | mutex_init(&mvm->mutex); | 422 | mutex_init(&mvm->mutex); |
420 | mutex_init(&mvm->d0i3_suspend_mutex); | 423 | mutex_init(&mvm->d0i3_suspend_mutex); |
@@ -456,7 +459,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
456 | trans_cfg.command_names = iwl_mvm_cmd_strings; | 459 | trans_cfg.command_names = iwl_mvm_cmd_strings; |
457 | 460 | ||
458 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; | 461 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; |
459 | trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO; | 462 | trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; |
460 | 463 | ||
461 | snprintf(mvm->hw->wiphy->fw_version, | 464 | snprintf(mvm->hw->wiphy->fw_version, |
462 | sizeof(mvm->hw->wiphy->fw_version), | 465 | sizeof(mvm->hw->wiphy->fw_version), |
@@ -494,7 +497,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
494 | goto out_free; | 497 | goto out_free; |
495 | 498 | ||
496 | /* | 499 | /* |
497 | * Even if nvm exists in the nvm_file driver should read agin the nvm | 500 | * Even if nvm exists in the nvm_file driver should read again the nvm |
498 | * from the nic because there might be entries that exist in the OTP | 501 | * from the nic because there might be entries that exist in the OTP |
499 | * and not in the file. | 502 | * and not in the file. |
500 | * for nics with no_power_up_nic_in_init: rely completley on nvm_file | 503 | * for nics with no_power_up_nic_in_init: rely completley on nvm_file |
@@ -700,14 +703,13 @@ static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
700 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) | 703 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) |
701 | return; | 704 | return; |
702 | 705 | ||
703 | if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) { | 706 | if (atomic_inc_return(&mvm->mac80211_queue_stop_count[mq]) > 1) { |
704 | IWL_DEBUG_TX_QUEUES(mvm, | 707 | IWL_DEBUG_TX_QUEUES(mvm, |
705 | "queue %d (mac80211 %d) already stopped\n", | 708 | "queue %d (mac80211 %d) already stopped\n", |
706 | queue, mq); | 709 | queue, mq); |
707 | return; | 710 | return; |
708 | } | 711 | } |
709 | 712 | ||
710 | set_bit(mq, &mvm->transport_queue_stop); | ||
711 | ieee80211_stop_queue(mvm->hw, mq); | 713 | ieee80211_stop_queue(mvm->hw, mq); |
712 | } | 714 | } |
713 | 715 | ||
@@ -719,15 +721,13 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
719 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) | 721 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) |
720 | return; | 722 | return; |
721 | 723 | ||
722 | if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) { | 724 | if (atomic_dec_return(&mvm->mac80211_queue_stop_count[mq]) > 0) { |
723 | IWL_DEBUG_TX_QUEUES(mvm, | 725 | IWL_DEBUG_TX_QUEUES(mvm, |
724 | "queue %d (mac80211 %d) already awake\n", | 726 | "queue %d (mac80211 %d) still stopped\n", |
725 | queue, mq); | 727 | queue, mq); |
726 | return; | 728 | return; |
727 | } | 729 | } |
728 | 730 | ||
729 | clear_bit(mq, &mvm->transport_queue_stop); | ||
730 | |||
731 | ieee80211_wake_queue(mvm->hw, mq); | 731 | ieee80211_wake_queue(mvm->hw, mq); |
732 | } | 732 | } |
733 | 733 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 6cc243f7cf60..12283b55ee84 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 2b2d10800a55..e7a6626fe839 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -198,8 +200,15 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, | |||
198 | } | 200 | } |
199 | } | 201 | } |
200 | 202 | ||
201 | if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) | 203 | if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { |
204 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
205 | /* set advanced pm flag with no uapsd ACs to enable ps-poll */ | ||
206 | if (mvmvif->dbgfs_pm.use_ps_poll) | ||
207 | cmd->flags |= | ||
208 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | ||
209 | #endif | ||
202 | return; | 210 | return; |
211 | } | ||
203 | 212 | ||
204 | cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); | 213 | cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); |
205 | 214 | ||
@@ -497,13 +506,31 @@ struct iwl_power_vifs { | |||
497 | bool p2p_tdls; | 506 | bool p2p_tdls; |
498 | }; | 507 | }; |
499 | 508 | ||
500 | static void iwl_mvm_power_iterator(void *_data, u8 *mac, | 509 | static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, |
501 | struct ieee80211_vif *vif) | 510 | struct ieee80211_vif *vif) |
502 | { | 511 | { |
503 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 512 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
504 | struct iwl_power_vifs *power_iterator = _data; | ||
505 | 513 | ||
506 | mvmvif->pm_enabled = false; | 514 | mvmvif->pm_enabled = false; |
515 | } | ||
516 | |||
517 | static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac, | ||
518 | struct ieee80211_vif *vif) | ||
519 | { | ||
520 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
521 | bool *disable_ps = _data; | ||
522 | |||
523 | if (mvmvif->phy_ctxt) | ||
524 | if (mvmvif->phy_ctxt->id < MAX_PHYS) | ||
525 | *disable_ps |= mvmvif->ps_disabled; | ||
526 | } | ||
527 | |||
528 | static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac, | ||
529 | struct ieee80211_vif *vif) | ||
530 | { | ||
531 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
532 | struct iwl_power_vifs *power_iterator = _data; | ||
533 | |||
507 | switch (ieee80211_vif_type_p2p(vif)) { | 534 | switch (ieee80211_vif_type_p2p(vif)) { |
508 | case NL80211_IFTYPE_P2P_DEVICE: | 535 | case NL80211_IFTYPE_P2P_DEVICE: |
509 | break; | 536 | break; |
@@ -559,9 +586,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac, | |||
559 | } | 586 | } |
560 | } | 587 | } |
561 | 588 | ||
562 | static void | 589 | static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm, |
563 | iwl_mvm_power_set_pm(struct iwl_mvm *mvm, | 590 | struct iwl_power_vifs *vifs) |
564 | struct iwl_power_vifs *vifs) | ||
565 | { | 591 | { |
566 | struct iwl_mvm_vif *bss_mvmvif = NULL; | 592 | struct iwl_mvm_vif *bss_mvmvif = NULL; |
567 | struct iwl_mvm_vif *p2p_mvmvif = NULL; | 593 | struct iwl_mvm_vif *p2p_mvmvif = NULL; |
@@ -571,10 +597,11 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm, | |||
571 | 597 | ||
572 | lockdep_assert_held(&mvm->mutex); | 598 | lockdep_assert_held(&mvm->mutex); |
573 | 599 | ||
574 | /* get vifs info + set pm_enable to false */ | 600 | /* set pm_enable to false */ |
575 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | 601 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, |
576 | IEEE80211_IFACE_ITER_NORMAL, | 602 | IEEE80211_IFACE_ITER_NORMAL, |
577 | iwl_mvm_power_iterator, vifs); | 603 | iwl_mvm_power_disable_pm_iterator, |
604 | NULL); | ||
578 | 605 | ||
579 | if (vifs->bss_vif) | 606 | if (vifs->bss_vif) |
580 | bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif); | 607 | bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif); |
@@ -817,32 +844,92 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, | |||
817 | return ret; | 844 | return ret; |
818 | } | 845 | } |
819 | 846 | ||
820 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | 847 | static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm) |
848 | { | ||
849 | bool disable_ps; | ||
850 | int ret; | ||
851 | |||
852 | /* disable PS if CAM */ | ||
853 | disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM); | ||
854 | /* ...or if any of the vifs require PS to be off */ | ||
855 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
856 | IEEE80211_IFACE_ITER_NORMAL, | ||
857 | iwl_mvm_power_ps_disabled_iterator, | ||
858 | &disable_ps); | ||
859 | |||
860 | /* update device power state if it has changed */ | ||
861 | if (mvm->ps_disabled != disable_ps) { | ||
862 | bool old_ps_disabled = mvm->ps_disabled; | ||
863 | |||
864 | mvm->ps_disabled = disable_ps; | ||
865 | ret = iwl_mvm_power_update_device(mvm); | ||
866 | if (ret) { | ||
867 | mvm->ps_disabled = old_ps_disabled; | ||
868 | return ret; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm, | ||
876 | struct iwl_power_vifs *vifs) | ||
821 | { | 877 | { |
822 | struct iwl_mvm_vif *mvmvif; | 878 | struct iwl_mvm_vif *mvmvif; |
879 | bool ba_enable; | ||
880 | |||
881 | if (!vifs->bf_vif) | ||
882 | return 0; | ||
883 | |||
884 | mvmvif = iwl_mvm_vif_from_mac80211(vifs->bf_vif); | ||
885 | |||
886 | ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled || | ||
887 | !vifs->bf_vif->bss_conf.ps || | ||
888 | iwl_mvm_vif_low_latency(mvmvif)); | ||
889 | |||
890 | return iwl_mvm_update_beacon_abort(mvm, vifs->bf_vif, ba_enable); | ||
891 | } | ||
892 | |||
893 | int iwl_mvm_power_update_ps(struct iwl_mvm *mvm) | ||
894 | { | ||
895 | struct iwl_power_vifs vifs = { | ||
896 | .mvm = mvm, | ||
897 | }; | ||
898 | int ret; | ||
899 | |||
900 | lockdep_assert_held(&mvm->mutex); | ||
901 | |||
902 | /* get vifs info */ | ||
903 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
904 | IEEE80211_IFACE_ITER_NORMAL, | ||
905 | iwl_mvm_power_get_vifs_iterator, &vifs); | ||
906 | |||
907 | ret = iwl_mvm_power_set_ps(mvm); | ||
908 | if (ret) | ||
909 | return ret; | ||
910 | |||
911 | return iwl_mvm_power_set_ba(mvm, &vifs); | ||
912 | } | ||
913 | |||
914 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | ||
915 | { | ||
823 | struct iwl_power_vifs vifs = { | 916 | struct iwl_power_vifs vifs = { |
824 | .mvm = mvm, | 917 | .mvm = mvm, |
825 | }; | 918 | }; |
826 | bool ba_enable; | ||
827 | int ret; | 919 | int ret; |
828 | 920 | ||
829 | lockdep_assert_held(&mvm->mutex); | 921 | lockdep_assert_held(&mvm->mutex); |
830 | 922 | ||
923 | /* get vifs info */ | ||
924 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
925 | IEEE80211_IFACE_ITER_NORMAL, | ||
926 | iwl_mvm_power_get_vifs_iterator, &vifs); | ||
927 | |||
831 | iwl_mvm_power_set_pm(mvm, &vifs); | 928 | iwl_mvm_power_set_pm(mvm, &vifs); |
832 | 929 | ||
833 | /* disable PS if CAM */ | 930 | ret = iwl_mvm_power_set_ps(mvm); |
834 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) { | 931 | if (ret) |
835 | mvm->ps_disabled = true; | 932 | return ret; |
836 | } else { | ||
837 | /* don't update device power state unless we add / remove monitor */ | ||
838 | if (vifs.monitor_vif) { | ||
839 | if (vifs.monitor_active) | ||
840 | mvm->ps_disabled = true; | ||
841 | ret = iwl_mvm_power_update_device(mvm); | ||
842 | if (ret) | ||
843 | return ret; | ||
844 | } | ||
845 | } | ||
846 | 933 | ||
847 | if (vifs.bss_vif) { | 934 | if (vifs.bss_vif) { |
848 | ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif); | 935 | ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif); |
@@ -856,16 +943,7 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | |||
856 | return ret; | 943 | return ret; |
857 | } | 944 | } |
858 | 945 | ||
859 | if (!vifs.bf_vif) | 946 | return iwl_mvm_power_set_ba(mvm, &vifs); |
860 | return 0; | ||
861 | |||
862 | mvmvif = iwl_mvm_vif_from_mac80211(vifs.bf_vif); | ||
863 | |||
864 | ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled || | ||
865 | !vifs.bf_vif->bss_conf.ps || | ||
866 | iwl_mvm_vif_low_latency(mvmvif)); | ||
867 | |||
868 | return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable); | ||
869 | } | 947 | } |
870 | 948 | ||
871 | int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, | 949 | int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 4e20b3ce2b6a..5fd502db03d1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -161,6 +163,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, | |||
161 | quota *= (beacon_int - mvm->noa_duration); | 163 | quota *= (beacon_int - mvm->noa_duration); |
162 | quota /= beacon_int; | 164 | quota /= beacon_int; |
163 | 165 | ||
166 | IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n", | ||
167 | le32_to_cpu(cmd->quotas[i].quota), quota); | ||
168 | |||
164 | cmd->quotas[i].quota = cpu_to_le32(quota); | 169 | cmd->quotas[i].quota = cpu_to_le32(quota); |
165 | } | 170 | } |
166 | #endif | 171 | #endif |
@@ -222,6 +227,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
222 | quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; | 227 | quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; |
223 | quota_rem = QUOTA_100 - n_non_lowlat * quota - | 228 | quota_rem = QUOTA_100 - n_non_lowlat * quota - |
224 | QUOTA_LOWLAT_MIN; | 229 | QUOTA_LOWLAT_MIN; |
230 | IWL_DEBUG_QUOTA(mvm, | ||
231 | "quota: low-latency binding active, remaining quota per other binding: %d\n", | ||
232 | quota); | ||
225 | } else if (num_active_macs) { | 233 | } else if (num_active_macs) { |
226 | /* | 234 | /* |
227 | * There are 0 or more than 1 low latency bindings, or all the | 235 | * There are 0 or more than 1 low latency bindings, or all the |
@@ -230,6 +238,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
230 | */ | 238 | */ |
231 | quota = QUOTA_100 / num_active_macs; | 239 | quota = QUOTA_100 / num_active_macs; |
232 | quota_rem = QUOTA_100 % num_active_macs; | 240 | quota_rem = QUOTA_100 % num_active_macs; |
241 | IWL_DEBUG_QUOTA(mvm, | ||
242 | "quota: splitting evenly per binding: %d\n", | ||
243 | quota); | ||
233 | } else { | 244 | } else { |
234 | /* values don't really matter - won't be used */ | 245 | /* values don't really matter - won't be used */ |
235 | quota = 0; | 246 | quota = 0; |
@@ -271,6 +282,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
271 | for (i = 0; i < MAX_BINDINGS; i++) { | 282 | for (i = 0; i < MAX_BINDINGS; i++) { |
272 | if (le32_to_cpu(cmd.quotas[i].quota) != 0) { | 283 | if (le32_to_cpu(cmd.quotas[i].quota) != 0) { |
273 | le32_add_cpu(&cmd.quotas[i].quota, quota_rem); | 284 | le32_add_cpu(&cmd.quotas[i].quota, quota_rem); |
285 | IWL_DEBUG_QUOTA(mvm, | ||
286 | "quota: giving remainder of %d to binding %d\n", | ||
287 | quota_rem, i); | ||
274 | break; | 288 | break; |
275 | } | 289 | } |
276 | } | 290 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index c70e959bf0e3..17002cf437db 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 7 | * under the terms of version 2 of the GNU General Public License as |
@@ -2678,6 +2679,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, | |||
2678 | int i; | 2679 | int i; |
2679 | int num_rates = ARRAY_SIZE(lq_cmd->rs_table); | 2680 | int num_rates = ARRAY_SIZE(lq_cmd->rs_table); |
2680 | __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); | 2681 | __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); |
2682 | u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; | ||
2681 | 2683 | ||
2682 | for (i = 0; i < num_rates; i++) | 2684 | for (i = 0; i < num_rates; i++) |
2683 | lq_cmd->rs_table[i] = ucode_rate_le32; | 2685 | lq_cmd->rs_table[i] = ucode_rate_le32; |
@@ -2688,6 +2690,13 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, | |||
2688 | lq_cmd->mimo_delim = num_rates - 1; | 2690 | lq_cmd->mimo_delim = num_rates - 1; |
2689 | else | 2691 | else |
2690 | lq_cmd->mimo_delim = 0; | 2692 | lq_cmd->mimo_delim = 0; |
2693 | |||
2694 | lq_cmd->reduced_tpc = 0; | ||
2695 | |||
2696 | if (num_of_ant(ant) == 1) | ||
2697 | lq_cmd->single_stream_ant_msk = ant; | ||
2698 | |||
2699 | lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
2691 | } | 2700 | } |
2692 | #endif /* CONFIG_MAC80211_DEBUGFS */ | 2701 | #endif /* CONFIG_MAC80211_DEBUGFS */ |
2693 | 2702 | ||
@@ -2811,31 +2820,55 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, | |||
2811 | const struct rs_rate *initial_rate) | 2820 | const struct rs_rate *initial_rate) |
2812 | { | 2821 | { |
2813 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; | 2822 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; |
2814 | u8 ant = initial_rate->ant; | 2823 | struct iwl_mvm_sta *mvmsta; |
2824 | struct iwl_mvm_vif *mvmvif; | ||
2825 | |||
2826 | lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | ||
2827 | lq_cmd->agg_time_limit = | ||
2828 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | ||
2815 | 2829 | ||
2816 | #ifdef CONFIG_MAC80211_DEBUGFS | 2830 | #ifdef CONFIG_MAC80211_DEBUGFS |
2817 | if (lq_sta->pers.dbg_fixed_rate) { | 2831 | if (lq_sta->pers.dbg_fixed_rate) { |
2818 | rs_build_rates_table_from_fixed(mvm, lq_cmd, | 2832 | rs_build_rates_table_from_fixed(mvm, lq_cmd, |
2819 | lq_sta->band, | 2833 | lq_sta->band, |
2820 | lq_sta->pers.dbg_fixed_rate); | 2834 | lq_sta->pers.dbg_fixed_rate); |
2821 | lq_cmd->reduced_tpc = 0; | 2835 | return; |
2822 | ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >> | 2836 | } |
2823 | RATE_MCS_ANT_POS; | ||
2824 | } else | ||
2825 | #endif | 2837 | #endif |
2826 | rs_build_rates_table(mvm, lq_sta, initial_rate); | 2838 | if (WARN_ON_ONCE(!sta || !initial_rate)) |
2839 | return; | ||
2827 | 2840 | ||
2828 | if (num_of_ant(ant) == 1) | 2841 | rs_build_rates_table(mvm, lq_sta, initial_rate); |
2829 | lq_cmd->single_stream_ant_msk = ant; | ||
2830 | 2842 | ||
2831 | lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | 2843 | if (num_of_ant(initial_rate->ant) == 1) |
2832 | lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | 2844 | lq_cmd->single_stream_ant_msk = initial_rate->ant; |
2833 | 2845 | ||
2834 | lq_cmd->agg_time_limit = | 2846 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
2835 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | 2847 | mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); |
2848 | |||
2849 | if (num_of_ant(initial_rate->ant) == 1) | ||
2850 | lq_cmd->single_stream_ant_msk = initial_rate->ant; | ||
2851 | |||
2852 | lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; | ||
2836 | 2853 | ||
2837 | if (sta) | 2854 | /* |
2838 | lq_cmd->agg_time_limit = | 2855 | * In case of low latency, tell the firwmare to leave a frame in the |
2856 | * Tx Fifo so that it can start a transaction in the same TxOP. This | ||
2857 | * basically allows the firmware to send bursts. | ||
2858 | */ | ||
2859 | if (iwl_mvm_vif_low_latency(mvmvif)) { | ||
2860 | lq_cmd->agg_frame_cnt_limit--; | ||
2861 | |||
2862 | if (mvm->low_latency_agg_frame_limit) | ||
2863 | lq_cmd->agg_frame_cnt_limit = | ||
2864 | min(lq_cmd->agg_frame_cnt_limit, | ||
2865 | mvm->low_latency_agg_frame_limit); | ||
2866 | } | ||
2867 | |||
2868 | if (mvmsta->vif->p2p) | ||
2869 | lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; | ||
2870 | |||
2871 | lq_cmd->agg_time_limit = | ||
2839 | cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); | 2872 | cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); |
2840 | } | 2873 | } |
2841 | 2874 | ||
@@ -2932,10 +2965,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm, | |||
2932 | lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); | 2965 | lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); |
2933 | 2966 | ||
2934 | if (lq_sta->pers.dbg_fixed_rate) { | 2967 | if (lq_sta->pers.dbg_fixed_rate) { |
2935 | struct rs_rate rate; | 2968 | rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL); |
2936 | rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate, | ||
2937 | lq_sta->band, &rate); | ||
2938 | rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate); | ||
2939 | iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); | 2969 | iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); |
2940 | } | 2970 | } |
2941 | } | 2971 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 4b98987fc413..48144e3ad527 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -491,10 +493,29 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, | |||
491 | .mvm = mvm, | 493 | .mvm = mvm, |
492 | }; | 494 | }; |
493 | 495 | ||
496 | /* | ||
497 | * set temperature debug enabled - ignore FW temperature updates | ||
498 | * and use the user set temperature. | ||
499 | */ | ||
500 | if (mvm->temperature_test) { | ||
501 | if (mvm->temperature < le32_to_cpu(common->temperature)) | ||
502 | IWL_DEBUG_TEMP(mvm, | ||
503 | "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n", | ||
504 | mvm->temperature, | ||
505 | le32_to_cpu(common->temperature)); | ||
506 | /* | ||
507 | * skip iwl_mvm_tt_handler since we are in | ||
508 | * temperature debug mode and we are ignoring | ||
509 | * the new temperature value | ||
510 | */ | ||
511 | goto update; | ||
512 | } | ||
513 | |||
494 | if (mvm->temperature != le32_to_cpu(common->temperature)) { | 514 | if (mvm->temperature != le32_to_cpu(common->temperature)) { |
495 | mvm->temperature = le32_to_cpu(common->temperature); | 515 | mvm->temperature = le32_to_cpu(common->temperature); |
496 | iwl_mvm_tt_handler(mvm); | 516 | iwl_mvm_tt_handler(mvm); |
497 | } | 517 | } |
518 | update: | ||
498 | iwl_mvm_update_rx_statistics(mvm, stats); | 519 | iwl_mvm_update_rx_statistics(mvm, stats); |
499 | 520 | ||
500 | ieee80211_iterate_active_interfaces(mvm->hw, | 521 | ieee80211_iterate_active_interfaces(mvm->hw, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 004b1f5d0314..bf9c63dc4a7d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -279,6 +281,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
279 | { | 281 | { |
280 | bool global_bound = false; | 282 | bool global_bound = false; |
281 | enum ieee80211_band band; | 283 | enum ieee80211_band band; |
284 | u8 frag_passive_dwell = 0; | ||
282 | 285 | ||
283 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | 286 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, |
284 | IEEE80211_IFACE_ITER_NORMAL, | 287 | IEEE80211_IFACE_ITER_NORMAL, |
@@ -288,12 +291,36 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
288 | if (!global_bound) | 291 | if (!global_bound) |
289 | goto not_bound; | 292 | goto not_bound; |
290 | 293 | ||
291 | params->suspend_time = 100; | 294 | params->suspend_time = 30; |
292 | params->max_out_time = 600; | 295 | params->max_out_time = 170; |
293 | 296 | ||
294 | if (iwl_mvm_low_latency(mvm)) { | 297 | if (iwl_mvm_low_latency(mvm)) { |
295 | params->suspend_time = 250; | 298 | if (mvm->fw->ucode_capa.api[0] & |
296 | params->max_out_time = 250; | 299 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { |
300 | params->suspend_time = 105; | ||
301 | params->max_out_time = 70; | ||
302 | frag_passive_dwell = 20; | ||
303 | } else { | ||
304 | params->suspend_time = 120; | ||
305 | params->max_out_time = 120; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] & | ||
310 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) { | ||
311 | /* | ||
312 | * P2P device scan should not be fragmented to avoid negative | ||
313 | * impact on P2P device discovery. Configure max_out_time to be | ||
314 | * equal to dwell time on passive channel. Take a longest | ||
315 | * possible value, one that corresponds to 2GHz band | ||
316 | */ | ||
317 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | ||
318 | u32 passive_dwell = | ||
319 | iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); | ||
320 | params->max_out_time = passive_dwell; | ||
321 | } else { | ||
322 | params->passive_fragmented = true; | ||
323 | } | ||
297 | } | 324 | } |
298 | 325 | ||
299 | if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) | 326 | if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) |
@@ -302,7 +329,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
302 | not_bound: | 329 | not_bound: |
303 | 330 | ||
304 | for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { | 331 | for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { |
305 | params->dwell[band].passive = iwl_mvm_get_passive_dwell(band); | 332 | if (params->passive_fragmented) |
333 | params->dwell[band].passive = frag_passive_dwell; | ||
334 | else | ||
335 | params->dwell[band].passive = | ||
336 | iwl_mvm_get_passive_dwell(band); | ||
306 | params->dwell[band].active = iwl_mvm_get_active_dwell(band, | 337 | params->dwell[band].active = iwl_mvm_get_active_dwell(band, |
307 | n_ssids); | 338 | n_ssids); |
308 | } | 339 | } |
@@ -1100,10 +1131,11 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, | |||
1100 | struct iwl_mvm_scan_params *params) | 1131 | struct iwl_mvm_scan_params *params) |
1101 | { | 1132 | { |
1102 | memset(cmd, 0, ksize(cmd)); | 1133 | memset(cmd, 0, ksize(cmd)); |
1103 | cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active; | 1134 | cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active; |
1104 | cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive; | 1135 | cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; |
1105 | /* TODO: Use params; now fragmented isn't used. */ | 1136 | if (params->passive_fragmented) |
1106 | cmd->fragmented_dwell = 0; | 1137 | cmd->fragmented_dwell = |
1138 | params->dwell[IEEE80211_BAND_2GHZ].passive; | ||
1107 | cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); | 1139 | cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); |
1108 | cmd->max_out_time = cpu_to_le32(params->max_out_time); | 1140 | cmd->max_out_time = cpu_to_le32(params->max_out_time); |
1109 | cmd->suspend_time = cpu_to_le32(params->suspend_time); | 1141 | cmd->suspend_time = cpu_to_le32(params->suspend_time); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c index 7edfd15efc9d..d1922afe06f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/iwlwifi/mvm/sf.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 763548880399..dd9f3a4347f6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -250,10 +252,14 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, | |||
250 | if (ret) | 252 | if (ret) |
251 | return ret; | 253 | return ret; |
252 | 254 | ||
253 | /* The first station added is the AP, the others are TDLS STAs */ | 255 | if (vif->type == NL80211_IFTYPE_STATION) { |
254 | if (vif->type == NL80211_IFTYPE_STATION && | 256 | if (!sta->tdls) { |
255 | mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | 257 | WARN_ON(mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT); |
256 | mvmvif->ap_sta_id = sta_id; | 258 | mvmvif->ap_sta_id = sta_id; |
259 | } else { | ||
260 | WARN_ON(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT); | ||
261 | } | ||
262 | } | ||
257 | 263 | ||
258 | rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); | 264 | rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); |
259 | 265 | ||
@@ -458,8 +464,9 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm, | |||
458 | return ret; | 464 | return ret; |
459 | } | 465 | } |
460 | 466 | ||
461 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | 467 | static int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, |
462 | u32 qmask, enum nl80211_iftype iftype) | 468 | struct iwl_mvm_int_sta *sta, |
469 | u32 qmask, enum nl80211_iftype iftype) | ||
463 | { | 470 | { |
464 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 471 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { |
465 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); | 472 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); |
@@ -474,7 +481,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | |||
474 | return 0; | 481 | return 0; |
475 | } | 482 | } |
476 | 483 | ||
477 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta) | 484 | static void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, |
485 | struct iwl_mvm_int_sta *sta) | ||
478 | { | 486 | { |
479 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL); | 487 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL); |
480 | memset(sta, 0, sizeof(struct iwl_mvm_int_sta)); | 488 | memset(sta, 0, sizeof(struct iwl_mvm_int_sta)); |
@@ -544,6 +552,13 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) | |||
544 | return ret; | 552 | return ret; |
545 | } | 553 | } |
546 | 554 | ||
555 | void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm) | ||
556 | { | ||
557 | lockdep_assert_held(&mvm->mutex); | ||
558 | |||
559 | iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); | ||
560 | } | ||
561 | |||
547 | /* | 562 | /* |
548 | * Send the add station command for the vif's broadcast station. | 563 | * Send the add station command for the vif's broadcast station. |
549 | * Assumes that the station was already allocated. | 564 | * Assumes that the station was already allocated. |
@@ -552,10 +567,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) | |||
552 | * @vif: the interface to which the broadcast station is added | 567 | * @vif: the interface to which the broadcast station is added |
553 | * @bsta: the broadcast station to add. | 568 | * @bsta: the broadcast station to add. |
554 | */ | 569 | */ |
555 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 570 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
556 | struct iwl_mvm_int_sta *bsta) | ||
557 | { | 571 | { |
558 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 572 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
573 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; | ||
559 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 574 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
560 | const u8 *baddr = _baddr; | 575 | const u8 *baddr = _baddr; |
561 | 576 | ||
@@ -573,19 +588,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
573 | 588 | ||
574 | /* Send the FW a request to remove the station from it's internal data | 589 | /* Send the FW a request to remove the station from it's internal data |
575 | * structures, but DO NOT remove the entry from the local data structures. */ | 590 | * structures, but DO NOT remove the entry from the local data structures. */ |
576 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 591 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
577 | struct iwl_mvm_int_sta *bsta) | ||
578 | { | 592 | { |
593 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
579 | int ret; | 594 | int ret; |
580 | 595 | ||
581 | lockdep_assert_held(&mvm->mutex); | 596 | lockdep_assert_held(&mvm->mutex); |
582 | 597 | ||
583 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 598 | ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id); |
584 | if (ret) | 599 | if (ret) |
585 | IWL_WARN(mvm, "Failed sending remove station\n"); | 600 | IWL_WARN(mvm, "Failed sending remove station\n"); |
586 | return ret; | 601 | return ret; |
587 | } | 602 | } |
588 | 603 | ||
604 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
605 | { | ||
606 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
607 | u32 qmask; | ||
608 | |||
609 | lockdep_assert_held(&mvm->mutex); | ||
610 | |||
611 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | ||
612 | |||
613 | /* | ||
614 | * The firmware defines the TFD queue mask to only be relevant | ||
615 | * for *unicast* queues, so the multicast (CAB) queue shouldn't | ||
616 | * be included. | ||
617 | */ | ||
618 | if (vif->type == NL80211_IFTYPE_AP) | ||
619 | qmask &= ~BIT(vif->cab_queue); | ||
620 | |||
621 | return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask, | ||
622 | ieee80211_vif_type_p2p(vif)); | ||
623 | } | ||
624 | |||
589 | /* Allocate a new station entry for the broadcast station to the given vif, | 625 | /* Allocate a new station entry for the broadcast station to the given vif, |
590 | * and send it to the FW. | 626 | * and send it to the FW. |
591 | * Note that each P2P mac should have its own broadcast station. | 627 | * Note that each P2P mac should have its own broadcast station. |
@@ -593,45 +629,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | |||
593 | * @mvm: the mvm component | 629 | * @mvm: the mvm component |
594 | * @vif: the interface to which the broadcast station is added | 630 | * @vif: the interface to which the broadcast station is added |
595 | * @bsta: the broadcast station to add. */ | 631 | * @bsta: the broadcast station to add. */ |
596 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 632 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
597 | struct iwl_mvm_int_sta *bsta) | ||
598 | { | 633 | { |
599 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 634 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
600 | static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 635 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; |
601 | u32 qmask; | ||
602 | int ret; | 636 | int ret; |
603 | 637 | ||
604 | lockdep_assert_held(&mvm->mutex); | 638 | lockdep_assert_held(&mvm->mutex); |
605 | 639 | ||
606 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 640 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
607 | ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask, | ||
608 | ieee80211_vif_type_p2p(vif)); | ||
609 | if (ret) | 641 | if (ret) |
610 | return ret; | 642 | return ret; |
611 | 643 | ||
612 | ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr, | 644 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
613 | mvmvif->id, mvmvif->color); | ||
614 | 645 | ||
615 | if (ret) | 646 | if (ret) |
616 | iwl_mvm_dealloc_int_sta(mvm, bsta); | 647 | iwl_mvm_dealloc_int_sta(mvm, bsta); |
648 | |||
617 | return ret; | 649 | return ret; |
618 | } | 650 | } |
619 | 651 | ||
652 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
653 | { | ||
654 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
655 | |||
656 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | ||
657 | } | ||
658 | |||
620 | /* | 659 | /* |
621 | * Send the FW a request to remove the station from it's internal data | 660 | * Send the FW a request to remove the station from it's internal data |
622 | * structures, and in addition remove it from the local data structure. | 661 | * structures, and in addition remove it from the local data structure. |
623 | */ | 662 | */ |
624 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) | 663 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
625 | { | 664 | { |
626 | int ret; | 665 | int ret; |
627 | 666 | ||
628 | lockdep_assert_held(&mvm->mutex); | 667 | lockdep_assert_held(&mvm->mutex); |
629 | 668 | ||
630 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 669 | ret = iwl_mvm_send_rm_bcast_sta(mvm, vif); |
631 | if (ret) | 670 | |
632 | return ret; | 671 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
633 | 672 | ||
634 | iwl_mvm_dealloc_int_sta(mvm, bsta); | ||
635 | return ret; | 673 | return ret; |
636 | } | 674 | } |
637 | 675 | ||
@@ -910,7 +948,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
910 | } | 948 | } |
911 | 949 | ||
912 | tid_data->ssn = 0xffff; | 950 | tid_data->ssn = 0xffff; |
913 | iwl_trans_txq_disable(mvm->trans, txq_id); | 951 | iwl_trans_txq_disable(mvm->trans, txq_id, true); |
914 | /* fall through */ | 952 | /* fall through */ |
915 | case IWL_AGG_STARTING: | 953 | case IWL_AGG_STARTING: |
916 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 954 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
@@ -965,7 +1003,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
965 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | 1003 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) |
966 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | 1004 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); |
967 | 1005 | ||
968 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | 1006 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); |
969 | } | 1007 | } |
970 | 1008 | ||
971 | mvm->queue_to_mac80211[tid_data->txq_id] = | 1009 | mvm->queue_to_mac80211[tid_data->txq_id] = |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 3b1c8bd6cb54..aeb3a7f80ceb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -387,17 +389,15 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
387 | struct ieee80211_sta *sta, u16 tid); | 389 | struct ieee80211_sta *sta, u16 tid); |
388 | 390 | ||
389 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); | 391 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); |
390 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | 392 | void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm); |
391 | u32 qmask, enum nl80211_iftype iftype); | 393 | |
392 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, | 394 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
393 | struct iwl_mvm_int_sta *sta); | 395 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
394 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 396 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
395 | struct iwl_mvm_int_sta *bsta); | 397 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
396 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 398 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
397 | struct iwl_mvm_int_sta *bsta); | 399 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
398 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 400 | |
399 | struct iwl_mvm_int_sta *bsta); | ||
400 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta); | ||
401 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); | 401 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); |
402 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, | 402 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, |
403 | struct ieee80211_sta *sta); | 403 | struct ieee80211_sta *sta); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h index 0241665925f7..79ab6beb6b26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/testmode.h +++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 33e5041f1efc..447d3b1003df 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -348,6 +350,38 @@ unlock: | |||
348 | return 0; | 350 | return 0; |
349 | } | 351 | } |
350 | 352 | ||
353 | static bool iwl_mvm_te_notif(struct iwl_notif_wait_data *notif_wait, | ||
354 | struct iwl_rx_packet *pkt, void *data) | ||
355 | { | ||
356 | struct iwl_mvm *mvm = | ||
357 | container_of(notif_wait, struct iwl_mvm, notif_wait); | ||
358 | struct iwl_mvm_time_event_data *te_data = data; | ||
359 | struct iwl_time_event_notif *resp; | ||
360 | int resp_len = iwl_rx_packet_payload_len(pkt); | ||
361 | |||
362 | if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_NOTIFICATION)) | ||
363 | return true; | ||
364 | |||
365 | if (WARN_ON_ONCE(resp_len != sizeof(*resp))) { | ||
366 | IWL_ERR(mvm, "Invalid TIME_EVENT_NOTIFICATION response\n"); | ||
367 | return true; | ||
368 | } | ||
369 | |||
370 | resp = (void *)pkt->data; | ||
371 | |||
372 | /* te_data->uid is already set in the TIME_EVENT_CMD response */ | ||
373 | if (le32_to_cpu(resp->unique_id) != te_data->uid) | ||
374 | return false; | ||
375 | |||
376 | IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response - UID = 0x%x\n", | ||
377 | te_data->uid); | ||
378 | if (!resp->status) | ||
379 | IWL_ERR(mvm, | ||
380 | "TIME_EVENT_NOTIFICATION received but not executed\n"); | ||
381 | |||
382 | return true; | ||
383 | } | ||
384 | |||
351 | static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, | 385 | static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, |
352 | struct iwl_rx_packet *pkt, void *data) | 386 | struct iwl_rx_packet *pkt, void *data) |
353 | { | 387 | { |
@@ -441,10 +475,12 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm, | |||
441 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, | 475 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, |
442 | struct ieee80211_vif *vif, | 476 | struct ieee80211_vif *vif, |
443 | u32 duration, u32 min_duration, | 477 | u32 duration, u32 min_duration, |
444 | u32 max_delay) | 478 | u32 max_delay, bool wait_for_notif) |
445 | { | 479 | { |
446 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 480 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
447 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; | 481 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; |
482 | const u8 te_notif_response[] = { TIME_EVENT_NOTIFICATION }; | ||
483 | struct iwl_notification_wait wait_te_notif; | ||
448 | struct iwl_time_event_cmd time_cmd = {}; | 484 | struct iwl_time_event_cmd time_cmd = {}; |
449 | 485 | ||
450 | lockdep_assert_held(&mvm->mutex); | 486 | lockdep_assert_held(&mvm->mutex); |
@@ -489,7 +525,28 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
489 | TE_V2_NOTIF_HOST_EVENT_END | | 525 | TE_V2_NOTIF_HOST_EVENT_END | |
490 | T2_V2_START_IMMEDIATELY); | 526 | T2_V2_START_IMMEDIATELY); |
491 | 527 | ||
492 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 528 | if (!wait_for_notif) { |
529 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | ||
530 | return; | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * Create notification_wait for the TIME_EVENT_NOTIFICATION to use | ||
535 | * right after we send the time event | ||
536 | */ | ||
537 | iwl_init_notification_wait(&mvm->notif_wait, &wait_te_notif, | ||
538 | te_notif_response, | ||
539 | ARRAY_SIZE(te_notif_response), | ||
540 | iwl_mvm_te_notif, te_data); | ||
541 | |||
542 | /* If TE was sent OK - wait for the notification that started */ | ||
543 | if (iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd)) { | ||
544 | IWL_ERR(mvm, "Failed to add TE to protect session\n"); | ||
545 | iwl_remove_notification(&mvm->notif_wait, &wait_te_notif); | ||
546 | } else if (iwl_wait_notification(&mvm->notif_wait, &wait_te_notif, | ||
547 | TU_TO_JIFFIES(max_delay))) { | ||
548 | IWL_ERR(mvm, "Failed to protect session until TE\n"); | ||
549 | } | ||
493 | } | 550 | } |
494 | 551 | ||
495 | /* | 552 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 2f48a90d4ad3..bee3b2446b35 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -124,10 +126,12 @@ | |||
124 | * @min_duration: will start a new session if the current session will end | 126 | * @min_duration: will start a new session if the current session will end |
125 | * in less than min_duration. | 127 | * in less than min_duration. |
126 | * @max_delay: maximum delay before starting the time event (in TU) | 128 | * @max_delay: maximum delay before starting the time event (in TU) |
129 | * @wait_for_notif: true if it is required that a time event notification be | ||
130 | * waited for (that the time event has been scheduled before returning) | ||
127 | * | 131 | * |
128 | * This function can be used to start a session protection which means that the | 132 | * This function can be used to start a session protection which means that the |
129 | * fw will stay on the channel for %duration_ms milliseconds. This function | 133 | * fw will stay on the channel for %duration_ms milliseconds. This function |
130 | * will block (sleep) until the session starts. This function can also be used | 134 | * can block (sleep) until the session starts. This function can also be used |
131 | * to extend a currently running session. | 135 | * to extend a currently running session. |
132 | * This function is meant to be used for BSS association for example, where we | 136 | * This function is meant to be used for BSS association for example, where we |
133 | * want to make sure that the fw stays on the channel during the association. | 137 | * want to make sure that the fw stays on the channel during the association. |
@@ -135,7 +139,7 @@ | |||
135 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, | 139 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, |
136 | struct ieee80211_vif *vif, | 140 | struct ieee80211_vif *vif, |
137 | u32 duration, u32 min_duration, | 141 | u32 duration, u32 min_duration, |
138 | u32 max_delay); | 142 | u32 max_delay, bool wait_for_notif); |
139 | 143 | ||
140 | /** | 144 | /** |
141 | * iwl_mvm_stop_session_protection - cancel the session protection. | 145 | * iwl_mvm_stop_session_protection - cancel the session protection. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index 0464599c111e..c3e1fe4282f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -314,14 +316,26 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) | |||
314 | { | 316 | { |
315 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; | 317 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; |
316 | 318 | ||
319 | if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | ||
320 | return; | ||
321 | |||
317 | IWL_ERR(mvm, "Enter CT Kill\n"); | 322 | IWL_ERR(mvm, "Enter CT Kill\n"); |
318 | iwl_mvm_set_hw_ctkill_state(mvm, true); | 323 | iwl_mvm_set_hw_ctkill_state(mvm, true); |
319 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | 324 | |
320 | round_jiffies_relative(duration * HZ)); | 325 | /* Don't schedule an exit work if we're in test mode, since |
326 | * the temperature will not change unless we manually set it | ||
327 | * again (or disable testing). | ||
328 | */ | ||
329 | if (!mvm->temperature_test) | ||
330 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | ||
331 | round_jiffies_relative(duration * HZ)); | ||
321 | } | 332 | } |
322 | 333 | ||
323 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) | 334 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) |
324 | { | 335 | { |
336 | if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | ||
337 | return; | ||
338 | |||
325 | IWL_ERR(mvm, "Exit CT Kill\n"); | 339 | IWL_ERR(mvm, "Exit CT Kill\n"); |
326 | iwl_mvm_set_hw_ctkill_state(mvm, false); | 340 | iwl_mvm_set_hw_ctkill_state(mvm, false); |
327 | } | 341 | } |
@@ -444,6 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
444 | return; | 458 | return; |
445 | } | 459 | } |
446 | 460 | ||
461 | if (params->support_ct_kill && | ||
462 | temperature <= tt->params->ct_kill_exit) { | ||
463 | iwl_mvm_exit_ctkill(mvm); | ||
464 | return; | ||
465 | } | ||
466 | |||
447 | if (params->support_dynamic_smps) { | 467 | if (params->support_dynamic_smps) { |
448 | if (!tt->dynamic_smps && | 468 | if (!tt->dynamic_smps && |
449 | temperature >= params->dynamic_smps_entry) { | 469 | temperature >= params->dynamic_smps_entry) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index dbc870713882..963edb8656ad 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -482,7 +484,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, | |||
482 | IWL_DEBUG_TX_QUEUES(mvm, | 484 | IWL_DEBUG_TX_QUEUES(mvm, |
483 | "Can continue DELBA flow ssn = next_recl = %d\n", | 485 | "Can continue DELBA flow ssn = next_recl = %d\n", |
484 | tid_data->next_reclaimed); | 486 | tid_data->next_reclaimed); |
485 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | 487 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); |
486 | tid_data->state = IWL_AGG_OFF; | 488 | tid_data->state = IWL_AGG_OFF; |
487 | /* | 489 | /* |
488 | * we can't hold the mutex - but since we are after a sequence | 490 | * we can't hold the mutex - but since we are after a sequence |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index ac249da8a22b..1958f298ac8b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -387,15 +389,19 @@ struct iwl_error_event_table { | |||
387 | struct iwl_umac_error_event_table { | 389 | struct iwl_umac_error_event_table { |
388 | u32 valid; /* (nonzero) valid, (0) log is empty */ | 390 | u32 valid; /* (nonzero) valid, (0) log is empty */ |
389 | u32 error_id; /* type of error */ | 391 | u32 error_id; /* type of error */ |
390 | u32 pc; /* program counter */ | ||
391 | u32 blink1; /* branch link */ | 392 | u32 blink1; /* branch link */ |
392 | u32 blink2; /* branch link */ | 393 | u32 blink2; /* branch link */ |
393 | u32 ilink1; /* interrupt link */ | 394 | u32 ilink1; /* interrupt link */ |
394 | u32 ilink2; /* interrupt link */ | 395 | u32 ilink2; /* interrupt link */ |
395 | u32 data1; /* error-specific data */ | 396 | u32 data1; /* error-specific data */ |
396 | u32 data2; /* error-specific data */ | 397 | u32 data2; /* error-specific data */ |
397 | u32 line; /* source code line of error */ | 398 | u32 data3; /* error-specific data */ |
398 | u32 umac_ver; /* umac version */ | 399 | u32 umac_fw_ver; /* UMAC version */ |
400 | u32 umac_fw_api_ver; /* UMAC FW API ver */ | ||
401 | u32 frame_pointer; /* core register 27*/ | ||
402 | u32 stack_pointer; /* core register 28 */ | ||
403 | u32 cmd_header; /* latest host cmd sent to UMAC */ | ||
404 | u32 nic_isr_pref; /* ISR status register */ | ||
399 | } __packed; | 405 | } __packed; |
400 | 406 | ||
401 | #define ERROR_START_OFFSET (1 * sizeof(u32)) | 407 | #define ERROR_START_OFFSET (1 * sizeof(u32)) |
@@ -409,7 +415,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm) | |||
409 | 415 | ||
410 | base = mvm->umac_error_event_table; | 416 | base = mvm->umac_error_event_table; |
411 | 417 | ||
412 | if (base < 0x800000 || base >= 0x80C000) { | 418 | if (base < 0x800000) { |
413 | IWL_ERR(mvm, | 419 | IWL_ERR(mvm, |
414 | "Not valid error log pointer 0x%08X for %s uCode\n", | 420 | "Not valid error log pointer 0x%08X for %s uCode\n", |
415 | base, | 421 | base, |
@@ -428,14 +434,19 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm) | |||
428 | 434 | ||
429 | IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, | 435 | IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, |
430 | desc_lookup(table.error_id)); | 436 | desc_lookup(table.error_id)); |
431 | IWL_ERR(mvm, "0x%08X | umac uPc\n", table.pc); | ||
432 | IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); | 437 | IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); |
433 | IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); | 438 | IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); |
434 | IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1); | 439 | IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1); |
435 | IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2); | 440 | IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2); |
436 | IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); | 441 | IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); |
437 | IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); | 442 | IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); |
438 | IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_ver); | 443 | IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); |
444 | IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); | ||
445 | IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); | ||
446 | IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); | ||
447 | IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); | ||
448 | IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); | ||
449 | IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); | ||
439 | } | 450 | } |
440 | 451 | ||
441 | void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | 452 | void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index f0e722ced080..dbbbf23082a2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 78f72c34438a..a4fedc4a7448 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
@@ -364,9 +365,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans); | |||
364 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); | 365 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); |
365 | int iwl_pcie_tx_stop(struct iwl_trans *trans); | 366 | int iwl_pcie_tx_stop(struct iwl_trans *trans); |
366 | void iwl_pcie_tx_free(struct iwl_trans *trans); | 367 | void iwl_pcie_tx_free(struct iwl_trans *trans); |
367 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 368 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, |
368 | int sta_id, int tid, int frame_limit, u16 ssn); | 369 | const struct iwl_trans_txq_scd_cfg *cfg); |
369 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); | 370 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue, |
371 | bool configure_scd); | ||
370 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 372 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
371 | struct iwl_device_cmd *dev_cmd, int txq_id); | 373 | struct iwl_device_cmd *dev_cmd, int txq_id); |
372 | void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); | 374 | void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index a2698e5e062c..702f47fb16fe 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 06e04aaf61ee..3076e0e9a490 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6acccb19c4f3..a6336b4aa3a4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
@@ -34,6 +35,7 @@ | |||
34 | #include "iwl-csr.h" | 35 | #include "iwl-csr.h" |
35 | #include "iwl-prph.h" | 36 | #include "iwl-prph.h" |
36 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-scd.h" | ||
37 | #include "iwl-op-mode.h" | 39 | #include "iwl-op-mode.h" |
38 | #include "internal.h" | 40 | #include "internal.h" |
39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 41 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
@@ -644,17 +646,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
644 | memset(txq, 0, sizeof(*txq)); | 646 | memset(txq, 0, sizeof(*txq)); |
645 | } | 647 | } |
646 | 648 | ||
647 | /* | ||
648 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
649 | */ | ||
650 | static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) | ||
651 | { | ||
652 | struct iwl_trans_pcie __maybe_unused *trans_pcie = | ||
653 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
654 | |||
655 | iwl_write_prph(trans, SCD_TXFACT, mask); | ||
656 | } | ||
657 | |||
658 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | 649 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) |
659 | { | 650 | { |
660 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 651 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -692,7 +683,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
692 | trans_pcie->cmd_fifo); | 683 | trans_pcie->cmd_fifo); |
693 | 684 | ||
694 | /* Activate all Tx DMA/FIFO channels */ | 685 | /* Activate all Tx DMA/FIFO channels */ |
695 | iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); | 686 | iwl_scd_activate_fifos(trans); |
696 | 687 | ||
697 | /* Enable DMA channel */ | 688 | /* Enable DMA channel */ |
698 | for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) | 689 | for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) |
@@ -745,7 +736,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) | |||
745 | /* Turn off all Tx DMA fifos */ | 736 | /* Turn off all Tx DMA fifos */ |
746 | spin_lock(&trans_pcie->irq_lock); | 737 | spin_lock(&trans_pcie->irq_lock); |
747 | 738 | ||
748 | iwl_pcie_txq_set_sched(trans, 0); | 739 | iwl_scd_deactivate_fifos(trans); |
749 | 740 | ||
750 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 741 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
751 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 742 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
@@ -886,7 +877,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) | |||
886 | spin_lock(&trans_pcie->irq_lock); | 877 | spin_lock(&trans_pcie->irq_lock); |
887 | 878 | ||
888 | /* Turn off all Tx DMA fifos */ | 879 | /* Turn off all Tx DMA fifos */ |
889 | iwl_write_prph(trans, SCD_TXFACT, 0); | 880 | iwl_scd_deactivate_fifos(trans); |
890 | 881 | ||
891 | /* Tell NIC where to find the "keep warm" buffer */ | 882 | /* Tell NIC where to find the "keep warm" buffer */ |
892 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | 883 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, |
@@ -1072,55 +1063,52 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | |||
1072 | return 0; | 1063 | return 0; |
1073 | } | 1064 | } |
1074 | 1065 | ||
1075 | static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans, | ||
1076 | u16 txq_id) | ||
1077 | { | ||
1078 | /* Simply stop the queue, but don't change any configuration; | ||
1079 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
1080 | iwl_write_prph(trans, | ||
1081 | SCD_QUEUE_STATUS_BITS(txq_id), | ||
1082 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
1083 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
1084 | } | ||
1085 | |||
1086 | /* Receiver address (actually, Rx station's index into station table), | 1066 | /* Receiver address (actually, Rx station's index into station table), |
1087 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ | 1067 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ |
1088 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) | 1068 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) |
1089 | 1069 | ||
1090 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 1070 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, |
1091 | int sta_id, int tid, int frame_limit, u16 ssn) | 1071 | const struct iwl_trans_txq_scd_cfg *cfg) |
1092 | { | 1072 | { |
1093 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1073 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1074 | int fifo = -1; | ||
1094 | 1075 | ||
1095 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 1076 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
1096 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 1077 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
1097 | 1078 | ||
1098 | /* Stop this Tx queue before configuring it */ | 1079 | if (cfg) { |
1099 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1080 | fifo = cfg->fifo; |
1100 | 1081 | ||
1101 | /* Set this queue as a chain-building queue unless it is CMD queue */ | 1082 | /* Disable the scheduler prior configuring the cmd queue */ |
1102 | if (txq_id != trans_pcie->cmd_queue) | 1083 | if (txq_id == trans_pcie->cmd_queue) |
1103 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 1084 | iwl_scd_enable_set_active(trans, 0); |
1104 | 1085 | ||
1105 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 1086 | /* Stop this Tx queue before configuring it */ |
1106 | if (sta_id >= 0) { | 1087 | iwl_scd_txq_set_inactive(trans, txq_id); |
1107 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | ||
1108 | 1088 | ||
1109 | /* Map receiver-address / traffic-ID to this queue */ | 1089 | /* Set this queue as a chain-building queue unless it is CMD */ |
1110 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); | 1090 | if (txq_id != trans_pcie->cmd_queue) |
1091 | iwl_scd_txq_set_chain(trans, txq_id); | ||
1111 | 1092 | ||
1112 | /* enable aggregations for the queue */ | 1093 | if (cfg->aggregate) { |
1113 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1094 | u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); |
1114 | trans_pcie->txq[txq_id].ampdu = true; | 1095 | |
1115 | } else { | 1096 | /* Map receiver-address / traffic-ID to this queue */ |
1116 | /* | 1097 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); |
1117 | * disable aggregations for the queue, this will also make the | 1098 | |
1118 | * ra_tid mapping configuration irrelevant since it is now a | 1099 | /* enable aggregations for the queue */ |
1119 | * non-AGG queue. | 1100 | iwl_scd_txq_enable_agg(trans, txq_id); |
1120 | */ | 1101 | trans_pcie->txq[txq_id].ampdu = true; |
1121 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1102 | } else { |
1103 | /* | ||
1104 | * disable aggregations for the queue, this will also | ||
1105 | * make the ra_tid mapping configuration irrelevant | ||
1106 | * since it is now a non-AGG queue. | ||
1107 | */ | ||
1108 | iwl_scd_txq_disable_agg(trans, txq_id); | ||
1122 | 1109 | ||
1123 | ssn = trans_pcie->txq[txq_id].q.read_ptr; | 1110 | ssn = trans_pcie->txq[txq_id].q.read_ptr; |
1111 | } | ||
1124 | } | 1112 | } |
1125 | 1113 | ||
1126 | /* Place first TFD at index corresponding to start sequence number. | 1114 | /* Place first TFD at index corresponding to start sequence number. |
@@ -1128,32 +1116,43 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1128 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); | 1116 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); |
1129 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); | 1117 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); |
1130 | 1118 | ||
1131 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 1119 | if (cfg) { |
1132 | (ssn & 0xff) | (txq_id << 8)); | 1120 | u8 frame_limit = cfg->frame_limit; |
1133 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1121 | |
1122 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | ||
1123 | (ssn & 0xff) | (txq_id << 8)); | ||
1124 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | ||
1134 | 1125 | ||
1135 | /* Set up Tx window size and frame limit for this queue */ | 1126 | /* Set up Tx window size and frame limit for this queue */ |
1136 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1127 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1137 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1128 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1138 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1129 | iwl_trans_write_mem32(trans, |
1130 | trans_pcie->scd_base_addr + | ||
1139 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1131 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1140 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1132 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1141 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1133 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
1142 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 1134 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
1143 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 1135 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
1144 | 1136 | ||
1145 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 1137 | /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */ |
1146 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | 1138 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), |
1147 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 1139 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
1148 | (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | | 1140 | (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | |
1149 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | | 1141 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
1150 | SCD_QUEUE_STTS_REG_MSK); | 1142 | SCD_QUEUE_STTS_REG_MSK); |
1143 | |||
1144 | /* enable the scheduler for this queue (only) */ | ||
1145 | if (txq_id == trans_pcie->cmd_queue) | ||
1146 | iwl_scd_enable_set_active(trans, BIT(txq_id)); | ||
1147 | } | ||
1148 | |||
1151 | trans_pcie->txq[txq_id].active = true; | 1149 | trans_pcie->txq[txq_id].active = true; |
1152 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", | 1150 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", |
1153 | txq_id, fifo, ssn & 0xff); | 1151 | txq_id, fifo, ssn & 0xff); |
1154 | } | 1152 | } |
1155 | 1153 | ||
1156 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 1154 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, |
1155 | bool configure_scd) | ||
1157 | { | 1156 | { |
1158 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1157 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1159 | u32 stts_addr = trans_pcie->scd_base_addr + | 1158 | u32 stts_addr = trans_pcie->scd_base_addr + |
@@ -1172,10 +1171,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1172 | return; | 1171 | return; |
1173 | } | 1172 | } |
1174 | 1173 | ||
1175 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1174 | if (configure_scd) { |
1175 | iwl_scd_txq_set_inactive(trans, txq_id); | ||
1176 | 1176 | ||
1177 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, | 1177 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1178 | ARRAY_SIZE(zero_val)); | 1178 | ARRAY_SIZE(zero_val)); |
1179 | } | ||
1179 | 1180 | ||
1180 | iwl_pcie_txq_unmap(trans, txq_id); | 1181 | iwl_pcie_txq_unmap(trans, txq_id); |
1181 | trans_pcie->txq[txq_id].ampdu = false; | 1182 | trans_pcie->txq[txq_id].ampdu = false; |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 47a998d8f99e..22884ba7d6cc 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -653,6 +653,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
653 | if (channel && | 653 | if (channel && |
654 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { | 654 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { |
655 | bss = cfg80211_inform_bss(wiphy, channel, | 655 | bss = cfg80211_inform_bss(wiphy, channel, |
656 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
656 | bssid, get_unaligned_le64(tsfdesc), | 657 | bssid, get_unaligned_le64(tsfdesc), |
657 | capa, intvl, ie, ielen, | 658 | capa, intvl, ie, ielen, |
658 | LBS_SCAN_RSSI_TO_MBM(rssi), | 659 | LBS_SCAN_RSSI_TO_MBM(rssi), |
@@ -1754,6 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1754 | 1755 | ||
1755 | bss = cfg80211_inform_bss(priv->wdev->wiphy, | 1756 | bss = cfg80211_inform_bss(priv->wdev->wiphy, |
1756 | params->chandef.chan, | 1757 | params->chandef.chan, |
1758 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
1757 | bssid, | 1759 | bssid, |
1758 | 0, | 1760 | 0, |
1759 | capability, | 1761 | capability, |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index e2e6bf13c2d8..c4723b0f5757 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -246,7 +246,7 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, | |||
246 | } | 246 | } |
247 | 247 | ||
248 | if (priv->roc_cfg.cookie) { | 248 | if (priv->roc_cfg.cookie) { |
249 | wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llu\n", | 249 | wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llx\n", |
250 | priv->roc_cfg.cookie); | 250 | priv->roc_cfg.cookie); |
251 | return -EBUSY; | 251 | return -EBUSY; |
252 | } | 252 | } |
@@ -1557,6 +1557,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
1557 | band)); | 1557 | band)); |
1558 | 1558 | ||
1559 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, | 1559 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, |
1560 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
1560 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, | 1561 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, |
1561 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 1562 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
1562 | cfg80211_put_bss(priv->wdev->wiphy, bss); | 1563 | cfg80211_put_bss(priv->wdev->wiphy, bss); |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index baf0aab63c04..985f6c2654fb 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -1470,7 +1470,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1470 | struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; | 1470 | struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; |
1471 | struct mwifiex_adapter *adapter = priv->adapter; | 1471 | struct mwifiex_adapter *adapter = priv->adapter; |
1472 | struct mwifiex_ie_types_header *tlv; | 1472 | struct mwifiex_ie_types_header *tlv; |
1473 | struct hw_spec_fw_api_rev *api_rev; | 1473 | struct hw_spec_api_rev *api_rev; |
1474 | u16 resp_size, api_id; | 1474 | u16 resp_size, api_id; |
1475 | int i, left_len, parsed_len = 0; | 1475 | int i, left_len, parsed_len = 0; |
1476 | 1476 | ||
@@ -1508,7 +1508,6 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); | 1510 | adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); |
1511 | adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff; | ||
1512 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); | 1511 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); |
1513 | 1512 | ||
1514 | if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { | 1513 | if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { |
@@ -1538,23 +1537,30 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1538 | while (left_len > sizeof(struct mwifiex_ie_types_header)) { | 1537 | while (left_len > sizeof(struct mwifiex_ie_types_header)) { |
1539 | tlv = (void *)&hw_spec->tlvs + parsed_len; | 1538 | tlv = (void *)&hw_spec->tlvs + parsed_len; |
1540 | switch (le16_to_cpu(tlv->type)) { | 1539 | switch (le16_to_cpu(tlv->type)) { |
1541 | case TLV_TYPE_FW_API_REV: | 1540 | case TLV_TYPE_API_REV: |
1542 | api_rev = (struct hw_spec_fw_api_rev *)tlv; | 1541 | api_rev = (struct hw_spec_api_rev *)tlv; |
1543 | api_id = le16_to_cpu(api_rev->api_id); | 1542 | api_id = le16_to_cpu(api_rev->api_id); |
1544 | switch (api_id) { | 1543 | switch (api_id) { |
1545 | case KEY_API_VER_ID: | 1544 | case KEY_API_VER_ID: |
1546 | adapter->fw_key_api_major_ver = | 1545 | adapter->key_api_major_ver = |
1547 | api_rev->major_ver; | 1546 | api_rev->major_ver; |
1548 | adapter->fw_key_api_minor_ver = | 1547 | adapter->key_api_minor_ver = |
1549 | api_rev->minor_ver; | 1548 | api_rev->minor_ver; |
1550 | dev_dbg(adapter->dev, | 1549 | dev_dbg(adapter->dev, |
1551 | "fw_key_api v%d.%d\n", | 1550 | "key_api v%d.%d\n", |
1552 | adapter->fw_key_api_major_ver, | 1551 | adapter->key_api_major_ver, |
1553 | adapter->fw_key_api_minor_ver); | 1552 | adapter->key_api_minor_ver); |
1553 | break; | ||
1554 | case FW_API_VER_ID: | ||
1555 | adapter->fw_api_ver = | ||
1556 | api_rev->major_ver; | ||
1557 | dev_dbg(adapter->dev, | ||
1558 | "Firmware api version %d\n", | ||
1559 | adapter->fw_api_ver); | ||
1554 | break; | 1560 | break; |
1555 | default: | 1561 | default: |
1556 | dev_warn(adapter->dev, | 1562 | dev_warn(adapter->dev, |
1557 | "Unknown FW api_id: %d\n", | 1563 | "Unknown api_id: %d\n", |
1558 | api_id); | 1564 | api_id); |
1559 | break; | 1565 | break; |
1560 | } | 1566 | } |
@@ -1567,7 +1573,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1567 | } | 1573 | } |
1568 | parsed_len += le16_to_cpu(tlv->len) + | 1574 | parsed_len += le16_to_cpu(tlv->len) + |
1569 | sizeof(struct mwifiex_ie_types_header); | 1575 | sizeof(struct mwifiex_ie_types_header); |
1570 | left_len -= parsed_len; | 1576 | left_len -= le16_to_cpu(tlv->len) + |
1577 | sizeof(struct mwifiex_ie_types_header); | ||
1571 | } | 1578 | } |
1572 | } | 1579 | } |
1573 | 1580 | ||
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 49da2d53d294..6a703ea18800 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -83,7 +83,7 @@ enum KEY_TYPE_ID { | |||
83 | #define WPA_PN_SIZE 8 | 83 | #define WPA_PN_SIZE 8 |
84 | #define KEY_PARAMS_FIXED_LEN 10 | 84 | #define KEY_PARAMS_FIXED_LEN 10 |
85 | #define KEY_INDEX_MASK 0xf | 85 | #define KEY_INDEX_MASK 0xf |
86 | #define FW_KEY_API_VER_MAJOR_V2 2 | 86 | #define KEY_API_VER_MAJOR_V2 2 |
87 | 87 | ||
88 | #define KEY_MCAST BIT(0) | 88 | #define KEY_MCAST BIT(0) |
89 | #define KEY_UNICAST BIT(1) | 89 | #define KEY_UNICAST BIT(1) |
@@ -170,7 +170,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { | |||
170 | #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) | 170 | #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) |
171 | #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) | 171 | #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) |
172 | #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) | 172 | #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) |
173 | #define TLV_TYPE_FW_API_REV (PROPRIETARY_TLV_BASE_ID + 199) | 173 | #define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) |
174 | 174 | ||
175 | #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 | 175 | #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 |
176 | 176 | ||
@@ -844,11 +844,12 @@ struct host_cmd_ds_802_11_ps_mode_enh { | |||
844 | } params; | 844 | } params; |
845 | } __packed; | 845 | } __packed; |
846 | 846 | ||
847 | enum FW_API_VER_ID { | 847 | enum API_VER_ID { |
848 | KEY_API_VER_ID = 1, | 848 | KEY_API_VER_ID = 1, |
849 | FW_API_VER_ID = 2, | ||
849 | }; | 850 | }; |
850 | 851 | ||
851 | struct hw_spec_fw_api_rev { | 852 | struct hw_spec_api_rev { |
852 | struct mwifiex_ie_types_header header; | 853 | struct mwifiex_ie_types_header header; |
853 | __le16 api_id; | 854 | __le16 api_id; |
854 | u8 major_ver; | 855 | u8 major_ver; |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 269a277d0a2e..80bda8087508 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -282,8 +282,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
282 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; | 282 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; |
283 | adapter->empty_tx_q_cnt = 0; | 283 | adapter->empty_tx_q_cnt = 0; |
284 | adapter->ext_scan = true; | 284 | adapter->ext_scan = true; |
285 | adapter->fw_key_api_major_ver = 0; | 285 | adapter->key_api_major_ver = 0; |
286 | adapter->fw_key_api_minor_ver = 0; | 286 | adapter->key_api_minor_ver = 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | /* | 289 | /* |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index a2733b1e63f9..54399631599a 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -833,7 +833,7 @@ struct mwifiex_adapter { | |||
833 | struct semaphore *card_sem; | 833 | struct semaphore *card_sem; |
834 | bool ext_scan; | 834 | bool ext_scan; |
835 | u8 fw_api_ver; | 835 | u8 fw_api_ver; |
836 | u8 fw_key_api_major_ver, fw_key_api_minor_ver; | 836 | u8 key_api_major_ver, key_api_minor_ver; |
837 | struct work_struct iface_work; | 837 | struct work_struct iface_work; |
838 | unsigned long iface_work_flags; | 838 | unsigned long iface_work_flags; |
839 | struct memory_type_mapping *mem_type_mapping_tbl; | 839 | struct memory_type_mapping *mem_type_mapping_tbl; |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index dee717a19ddb..195ef0ca343f 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1719,7 +1719,8 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, | |||
1719 | 1719 | ||
1720 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | 1720 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { |
1721 | bss = cfg80211_inform_bss(priv->wdev->wiphy, | 1721 | bss = cfg80211_inform_bss(priv->wdev->wiphy, |
1722 | chan, bssid, timestamp, | 1722 | chan, CFG80211_BSS_FTYPE_UNKNOWN, |
1723 | bssid, timestamp, | ||
1723 | cap_info_bitmap, beacon_period, | 1724 | cap_info_bitmap, beacon_period, |
1724 | ie_buf, ie_len, rssi, GFP_KERNEL); | 1725 | ie_buf, ie_len, rssi, GFP_KERNEL); |
1725 | bss_priv = (struct mwifiex_bss_priv *)bss->priv; | 1726 | bss_priv = (struct mwifiex_bss_priv *)bss->priv; |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 733de92a4c61..225f7498048b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -965,7 +965,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
965 | u16 cmd_action, u32 cmd_oid, | 965 | u16 cmd_action, u32 cmd_oid, |
966 | struct mwifiex_ds_encrypt_key *enc_key) | 966 | struct mwifiex_ds_encrypt_key *enc_key) |
967 | { | 967 | { |
968 | if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) | 968 | if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) |
969 | return mwifiex_cmd_802_11_key_material_v2(priv, cmd, | 969 | return mwifiex_cmd_802_11_key_material_v2(priv, cmd, |
970 | cmd_action, cmd_oid, | 970 | cmd_action, cmd_oid, |
971 | enc_key); | 971 | enc_key); |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 08b78baeb846..62866b0f0830 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -637,7 +637,7 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, | |||
637 | static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, | 637 | static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, |
638 | struct host_cmd_ds_command *resp) | 638 | struct host_cmd_ds_command *resp) |
639 | { | 639 | { |
640 | if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) | 640 | if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) |
641 | return mwifiex_ret_802_11_key_material_v2(priv, resp); | 641 | return mwifiex_ret_802_11_key_material_v2(priv, resp); |
642 | else | 642 | else |
643 | return mwifiex_ret_802_11_key_material_v1(priv, resp); | 643 | return mwifiex_ret_802_11_key_material_v1(priv, resp); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index caae9738100a..b95a29b868d1 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -877,7 +877,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, | |||
877 | return -1; | 877 | return -1; |
878 | } | 878 | } |
879 | 879 | ||
880 | if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) { | 880 | if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) { |
881 | memcpy(encrypt_key->key_material, | 881 | memcpy(encrypt_key->key_material, |
882 | wep_key->key_material, wep_key->key_length); | 882 | wep_key->key_material, wep_key->key_length); |
883 | encrypt_key->key_len = wep_key->key_length; | 883 | encrypt_key->key_len = wep_key->key_length; |
@@ -903,7 +903,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, | |||
903 | memset(&priv->wep_key[index], 0, | 903 | memset(&priv->wep_key[index], 0, |
904 | sizeof(struct mwifiex_wep_key)); | 904 | sizeof(struct mwifiex_wep_key)); |
905 | 905 | ||
906 | if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) | 906 | if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) |
907 | enc_key = encrypt_key; | 907 | enc_key = encrypt_key; |
908 | else | 908 | else |
909 | enc_key = NULL; | 909 | enc_key = NULL; |
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index cee028321a9a..ec79c49de097 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c | |||
@@ -172,7 +172,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, | |||
172 | 172 | ||
173 | cfg80211_rx_mgmt(priv->wdev, priv->roc_cfg.chan.center_freq, | 173 | cfg80211_rx_mgmt(priv->wdev, priv->roc_cfg.chan.center_freq, |
174 | CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len, | 174 | CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len, |
175 | 0, GFP_ATOMIC); | 175 | 0); |
176 | 176 | ||
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index d3cf7c3ebfd6..f4b784fc882b 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c | |||
@@ -1605,10 +1605,7 @@ static int ezusb_probe(struct usb_interface *interface, | |||
1605 | for (i = 0; i < iface_desc->bNumEndpoints; ++i) { | 1605 | for (i = 0; i < iface_desc->bNumEndpoints; ++i) { |
1606 | ep = &interface->altsetting[0].endpoint[i].desc; | 1606 | ep = &interface->altsetting[0].endpoint[i].desc; |
1607 | 1607 | ||
1608 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1608 | if (usb_endpoint_is_bulk_in(ep)) { |
1609 | == USB_DIR_IN) && | ||
1610 | ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1611 | == USB_ENDPOINT_XFER_BULK)) { | ||
1612 | /* we found a bulk in endpoint */ | 1609 | /* we found a bulk in endpoint */ |
1613 | if (upriv->read_urb != NULL) { | 1610 | if (upriv->read_urb != NULL) { |
1614 | pr_warning("Found a second bulk in ep, ignored"); | 1611 | pr_warning("Found a second bulk in ep, ignored"); |
@@ -1636,10 +1633,7 @@ static int ezusb_probe(struct usb_interface *interface, | |||
1636 | } | 1633 | } |
1637 | } | 1634 | } |
1638 | 1635 | ||
1639 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1636 | if (usb_endpoint_is_bulk_out(ep)) { |
1640 | == USB_DIR_OUT) && | ||
1641 | ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1642 | == USB_ENDPOINT_XFER_BULK)) { | ||
1643 | /* we found a bulk out endpoint */ | 1637 | /* we found a bulk out endpoint */ |
1644 | if (upriv->bap_buf != NULL) { | 1638 | if (upriv->bap_buf != NULL) { |
1645 | pr_warning("Found a second bulk out ep, ignored"); | 1639 | pr_warning("Found a second bulk out ep, ignored"); |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index e175b9b8561b..2c66166add70 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
@@ -123,9 +123,10 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, | |||
123 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); | 123 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); |
124 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); | 124 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); |
125 | 125 | ||
126 | cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, | 126 | cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, |
127 | capability, beacon_interval, ie_buf, ie_len, | 127 | bss->a.bssid, timestamp, capability, |
128 | signal, GFP_KERNEL); | 128 | beacon_interval, ie_buf, ie_len, signal, |
129 | GFP_KERNEL); | ||
129 | cfg80211_put_bss(wiphy, cbss); | 130 | cfg80211_put_bss(wiphy, cbss); |
130 | } | 131 | } |
131 | 132 | ||
@@ -156,9 +157,10 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
156 | ie = bss->data; | 157 | ie = bss->data; |
157 | signal = SIGNAL_TO_MBM(bss->level); | 158 | signal = SIGNAL_TO_MBM(bss->level); |
158 | 159 | ||
159 | cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, | 160 | cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, |
160 | capability, beacon_interval, ie, ie_len, | 161 | bss->bssid, timestamp, capability, |
161 | signal, GFP_KERNEL); | 162 | beacon_interval, ie, ie_len, signal, |
163 | GFP_KERNEL); | ||
162 | cfg80211_put_bss(wiphy, cbss); | 164 | cfg80211_put_bss(wiphy, cbss); |
163 | } | 165 | } |
164 | 166 | ||
diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index e79848fbcca1..524c2f02dd82 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h | |||
@@ -3,7 +3,8 @@ | |||
3 | Written by Corey Thomas | 3 | Written by Corey Thomas |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef RAYLINK_H | 6 | #ifndef _RAY_CS_H_ |
7 | #define _RAY_CS_H_ | ||
7 | 8 | ||
8 | struct beacon_rx { | 9 | struct beacon_rx { |
9 | struct mac_header mac; | 10 | struct mac_header mac; |
@@ -69,4 +70,4 @@ typedef struct ray_dev_t { | |||
69 | } ray_dev_t; | 70 | } ray_dev_t; |
70 | /*****************************************************************************/ | 71 | /*****************************************************************************/ |
71 | 72 | ||
72 | #endif /* RAYLINK_H */ | 73 | #endif /* _RAY_CS_H_ */ |
diff --git a/drivers/net/wireless/rayctl.h b/drivers/net/wireless/rayctl.h index 3c3b98b152c3..b21ed64e15df 100644 --- a/drivers/net/wireless/rayctl.h +++ b/drivers/net/wireless/rayctl.h | |||
@@ -1,4 +1,5 @@ | |||
1 | #ifndef RAYLINK_H | 1 | #ifndef _RAYCTL_H_ |
2 | #define _RAYCTL_H_ | ||
2 | 3 | ||
3 | typedef unsigned char UCHAR; | 4 | typedef unsigned char UCHAR; |
4 | 5 | ||
@@ -729,4 +730,4 @@ typedef struct snaphdr_t | |||
729 | #define RAY_IPX_TYPE 0x8137 | 730 | #define RAY_IPX_TYPE 0x8137 |
730 | #define APPLEARP_TYPE 0x80f3 | 731 | #define APPLEARP_TYPE 0x80f3 |
731 | /*****************************************************************************/ | 732 | /*****************************************************************************/ |
732 | #endif /* #ifndef RAYLINK_H */ | 733 | #endif /* _RAYCTL_H_ */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d2a9a08210be..1a4facd1fbf3 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -2022,9 +2022,10 @@ static bool rndis_bss_info_update(struct usbnet *usbdev, | |||
2022 | capability = le16_to_cpu(fixed->capabilities); | 2022 | capability = le16_to_cpu(fixed->capabilities); |
2023 | beacon_interval = le16_to_cpu(fixed->beacon_interval); | 2023 | beacon_interval = le16_to_cpu(fixed->beacon_interval); |
2024 | 2024 | ||
2025 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, | 2025 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, |
2026 | timestamp, capability, beacon_interval, ie, ie_len, signal, | 2026 | CFG80211_BSS_FTYPE_UNKNOWN, bssid->mac, |
2027 | GFP_KERNEL); | 2027 | timestamp, capability, beacon_interval, |
2028 | ie, ie_len, signal, GFP_KERNEL); | ||
2028 | cfg80211_put_bss(priv->wdev.wiphy, bss); | 2029 | cfg80211_put_bss(priv->wdev.wiphy, bss); |
2029 | 2030 | ||
2030 | return (bss != NULL); | 2031 | return (bss != NULL); |
@@ -2711,9 +2712,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2711 | bssid, (u32)timestamp, capability, beacon_period, ie_len, | 2712 | bssid, (u32)timestamp, capability, beacon_period, ie_len, |
2712 | ssid.essid, signal); | 2713 | ssid.essid, signal); |
2713 | 2714 | ||
2714 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, | 2715 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, |
2715 | timestamp, capability, beacon_period, ie_buf, ie_len, | 2716 | CFG80211_BSS_FTYPE_UNKNOWN, bssid, |
2716 | signal, GFP_KERNEL); | 2717 | timestamp, capability, beacon_period, |
2718 | ie_buf, ie_len, signal, GFP_KERNEL); | ||
2717 | cfg80211_put_bss(priv->wdev.wiphy, bss); | 2719 | cfg80211_put_bss(priv->wdev.wiphy, bss); |
2718 | } | 2720 | } |
2719 | 2721 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index a394a9a95919..b7434df51e7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -52,6 +52,7 @@ | |||
52 | * RF5592 2.4G/5G 2T2R | 52 | * RF5592 2.4G/5G 2T2R |
53 | * RF3070 2.4G 1T1R | 53 | * RF3070 2.4G 1T1R |
54 | * RF5360 2.4G 1T1R | 54 | * RF5360 2.4G 1T1R |
55 | * RF5362 2.4G 1T1R | ||
55 | * RF5370 2.4G 1T1R | 56 | * RF5370 2.4G 1T1R |
56 | * RF5390 2.4G 1T1R | 57 | * RF5390 2.4G 1T1R |
57 | */ | 58 | */ |
@@ -72,6 +73,7 @@ | |||
72 | #define RF3070 0x3070 | 73 | #define RF3070 0x3070 |
73 | #define RF3290 0x3290 | 74 | #define RF3290 0x3290 |
74 | #define RF5360 0x5360 | 75 | #define RF5360 0x5360 |
76 | #define RF5362 0x5362 | ||
75 | #define RF5370 0x5370 | 77 | #define RF5370 0x5370 |
76 | #define RF5372 0x5372 | 78 | #define RF5372 0x5372 |
77 | #define RF5390 0x5390 | 79 | #define RF5390 0x5390 |
@@ -2145,7 +2147,7 @@ struct mac_iveiv_entry { | |||
2145 | /* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ | 2147 | /* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ |
2146 | #define RFCSR3_PA1_BIAS_CCK FIELD8(0x70) | 2148 | #define RFCSR3_PA1_BIAS_CCK FIELD8(0x70) |
2147 | #define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80) | 2149 | #define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80) |
2148 | /* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */ | 2150 | /* Bits for RF3290/RF5360/RF5362/RF5370/RF5372/RF5390/RF5392 */ |
2149 | #define RFCSR3_VCOCAL_EN FIELD8(0x80) | 2151 | #define RFCSR3_VCOCAL_EN FIELD8(0x80) |
2150 | /* Bits for RF3050 */ | 2152 | /* Bits for RF3050 */ |
2151 | #define RFCSR3_BIT1 FIELD8(0x02) | 2153 | #define RFCSR3_BIT1 FIELD8(0x02) |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 893c9d5f3d6f..9f57a2db791c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -3186,6 +3186,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
3186 | break; | 3186 | break; |
3187 | case RF3070: | 3187 | case RF3070: |
3188 | case RF5360: | 3188 | case RF5360: |
3189 | case RF5362: | ||
3189 | case RF5370: | 3190 | case RF5370: |
3190 | case RF5372: | 3191 | case RF5372: |
3191 | case RF5390: | 3192 | case RF5390: |
@@ -3203,6 +3204,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
3203 | rt2x00_rf(rt2x00dev, RF3290) || | 3204 | rt2x00_rf(rt2x00dev, RF3290) || |
3204 | rt2x00_rf(rt2x00dev, RF3322) || | 3205 | rt2x00_rf(rt2x00dev, RF3322) || |
3205 | rt2x00_rf(rt2x00dev, RF5360) || | 3206 | rt2x00_rf(rt2x00dev, RF5360) || |
3207 | rt2x00_rf(rt2x00dev, RF5362) || | ||
3206 | rt2x00_rf(rt2x00dev, RF5370) || | 3208 | rt2x00_rf(rt2x00dev, RF5370) || |
3207 | rt2x00_rf(rt2x00dev, RF5372) || | 3209 | rt2x00_rf(rt2x00dev, RF5372) || |
3208 | rt2x00_rf(rt2x00dev, RF5390) || | 3210 | rt2x00_rf(rt2x00dev, RF5390) || |
@@ -4317,6 +4319,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) | |||
4317 | case RF3070: | 4319 | case RF3070: |
4318 | case RF3290: | 4320 | case RF3290: |
4319 | case RF5360: | 4321 | case RF5360: |
4322 | case RF5362: | ||
4320 | case RF5370: | 4323 | case RF5370: |
4321 | case RF5372: | 4324 | case RF5372: |
4322 | case RF5390: | 4325 | case RF5390: |
@@ -7095,6 +7098,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
7095 | case RF3320: | 7098 | case RF3320: |
7096 | case RF3322: | 7099 | case RF3322: |
7097 | case RF5360: | 7100 | case RF5360: |
7101 | case RF5362: | ||
7098 | case RF5370: | 7102 | case RF5370: |
7099 | case RF5372: | 7103 | case RF5372: |
7100 | case RF5390: | 7104 | case RF5390: |
@@ -7551,6 +7555,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
7551 | case RF3320: | 7555 | case RF3320: |
7552 | case RF3322: | 7556 | case RF3322: |
7553 | case RF5360: | 7557 | case RF5360: |
7558 | case RF5362: | ||
7554 | case RF5370: | 7559 | case RF5370: |
7555 | case RF5372: | 7560 | case RF5372: |
7556 | case RF5390: | 7561 | case RF5390: |
@@ -7680,6 +7685,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
7680 | case RF3070: | 7685 | case RF3070: |
7681 | case RF3290: | 7686 | case RF3290: |
7682 | case RF5360: | 7687 | case RF5360: |
7688 | case RF5362: | ||
7683 | case RF5370: | 7689 | case RF5370: |
7684 | case RF5372: | 7690 | case RF5372: |
7685 | case RF5390: | 7691 | case RF5390: |
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index a0aa8fa72392..735be5352143 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c | |||
@@ -345,7 +345,6 @@ static int wl1251_spi_remove(struct spi_device *spi) | |||
345 | { | 345 | { |
346 | struct wl1251 *wl = spi_get_drvdata(spi); | 346 | struct wl1251 *wl = spi_get_drvdata(spi); |
347 | 347 | ||
348 | free_irq(wl->irq, wl); | ||
349 | wl1251_free_hw(wl); | 348 | wl1251_free_hw(wl); |
350 | regulator_disable(wl->vio); | 349 | regulator_disable(wl->vio); |
351 | 350 | ||
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index 392c882b28f0..69601f6741d9 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c | |||
@@ -327,23 +327,22 @@ static int wl1271_probe(struct spi_device *spi) | |||
327 | struct wl12xx_spi_glue *glue; | 327 | struct wl12xx_spi_glue *glue; |
328 | struct wlcore_platdev_data pdev_data; | 328 | struct wlcore_platdev_data pdev_data; |
329 | struct resource res[1]; | 329 | struct resource res[1]; |
330 | int ret = -ENOMEM; | 330 | int ret; |
331 | 331 | ||
332 | memset(&pdev_data, 0x00, sizeof(pdev_data)); | 332 | memset(&pdev_data, 0x00, sizeof(pdev_data)); |
333 | 333 | ||
334 | pdev_data.pdata = dev_get_platdata(&spi->dev); | 334 | pdev_data.pdata = dev_get_platdata(&spi->dev); |
335 | if (!pdev_data.pdata) { | 335 | if (!pdev_data.pdata) { |
336 | dev_err(&spi->dev, "no platform data\n"); | 336 | dev_err(&spi->dev, "no platform data\n"); |
337 | ret = -ENODEV; | 337 | return -ENODEV; |
338 | goto out; | ||
339 | } | 338 | } |
340 | 339 | ||
341 | pdev_data.if_ops = &spi_ops; | 340 | pdev_data.if_ops = &spi_ops; |
342 | 341 | ||
343 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 342 | glue = devm_kzalloc(&spi->dev, sizeof(*glue), GFP_KERNEL); |
344 | if (!glue) { | 343 | if (!glue) { |
345 | dev_err(&spi->dev, "can't allocate glue\n"); | 344 | dev_err(&spi->dev, "can't allocate glue\n"); |
346 | goto out; | 345 | return -ENOMEM; |
347 | } | 346 | } |
348 | 347 | ||
349 | glue->dev = &spi->dev; | 348 | glue->dev = &spi->dev; |
@@ -357,14 +356,13 @@ static int wl1271_probe(struct spi_device *spi) | |||
357 | ret = spi_setup(spi); | 356 | ret = spi_setup(spi); |
358 | if (ret < 0) { | 357 | if (ret < 0) { |
359 | dev_err(glue->dev, "spi_setup failed\n"); | 358 | dev_err(glue->dev, "spi_setup failed\n"); |
360 | goto out_free_glue; | 359 | return ret; |
361 | } | 360 | } |
362 | 361 | ||
363 | glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO); | 362 | glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO); |
364 | if (!glue->core) { | 363 | if (!glue->core) { |
365 | dev_err(glue->dev, "can't allocate platform_device\n"); | 364 | dev_err(glue->dev, "can't allocate platform_device\n"); |
366 | ret = -ENOMEM; | 365 | return -ENOMEM; |
367 | goto out_free_glue; | ||
368 | } | 366 | } |
369 | 367 | ||
370 | glue->core->dev.parent = &spi->dev; | 368 | glue->core->dev.parent = &spi->dev; |
@@ -398,11 +396,6 @@ static int wl1271_probe(struct spi_device *spi) | |||
398 | 396 | ||
399 | out_dev_put: | 397 | out_dev_put: |
400 | platform_device_put(glue->core); | 398 | platform_device_put(glue->core); |
401 | |||
402 | out_free_glue: | ||
403 | kfree(glue); | ||
404 | |||
405 | out: | ||
406 | return ret; | 399 | return ret; |
407 | } | 400 | } |
408 | 401 | ||
@@ -411,7 +404,6 @@ static int wl1271_remove(struct spi_device *spi) | |||
411 | struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); | 404 | struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); |
412 | 405 | ||
413 | platform_device_unregister(glue->core); | 406 | platform_device_unregister(glue->core); |
414 | kfree(glue); | ||
415 | 407 | ||
416 | return 0; | 408 | return 0; |
417 | } | 409 | } |
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index c5fdcb89dacd..2a1502f351f8 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c | |||
@@ -2128,7 +2128,7 @@ static int on_action_public23a(struct rtw_adapter *padapter, | |||
2128 | IEEE80211_BAND_5GHZ); | 2128 | IEEE80211_BAND_5GHZ); |
2129 | 2129 | ||
2130 | if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe, | 2130 | if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe, |
2131 | skb->len, 0, GFP_ATOMIC)) | 2131 | skb->len, 0)) |
2132 | return _SUCCESS; | 2132 | return _SUCCESS; |
2133 | 2133 | ||
2134 | return _FAIL; | 2134 | return _FAIL; |
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index 93dc844a10b3..8b0ccb5c5fc4 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | |||
@@ -279,6 +279,7 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter, | |||
279 | } | 279 | } |
280 | 280 | ||
281 | bss = cfg80211_inform_bss(wiphy, notify_channel, | 281 | bss = cfg80211_inform_bss(wiphy, notify_channel, |
282 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
282 | pnetwork->network.MacAddress, | 283 | pnetwork->network.MacAddress, |
283 | pnetwork->network.tsf, | 284 | pnetwork->network.tsf, |
284 | pnetwork->network.capability, | 285 | pnetwork->network.capability, |
@@ -2379,7 +2380,7 @@ void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, | |||
2379 | IEEE80211_BAND_5GHZ); | 2380 | IEEE80211_BAND_5GHZ); |
2380 | 2381 | ||
2381 | cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len, | 2382 | cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len, |
2382 | 0, GFP_ATOMIC); | 2383 | 0); |
2383 | #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ | 2384 | #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ |
2384 | } | 2385 | } |
2385 | 2386 | ||
@@ -2425,7 +2426,7 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter, | |||
2425 | frame_len = sizeof(struct ieee80211_hdr_3addr) + 2; | 2426 | frame_len = sizeof(struct ieee80211_hdr_3addr) + 2; |
2426 | 2427 | ||
2427 | cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len, | 2428 | cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len, |
2428 | 0, GFP_ATOMIC); | 2429 | 0); |
2429 | #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ | 2430 | #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ |
2430 | } | 2431 | } |
2431 | 2432 | ||
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 3727f6d25cf1..8942dcb44180 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -422,6 +422,7 @@ static int prism2_scan(struct wiphy *wiphy, | |||
422 | IEEE80211_BAND_2GHZ); | 422 | IEEE80211_BAND_2GHZ); |
423 | bss = cfg80211_inform_bss(wiphy, | 423 | bss = cfg80211_inform_bss(wiphy, |
424 | ieee80211_get_channel(wiphy, freq), | 424 | ieee80211_get_channel(wiphy, freq), |
425 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
425 | (const u8 *) &(msg2.bssid.data.data), | 426 | (const u8 *) &(msg2.bssid.data.data), |
426 | msg2.timestamp.data, msg2.capinfo.data, | 427 | msg2.timestamp.data, msg2.capinfo.data, |
427 | msg2.beaconperiod.data, | 428 | msg2.beaconperiod.data, |
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 917dcd7965e7..e64ae7bf80a1 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h | |||
@@ -39,6 +39,11 @@ | |||
39 | #define BCMA_RESET_CTL_RESET 0x0001 | 39 | #define BCMA_RESET_CTL_RESET 0x0001 |
40 | #define BCMA_RESET_ST 0x0804 | 40 | #define BCMA_RESET_ST 0x0804 |
41 | 41 | ||
42 | #define BCMA_NS_ROM_IOST_BOOT_DEV_MASK 0x0003 | ||
43 | #define BCMA_NS_ROM_IOST_BOOT_DEV_NOR 0x0000 | ||
44 | #define BCMA_NS_ROM_IOST_BOOT_DEV_NAND 0x0001 | ||
45 | #define BCMA_NS_ROM_IOST_BOOT_DEV_ROM 0x0002 | ||
46 | |||
42 | /* BCMA PCI config space registers. */ | 47 | /* BCMA PCI config space registers. */ |
43 | #define BCMA_PCI_PMCSR 0x44 | 48 | #define BCMA_PCI_PMCSR 0x44 |
44 | #define BCMA_PCI_PE 0x100 | 49 | #define BCMA_PCI_PE 0x100 |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 63ab3873c5ed..8018c915ee63 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -838,6 +838,16 @@ enum ieee80211_vht_opmode_bits { | |||
838 | 838 | ||
839 | #define WLAN_SA_QUERY_TR_ID_LEN 2 | 839 | #define WLAN_SA_QUERY_TR_ID_LEN 2 |
840 | 840 | ||
841 | /** | ||
842 | * struct ieee80211_tpc_report_ie | ||
843 | * | ||
844 | * This structure refers to "TPC Report element" | ||
845 | */ | ||
846 | struct ieee80211_tpc_report_ie { | ||
847 | u8 tx_power; | ||
848 | u8 link_margin; | ||
849 | } __packed; | ||
850 | |||
841 | struct ieee80211_mgmt { | 851 | struct ieee80211_mgmt { |
842 | __le16 frame_control; | 852 | __le16 frame_control; |
843 | __le16 duration; | 853 | __le16 duration; |
@@ -973,6 +983,13 @@ struct ieee80211_mgmt { | |||
973 | u8 action_code; | 983 | u8 action_code; |
974 | u8 operating_mode; | 984 | u8 operating_mode; |
975 | } __packed vht_opmode_notif; | 985 | } __packed vht_opmode_notif; |
986 | struct { | ||
987 | u8 action_code; | ||
988 | u8 dialog_token; | ||
989 | u8 tpc_elem_id; | ||
990 | u8 tpc_elem_length; | ||
991 | struct ieee80211_tpc_report_ie tpc; | ||
992 | } __packed tpc_report; | ||
976 | } u; | 993 | } u; |
977 | } __packed action; | 994 | } __packed action; |
978 | } u; | 995 | } u; |
@@ -1865,6 +1882,7 @@ enum ieee80211_category { | |||
1865 | WLAN_CATEGORY_DLS = 2, | 1882 | WLAN_CATEGORY_DLS = 2, |
1866 | WLAN_CATEGORY_BACK = 3, | 1883 | WLAN_CATEGORY_BACK = 3, |
1867 | WLAN_CATEGORY_PUBLIC = 4, | 1884 | WLAN_CATEGORY_PUBLIC = 4, |
1885 | WLAN_CATEGORY_RADIO_MEASUREMENT = 5, | ||
1868 | WLAN_CATEGORY_HT = 7, | 1886 | WLAN_CATEGORY_HT = 7, |
1869 | WLAN_CATEGORY_SA_QUERY = 8, | 1887 | WLAN_CATEGORY_SA_QUERY = 8, |
1870 | WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, | 1888 | WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, |
@@ -2378,4 +2396,51 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim, | |||
2378 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) | 2396 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) |
2379 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) | 2397 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) |
2380 | 2398 | ||
2399 | /** | ||
2400 | * ieee80211_action_contains_tpc - checks if the frame contains TPC element | ||
2401 | * @skb: the skb containing the frame, length will be checked | ||
2402 | * | ||
2403 | * This function checks if it's either TPC report action frame or Link | ||
2404 | * Measurement report action frame as defined in IEEE Std. 802.11-2012 8.5.2.5 | ||
2405 | * and 8.5.7.5 accordingly. | ||
2406 | */ | ||
2407 | static inline bool ieee80211_action_contains_tpc(struct sk_buff *skb) | ||
2408 | { | ||
2409 | struct ieee80211_mgmt *mgmt = (void *)skb->data; | ||
2410 | |||
2411 | if (!ieee80211_is_action(mgmt->frame_control)) | ||
2412 | return false; | ||
2413 | |||
2414 | if (skb->len < IEEE80211_MIN_ACTION_SIZE + | ||
2415 | sizeof(mgmt->u.action.u.tpc_report)) | ||
2416 | return false; | ||
2417 | |||
2418 | /* | ||
2419 | * TPC report - check that: | ||
2420 | * category = 0 (Spectrum Management) or 5 (Radio Measurement) | ||
2421 | * spectrum management action = 3 (TPC/Link Measurement report) | ||
2422 | * TPC report EID = 35 | ||
2423 | * TPC report element length = 2 | ||
2424 | * | ||
2425 | * The spectrum management's tpc_report struct is used here both for | ||
2426 | * parsing tpc_report and radio measurement's link measurement report | ||
2427 | * frame, since the relevant part is identical in both frames. | ||
2428 | */ | ||
2429 | if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT && | ||
2430 | mgmt->u.action.category != WLAN_CATEGORY_RADIO_MEASUREMENT) | ||
2431 | return false; | ||
2432 | |||
2433 | /* both spectrum mgmt and link measurement have same action code */ | ||
2434 | if (mgmt->u.action.u.tpc_report.action_code != | ||
2435 | WLAN_ACTION_SPCT_TPC_RPRT) | ||
2436 | return false; | ||
2437 | |||
2438 | if (mgmt->u.action.u.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT || | ||
2439 | mgmt->u.action.u.tpc_report.tpc_elem_length != | ||
2440 | sizeof(struct ieee80211_tpc_report_ie)) | ||
2441 | return false; | ||
2442 | |||
2443 | return true; | ||
2444 | } | ||
2445 | |||
2381 | #endif /* LINUX_IEEE80211_H */ | 2446 | #endif /* LINUX_IEEE80211_H */ |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6f884e6c731e..b0ded1333865 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -302,7 +302,7 @@ struct hci_dev { | |||
302 | __u32 req_status; | 302 | __u32 req_status; |
303 | __u32 req_result; | 303 | __u32 req_result; |
304 | 304 | ||
305 | struct crypto_blkcipher *tfm_aes; | 305 | void *smp_data; |
306 | 306 | ||
307 | struct discovery_state discovery; | 307 | struct discovery_state discovery; |
308 | struct hci_conn_hash conn_hash; | 308 | struct hci_conn_hash conn_hash; |
@@ -970,6 +970,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
970 | #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) | 970 | #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) |
971 | #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) | 971 | #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) |
972 | 972 | ||
973 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ | ||
974 | !test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | ||
975 | |||
973 | /* ----- HCI protocols ----- */ | 976 | /* ----- HCI protocols ----- */ |
974 | #define HCI_PROTO_DEFER 0x01 | 977 | #define HCI_PROTO_DEFER 0x01 |
975 | 978 | ||
@@ -1258,6 +1261,8 @@ bool hci_req_pending(struct hci_dev *hdev); | |||
1258 | void hci_req_add_le_scan_disable(struct hci_request *req); | 1261 | void hci_req_add_le_scan_disable(struct hci_request *req); |
1259 | void hci_req_add_le_passive_scan(struct hci_request *req); | 1262 | void hci_req_add_le_passive_scan(struct hci_request *req); |
1260 | 1263 | ||
1264 | void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req); | ||
1265 | |||
1261 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | 1266 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, |
1262 | const void *param, u32 timeout); | 1267 | const void *param, u32 timeout); |
1263 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 1268 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
@@ -1353,6 +1358,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
1353 | void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1358 | void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
1354 | u8 addr_type, s8 rssi, u8 *name, u8 name_len); | 1359 | u8 addr_type, s8 rssi, u8 *name, u8 name_len); |
1355 | void mgmt_discovering(struct hci_dev *hdev, u8 discovering); | 1360 | void mgmt_discovering(struct hci_dev *hdev, u8 discovering); |
1361 | bool mgmt_powering_down(struct hci_dev *hdev); | ||
1356 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); | 1362 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); |
1357 | void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); | 1363 | void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); |
1358 | void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, | 1364 | void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 8df15ad0d43f..cedda399f9c0 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -625,6 +625,9 @@ struct l2cap_conn { | |||
625 | 625 | ||
626 | struct delayed_work info_timer; | 626 | struct delayed_work info_timer; |
627 | 627 | ||
628 | int disconn_err; | ||
629 | struct work_struct disconn_work; | ||
630 | |||
628 | struct sk_buff *rx_skb; | 631 | struct sk_buff *rx_skb; |
629 | __u32 rx_len; | 632 | __u32 rx_len; |
630 | __u8 tx_ident; | 633 | __u8 tx_ident; |
@@ -635,8 +638,7 @@ struct l2cap_conn { | |||
635 | 638 | ||
636 | __u8 disc_reason; | 639 | __u8 disc_reason; |
637 | 640 | ||
638 | struct delayed_work security_timer; | 641 | struct l2cap_chan *smp; |
639 | struct smp_chan *smp_chan; | ||
640 | 642 | ||
641 | struct list_head chan_l; | 643 | struct list_head chan_l; |
642 | struct mutex chan_lock; | 644 | struct mutex chan_lock; |
@@ -708,6 +710,7 @@ enum { | |||
708 | FLAG_EFS_ENABLE, | 710 | FLAG_EFS_ENABLE, |
709 | FLAG_DEFER_SETUP, | 711 | FLAG_DEFER_SETUP, |
710 | FLAG_LE_CONN_REQ_SENT, | 712 | FLAG_LE_CONN_REQ_SENT, |
713 | FLAG_PENDING_SECURITY, | ||
711 | }; | 714 | }; |
712 | 715 | ||
713 | enum { | 716 | enum { |
@@ -837,18 +840,43 @@ static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan | |||
837 | return NULL; | 840 | return NULL; |
838 | } | 841 | } |
839 | 842 | ||
843 | static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb) | ||
844 | { | ||
845 | return -ENOSYS; | ||
846 | } | ||
847 | |||
848 | static inline struct sk_buff *l2cap_chan_no_alloc_skb(struct l2cap_chan *chan, | ||
849 | unsigned long hdr_len, | ||
850 | unsigned long len, int nb) | ||
851 | { | ||
852 | return ERR_PTR(-ENOSYS); | ||
853 | } | ||
854 | |||
840 | static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) | 855 | static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) |
841 | { | 856 | { |
842 | } | 857 | } |
843 | 858 | ||
859 | static inline void l2cap_chan_no_close(struct l2cap_chan *chan) | ||
860 | { | ||
861 | } | ||
862 | |||
844 | static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) | 863 | static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) |
845 | { | 864 | { |
846 | } | 865 | } |
847 | 866 | ||
867 | static inline void l2cap_chan_no_state_change(struct l2cap_chan *chan, | ||
868 | int state, int err) | ||
869 | { | ||
870 | } | ||
871 | |||
848 | static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) | 872 | static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) |
849 | { | 873 | { |
850 | } | 874 | } |
851 | 875 | ||
876 | static inline void l2cap_chan_no_suspend(struct l2cap_chan *chan) | ||
877 | { | ||
878 | } | ||
879 | |||
852 | static inline void l2cap_chan_no_resume(struct l2cap_chan *chan) | 880 | static inline void l2cap_chan_no_resume(struct l2cap_chan *chan) |
853 | { | 881 | { |
854 | } | 882 | } |
@@ -918,6 +946,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, | |||
918 | u8 status); | 946 | u8 status); |
919 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); | 947 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); |
920 | 948 | ||
949 | void l2cap_conn_shutdown(struct l2cap_conn *conn, int err); | ||
921 | void l2cap_conn_get(struct l2cap_conn *conn); | 950 | void l2cap_conn_get(struct l2cap_conn *conn); |
922 | void l2cap_conn_put(struct l2cap_conn *conn); | 951 | void l2cap_conn_put(struct l2cap_conn *conn); |
923 | 952 | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0a080c4de275..ab21299c8f4d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1503,12 +1503,14 @@ enum cfg80211_signal_type { | |||
1503 | * @tsf: TSF contained in the frame that carried these IEs | 1503 | * @tsf: TSF contained in the frame that carried these IEs |
1504 | * @rcu_head: internal use, for freeing | 1504 | * @rcu_head: internal use, for freeing |
1505 | * @len: length of the IEs | 1505 | * @len: length of the IEs |
1506 | * @from_beacon: these IEs are known to come from a beacon | ||
1506 | * @data: IE data | 1507 | * @data: IE data |
1507 | */ | 1508 | */ |
1508 | struct cfg80211_bss_ies { | 1509 | struct cfg80211_bss_ies { |
1509 | u64 tsf; | 1510 | u64 tsf; |
1510 | struct rcu_head rcu_head; | 1511 | struct rcu_head rcu_head; |
1511 | int len; | 1512 | int len; |
1513 | bool from_beacon; | ||
1512 | u8 data[]; | 1514 | u8 data[]; |
1513 | }; | 1515 | }; |
1514 | 1516 | ||
@@ -3765,11 +3767,25 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
3765 | } | 3767 | } |
3766 | 3768 | ||
3767 | /** | 3769 | /** |
3768 | * cfg80211_inform_bss - inform cfg80211 of a new BSS | 3770 | * enum cfg80211_bss_frame_type - frame type that the BSS data came from |
3771 | * @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is | ||
3772 | * from a beacon or probe response | ||
3773 | * @CFG80211_BSS_FTYPE_BEACON: data comes from a beacon | ||
3774 | * @CFG80211_BSS_FTYPE_PRESP: data comes from a probe response | ||
3775 | */ | ||
3776 | enum cfg80211_bss_frame_type { | ||
3777 | CFG80211_BSS_FTYPE_UNKNOWN, | ||
3778 | CFG80211_BSS_FTYPE_BEACON, | ||
3779 | CFG80211_BSS_FTYPE_PRESP, | ||
3780 | }; | ||
3781 | |||
3782 | /** | ||
3783 | * cfg80211_inform_bss_width - inform cfg80211 of a new BSS | ||
3769 | * | 3784 | * |
3770 | * @wiphy: the wiphy reporting the BSS | 3785 | * @wiphy: the wiphy reporting the BSS |
3771 | * @rx_channel: The channel the frame was received on | 3786 | * @rx_channel: The channel the frame was received on |
3772 | * @scan_width: width of the control channel | 3787 | * @scan_width: width of the control channel |
3788 | * @ftype: frame type (if known) | ||
3773 | * @bssid: the BSSID of the BSS | 3789 | * @bssid: the BSSID of the BSS |
3774 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) | 3790 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) |
3775 | * @capability: the capability field sent by the peer | 3791 | * @capability: the capability field sent by the peer |
@@ -3789,6 +3805,7 @@ struct cfg80211_bss * __must_check | |||
3789 | cfg80211_inform_bss_width(struct wiphy *wiphy, | 3805 | cfg80211_inform_bss_width(struct wiphy *wiphy, |
3790 | struct ieee80211_channel *rx_channel, | 3806 | struct ieee80211_channel *rx_channel, |
3791 | enum nl80211_bss_scan_width scan_width, | 3807 | enum nl80211_bss_scan_width scan_width, |
3808 | enum cfg80211_bss_frame_type ftype, | ||
3792 | const u8 *bssid, u64 tsf, u16 capability, | 3809 | const u8 *bssid, u64 tsf, u16 capability, |
3793 | u16 beacon_interval, const u8 *ie, size_t ielen, | 3810 | u16 beacon_interval, const u8 *ie, size_t ielen, |
3794 | s32 signal, gfp_t gfp); | 3811 | s32 signal, gfp_t gfp); |
@@ -3796,12 +3813,13 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
3796 | static inline struct cfg80211_bss * __must_check | 3813 | static inline struct cfg80211_bss * __must_check |
3797 | cfg80211_inform_bss(struct wiphy *wiphy, | 3814 | cfg80211_inform_bss(struct wiphy *wiphy, |
3798 | struct ieee80211_channel *rx_channel, | 3815 | struct ieee80211_channel *rx_channel, |
3816 | enum cfg80211_bss_frame_type ftype, | ||
3799 | const u8 *bssid, u64 tsf, u16 capability, | 3817 | const u8 *bssid, u64 tsf, u16 capability, |
3800 | u16 beacon_interval, const u8 *ie, size_t ielen, | 3818 | u16 beacon_interval, const u8 *ie, size_t ielen, |
3801 | s32 signal, gfp_t gfp) | 3819 | s32 signal, gfp_t gfp) |
3802 | { | 3820 | { |
3803 | return cfg80211_inform_bss_width(wiphy, rx_channel, | 3821 | return cfg80211_inform_bss_width(wiphy, rx_channel, |
3804 | NL80211_BSS_CHAN_WIDTH_20, | 3822 | NL80211_BSS_CHAN_WIDTH_20, ftype, |
3805 | bssid, tsf, capability, | 3823 | bssid, tsf, capability, |
3806 | beacon_interval, ie, ielen, signal, | 3824 | beacon_interval, ie, ielen, signal, |
3807 | gfp); | 3825 | gfp); |
@@ -4412,7 +4430,6 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | |||
4412 | * @buf: Management frame (header + body) | 4430 | * @buf: Management frame (header + body) |
4413 | * @len: length of the frame data | 4431 | * @len: length of the frame data |
4414 | * @flags: flags, as defined in enum nl80211_rxmgmt_flags | 4432 | * @flags: flags, as defined in enum nl80211_rxmgmt_flags |
4415 | * @gfp: context flags | ||
4416 | * | 4433 | * |
4417 | * This function is called whenever an Action frame is received for a station | 4434 | * This function is called whenever an Action frame is received for a station |
4418 | * mode interface, but is not processed in kernel. | 4435 | * mode interface, but is not processed in kernel. |
@@ -4423,7 +4440,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | |||
4423 | * driver is responsible for rejecting the frame. | 4440 | * driver is responsible for rejecting the frame. |
4424 | */ | 4441 | */ |
4425 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, | 4442 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, |
4426 | const u8 *buf, size_t len, u32 flags, gfp_t gfp); | 4443 | const u8 *buf, size_t len, u32 flags); |
4427 | 4444 | ||
4428 | /** | 4445 | /** |
4429 | * cfg80211_mgmt_tx_status - notification of TX status for management frame | 4446 | * cfg80211_mgmt_tx_status - notification of TX status for management frame |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dae2e24616e1..c9b2bec8db47 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1226,7 +1226,8 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); | |||
1226 | * | 1226 | * |
1227 | * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the | 1227 | * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the |
1228 | * driver to indicate that it requires IV generation for this | 1228 | * driver to indicate that it requires IV generation for this |
1229 | * particular key. | 1229 | * particular key. Setting this flag does not necessarily mean that SKBs |
1230 | * will have sufficient tailroom for ICV or MIC. | ||
1230 | * @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by | 1231 | * @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by |
1231 | * the driver for a TKIP key if it requires Michael MIC | 1232 | * the driver for a TKIP key if it requires Michael MIC |
1232 | * generation in software. | 1233 | * generation in software. |
@@ -1238,7 +1239,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); | |||
1238 | * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver | 1239 | * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver |
1239 | * if space should be prepared for the IV, but the IV | 1240 | * if space should be prepared for the IV, but the IV |
1240 | * itself should not be generated. Do not set together with | 1241 | * itself should not be generated. Do not set together with |
1241 | * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. | 1242 | * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. Setting this flag does |
1243 | * not necessarily mean that SKBs will have sufficient tailroom for ICV or | ||
1244 | * MIC. | ||
1242 | * @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received | 1245 | * @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received |
1243 | * management frames. The flag can help drivers that have a hardware | 1246 | * management frames. The flag can help drivers that have a hardware |
1244 | * crypto implementation that doesn't deal with management frames | 1247 | * crypto implementation that doesn't deal with management frames |
@@ -1405,7 +1408,7 @@ struct ieee80211_sta_rates { | |||
1405 | * @supp_rates: Bitmap of supported rates (per band) | 1408 | * @supp_rates: Bitmap of supported rates (per band) |
1406 | * @ht_cap: HT capabilities of this STA; restricted to our own capabilities | 1409 | * @ht_cap: HT capabilities of this STA; restricted to our own capabilities |
1407 | * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities | 1410 | * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities |
1408 | * @wme: indicates whether the STA supports WME. Only valid during AP-mode. | 1411 | * @wme: indicates whether the STA supports QoS/WME. |
1409 | * @drv_priv: data area for driver use, will always be aligned to | 1412 | * @drv_priv: data area for driver use, will always be aligned to |
1410 | * sizeof(void *), size is determined in hw information. | 1413 | * sizeof(void *), size is determined in hw information. |
1411 | * @uapsd_queues: bitmap of queues configured for uapsd. Only valid | 1414 | * @uapsd_queues: bitmap of queues configured for uapsd. Only valid |
@@ -1606,6 +1609,9 @@ struct ieee80211_tx_control { | |||
1606 | * is not enabled the default action is to disconnect when getting the | 1609 | * is not enabled the default action is to disconnect when getting the |
1607 | * CSA frame. | 1610 | * CSA frame. |
1608 | * | 1611 | * |
1612 | * @IEEE80211_HW_SUPPORTS_CLONED_SKBS: The driver will never modify the payload | ||
1613 | * or tailroom of TX skbs without copying them first. | ||
1614 | * | ||
1609 | * @IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS: The HW supports scanning on all bands | 1615 | * @IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS: The HW supports scanning on all bands |
1610 | * in one command, mac80211 doesn't have to run separate scans per band. | 1616 | * in one command, mac80211 doesn't have to run separate scans per band. |
1611 | */ | 1617 | */ |
@@ -1639,7 +1645,7 @@ enum ieee80211_hw_flags { | |||
1639 | IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, | 1645 | IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, |
1640 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27, | 1646 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27, |
1641 | IEEE80211_HW_CHANCTX_STA_CSA = 1<<28, | 1647 | IEEE80211_HW_CHANCTX_STA_CSA = 1<<28, |
1642 | /* bit 29 unused */ | 1648 | IEEE80211_HW_SUPPORTS_CLONED_SKBS = 1<<29, |
1643 | IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS = 1<<30, | 1649 | IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS = 1<<30, |
1644 | }; | 1650 | }; |
1645 | 1651 | ||
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f1db15b9c041..d097568da690 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -3055,14 +3055,20 @@ enum nl80211_bss_scan_width { | |||
3055 | * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) | 3055 | * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) |
3056 | * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) | 3056 | * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) |
3057 | * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) | 3057 | * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) |
3058 | * (if @NL80211_BSS_PRESP_DATA is present then this is known to be | ||
3059 | * from a probe response, otherwise it may be from the same beacon | ||
3060 | * that the NL80211_BSS_BEACON_TSF will be from) | ||
3058 | * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) | 3061 | * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) |
3059 | * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) | 3062 | * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) |
3060 | * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the | 3063 | * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the |
3061 | * raw information elements from the probe response/beacon (bin); | 3064 | * raw information elements from the probe response/beacon (bin); |
3062 | * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are | 3065 | * if the %NL80211_BSS_BEACON_IES attribute is present and the data is |
3063 | * from a Probe Response frame; otherwise they are from a Beacon frame. | 3066 | * different then the IEs here are from a Probe Response frame; otherwise |
3067 | * they are from a Beacon frame. | ||
3064 | * However, if the driver does not indicate the source of the IEs, these | 3068 | * However, if the driver does not indicate the source of the IEs, these |
3065 | * IEs may be from either frame subtype. | 3069 | * IEs may be from either frame subtype. |
3070 | * If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the | ||
3071 | * data here is known to be from a probe response, without any heuristics. | ||
3066 | * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon | 3072 | * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon |
3067 | * in mBm (100 * dBm) (s32) | 3073 | * in mBm (100 * dBm) (s32) |
3068 | * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon | 3074 | * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon |
@@ -3074,6 +3080,10 @@ enum nl80211_bss_scan_width { | |||
3074 | * yet been received | 3080 | * yet been received |
3075 | * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel | 3081 | * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel |
3076 | * (u32, enum nl80211_bss_scan_width) | 3082 | * (u32, enum nl80211_bss_scan_width) |
3083 | * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64) | ||
3084 | * (not present if no beacon frame has been received yet) | ||
3085 | * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and | ||
3086 | * @NL80211_BSS_TSF is known to be from a probe response (flag attribute) | ||
3077 | * @__NL80211_BSS_AFTER_LAST: internal | 3087 | * @__NL80211_BSS_AFTER_LAST: internal |
3078 | * @NL80211_BSS_MAX: highest BSS attribute | 3088 | * @NL80211_BSS_MAX: highest BSS attribute |
3079 | */ | 3089 | */ |
@@ -3091,6 +3101,8 @@ enum nl80211_bss { | |||
3091 | NL80211_BSS_SEEN_MS_AGO, | 3101 | NL80211_BSS_SEEN_MS_AGO, |
3092 | NL80211_BSS_BEACON_IES, | 3102 | NL80211_BSS_BEACON_IES, |
3093 | NL80211_BSS_CHAN_WIDTH, | 3103 | NL80211_BSS_CHAN_WIDTH, |
3104 | NL80211_BSS_BEACON_TSF, | ||
3105 | NL80211_BSS_PRESP_DATA, | ||
3094 | 3106 | ||
3095 | /* keep last */ | 3107 | /* keep last */ |
3096 | __NL80211_BSS_AFTER_LAST, | 3108 | __NL80211_BSS_AFTER_LAST, |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 206b65ccd5b8..35ebe79c87b0 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -772,16 +772,16 @@ static inline void chan_ready_cb(struct l2cap_chan *chan) | |||
772 | ifup(dev->netdev); | 772 | ifup(dev->netdev); |
773 | } | 773 | } |
774 | 774 | ||
775 | static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *chan) | 775 | static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan) |
776 | { | 776 | { |
777 | struct l2cap_chan *pchan; | 777 | struct l2cap_chan *chan; |
778 | 778 | ||
779 | pchan = chan_open(chan); | 779 | chan = chan_open(pchan); |
780 | pchan->ops = chan->ops; | 780 | chan->ops = pchan->ops; |
781 | 781 | ||
782 | BT_DBG("chan %p pchan %p", chan, pchan); | 782 | BT_DBG("chan %p pchan %p", chan, pchan); |
783 | 783 | ||
784 | return pchan; | 784 | return chan; |
785 | } | 785 | } |
786 | 786 | ||
787 | static void delete_netdev(struct work_struct *work) | 787 | static void delete_netdev(struct work_struct *work) |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 1d9c29a00568..9b7145959a49 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1898,6 +1898,8 @@ static int __hci_init(struct hci_dev *hdev) | |||
1898 | debugfs_create_u16("discov_interleaved_timeout", 0644, | 1898 | debugfs_create_u16("discov_interleaved_timeout", 0644, |
1899 | hdev->debugfs, | 1899 | hdev->debugfs, |
1900 | &hdev->discov_interleaved_timeout); | 1900 | &hdev->discov_interleaved_timeout); |
1901 | |||
1902 | smp_register(hdev); | ||
1901 | } | 1903 | } |
1902 | 1904 | ||
1903 | return 0; | 1905 | return 0; |
@@ -3238,7 +3240,7 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) | |||
3238 | } | 3240 | } |
3239 | 3241 | ||
3240 | list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { | 3242 | list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { |
3241 | if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { | 3243 | if (smp_irk_matches(hdev, irk->val, rpa)) { |
3242 | bacpy(&irk->rpa, rpa); | 3244 | bacpy(&irk->rpa, rpa); |
3243 | return irk; | 3245 | return irk; |
3244 | } | 3246 | } |
@@ -3892,7 +3894,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, | |||
3892 | !bacmp(&hdev->random_addr, &hdev->rpa)) | 3894 | !bacmp(&hdev->random_addr, &hdev->rpa)) |
3893 | return 0; | 3895 | return 0; |
3894 | 3896 | ||
3895 | err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); | 3897 | err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); |
3896 | if (err < 0) { | 3898 | if (err < 0) { |
3897 | BT_ERR("%s failed to generate new RPA", hdev->name); | 3899 | BT_ERR("%s failed to generate new RPA", hdev->name); |
3898 | return err; | 3900 | return err; |
@@ -4100,18 +4102,9 @@ int hci_register_dev(struct hci_dev *hdev) | |||
4100 | 4102 | ||
4101 | dev_set_name(&hdev->dev, "%s", hdev->name); | 4103 | dev_set_name(&hdev->dev, "%s", hdev->name); |
4102 | 4104 | ||
4103 | hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, | ||
4104 | CRYPTO_ALG_ASYNC); | ||
4105 | if (IS_ERR(hdev->tfm_aes)) { | ||
4106 | BT_ERR("Unable to create crypto context"); | ||
4107 | error = PTR_ERR(hdev->tfm_aes); | ||
4108 | hdev->tfm_aes = NULL; | ||
4109 | goto err_wqueue; | ||
4110 | } | ||
4111 | |||
4112 | error = device_add(&hdev->dev); | 4105 | error = device_add(&hdev->dev); |
4113 | if (error < 0) | 4106 | if (error < 0) |
4114 | goto err_tfm; | 4107 | goto err_wqueue; |
4115 | 4108 | ||
4116 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, | 4109 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, |
4117 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, | 4110 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, |
@@ -4153,8 +4146,6 @@ int hci_register_dev(struct hci_dev *hdev) | |||
4153 | 4146 | ||
4154 | return id; | 4147 | return id; |
4155 | 4148 | ||
4156 | err_tfm: | ||
4157 | crypto_free_blkcipher(hdev->tfm_aes); | ||
4158 | err_wqueue: | 4149 | err_wqueue: |
4159 | destroy_workqueue(hdev->workqueue); | 4150 | destroy_workqueue(hdev->workqueue); |
4160 | destroy_workqueue(hdev->req_workqueue); | 4151 | destroy_workqueue(hdev->req_workqueue); |
@@ -4206,8 +4197,7 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
4206 | rfkill_destroy(hdev->rfkill); | 4197 | rfkill_destroy(hdev->rfkill); |
4207 | } | 4198 | } |
4208 | 4199 | ||
4209 | if (hdev->tfm_aes) | 4200 | smp_unregister(hdev); |
4210 | crypto_free_blkcipher(hdev->tfm_aes); | ||
4211 | 4201 | ||
4212 | device_del(&hdev->dev); | 4202 | device_del(&hdev->dev); |
4213 | 4203 | ||
@@ -5690,3 +5680,52 @@ void hci_update_background_scan(struct hci_dev *hdev) | |||
5690 | if (err) | 5680 | if (err) |
5691 | BT_ERR("Failed to run HCI request: err %d", err); | 5681 | BT_ERR("Failed to run HCI request: err %d", err); |
5692 | } | 5682 | } |
5683 | |||
5684 | static bool disconnected_whitelist_entries(struct hci_dev *hdev) | ||
5685 | { | ||
5686 | struct bdaddr_list *b; | ||
5687 | |||
5688 | list_for_each_entry(b, &hdev->whitelist, list) { | ||
5689 | struct hci_conn *conn; | ||
5690 | |||
5691 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr); | ||
5692 | if (!conn) | ||
5693 | return true; | ||
5694 | |||
5695 | if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) | ||
5696 | return true; | ||
5697 | } | ||
5698 | |||
5699 | return false; | ||
5700 | } | ||
5701 | |||
5702 | void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req) | ||
5703 | { | ||
5704 | u8 scan; | ||
5705 | |||
5706 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | ||
5707 | return; | ||
5708 | |||
5709 | if (!hdev_is_powered(hdev)) | ||
5710 | return; | ||
5711 | |||
5712 | if (mgmt_powering_down(hdev)) | ||
5713 | return; | ||
5714 | |||
5715 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || | ||
5716 | disconnected_whitelist_entries(hdev)) | ||
5717 | scan = SCAN_PAGE; | ||
5718 | else | ||
5719 | scan = SCAN_DISABLED; | ||
5720 | |||
5721 | if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE)) | ||
5722 | return; | ||
5723 | |||
5724 | if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | ||
5725 | scan |= SCAN_INQUIRY; | ||
5726 | |||
5727 | if (req) | ||
5728 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
5729 | else | ||
5730 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
5731 | } | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a6000823f0ff..3a99f30a3317 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2071,6 +2071,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2071 | cp.handle = ev->handle; | 2071 | cp.handle = ev->handle; |
2072 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, | 2072 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, |
2073 | sizeof(cp), &cp); | 2073 | sizeof(cp), &cp); |
2074 | |||
2075 | hci_update_page_scan(hdev, NULL); | ||
2074 | } | 2076 | } |
2075 | 2077 | ||
2076 | /* Set packet type for incoming connection */ | 2078 | /* Set packet type for incoming connection */ |
@@ -2247,9 +2249,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2247 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, | 2249 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, |
2248 | reason, mgmt_connected); | 2250 | reason, mgmt_connected); |
2249 | 2251 | ||
2250 | if (conn->type == ACL_LINK && | 2252 | if (conn->type == ACL_LINK) { |
2251 | test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) | 2253 | if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) |
2252 | hci_remove_link_key(hdev, &conn->dst); | 2254 | hci_remove_link_key(hdev, &conn->dst); |
2255 | |||
2256 | hci_update_page_scan(hdev, NULL); | ||
2257 | } | ||
2253 | 2258 | ||
2254 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); | 2259 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); |
2255 | if (params) { | 2260 | if (params) { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 46547b920f88..4a90438d99df 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -210,6 +210,10 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) | |||
210 | { | 210 | { |
211 | write_lock(&chan_list_lock); | 211 | write_lock(&chan_list_lock); |
212 | 212 | ||
213 | /* Override the defaults (which are for conn-oriented) */ | ||
214 | chan->omtu = L2CAP_DEFAULT_MTU; | ||
215 | chan->chan_type = L2CAP_CHAN_FIXED; | ||
216 | |||
213 | chan->scid = scid; | 217 | chan->scid = scid; |
214 | 218 | ||
215 | write_unlock(&chan_list_lock); | 219 | write_unlock(&chan_list_lock); |
@@ -562,6 +566,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
562 | 566 | ||
563 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); | 567 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); |
564 | 568 | ||
569 | chan->ops->teardown(chan, err); | ||
570 | |||
565 | if (conn) { | 571 | if (conn) { |
566 | struct amp_mgr *mgr = conn->hcon->amp_mgr; | 572 | struct amp_mgr *mgr = conn->hcon->amp_mgr; |
567 | /* Delete from channel list */ | 573 | /* Delete from channel list */ |
@@ -585,8 +591,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
585 | amp_disconnect_logical_link(hs_hchan); | 591 | amp_disconnect_logical_link(hs_hchan); |
586 | } | 592 | } |
587 | 593 | ||
588 | chan->ops->teardown(chan, err); | ||
589 | |||
590 | if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) | 594 | if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) |
591 | return; | 595 | return; |
592 | 596 | ||
@@ -1082,6 +1086,9 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) | |||
1082 | 1086 | ||
1083 | static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) | 1087 | static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) |
1084 | { | 1088 | { |
1089 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) | ||
1090 | return true; | ||
1091 | |||
1085 | return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); | 1092 | return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); |
1086 | } | 1093 | } |
1087 | 1094 | ||
@@ -1417,71 +1424,18 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
1417 | mutex_unlock(&conn->chan_lock); | 1424 | mutex_unlock(&conn->chan_lock); |
1418 | } | 1425 | } |
1419 | 1426 | ||
1420 | /* Find socket with cid and source/destination bdaddr. | ||
1421 | * Returns closest match, locked. | ||
1422 | */ | ||
1423 | static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, | ||
1424 | bdaddr_t *src, | ||
1425 | bdaddr_t *dst) | ||
1426 | { | ||
1427 | struct l2cap_chan *c, *c1 = NULL; | ||
1428 | |||
1429 | read_lock(&chan_list_lock); | ||
1430 | |||
1431 | list_for_each_entry(c, &chan_list, global_l) { | ||
1432 | if (state && c->state != state) | ||
1433 | continue; | ||
1434 | |||
1435 | if (c->scid == cid) { | ||
1436 | int src_match, dst_match; | ||
1437 | int src_any, dst_any; | ||
1438 | |||
1439 | /* Exact match. */ | ||
1440 | src_match = !bacmp(&c->src, src); | ||
1441 | dst_match = !bacmp(&c->dst, dst); | ||
1442 | if (src_match && dst_match) { | ||
1443 | read_unlock(&chan_list_lock); | ||
1444 | return c; | ||
1445 | } | ||
1446 | |||
1447 | /* Closest match */ | ||
1448 | src_any = !bacmp(&c->src, BDADDR_ANY); | ||
1449 | dst_any = !bacmp(&c->dst, BDADDR_ANY); | ||
1450 | if ((src_match && dst_any) || (src_any && dst_match) || | ||
1451 | (src_any && dst_any)) | ||
1452 | c1 = c; | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1456 | read_unlock(&chan_list_lock); | ||
1457 | |||
1458 | return c1; | ||
1459 | } | ||
1460 | |||
1461 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 1427 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
1462 | { | 1428 | { |
1463 | struct hci_conn *hcon = conn->hcon; | 1429 | struct hci_conn *hcon = conn->hcon; |
1464 | struct hci_dev *hdev = hcon->hdev; | 1430 | struct hci_dev *hdev = hcon->hdev; |
1465 | struct l2cap_chan *chan, *pchan; | ||
1466 | u8 dst_type; | ||
1467 | 1431 | ||
1468 | BT_DBG(""); | 1432 | BT_DBG("%s conn %p", hdev->name, conn); |
1469 | 1433 | ||
1470 | /* Check if we have socket listening on cid */ | 1434 | /* For outgoing pairing which doesn't necessarily have an |
1471 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, | 1435 | * associated socket (e.g. mgmt_pair_device). |
1472 | &hcon->src, &hcon->dst); | 1436 | */ |
1473 | if (!pchan) | 1437 | if (hcon->out) |
1474 | return; | 1438 | smp_conn_security(hcon, hcon->pending_sec_level); |
1475 | |||
1476 | /* Client ATT sockets should override the server one */ | ||
1477 | if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) | ||
1478 | return; | ||
1479 | |||
1480 | dst_type = bdaddr_type(hcon, hcon->dst_type); | ||
1481 | |||
1482 | /* If device is blocked, do not create a channel for it */ | ||
1483 | if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type)) | ||
1484 | return; | ||
1485 | 1439 | ||
1486 | /* For LE slave connections, make sure the connection interval | 1440 | /* For LE slave connections, make sure the connection interval |
1487 | * is in the range of the minium and maximum interval that has | 1441 | * is in the range of the minium and maximum interval that has |
@@ -1501,22 +1455,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1501 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 1455 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
1502 | L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req); | 1456 | L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req); |
1503 | } | 1457 | } |
1504 | |||
1505 | l2cap_chan_lock(pchan); | ||
1506 | |||
1507 | chan = pchan->ops->new_connection(pchan); | ||
1508 | if (!chan) | ||
1509 | goto clean; | ||
1510 | |||
1511 | bacpy(&chan->src, &hcon->src); | ||
1512 | bacpy(&chan->dst, &hcon->dst); | ||
1513 | chan->src_type = bdaddr_type(hcon, hcon->src_type); | ||
1514 | chan->dst_type = dst_type; | ||
1515 | |||
1516 | __l2cap_chan_add(conn, chan); | ||
1517 | |||
1518 | clean: | ||
1519 | l2cap_chan_unlock(pchan); | ||
1520 | } | 1458 | } |
1521 | 1459 | ||
1522 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 1460 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
@@ -1526,17 +1464,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1526 | 1464 | ||
1527 | BT_DBG("conn %p", conn); | 1465 | BT_DBG("conn %p", conn); |
1528 | 1466 | ||
1529 | /* For outgoing pairing which doesn't necessarily have an | ||
1530 | * associated socket (e.g. mgmt_pair_device). | ||
1531 | */ | ||
1532 | if (hcon->out && hcon->type == LE_LINK) | ||
1533 | smp_conn_security(hcon, hcon->pending_sec_level); | ||
1534 | |||
1535 | mutex_lock(&conn->chan_lock); | 1467 | mutex_lock(&conn->chan_lock); |
1536 | 1468 | ||
1537 | if (hcon->type == LE_LINK) | ||
1538 | l2cap_le_conn_ready(conn); | ||
1539 | |||
1540 | list_for_each_entry(chan, &conn->chan_l, list) { | 1469 | list_for_each_entry(chan, &conn->chan_l, list) { |
1541 | 1470 | ||
1542 | l2cap_chan_lock(chan); | 1471 | l2cap_chan_lock(chan); |
@@ -1560,6 +1489,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1560 | 1489 | ||
1561 | mutex_unlock(&conn->chan_lock); | 1490 | mutex_unlock(&conn->chan_lock); |
1562 | 1491 | ||
1492 | if (hcon->type == LE_LINK) | ||
1493 | l2cap_le_conn_ready(conn); | ||
1494 | |||
1563 | queue_work(hcon->hdev->workqueue, &conn->pending_rx_work); | 1495 | queue_work(hcon->hdev->workqueue, &conn->pending_rx_work); |
1564 | } | 1496 | } |
1565 | 1497 | ||
@@ -1695,6 +1627,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1695 | if (work_pending(&conn->pending_rx_work)) | 1627 | if (work_pending(&conn->pending_rx_work)) |
1696 | cancel_work_sync(&conn->pending_rx_work); | 1628 | cancel_work_sync(&conn->pending_rx_work); |
1697 | 1629 | ||
1630 | if (work_pending(&conn->disconn_work)) | ||
1631 | cancel_work_sync(&conn->disconn_work); | ||
1632 | |||
1698 | l2cap_unregister_all_users(conn); | 1633 | l2cap_unregister_all_users(conn); |
1699 | 1634 | ||
1700 | mutex_lock(&conn->chan_lock); | 1635 | mutex_lock(&conn->chan_lock); |
@@ -1719,27 +1654,29 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1719 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1654 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
1720 | cancel_delayed_work_sync(&conn->info_timer); | 1655 | cancel_delayed_work_sync(&conn->info_timer); |
1721 | 1656 | ||
1722 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { | ||
1723 | cancel_delayed_work_sync(&conn->security_timer); | ||
1724 | smp_chan_destroy(conn); | ||
1725 | } | ||
1726 | |||
1727 | hcon->l2cap_data = NULL; | 1657 | hcon->l2cap_data = NULL; |
1728 | conn->hchan = NULL; | 1658 | conn->hchan = NULL; |
1729 | l2cap_conn_put(conn); | 1659 | l2cap_conn_put(conn); |
1730 | } | 1660 | } |
1731 | 1661 | ||
1732 | static void security_timeout(struct work_struct *work) | 1662 | static void disconn_work(struct work_struct *work) |
1733 | { | 1663 | { |
1734 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, | 1664 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
1735 | security_timer.work); | 1665 | disconn_work); |
1736 | 1666 | ||
1737 | BT_DBG("conn %p", conn); | 1667 | BT_DBG("conn %p", conn); |
1738 | 1668 | ||
1739 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { | 1669 | l2cap_conn_del(conn->hcon, conn->disconn_err); |
1740 | smp_chan_destroy(conn); | 1670 | } |
1741 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | 1671 | |
1742 | } | 1672 | void l2cap_conn_shutdown(struct l2cap_conn *conn, int err) |
1673 | { | ||
1674 | struct hci_dev *hdev = conn->hcon->hdev; | ||
1675 | |||
1676 | BT_DBG("conn %p err %d", conn, err); | ||
1677 | |||
1678 | conn->disconn_err = err; | ||
1679 | queue_work(hdev->workqueue, &conn->disconn_work); | ||
1743 | } | 1680 | } |
1744 | 1681 | ||
1745 | static void l2cap_conn_free(struct kref *ref) | 1682 | static void l2cap_conn_free(struct kref *ref) |
@@ -1794,6 +1731,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, | |||
1794 | src_match = !bacmp(&c->src, src); | 1731 | src_match = !bacmp(&c->src, src); |
1795 | dst_match = !bacmp(&c->dst, dst); | 1732 | dst_match = !bacmp(&c->dst, dst); |
1796 | if (src_match && dst_match) { | 1733 | if (src_match && dst_match) { |
1734 | l2cap_chan_hold(c); | ||
1797 | read_unlock(&chan_list_lock); | 1735 | read_unlock(&chan_list_lock); |
1798 | return c; | 1736 | return c; |
1799 | } | 1737 | } |
@@ -1807,6 +1745,9 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, | |||
1807 | } | 1745 | } |
1808 | } | 1746 | } |
1809 | 1747 | ||
1748 | if (c1) | ||
1749 | l2cap_chan_hold(c1); | ||
1750 | |||
1810 | read_unlock(&chan_list_lock); | 1751 | read_unlock(&chan_list_lock); |
1811 | 1752 | ||
1812 | return c1; | 1753 | return c1; |
@@ -2027,10 +1968,12 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) | |||
2027 | tx_skb->data + L2CAP_HDR_SIZE); | 1968 | tx_skb->data + L2CAP_HDR_SIZE); |
2028 | } | 1969 | } |
2029 | 1970 | ||
1971 | /* Update FCS */ | ||
2030 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1972 | if (chan->fcs == L2CAP_FCS_CRC16) { |
2031 | u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len); | 1973 | u16 fcs = crc16(0, (u8 *) tx_skb->data, |
2032 | put_unaligned_le16(fcs, skb_put(tx_skb, | 1974 | tx_skb->len - L2CAP_FCS_SIZE); |
2033 | L2CAP_FCS_SIZE)); | 1975 | put_unaligned_le16(fcs, skb_tail_pointer(tx_skb) - |
1976 | L2CAP_FCS_SIZE); | ||
2034 | } | 1977 | } |
2035 | 1978 | ||
2036 | l2cap_do_send(chan, tx_skb); | 1979 | l2cap_do_send(chan, tx_skb); |
@@ -2334,7 +2277,6 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, | |||
2334 | } else { | 2277 | } else { |
2335 | sar = L2CAP_SAR_START; | 2278 | sar = L2CAP_SAR_START; |
2336 | sdu_len = len; | 2279 | sdu_len = len; |
2337 | pdu_len -= L2CAP_SDULEN_SIZE; | ||
2338 | } | 2280 | } |
2339 | 2281 | ||
2340 | while (len > 0) { | 2282 | while (len > 0) { |
@@ -2349,10 +2291,8 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, | |||
2349 | __skb_queue_tail(seg_queue, skb); | 2291 | __skb_queue_tail(seg_queue, skb); |
2350 | 2292 | ||
2351 | len -= pdu_len; | 2293 | len -= pdu_len; |
2352 | if (sdu_len) { | 2294 | if (sdu_len) |
2353 | sdu_len = 0; | 2295 | sdu_len = 0; |
2354 | pdu_len += L2CAP_SDULEN_SIZE; | ||
2355 | } | ||
2356 | 2296 | ||
2357 | if (len <= pdu_len) { | 2297 | if (len <= pdu_len) { |
2358 | sar = L2CAP_SAR_END; | 2298 | sar = L2CAP_SAR_END; |
@@ -3884,6 +3824,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3884 | response: | 3824 | response: |
3885 | l2cap_chan_unlock(pchan); | 3825 | l2cap_chan_unlock(pchan); |
3886 | mutex_unlock(&conn->chan_lock); | 3826 | mutex_unlock(&conn->chan_lock); |
3827 | l2cap_chan_put(pchan); | ||
3887 | 3828 | ||
3888 | sendresp: | 3829 | sendresp: |
3889 | rsp.scid = cpu_to_le16(scid); | 3830 | rsp.scid = cpu_to_le16(scid); |
@@ -5497,6 +5438,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, | |||
5497 | response_unlock: | 5438 | response_unlock: |
5498 | l2cap_chan_unlock(pchan); | 5439 | l2cap_chan_unlock(pchan); |
5499 | mutex_unlock(&conn->chan_lock); | 5440 | mutex_unlock(&conn->chan_lock); |
5441 | l2cap_chan_put(pchan); | ||
5500 | 5442 | ||
5501 | if (result == L2CAP_CR_PEND) | 5443 | if (result == L2CAP_CR_PEND) |
5502 | return 0; | 5444 | return 0; |
@@ -6845,12 +6787,12 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | |||
6845 | struct l2cap_chan *chan; | 6787 | struct l2cap_chan *chan; |
6846 | 6788 | ||
6847 | if (hcon->type != ACL_LINK) | 6789 | if (hcon->type != ACL_LINK) |
6848 | goto drop; | 6790 | goto free_skb; |
6849 | 6791 | ||
6850 | chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst, | 6792 | chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst, |
6851 | ACL_LINK); | 6793 | ACL_LINK); |
6852 | if (!chan) | 6794 | if (!chan) |
6853 | goto drop; | 6795 | goto free_skb; |
6854 | 6796 | ||
6855 | BT_DBG("chan %p, len %d", chan, skb->len); | 6797 | BT_DBG("chan %p, len %d", chan, skb->len); |
6856 | 6798 | ||
@@ -6864,36 +6806,14 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | |||
6864 | bacpy(&bt_cb(skb)->bdaddr, &hcon->dst); | 6806 | bacpy(&bt_cb(skb)->bdaddr, &hcon->dst); |
6865 | bt_cb(skb)->psm = psm; | 6807 | bt_cb(skb)->psm = psm; |
6866 | 6808 | ||
6867 | if (!chan->ops->recv(chan, skb)) | 6809 | if (!chan->ops->recv(chan, skb)) { |
6868 | return; | 6810 | l2cap_chan_put(chan); |
6869 | |||
6870 | drop: | ||
6871 | kfree_skb(skb); | ||
6872 | } | ||
6873 | |||
6874 | static void l2cap_att_channel(struct l2cap_conn *conn, | ||
6875 | struct sk_buff *skb) | ||
6876 | { | ||
6877 | struct hci_conn *hcon = conn->hcon; | ||
6878 | struct l2cap_chan *chan; | ||
6879 | |||
6880 | if (hcon->type != LE_LINK) | ||
6881 | goto drop; | ||
6882 | |||
6883 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, | ||
6884 | &hcon->src, &hcon->dst); | ||
6885 | if (!chan) | ||
6886 | goto drop; | ||
6887 | |||
6888 | BT_DBG("chan %p, len %d", chan, skb->len); | ||
6889 | |||
6890 | if (chan->imtu < skb->len) | ||
6891 | goto drop; | ||
6892 | |||
6893 | if (!chan->ops->recv(chan, skb)) | ||
6894 | return; | 6811 | return; |
6812 | } | ||
6895 | 6813 | ||
6896 | drop: | 6814 | drop: |
6815 | l2cap_chan_put(chan); | ||
6816 | free_skb: | ||
6897 | kfree_skb(skb); | 6817 | kfree_skb(skb); |
6898 | } | 6818 | } |
6899 | 6819 | ||
@@ -6942,19 +6862,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6942 | l2cap_conless_channel(conn, psm, skb); | 6862 | l2cap_conless_channel(conn, psm, skb); |
6943 | break; | 6863 | break; |
6944 | 6864 | ||
6945 | case L2CAP_CID_ATT: | ||
6946 | l2cap_att_channel(conn, skb); | ||
6947 | break; | ||
6948 | |||
6949 | case L2CAP_CID_LE_SIGNALING: | 6865 | case L2CAP_CID_LE_SIGNALING: |
6950 | l2cap_le_sig_channel(conn, skb); | 6866 | l2cap_le_sig_channel(conn, skb); |
6951 | break; | 6867 | break; |
6952 | 6868 | ||
6953 | case L2CAP_CID_SMP: | ||
6954 | if (smp_sig_channel(conn, skb)) | ||
6955 | l2cap_conn_del(conn->hcon, EACCES); | ||
6956 | break; | ||
6957 | |||
6958 | default: | 6869 | default: |
6959 | l2cap_data_channel(conn, cid, skb); | 6870 | l2cap_data_channel(conn, cid, skb); |
6960 | break; | 6871 | break; |
@@ -7023,10 +6934,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) | |||
7023 | INIT_LIST_HEAD(&conn->chan_l); | 6934 | INIT_LIST_HEAD(&conn->chan_l); |
7024 | INIT_LIST_HEAD(&conn->users); | 6935 | INIT_LIST_HEAD(&conn->users); |
7025 | 6936 | ||
7026 | if (hcon->type == LE_LINK) | 6937 | INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); |
7027 | INIT_DELAYED_WORK(&conn->security_timer, security_timeout); | 6938 | |
7028 | else | 6939 | INIT_WORK(&conn->disconn_work, disconn_work); |
7029 | INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); | ||
7030 | 6940 | ||
7031 | skb_queue_head_init(&conn->pending_rx); | 6941 | skb_queue_head_init(&conn->pending_rx); |
7032 | INIT_WORK(&conn->pending_rx_work, process_pending_rx); | 6942 | INIT_WORK(&conn->pending_rx_work, process_pending_rx); |
@@ -7239,19 +7149,99 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
7239 | return exact ? lm1 : lm2; | 7149 | return exact ? lm1 : lm2; |
7240 | } | 7150 | } |
7241 | 7151 | ||
7152 | /* Find the next fixed channel in BT_LISTEN state, continue iteration | ||
7153 | * from an existing channel in the list or from the beginning of the | ||
7154 | * global list (by passing NULL as first parameter). | ||
7155 | */ | ||
7156 | static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, | ||
7157 | bdaddr_t *src, u8 link_type) | ||
7158 | { | ||
7159 | read_lock(&chan_list_lock); | ||
7160 | |||
7161 | if (c) | ||
7162 | c = list_next_entry(c, global_l); | ||
7163 | else | ||
7164 | c = list_entry(chan_list.next, typeof(*c), global_l); | ||
7165 | |||
7166 | list_for_each_entry_from(c, &chan_list, global_l) { | ||
7167 | if (c->chan_type != L2CAP_CHAN_FIXED) | ||
7168 | continue; | ||
7169 | if (c->state != BT_LISTEN) | ||
7170 | continue; | ||
7171 | if (bacmp(&c->src, src) && bacmp(&c->src, BDADDR_ANY)) | ||
7172 | continue; | ||
7173 | if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR) | ||
7174 | continue; | ||
7175 | if (link_type == LE_LINK && c->src_type == BDADDR_BREDR) | ||
7176 | continue; | ||
7177 | |||
7178 | l2cap_chan_hold(c); | ||
7179 | read_unlock(&chan_list_lock); | ||
7180 | return c; | ||
7181 | } | ||
7182 | |||
7183 | read_unlock(&chan_list_lock); | ||
7184 | |||
7185 | return NULL; | ||
7186 | } | ||
7187 | |||
7242 | void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | 7188 | void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) |
7243 | { | 7189 | { |
7190 | struct hci_dev *hdev = hcon->hdev; | ||
7244 | struct l2cap_conn *conn; | 7191 | struct l2cap_conn *conn; |
7192 | struct l2cap_chan *pchan; | ||
7193 | u8 dst_type; | ||
7245 | 7194 | ||
7246 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); | 7195 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); |
7247 | 7196 | ||
7248 | if (!status) { | 7197 | if (status) { |
7249 | conn = l2cap_conn_add(hcon); | ||
7250 | if (conn) | ||
7251 | l2cap_conn_ready(conn); | ||
7252 | } else { | ||
7253 | l2cap_conn_del(hcon, bt_to_errno(status)); | 7198 | l2cap_conn_del(hcon, bt_to_errno(status)); |
7199 | return; | ||
7254 | } | 7200 | } |
7201 | |||
7202 | conn = l2cap_conn_add(hcon); | ||
7203 | if (!conn) | ||
7204 | return; | ||
7205 | |||
7206 | dst_type = bdaddr_type(hcon, hcon->dst_type); | ||
7207 | |||
7208 | /* If device is blocked, do not create channels for it */ | ||
7209 | if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type)) | ||
7210 | return; | ||
7211 | |||
7212 | /* Find fixed channels and notify them of the new connection. We | ||
7213 | * use multiple individual lookups, continuing each time where | ||
7214 | * we left off, because the list lock would prevent calling the | ||
7215 | * potentially sleeping l2cap_chan_lock() function. | ||
7216 | */ | ||
7217 | pchan = l2cap_global_fixed_chan(NULL, &hdev->bdaddr, hcon->type); | ||
7218 | while (pchan) { | ||
7219 | struct l2cap_chan *chan, *next; | ||
7220 | |||
7221 | /* Client fixed channels should override server ones */ | ||
7222 | if (__l2cap_get_chan_by_dcid(conn, pchan->scid)) | ||
7223 | goto next; | ||
7224 | |||
7225 | l2cap_chan_lock(pchan); | ||
7226 | chan = pchan->ops->new_connection(pchan); | ||
7227 | if (chan) { | ||
7228 | bacpy(&chan->src, &hcon->src); | ||
7229 | bacpy(&chan->dst, &hcon->dst); | ||
7230 | chan->src_type = bdaddr_type(hcon, hcon->src_type); | ||
7231 | chan->dst_type = dst_type; | ||
7232 | |||
7233 | __l2cap_chan_add(conn, chan); | ||
7234 | } | ||
7235 | |||
7236 | l2cap_chan_unlock(pchan); | ||
7237 | next: | ||
7238 | next = l2cap_global_fixed_chan(pchan, &hdev->bdaddr, | ||
7239 | hcon->type); | ||
7240 | l2cap_chan_put(pchan); | ||
7241 | pchan = next; | ||
7242 | } | ||
7243 | |||
7244 | l2cap_conn_ready(conn); | ||
7255 | } | 7245 | } |
7256 | 7246 | ||
7257 | int l2cap_disconn_ind(struct hci_conn *hcon) | 7247 | int l2cap_disconn_ind(struct hci_conn *hcon) |
@@ -7299,12 +7289,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
7299 | 7289 | ||
7300 | BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); | 7290 | BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); |
7301 | 7291 | ||
7302 | if (hcon->type == LE_LINK) { | ||
7303 | if (!status && encrypt) | ||
7304 | smp_distribute_keys(conn); | ||
7305 | cancel_delayed_work(&conn->security_timer); | ||
7306 | } | ||
7307 | |||
7308 | mutex_lock(&conn->chan_lock); | 7292 | mutex_lock(&conn->chan_lock); |
7309 | 7293 | ||
7310 | list_for_each_entry(chan, &conn->chan_l, list) { | 7294 | list_for_each_entry(chan, &conn->chan_l, list) { |
@@ -7318,15 +7302,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
7318 | continue; | 7302 | continue; |
7319 | } | 7303 | } |
7320 | 7304 | ||
7321 | if (chan->scid == L2CAP_CID_ATT) { | 7305 | if (!status && encrypt) |
7322 | if (!status && encrypt) { | 7306 | chan->sec_level = hcon->sec_level; |
7323 | chan->sec_level = hcon->sec_level; | ||
7324 | l2cap_chan_ready(chan); | ||
7325 | } | ||
7326 | |||
7327 | l2cap_chan_unlock(chan); | ||
7328 | continue; | ||
7329 | } | ||
7330 | 7307 | ||
7331 | if (!__l2cap_no_conn_pending(chan)) { | 7308 | if (!__l2cap_no_conn_pending(chan)) { |
7332 | l2cap_chan_unlock(chan); | 7309 | l2cap_chan_unlock(chan); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1884f72083c2..ed06f88e6f10 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -99,15 +99,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
99 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) | 99 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) |
100 | return -EINVAL; | 100 | return -EINVAL; |
101 | 101 | ||
102 | if (la.l2_cid) { | ||
103 | /* When the socket gets created it defaults to | ||
104 | * CHAN_CONN_ORIENTED, so we need to overwrite the | ||
105 | * default here. | ||
106 | */ | ||
107 | chan->chan_type = L2CAP_CHAN_FIXED; | ||
108 | chan->omtu = L2CAP_DEFAULT_MTU; | ||
109 | } | ||
110 | |||
111 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { | 102 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { |
112 | /* We only allow ATT user space socket */ | 103 | /* We only allow ATT user space socket */ |
113 | if (la.l2_cid && | 104 | if (la.l2_cid && |
@@ -790,6 +781,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |||
790 | if (chan->scid == L2CAP_CID_ATT) { | 781 | if (chan->scid == L2CAP_CID_ATT) { |
791 | if (smp_conn_security(conn->hcon, sec.level)) | 782 | if (smp_conn_security(conn->hcon, sec.level)) |
792 | break; | 783 | break; |
784 | set_bit(FLAG_PENDING_SECURITY, &chan->flags); | ||
793 | sk->sk_state = BT_CONFIG; | 785 | sk->sk_state = BT_CONFIG; |
794 | chan->state = BT_CONFIG; | 786 | chan->state = BT_CONFIG; |
795 | 787 | ||
@@ -1359,6 +1351,11 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) | |||
1359 | { | 1351 | { |
1360 | struct sock *sk = chan->data; | 1352 | struct sock *sk = chan->data; |
1361 | 1353 | ||
1354 | if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) { | ||
1355 | sk->sk_state = BT_CONNECTED; | ||
1356 | chan->state = BT_CONNECTED; | ||
1357 | } | ||
1358 | |||
1362 | clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); | 1359 | clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); |
1363 | sk->sk_state_change(sk); | 1360 | sk->sk_state_change(sk); |
1364 | } | 1361 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b8554d429d88..c2457435a670 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -129,9 +129,6 @@ static const u16 mgmt_events[] = { | |||
129 | 129 | ||
130 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) | 130 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) |
131 | 131 | ||
132 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ | ||
133 | !test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | ||
134 | |||
135 | struct pending_cmd { | 132 | struct pending_cmd { |
136 | struct list_head list; | 133 | struct list_head list; |
137 | u16 opcode; | 134 | u16 opcode; |
@@ -1536,9 +1533,11 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status) | |||
1536 | 1533 | ||
1537 | /* When the discoverable mode gets changed, make sure | 1534 | /* When the discoverable mode gets changed, make sure |
1538 | * that class of device has the limited discoverable | 1535 | * that class of device has the limited discoverable |
1539 | * bit correctly set. | 1536 | * bit correctly set. Also update page scan based on whitelist |
1537 | * entries. | ||
1540 | */ | 1538 | */ |
1541 | hci_req_init(&req, hdev); | 1539 | hci_req_init(&req, hdev); |
1540 | hci_update_page_scan(hdev, &req); | ||
1542 | update_class(&req); | 1541 | update_class(&req); |
1543 | hci_req_run(&req, NULL); | 1542 | hci_req_run(&req, NULL); |
1544 | 1543 | ||
@@ -1785,6 +1784,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status) | |||
1785 | 1784 | ||
1786 | if (conn_changed || discov_changed) { | 1785 | if (conn_changed || discov_changed) { |
1787 | new_settings(hdev, cmd->sk); | 1786 | new_settings(hdev, cmd->sk); |
1787 | hci_update_page_scan(hdev, NULL); | ||
1788 | if (discov_changed) | 1788 | if (discov_changed) |
1789 | mgmt_update_adv_data(hdev); | 1789 | mgmt_update_adv_data(hdev); |
1790 | hci_update_background_scan(hdev); | 1790 | hci_update_background_scan(hdev); |
@@ -1818,6 +1818,7 @@ static int set_connectable_update_settings(struct hci_dev *hdev, | |||
1818 | return err; | 1818 | return err; |
1819 | 1819 | ||
1820 | if (changed) { | 1820 | if (changed) { |
1821 | hci_update_page_scan(hdev, NULL); | ||
1821 | hci_update_background_scan(hdev); | 1822 | hci_update_background_scan(hdev); |
1822 | return new_settings(hdev, sk); | 1823 | return new_settings(hdev, sk); |
1823 | } | 1824 | } |
@@ -4381,27 +4382,6 @@ unlock: | |||
4381 | return err; | 4382 | return err; |
4382 | } | 4383 | } |
4383 | 4384 | ||
4384 | static void set_bredr_scan(struct hci_request *req) | ||
4385 | { | ||
4386 | struct hci_dev *hdev = req->hdev; | ||
4387 | u8 scan = 0; | ||
4388 | |||
4389 | /* Ensure that fast connectable is disabled. This function will | ||
4390 | * not do anything if the page scan parameters are already what | ||
4391 | * they should be. | ||
4392 | */ | ||
4393 | write_fast_connectable(req, false); | ||
4394 | |||
4395 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || | ||
4396 | !list_empty(&hdev->whitelist)) | ||
4397 | scan |= SCAN_PAGE; | ||
4398 | if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | ||
4399 | scan |= SCAN_INQUIRY; | ||
4400 | |||
4401 | if (scan) | ||
4402 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
4403 | } | ||
4404 | |||
4405 | static void set_bredr_complete(struct hci_dev *hdev, u8 status) | 4385 | static void set_bredr_complete(struct hci_dev *hdev, u8 status) |
4406 | { | 4386 | { |
4407 | struct pending_cmd *cmd; | 4387 | struct pending_cmd *cmd; |
@@ -4507,9 +4487,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
4507 | 4487 | ||
4508 | hci_req_init(&req, hdev); | 4488 | hci_req_init(&req, hdev); |
4509 | 4489 | ||
4510 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || | 4490 | write_fast_connectable(&req, false); |
4511 | !list_empty(&hdev->whitelist)) | 4491 | hci_update_page_scan(hdev, &req); |
4512 | set_bredr_scan(&req); | ||
4513 | 4492 | ||
4514 | /* Since only the advertising data flags will change, there | 4493 | /* Since only the advertising data flags will change, there |
4515 | * is no need to update the scan response data. | 4494 | * is no need to update the scan response data. |
@@ -5235,27 +5214,6 @@ unlock: | |||
5235 | return err; | 5214 | return err; |
5236 | } | 5215 | } |
5237 | 5216 | ||
5238 | /* Helper for Add/Remove Device commands */ | ||
5239 | static void update_page_scan(struct hci_dev *hdev, u8 scan) | ||
5240 | { | ||
5241 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | ||
5242 | return; | ||
5243 | |||
5244 | if (!hdev_is_powered(hdev)) | ||
5245 | return; | ||
5246 | |||
5247 | /* If HCI_CONNECTABLE is set then Add/Remove Device should not | ||
5248 | * make any changes to page scanning. | ||
5249 | */ | ||
5250 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | ||
5251 | return; | ||
5252 | |||
5253 | if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | ||
5254 | scan |= SCAN_INQUIRY; | ||
5255 | |||
5256 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
5257 | } | ||
5258 | |||
5259 | static void device_added(struct sock *sk, struct hci_dev *hdev, | 5217 | static void device_added(struct sock *sk, struct hci_dev *hdev, |
5260 | bdaddr_t *bdaddr, u8 type, u8 action) | 5218 | bdaddr_t *bdaddr, u8 type, u8 action) |
5261 | { | 5219 | { |
@@ -5291,8 +5249,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
5291 | hci_dev_lock(hdev); | 5249 | hci_dev_lock(hdev); |
5292 | 5250 | ||
5293 | if (cp->addr.type == BDADDR_BREDR) { | 5251 | if (cp->addr.type == BDADDR_BREDR) { |
5294 | bool update_scan; | ||
5295 | |||
5296 | /* Only incoming connections action is supported for now */ | 5252 | /* Only incoming connections action is supported for now */ |
5297 | if (cp->action != 0x01) { | 5253 | if (cp->action != 0x01) { |
5298 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5254 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, |
@@ -5301,15 +5257,12 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
5301 | goto unlock; | 5257 | goto unlock; |
5302 | } | 5258 | } |
5303 | 5259 | ||
5304 | update_scan = list_empty(&hdev->whitelist); | ||
5305 | |||
5306 | err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr, | 5260 | err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr, |
5307 | cp->addr.type); | 5261 | cp->addr.type); |
5308 | if (err) | 5262 | if (err) |
5309 | goto unlock; | 5263 | goto unlock; |
5310 | 5264 | ||
5311 | if (update_scan) | 5265 | hci_update_page_scan(hdev, NULL); |
5312 | update_page_scan(hdev, SCAN_PAGE); | ||
5313 | 5266 | ||
5314 | goto added; | 5267 | goto added; |
5315 | } | 5268 | } |
@@ -5392,8 +5345,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
5392 | goto unlock; | 5345 | goto unlock; |
5393 | } | 5346 | } |
5394 | 5347 | ||
5395 | if (list_empty(&hdev->whitelist)) | 5348 | hci_update_page_scan(hdev, NULL); |
5396 | update_page_scan(hdev, SCAN_DISABLED); | ||
5397 | 5349 | ||
5398 | device_removed(sk, hdev, &cp->addr.bdaddr, | 5350 | device_removed(sk, hdev, &cp->addr.bdaddr, |
5399 | cp->addr.type); | 5351 | cp->addr.type); |
@@ -5444,7 +5396,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
5444 | kfree(b); | 5396 | kfree(b); |
5445 | } | 5397 | } |
5446 | 5398 | ||
5447 | update_page_scan(hdev, SCAN_DISABLED); | 5399 | hci_update_page_scan(hdev, NULL); |
5448 | 5400 | ||
5449 | list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { | 5401 | list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { |
5450 | if (p->auto_connect == HCI_AUTO_CONN_DISABLED) | 5402 | if (p->auto_connect == HCI_AUTO_CONN_DISABLED) |
@@ -5969,8 +5921,8 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
5969 | sizeof(link_sec), &link_sec); | 5921 | sizeof(link_sec), &link_sec); |
5970 | 5922 | ||
5971 | if (lmp_bredr_capable(hdev)) { | 5923 | if (lmp_bredr_capable(hdev)) { |
5972 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | 5924 | write_fast_connectable(&req, false); |
5973 | set_bredr_scan(&req); | 5925 | hci_update_page_scan(hdev, &req); |
5974 | update_class(&req); | 5926 | update_class(&req); |
5975 | update_name(&req); | 5927 | update_name(&req); |
5976 | update_eir(&req); | 5928 | update_eir(&req); |
@@ -6281,25 +6233,35 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data) | |||
6281 | mgmt_pending_remove(cmd); | 6233 | mgmt_pending_remove(cmd); |
6282 | } | 6234 | } |
6283 | 6235 | ||
6236 | bool mgmt_powering_down(struct hci_dev *hdev) | ||
6237 | { | ||
6238 | struct pending_cmd *cmd; | ||
6239 | struct mgmt_mode *cp; | ||
6240 | |||
6241 | cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | ||
6242 | if (!cmd) | ||
6243 | return false; | ||
6244 | |||
6245 | cp = cmd->param; | ||
6246 | if (!cp->val) | ||
6247 | return true; | ||
6248 | |||
6249 | return false; | ||
6250 | } | ||
6251 | |||
6284 | void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, | 6252 | void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, |
6285 | u8 link_type, u8 addr_type, u8 reason, | 6253 | u8 link_type, u8 addr_type, u8 reason, |
6286 | bool mgmt_connected) | 6254 | bool mgmt_connected) |
6287 | { | 6255 | { |
6288 | struct mgmt_ev_device_disconnected ev; | 6256 | struct mgmt_ev_device_disconnected ev; |
6289 | struct pending_cmd *power_off; | ||
6290 | struct sock *sk = NULL; | 6257 | struct sock *sk = NULL; |
6291 | 6258 | ||
6292 | power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | 6259 | /* The connection is still in hci_conn_hash so test for 1 |
6293 | if (power_off) { | 6260 | * instead of 0 to know if this is the last one. |
6294 | struct mgmt_mode *cp = power_off->param; | 6261 | */ |
6295 | 6262 | if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { | |
6296 | /* The connection is still in hci_conn_hash so test for 1 | 6263 | cancel_delayed_work(&hdev->power_off); |
6297 | * instead of 0 to know if this is the last one. | 6264 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
6298 | */ | ||
6299 | if (!cp->val && hci_conn_count(hdev) == 1) { | ||
6300 | cancel_delayed_work(&hdev->power_off); | ||
6301 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | ||
6302 | } | ||
6303 | } | 6265 | } |
6304 | 6266 | ||
6305 | if (!mgmt_connected) | 6267 | if (!mgmt_connected) |
@@ -6359,19 +6321,13 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
6359 | u8 addr_type, u8 status) | 6321 | u8 addr_type, u8 status) |
6360 | { | 6322 | { |
6361 | struct mgmt_ev_connect_failed ev; | 6323 | struct mgmt_ev_connect_failed ev; |
6362 | struct pending_cmd *power_off; | ||
6363 | |||
6364 | power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | ||
6365 | if (power_off) { | ||
6366 | struct mgmt_mode *cp = power_off->param; | ||
6367 | 6324 | ||
6368 | /* The connection is still in hci_conn_hash so test for 1 | 6325 | /* The connection is still in hci_conn_hash so test for 1 |
6369 | * instead of 0 to know if this is the last one. | 6326 | * instead of 0 to know if this is the last one. |
6370 | */ | 6327 | */ |
6371 | if (!cp->val && hci_conn_count(hdev) == 1) { | 6328 | if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { |
6372 | cancel_delayed_work(&hdev->power_off); | 6329 | cancel_delayed_work(&hdev->power_off); |
6373 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | 6330 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
6374 | } | ||
6375 | } | 6331 | } |
6376 | 6332 | ||
6377 | bacpy(&ev.addr.bdaddr, bdaddr); | 6333 | bacpy(&ev.addr.bdaddr, bdaddr); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fd3294300803..07ca4ce0943b 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -44,7 +44,10 @@ enum { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct smp_chan { | 46 | struct smp_chan { |
47 | struct l2cap_conn *conn; | 47 | struct l2cap_conn *conn; |
48 | struct delayed_work security_timer; | ||
49 | struct work_struct distribute_work; | ||
50 | |||
48 | u8 preq[7]; /* SMP Pairing Request */ | 51 | u8 preq[7]; /* SMP Pairing Request */ |
49 | u8 prsp[7]; /* SMP Pairing Response */ | 52 | u8 prsp[7]; /* SMP Pairing Response */ |
50 | u8 prnd[16]; /* SMP Pairing Random (local) */ | 53 | u8 prnd[16]; /* SMP Pairing Random (local) */ |
@@ -139,12 +142,18 @@ static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) | |||
139 | return 0; | 142 | return 0; |
140 | } | 143 | } |
141 | 144 | ||
142 | bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], | 145 | bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr) |
143 | bdaddr_t *bdaddr) | ||
144 | { | 146 | { |
147 | struct l2cap_chan *chan = hdev->smp_data; | ||
148 | struct crypto_blkcipher *tfm; | ||
145 | u8 hash[3]; | 149 | u8 hash[3]; |
146 | int err; | 150 | int err; |
147 | 151 | ||
152 | if (!chan || !chan->data) | ||
153 | return false; | ||
154 | |||
155 | tfm = chan->data; | ||
156 | |||
148 | BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); | 157 | BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); |
149 | 158 | ||
150 | err = smp_ah(tfm, irk, &bdaddr->b[3], hash); | 159 | err = smp_ah(tfm, irk, &bdaddr->b[3], hash); |
@@ -154,10 +163,17 @@ bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], | |||
154 | return !memcmp(bdaddr->b, hash, 3); | 163 | return !memcmp(bdaddr->b, hash, 3); |
155 | } | 164 | } |
156 | 165 | ||
157 | int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa) | 166 | int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa) |
158 | { | 167 | { |
168 | struct l2cap_chan *chan = hdev->smp_data; | ||
169 | struct crypto_blkcipher *tfm; | ||
159 | int err; | 170 | int err; |
160 | 171 | ||
172 | if (!chan || !chan->data) | ||
173 | return -EOPNOTSUPP; | ||
174 | |||
175 | tfm = chan->data; | ||
176 | |||
161 | get_random_bytes(&rpa->b[3], 3); | 177 | get_random_bytes(&rpa->b[3], 3); |
162 | 178 | ||
163 | rpa->b[5] &= 0x3f; /* Clear two most significant bits */ | 179 | rpa->b[5] &= 0x3f; /* Clear two most significant bits */ |
@@ -235,47 +251,39 @@ static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], | |||
235 | return err; | 251 | return err; |
236 | } | 252 | } |
237 | 253 | ||
238 | static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, | 254 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) |
239 | u16 dlen, void *data) | ||
240 | { | 255 | { |
241 | struct sk_buff *skb; | 256 | struct l2cap_chan *chan = conn->smp; |
242 | struct l2cap_hdr *lh; | 257 | struct smp_chan *smp; |
243 | int len; | 258 | struct kvec iv[2]; |
244 | 259 | struct msghdr msg; | |
245 | len = L2CAP_HDR_SIZE + sizeof(code) + dlen; | ||
246 | |||
247 | if (len > conn->mtu) | ||
248 | return NULL; | ||
249 | 260 | ||
250 | skb = bt_skb_alloc(len, GFP_ATOMIC); | 261 | if (!chan) |
251 | if (!skb) | 262 | return; |
252 | return NULL; | ||
253 | 263 | ||
254 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 264 | BT_DBG("code 0x%2.2x", code); |
255 | lh->len = cpu_to_le16(sizeof(code) + dlen); | ||
256 | lh->cid = cpu_to_le16(L2CAP_CID_SMP); | ||
257 | 265 | ||
258 | memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); | 266 | iv[0].iov_base = &code; |
267 | iv[0].iov_len = 1; | ||
259 | 268 | ||
260 | memcpy(skb_put(skb, dlen), data, dlen); | 269 | iv[1].iov_base = data; |
270 | iv[1].iov_len = len; | ||
261 | 271 | ||
262 | return skb; | 272 | memset(&msg, 0, sizeof(msg)); |
263 | } | ||
264 | 273 | ||
265 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | 274 | msg.msg_iov = (struct iovec *) &iv; |
266 | { | 275 | msg.msg_iovlen = 2; |
267 | struct sk_buff *skb = smp_build_cmd(conn, code, len, data); | ||
268 | 276 | ||
269 | BT_DBG("code 0x%2.2x", code); | 277 | l2cap_chan_send(chan, &msg, 1 + len); |
270 | 278 | ||
271 | if (!skb) | 279 | if (!chan->data) |
272 | return; | 280 | return; |
273 | 281 | ||
274 | skb->priority = HCI_PRIO_MAX; | 282 | smp = chan->data; |
275 | hci_send_acl(conn->hchan, skb, 0); | ||
276 | 283 | ||
277 | cancel_delayed_work_sync(&conn->security_timer); | 284 | cancel_delayed_work_sync(&smp->security_timer); |
278 | schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT); | 285 | if (test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) |
286 | schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); | ||
279 | } | 287 | } |
280 | 288 | ||
281 | static __u8 authreq_to_seclevel(__u8 authreq) | 289 | static __u8 authreq_to_seclevel(__u8 authreq) |
@@ -302,7 +310,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
302 | struct smp_cmd_pairing *req, | 310 | struct smp_cmd_pairing *req, |
303 | struct smp_cmd_pairing *rsp, __u8 authreq) | 311 | struct smp_cmd_pairing *rsp, __u8 authreq) |
304 | { | 312 | { |
305 | struct smp_chan *smp = conn->smp_chan; | 313 | struct l2cap_chan *chan = conn->smp; |
314 | struct smp_chan *smp = chan->data; | ||
306 | struct hci_conn *hcon = conn->hcon; | 315 | struct hci_conn *hcon = conn->hcon; |
307 | struct hci_dev *hdev = hcon->hdev; | 316 | struct hci_dev *hdev = hcon->hdev; |
308 | u8 local_dist = 0, remote_dist = 0; | 317 | u8 local_dist = 0, remote_dist = 0; |
@@ -345,7 +354,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
345 | 354 | ||
346 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | 355 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) |
347 | { | 356 | { |
348 | struct smp_chan *smp = conn->smp_chan; | 357 | struct l2cap_chan *chan = conn->smp; |
358 | struct smp_chan *smp = chan->data; | ||
349 | 359 | ||
350 | if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || | 360 | if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || |
351 | (max_key_size < SMP_MIN_ENC_KEY_SIZE)) | 361 | (max_key_size < SMP_MIN_ENC_KEY_SIZE)) |
@@ -356,9 +366,61 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | |||
356 | return 0; | 366 | return 0; |
357 | } | 367 | } |
358 | 368 | ||
369 | static void smp_chan_destroy(struct l2cap_conn *conn) | ||
370 | { | ||
371 | struct l2cap_chan *chan = conn->smp; | ||
372 | struct smp_chan *smp = chan->data; | ||
373 | bool complete; | ||
374 | |||
375 | BUG_ON(!smp); | ||
376 | |||
377 | cancel_delayed_work_sync(&smp->security_timer); | ||
378 | /* In case the timeout freed the SMP context */ | ||
379 | if (!chan->data) | ||
380 | return; | ||
381 | |||
382 | if (work_pending(&smp->distribute_work)) { | ||
383 | cancel_work_sync(&smp->distribute_work); | ||
384 | if (!chan->data) | ||
385 | return; | ||
386 | } | ||
387 | |||
388 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
389 | mgmt_smp_complete(conn->hcon, complete); | ||
390 | |||
391 | kfree(smp->csrk); | ||
392 | kfree(smp->slave_csrk); | ||
393 | |||
394 | crypto_free_blkcipher(smp->tfm_aes); | ||
395 | |||
396 | /* If pairing failed clean up any keys we might have */ | ||
397 | if (!complete) { | ||
398 | if (smp->ltk) { | ||
399 | list_del(&smp->ltk->list); | ||
400 | kfree(smp->ltk); | ||
401 | } | ||
402 | |||
403 | if (smp->slave_ltk) { | ||
404 | list_del(&smp->slave_ltk->list); | ||
405 | kfree(smp->slave_ltk); | ||
406 | } | ||
407 | |||
408 | if (smp->remote_irk) { | ||
409 | list_del(&smp->remote_irk->list); | ||
410 | kfree(smp->remote_irk); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | chan->data = NULL; | ||
415 | kfree(smp); | ||
416 | hci_conn_drop(conn->hcon); | ||
417 | } | ||
418 | |||
359 | static void smp_failure(struct l2cap_conn *conn, u8 reason) | 419 | static void smp_failure(struct l2cap_conn *conn, u8 reason) |
360 | { | 420 | { |
361 | struct hci_conn *hcon = conn->hcon; | 421 | struct hci_conn *hcon = conn->hcon; |
422 | struct l2cap_chan *chan = conn->smp; | ||
423 | struct smp_chan *smp; | ||
362 | 424 | ||
363 | if (reason) | 425 | if (reason) |
364 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), | 426 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), |
@@ -368,7 +430,10 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason) | |||
368 | mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, | 430 | mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, |
369 | HCI_ERROR_AUTH_FAILURE); | 431 | HCI_ERROR_AUTH_FAILURE); |
370 | 432 | ||
371 | cancel_delayed_work_sync(&conn->security_timer); | 433 | if (!chan->data) |
434 | return; | ||
435 | |||
436 | smp = chan->data; | ||
372 | 437 | ||
373 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 438 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) |
374 | smp_chan_destroy(conn); | 439 | smp_chan_destroy(conn); |
@@ -405,7 +470,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
405 | u8 local_io, u8 remote_io) | 470 | u8 local_io, u8 remote_io) |
406 | { | 471 | { |
407 | struct hci_conn *hcon = conn->hcon; | 472 | struct hci_conn *hcon = conn->hcon; |
408 | struct smp_chan *smp = conn->smp_chan; | 473 | struct l2cap_chan *chan = conn->smp; |
474 | struct smp_chan *smp = chan->data; | ||
409 | u8 method; | 475 | u8 method; |
410 | u32 passkey = 0; | 476 | u32 passkey = 0; |
411 | int ret = 0; | 477 | int ret = 0; |
@@ -574,8 +640,201 @@ static u8 smp_random(struct smp_chan *smp) | |||
574 | return 0; | 640 | return 0; |
575 | } | 641 | } |
576 | 642 | ||
643 | static void smp_notify_keys(struct l2cap_conn *conn) | ||
644 | { | ||
645 | struct l2cap_chan *chan = conn->smp; | ||
646 | struct smp_chan *smp = chan->data; | ||
647 | struct hci_conn *hcon = conn->hcon; | ||
648 | struct hci_dev *hdev = hcon->hdev; | ||
649 | struct smp_cmd_pairing *req = (void *) &smp->preq[1]; | ||
650 | struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; | ||
651 | bool persistent; | ||
652 | |||
653 | if (smp->remote_irk) { | ||
654 | mgmt_new_irk(hdev, smp->remote_irk); | ||
655 | /* Now that user space can be considered to know the | ||
656 | * identity address track the connection based on it | ||
657 | * from now on. | ||
658 | */ | ||
659 | bacpy(&hcon->dst, &smp->remote_irk->bdaddr); | ||
660 | hcon->dst_type = smp->remote_irk->addr_type; | ||
661 | l2cap_conn_update_id_addr(hcon); | ||
662 | |||
663 | /* When receiving an indentity resolving key for | ||
664 | * a remote device that does not use a resolvable | ||
665 | * private address, just remove the key so that | ||
666 | * it is possible to use the controller white | ||
667 | * list for scanning. | ||
668 | * | ||
669 | * Userspace will have been told to not store | ||
670 | * this key at this point. So it is safe to | ||
671 | * just remove it. | ||
672 | */ | ||
673 | if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { | ||
674 | list_del(&smp->remote_irk->list); | ||
675 | kfree(smp->remote_irk); | ||
676 | smp->remote_irk = NULL; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | /* The LTKs and CSRKs should be persistent only if both sides | ||
681 | * had the bonding bit set in their authentication requests. | ||
682 | */ | ||
683 | persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); | ||
684 | |||
685 | if (smp->csrk) { | ||
686 | smp->csrk->bdaddr_type = hcon->dst_type; | ||
687 | bacpy(&smp->csrk->bdaddr, &hcon->dst); | ||
688 | mgmt_new_csrk(hdev, smp->csrk, persistent); | ||
689 | } | ||
690 | |||
691 | if (smp->slave_csrk) { | ||
692 | smp->slave_csrk->bdaddr_type = hcon->dst_type; | ||
693 | bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); | ||
694 | mgmt_new_csrk(hdev, smp->slave_csrk, persistent); | ||
695 | } | ||
696 | |||
697 | if (smp->ltk) { | ||
698 | smp->ltk->bdaddr_type = hcon->dst_type; | ||
699 | bacpy(&smp->ltk->bdaddr, &hcon->dst); | ||
700 | mgmt_new_ltk(hdev, smp->ltk, persistent); | ||
701 | } | ||
702 | |||
703 | if (smp->slave_ltk) { | ||
704 | smp->slave_ltk->bdaddr_type = hcon->dst_type; | ||
705 | bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); | ||
706 | mgmt_new_ltk(hdev, smp->slave_ltk, persistent); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | static void smp_distribute_keys(struct work_struct *work) | ||
711 | { | ||
712 | struct smp_chan *smp = container_of(work, struct smp_chan, | ||
713 | distribute_work); | ||
714 | struct smp_cmd_pairing *req, *rsp; | ||
715 | struct l2cap_conn *conn = smp->conn; | ||
716 | struct hci_conn *hcon = conn->hcon; | ||
717 | struct hci_dev *hdev = hcon->hdev; | ||
718 | __u8 *keydist; | ||
719 | |||
720 | BT_DBG("conn %p", conn); | ||
721 | |||
722 | if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | ||
723 | return; | ||
724 | |||
725 | rsp = (void *) &smp->prsp[1]; | ||
726 | |||
727 | /* The responder sends its keys first */ | ||
728 | if (hcon->out && (smp->remote_key_dist & 0x07)) | ||
729 | return; | ||
730 | |||
731 | req = (void *) &smp->preq[1]; | ||
732 | |||
733 | if (hcon->out) { | ||
734 | keydist = &rsp->init_key_dist; | ||
735 | *keydist &= req->init_key_dist; | ||
736 | } else { | ||
737 | keydist = &rsp->resp_key_dist; | ||
738 | *keydist &= req->resp_key_dist; | ||
739 | } | ||
740 | |||
741 | BT_DBG("keydist 0x%x", *keydist); | ||
742 | |||
743 | if (*keydist & SMP_DIST_ENC_KEY) { | ||
744 | struct smp_cmd_encrypt_info enc; | ||
745 | struct smp_cmd_master_ident ident; | ||
746 | struct smp_ltk *ltk; | ||
747 | u8 authenticated; | ||
748 | __le16 ediv; | ||
749 | __le64 rand; | ||
750 | |||
751 | get_random_bytes(enc.ltk, sizeof(enc.ltk)); | ||
752 | get_random_bytes(&ediv, sizeof(ediv)); | ||
753 | get_random_bytes(&rand, sizeof(rand)); | ||
754 | |||
755 | smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); | ||
756 | |||
757 | authenticated = hcon->sec_level == BT_SECURITY_HIGH; | ||
758 | ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, | ||
759 | SMP_LTK_SLAVE, authenticated, enc.ltk, | ||
760 | smp->enc_key_size, ediv, rand); | ||
761 | smp->slave_ltk = ltk; | ||
762 | |||
763 | ident.ediv = ediv; | ||
764 | ident.rand = rand; | ||
765 | |||
766 | smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); | ||
767 | |||
768 | *keydist &= ~SMP_DIST_ENC_KEY; | ||
769 | } | ||
770 | |||
771 | if (*keydist & SMP_DIST_ID_KEY) { | ||
772 | struct smp_cmd_ident_addr_info addrinfo; | ||
773 | struct smp_cmd_ident_info idinfo; | ||
774 | |||
775 | memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); | ||
776 | |||
777 | smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); | ||
778 | |||
779 | /* The hci_conn contains the local identity address | ||
780 | * after the connection has been established. | ||
781 | * | ||
782 | * This is true even when the connection has been | ||
783 | * established using a resolvable random address. | ||
784 | */ | ||
785 | bacpy(&addrinfo.bdaddr, &hcon->src); | ||
786 | addrinfo.addr_type = hcon->src_type; | ||
787 | |||
788 | smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), | ||
789 | &addrinfo); | ||
790 | |||
791 | *keydist &= ~SMP_DIST_ID_KEY; | ||
792 | } | ||
793 | |||
794 | if (*keydist & SMP_DIST_SIGN) { | ||
795 | struct smp_cmd_sign_info sign; | ||
796 | struct smp_csrk *csrk; | ||
797 | |||
798 | /* Generate a new random key */ | ||
799 | get_random_bytes(sign.csrk, sizeof(sign.csrk)); | ||
800 | |||
801 | csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); | ||
802 | if (csrk) { | ||
803 | csrk->master = 0x00; | ||
804 | memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); | ||
805 | } | ||
806 | smp->slave_csrk = csrk; | ||
807 | |||
808 | smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); | ||
809 | |||
810 | *keydist &= ~SMP_DIST_SIGN; | ||
811 | } | ||
812 | |||
813 | /* If there are still keys to be received wait for them */ | ||
814 | if ((smp->remote_key_dist & 0x07)) | ||
815 | return; | ||
816 | |||
817 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); | ||
818 | set_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
819 | smp_notify_keys(conn); | ||
820 | |||
821 | smp_chan_destroy(conn); | ||
822 | } | ||
823 | |||
824 | static void smp_timeout(struct work_struct *work) | ||
825 | { | ||
826 | struct smp_chan *smp = container_of(work, struct smp_chan, | ||
827 | security_timer.work); | ||
828 | struct l2cap_conn *conn = smp->conn; | ||
829 | |||
830 | BT_DBG("conn %p", conn); | ||
831 | |||
832 | l2cap_conn_shutdown(conn, ETIMEDOUT); | ||
833 | } | ||
834 | |||
577 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | 835 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) |
578 | { | 836 | { |
837 | struct l2cap_chan *chan = conn->smp; | ||
579 | struct smp_chan *smp; | 838 | struct smp_chan *smp; |
580 | 839 | ||
581 | smp = kzalloc(sizeof(*smp), GFP_ATOMIC); | 840 | smp = kzalloc(sizeof(*smp), GFP_ATOMIC); |
@@ -593,54 +852,20 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
593 | } | 852 | } |
594 | 853 | ||
595 | smp->conn = conn; | 854 | smp->conn = conn; |
596 | conn->smp_chan = smp; | 855 | chan->data = smp; |
856 | |||
857 | INIT_WORK(&smp->distribute_work, smp_distribute_keys); | ||
858 | INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); | ||
597 | 859 | ||
598 | hci_conn_hold(conn->hcon); | 860 | hci_conn_hold(conn->hcon); |
599 | 861 | ||
600 | return smp; | 862 | return smp; |
601 | } | 863 | } |
602 | 864 | ||
603 | void smp_chan_destroy(struct l2cap_conn *conn) | ||
604 | { | ||
605 | struct smp_chan *smp = conn->smp_chan; | ||
606 | bool complete; | ||
607 | |||
608 | BUG_ON(!smp); | ||
609 | |||
610 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
611 | mgmt_smp_complete(conn->hcon, complete); | ||
612 | |||
613 | kfree(smp->csrk); | ||
614 | kfree(smp->slave_csrk); | ||
615 | |||
616 | crypto_free_blkcipher(smp->tfm_aes); | ||
617 | |||
618 | /* If pairing failed clean up any keys we might have */ | ||
619 | if (!complete) { | ||
620 | if (smp->ltk) { | ||
621 | list_del(&smp->ltk->list); | ||
622 | kfree(smp->ltk); | ||
623 | } | ||
624 | |||
625 | if (smp->slave_ltk) { | ||
626 | list_del(&smp->slave_ltk->list); | ||
627 | kfree(smp->slave_ltk); | ||
628 | } | ||
629 | |||
630 | if (smp->remote_irk) { | ||
631 | list_del(&smp->remote_irk->list); | ||
632 | kfree(smp->remote_irk); | ||
633 | } | ||
634 | } | ||
635 | |||
636 | kfree(smp); | ||
637 | conn->smp_chan = NULL; | ||
638 | hci_conn_drop(conn->hcon); | ||
639 | } | ||
640 | |||
641 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | 865 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) |
642 | { | 866 | { |
643 | struct l2cap_conn *conn = hcon->l2cap_data; | 867 | struct l2cap_conn *conn = hcon->l2cap_data; |
868 | struct l2cap_chan *chan; | ||
644 | struct smp_chan *smp; | 869 | struct smp_chan *smp; |
645 | u32 value; | 870 | u32 value; |
646 | 871 | ||
@@ -649,7 +874,11 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
649 | if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 874 | if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) |
650 | return -ENOTCONN; | 875 | return -ENOTCONN; |
651 | 876 | ||
652 | smp = conn->smp_chan; | 877 | chan = conn->smp; |
878 | if (!chan) | ||
879 | return -ENOTCONN; | ||
880 | |||
881 | smp = chan->data; | ||
653 | 882 | ||
654 | switch (mgmt_op) { | 883 | switch (mgmt_op) { |
655 | case MGMT_OP_USER_PASSKEY_REPLY: | 884 | case MGMT_OP_USER_PASSKEY_REPLY: |
@@ -696,10 +925,12 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
696 | if (conn->hcon->role != HCI_ROLE_SLAVE) | 925 | if (conn->hcon->role != HCI_ROLE_SLAVE) |
697 | return SMP_CMD_NOTSUPP; | 926 | return SMP_CMD_NOTSUPP; |
698 | 927 | ||
699 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | 928 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { |
700 | smp = smp_chan_create(conn); | 929 | smp = smp_chan_create(conn); |
701 | else | 930 | } else { |
702 | smp = conn->smp_chan; | 931 | struct l2cap_chan *chan = conn->smp; |
932 | smp = chan->data; | ||
933 | } | ||
703 | 934 | ||
704 | if (!smp) | 935 | if (!smp) |
705 | return SMP_UNSPECIFIED; | 936 | return SMP_UNSPECIFIED; |
@@ -753,7 +984,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
753 | static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | 984 | static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) |
754 | { | 985 | { |
755 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | 986 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; |
756 | struct smp_chan *smp = conn->smp_chan; | 987 | struct l2cap_chan *chan = conn->smp; |
988 | struct smp_chan *smp = chan->data; | ||
757 | u8 key_size, auth = SMP_AUTH_NONE; | 989 | u8 key_size, auth = SMP_AUTH_NONE; |
758 | int ret; | 990 | int ret; |
759 | 991 | ||
@@ -814,7 +1046,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
814 | 1046 | ||
815 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | 1047 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) |
816 | { | 1048 | { |
817 | struct smp_chan *smp = conn->smp_chan; | 1049 | struct l2cap_chan *chan = conn->smp; |
1050 | struct smp_chan *smp = chan->data; | ||
818 | 1051 | ||
819 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | 1052 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); |
820 | 1053 | ||
@@ -837,7 +1070,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
837 | 1070 | ||
838 | static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | 1071 | static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) |
839 | { | 1072 | { |
840 | struct smp_chan *smp = conn->smp_chan; | 1073 | struct l2cap_chan *chan = conn->smp; |
1074 | struct smp_chan *smp = chan->data; | ||
841 | 1075 | ||
842 | BT_DBG("conn %p", conn); | 1076 | BT_DBG("conn %p", conn); |
843 | 1077 | ||
@@ -1010,7 +1244,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
1010 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | 1244 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) |
1011 | { | 1245 | { |
1012 | struct smp_cmd_encrypt_info *rp = (void *) skb->data; | 1246 | struct smp_cmd_encrypt_info *rp = (void *) skb->data; |
1013 | struct smp_chan *smp = conn->smp_chan; | 1247 | struct l2cap_chan *chan = conn->smp; |
1248 | struct smp_chan *smp = chan->data; | ||
1014 | 1249 | ||
1015 | BT_DBG("conn %p", conn); | 1250 | BT_DBG("conn %p", conn); |
1016 | 1251 | ||
@@ -1031,7 +1266,8 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1031 | static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | 1266 | static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) |
1032 | { | 1267 | { |
1033 | struct smp_cmd_master_ident *rp = (void *) skb->data; | 1268 | struct smp_cmd_master_ident *rp = (void *) skb->data; |
1034 | struct smp_chan *smp = conn->smp_chan; | 1269 | struct l2cap_chan *chan = conn->smp; |
1270 | struct smp_chan *smp = chan->data; | ||
1035 | struct hci_dev *hdev = conn->hcon->hdev; | 1271 | struct hci_dev *hdev = conn->hcon->hdev; |
1036 | struct hci_conn *hcon = conn->hcon; | 1272 | struct hci_conn *hcon = conn->hcon; |
1037 | struct smp_ltk *ltk; | 1273 | struct smp_ltk *ltk; |
@@ -1058,7 +1294,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1058 | rp->ediv, rp->rand); | 1294 | rp->ediv, rp->rand); |
1059 | smp->ltk = ltk; | 1295 | smp->ltk = ltk; |
1060 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | 1296 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) |
1061 | smp_distribute_keys(conn); | 1297 | queue_work(hdev->workqueue, &smp->distribute_work); |
1062 | hci_dev_unlock(hdev); | 1298 | hci_dev_unlock(hdev); |
1063 | 1299 | ||
1064 | return 0; | 1300 | return 0; |
@@ -1067,7 +1303,8 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1067 | static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) | 1303 | static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) |
1068 | { | 1304 | { |
1069 | struct smp_cmd_ident_info *info = (void *) skb->data; | 1305 | struct smp_cmd_ident_info *info = (void *) skb->data; |
1070 | struct smp_chan *smp = conn->smp_chan; | 1306 | struct l2cap_chan *chan = conn->smp; |
1307 | struct smp_chan *smp = chan->data; | ||
1071 | 1308 | ||
1072 | BT_DBG(""); | 1309 | BT_DBG(""); |
1073 | 1310 | ||
@@ -1089,8 +1326,10 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1089 | struct sk_buff *skb) | 1326 | struct sk_buff *skb) |
1090 | { | 1327 | { |
1091 | struct smp_cmd_ident_addr_info *info = (void *) skb->data; | 1328 | struct smp_cmd_ident_addr_info *info = (void *) skb->data; |
1092 | struct smp_chan *smp = conn->smp_chan; | 1329 | struct l2cap_chan *chan = conn->smp; |
1330 | struct smp_chan *smp = chan->data; | ||
1093 | struct hci_conn *hcon = conn->hcon; | 1331 | struct hci_conn *hcon = conn->hcon; |
1332 | struct hci_dev *hdev = hcon->hdev; | ||
1094 | bdaddr_t rpa; | 1333 | bdaddr_t rpa; |
1095 | 1334 | ||
1096 | BT_DBG(""); | 1335 | BT_DBG(""); |
@@ -1133,7 +1372,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1133 | smp->id_addr_type, smp->irk, &rpa); | 1372 | smp->id_addr_type, smp->irk, &rpa); |
1134 | 1373 | ||
1135 | distribute: | 1374 | distribute: |
1136 | smp_distribute_keys(conn); | 1375 | queue_work(hdev->workqueue, &smp->distribute_work); |
1137 | 1376 | ||
1138 | hci_dev_unlock(hcon->hdev); | 1377 | hci_dev_unlock(hcon->hdev); |
1139 | 1378 | ||
@@ -1143,7 +1382,8 @@ distribute: | |||
1143 | static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | 1382 | static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) |
1144 | { | 1383 | { |
1145 | struct smp_cmd_sign_info *rp = (void *) skb->data; | 1384 | struct smp_cmd_sign_info *rp = (void *) skb->data; |
1146 | struct smp_chan *smp = conn->smp_chan; | 1385 | struct l2cap_chan *chan = conn->smp; |
1386 | struct smp_chan *smp = chan->data; | ||
1147 | struct hci_dev *hdev = conn->hcon->hdev; | 1387 | struct hci_dev *hdev = conn->hcon->hdev; |
1148 | struct smp_csrk *csrk; | 1388 | struct smp_csrk *csrk; |
1149 | 1389 | ||
@@ -1168,15 +1408,15 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1168 | memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); | 1408 | memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); |
1169 | } | 1409 | } |
1170 | smp->csrk = csrk; | 1410 | smp->csrk = csrk; |
1171 | if (!(smp->remote_key_dist & SMP_DIST_SIGN)) | 1411 | queue_work(hdev->workqueue, &smp->distribute_work); |
1172 | smp_distribute_keys(conn); | ||
1173 | hci_dev_unlock(hdev); | 1412 | hci_dev_unlock(hdev); |
1174 | 1413 | ||
1175 | return 0; | 1414 | return 0; |
1176 | } | 1415 | } |
1177 | 1416 | ||
1178 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | 1417 | static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) |
1179 | { | 1418 | { |
1419 | struct l2cap_conn *conn = chan->conn; | ||
1180 | struct hci_conn *hcon = conn->hcon; | 1420 | struct hci_conn *hcon = conn->hcon; |
1181 | __u8 code, reason; | 1421 | __u8 code, reason; |
1182 | int err = 0; | 1422 | int err = 0; |
@@ -1186,10 +1426,8 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1186 | return 0; | 1426 | return 0; |
1187 | } | 1427 | } |
1188 | 1428 | ||
1189 | if (skb->len < 1) { | 1429 | if (skb->len < 1) |
1190 | kfree_skb(skb); | ||
1191 | return -EILSEQ; | 1430 | return -EILSEQ; |
1192 | } | ||
1193 | 1431 | ||
1194 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { | 1432 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { |
1195 | err = -EOPNOTSUPP; | 1433 | err = -EOPNOTSUPP; |
@@ -1207,10 +1445,11 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1207 | * returns an error). | 1445 | * returns an error). |
1208 | */ | 1446 | */ |
1209 | if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && | 1447 | if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && |
1210 | !conn->smp_chan) { | 1448 | !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { |
1211 | BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); | 1449 | BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); |
1212 | kfree_skb(skb); | 1450 | reason = SMP_CMD_NOTSUPP; |
1213 | return -EOPNOTSUPP; | 1451 | err = -EOPNOTSUPP; |
1452 | goto done; | ||
1214 | } | 1453 | } |
1215 | 1454 | ||
1216 | switch (code) { | 1455 | switch (code) { |
@@ -1271,188 +1510,201 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1271 | done: | 1510 | done: |
1272 | if (reason) | 1511 | if (reason) |
1273 | smp_failure(conn, reason); | 1512 | smp_failure(conn, reason); |
1274 | 1513 | if (!err) | |
1275 | kfree_skb(skb); | 1514 | kfree_skb(skb); |
1276 | return err; | 1515 | return err; |
1277 | } | 1516 | } |
1278 | 1517 | ||
1279 | static void smp_notify_keys(struct l2cap_conn *conn) | 1518 | static void smp_teardown_cb(struct l2cap_chan *chan, int err) |
1280 | { | 1519 | { |
1281 | struct smp_chan *smp = conn->smp_chan; | 1520 | struct l2cap_conn *conn = chan->conn; |
1521 | |||
1522 | BT_DBG("chan %p", chan); | ||
1523 | |||
1524 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | ||
1525 | smp_chan_destroy(conn); | ||
1526 | |||
1527 | conn->smp = NULL; | ||
1528 | l2cap_chan_put(chan); | ||
1529 | } | ||
1530 | |||
1531 | static void smp_resume_cb(struct l2cap_chan *chan) | ||
1532 | { | ||
1533 | struct smp_chan *smp = chan->data; | ||
1534 | struct l2cap_conn *conn = chan->conn; | ||
1282 | struct hci_conn *hcon = conn->hcon; | 1535 | struct hci_conn *hcon = conn->hcon; |
1283 | struct hci_dev *hdev = hcon->hdev; | 1536 | struct hci_dev *hdev = hcon->hdev; |
1284 | struct smp_cmd_pairing *req = (void *) &smp->preq[1]; | ||
1285 | struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; | ||
1286 | bool persistent; | ||
1287 | 1537 | ||
1288 | if (smp->remote_irk) { | 1538 | BT_DBG("chan %p", chan); |
1289 | mgmt_new_irk(hdev, smp->remote_irk); | ||
1290 | /* Now that user space can be considered to know the | ||
1291 | * identity address track the connection based on it | ||
1292 | * from now on. | ||
1293 | */ | ||
1294 | bacpy(&hcon->dst, &smp->remote_irk->bdaddr); | ||
1295 | hcon->dst_type = smp->remote_irk->addr_type; | ||
1296 | l2cap_conn_update_id_addr(hcon); | ||
1297 | 1539 | ||
1298 | /* When receiving an indentity resolving key for | 1540 | if (!smp) |
1299 | * a remote device that does not use a resolvable | 1541 | return; |
1300 | * private address, just remove the key so that | ||
1301 | * it is possible to use the controller white | ||
1302 | * list for scanning. | ||
1303 | * | ||
1304 | * Userspace will have been told to not store | ||
1305 | * this key at this point. So it is safe to | ||
1306 | * just remove it. | ||
1307 | */ | ||
1308 | if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { | ||
1309 | list_del(&smp->remote_irk->list); | ||
1310 | kfree(smp->remote_irk); | ||
1311 | smp->remote_irk = NULL; | ||
1312 | } | ||
1313 | } | ||
1314 | 1542 | ||
1315 | /* The LTKs and CSRKs should be persistent only if both sides | 1543 | cancel_delayed_work(&smp->security_timer); |
1316 | * had the bonding bit set in their authentication requests. | ||
1317 | */ | ||
1318 | persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); | ||
1319 | 1544 | ||
1320 | if (smp->csrk) { | 1545 | if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) |
1321 | smp->csrk->bdaddr_type = hcon->dst_type; | 1546 | queue_work(hdev->workqueue, &smp->distribute_work); |
1322 | bacpy(&smp->csrk->bdaddr, &hcon->dst); | 1547 | } |
1323 | mgmt_new_csrk(hdev, smp->csrk, persistent); | ||
1324 | } | ||
1325 | 1548 | ||
1326 | if (smp->slave_csrk) { | 1549 | static void smp_ready_cb(struct l2cap_chan *chan) |
1327 | smp->slave_csrk->bdaddr_type = hcon->dst_type; | 1550 | { |
1328 | bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); | 1551 | struct l2cap_conn *conn = chan->conn; |
1329 | mgmt_new_csrk(hdev, smp->slave_csrk, persistent); | ||
1330 | } | ||
1331 | 1552 | ||
1332 | if (smp->ltk) { | 1553 | BT_DBG("chan %p", chan); |
1333 | smp->ltk->bdaddr_type = hcon->dst_type; | ||
1334 | bacpy(&smp->ltk->bdaddr, &hcon->dst); | ||
1335 | mgmt_new_ltk(hdev, smp->ltk, persistent); | ||
1336 | } | ||
1337 | 1554 | ||
1338 | if (smp->slave_ltk) { | 1555 | conn->smp = chan; |
1339 | smp->slave_ltk->bdaddr_type = hcon->dst_type; | 1556 | l2cap_chan_hold(chan); |
1340 | bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); | ||
1341 | mgmt_new_ltk(hdev, smp->slave_ltk, persistent); | ||
1342 | } | ||
1343 | } | 1557 | } |
1344 | 1558 | ||
1345 | int smp_distribute_keys(struct l2cap_conn *conn) | 1559 | static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) |
1346 | { | 1560 | { |
1347 | struct smp_cmd_pairing *req, *rsp; | 1561 | int err; |
1348 | struct smp_chan *smp = conn->smp_chan; | ||
1349 | struct hci_conn *hcon = conn->hcon; | ||
1350 | struct hci_dev *hdev = hcon->hdev; | ||
1351 | __u8 *keydist; | ||
1352 | 1562 | ||
1353 | BT_DBG("conn %p", conn); | 1563 | BT_DBG("chan %p", chan); |
1354 | 1564 | ||
1355 | if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 1565 | err = smp_sig_channel(chan, skb); |
1356 | return 0; | 1566 | if (err) { |
1567 | struct smp_chan *smp = chan->data; | ||
1357 | 1568 | ||
1358 | rsp = (void *) &smp->prsp[1]; | 1569 | if (smp) |
1570 | cancel_delayed_work_sync(&smp->security_timer); | ||
1359 | 1571 | ||
1360 | /* The responder sends its keys first */ | 1572 | l2cap_conn_shutdown(chan->conn, -err); |
1361 | if (hcon->out && (smp->remote_key_dist & 0x07)) | 1573 | } |
1362 | return 0; | ||
1363 | 1574 | ||
1364 | req = (void *) &smp->preq[1]; | 1575 | return err; |
1576 | } | ||
1365 | 1577 | ||
1366 | if (hcon->out) { | 1578 | static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, |
1367 | keydist = &rsp->init_key_dist; | 1579 | unsigned long hdr_len, |
1368 | *keydist &= req->init_key_dist; | 1580 | unsigned long len, int nb) |
1369 | } else { | 1581 | { |
1370 | keydist = &rsp->resp_key_dist; | 1582 | struct sk_buff *skb; |
1371 | *keydist &= req->resp_key_dist; | ||
1372 | } | ||
1373 | 1583 | ||
1374 | BT_DBG("keydist 0x%x", *keydist); | 1584 | skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); |
1585 | if (!skb) | ||
1586 | return ERR_PTR(-ENOMEM); | ||
1375 | 1587 | ||
1376 | if (*keydist & SMP_DIST_ENC_KEY) { | 1588 | skb->priority = HCI_PRIO_MAX; |
1377 | struct smp_cmd_encrypt_info enc; | 1589 | bt_cb(skb)->chan = chan; |
1378 | struct smp_cmd_master_ident ident; | ||
1379 | struct smp_ltk *ltk; | ||
1380 | u8 authenticated; | ||
1381 | __le16 ediv; | ||
1382 | __le64 rand; | ||
1383 | 1590 | ||
1384 | get_random_bytes(enc.ltk, sizeof(enc.ltk)); | 1591 | return skb; |
1385 | get_random_bytes(&ediv, sizeof(ediv)); | 1592 | } |
1386 | get_random_bytes(&rand, sizeof(rand)); | ||
1387 | 1593 | ||
1388 | smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); | 1594 | static const struct l2cap_ops smp_chan_ops = { |
1595 | .name = "Security Manager", | ||
1596 | .ready = smp_ready_cb, | ||
1597 | .recv = smp_recv_cb, | ||
1598 | .alloc_skb = smp_alloc_skb_cb, | ||
1599 | .teardown = smp_teardown_cb, | ||
1600 | .resume = smp_resume_cb, | ||
1601 | |||
1602 | .new_connection = l2cap_chan_no_new_connection, | ||
1603 | .state_change = l2cap_chan_no_state_change, | ||
1604 | .close = l2cap_chan_no_close, | ||
1605 | .defer = l2cap_chan_no_defer, | ||
1606 | .suspend = l2cap_chan_no_suspend, | ||
1607 | .set_shutdown = l2cap_chan_no_set_shutdown, | ||
1608 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | ||
1609 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
1610 | }; | ||
1389 | 1611 | ||
1390 | authenticated = hcon->sec_level == BT_SECURITY_HIGH; | 1612 | static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) |
1391 | ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, | 1613 | { |
1392 | SMP_LTK_SLAVE, authenticated, enc.ltk, | 1614 | struct l2cap_chan *chan; |
1393 | smp->enc_key_size, ediv, rand); | ||
1394 | smp->slave_ltk = ltk; | ||
1395 | 1615 | ||
1396 | ident.ediv = ediv; | 1616 | BT_DBG("pchan %p", pchan); |
1397 | ident.rand = rand; | ||
1398 | 1617 | ||
1399 | smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); | 1618 | chan = l2cap_chan_create(); |
1619 | if (!chan) | ||
1620 | return NULL; | ||
1400 | 1621 | ||
1401 | *keydist &= ~SMP_DIST_ENC_KEY; | 1622 | chan->chan_type = pchan->chan_type; |
1402 | } | 1623 | chan->ops = &smp_chan_ops; |
1624 | chan->scid = pchan->scid; | ||
1625 | chan->dcid = chan->scid; | ||
1626 | chan->imtu = pchan->imtu; | ||
1627 | chan->omtu = pchan->omtu; | ||
1628 | chan->mode = pchan->mode; | ||
1403 | 1629 | ||
1404 | if (*keydist & SMP_DIST_ID_KEY) { | 1630 | BT_DBG("created chan %p", chan); |
1405 | struct smp_cmd_ident_addr_info addrinfo; | ||
1406 | struct smp_cmd_ident_info idinfo; | ||
1407 | 1631 | ||
1408 | memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); | 1632 | return chan; |
1633 | } | ||
1409 | 1634 | ||
1410 | smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); | 1635 | static const struct l2cap_ops smp_root_chan_ops = { |
1636 | .name = "Security Manager Root", | ||
1637 | .new_connection = smp_new_conn_cb, | ||
1638 | |||
1639 | /* None of these are implemented for the root channel */ | ||
1640 | .close = l2cap_chan_no_close, | ||
1641 | .alloc_skb = l2cap_chan_no_alloc_skb, | ||
1642 | .recv = l2cap_chan_no_recv, | ||
1643 | .state_change = l2cap_chan_no_state_change, | ||
1644 | .teardown = l2cap_chan_no_teardown, | ||
1645 | .ready = l2cap_chan_no_ready, | ||
1646 | .defer = l2cap_chan_no_defer, | ||
1647 | .suspend = l2cap_chan_no_suspend, | ||
1648 | .resume = l2cap_chan_no_resume, | ||
1649 | .set_shutdown = l2cap_chan_no_set_shutdown, | ||
1650 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | ||
1651 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
1652 | }; | ||
1411 | 1653 | ||
1412 | /* The hci_conn contains the local identity address | 1654 | int smp_register(struct hci_dev *hdev) |
1413 | * after the connection has been established. | 1655 | { |
1414 | * | 1656 | struct l2cap_chan *chan; |
1415 | * This is true even when the connection has been | 1657 | struct crypto_blkcipher *tfm_aes; |
1416 | * established using a resolvable random address. | ||
1417 | */ | ||
1418 | bacpy(&addrinfo.bdaddr, &hcon->src); | ||
1419 | addrinfo.addr_type = hcon->src_type; | ||
1420 | 1658 | ||
1421 | smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), | 1659 | BT_DBG("%s", hdev->name); |
1422 | &addrinfo); | ||
1423 | 1660 | ||
1424 | *keydist &= ~SMP_DIST_ID_KEY; | 1661 | tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); |
1662 | if (IS_ERR(tfm_aes)) { | ||
1663 | int err = PTR_ERR(tfm_aes); | ||
1664 | BT_ERR("Unable to create crypto context"); | ||
1665 | return err; | ||
1425 | } | 1666 | } |
1426 | 1667 | ||
1427 | if (*keydist & SMP_DIST_SIGN) { | 1668 | chan = l2cap_chan_create(); |
1428 | struct smp_cmd_sign_info sign; | 1669 | if (!chan) { |
1429 | struct smp_csrk *csrk; | 1670 | crypto_free_blkcipher(tfm_aes); |
1671 | return -ENOMEM; | ||
1672 | } | ||
1430 | 1673 | ||
1431 | /* Generate a new random key */ | 1674 | chan->data = tfm_aes; |
1432 | get_random_bytes(sign.csrk, sizeof(sign.csrk)); | ||
1433 | 1675 | ||
1434 | csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); | 1676 | l2cap_add_scid(chan, L2CAP_CID_SMP); |
1435 | if (csrk) { | ||
1436 | csrk->master = 0x00; | ||
1437 | memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); | ||
1438 | } | ||
1439 | smp->slave_csrk = csrk; | ||
1440 | 1677 | ||
1441 | smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); | 1678 | l2cap_chan_set_defaults(chan); |
1442 | 1679 | ||
1443 | *keydist &= ~SMP_DIST_SIGN; | 1680 | bacpy(&chan->src, &hdev->bdaddr); |
1444 | } | 1681 | chan->src_type = BDADDR_LE_PUBLIC; |
1682 | chan->state = BT_LISTEN; | ||
1683 | chan->mode = L2CAP_MODE_BASIC; | ||
1684 | chan->imtu = L2CAP_DEFAULT_MTU; | ||
1685 | chan->ops = &smp_root_chan_ops; | ||
1445 | 1686 | ||
1446 | /* If there are still keys to be received wait for them */ | 1687 | hdev->smp_data = chan; |
1447 | if ((smp->remote_key_dist & 0x07)) | ||
1448 | return 0; | ||
1449 | 1688 | ||
1450 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); | 1689 | return 0; |
1451 | cancel_delayed_work_sync(&conn->security_timer); | 1690 | } |
1452 | set_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
1453 | smp_notify_keys(conn); | ||
1454 | 1691 | ||
1455 | smp_chan_destroy(conn); | 1692 | void smp_unregister(struct hci_dev *hdev) |
1693 | { | ||
1694 | struct l2cap_chan *chan = hdev->smp_data; | ||
1695 | struct crypto_blkcipher *tfm_aes; | ||
1456 | 1696 | ||
1457 | return 0; | 1697 | if (!chan) |
1698 | return; | ||
1699 | |||
1700 | BT_DBG("%s chan %p", hdev->name, chan); | ||
1701 | |||
1702 | tfm_aes = chan->data; | ||
1703 | if (tfm_aes) { | ||
1704 | chan->data = NULL; | ||
1705 | crypto_free_blkcipher(tfm_aes); | ||
1706 | } | ||
1707 | |||
1708 | hdev->smp_data = NULL; | ||
1709 | l2cap_chan_put(chan); | ||
1458 | } | 1710 | } |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 796f4f45f92f..cf1094617c69 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -126,14 +126,12 @@ enum { | |||
126 | /* SMP Commands */ | 126 | /* SMP Commands */ |
127 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); | 127 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); |
128 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 128 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |
129 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); | ||
130 | int smp_distribute_keys(struct l2cap_conn *conn); | ||
131 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | 129 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); |
132 | 130 | ||
133 | void smp_chan_destroy(struct l2cap_conn *conn); | 131 | bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr); |
132 | int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa); | ||
134 | 133 | ||
135 | bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], | 134 | int smp_register(struct hci_dev *hdev); |
136 | bdaddr_t *bdaddr); | 135 | void smp_unregister(struct hci_dev *hdev); |
137 | int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa); | ||
138 | 136 | ||
139 | #endif /* __SMP_H */ | 137 | #endif /* __SMP_H */ |
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 6591d27e53a4..5e788cdc499a 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c | |||
@@ -77,14 +77,6 @@ lowpan_dev_info *lowpan_dev_info(const struct net_device *dev) | |||
77 | return netdev_priv(dev); | 77 | return netdev_priv(dev); |
78 | } | 78 | } |
79 | 79 | ||
80 | static inline void lowpan_address_flip(u8 *src, u8 *dest) | ||
81 | { | ||
82 | int i; | ||
83 | |||
84 | for (i = 0; i < IEEE802154_ADDR_LEN; i++) | ||
85 | (dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i]; | ||
86 | } | ||
87 | |||
88 | static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev, | 80 | static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev, |
89 | unsigned short type, const void *_daddr, | 81 | unsigned short type, const void *_daddr, |
90 | const void *_saddr, unsigned int len) | 82 | const void *_saddr, unsigned int len) |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 927b4ea0128b..4d8989b87960 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1011,15 +1011,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1011 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); | 1011 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | if (mask & BIT(NL80211_STA_FLAG_WME)) { | 1014 | if (mask & BIT(NL80211_STA_FLAG_WME)) |
1015 | if (set & BIT(NL80211_STA_FLAG_WME)) { | 1015 | sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); |
1016 | set_sta_flag(sta, WLAN_STA_WME); | ||
1017 | sta->sta.wme = true; | ||
1018 | } else { | ||
1019 | clear_sta_flag(sta, WLAN_STA_WME); | ||
1020 | sta->sta.wme = false; | ||
1021 | } | ||
1022 | } | ||
1023 | 1016 | ||
1024 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { | 1017 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { |
1025 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 1018 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
@@ -3352,7 +3345,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
3352 | band = chanctx_conf->def.chan->band; | 3345 | band = chanctx_conf->def.chan->band; |
3353 | sta = sta_info_get_bss(sdata, peer); | 3346 | sta = sta_info_get_bss(sdata, peer); |
3354 | if (sta) { | 3347 | if (sta) { |
3355 | qos = test_sta_flag(sta, WLAN_STA_WME); | 3348 | qos = sta->sta.wme; |
3356 | } else { | 3349 | } else { |
3357 | rcu_read_unlock(); | 3350 | rcu_read_unlock(); |
3358 | return -ENOLINK; | 3351 | return -ENOLINK; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 399ad82c997f..4c74e8da64b9 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -549,12 +549,12 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, | |||
549 | 549 | ||
550 | compat = cfg80211_chandef_compatible( | 550 | compat = cfg80211_chandef_compatible( |
551 | &sdata->vif.bss_conf.chandef, compat); | 551 | &sdata->vif.bss_conf.chandef, compat); |
552 | if (!compat) | 552 | if (WARN_ON_ONCE(!compat)) |
553 | break; | 553 | break; |
554 | } | 554 | } |
555 | rcu_read_unlock(); | 555 | rcu_read_unlock(); |
556 | 556 | ||
557 | if (WARN_ON_ONCE(!compat)) | 557 | if (!compat) |
558 | return; | 558 | return; |
559 | 559 | ||
560 | ieee80211_change_chanctx(local, ctx, compat); | 560 | ieee80211_change_chanctx(local, ctx, compat); |
@@ -639,41 +639,6 @@ out: | |||
639 | return ret; | 639 | return ret; |
640 | } | 640 | } |
641 | 641 | ||
642 | static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | ||
643 | { | ||
644 | struct ieee80211_local *local = sdata->local; | ||
645 | struct ieee80211_chanctx_conf *conf; | ||
646 | struct ieee80211_chanctx *ctx; | ||
647 | bool use_reserved_switch = false; | ||
648 | |||
649 | lockdep_assert_held(&local->chanctx_mtx); | ||
650 | |||
651 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | ||
652 | lockdep_is_held(&local->chanctx_mtx)); | ||
653 | if (!conf) | ||
654 | return; | ||
655 | |||
656 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | ||
657 | |||
658 | if (sdata->reserved_chanctx) { | ||
659 | if (sdata->reserved_chanctx->replace_state == | ||
660 | IEEE80211_CHANCTX_REPLACES_OTHER && | ||
661 | ieee80211_chanctx_num_reserved(local, | ||
662 | sdata->reserved_chanctx) > 1) | ||
663 | use_reserved_switch = true; | ||
664 | |||
665 | ieee80211_vif_unreserve_chanctx(sdata); | ||
666 | } | ||
667 | |||
668 | ieee80211_assign_vif_chanctx(sdata, NULL); | ||
669 | if (ieee80211_chanctx_refcount(local, ctx) == 0) | ||
670 | ieee80211_free_chanctx(local, ctx); | ||
671 | |||
672 | /* Unreserving may ready an in-place reservation. */ | ||
673 | if (use_reserved_switch) | ||
674 | ieee80211_vif_use_reserved_switch(local); | ||
675 | } | ||
676 | |||
677 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | 642 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, |
678 | struct ieee80211_chanctx *chanctx) | 643 | struct ieee80211_chanctx *chanctx) |
679 | { | 644 | { |
@@ -764,63 +729,6 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | |||
764 | drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); | 729 | drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); |
765 | } | 730 | } |
766 | 731 | ||
767 | int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | ||
768 | const struct cfg80211_chan_def *chandef, | ||
769 | enum ieee80211_chanctx_mode mode) | ||
770 | { | ||
771 | struct ieee80211_local *local = sdata->local; | ||
772 | struct ieee80211_chanctx *ctx; | ||
773 | u8 radar_detect_width = 0; | ||
774 | int ret; | ||
775 | |||
776 | lockdep_assert_held(&local->mtx); | ||
777 | |||
778 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | ||
779 | |||
780 | mutex_lock(&local->chanctx_mtx); | ||
781 | |||
782 | ret = cfg80211_chandef_dfs_required(local->hw.wiphy, | ||
783 | chandef, | ||
784 | sdata->wdev.iftype); | ||
785 | if (ret < 0) | ||
786 | goto out; | ||
787 | if (ret > 0) | ||
788 | radar_detect_width = BIT(chandef->width); | ||
789 | |||
790 | sdata->radar_required = ret; | ||
791 | |||
792 | ret = ieee80211_check_combinations(sdata, chandef, mode, | ||
793 | radar_detect_width); | ||
794 | if (ret < 0) | ||
795 | goto out; | ||
796 | |||
797 | __ieee80211_vif_release_channel(sdata); | ||
798 | |||
799 | ctx = ieee80211_find_chanctx(local, chandef, mode); | ||
800 | if (!ctx) | ||
801 | ctx = ieee80211_new_chanctx(local, chandef, mode); | ||
802 | if (IS_ERR(ctx)) { | ||
803 | ret = PTR_ERR(ctx); | ||
804 | goto out; | ||
805 | } | ||
806 | |||
807 | sdata->vif.bss_conf.chandef = *chandef; | ||
808 | |||
809 | ret = ieee80211_assign_vif_chanctx(sdata, ctx); | ||
810 | if (ret) { | ||
811 | /* if assign fails refcount stays the same */ | ||
812 | if (ieee80211_chanctx_refcount(local, ctx) == 0) | ||
813 | ieee80211_free_chanctx(local, ctx); | ||
814 | goto out; | ||
815 | } | ||
816 | |||
817 | ieee80211_recalc_smps_chanctx(local, ctx); | ||
818 | ieee80211_recalc_radar_chanctx(local, ctx); | ||
819 | out: | ||
820 | mutex_unlock(&local->chanctx_mtx); | ||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | static void | 732 | static void |
825 | __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, | 733 | __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, |
826 | bool clear) | 734 | bool clear) |
@@ -1269,8 +1177,7 @@ err: | |||
1269 | return err; | 1177 | return err; |
1270 | } | 1178 | } |
1271 | 1179 | ||
1272 | int | 1180 | static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) |
1273 | ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) | ||
1274 | { | 1181 | { |
1275 | struct ieee80211_sub_if_data *sdata, *sdata_tmp; | 1182 | struct ieee80211_sub_if_data *sdata, *sdata_tmp; |
1276 | struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; | 1183 | struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; |
@@ -1522,6 +1429,98 @@ err: | |||
1522 | return err; | 1429 | return err; |
1523 | } | 1430 | } |
1524 | 1431 | ||
1432 | static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | ||
1433 | { | ||
1434 | struct ieee80211_local *local = sdata->local; | ||
1435 | struct ieee80211_chanctx_conf *conf; | ||
1436 | struct ieee80211_chanctx *ctx; | ||
1437 | bool use_reserved_switch = false; | ||
1438 | |||
1439 | lockdep_assert_held(&local->chanctx_mtx); | ||
1440 | |||
1441 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | ||
1442 | lockdep_is_held(&local->chanctx_mtx)); | ||
1443 | if (!conf) | ||
1444 | return; | ||
1445 | |||
1446 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | ||
1447 | |||
1448 | if (sdata->reserved_chanctx) { | ||
1449 | if (sdata->reserved_chanctx->replace_state == | ||
1450 | IEEE80211_CHANCTX_REPLACES_OTHER && | ||
1451 | ieee80211_chanctx_num_reserved(local, | ||
1452 | sdata->reserved_chanctx) > 1) | ||
1453 | use_reserved_switch = true; | ||
1454 | |||
1455 | ieee80211_vif_unreserve_chanctx(sdata); | ||
1456 | } | ||
1457 | |||
1458 | ieee80211_assign_vif_chanctx(sdata, NULL); | ||
1459 | if (ieee80211_chanctx_refcount(local, ctx) == 0) | ||
1460 | ieee80211_free_chanctx(local, ctx); | ||
1461 | |||
1462 | /* Unreserving may ready an in-place reservation. */ | ||
1463 | if (use_reserved_switch) | ||
1464 | ieee80211_vif_use_reserved_switch(local); | ||
1465 | } | ||
1466 | |||
1467 | int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | ||
1468 | const struct cfg80211_chan_def *chandef, | ||
1469 | enum ieee80211_chanctx_mode mode) | ||
1470 | { | ||
1471 | struct ieee80211_local *local = sdata->local; | ||
1472 | struct ieee80211_chanctx *ctx; | ||
1473 | u8 radar_detect_width = 0; | ||
1474 | int ret; | ||
1475 | |||
1476 | lockdep_assert_held(&local->mtx); | ||
1477 | |||
1478 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | ||
1479 | |||
1480 | mutex_lock(&local->chanctx_mtx); | ||
1481 | |||
1482 | ret = cfg80211_chandef_dfs_required(local->hw.wiphy, | ||
1483 | chandef, | ||
1484 | sdata->wdev.iftype); | ||
1485 | if (ret < 0) | ||
1486 | goto out; | ||
1487 | if (ret > 0) | ||
1488 | radar_detect_width = BIT(chandef->width); | ||
1489 | |||
1490 | sdata->radar_required = ret; | ||
1491 | |||
1492 | ret = ieee80211_check_combinations(sdata, chandef, mode, | ||
1493 | radar_detect_width); | ||
1494 | if (ret < 0) | ||
1495 | goto out; | ||
1496 | |||
1497 | __ieee80211_vif_release_channel(sdata); | ||
1498 | |||
1499 | ctx = ieee80211_find_chanctx(local, chandef, mode); | ||
1500 | if (!ctx) | ||
1501 | ctx = ieee80211_new_chanctx(local, chandef, mode); | ||
1502 | if (IS_ERR(ctx)) { | ||
1503 | ret = PTR_ERR(ctx); | ||
1504 | goto out; | ||
1505 | } | ||
1506 | |||
1507 | sdata->vif.bss_conf.chandef = *chandef; | ||
1508 | |||
1509 | ret = ieee80211_assign_vif_chanctx(sdata, ctx); | ||
1510 | if (ret) { | ||
1511 | /* if assign fails refcount stays the same */ | ||
1512 | if (ieee80211_chanctx_refcount(local, ctx) == 0) | ||
1513 | ieee80211_free_chanctx(local, ctx); | ||
1514 | goto out; | ||
1515 | } | ||
1516 | |||
1517 | ieee80211_recalc_smps_chanctx(local, ctx); | ||
1518 | ieee80211_recalc_radar_chanctx(local, ctx); | ||
1519 | out: | ||
1520 | mutex_unlock(&local->chanctx_mtx); | ||
1521 | return ret; | ||
1522 | } | ||
1523 | |||
1525 | int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata) | 1524 | int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata) |
1526 | { | 1525 | { |
1527 | struct ieee80211_local *local = sdata->local; | 1526 | struct ieee80211_local *local = sdata->local; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 86173c0de40e..33eb4a43a2f3 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -77,7 +77,8 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
77 | TEST(AUTH), TEST(ASSOC), TEST(PS_STA), | 77 | TEST(AUTH), TEST(ASSOC), TEST(PS_STA), |
78 | TEST(PS_DRIVER), TEST(AUTHORIZED), | 78 | TEST(PS_DRIVER), TEST(AUTHORIZED), |
79 | TEST(SHORT_PREAMBLE), | 79 | TEST(SHORT_PREAMBLE), |
80 | TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), | 80 | sta->sta.wme ? "WME\n" : "", |
81 | TEST(WDS), TEST(CLEAR_PS_FILT), | ||
81 | TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), | 82 | TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), |
82 | TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), | 83 | TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), |
83 | TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), | 84 | TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 9713dc54ea4b..5f9654d31a8d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1038,7 +1038,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | if (sta && elems->wmm_info) | 1040 | if (sta && elems->wmm_info) |
1041 | set_sta_flag(sta, WLAN_STA_WME); | 1041 | sta->sta.wme = true; |
1042 | 1042 | ||
1043 | if (sta && elems->ht_operation && elems->ht_cap_elem && | 1043 | if (sta && elems->ht_operation && elems->ht_cap_elem && |
1044 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 1044 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ef7a089ac546..ffb20e5e6cf3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1869,7 +1869,6 @@ ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata, | |||
1869 | int __must_check | 1869 | int __must_check |
1870 | ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata); | 1870 | ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata); |
1871 | int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata); | 1871 | int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata); |
1872 | int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local); | ||
1873 | 1872 | ||
1874 | int __must_check | 1873 | int __must_check |
1875 | ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, | 1874 | ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index d808cff80153..6429d0e1d4a1 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -130,9 +130,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
130 | if (!ret) { | 130 | if (!ret) { |
131 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 131 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
132 | 132 | ||
133 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 133 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) |
134 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
135 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
136 | sdata->crypto_tx_tailroom_needed_cnt--; | 134 | sdata->crypto_tx_tailroom_needed_cnt--; |
137 | 135 | ||
138 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | 136 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
@@ -180,9 +178,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
180 | sta = key->sta; | 178 | sta = key->sta; |
181 | sdata = key->sdata; | 179 | sdata = key->sdata; |
182 | 180 | ||
183 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 181 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) |
184 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
185 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
186 | increment_tailroom_need_count(sdata); | 182 | increment_tailroom_need_count(sdata); |
187 | 183 | ||
188 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, | 184 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, |
@@ -878,9 +874,7 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) | |||
878 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 874 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
879 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 875 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
880 | 876 | ||
881 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 877 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) |
882 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
883 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
884 | increment_tailroom_need_count(key->sdata); | 878 | increment_tailroom_need_count(key->sdata); |
885 | } | 879 | } |
886 | 880 | ||
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index cf032a8db9d7..a6699dceae7c 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -729,7 +729,7 @@ void mesh_plink_broken(struct sta_info *sta) | |||
729 | tbl = rcu_dereference(mesh_paths); | 729 | tbl = rcu_dereference(mesh_paths); |
730 | for_each_mesh_entry(tbl, node, i) { | 730 | for_each_mesh_entry(tbl, node, i) { |
731 | mpath = node->mpath; | 731 | mpath = node->mpath; |
732 | if (rcu_dereference(mpath->next_hop) == sta && | 732 | if (rcu_access_pointer(mpath->next_hop) == sta && |
733 | mpath->flags & MESH_PATH_ACTIVE && | 733 | mpath->flags & MESH_PATH_ACTIVE && |
734 | !(mpath->flags & MESH_PATH_FIXED)) { | 734 | !(mpath->flags & MESH_PATH_FIXED)) { |
735 | spin_lock_bh(&mpath->state_lock); | 735 | spin_lock_bh(&mpath->state_lock); |
@@ -794,7 +794,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) | |||
794 | tbl = resize_dereference_mesh_paths(); | 794 | tbl = resize_dereference_mesh_paths(); |
795 | for_each_mesh_entry(tbl, node, i) { | 795 | for_each_mesh_entry(tbl, node, i) { |
796 | mpath = node->mpath; | 796 | mpath = node->mpath; |
797 | if (rcu_dereference(mpath->next_hop) == sta) { | 797 | if (rcu_access_pointer(mpath->next_hop) == sta) { |
798 | spin_lock(&tbl->hashwlock[i]); | 798 | spin_lock(&tbl->hashwlock[i]); |
799 | __mesh_path_del(tbl, node); | 799 | __mesh_path_del(tbl, node); |
800 | spin_unlock(&tbl->hashwlock[i]); | 800 | spin_unlock(&tbl->hashwlock[i]); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index c47194d27149..b488e1859b18 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -431,14 +431,12 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) | |||
431 | return NULL; | 431 | return NULL; |
432 | 432 | ||
433 | sta->plink_state = NL80211_PLINK_LISTEN; | 433 | sta->plink_state = NL80211_PLINK_LISTEN; |
434 | sta->sta.wme = true; | ||
434 | 435 | ||
435 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | 436 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); |
436 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); | 437 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); |
437 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); | 438 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); |
438 | 439 | ||
439 | set_sta_flag(sta, WLAN_STA_WME); | ||
440 | sta->sta.wme = true; | ||
441 | |||
442 | return sta; | 440 | return sta; |
443 | } | 441 | } |
444 | 442 | ||
@@ -1004,7 +1002,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
1004 | enum ieee80211_self_protected_actioncode ftype; | 1002 | enum ieee80211_self_protected_actioncode ftype; |
1005 | u32 changed = 0; | 1003 | u32 changed = 0; |
1006 | u8 ie_len = elems->peering_len; | 1004 | u8 ie_len = elems->peering_len; |
1007 | __le16 _plid, _llid; | ||
1008 | u16 plid, llid = 0; | 1005 | u16 plid, llid = 0; |
1009 | 1006 | ||
1010 | if (!elems->peering) { | 1007 | if (!elems->peering) { |
@@ -1039,13 +1036,10 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
1039 | /* Note the lines below are correct, the llid in the frame is the plid | 1036 | /* Note the lines below are correct, the llid in the frame is the plid |
1040 | * from the point of view of this host. | 1037 | * from the point of view of this host. |
1041 | */ | 1038 | */ |
1042 | memcpy(&_plid, PLINK_GET_LLID(elems->peering), sizeof(__le16)); | 1039 | plid = get_unaligned_le16(PLINK_GET_LLID(elems->peering)); |
1043 | plid = le16_to_cpu(_plid); | ||
1044 | if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || | 1040 | if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || |
1045 | (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) { | 1041 | (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) |
1046 | memcpy(&_llid, PLINK_GET_PLID(elems->peering), sizeof(__le16)); | 1042 | llid = get_unaligned_le16(PLINK_GET_PLID(elems->peering)); |
1047 | llid = le16_to_cpu(_llid); | ||
1048 | } | ||
1049 | 1043 | ||
1050 | /* WARNING: Only for sta pointer, is dropped & re-acquired */ | 1044 | /* WARNING: Only for sta pointer, is dropped & re-acquired */ |
1051 | rcu_read_lock(); | 1045 | rcu_read_lock(); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b82a12a9f0f1..8a73de6a5f5b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -149,6 +149,7 @@ static u32 | |||
149 | ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | 149 | ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, |
150 | struct ieee80211_supported_band *sband, | 150 | struct ieee80211_supported_band *sband, |
151 | struct ieee80211_channel *channel, | 151 | struct ieee80211_channel *channel, |
152 | const struct ieee80211_ht_cap *ht_cap, | ||
152 | const struct ieee80211_ht_operation *ht_oper, | 153 | const struct ieee80211_ht_operation *ht_oper, |
153 | const struct ieee80211_vht_operation *vht_oper, | 154 | const struct ieee80211_vht_operation *vht_oper, |
154 | struct cfg80211_chan_def *chandef, bool tracking) | 155 | struct cfg80211_chan_def *chandef, bool tracking) |
@@ -162,13 +163,19 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
162 | chandef->center_freq1 = channel->center_freq; | 163 | chandef->center_freq1 = channel->center_freq; |
163 | chandef->center_freq2 = 0; | 164 | chandef->center_freq2 = 0; |
164 | 165 | ||
165 | if (!ht_oper || !sband->ht_cap.ht_supported) { | 166 | if (!ht_cap || !ht_oper || !sband->ht_cap.ht_supported) { |
166 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; | 167 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; |
167 | goto out; | 168 | goto out; |
168 | } | 169 | } |
169 | 170 | ||
170 | chandef->width = NL80211_CHAN_WIDTH_20; | 171 | chandef->width = NL80211_CHAN_WIDTH_20; |
171 | 172 | ||
173 | if (!(ht_cap->cap_info & | ||
174 | cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) { | ||
175 | ret = IEEE80211_STA_DISABLE_40MHZ | IEEE80211_STA_DISABLE_VHT; | ||
176 | goto out; | ||
177 | } | ||
178 | |||
172 | ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, | 179 | ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, |
173 | channel->band); | 180 | channel->band); |
174 | /* check that channel matches the right operating channel */ | 181 | /* check that channel matches the right operating channel */ |
@@ -328,6 +335,7 @@ out: | |||
328 | 335 | ||
329 | static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, | 336 | static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, |
330 | struct sta_info *sta, | 337 | struct sta_info *sta, |
338 | const struct ieee80211_ht_cap *ht_cap, | ||
331 | const struct ieee80211_ht_operation *ht_oper, | 339 | const struct ieee80211_ht_operation *ht_oper, |
332 | const struct ieee80211_vht_operation *vht_oper, | 340 | const struct ieee80211_vht_operation *vht_oper, |
333 | const u8 *bssid, u32 *changed) | 341 | const u8 *bssid, u32 *changed) |
@@ -367,8 +375,9 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, | |||
367 | sband = local->hw.wiphy->bands[chan->band]; | 375 | sband = local->hw.wiphy->bands[chan->band]; |
368 | 376 | ||
369 | /* calculate new channel (type) based on HT/VHT operation IEs */ | 377 | /* calculate new channel (type) based on HT/VHT operation IEs */ |
370 | flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper, | 378 | flags = ieee80211_determine_chantype(sdata, sband, chan, |
371 | vht_oper, &chandef, true); | 379 | ht_cap, ht_oper, vht_oper, |
380 | &chandef, true); | ||
372 | 381 | ||
373 | /* | 382 | /* |
374 | * Downgrade the new channel if we associated with restricted | 383 | * Downgrade the new channel if we associated with restricted |
@@ -2677,8 +2686,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2677 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) | 2686 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) |
2678 | set_sta_flag(sta, WLAN_STA_MFP); | 2687 | set_sta_flag(sta, WLAN_STA_MFP); |
2679 | 2688 | ||
2680 | if (elems.wmm_param) | 2689 | sta->sta.wme = elems.wmm_param; |
2681 | set_sta_flag(sta, WLAN_STA_WME); | ||
2682 | 2690 | ||
2683 | err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | 2691 | err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); |
2684 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 2692 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
@@ -3174,7 +3182,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3174 | mutex_lock(&local->sta_mtx); | 3182 | mutex_lock(&local->sta_mtx); |
3175 | sta = sta_info_get(sdata, bssid); | 3183 | sta = sta_info_get(sdata, bssid); |
3176 | 3184 | ||
3177 | if (ieee80211_config_bw(sdata, sta, elems.ht_operation, | 3185 | if (ieee80211_config_bw(sdata, sta, |
3186 | elems.ht_cap_elem, elems.ht_operation, | ||
3178 | elems.vht_operation, bssid, &changed)) { | 3187 | elems.vht_operation, bssid, &changed)) { |
3179 | mutex_unlock(&local->sta_mtx); | 3188 | mutex_unlock(&local->sta_mtx); |
3180 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3189 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
@@ -3808,6 +3817,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3808 | { | 3817 | { |
3809 | struct ieee80211_local *local = sdata->local; | 3818 | struct ieee80211_local *local = sdata->local; |
3810 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3819 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3820 | const struct ieee80211_ht_cap *ht_cap = NULL; | ||
3811 | const struct ieee80211_ht_operation *ht_oper = NULL; | 3821 | const struct ieee80211_ht_operation *ht_oper = NULL; |
3812 | const struct ieee80211_vht_operation *vht_oper = NULL; | 3822 | const struct ieee80211_vht_operation *vht_oper = NULL; |
3813 | struct ieee80211_supported_band *sband; | 3823 | struct ieee80211_supported_band *sband; |
@@ -3824,14 +3834,17 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3824 | 3834 | ||
3825 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | 3835 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && |
3826 | sband->ht_cap.ht_supported) { | 3836 | sband->ht_cap.ht_supported) { |
3827 | const u8 *ht_oper_ie, *ht_cap; | 3837 | const u8 *ht_oper_ie, *ht_cap_ie; |
3828 | 3838 | ||
3829 | ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); | 3839 | ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); |
3830 | if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) | 3840 | if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) |
3831 | ht_oper = (void *)(ht_oper_ie + 2); | 3841 | ht_oper = (void *)(ht_oper_ie + 2); |
3832 | 3842 | ||
3833 | ht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY); | 3843 | ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY); |
3834 | if (!ht_cap || ht_cap[1] < sizeof(struct ieee80211_ht_cap)) { | 3844 | if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) |
3845 | ht_cap = (void *)(ht_cap_ie + 2); | ||
3846 | |||
3847 | if (!ht_cap) { | ||
3835 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; | 3848 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; |
3836 | ht_oper = NULL; | 3849 | ht_oper = NULL; |
3837 | } | 3850 | } |
@@ -3862,7 +3875,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3862 | 3875 | ||
3863 | ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, | 3876 | ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, |
3864 | cbss->channel, | 3877 | cbss->channel, |
3865 | ht_oper, vht_oper, | 3878 | ht_cap, ht_oper, vht_oper, |
3866 | &chandef, false); | 3879 | &chandef, false); |
3867 | 3880 | ||
3868 | sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), | 3881 | sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bd2c9b22c945..a8d862f9183c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2725,7 +2725,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2725 | sig = status->signal; | 2725 | sig = status->signal; |
2726 | 2726 | ||
2727 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, | 2727 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, |
2728 | rx->skb->data, rx->skb->len, 0, GFP_ATOMIC)) { | 2728 | rx->skb->data, rx->skb->len, 0)) { |
2729 | if (rx->sta) | 2729 | if (rx->sta) |
2730 | rx->sta->rx_packets++; | 2730 | rx->sta->rx_packets++; |
2731 | dev_kfree_skb(rx->skb); | 2731 | dev_kfree_skb(rx->skb); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index a0a938145dcc..a9bb6eb8c3e0 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -1094,7 +1094,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) | |||
1094 | if (rcu_access_pointer(local->sched_scan_sdata)) { | 1094 | if (rcu_access_pointer(local->sched_scan_sdata)) { |
1095 | ret = drv_sched_scan_stop(local, sdata); | 1095 | ret = drv_sched_scan_stop(local, sdata); |
1096 | if (!ret) | 1096 | if (!ret) |
1097 | rcu_assign_pointer(local->sched_scan_sdata, NULL); | 1097 | RCU_INIT_POINTER(local->sched_scan_sdata, NULL); |
1098 | } | 1098 | } |
1099 | out: | 1099 | out: |
1100 | mutex_unlock(&local->mtx); | 1100 | mutex_unlock(&local->mtx); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 441875f03750..730030542024 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1182,7 +1182,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1182 | struct sk_buff *skb; | 1182 | struct sk_buff *skb; |
1183 | int size = sizeof(*nullfunc); | 1183 | int size = sizeof(*nullfunc); |
1184 | __le16 fc; | 1184 | __le16 fc; |
1185 | bool qos = test_sta_flag(sta, WLAN_STA_WME); | 1185 | bool qos = sta->sta.wme; |
1186 | struct ieee80211_tx_info *info; | 1186 | struct ieee80211_tx_info *info; |
1187 | struct ieee80211_chanctx_conf *chanctx_conf; | 1187 | struct ieee80211_chanctx_conf *chanctx_conf; |
1188 | 1188 | ||
@@ -1837,7 +1837,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1837 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | 1837 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); |
1838 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) | 1838 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) |
1839 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); | 1839 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); |
1840 | if (test_sta_flag(sta, WLAN_STA_WME)) | 1840 | if (sta->sta.wme) |
1841 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); | 1841 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); |
1842 | if (test_sta_flag(sta, WLAN_STA_MFP)) | 1842 | if (test_sta_flag(sta, WLAN_STA_MFP)) |
1843 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | 1843 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index d411bcc8ef08..89c40d5c0633 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -31,7 +31,6 @@ | |||
31 | * when virtual port control is not in use. | 31 | * when virtual port control is not in use. |
32 | * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble | 32 | * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble |
33 | * frames. | 33 | * frames. |
34 | * @WLAN_STA_WME: Station is a QoS-STA. | ||
35 | * @WLAN_STA_WDS: Station is one of our WDS peers. | 34 | * @WLAN_STA_WDS: Station is one of our WDS peers. |
36 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the | 35 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the |
37 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next | 36 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next |
@@ -69,7 +68,6 @@ enum ieee80211_sta_info_flags { | |||
69 | WLAN_STA_PS_STA, | 68 | WLAN_STA_PS_STA, |
70 | WLAN_STA_AUTHORIZED, | 69 | WLAN_STA_AUTHORIZED, |
71 | WLAN_STA_SHORT_PREAMBLE, | 70 | WLAN_STA_SHORT_PREAMBLE, |
72 | WLAN_STA_WME, | ||
73 | WLAN_STA_WDS, | 71 | WLAN_STA_WDS, |
74 | WLAN_STA_CLEAR_PS_FILT, | 72 | WLAN_STA_CLEAR_PS_FILT, |
75 | WLAN_STA_MFP, | 73 | WLAN_STA_MFP, |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 1b21050be174..f2cb3b6c1871 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -316,8 +316,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, | |||
316 | } | 316 | } |
317 | 317 | ||
318 | /* add the QoS param IE if both the peer and we support it */ | 318 | /* add the QoS param IE if both the peer and we support it */ |
319 | if (local->hw.queues >= IEEE80211_NUM_ACS && | 319 | if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme) |
320 | test_sta_flag(sta, WLAN_STA_WME)) | ||
321 | ieee80211_tdls_add_wmm_param_ie(sdata, skb); | 320 | ieee80211_tdls_add_wmm_param_ie(sdata, skb); |
322 | 321 | ||
323 | /* add any custom IEs that go before HT operation */ | 322 | /* add any custom IEs that go before HT operation */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 464106c023d8..925c39f4099e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1478,7 +1478,10 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1478 | tail_need = max_t(int, tail_need, 0); | 1478 | tail_need = max_t(int, tail_need, 0); |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | if (skb_cloned(skb)) | 1481 | if (skb_cloned(skb) && |
1482 | (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CLONED_SKBS) || | ||
1483 | !skb_clone_writable(skb, ETH_HLEN) || | ||
1484 | sdata->crypto_tx_tailroom_needed_cnt)) | ||
1482 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | 1485 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); |
1483 | else if (head_need || tail_need) | 1486 | else if (head_need || tail_need) |
1484 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1487 | I802_DEBUG_INC(local->tx_expand_skb_head); |
@@ -1844,7 +1847,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1844 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1847 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
1845 | hdrlen = 30; | 1848 | hdrlen = 30; |
1846 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | 1849 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1847 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | 1850 | wme_sta = sta->sta.wme; |
1848 | } | 1851 | } |
1849 | ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | 1852 | ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, |
1850 | u.ap); | 1853 | u.ap); |
@@ -1957,7 +1960,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1957 | if (sta) { | 1960 | if (sta) { |
1958 | authorized = test_sta_flag(sta, | 1961 | authorized = test_sta_flag(sta, |
1959 | WLAN_STA_AUTHORIZED); | 1962 | WLAN_STA_AUTHORIZED); |
1960 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | 1963 | wme_sta = sta->sta.wme; |
1961 | tdls_peer = test_sta_flag(sta, | 1964 | tdls_peer = test_sta_flag(sta, |
1962 | WLAN_STA_TDLS_PEER); | 1965 | WLAN_STA_TDLS_PEER); |
1963 | tdls_auth = test_sta_flag(sta, | 1966 | tdls_auth = test_sta_flag(sta, |
@@ -2035,7 +2038,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2035 | sta = sta_info_get(sdata, hdr.addr1); | 2038 | sta = sta_info_get(sdata, hdr.addr1); |
2036 | if (sta) { | 2039 | if (sta) { |
2037 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | 2040 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
2038 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | 2041 | wme_sta = sta->sta.wme; |
2039 | } | 2042 | } |
2040 | } | 2043 | } |
2041 | 2044 | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index d51422c778de..6459946f0b74 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -118,7 +118,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
118 | case NL80211_IFTYPE_AP_VLAN: | 118 | case NL80211_IFTYPE_AP_VLAN: |
119 | sta = rcu_dereference(sdata->u.vlan.sta); | 119 | sta = rcu_dereference(sdata->u.vlan.sta); |
120 | if (sta) { | 120 | if (sta) { |
121 | qos = test_sta_flag(sta, WLAN_STA_WME); | 121 | qos = sta->sta.wme; |
122 | break; | 122 | break; |
123 | } | 123 | } |
124 | case NL80211_IFTYPE_AP: | 124 | case NL80211_IFTYPE_AP: |
@@ -145,7 +145,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
145 | if (!sta && ra && !is_multicast_ether_addr(ra)) { | 145 | if (!sta && ra && !is_multicast_ether_addr(ra)) { |
146 | sta = sta_info_get(sdata, ra); | 146 | sta = sta_info_get(sdata, ra); |
147 | if (sta) | 147 | if (sta) |
148 | qos = test_sta_flag(sta, WLAN_STA_WME); | 148 | qos = sta->sta.wme; |
149 | } | 149 | } |
150 | rcu_read_unlock(); | 150 | rcu_read_unlock(); |
151 | 151 | ||
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 7f820a108a9c..a14cf9ede171 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c | |||
@@ -86,9 +86,8 @@ fail: | |||
86 | static void mac802154_rx_worker(struct work_struct *work) | 86 | static void mac802154_rx_worker(struct work_struct *work) |
87 | { | 87 | { |
88 | struct rx_work *rw = container_of(work, struct rx_work, work); | 88 | struct rx_work *rw = container_of(work, struct rx_work, work); |
89 | struct sk_buff *skb = rw->skb; | ||
90 | 89 | ||
91 | mac802154_subif_rx(rw->dev, skb, rw->lqi); | 90 | mac802154_subif_rx(rw->dev, rw->skb, rw->lqi); |
92 | kfree(rw); | 91 | kfree(rw); |
93 | } | 92 | } |
94 | 93 | ||
@@ -101,7 +100,7 @@ ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) | |||
101 | if (!skb) | 100 | if (!skb) |
102 | return; | 101 | return; |
103 | 102 | ||
104 | work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC); | 103 | work = kzalloc(sizeof(*work), GFP_ATOMIC); |
105 | if (!work) | 104 | if (!work) |
106 | return; | 105 | return; |
107 | 106 | ||
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8124353646ae..fdf4c0e67259 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c | |||
@@ -89,8 +89,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, | |||
89 | 89 | ||
90 | if (!(priv->phy->channels_supported[page] & (1 << chan))) { | 90 | if (!(priv->phy->channels_supported[page] & (1 << chan))) { |
91 | WARN_ON(1); | 91 | WARN_ON(1); |
92 | kfree_skb(skb); | 92 | goto err_tx; |
93 | return NETDEV_TX_OK; | ||
94 | } | 93 | } |
95 | 94 | ||
96 | mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); | 95 | mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); |
@@ -103,12 +102,10 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, | |||
103 | data[1] = crc >> 8; | 102 | data[1] = crc >> 8; |
104 | } | 103 | } |
105 | 104 | ||
106 | if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) { | 105 | if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) |
107 | kfree_skb(skb); | 106 | goto err_tx; |
108 | return NETDEV_TX_OK; | ||
109 | } | ||
110 | 107 | ||
111 | work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC); | 108 | work = kzalloc(sizeof(*work), GFP_ATOMIC); |
112 | if (!work) { | 109 | if (!work) { |
113 | kfree_skb(skb); | 110 | kfree_skb(skb); |
114 | return NETDEV_TX_BUSY; | 111 | return NETDEV_TX_BUSY; |
@@ -129,4 +126,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, | |||
129 | queue_work(priv->dev_workqueue, &work->work); | 126 | queue_work(priv->dev_workqueue, &work->work); |
130 | 127 | ||
131 | return NETDEV_TX_OK; | 128 | return NETDEV_TX_OK; |
129 | |||
130 | err_tx: | ||
131 | kfree_skb(skb); | ||
132 | return NETDEV_TX_OK; | ||
132 | } | 133 | } |
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 547838822d5e..b7961129ce4d 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c | |||
@@ -475,8 +475,7 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, | |||
475 | rc = mac802154_llsec_decrypt(&sdata->sec, skb); | 475 | rc = mac802154_llsec_decrypt(&sdata->sec, skb); |
476 | if (rc) { | 476 | if (rc) { |
477 | pr_debug("decryption failed: %i\n", rc); | 477 | pr_debug("decryption failed: %i\n", rc); |
478 | kfree_skb(skb); | 478 | goto fail; |
479 | return NET_RX_DROP; | ||
480 | } | 479 | } |
481 | 480 | ||
482 | sdata->dev->stats.rx_packets++; | 481 | sdata->dev->stats.rx_packets++; |
@@ -488,9 +487,12 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, | |||
488 | default: | 487 | default: |
489 | pr_warn("ieee802154: bad frame received (type = %d)\n", | 488 | pr_warn("ieee802154: bad frame received (type = %d)\n", |
490 | mac_cb(skb)->type); | 489 | mac_cb(skb)->type); |
491 | kfree_skb(skb); | 490 | goto fail; |
492 | return NET_RX_DROP; | ||
493 | } | 491 | } |
492 | |||
493 | fail: | ||
494 | kfree_skb(skb); | ||
495 | return NET_RX_DROP; | ||
494 | } | 496 | } |
495 | 497 | ||
496 | static void mac802154_print_addr(const char *name, | 498 | static void mac802154_print_addr(const char *name, |
diff --git a/net/wireless/core.c b/net/wireless/core.c index afee5e0455ea..c6620aa679e0 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -492,12 +492,6 @@ int wiphy_register(struct wiphy *wiphy) | |||
492 | int i; | 492 | int i; |
493 | u16 ifmodes = wiphy->interface_modes; | 493 | u16 ifmodes = wiphy->interface_modes; |
494 | 494 | ||
495 | /* | ||
496 | * There are major locking problems in nl80211/mac80211 for CSA, | ||
497 | * disable for all drivers until this has been reworked. | ||
498 | */ | ||
499 | wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH; | ||
500 | |||
501 | #ifdef CONFIG_PM | 495 | #ifdef CONFIG_PM |
502 | if (WARN_ON(wiphy->wowlan && | 496 | if (WARN_ON(wiphy->wowlan && |
503 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 497 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
@@ -635,6 +629,9 @@ int wiphy_register(struct wiphy *wiphy) | |||
635 | if (IS_ERR(rdev->wiphy.debugfsdir)) | 629 | if (IS_ERR(rdev->wiphy.debugfsdir)) |
636 | rdev->wiphy.debugfsdir = NULL; | 630 | rdev->wiphy.debugfsdir = NULL; |
637 | 631 | ||
632 | cfg80211_debugfs_rdev_add(rdev); | ||
633 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); | ||
634 | |||
638 | if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { | 635 | if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { |
639 | struct regulatory_request request; | 636 | struct regulatory_request request; |
640 | 637 | ||
@@ -646,8 +643,6 @@ int wiphy_register(struct wiphy *wiphy) | |||
646 | nl80211_send_reg_change_event(&request); | 643 | nl80211_send_reg_change_event(&request); |
647 | } | 644 | } |
648 | 645 | ||
649 | cfg80211_debugfs_rdev_add(rdev); | ||
650 | |||
651 | rdev->wiphy.registered = true; | 646 | rdev->wiphy.registered = true; |
652 | rtnl_unlock(); | 647 | rtnl_unlock(); |
653 | 648 | ||
@@ -659,8 +654,6 @@ int wiphy_register(struct wiphy *wiphy) | |||
659 | return res; | 654 | return res; |
660 | } | 655 | } |
661 | 656 | ||
662 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); | ||
663 | |||
664 | return 0; | 657 | return 0; |
665 | } | 658 | } |
666 | EXPORT_SYMBOL(wiphy_register); | 659 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 266766b8d80b..369fc334fdad 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -605,7 +605,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
605 | } | 605 | } |
606 | 606 | ||
607 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | 607 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, |
608 | const u8 *buf, size_t len, u32 flags, gfp_t gfp) | 608 | const u8 *buf, size_t len, u32 flags) |
609 | { | 609 | { |
610 | struct wiphy *wiphy = wdev->wiphy; | 610 | struct wiphy *wiphy = wdev->wiphy; |
611 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 611 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
@@ -648,7 +648,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
648 | /* Indicate the received Action frame to user space */ | 648 | /* Indicate the received Action frame to user space */ |
649 | if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, | 649 | if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, |
650 | freq, sig_mbm, | 650 | freq, sig_mbm, |
651 | buf, len, flags, gfp)) | 651 | buf, len, flags, GFP_ATOMIC)) |
652 | continue; | 652 | continue; |
653 | 653 | ||
654 | result = true; | 654 | result = true; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index df7b1332a1ec..3011401f52c0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6033,7 +6033,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | |||
6033 | const struct cfg80211_bss_ies *ies; | 6033 | const struct cfg80211_bss_ies *ies; |
6034 | void *hdr; | 6034 | void *hdr; |
6035 | struct nlattr *bss; | 6035 | struct nlattr *bss; |
6036 | bool tsf = false; | ||
6037 | 6036 | ||
6038 | ASSERT_WDEV_LOCK(wdev); | 6037 | ASSERT_WDEV_LOCK(wdev); |
6039 | 6038 | ||
@@ -6060,18 +6059,27 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | |||
6060 | goto nla_put_failure; | 6059 | goto nla_put_failure; |
6061 | 6060 | ||
6062 | rcu_read_lock(); | 6061 | rcu_read_lock(); |
6062 | /* indicate whether we have probe response data or not */ | ||
6063 | if (rcu_access_pointer(res->proberesp_ies) && | ||
6064 | nla_put_flag(msg, NL80211_BSS_PRESP_DATA)) | ||
6065 | goto fail_unlock_rcu; | ||
6066 | |||
6067 | /* this pointer prefers to be pointed to probe response data | ||
6068 | * but is always valid | ||
6069 | */ | ||
6063 | ies = rcu_dereference(res->ies); | 6070 | ies = rcu_dereference(res->ies); |
6064 | if (ies) { | 6071 | if (ies) { |
6065 | if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) | 6072 | if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) |
6066 | goto fail_unlock_rcu; | 6073 | goto fail_unlock_rcu; |
6067 | tsf = true; | ||
6068 | if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, | 6074 | if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, |
6069 | ies->len, ies->data)) | 6075 | ies->len, ies->data)) |
6070 | goto fail_unlock_rcu; | 6076 | goto fail_unlock_rcu; |
6071 | } | 6077 | } |
6078 | |||
6079 | /* and this pointer is always (unless driver didn't know) beacon data */ | ||
6072 | ies = rcu_dereference(res->beacon_ies); | 6080 | ies = rcu_dereference(res->beacon_ies); |
6073 | if (ies) { | 6081 | if (ies && ies->from_beacon) { |
6074 | if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) | 6082 | if (nla_put_u64(msg, NL80211_BSS_BEACON_TSF, ies->tsf)) |
6075 | goto fail_unlock_rcu; | 6083 | goto fail_unlock_rcu; |
6076 | if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, | 6084 | if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, |
6077 | ies->len, ies->data)) | 6085 | ies->len, ies->data)) |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0798c62e6085..620a4b40d466 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -884,6 +884,7 @@ struct cfg80211_bss* | |||
884 | cfg80211_inform_bss_width(struct wiphy *wiphy, | 884 | cfg80211_inform_bss_width(struct wiphy *wiphy, |
885 | struct ieee80211_channel *rx_channel, | 885 | struct ieee80211_channel *rx_channel, |
886 | enum nl80211_bss_scan_width scan_width, | 886 | enum nl80211_bss_scan_width scan_width, |
887 | enum cfg80211_bss_frame_type ftype, | ||
887 | const u8 *bssid, u64 tsf, u16 capability, | 888 | const u8 *bssid, u64 tsf, u16 capability, |
888 | u16 beacon_interval, const u8 *ie, size_t ielen, | 889 | u16 beacon_interval, const u8 *ie, size_t ielen, |
889 | s32 signal, gfp_t gfp) | 890 | s32 signal, gfp_t gfp) |
@@ -911,21 +912,32 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
911 | tmp.pub.beacon_interval = beacon_interval; | 912 | tmp.pub.beacon_interval = beacon_interval; |
912 | tmp.pub.capability = capability; | 913 | tmp.pub.capability = capability; |
913 | /* | 914 | /* |
914 | * Since we do not know here whether the IEs are from a Beacon or Probe | 915 | * If we do not know here whether the IEs are from a Beacon or Probe |
915 | * Response frame, we need to pick one of the options and only use it | 916 | * Response frame, we need to pick one of the options and only use it |
916 | * with the driver that does not provide the full Beacon/Probe Response | 917 | * with the driver that does not provide the full Beacon/Probe Response |
917 | * frame. Use Beacon frame pointer to avoid indicating that this should | 918 | * frame. Use Beacon frame pointer to avoid indicating that this should |
918 | * override the IEs pointer should we have received an earlier | 919 | * override the IEs pointer should we have received an earlier |
919 | * indication of Probe Response data. | 920 | * indication of Probe Response data. |
920 | */ | 921 | */ |
921 | ies = kmalloc(sizeof(*ies) + ielen, gfp); | 922 | ies = kzalloc(sizeof(*ies) + ielen, gfp); |
922 | if (!ies) | 923 | if (!ies) |
923 | return NULL; | 924 | return NULL; |
924 | ies->len = ielen; | 925 | ies->len = ielen; |
925 | ies->tsf = tsf; | 926 | ies->tsf = tsf; |
927 | ies->from_beacon = false; | ||
926 | memcpy(ies->data, ie, ielen); | 928 | memcpy(ies->data, ie, ielen); |
927 | 929 | ||
928 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); | 930 | switch (ftype) { |
931 | case CFG80211_BSS_FTYPE_BEACON: | ||
932 | ies->from_beacon = true; | ||
933 | /* fall through to assign */ | ||
934 | case CFG80211_BSS_FTYPE_UNKNOWN: | ||
935 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); | ||
936 | break; | ||
937 | case CFG80211_BSS_FTYPE_PRESP: | ||
938 | rcu_assign_pointer(tmp.pub.proberesp_ies, ies); | ||
939 | break; | ||
940 | } | ||
929 | rcu_assign_pointer(tmp.pub.ies, ies); | 941 | rcu_assign_pointer(tmp.pub.ies, ies); |
930 | 942 | ||
931 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= | 943 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= |
@@ -982,11 +994,12 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
982 | if (!channel) | 994 | if (!channel) |
983 | return NULL; | 995 | return NULL; |
984 | 996 | ||
985 | ies = kmalloc(sizeof(*ies) + ielen, gfp); | 997 | ies = kzalloc(sizeof(*ies) + ielen, gfp); |
986 | if (!ies) | 998 | if (!ies) |
987 | return NULL; | 999 | return NULL; |
988 | ies->len = ielen; | 1000 | ies->len = ielen; |
989 | ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); | 1001 | ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); |
1002 | ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); | ||
990 | memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); | 1003 | memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); |
991 | 1004 | ||
992 | if (ieee80211_is_probe_resp(mgmt->frame_control)) | 1005 | if (ieee80211_is_probe_resp(mgmt->frame_control)) |