diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-04-25 14:34:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-25 14:34:25 -0400 |
commit | cfef6047c4027a8448ec8dafeaf2bb362cc882e4 (patch) | |
tree | c254bd25aa8b4b0696b5b5cc45d8e30c7c1bb9dd | |
parent | b71d1d426d263b0b6cb5760322efebbfc89d4463 (diff) | |
parent | 73b48099cc265f88fa1255f3f43e52fe6a94fd5c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.h
192 files changed, 7199 insertions, 5933 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 8e0de9a05867..11b41fd40c27 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -188,7 +188,7 @@ config BT_MRVL | |||
188 | The core driver to support Marvell Bluetooth devices. | 188 | The core driver to support Marvell Bluetooth devices. |
189 | 189 | ||
190 | This driver is required if you want to support | 190 | This driver is required if you want to support |
191 | Marvell Bluetooth devices, such as 8688. | 191 | Marvell Bluetooth devices, such as 8688/8787. |
192 | 192 | ||
193 | Say Y here to compile Marvell Bluetooth driver | 193 | Say Y here to compile Marvell Bluetooth driver |
194 | into the kernel or say M to compile it as module. | 194 | into the kernel or say M to compile it as module. |
@@ -201,7 +201,7 @@ config BT_MRVL_SDIO | |||
201 | The driver for Marvell Bluetooth chipsets with SDIO interface. | 201 | The driver for Marvell Bluetooth chipsets with SDIO interface. |
202 | 202 | ||
203 | This driver is required if you want to use Marvell Bluetooth | 203 | This driver is required if you want to use Marvell Bluetooth |
204 | devices with SDIO interface. Currently only SD8688 chipset is | 204 | devices with SDIO interface. Currently SD8688/SD8787 chipsets are |
205 | supported. | 205 | supported. |
206 | 206 | ||
207 | Say Y here to compile support for Marvell BT-over-SDIO driver | 207 | Say Y here to compile support for Marvell BT-over-SDIO driver |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 5577ed656e2f..695d4414bd4c 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -138,9 +138,6 @@ static int ath3k_load_firmware(struct usb_device *udev, | |||
138 | count -= size; | 138 | count -= size; |
139 | } | 139 | } |
140 | 140 | ||
141 | kfree(send_buf); | ||
142 | return 0; | ||
143 | |||
144 | error: | 141 | error: |
145 | kfree(send_buf); | 142 | kfree(send_buf); |
146 | return err; | 143 | return err; |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index dcc2a6ec23f0..7f521d4ac657 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -49,15 +49,59 @@ | |||
49 | static u8 user_rmmod; | 49 | static u8 user_rmmod; |
50 | static u8 sdio_ireg; | 50 | static u8 sdio_ireg; |
51 | 51 | ||
52 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { | ||
53 | .cfg = 0x03, | ||
54 | .host_int_mask = 0x04, | ||
55 | .host_intstatus = 0x05, | ||
56 | .card_status = 0x20, | ||
57 | .sq_read_base_addr_a0 = 0x10, | ||
58 | .sq_read_base_addr_a1 = 0x11, | ||
59 | .card_fw_status0 = 0x40, | ||
60 | .card_fw_status1 = 0x41, | ||
61 | .card_rx_len = 0x42, | ||
62 | .card_rx_unit = 0x43, | ||
63 | .io_port_0 = 0x00, | ||
64 | .io_port_1 = 0x01, | ||
65 | .io_port_2 = 0x02, | ||
66 | }; | ||
67 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { | ||
68 | .cfg = 0x00, | ||
69 | .host_int_mask = 0x02, | ||
70 | .host_intstatus = 0x03, | ||
71 | .card_status = 0x30, | ||
72 | .sq_read_base_addr_a0 = 0x40, | ||
73 | .sq_read_base_addr_a1 = 0x41, | ||
74 | .card_revision = 0x5c, | ||
75 | .card_fw_status0 = 0x60, | ||
76 | .card_fw_status1 = 0x61, | ||
77 | .card_rx_len = 0x62, | ||
78 | .card_rx_unit = 0x63, | ||
79 | .io_port_0 = 0x78, | ||
80 | .io_port_1 = 0x79, | ||
81 | .io_port_2 = 0x7a, | ||
82 | }; | ||
83 | |||
52 | static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { | 84 | static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { |
53 | .helper = "sd8688_helper.bin", | 85 | .helper = "sd8688_helper.bin", |
54 | .firmware = "sd8688.bin", | 86 | .firmware = "sd8688.bin", |
87 | .reg = &btmrvl_reg_8688, | ||
88 | .sd_blksz_fw_dl = 64, | ||
89 | }; | ||
90 | |||
91 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { | ||
92 | .helper = NULL, | ||
93 | .firmware = "mrvl/sd8787_uapsta.bin", | ||
94 | .reg = &btmrvl_reg_8787, | ||
95 | .sd_blksz_fw_dl = 256, | ||
55 | }; | 96 | }; |
56 | 97 | ||
57 | static const struct sdio_device_id btmrvl_sdio_ids[] = { | 98 | static const struct sdio_device_id btmrvl_sdio_ids[] = { |
58 | /* Marvell SD8688 Bluetooth device */ | 99 | /* Marvell SD8688 Bluetooth device */ |
59 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), | 100 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), |
60 | .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, | 101 | .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, |
102 | /* Marvell SD8787 Bluetooth device */ | ||
103 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), | ||
104 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, | ||
61 | 105 | ||
62 | { } /* Terminating entry */ | 106 | { } /* Terminating entry */ |
63 | }; | 107 | }; |
@@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) | |||
69 | u8 reg; | 113 | u8 reg; |
70 | int ret; | 114 | int ret; |
71 | 115 | ||
72 | reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret); | 116 | reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret); |
73 | if (!ret) | 117 | if (!ret) |
74 | card->rx_unit = reg; | 118 | card->rx_unit = reg; |
75 | 119 | ||
@@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) | |||
83 | 127 | ||
84 | *dat = 0; | 128 | *dat = 0; |
85 | 129 | ||
86 | fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); | 130 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); |
87 | if (ret) | 131 | if (ret) |
88 | return -EIO; | 132 | return -EIO; |
89 | 133 | ||
90 | fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); | 134 | fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret); |
91 | if (ret) | 135 | if (ret) |
92 | return -EIO; | 136 | return -EIO; |
93 | 137 | ||
@@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) | |||
101 | u8 reg; | 145 | u8 reg; |
102 | int ret; | 146 | int ret; |
103 | 147 | ||
104 | reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret); | 148 | reg = sdio_readb(card->func, card->reg->card_rx_len, &ret); |
105 | if (!ret) | 149 | if (!ret) |
106 | *dat = (u16) reg << card->rx_unit; | 150 | *dat = (u16) reg << card->rx_unit; |
107 | 151 | ||
@@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, | |||
113 | { | 157 | { |
114 | int ret; | 158 | int ret; |
115 | 159 | ||
116 | sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret); | 160 | sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret); |
117 | if (ret) { | 161 | if (ret) { |
118 | BT_ERR("Unable to enable the host interrupt!"); | 162 | BT_ERR("Unable to enable the host interrupt!"); |
119 | ret = -EIO; | 163 | ret = -EIO; |
@@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, | |||
128 | u8 host_int_mask; | 172 | u8 host_int_mask; |
129 | int ret; | 173 | int ret; |
130 | 174 | ||
131 | host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); | 175 | host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret); |
132 | if (ret) | 176 | if (ret) |
133 | return -EIO; | 177 | return -EIO; |
134 | 178 | ||
135 | host_int_mask &= ~mask; | 179 | host_int_mask &= ~mask; |
136 | 180 | ||
137 | sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); | 181 | sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret); |
138 | if (ret < 0) { | 182 | if (ret < 0) { |
139 | BT_ERR("Unable to disable the host interrupt!"); | 183 | BT_ERR("Unable to disable the host interrupt!"); |
140 | return -EIO; | 184 | return -EIO; |
@@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits) | |||
150 | int ret; | 194 | int ret; |
151 | 195 | ||
152 | for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { | 196 | for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { |
153 | status = sdio_readb(card->func, CARD_STATUS_REG, &ret); | 197 | status = sdio_readb(card->func, card->reg->card_status, &ret); |
154 | if (ret) | 198 | if (ret) |
155 | goto failed; | 199 | goto failed; |
156 | if ((status & bits) == bits) | 200 | if ((status & bits) == bits) |
@@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
299 | u8 base0, base1; | 343 | u8 base0, base1; |
300 | void *tmpfwbuf = NULL; | 344 | void *tmpfwbuf = NULL; |
301 | u8 *fwbuf; | 345 | u8 *fwbuf; |
302 | u16 len; | 346 | u16 len, blksz_dl = card->sd_blksz_fw_dl; |
303 | int txlen = 0, tx_blocks = 0, count = 0; | 347 | int txlen = 0, tx_blocks = 0, count = 0; |
304 | 348 | ||
305 | ret = request_firmware(&fw_firmware, card->firmware, | 349 | ret = request_firmware(&fw_firmware, card->firmware, |
@@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
345 | 389 | ||
346 | for (tries = 0; tries < MAX_POLL_TRIES; tries++) { | 390 | for (tries = 0; tries < MAX_POLL_TRIES; tries++) { |
347 | base0 = sdio_readb(card->func, | 391 | base0 = sdio_readb(card->func, |
348 | SQ_READ_BASE_ADDRESS_A0_REG, &ret); | 392 | card->reg->sq_read_base_addr_a0, &ret); |
349 | if (ret) { | 393 | if (ret) { |
350 | BT_ERR("BASE0 register read failed:" | 394 | BT_ERR("BASE0 register read failed:" |
351 | " base0 = 0x%04X(%d)." | 395 | " base0 = 0x%04X(%d)." |
@@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
355 | goto done; | 399 | goto done; |
356 | } | 400 | } |
357 | base1 = sdio_readb(card->func, | 401 | base1 = sdio_readb(card->func, |
358 | SQ_READ_BASE_ADDRESS_A1_REG, &ret); | 402 | card->reg->sq_read_base_addr_a1, &ret); |
359 | if (ret) { | 403 | if (ret) { |
360 | BT_ERR("BASE1 register read failed:" | 404 | BT_ERR("BASE1 register read failed:" |
361 | " base1 = 0x%04X(%d)." | 405 | " base1 = 0x%04X(%d)." |
@@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
403 | if (firmwarelen - offset < txlen) | 447 | if (firmwarelen - offset < txlen) |
404 | txlen = firmwarelen - offset; | 448 | txlen = firmwarelen - offset; |
405 | 449 | ||
406 | tx_blocks = | 450 | tx_blocks = (txlen + blksz_dl - 1) / blksz_dl; |
407 | (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE; | ||
408 | 451 | ||
409 | memcpy(fwbuf, &firmware[offset], txlen); | 452 | memcpy(fwbuf, &firmware[offset], txlen); |
410 | } | 453 | } |
411 | 454 | ||
412 | ret = sdio_writesb(card->func, card->ioport, fwbuf, | 455 | ret = sdio_writesb(card->func, card->ioport, fwbuf, |
413 | tx_blocks * SDIO_BLOCK_SIZE); | 456 | tx_blocks * blksz_dl); |
414 | 457 | ||
415 | if (ret < 0) { | 458 | if (ret < 0) { |
416 | BT_ERR("FW download, writesb(%d) failed @%d", | 459 | BT_ERR("FW download, writesb(%d) failed @%d", |
417 | count, offset); | 460 | count, offset); |
418 | sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, | 461 | sdio_writeb(card->func, HOST_CMD53_FIN, |
419 | &ret); | 462 | card->reg->cfg, &ret); |
420 | if (ret) | 463 | if (ret) |
421 | BT_ERR("writeb failed (CFG)"); | 464 | BT_ERR("writeb failed (CFG)"); |
422 | } | 465 | } |
@@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) | |||
597 | 640 | ||
598 | priv = card->priv; | 641 | priv = card->priv; |
599 | 642 | ||
600 | ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); | 643 | ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); |
601 | if (ret) { | 644 | if (ret) { |
602 | BT_ERR("sdio_readb: read int status register failed"); | 645 | BT_ERR("sdio_readb: read int status register failed"); |
603 | return; | 646 | return; |
@@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) | |||
613 | 656 | ||
614 | sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | | 657 | sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | |
615 | UP_LD_HOST_INT_STATUS), | 658 | UP_LD_HOST_INT_STATUS), |
616 | HOST_INTSTATUS_REG, &ret); | 659 | card->reg->host_intstatus, &ret); |
617 | if (ret) { | 660 | if (ret) { |
618 | BT_ERR("sdio_writeb: clear int status register failed"); | 661 | BT_ERR("sdio_writeb: clear int status register failed"); |
619 | return; | 662 | return; |
@@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
664 | goto release_irq; | 707 | goto release_irq; |
665 | } | 708 | } |
666 | 709 | ||
667 | reg = sdio_readb(func, IO_PORT_0_REG, &ret); | 710 | reg = sdio_readb(func, card->reg->io_port_0, &ret); |
668 | if (ret < 0) { | 711 | if (ret < 0) { |
669 | ret = -EIO; | 712 | ret = -EIO; |
670 | goto release_irq; | 713 | goto release_irq; |
@@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
672 | 715 | ||
673 | card->ioport = reg; | 716 | card->ioport = reg; |
674 | 717 | ||
675 | reg = sdio_readb(func, IO_PORT_1_REG, &ret); | 718 | reg = sdio_readb(func, card->reg->io_port_1, &ret); |
676 | if (ret < 0) { | 719 | if (ret < 0) { |
677 | ret = -EIO; | 720 | ret = -EIO; |
678 | goto release_irq; | 721 | goto release_irq; |
@@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
680 | 723 | ||
681 | card->ioport |= (reg << 8); | 724 | card->ioport |= (reg << 8); |
682 | 725 | ||
683 | reg = sdio_readb(func, IO_PORT_2_REG, &ret); | 726 | reg = sdio_readb(func, card->reg->io_port_2, &ret); |
684 | if (ret < 0) { | 727 | if (ret < 0) { |
685 | ret = -EIO; | 728 | ret = -EIO; |
686 | goto release_irq; | 729 | goto release_irq; |
@@ -815,6 +858,8 @@ exit: | |||
815 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | 858 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) |
816 | { | 859 | { |
817 | int ret = 0; | 860 | int ret = 0; |
861 | u8 fws0; | ||
862 | int pollnum = MAX_POLL_TRIES; | ||
818 | 863 | ||
819 | if (!card || !card->func) { | 864 | if (!card || !card->func) { |
820 | BT_ERR("card or function is NULL!"); | 865 | BT_ERR("card or function is NULL!"); |
@@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | |||
827 | goto done; | 872 | goto done; |
828 | } | 873 | } |
829 | 874 | ||
830 | ret = btmrvl_sdio_download_helper(card); | 875 | /* Check if other function driver is downloading the firmware */ |
876 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); | ||
831 | if (ret) { | 877 | if (ret) { |
832 | BT_ERR("Failed to download helper!"); | 878 | BT_ERR("Failed to read FW downloading status!"); |
833 | ret = -EIO; | 879 | ret = -EIO; |
834 | goto done; | 880 | goto done; |
835 | } | 881 | } |
882 | if (fws0) { | ||
883 | BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0); | ||
884 | |||
885 | /* Give other function more time to download the firmware */ | ||
886 | pollnum *= 10; | ||
887 | } else { | ||
888 | if (card->helper) { | ||
889 | ret = btmrvl_sdio_download_helper(card); | ||
890 | if (ret) { | ||
891 | BT_ERR("Failed to download helper!"); | ||
892 | ret = -EIO; | ||
893 | goto done; | ||
894 | } | ||
895 | } | ||
836 | 896 | ||
837 | if (btmrvl_sdio_download_fw_w_helper(card)) { | 897 | if (btmrvl_sdio_download_fw_w_helper(card)) { |
838 | BT_ERR("Failed to download firmware!"); | 898 | BT_ERR("Failed to download firmware!"); |
839 | ret = -EIO; | 899 | ret = -EIO; |
840 | goto done; | 900 | goto done; |
901 | } | ||
841 | } | 902 | } |
842 | 903 | ||
843 | if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) { | 904 | if (btmrvl_sdio_verify_fw_download(card, pollnum)) { |
844 | BT_ERR("FW failed to be active in time!"); | 905 | BT_ERR("FW failed to be active in time!"); |
845 | ret = -ETIMEDOUT; | 906 | ret = -ETIMEDOUT; |
846 | goto done; | 907 | goto done; |
@@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) | |||
864 | 925 | ||
865 | sdio_claim_host(card->func); | 926 | sdio_claim_host(card->func); |
866 | 927 | ||
867 | sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret); | 928 | sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret); |
868 | 929 | ||
869 | sdio_release_host(card->func); | 930 | sdio_release_host(card->func); |
870 | 931 | ||
@@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
893 | 954 | ||
894 | if (id->driver_data) { | 955 | if (id->driver_data) { |
895 | struct btmrvl_sdio_device *data = (void *) id->driver_data; | 956 | struct btmrvl_sdio_device *data = (void *) id->driver_data; |
896 | card->helper = data->helper; | 957 | card->helper = data->helper; |
897 | card->firmware = data->firmware; | 958 | card->firmware = data->firmware; |
959 | card->reg = data->reg; | ||
960 | card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; | ||
898 | } | 961 | } |
899 | 962 | ||
900 | if (btmrvl_sdio_register_dev(card) < 0) { | 963 | if (btmrvl_sdio_register_dev(card) < 0) { |
@@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION); | |||
1011 | MODULE_LICENSE("GPL v2"); | 1074 | MODULE_LICENSE("GPL v2"); |
1012 | MODULE_FIRMWARE("sd8688_helper.bin"); | 1075 | MODULE_FIRMWARE("sd8688_helper.bin"); |
1013 | MODULE_FIRMWARE("sd8688.bin"); | 1076 | MODULE_FIRMWARE("sd8688.bin"); |
1077 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); | ||
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h index 27329f107e5a..43d35a609ca9 100644 --- a/drivers/bluetooth/btmrvl_sdio.h +++ b/drivers/bluetooth/btmrvl_sdio.h | |||
@@ -47,44 +47,46 @@ | |||
47 | /* Max retry number of CMD53 write */ | 47 | /* Max retry number of CMD53 write */ |
48 | #define MAX_WRITE_IOMEM_RETRY 2 | 48 | #define MAX_WRITE_IOMEM_RETRY 2 |
49 | 49 | ||
50 | /* Host Control Registers */ | 50 | /* register bitmasks */ |
51 | #define IO_PORT_0_REG 0x00 | 51 | #define HOST_POWER_UP BIT(1) |
52 | #define IO_PORT_1_REG 0x01 | 52 | #define HOST_CMD53_FIN BIT(2) |
53 | #define IO_PORT_2_REG 0x02 | 53 | |
54 | 54 | #define HIM_DISABLE 0xff | |
55 | #define CONFIG_REG 0x03 | 55 | #define HIM_ENABLE (BIT(0) | BIT(1)) |
56 | #define HOST_POWER_UP BIT(1) | 56 | |
57 | #define HOST_CMD53_FIN BIT(2) | 57 | #define UP_LD_HOST_INT_STATUS BIT(0) |
58 | 58 | #define DN_LD_HOST_INT_STATUS BIT(1) | |
59 | #define HOST_INT_MASK_REG 0x04 | 59 | |
60 | #define HIM_DISABLE 0xff | 60 | #define DN_LD_CARD_RDY BIT(0) |
61 | #define HIM_ENABLE (BIT(0) | BIT(1)) | 61 | #define CARD_IO_READY BIT(3) |
62 | 62 | ||
63 | #define HOST_INTSTATUS_REG 0x05 | 63 | #define FIRMWARE_READY 0xfedc |
64 | #define UP_LD_HOST_INT_STATUS BIT(0) | 64 | |
65 | #define DN_LD_HOST_INT_STATUS BIT(1) | 65 | |
66 | 66 | struct btmrvl_sdio_card_reg { | |
67 | /* Card Control Registers */ | 67 | u8 cfg; |
68 | #define SQ_READ_BASE_ADDRESS_A0_REG 0x10 | 68 | u8 host_int_mask; |
69 | #define SQ_READ_BASE_ADDRESS_A1_REG 0x11 | 69 | u8 host_intstatus; |
70 | 70 | u8 card_status; | |
71 | #define CARD_STATUS_REG 0x20 | 71 | u8 sq_read_base_addr_a0; |
72 | #define DN_LD_CARD_RDY BIT(0) | 72 | u8 sq_read_base_addr_a1; |
73 | #define CARD_IO_READY BIT(3) | 73 | u8 card_revision; |
74 | 74 | u8 card_fw_status0; | |
75 | #define CARD_FW_STATUS0_REG 0x40 | 75 | u8 card_fw_status1; |
76 | #define CARD_FW_STATUS1_REG 0x41 | 76 | u8 card_rx_len; |
77 | #define FIRMWARE_READY 0xfedc | 77 | u8 card_rx_unit; |
78 | 78 | u8 io_port_0; | |
79 | #define CARD_RX_LEN_REG 0x42 | 79 | u8 io_port_1; |
80 | #define CARD_RX_UNIT_REG 0x43 | 80 | u8 io_port_2; |
81 | 81 | }; | |
82 | 82 | ||
83 | struct btmrvl_sdio_card { | 83 | struct btmrvl_sdio_card { |
84 | struct sdio_func *func; | 84 | struct sdio_func *func; |
85 | u32 ioport; | 85 | u32 ioport; |
86 | const char *helper; | 86 | const char *helper; |
87 | const char *firmware; | 87 | const char *firmware; |
88 | const struct btmrvl_sdio_card_reg *reg; | ||
89 | u16 sd_blksz_fw_dl; | ||
88 | u8 rx_unit; | 90 | u8 rx_unit; |
89 | struct btmrvl_private *priv; | 91 | struct btmrvl_private *priv; |
90 | }; | 92 | }; |
@@ -92,6 +94,8 @@ struct btmrvl_sdio_card { | |||
92 | struct btmrvl_sdio_device { | 94 | struct btmrvl_sdio_device { |
93 | const char *helper; | 95 | const char *helper; |
94 | const char *firmware; | 96 | const char *firmware; |
97 | const struct btmrvl_sdio_card_reg *reg; | ||
98 | u16 sd_blksz_fw_dl; | ||
95 | }; | 99 | }; |
96 | 100 | ||
97 | 101 | ||
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index bd34406faaae..4093935ddf42 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c | |||
@@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) | |||
201 | /* Recv data */ | 201 | /* Recv data */ |
202 | static int ath_recv(struct hci_uart *hu, void *data, int count) | 202 | static int ath_recv(struct hci_uart *hu, void *data, int count) |
203 | { | 203 | { |
204 | if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | 204 | int ret; |
205 | |||
206 | ret = hci_recv_stream_fragment(hu->hdev, data, count); | ||
207 | if (ret < 0) { | ||
205 | BT_ERR("Frame Reassembly Failed"); | 208 | BT_ERR("Frame Reassembly Failed"); |
209 | return ret; | ||
210 | } | ||
206 | 211 | ||
207 | return count; | 212 | return count; |
208 | } | 213 | } |
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 7b8ad93e2c36..2fcd8b387d69 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c | |||
@@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
151 | /* Recv data */ | 151 | /* Recv data */ |
152 | static int h4_recv(struct hci_uart *hu, void *data, int count) | 152 | static int h4_recv(struct hci_uart *hu, void *data, int count) |
153 | { | 153 | { |
154 | if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | 154 | int ret; |
155 | |||
156 | ret = hci_recv_stream_fragment(hu->hdev, data, count); | ||
157 | if (ret < 0) { | ||
155 | BT_ERR("Frame Reassembly Failed"); | 158 | BT_ERR("Frame Reassembly Failed"); |
159 | return ret; | ||
160 | } | ||
156 | 161 | ||
157 | return count; | 162 | return count; |
158 | } | 163 | } |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 48ad2a7ab080..320f71803a2b 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -359,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
359 | */ | 359 | */ |
360 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) | 360 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) |
361 | { | 361 | { |
362 | int ret; | ||
362 | struct hci_uart *hu = (void *)tty->disc_data; | 363 | struct hci_uart *hu = (void *)tty->disc_data; |
363 | 364 | ||
364 | if (!hu || tty != hu->tty) | 365 | if (!hu || tty != hu->tty) |
@@ -368,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f | |||
368 | return; | 369 | return; |
369 | 370 | ||
370 | spin_lock(&hu->rx_lock); | 371 | spin_lock(&hu->rx_lock); |
371 | hu->proto->recv(hu, (void *) data, count); | 372 | ret = hu->proto->recv(hu, (void *) data, count); |
372 | hu->hdev->stat.byte_rx += count; | 373 | if (ret > 0) |
374 | hu->hdev->stat.byte_rx += count; | ||
373 | spin_unlock(&hu->rx_lock); | 375 | spin_unlock(&hu->rx_lock); |
374 | 376 | ||
375 | tty_unthrottle(tty); | 377 | tty_unthrottle(tty); |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 6d7105b7e8f1..7cf4317a2a84 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -123,14 +123,7 @@ struct ath_ops { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct ath_common; | 125 | struct ath_common; |
126 | 126 | struct ath_bus_ops; | |
127 | struct ath_bus_ops { | ||
128 | enum ath_bus_type ath_bus_type; | ||
129 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
130 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
131 | void (*bt_coex_prep)(struct ath_common *common); | ||
132 | void (*extn_synch_en)(struct ath_common *common); | ||
133 | }; | ||
134 | 127 | ||
135 | struct ath_common { | 128 | struct ath_common { |
136 | void *ah; | 129 | void *ah; |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 82324e98efef..ea9982781559 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/etherdevice.h> | ||
21 | #include <ar231x_platform.h> | 22 | #include <ar231x_platform.h> |
22 | #include "ath5k.h" | 23 | #include "ath5k.h" |
23 | #include "debug.h" | 24 | #include "debug.h" |
@@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
67 | { | ||
68 | struct ath5k_softc *sc = ah->ah_sc; | ||
69 | struct platform_device *pdev = to_platform_device(sc->dev); | ||
70 | struct ar231x_board_config *bcfg = pdev->dev.platform_data; | ||
71 | u8 *cfg_mac; | ||
72 | |||
73 | if (to_platform_device(sc->dev)->id == 0) | ||
74 | cfg_mac = bcfg->config->wlan0_mac; | ||
75 | else | ||
76 | cfg_mac = bcfg->config->wlan1_mac; | ||
77 | |||
78 | memcpy(mac, cfg_mac, ETH_ALEN); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
65 | static const struct ath_bus_ops ath_ahb_bus_ops = { | 82 | static const struct ath_bus_ops ath_ahb_bus_ops = { |
66 | .ath_bus_type = ATH_AHB, | 83 | .ath_bus_type = ATH_AHB, |
67 | .read_cachesize = ath5k_ahb_read_cachesize, | 84 | .read_cachesize = ath5k_ahb_read_cachesize, |
68 | .eeprom_read = ath5k_ahb_eeprom_read, | 85 | .eeprom_read = ath5k_ahb_eeprom_read, |
86 | .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, | ||
69 | }; | 87 | }; |
70 | 88 | ||
71 | /*Initialization*/ | 89 | /*Initialization*/ |
@@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
142 | else | 160 | else |
143 | reg |= AR5K_AR5312_ENABLE_WLAN1; | 161 | reg |= AR5K_AR5312_ENABLE_WLAN1; |
144 | __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); | 162 | __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); |
163 | |||
164 | /* | ||
165 | * On a dual-band AR5312, the multiband radio is only | ||
166 | * used as pass-through. Disable 2 GHz support in the | ||
167 | * driver for it | ||
168 | */ | ||
169 | if (to_platform_device(sc->dev)->id == 0 && | ||
170 | (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) == | ||
171 | (BD_WLAN1|BD_WLAN0)) | ||
172 | __set_bit(ATH_STAT_2G_DISABLED, sc->status); | ||
145 | } | 173 | } |
146 | 174 | ||
147 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); | 175 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8a06dbd39629..bb50700436fe 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -224,8 +224,7 @@ | |||
224 | 224 | ||
225 | /* SIFS */ | 225 | /* SIFS */ |
226 | #define AR5K_INIT_SIFS_TURBO 6 | 226 | #define AR5K_INIT_SIFS_TURBO 6 |
227 | /* XXX: 8 from initvals 10 from standard */ | 227 | #define AR5K_INIT_SIFS_DEFAULT_BG 10 |
228 | #define AR5K_INIT_SIFS_DEFAULT_BG 8 | ||
229 | #define AR5K_INIT_SIFS_DEFAULT_A 16 | 228 | #define AR5K_INIT_SIFS_DEFAULT_A 16 |
230 | #define AR5K_INIT_SIFS_HALF_RATE 32 | 229 | #define AR5K_INIT_SIFS_HALF_RATE 32 |
231 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 | 230 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 |
@@ -453,12 +452,10 @@ struct ath5k_tx_status { | |||
453 | u16 ts_seqnum; | 452 | u16 ts_seqnum; |
454 | u16 ts_tstamp; | 453 | u16 ts_tstamp; |
455 | u8 ts_status; | 454 | u8 ts_status; |
456 | u8 ts_rate[4]; | ||
457 | u8 ts_retry[4]; | ||
458 | u8 ts_final_idx; | 455 | u8 ts_final_idx; |
456 | u8 ts_final_retry; | ||
459 | s8 ts_rssi; | 457 | s8 ts_rssi; |
460 | u8 ts_shortretry; | 458 | u8 ts_shortretry; |
461 | u8 ts_longretry; | ||
462 | u8 ts_virtcol; | 459 | u8 ts_virtcol; |
463 | u8 ts_antenna; | 460 | u8 ts_antenna; |
464 | }; | 461 | }; |
@@ -875,6 +872,19 @@ enum ath5k_int { | |||
875 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ | 872 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ |
876 | AR5K_INT_GLOBAL = 0x80000000, | 873 | AR5K_INT_GLOBAL = 0x80000000, |
877 | 874 | ||
875 | AR5K_INT_TX_ALL = AR5K_INT_TXOK | ||
876 | | AR5K_INT_TXDESC | ||
877 | | AR5K_INT_TXERR | ||
878 | | AR5K_INT_TXEOL | ||
879 | | AR5K_INT_TXURN, | ||
880 | |||
881 | AR5K_INT_RX_ALL = AR5K_INT_RXOK | ||
882 | | AR5K_INT_RXDESC | ||
883 | | AR5K_INT_RXERR | ||
884 | | AR5K_INT_RXNOFRM | ||
885 | | AR5K_INT_RXEOL | ||
886 | | AR5K_INT_RXORN, | ||
887 | |||
878 | AR5K_INT_COMMON = AR5K_INT_RXOK | 888 | AR5K_INT_COMMON = AR5K_INT_RXOK |
879 | | AR5K_INT_RXDESC | 889 | | AR5K_INT_RXDESC |
880 | | AR5K_INT_RXERR | 890 | | AR5K_INT_RXERR |
@@ -1058,6 +1068,7 @@ struct ath5k_hw { | |||
1058 | u8 ah_coverage_class; | 1068 | u8 ah_coverage_class; |
1059 | bool ah_ack_bitrate_high; | 1069 | bool ah_ack_bitrate_high; |
1060 | u8 ah_bwmode; | 1070 | u8 ah_bwmode; |
1071 | bool ah_short_slot; | ||
1061 | 1072 | ||
1062 | /* Antenna Control */ | 1073 | /* Antenna Control */ |
1063 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | 1074 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; |
@@ -1144,6 +1155,13 @@ struct ath5k_hw { | |||
1144 | struct ath5k_rx_status *); | 1155 | struct ath5k_rx_status *); |
1145 | }; | 1156 | }; |
1146 | 1157 | ||
1158 | struct ath_bus_ops { | ||
1159 | enum ath_bus_type ath_bus_type; | ||
1160 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
1161 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
1162 | int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac); | ||
1163 | }; | ||
1164 | |||
1147 | /* | 1165 | /* |
1148 | * Prototypes | 1166 | * Prototypes |
1149 | */ | 1167 | */ |
@@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah); | |||
1227 | /* EEPROM access functions */ | 1245 | /* EEPROM access functions */ |
1228 | int ath5k_eeprom_init(struct ath5k_hw *ah); | 1246 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
1229 | void ath5k_eeprom_detach(struct ath5k_hw *ah); | 1247 | void ath5k_eeprom_detach(struct ath5k_hw *ah); |
1230 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | ||
1231 | 1248 | ||
1232 | 1249 | ||
1233 | /* Protocol Control Unit Functions */ | 1250 | /* Protocol Control Unit Functions */ |
1234 | /* Helpers */ | 1251 | /* Helpers */ |
1235 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 1252 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
1236 | int len, struct ieee80211_rate *rate); | 1253 | int len, struct ieee80211_rate *rate, bool shortpre); |
1237 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); | 1254 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); |
1238 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); | 1255 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); |
1239 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); | 1256 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index bc8240560488..1588401de3c4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc) | |||
313 | goto err; | 313 | goto err; |
314 | } | 314 | } |
315 | 315 | ||
316 | if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) { | ||
317 | __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); | ||
318 | __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); | ||
319 | } | ||
320 | |||
316 | /* Crypto settings */ | 321 | /* Crypto settings */ |
317 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? | 322 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? |
318 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); | 323 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); |
319 | 324 | ||
320 | if (srev >= AR5K_SREV_AR5212_V4 && | 325 | if (srev >= AR5K_SREV_AR5212_V4 && |
321 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | 326 | (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || |
322 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) | 327 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) |
323 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | 328 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; |
324 | 329 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 349a5963931b..203243bacc89 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | static void | 1446 | static void |
1447 | ath5k_set_current_imask(struct ath5k_softc *sc) | ||
1448 | { | ||
1449 | enum ath5k_int imask = sc->imask; | ||
1450 | unsigned long flags; | ||
1451 | |||
1452 | spin_lock_irqsave(&sc->irqlock, flags); | ||
1453 | if (sc->rx_pending) | ||
1454 | imask &= ~AR5K_INT_RX_ALL; | ||
1455 | if (sc->tx_pending) | ||
1456 | imask &= ~AR5K_INT_TX_ALL; | ||
1457 | ath5k_hw_set_imr(sc->ah, imask); | ||
1458 | spin_unlock_irqrestore(&sc->irqlock, flags); | ||
1459 | } | ||
1460 | |||
1461 | static void | ||
1447 | ath5k_tasklet_rx(unsigned long data) | 1462 | ath5k_tasklet_rx(unsigned long data) |
1448 | { | 1463 | { |
1449 | struct ath5k_rx_status rs = {}; | 1464 | struct ath5k_rx_status rs = {}; |
@@ -1506,6 +1521,8 @@ next: | |||
1506 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1521 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
1507 | unlock: | 1522 | unlock: |
1508 | spin_unlock(&sc->rxbuflock); | 1523 | spin_unlock(&sc->rxbuflock); |
1524 | sc->rx_pending = false; | ||
1525 | ath5k_set_current_imask(sc); | ||
1509 | } | 1526 | } |
1510 | 1527 | ||
1511 | 1528 | ||
@@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1573 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) | 1590 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) |
1574 | { | 1591 | { |
1575 | struct ieee80211_tx_info *info; | 1592 | struct ieee80211_tx_info *info; |
1593 | u8 tries[3]; | ||
1576 | int i; | 1594 | int i; |
1577 | 1595 | ||
1578 | sc->stats.tx_all_count++; | 1596 | sc->stats.tx_all_count++; |
1579 | sc->stats.tx_bytes_count += skb->len; | 1597 | sc->stats.tx_bytes_count += skb->len; |
1580 | info = IEEE80211_SKB_CB(skb); | 1598 | info = IEEE80211_SKB_CB(skb); |
1581 | 1599 | ||
1600 | tries[0] = info->status.rates[0].count; | ||
1601 | tries[1] = info->status.rates[1].count; | ||
1602 | tries[2] = info->status.rates[2].count; | ||
1603 | |||
1582 | ieee80211_tx_info_clear_status(info); | 1604 | ieee80211_tx_info_clear_status(info); |
1583 | for (i = 0; i < 4; i++) { | 1605 | |
1606 | for (i = 0; i < ts->ts_final_idx; i++) { | ||
1584 | struct ieee80211_tx_rate *r = | 1607 | struct ieee80211_tx_rate *r = |
1585 | &info->status.rates[i]; | 1608 | &info->status.rates[i]; |
1586 | 1609 | ||
1587 | if (ts->ts_rate[i]) { | 1610 | r->count = tries[i]; |
1588 | r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); | ||
1589 | r->count = ts->ts_retry[i]; | ||
1590 | } else { | ||
1591 | r->idx = -1; | ||
1592 | r->count = 0; | ||
1593 | } | ||
1594 | } | 1611 | } |
1595 | 1612 | ||
1596 | /* count the successful attempt as well */ | 1613 | info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; |
1597 | info->status.rates[ts->ts_final_idx].count++; | 1614 | info->status.rates[ts->ts_final_idx + 1].idx = -1; |
1598 | 1615 | ||
1599 | if (unlikely(ts->ts_status)) { | 1616 | if (unlikely(ts->ts_status)) { |
1600 | sc->stats.ack_fail++; | 1617 | sc->stats.ack_fail++; |
@@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1609 | } else { | 1626 | } else { |
1610 | info->flags |= IEEE80211_TX_STAT_ACK; | 1627 | info->flags |= IEEE80211_TX_STAT_ACK; |
1611 | info->status.ack_signal = ts->ts_rssi; | 1628 | info->status.ack_signal = ts->ts_rssi; |
1629 | |||
1630 | /* count the successful attempt as well */ | ||
1631 | info->status.rates[ts->ts_final_idx].count++; | ||
1612 | } | 1632 | } |
1613 | 1633 | ||
1614 | /* | 1634 | /* |
@@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data) | |||
1690 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) | 1710 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) |
1691 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) | 1711 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) |
1692 | ath5k_tx_processq(sc, &sc->txqs[i]); | 1712 | ath5k_tx_processq(sc, &sc->txqs[i]); |
1713 | |||
1714 | sc->tx_pending = false; | ||
1715 | ath5k_set_current_imask(sc); | ||
1693 | } | 1716 | } |
1694 | 1717 | ||
1695 | 1718 | ||
@@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) | |||
2119 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | 2142 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ |
2120 | } | 2143 | } |
2121 | 2144 | ||
2145 | static void | ||
2146 | ath5k_schedule_rx(struct ath5k_softc *sc) | ||
2147 | { | ||
2148 | sc->rx_pending = true; | ||
2149 | tasklet_schedule(&sc->rxtq); | ||
2150 | } | ||
2151 | |||
2152 | static void | ||
2153 | ath5k_schedule_tx(struct ath5k_softc *sc) | ||
2154 | { | ||
2155 | sc->tx_pending = true; | ||
2156 | tasklet_schedule(&sc->txtq); | ||
2157 | } | ||
2158 | |||
2122 | irqreturn_t | 2159 | irqreturn_t |
2123 | ath5k_intr(int irq, void *dev_id) | 2160 | ath5k_intr(int irq, void *dev_id) |
2124 | { | 2161 | { |
@@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2161 | ieee80211_queue_work(sc->hw, &sc->reset_work); | 2198 | ieee80211_queue_work(sc->hw, &sc->reset_work); |
2162 | } | 2199 | } |
2163 | else | 2200 | else |
2164 | tasklet_schedule(&sc->rxtq); | 2201 | ath5k_schedule_rx(sc); |
2165 | } else { | 2202 | } else { |
2166 | if (status & AR5K_INT_SWBA) { | 2203 | if (status & AR5K_INT_SWBA) { |
2167 | tasklet_hi_schedule(&sc->beacontq); | 2204 | tasklet_hi_schedule(&sc->beacontq); |
@@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id) | |||
2179 | ath5k_hw_update_tx_triglevel(ah, true); | 2216 | ath5k_hw_update_tx_triglevel(ah, true); |
2180 | } | 2217 | } |
2181 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) | 2218 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) |
2182 | tasklet_schedule(&sc->rxtq); | 2219 | ath5k_schedule_rx(sc); |
2183 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | 2220 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC |
2184 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) | 2221 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) |
2185 | tasklet_schedule(&sc->txtq); | 2222 | ath5k_schedule_tx(sc); |
2186 | if (status & AR5K_INT_BMISS) { | 2223 | if (status & AR5K_INT_BMISS) { |
2187 | /* TODO */ | 2224 | /* TODO */ |
2188 | } | 2225 | } |
@@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2201 | 2238 | ||
2202 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2239 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2203 | 2240 | ||
2241 | if (sc->rx_pending || sc->tx_pending) | ||
2242 | ath5k_set_current_imask(sc); | ||
2243 | |||
2204 | if (unlikely(!counter)) | 2244 | if (unlikely(!counter)) |
2205 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); | 2245 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); |
2206 | 2246 | ||
@@ -2572,6 +2612,8 @@ done: | |||
2572 | 2612 | ||
2573 | static void stop_tasklets(struct ath5k_softc *sc) | 2613 | static void stop_tasklets(struct ath5k_softc *sc) |
2574 | { | 2614 | { |
2615 | sc->rx_pending = false; | ||
2616 | sc->tx_pending = false; | ||
2575 | tasklet_kill(&sc->rxtq); | 2617 | tasklet_kill(&sc->rxtq); |
2576 | tasklet_kill(&sc->txtq); | 2618 | tasklet_kill(&sc->txtq); |
2577 | tasklet_kill(&sc->calib); | 2619 | tasklet_kill(&sc->calib); |
@@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw) | |||
2838 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | 2880 | INIT_WORK(&sc->reset_work, ath5k_reset_work); |
2839 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); | 2881 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); |
2840 | 2882 | ||
2841 | ret = ath5k_eeprom_read_mac(ah, mac); | 2883 | ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); |
2842 | if (ret) { | 2884 | if (ret) { |
2843 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); | 2885 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); |
2844 | goto err_queues; | 2886 | goto err_queues; |
@@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2898 | * XXX: ??? detach ath5k_hw ??? | 2940 | * XXX: ??? detach ath5k_hw ??? |
2899 | * Other than that, it's straightforward... | 2941 | * Other than that, it's straightforward... |
2900 | */ | 2942 | */ |
2901 | ath5k_debug_finish_device(sc); | ||
2902 | ieee80211_unregister_hw(hw); | 2943 | ieee80211_unregister_hw(hw); |
2903 | ath5k_desc_free(sc); | 2944 | ath5k_desc_free(sc); |
2904 | ath5k_txq_release(sc); | 2945 | ath5k_txq_release(sc); |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 978f1f4ac2f3..b294f3305011 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -193,12 +193,13 @@ struct ath5k_softc { | |||
193 | dma_addr_t desc_daddr; /* DMA (physical) address */ | 193 | dma_addr_t desc_daddr; /* DMA (physical) address */ |
194 | size_t desc_len; /* size of TX/RX descriptors */ | 194 | size_t desc_len; /* size of TX/RX descriptors */ |
195 | 195 | ||
196 | DECLARE_BITMAP(status, 5); | 196 | DECLARE_BITMAP(status, 6); |
197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ | 197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ |
198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ | 198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ |
199 | #define ATH_STAT_PROMISC 2 | 199 | #define ATH_STAT_PROMISC 2 |
200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ | 200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ |
201 | #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ | 201 | #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ |
202 | #define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */ | ||
202 | 203 | ||
203 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ | 204 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ |
204 | struct ieee80211_channel *curchan; /* current h/w channel */ | 205 | struct ieee80211_channel *curchan; /* current h/w channel */ |
@@ -207,6 +208,10 @@ struct ath5k_softc { | |||
207 | 208 | ||
208 | enum ath5k_int imask; /* interrupt mask copy */ | 209 | enum ath5k_int imask; /* interrupt mask copy */ |
209 | 210 | ||
211 | spinlock_t irqlock; | ||
212 | bool rx_pending; /* rx tasklet pending */ | ||
213 | bool tx_pending; /* tx tasklet pending */ | ||
214 | |||
210 | u8 lladdr[ETH_ALEN]; | 215 | u8 lladdr[ETH_ALEN]; |
211 | u8 bssidmask[ETH_ALEN]; | 216 | u8 bssidmask[ETH_ALEN]; |
212 | 217 | ||
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index f77e8a703c5c..7dd88e1c3ff8 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) | ||
98 | __clear_bit(AR5K_MODE_11A, caps->cap_mode); | ||
99 | |||
97 | /* Set number of supported TX queues */ | 100 | /* Set number of supported TX queues */ |
98 | if (ah->ah_version == AR5K_AR5210) | 101 | if (ah->ah_version == AR5K_AR5210) |
99 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; | 102 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0230f30e9e9a..0bf7313b8a17 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -888,65 +888,38 @@ static const struct file_operations fops_queue = { | |||
888 | void | 888 | void |
889 | ath5k_debug_init_device(struct ath5k_softc *sc) | 889 | ath5k_debug_init_device(struct ath5k_softc *sc) |
890 | { | 890 | { |
891 | sc->debug.level = ath5k_debug; | 891 | struct dentry *phydir; |
892 | 892 | ||
893 | sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", | 893 | sc->debug.level = ath5k_debug; |
894 | sc->hw->wiphy->debugfsdir); | ||
895 | 894 | ||
896 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 895 | phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); |
897 | S_IWUSR | S_IRUSR, | 896 | if (!phydir) |
898 | sc->debug.debugfs_phydir, sc, &fops_debug); | 897 | return; |
899 | 898 | ||
900 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, | 899 | debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, |
901 | sc->debug.debugfs_phydir, sc, &fops_registers); | 900 | &fops_debug); |
902 | 901 | ||
903 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", | 902 | debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers); |
904 | S_IWUSR | S_IRUSR, | ||
905 | sc->debug.debugfs_phydir, sc, &fops_beacon); | ||
906 | 903 | ||
907 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, | 904 | debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc, |
908 | sc->debug.debugfs_phydir, sc, &fops_reset); | 905 | &fops_beacon); |
909 | 906 | ||
910 | sc->debug.debugfs_antenna = debugfs_create_file("antenna", | 907 | debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset); |
911 | S_IWUSR | S_IRUSR, | ||
912 | sc->debug.debugfs_phydir, sc, &fops_antenna); | ||
913 | 908 | ||
914 | sc->debug.debugfs_misc = debugfs_create_file("misc", | 909 | debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc, |
915 | S_IRUSR, | 910 | &fops_antenna); |
916 | sc->debug.debugfs_phydir, sc, &fops_misc); | ||
917 | 911 | ||
918 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | 912 | debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc); |
919 | S_IWUSR | S_IRUSR, | ||
920 | sc->debug.debugfs_phydir, sc, | ||
921 | &fops_frameerrors); | ||
922 | 913 | ||
923 | sc->debug.debugfs_ani = debugfs_create_file("ani", | 914 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc, |
924 | S_IWUSR | S_IRUSR, | 915 | &fops_frameerrors); |
925 | sc->debug.debugfs_phydir, sc, | ||
926 | &fops_ani); | ||
927 | 916 | ||
928 | sc->debug.debugfs_queue = debugfs_create_file("queue", | 917 | debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani); |
929 | S_IWUSR | S_IRUSR, | ||
930 | sc->debug.debugfs_phydir, sc, | ||
931 | &fops_queue); | ||
932 | } | ||
933 | 918 | ||
934 | void | 919 | debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, |
935 | ath5k_debug_finish_device(struct ath5k_softc *sc) | 920 | &fops_queue); |
936 | { | ||
937 | debugfs_remove(sc->debug.debugfs_debug); | ||
938 | debugfs_remove(sc->debug.debugfs_registers); | ||
939 | debugfs_remove(sc->debug.debugfs_beacon); | ||
940 | debugfs_remove(sc->debug.debugfs_reset); | ||
941 | debugfs_remove(sc->debug.debugfs_antenna); | ||
942 | debugfs_remove(sc->debug.debugfs_misc); | ||
943 | debugfs_remove(sc->debug.debugfs_frameerrors); | ||
944 | debugfs_remove(sc->debug.debugfs_ani); | ||
945 | debugfs_remove(sc->debug.debugfs_queue); | ||
946 | debugfs_remove(sc->debug.debugfs_phydir); | ||
947 | } | 921 | } |
948 | 922 | ||
949 | |||
950 | /* functions used in other places */ | 923 | /* functions used in other places */ |
951 | 924 | ||
952 | void | 925 | void |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index b0355aef68d3..193dd2d4ea3c 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -68,17 +68,6 @@ struct ath5k_buf; | |||
68 | 68 | ||
69 | struct ath5k_dbg_info { | 69 | struct ath5k_dbg_info { |
70 | unsigned int level; /* debug level */ | 70 | unsigned int level; /* debug level */ |
71 | /* debugfs entries */ | ||
72 | struct dentry *debugfs_phydir; | ||
73 | struct dentry *debugfs_debug; | ||
74 | struct dentry *debugfs_registers; | ||
75 | struct dentry *debugfs_beacon; | ||
76 | struct dentry *debugfs_reset; | ||
77 | struct dentry *debugfs_antenna; | ||
78 | struct dentry *debugfs_misc; | ||
79 | struct dentry *debugfs_frameerrors; | ||
80 | struct dentry *debugfs_ani; | ||
81 | struct dentry *debugfs_queue; | ||
82 | }; | 71 | }; |
83 | 72 | ||
84 | /** | 73 | /** |
@@ -141,9 +130,6 @@ void | |||
141 | ath5k_debug_init_device(struct ath5k_softc *sc); | 130 | ath5k_debug_init_device(struct ath5k_softc *sc); |
142 | 131 | ||
143 | void | 132 | void |
144 | ath5k_debug_finish_device(struct ath5k_softc *sc); | ||
145 | |||
146 | void | ||
147 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); | 133 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); |
148 | 134 | ||
149 | void | 135 | void |
@@ -167,9 +153,6 @@ static inline void | |||
167 | ath5k_debug_init_device(struct ath5k_softc *sc) {} | 153 | ath5k_debug_init_device(struct ath5k_softc *sc) {} |
168 | 154 | ||
169 | static inline void | 155 | static inline void |
170 | ath5k_debug_finish_device(struct ath5k_softc *sc) {} | ||
171 | |||
172 | static inline void | ||
173 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} | 156 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} |
174 | 157 | ||
175 | static inline void | 158 | static inline void |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index a8fcc94269f7..62172d585723 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -185,6 +185,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
186 | unsigned int frame_len; | 186 | unsigned int frame_len; |
187 | 187 | ||
188 | /* | ||
189 | * Use local variables for these to reduce load/store access on | ||
190 | * uncached memory | ||
191 | */ | ||
192 | u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; | ||
193 | |||
188 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 194 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
189 | 195 | ||
190 | /* | 196 | /* |
@@ -208,8 +214,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
208 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) | 214 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) |
209 | tx_power = AR5K_TUNE_MAX_TXPOWER; | 215 | tx_power = AR5K_TUNE_MAX_TXPOWER; |
210 | 216 | ||
211 | /* Clear descriptor */ | 217 | /* Clear descriptor status area */ |
212 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | 218 | memset(&desc->ud.ds_tx5212.tx_stat, 0, |
219 | sizeof(desc->ud.ds_tx5212.tx_stat)); | ||
213 | 220 | ||
214 | /* Setup control descriptor */ | 221 | /* Setup control descriptor */ |
215 | 222 | ||
@@ -221,7 +228,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
221 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 228 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
222 | return -EINVAL; | 229 | return -EINVAL; |
223 | 230 | ||
224 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | 231 | txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; |
225 | 232 | ||
226 | /* Verify and set buffer length */ | 233 | /* Verify and set buffer length */ |
227 | 234 | ||
@@ -232,21 +239,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
232 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | 239 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) |
233 | return -EINVAL; | 240 | return -EINVAL; |
234 | 241 | ||
235 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | 242 | txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; |
236 | 243 | ||
237 | tx_ctl->tx_control_0 |= | 244 | txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | |
238 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | 245 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
239 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 246 | txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
240 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 247 | txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
241 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 248 | txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
242 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, | ||
243 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
244 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
245 | 249 | ||
246 | #define _TX_FLAGS(_c, _flag) \ | 250 | #define _TX_FLAGS(_c, _flag) \ |
247 | if (flags & AR5K_TXDESC_##_flag) { \ | 251 | if (flags & AR5K_TXDESC_##_flag) { \ |
248 | tx_ctl->tx_control_##_c |= \ | 252 | txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ |
249 | AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ | ||
250 | } | 253 | } |
251 | 254 | ||
252 | _TX_FLAGS(0, CLRDMASK); | 255 | _TX_FLAGS(0, CLRDMASK); |
@@ -262,8 +265,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
262 | * WEP crap | 265 | * WEP crap |
263 | */ | 266 | */ |
264 | if (key_index != AR5K_TXKEYIX_INVALID) { | 267 | if (key_index != AR5K_TXKEYIX_INVALID) { |
265 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | 268 | txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; |
266 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | 269 | txctl1 |= AR5K_REG_SM(key_index, |
267 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); | 270 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); |
268 | } | 271 | } |
269 | 272 | ||
@@ -274,12 +277,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
274 | if ((flags & AR5K_TXDESC_RTSENA) && | 277 | if ((flags & AR5K_TXDESC_RTSENA) && |
275 | (flags & AR5K_TXDESC_CTSENA)) | 278 | (flags & AR5K_TXDESC_CTSENA)) |
276 | return -EINVAL; | 279 | return -EINVAL; |
277 | tx_ctl->tx_control_2 |= rtscts_duration & | 280 | txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; |
278 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | 281 | txctl3 |= AR5K_REG_SM(rtscts_rate, |
279 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
280 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | 282 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); |
281 | } | 283 | } |
282 | 284 | ||
285 | tx_ctl->tx_control_0 = txctl0; | ||
286 | tx_ctl->tx_control_1 = txctl1; | ||
287 | tx_ctl->tx_control_2 = txctl2; | ||
288 | tx_ctl->tx_control_3 = txctl3; | ||
289 | |||
283 | return 0; | 290 | return 0; |
284 | } | 291 | } |
285 | 292 | ||
@@ -364,7 +371,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
364 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 371 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
365 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 372 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, |
366 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 373 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
367 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 374 | ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, |
368 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 375 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
369 | /*TODO: ts->ts_virtcol + test*/ | 376 | /*TODO: ts->ts_virtcol + test*/ |
370 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 377 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, |
@@ -373,9 +380,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
373 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 380 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
374 | ts->ts_antenna = 1; | 381 | ts->ts_antenna = 1; |
375 | ts->ts_status = 0; | 382 | ts->ts_status = 0; |
376 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
377 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
378 | ts->ts_retry[0] = ts->ts_longretry; | ||
379 | ts->ts_final_idx = 0; | 383 | ts->ts_final_idx = 0; |
380 | 384 | ||
381 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 385 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
@@ -401,81 +405,48 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | |||
401 | { | 405 | { |
402 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 406 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
403 | struct ath5k_hw_tx_status *tx_status; | 407 | struct ath5k_hw_tx_status *tx_status; |
408 | u32 txstat0, txstat1; | ||
404 | 409 | ||
405 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 410 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
406 | tx_status = &desc->ud.ds_tx5212.tx_stat; | 411 | tx_status = &desc->ud.ds_tx5212.tx_stat; |
407 | 412 | ||
413 | txstat1 = ACCESS_ONCE(tx_status->tx_status_1); | ||
414 | |||
408 | /* No frame has been send or error */ | 415 | /* No frame has been send or error */ |
409 | if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) | 416 | if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) |
410 | return -EINPROGRESS; | 417 | return -EINPROGRESS; |
411 | 418 | ||
419 | txstat0 = ACCESS_ONCE(tx_status->tx_status_0); | ||
420 | |||
412 | /* | 421 | /* |
413 | * Get descriptor status | 422 | * Get descriptor status |
414 | */ | 423 | */ |
415 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | 424 | ts->ts_tstamp = AR5K_REG_MS(txstat0, |
416 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 425 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
417 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 426 | ts->ts_shortretry = AR5K_REG_MS(txstat0, |
418 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 427 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
419 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 428 | ts->ts_final_retry = AR5K_REG_MS(txstat0, |
420 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 429 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
421 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 430 | ts->ts_seqnum = AR5K_REG_MS(txstat1, |
422 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | 431 | AR5K_DESC_TX_STATUS1_SEQ_NUM); |
423 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | 432 | ts->ts_rssi = AR5K_REG_MS(txstat1, |
424 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 433 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
425 | ts->ts_antenna = (tx_status->tx_status_1 & | 434 | ts->ts_antenna = (txstat1 & |
426 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; | 435 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; |
427 | ts->ts_status = 0; | 436 | ts->ts_status = 0; |
428 | 437 | ||
429 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, | 438 | ts->ts_final_idx = AR5K_REG_MS(txstat1, |
430 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); | 439 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); |
431 | 440 | ||
432 | /* The longretry counter has the number of un-acked retries | ||
433 | * for the final rate. To get the total number of retries | ||
434 | * we have to add the retry counters for the other rates | ||
435 | * as well | ||
436 | */ | ||
437 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
438 | switch (ts->ts_final_idx) { | ||
439 | case 3: | ||
440 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
441 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
442 | |||
443 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
444 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
445 | ts->ts_longretry += ts->ts_retry[2]; | ||
446 | /* fall through */ | ||
447 | case 2: | ||
448 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
449 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
450 | |||
451 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
452 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
453 | ts->ts_longretry += ts->ts_retry[1]; | ||
454 | /* fall through */ | ||
455 | case 1: | ||
456 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
457 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
458 | |||
459 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
460 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
461 | ts->ts_longretry += ts->ts_retry[0]; | ||
462 | /* fall through */ | ||
463 | case 0: | ||
464 | ts->ts_rate[0] = tx_ctl->tx_control_3 & | ||
465 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
466 | break; | ||
467 | } | ||
468 | |||
469 | /* TX error */ | 441 | /* TX error */ |
470 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 442 | if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
471 | if (tx_status->tx_status_0 & | 443 | if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) |
472 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
473 | ts->ts_status |= AR5K_TXERR_XRETRY; | 444 | ts->ts_status |= AR5K_TXERR_XRETRY; |
474 | 445 | ||
475 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | 446 | if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) |
476 | ts->ts_status |= AR5K_TXERR_FIFO; | 447 | ts->ts_status |= AR5K_TXERR_FIFO; |
477 | 448 | ||
478 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | 449 | if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) |
479 | ts->ts_status |= AR5K_TXERR_FILT; | 450 | ts->ts_status |= AR5K_TXERR_FILT; |
480 | } | 451 | } |
481 | 452 | ||
@@ -609,37 +580,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
609 | struct ath5k_rx_status *rs) | 580 | struct ath5k_rx_status *rs) |
610 | { | 581 | { |
611 | struct ath5k_hw_rx_status *rx_status; | 582 | struct ath5k_hw_rx_status *rx_status; |
583 | u32 rxstat0, rxstat1; | ||
612 | 584 | ||
613 | rx_status = &desc->ud.ds_rx.rx_stat; | 585 | rx_status = &desc->ud.ds_rx.rx_stat; |
586 | rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); | ||
614 | 587 | ||
615 | /* No frame received / not ready */ | 588 | /* No frame received / not ready */ |
616 | if (unlikely(!(rx_status->rx_status_1 & | 589 | if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) |
617 | AR5K_5212_RX_DESC_STATUS1_DONE))) | ||
618 | return -EINPROGRESS; | 590 | return -EINPROGRESS; |
619 | 591 | ||
620 | memset(rs, 0, sizeof(struct ath5k_rx_status)); | 592 | memset(rs, 0, sizeof(struct ath5k_rx_status)); |
593 | rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); | ||
621 | 594 | ||
622 | /* | 595 | /* |
623 | * Frame receive status | 596 | * Frame receive status |
624 | */ | 597 | */ |
625 | rs->rs_datalen = rx_status->rx_status_0 & | 598 | rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; |
626 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | 599 | rs->rs_rssi = AR5K_REG_MS(rxstat0, |
627 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
628 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 600 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
629 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 601 | rs->rs_rate = AR5K_REG_MS(rxstat0, |
630 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 602 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
631 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, | 603 | rs->rs_antenna = AR5K_REG_MS(rxstat0, |
632 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); | 604 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
633 | rs->rs_more = !!(rx_status->rx_status_0 & | 605 | rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); |
634 | AR5K_5212_RX_DESC_STATUS0_MORE); | 606 | rs->rs_tstamp = AR5K_REG_MS(rxstat1, |
635 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
636 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 607 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
637 | 608 | ||
638 | /* | 609 | /* |
639 | * Key table status | 610 | * Key table status |
640 | */ | 611 | */ |
641 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | 612 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) |
642 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | 613 | rs->rs_keyix = AR5K_REG_MS(rxstat1, |
643 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | 614 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); |
644 | else | 615 | else |
645 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | 616 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; |
@@ -647,27 +618,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
647 | /* | 618 | /* |
648 | * Receive/descriptor errors | 619 | * Receive/descriptor errors |
649 | */ | 620 | */ |
650 | if (!(rx_status->rx_status_1 & | 621 | if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { |
651 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | 622 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) |
652 | if (rx_status->rx_status_1 & | ||
653 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
654 | rs->rs_status |= AR5K_RXERR_CRC; | 623 | rs->rs_status |= AR5K_RXERR_CRC; |
655 | 624 | ||
656 | if (rx_status->rx_status_1 & | 625 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
657 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
658 | rs->rs_status |= AR5K_RXERR_PHY; | 626 | rs->rs_status |= AR5K_RXERR_PHY; |
659 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 627 | rs->rs_phyerr = AR5K_REG_MS(rxstat1, |
660 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); | 628 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); |
661 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | 629 | if (!ah->ah_capabilities.cap_has_phyerr_counters) |
662 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); | 630 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); |
663 | } | 631 | } |
664 | 632 | ||
665 | if (rx_status->rx_status_1 & | 633 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) |
666 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
667 | rs->rs_status |= AR5K_RXERR_DECRYPT; | 634 | rs->rs_status |= AR5K_RXERR_DECRYPT; |
668 | 635 | ||
669 | if (rx_status->rx_status_1 & | 636 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) |
670 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
671 | rs->rs_status |= AR5K_RXERR_MIC; | 637 | rs->rs_status |= AR5K_RXERR_MIC; |
672 | } | 638 | } |
673 | return 0; | 639 | return 0; |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index efb672cb31e4..1fef84f87c78 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | |||
660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; | 660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int | ||
664 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
665 | { | ||
666 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
667 | struct ath5k_chan_pcal_info *chinfo; | ||
668 | u8 pier, pdg; | ||
669 | |||
670 | switch (mode) { | ||
671 | case AR5K_EEPROM_MODE_11A: | ||
672 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
673 | return 0; | ||
674 | chinfo = ee->ee_pwr_cal_a; | ||
675 | break; | ||
676 | case AR5K_EEPROM_MODE_11B: | ||
677 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
678 | return 0; | ||
679 | chinfo = ee->ee_pwr_cal_b; | ||
680 | break; | ||
681 | case AR5K_EEPROM_MODE_11G: | ||
682 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
683 | return 0; | ||
684 | chinfo = ee->ee_pwr_cal_g; | ||
685 | break; | ||
686 | default: | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
690 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
691 | if (!chinfo[pier].pd_curves) | ||
692 | continue; | ||
693 | |||
694 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
695 | struct ath5k_pdgain_info *pd = | ||
696 | &chinfo[pier].pd_curves[pdg]; | ||
697 | |||
698 | if (pd != NULL) { | ||
699 | kfree(pd->pd_step); | ||
700 | kfree(pd->pd_pwr); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | kfree(chinfo[pier].pd_curves); | ||
705 | } | ||
706 | |||
707 | return 0; | ||
708 | } | ||
709 | |||
663 | /* Convert RF5111 specific data to generic raw data | 710 | /* Convert RF5111 specific data to generic raw data |
664 | * used by interpolation code */ | 711 | * used by interpolation code */ |
665 | static int | 712 | static int |
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
684 | GFP_KERNEL); | 731 | GFP_KERNEL); |
685 | 732 | ||
686 | if (!chinfo[pier].pd_curves) | 733 | if (!chinfo[pier].pd_curves) |
687 | return -ENOMEM; | 734 | goto err_out; |
688 | 735 | ||
689 | /* Only one curve for RF5111 | 736 | /* Only one curve for RF5111 |
690 | * find out which one and place | 737 | * find out which one and place |
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
708 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 755 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
709 | sizeof(u8), GFP_KERNEL); | 756 | sizeof(u8), GFP_KERNEL); |
710 | if (!pd->pd_step) | 757 | if (!pd->pd_step) |
711 | return -ENOMEM; | 758 | goto err_out; |
712 | 759 | ||
713 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 760 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
714 | sizeof(s16), GFP_KERNEL); | 761 | sizeof(s16), GFP_KERNEL); |
715 | if (!pd->pd_pwr) | 762 | if (!pd->pd_pwr) |
716 | return -ENOMEM; | 763 | goto err_out; |
717 | 764 | ||
718 | /* Fill raw dataset | 765 | /* Fill raw dataset |
719 | * (convert power to 0.25dB units | 766 | * (convert power to 0.25dB units |
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
734 | } | 781 | } |
735 | 782 | ||
736 | return 0; | 783 | return 0; |
784 | |||
785 | err_out: | ||
786 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
787 | return -ENOMEM; | ||
737 | } | 788 | } |
738 | 789 | ||
739 | /* Parse EEPROM data */ | 790 | /* Parse EEPROM data */ |
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
867 | GFP_KERNEL); | 918 | GFP_KERNEL); |
868 | 919 | ||
869 | if (!chinfo[pier].pd_curves) | 920 | if (!chinfo[pier].pd_curves) |
870 | return -ENOMEM; | 921 | goto err_out; |
871 | 922 | ||
872 | /* Fill pd_curves */ | 923 | /* Fill pd_curves */ |
873 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 924 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
886 | sizeof(u8), GFP_KERNEL); | 937 | sizeof(u8), GFP_KERNEL); |
887 | 938 | ||
888 | if (!pd->pd_step) | 939 | if (!pd->pd_step) |
889 | return -ENOMEM; | 940 | goto err_out; |
890 | 941 | ||
891 | pd->pd_pwr = kcalloc(pd->pd_points, | 942 | pd->pd_pwr = kcalloc(pd->pd_points, |
892 | sizeof(s16), GFP_KERNEL); | 943 | sizeof(s16), GFP_KERNEL); |
893 | 944 | ||
894 | if (!pd->pd_pwr) | 945 | if (!pd->pd_pwr) |
895 | return -ENOMEM; | 946 | goto err_out; |
896 | |||
897 | 947 | ||
898 | /* Fill raw dataset | 948 | /* Fill raw dataset |
899 | * (all power levels are in 0.25dB units) */ | 949 | * (all power levels are in 0.25dB units) */ |
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
925 | sizeof(u8), GFP_KERNEL); | 975 | sizeof(u8), GFP_KERNEL); |
926 | 976 | ||
927 | if (!pd->pd_step) | 977 | if (!pd->pd_step) |
928 | return -ENOMEM; | 978 | goto err_out; |
929 | 979 | ||
930 | pd->pd_pwr = kcalloc(pd->pd_points, | 980 | pd->pd_pwr = kcalloc(pd->pd_points, |
931 | sizeof(s16), GFP_KERNEL); | 981 | sizeof(s16), GFP_KERNEL); |
932 | 982 | ||
933 | if (!pd->pd_pwr) | 983 | if (!pd->pd_pwr) |
934 | return -ENOMEM; | 984 | goto err_out; |
935 | 985 | ||
936 | /* Fill raw dataset | 986 | /* Fill raw dataset |
937 | * (all power levels are in 0.25dB units) */ | 987 | * (all power levels are in 0.25dB units) */ |
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
954 | } | 1004 | } |
955 | 1005 | ||
956 | return 0; | 1006 | return 0; |
1007 | |||
1008 | err_out: | ||
1009 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1010 | return -ENOMEM; | ||
957 | } | 1011 | } |
958 | 1012 | ||
959 | /* Parse EEPROM data */ | 1013 | /* Parse EEPROM data */ |
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1156 | GFP_KERNEL); | 1210 | GFP_KERNEL); |
1157 | 1211 | ||
1158 | if (!chinfo[pier].pd_curves) | 1212 | if (!chinfo[pier].pd_curves) |
1159 | return -ENOMEM; | 1213 | goto err_out; |
1160 | 1214 | ||
1161 | /* Fill pd_curves */ | 1215 | /* Fill pd_curves */ |
1162 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 1216 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1177 | sizeof(u8), GFP_KERNEL); | 1231 | sizeof(u8), GFP_KERNEL); |
1178 | 1232 | ||
1179 | if (!pd->pd_step) | 1233 | if (!pd->pd_step) |
1180 | return -ENOMEM; | 1234 | goto err_out; |
1181 | 1235 | ||
1182 | pd->pd_pwr = kcalloc(pd->pd_points, | 1236 | pd->pd_pwr = kcalloc(pd->pd_points, |
1183 | sizeof(s16), GFP_KERNEL); | 1237 | sizeof(s16), GFP_KERNEL); |
1184 | 1238 | ||
1185 | if (!pd->pd_pwr) | 1239 | if (!pd->pd_pwr) |
1186 | return -ENOMEM; | 1240 | goto err_out; |
1187 | 1241 | ||
1188 | /* Fill raw dataset | 1242 | /* Fill raw dataset |
1189 | * convert all pwr levels to | 1243 | * convert all pwr levels to |
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1213 | } | 1267 | } |
1214 | 1268 | ||
1215 | return 0; | 1269 | return 0; |
1270 | |||
1271 | err_out: | ||
1272 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1273 | return -ENOMEM; | ||
1216 | } | 1274 | } |
1217 | 1275 | ||
1218 | /* Parse EEPROM data */ | 1276 | /* Parse EEPROM data */ |
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | |||
1534 | return 0; | 1592 | return 0; |
1535 | } | 1593 | } |
1536 | 1594 | ||
1537 | static int | ||
1538 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
1539 | { | ||
1540 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1541 | struct ath5k_chan_pcal_info *chinfo; | ||
1542 | u8 pier, pdg; | ||
1543 | |||
1544 | switch (mode) { | ||
1545 | case AR5K_EEPROM_MODE_11A: | ||
1546 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
1547 | return 0; | ||
1548 | chinfo = ee->ee_pwr_cal_a; | ||
1549 | break; | ||
1550 | case AR5K_EEPROM_MODE_11B: | ||
1551 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
1552 | return 0; | ||
1553 | chinfo = ee->ee_pwr_cal_b; | ||
1554 | break; | ||
1555 | case AR5K_EEPROM_MODE_11G: | ||
1556 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
1557 | return 0; | ||
1558 | chinfo = ee->ee_pwr_cal_g; | ||
1559 | break; | ||
1560 | default: | ||
1561 | return -EINVAL; | ||
1562 | } | ||
1563 | |||
1564 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
1565 | if (!chinfo[pier].pd_curves) | ||
1566 | continue; | ||
1567 | |||
1568 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
1569 | struct ath5k_pdgain_info *pd = | ||
1570 | &chinfo[pier].pd_curves[pdg]; | ||
1571 | |||
1572 | if (pd != NULL) { | ||
1573 | kfree(pd->pd_step); | ||
1574 | kfree(pd->pd_pwr); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | kfree(chinfo[pier].pd_curves); | ||
1579 | } | ||
1580 | |||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | /* Read conformance test limits used for regulatory control */ | 1595 | /* Read conformance test limits used for regulatory control */ |
1585 | static int | 1596 | static int |
1586 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | 1597 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) |
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) | |||
1721 | return ret; | 1732 | return ret; |
1722 | } | 1733 | } |
1723 | 1734 | ||
1724 | /* | ||
1725 | * Read the MAC address from eeprom | ||
1726 | */ | ||
1727 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
1728 | { | ||
1729 | u8 mac_d[ETH_ALEN] = {}; | ||
1730 | u32 total, offset; | ||
1731 | u16 data; | ||
1732 | int octet; | ||
1733 | |||
1734 | AR5K_EEPROM_READ(0x20, data); | ||
1735 | |||
1736 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
1737 | AR5K_EEPROM_READ(offset, data); | ||
1738 | |||
1739 | total += data; | ||
1740 | mac_d[octet + 1] = data & 0xff; | ||
1741 | mac_d[octet] = data >> 8; | ||
1742 | octet += 2; | ||
1743 | } | ||
1744 | |||
1745 | if (!total || total == 3 * 0xffff) | ||
1746 | return -EINVAL; | ||
1747 | |||
1748 | memcpy(mac, mac_d, ETH_ALEN); | ||
1749 | |||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | 1735 | ||
1754 | /***********************\ | 1736 | /***********************\ |
1755 | * Init/Detach functions * | 1737 | * Init/Detach functions * |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 9be29b728b1c..807bd6440169 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
282 | if (changes & BSS_CHANGED_BEACON_INT) | 282 | if (changes & BSS_CHANGED_BEACON_INT) |
283 | sc->bintval = bss_conf->beacon_int; | 283 | sc->bintval = bss_conf->beacon_int; |
284 | 284 | ||
285 | if (changes & BSS_CHANGED_ERP_SLOT) { | ||
286 | int slot_time; | ||
287 | |||
288 | ah->ah_short_slot = bss_conf->use_short_slot; | ||
289 | slot_time = ath5k_hw_get_default_slottime(ah) + | ||
290 | 3 * ah->ah_coverage_class; | ||
291 | ath5k_hw_set_ifs_intervals(ah, slot_time); | ||
292 | } | ||
293 | |||
285 | if (changes & BSS_CHANGED_ASSOC) { | 294 | if (changes & BSS_CHANGED_ASSOC) { |
286 | avf->assoc = bss_conf->assoc; | 295 | avf->assoc = bss_conf->assoc; |
287 | if (bss_conf->assoc) | 296 | if (bss_conf->assoc) |
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 3c44689a700b..296c316a8341 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/pci-aspm.h> | 19 | #include <linux/pci-aspm.h> |
20 | #include <linux/etherdevice.h> | ||
20 | #include "../ath.h" | 21 | #include "../ath.h" |
21 | #include "ath5k.h" | 22 | #include "ath5k.h" |
22 | #include "debug.h" | 23 | #include "debug.h" |
@@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
112 | /* | ||
113 | * Read the MAC address from eeprom or platform_data | ||
114 | */ | ||
115 | static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
116 | { | ||
117 | u8 mac_d[ETH_ALEN] = {}; | ||
118 | u32 total, offset; | ||
119 | u16 data; | ||
120 | int octet; | ||
121 | |||
122 | AR5K_EEPROM_READ(0x20, data); | ||
123 | |||
124 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
125 | AR5K_EEPROM_READ(offset, data); | ||
126 | |||
127 | total += data; | ||
128 | mac_d[octet + 1] = data & 0xff; | ||
129 | mac_d[octet] = data >> 8; | ||
130 | octet += 2; | ||
131 | } | ||
132 | |||
133 | if (!total || total == 3 * 0xffff) | ||
134 | return -EINVAL; | ||
135 | |||
136 | memcpy(mac, mac_d, ETH_ALEN); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | |||
111 | /* Common ath_bus_opts structure */ | 142 | /* Common ath_bus_opts structure */ |
112 | static const struct ath_bus_ops ath_pci_bus_ops = { | 143 | static const struct ath_bus_ops ath_pci_bus_ops = { |
113 | .ath_bus_type = ATH_PCI, | 144 | .ath_bus_type = ATH_PCI, |
114 | .read_cachesize = ath5k_pci_read_cachesize, | 145 | .read_cachesize = ath5k_pci_read_cachesize, |
115 | .eeprom_read = ath5k_pci_eeprom_read, | 146 | .eeprom_read = ath5k_pci_eeprom_read, |
147 | .eeprom_read_mac = ath5k_pci_eeprom_read_mac, | ||
116 | }; | 148 | }; |
117 | 149 | ||
118 | /********************\ | 150 | /********************\ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index d9b3f828455a..712a9ac4000e 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] = | |||
75 | * bwmodes. | 75 | * bwmodes. |
76 | */ | 76 | */ |
77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
78 | int len, struct ieee80211_rate *rate) | 78 | int len, struct ieee80211_rate *rate, bool shortpre) |
79 | { | 79 | { |
80 | struct ath5k_softc *sc = ah->ah_sc; | 80 | struct ath5k_softc *sc = ah->ah_sc; |
81 | int sifs, preamble, plcp_bits, sym_time; | 81 | int sifs, preamble, plcp_bits, sym_time; |
@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
84 | 84 | ||
85 | /* Fallback */ | 85 | /* Fallback */ |
86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, |
88 | NULL, len, rate); | 88 | NULL, len, rate); |
89 | return le16_to_cpu(dur); | 89 | |
90 | /* subtract difference between long and short preamble */ | ||
91 | dur = le16_to_cpu(raw_dur); | ||
92 | if (shortpre) | ||
93 | dur -= 96; | ||
94 | |||
95 | return dur; | ||
90 | } | 96 | } |
91 | 97 | ||
92 | bitrate = rate->bitrate; | 98 | bitrate = rate->bitrate; |
@@ -145,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | |||
145 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; | 151 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; |
146 | break; | 152 | break; |
147 | case AR5K_BWMODE_DEFAULT: | 153 | case AR5K_BWMODE_DEFAULT: |
148 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; | ||
149 | default: | 154 | default: |
150 | if (channel->hw_value & CHANNEL_CCK) | 155 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; |
156 | if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) | ||
151 | slot_time = AR5K_INIT_SLOT_TIME_B; | 157 | slot_time = AR5K_INIT_SLOT_TIME_B; |
152 | break; | 158 | break; |
153 | } | 159 | } |
@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
263 | * actual rate for this rate. See mac80211 tx.c | 269 | * actual rate for this rate. See mac80211 tx.c |
264 | * ieee80211_duration() for a brief description of | 270 | * ieee80211_duration() for a brief description of |
265 | * what rate we should choose to TX ACKs. */ | 271 | * what rate we should choose to TX ACKs. */ |
266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 272 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
267 | 273 | ||
268 | ath5k_hw_reg_write(ah, tx_time, reg); | 274 | ath5k_hw_reg_write(ah, tx_time, reg); |
269 | 275 | ||
270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 276 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
271 | continue; | 277 | continue; |
272 | 278 | ||
273 | /* | 279 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); |
274 | * We're not distinguishing short preamble here, | ||
275 | * This is true, all we'll get is a longer value here | ||
276 | * which is not necessarilly bad. We could use | ||
277 | * export ieee80211_frame_duration() but that needs to be | ||
278 | * fixed first to be properly used by mac802111 drivers: | ||
279 | * | ||
280 | * - remove erp stuff and let the routine figure ofdm | ||
281 | * erp rates | ||
282 | * - remove passing argument ieee80211_local as | ||
283 | * drivers don't have access to it | ||
284 | * - move drivers using ieee80211_generic_frame_duration() | ||
285 | * to this | ||
286 | */ | ||
287 | ath5k_hw_reg_write(ah, tx_time, | 280 | ath5k_hw_reg_write(ah, tx_time, |
288 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | 281 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); |
289 | } | 282 | } |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 3343fb9e4940..b18c5021aac3 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
519 | return -EINVAL; | 519 | return -EINVAL; |
520 | 520 | ||
521 | sifs = ath5k_hw_get_default_sifs(ah); | 521 | sifs = ath5k_hw_get_default_sifs(ah); |
522 | sifs_clock = ath5k_hw_htoclock(ah, sifs); | 522 | sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); |
523 | 523 | ||
524 | /* EIFS | 524 | /* EIFS |
525 | * Txtime of ack at lowest rate + SIFS + DIFS | 525 | * Txtime of ack at lowest rate + SIFS + DIFS |
@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
550 | else | 550 | else |
551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; | 551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; |
552 | 552 | ||
553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
554 | 554 | ||
555 | /* ack_tx_time includes an SIFS already */ | 555 | /* ack_tx_time includes an SIFS already */ |
556 | eifs = ack_tx_time + sifs + 2 * slot_time; | 556 | eifs = ack_tx_time + sifs + 2 * slot_time; |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ad57a6d23110..d9ff8413ab9a 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -5,7 +5,7 @@ config ATH9K_COMMON | |||
5 | 5 | ||
6 | config ATH9K | 6 | config ATH9K |
7 | tristate "Atheros 802.11n wireless cards support" | 7 | tristate "Atheros 802.11n wireless cards support" |
8 | depends on PCI && MAC80211 | 8 | depends on MAC80211 |
9 | select ATH9K_HW | 9 | select ATH9K_HW |
10 | select MAC80211_LEDS | 10 | select MAC80211_LEDS |
11 | select LEDS_CLASS | 11 | select LEDS_CLASS |
@@ -23,6 +23,25 @@ config ATH9K | |||
23 | 23 | ||
24 | If you choose to build a module, it'll be called ath9k. | 24 | If you choose to build a module, it'll be called ath9k. |
25 | 25 | ||
26 | config ATH9K_PCI | ||
27 | bool "Atheros ath9k PCI/PCIe bus support" | ||
28 | depends on ATH9K && PCI | ||
29 | default PCI | ||
30 | ---help--- | ||
31 | This option enables the PCI bus support in ath9k. | ||
32 | |||
33 | Say Y, if you have a compatible PCI/PCIe wireless card. | ||
34 | |||
35 | config ATH9K_AHB | ||
36 | bool "Atheros ath9k AHB bus support" | ||
37 | depends on ATH9K | ||
38 | default n | ||
39 | ---help--- | ||
40 | This option enables the AHB bus support in ath9k. | ||
41 | |||
42 | Say Y, if you have a SoC with a compatible built-in | ||
43 | wireless MAC. Say N if unsure. | ||
44 | |||
26 | config ATH9K_DEBUGFS | 45 | config ATH9K_DEBUGFS |
27 | bool "Atheros ath9k debugging" | 46 | bool "Atheros ath9k debugging" |
28 | depends on ATH9K && DEBUG_FS | 47 | depends on ATH9K && DEBUG_FS |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d66ca8042eb..05a6fade7b1c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -6,8 +6,8 @@ ath9k-y += beacon.o \ | |||
6 | xmit.o \ | 6 | xmit.o \ |
7 | 7 | ||
8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
9 | ath9k-$(CONFIG_PCI) += pci.o | 9 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
10 | ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o | 10 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | 11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
12 | 12 | ||
13 | obj-$(CONFIG_ATH9K) += ath9k.o | 13 | obj-$(CONFIG_ATH9K) += ath9k.o |
@@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \ | |||
48 | htc_drv_init.o \ | 48 | htc_drv_init.o \ |
49 | htc_drv_gpio.o | 49 | htc_drv_gpio.o |
50 | 50 | ||
51 | ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o | ||
52 | |||
51 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o | 53 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cb0efa9b4c0..5193ed58a17b 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -21,6 +21,14 @@ | |||
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include "ath9k.h" | 22 | #include "ath9k.h" |
23 | 23 | ||
24 | const struct platform_device_id ath9k_platform_id_table[] = { | ||
25 | { | ||
26 | .name = "ath9k", | ||
27 | .driver_data = AR5416_AR9100_DEVID, | ||
28 | }, | ||
29 | {}, | ||
30 | }; | ||
31 | |||
24 | /* return bus cachesize in 4B word units */ | 32 | /* return bus cachesize in 4B word units */ |
25 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) | 33 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) |
26 | { | 34 | { |
@@ -57,6 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
57 | struct ath_softc *sc; | 65 | struct ath_softc *sc; |
58 | struct ieee80211_hw *hw; | 66 | struct ieee80211_hw *hw; |
59 | struct resource *res; | 67 | struct resource *res; |
68 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
60 | int irq; | 69 | int irq; |
61 | int ret = 0; | 70 | int ret = 0; |
62 | struct ath_hw *ah; | 71 | struct ath_hw *ah; |
@@ -116,7 +125,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
116 | goto err_free_hw; | 125 | goto err_free_hw; |
117 | } | 126 | } |
118 | 127 | ||
119 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 128 | ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); |
120 | if (ret) { | 129 | if (ret) { |
121 | dev_err(&pdev->dev, "failed to initialize device\n"); | 130 | dev_err(&pdev->dev, "failed to initialize device\n"); |
122 | goto err_irq; | 131 | goto err_irq; |
@@ -165,8 +174,11 @@ static struct platform_driver ath_ahb_driver = { | |||
165 | .name = "ath9k", | 174 | .name = "ath9k", |
166 | .owner = THIS_MODULE, | 175 | .owner = THIS_MODULE, |
167 | }, | 176 | }, |
177 | .id_table = ath9k_platform_id_table, | ||
168 | }; | 178 | }; |
169 | 179 | ||
180 | MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table); | ||
181 | |||
170 | int ath_ahb_init(void) | 182 | int ath_ahb_init(void) |
171 | { | 183 | { |
172 | return platform_driver_register(&ath_ahb_driver); | 184 | return platform_driver_register(&ath_ahb_driver); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 8dd8f6308502..c338efbccf40 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
290 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | 290 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) |
291 | | SM(txPower, AR_XmitPower) | 291 | | SM(txPower, AR_XmitPower) |
292 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | 292 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) |
293 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
294 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | 293 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) |
295 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); | 294 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); |
296 | 295 | ||
@@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
311 | } | 310 | } |
312 | } | 311 | } |
313 | 312 | ||
313 | static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) | ||
314 | { | ||
315 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
316 | |||
317 | if (val) | ||
318 | ads->ds_ctl0 |= AR_ClrDestMask; | ||
319 | else | ||
320 | ads->ds_ctl0 &= ~AR_ClrDestMask; | ||
321 | } | ||
322 | |||
314 | static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | 323 | static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, |
315 | void *lastds, | 324 | void *lastds, |
316 | u32 durUpdateEn, u32 rtsctsRate, | 325 | u32 durUpdateEn, u32 rtsctsRate, |
@@ -448,4 +457,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) | |||
448 | ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; | 457 | ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; |
449 | ops->clr11n_aggr = ar9002_hw_clr11n_aggr; | 458 | ops->clr11n_aggr = ar9002_hw_clr11n_aggr; |
450 | ops->set11n_burstduration = ar9002_hw_set11n_burstduration; | 459 | ops->set11n_burstduration = ar9002_hw_set11n_burstduration; |
460 | ops->set_clrdmask = ar9002_hw_set_clrdmask; | ||
451 | } | 461 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 37663dbbcf57..47780ef1c892 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -483,7 +483,11 @@ | |||
483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | 483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 |
484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | 484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 |
485 | 485 | ||
486 | #define AR_PHY_TX_PWRCTRL8 0xa278 | ||
487 | |||
486 | #define AR_PHY_TX_PWRCTRL9 0xa27C | 488 | #define AR_PHY_TX_PWRCTRL9 0xa27C |
489 | |||
490 | #define AR_PHY_TX_PWRCTRL10 0xa394 | ||
487 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | 491 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 |
488 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | 492 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 |
489 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 | 493 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 |
@@ -495,6 +499,8 @@ | |||
495 | 499 | ||
496 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 | 500 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 |
497 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 | 501 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 |
502 | #define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc | ||
503 | #define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0 | ||
498 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 | 504 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 |
499 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 | 505 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 |
500 | 506 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 9ecca93392e8..f915a3dbfcad 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { | |||
34 | 34 | ||
35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | 35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { |
36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | |||
119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | 131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, |
132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = { | |||
835 | 835 | ||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | 836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { |
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | 932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, |
933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
@@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
941 | 941 | ||
942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | 942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { |
943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | |||
1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | 1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, |
1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { | |||
1307 | 1307 | ||
1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | 1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { |
1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1310 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1310 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1311 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1311 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1312 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1312 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | 1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, |
1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | 1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, |
1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | 1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, |
1332 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | 1332 | {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, |
1333 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | 1333 | {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, |
1334 | {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, | 1334 | {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, |
1335 | {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, | 1335 | {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, |
1336 | {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, | 1336 | {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, |
1337 | {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, | 1337 | {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, |
1338 | {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, | 1338 | {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, |
1339 | {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, | 1339 | {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, |
1340 | {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1340 | {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1341 | {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1341 | {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1342 | {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1342 | {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1343 | {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1343 | {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1344 | {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1344 | {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1345 | {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1345 | {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1346 | {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1346 | {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | 1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, |
1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | 1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, |
1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | 1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, |
@@ -1361,45 +1361,45 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | 1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, |
1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | 1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, |
1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | 1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, |
1364 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | 1364 | {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, |
1365 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | 1365 | {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, |
1366 | {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, | 1366 | {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, |
1367 | {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, | 1367 | {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, |
1368 | {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, | 1368 | {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, |
1369 | {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, | 1369 | {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, |
1370 | {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, | 1370 | {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, |
1371 | {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, | 1371 | {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, |
1372 | {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1372 | {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1373 | {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1373 | {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1374 | {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1374 | {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1375 | {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1375 | {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1376 | {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1376 | {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1377 | {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1377 | {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1378 | {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1378 | {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1384 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | 1384 | {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, |
1385 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | 1385 | {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, |
1386 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, | 1386 | {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, |
1387 | {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, | 1387 | {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, |
1388 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | 1388 | {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, |
1389 | {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, | 1389 | {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, |
1390 | {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, | 1390 | {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1391 | {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1391 | {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1392 | {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1392 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1393 | {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1393 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1394 | {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1394 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1395 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1395 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1396 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1396 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1397 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1397 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1399 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1399 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1400 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1400 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1401 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1401 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, | 1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 724ac2464ad5..c1264d60c499 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
329 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | 329 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) |
330 | | SM(txpower, AR_XmitPower) | 330 | | SM(txpower, AR_XmitPower) |
331 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | 331 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) |
332 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
333 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | 332 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) |
334 | | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); | 333 | | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); |
335 | 334 | ||
@@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
350 | ads->ctl22 = 0; | 349 | ads->ctl22 = 0; |
351 | } | 350 | } |
352 | 351 | ||
352 | static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) | ||
353 | { | ||
354 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
355 | |||
356 | if (val) | ||
357 | ads->ctl11 |= AR_ClrDestMask; | ||
358 | else | ||
359 | ads->ctl11 &= ~AR_ClrDestMask; | ||
360 | } | ||
361 | |||
353 | static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | 362 | static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, |
354 | void *lastds, | 363 | void *lastds, |
355 | u32 durUpdateEn, u32 rtsctsRate, | 364 | u32 durUpdateEn, u32 rtsctsRate, |
@@ -510,6 +519,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | |||
510 | ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; | 519 | ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; |
511 | ops->clr11n_aggr = ar9003_hw_clr11n_aggr; | 520 | ops->clr11n_aggr = ar9003_hw_clr11n_aggr; |
512 | ops->set11n_burstduration = ar9003_hw_set11n_burstduration; | 521 | ops->set11n_burstduration = ar9003_hw_set11n_burstduration; |
522 | ops->set_clrdmask = ar9003_hw_set_clrdmask; | ||
513 | } | 523 | } |
514 | 524 | ||
515 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) | 525 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eb250d6b8038..1bc33f51e466 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -75,9 +75,18 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
75 | freq = centers.synth_center; | 75 | freq = centers.synth_center; |
76 | 76 | ||
77 | if (freq < 4800) { /* 2 GHz, fractional mode */ | 77 | if (freq < 4800) { /* 2 GHz, fractional mode */ |
78 | if (AR_SREV_9485(ah)) | 78 | if (AR_SREV_9485(ah)) { |
79 | channelSel = CHANSEL_2G_9485(freq); | 79 | u32 chan_frac; |
80 | else | 80 | |
81 | /* | ||
82 | * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 | ||
83 | * ndiv = ((chan_mhz * 4) / 3) / freq_ref; | ||
84 | * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 | ||
85 | */ | ||
86 | channelSel = (freq * 4) / 120; | ||
87 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | ||
88 | channelSel = (channelSel << 17) | chan_frac; | ||
89 | } else | ||
81 | channelSel = CHANSEL_2G(freq); | 90 | channelSel = CHANSEL_2G(freq); |
82 | /* Set to 2G mode */ | 91 | /* Set to 2G mode */ |
83 | bMode = 1; | 92 | bMode = 1; |
@@ -401,7 +410,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, | |||
401 | 410 | ||
402 | ar9003_hw_spur_ofdm_clear(ah); | 411 | ar9003_hw_spur_ofdm_clear(ah); |
403 | 412 | ||
404 | for (i = 0; spurChansPtr[i] && i < 5; i++) { | 413 | for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { |
405 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; | 414 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; |
406 | if (abs(freq_offset) < range) { | 415 | if (abs(freq_offset) < range) { |
407 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); | 416 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index f91f73e50d00..fbdde29f0ab8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -396,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { | |||
396 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 396 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
397 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 397 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
398 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 398 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
399 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 399 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
400 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 400 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
401 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 401 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
402 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 402 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -469,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { | |||
469 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 469 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
470 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 470 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
471 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 471 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
472 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 472 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
473 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 473 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
474 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 474 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
475 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 475 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -635,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
635 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 635 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
636 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 636 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
637 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 637 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
638 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 638 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
639 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 639 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
640 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 640 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
641 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 641 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -728,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { | |||
728 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 728 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
729 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 729 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
730 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 730 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
731 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 731 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
732 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 732 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
733 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 733 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
734 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 734 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -827,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { | |||
827 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 827 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
828 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 828 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
829 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 829 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
830 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 830 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
831 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 831 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
832 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 832 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
833 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 833 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 38835bc324b2..a6b538802251 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -200,6 +200,7 @@ struct ath_atx_ac { | |||
200 | int sched; | 200 | int sched; |
201 | struct list_head list; | 201 | struct list_head list; |
202 | struct list_head tid_q; | 202 | struct list_head tid_q; |
203 | bool clear_ps_filter; | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | struct ath_frame_info { | 206 | struct ath_frame_info { |
@@ -255,8 +256,12 @@ struct ath_node { | |||
255 | #endif | 256 | #endif |
256 | struct ath_atx_tid tid[WME_NUM_TID]; | 257 | struct ath_atx_tid tid[WME_NUM_TID]; |
257 | struct ath_atx_ac ac[WME_NUM_AC]; | 258 | struct ath_atx_ac ac[WME_NUM_AC]; |
259 | int ps_key; | ||
260 | |||
258 | u16 maxampdu; | 261 | u16 maxampdu; |
259 | u8 mpdudensity; | 262 | u8 mpdudensity; |
263 | |||
264 | bool sleeping; | ||
260 | }; | 265 | }; |
261 | 266 | ||
262 | #define AGGR_CLEANUP BIT(1) | 267 | #define AGGR_CLEANUP BIT(1) |
@@ -338,6 +343,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
338 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 343 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
339 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 344 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
340 | 345 | ||
346 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); | ||
347 | bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); | ||
348 | |||
341 | /********/ | 349 | /********/ |
342 | /* VIFs */ | 350 | /* VIFs */ |
343 | /********/ | 351 | /********/ |
@@ -665,7 +673,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | |||
665 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | 673 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); |
666 | bool ath9k_uses_beacons(int type); | 674 | bool ath9k_uses_beacons(int type); |
667 | 675 | ||
668 | #ifdef CONFIG_PCI | 676 | #ifdef CONFIG_ATH9K_PCI |
669 | int ath_pci_init(void); | 677 | int ath_pci_init(void); |
670 | void ath_pci_exit(void); | 678 | void ath_pci_exit(void); |
671 | #else | 679 | #else |
@@ -673,7 +681,7 @@ static inline int ath_pci_init(void) { return 0; }; | |||
673 | static inline void ath_pci_exit(void) {}; | 681 | static inline void ath_pci_exit(void) {}; |
674 | #endif | 682 | #endif |
675 | 683 | ||
676 | #ifdef CONFIG_ATHEROS_AR71XX | 684 | #ifdef CONFIG_ATH9K_AHB |
677 | int ath_ahb_init(void); | 685 | int ath_ahb_init(void); |
678 | void ath_ahb_exit(void); | 686 | void ath_ahb_exit(void); |
679 | #else | 687 | #else |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eccb0ec87adb..24f565ba9988 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
320 | if (avp->av_bcbuf != NULL) { | 320 | if (avp->av_bcbuf != NULL) { |
321 | struct ath_buf *bf; | 321 | struct ath_buf *bf; |
322 | 322 | ||
323 | avp->is_bslot_active = false; | ||
323 | if (avp->av_bslot != -1) { | 324 | if (avp->av_bslot != -1) { |
324 | sc->beacon.bslot[avp->av_bslot] = NULL; | 325 | sc->beacon.bslot[avp->av_bslot] = NULL; |
325 | sc->nbcnvifs--; | 326 | sc->nbcnvifs--; |
@@ -743,9 +744,27 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
743 | cur_conf->dtim_period = 1; | 744 | cur_conf->dtim_period = 1; |
744 | 745 | ||
745 | ath_set_beacon(sc); | 746 | ath_set_beacon(sc); |
746 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
747 | } | 747 | } |
748 | 748 | ||
749 | static bool ath_has_valid_bslot(struct ath_softc *sc) | ||
750 | { | ||
751 | struct ath_vif *avp; | ||
752 | int slot; | ||
753 | bool found = false; | ||
754 | |||
755 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
756 | if (sc->beacon.bslot[slot]) { | ||
757 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
758 | if (avp->is_bslot_active) { | ||
759 | found = true; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | } | ||
764 | return found; | ||
765 | } | ||
766 | |||
767 | |||
749 | void ath_set_beacon(struct ath_softc *sc) | 768 | void ath_set_beacon(struct ath_softc *sc) |
750 | { | 769 | { |
751 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 770 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -753,7 +772,8 @@ void ath_set_beacon(struct ath_softc *sc) | |||
753 | 772 | ||
754 | switch (sc->sc_ah->opmode) { | 773 | switch (sc->sc_ah->opmode) { |
755 | case NL80211_IFTYPE_AP: | 774 | case NL80211_IFTYPE_AP: |
756 | ath_beacon_config_ap(sc, cur_conf); | 775 | if (ath_has_valid_bslot(sc)) |
776 | ath_beacon_config_ap(sc, cur_conf); | ||
757 | break; | 777 | break; |
758 | case NL80211_IFTYPE_ADHOC: | 778 | case NL80211_IFTYPE_ADHOC: |
759 | case NL80211_IFTYPE_MESH_POINT: | 779 | case NL80211_IFTYPE_MESH_POINT: |
@@ -761,6 +781,12 @@ void ath_set_beacon(struct ath_softc *sc) | |||
761 | break; | 781 | break; |
762 | case NL80211_IFTYPE_STATION: | 782 | case NL80211_IFTYPE_STATION: |
763 | ath_beacon_config_sta(sc, cur_conf); | 783 | ath_beacon_config_sta(sc, cur_conf); |
784 | /* | ||
785 | * Request a re-configuration of Beacon related timers | ||
786 | * on the receipt of the first Beacon frame (i.e., | ||
787 | * after time sync with the AP). | ||
788 | */ | ||
789 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
764 | break; | 790 | break; |
765 | default: | 791 | default: |
766 | ath_dbg(common, ATH_DBG_CONFIG, | 792 | ath_dbg(common, ATH_DBG_CONFIG, |
@@ -774,20 +800,8 @@ void ath_set_beacon(struct ath_softc *sc) | |||
774 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | 800 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) |
775 | { | 801 | { |
776 | struct ath_hw *ah = sc->sc_ah; | 802 | struct ath_hw *ah = sc->sc_ah; |
777 | struct ath_vif *avp; | ||
778 | int slot; | ||
779 | bool found = false; | ||
780 | 803 | ||
781 | for (slot = 0; slot < ATH_BCBUF; slot++) { | 804 | if (!ath_has_valid_bslot(sc)) |
782 | if (sc->beacon.bslot[slot]) { | ||
783 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
784 | if (avp->is_bslot_active) { | ||
785 | found = true; | ||
786 | break; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | if (!found) | ||
791 | return; | 805 | return; |
792 | 806 | ||
793 | ath9k_ps_wakeup(sc); | 807 | ath9k_ps_wakeup(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a762cadb3ab7..34f191ec8e8c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -845,7 +845,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
845 | 845 | ||
846 | struct ath_softc *sc = file->private_data; | 846 | struct ath_softc *sc = file->private_data; |
847 | char *buf; | 847 | char *buf; |
848 | unsigned int len = 0, size = 1152; | 848 | unsigned int len = 0, size = 1400; |
849 | ssize_t retval = 0; | 849 | ssize_t retval = 0; |
850 | 850 | ||
851 | buf = kzalloc(size, GFP_KERNEL); | 851 | buf = kzalloc(size, GFP_KERNEL); |
@@ -874,6 +874,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
874 | "%18s : %10u\n", "DECRYPT BUSY ERR", | 874 | "%18s : %10u\n", "DECRYPT BUSY ERR", |
875 | sc->debug.stats.rxstats.decrypt_busy_err); | 875 | sc->debug.stats.rxstats.decrypt_busy_err); |
876 | 876 | ||
877 | len += snprintf(buf + len, size - len, | ||
878 | "%18s : %10d\n", "RSSI-CTL0", | ||
879 | sc->debug.stats.rxstats.rs_rssi_ctl0); | ||
880 | |||
881 | len += snprintf(buf + len, size - len, | ||
882 | "%18s : %10d\n", "RSSI-CTL1", | ||
883 | sc->debug.stats.rxstats.rs_rssi_ctl1); | ||
884 | |||
885 | len += snprintf(buf + len, size - len, | ||
886 | "%18s : %10d\n", "RSSI-CTL2", | ||
887 | sc->debug.stats.rxstats.rs_rssi_ctl2); | ||
888 | |||
889 | len += snprintf(buf + len, size - len, | ||
890 | "%18s : %10d\n", "RSSI-EXT0", | ||
891 | sc->debug.stats.rxstats.rs_rssi_ext0); | ||
892 | |||
893 | len += snprintf(buf + len, size - len, | ||
894 | "%18s : %10d\n", "RSSI-EXT1", | ||
895 | sc->debug.stats.rxstats.rs_rssi_ext1); | ||
896 | |||
897 | len += snprintf(buf + len, size - len, | ||
898 | "%18s : %10d\n", "RSSI-EXT2", | ||
899 | sc->debug.stats.rxstats.rs_rssi_ext2); | ||
900 | |||
901 | len += snprintf(buf + len, size - len, | ||
902 | "%18s : %10d\n", "Rx Antenna", | ||
903 | sc->debug.stats.rxstats.rs_antenna); | ||
904 | |||
877 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | 905 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); |
878 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | 906 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); |
879 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | 907 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); |
@@ -948,6 +976,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
948 | RX_PHY_ERR_INC(phyerr); | 976 | RX_PHY_ERR_INC(phyerr); |
949 | } | 977 | } |
950 | 978 | ||
979 | sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; | ||
980 | sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; | ||
981 | sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; | ||
982 | |||
983 | sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; | ||
984 | sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; | ||
985 | sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; | ||
986 | |||
987 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | ||
988 | |||
951 | #undef RX_STAT_INC | 989 | #undef RX_STAT_INC |
952 | #undef RX_PHY_ERR_INC | 990 | #undef RX_PHY_ERR_INC |
953 | } | 991 | } |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 59338de0ce19..1f9f8eada465 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -157,6 +157,13 @@ struct ath_rx_stats { | |||
157 | u32 post_delim_crc_err; | 157 | u32 post_delim_crc_err; |
158 | u32 decrypt_busy_err; | 158 | u32 decrypt_busy_err; |
159 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | 159 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; |
160 | int8_t rs_rssi_ctl0; | ||
161 | int8_t rs_rssi_ctl1; | ||
162 | int8_t rs_rssi_ctl2; | ||
163 | int8_t rs_rssi_ext0; | ||
164 | int8_t rs_rssi_ext1; | ||
165 | int8_t rs_rssi_ext2; | ||
166 | u8 rs_antenna; | ||
160 | }; | 167 | }; |
161 | 168 | ||
162 | struct ath_stats { | 169 | struct ath_stats { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index bd82447f5b78..3e316133f114 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -436,7 +436,11 @@ struct modal_eep_4k_header { | |||
436 | u8 db2_2:4, db2_3:4; | 436 | u8 db2_2:4, db2_3:4; |
437 | u8 db2_4:4, reserved:4; | 437 | u8 db2_4:4, reserved:4; |
438 | #endif | 438 | #endif |
439 | u8 futureModal[4]; | 439 | u8 tx_diversity; |
440 | u8 flc_pwr_thresh; | ||
441 | u8 bb_scale_smrt_antenna; | ||
442 | #define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f | ||
443 | u8 futureModal[1]; | ||
440 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; | 444 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; |
441 | } __packed; | 445 | } __packed; |
442 | 446 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index bc77a308c901..6f714dd72365 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
781 | { | 781 | { |
782 | struct modal_eep_4k_header *pModal; | 782 | struct modal_eep_4k_header *pModal; |
783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | 783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; |
784 | struct base_eep_header_4k *pBase = &eep->baseEepHeader; | ||
784 | u8 txRxAttenLocal; | 785 | u8 txRxAttenLocal; |
785 | u8 ob[5], db1[5], db2[5]; | 786 | u8 ob[5], db1[5], db2[5]; |
786 | u8 ant_div_control1, ant_div_control2; | 787 | u8 ant_div_control1, ant_div_control2; |
@@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
1003 | AR_PHY_SETTLING_SWITCH, | 1004 | AR_PHY_SETTLING_SWITCH, |
1004 | pModal->swSettleHt40); | 1005 | pModal->swSettleHt40); |
1005 | } | 1006 | } |
1007 | if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { | ||
1008 | u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & | ||
1009 | EEP_4K_BB_DESIRED_SCALE_MASK); | ||
1010 | if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { | ||
1011 | u32 pwrctrl, mask, clr; | ||
1012 | |||
1013 | mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); | ||
1014 | pwrctrl = mask * bb_desired_scale; | ||
1015 | clr = mask * 0x1f; | ||
1016 | REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); | ||
1017 | REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); | ||
1018 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); | ||
1019 | |||
1020 | mask = BIT(0)|BIT(5)|BIT(15); | ||
1021 | pwrctrl = mask * bb_desired_scale; | ||
1022 | clr = mask * 0x1f; | ||
1023 | REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); | ||
1024 | |||
1025 | mask = BIT(0)|BIT(5); | ||
1026 | pwrctrl = mask * bb_desired_scale; | ||
1027 | clr = mask * 0x1f; | ||
1028 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); | ||
1029 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); | ||
1030 | } | ||
1031 | } | ||
1006 | } | 1032 | } |
1007 | 1033 | ||
1008 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 1034 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 2f0712ea49a6..13579752a300 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -858,35 +858,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, | |||
858 | { | 858 | { |
859 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 859 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
860 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; | 860 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; |
861 | u16 antWrites[AR9287_ANT_16S]; | ||
862 | u32 regChainOffset, regval; | 861 | u32 regChainOffset, regval; |
863 | u8 txRxAttenLocal; | 862 | u8 txRxAttenLocal; |
864 | int i, j, offset_num; | 863 | int i; |
865 | 864 | ||
866 | pModal = &eep->modalHeader; | 865 | pModal = &eep->modalHeader; |
867 | 866 | ||
868 | antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); | ||
869 | antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); | ||
870 | antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); | ||
871 | antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); | ||
872 | antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); | ||
873 | antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); | ||
874 | antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); | ||
875 | antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); | ||
876 | |||
877 | offset_num = 8; | ||
878 | |||
879 | for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { | ||
880 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); | ||
881 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); | ||
882 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); | ||
883 | antWrites[j++] = 0; | ||
884 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); | ||
885 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); | ||
886 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); | ||
887 | antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); | ||
888 | } | ||
889 | |||
890 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); | 867 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); |
891 | 868 | ||
892 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { | 869 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 2d10239ce829..2e3a33a53406 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -17,11 +17,9 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | /* identify firmware images */ | 19 | /* identify firmware images */ |
20 | #define FIRMWARE_AR7010 "ar7010.fw" | 20 | #define FIRMWARE_AR7010_1_1 "htc_7010.fw" |
21 | #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" | 21 | #define FIRMWARE_AR9271 "htc_9271.fw" |
22 | #define FIRMWARE_AR9271 "ar9271.fw" | ||
23 | 22 | ||
24 | MODULE_FIRMWARE(FIRMWARE_AR7010); | ||
25 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); | 23 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); |
26 | MODULE_FIRMWARE(FIRMWARE_AR9271); | 24 | MODULE_FIRMWARE(FIRMWARE_AR9271); |
27 | 25 | ||
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) | |||
80 | 78 | ||
81 | if (cmd) { | 79 | if (cmd) { |
82 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | 80 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, |
83 | cmd->skb, 1); | 81 | cmd->skb, true); |
84 | kfree(cmd); | 82 | kfree(cmd); |
85 | } | 83 | } |
86 | 84 | ||
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | |||
126 | return ret; | 124 | return ret; |
127 | } | 125 | } |
128 | 126 | ||
127 | static void hif_usb_mgmt_cb(struct urb *urb) | ||
128 | { | ||
129 | struct cmd_buf *cmd = (struct cmd_buf *)urb->context; | ||
130 | struct hif_device_usb *hif_dev = cmd->hif_dev; | ||
131 | bool txok = true; | ||
132 | |||
133 | if (!cmd || !cmd->skb || !cmd->hif_dev) | ||
134 | return; | ||
135 | |||
136 | switch (urb->status) { | ||
137 | case 0: | ||
138 | break; | ||
139 | case -ENOENT: | ||
140 | case -ECONNRESET: | ||
141 | case -ENODEV: | ||
142 | case -ESHUTDOWN: | ||
143 | txok = false; | ||
144 | |||
145 | /* | ||
146 | * If the URBs are being flushed, no need to complete | ||
147 | * this packet. | ||
148 | */ | ||
149 | spin_lock(&hif_dev->tx.tx_lock); | ||
150 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | ||
151 | spin_unlock(&hif_dev->tx.tx_lock); | ||
152 | dev_kfree_skb_any(cmd->skb); | ||
153 | kfree(cmd); | ||
154 | return; | ||
155 | } | ||
156 | spin_unlock(&hif_dev->tx.tx_lock); | ||
157 | |||
158 | break; | ||
159 | default: | ||
160 | txok = false; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | skb_pull(cmd->skb, 4); | ||
165 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | ||
166 | cmd->skb, txok); | ||
167 | kfree(cmd); | ||
168 | } | ||
169 | |||
170 | static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, | ||
171 | struct sk_buff *skb) | ||
172 | { | ||
173 | struct urb *urb; | ||
174 | struct cmd_buf *cmd; | ||
175 | int ret = 0; | ||
176 | __le16 *hdr; | ||
177 | |||
178 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
179 | if (urb == NULL) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); | ||
183 | if (cmd == NULL) { | ||
184 | usb_free_urb(urb); | ||
185 | return -ENOMEM; | ||
186 | } | ||
187 | |||
188 | cmd->skb = skb; | ||
189 | cmd->hif_dev = hif_dev; | ||
190 | |||
191 | hdr = (__le16 *) skb_push(skb, 4); | ||
192 | *hdr++ = cpu_to_le16(skb->len - 4); | ||
193 | *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); | ||
194 | |||
195 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
196 | usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), | ||
197 | skb->data, skb->len, | ||
198 | hif_usb_mgmt_cb, cmd); | ||
199 | |||
200 | usb_anchor_urb(urb, &hif_dev->mgmt_submitted); | ||
201 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
202 | if (ret) { | ||
203 | usb_unanchor_urb(urb); | ||
204 | kfree(cmd); | ||
205 | } | ||
206 | usb_free_urb(urb); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
210 | |||
129 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | 211 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, |
130 | struct sk_buff_head *list) | 212 | struct sk_buff_head *list) |
131 | { | 213 | { |
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | |||
133 | 215 | ||
134 | while ((skb = __skb_dequeue(list)) != NULL) { | 216 | while ((skb = __skb_dequeue(list)) != NULL) { |
135 | dev_kfree_skb_any(skb); | 217 | dev_kfree_skb_any(skb); |
136 | TX_STAT_INC(skb_dropped); | 218 | } |
219 | } | ||
220 | |||
221 | static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, | ||
222 | struct sk_buff_head *queue, | ||
223 | bool txok) | ||
224 | { | ||
225 | struct sk_buff *skb; | ||
226 | |||
227 | while ((skb = __skb_dequeue(queue)) != NULL) { | ||
228 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
229 | skb, txok); | ||
230 | if (txok) | ||
231 | TX_STAT_INC(skb_success); | ||
232 | else | ||
233 | TX_STAT_INC(skb_failed); | ||
137 | } | 234 | } |
138 | } | 235 | } |
139 | 236 | ||
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
141 | { | 238 | { |
142 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | 239 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; |
143 | struct hif_device_usb *hif_dev; | 240 | struct hif_device_usb *hif_dev; |
144 | struct sk_buff *skb; | 241 | bool txok = true; |
145 | 242 | ||
146 | if (!tx_buf || !tx_buf->hif_dev) | 243 | if (!tx_buf || !tx_buf->hif_dev) |
147 | return; | 244 | return; |
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
155 | case -ECONNRESET: | 252 | case -ECONNRESET: |
156 | case -ENODEV: | 253 | case -ENODEV: |
157 | case -ESHUTDOWN: | 254 | case -ESHUTDOWN: |
158 | /* | 255 | txok = false; |
159 | * The URB has been killed, free the SKBs. | ||
160 | */ | ||
161 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
162 | 256 | ||
163 | /* | 257 | /* |
164 | * If the URBs are being flushed, no need to add this | 258 | * If the URBs are being flushed, no need to add this |
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
167 | spin_lock(&hif_dev->tx.tx_lock); | 261 | spin_lock(&hif_dev->tx.tx_lock); |
168 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | 262 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { |
169 | spin_unlock(&hif_dev->tx.tx_lock); | 263 | spin_unlock(&hif_dev->tx.tx_lock); |
264 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
170 | return; | 265 | return; |
171 | } | 266 | } |
172 | spin_unlock(&hif_dev->tx.tx_lock); | 267 | spin_unlock(&hif_dev->tx.tx_lock); |
173 | 268 | ||
174 | /* | 269 | break; |
175 | * In the stop() case, this URB has to be added to | ||
176 | * the free list. | ||
177 | */ | ||
178 | goto add_free; | ||
179 | default: | 270 | default: |
271 | txok = false; | ||
180 | break; | 272 | break; |
181 | } | 273 | } |
182 | 274 | ||
183 | /* | 275 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); |
184 | * Check if TX has been stopped, this is needed because | ||
185 | * this CB could have been invoked just after the TX lock | ||
186 | * was released in hif_stop() and kill_urb() hasn't been | ||
187 | * called yet. | ||
188 | */ | ||
189 | spin_lock(&hif_dev->tx.tx_lock); | ||
190 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
191 | spin_unlock(&hif_dev->tx.tx_lock); | ||
192 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
193 | goto add_free; | ||
194 | } | ||
195 | spin_unlock(&hif_dev->tx.tx_lock); | ||
196 | |||
197 | /* Complete the queued SKBs. */ | ||
198 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
199 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
200 | skb, 1); | ||
201 | TX_STAT_INC(skb_completed); | ||
202 | } | ||
203 | 276 | ||
204 | add_free: | ||
205 | /* Re-initialize the SKB queue */ | 277 | /* Re-initialize the SKB queue */ |
206 | tx_buf->len = tx_buf->offset = 0; | 278 | tx_buf->len = tx_buf->offset = 0; |
207 | __skb_queue_head_init(&tx_buf->skb_queue); | 279 | __skb_queue_head_init(&tx_buf->skb_queue); |
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
274 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); | 346 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); |
275 | if (ret) { | 347 | if (ret) { |
276 | tx_buf->len = tx_buf->offset = 0; | 348 | tx_buf->len = tx_buf->offset = 0; |
277 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | 349 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); |
278 | __skb_queue_head_init(&tx_buf->skb_queue); | 350 | __skb_queue_head_init(&tx_buf->skb_queue); |
279 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | 351 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); |
280 | hif_dev->tx.tx_buf_cnt++; | 352 | hif_dev->tx.tx_buf_cnt++; |
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
286 | return ret; | 358 | return ret; |
287 | } | 359 | } |
288 | 360 | ||
289 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | 361 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) |
290 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 362 | { |
363 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
292 | unsigned long flags; | 364 | unsigned long flags; |
365 | int ret = 0; | ||
293 | 366 | ||
294 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 367 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
295 | 368 | ||
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | |||
304 | return -ENOMEM; | 377 | return -ENOMEM; |
305 | } | 378 | } |
306 | 379 | ||
307 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | 380 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
308 | hif_dev->tx.tx_skb_cnt++; | ||
309 | 381 | ||
310 | /* Send normal frames immediately */ | 382 | tx_ctl = HTC_SKB_CB(skb); |
311 | if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) | 383 | |
312 | __hif_usb_tx(hif_dev); | 384 | /* Mgmt/Beacon frames don't use the TX buffer pool */ |
385 | if ((tx_ctl->type == ATH9K_HTC_MGMT) || | ||
386 | (tx_ctl->type == ATH9K_HTC_BEACON)) { | ||
387 | ret = hif_usb_send_mgmt(hif_dev, skb); | ||
388 | } | ||
389 | |||
390 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
391 | |||
392 | if ((tx_ctl->type == ATH9K_HTC_NORMAL) || | ||
393 | (tx_ctl->type == ATH9K_HTC_AMPDU)) { | ||
394 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | ||
395 | hif_dev->tx.tx_skb_cnt++; | ||
396 | } | ||
313 | 397 | ||
314 | /* Check if AMPDUs have to be sent immediately */ | 398 | /* Check if AMPDUs have to be sent immediately */ |
315 | if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && | 399 | if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && |
316 | (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && | ||
317 | (hif_dev->tx.tx_skb_cnt < 2)) { | 400 | (hif_dev->tx.tx_skb_cnt < 2)) { |
318 | __hif_usb_tx(hif_dev); | 401 | __hif_usb_tx(hif_dev); |
319 | } | 402 | } |
320 | 403 | ||
321 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 404 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
322 | 405 | ||
323 | return 0; | 406 | return ret; |
324 | } | 407 | } |
325 | 408 | ||
326 | static void hif_usb_start(void *hif_handle, u8 pipe_id) | 409 | static void hif_usb_start(void *hif_handle) |
327 | { | 410 | { |
328 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 411 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
329 | unsigned long flags; | 412 | unsigned long flags; |
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) | |||
335 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 418 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
336 | } | 419 | } |
337 | 420 | ||
338 | static void hif_usb_stop(void *hif_handle, u8 pipe_id) | 421 | static void hif_usb_stop(void *hif_handle) |
339 | { | 422 | { |
340 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 423 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
341 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | 424 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; |
342 | unsigned long flags; | 425 | unsigned long flags; |
343 | 426 | ||
344 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 427 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
345 | ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); | 428 | ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); |
346 | hif_dev->tx.tx_skb_cnt = 0; | 429 | hif_dev->tx.tx_skb_cnt = 0; |
347 | hif_dev->tx.flags |= HIF_USB_TX_STOP; | 430 | hif_dev->tx.flags |= HIF_USB_TX_STOP; |
348 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 431 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) | |||
352 | &hif_dev->tx.tx_pending, list) { | 435 | &hif_dev->tx.tx_pending, list) { |
353 | usb_kill_urb(tx_buf->urb); | 436 | usb_kill_urb(tx_buf->urb); |
354 | } | 437 | } |
438 | |||
439 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
355 | } | 440 | } |
356 | 441 | ||
357 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | 442 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) |
358 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
359 | { | 443 | { |
360 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 444 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
361 | int ret = 0; | 445 | int ret = 0; |
362 | 446 | ||
363 | switch (pipe_id) { | 447 | switch (pipe_id) { |
364 | case USB_WLAN_TX_PIPE: | 448 | case USB_WLAN_TX_PIPE: |
365 | ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); | 449 | ret = hif_usb_send_tx(hif_dev, skb); |
366 | break; | 450 | break; |
367 | case USB_REG_OUT_PIPE: | 451 | case USB_REG_OUT_PIPE: |
368 | ret = hif_usb_send_regout(hif_dev, skb); | 452 | ret = hif_usb_send_regout(hif_dev, skb); |
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | |||
377 | return ret; | 461 | return ret; |
378 | } | 462 | } |
379 | 463 | ||
464 | static inline bool check_index(struct sk_buff *skb, u8 idx) | ||
465 | { | ||
466 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
467 | |||
468 | tx_ctl = HTC_SKB_CB(skb); | ||
469 | |||
470 | if ((tx_ctl->type == ATH9K_HTC_AMPDU) && | ||
471 | (tx_ctl->sta_idx == idx)) | ||
472 | return true; | ||
473 | |||
474 | return false; | ||
475 | } | ||
476 | |||
477 | static void hif_usb_sta_drain(void *hif_handle, u8 idx) | ||
478 | { | ||
479 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
480 | struct sk_buff *skb, *tmp; | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
484 | |||
485 | skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { | ||
486 | if (check_index(skb, idx)) { | ||
487 | __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); | ||
488 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
489 | skb, false); | ||
490 | hif_dev->tx.tx_skb_cnt--; | ||
491 | TX_STAT_INC(skb_failed); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
496 | } | ||
497 | |||
380 | static struct ath9k_htc_hif hif_usb = { | 498 | static struct ath9k_htc_hif hif_usb = { |
381 | .transport = ATH9K_HIF_USB, | 499 | .transport = ATH9K_HIF_USB, |
382 | .name = "ath9k_hif_usb", | 500 | .name = "ath9k_hif_usb", |
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = { | |||
386 | 504 | ||
387 | .start = hif_usb_start, | 505 | .start = hif_usb_start, |
388 | .stop = hif_usb_stop, | 506 | .stop = hif_usb_stop, |
507 | .sta_drain = hif_usb_sta_drain, | ||
389 | .send = hif_usb_send, | 508 | .send = hif_usb_send, |
390 | }; | 509 | }; |
391 | 510 | ||
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
567 | case -ESHUTDOWN: | 686 | case -ESHUTDOWN: |
568 | goto free; | 687 | goto free; |
569 | default: | 688 | default: |
689 | skb_reset_tail_pointer(skb); | ||
690 | skb_trim(skb, 0); | ||
691 | |||
570 | goto resubmit; | 692 | goto resubmit; |
571 | } | 693 | } |
572 | 694 | ||
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
591 | USB_REG_IN_PIPE), | 713 | USB_REG_IN_PIPE), |
592 | nskb->data, MAX_REG_IN_BUF_SIZE, | 714 | nskb->data, MAX_REG_IN_BUF_SIZE, |
593 | ath9k_hif_usb_reg_in_cb, nskb); | 715 | ath9k_hif_usb_reg_in_cb, nskb); |
594 | |||
595 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
596 | if (ret) { | ||
597 | kfree_skb(nskb); | ||
598 | urb->context = NULL; | ||
599 | } | ||
600 | |||
601 | return; | ||
602 | } | 716 | } |
603 | 717 | ||
604 | resubmit: | 718 | resubmit: |
605 | skb_reset_tail_pointer(skb); | 719 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); |
606 | skb_trim(skb, 0); | ||
607 | |||
608 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 720 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
609 | if (ret) | 721 | if (ret) { |
722 | usb_unanchor_urb(urb); | ||
610 | goto free; | 723 | goto free; |
724 | } | ||
611 | 725 | ||
612 | return; | 726 | return; |
613 | free: | 727 | free: |
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
641 | kfree(tx_buf->buf); | 755 | kfree(tx_buf->buf); |
642 | kfree(tx_buf); | 756 | kfree(tx_buf); |
643 | } | 757 | } |
758 | |||
759 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
644 | } | 760 | } |
645 | 761 | ||
646 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | 762 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) |
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
652 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); | 768 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); |
653 | spin_lock_init(&hif_dev->tx.tx_lock); | 769 | spin_lock_init(&hif_dev->tx.tx_lock); |
654 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); | 770 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); |
771 | init_usb_anchor(&hif_dev->mgmt_submitted); | ||
655 | 772 | ||
656 | for (i = 0; i < MAX_TX_URB_NUM; i++) { | 773 | for (i = 0; i < MAX_TX_URB_NUM; i++) { |
657 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); | 774 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); |
@@ -748,43 +865,67 @@ err_urb: | |||
748 | return ret; | 865 | return ret; |
749 | } | 866 | } |
750 | 867 | ||
751 | static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) | 868 | static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
752 | { | 869 | { |
753 | if (hif_dev->reg_in_urb) { | 870 | usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); |
754 | usb_kill_urb(hif_dev->reg_in_urb); | ||
755 | if (hif_dev->reg_in_urb->context) | ||
756 | kfree_skb((void *)hif_dev->reg_in_urb->context); | ||
757 | usb_free_urb(hif_dev->reg_in_urb); | ||
758 | hif_dev->reg_in_urb = NULL; | ||
759 | } | ||
760 | } | 871 | } |
761 | 872 | ||
762 | static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) | 873 | static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
763 | { | 874 | { |
764 | struct sk_buff *skb; | 875 | struct urb *urb = NULL; |
876 | struct sk_buff *skb = NULL; | ||
877 | int i, ret; | ||
765 | 878 | ||
766 | hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 879 | init_usb_anchor(&hif_dev->reg_in_submitted); |
767 | if (hif_dev->reg_in_urb == NULL) | ||
768 | return -ENOMEM; | ||
769 | 880 | ||
770 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); | 881 | for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { |
771 | if (!skb) | ||
772 | goto err; | ||
773 | 882 | ||
774 | usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, | 883 | /* Allocate URB */ |
775 | usb_rcvbulkpipe(hif_dev->udev, | 884 | urb = usb_alloc_urb(0, GFP_KERNEL); |
776 | USB_REG_IN_PIPE), | 885 | if (urb == NULL) { |
777 | skb->data, MAX_REG_IN_BUF_SIZE, | 886 | ret = -ENOMEM; |
778 | ath9k_hif_usb_reg_in_cb, skb); | 887 | goto err_urb; |
888 | } | ||
779 | 889 | ||
780 | if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) | 890 | /* Allocate buffer */ |
781 | goto err; | 891 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); |
892 | if (!skb) { | ||
893 | ret = -ENOMEM; | ||
894 | goto err_skb; | ||
895 | } | ||
896 | |||
897 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
898 | usb_rcvbulkpipe(hif_dev->udev, | ||
899 | USB_REG_IN_PIPE), | ||
900 | skb->data, MAX_REG_IN_BUF_SIZE, | ||
901 | ath9k_hif_usb_reg_in_cb, skb); | ||
902 | |||
903 | /* Anchor URB */ | ||
904 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); | ||
905 | |||
906 | /* Submit URB */ | ||
907 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
908 | if (ret) { | ||
909 | usb_unanchor_urb(urb); | ||
910 | goto err_submit; | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * Drop reference count. | ||
915 | * This ensures that the URB is freed when killing them. | ||
916 | */ | ||
917 | usb_free_urb(urb); | ||
918 | } | ||
782 | 919 | ||
783 | return 0; | 920 | return 0; |
784 | 921 | ||
785 | err: | 922 | err_submit: |
786 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 923 | kfree_skb(skb); |
787 | return -ENOMEM; | 924 | err_skb: |
925 | usb_free_urb(urb); | ||
926 | err_urb: | ||
927 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); | ||
928 | return ret; | ||
788 | } | 929 | } |
789 | 930 | ||
790 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | 931 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) |
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | |||
801 | goto err_rx; | 942 | goto err_rx; |
802 | 943 | ||
803 | /* Register Read */ | 944 | /* Register Read */ |
804 | if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) | 945 | if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) |
805 | goto err_reg; | 946 | goto err_reg; |
806 | 947 | ||
807 | return 0; | 948 | return 0; |
@@ -816,7 +957,7 @@ err: | |||
816 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) | 957 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) |
817 | { | 958 | { |
818 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); | 959 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); |
819 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 960 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); |
820 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | 961 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); |
821 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | 962 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); |
822 | } | 963 | } |
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
1026 | /* Find out which firmware to load */ | 1167 | /* Find out which firmware to load */ |
1027 | 1168 | ||
1028 | if (IS_AR7010_DEVICE(id->driver_info)) | 1169 | if (IS_AR7010_DEVICE(id->driver_info)) |
1029 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) | 1170 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; |
1030 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; | ||
1031 | else | ||
1032 | hif_dev->fw_name = FIRMWARE_AR7010; | ||
1033 | else | 1171 | else |
1034 | hif_dev->fw_name = FIRMWARE_AR9271; | 1172 | hif_dev->fw_name = FIRMWARE_AR9271; |
1035 | 1173 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7b9d863d4035..f59df48a86e2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* FIXME: Verify these numbers (with Windows) */ | 32 | /* FIXME: Verify these numbers (with Windows) */ |
33 | #define MAX_TX_URB_NUM 8 | 33 | #define MAX_TX_URB_NUM 8 |
34 | #define MAX_TX_BUF_NUM 1024 | 34 | #define MAX_TX_BUF_NUM 256 |
35 | #define MAX_TX_BUF_SIZE 32768 | 35 | #define MAX_TX_BUF_SIZE 32768 |
36 | #define MAX_TX_AGGR_NUM 20 | 36 | #define MAX_TX_AGGR_NUM 20 |
37 | 37 | ||
@@ -40,7 +40,7 @@ | |||
40 | #define MAX_PKT_NUM_IN_TRANSFER 10 | 40 | #define MAX_PKT_NUM_IN_TRANSFER 10 |
41 | 41 | ||
42 | #define MAX_REG_OUT_URB_NUM 1 | 42 | #define MAX_REG_OUT_URB_NUM 1 |
43 | #define MAX_REG_OUT_BUF_NUM 8 | 43 | #define MAX_REG_IN_URB_NUM 64 |
44 | 44 | ||
45 | #define MAX_REG_IN_BUF_SIZE 64 | 45 | #define MAX_REG_IN_BUF_SIZE 64 |
46 | 46 | ||
@@ -90,9 +90,10 @@ struct hif_device_usb { | |||
90 | const struct firmware *firmware; | 90 | const struct firmware *firmware; |
91 | struct htc_target *htc_handle; | 91 | struct htc_target *htc_handle; |
92 | struct hif_usb_tx tx; | 92 | struct hif_usb_tx tx; |
93 | struct urb *reg_in_urb; | ||
94 | struct usb_anchor regout_submitted; | 93 | struct usb_anchor regout_submitted; |
95 | struct usb_anchor rx_submitted; | 94 | struct usb_anchor rx_submitted; |
95 | struct usb_anchor reg_in_submitted; | ||
96 | struct usb_anchor mgmt_submitted; | ||
96 | struct sk_buff *remain_skb; | 97 | struct sk_buff *remain_skb; |
97 | const char *fw_name; | 98 | const char *fw_name; |
98 | int rx_remain_len; | 99 | int rx_remain_len; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ec47be94b74f..48a885575085 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -67,8 +67,11 @@ enum htc_opmode { | |||
67 | }; | 67 | }; |
68 | 68 | ||
69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | 69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) |
70 | #define ATH9K_HTC_AMPDU 1 | 70 | |
71 | #define ATH9K_HTC_AMPDU 1 | ||
71 | #define ATH9K_HTC_NORMAL 2 | 72 | #define ATH9K_HTC_NORMAL 2 |
73 | #define ATH9K_HTC_BEACON 3 | ||
74 | #define ATH9K_HTC_MGMT 4 | ||
72 | 75 | ||
73 | #define ATH9K_HTC_TX_CTSONLY 0x1 | 76 | #define ATH9K_HTC_TX_CTSONLY 0x1 |
74 | #define ATH9K_HTC_TX_RTSCTS 0x2 | 77 | #define ATH9K_HTC_TX_RTSCTS 0x2 |
@@ -82,7 +85,8 @@ struct tx_frame_hdr { | |||
82 | __be32 flags; /* ATH9K_HTC_TX_* */ | 85 | __be32 flags; /* ATH9K_HTC_TX_* */ |
83 | u8 key_type; | 86 | u8 key_type; |
84 | u8 keyix; | 87 | u8 keyix; |
85 | u8 reserved[26]; | 88 | u8 cookie; |
89 | u8 pad; | ||
86 | } __packed; | 90 | } __packed; |
87 | 91 | ||
88 | struct tx_mgmt_hdr { | 92 | struct tx_mgmt_hdr { |
@@ -92,26 +96,16 @@ struct tx_mgmt_hdr { | |||
92 | u8 flags; | 96 | u8 flags; |
93 | u8 key_type; | 97 | u8 key_type; |
94 | u8 keyix; | 98 | u8 keyix; |
95 | u16 reserved; | 99 | u8 cookie; |
100 | u8 pad; | ||
96 | } __packed; | 101 | } __packed; |
97 | 102 | ||
98 | struct tx_beacon_header { | 103 | struct tx_beacon_header { |
99 | u8 len_changed; | ||
100 | u8 vif_index; | 104 | u8 vif_index; |
105 | u8 len_changed; | ||
101 | u16 rev; | 106 | u16 rev; |
102 | } __packed; | 107 | } __packed; |
103 | 108 | ||
104 | struct ath9k_htc_target_hw { | ||
105 | u32 flags; | ||
106 | u32 flags_ext; | ||
107 | u32 ampdu_limit; | ||
108 | u8 ampdu_subframes; | ||
109 | u8 tx_chainmask; | ||
110 | u8 tx_chainmask_legacy; | ||
111 | u8 rtscts_ratecode; | ||
112 | u8 protmode; | ||
113 | } __packed; | ||
114 | |||
115 | struct ath9k_htc_cap_target { | 109 | struct ath9k_htc_cap_target { |
116 | u32 flags; | 110 | u32 flags; |
117 | u32 flags_ext; | 111 | u32 flags_ext; |
@@ -121,21 +115,16 @@ struct ath9k_htc_cap_target { | |||
121 | u8 tx_chainmask_legacy; | 115 | u8 tx_chainmask_legacy; |
122 | u8 rtscts_ratecode; | 116 | u8 rtscts_ratecode; |
123 | u8 protmode; | 117 | u8 protmode; |
118 | u8 pad; | ||
124 | } __packed; | 119 | } __packed; |
125 | 120 | ||
126 | struct ath9k_htc_target_vif { | 121 | struct ath9k_htc_target_vif { |
127 | u8 index; | 122 | u8 index; |
128 | u8 des_bssid[ETH_ALEN]; | 123 | u8 opmode; |
129 | __be32 opmode; | ||
130 | u8 myaddr[ETH_ALEN]; | 124 | u8 myaddr[ETH_ALEN]; |
131 | u8 bssid[ETH_ALEN]; | ||
132 | u32 flags; | ||
133 | u32 flags_ext; | ||
134 | u16 ps_sta; | ||
135 | __be16 rtsthreshold; | ||
136 | u8 ath_cap; | 125 | u8 ath_cap; |
137 | u8 node; | 126 | __be16 rtsthreshold; |
138 | s8 mcast_rate; | 127 | u8 pad; |
139 | } __packed; | 128 | } __packed; |
140 | 129 | ||
141 | #define ATH_HTC_STA_AUTH 0x0001 | 130 | #define ATH_HTC_STA_AUTH 0x0001 |
@@ -143,27 +132,16 @@ struct ath9k_htc_target_vif { | |||
143 | #define ATH_HTC_STA_ERP 0x0004 | 132 | #define ATH_HTC_STA_ERP 0x0004 |
144 | #define ATH_HTC_STA_HT 0x0008 | 133 | #define ATH_HTC_STA_HT 0x0008 |
145 | 134 | ||
146 | /* FIXME: UAPSD variables */ | ||
147 | struct ath9k_htc_target_sta { | 135 | struct ath9k_htc_target_sta { |
148 | u16 associd; | ||
149 | u16 txpower; | ||
150 | u32 ucastkey; | ||
151 | u8 macaddr[ETH_ALEN]; | 136 | u8 macaddr[ETH_ALEN]; |
152 | u8 bssid[ETH_ALEN]; | 137 | u8 bssid[ETH_ALEN]; |
153 | u8 sta_index; | 138 | u8 sta_index; |
154 | u8 vif_index; | 139 | u8 vif_index; |
155 | u8 vif_sta; | ||
156 | __be16 flags; /* ATH_HTC_STA_* */ | ||
157 | u16 htcap; | ||
158 | u8 valid; | ||
159 | u16 capinfo; | ||
160 | struct ath9k_htc_target_hw *hw; | ||
161 | struct ath9k_htc_target_vif *vif; | ||
162 | u16 txseqmgmt; | ||
163 | u8 is_vif_sta; | 140 | u8 is_vif_sta; |
164 | u16 maxampdu; | 141 | __be16 flags; /* ATH_HTC_STA_* */ |
165 | u16 iv16; | 142 | __be16 htcap; |
166 | u32 iv32; | 143 | __be16 maxampdu; |
144 | u8 pad; | ||
167 | } __packed; | 145 | } __packed; |
168 | 146 | ||
169 | struct ath9k_htc_target_aggr { | 147 | struct ath9k_htc_target_aggr { |
@@ -197,12 +175,31 @@ struct ath9k_htc_target_rate { | |||
197 | struct ath9k_htc_rate rates; | 175 | struct ath9k_htc_rate rates; |
198 | }; | 176 | }; |
199 | 177 | ||
200 | struct ath9k_htc_target_stats { | 178 | struct ath9k_htc_target_int_stats { |
201 | __be32 tx_shortretry; | 179 | __be32 rx; |
202 | __be32 tx_longretry; | 180 | __be32 rxorn; |
203 | __be32 tx_xretries; | 181 | __be32 rxeol; |
204 | __be32 ht_txunaggr_xretry; | 182 | __be32 txurn; |
205 | __be32 ht_tx_xretries; | 183 | __be32 txto; |
184 | __be32 cst; | ||
185 | } __packed; | ||
186 | |||
187 | struct ath9k_htc_target_tx_stats { | ||
188 | __be32 xretries; | ||
189 | __be32 fifoerr; | ||
190 | __be32 filtered; | ||
191 | __be32 timer_exp; | ||
192 | __be32 shortretries; | ||
193 | __be32 longretries; | ||
194 | __be32 qnull; | ||
195 | __be32 encap_fail; | ||
196 | __be32 nobuf; | ||
197 | } __packed; | ||
198 | |||
199 | struct ath9k_htc_target_rx_stats { | ||
200 | __be32 nobuf; | ||
201 | __be32 host_send; | ||
202 | __be32 host_done; | ||
206 | } __packed; | 203 | } __packed; |
207 | 204 | ||
208 | #define ATH9K_HTC_MAX_VIF 2 | 205 | #define ATH9K_HTC_MAX_VIF 2 |
@@ -244,6 +241,8 @@ struct ath9k_htc_vif { | |||
244 | u8 index; | 241 | u8 index; |
245 | u16 seq_no; | 242 | u16 seq_no; |
246 | bool beacon_configured; | 243 | bool beacon_configured; |
244 | int bslot; | ||
245 | __le64 tsfadjust; | ||
247 | }; | 246 | }; |
248 | 247 | ||
249 | struct ath9k_vif_iter_data { | 248 | struct ath9k_vif_iter_data { |
@@ -282,23 +281,65 @@ struct ath9k_htc_rx { | |||
282 | spinlock_t rxbuflock; | 281 | spinlock_t rxbuflock; |
283 | }; | 282 | }; |
284 | 283 | ||
284 | #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ | ||
285 | #define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ | ||
286 | #define ATH9K_HTC_TX_RESERVE 10 | ||
287 | #define ATH9K_HTC_TX_TIMEOUT_COUNT 20 | ||
288 | #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) | ||
289 | |||
290 | #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) | ||
291 | #define ATH9K_HTC_OP_TX_DRAIN BIT(1) | ||
292 | |||
293 | struct ath9k_htc_tx { | ||
294 | u8 flags; | ||
295 | int queued_cnt; | ||
296 | struct sk_buff_head mgmt_ep_queue; | ||
297 | struct sk_buff_head cab_ep_queue; | ||
298 | struct sk_buff_head data_be_queue; | ||
299 | struct sk_buff_head data_bk_queue; | ||
300 | struct sk_buff_head data_vi_queue; | ||
301 | struct sk_buff_head data_vo_queue; | ||
302 | struct sk_buff_head tx_failed; | ||
303 | DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); | ||
304 | struct timer_list cleanup_timer; | ||
305 | spinlock_t tx_lock; | ||
306 | }; | ||
307 | |||
285 | struct ath9k_htc_tx_ctl { | 308 | struct ath9k_htc_tx_ctl { |
286 | u8 type; /* ATH9K_HTC_* */ | 309 | u8 type; /* ATH9K_HTC_* */ |
310 | u8 epid; | ||
311 | u8 txok; | ||
312 | u8 sta_idx; | ||
313 | unsigned long timestamp; | ||
287 | }; | 314 | }; |
288 | 315 | ||
316 | static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) | ||
317 | { | ||
318 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
319 | |||
320 | BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) > | ||
321 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE); | ||
322 | return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data; | ||
323 | } | ||
324 | |||
289 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 325 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
290 | 326 | ||
291 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) | 327 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) |
292 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) | 328 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) |
329 | #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ | ||
293 | 330 | ||
294 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) | 331 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) |
295 | 332 | ||
333 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
334 | struct ath_htc_rx_status *rxs); | ||
335 | |||
296 | struct ath_tx_stats { | 336 | struct ath_tx_stats { |
297 | u32 buf_queued; | 337 | u32 buf_queued; |
298 | u32 buf_completed; | 338 | u32 buf_completed; |
299 | u32 skb_queued; | 339 | u32 skb_queued; |
300 | u32 skb_completed; | 340 | u32 skb_success; |
301 | u32 skb_dropped; | 341 | u32 skb_failed; |
342 | u32 cab_queued; | ||
302 | u32 queue_stats[WME_NUM_AC]; | 343 | u32 queue_stats[WME_NUM_AC]; |
303 | }; | 344 | }; |
304 | 345 | ||
@@ -306,25 +347,35 @@ struct ath_rx_stats { | |||
306 | u32 skb_allocated; | 347 | u32 skb_allocated; |
307 | u32 skb_completed; | 348 | u32 skb_completed; |
308 | u32 skb_dropped; | 349 | u32 skb_dropped; |
350 | u32 err_crc; | ||
351 | u32 err_decrypt_crc; | ||
352 | u32 err_mic; | ||
353 | u32 err_pre_delim; | ||
354 | u32 err_post_delim; | ||
355 | u32 err_decrypt_busy; | ||
356 | u32 err_phy; | ||
357 | u32 err_phy_stats[ATH9K_PHYERR_MAX]; | ||
309 | }; | 358 | }; |
310 | 359 | ||
311 | struct ath9k_debug { | 360 | struct ath9k_debug { |
312 | struct dentry *debugfs_phy; | 361 | struct dentry *debugfs_phy; |
313 | struct dentry *debugfs_tgt_stats; | ||
314 | struct dentry *debugfs_xmit; | ||
315 | struct dentry *debugfs_recv; | ||
316 | struct ath_tx_stats tx_stats; | 362 | struct ath_tx_stats tx_stats; |
317 | struct ath_rx_stats rx_stats; | 363 | struct ath_rx_stats rx_stats; |
318 | u32 txrate; | ||
319 | }; | 364 | }; |
320 | 365 | ||
321 | #else | 366 | #else |
322 | 367 | ||
323 | #define TX_STAT_INC(c) do { } while (0) | 368 | #define TX_STAT_INC(c) do { } while (0) |
324 | #define RX_STAT_INC(c) do { } while (0) | 369 | #define RX_STAT_INC(c) do { } while (0) |
370 | #define CAB_STAT_INC do { } while (0) | ||
325 | 371 | ||
326 | #define TX_QSTAT_INC(c) do { } while (0) | 372 | #define TX_QSTAT_INC(c) do { } while (0) |
327 | 373 | ||
374 | static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
375 | struct ath_htc_rx_status *rxs) | ||
376 | { | ||
377 | } | ||
378 | |||
328 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | 379 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ |
329 | 380 | ||
330 | #define ATH_LED_PIN_DEF 1 | 381 | #define ATH_LED_PIN_DEF 1 |
@@ -351,10 +402,21 @@ struct ath_led { | |||
351 | int brightness; | 402 | int brightness; |
352 | }; | 403 | }; |
353 | 404 | ||
405 | #define BSTUCK_THRESHOLD 10 | ||
406 | |||
407 | /* | ||
408 | * Adjust these when the max. no of beaconing interfaces is | ||
409 | * increased. | ||
410 | */ | ||
411 | #define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ | ||
412 | #define MIN_SWBA_RESPONSE 10 /* in TUs */ | ||
413 | |||
354 | struct htc_beacon_config { | 414 | struct htc_beacon_config { |
415 | struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; | ||
355 | u16 beacon_interval; | 416 | u16 beacon_interval; |
356 | u16 dtim_period; | 417 | u16 dtim_period; |
357 | u16 bmiss_timeout; | 418 | u16 bmiss_timeout; |
419 | u32 bmiss_cnt; | ||
358 | }; | 420 | }; |
359 | 421 | ||
360 | struct ath_btcoex { | 422 | struct ath_btcoex { |
@@ -388,6 +450,9 @@ struct ath9k_htc_priv { | |||
388 | struct htc_target *htc; | 450 | struct htc_target *htc; |
389 | struct wmi *wmi; | 451 | struct wmi *wmi; |
390 | 452 | ||
453 | u16 fw_version_major; | ||
454 | u16 fw_version_minor; | ||
455 | |||
391 | enum htc_endpoint_id wmi_cmd_ep; | 456 | enum htc_endpoint_id wmi_cmd_ep; |
392 | enum htc_endpoint_id beacon_ep; | 457 | enum htc_endpoint_id beacon_ep; |
393 | enum htc_endpoint_id cab_ep; | 458 | enum htc_endpoint_id cab_ep; |
@@ -411,27 +476,23 @@ struct ath9k_htc_priv { | |||
411 | u16 txpowlimit; | 476 | u16 txpowlimit; |
412 | u16 nvifs; | 477 | u16 nvifs; |
413 | u16 nstations; | 478 | u16 nstations; |
414 | u32 bmiss_cnt; | ||
415 | bool rearm_ani; | 479 | bool rearm_ani; |
416 | bool reconfig_beacon; | 480 | bool reconfig_beacon; |
481 | unsigned int rxfilter; | ||
417 | 482 | ||
418 | struct ath9k_hw_cal_data caldata; | 483 | struct ath9k_hw_cal_data caldata; |
484 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
419 | 485 | ||
420 | spinlock_t beacon_lock; | 486 | spinlock_t beacon_lock; |
487 | struct htc_beacon_config cur_beacon_conf; | ||
421 | 488 | ||
422 | bool tx_queues_stop; | 489 | struct ath9k_htc_rx rx; |
423 | spinlock_t tx_lock; | 490 | struct ath9k_htc_tx tx; |
424 | 491 | ||
425 | struct ieee80211_vif *vif; | ||
426 | struct htc_beacon_config cur_beacon_conf; | ||
427 | unsigned int rxfilter; | ||
428 | struct tasklet_struct swba_tasklet; | 492 | struct tasklet_struct swba_tasklet; |
429 | struct tasklet_struct rx_tasklet; | 493 | struct tasklet_struct rx_tasklet; |
430 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
431 | struct ath9k_htc_rx rx; | ||
432 | struct tasklet_struct tx_tasklet; | ||
433 | struct sk_buff_head tx_queue; | ||
434 | struct delayed_work ani_work; | 494 | struct delayed_work ani_work; |
495 | struct tasklet_struct tx_failed_tasklet; | ||
435 | struct work_struct ps_work; | 496 | struct work_struct ps_work; |
436 | struct work_struct fatal_work; | 497 | struct work_struct fatal_work; |
437 | 498 | ||
@@ -470,11 +531,18 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
470 | 531 | ||
471 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); | 532 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); |
472 | 533 | ||
534 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | ||
535 | struct ieee80211_vif *vif); | ||
536 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
537 | struct ieee80211_vif *vif); | ||
538 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
539 | struct ieee80211_vif *vif); | ||
473 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); | 540 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); |
474 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | 541 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, |
475 | struct ieee80211_vif *vif); | 542 | struct ieee80211_vif *vif); |
476 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); | 543 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); |
477 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); | 544 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, |
545 | struct wmi_event_swba *swba); | ||
478 | 546 | ||
479 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, | 547 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, |
480 | enum htc_endpoint_id ep_id); | 548 | enum htc_endpoint_id ep_id); |
@@ -491,14 +559,23 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); | |||
491 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); | 559 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); |
492 | 560 | ||
493 | int ath9k_tx_init(struct ath9k_htc_priv *priv); | 561 | int ath9k_tx_init(struct ath9k_htc_priv *priv); |
494 | void ath9k_tx_tasklet(unsigned long data); | 562 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, |
495 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); | 563 | struct sk_buff *skb, u8 slot, bool is_cab); |
496 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); | 564 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); |
497 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); | 565 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); |
498 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); | 566 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); |
499 | int get_hw_qnum(u16 queue, int *hwq_map); | 567 | int get_hw_qnum(u16 queue, int *hwq_map); |
500 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 568 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
501 | struct ath9k_tx_queue_info *qinfo); | 569 | struct ath9k_tx_queue_info *qinfo); |
570 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); | ||
571 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); | ||
572 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); | ||
573 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); | ||
574 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); | ||
575 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); | ||
576 | void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); | ||
577 | void ath9k_tx_failed_tasklet(unsigned long data); | ||
578 | void ath9k_htc_tx_cleanup_timer(unsigned long data); | ||
502 | 579 | ||
503 | int ath9k_rx_init(struct ath9k_htc_priv *priv); | 580 | int ath9k_rx_init(struct ath9k_htc_priv *priv); |
504 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); | 581 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); |
@@ -528,15 +605,9 @@ void ath9k_htc_suspend(struct htc_target *htc_handle); | |||
528 | int ath9k_htc_resume(struct htc_target *htc_handle); | 605 | int ath9k_htc_resume(struct htc_target *htc_handle); |
529 | #endif | 606 | #endif |
530 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 607 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
531 | int ath9k_htc_debug_create_root(void); | ||
532 | void ath9k_htc_debug_remove_root(void); | ||
533 | int ath9k_htc_init_debug(struct ath_hw *ah); | 608 | int ath9k_htc_init_debug(struct ath_hw *ah); |
534 | void ath9k_htc_exit_debug(struct ath_hw *ah); | ||
535 | #else | 609 | #else |
536 | static inline int ath9k_htc_debug_create_root(void) { return 0; }; | ||
537 | static inline void ath9k_htc_debug_remove_root(void) {}; | ||
538 | static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; | 610 | static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; |
539 | static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {}; | ||
540 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | 611 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ |
541 | 612 | ||
542 | #endif /* HTC_H */ | 613 | #endif /* HTC_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8f56158e5887..a157107b3f3b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -18,6 +18,50 @@ | |||
18 | 18 | ||
19 | #define FUDGE 2 | 19 | #define FUDGE 2 |
20 | 20 | ||
21 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | ||
22 | { | ||
23 | struct ath_hw *ah = priv->ah; | ||
24 | struct ath9k_tx_queue_info qi, qi_be; | ||
25 | |||
26 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
27 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | ||
28 | |||
29 | ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); | ||
30 | |||
31 | if (priv->ah->opmode == NL80211_IFTYPE_AP) { | ||
32 | qi.tqi_aifs = 1; | ||
33 | qi.tqi_cwmin = 0; | ||
34 | qi.tqi_cwmax = 0; | ||
35 | } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { | ||
36 | int qnum = priv->hwq_map[WME_AC_BE]; | ||
37 | |||
38 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | ||
39 | |||
40 | qi.tqi_aifs = qi_be.tqi_aifs; | ||
41 | |||
42 | /* | ||
43 | * For WIFI Beacon Distribution | ||
44 | * Long slot time : 2x cwmin | ||
45 | * Short slot time : 4x cwmin | ||
46 | */ | ||
47 | if (ah->slottime == ATH9K_SLOT_TIME_20) | ||
48 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
49 | else | ||
50 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
51 | |||
52 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
53 | |||
54 | } | ||
55 | |||
56 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | ||
57 | ath_err(ath9k_hw_common(ah), | ||
58 | "Unable to update beacon queue %u!\n", priv->beaconq); | ||
59 | } else { | ||
60 | ath9k_hw_resettxqueue(ah, priv->beaconq); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | |||
21 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | 65 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, |
22 | struct htc_beacon_config *bss_conf) | 66 | struct htc_beacon_config *bss_conf) |
23 | { | 67 | { |
@@ -154,6 +198,15 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
154 | intval /= ATH9K_HTC_MAX_BCN_VIF; | 198 | intval /= ATH9K_HTC_MAX_BCN_VIF; |
155 | nexttbtt = intval; | 199 | nexttbtt = intval; |
156 | 200 | ||
201 | /* | ||
202 | * To reduce beacon misses under heavy TX load, | ||
203 | * set the beacon response time to a larger value. | ||
204 | */ | ||
205 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
206 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
207 | else | ||
208 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
209 | |||
157 | if (priv->op_flags & OP_TSF_RESET) { | 210 | if (priv->op_flags & OP_TSF_RESET) { |
158 | ath9k_hw_reset_tsf(priv->ah); | 211 | ath9k_hw_reset_tsf(priv->ah); |
159 | priv->op_flags &= ~OP_TSF_RESET; | 212 | priv->op_flags &= ~OP_TSF_RESET; |
@@ -172,12 +225,16 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
172 | imask |= ATH9K_INT_SWBA; | 225 | imask |= ATH9K_INT_SWBA; |
173 | 226 | ||
174 | ath_dbg(common, ATH_DBG_CONFIG, | 227 | ath_dbg(common, ATH_DBG_CONFIG, |
175 | "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", | 228 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " |
176 | bss_conf->beacon_interval, nexttbtt, imask); | 229 | "imask: 0x%x\n", |
230 | bss_conf->beacon_interval, nexttbtt, | ||
231 | priv->ah->config.sw_beacon_response_time, imask); | ||
232 | |||
233 | ath9k_htc_beaconq_config(priv); | ||
177 | 234 | ||
178 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 235 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
179 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 236 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
180 | priv->bmiss_cnt = 0; | 237 | priv->cur_beacon_conf.bmiss_cnt = 0; |
181 | htc_imask = cpu_to_be32(imask); | 238 | htc_imask = cpu_to_be32(imask); |
182 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 239 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
183 | } | 240 | } |
@@ -205,16 +262,26 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
205 | nexttbtt += intval; | 262 | nexttbtt += intval; |
206 | } while (nexttbtt < tsftu); | 263 | } while (nexttbtt < tsftu); |
207 | 264 | ||
265 | /* | ||
266 | * Only one IBSS interfce is allowed. | ||
267 | */ | ||
268 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
269 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
270 | else | ||
271 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
272 | |||
208 | if (priv->op_flags & OP_ENABLE_BEACON) | 273 | if (priv->op_flags & OP_ENABLE_BEACON) |
209 | imask |= ATH9K_INT_SWBA; | 274 | imask |= ATH9K_INT_SWBA; |
210 | 275 | ||
211 | ath_dbg(common, ATH_DBG_CONFIG, | 276 | ath_dbg(common, ATH_DBG_CONFIG, |
212 | "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", | 277 | "IBSS Beacon config, intval: %d, nexttbtt: %u, " |
213 | bss_conf->beacon_interval, nexttbtt, imask); | 278 | "resp_time: %d, imask: 0x%x\n", |
279 | bss_conf->beacon_interval, nexttbtt, | ||
280 | priv->ah->config.sw_beacon_response_time, imask); | ||
214 | 281 | ||
215 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 282 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
216 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 283 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
217 | priv->bmiss_cnt = 0; | 284 | priv->cur_beacon_conf.bmiss_cnt = 0; |
218 | htc_imask = cpu_to_be32(imask); | 285 | htc_imask = cpu_to_be32(imask); |
219 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 286 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
220 | } | 287 | } |
@@ -225,38 +292,101 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | |||
225 | dev_kfree_skb_any(skb); | 292 | dev_kfree_skb_any(skb); |
226 | } | 293 | } |
227 | 294 | ||
228 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | 295 | static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, |
296 | int slot) | ||
297 | { | ||
298 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
299 | struct ieee80211_vif *vif; | ||
300 | struct sk_buff *skb; | ||
301 | struct ieee80211_hdr *hdr; | ||
302 | int padpos, padsize, ret, tx_slot; | ||
303 | |||
304 | spin_lock_bh(&priv->beacon_lock); | ||
305 | |||
306 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
307 | |||
308 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
309 | |||
310 | while(skb) { | ||
311 | hdr = (struct ieee80211_hdr *) skb->data; | ||
312 | |||
313 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
314 | padsize = padpos & 3; | ||
315 | if (padsize && skb->len > padpos) { | ||
316 | if (skb_headroom(skb) < padsize) { | ||
317 | dev_kfree_skb_any(skb); | ||
318 | goto next; | ||
319 | } | ||
320 | skb_push(skb, padsize); | ||
321 | memmove(skb->data, skb->data + padsize, padpos); | ||
322 | } | ||
323 | |||
324 | tx_slot = ath9k_htc_tx_get_slot(priv); | ||
325 | if (tx_slot < 0) { | ||
326 | ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); | ||
327 | dev_kfree_skb_any(skb); | ||
328 | goto next; | ||
329 | } | ||
330 | |||
331 | ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); | ||
332 | if (ret != 0) { | ||
333 | ath9k_htc_tx_clear_slot(priv, tx_slot); | ||
334 | dev_kfree_skb_any(skb); | ||
335 | |||
336 | ath_dbg(common, ATH_DBG_XMIT, | ||
337 | "Failed to send CAB frame\n"); | ||
338 | } else { | ||
339 | spin_lock_bh(&priv->tx.tx_lock); | ||
340 | priv->tx.queued_cnt++; | ||
341 | spin_unlock_bh(&priv->tx.tx_lock); | ||
342 | } | ||
343 | next: | ||
344 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
345 | } | ||
346 | |||
347 | spin_unlock_bh(&priv->beacon_lock); | ||
348 | } | ||
349 | |||
350 | static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | ||
351 | int slot) | ||
229 | { | 352 | { |
230 | struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; | 353 | struct ath_common *common = ath9k_hw_common(priv->ah); |
354 | struct ieee80211_vif *vif; | ||
355 | struct ath9k_htc_vif *avp; | ||
231 | struct tx_beacon_header beacon_hdr; | 356 | struct tx_beacon_header beacon_hdr; |
232 | struct ath9k_htc_tx_ctl tx_ctl; | 357 | struct ath9k_htc_tx_ctl *tx_ctl; |
233 | struct ieee80211_tx_info *info; | 358 | struct ieee80211_tx_info *info; |
359 | struct ieee80211_mgmt *mgmt; | ||
234 | struct sk_buff *beacon; | 360 | struct sk_buff *beacon; |
235 | u8 *tx_fhdr; | 361 | u8 *tx_fhdr; |
362 | int ret; | ||
236 | 363 | ||
237 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); | 364 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); |
238 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | ||
239 | |||
240 | /* FIXME: Handle BMISS */ | ||
241 | if (beacon_pending != 0) { | ||
242 | priv->bmiss_cnt++; | ||
243 | return; | ||
244 | } | ||
245 | 365 | ||
246 | spin_lock_bh(&priv->beacon_lock); | 366 | spin_lock_bh(&priv->beacon_lock); |
247 | 367 | ||
368 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
369 | avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
370 | |||
248 | if (unlikely(priv->op_flags & OP_SCANNING)) { | 371 | if (unlikely(priv->op_flags & OP_SCANNING)) { |
249 | spin_unlock_bh(&priv->beacon_lock); | 372 | spin_unlock_bh(&priv->beacon_lock); |
250 | return; | 373 | return; |
251 | } | 374 | } |
252 | 375 | ||
253 | /* Get a new beacon */ | 376 | /* Get a new beacon */ |
254 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 377 | beacon = ieee80211_beacon_get(priv->hw, vif); |
255 | if (!beacon) { | 378 | if (!beacon) { |
256 | spin_unlock_bh(&priv->beacon_lock); | 379 | spin_unlock_bh(&priv->beacon_lock); |
257 | return; | 380 | return; |
258 | } | 381 | } |
259 | 382 | ||
383 | /* | ||
384 | * Update the TSF adjust value here, the HW will | ||
385 | * add this value for every beacon. | ||
386 | */ | ||
387 | mgmt = (struct ieee80211_mgmt *)beacon->data; | ||
388 | mgmt->u.beacon.timestamp = avp->tsfadjust; | ||
389 | |||
260 | info = IEEE80211_SKB_CB(beacon); | 390 | info = IEEE80211_SKB_CB(beacon); |
261 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 391 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
262 | struct ieee80211_hdr *hdr = | 392 | struct ieee80211_hdr *hdr = |
@@ -266,45 +396,149 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
266 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); | 396 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); |
267 | } | 397 | } |
268 | 398 | ||
269 | tx_ctl.type = ATH9K_HTC_NORMAL; | 399 | tx_ctl = HTC_SKB_CB(beacon); |
400 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
401 | |||
402 | tx_ctl->type = ATH9K_HTC_BEACON; | ||
403 | tx_ctl->epid = priv->beacon_ep; | ||
404 | |||
270 | beacon_hdr.vif_index = avp->index; | 405 | beacon_hdr.vif_index = avp->index; |
271 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); | 406 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); |
272 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); | 407 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); |
273 | 408 | ||
274 | htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); | 409 | ret = htc_send(priv->htc, beacon); |
410 | if (ret != 0) { | ||
411 | if (ret == -ENOMEM) { | ||
412 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
413 | "Failed to send beacon, no free TX buffer\n"); | ||
414 | } | ||
415 | dev_kfree_skb_any(beacon); | ||
416 | } | ||
417 | |||
418 | spin_unlock_bh(&priv->beacon_lock); | ||
419 | } | ||
420 | |||
421 | static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, | ||
422 | struct wmi_event_swba *swba) | ||
423 | { | ||
424 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
425 | u64 tsf; | ||
426 | u32 tsftu; | ||
427 | u16 intval; | ||
428 | int slot; | ||
429 | |||
430 | intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; | ||
275 | 431 | ||
432 | tsf = be64_to_cpu(swba->tsf); | ||
433 | tsftu = TSF_TO_TU(tsf >> 32, tsf); | ||
434 | slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; | ||
435 | slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; | ||
436 | |||
437 | ath_dbg(common, ATH_DBG_BEACON, | ||
438 | "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", | ||
439 | slot, tsf, tsftu, intval); | ||
440 | |||
441 | return slot; | ||
442 | } | ||
443 | |||
444 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, | ||
445 | struct wmi_event_swba *swba) | ||
446 | { | ||
447 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
448 | int slot; | ||
449 | |||
450 | if (swba->beacon_pending != 0) { | ||
451 | priv->cur_beacon_conf.bmiss_cnt++; | ||
452 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { | ||
453 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
454 | "Beacon stuck, HW reset\n"); | ||
455 | ieee80211_queue_work(priv->hw, | ||
456 | &priv->fatal_work); | ||
457 | } | ||
458 | return; | ||
459 | } | ||
460 | |||
461 | if (priv->cur_beacon_conf.bmiss_cnt) { | ||
462 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
463 | "Resuming beacon xmit after %u misses\n", | ||
464 | priv->cur_beacon_conf.bmiss_cnt); | ||
465 | priv->cur_beacon_conf.bmiss_cnt = 0; | ||
466 | } | ||
467 | |||
468 | slot = ath9k_htc_choose_bslot(priv, swba); | ||
469 | spin_lock_bh(&priv->beacon_lock); | ||
470 | if (priv->cur_beacon_conf.bslot[slot] == NULL) { | ||
471 | spin_unlock_bh(&priv->beacon_lock); | ||
472 | return; | ||
473 | } | ||
276 | spin_unlock_bh(&priv->beacon_lock); | 474 | spin_unlock_bh(&priv->beacon_lock); |
475 | |||
476 | ath9k_htc_send_buffered(priv, slot); | ||
477 | ath9k_htc_send_beacon(priv, slot); | ||
277 | } | 478 | } |
278 | 479 | ||
279 | /* Currently, only for IBSS */ | 480 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, |
280 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | 481 | struct ieee80211_vif *vif) |
281 | { | 482 | { |
282 | struct ath_hw *ah = priv->ah; | 483 | struct ath_common *common = ath9k_hw_common(priv->ah); |
283 | struct ath9k_tx_queue_info qi, qi_be; | 484 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; |
284 | int qnum = priv->hwq_map[WME_AC_BE]; | 485 | int i = 0; |
285 | 486 | ||
286 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | 487 | spin_lock_bh(&priv->beacon_lock); |
287 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | 488 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { |
489 | if (priv->cur_beacon_conf.bslot[i] == NULL) { | ||
490 | avp->bslot = i; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; | ||
496 | spin_unlock_bh(&priv->beacon_lock); | ||
497 | |||
498 | ath_dbg(common, ATH_DBG_CONFIG, | ||
499 | "Added interface at beacon slot: %d\n", avp->bslot); | ||
500 | } | ||
501 | |||
502 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
503 | struct ieee80211_vif *vif) | ||
504 | { | ||
505 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
506 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
507 | |||
508 | spin_lock_bh(&priv->beacon_lock); | ||
509 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; | ||
510 | spin_unlock_bh(&priv->beacon_lock); | ||
511 | |||
512 | ath_dbg(common, ATH_DBG_CONFIG, | ||
513 | "Removed interface at beacon slot: %d\n", avp->bslot); | ||
514 | } | ||
288 | 515 | ||
289 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | 516 | /* |
517 | * Calculate the TSF adjustment value for all slots | ||
518 | * other than zero. | ||
519 | */ | ||
520 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
521 | struct ieee80211_vif *vif) | ||
522 | { | ||
523 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
524 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
525 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | ||
526 | u64 tsfadjust; | ||
527 | |||
528 | if (avp->bslot == 0) | ||
529 | return; | ||
290 | 530 | ||
291 | qi.tqi_aifs = qi_be.tqi_aifs; | 531 | /* |
292 | /* For WIFI Beacon Distribution | 532 | * The beacon interval cannot be different for multi-AP mode, |
293 | * Long slot time : 2x cwmin | 533 | * and we reach here only for VIF slots greater than zero, |
294 | * Short slot time : 4x cwmin | 534 | * so beacon_interval is guaranteed to be set in cur_conf. |
295 | */ | 535 | */ |
296 | if (ah->slottime == ATH9K_SLOT_TIME_20) | 536 | tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; |
297 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | 537 | avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); |
298 | else | ||
299 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
300 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
301 | 538 | ||
302 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | 539 | ath_dbg(common, ATH_DBG_CONFIG, |
303 | ath_err(ath9k_hw_common(ah), | 540 | "tsfadjust is: %llu for bslot: %d\n", |
304 | "Unable to update beacon queue %u!\n", qnum); | 541 | (unsigned long long)tsfadjust, avp->bslot); |
305 | } else { | ||
306 | ath9k_hw_resettxqueue(ah, priv->beaconq); | ||
307 | } | ||
308 | } | 542 | } |
309 | 543 | ||
310 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 544 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c new file mode 100644 index 000000000000..eca777497fe5 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications 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 "htc.h" | ||
18 | |||
19 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
20 | { | ||
21 | file->private_data = inode->i_private; | ||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | ||
26 | size_t count, loff_t *ppos) | ||
27 | { | ||
28 | struct ath9k_htc_priv *priv = file->private_data; | ||
29 | struct ath9k_htc_target_int_stats cmd_rsp; | ||
30 | char buf[512]; | ||
31 | unsigned int len = 0; | ||
32 | int ret = 0; | ||
33 | |||
34 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
35 | |||
36 | WMI_CMD(WMI_INT_STATS_CMDID); | ||
37 | if (ret) | ||
38 | return -EINVAL; | ||
39 | |||
40 | len += snprintf(buf + len, sizeof(buf) - len, | ||
41 | "%20s : %10u\n", "RX", | ||
42 | be32_to_cpu(cmd_rsp.rx)); | ||
43 | |||
44 | len += snprintf(buf + len, sizeof(buf) - len, | ||
45 | "%20s : %10u\n", "RXORN", | ||
46 | be32_to_cpu(cmd_rsp.rxorn)); | ||
47 | |||
48 | len += snprintf(buf + len, sizeof(buf) - len, | ||
49 | "%20s : %10u\n", "RXEOL", | ||
50 | be32_to_cpu(cmd_rsp.rxeol)); | ||
51 | |||
52 | len += snprintf(buf + len, sizeof(buf) - len, | ||
53 | "%20s : %10u\n", "TXURN", | ||
54 | be32_to_cpu(cmd_rsp.txurn)); | ||
55 | |||
56 | len += snprintf(buf + len, sizeof(buf) - len, | ||
57 | "%20s : %10u\n", "TXTO", | ||
58 | be32_to_cpu(cmd_rsp.txto)); | ||
59 | |||
60 | len += snprintf(buf + len, sizeof(buf) - len, | ||
61 | "%20s : %10u\n", "CST", | ||
62 | be32_to_cpu(cmd_rsp.cst)); | ||
63 | |||
64 | if (len > sizeof(buf)) | ||
65 | len = sizeof(buf); | ||
66 | |||
67 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
68 | } | ||
69 | |||
70 | static const struct file_operations fops_tgt_int_stats = { | ||
71 | .read = read_file_tgt_int_stats, | ||
72 | .open = ath9k_debugfs_open, | ||
73 | .owner = THIS_MODULE, | ||
74 | .llseek = default_llseek, | ||
75 | }; | ||
76 | |||
77 | static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | ||
78 | size_t count, loff_t *ppos) | ||
79 | { | ||
80 | struct ath9k_htc_priv *priv = file->private_data; | ||
81 | struct ath9k_htc_target_tx_stats cmd_rsp; | ||
82 | char buf[512]; | ||
83 | unsigned int len = 0; | ||
84 | int ret = 0; | ||
85 | |||
86 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
87 | |||
88 | WMI_CMD(WMI_TX_STATS_CMDID); | ||
89 | if (ret) | ||
90 | return -EINVAL; | ||
91 | |||
92 | len += snprintf(buf + len, sizeof(buf) - len, | ||
93 | "%20s : %10u\n", "Xretries", | ||
94 | be32_to_cpu(cmd_rsp.xretries)); | ||
95 | |||
96 | len += snprintf(buf + len, sizeof(buf) - len, | ||
97 | "%20s : %10u\n", "FifoErr", | ||
98 | be32_to_cpu(cmd_rsp.fifoerr)); | ||
99 | |||
100 | len += snprintf(buf + len, sizeof(buf) - len, | ||
101 | "%20s : %10u\n", "Filtered", | ||
102 | be32_to_cpu(cmd_rsp.filtered)); | ||
103 | |||
104 | len += snprintf(buf + len, sizeof(buf) - len, | ||
105 | "%20s : %10u\n", "TimerExp", | ||
106 | be32_to_cpu(cmd_rsp.timer_exp)); | ||
107 | |||
108 | len += snprintf(buf + len, sizeof(buf) - len, | ||
109 | "%20s : %10u\n", "ShortRetries", | ||
110 | be32_to_cpu(cmd_rsp.shortretries)); | ||
111 | |||
112 | len += snprintf(buf + len, sizeof(buf) - len, | ||
113 | "%20s : %10u\n", "LongRetries", | ||
114 | be32_to_cpu(cmd_rsp.longretries)); | ||
115 | |||
116 | len += snprintf(buf + len, sizeof(buf) - len, | ||
117 | "%20s : %10u\n", "QueueNull", | ||
118 | be32_to_cpu(cmd_rsp.qnull)); | ||
119 | |||
120 | len += snprintf(buf + len, sizeof(buf) - len, | ||
121 | "%20s : %10u\n", "EncapFail", | ||
122 | be32_to_cpu(cmd_rsp.encap_fail)); | ||
123 | |||
124 | len += snprintf(buf + len, sizeof(buf) - len, | ||
125 | "%20s : %10u\n", "NoBuf", | ||
126 | be32_to_cpu(cmd_rsp.nobuf)); | ||
127 | |||
128 | if (len > sizeof(buf)) | ||
129 | len = sizeof(buf); | ||
130 | |||
131 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
132 | } | ||
133 | |||
134 | static const struct file_operations fops_tgt_tx_stats = { | ||
135 | .read = read_file_tgt_tx_stats, | ||
136 | .open = ath9k_debugfs_open, | ||
137 | .owner = THIS_MODULE, | ||
138 | .llseek = default_llseek, | ||
139 | }; | ||
140 | |||
141 | static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | ||
142 | size_t count, loff_t *ppos) | ||
143 | { | ||
144 | struct ath9k_htc_priv *priv = file->private_data; | ||
145 | struct ath9k_htc_target_rx_stats cmd_rsp; | ||
146 | char buf[512]; | ||
147 | unsigned int len = 0; | ||
148 | int ret = 0; | ||
149 | |||
150 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
151 | |||
152 | WMI_CMD(WMI_RX_STATS_CMDID); | ||
153 | if (ret) | ||
154 | return -EINVAL; | ||
155 | |||
156 | len += snprintf(buf + len, sizeof(buf) - len, | ||
157 | "%20s : %10u\n", "NoBuf", | ||
158 | be32_to_cpu(cmd_rsp.nobuf)); | ||
159 | |||
160 | len += snprintf(buf + len, sizeof(buf) - len, | ||
161 | "%20s : %10u\n", "HostSend", | ||
162 | be32_to_cpu(cmd_rsp.host_send)); | ||
163 | |||
164 | len += snprintf(buf + len, sizeof(buf) - len, | ||
165 | "%20s : %10u\n", "HostDone", | ||
166 | be32_to_cpu(cmd_rsp.host_done)); | ||
167 | |||
168 | if (len > sizeof(buf)) | ||
169 | len = sizeof(buf); | ||
170 | |||
171 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
172 | } | ||
173 | |||
174 | static const struct file_operations fops_tgt_rx_stats = { | ||
175 | .read = read_file_tgt_rx_stats, | ||
176 | .open = ath9k_debugfs_open, | ||
177 | .owner = THIS_MODULE, | ||
178 | .llseek = default_llseek, | ||
179 | }; | ||
180 | |||
181 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
182 | size_t count, loff_t *ppos) | ||
183 | { | ||
184 | struct ath9k_htc_priv *priv = file->private_data; | ||
185 | char buf[512]; | ||
186 | unsigned int len = 0; | ||
187 | |||
188 | len += snprintf(buf + len, sizeof(buf) - len, | ||
189 | "%20s : %10u\n", "Buffers queued", | ||
190 | priv->debug.tx_stats.buf_queued); | ||
191 | len += snprintf(buf + len, sizeof(buf) - len, | ||
192 | "%20s : %10u\n", "Buffers completed", | ||
193 | priv->debug.tx_stats.buf_completed); | ||
194 | len += snprintf(buf + len, sizeof(buf) - len, | ||
195 | "%20s : %10u\n", "SKBs queued", | ||
196 | priv->debug.tx_stats.skb_queued); | ||
197 | len += snprintf(buf + len, sizeof(buf) - len, | ||
198 | "%20s : %10u\n", "SKBs success", | ||
199 | priv->debug.tx_stats.skb_success); | ||
200 | len += snprintf(buf + len, sizeof(buf) - len, | ||
201 | "%20s : %10u\n", "SKBs failed", | ||
202 | priv->debug.tx_stats.skb_failed); | ||
203 | len += snprintf(buf + len, sizeof(buf) - len, | ||
204 | "%20s : %10u\n", "CAB queued", | ||
205 | priv->debug.tx_stats.cab_queued); | ||
206 | |||
207 | len += snprintf(buf + len, sizeof(buf) - len, | ||
208 | "%20s : %10u\n", "BE queued", | ||
209 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
210 | len += snprintf(buf + len, sizeof(buf) - len, | ||
211 | "%20s : %10u\n", "BK queued", | ||
212 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
213 | len += snprintf(buf + len, sizeof(buf) - len, | ||
214 | "%20s : %10u\n", "VI queued", | ||
215 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
216 | len += snprintf(buf + len, sizeof(buf) - len, | ||
217 | "%20s : %10u\n", "VO queued", | ||
218 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
219 | |||
220 | if (len > sizeof(buf)) | ||
221 | len = sizeof(buf); | ||
222 | |||
223 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
224 | } | ||
225 | |||
226 | static const struct file_operations fops_xmit = { | ||
227 | .read = read_file_xmit, | ||
228 | .open = ath9k_debugfs_open, | ||
229 | .owner = THIS_MODULE, | ||
230 | .llseek = default_llseek, | ||
231 | }; | ||
232 | |||
233 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
234 | struct ath_htc_rx_status *rxs) | ||
235 | { | ||
236 | #define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ | ||
237 | |||
238 | if (rxs->rs_status & ATH9K_RXERR_CRC) | ||
239 | priv->debug.rx_stats.err_crc++; | ||
240 | if (rxs->rs_status & ATH9K_RXERR_DECRYPT) | ||
241 | priv->debug.rx_stats.err_decrypt_crc++; | ||
242 | if (rxs->rs_status & ATH9K_RXERR_MIC) | ||
243 | priv->debug.rx_stats.err_mic++; | ||
244 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE) | ||
245 | priv->debug.rx_stats.err_pre_delim++; | ||
246 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST) | ||
247 | priv->debug.rx_stats.err_post_delim++; | ||
248 | if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY) | ||
249 | priv->debug.rx_stats.err_decrypt_busy++; | ||
250 | |||
251 | if (rxs->rs_status & ATH9K_RXERR_PHY) { | ||
252 | priv->debug.rx_stats.err_phy++; | ||
253 | if (rxs->rs_phyerr < ATH9K_PHYERR_MAX) | ||
254 | RX_PHY_ERR_INC(rxs->rs_phyerr); | ||
255 | } | ||
256 | |||
257 | #undef RX_PHY_ERR_INC | ||
258 | } | ||
259 | |||
260 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
261 | size_t count, loff_t *ppos) | ||
262 | { | ||
263 | #define PHY_ERR(s, p) \ | ||
264 | len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ | ||
265 | priv->debug.rx_stats.err_phy_stats[p]); | ||
266 | |||
267 | struct ath9k_htc_priv *priv = file->private_data; | ||
268 | char *buf; | ||
269 | unsigned int len = 0, size = 1500; | ||
270 | ssize_t retval = 0; | ||
271 | |||
272 | buf = kzalloc(size, GFP_KERNEL); | ||
273 | if (buf == NULL) | ||
274 | return -ENOMEM; | ||
275 | |||
276 | len += snprintf(buf + len, size - len, | ||
277 | "%20s : %10u\n", "SKBs allocated", | ||
278 | priv->debug.rx_stats.skb_allocated); | ||
279 | len += snprintf(buf + len, size - len, | ||
280 | "%20s : %10u\n", "SKBs completed", | ||
281 | priv->debug.rx_stats.skb_completed); | ||
282 | len += snprintf(buf + len, size - len, | ||
283 | "%20s : %10u\n", "SKBs Dropped", | ||
284 | priv->debug.rx_stats.skb_dropped); | ||
285 | |||
286 | len += snprintf(buf + len, size - len, | ||
287 | "%20s : %10u\n", "CRC ERR", | ||
288 | priv->debug.rx_stats.err_crc); | ||
289 | len += snprintf(buf + len, size - len, | ||
290 | "%20s : %10u\n", "DECRYPT CRC ERR", | ||
291 | priv->debug.rx_stats.err_decrypt_crc); | ||
292 | len += snprintf(buf + len, size - len, | ||
293 | "%20s : %10u\n", "MIC ERR", | ||
294 | priv->debug.rx_stats.err_mic); | ||
295 | len += snprintf(buf + len, size - len, | ||
296 | "%20s : %10u\n", "PRE-DELIM CRC ERR", | ||
297 | priv->debug.rx_stats.err_pre_delim); | ||
298 | len += snprintf(buf + len, size - len, | ||
299 | "%20s : %10u\n", "POST-DELIM CRC ERR", | ||
300 | priv->debug.rx_stats.err_post_delim); | ||
301 | len += snprintf(buf + len, size - len, | ||
302 | "%20s : %10u\n", "DECRYPT BUSY ERR", | ||
303 | priv->debug.rx_stats.err_decrypt_busy); | ||
304 | len += snprintf(buf + len, size - len, | ||
305 | "%20s : %10u\n", "TOTAL PHY ERR", | ||
306 | priv->debug.rx_stats.err_phy); | ||
307 | |||
308 | |||
309 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | ||
310 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | ||
311 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | ||
312 | PHY_ERR("RATE", ATH9K_PHYERR_RATE); | ||
313 | PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); | ||
314 | PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); | ||
315 | PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); | ||
316 | PHY_ERR("TOR", ATH9K_PHYERR_TOR); | ||
317 | PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); | ||
318 | PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
319 | PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
320 | PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
321 | PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
322 | PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); | ||
323 | PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); | ||
324 | PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
325 | PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); | ||
326 | PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
327 | PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
328 | PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); | ||
329 | PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); | ||
330 | PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
331 | PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); | ||
332 | PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); | ||
333 | PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
334 | PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
335 | |||
336 | if (len > size) | ||
337 | len = size; | ||
338 | |||
339 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
340 | kfree(buf); | ||
341 | |||
342 | return retval; | ||
343 | |||
344 | #undef PHY_ERR | ||
345 | } | ||
346 | |||
347 | static const struct file_operations fops_recv = { | ||
348 | .read = read_file_recv, | ||
349 | .open = ath9k_debugfs_open, | ||
350 | .owner = THIS_MODULE, | ||
351 | .llseek = default_llseek, | ||
352 | }; | ||
353 | |||
354 | static ssize_t read_file_slot(struct file *file, char __user *user_buf, | ||
355 | size_t count, loff_t *ppos) | ||
356 | { | ||
357 | struct ath9k_htc_priv *priv = file->private_data; | ||
358 | char buf[512]; | ||
359 | unsigned int len = 0; | ||
360 | |||
361 | spin_lock_bh(&priv->tx.tx_lock); | ||
362 | |||
363 | len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); | ||
364 | |||
365 | len += bitmap_scnprintf(buf + len, sizeof(buf) - len, | ||
366 | priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
367 | |||
368 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
369 | |||
370 | len += snprintf(buf + len, sizeof(buf) - len, | ||
371 | "Used slots : %d\n", | ||
372 | bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); | ||
373 | |||
374 | spin_unlock_bh(&priv->tx.tx_lock); | ||
375 | |||
376 | if (len > sizeof(buf)) | ||
377 | len = sizeof(buf); | ||
378 | |||
379 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
380 | } | ||
381 | |||
382 | static const struct file_operations fops_slot = { | ||
383 | .read = read_file_slot, | ||
384 | .open = ath9k_debugfs_open, | ||
385 | .owner = THIS_MODULE, | ||
386 | .llseek = default_llseek, | ||
387 | }; | ||
388 | |||
389 | static ssize_t read_file_queue(struct file *file, char __user *user_buf, | ||
390 | size_t count, loff_t *ppos) | ||
391 | { | ||
392 | struct ath9k_htc_priv *priv = file->private_data; | ||
393 | char buf[512]; | ||
394 | unsigned int len = 0; | ||
395 | |||
396 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
397 | "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); | ||
398 | |||
399 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
400 | "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); | ||
401 | |||
402 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
403 | "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); | ||
404 | |||
405 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
406 | "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); | ||
407 | |||
408 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
409 | "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); | ||
410 | |||
411 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
412 | "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); | ||
413 | |||
414 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
415 | "Failed queue", skb_queue_len(&priv->tx.tx_failed)); | ||
416 | |||
417 | spin_lock_bh(&priv->tx.tx_lock); | ||
418 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
419 | "Queued count", priv->tx.queued_cnt); | ||
420 | spin_unlock_bh(&priv->tx.tx_lock); | ||
421 | |||
422 | if (len > sizeof(buf)) | ||
423 | len = sizeof(buf); | ||
424 | |||
425 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
426 | |||
427 | } | ||
428 | |||
429 | static const struct file_operations fops_queue = { | ||
430 | .read = read_file_queue, | ||
431 | .open = ath9k_debugfs_open, | ||
432 | .owner = THIS_MODULE, | ||
433 | .llseek = default_llseek, | ||
434 | }; | ||
435 | |||
436 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, | ||
437 | size_t count, loff_t *ppos) | ||
438 | { | ||
439 | struct ath9k_htc_priv *priv = file->private_data; | ||
440 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
441 | char buf[32]; | ||
442 | unsigned int len; | ||
443 | |||
444 | len = sprintf(buf, "0x%08x\n", common->debug_mask); | ||
445 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
446 | } | ||
447 | |||
448 | static ssize_t write_file_debug(struct file *file, const char __user *user_buf, | ||
449 | size_t count, loff_t *ppos) | ||
450 | { | ||
451 | struct ath9k_htc_priv *priv = file->private_data; | ||
452 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
453 | unsigned long mask; | ||
454 | char buf[32]; | ||
455 | ssize_t len; | ||
456 | |||
457 | len = min(count, sizeof(buf) - 1); | ||
458 | if (copy_from_user(buf, user_buf, len)) | ||
459 | return -EFAULT; | ||
460 | |||
461 | buf[len] = '\0'; | ||
462 | if (strict_strtoul(buf, 0, &mask)) | ||
463 | return -EINVAL; | ||
464 | |||
465 | common->debug_mask = mask; | ||
466 | return count; | ||
467 | } | ||
468 | |||
469 | static const struct file_operations fops_debug = { | ||
470 | .read = read_file_debug, | ||
471 | .write = write_file_debug, | ||
472 | .open = ath9k_debugfs_open, | ||
473 | .owner = THIS_MODULE, | ||
474 | .llseek = default_llseek, | ||
475 | }; | ||
476 | |||
477 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
478 | { | ||
479 | struct ath_common *common = ath9k_hw_common(ah); | ||
480 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
481 | |||
482 | priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, | ||
483 | priv->hw->wiphy->debugfsdir); | ||
484 | if (!priv->debug.debugfs_phy) | ||
485 | return -ENOMEM; | ||
486 | |||
487 | debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
488 | priv, &fops_tgt_int_stats); | ||
489 | debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
490 | priv, &fops_tgt_tx_stats); | ||
491 | debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
492 | priv, &fops_tgt_rx_stats); | ||
493 | debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, | ||
494 | priv, &fops_xmit); | ||
495 | debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, | ||
496 | priv, &fops_recv); | ||
497 | debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, | ||
498 | priv, &fops_slot); | ||
499 | debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, | ||
500 | priv, &fops_queue); | ||
501 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, | ||
502 | priv, &fops_debug); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 7e630a81b453..dc0b33d01210 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -398,9 +398,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) | |||
398 | 398 | ||
399 | /* Start TX */ | 399 | /* Start TX */ |
400 | htc_start(priv->htc); | 400 | htc_start(priv->htc); |
401 | spin_lock_bh(&priv->tx_lock); | 401 | spin_lock_bh(&priv->tx.tx_lock); |
402 | priv->tx_queues_stop = false; | 402 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
403 | spin_unlock_bh(&priv->tx_lock); | 403 | spin_unlock_bh(&priv->tx.tx_lock); |
404 | ieee80211_wake_queues(hw); | 404 | ieee80211_wake_queues(hw); |
405 | 405 | ||
406 | WMI_CMD(WMI_ENABLE_INTR_CMDID); | 406 | WMI_CMD(WMI_ENABLE_INTR_CMDID); |
@@ -429,13 +429,15 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | |||
429 | 429 | ||
430 | /* Stop TX */ | 430 | /* Stop TX */ |
431 | ieee80211_stop_queues(hw); | 431 | ieee80211_stop_queues(hw); |
432 | htc_stop(priv->htc); | 432 | ath9k_htc_tx_drain(priv); |
433 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 433 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
434 | skb_queue_purge(&priv->tx_queue); | ||
435 | 434 | ||
436 | /* Stop RX */ | 435 | /* Stop RX */ |
437 | WMI_CMD(WMI_STOP_RECV_CMDID); | 436 | WMI_CMD(WMI_STOP_RECV_CMDID); |
438 | 437 | ||
438 | /* Clear the WMI event queue */ | ||
439 | ath9k_wmi_event_drain(priv); | ||
440 | |||
439 | /* | 441 | /* |
440 | * The MIB counters have to be disabled here, | 442 | * The MIB counters have to be disabled here, |
441 | * since the target doesn't do it. | 443 | * since the target doesn't do it. |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8303b34bdc90..06e043bffaf4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -140,7 +140,6 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | |||
140 | 140 | ||
141 | static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | 141 | static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) |
142 | { | 142 | { |
143 | ath9k_htc_exit_debug(priv->ah); | ||
144 | ath9k_hw_deinit(priv->ah); | 143 | ath9k_hw_deinit(priv->ah); |
145 | kfree(priv->ah); | 144 | kfree(priv->ah); |
146 | priv->ah = NULL; | 145 | priv->ah = NULL; |
@@ -643,7 +642,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
643 | { | 642 | { |
644 | struct ath_hw *ah = NULL; | 643 | struct ath_hw *ah = NULL; |
645 | struct ath_common *common; | 644 | struct ath_common *common; |
646 | int ret = 0, csz = 0; | 645 | int i, ret = 0, csz = 0; |
647 | 646 | ||
648 | priv->op_flags |= OP_INVALID; | 647 | priv->op_flags |= OP_INVALID; |
649 | 648 | ||
@@ -671,20 +670,19 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
671 | common->priv = priv; | 670 | common->priv = priv; |
672 | common->debug_mask = ath9k_debug; | 671 | common->debug_mask = ath9k_debug; |
673 | 672 | ||
674 | spin_lock_init(&priv->wmi->wmi_lock); | ||
675 | spin_lock_init(&priv->beacon_lock); | 673 | spin_lock_init(&priv->beacon_lock); |
676 | spin_lock_init(&priv->tx_lock); | 674 | spin_lock_init(&priv->tx.tx_lock); |
677 | mutex_init(&priv->mutex); | 675 | mutex_init(&priv->mutex); |
678 | mutex_init(&priv->htc_pm_lock); | 676 | mutex_init(&priv->htc_pm_lock); |
679 | tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet, | ||
680 | (unsigned long)priv); | ||
681 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, | 677 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, |
682 | (unsigned long)priv); | 678 | (unsigned long)priv); |
683 | tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, | 679 | tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet, |
684 | (unsigned long)priv); | 680 | (unsigned long)priv); |
685 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); | 681 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); |
686 | INIT_WORK(&priv->ps_work, ath9k_ps_work); | 682 | INIT_WORK(&priv->ps_work, ath9k_ps_work); |
687 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); | 683 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); |
684 | setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer, | ||
685 | (unsigned long)priv); | ||
688 | 686 | ||
689 | /* | 687 | /* |
690 | * Cache line size is used to size and align various | 688 | * Cache line size is used to size and align various |
@@ -701,16 +699,13 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
701 | goto err_hw; | 699 | goto err_hw; |
702 | } | 700 | } |
703 | 701 | ||
704 | ret = ath9k_htc_init_debug(ah); | ||
705 | if (ret) { | ||
706 | ath_err(common, "Unable to create debugfs files\n"); | ||
707 | goto err_debug; | ||
708 | } | ||
709 | |||
710 | ret = ath9k_init_queues(priv); | 702 | ret = ath9k_init_queues(priv); |
711 | if (ret) | 703 | if (ret) |
712 | goto err_queues; | 704 | goto err_queues; |
713 | 705 | ||
706 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) | ||
707 | priv->cur_beacon_conf.bslot[i] = NULL; | ||
708 | |||
714 | ath9k_init_crypto(priv); | 709 | ath9k_init_crypto(priv); |
715 | ath9k_init_channels_rates(priv); | 710 | ath9k_init_channels_rates(priv); |
716 | ath9k_init_misc(priv); | 711 | ath9k_init_misc(priv); |
@@ -723,8 +718,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
723 | return 0; | 718 | return 0; |
724 | 719 | ||
725 | err_queues: | 720 | err_queues: |
726 | ath9k_htc_exit_debug(ah); | ||
727 | err_debug: | ||
728 | ath9k_hw_deinit(ah); | 721 | ath9k_hw_deinit(ah); |
729 | err_hw: | 722 | err_hw: |
730 | 723 | ||
@@ -745,11 +738,15 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
745 | IEEE80211_HW_HAS_RATE_CONTROL | | 738 | IEEE80211_HW_HAS_RATE_CONTROL | |
746 | IEEE80211_HW_RX_INCLUDES_FCS | | 739 | IEEE80211_HW_RX_INCLUDES_FCS | |
747 | IEEE80211_HW_SUPPORTS_PS | | 740 | IEEE80211_HW_SUPPORTS_PS | |
748 | IEEE80211_HW_PS_NULLFUNC_STACK; | 741 | IEEE80211_HW_PS_NULLFUNC_STACK | |
742 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | ||
749 | 743 | ||
750 | hw->wiphy->interface_modes = | 744 | hw->wiphy->interface_modes = |
751 | BIT(NL80211_IFTYPE_STATION) | | 745 | BIT(NL80211_IFTYPE_STATION) | |
752 | BIT(NL80211_IFTYPE_ADHOC); | 746 | BIT(NL80211_IFTYPE_ADHOC) | |
747 | BIT(NL80211_IFTYPE_AP) | | ||
748 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
749 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
753 | 750 | ||
754 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 751 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
755 | 752 | ||
@@ -782,6 +779,32 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
782 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 779 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
783 | } | 780 | } |
784 | 781 | ||
782 | static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | ||
783 | { | ||
784 | struct ieee80211_hw *hw = priv->hw; | ||
785 | struct wmi_fw_version cmd_rsp; | ||
786 | int ret; | ||
787 | |||
788 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
789 | |||
790 | WMI_CMD(WMI_GET_FW_VERSION); | ||
791 | if (ret) | ||
792 | return -EINVAL; | ||
793 | |||
794 | priv->fw_version_major = be16_to_cpu(cmd_rsp.major); | ||
795 | priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor); | ||
796 | |||
797 | snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d", | ||
798 | priv->fw_version_major, | ||
799 | priv->fw_version_minor); | ||
800 | |||
801 | dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n", | ||
802 | priv->fw_version_major, | ||
803 | priv->fw_version_minor); | ||
804 | |||
805 | return 0; | ||
806 | } | ||
807 | |||
785 | static int ath9k_init_device(struct ath9k_htc_priv *priv, | 808 | static int ath9k_init_device(struct ath9k_htc_priv *priv, |
786 | u16 devid, char *product, u32 drv_info) | 809 | u16 devid, char *product, u32 drv_info) |
787 | { | 810 | { |
@@ -801,6 +824,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
801 | common = ath9k_hw_common(ah); | 824 | common = ath9k_hw_common(ah); |
802 | ath9k_set_hw_capab(priv, hw); | 825 | ath9k_set_hw_capab(priv, hw); |
803 | 826 | ||
827 | error = ath9k_init_firmware_version(priv); | ||
828 | if (error != 0) | ||
829 | goto err_fw; | ||
830 | |||
804 | /* Initialize regulatory */ | 831 | /* Initialize regulatory */ |
805 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, | 832 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, |
806 | ath9k_reg_notifier); | 833 | ath9k_reg_notifier); |
@@ -831,6 +858,12 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
831 | goto err_world; | 858 | goto err_world; |
832 | } | 859 | } |
833 | 860 | ||
861 | error = ath9k_htc_init_debug(priv->ah); | ||
862 | if (error) { | ||
863 | ath_err(common, "Unable to create debugfs files\n"); | ||
864 | goto err_world; | ||
865 | } | ||
866 | |||
834 | ath_dbg(common, ATH_DBG_CONFIG, | 867 | ath_dbg(common, ATH_DBG_CONFIG, |
835 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " | 868 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " |
836 | "BE:%d, BK:%d, VI:%d, VO:%d\n", | 869 | "BE:%d, BK:%d, VI:%d, VO:%d\n", |
@@ -861,6 +894,8 @@ err_rx: | |||
861 | err_tx: | 894 | err_tx: |
862 | /* Nothing */ | 895 | /* Nothing */ |
863 | err_regd: | 896 | err_regd: |
897 | /* Nothing */ | ||
898 | err_fw: | ||
864 | ath9k_deinit_priv(priv); | 899 | ath9k_deinit_priv(priv); |
865 | err_init: | 900 | err_init: |
866 | return error; | 901 | return error; |
@@ -949,38 +984,20 @@ int ath9k_htc_resume(struct htc_target *htc_handle) | |||
949 | 984 | ||
950 | static int __init ath9k_htc_init(void) | 985 | static int __init ath9k_htc_init(void) |
951 | { | 986 | { |
952 | int error; | 987 | if (ath9k_hif_usb_init() < 0) { |
953 | |||
954 | error = ath9k_htc_debug_create_root(); | ||
955 | if (error < 0) { | ||
956 | printk(KERN_ERR | ||
957 | "ath9k_htc: Unable to create debugfs root: %d\n", | ||
958 | error); | ||
959 | goto err_dbg; | ||
960 | } | ||
961 | |||
962 | error = ath9k_hif_usb_init(); | ||
963 | if (error < 0) { | ||
964 | printk(KERN_ERR | 988 | printk(KERN_ERR |
965 | "ath9k_htc: No USB devices found," | 989 | "ath9k_htc: No USB devices found," |
966 | " driver not installed.\n"); | 990 | " driver not installed.\n"); |
967 | error = -ENODEV; | 991 | return -ENODEV; |
968 | goto err_usb; | ||
969 | } | 992 | } |
970 | 993 | ||
971 | return 0; | 994 | return 0; |
972 | |||
973 | err_usb: | ||
974 | ath9k_htc_debug_remove_root(); | ||
975 | err_dbg: | ||
976 | return error; | ||
977 | } | 995 | } |
978 | module_init(ath9k_htc_init); | 996 | module_init(ath9k_htc_init); |
979 | 997 | ||
980 | static void __exit ath9k_htc_exit(void) | 998 | static void __exit ath9k_htc_exit(void) |
981 | { | 999 | { |
982 | ath9k_hif_usb_exit(); | 1000 | ath9k_hif_usb_exit(); |
983 | ath9k_htc_debug_remove_root(); | ||
984 | printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); | 1001 | printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); |
985 | } | 1002 | } |
986 | module_exit(ath9k_htc_exit); | 1003 | module_exit(ath9k_htc_exit); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index db8c0c044e9e..4de38643cb53 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -16,10 +16,6 @@ | |||
16 | 16 | ||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
20 | static struct dentry *ath9k_debugfs_root; | ||
21 | #endif | ||
22 | |||
23 | /*************/ | 19 | /*************/ |
24 | /* Utilities */ | 20 | /* Utilities */ |
25 | /*************/ | 21 | /*************/ |
@@ -197,11 +193,16 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
197 | 193 | ||
198 | ath9k_htc_stop_ani(priv); | 194 | ath9k_htc_stop_ani(priv); |
199 | ieee80211_stop_queues(priv->hw); | 195 | ieee80211_stop_queues(priv->hw); |
200 | htc_stop(priv->htc); | 196 | |
197 | del_timer_sync(&priv->tx.cleanup_timer); | ||
198 | ath9k_htc_tx_drain(priv); | ||
199 | |||
201 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 200 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
202 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 201 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
203 | WMI_CMD(WMI_STOP_RECV_CMDID); | 202 | WMI_CMD(WMI_STOP_RECV_CMDID); |
204 | 203 | ||
204 | ath9k_wmi_event_drain(priv); | ||
205 | |||
205 | caldata = &priv->caldata; | 206 | caldata = &priv->caldata; |
206 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); | 207 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); |
207 | if (ret) { | 208 | if (ret) { |
@@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
225 | ath9k_htc_vif_reconfig(priv); | 226 | ath9k_htc_vif_reconfig(priv); |
226 | ieee80211_wake_queues(priv->hw); | 227 | ieee80211_wake_queues(priv->hw); |
227 | 228 | ||
229 | mod_timer(&priv->tx.cleanup_timer, | ||
230 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
231 | |||
228 | ath9k_htc_ps_restore(priv); | 232 | ath9k_htc_ps_restore(priv); |
229 | mutex_unlock(&priv->mutex); | 233 | mutex_unlock(&priv->mutex); |
230 | } | 234 | } |
@@ -250,11 +254,16 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
250 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); | 254 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); |
251 | 255 | ||
252 | ath9k_htc_ps_wakeup(priv); | 256 | ath9k_htc_ps_wakeup(priv); |
253 | htc_stop(priv->htc); | 257 | |
258 | del_timer_sync(&priv->tx.cleanup_timer); | ||
259 | ath9k_htc_tx_drain(priv); | ||
260 | |||
254 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 261 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
255 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 262 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
256 | WMI_CMD(WMI_STOP_RECV_CMDID); | 263 | WMI_CMD(WMI_STOP_RECV_CMDID); |
257 | 264 | ||
265 | ath9k_wmi_event_drain(priv); | ||
266 | |||
258 | ath_dbg(common, ATH_DBG_CONFIG, | 267 | ath_dbg(common, ATH_DBG_CONFIG, |
259 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", | 268 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", |
260 | priv->ah->curchan->channel, | 269 | priv->ah->curchan->channel, |
@@ -263,6 +272,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
263 | 272 | ||
264 | if (!fastcc) | 273 | if (!fastcc) |
265 | caldata = &priv->caldata; | 274 | caldata = &priv->caldata; |
275 | |||
266 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); | 276 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
267 | if (ret) { | 277 | if (ret) { |
268 | ath_err(common, | 278 | ath_err(common, |
@@ -296,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
296 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 306 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
297 | ath9k_htc_vif_reconfig(priv); | 307 | ath9k_htc_vif_reconfig(priv); |
298 | 308 | ||
309 | mod_timer(&priv->tx.cleanup_timer, | ||
310 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
311 | |||
299 | err: | 312 | err: |
300 | ath9k_htc_ps_restore(priv); | 313 | ath9k_htc_ps_restore(priv); |
301 | return ret; | 314 | return ret; |
@@ -349,7 +362,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
349 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | 362 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); |
350 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | 363 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); |
351 | 364 | ||
352 | hvif.opmode = cpu_to_be32(HTC_M_MONITOR); | 365 | hvif.opmode = HTC_M_MONITOR; |
353 | hvif.index = ffz(priv->vif_slot); | 366 | hvif.index = ffz(priv->vif_slot); |
354 | 367 | ||
355 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); | 368 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); |
@@ -382,7 +395,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
382 | tsta.is_vif_sta = 1; | 395 | tsta.is_vif_sta = 1; |
383 | tsta.sta_index = sta_idx; | 396 | tsta.sta_index = sta_idx; |
384 | tsta.vif_index = hvif.index; | 397 | tsta.vif_index = hvif.index; |
385 | tsta.maxampdu = 0xffff; | 398 | tsta.maxampdu = cpu_to_be16(0xffff); |
386 | 399 | ||
387 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); | 400 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); |
388 | if (ret) { | 401 | if (ret) { |
@@ -463,9 +476,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
463 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 476 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
464 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); | 477 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); |
465 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); | 478 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); |
466 | tsta.associd = common->curaid; | ||
467 | tsta.is_vif_sta = 0; | 479 | tsta.is_vif_sta = 0; |
468 | tsta.valid = true; | ||
469 | ista->index = sta_idx; | 480 | ista->index = sta_idx; |
470 | } else { | 481 | } else { |
471 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); | 482 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); |
@@ -474,7 +485,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
474 | 485 | ||
475 | tsta.sta_index = sta_idx; | 486 | tsta.sta_index = sta_idx; |
476 | tsta.vif_index = avp->index; | 487 | tsta.vif_index = avp->index; |
477 | tsta.maxampdu = 0xffff; | 488 | tsta.maxampdu = cpu_to_be16(0xffff); |
478 | if (sta && sta->ht_cap.ht_supported) | 489 | if (sta && sta->ht_cap.ht_supported) |
479 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | 490 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); |
480 | 491 | ||
@@ -709,218 +720,13 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, | |||
709 | (aggr.aggr_enable) ? "Starting" : "Stopping", | 720 | (aggr.aggr_enable) ? "Starting" : "Stopping", |
710 | sta->addr, tid); | 721 | sta->addr, tid); |
711 | 722 | ||
712 | spin_lock_bh(&priv->tx_lock); | 723 | spin_lock_bh(&priv->tx.tx_lock); |
713 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; | 724 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; |
714 | spin_unlock_bh(&priv->tx_lock); | 725 | spin_unlock_bh(&priv->tx.tx_lock); |
715 | 726 | ||
716 | return ret; | 727 | return ret; |
717 | } | 728 | } |
718 | 729 | ||
719 | /*********/ | ||
720 | /* DEBUG */ | ||
721 | /*********/ | ||
722 | |||
723 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
724 | |||
725 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
726 | { | ||
727 | file->private_data = inode->i_private; | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | ||
732 | size_t count, loff_t *ppos) | ||
733 | { | ||
734 | struct ath9k_htc_priv *priv = file->private_data; | ||
735 | struct ath9k_htc_target_stats cmd_rsp; | ||
736 | char buf[512]; | ||
737 | unsigned int len = 0; | ||
738 | int ret = 0; | ||
739 | |||
740 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
741 | |||
742 | WMI_CMD(WMI_TGT_STATS_CMDID); | ||
743 | if (ret) | ||
744 | return -EINVAL; | ||
745 | |||
746 | |||
747 | len += snprintf(buf + len, sizeof(buf) - len, | ||
748 | "%19s : %10u\n", "TX Short Retries", | ||
749 | be32_to_cpu(cmd_rsp.tx_shortretry)); | ||
750 | len += snprintf(buf + len, sizeof(buf) - len, | ||
751 | "%19s : %10u\n", "TX Long Retries", | ||
752 | be32_to_cpu(cmd_rsp.tx_longretry)); | ||
753 | len += snprintf(buf + len, sizeof(buf) - len, | ||
754 | "%19s : %10u\n", "TX Xretries", | ||
755 | be32_to_cpu(cmd_rsp.tx_xretries)); | ||
756 | len += snprintf(buf + len, sizeof(buf) - len, | ||
757 | "%19s : %10u\n", "TX Unaggr. Xretries", | ||
758 | be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); | ||
759 | len += snprintf(buf + len, sizeof(buf) - len, | ||
760 | "%19s : %10u\n", "TX Xretries (HT)", | ||
761 | be32_to_cpu(cmd_rsp.ht_tx_xretries)); | ||
762 | len += snprintf(buf + len, sizeof(buf) - len, | ||
763 | "%19s : %10u\n", "TX Rate", priv->debug.txrate); | ||
764 | |||
765 | if (len > sizeof(buf)) | ||
766 | len = sizeof(buf); | ||
767 | |||
768 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
769 | } | ||
770 | |||
771 | static const struct file_operations fops_tgt_stats = { | ||
772 | .read = read_file_tgt_stats, | ||
773 | .open = ath9k_debugfs_open, | ||
774 | .owner = THIS_MODULE, | ||
775 | .llseek = default_llseek, | ||
776 | }; | ||
777 | |||
778 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
779 | size_t count, loff_t *ppos) | ||
780 | { | ||
781 | struct ath9k_htc_priv *priv = file->private_data; | ||
782 | char buf[512]; | ||
783 | unsigned int len = 0; | ||
784 | |||
785 | len += snprintf(buf + len, sizeof(buf) - len, | ||
786 | "%20s : %10u\n", "Buffers queued", | ||
787 | priv->debug.tx_stats.buf_queued); | ||
788 | len += snprintf(buf + len, sizeof(buf) - len, | ||
789 | "%20s : %10u\n", "Buffers completed", | ||
790 | priv->debug.tx_stats.buf_completed); | ||
791 | len += snprintf(buf + len, sizeof(buf) - len, | ||
792 | "%20s : %10u\n", "SKBs queued", | ||
793 | priv->debug.tx_stats.skb_queued); | ||
794 | len += snprintf(buf + len, sizeof(buf) - len, | ||
795 | "%20s : %10u\n", "SKBs completed", | ||
796 | priv->debug.tx_stats.skb_completed); | ||
797 | len += snprintf(buf + len, sizeof(buf) - len, | ||
798 | "%20s : %10u\n", "SKBs dropped", | ||
799 | priv->debug.tx_stats.skb_dropped); | ||
800 | |||
801 | len += snprintf(buf + len, sizeof(buf) - len, | ||
802 | "%20s : %10u\n", "BE queued", | ||
803 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
804 | len += snprintf(buf + len, sizeof(buf) - len, | ||
805 | "%20s : %10u\n", "BK queued", | ||
806 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
807 | len += snprintf(buf + len, sizeof(buf) - len, | ||
808 | "%20s : %10u\n", "VI queued", | ||
809 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
810 | len += snprintf(buf + len, sizeof(buf) - len, | ||
811 | "%20s : %10u\n", "VO queued", | ||
812 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
813 | |||
814 | if (len > sizeof(buf)) | ||
815 | len = sizeof(buf); | ||
816 | |||
817 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
818 | } | ||
819 | |||
820 | static const struct file_operations fops_xmit = { | ||
821 | .read = read_file_xmit, | ||
822 | .open = ath9k_debugfs_open, | ||
823 | .owner = THIS_MODULE, | ||
824 | .llseek = default_llseek, | ||
825 | }; | ||
826 | |||
827 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
828 | size_t count, loff_t *ppos) | ||
829 | { | ||
830 | struct ath9k_htc_priv *priv = file->private_data; | ||
831 | char buf[512]; | ||
832 | unsigned int len = 0; | ||
833 | |||
834 | len += snprintf(buf + len, sizeof(buf) - len, | ||
835 | "%20s : %10u\n", "SKBs allocated", | ||
836 | priv->debug.rx_stats.skb_allocated); | ||
837 | len += snprintf(buf + len, sizeof(buf) - len, | ||
838 | "%20s : %10u\n", "SKBs completed", | ||
839 | priv->debug.rx_stats.skb_completed); | ||
840 | len += snprintf(buf + len, sizeof(buf) - len, | ||
841 | "%20s : %10u\n", "SKBs Dropped", | ||
842 | priv->debug.rx_stats.skb_dropped); | ||
843 | |||
844 | if (len > sizeof(buf)) | ||
845 | len = sizeof(buf); | ||
846 | |||
847 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
848 | } | ||
849 | |||
850 | static const struct file_operations fops_recv = { | ||
851 | .read = read_file_recv, | ||
852 | .open = ath9k_debugfs_open, | ||
853 | .owner = THIS_MODULE, | ||
854 | .llseek = default_llseek, | ||
855 | }; | ||
856 | |||
857 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
858 | { | ||
859 | struct ath_common *common = ath9k_hw_common(ah); | ||
860 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
861 | |||
862 | if (!ath9k_debugfs_root) | ||
863 | return -ENOENT; | ||
864 | |||
865 | priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), | ||
866 | ath9k_debugfs_root); | ||
867 | if (!priv->debug.debugfs_phy) | ||
868 | goto err; | ||
869 | |||
870 | priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, | ||
871 | priv->debug.debugfs_phy, | ||
872 | priv, &fops_tgt_stats); | ||
873 | if (!priv->debug.debugfs_tgt_stats) | ||
874 | goto err; | ||
875 | |||
876 | |||
877 | priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, | ||
878 | priv->debug.debugfs_phy, | ||
879 | priv, &fops_xmit); | ||
880 | if (!priv->debug.debugfs_xmit) | ||
881 | goto err; | ||
882 | |||
883 | priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, | ||
884 | priv->debug.debugfs_phy, | ||
885 | priv, &fops_recv); | ||
886 | if (!priv->debug.debugfs_recv) | ||
887 | goto err; | ||
888 | |||
889 | return 0; | ||
890 | |||
891 | err: | ||
892 | ath9k_htc_exit_debug(ah); | ||
893 | return -ENOMEM; | ||
894 | } | ||
895 | |||
896 | void ath9k_htc_exit_debug(struct ath_hw *ah) | ||
897 | { | ||
898 | struct ath_common *common = ath9k_hw_common(ah); | ||
899 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
900 | |||
901 | debugfs_remove(priv->debug.debugfs_recv); | ||
902 | debugfs_remove(priv->debug.debugfs_xmit); | ||
903 | debugfs_remove(priv->debug.debugfs_tgt_stats); | ||
904 | debugfs_remove(priv->debug.debugfs_phy); | ||
905 | } | ||
906 | |||
907 | int ath9k_htc_debug_create_root(void) | ||
908 | { | ||
909 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
910 | if (!ath9k_debugfs_root) | ||
911 | return -ENOENT; | ||
912 | |||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | void ath9k_htc_debug_remove_root(void) | ||
917 | { | ||
918 | debugfs_remove(ath9k_debugfs_root); | ||
919 | ath9k_debugfs_root = NULL; | ||
920 | } | ||
921 | |||
922 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
923 | |||
924 | /*******/ | 730 | /*******/ |
925 | /* ANI */ | 731 | /* ANI */ |
926 | /*******/ | 732 | /*******/ |
@@ -1040,7 +846,8 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1040 | { | 846 | { |
1041 | struct ieee80211_hdr *hdr; | 847 | struct ieee80211_hdr *hdr; |
1042 | struct ath9k_htc_priv *priv = hw->priv; | 848 | struct ath9k_htc_priv *priv = hw->priv; |
1043 | int padpos, padsize, ret; | 849 | struct ath_common *common = ath9k_hw_common(priv->ah); |
850 | int padpos, padsize, ret, slot; | ||
1044 | 851 | ||
1045 | hdr = (struct ieee80211_hdr *) skb->data; | 852 | hdr = (struct ieee80211_hdr *) skb->data; |
1046 | 853 | ||
@@ -1048,30 +855,32 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1048 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 855 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1049 | padsize = padpos & 3; | 856 | padsize = padpos & 3; |
1050 | if (padsize && skb->len > padpos) { | 857 | if (padsize && skb->len > padpos) { |
1051 | if (skb_headroom(skb) < padsize) | 858 | if (skb_headroom(skb) < padsize) { |
859 | ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); | ||
1052 | goto fail_tx; | 860 | goto fail_tx; |
861 | } | ||
1053 | skb_push(skb, padsize); | 862 | skb_push(skb, padsize); |
1054 | memmove(skb->data, skb->data + padsize, padpos); | 863 | memmove(skb->data, skb->data + padsize, padpos); |
1055 | } | 864 | } |
1056 | 865 | ||
1057 | ret = ath9k_htc_tx_start(priv, skb); | 866 | slot = ath9k_htc_tx_get_slot(priv); |
1058 | if (ret != 0) { | 867 | if (slot < 0) { |
1059 | if (ret == -ENOMEM) { | 868 | ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); |
1060 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1061 | "Stopping TX queues\n"); | ||
1062 | ieee80211_stop_queues(hw); | ||
1063 | spin_lock_bh(&priv->tx_lock); | ||
1064 | priv->tx_queues_stop = true; | ||
1065 | spin_unlock_bh(&priv->tx_lock); | ||
1066 | } else { | ||
1067 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1068 | "Tx failed\n"); | ||
1069 | } | ||
1070 | goto fail_tx; | 869 | goto fail_tx; |
1071 | } | 870 | } |
1072 | 871 | ||
872 | ret = ath9k_htc_tx_start(priv, skb, slot, false); | ||
873 | if (ret != 0) { | ||
874 | ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); | ||
875 | goto clear_slot; | ||
876 | } | ||
877 | |||
878 | ath9k_htc_check_stop_queues(priv); | ||
879 | |||
1073 | return; | 880 | return; |
1074 | 881 | ||
882 | clear_slot: | ||
883 | ath9k_htc_tx_clear_slot(priv, slot); | ||
1075 | fail_tx: | 884 | fail_tx: |
1076 | dev_kfree_skb_any(skb); | 885 | dev_kfree_skb_any(skb); |
1077 | } | 886 | } |
@@ -1130,12 +939,15 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1130 | priv->op_flags &= ~OP_INVALID; | 939 | priv->op_flags &= ~OP_INVALID; |
1131 | htc_start(priv->htc); | 940 | htc_start(priv->htc); |
1132 | 941 | ||
1133 | spin_lock_bh(&priv->tx_lock); | 942 | spin_lock_bh(&priv->tx.tx_lock); |
1134 | priv->tx_queues_stop = false; | 943 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
1135 | spin_unlock_bh(&priv->tx_lock); | 944 | spin_unlock_bh(&priv->tx.tx_lock); |
1136 | 945 | ||
1137 | ieee80211_wake_queues(hw); | 946 | ieee80211_wake_queues(hw); |
1138 | 947 | ||
948 | mod_timer(&priv->tx.cleanup_timer, | ||
949 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
950 | |||
1139 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { | 951 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { |
1140 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 952 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1141 | AR_STOMP_LOW_WLAN_WGHT); | 953 | AR_STOMP_LOW_WLAN_WGHT); |
@@ -1164,16 +976,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1164 | } | 976 | } |
1165 | 977 | ||
1166 | ath9k_htc_ps_wakeup(priv); | 978 | ath9k_htc_ps_wakeup(priv); |
1167 | htc_stop(priv->htc); | 979 | |
1168 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 980 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
1169 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 981 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
1170 | WMI_CMD(WMI_STOP_RECV_CMDID); | 982 | WMI_CMD(WMI_STOP_RECV_CMDID); |
1171 | 983 | ||
1172 | tasklet_kill(&priv->swba_tasklet); | ||
1173 | tasklet_kill(&priv->rx_tasklet); | 984 | tasklet_kill(&priv->rx_tasklet); |
1174 | tasklet_kill(&priv->tx_tasklet); | ||
1175 | 985 | ||
1176 | skb_queue_purge(&priv->tx_queue); | 986 | del_timer_sync(&priv->tx.cleanup_timer); |
987 | ath9k_htc_tx_drain(priv); | ||
988 | ath9k_wmi_event_drain(priv); | ||
1177 | 989 | ||
1178 | mutex_unlock(&priv->mutex); | 990 | mutex_unlock(&priv->mutex); |
1179 | 991 | ||
@@ -1245,13 +1057,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1245 | 1057 | ||
1246 | switch (vif->type) { | 1058 | switch (vif->type) { |
1247 | case NL80211_IFTYPE_STATION: | 1059 | case NL80211_IFTYPE_STATION: |
1248 | hvif.opmode = cpu_to_be32(HTC_M_STA); | 1060 | hvif.opmode = HTC_M_STA; |
1249 | break; | 1061 | break; |
1250 | case NL80211_IFTYPE_ADHOC: | 1062 | case NL80211_IFTYPE_ADHOC: |
1251 | hvif.opmode = cpu_to_be32(HTC_M_IBSS); | 1063 | hvif.opmode = HTC_M_IBSS; |
1252 | break; | 1064 | break; |
1253 | case NL80211_IFTYPE_AP: | 1065 | case NL80211_IFTYPE_AP: |
1254 | hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); | 1066 | hvif.opmode = HTC_M_HOSTAP; |
1255 | break; | 1067 | break; |
1256 | default: | 1068 | default: |
1257 | ath_err(common, | 1069 | ath_err(common, |
@@ -1281,14 +1093,20 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1281 | 1093 | ||
1282 | priv->vif_slot |= (1 << avp->index); | 1094 | priv->vif_slot |= (1 << avp->index); |
1283 | priv->nvifs++; | 1095 | priv->nvifs++; |
1284 | priv->vif = vif; | ||
1285 | 1096 | ||
1286 | INC_VIF(priv, vif->type); | 1097 | INC_VIF(priv, vif->type); |
1098 | |||
1099 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1100 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1101 | ath9k_htc_assign_bslot(priv, vif); | ||
1102 | |||
1287 | ath9k_htc_set_opmode(priv); | 1103 | ath9k_htc_set_opmode(priv); |
1288 | 1104 | ||
1289 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && | 1105 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && |
1290 | !(priv->op_flags & OP_ANI_RUNNING)) | 1106 | !(priv->op_flags & OP_ANI_RUNNING)) { |
1107 | ath9k_hw_set_tsfadjust(priv->ah, 1); | ||
1291 | ath9k_htc_start_ani(priv); | 1108 | ath9k_htc_start_ani(priv); |
1109 | } | ||
1292 | 1110 | ||
1293 | ath_dbg(common, ATH_DBG_CONFIG, | 1111 | ath_dbg(common, ATH_DBG_CONFIG, |
1294 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); | 1112 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); |
@@ -1321,9 +1139,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1321 | priv->vif_slot &= ~(1 << avp->index); | 1139 | priv->vif_slot &= ~(1 << avp->index); |
1322 | 1140 | ||
1323 | ath9k_htc_remove_station(priv, vif, NULL); | 1141 | ath9k_htc_remove_station(priv, vif, NULL); |
1324 | priv->vif = NULL; | ||
1325 | 1142 | ||
1326 | DEC_VIF(priv, vif->type); | 1143 | DEC_VIF(priv, vif->type); |
1144 | |||
1145 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1146 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1147 | ath9k_htc_remove_bslot(priv, vif); | ||
1148 | |||
1327 | ath9k_htc_set_opmode(priv); | 1149 | ath9k_htc_set_opmode(priv); |
1328 | 1150 | ||
1329 | /* | 1151 | /* |
@@ -1493,10 +1315,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
1493 | struct ieee80211_sta *sta) | 1315 | struct ieee80211_sta *sta) |
1494 | { | 1316 | { |
1495 | struct ath9k_htc_priv *priv = hw->priv; | 1317 | struct ath9k_htc_priv *priv = hw->priv; |
1318 | struct ath9k_htc_sta *ista; | ||
1496 | int ret; | 1319 | int ret; |
1497 | 1320 | ||
1498 | mutex_lock(&priv->mutex); | 1321 | mutex_lock(&priv->mutex); |
1499 | ath9k_htc_ps_wakeup(priv); | 1322 | ath9k_htc_ps_wakeup(priv); |
1323 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1324 | htc_sta_drain(priv->htc, ista->index); | ||
1500 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1325 | ret = ath9k_htc_remove_station(priv, vif, sta); |
1501 | ath9k_htc_ps_restore(priv); | 1326 | ath9k_htc_ps_restore(priv); |
1502 | mutex_unlock(&priv->mutex); | 1327 | mutex_unlock(&priv->mutex); |
@@ -1644,6 +1469,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1644 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { | 1469 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { |
1645 | ath_dbg(common, ATH_DBG_CONFIG, | 1470 | ath_dbg(common, ATH_DBG_CONFIG, |
1646 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); | 1471 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); |
1472 | ath9k_htc_set_tsfadjust(priv, vif); | ||
1647 | priv->op_flags |= OP_ENABLE_BEACON; | 1473 | priv->op_flags |= OP_ENABLE_BEACON; |
1648 | ath9k_htc_beacon_config(priv, vif); | 1474 | ath9k_htc_beacon_config(priv, vif); |
1649 | } | 1475 | } |
@@ -1758,9 +1584,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1758 | break; | 1584 | break; |
1759 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1585 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
1760 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 1586 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
1761 | spin_lock_bh(&priv->tx_lock); | 1587 | spin_lock_bh(&priv->tx.tx_lock); |
1762 | ista->tid_state[tid] = AGGR_OPERATIONAL; | 1588 | ista->tid_state[tid] = AGGR_OPERATIONAL; |
1763 | spin_unlock_bh(&priv->tx_lock); | 1589 | spin_unlock_bh(&priv->tx.tx_lock); |
1764 | break; | 1590 | break; |
1765 | default: | 1591 | default: |
1766 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); | 1592 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27ba96af..723a3a9c5cd9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -53,6 +53,138 @@ int get_hw_qnum(u16 queue, int *hwq_map) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv) | ||
57 | { | ||
58 | spin_lock_bh(&priv->tx.tx_lock); | ||
59 | priv->tx.queued_cnt++; | ||
60 | if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) && | ||
61 | !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
62 | priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
63 | ieee80211_stop_queues(priv->hw); | ||
64 | } | ||
65 | spin_unlock_bh(&priv->tx.tx_lock); | ||
66 | } | ||
67 | |||
68 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) | ||
69 | { | ||
70 | spin_lock_bh(&priv->tx.tx_lock); | ||
71 | if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) && | ||
72 | (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
73 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
74 | ieee80211_wake_queues(priv->hw); | ||
75 | } | ||
76 | spin_unlock_bh(&priv->tx.tx_lock); | ||
77 | } | ||
78 | |||
79 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv) | ||
80 | { | ||
81 | int slot; | ||
82 | |||
83 | spin_lock_bh(&priv->tx.tx_lock); | ||
84 | slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
85 | if (slot >= MAX_TX_BUF_NUM) { | ||
86 | spin_unlock_bh(&priv->tx.tx_lock); | ||
87 | return -ENOBUFS; | ||
88 | } | ||
89 | __set_bit(slot, priv->tx.tx_slot); | ||
90 | spin_unlock_bh(&priv->tx.tx_lock); | ||
91 | |||
92 | return slot; | ||
93 | } | ||
94 | |||
95 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) | ||
96 | { | ||
97 | spin_lock_bh(&priv->tx.tx_lock); | ||
98 | __clear_bit(slot, priv->tx.tx_slot); | ||
99 | spin_unlock_bh(&priv->tx.tx_lock); | ||
100 | } | ||
101 | |||
102 | static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, | ||
103 | u16 qnum) | ||
104 | { | ||
105 | enum htc_endpoint_id epid; | ||
106 | |||
107 | switch (qnum) { | ||
108 | case 0: | ||
109 | TX_QSTAT_INC(WME_AC_VO); | ||
110 | epid = priv->data_vo_ep; | ||
111 | break; | ||
112 | case 1: | ||
113 | TX_QSTAT_INC(WME_AC_VI); | ||
114 | epid = priv->data_vi_ep; | ||
115 | break; | ||
116 | case 2: | ||
117 | TX_QSTAT_INC(WME_AC_BE); | ||
118 | epid = priv->data_be_ep; | ||
119 | break; | ||
120 | case 3: | ||
121 | default: | ||
122 | TX_QSTAT_INC(WME_AC_BK); | ||
123 | epid = priv->data_bk_ep; | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | return epid; | ||
128 | } | ||
129 | |||
130 | static inline struct sk_buff_head* | ||
131 | get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid) | ||
132 | { | ||
133 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
134 | struct sk_buff_head *epid_queue = NULL; | ||
135 | |||
136 | if (epid == priv->mgmt_ep) | ||
137 | epid_queue = &priv->tx.mgmt_ep_queue; | ||
138 | else if (epid == priv->cab_ep) | ||
139 | epid_queue = &priv->tx.cab_ep_queue; | ||
140 | else if (epid == priv->data_be_ep) | ||
141 | epid_queue = &priv->tx.data_be_queue; | ||
142 | else if (epid == priv->data_bk_ep) | ||
143 | epid_queue = &priv->tx.data_bk_queue; | ||
144 | else if (epid == priv->data_vi_ep) | ||
145 | epid_queue = &priv->tx.data_vi_queue; | ||
146 | else if (epid == priv->data_vo_ep) | ||
147 | epid_queue = &priv->tx.data_vo_queue; | ||
148 | else | ||
149 | ath_err(common, "Invalid EPID: %d\n", epid); | ||
150 | |||
151 | return epid_queue; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Removes the driver header and returns the TX slot number | ||
156 | */ | ||
157 | static inline int strip_drv_header(struct ath9k_htc_priv *priv, | ||
158 | struct sk_buff *skb) | ||
159 | { | ||
160 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
161 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
162 | int slot; | ||
163 | |||
164 | tx_ctl = HTC_SKB_CB(skb); | ||
165 | |||
166 | if (tx_ctl->epid == priv->mgmt_ep) { | ||
167 | struct tx_mgmt_hdr *tx_mhdr = | ||
168 | (struct tx_mgmt_hdr *)skb->data; | ||
169 | slot = tx_mhdr->cookie; | ||
170 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | ||
171 | } else if ((tx_ctl->epid == priv->data_bk_ep) || | ||
172 | (tx_ctl->epid == priv->data_be_ep) || | ||
173 | (tx_ctl->epid == priv->data_vi_ep) || | ||
174 | (tx_ctl->epid == priv->data_vo_ep) || | ||
175 | (tx_ctl->epid == priv->cab_ep)) { | ||
176 | struct tx_frame_hdr *tx_fhdr = | ||
177 | (struct tx_frame_hdr *)skb->data; | ||
178 | slot = tx_fhdr->cookie; | ||
179 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
180 | } else { | ||
181 | ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); | ||
182 | slot = -EINVAL; | ||
183 | } | ||
184 | |||
185 | return slot; | ||
186 | } | ||
187 | |||
56 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 188 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
57 | struct ath9k_tx_queue_info *qinfo) | 189 | struct ath9k_tx_queue_info *qinfo) |
58 | { | 190 | { |
@@ -79,23 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | |||
79 | return error; | 211 | return error; |
80 | } | 212 | } |
81 | 213 | ||
82 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | 214 | static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv, |
215 | struct ath9k_htc_vif *avp, | ||
216 | struct sk_buff *skb, | ||
217 | u8 sta_idx, u8 vif_idx, u8 slot) | ||
218 | { | ||
219 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
220 | struct ieee80211_mgmt *mgmt; | ||
221 | struct ieee80211_hdr *hdr; | ||
222 | struct tx_mgmt_hdr mgmt_hdr; | ||
223 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
224 | u8 *tx_fhdr; | ||
225 | |||
226 | tx_ctl = HTC_SKB_CB(skb); | ||
227 | hdr = (struct ieee80211_hdr *) skb->data; | ||
228 | |||
229 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
230 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | ||
231 | |||
232 | /* | ||
233 | * Set the TSF adjust value for probe response | ||
234 | * frame also. | ||
235 | */ | ||
236 | if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { | ||
237 | mgmt = (struct ieee80211_mgmt *)skb->data; | ||
238 | mgmt->u.probe_resp.timestamp = avp->tsfadjust; | ||
239 | } | ||
240 | |||
241 | tx_ctl->type = ATH9K_HTC_MGMT; | ||
242 | |||
243 | mgmt_hdr.node_idx = sta_idx; | ||
244 | mgmt_hdr.vif_idx = vif_idx; | ||
245 | mgmt_hdr.tidno = 0; | ||
246 | mgmt_hdr.flags = 0; | ||
247 | mgmt_hdr.cookie = slot; | ||
248 | |||
249 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
250 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
251 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
252 | else | ||
253 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
254 | |||
255 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | ||
256 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | ||
257 | tx_ctl->epid = priv->mgmt_ep; | ||
258 | } | ||
259 | |||
260 | static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, | ||
261 | struct ieee80211_vif *vif, | ||
262 | struct sk_buff *skb, | ||
263 | u8 sta_idx, u8 vif_idx, u8 slot, | ||
264 | bool is_cab) | ||
265 | { | ||
266 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
267 | struct ieee80211_hdr *hdr; | ||
268 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
269 | struct tx_frame_hdr tx_hdr; | ||
270 | u32 flags = 0; | ||
271 | u8 *qc, *tx_fhdr; | ||
272 | u16 qnum; | ||
273 | |||
274 | tx_ctl = HTC_SKB_CB(skb); | ||
275 | hdr = (struct ieee80211_hdr *) skb->data; | ||
276 | |||
277 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
278 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | ||
279 | |||
280 | tx_hdr.node_idx = sta_idx; | ||
281 | tx_hdr.vif_idx = vif_idx; | ||
282 | tx_hdr.cookie = slot; | ||
283 | |||
284 | /* | ||
285 | * This is a bit redundant but it helps to get | ||
286 | * the per-packet index quickly when draining the | ||
287 | * TX queue in the HIF layer. Otherwise we would | ||
288 | * have to parse the packet contents ... | ||
289 | */ | ||
290 | tx_ctl->sta_idx = sta_idx; | ||
291 | |||
292 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
293 | tx_ctl->type = ATH9K_HTC_AMPDU; | ||
294 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | ||
295 | } else { | ||
296 | tx_ctl->type = ATH9K_HTC_NORMAL; | ||
297 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | ||
298 | } | ||
299 | |||
300 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
301 | qc = ieee80211_get_qos_ctl(hdr); | ||
302 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
303 | } | ||
304 | |||
305 | /* Check for RTS protection */ | ||
306 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | ||
307 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
308 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
309 | |||
310 | /* CTS-to-self */ | ||
311 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | ||
312 | (vif && vif->bss_conf.use_cts_prot)) | ||
313 | flags |= ATH9K_HTC_TX_CTSONLY; | ||
314 | |||
315 | tx_hdr.flags = cpu_to_be32(flags); | ||
316 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
317 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
318 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
319 | else | ||
320 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
321 | |||
322 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | ||
323 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | ||
324 | |||
325 | if (is_cab) { | ||
326 | CAB_STAT_INC; | ||
327 | tx_ctl->epid = priv->cab_ep; | ||
328 | return; | ||
329 | } | ||
330 | |||
331 | qnum = skb_get_queue_mapping(skb); | ||
332 | tx_ctl->epid = get_htc_epid(priv, qnum); | ||
333 | } | ||
334 | |||
335 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, | ||
336 | struct sk_buff *skb, | ||
337 | u8 slot, bool is_cab) | ||
83 | { | 338 | { |
84 | struct ieee80211_hdr *hdr; | 339 | struct ieee80211_hdr *hdr; |
85 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 340 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
86 | struct ieee80211_sta *sta = tx_info->control.sta; | 341 | struct ieee80211_sta *sta = tx_info->control.sta; |
87 | struct ieee80211_vif *vif = tx_info->control.vif; | 342 | struct ieee80211_vif *vif = tx_info->control.vif; |
88 | struct ath9k_htc_sta *ista; | 343 | struct ath9k_htc_sta *ista; |
89 | struct ath9k_htc_vif *avp; | 344 | struct ath9k_htc_vif *avp = NULL; |
90 | struct ath9k_htc_tx_ctl tx_ctl; | ||
91 | enum htc_endpoint_id epid; | ||
92 | u16 qnum; | ||
93 | __le16 fc; | ||
94 | u8 *tx_fhdr; | ||
95 | u8 sta_idx, vif_idx; | 345 | u8 sta_idx, vif_idx; |
96 | 346 | ||
97 | hdr = (struct ieee80211_hdr *) skb->data; | 347 | hdr = (struct ieee80211_hdr *) skb->data; |
98 | fc = hdr->frame_control; | ||
99 | 348 | ||
100 | /* | 349 | /* |
101 | * Find out on which interface this packet has to be | 350 | * Find out on which interface this packet has to be |
@@ -124,218 +373,432 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
124 | sta_idx = priv->vif_sta_pos[vif_idx]; | 373 | sta_idx = priv->vif_sta_pos[vif_idx]; |
125 | } | 374 | } |
126 | 375 | ||
127 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | 376 | if (ieee80211_is_data(hdr->frame_control)) |
377 | ath9k_htc_tx_data(priv, vif, skb, | ||
378 | sta_idx, vif_idx, slot, is_cab); | ||
379 | else | ||
380 | ath9k_htc_tx_mgmt(priv, avp, skb, | ||
381 | sta_idx, vif_idx, slot); | ||
128 | 382 | ||
129 | if (ieee80211_is_data(fc)) { | ||
130 | struct tx_frame_hdr tx_hdr; | ||
131 | u32 flags = 0; | ||
132 | u8 *qc; | ||
133 | 383 | ||
134 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | 384 | return htc_send(priv->htc, skb); |
385 | } | ||
135 | 386 | ||
136 | tx_hdr.node_idx = sta_idx; | 387 | static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, |
137 | tx_hdr.vif_idx = vif_idx; | 388 | struct ath9k_htc_sta *ista, u8 tid) |
389 | { | ||
390 | bool ret = false; | ||
138 | 391 | ||
139 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 392 | spin_lock_bh(&priv->tx.tx_lock); |
140 | tx_ctl.type = ATH9K_HTC_AMPDU; | 393 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) |
141 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | 394 | ret = true; |
142 | } else { | 395 | spin_unlock_bh(&priv->tx.tx_lock); |
143 | tx_ctl.type = ATH9K_HTC_NORMAL; | 396 | |
144 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | 397 | return ret; |
145 | } | 398 | } |
399 | |||
400 | static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | ||
401 | struct ieee80211_vif *vif, | ||
402 | struct sk_buff *skb) | ||
403 | { | ||
404 | struct ieee80211_sta *sta; | ||
405 | struct ieee80211_hdr *hdr; | ||
406 | __le16 fc; | ||
407 | |||
408 | hdr = (struct ieee80211_hdr *) skb->data; | ||
409 | fc = hdr->frame_control; | ||
410 | |||
411 | rcu_read_lock(); | ||
412 | |||
413 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
414 | if (!sta) { | ||
415 | rcu_read_unlock(); | ||
416 | return; | ||
417 | } | ||
146 | 418 | ||
419 | if (sta && conf_is_ht(&priv->hw->conf) && | ||
420 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
147 | if (ieee80211_is_data_qos(fc)) { | 421 | if (ieee80211_is_data_qos(fc)) { |
422 | u8 *qc, tid; | ||
423 | struct ath9k_htc_sta *ista; | ||
424 | |||
148 | qc = ieee80211_get_qos_ctl(hdr); | 425 | qc = ieee80211_get_qos_ctl(hdr); |
149 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 426 | tid = qc[0] & 0xf; |
427 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | ||
428 | if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) { | ||
429 | ieee80211_start_tx_ba_session(sta, tid, 0); | ||
430 | spin_lock_bh(&priv->tx.tx_lock); | ||
431 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
432 | spin_unlock_bh(&priv->tx.tx_lock); | ||
433 | } | ||
150 | } | 434 | } |
435 | } | ||
151 | 436 | ||
152 | /* Check for RTS protection */ | 437 | rcu_read_unlock(); |
153 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | 438 | } |
154 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
155 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
156 | 439 | ||
157 | /* CTS-to-self */ | 440 | static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, |
158 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | 441 | struct sk_buff *skb, |
159 | (vif && vif->bss_conf.use_cts_prot)) | 442 | struct __wmi_event_txstatus *txs) |
160 | flags |= ATH9K_HTC_TX_CTSONLY; | 443 | { |
444 | struct ieee80211_vif *vif; | ||
445 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
446 | struct ieee80211_tx_info *tx_info; | ||
447 | struct ieee80211_tx_rate *rate; | ||
448 | struct ieee80211_conf *cur_conf = &priv->hw->conf; | ||
449 | struct ieee80211_supported_band *sband; | ||
450 | bool txok; | ||
451 | int slot; | ||
161 | 452 | ||
162 | tx_hdr.flags = cpu_to_be32(flags); | 453 | slot = strip_drv_header(priv, skb); |
163 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 454 | if (slot < 0) { |
164 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 455 | dev_kfree_skb_any(skb); |
165 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | 456 | return; |
166 | else | 457 | } |
167 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
168 | 458 | ||
169 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | 459 | tx_ctl = HTC_SKB_CB(skb); |
170 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | 460 | txok = tx_ctl->txok; |
461 | tx_info = IEEE80211_SKB_CB(skb); | ||
462 | vif = tx_info->control.vif; | ||
463 | rate = &tx_info->status.rates[0]; | ||
464 | sband = priv->hw->wiphy->bands[cur_conf->channel->band]; | ||
171 | 465 | ||
172 | qnum = skb_get_queue_mapping(skb); | 466 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
173 | 467 | ||
174 | switch (qnum) { | 468 | /* |
175 | case 0: | 469 | * URB submission failed for this frame, it never reached |
176 | TX_QSTAT_INC(WME_AC_VO); | 470 | * the target. |
177 | epid = priv->data_vo_ep; | 471 | */ |
178 | break; | 472 | if (!txok || !vif || !txs) |
179 | case 1: | 473 | goto send_mac80211; |
180 | TX_QSTAT_INC(WME_AC_VI); | ||
181 | epid = priv->data_vi_ep; | ||
182 | break; | ||
183 | case 2: | ||
184 | TX_QSTAT_INC(WME_AC_BE); | ||
185 | epid = priv->data_be_ep; | ||
186 | break; | ||
187 | case 3: | ||
188 | default: | ||
189 | TX_QSTAT_INC(WME_AC_BK); | ||
190 | epid = priv->data_bk_ep; | ||
191 | break; | ||
192 | } | ||
193 | } else { | ||
194 | struct tx_mgmt_hdr mgmt_hdr; | ||
195 | 474 | ||
196 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | 475 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) |
476 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
477 | |||
478 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT) | ||
479 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
197 | 480 | ||
198 | tx_ctl.type = ATH9K_HTC_NORMAL; | 481 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS) |
482 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
199 | 483 | ||
200 | mgmt_hdr.node_idx = sta_idx; | 484 | rate->count = 1; |
201 | mgmt_hdr.vif_idx = vif_idx; | 485 | rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE); |
202 | mgmt_hdr.tidno = 0; | ||
203 | mgmt_hdr.flags = 0; | ||
204 | 486 | ||
205 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 487 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) { |
206 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 488 | rate->flags |= IEEE80211_TX_RC_MCS; |
207 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
208 | else | ||
209 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
210 | 489 | ||
211 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | 490 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40) |
212 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | 491 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
213 | epid = priv->mgmt_ep; | 492 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) |
493 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
494 | } else { | ||
495 | if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) | ||
496 | rate->idx += 4; /* No CCK rates */ | ||
214 | } | 497 | } |
215 | 498 | ||
216 | return htc_send(priv->htc, skb, epid, &tx_ctl); | 499 | ath9k_htc_check_tx_aggr(priv, vif, skb); |
500 | |||
501 | send_mac80211: | ||
502 | spin_lock_bh(&priv->tx.tx_lock); | ||
503 | if (WARN_ON(--priv->tx.queued_cnt < 0)) | ||
504 | priv->tx.queued_cnt = 0; | ||
505 | spin_unlock_bh(&priv->tx.tx_lock); | ||
506 | |||
507 | ath9k_htc_tx_clear_slot(priv, slot); | ||
508 | |||
509 | /* Send status to mac80211 */ | ||
510 | ieee80211_tx_status(priv->hw, skb); | ||
217 | } | 511 | } |
218 | 512 | ||
219 | static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | 513 | static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, |
220 | struct ath9k_htc_sta *ista, u8 tid) | 514 | struct sk_buff_head *queue) |
221 | { | 515 | { |
222 | bool ret = false; | 516 | struct sk_buff *skb; |
223 | 517 | ||
224 | spin_lock_bh(&priv->tx_lock); | 518 | while ((skb = skb_dequeue(queue)) != NULL) { |
225 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) | 519 | ath9k_htc_tx_process(priv, skb, NULL); |
226 | ret = true; | 520 | } |
227 | spin_unlock_bh(&priv->tx_lock); | 521 | } |
228 | 522 | ||
229 | return ret; | 523 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) |
524 | { | ||
525 | struct ath9k_htc_tx_event *event, *tmp; | ||
526 | |||
527 | spin_lock_bh(&priv->tx.tx_lock); | ||
528 | priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; | ||
529 | spin_unlock_bh(&priv->tx.tx_lock); | ||
530 | |||
531 | /* | ||
532 | * Ensure that all pending TX frames are flushed, | ||
533 | * and that the TX completion/failed tasklets is killed. | ||
534 | */ | ||
535 | htc_stop(priv->htc); | ||
536 | tasklet_kill(&priv->wmi->wmi_event_tasklet); | ||
537 | tasklet_kill(&priv->tx_failed_tasklet); | ||
538 | |||
539 | ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue); | ||
540 | ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue); | ||
541 | ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue); | ||
542 | ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue); | ||
543 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue); | ||
544 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); | ||
545 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); | ||
546 | |||
547 | /* | ||
548 | * The TX cleanup timer has already been killed. | ||
549 | */ | ||
550 | spin_lock_bh(&priv->wmi->event_lock); | ||
551 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
552 | list_del(&event->list); | ||
553 | kfree(event); | ||
554 | } | ||
555 | spin_unlock_bh(&priv->wmi->event_lock); | ||
556 | |||
557 | spin_lock_bh(&priv->tx.tx_lock); | ||
558 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; | ||
559 | spin_unlock_bh(&priv->tx.tx_lock); | ||
230 | } | 560 | } |
231 | 561 | ||
232 | void ath9k_tx_tasklet(unsigned long data) | 562 | void ath9k_tx_failed_tasklet(unsigned long data) |
233 | { | 563 | { |
234 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 564 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
235 | struct ieee80211_vif *vif; | ||
236 | struct ieee80211_sta *sta; | ||
237 | struct ieee80211_hdr *hdr; | ||
238 | struct ieee80211_tx_info *tx_info; | ||
239 | struct sk_buff *skb = NULL; | ||
240 | __le16 fc; | ||
241 | 565 | ||
242 | while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { | 566 | spin_lock_bh(&priv->tx.tx_lock); |
567 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
568 | spin_unlock_bh(&priv->tx.tx_lock); | ||
569 | return; | ||
570 | } | ||
571 | spin_unlock_bh(&priv->tx.tx_lock); | ||
243 | 572 | ||
244 | hdr = (struct ieee80211_hdr *) skb->data; | 573 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); |
245 | fc = hdr->frame_control; | 574 | } |
246 | tx_info = IEEE80211_SKB_CB(skb); | ||
247 | vif = tx_info->control.vif; | ||
248 | 575 | ||
249 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 576 | static inline bool check_cookie(struct ath9k_htc_priv *priv, |
577 | struct sk_buff *skb, | ||
578 | u8 cookie, u8 epid) | ||
579 | { | ||
580 | u8 fcookie = 0; | ||
581 | |||
582 | if (epid == priv->mgmt_ep) { | ||
583 | struct tx_mgmt_hdr *hdr; | ||
584 | hdr = (struct tx_mgmt_hdr *) skb->data; | ||
585 | fcookie = hdr->cookie; | ||
586 | } else if ((epid == priv->data_bk_ep) || | ||
587 | (epid == priv->data_be_ep) || | ||
588 | (epid == priv->data_vi_ep) || | ||
589 | (epid == priv->data_vo_ep) || | ||
590 | (epid == priv->cab_ep)) { | ||
591 | struct tx_frame_hdr *hdr; | ||
592 | hdr = (struct tx_frame_hdr *) skb->data; | ||
593 | fcookie = hdr->cookie; | ||
594 | } | ||
250 | 595 | ||
251 | if (!vif) | 596 | if (fcookie == cookie) |
252 | goto send_mac80211; | 597 | return true; |
253 | 598 | ||
254 | rcu_read_lock(); | 599 | return false; |
600 | } | ||
255 | 601 | ||
256 | sta = ieee80211_find_sta(vif, hdr->addr1); | 602 | static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, |
257 | if (!sta) { | 603 | struct __wmi_event_txstatus *txs) |
258 | rcu_read_unlock(); | 604 | { |
259 | ieee80211_tx_status(priv->hw, skb); | 605 | struct ath_common *common = ath9k_hw_common(priv->ah); |
260 | continue; | 606 | struct sk_buff_head *epid_queue; |
607 | struct sk_buff *skb, *tmp; | ||
608 | unsigned long flags; | ||
609 | u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID); | ||
610 | |||
611 | epid_queue = get_htc_epid_queue(priv, epid); | ||
612 | if (!epid_queue) | ||
613 | return NULL; | ||
614 | |||
615 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
616 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
617 | if (check_cookie(priv, skb, txs->cookie, epid)) { | ||
618 | __skb_unlink(skb, epid_queue); | ||
619 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
620 | return skb; | ||
261 | } | 621 | } |
622 | } | ||
623 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
262 | 624 | ||
263 | /* Check if we need to start aggregation */ | 625 | ath_dbg(common, ATH_DBG_XMIT, |
626 | "No matching packet for cookie: %d, epid: %d\n", | ||
627 | txs->cookie, epid); | ||
264 | 628 | ||
265 | if (sta && conf_is_ht(&priv->hw->conf) && | 629 | return NULL; |
266 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 630 | } |
267 | if (ieee80211_is_data_qos(fc)) { | ||
268 | u8 *qc, tid; | ||
269 | struct ath9k_htc_sta *ista; | ||
270 | 631 | ||
271 | qc = ieee80211_get_qos_ctl(hdr); | 632 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) |
272 | tid = qc[0] & 0xf; | 633 | { |
273 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | 634 | struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; |
635 | struct __wmi_event_txstatus *__txs; | ||
636 | struct sk_buff *skb; | ||
637 | struct ath9k_htc_tx_event *tx_pend; | ||
638 | int i; | ||
274 | 639 | ||
275 | if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { | 640 | for (i = 0; i < txs->cnt; i++) { |
276 | ieee80211_start_tx_ba_session(sta, tid, 0); | 641 | WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); |
277 | spin_lock_bh(&priv->tx_lock); | ||
278 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
279 | spin_unlock_bh(&priv->tx_lock); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | 642 | ||
284 | rcu_read_unlock(); | 643 | __txs = &txs->txstatus[i]; |
644 | |||
645 | skb = ath9k_htc_tx_get_packet(priv, __txs); | ||
646 | if (!skb) { | ||
647 | /* | ||
648 | * Store this event, so that the TX cleanup | ||
649 | * routine can check later for the needed packet. | ||
650 | */ | ||
651 | tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), | ||
652 | GFP_ATOMIC); | ||
653 | if (!tx_pend) | ||
654 | continue; | ||
655 | |||
656 | memcpy(&tx_pend->txs, __txs, | ||
657 | sizeof(struct __wmi_event_txstatus)); | ||
658 | |||
659 | spin_lock(&priv->wmi->event_lock); | ||
660 | list_add_tail(&tx_pend->list, | ||
661 | &priv->wmi->pending_tx_events); | ||
662 | spin_unlock(&priv->wmi->event_lock); | ||
285 | 663 | ||
286 | send_mac80211: | 664 | continue; |
287 | /* Send status to mac80211 */ | 665 | } |
288 | ieee80211_tx_status(priv->hw, skb); | 666 | |
667 | ath9k_htc_tx_process(priv, skb, __txs); | ||
289 | } | 668 | } |
290 | 669 | ||
291 | /* Wake TX queues if needed */ | 670 | /* Wake TX queues if needed */ |
292 | spin_lock_bh(&priv->tx_lock); | 671 | ath9k_htc_check_wake_queues(priv); |
293 | if (priv->tx_queues_stop) { | ||
294 | priv->tx_queues_stop = false; | ||
295 | spin_unlock_bh(&priv->tx_lock); | ||
296 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
297 | "Waking up TX queues\n"); | ||
298 | ieee80211_wake_queues(priv->hw); | ||
299 | return; | ||
300 | } | ||
301 | spin_unlock_bh(&priv->tx_lock); | ||
302 | } | 672 | } |
303 | 673 | ||
304 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, | 674 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, |
305 | enum htc_endpoint_id ep_id, bool txok) | 675 | enum htc_endpoint_id ep_id, bool txok) |
306 | { | 676 | { |
307 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; | 677 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; |
308 | struct ath_common *common = ath9k_hw_common(priv->ah); | 678 | struct ath9k_htc_tx_ctl *tx_ctl; |
309 | struct ieee80211_tx_info *tx_info; | 679 | struct sk_buff_head *epid_queue; |
310 | 680 | ||
311 | if (!skb) | 681 | tx_ctl = HTC_SKB_CB(skb); |
682 | tx_ctl->txok = txok; | ||
683 | tx_ctl->timestamp = jiffies; | ||
684 | |||
685 | if (!txok) { | ||
686 | skb_queue_tail(&priv->tx.tx_failed, skb); | ||
687 | tasklet_schedule(&priv->tx_failed_tasklet); | ||
312 | return; | 688 | return; |
689 | } | ||
313 | 690 | ||
314 | if (ep_id == priv->mgmt_ep) { | 691 | epid_queue = get_htc_epid_queue(priv, ep_id); |
315 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | 692 | if (!epid_queue) { |
316 | } else if ((ep_id == priv->data_bk_ep) || | ||
317 | (ep_id == priv->data_be_ep) || | ||
318 | (ep_id == priv->data_vi_ep) || | ||
319 | (ep_id == priv->data_vo_ep)) { | ||
320 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
321 | } else { | ||
322 | ath_err(common, "Unsupported TX EPID: %d\n", ep_id); | ||
323 | dev_kfree_skb_any(skb); | 693 | dev_kfree_skb_any(skb); |
324 | return; | 694 | return; |
325 | } | 695 | } |
326 | 696 | ||
327 | tx_info = IEEE80211_SKB_CB(skb); | 697 | skb_queue_tail(epid_queue, skb); |
698 | } | ||
328 | 699 | ||
329 | if (txok) | 700 | static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb) |
330 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 701 | { |
702 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
703 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
331 | 704 | ||
332 | skb_queue_tail(&priv->tx_queue, skb); | 705 | tx_ctl = HTC_SKB_CB(skb); |
333 | tasklet_schedule(&priv->tx_tasklet); | 706 | |
707 | if (time_after(jiffies, | ||
708 | tx_ctl->timestamp + | ||
709 | msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { | ||
710 | ath_dbg(common, ATH_DBG_XMIT, | ||
711 | "Dropping a packet due to TX timeout\n"); | ||
712 | return true; | ||
713 | } | ||
714 | |||
715 | return false; | ||
716 | } | ||
717 | |||
718 | static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv, | ||
719 | struct sk_buff_head *epid_queue) | ||
720 | { | ||
721 | bool process = false; | ||
722 | unsigned long flags; | ||
723 | struct sk_buff *skb, *tmp; | ||
724 | struct sk_buff_head queue; | ||
725 | |||
726 | skb_queue_head_init(&queue); | ||
727 | |||
728 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
729 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
730 | if (check_packet(priv, skb)) { | ||
731 | __skb_unlink(skb, epid_queue); | ||
732 | __skb_queue_tail(&queue, skb); | ||
733 | process = true; | ||
734 | } | ||
735 | } | ||
736 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
737 | |||
738 | if (process) { | ||
739 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
740 | __skb_unlink(skb, &queue); | ||
741 | ath9k_htc_tx_process(priv, skb, NULL); | ||
742 | } | ||
743 | } | ||
744 | } | ||
745 | |||
746 | void ath9k_htc_tx_cleanup_timer(unsigned long data) | ||
747 | { | ||
748 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data; | ||
749 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
750 | struct ath9k_htc_tx_event *event, *tmp; | ||
751 | struct sk_buff *skb; | ||
752 | |||
753 | spin_lock(&priv->wmi->event_lock); | ||
754 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
755 | |||
756 | skb = ath9k_htc_tx_get_packet(priv, &event->txs); | ||
757 | if (skb) { | ||
758 | ath_dbg(common, ATH_DBG_XMIT, | ||
759 | "Found packet for cookie: %d, epid: %d\n", | ||
760 | event->txs.cookie, | ||
761 | MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); | ||
762 | |||
763 | ath9k_htc_tx_process(priv, skb, &event->txs); | ||
764 | list_del(&event->list); | ||
765 | kfree(event); | ||
766 | continue; | ||
767 | } | ||
768 | |||
769 | if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) { | ||
770 | list_del(&event->list); | ||
771 | kfree(event); | ||
772 | } | ||
773 | } | ||
774 | spin_unlock(&priv->wmi->event_lock); | ||
775 | |||
776 | /* | ||
777 | * Check if status-pending packets have to be cleaned up. | ||
778 | */ | ||
779 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue); | ||
780 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue); | ||
781 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue); | ||
782 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue); | ||
783 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue); | ||
784 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue); | ||
785 | |||
786 | /* Wake TX queues if needed */ | ||
787 | ath9k_htc_check_wake_queues(priv); | ||
788 | |||
789 | mod_timer(&priv->tx.cleanup_timer, | ||
790 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
334 | } | 791 | } |
335 | 792 | ||
336 | int ath9k_tx_init(struct ath9k_htc_priv *priv) | 793 | int ath9k_tx_init(struct ath9k_htc_priv *priv) |
337 | { | 794 | { |
338 | skb_queue_head_init(&priv->tx_queue); | 795 | skb_queue_head_init(&priv->tx.mgmt_ep_queue); |
796 | skb_queue_head_init(&priv->tx.cab_ep_queue); | ||
797 | skb_queue_head_init(&priv->tx.data_be_queue); | ||
798 | skb_queue_head_init(&priv->tx.data_bk_queue); | ||
799 | skb_queue_head_init(&priv->tx.data_vi_queue); | ||
800 | skb_queue_head_init(&priv->tx.data_vo_queue); | ||
801 | skb_queue_head_init(&priv->tx.tx_failed); | ||
339 | return 0; | 802 | return 0; |
340 | } | 803 | } |
341 | 804 | ||
@@ -507,8 +970,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
507 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 970 | int last_rssi = ATH_RSSI_DUMMY_MARKER; |
508 | __le16 fc; | 971 | __le16 fc; |
509 | 972 | ||
510 | if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { | 973 | if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { |
511 | ath_err(common, "Corrupted RX frame, dropping\n"); | 974 | ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", |
975 | skb->len); | ||
512 | goto rx_next; | 976 | goto rx_next; |
513 | } | 977 | } |
514 | 978 | ||
@@ -522,6 +986,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
522 | goto rx_next; | 986 | goto rx_next; |
523 | } | 987 | } |
524 | 988 | ||
989 | ath9k_htc_err_stat_rx(priv, rxstatus); | ||
990 | |||
525 | /* Get the RX status information */ | 991 | /* Get the RX status information */ |
526 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | 992 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); |
527 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | 993 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 62e139a30a74..cee970fdf652 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | 19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, |
20 | u16 len, u8 flags, u8 epid, | 20 | u16 len, u8 flags, u8 epid) |
21 | struct ath9k_htc_tx_ctl *tx_ctl) | 21 | |
22 | { | 22 | { |
23 | struct htc_frame_hdr *hdr; | 23 | struct htc_frame_hdr *hdr; |
24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; | 24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; |
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | |||
30 | hdr->flags = flags; | 30 | hdr->flags = flags; |
31 | hdr->payload_len = cpu_to_be16(len); | 31 | hdr->payload_len = cpu_to_be16(len); |
32 | 32 | ||
33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, | 33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); |
34 | tx_ctl); | 34 | |
35 | return status; | 35 | return status; |
36 | } | 36 | } |
37 | 37 | ||
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target) | |||
162 | 162 | ||
163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; | 163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; |
164 | 164 | ||
165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
166 | if (ret) | 166 | if (ret) |
167 | goto err; | 167 | goto err; |
168 | 168 | ||
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target) | |||
197 | 197 | ||
198 | target->htc_flags |= HTC_OP_START_WAIT; | 198 | target->htc_flags |= HTC_OP_START_WAIT; |
199 | 199 | ||
200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
201 | if (ret) | 201 | if (ret) |
202 | goto err; | 202 | goto err; |
203 | 203 | ||
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target, | |||
268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; | 268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; |
269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; | 269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; |
270 | 270 | ||
271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
272 | if (ret) | 272 | if (ret) |
273 | goto err; | 273 | goto err; |
274 | 274 | ||
@@ -286,35 +286,33 @@ err: | |||
286 | return ret; | 286 | return ret; |
287 | } | 287 | } |
288 | 288 | ||
289 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 289 | int htc_send(struct htc_target *target, struct sk_buff *skb) |
290 | enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 290 | { |
292 | return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); | 291 | struct ath9k_htc_tx_ctl *tx_ctl; |
292 | |||
293 | tx_ctl = HTC_SKB_CB(skb); | ||
294 | return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid); | ||
293 | } | 295 | } |
294 | 296 | ||
295 | void htc_stop(struct htc_target *target) | 297 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
298 | enum htc_endpoint_id epid) | ||
296 | { | 299 | { |
297 | enum htc_endpoint_id epid; | 300 | return htc_issue_send(target, skb, skb->len, 0, epid); |
298 | struct htc_endpoint *endpoint; | 301 | } |
299 | 302 | ||
300 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 303 | void htc_stop(struct htc_target *target) |
301 | endpoint = &target->endpoint[epid]; | 304 | { |
302 | if (endpoint->service_id != 0) | 305 | target->hif->stop(target->hif_dev); |
303 | target->hif->stop(target->hif_dev, endpoint->ul_pipeid); | ||
304 | } | ||
305 | } | 306 | } |
306 | 307 | ||
307 | void htc_start(struct htc_target *target) | 308 | void htc_start(struct htc_target *target) |
308 | { | 309 | { |
309 | enum htc_endpoint_id epid; | 310 | target->hif->start(target->hif_dev); |
310 | struct htc_endpoint *endpoint; | 311 | } |
311 | 312 | ||
312 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 313 | void htc_sta_drain(struct htc_target *target, u8 idx) |
313 | endpoint = &target->endpoint[epid]; | 314 | { |
314 | if (endpoint->service_id != 0) | 315 | target->hif->sta_drain(target->hif_dev, idx); |
315 | target->hif->start(target->hif_dev, | ||
316 | endpoint->ul_pipeid); | ||
317 | } | ||
318 | } | 316 | } |
319 | 317 | ||
320 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | 318 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index ecd018798c47..cb9174ade53e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -33,10 +33,10 @@ struct ath9k_htc_hif { | |||
33 | u8 control_dl_pipe; | 33 | u8 control_dl_pipe; |
34 | u8 control_ul_pipe; | 34 | u8 control_ul_pipe; |
35 | 35 | ||
36 | void (*start) (void *hif_handle, u8 pipe); | 36 | void (*start) (void *hif_handle); |
37 | void (*stop) (void *hif_handle, u8 pipe); | 37 | void (*stop) (void *hif_handle); |
38 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, | 38 | void (*sta_drain) (void *hif_handle, u8 idx); |
39 | struct ath9k_htc_tx_ctl *tx_ctl); | 39 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | enum htc_endpoint_id { | 42 | enum htc_endpoint_id { |
@@ -205,10 +205,12 @@ int htc_init(struct htc_target *target); | |||
205 | int htc_connect_service(struct htc_target *target, | 205 | int htc_connect_service(struct htc_target *target, |
206 | struct htc_service_connreq *service_connreq, | 206 | struct htc_service_connreq *service_connreq, |
207 | enum htc_endpoint_id *conn_rsp_eid); | 207 | enum htc_endpoint_id *conn_rsp_eid); |
208 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 208 | int htc_send(struct htc_target *target, struct sk_buff *skb); |
209 | enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); | 209 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
210 | enum htc_endpoint_id epid); | ||
210 | void htc_stop(struct htc_target *target); | 211 | void htc_stop(struct htc_target *target); |
211 | void htc_start(struct htc_target *target); | 212 | void htc_start(struct htc_target *target); |
213 | void htc_sta_drain(struct htc_target *target, u8 idx); | ||
212 | 214 | ||
213 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, | 215 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, |
214 | struct sk_buff *skb, u32 len, u8 pipe_id); | 216 | struct sk_buff *skb, u32 len, u8 pipe_id); |
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 22ee888b0baf..9dd90a85ad63 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -122,6 +122,11 @@ static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | |||
122 | ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); | 122 | ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); |
123 | } | 123 | } |
124 | 124 | ||
125 | static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) | ||
126 | { | ||
127 | ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); | ||
128 | } | ||
129 | |||
125 | /* Private hardware call ops */ | 130 | /* Private hardware call ops */ |
126 | 131 | ||
127 | /* PHY ops */ | 132 | /* PHY ops */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c8a2d0dae796..045abd557840 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -676,42 +676,55 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | |||
676 | } | 676 | } |
677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | 677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); |
678 | 678 | ||
679 | #define DPLL2_KD_VAL 0x3D | 679 | #define DPLL3_PHASE_SHIFT_VAL 0x1 |
680 | #define DPLL2_KI_VAL 0x06 | ||
681 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
682 | |||
683 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 680 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
684 | struct ath9k_channel *chan) | 681 | struct ath9k_channel *chan) |
685 | { | 682 | { |
686 | u32 pll; | 683 | u32 pll; |
687 | 684 | ||
688 | if (AR_SREV_9485(ah)) { | 685 | if (AR_SREV_9485(ah)) { |
689 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | ||
690 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); | ||
691 | |||
692 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | ||
693 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
694 | 686 | ||
695 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 687 | /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ |
696 | udelay(1000); | 688 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
689 | AR_CH0_BB_DPLL2_PLL_PWD, 0x1); | ||
690 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
691 | AR_CH0_DPLL2_KD, 0x40); | ||
692 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
693 | AR_CH0_DPLL2_KI, 0x4); | ||
697 | 694 | ||
698 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | 695 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, |
696 | AR_CH0_BB_DPLL1_REFDIV, 0x5); | ||
697 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
698 | AR_CH0_BB_DPLL1_NINI, 0x58); | ||
699 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
700 | AR_CH0_BB_DPLL1_NFRAC, 0x0); | ||
699 | 701 | ||
700 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 702 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
701 | AR_CH0_DPLL2_KD, DPLL2_KD_VAL); | 703 | AR_CH0_BB_DPLL2_OUTDIV, 0x1); |
704 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
705 | AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); | ||
702 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 706 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
703 | AR_CH0_DPLL2_KI, DPLL2_KI_VAL); | 707 | AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); |
704 | 708 | ||
709 | /* program BB PLL phase_shift to 0x6 */ | ||
705 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 710 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, |
706 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 711 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); |
707 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); | 712 | |
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
714 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | ||
708 | udelay(1000); | 715 | udelay(1000); |
716 | |||
717 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||
718 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
709 | } | 719 | } |
710 | 720 | ||
711 | pll = ath9k_hw_compute_pll_control(ah, chan); | 721 | pll = ath9k_hw_compute_pll_control(ah, chan); |
712 | 722 | ||
713 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 723 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
714 | 724 | ||
725 | if (AR_SREV_9485(ah)) | ||
726 | udelay(1000); | ||
727 | |||
715 | /* Switch the core clock for ar9271 to 117Mhz */ | 728 | /* Switch the core clock for ar9271 to 117Mhz */ |
716 | if (AR_SREV_9271(ah)) { | 729 | if (AR_SREV_9271(ah)) { |
717 | udelay(500); | 730 | udelay(500); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a778b66f4438..1018d6cbd530 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -626,6 +626,7 @@ struct ath_hw_ops { | |||
626 | void (*clr11n_aggr)(struct ath_hw *ah, void *ds); | 626 | void (*clr11n_aggr)(struct ath_hw *ah, void *ds); |
627 | void (*set11n_burstduration)(struct ath_hw *ah, void *ds, | 627 | void (*set11n_burstduration)(struct ath_hw *ah, void *ds, |
628 | u32 burstDuration); | 628 | u32 burstDuration); |
629 | void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); | ||
629 | }; | 630 | }; |
630 | 631 | ||
631 | struct ath_nf_limits { | 632 | struct ath_nf_limits { |
@@ -846,6 +847,14 @@ struct ath_hw { | |||
846 | u32 ent_mode; | 847 | u32 ent_mode; |
847 | }; | 848 | }; |
848 | 849 | ||
850 | struct ath_bus_ops { | ||
851 | enum ath_bus_type ath_bus_type; | ||
852 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
853 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
854 | void (*bt_coex_prep)(struct ath_common *common); | ||
855 | void (*extn_synch_en)(struct ath_common *common); | ||
856 | }; | ||
857 | |||
849 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) | 858 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
850 | { | 859 | { |
851 | return &ah->common; | 860 | return &ah->common; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index c2a59386fb9c..b60c130917f7 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -239,7 +239,6 @@ struct ath_desc { | |||
239 | void *ds_vdata; | 239 | void *ds_vdata; |
240 | } __packed __aligned(4); | 240 | } __packed __aligned(4); |
241 | 241 | ||
242 | #define ATH9K_TXDESC_CLRDMASK 0x0001 | ||
243 | #define ATH9K_TXDESC_NOACK 0x0002 | 242 | #define ATH9K_TXDESC_NOACK 0x0002 |
244 | #define ATH9K_TXDESC_RTSENA 0x0004 | 243 | #define ATH9K_TXDESC_RTSENA 0x0004 |
245 | #define ATH9K_TXDESC_CTSENA 0x0008 | 244 | #define ATH9K_TXDESC_CTSENA 0x0008 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4c5c9997dac6..a8d9009a76d5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1373,6 +1373,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1373 | if ((iter_data.naps + iter_data.nadhocs) > 0) { | 1373 | if ((iter_data.naps + iter_data.nadhocs) > 0) { |
1374 | sc->sc_flags |= SC_OP_ANI_RUN; | 1374 | sc->sc_flags |= SC_OP_ANI_RUN; |
1375 | ath_start_ani(common); | 1375 | ath_start_ani(common); |
1376 | } else { | ||
1377 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
1378 | del_timer_sync(&common->ani.timer); | ||
1376 | } | 1379 | } |
1377 | } | 1380 | } |
1378 | 1381 | ||
@@ -1733,23 +1736,63 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1733 | struct ieee80211_sta *sta) | 1736 | struct ieee80211_sta *sta) |
1734 | { | 1737 | { |
1735 | struct ath_softc *sc = hw->priv; | 1738 | struct ath_softc *sc = hw->priv; |
1739 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1740 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1741 | struct ieee80211_key_conf ps_key = { }; | ||
1736 | 1742 | ||
1737 | ath_node_attach(sc, sta); | 1743 | ath_node_attach(sc, sta); |
1744 | an->ps_key = ath_key_config(common, vif, sta, &ps_key); | ||
1738 | 1745 | ||
1739 | return 0; | 1746 | return 0; |
1740 | } | 1747 | } |
1741 | 1748 | ||
1749 | static void ath9k_del_ps_key(struct ath_softc *sc, | ||
1750 | struct ieee80211_vif *vif, | ||
1751 | struct ieee80211_sta *sta) | ||
1752 | { | ||
1753 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1754 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1755 | struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; | ||
1756 | |||
1757 | if (!an->ps_key) | ||
1758 | return; | ||
1759 | |||
1760 | ath_key_delete(common, &ps_key); | ||
1761 | } | ||
1762 | |||
1742 | static int ath9k_sta_remove(struct ieee80211_hw *hw, | 1763 | static int ath9k_sta_remove(struct ieee80211_hw *hw, |
1743 | struct ieee80211_vif *vif, | 1764 | struct ieee80211_vif *vif, |
1744 | struct ieee80211_sta *sta) | 1765 | struct ieee80211_sta *sta) |
1745 | { | 1766 | { |
1746 | struct ath_softc *sc = hw->priv; | 1767 | struct ath_softc *sc = hw->priv; |
1747 | 1768 | ||
1769 | ath9k_del_ps_key(sc, vif, sta); | ||
1748 | ath_node_detach(sc, sta); | 1770 | ath_node_detach(sc, sta); |
1749 | 1771 | ||
1750 | return 0; | 1772 | return 0; |
1751 | } | 1773 | } |
1752 | 1774 | ||
1775 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | ||
1776 | struct ieee80211_vif *vif, | ||
1777 | enum sta_notify_cmd cmd, | ||
1778 | struct ieee80211_sta *sta) | ||
1779 | { | ||
1780 | struct ath_softc *sc = hw->priv; | ||
1781 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1782 | |||
1783 | switch (cmd) { | ||
1784 | case STA_NOTIFY_SLEEP: | ||
1785 | an->sleeping = true; | ||
1786 | if (ath_tx_aggr_sleep(sc, an)) | ||
1787 | ieee80211_sta_set_tim(sta); | ||
1788 | break; | ||
1789 | case STA_NOTIFY_AWAKE: | ||
1790 | an->sleeping = false; | ||
1791 | ath_tx_aggr_wakeup(sc, an); | ||
1792 | break; | ||
1793 | } | ||
1794 | } | ||
1795 | |||
1753 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1796 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
1754 | const struct ieee80211_tx_queue_params *params) | 1797 | const struct ieee80211_tx_queue_params *params) |
1755 | { | 1798 | { |
@@ -1826,6 +1869,9 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1826 | 1869 | ||
1827 | switch (cmd) { | 1870 | switch (cmd) { |
1828 | case SET_KEY: | 1871 | case SET_KEY: |
1872 | if (sta) | ||
1873 | ath9k_del_ps_key(sc, vif, sta); | ||
1874 | |||
1829 | ret = ath_key_config(common, vif, sta, key); | 1875 | ret = ath_key_config(common, vif, sta, key); |
1830 | if (ret >= 0) { | 1876 | if (ret >= 0) { |
1831 | key->hw_key_idx = ret; | 1877 | key->hw_key_idx = ret; |
@@ -2209,6 +2255,21 @@ out: | |||
2209 | ath9k_ps_restore(sc); | 2255 | ath9k_ps_restore(sc); |
2210 | } | 2256 | } |
2211 | 2257 | ||
2258 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | ||
2259 | { | ||
2260 | struct ath_softc *sc = hw->priv; | ||
2261 | int i; | ||
2262 | |||
2263 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2264 | if (!ATH_TXQ_SETUP(sc, i)) | ||
2265 | continue; | ||
2266 | |||
2267 | if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) | ||
2268 | return true; | ||
2269 | } | ||
2270 | return false; | ||
2271 | } | ||
2272 | |||
2212 | struct ieee80211_ops ath9k_ops = { | 2273 | struct ieee80211_ops ath9k_ops = { |
2213 | .tx = ath9k_tx, | 2274 | .tx = ath9k_tx, |
2214 | .start = ath9k_start, | 2275 | .start = ath9k_start, |
@@ -2220,6 +2281,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2220 | .configure_filter = ath9k_configure_filter, | 2281 | .configure_filter = ath9k_configure_filter, |
2221 | .sta_add = ath9k_sta_add, | 2282 | .sta_add = ath9k_sta_add, |
2222 | .sta_remove = ath9k_sta_remove, | 2283 | .sta_remove = ath9k_sta_remove, |
2284 | .sta_notify = ath9k_sta_notify, | ||
2223 | .conf_tx = ath9k_conf_tx, | 2285 | .conf_tx = ath9k_conf_tx, |
2224 | .bss_info_changed = ath9k_bss_info_changed, | 2286 | .bss_info_changed = ath9k_bss_info_changed, |
2225 | .set_key = ath9k_set_key, | 2287 | .set_key = ath9k_set_key, |
@@ -2231,4 +2293,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2231 | .rfkill_poll = ath9k_rfkill_poll_state, | 2293 | .rfkill_poll = ath9k_rfkill_poll_state, |
2232 | .set_coverage_class = ath9k_set_coverage_class, | 2294 | .set_coverage_class = ath9k_set_coverage_class, |
2233 | .flush = ath9k_flush, | 2295 | .flush = ath9k_flush, |
2296 | .tx_frames_pending = ath9k_tx_frames_pending, | ||
2234 | }; | 2297 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index f50e2c29f71e..8e5fe9d7f174 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #define CHANSEL_DIV 15 | 20 | #define CHANSEL_DIV 15 |
21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) | 21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) |
22 | #define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV) | ||
23 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) | 22 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) |
24 | 23 | ||
25 | #define AR_PHY_BASE 0x9800 | 24 | #define AR_PHY_BASE 0x9800 |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 4c0d36a6980f..18094094b298 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1092,8 +1092,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | |||
1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) | 1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) |
1093 | return rate->idx; | 1093 | return rate->idx; |
1094 | 1094 | ||
1095 | while (rate->idx > mcs_rix_off[i] && | 1095 | while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { |
1096 | i < ARRAY_SIZE(mcs_rix_off)) { | ||
1097 | rix++; i++; | 1096 | rix++; i++; |
1098 | } | 1097 | } |
1099 | 1098 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index cfaf0a48b939..642504f9638c 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | |||
75 | *sc->rx.rxlink = bf->bf_daddr; | 75 | *sc->rx.rxlink = bf->bf_daddr; |
76 | 76 | ||
77 | sc->rx.rxlink = &ds->ds_link; | 77 | sc->rx.rxlink = &ds->ds_link; |
78 | ath9k_hw_rxena(ah); | ||
79 | } | 78 | } |
80 | 79 | ||
81 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) | 80 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) |
@@ -426,9 +425,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
426 | else | 425 | else |
427 | rfilt |= ATH9K_RX_FILTER_BEACON; | 426 | rfilt |= ATH9K_RX_FILTER_BEACON; |
428 | 427 | ||
429 | if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || | 428 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
430 | AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && | ||
431 | (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | ||
432 | (sc->rx.rxfilter & FIF_PSPOLL)) | 429 | (sc->rx.rxfilter & FIF_PSPOLL)) |
433 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 430 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
434 | 431 | ||
@@ -1767,6 +1764,7 @@ requeue: | |||
1767 | } else { | 1764 | } else { |
1768 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 1765 | list_move_tail(&bf->list, &sc->rx.rxbuf); |
1769 | ath_rx_buf_link(sc, bf); | 1766 | ath_rx_buf_link(sc, bf); |
1767 | ath9k_hw_rxena(ah); | ||
1770 | } | 1768 | } |
1771 | } while (1); | 1769 | } while (1); |
1772 | 1770 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 693d543937b5..6acbf0e2240b 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -858,9 +858,7 @@ | |||
858 | #define AR_SREV_9300(_ah) \ | 858 | #define AR_SREV_9300(_ah) \ |
859 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) | 859 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) |
860 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | 860 | #define AR_SREV_9300_20_OR_LATER(_ah) \ |
861 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ | 861 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) |
862 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ | ||
863 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) | ||
864 | 862 | ||
865 | #define AR_SREV_9485(_ah) \ | 863 | #define AR_SREV_9485(_ah) \ |
866 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) | 864 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) |
@@ -1088,14 +1086,35 @@ enum { | |||
1088 | #define AR_ENT_OTP 0x40d8 | 1086 | #define AR_ENT_OTP 0x40d8 |
1089 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1087 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1090 | #define AR_ENT_OTP_MPSD 0x00800000 | 1088 | #define AR_ENT_OTP_MPSD 0x00800000 |
1091 | #define AR_CH0_BB_DPLL2 0x16184 | 1089 | |
1090 | #define AR_CH0_BB_DPLL1 0x16180 | ||
1091 | #define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 | ||
1092 | #define AR_CH0_BB_DPLL1_REFDIV_S 27 | ||
1093 | #define AR_CH0_BB_DPLL1_NINI 0x07FC0000 | ||
1094 | #define AR_CH0_BB_DPLL1_NINI_S 18 | ||
1095 | #define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF | ||
1096 | #define AR_CH0_BB_DPLL1_NFRAC_S 0 | ||
1097 | |||
1098 | #define AR_CH0_BB_DPLL2 0x16184 | ||
1099 | #define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000 | ||
1100 | #define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30 | ||
1101 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1102 | #define AR_CH0_DPLL2_KI_S 26 | ||
1103 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1104 | #define AR_CH0_DPLL2_KD_S 19 | ||
1105 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000 | ||
1106 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18 | ||
1107 | #define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000 | ||
1108 | #define AR_CH0_BB_DPLL2_PLL_PWD_S 16 | ||
1109 | #define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000 | ||
1110 | #define AR_CH0_BB_DPLL2_OUTDIV_S 13 | ||
1111 | |||
1092 | #define AR_CH0_BB_DPLL3 0x16188 | 1112 | #define AR_CH0_BB_DPLL3 0x16188 |
1113 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000 | ||
1114 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23 | ||
1115 | |||
1093 | #define AR_CH0_DDR_DPLL2 0x16244 | 1116 | #define AR_CH0_DDR_DPLL2 0x16244 |
1094 | #define AR_CH0_DDR_DPLL3 0x16248 | 1117 | #define AR_CH0_DDR_DPLL3 0x16248 |
1095 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1096 | #define AR_CH0_DPLL2_KD_S 19 | ||
1097 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1098 | #define AR_CH0_DPLL2_KI_S 26 | ||
1099 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 | 1118 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 |
1100 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 | 1119 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 |
1101 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 | 1120 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index d3d24904f62f..8f095ad0a3db 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
23 | return "WMI_ECHO_CMDID"; | 23 | return "WMI_ECHO_CMDID"; |
24 | case WMI_ACCESS_MEMORY_CMDID: | 24 | case WMI_ACCESS_MEMORY_CMDID: |
25 | return "WMI_ACCESS_MEMORY_CMDID"; | 25 | return "WMI_ACCESS_MEMORY_CMDID"; |
26 | case WMI_GET_FW_VERSION: | ||
27 | return "WMI_GET_FW_VERSION"; | ||
26 | case WMI_DISABLE_INTR_CMDID: | 28 | case WMI_DISABLE_INTR_CMDID: |
27 | return "WMI_DISABLE_INTR_CMDID"; | 29 | return "WMI_DISABLE_INTR_CMDID"; |
28 | case WMI_ENABLE_INTR_CMDID: | 30 | case WMI_ENABLE_INTR_CMDID: |
29 | return "WMI_ENABLE_INTR_CMDID"; | 31 | return "WMI_ENABLE_INTR_CMDID"; |
30 | case WMI_RX_LINK_CMDID: | ||
31 | return "WMI_RX_LINK_CMDID"; | ||
32 | case WMI_ATH_INIT_CMDID: | 32 | case WMI_ATH_INIT_CMDID: |
33 | return "WMI_ATH_INIT_CMDID"; | 33 | return "WMI_ATH_INIT_CMDID"; |
34 | case WMI_ABORT_TXQ_CMDID: | 34 | case WMI_ABORT_TXQ_CMDID: |
35 | return "WMI_ABORT_TXQ_CMDID"; | 35 | return "WMI_ABORT_TXQ_CMDID"; |
36 | case WMI_STOP_TX_DMA_CMDID: | 36 | case WMI_STOP_TX_DMA_CMDID: |
37 | return "WMI_STOP_TX_DMA_CMDID"; | 37 | return "WMI_STOP_TX_DMA_CMDID"; |
38 | case WMI_STOP_DMA_RECV_CMDID: | ||
39 | return "WMI_STOP_DMA_RECV_CMDID"; | ||
40 | case WMI_ABORT_TX_DMA_CMDID: | 38 | case WMI_ABORT_TX_DMA_CMDID: |
41 | return "WMI_ABORT_TX_DMA_CMDID"; | 39 | return "WMI_ABORT_TX_DMA_CMDID"; |
42 | case WMI_DRAIN_TXQ_CMDID: | 40 | case WMI_DRAIN_TXQ_CMDID: |
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
51 | return "WMI_FLUSH_RECV_CMDID"; | 49 | return "WMI_FLUSH_RECV_CMDID"; |
52 | case WMI_SET_MODE_CMDID: | 50 | case WMI_SET_MODE_CMDID: |
53 | return "WMI_SET_MODE_CMDID"; | 51 | return "WMI_SET_MODE_CMDID"; |
54 | case WMI_RESET_CMDID: | ||
55 | return "WMI_RESET_CMDID"; | ||
56 | case WMI_NODE_CREATE_CMDID: | 52 | case WMI_NODE_CREATE_CMDID: |
57 | return "WMI_NODE_CREATE_CMDID"; | 53 | return "WMI_NODE_CREATE_CMDID"; |
58 | case WMI_NODE_REMOVE_CMDID: | 54 | case WMI_NODE_REMOVE_CMDID: |
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
61 | return "WMI_VAP_REMOVE_CMDID"; | 57 | return "WMI_VAP_REMOVE_CMDID"; |
62 | case WMI_VAP_CREATE_CMDID: | 58 | case WMI_VAP_CREATE_CMDID: |
63 | return "WMI_VAP_CREATE_CMDID"; | 59 | return "WMI_VAP_CREATE_CMDID"; |
64 | case WMI_BEACON_UPDATE_CMDID: | ||
65 | return "WMI_BEACON_UPDATE_CMDID"; | ||
66 | case WMI_REG_READ_CMDID: | 60 | case WMI_REG_READ_CMDID: |
67 | return "WMI_REG_READ_CMDID"; | 61 | return "WMI_REG_READ_CMDID"; |
68 | case WMI_REG_WRITE_CMDID: | 62 | case WMI_REG_WRITE_CMDID: |
@@ -71,20 +65,20 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
71 | return "WMI_RC_STATE_CHANGE_CMDID"; | 65 | return "WMI_RC_STATE_CHANGE_CMDID"; |
72 | case WMI_RC_RATE_UPDATE_CMDID: | 66 | case WMI_RC_RATE_UPDATE_CMDID: |
73 | return "WMI_RC_RATE_UPDATE_CMDID"; | 67 | return "WMI_RC_RATE_UPDATE_CMDID"; |
74 | case WMI_DEBUG_INFO_CMDID: | ||
75 | return "WMI_DEBUG_INFO_CMDID"; | ||
76 | case WMI_HOST_ATTACH: | ||
77 | return "WMI_HOST_ATTACH"; | ||
78 | case WMI_TARGET_IC_UPDATE_CMDID: | 68 | case WMI_TARGET_IC_UPDATE_CMDID: |
79 | return "WMI_TARGET_IC_UPDATE_CMDID"; | 69 | return "WMI_TARGET_IC_UPDATE_CMDID"; |
80 | case WMI_TGT_STATS_CMDID: | ||
81 | return "WMI_TGT_STATS_CMDID"; | ||
82 | case WMI_TX_AGGR_ENABLE_CMDID: | 70 | case WMI_TX_AGGR_ENABLE_CMDID: |
83 | return "WMI_TX_AGGR_ENABLE_CMDID"; | 71 | return "WMI_TX_AGGR_ENABLE_CMDID"; |
84 | case WMI_TGT_DETACH_CMDID: | 72 | case WMI_TGT_DETACH_CMDID: |
85 | return "WMI_TGT_DETACH_CMDID"; | 73 | return "WMI_TGT_DETACH_CMDID"; |
86 | case WMI_TGT_TXQ_ENABLE_CMDID: | 74 | case WMI_NODE_UPDATE_CMDID: |
87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; | 75 | return "WMI_NODE_UPDATE_CMDID"; |
76 | case WMI_INT_STATS_CMDID: | ||
77 | return "WMI_INT_STATS_CMDID"; | ||
78 | case WMI_TX_STATS_CMDID: | ||
79 | return "WMI_TX_STATS_CMDID"; | ||
80 | case WMI_RX_STATS_CMDID: | ||
81 | return "WMI_RX_STATS_CMDID"; | ||
88 | case WMI_AGGR_LIMIT_CMD: | 82 | case WMI_AGGR_LIMIT_CMD: |
89 | return "WMI_AGGR_LIMIT_CMD"; | 83 | return "WMI_AGGR_LIMIT_CMD"; |
90 | } | 84 | } |
@@ -102,9 +96,15 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) | |||
102 | 96 | ||
103 | wmi->drv_priv = priv; | 97 | wmi->drv_priv = priv; |
104 | wmi->stopped = false; | 98 | wmi->stopped = false; |
99 | skb_queue_head_init(&wmi->wmi_event_queue); | ||
100 | spin_lock_init(&wmi->wmi_lock); | ||
101 | spin_lock_init(&wmi->event_lock); | ||
105 | mutex_init(&wmi->op_mutex); | 102 | mutex_init(&wmi->op_mutex); |
106 | mutex_init(&wmi->multi_write_mutex); | 103 | mutex_init(&wmi->multi_write_mutex); |
107 | init_completion(&wmi->cmd_wait); | 104 | init_completion(&wmi->cmd_wait); |
105 | INIT_LIST_HEAD(&wmi->pending_tx_events); | ||
106 | tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, | ||
107 | (unsigned long)wmi); | ||
108 | 108 | ||
109 | return wmi; | 109 | return wmi; |
110 | } | 110 | } |
@@ -120,11 +120,65 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) | |||
120 | kfree(priv->wmi); | 120 | kfree(priv->wmi); |
121 | } | 121 | } |
122 | 122 | ||
123 | void ath9k_swba_tasklet(unsigned long data) | 123 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) |
124 | { | 124 | { |
125 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 125 | unsigned long flags; |
126 | 126 | ||
127 | ath9k_htc_swba(priv, priv->wmi->beacon_pending); | 127 | tasklet_kill(&priv->wmi->wmi_event_tasklet); |
128 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); | ||
129 | __skb_queue_purge(&priv->wmi->wmi_event_queue); | ||
130 | spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); | ||
131 | } | ||
132 | |||
133 | void ath9k_wmi_event_tasklet(unsigned long data) | ||
134 | { | ||
135 | struct wmi *wmi = (struct wmi *)data; | ||
136 | struct ath9k_htc_priv *priv = wmi->drv_priv; | ||
137 | struct wmi_cmd_hdr *hdr; | ||
138 | void *wmi_event; | ||
139 | struct wmi_event_swba *swba; | ||
140 | struct sk_buff *skb = NULL; | ||
141 | unsigned long flags; | ||
142 | u16 cmd_id; | ||
143 | |||
144 | do { | ||
145 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
146 | skb = __skb_dequeue(&wmi->wmi_event_queue); | ||
147 | if (!skb) { | ||
148 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
149 | return; | ||
150 | } | ||
151 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
152 | |||
153 | hdr = (struct wmi_cmd_hdr *) skb->data; | ||
154 | cmd_id = be16_to_cpu(hdr->command_id); | ||
155 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | ||
156 | |||
157 | switch (cmd_id) { | ||
158 | case WMI_SWBA_EVENTID: | ||
159 | swba = (struct wmi_event_swba *) wmi_event; | ||
160 | ath9k_htc_swba(priv, swba); | ||
161 | break; | ||
162 | case WMI_FATAL_EVENTID: | ||
163 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
164 | &wmi->drv_priv->fatal_work); | ||
165 | break; | ||
166 | case WMI_TXSTATUS_EVENTID: | ||
167 | spin_lock_bh(&priv->tx.tx_lock); | ||
168 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
169 | spin_unlock_bh(&priv->tx.tx_lock); | ||
170 | break; | ||
171 | } | ||
172 | spin_unlock_bh(&priv->tx.tx_lock); | ||
173 | |||
174 | ath9k_htc_txstatus(priv, wmi_event); | ||
175 | break; | ||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | |||
180 | kfree_skb(skb); | ||
181 | } while (1); | ||
128 | } | 182 | } |
129 | 183 | ||
130 | void ath9k_fatal_work(struct work_struct *work) | 184 | void ath9k_fatal_work(struct work_struct *work) |
@@ -153,10 +207,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
153 | struct wmi *wmi = (struct wmi *) priv; | 207 | struct wmi *wmi = (struct wmi *) priv; |
154 | struct wmi_cmd_hdr *hdr; | 208 | struct wmi_cmd_hdr *hdr; |
155 | u16 cmd_id; | 209 | u16 cmd_id; |
156 | void *wmi_event; | ||
157 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
158 | __be32 txrate; | ||
159 | #endif | ||
160 | 210 | ||
161 | if (unlikely(wmi->stopped)) | 211 | if (unlikely(wmi->stopped)) |
162 | goto free_skb; | 212 | goto free_skb; |
@@ -165,26 +215,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
165 | cmd_id = be16_to_cpu(hdr->command_id); | 215 | cmd_id = be16_to_cpu(hdr->command_id); |
166 | 216 | ||
167 | if (cmd_id & 0x1000) { | 217 | if (cmd_id & 0x1000) { |
168 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | 218 | spin_lock(&wmi->wmi_lock); |
169 | switch (cmd_id) { | 219 | __skb_queue_tail(&wmi->wmi_event_queue, skb); |
170 | case WMI_SWBA_EVENTID: | 220 | spin_unlock(&wmi->wmi_lock); |
171 | wmi->beacon_pending = *(u8 *)wmi_event; | 221 | tasklet_schedule(&wmi->wmi_event_tasklet); |
172 | tasklet_schedule(&wmi->drv_priv->swba_tasklet); | ||
173 | break; | ||
174 | case WMI_FATAL_EVENTID: | ||
175 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
176 | &wmi->drv_priv->fatal_work); | ||
177 | break; | ||
178 | case WMI_TXRATE_EVENTID: | ||
179 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
180 | txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; | ||
181 | wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); | ||
182 | #endif | ||
183 | break; | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | kfree_skb(skb); | ||
188 | return; | 222 | return; |
189 | } | 223 | } |
190 | 224 | ||
@@ -243,7 +277,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, | |||
243 | hdr->command_id = cpu_to_be16(cmd); | 277 | hdr->command_id = cpu_to_be16(cmd); |
244 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); | 278 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); |
245 | 279 | ||
246 | return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); | 280 | return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); |
247 | } | 281 | } |
248 | 282 | ||
249 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | 283 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 42084277522d..02ecb9f06db0 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #ifndef WMI_H | 17 | #ifndef WMI_H |
18 | #define WMI_H | 18 | #define WMI_H |
19 | 19 | ||
20 | |||
21 | struct wmi_event_txrate { | 20 | struct wmi_event_txrate { |
22 | __be32 txrate; | 21 | __be32 txrate; |
23 | struct { | 22 | struct { |
@@ -31,18 +30,65 @@ struct wmi_cmd_hdr { | |||
31 | __be16 seq_no; | 30 | __be16 seq_no; |
32 | } __packed; | 31 | } __packed; |
33 | 32 | ||
33 | struct wmi_fw_version { | ||
34 | __be16 major; | ||
35 | __be16 minor; | ||
36 | |||
37 | } __packed; | ||
38 | |||
39 | struct wmi_event_swba { | ||
40 | __be64 tsf; | ||
41 | u8 beacon_pending; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * 64 - HTC header - WMI header - 1 / txstatus | ||
46 | * And some other hdr. space is also accounted for. | ||
47 | * 12 seems to be the magic number. | ||
48 | */ | ||
49 | #define HTC_MAX_TX_STATUS 12 | ||
50 | |||
51 | #define ATH9K_HTC_TXSTAT_ACK BIT(0) | ||
52 | #define ATH9K_HTC_TXSTAT_FILT BIT(1) | ||
53 | #define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2) | ||
54 | #define ATH9K_HTC_TXSTAT_MCS BIT(3) | ||
55 | #define ATH9K_HTC_TXSTAT_CW40 BIT(4) | ||
56 | #define ATH9K_HTC_TXSTAT_SGI BIT(5) | ||
57 | |||
58 | /* | ||
59 | * Legacy rates are indicated as indices. | ||
60 | * HT rates are indicated as dot11 numbers. | ||
61 | * This allows us to resrict the rate field | ||
62 | * to 4 bits. | ||
63 | */ | ||
64 | #define ATH9K_HTC_TXSTAT_RATE 0x0f | ||
65 | #define ATH9K_HTC_TXSTAT_RATE_S 0 | ||
66 | |||
67 | #define ATH9K_HTC_TXSTAT_EPID 0xf0 | ||
68 | #define ATH9K_HTC_TXSTAT_EPID_S 4 | ||
69 | |||
70 | struct __wmi_event_txstatus { | ||
71 | u8 cookie; | ||
72 | u8 ts_rate; /* Also holds EP ID */ | ||
73 | u8 ts_flags; | ||
74 | }; | ||
75 | |||
76 | struct wmi_event_txstatus { | ||
77 | u8 cnt; | ||
78 | struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS]; | ||
79 | } __packed; | ||
80 | |||
34 | enum wmi_cmd_id { | 81 | enum wmi_cmd_id { |
35 | WMI_ECHO_CMDID = 0x0001, | 82 | WMI_ECHO_CMDID = 0x0001, |
36 | WMI_ACCESS_MEMORY_CMDID, | 83 | WMI_ACCESS_MEMORY_CMDID, |
37 | 84 | ||
38 | /* Commands to Target */ | 85 | /* Commands to Target */ |
86 | WMI_GET_FW_VERSION, | ||
39 | WMI_DISABLE_INTR_CMDID, | 87 | WMI_DISABLE_INTR_CMDID, |
40 | WMI_ENABLE_INTR_CMDID, | 88 | WMI_ENABLE_INTR_CMDID, |
41 | WMI_RX_LINK_CMDID, | ||
42 | WMI_ATH_INIT_CMDID, | 89 | WMI_ATH_INIT_CMDID, |
43 | WMI_ABORT_TXQ_CMDID, | 90 | WMI_ABORT_TXQ_CMDID, |
44 | WMI_STOP_TX_DMA_CMDID, | 91 | WMI_STOP_TX_DMA_CMDID, |
45 | WMI_STOP_DMA_RECV_CMDID, | ||
46 | WMI_ABORT_TX_DMA_CMDID, | 92 | WMI_ABORT_TX_DMA_CMDID, |
47 | WMI_DRAIN_TXQ_CMDID, | 93 | WMI_DRAIN_TXQ_CMDID, |
48 | WMI_DRAIN_TXQ_ALL_CMDID, | 94 | WMI_DRAIN_TXQ_ALL_CMDID, |
@@ -50,23 +96,21 @@ enum wmi_cmd_id { | |||
50 | WMI_STOP_RECV_CMDID, | 96 | WMI_STOP_RECV_CMDID, |
51 | WMI_FLUSH_RECV_CMDID, | 97 | WMI_FLUSH_RECV_CMDID, |
52 | WMI_SET_MODE_CMDID, | 98 | WMI_SET_MODE_CMDID, |
53 | WMI_RESET_CMDID, | ||
54 | WMI_NODE_CREATE_CMDID, | 99 | WMI_NODE_CREATE_CMDID, |
55 | WMI_NODE_REMOVE_CMDID, | 100 | WMI_NODE_REMOVE_CMDID, |
56 | WMI_VAP_REMOVE_CMDID, | 101 | WMI_VAP_REMOVE_CMDID, |
57 | WMI_VAP_CREATE_CMDID, | 102 | WMI_VAP_CREATE_CMDID, |
58 | WMI_BEACON_UPDATE_CMDID, | ||
59 | WMI_REG_READ_CMDID, | 103 | WMI_REG_READ_CMDID, |
60 | WMI_REG_WRITE_CMDID, | 104 | WMI_REG_WRITE_CMDID, |
61 | WMI_RC_STATE_CHANGE_CMDID, | 105 | WMI_RC_STATE_CHANGE_CMDID, |
62 | WMI_RC_RATE_UPDATE_CMDID, | 106 | WMI_RC_RATE_UPDATE_CMDID, |
63 | WMI_DEBUG_INFO_CMDID, | ||
64 | WMI_HOST_ATTACH, | ||
65 | WMI_TARGET_IC_UPDATE_CMDID, | 107 | WMI_TARGET_IC_UPDATE_CMDID, |
66 | WMI_TGT_STATS_CMDID, | ||
67 | WMI_TX_AGGR_ENABLE_CMDID, | 108 | WMI_TX_AGGR_ENABLE_CMDID, |
68 | WMI_TGT_DETACH_CMDID, | 109 | WMI_TGT_DETACH_CMDID, |
69 | WMI_TGT_TXQ_ENABLE_CMDID, | 110 | WMI_NODE_UPDATE_CMDID, |
111 | WMI_INT_STATS_CMDID, | ||
112 | WMI_TX_STATS_CMDID, | ||
113 | WMI_RX_STATS_CMDID, | ||
70 | WMI_AGGR_LIMIT_CMD = 0x0026, | 114 | WMI_AGGR_LIMIT_CMD = 0x0026, |
71 | }; | 115 | }; |
72 | 116 | ||
@@ -76,9 +120,8 @@ enum wmi_event_id { | |||
76 | WMI_FATAL_EVENTID, | 120 | WMI_FATAL_EVENTID, |
77 | WMI_TXTO_EVENTID, | 121 | WMI_TXTO_EVENTID, |
78 | WMI_BMISS_EVENTID, | 122 | WMI_BMISS_EVENTID, |
79 | WMI_WLAN_TXCOMP_EVENTID, | ||
80 | WMI_DELBA_EVENTID, | 123 | WMI_DELBA_EVENTID, |
81 | WMI_TXRATE_EVENTID, | 124 | WMI_TXSTATUS_EVENTID, |
82 | }; | 125 | }; |
83 | 126 | ||
84 | #define MAX_CMD_NUMBER 62 | 127 | #define MAX_CMD_NUMBER 62 |
@@ -88,6 +131,12 @@ struct register_write { | |||
88 | __be32 val; | 131 | __be32 val; |
89 | }; | 132 | }; |
90 | 133 | ||
134 | struct ath9k_htc_tx_event { | ||
135 | int count; | ||
136 | struct __wmi_event_txstatus txs; | ||
137 | struct list_head list; | ||
138 | }; | ||
139 | |||
91 | struct wmi { | 140 | struct wmi { |
92 | struct ath9k_htc_priv *drv_priv; | 141 | struct ath9k_htc_priv *drv_priv; |
93 | struct htc_target *htc; | 142 | struct htc_target *htc; |
@@ -95,12 +144,16 @@ struct wmi { | |||
95 | struct mutex op_mutex; | 144 | struct mutex op_mutex; |
96 | struct completion cmd_wait; | 145 | struct completion cmd_wait; |
97 | enum wmi_cmd_id last_cmd_id; | 146 | enum wmi_cmd_id last_cmd_id; |
147 | struct sk_buff_head wmi_event_queue; | ||
148 | struct tasklet_struct wmi_event_tasklet; | ||
98 | u16 tx_seq_id; | 149 | u16 tx_seq_id; |
99 | u8 *cmd_rsp_buf; | 150 | u8 *cmd_rsp_buf; |
100 | u32 cmd_rsp_len; | 151 | u32 cmd_rsp_len; |
101 | bool stopped; | 152 | bool stopped; |
102 | 153 | ||
103 | u8 beacon_pending; | 154 | struct list_head pending_tx_events; |
155 | spinlock_t event_lock; | ||
156 | |||
104 | spinlock_t wmi_lock; | 157 | spinlock_t wmi_lock; |
105 | 158 | ||
106 | atomic_t mwrite_cnt; | 159 | atomic_t mwrite_cnt; |
@@ -117,8 +170,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
117 | u8 *cmd_buf, u32 cmd_len, | 170 | u8 *cmd_buf, u32 cmd_len, |
118 | u8 *rsp_buf, u32 rsp_len, | 171 | u8 *rsp_buf, u32 rsp_len, |
119 | u32 timeout); | 172 | u32 timeout); |
120 | void ath9k_swba_tasklet(unsigned long data); | 173 | void ath9k_wmi_event_tasklet(unsigned long data); |
121 | void ath9k_fatal_work(struct work_struct *work); | 174 | void ath9k_fatal_work(struct work_struct *work); |
175 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); | ||
122 | 176 | ||
123 | #define WMI_CMD(_wmi_cmd) \ | 177 | #define WMI_CMD(_wmi_cmd) \ |
124 | do { \ | 178 | do { \ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3cea3f76e373..e9e99f730ca8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
357 | struct ath_frame_info *fi; | 357 | struct ath_frame_info *fi; |
358 | int nframes; | 358 | int nframes; |
359 | u8 tidno; | 359 | u8 tidno; |
360 | bool clear_filter; | ||
360 | 361 | ||
361 | skb = bf->bf_mpdu; | 362 | skb = bf->bf_mpdu; |
362 | hdr = (struct ieee80211_hdr *)skb->data; | 363 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -441,22 +442,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
441 | /* transmit completion */ | 442 | /* transmit completion */ |
442 | acked_cnt++; | 443 | acked_cnt++; |
443 | } else { | 444 | } else { |
444 | if (!(tid->state & AGGR_CLEANUP) && retry) { | 445 | if ((tid->state & AGGR_CLEANUP) || !retry) { |
445 | if (fi->retries < ATH_MAX_SW_RETRIES) { | ||
446 | ath_tx_set_retry(sc, txq, bf->bf_mpdu); | ||
447 | txpending = 1; | ||
448 | } else { | ||
449 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
450 | txfail = 1; | ||
451 | sendbar = 1; | ||
452 | txfail_cnt++; | ||
453 | } | ||
454 | } else { | ||
455 | /* | 446 | /* |
456 | * cleanup in progress, just fail | 447 | * cleanup in progress, just fail |
457 | * the un-acked sub-frames | 448 | * the un-acked sub-frames |
458 | */ | 449 | */ |
459 | txfail = 1; | 450 | txfail = 1; |
451 | } else if (fi->retries < ATH_MAX_SW_RETRIES) { | ||
452 | if (!(ts->ts_status & ATH9K_TXERR_FILT) || | ||
453 | !an->sleeping) | ||
454 | ath_tx_set_retry(sc, txq, bf->bf_mpdu); | ||
455 | |||
456 | clear_filter = true; | ||
457 | txpending = 1; | ||
458 | } else { | ||
459 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
460 | txfail = 1; | ||
461 | sendbar = 1; | ||
462 | txfail_cnt++; | ||
460 | } | 463 | } |
461 | } | 464 | } |
462 | 465 | ||
@@ -496,6 +499,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
496 | !txfail, sendbar); | 499 | !txfail, sendbar); |
497 | } else { | 500 | } else { |
498 | /* retry the un-acked ones */ | 501 | /* retry the un-acked ones */ |
502 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); | ||
499 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { | 503 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { |
500 | if (bf->bf_next == NULL && bf_last->bf_stale) { | 504 | if (bf->bf_next == NULL && bf_last->bf_stale) { |
501 | struct ath_buf *tbf; | 505 | struct ath_buf *tbf; |
@@ -546,7 +550,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
546 | 550 | ||
547 | /* prepend un-acked frames to the beginning of the pending frame queue */ | 551 | /* prepend un-acked frames to the beginning of the pending frame queue */ |
548 | if (!list_empty(&bf_pending)) { | 552 | if (!list_empty(&bf_pending)) { |
553 | if (an->sleeping) | ||
554 | ieee80211_sta_set_tim(sta); | ||
555 | |||
549 | spin_lock_bh(&txq->axq_lock); | 556 | spin_lock_bh(&txq->axq_lock); |
557 | if (clear_filter) | ||
558 | tid->ac->clear_ps_filter = true; | ||
550 | list_splice(&bf_pending, &tid->buf_q); | 559 | list_splice(&bf_pending, &tid->buf_q); |
551 | ath_tx_queue_tid(txq, tid); | 560 | ath_tx_queue_tid(txq, tid); |
552 | spin_unlock_bh(&txq->axq_lock); | 561 | spin_unlock_bh(&txq->axq_lock); |
@@ -816,6 +825,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
816 | bf = list_first_entry(&bf_q, struct ath_buf, list); | 825 | bf = list_first_entry(&bf_q, struct ath_buf, list); |
817 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); | 826 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); |
818 | 827 | ||
828 | if (tid->ac->clear_ps_filter) { | ||
829 | tid->ac->clear_ps_filter = false; | ||
830 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | ||
831 | } | ||
832 | |||
819 | /* if only one frame, send as non-aggregate */ | 833 | /* if only one frame, send as non-aggregate */ |
820 | if (bf == bf->bf_lastbf) { | 834 | if (bf == bf->bf_lastbf) { |
821 | fi = get_frame_info(bf->bf_mpdu); | 835 | fi = get_frame_info(bf->bf_mpdu); |
@@ -896,6 +910,67 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
896 | ath_tx_flush_tid(sc, txtid); | 910 | ath_tx_flush_tid(sc, txtid); |
897 | } | 911 | } |
898 | 912 | ||
913 | bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) | ||
914 | { | ||
915 | struct ath_atx_tid *tid; | ||
916 | struct ath_atx_ac *ac; | ||
917 | struct ath_txq *txq; | ||
918 | bool buffered = false; | ||
919 | int tidno; | ||
920 | |||
921 | for (tidno = 0, tid = &an->tid[tidno]; | ||
922 | tidno < WME_NUM_TID; tidno++, tid++) { | ||
923 | |||
924 | if (!tid->sched) | ||
925 | continue; | ||
926 | |||
927 | ac = tid->ac; | ||
928 | txq = ac->txq; | ||
929 | |||
930 | spin_lock_bh(&txq->axq_lock); | ||
931 | |||
932 | if (!list_empty(&tid->buf_q)) | ||
933 | buffered = true; | ||
934 | |||
935 | tid->sched = false; | ||
936 | list_del(&tid->list); | ||
937 | |||
938 | if (ac->sched) { | ||
939 | ac->sched = false; | ||
940 | list_del(&ac->list); | ||
941 | } | ||
942 | |||
943 | spin_unlock_bh(&txq->axq_lock); | ||
944 | } | ||
945 | |||
946 | return buffered; | ||
947 | } | ||
948 | |||
949 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | ||
950 | { | ||
951 | struct ath_atx_tid *tid; | ||
952 | struct ath_atx_ac *ac; | ||
953 | struct ath_txq *txq; | ||
954 | int tidno; | ||
955 | |||
956 | for (tidno = 0, tid = &an->tid[tidno]; | ||
957 | tidno < WME_NUM_TID; tidno++, tid++) { | ||
958 | |||
959 | ac = tid->ac; | ||
960 | txq = ac->txq; | ||
961 | |||
962 | spin_lock_bh(&txq->axq_lock); | ||
963 | ac->clear_ps_filter = true; | ||
964 | |||
965 | if (!list_empty(&tid->buf_q) && !tid->paused) { | ||
966 | ath_tx_queue_tid(txq, tid); | ||
967 | ath_txq_schedule(sc, txq); | ||
968 | } | ||
969 | |||
970 | spin_unlock_bh(&txq->axq_lock); | ||
971 | } | ||
972 | } | ||
973 | |||
899 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 974 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
900 | { | 975 | { |
901 | struct ath_atx_tid *txtid; | 976 | struct ath_atx_tid *txtid; |
@@ -1451,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1451 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 1526 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
1452 | struct ieee80211_hdr *hdr; | 1527 | struct ieee80211_hdr *hdr; |
1453 | struct ath_frame_info *fi = get_frame_info(skb); | 1528 | struct ath_frame_info *fi = get_frame_info(skb); |
1454 | struct ath_node *an; | 1529 | struct ath_node *an = NULL; |
1455 | struct ath_atx_tid *tid; | 1530 | struct ath_atx_tid *tid; |
1456 | enum ath9k_key_type keytype; | 1531 | enum ath9k_key_type keytype; |
1457 | u16 seqno = 0; | 1532 | u16 seqno = 0; |
@@ -1459,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1459 | 1534 | ||
1460 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); | 1535 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); |
1461 | 1536 | ||
1537 | if (sta) | ||
1538 | an = (struct ath_node *) sta->drv_priv; | ||
1539 | |||
1462 | hdr = (struct ieee80211_hdr *)skb->data; | 1540 | hdr = (struct ieee80211_hdr *)skb->data; |
1463 | if (sta && ieee80211_is_data_qos(hdr->frame_control) && | 1541 | if (an && ieee80211_is_data_qos(hdr->frame_control) && |
1464 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { | 1542 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { |
1465 | 1543 | ||
1466 | an = (struct ath_node *) sta->drv_priv; | ||
1467 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; | 1544 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
1468 | 1545 | ||
1469 | /* | 1546 | /* |
@@ -1479,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1479 | memset(fi, 0, sizeof(*fi)); | 1556 | memset(fi, 0, sizeof(*fi)); |
1480 | if (hw_key) | 1557 | if (hw_key) |
1481 | fi->keyix = hw_key->hw_key_idx; | 1558 | fi->keyix = hw_key->hw_key_idx; |
1559 | else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) | ||
1560 | fi->keyix = an->ps_key; | ||
1482 | else | 1561 | else |
1483 | fi->keyix = ATH9K_TXKEYIX_INVALID; | 1562 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
1484 | fi->keytype = keytype; | 1563 | fi->keytype = keytype; |
@@ -1491,7 +1570,6 @@ static int setup_tx_flags(struct sk_buff *skb) | |||
1491 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1570 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1492 | int flags = 0; | 1571 | int flags = 0; |
1493 | 1572 | ||
1494 | flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ | ||
1495 | flags |= ATH9K_TXDESC_INTREQ; | 1573 | flags |= ATH9K_TXDESC_INTREQ; |
1496 | 1574 | ||
1497 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | 1575 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) |
@@ -1754,6 +1832,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1754 | if (txctl->paprd) | 1832 | if (txctl->paprd) |
1755 | bf->bf_state.bfs_paprd_timestamp = jiffies; | 1833 | bf->bf_state.bfs_paprd_timestamp = jiffies; |
1756 | 1834 | ||
1835 | if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | ||
1836 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | ||
1837 | |||
1757 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); | 1838 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); |
1758 | } | 1839 | } |
1759 | 1840 | ||
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 0d4f39cbdcab..a61ef3d6d89c 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c | |||
@@ -483,6 +483,9 @@ int ath_key_config(struct ath_common *common, | |||
483 | memset(&hk, 0, sizeof(hk)); | 483 | memset(&hk, 0, sizeof(hk)); |
484 | 484 | ||
485 | switch (key->cipher) { | 485 | switch (key->cipher) { |
486 | case 0: | ||
487 | hk.kv_type = ATH_CIPHER_CLR; | ||
488 | break; | ||
486 | case WLAN_CIPHER_SUITE_WEP40: | 489 | case WLAN_CIPHER_SUITE_WEP40: |
487 | case WLAN_CIPHER_SUITE_WEP104: | 490 | case WLAN_CIPHER_SUITE_WEP104: |
488 | hk.kv_type = ATH_CIPHER_WEP; | 491 | hk.kv_type = ATH_CIPHER_WEP; |
@@ -498,7 +501,8 @@ int ath_key_config(struct ath_common *common, | |||
498 | } | 501 | } |
499 | 502 | ||
500 | hk.kv_len = key->keylen; | 503 | hk.kv_len = key->keylen; |
501 | memcpy(hk.kv_val, key->key, key->keylen); | 504 | if (key->keylen) |
505 | memcpy(hk.kv_val, key->key, key->keylen); | ||
502 | 506 | ||
503 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | 507 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
504 | switch (vif->type) { | 508 | switch (vif->type) { |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 0e1b8793c864..028310f263c8 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { | |||
97 | } | 97 | } |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Can be used by 0x67, 0x6A and 0x68 */ | 100 | /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ |
101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { | 101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { |
102 | .n_reg_rules = 4, | 102 | .n_reg_rules = 4, |
103 | .alpha2 = "99", | 103 | .alpha2 = "99", |
104 | .reg_rules = { | 104 | .reg_rules = { |
@@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) | |||
151 | case 0x67: | 151 | case 0x67: |
152 | case 0x68: | 152 | case 0x68: |
153 | case 0x6A: | 153 | case 0x6A: |
154 | return &ath_world_regdom_67_68_6A; | 154 | case 0x6C: |
155 | return &ath_world_regdom_67_68_6A_6C; | ||
155 | default: | 156 | default: |
156 | WARN_ON(1); | 157 | WARN_ON(1); |
157 | return ath_default_world_regdomain(); | 158 | return ath_default_world_regdomain(); |
@@ -333,6 +334,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, | |||
333 | case 0x63: | 334 | case 0x63: |
334 | case 0x66: | 335 | case 0x66: |
335 | case 0x67: | 336 | case 0x67: |
337 | case 0x6C: | ||
336 | ath_reg_apply_beaconing_flags(wiphy, initiator); | 338 | ath_reg_apply_beaconing_flags(wiphy, initiator); |
337 | break; | 339 | break; |
338 | case 0x68: | 340 | case 0x68: |
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h index 5c2cfe694152..24b53839fc3a 100644 --- a/drivers/net/wireless/ath/regd_common.h +++ b/drivers/net/wireless/ath/regd_common.h | |||
@@ -86,6 +86,7 @@ enum EnumRd { | |||
86 | WOR9_WORLD = 0x69, | 86 | WOR9_WORLD = 0x69, |
87 | WORA_WORLD = 0x6A, | 87 | WORA_WORLD = 0x6A, |
88 | WORB_WORLD = 0x6B, | 88 | WORB_WORLD = 0x6B, |
89 | WORC_WORLD = 0x6C, | ||
89 | 90 | ||
90 | MKK3_MKKB = 0x80, | 91 | MKK3_MKKB = 0x80, |
91 | MKK3_MKKA2 = 0x81, | 92 | MKK3_MKKA2 = 0x81, |
@@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { | |||
282 | {WOR9_WORLD, NO_CTL, NO_CTL}, | 283 | {WOR9_WORLD, NO_CTL, NO_CTL}, |
283 | {WORA_WORLD, NO_CTL, NO_CTL}, | 284 | {WORA_WORLD, NO_CTL, NO_CTL}, |
284 | {WORB_WORLD, NO_CTL, NO_CTL}, | 285 | {WORB_WORLD, NO_CTL, NO_CTL}, |
286 | {WORC_WORLD, NO_CTL, NO_CTL}, | ||
285 | }; | 287 | }; |
286 | 288 | ||
287 | static struct country_code_to_enum_rd allCountries[] = { | 289 | static struct country_code_to_enum_rd allCountries[] = { |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 31ac672b64e1..89509392ef5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c | |||
@@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = { | |||
2860 | 2860 | ||
2861 | int iwl4965_rate_control_register(void) | 2861 | int iwl4965_rate_control_register(void) |
2862 | { | 2862 | { |
2863 | pr_err("Registering 4965 rate control operations\n"); | ||
2864 | return ieee80211_rate_control_register(&rs_4965_ops); | 2863 | return ieee80211_rate_control_register(&rs_4965_ops); |
2865 | } | 2864 | } |
2866 | 2865 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index d484c3678163..f8870543d68f 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c | |||
@@ -3173,7 +3173,7 @@ static void iwl4965_hw_detect(struct iwl_priv *priv) | |||
3173 | { | 3173 | { |
3174 | priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV); | 3174 | priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV); |
3175 | priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG); | 3175 | priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG); |
3176 | pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); | 3176 | priv->rev_id = priv->pci_dev->revision; |
3177 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); | 3177 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); |
3178 | } | 3178 | } |
3179 | 3179 | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 3652931753e0..bb6a737de61f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # AGN | 1 | # AGN |
2 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 2 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
3 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o | 3 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o |
4 | iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o | 4 | iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o |
5 | iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o | 5 | iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o |
6 | iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o | 6 | iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1b2799291834..baf80111efaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "iwl-agn.h" | 45 | #include "iwl-agn.h" |
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-agn-led.h" | ||
49 | #include "iwl-agn-debugfs.h" | 48 | #include "iwl-agn-debugfs.h" |
50 | 49 | ||
51 | /* Highest firmware API version supported */ | 50 | /* Highest firmware API version supported */ |
@@ -57,12 +56,10 @@ | |||
57 | #define IWL100_UCODE_API_MIN 5 | 56 | #define IWL100_UCODE_API_MIN 5 |
58 | 57 | ||
59 | #define IWL1000_FW_PRE "iwlwifi-1000-" | 58 | #define IWL1000_FW_PRE "iwlwifi-1000-" |
60 | #define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" | 59 | #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" |
61 | #define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) | ||
62 | 60 | ||
63 | #define IWL100_FW_PRE "iwlwifi-100-" | 61 | #define IWL100_FW_PRE "iwlwifi-100-" |
64 | #define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" | 62 | #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" |
65 | #define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) | ||
66 | 63 | ||
67 | 64 | ||
68 | /* | 65 | /* |
@@ -184,10 +181,6 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
184 | .rx_handler_setup = iwlagn_rx_handler_setup, | 181 | .rx_handler_setup = iwlagn_rx_handler_setup, |
185 | .setup_deferred_work = iwlagn_setup_deferred_work, | 182 | .setup_deferred_work = iwlagn_setup_deferred_work, |
186 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 183 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
187 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
188 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
189 | .dump_csr = iwl_dump_csr, | ||
190 | .dump_fh = iwl_dump_fh, | ||
191 | .send_tx_power = iwlagn_send_tx_power, | 184 | .send_tx_power = iwlagn_send_tx_power, |
192 | .update_chain_flags = iwl_update_chain_flags, | 185 | .update_chain_flags = iwl_update_chain_flags, |
193 | .apm_ops = { | 186 | .apm_ops = { |
@@ -202,7 +195,7 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
202 | EEPROM_REG_BAND_4_CHANNELS, | 195 | EEPROM_REG_BAND_4_CHANNELS, |
203 | EEPROM_REG_BAND_5_CHANNELS, | 196 | EEPROM_REG_BAND_5_CHANNELS, |
204 | EEPROM_REG_BAND_24_HT40_CHANNELS, | 197 | EEPROM_REG_BAND_24_HT40_CHANNELS, |
205 | EEPROM_REG_BAND_52_HT40_CHANNELS | 198 | EEPROM_REGULATORY_BAND_NO_HT40, |
206 | }, | 199 | }, |
207 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | 200 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, |
208 | .release_semaphore = iwlcore_eeprom_release_semaphore, | 201 | .release_semaphore = iwlcore_eeprom_release_semaphore, |
@@ -221,19 +214,12 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
221 | }, | 214 | }, |
222 | .txfifo_flush = iwlagn_txfifo_flush, | 215 | .txfifo_flush = iwlagn_txfifo_flush, |
223 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 216 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
224 | .tt_ops = { | ||
225 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
226 | .tt_power_mode = iwl_tt_current_power_mode, | ||
227 | .ct_kill_check = iwl_check_for_ct_kill, | ||
228 | } | ||
229 | }; | 217 | }; |
230 | 218 | ||
231 | static const struct iwl_ops iwl1000_ops = { | 219 | static const struct iwl_ops iwl1000_ops = { |
232 | .lib = &iwl1000_lib, | 220 | .lib = &iwl1000_lib, |
233 | .hcmd = &iwlagn_hcmd, | 221 | .hcmd = &iwlagn_hcmd, |
234 | .utils = &iwlagn_hcmd_utils, | 222 | .utils = &iwlagn_hcmd_utils, |
235 | .led = &iwlagn_led_ops, | ||
236 | .ieee80211_ops = &iwlagn_hw_ops, | ||
237 | }; | 223 | }; |
238 | 224 | ||
239 | static struct iwl_base_params iwl1000_base_params = { | 225 | static struct iwl_base_params iwl1000_base_params = { |
@@ -241,7 +227,6 @@ static struct iwl_base_params iwl1000_base_params = { | |||
241 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 227 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
242 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 228 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
243 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, | 229 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
244 | .set_l0s = true, | ||
245 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, | 230 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, |
246 | .shadow_ram_support = false, | 231 | .shadow_ram_support = false, |
247 | .led_compensation = 51, | 232 | .led_compensation = 51, |
@@ -251,9 +236,6 @@ static struct iwl_base_params iwl1000_base_params = { | |||
251 | .chain_noise_scale = 1000, | 236 | .chain_noise_scale = 1000, |
252 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 237 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
253 | .max_event_log_size = 128, | 238 | .max_event_log_size = 128, |
254 | .ucode_tracing = true, | ||
255 | .sensitivity_calib_by_driver = true, | ||
256 | .chain_noise_calib_by_driver = true, | ||
257 | }; | 239 | }; |
258 | static struct iwl_ht_params iwl1000_ht_params = { | 240 | static struct iwl_ht_params iwl1000_ht_params = { |
259 | .ht_greenfield_support = true, | 241 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index f602af4b9408..e76e02c28928 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-6000-hw.h" | 48 | #include "iwl-6000-hw.h" |
49 | #include "iwl-agn-led.h" | ||
50 | #include "iwl-agn-debugfs.h" | 49 | #include "iwl-agn-debugfs.h" |
51 | 50 | ||
52 | /* Highest firmware API version supported */ | 51 | /* Highest firmware API version supported */ |
@@ -60,16 +59,13 @@ | |||
60 | #define IWL200_UCODE_API_MIN 5 | 59 | #define IWL200_UCODE_API_MIN 5 |
61 | 60 | ||
62 | #define IWL2030_FW_PRE "iwlwifi-2030-" | 61 | #define IWL2030_FW_PRE "iwlwifi-2030-" |
63 | #define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" | 62 | #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" |
64 | #define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api) | ||
65 | 63 | ||
66 | #define IWL2000_FW_PRE "iwlwifi-2000-" | 64 | #define IWL2000_FW_PRE "iwlwifi-2000-" |
67 | #define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" | 65 | #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" |
68 | #define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api) | ||
69 | 66 | ||
70 | #define IWL200_FW_PRE "iwlwifi-200-" | 67 | #define IWL200_FW_PRE "iwlwifi-200-" |
71 | #define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" | 68 | #define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" |
72 | #define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api) | ||
73 | 69 | ||
74 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | 70 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) |
75 | { | 71 | { |
@@ -101,6 +97,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) | |||
101 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | 97 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, |
102 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 98 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
103 | 99 | ||
100 | if (priv->cfg->disable_otp_refresh) | ||
101 | iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010); | ||
104 | } | 102 | } |
105 | 103 | ||
106 | static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | 104 | static struct iwl_sensitivity_ranges iwl2000_sensitivity = { |
@@ -265,10 +263,6 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
265 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 263 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
266 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 264 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
267 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 265 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
268 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
269 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
270 | .dump_csr = iwl_dump_csr, | ||
271 | .dump_fh = iwl_dump_fh, | ||
272 | .send_tx_power = iwlagn_send_tx_power, | 266 | .send_tx_power = iwlagn_send_tx_power, |
273 | .update_chain_flags = iwl_update_chain_flags, | 267 | .update_chain_flags = iwl_update_chain_flags, |
274 | .set_channel_switch = iwl2030_hw_channel_switch, | 268 | .set_channel_switch = iwl2030_hw_channel_switch, |
@@ -284,7 +278,7 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
284 | EEPROM_REG_BAND_4_CHANNELS, | 278 | EEPROM_REG_BAND_4_CHANNELS, |
285 | EEPROM_REG_BAND_5_CHANNELS, | 279 | EEPROM_REG_BAND_5_CHANNELS, |
286 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 280 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
287 | EEPROM_REG_BAND_52_HT40_CHANNELS | 281 | EEPROM_REGULATORY_BAND_NO_HT40, |
288 | }, | 282 | }, |
289 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | 283 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, |
290 | .release_semaphore = iwlcore_eeprom_release_semaphore, | 284 | .release_semaphore = iwlcore_eeprom_release_semaphore, |
@@ -304,43 +298,30 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
304 | }, | 298 | }, |
305 | .txfifo_flush = iwlagn_txfifo_flush, | 299 | .txfifo_flush = iwlagn_txfifo_flush, |
306 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 300 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
307 | .tt_ops = { | ||
308 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
309 | .tt_power_mode = iwl_tt_current_power_mode, | ||
310 | .ct_kill_check = iwl_check_for_ct_kill, | ||
311 | } | ||
312 | }; | 301 | }; |
313 | 302 | ||
314 | static const struct iwl_ops iwl2000_ops = { | 303 | static const struct iwl_ops iwl2000_ops = { |
315 | .lib = &iwl2000_lib, | 304 | .lib = &iwl2000_lib, |
316 | .hcmd = &iwlagn_hcmd, | 305 | .hcmd = &iwlagn_hcmd, |
317 | .utils = &iwlagn_hcmd_utils, | 306 | .utils = &iwlagn_hcmd_utils, |
318 | .led = &iwlagn_led_ops, | ||
319 | .ieee80211_ops = &iwlagn_hw_ops, | ||
320 | }; | 307 | }; |
321 | 308 | ||
322 | static const struct iwl_ops iwl2030_ops = { | 309 | static const struct iwl_ops iwl2030_ops = { |
323 | .lib = &iwl2000_lib, | 310 | .lib = &iwl2000_lib, |
324 | .hcmd = &iwlagn_bt_hcmd, | 311 | .hcmd = &iwlagn_bt_hcmd, |
325 | .utils = &iwlagn_hcmd_utils, | 312 | .utils = &iwlagn_hcmd_utils, |
326 | .led = &iwlagn_led_ops, | ||
327 | .ieee80211_ops = &iwlagn_hw_ops, | ||
328 | }; | 313 | }; |
329 | 314 | ||
330 | static const struct iwl_ops iwl200_ops = { | 315 | static const struct iwl_ops iwl200_ops = { |
331 | .lib = &iwl2000_lib, | 316 | .lib = &iwl2000_lib, |
332 | .hcmd = &iwlagn_hcmd, | 317 | .hcmd = &iwlagn_hcmd, |
333 | .utils = &iwlagn_hcmd_utils, | 318 | .utils = &iwlagn_hcmd_utils, |
334 | .led = &iwlagn_led_ops, | ||
335 | .ieee80211_ops = &iwlagn_hw_ops, | ||
336 | }; | 319 | }; |
337 | 320 | ||
338 | static const struct iwl_ops iwl230_ops = { | 321 | static const struct iwl_ops iwl230_ops = { |
339 | .lib = &iwl2000_lib, | 322 | .lib = &iwl2000_lib, |
340 | .hcmd = &iwlagn_bt_hcmd, | 323 | .hcmd = &iwlagn_bt_hcmd, |
341 | .utils = &iwlagn_hcmd_utils, | 324 | .utils = &iwlagn_hcmd_utils, |
342 | .led = &iwlagn_led_ops, | ||
343 | .ieee80211_ops = &iwlagn_hw_ops, | ||
344 | }; | 325 | }; |
345 | 326 | ||
346 | static struct iwl_base_params iwl2000_base_params = { | 327 | static struct iwl_base_params iwl2000_base_params = { |
@@ -348,7 +329,6 @@ static struct iwl_base_params iwl2000_base_params = { | |||
348 | .num_of_queues = IWLAGN_NUM_QUEUES, | 329 | .num_of_queues = IWLAGN_NUM_QUEUES, |
349 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 330 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
350 | .pll_cfg_val = 0, | 331 | .pll_cfg_val = 0, |
351 | .set_l0s = true, | ||
352 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, | 332 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, |
353 | .shadow_ram_support = true, | 333 | .shadow_ram_support = true, |
354 | .led_compensation = 51, | 334 | .led_compensation = 51, |
@@ -359,9 +339,6 @@ static struct iwl_base_params iwl2000_base_params = { | |||
359 | .chain_noise_scale = 1000, | 339 | .chain_noise_scale = 1000, |
360 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 340 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
361 | .max_event_log_size = 512, | 341 | .max_event_log_size = 512, |
362 | .ucode_tracing = true, | ||
363 | .sensitivity_calib_by_driver = true, | ||
364 | .chain_noise_calib_by_driver = true, | ||
365 | .shadow_reg_enable = true, | 342 | .shadow_reg_enable = true, |
366 | }; | 343 | }; |
367 | 344 | ||
@@ -371,7 +348,6 @@ static struct iwl_base_params iwl2030_base_params = { | |||
371 | .num_of_queues = IWLAGN_NUM_QUEUES, | 348 | .num_of_queues = IWLAGN_NUM_QUEUES, |
372 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 349 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
373 | .pll_cfg_val = 0, | 350 | .pll_cfg_val = 0, |
374 | .set_l0s = true, | ||
375 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, | 351 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, |
376 | .shadow_ram_support = true, | 352 | .shadow_ram_support = true, |
377 | .led_compensation = 57, | 353 | .led_compensation = 57, |
@@ -382,9 +358,6 @@ static struct iwl_base_params iwl2030_base_params = { | |||
382 | .chain_noise_scale = 1000, | 358 | .chain_noise_scale = 1000, |
383 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 359 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
384 | .max_event_log_size = 512, | 360 | .max_event_log_size = 512, |
385 | .ucode_tracing = true, | ||
386 | .sensitivity_calib_by_driver = true, | ||
387 | .chain_noise_calib_by_driver = true, | ||
388 | .shadow_reg_enable = true, | 361 | .shadow_reg_enable = true, |
389 | }; | 362 | }; |
390 | 363 | ||
@@ -394,7 +367,6 @@ static struct iwl_ht_params iwl2000_ht_params = { | |||
394 | }; | 367 | }; |
395 | 368 | ||
396 | static struct iwl_bt_params iwl2030_bt_params = { | 369 | static struct iwl_bt_params iwl2030_bt_params = { |
397 | .bt_statistics = true, | ||
398 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 370 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
399 | .advanced_bt_coexist = true, | 371 | .advanced_bt_coexist = true, |
400 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 372 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
@@ -416,7 +388,8 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
416 | .need_dc_calib = true, \ | 388 | .need_dc_calib = true, \ |
417 | .need_temp_offset_calib = true, \ | 389 | .need_temp_offset_calib = true, \ |
418 | .led_mode = IWL_LED_RF_STATE, \ | 390 | .led_mode = IWL_LED_RF_STATE, \ |
419 | .iq_invert = true \ | 391 | .iq_invert = true, \ |
392 | .disable_otp_refresh = true \ | ||
420 | 393 | ||
421 | struct iwl_cfg iwl2000_2bgn_cfg = { | 394 | struct iwl_cfg iwl2000_2bgn_cfg = { |
422 | .name = "2000 Series 2x2 BGN", | 395 | .name = "2000 Series 2x2 BGN", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 66f5fe8fe1ac..655afc19f68f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "iwl-sta.h" | 45 | #include "iwl-sta.h" |
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn.h" | 47 | #include "iwl-agn.h" |
48 | #include "iwl-agn-led.h" | ||
49 | #include "iwl-agn-hw.h" | 48 | #include "iwl-agn-hw.h" |
50 | #include "iwl-5000-hw.h" | 49 | #include "iwl-5000-hw.h" |
51 | #include "iwl-agn-debugfs.h" | 50 | #include "iwl-agn-debugfs.h" |
@@ -59,12 +58,10 @@ | |||
59 | #define IWL5150_UCODE_API_MIN 1 | 58 | #define IWL5150_UCODE_API_MIN 1 |
60 | 59 | ||
61 | #define IWL5000_FW_PRE "iwlwifi-5000-" | 60 | #define IWL5000_FW_PRE "iwlwifi-5000-" |
62 | #define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" | 61 | #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" |
63 | #define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api) | ||
64 | 62 | ||
65 | #define IWL5150_FW_PRE "iwlwifi-5150-" | 63 | #define IWL5150_FW_PRE "iwlwifi-5150-" |
66 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" | 64 | #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" |
67 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) | ||
68 | 65 | ||
69 | /* NIC configuration for 5000 series */ | 66 | /* NIC configuration for 5000 series */ |
70 | static void iwl5000_nic_config(struct iwl_priv *priv) | 67 | static void iwl5000_nic_config(struct iwl_priv *priv) |
@@ -261,7 +258,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) | |||
261 | u32 vt = 0; | 258 | u32 vt = 0; |
262 | s32 offset = iwl_temp_calib_to_offset(priv); | 259 | s32 offset = iwl_temp_calib_to_offset(priv); |
263 | 260 | ||
264 | vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); | 261 | vt = le32_to_cpu(priv->statistics.common.temperature); |
265 | vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; | 262 | vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; |
266 | /* now vt hold the temperature in Kelvin */ | 263 | /* now vt hold the temperature in Kelvin */ |
267 | priv->temperature = KELVIN_TO_CELSIUS(vt); | 264 | priv->temperature = KELVIN_TO_CELSIUS(vt); |
@@ -352,10 +349,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
352 | .rx_handler_setup = iwlagn_rx_handler_setup, | 349 | .rx_handler_setup = iwlagn_rx_handler_setup, |
353 | .setup_deferred_work = iwlagn_setup_deferred_work, | 350 | .setup_deferred_work = iwlagn_setup_deferred_work, |
354 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 351 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
355 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
356 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
357 | .dump_csr = iwl_dump_csr, | ||
358 | .dump_fh = iwl_dump_fh, | ||
359 | .send_tx_power = iwlagn_send_tx_power, | 352 | .send_tx_power = iwlagn_send_tx_power, |
360 | .update_chain_flags = iwl_update_chain_flags, | 353 | .update_chain_flags = iwl_update_chain_flags, |
361 | .set_channel_switch = iwl5000_hw_channel_switch, | 354 | .set_channel_switch = iwl5000_hw_channel_switch, |
@@ -390,11 +383,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
390 | }, | 383 | }, |
391 | .txfifo_flush = iwlagn_txfifo_flush, | 384 | .txfifo_flush = iwlagn_txfifo_flush, |
392 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 385 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
393 | .tt_ops = { | ||
394 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
395 | .tt_power_mode = iwl_tt_current_power_mode, | ||
396 | .ct_kill_check = iwl_check_for_ct_kill, | ||
397 | } | ||
398 | }; | 386 | }; |
399 | 387 | ||
400 | static struct iwl_lib_ops iwl5150_lib = { | 388 | static struct iwl_lib_ops iwl5150_lib = { |
@@ -408,9 +396,6 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
408 | .rx_handler_setup = iwlagn_rx_handler_setup, | 396 | .rx_handler_setup = iwlagn_rx_handler_setup, |
409 | .setup_deferred_work = iwlagn_setup_deferred_work, | 397 | .setup_deferred_work = iwlagn_setup_deferred_work, |
410 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 398 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
411 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
412 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
413 | .dump_csr = iwl_dump_csr, | ||
414 | .send_tx_power = iwlagn_send_tx_power, | 399 | .send_tx_power = iwlagn_send_tx_power, |
415 | .update_chain_flags = iwl_update_chain_flags, | 400 | .update_chain_flags = iwl_update_chain_flags, |
416 | .set_channel_switch = iwl5000_hw_channel_switch, | 401 | .set_channel_switch = iwl5000_hw_channel_switch, |
@@ -445,27 +430,18 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
445 | }, | 430 | }, |
446 | .txfifo_flush = iwlagn_txfifo_flush, | 431 | .txfifo_flush = iwlagn_txfifo_flush, |
447 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 432 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
448 | .tt_ops = { | ||
449 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
450 | .tt_power_mode = iwl_tt_current_power_mode, | ||
451 | .ct_kill_check = iwl_check_for_ct_kill, | ||
452 | } | ||
453 | }; | 433 | }; |
454 | 434 | ||
455 | static const struct iwl_ops iwl5000_ops = { | 435 | static const struct iwl_ops iwl5000_ops = { |
456 | .lib = &iwl5000_lib, | 436 | .lib = &iwl5000_lib, |
457 | .hcmd = &iwlagn_hcmd, | 437 | .hcmd = &iwlagn_hcmd, |
458 | .utils = &iwlagn_hcmd_utils, | 438 | .utils = &iwlagn_hcmd_utils, |
459 | .led = &iwlagn_led_ops, | ||
460 | .ieee80211_ops = &iwlagn_hw_ops, | ||
461 | }; | 439 | }; |
462 | 440 | ||
463 | static const struct iwl_ops iwl5150_ops = { | 441 | static const struct iwl_ops iwl5150_ops = { |
464 | .lib = &iwl5150_lib, | 442 | .lib = &iwl5150_lib, |
465 | .hcmd = &iwlagn_hcmd, | 443 | .hcmd = &iwlagn_hcmd, |
466 | .utils = &iwlagn_hcmd_utils, | 444 | .utils = &iwlagn_hcmd_utils, |
467 | .led = &iwlagn_led_ops, | ||
468 | .ieee80211_ops = &iwlagn_hw_ops, | ||
469 | }; | 445 | }; |
470 | 446 | ||
471 | static struct iwl_base_params iwl5000_base_params = { | 447 | static struct iwl_base_params iwl5000_base_params = { |
@@ -473,16 +449,12 @@ static struct iwl_base_params iwl5000_base_params = { | |||
473 | .num_of_queues = IWLAGN_NUM_QUEUES, | 449 | .num_of_queues = IWLAGN_NUM_QUEUES, |
474 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 450 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
475 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, | 451 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
476 | .set_l0s = true, | ||
477 | .led_compensation = 51, | 452 | .led_compensation = 51, |
478 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 453 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
479 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 454 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
480 | .chain_noise_scale = 1000, | 455 | .chain_noise_scale = 1000, |
481 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 456 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
482 | .max_event_log_size = 512, | 457 | .max_event_log_size = 512, |
483 | .ucode_tracing = true, | ||
484 | .sensitivity_calib_by_driver = true, | ||
485 | .chain_noise_calib_by_driver = true, | ||
486 | }; | 458 | }; |
487 | static struct iwl_ht_params iwl5000_ht_params = { | 459 | static struct iwl_ht_params iwl5000_ht_params = { |
488 | .ht_greenfield_support = true, | 460 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 24d105b29aec..905eb57f7cab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-6000-hw.h" | 48 | #include "iwl-6000-hw.h" |
49 | #include "iwl-agn-led.h" | ||
50 | #include "iwl-agn-debugfs.h" | 49 | #include "iwl-agn-debugfs.h" |
51 | 50 | ||
52 | /* Highest firmware API version supported */ | 51 | /* Highest firmware API version supported */ |
@@ -60,20 +59,16 @@ | |||
60 | #define IWL6000G2_UCODE_API_MIN 4 | 59 | #define IWL6000G2_UCODE_API_MIN 4 |
61 | 60 | ||
62 | #define IWL6000_FW_PRE "iwlwifi-6000-" | 61 | #define IWL6000_FW_PRE "iwlwifi-6000-" |
63 | #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" | 62 | #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" |
64 | #define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api) | ||
65 | 63 | ||
66 | #define IWL6050_FW_PRE "iwlwifi-6050-" | 64 | #define IWL6050_FW_PRE "iwlwifi-6050-" |
67 | #define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" | 65 | #define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" |
68 | #define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) | ||
69 | 66 | ||
70 | #define IWL6005_FW_PRE "iwlwifi-6000g2a-" | 67 | #define IWL6005_FW_PRE "iwlwifi-6000g2a-" |
71 | #define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" | 68 | #define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" |
72 | #define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api) | ||
73 | 69 | ||
74 | #define IWL6030_FW_PRE "iwlwifi-6000g2b-" | 70 | #define IWL6030_FW_PRE "iwlwifi-6000g2b-" |
75 | #define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" | 71 | #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" |
76 | #define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api) | ||
77 | 72 | ||
78 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | 73 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) |
79 | { | 74 | { |
@@ -293,10 +288,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
293 | .rx_handler_setup = iwlagn_rx_handler_setup, | 288 | .rx_handler_setup = iwlagn_rx_handler_setup, |
294 | .setup_deferred_work = iwlagn_setup_deferred_work, | 289 | .setup_deferred_work = iwlagn_setup_deferred_work, |
295 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 290 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
296 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
297 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
298 | .dump_csr = iwl_dump_csr, | ||
299 | .dump_fh = iwl_dump_fh, | ||
300 | .send_tx_power = iwlagn_send_tx_power, | 291 | .send_tx_power = iwlagn_send_tx_power, |
301 | .update_chain_flags = iwl_update_chain_flags, | 292 | .update_chain_flags = iwl_update_chain_flags, |
302 | .set_channel_switch = iwl6000_hw_channel_switch, | 293 | .set_channel_switch = iwl6000_hw_channel_switch, |
@@ -332,11 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
332 | }, | 323 | }, |
333 | .txfifo_flush = iwlagn_txfifo_flush, | 324 | .txfifo_flush = iwlagn_txfifo_flush, |
334 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 325 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
335 | .tt_ops = { | ||
336 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
337 | .tt_power_mode = iwl_tt_current_power_mode, | ||
338 | .ct_kill_check = iwl_check_for_ct_kill, | ||
339 | } | ||
340 | }; | 326 | }; |
341 | 327 | ||
342 | static struct iwl_lib_ops iwl6030_lib = { | 328 | static struct iwl_lib_ops iwl6030_lib = { |
@@ -351,10 +337,6 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
351 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 337 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
352 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 338 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
353 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 339 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
354 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
355 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
356 | .dump_csr = iwl_dump_csr, | ||
357 | .dump_fh = iwl_dump_fh, | ||
358 | .send_tx_power = iwlagn_send_tx_power, | 340 | .send_tx_power = iwlagn_send_tx_power, |
359 | .update_chain_flags = iwl_update_chain_flags, | 341 | .update_chain_flags = iwl_update_chain_flags, |
360 | .set_channel_switch = iwl6000_hw_channel_switch, | 342 | .set_channel_switch = iwl6000_hw_channel_switch, |
@@ -390,11 +372,6 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
390 | }, | 372 | }, |
391 | .txfifo_flush = iwlagn_txfifo_flush, | 373 | .txfifo_flush = iwlagn_txfifo_flush, |
392 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 374 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
393 | .tt_ops = { | ||
394 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
395 | .tt_power_mode = iwl_tt_current_power_mode, | ||
396 | .ct_kill_check = iwl_check_for_ct_kill, | ||
397 | } | ||
398 | }; | 375 | }; |
399 | 376 | ||
400 | static struct iwl_nic_ops iwl6050_nic_ops = { | 377 | static struct iwl_nic_ops iwl6050_nic_ops = { |
@@ -409,34 +386,26 @@ static const struct iwl_ops iwl6000_ops = { | |||
409 | .lib = &iwl6000_lib, | 386 | .lib = &iwl6000_lib, |
410 | .hcmd = &iwlagn_hcmd, | 387 | .hcmd = &iwlagn_hcmd, |
411 | .utils = &iwlagn_hcmd_utils, | 388 | .utils = &iwlagn_hcmd_utils, |
412 | .led = &iwlagn_led_ops, | ||
413 | .ieee80211_ops = &iwlagn_hw_ops, | ||
414 | }; | 389 | }; |
415 | 390 | ||
416 | static const struct iwl_ops iwl6050_ops = { | 391 | static const struct iwl_ops iwl6050_ops = { |
417 | .lib = &iwl6000_lib, | 392 | .lib = &iwl6000_lib, |
418 | .hcmd = &iwlagn_hcmd, | 393 | .hcmd = &iwlagn_hcmd, |
419 | .utils = &iwlagn_hcmd_utils, | 394 | .utils = &iwlagn_hcmd_utils, |
420 | .led = &iwlagn_led_ops, | ||
421 | .nic = &iwl6050_nic_ops, | 395 | .nic = &iwl6050_nic_ops, |
422 | .ieee80211_ops = &iwlagn_hw_ops, | ||
423 | }; | 396 | }; |
424 | 397 | ||
425 | static const struct iwl_ops iwl6150_ops = { | 398 | static const struct iwl_ops iwl6150_ops = { |
426 | .lib = &iwl6000_lib, | 399 | .lib = &iwl6000_lib, |
427 | .hcmd = &iwlagn_hcmd, | 400 | .hcmd = &iwlagn_hcmd, |
428 | .utils = &iwlagn_hcmd_utils, | 401 | .utils = &iwlagn_hcmd_utils, |
429 | .led = &iwlagn_led_ops, | ||
430 | .nic = &iwl6150_nic_ops, | 402 | .nic = &iwl6150_nic_ops, |
431 | .ieee80211_ops = &iwlagn_hw_ops, | ||
432 | }; | 403 | }; |
433 | 404 | ||
434 | static const struct iwl_ops iwl6030_ops = { | 405 | static const struct iwl_ops iwl6030_ops = { |
435 | .lib = &iwl6030_lib, | 406 | .lib = &iwl6030_lib, |
436 | .hcmd = &iwlagn_bt_hcmd, | 407 | .hcmd = &iwlagn_bt_hcmd, |
437 | .utils = &iwlagn_hcmd_utils, | 408 | .utils = &iwlagn_hcmd_utils, |
438 | .led = &iwlagn_led_ops, | ||
439 | .ieee80211_ops = &iwlagn_hw_ops, | ||
440 | }; | 409 | }; |
441 | 410 | ||
442 | static struct iwl_base_params iwl6000_base_params = { | 411 | static struct iwl_base_params iwl6000_base_params = { |
@@ -444,7 +413,6 @@ static struct iwl_base_params iwl6000_base_params = { | |||
444 | .num_of_queues = IWLAGN_NUM_QUEUES, | 413 | .num_of_queues = IWLAGN_NUM_QUEUES, |
445 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 414 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
446 | .pll_cfg_val = 0, | 415 | .pll_cfg_val = 0, |
447 | .set_l0s = true, | ||
448 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 416 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
449 | .shadow_ram_support = true, | 417 | .shadow_ram_support = true, |
450 | .led_compensation = 51, | 418 | .led_compensation = 51, |
@@ -455,9 +423,6 @@ static struct iwl_base_params iwl6000_base_params = { | |||
455 | .chain_noise_scale = 1000, | 423 | .chain_noise_scale = 1000, |
456 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 424 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
457 | .max_event_log_size = 512, | 425 | .max_event_log_size = 512, |
458 | .ucode_tracing = true, | ||
459 | .sensitivity_calib_by_driver = true, | ||
460 | .chain_noise_calib_by_driver = true, | ||
461 | .shadow_reg_enable = true, | 426 | .shadow_reg_enable = true, |
462 | }; | 427 | }; |
463 | 428 | ||
@@ -466,7 +431,6 @@ static struct iwl_base_params iwl6050_base_params = { | |||
466 | .num_of_queues = IWLAGN_NUM_QUEUES, | 431 | .num_of_queues = IWLAGN_NUM_QUEUES, |
467 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 432 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
468 | .pll_cfg_val = 0, | 433 | .pll_cfg_val = 0, |
469 | .set_l0s = true, | ||
470 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, | 434 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, |
471 | .shadow_ram_support = true, | 435 | .shadow_ram_support = true, |
472 | .led_compensation = 51, | 436 | .led_compensation = 51, |
@@ -477,9 +441,6 @@ static struct iwl_base_params iwl6050_base_params = { | |||
477 | .chain_noise_scale = 1500, | 441 | .chain_noise_scale = 1500, |
478 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 442 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
479 | .max_event_log_size = 1024, | 443 | .max_event_log_size = 1024, |
480 | .ucode_tracing = true, | ||
481 | .sensitivity_calib_by_driver = true, | ||
482 | .chain_noise_calib_by_driver = true, | ||
483 | .shadow_reg_enable = true, | 444 | .shadow_reg_enable = true, |
484 | }; | 445 | }; |
485 | static struct iwl_base_params iwl6000_g2_base_params = { | 446 | static struct iwl_base_params iwl6000_g2_base_params = { |
@@ -487,7 +448,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { | |||
487 | .num_of_queues = IWLAGN_NUM_QUEUES, | 448 | .num_of_queues = IWLAGN_NUM_QUEUES, |
488 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 449 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
489 | .pll_cfg_val = 0, | 450 | .pll_cfg_val = 0, |
490 | .set_l0s = true, | ||
491 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 451 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
492 | .shadow_ram_support = true, | 452 | .shadow_ram_support = true, |
493 | .led_compensation = 57, | 453 | .led_compensation = 57, |
@@ -498,9 +458,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { | |||
498 | .chain_noise_scale = 1000, | 458 | .chain_noise_scale = 1000, |
499 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 459 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
500 | .max_event_log_size = 512, | 460 | .max_event_log_size = 512, |
501 | .ucode_tracing = true, | ||
502 | .sensitivity_calib_by_driver = true, | ||
503 | .chain_noise_calib_by_driver = true, | ||
504 | .shadow_reg_enable = true, | 461 | .shadow_reg_enable = true, |
505 | }; | 462 | }; |
506 | 463 | ||
@@ -510,7 +467,6 @@ static struct iwl_ht_params iwl6000_ht_params = { | |||
510 | }; | 467 | }; |
511 | 468 | ||
512 | static struct iwl_bt_params iwl6000_bt_params = { | 469 | static struct iwl_bt_params iwl6000_bt_params = { |
513 | .bt_statistics = true, | ||
514 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 470 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
515 | .advanced_bt_coexist = true, | 471 | .advanced_bt_coexist = true, |
516 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 472 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 7b761de77b0a..0f6bb9b2e642 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
605 | IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); | 605 | IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); |
606 | } | 606 | } |
607 | 607 | ||
608 | void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) | 608 | void iwl_sensitivity_calibration(struct iwl_priv *priv) |
609 | { | 609 | { |
610 | u32 rx_enable_time; | 610 | u32 rx_enable_time; |
611 | u32 fa_cck; | 611 | u32 fa_cck; |
@@ -631,16 +631,9 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) | |||
631 | } | 631 | } |
632 | 632 | ||
633 | spin_lock_irqsave(&priv->lock, flags); | 633 | spin_lock_irqsave(&priv->lock, flags); |
634 | if (iwl_bt_statistics(priv)) { | 634 | rx_info = &priv->statistics.rx_non_phy; |
635 | rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> | 635 | ofdm = &priv->statistics.rx_ofdm; |
636 | rx.general.common); | 636 | cck = &priv->statistics.rx_cck; |
637 | ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); | ||
638 | cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); | ||
639 | } else { | ||
640 | rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); | ||
641 | ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); | ||
642 | cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); | ||
643 | } | ||
644 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 637 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
645 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); | 638 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); |
646 | spin_unlock_irqrestore(&priv->lock, flags); | 639 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
851 | * 1) Which antennas are connected. | 844 | * 1) Which antennas are connected. |
852 | * 2) Differential rx gain settings to balance the 3 receivers. | 845 | * 2) Differential rx gain settings to balance the 3 receivers. |
853 | */ | 846 | */ |
854 | void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | 847 | void iwl_chain_noise_calibration(struct iwl_priv *priv) |
855 | { | 848 | { |
856 | struct iwl_chain_noise_data *data = NULL; | 849 | struct iwl_chain_noise_data *data = NULL; |
857 | 850 | ||
@@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | |||
896 | } | 889 | } |
897 | 890 | ||
898 | spin_lock_irqsave(&priv->lock, flags); | 891 | spin_lock_irqsave(&priv->lock, flags); |
899 | if (iwl_bt_statistics(priv)) { | 892 | |
900 | rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> | 893 | rx_info = &priv->statistics.rx_non_phy; |
901 | rx.general.common); | 894 | |
902 | } else { | ||
903 | rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> | ||
904 | rx.general); | ||
905 | } | ||
906 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 895 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
907 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); | 896 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); |
908 | spin_unlock_irqrestore(&priv->lock, flags); | 897 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | |||
911 | 900 | ||
912 | rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); | 901 | rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); |
913 | rxon_chnum = le16_to_cpu(ctx->staging.channel); | 902 | rxon_chnum = le16_to_cpu(ctx->staging.channel); |
914 | if (iwl_bt_statistics(priv)) { | 903 | stat_band24 = |
915 | stat_band24 = !!(((struct iwl_bt_notif_statistics *) | 904 | !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); |
916 | stat_resp)->flag & | 905 | stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16; |
917 | STATISTICS_REPLY_FLG_BAND_24G_MSK); | ||
918 | stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) | ||
919 | stat_resp)->flag) >> 16; | ||
920 | } else { | ||
921 | stat_band24 = !!(((struct iwl_notif_statistics *) | ||
922 | stat_resp)->flag & | ||
923 | STATISTICS_REPLY_FLG_BAND_24G_MSK); | ||
924 | stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) | ||
925 | stat_resp)->flag) >> 16; | ||
926 | } | ||
927 | 906 | ||
928 | /* Make sure we accumulate data for just the associated channel | 907 | /* Make sure we accumulate data for just the associated channel |
929 | * (even if scanning). */ | 908 | * (even if scanning). */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index ef4d5079a7ed..4ef4dd934254 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h | |||
@@ -66,8 +66,8 @@ | |||
66 | #include "iwl-core.h" | 66 | #include "iwl-core.h" |
67 | #include "iwl-commands.h" | 67 | #include "iwl-commands.h" |
68 | 68 | ||
69 | void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); | 69 | void iwl_chain_noise_calibration(struct iwl_priv *priv); |
70 | void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); | 70 | void iwl_sensitivity_calibration(struct iwl_priv *priv); |
71 | 71 | ||
72 | void iwl_init_sensitivity(struct iwl_priv *priv); | 72 | void iwl_init_sensitivity(struct iwl_priv *priv); |
73 | void iwl_reset_run_time_calib(struct iwl_priv *priv); | 73 | void iwl_reset_run_time_calib(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index d1834aa7edf0..71a5f31cd7cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | |||
@@ -39,10 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | |||
39 | int p = 0; | 39 | int p = 0; |
40 | u32 flag; | 40 | u32 flag; |
41 | 41 | ||
42 | if (iwl_bt_statistics(priv)) | 42 | flag = le32_to_cpu(priv->statistics.flag); |
43 | flag = le32_to_cpu(priv->_agn.statistics_bt.flag); | ||
44 | else | ||
45 | flag = le32_to_cpu(priv->_agn.statistics.flag); | ||
46 | 43 | ||
47 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | 44 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); |
48 | if (flag & UCODE_STATISTICS_CLEAR_MSK) | 45 | if (flag & UCODE_STATISTICS_CLEAR_MSK) |
@@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | |||
88 | * the last statistics notification from uCode | 85 | * the last statistics notification from uCode |
89 | * might not reflect the current uCode activity | 86 | * might not reflect the current uCode activity |
90 | */ | 87 | */ |
91 | if (iwl_bt_statistics(priv)) { | 88 | ofdm = &priv->statistics.rx_ofdm; |
92 | ofdm = &priv->_agn.statistics_bt.rx.ofdm; | 89 | cck = &priv->statistics.rx_cck; |
93 | cck = &priv->_agn.statistics_bt.rx.cck; | 90 | general = &priv->statistics.rx_non_phy; |
94 | general = &priv->_agn.statistics_bt.rx.general.common; | 91 | ht = &priv->statistics.rx_ofdm_ht; |
95 | ht = &priv->_agn.statistics_bt.rx.ofdm_ht; | 92 | accum_ofdm = &priv->accum_stats.rx_ofdm; |
96 | accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; | 93 | accum_cck = &priv->accum_stats.rx_cck; |
97 | accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; | 94 | accum_general = &priv->accum_stats.rx_non_phy; |
98 | accum_general = | 95 | accum_ht = &priv->accum_stats.rx_ofdm_ht; |
99 | &priv->_agn.accum_statistics_bt.rx.general.common; | 96 | delta_ofdm = &priv->delta_stats.rx_ofdm; |
100 | accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; | 97 | delta_cck = &priv->delta_stats.rx_cck; |
101 | delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; | 98 | delta_general = &priv->delta_stats.rx_non_phy; |
102 | delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; | 99 | delta_ht = &priv->delta_stats.rx_ofdm_ht; |
103 | delta_general = | 100 | max_ofdm = &priv->max_delta_stats.rx_ofdm; |
104 | &priv->_agn.delta_statistics_bt.rx.general.common; | 101 | max_cck = &priv->max_delta_stats.rx_cck; |
105 | delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; | 102 | max_general = &priv->max_delta_stats.rx_non_phy; |
106 | max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; | 103 | max_ht = &priv->max_delta_stats.rx_ofdm_ht; |
107 | max_cck = &priv->_agn.max_delta_bt.rx.cck; | ||
108 | max_general = &priv->_agn.max_delta_bt.rx.general.common; | ||
109 | max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; | ||
110 | } else { | ||
111 | ofdm = &priv->_agn.statistics.rx.ofdm; | ||
112 | cck = &priv->_agn.statistics.rx.cck; | ||
113 | general = &priv->_agn.statistics.rx.general; | ||
114 | ht = &priv->_agn.statistics.rx.ofdm_ht; | ||
115 | accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; | ||
116 | accum_cck = &priv->_agn.accum_statistics.rx.cck; | ||
117 | accum_general = &priv->_agn.accum_statistics.rx.general; | ||
118 | accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; | ||
119 | delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; | ||
120 | delta_cck = &priv->_agn.delta_statistics.rx.cck; | ||
121 | delta_general = &priv->_agn.delta_statistics.rx.general; | ||
122 | delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; | ||
123 | max_ofdm = &priv->_agn.max_delta.rx.ofdm; | ||
124 | max_cck = &priv->_agn.max_delta.rx.cck; | ||
125 | max_general = &priv->_agn.max_delta.rx.general; | ||
126 | max_ht = &priv->_agn.max_delta.rx.ofdm_ht; | ||
127 | } | ||
128 | 104 | ||
129 | pos += iwl_statistics_flag(priv, buf, bufsz); | 105 | pos += iwl_statistics_flag(priv, buf, bufsz); |
130 | pos += scnprintf(buf + pos, bufsz - pos, | 106 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, | |||
531 | } | 507 | } |
532 | 508 | ||
533 | /* the statistic information display here is based on | 509 | /* the statistic information display here is based on |
534 | * the last statistics notification from uCode | 510 | * the last statistics notification from uCode |
535 | * might not reflect the current uCode activity | 511 | * might not reflect the current uCode activity |
536 | */ | 512 | */ |
537 | if (iwl_bt_statistics(priv)) { | 513 | tx = &priv->statistics.tx; |
538 | tx = &priv->_agn.statistics_bt.tx; | 514 | accum_tx = &priv->accum_stats.tx; |
539 | accum_tx = &priv->_agn.accum_statistics_bt.tx; | 515 | delta_tx = &priv->delta_stats.tx; |
540 | delta_tx = &priv->_agn.delta_statistics_bt.tx; | 516 | max_tx = &priv->max_delta_stats.tx; |
541 | max_tx = &priv->_agn.max_delta_bt.tx; | ||
542 | } else { | ||
543 | tx = &priv->_agn.statistics.tx; | ||
544 | accum_tx = &priv->_agn.accum_statistics.tx; | ||
545 | delta_tx = &priv->_agn.delta_statistics.tx; | ||
546 | max_tx = &priv->_agn.max_delta.tx; | ||
547 | } | ||
548 | 517 | ||
549 | pos += iwl_statistics_flag(priv, buf, bufsz); | 518 | pos += iwl_statistics_flag(priv, buf, bufsz); |
550 | pos += scnprintf(buf + pos, bufsz - pos, | 519 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | |||
731 | } | 700 | } |
732 | 701 | ||
733 | /* the statistic information display here is based on | 702 | /* the statistic information display here is based on |
734 | * the last statistics notification from uCode | 703 | * the last statistics notification from uCode |
735 | * might not reflect the current uCode activity | 704 | * might not reflect the current uCode activity |
736 | */ | 705 | */ |
737 | if (iwl_bt_statistics(priv)) { | 706 | general = &priv->statistics.common; |
738 | general = &priv->_agn.statistics_bt.general.common; | 707 | dbg = &priv->statistics.common.dbg; |
739 | dbg = &priv->_agn.statistics_bt.general.common.dbg; | 708 | div = &priv->statistics.common.div; |
740 | div = &priv->_agn.statistics_bt.general.common.div; | 709 | accum_general = &priv->accum_stats.common; |
741 | accum_general = &priv->_agn.accum_statistics_bt.general.common; | 710 | accum_dbg = &priv->accum_stats.common.dbg; |
742 | accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; | 711 | accum_div = &priv->accum_stats.common.div; |
743 | accum_div = &priv->_agn.accum_statistics_bt.general.common.div; | 712 | delta_general = &priv->delta_stats.common; |
744 | delta_general = &priv->_agn.delta_statistics_bt.general.common; | 713 | max_general = &priv->max_delta_stats.common; |
745 | max_general = &priv->_agn.max_delta_bt.general.common; | 714 | delta_dbg = &priv->delta_stats.common.dbg; |
746 | delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; | 715 | max_dbg = &priv->max_delta_stats.common.dbg; |
747 | max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; | 716 | delta_div = &priv->delta_stats.common.div; |
748 | delta_div = &priv->_agn.delta_statistics_bt.general.common.div; | 717 | max_div = &priv->max_delta_stats.common.div; |
749 | max_div = &priv->_agn.max_delta_bt.general.common.div; | ||
750 | } else { | ||
751 | general = &priv->_agn.statistics.general.common; | ||
752 | dbg = &priv->_agn.statistics.general.common.dbg; | ||
753 | div = &priv->_agn.statistics.general.common.div; | ||
754 | accum_general = &priv->_agn.accum_statistics.general.common; | ||
755 | accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; | ||
756 | accum_div = &priv->_agn.accum_statistics.general.common.div; | ||
757 | delta_general = &priv->_agn.delta_statistics.general.common; | ||
758 | max_general = &priv->_agn.max_delta.general.common; | ||
759 | delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; | ||
760 | max_dbg = &priv->_agn.max_delta.general.common.dbg; | ||
761 | delta_div = &priv->_agn.delta_statistics.general.common.div; | ||
762 | max_div = &priv->_agn.max_delta.general.common.div; | ||
763 | } | ||
764 | 718 | ||
765 | pos += iwl_statistics_flag(priv, buf, bufsz); | 719 | pos += iwl_statistics_flag(priv, buf, bufsz); |
766 | pos += scnprintf(buf + pos, bufsz - pos, | 720 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, | |||
876 | * the last statistics notification from uCode | 830 | * the last statistics notification from uCode |
877 | * might not reflect the current uCode activity | 831 | * might not reflect the current uCode activity |
878 | */ | 832 | */ |
879 | bt = &priv->_agn.statistics_bt.general.activity; | 833 | bt = &priv->statistics.bt_activity; |
880 | accum_bt = &priv->_agn.accum_statistics_bt.general.activity; | 834 | accum_bt = &priv->accum_stats.bt_activity; |
881 | 835 | ||
882 | pos += iwl_statistics_flag(priv, buf, bufsz); | 836 | pos += iwl_statistics_flag(priv, buf, bufsz); |
883 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); | 837 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); |
@@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, | |||
918 | 872 | ||
919 | pos += scnprintf(buf + pos, bufsz - pos, | 873 | pos += scnprintf(buf + pos, bufsz - pos, |
920 | "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", | 874 | "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", |
921 | le32_to_cpu(priv->_agn.statistics_bt.rx. | 875 | le32_to_cpu(priv->statistics.num_bt_kills), |
922 | general.num_bt_kills), | 876 | priv->statistics.accum_num_bt_kills); |
923 | priv->_agn.accum_statistics_bt.rx. | ||
924 | general.num_bt_kills); | ||
925 | 877 | ||
926 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 878 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
927 | kfree(buf); | 879 | kfree(buf); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c deleted file mode 100644 index 4bb877e600c7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * 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 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/wireless.h> | ||
36 | #include <net/mac80211.h> | ||
37 | #include <linux/etherdevice.h> | ||
38 | #include <asm/unaligned.h> | ||
39 | |||
40 | #include "iwl-commands.h" | ||
41 | #include "iwl-dev.h" | ||
42 | #include "iwl-core.h" | ||
43 | #include "iwl-io.h" | ||
44 | #include "iwl-agn-led.h" | ||
45 | |||
46 | /* Send led command */ | ||
47 | static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | ||
48 | { | ||
49 | struct iwl_host_cmd cmd = { | ||
50 | .id = REPLY_LEDS_CMD, | ||
51 | .len = sizeof(struct iwl_led_cmd), | ||
52 | .data = led_cmd, | ||
53 | .flags = CMD_ASYNC, | ||
54 | .callback = NULL, | ||
55 | }; | ||
56 | u32 reg; | ||
57 | |||
58 | reg = iwl_read32(priv, CSR_LED_REG); | ||
59 | if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) | ||
60 | iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); | ||
61 | |||
62 | return iwl_send_cmd(priv, &cmd); | ||
63 | } | ||
64 | |||
65 | /* Set led register off */ | ||
66 | void iwlagn_led_enable(struct iwl_priv *priv) | ||
67 | { | ||
68 | iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); | ||
69 | } | ||
70 | |||
71 | const struct iwl_led_ops iwlagn_led_ops = { | ||
72 | .cmd = iwl_send_led_cmd, | ||
73 | }; | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h deleted file mode 100644 index c0b7611b72c3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * 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 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #ifndef __iwl_agn_led_h__ | ||
28 | #define __iwl_agn_led_h__ | ||
29 | |||
30 | extern const struct iwl_led_ops iwlagn_led_ops; | ||
31 | void iwlagn_led_enable(struct iwl_priv *priv); | ||
32 | |||
33 | #endif /* __iwl_agn_led_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9e47be6a7393..e741128842bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -172,6 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) | |||
172 | 172 | ||
173 | static void iwlagn_set_tx_status(struct iwl_priv *priv, | 173 | static void iwlagn_set_tx_status(struct iwl_priv *priv, |
174 | struct ieee80211_tx_info *info, | 174 | struct ieee80211_tx_info *info, |
175 | struct iwl_rxon_context *ctx, | ||
175 | struct iwlagn_tx_resp *tx_resp, | 176 | struct iwlagn_tx_resp *tx_resp, |
176 | int txq_id, bool is_agg) | 177 | int txq_id, bool is_agg) |
177 | { | 178 | { |
@@ -186,6 +187,13 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, | |||
186 | if (!iwl_is_tx_success(status)) | 187 | if (!iwl_is_tx_success(status)) |
187 | iwlagn_count_tx_err_status(priv, status); | 188 | iwlagn_count_tx_err_status(priv, status); |
188 | 189 | ||
190 | if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && | ||
191 | iwl_is_associated_ctx(ctx) && ctx->vif && | ||
192 | ctx->vif->type == NL80211_IFTYPE_STATION) { | ||
193 | ctx->last_tx_rejected = true; | ||
194 | iwl_stop_queue(priv, &priv->txq[txq_id]); | ||
195 | } | ||
196 | |||
189 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " | 197 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " |
190 | "0x%x retries %d\n", | 198 | "0x%x retries %d\n", |
191 | txq_id, | 199 | txq_id, |
@@ -242,15 +250,16 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | |||
242 | 250 | ||
243 | /* # frames attempted by Tx command */ | 251 | /* # frames attempted by Tx command */ |
244 | if (agg->frame_count == 1) { | 252 | if (agg->frame_count == 1) { |
253 | struct iwl_tx_info *txb; | ||
254 | |||
245 | /* Only one frame was attempted; no block-ack will arrive */ | 255 | /* Only one frame was attempted; no block-ack will arrive */ |
246 | idx = start_idx; | 256 | idx = start_idx; |
247 | 257 | ||
248 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", | 258 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", |
249 | agg->frame_count, agg->start_idx, idx); | 259 | agg->frame_count, agg->start_idx, idx); |
250 | iwlagn_set_tx_status(priv, | 260 | txb = &priv->txq[txq_id].txb[idx]; |
251 | IEEE80211_SKB_CB( | 261 | iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb), |
252 | priv->txq[txq_id].txb[idx].skb), | 262 | txb->ctx, tx_resp, txq_id, true); |
253 | tx_resp, txq_id, true); | ||
254 | agg->wait_for_ba = 0; | 263 | agg->wait_for_ba = 0; |
255 | } else { | 264 | } else { |
256 | /* Two or more frames were attempted; expect block-ack */ | 265 | /* Two or more frames were attempted; expect block-ack */ |
@@ -391,7 +400,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
391 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 400 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
392 | struct ieee80211_tx_info *info; | 401 | struct ieee80211_tx_info *info; |
393 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 402 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
394 | u32 status = le16_to_cpu(tx_resp->status.status); | 403 | struct iwl_tx_info *txb; |
404 | u32 status = le16_to_cpu(tx_resp->status.status); | ||
395 | int tid; | 405 | int tid; |
396 | int sta_id; | 406 | int sta_id; |
397 | int freed; | 407 | int freed; |
@@ -406,7 +416,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
406 | } | 416 | } |
407 | 417 | ||
408 | txq->time_stamp = jiffies; | 418 | txq->time_stamp = jiffies; |
409 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); | 419 | txb = &txq->txb[txq->q.read_ptr]; |
420 | info = IEEE80211_SKB_CB(txb->skb); | ||
410 | memset(&info->status, 0, sizeof(info->status)); | 421 | memset(&info->status, 0, sizeof(info->status)); |
411 | 422 | ||
412 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> | 423 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> |
@@ -450,12 +461,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
450 | iwl_wake_queue(priv, txq); | 461 | iwl_wake_queue(priv, txq); |
451 | } | 462 | } |
452 | } else { | 463 | } else { |
453 | iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); | 464 | iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp, |
465 | txq_id, false); | ||
454 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); | 466 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); |
455 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | 467 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
456 | 468 | ||
457 | if (priv->mac80211_registered && | 469 | if (priv->mac80211_registered && |
458 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 470 | iwl_queue_space(&txq->q) > txq->q.low_mark && |
471 | status != TX_STATUS_FAIL_PASSIVE_NO_RX) | ||
459 | iwl_wake_queue(priv, txq); | 472 | iwl_wake_queue(priv, txq); |
460 | } | 473 | } |
461 | 474 | ||
@@ -482,8 +495,10 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) | |||
482 | 495 | ||
483 | void iwlagn_setup_deferred_work(struct iwl_priv *priv) | 496 | void iwlagn_setup_deferred_work(struct iwl_priv *priv) |
484 | { | 497 | { |
485 | /* in agn, the tx power calibration is done in uCode */ | 498 | /* |
486 | priv->disable_tx_power_cal = 1; | 499 | * nothing need to be done here anymore |
500 | * still keep for future use if needed | ||
501 | */ | ||
487 | } | 502 | } |
488 | 503 | ||
489 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) | 504 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) |
@@ -534,9 +549,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
534 | void iwlagn_temperature(struct iwl_priv *priv) | 549 | void iwlagn_temperature(struct iwl_priv *priv) |
535 | { | 550 | { |
536 | /* store temperature from correct statistics (in Celsius) */ | 551 | /* store temperature from correct statistics (in Celsius) */ |
537 | priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? | 552 | priv->temperature = le32_to_cpu(priv->statistics.common.temperature); |
538 | priv->_agn.statistics_bt.general.common.temperature : | ||
539 | priv->_agn.statistics.general.common.temperature); | ||
540 | iwl_tt_handler(priv); | 553 | iwl_tt_handler(priv); |
541 | } | 554 | } |
542 | 555 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 69a29932babc..bdae82e7fa90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -83,7 +83,6 @@ enum { | |||
83 | 83 | ||
84 | enum { | 84 | enum { |
85 | IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, | 85 | IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, |
86 | IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, | ||
87 | IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, | 86 | IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, |
88 | IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, | 87 | IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, |
89 | IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, | 88 | IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c335ee6883ee..56f46ee3bacd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "iwl-sta.h" | 29 | #include "iwl-sta.h" |
30 | #include "iwl-core.h" | 30 | #include "iwl-core.h" |
31 | #include "iwl-agn-calib.h" | 31 | #include "iwl-agn-calib.h" |
32 | #include "iwl-helpers.h" | ||
32 | 33 | ||
33 | static int iwlagn_disable_bss(struct iwl_priv *priv, | 34 | static int iwlagn_disable_bss(struct iwl_priv *priv, |
34 | struct iwl_rxon_context *ctx, | 35 | struct iwl_rxon_context *ctx, |
@@ -600,6 +601,18 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
600 | priv->timestamp = bss_conf->timestamp; | 601 | priv->timestamp = bss_conf->timestamp; |
601 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 602 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
602 | } else { | 603 | } else { |
604 | /* | ||
605 | * If we disassociate while there are pending | ||
606 | * frames, just wake up the queues and let the | ||
607 | * frames "escape" ... This shouldn't really | ||
608 | * be happening to start with, but we should | ||
609 | * not get stuck in this case either since it | ||
610 | * can happen if userspace gets confused. | ||
611 | */ | ||
612 | if (ctx->last_tx_rejected) { | ||
613 | ctx->last_tx_rejected = false; | ||
614 | iwl_wake_any_queue(priv, ctx); | ||
615 | } | ||
603 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 616 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
604 | } | 617 | } |
605 | } | 618 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 01a6d2fc795c..5c30f6b19a7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -428,6 +428,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | |||
428 | int iwlagn_alive_notify(struct iwl_priv *priv) | 428 | int iwlagn_alive_notify(struct iwl_priv *priv) |
429 | { | 429 | { |
430 | const struct queue_to_fifo_ac *queue_to_fifo; | 430 | const struct queue_to_fifo_ac *queue_to_fifo; |
431 | struct iwl_rxon_context *ctx; | ||
431 | u32 a; | 432 | u32 a; |
432 | unsigned long flags; | 433 | unsigned long flags; |
433 | int i, chan; | 434 | int i, chan; |
@@ -501,6 +502,8 @@ int iwlagn_alive_notify(struct iwl_priv *priv) | |||
501 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | 502 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); |
502 | for (i = 0; i < 4; i++) | 503 | for (i = 0; i < 4; i++) |
503 | atomic_set(&priv->queue_stop_count[i], 0); | 504 | atomic_set(&priv->queue_stop_count[i], 0); |
505 | for_each_context(priv, ctx) | ||
506 | ctx->last_tx_rejected = false; | ||
504 | 507 | ||
505 | /* reset to 0 to enable all the queue first */ | 508 | /* reset to 0 to enable all the queue first */ |
506 | priv->txq_ctx_active_msk = 0; | 509 | priv->txq_ctx_active_msk = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 60bfde75ce87..cdeb09eee739 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include "iwl-sta.h" | 59 | #include "iwl-sta.h" |
60 | #include "iwl-agn-calib.h" | 60 | #include "iwl-agn-calib.h" |
61 | #include "iwl-agn.h" | 61 | #include "iwl-agn.h" |
62 | #include "iwl-agn-led.h" | ||
63 | 62 | ||
64 | 63 | ||
65 | /****************************************************************************** | 64 | /****************************************************************************** |
@@ -254,6 +253,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
254 | struct iwl_frame *frame; | 253 | struct iwl_frame *frame; |
255 | unsigned int frame_size; | 254 | unsigned int frame_size; |
256 | int rc; | 255 | int rc; |
256 | struct iwl_host_cmd cmd = { | ||
257 | .id = REPLY_TX_BEACON, | ||
258 | .flags = CMD_SIZE_HUGE, | ||
259 | }; | ||
257 | 260 | ||
258 | frame = iwl_get_free_frame(priv); | 261 | frame = iwl_get_free_frame(priv); |
259 | if (!frame) { | 262 | if (!frame) { |
@@ -269,8 +272,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
269 | return -EINVAL; | 272 | return -EINVAL; |
270 | } | 273 | } |
271 | 274 | ||
272 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, | 275 | cmd.len = frame_size; |
273 | &frame->u.cmd[0]); | 276 | cmd.data = &frame->u.cmd[0]; |
277 | |||
278 | rc = iwl_send_cmd_sync(priv, &cmd); | ||
274 | 279 | ||
275 | iwl_free_frame(priv, frame); | 280 | iwl_free_frame(priv, frame); |
276 | 281 | ||
@@ -395,7 +400,9 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | |||
395 | return -EINVAL; | 400 | return -EINVAL; |
396 | } | 401 | } |
397 | 402 | ||
398 | BUG_ON(addr & ~DMA_BIT_MASK(36)); | 403 | if (WARN_ON(addr & ~DMA_BIT_MASK(36))) |
404 | return -EINVAL; | ||
405 | |||
399 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | 406 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) |
400 | IWL_ERR(priv, "Unaligned address = %llx\n", | 407 | IWL_ERR(priv, "Unaligned address = %llx\n", |
401 | (unsigned long long)addr); | 408 | (unsigned long long)addr); |
@@ -719,7 +726,10 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
719 | /* If an RXB doesn't have a Rx queue slot associated with it, | 726 | /* If an RXB doesn't have a Rx queue slot associated with it, |
720 | * then a bug has been introduced in the queue refilling | 727 | * then a bug has been introduced in the queue refilling |
721 | * routines -- catch it here */ | 728 | * routines -- catch it here */ |
722 | BUG_ON(rxb == NULL); | 729 | if (WARN_ON(rxb == NULL)) { |
730 | i = (i + 1) & RX_QUEUE_MASK; | ||
731 | continue; | ||
732 | } | ||
723 | 733 | ||
724 | rxq->queue[i] = NULL; | 734 | rxq->queue[i] = NULL; |
725 | 735 | ||
@@ -1481,7 +1491,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
1481 | le32_to_cpup((__le32 *)tlv_data); | 1491 | le32_to_cpup((__le32 *)tlv_data); |
1482 | break; | 1492 | break; |
1483 | default: | 1493 | default: |
1484 | IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); | 1494 | IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); |
1485 | break; | 1495 | break; |
1486 | } | 1496 | } |
1487 | } | 1497 | } |
@@ -1705,10 +1715,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1705 | else | 1715 | else |
1706 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | 1716 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; |
1707 | 1717 | ||
1708 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS || | ||
1709 | (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)) | ||
1710 | priv->bt_statistics = true; | ||
1711 | |||
1712 | /* Copy images into buffers for card's bus-master reads ... */ | 1718 | /* Copy images into buffers for card's bus-master reads ... */ |
1713 | 1719 | ||
1714 | /* Runtime instructions (first block of data in file) */ | 1720 | /* Runtime instructions (first block of data in file) */ |
@@ -2626,17 +2632,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
2626 | } | 2632 | } |
2627 | 2633 | ||
2628 | if (priv->start_calib) { | 2634 | if (priv->start_calib) { |
2629 | if (iwl_bt_statistics(priv)) { | 2635 | iwl_chain_noise_calibration(priv); |
2630 | iwl_chain_noise_calibration(priv, | 2636 | iwl_sensitivity_calibration(priv); |
2631 | (void *)&priv->_agn.statistics_bt); | ||
2632 | iwl_sensitivity_calibration(priv, | ||
2633 | (void *)&priv->_agn.statistics_bt); | ||
2634 | } else { | ||
2635 | iwl_chain_noise_calibration(priv, | ||
2636 | (void *)&priv->_agn.statistics); | ||
2637 | iwl_sensitivity_calibration(priv, | ||
2638 | (void *)&priv->_agn.statistics); | ||
2639 | } | ||
2640 | } | 2637 | } |
2641 | 2638 | ||
2642 | mutex_unlock(&priv->mutex); | 2639 | mutex_unlock(&priv->mutex); |
@@ -2828,9 +2825,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
2828 | 2825 | ||
2829 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | 2826 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; |
2830 | 2827 | ||
2831 | if (!priv->cfg->base_params->broken_powersave) | 2828 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
2832 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 2829 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
2833 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
2834 | 2830 | ||
2835 | if (priv->cfg->sku & IWL_SKU_N) | 2831 | if (priv->cfg->sku & IWL_SKU_N) |
2836 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 2832 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
@@ -3732,6 +3728,28 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
3732 | 7, 6, 5, 4, | 3728 | 7, 6, 5, 4, |
3733 | }; | 3729 | }; |
3734 | 3730 | ||
3731 | /* This function both allocates and initializes hw and priv. */ | ||
3732 | static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) | ||
3733 | { | ||
3734 | struct iwl_priv *priv; | ||
3735 | /* mac80211 allocates memory for this device instance, including | ||
3736 | * space for this driver's private structure */ | ||
3737 | struct ieee80211_hw *hw; | ||
3738 | |||
3739 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); | ||
3740 | if (hw == NULL) { | ||
3741 | pr_err("%s: Can not allocate network device\n", | ||
3742 | cfg->name); | ||
3743 | goto out; | ||
3744 | } | ||
3745 | |||
3746 | priv = hw->priv; | ||
3747 | priv->hw = hw; | ||
3748 | |||
3749 | out: | ||
3750 | return hw; | ||
3751 | } | ||
3752 | |||
3735 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3753 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
3736 | { | 3754 | { |
3737 | int err = 0, i; | 3755 | int err = 0, i; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 016b79e4421e..078a23e5d99d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -173,8 +173,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv); | |||
173 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); | 173 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); |
174 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 174 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
175 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 175 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
176 | void iwl_dump_csr(struct iwl_priv *priv); | ||
177 | int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); | ||
178 | 176 | ||
179 | /* rx */ | 177 | /* rx */ |
180 | void iwlagn_rx_queue_restock(struct iwl_priv *priv); | 178 | void iwlagn_rx_queue_restock(struct iwl_priv *priv); |
@@ -222,6 +220,7 @@ static inline u32 iwl_tx_status_to_mac80211(u32 status) | |||
222 | case TX_STATUS_DIRECT_DONE: | 220 | case TX_STATUS_DIRECT_DONE: |
223 | return IEEE80211_TX_STAT_ACK; | 221 | return IEEE80211_TX_STAT_ACK; |
224 | case TX_STATUS_FAIL_DEST_PS: | 222 | case TX_STATUS_FAIL_DEST_PS: |
223 | case TX_STATUS_FAIL_PASSIVE_NO_RX: | ||
225 | return IEEE80211_TX_STAT_TX_FILTERED; | 224 | return IEEE80211_TX_STAT_TX_FILTERED; |
226 | default: | 225 | default: |
227 | return 0; | 226 | return 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index a1a5c1b23096..0edba8a6419b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -2535,53 +2535,6 @@ struct rate_histogram { | |||
2535 | 2535 | ||
2536 | /* statistics command response */ | 2536 | /* statistics command response */ |
2537 | 2537 | ||
2538 | struct iwl39_statistics_rx_phy { | ||
2539 | __le32 ina_cnt; | ||
2540 | __le32 fina_cnt; | ||
2541 | __le32 plcp_err; | ||
2542 | __le32 crc32_err; | ||
2543 | __le32 overrun_err; | ||
2544 | __le32 early_overrun_err; | ||
2545 | __le32 crc32_good; | ||
2546 | __le32 false_alarm_cnt; | ||
2547 | __le32 fina_sync_err_cnt; | ||
2548 | __le32 sfd_timeout; | ||
2549 | __le32 fina_timeout; | ||
2550 | __le32 unresponded_rts; | ||
2551 | __le32 rxe_frame_limit_overrun; | ||
2552 | __le32 sent_ack_cnt; | ||
2553 | __le32 sent_cts_cnt; | ||
2554 | } __packed; | ||
2555 | |||
2556 | struct iwl39_statistics_rx_non_phy { | ||
2557 | __le32 bogus_cts; /* CTS received when not expecting CTS */ | ||
2558 | __le32 bogus_ack; /* ACK received when not expecting ACK */ | ||
2559 | __le32 non_bssid_frames; /* number of frames with BSSID that | ||
2560 | * doesn't belong to the STA BSSID */ | ||
2561 | __le32 filtered_frames; /* count frames that were dumped in the | ||
2562 | * filtering process */ | ||
2563 | __le32 non_channel_beacons; /* beacons with our bss id but not on | ||
2564 | * our serving channel */ | ||
2565 | } __packed; | ||
2566 | |||
2567 | struct iwl39_statistics_rx { | ||
2568 | struct iwl39_statistics_rx_phy ofdm; | ||
2569 | struct iwl39_statistics_rx_phy cck; | ||
2570 | struct iwl39_statistics_rx_non_phy general; | ||
2571 | } __packed; | ||
2572 | |||
2573 | struct iwl39_statistics_tx { | ||
2574 | __le32 preamble_cnt; | ||
2575 | __le32 rx_detected_cnt; | ||
2576 | __le32 bt_prio_defer_cnt; | ||
2577 | __le32 bt_prio_kill_cnt; | ||
2578 | __le32 few_bytes_cnt; | ||
2579 | __le32 cts_timeout; | ||
2580 | __le32 ack_timeout; | ||
2581 | __le32 expected_ack_cnt; | ||
2582 | __le32 actual_ack_cnt; | ||
2583 | } __packed; | ||
2584 | |||
2585 | struct statistics_dbg { | 2538 | struct statistics_dbg { |
2586 | __le32 burst_check; | 2539 | __le32 burst_check; |
2587 | __le32 burst_count; | 2540 | __le32 burst_count; |
@@ -2589,23 +2542,6 @@ struct statistics_dbg { | |||
2589 | __le32 reserved[3]; | 2542 | __le32 reserved[3]; |
2590 | } __packed; | 2543 | } __packed; |
2591 | 2544 | ||
2592 | struct iwl39_statistics_div { | ||
2593 | __le32 tx_on_a; | ||
2594 | __le32 tx_on_b; | ||
2595 | __le32 exec_time; | ||
2596 | __le32 probe_time; | ||
2597 | } __packed; | ||
2598 | |||
2599 | struct iwl39_statistics_general { | ||
2600 | __le32 temperature; | ||
2601 | struct statistics_dbg dbg; | ||
2602 | __le32 sleep_time; | ||
2603 | __le32 slots_out; | ||
2604 | __le32 slots_idle; | ||
2605 | __le32 ttl_timestamp; | ||
2606 | struct iwl39_statistics_div div; | ||
2607 | } __packed; | ||
2608 | |||
2609 | struct statistics_rx_phy { | 2545 | struct statistics_rx_phy { |
2610 | __le32 ina_cnt; | 2546 | __le32 ina_cnt; |
2611 | __le32 fina_cnt; | 2547 | __le32 fina_cnt; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 45ec5cfe3fcf..885167f8168d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -67,30 +67,6 @@ u32 iwl_debug_level; | |||
67 | 67 | ||
68 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 68 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
69 | 69 | ||
70 | |||
71 | /* This function both allocates and initializes hw and priv. */ | ||
72 | struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) | ||
73 | { | ||
74 | struct iwl_priv *priv; | ||
75 | /* mac80211 allocates memory for this device instance, including | ||
76 | * space for this driver's private structure */ | ||
77 | struct ieee80211_hw *hw; | ||
78 | |||
79 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), | ||
80 | cfg->ops->ieee80211_ops); | ||
81 | if (hw == NULL) { | ||
82 | pr_err("%s: Can not allocate network device\n", | ||
83 | cfg->name); | ||
84 | goto out; | ||
85 | } | ||
86 | |||
87 | priv = hw->priv; | ||
88 | priv->hw = hw; | ||
89 | |||
90 | out: | ||
91 | return hw; | ||
92 | } | ||
93 | |||
94 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | 70 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ |
95 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | 71 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ |
96 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | 72 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, |
@@ -965,12 +941,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv) | |||
965 | IWL_ERR(priv, "Loaded firmware version: %s\n", | 941 | IWL_ERR(priv, "Loaded firmware version: %s\n", |
966 | priv->hw->wiphy->fw_version); | 942 | priv->hw->wiphy->fw_version); |
967 | 943 | ||
968 | priv->cfg->ops->lib->dump_nic_error_log(priv); | 944 | iwl_dump_nic_error_log(priv); |
969 | if (priv->cfg->ops->lib->dump_csr) | 945 | iwl_dump_csr(priv); |
970 | priv->cfg->ops->lib->dump_csr(priv); | 946 | iwl_dump_fh(priv, NULL, false); |
971 | if (priv->cfg->ops->lib->dump_fh) | 947 | iwl_dump_nic_event_log(priv, false, NULL, false); |
972 | priv->cfg->ops->lib->dump_fh(priv, NULL, false); | ||
973 | priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); | ||
974 | #ifdef CONFIG_IWLWIFI_DEBUG | 948 | #ifdef CONFIG_IWLWIFI_DEBUG |
975 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) | 949 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) |
976 | iwl_print_rx_config_cmd(priv, | 950 | iwl_print_rx_config_cmd(priv, |
@@ -1051,7 +1025,6 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
1051 | /* | 1025 | /* |
1052 | * Enable HAP INTA (interrupt from management bus) to | 1026 | * Enable HAP INTA (interrupt from management bus) to |
1053 | * wake device's PCI Express link L1a -> L0s | 1027 | * wake device's PCI Express link L1a -> L0s |
1054 | * NOTE: This is no-op for 3945 (non-existent bit) | ||
1055 | */ | 1028 | */ |
1056 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1029 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1057 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | 1030 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); |
@@ -1064,20 +1037,18 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
1064 | * If not (unlikely), enable L0S, so there is at least some | 1037 | * If not (unlikely), enable L0S, so there is at least some |
1065 | * power savings, even without L1. | 1038 | * power savings, even without L1. |
1066 | */ | 1039 | */ |
1067 | if (priv->cfg->base_params->set_l0s) { | 1040 | lctl = iwl_pcie_link_ctl(priv); |
1068 | lctl = iwl_pcie_link_ctl(priv); | 1041 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == |
1069 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | 1042 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { |
1070 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | 1043 | /* L1-ASPM enabled; disable(!) L0S */ |
1071 | /* L1-ASPM enabled; disable(!) L0S */ | 1044 | iwl_set_bit(priv, CSR_GIO_REG, |
1072 | iwl_set_bit(priv, CSR_GIO_REG, | 1045 | CSR_GIO_REG_VAL_L0S_ENABLED); |
1073 | CSR_GIO_REG_VAL_L0S_ENABLED); | 1046 | IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); |
1074 | IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); | 1047 | } else { |
1075 | } else { | 1048 | /* L1-ASPM disabled; enable(!) L0S */ |
1076 | /* L1-ASPM disabled; enable(!) L0S */ | 1049 | iwl_clear_bit(priv, CSR_GIO_REG, |
1077 | iwl_clear_bit(priv, CSR_GIO_REG, | 1050 | CSR_GIO_REG_VAL_L0S_ENABLED); |
1078 | CSR_GIO_REG_VAL_L0S_ENABLED); | 1051 | IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); |
1079 | IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); | ||
1080 | } | ||
1081 | } | 1052 | } |
1082 | 1053 | ||
1083 | /* Configure analog phase-lock-loop before activating to D0A */ | 1054 | /* Configure analog phase-lock-loop before activating to D0A */ |
@@ -1777,6 +1748,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1777 | 1748 | ||
1778 | mutex_lock(&priv->mutex); | 1749 | mutex_lock(&priv->mutex); |
1779 | 1750 | ||
1751 | if (!ctx->vif || !iwl_is_ready_rf(priv)) { | ||
1752 | /* | ||
1753 | * Huh? But wait ... this can maybe happen when | ||
1754 | * we're in the middle of a firmware restart! | ||
1755 | */ | ||
1756 | err = -EBUSY; | ||
1757 | goto out; | ||
1758 | } | ||
1759 | |||
1780 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; | 1760 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; |
1781 | 1761 | ||
1782 | if (!(interface_modes & BIT(newtype))) { | 1762 | if (!(interface_modes & BIT(newtype))) { |
@@ -1804,6 +1784,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1804 | /* success */ | 1784 | /* success */ |
1805 | iwl_teardown_interface(priv, vif, true); | 1785 | iwl_teardown_interface(priv, vif, true); |
1806 | vif->type = newtype; | 1786 | vif->type = newtype; |
1787 | vif->p2p = newp2p; | ||
1807 | err = iwl_setup_interface(priv, ctx); | 1788 | err = iwl_setup_interface(priv, ctx); |
1808 | WARN_ON(err); | 1789 | WARN_ON(err); |
1809 | /* | 1790 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 82939f851eb9..32a990ff09ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -139,12 +139,6 @@ struct iwl_temp_ops { | |||
139 | void (*temperature)(struct iwl_priv *priv); | 139 | void (*temperature)(struct iwl_priv *priv); |
140 | }; | 140 | }; |
141 | 141 | ||
142 | struct iwl_tt_ops { | ||
143 | bool (*lower_power_detection)(struct iwl_priv *priv); | ||
144 | u8 (*tt_power_mode)(struct iwl_priv *priv); | ||
145 | bool (*ct_kill_check)(struct iwl_priv *priv); | ||
146 | }; | ||
147 | |||
148 | struct iwl_lib_ops { | 142 | struct iwl_lib_ops { |
149 | /* set hw dependent parameters */ | 143 | /* set hw dependent parameters */ |
150 | int (*set_hw_params)(struct iwl_priv *priv); | 144 | int (*set_hw_params)(struct iwl_priv *priv); |
@@ -171,12 +165,6 @@ struct iwl_lib_ops { | |||
171 | void (*cancel_deferred_work)(struct iwl_priv *priv); | 165 | void (*cancel_deferred_work)(struct iwl_priv *priv); |
172 | /* check validity of rtc data address */ | 166 | /* check validity of rtc data address */ |
173 | int (*is_valid_rtc_data_addr)(u32 addr); | 167 | int (*is_valid_rtc_data_addr)(u32 addr); |
174 | |||
175 | int (*dump_nic_event_log)(struct iwl_priv *priv, | ||
176 | bool full_log, char **buf, bool display); | ||
177 | void (*dump_nic_error_log)(struct iwl_priv *priv); | ||
178 | void (*dump_csr)(struct iwl_priv *priv); | ||
179 | int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); | ||
180 | int (*set_channel_switch)(struct iwl_priv *priv, | 168 | int (*set_channel_switch)(struct iwl_priv *priv, |
181 | struct ieee80211_channel_switch *ch_switch); | 169 | struct ieee80211_channel_switch *ch_switch); |
182 | /* power management */ | 170 | /* power management */ |
@@ -196,13 +184,6 @@ struct iwl_lib_ops { | |||
196 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | 184 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); |
197 | 185 | ||
198 | struct iwl_debugfs_ops debugfs_ops; | 186 | struct iwl_debugfs_ops debugfs_ops; |
199 | |||
200 | /* thermal throttling */ | ||
201 | struct iwl_tt_ops tt_ops; | ||
202 | }; | ||
203 | |||
204 | struct iwl_led_ops { | ||
205 | int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); | ||
206 | }; | 187 | }; |
207 | 188 | ||
208 | /* NIC specific ops */ | 189 | /* NIC specific ops */ |
@@ -210,23 +191,11 @@ struct iwl_nic_ops { | |||
210 | void (*additional_nic_config)(struct iwl_priv *priv); | 191 | void (*additional_nic_config)(struct iwl_priv *priv); |
211 | }; | 192 | }; |
212 | 193 | ||
213 | struct iwl_legacy_ops { | ||
214 | void (*post_associate)(struct iwl_priv *priv); | ||
215 | void (*config_ap)(struct iwl_priv *priv); | ||
216 | /* station management */ | ||
217 | int (*update_bcast_stations)(struct iwl_priv *priv); | ||
218 | int (*manage_ibss_station)(struct iwl_priv *priv, | ||
219 | struct ieee80211_vif *vif, bool add); | ||
220 | }; | ||
221 | |||
222 | struct iwl_ops { | 194 | struct iwl_ops { |
223 | const struct iwl_lib_ops *lib; | 195 | const struct iwl_lib_ops *lib; |
224 | const struct iwl_hcmd_ops *hcmd; | 196 | const struct iwl_hcmd_ops *hcmd; |
225 | const struct iwl_hcmd_utils_ops *utils; | 197 | const struct iwl_hcmd_utils_ops *utils; |
226 | const struct iwl_led_ops *led; | ||
227 | const struct iwl_nic_ops *nic; | 198 | const struct iwl_nic_ops *nic; |
228 | const struct iwl_legacy_ops *legacy; | ||
229 | const struct ieee80211_ops *ieee80211_ops; | ||
230 | }; | 199 | }; |
231 | 200 | ||
232 | struct iwl_mod_params { | 201 | struct iwl_mod_params { |
@@ -256,13 +225,6 @@ struct iwl_mod_params { | |||
256 | * @wd_timeout: TX queues watchdog timeout | 225 | * @wd_timeout: TX queues watchdog timeout |
257 | * @temperature_kelvin: temperature report by uCode in kelvin | 226 | * @temperature_kelvin: temperature report by uCode in kelvin |
258 | * @max_event_log_size: size of event log buffer size for ucode event logging | 227 | * @max_event_log_size: size of event log buffer size for ucode event logging |
259 | * @tx_power_by_driver: tx power calibration performed by driver | ||
260 | * instead of uCode | ||
261 | * @ucode_tracing: support ucode continuous tracing | ||
262 | * @sensitivity_calib_by_driver: driver has the capability to perform | ||
263 | * sensitivity calibration operation | ||
264 | * @chain_noise_calib_by_driver: driver has the capability to perform | ||
265 | * chain noise calibration operation | ||
266 | * @shadow_reg_enable: HW shadhow register bit | 228 | * @shadow_reg_enable: HW shadhow register bit |
267 | */ | 229 | */ |
268 | struct iwl_base_params { | 230 | struct iwl_base_params { |
@@ -271,12 +233,10 @@ struct iwl_base_params { | |||
271 | int num_of_ampdu_queues;/* def: HW dependent */ | 233 | int num_of_ampdu_queues;/* def: HW dependent */ |
272 | /* for iwl_apm_init() */ | 234 | /* for iwl_apm_init() */ |
273 | u32 pll_cfg_val; | 235 | u32 pll_cfg_val; |
274 | bool set_l0s; | ||
275 | 236 | ||
276 | const u16 max_ll_items; | 237 | const u16 max_ll_items; |
277 | const bool shadow_ram_support; | 238 | const bool shadow_ram_support; |
278 | u16 led_compensation; | 239 | u16 led_compensation; |
279 | const bool broken_powersave; | ||
280 | int chain_noise_num_beacons; | 240 | int chain_noise_num_beacons; |
281 | bool adv_thermal_throttle; | 241 | bool adv_thermal_throttle; |
282 | bool support_ct_kill_exit; | 242 | bool support_ct_kill_exit; |
@@ -286,17 +246,12 @@ struct iwl_base_params { | |||
286 | unsigned int wd_timeout; | 246 | unsigned int wd_timeout; |
287 | bool temperature_kelvin; | 247 | bool temperature_kelvin; |
288 | u32 max_event_log_size; | 248 | u32 max_event_log_size; |
289 | const bool tx_power_by_driver; | ||
290 | const bool ucode_tracing; | ||
291 | const bool sensitivity_calib_by_driver; | ||
292 | const bool chain_noise_calib_by_driver; | ||
293 | const bool shadow_reg_enable; | 249 | const bool shadow_reg_enable; |
294 | }; | 250 | }; |
295 | /* | 251 | /* |
296 | * @advanced_bt_coexist: support advanced bt coexist | 252 | * @advanced_bt_coexist: support advanced bt coexist |
297 | * @bt_init_traffic_load: specify initial bt traffic load | 253 | * @bt_init_traffic_load: specify initial bt traffic load |
298 | * @bt_prio_boost: default bt priority boost value | 254 | * @bt_prio_boost: default bt priority boost value |
299 | * @bt_statistics: use BT version of statistics notification | ||
300 | * @agg_time_limit: maximum number of uSec in aggregation | 255 | * @agg_time_limit: maximum number of uSec in aggregation |
301 | * @ampdu_factor: Maximum A-MPDU length factor | 256 | * @ampdu_factor: Maximum A-MPDU length factor |
302 | * @ampdu_density: Minimum A-MPDU spacing | 257 | * @ampdu_density: Minimum A-MPDU spacing |
@@ -306,7 +261,6 @@ struct iwl_bt_params { | |||
306 | bool advanced_bt_coexist; | 261 | bool advanced_bt_coexist; |
307 | u8 bt_init_traffic_load; | 262 | u8 bt_init_traffic_load; |
308 | u8 bt_prio_boost; | 263 | u8 bt_prio_boost; |
309 | const bool bt_statistics; | ||
310 | u16 agg_time_limit; | 264 | u16 agg_time_limit; |
311 | u8 ampdu_factor; | 265 | u8 ampdu_factor; |
312 | u8 ampdu_density; | 266 | u8 ampdu_density; |
@@ -337,6 +291,7 @@ struct iwl_ht_params { | |||
337 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | 291 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity |
338 | * @internal_wimax_coex: internal wifi/wimax combo device | 292 | * @internal_wimax_coex: internal wifi/wimax combo device |
339 | * @iq_invert: I/Q inversion | 293 | * @iq_invert: I/Q inversion |
294 | * @disable_otp_refresh: disable OTP refresh current limit | ||
340 | * | 295 | * |
341 | * We enable the driver to be backward compatible wrt API version. The | 296 | * We enable the driver to be backward compatible wrt API version. The |
342 | * driver specifies which APIs it supports (with @ucode_api_max being the | 297 | * driver specifies which APIs it supports (with @ucode_api_max being the |
@@ -387,13 +342,13 @@ struct iwl_cfg { | |||
387 | const bool rx_with_siso_diversity; | 342 | const bool rx_with_siso_diversity; |
388 | const bool internal_wimax_coex; | 343 | const bool internal_wimax_coex; |
389 | const bool iq_invert; | 344 | const bool iq_invert; |
345 | const bool disable_otp_refresh; | ||
390 | }; | 346 | }; |
391 | 347 | ||
392 | /*************************** | 348 | /*************************** |
393 | * L i b * | 349 | * L i b * |
394 | ***************************/ | 350 | ***************************/ |
395 | 351 | ||
396 | struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg); | ||
397 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | 352 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, |
398 | const struct ieee80211_tx_queue_params *params); | 353 | const struct ieee80211_tx_queue_params *params); |
399 | int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); | 354 | int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); |
@@ -598,6 +553,8 @@ extern const struct dev_pm_ops iwl_pm_ops; | |||
598 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 553 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
599 | int iwl_dump_nic_event_log(struct iwl_priv *priv, | 554 | int iwl_dump_nic_event_log(struct iwl_priv *priv, |
600 | bool full_log, char **buf, bool display); | 555 | bool full_log, char **buf, bool display); |
556 | void iwl_dump_csr(struct iwl_priv *priv); | ||
557 | int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); | ||
601 | #ifdef CONFIG_IWLWIFI_DEBUG | 558 | #ifdef CONFIG_IWLWIFI_DEBUG |
602 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, | 559 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, |
603 | struct iwl_rxon_context *ctx); | 560 | struct iwl_rxon_context *ctx); |
@@ -709,11 +666,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | |||
709 | priv->cfg->bt_params->advanced_bt_coexist; | 666 | priv->cfg->bt_params->advanced_bt_coexist; |
710 | } | 667 | } |
711 | 668 | ||
712 | static inline bool iwl_bt_statistics(struct iwl_priv *priv) | ||
713 | { | ||
714 | return priv->bt_statistics; | ||
715 | } | ||
716 | |||
717 | extern bool bt_coex_active; | 669 | extern bool bt_coex_active; |
718 | extern bool bt_siso_mode; | 670 | extern bool bt_siso_mode; |
719 | 671 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 92f6efd2c73f..c272204fccff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -437,8 +437,7 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file, | |||
437 | int pos = 0; | 437 | int pos = 0; |
438 | ssize_t ret = -ENOMEM; | 438 | ssize_t ret = -ENOMEM; |
439 | 439 | ||
440 | ret = pos = priv->cfg->ops->lib->dump_nic_event_log( | 440 | ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true); |
441 | priv, true, &buf, true); | ||
442 | if (buf) { | 441 | if (buf) { |
443 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 442 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
444 | kfree(buf); | 443 | kfree(buf); |
@@ -462,8 +461,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
462 | if (sscanf(buf, "%d", &event_log_flag) != 1) | 461 | if (sscanf(buf, "%d", &event_log_flag) != 1) |
463 | return -EFAULT; | 462 | return -EFAULT; |
464 | if (event_log_flag == 1) | 463 | if (event_log_flag == 1) |
465 | priv->cfg->ops->lib->dump_nic_event_log(priv, true, | 464 | iwl_dump_nic_event_log(priv, true, NULL, false); |
466 | NULL, false); | ||
467 | 465 | ||
468 | return count; | 466 | return count; |
469 | } | 467 | } |
@@ -1268,8 +1266,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, | |||
1268 | if (sscanf(buf, "%d", &csr) != 1) | 1266 | if (sscanf(buf, "%d", &csr) != 1) |
1269 | return -EFAULT; | 1267 | return -EFAULT; |
1270 | 1268 | ||
1271 | if (priv->cfg->ops->lib->dump_csr) | 1269 | iwl_dump_csr(priv); |
1272 | priv->cfg->ops->lib->dump_csr(priv); | ||
1273 | 1270 | ||
1274 | return count; | 1271 | return count; |
1275 | } | 1272 | } |
@@ -1359,13 +1356,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
1359 | int pos = 0; | 1356 | int pos = 0; |
1360 | ssize_t ret = -EFAULT; | 1357 | ssize_t ret = -EFAULT; |
1361 | 1358 | ||
1362 | if (priv->cfg->ops->lib->dump_fh) { | 1359 | ret = pos = iwl_dump_fh(priv, &buf, true); |
1363 | ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); | 1360 | if (buf) { |
1364 | if (buf) { | 1361 | ret = simple_read_from_buffer(user_buf, |
1365 | ret = simple_read_from_buffer(user_buf, | 1362 | count, ppos, buf, pos); |
1366 | count, ppos, buf, pos); | 1363 | kfree(buf); |
1367 | kfree(buf); | ||
1368 | } | ||
1369 | } | 1364 | } |
1370 | 1365 | ||
1371 | return ret; | 1366 | return ret; |
@@ -1728,11 +1723,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1728 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 1723 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); |
1729 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); | 1724 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); |
1730 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 1725 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); |
1731 | if (!priv->cfg->base_params->broken_powersave) { | 1726 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); |
1732 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, | 1727 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); |
1733 | S_IWUSR | S_IRUSR); | ||
1734 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); | ||
1735 | } | ||
1736 | DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); | 1728 | DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); |
1737 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); | 1729 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); |
1738 | DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); | 1730 | DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); |
@@ -1755,29 +1747,20 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1755 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); | 1747 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); |
1756 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); | 1748 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); |
1757 | 1749 | ||
1758 | if (priv->cfg->base_params->sensitivity_calib_by_driver) | 1750 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); |
1759 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); | 1751 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); |
1760 | if (priv->cfg->base_params->chain_noise_calib_by_driver) | 1752 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); |
1761 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 1753 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); |
1762 | if (priv->cfg->base_params->ucode_tracing) | ||
1763 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | ||
1764 | if (iwl_bt_statistics(priv)) | ||
1765 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); | ||
1766 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); | 1754 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); |
1767 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 1755 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); |
1768 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 1756 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); |
1769 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); | 1757 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); |
1770 | if (iwl_advanced_bt_coexist(priv)) | 1758 | if (iwl_advanced_bt_coexist(priv)) |
1771 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 1759 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); |
1772 | if (priv->cfg->base_params->sensitivity_calib_by_driver) | 1760 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
1773 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 1761 | &priv->disable_sens_cal); |
1774 | &priv->disable_sens_cal); | 1762 | DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, |
1775 | if (priv->cfg->base_params->chain_noise_calib_by_driver) | 1763 | &priv->disable_chain_noise_cal); |
1776 | DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, | ||
1777 | &priv->disable_chain_noise_cal); | ||
1778 | if (priv->cfg->base_params->tx_power_by_driver) | ||
1779 | DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, | ||
1780 | &priv->disable_tx_power_cal); | ||
1781 | return 0; | 1764 | return 0; |
1782 | 1765 | ||
1783 | err: | 1766 | err: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 72133368c1f5..e84534c4d956 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -543,13 +543,12 @@ enum iwl_ucode_tlv_type { | |||
543 | * enum iwl_ucode_tlv_flag - ucode API flags | 543 | * enum iwl_ucode_tlv_flag - ucode API flags |
544 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | 544 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously |
545 | * was a separate TLV but moved here to save space. | 545 | * was a separate TLV but moved here to save space. |
546 | * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which | 546 | * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved |
547 | * may be true even if the device doesn't have BT. | ||
548 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | 547 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). |
549 | */ | 548 | */ |
550 | enum iwl_ucode_tlv_flag { | 549 | enum iwl_ucode_tlv_flag { |
551 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | 550 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), |
552 | IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1), | 551 | IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1), |
553 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | 552 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), |
554 | }; | 553 | }; |
555 | 554 | ||
@@ -1170,6 +1169,8 @@ struct iwl_rxon_context { | |||
1170 | bool enabled, is_40mhz; | 1169 | bool enabled, is_40mhz; |
1171 | u8 extension_chan_offset; | 1170 | u8 extension_chan_offset; |
1172 | } ht; | 1171 | } ht; |
1172 | |||
1173 | bool last_tx_rejected; | ||
1173 | }; | 1174 | }; |
1174 | 1175 | ||
1175 | enum iwl_scan_type { | 1176 | enum iwl_scan_type { |
@@ -1355,6 +1356,31 @@ struct iwl_priv { | |||
1355 | u64 timestamp; | 1356 | u64 timestamp; |
1356 | 1357 | ||
1357 | struct { | 1358 | struct { |
1359 | __le32 flag; | ||
1360 | struct statistics_general_common common; | ||
1361 | struct statistics_rx_non_phy rx_non_phy; | ||
1362 | struct statistics_rx_phy rx_ofdm; | ||
1363 | struct statistics_rx_ht_phy rx_ofdm_ht; | ||
1364 | struct statistics_rx_phy rx_cck; | ||
1365 | struct statistics_tx tx; | ||
1366 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1367 | struct statistics_bt_activity bt_activity; | ||
1368 | __le32 num_bt_kills, accum_num_bt_kills; | ||
1369 | #endif | ||
1370 | } statistics; | ||
1371 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1372 | struct { | ||
1373 | struct statistics_general_common common; | ||
1374 | struct statistics_rx_non_phy rx_non_phy; | ||
1375 | struct statistics_rx_phy rx_ofdm; | ||
1376 | struct statistics_rx_ht_phy rx_ofdm_ht; | ||
1377 | struct statistics_rx_phy rx_cck; | ||
1378 | struct statistics_tx tx; | ||
1379 | struct statistics_bt_activity bt_activity; | ||
1380 | } accum_stats, delta_stats, max_delta_stats; | ||
1381 | #endif | ||
1382 | |||
1383 | struct { | ||
1358 | /* INT ICT Table */ | 1384 | /* INT ICT Table */ |
1359 | __le32 *ict_tbl; | 1385 | __le32 *ict_tbl; |
1360 | void *ict_tbl_vir; | 1386 | void *ict_tbl_vir; |
@@ -1385,19 +1411,9 @@ struct iwl_priv { | |||
1385 | u8 phy_calib_chain_noise_reset_cmd; | 1411 | u8 phy_calib_chain_noise_reset_cmd; |
1386 | u8 phy_calib_chain_noise_gain_cmd; | 1412 | u8 phy_calib_chain_noise_gain_cmd; |
1387 | 1413 | ||
1388 | struct iwl_notif_statistics statistics; | ||
1389 | struct iwl_bt_notif_statistics statistics_bt; | ||
1390 | /* counts reply_tx error */ | 1414 | /* counts reply_tx error */ |
1391 | struct reply_tx_error_statistics reply_tx_stats; | 1415 | struct reply_tx_error_statistics reply_tx_stats; |
1392 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; | 1416 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; |
1393 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1394 | struct iwl_notif_statistics accum_statistics; | ||
1395 | struct iwl_notif_statistics delta_statistics; | ||
1396 | struct iwl_notif_statistics max_delta; | ||
1397 | struct iwl_bt_notif_statistics accum_statistics_bt; | ||
1398 | struct iwl_bt_notif_statistics delta_statistics_bt; | ||
1399 | struct iwl_bt_notif_statistics max_delta_bt; | ||
1400 | #endif | ||
1401 | /* notification wait support */ | 1417 | /* notification wait support */ |
1402 | struct list_head notif_waits; | 1418 | struct list_head notif_waits; |
1403 | spinlock_t notif_wait_lock; | 1419 | spinlock_t notif_wait_lock; |
@@ -1422,7 +1438,6 @@ struct iwl_priv { | |||
1422 | bool bt_ch_announce; | 1438 | bool bt_ch_announce; |
1423 | bool bt_full_concurrent; | 1439 | bool bt_full_concurrent; |
1424 | bool bt_ant_couple_ok; | 1440 | bool bt_ant_couple_ok; |
1425 | bool bt_statistics; | ||
1426 | __le32 kill_ack_mask; | 1441 | __le32 kill_ack_mask; |
1427 | __le32 kill_cts_mask; | 1442 | __le32 kill_cts_mask; |
1428 | __le16 bt_valid; | 1443 | __le16 bt_valid; |
@@ -1487,7 +1502,6 @@ struct iwl_priv { | |||
1487 | struct work_struct txpower_work; | 1502 | struct work_struct txpower_work; |
1488 | u32 disable_sens_cal; | 1503 | u32 disable_sens_cal; |
1489 | u32 disable_chain_noise_cal; | 1504 | u32 disable_chain_noise_cal; |
1490 | u32 disable_tx_power_cal; | ||
1491 | struct work_struct run_time_calib_work; | 1505 | struct work_struct run_time_calib_work; |
1492 | struct timer_list statistics_periodic; | 1506 | struct timer_list statistics_periodic; |
1493 | struct timer_list ucode_trace; | 1507 | struct timer_list ucode_trace; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 859b94a12297..402733638f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -215,12 +215,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
215 | return nvm_type; | 215 | return nvm_type; |
216 | } | 216 | } |
217 | 217 | ||
218 | const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) | ||
219 | { | ||
220 | BUG_ON(offset >= priv->cfg->base_params->eeprom_size); | ||
221 | return &priv->eeprom[offset]; | ||
222 | } | ||
223 | |||
224 | static int iwl_init_otp_access(struct iwl_priv *priv) | 218 | static int iwl_init_otp_access(struct iwl_priv *priv) |
225 | { | 219 | { |
226 | int ret; | 220 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 0e9d9703636a..9ce052573c6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -309,7 +309,6 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv); | |||
309 | const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); | 309 | const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); |
310 | int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); | 310 | int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); |
311 | u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); | 311 | u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); |
312 | const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); | ||
313 | int iwl_init_channel_map(struct iwl_priv *priv); | 312 | int iwl_init_channel_map(struct iwl_priv *priv); |
314 | void iwl_free_channel_map(struct iwl_priv *priv); | 313 | void iwl_free_channel_map(struct iwl_priv *priv); |
315 | const struct iwl_channel_info *iwl_get_channel_info( | 314 | const struct iwl_channel_info *iwl_get_channel_info( |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index e7a1bc6b76fd..6dfa806aefec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -77,14 +77,14 @@ | |||
77 | /** | 77 | /** |
78 | * Keep-Warm (KW) buffer base address. | 78 | * Keep-Warm (KW) buffer base address. |
79 | * | 79 | * |
80 | * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the | 80 | * Driver must allocate a 4KByte buffer that is for keeping the |
81 | * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency | 81 | * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency |
82 | * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host | 82 | * DRAM access when doing Txing or Rxing. The dummy accesses prevent host |
83 | * from going into a power-savings mode that would cause higher DRAM latency, | 83 | * from going into a power-savings mode that would cause higher DRAM latency, |
84 | * and possible data over/under-runs, before all Tx/Rx is complete. | 84 | * and possible data over/under-runs, before all Tx/Rx is complete. |
85 | * | 85 | * |
86 | * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) | 86 | * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) |
87 | * of the buffer, which must be 4K aligned. Once this is set up, the 4965 | 87 | * of the buffer, which must be 4K aligned. Once this is set up, the device |
88 | * automatically invokes keep-warm accesses when normal accesses might not | 88 | * automatically invokes keep-warm accesses when normal accesses might not |
89 | * be sufficient to maintain fast DRAM response. | 89 | * be sufficient to maintain fast DRAM response. |
90 | * | 90 | * |
@@ -97,7 +97,7 @@ | |||
97 | /** | 97 | /** |
98 | * TFD Circular Buffers Base (CBBC) addresses | 98 | * TFD Circular Buffers Base (CBBC) addresses |
99 | * | 99 | * |
100 | * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident | 100 | * Device has 16 base pointer registers, one for each of 16 host-DRAM-resident |
101 | * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) | 101 | * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) |
102 | * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 | 102 | * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 |
103 | * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte | 103 | * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte |
@@ -116,16 +116,16 @@ | |||
116 | /** | 116 | /** |
117 | * Rx SRAM Control and Status Registers (RSCSR) | 117 | * Rx SRAM Control and Status Registers (RSCSR) |
118 | * | 118 | * |
119 | * These registers provide handshake between driver and 4965 for the Rx queue | 119 | * These registers provide handshake between driver and device for the Rx queue |
120 | * (this queue handles *all* command responses, notifications, Rx data, etc. | 120 | * (this queue handles *all* command responses, notifications, Rx data, etc. |
121 | * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx | 121 | * sent from uCode to host driver). Unlike Tx, there is only one Rx |
122 | * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can | 122 | * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can |
123 | * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer | 123 | * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer |
124 | * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 | 124 | * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 |
125 | * mapping between RBDs and RBs. | 125 | * mapping between RBDs and RBs. |
126 | * | 126 | * |
127 | * Driver must allocate host DRAM memory for the following, and set the | 127 | * Driver must allocate host DRAM memory for the following, and set the |
128 | * physical address of each into 4965 registers: | 128 | * physical address of each into device registers: |
129 | * | 129 | * |
130 | * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 | 130 | * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 |
131 | * entries (although any power of 2, up to 4096, is selectable by driver). | 131 | * entries (although any power of 2, up to 4096, is selectable by driver). |
@@ -140,20 +140,20 @@ | |||
140 | * Driver sets physical address [35:8] of base of RBD circular buffer | 140 | * Driver sets physical address [35:8] of base of RBD circular buffer |
141 | * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. | 141 | * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. |
142 | * | 142 | * |
143 | * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers | 143 | * 2) Rx status buffer, 8 bytes, in which uCode indicates which Rx Buffers |
144 | * (RBs) have been filled, via a "write pointer", actually the index of | 144 | * (RBs) have been filled, via a "write pointer", actually the index of |
145 | * the RB's corresponding RBD within the circular buffer. Driver sets | 145 | * the RB's corresponding RBD within the circular buffer. Driver sets |
146 | * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. | 146 | * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. |
147 | * | 147 | * |
148 | * Bit fields in lower dword of Rx status buffer (upper dword not used | 148 | * Bit fields in lower dword of Rx status buffer (upper dword not used |
149 | * by driver; see struct iwl4965_shared, val0): | 149 | * by driver: |
150 | * 31-12: Not used by driver | 150 | * 31-12: Not used by driver |
151 | * 11- 0: Index of last filled Rx buffer descriptor | 151 | * 11- 0: Index of last filled Rx buffer descriptor |
152 | * (4965 writes, driver reads this value) | 152 | * (device writes, driver reads this value) |
153 | * | 153 | * |
154 | * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must | 154 | * As the driver prepares Receive Buffers (RBs) for device to fill, driver must |
155 | * enter pointers to these RBs into contiguous RBD circular buffer entries, | 155 | * enter pointers to these RBs into contiguous RBD circular buffer entries, |
156 | * and update the 4965's "write" index register, | 156 | * and update the device's "write" index register, |
157 | * FH_RSCSR_CHNL0_RBDCB_WPTR_REG. | 157 | * FH_RSCSR_CHNL0_RBDCB_WPTR_REG. |
158 | * | 158 | * |
159 | * This "write" index corresponds to the *next* RBD that the driver will make | 159 | * This "write" index corresponds to the *next* RBD that the driver will make |
@@ -162,12 +162,12 @@ | |||
162 | * RBs), should be 8 after preparing the first 8 RBs (for example), and must | 162 | * RBs), should be 8 after preparing the first 8 RBs (for example), and must |
163 | * wrap back to 0 at the end of the circular buffer (but don't wrap before | 163 | * wrap back to 0 at the end of the circular buffer (but don't wrap before |
164 | * "read" index has advanced past 1! See below). | 164 | * "read" index has advanced past 1! See below). |
165 | * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. | 165 | * NOTE: DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. |
166 | * | 166 | * |
167 | * As the 4965 fills RBs (referenced from contiguous RBDs within the circular | 167 | * As the device fills RBs (referenced from contiguous RBDs within the circular |
168 | * buffer), it updates the Rx status buffer in host DRAM, 2) described above, | 168 | * buffer), it updates the Rx status buffer in host DRAM, 2) described above, |
169 | * to tell the driver the index of the latest filled RBD. The driver must | 169 | * to tell the driver the index of the latest filled RBD. The driver must |
170 | * read this "read" index from DRAM after receiving an Rx interrupt from 4965. | 170 | * read this "read" index from DRAM after receiving an Rx interrupt from device |
171 | * | 171 | * |
172 | * The driver must also internally keep track of a third index, which is the | 172 | * The driver must also internally keep track of a third index, which is the |
173 | * next RBD to process. When receiving an Rx interrupt, driver should process | 173 | * next RBD to process. When receiving an Rx interrupt, driver should process |
@@ -176,7 +176,7 @@ | |||
176 | * driver may process the RB pointed to by RBD 0. Depending on volume of | 176 | * driver may process the RB pointed to by RBD 0. Depending on volume of |
177 | * traffic, there may be many RBs to process. | 177 | * traffic, there may be many RBs to process. |
178 | * | 178 | * |
179 | * If read index == write index, 4965 thinks there is no room to put new data. | 179 | * If read index == write index, device thinks there is no room to put new data. |
180 | * Due to this, the maximum number of filled RBs is 255, instead of 256. To | 180 | * Due to this, the maximum number of filled RBs is 255, instead of 256. To |
181 | * be safe, make sure that there is a gap of at least 2 RBDs between "write" | 181 | * be safe, make sure that there is a gap of at least 2 RBDs between "write" |
182 | * and "read" indexes; that is, make sure that there are no more than 254 | 182 | * and "read" indexes; that is, make sure that there are no more than 254 |
@@ -303,7 +303,7 @@ | |||
303 | /** | 303 | /** |
304 | * Transmit DMA Channel Control/Status Registers (TCSR) | 304 | * Transmit DMA Channel Control/Status Registers (TCSR) |
305 | * | 305 | * |
306 | * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels | 306 | * Device has one configuration register for each of 8 Tx DMA/FIFO channels |
307 | * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, | 307 | * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, |
308 | * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. | 308 | * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. |
309 | * | 309 | * |
@@ -326,7 +326,6 @@ | |||
326 | #define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) | 326 | #define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) |
327 | 327 | ||
328 | /* Find Control/Status reg for given Tx DMA/FIFO channel */ | 328 | /* Find Control/Status reg for given Tx DMA/FIFO channel */ |
329 | #define FH49_TCSR_CHNL_NUM (7) | ||
330 | #define FH50_TCSR_CHNL_NUM (8) | 329 | #define FH50_TCSR_CHNL_NUM (8) |
331 | 330 | ||
332 | /* TCSR: tx_config register values */ | 331 | /* TCSR: tx_config register values */ |
@@ -424,7 +423,6 @@ | |||
424 | #define RX_LOW_WATERMARK 8 | 423 | #define RX_LOW_WATERMARK 8 |
425 | 424 | ||
426 | /* Size of one Rx buffer in host DRAM */ | 425 | /* Size of one Rx buffer in host DRAM */ |
427 | #define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */ | ||
428 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | 426 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) |
429 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | 427 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) |
430 | 428 | ||
@@ -443,7 +441,7 @@ struct iwl_rb_status { | |||
443 | __le16 closed_fr_num; | 441 | __le16 closed_fr_num; |
444 | __le16 finished_rb_num; | 442 | __le16 finished_rb_num; |
445 | __le16 finished_fr_nam; | 443 | __le16 finished_fr_nam; |
446 | __le32 __unused; /* 3945 only */ | 444 | __le32 __unused; |
447 | } __packed; | 445 | } __packed; |
448 | 446 | ||
449 | 447 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 9177b553fe57..8f0beb992ccf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -143,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
143 | { | 143 | { |
144 | int ret; | 144 | int ret; |
145 | 145 | ||
146 | BUG_ON(!(cmd->flags & CMD_ASYNC)); | 146 | if (WARN_ON(!(cmd->flags & CMD_ASYNC))) |
147 | return -EINVAL; | ||
147 | 148 | ||
148 | /* An asynchronous command can not expect an SKB to be set. */ | 149 | /* An asynchronous command can not expect an SKB to be set. */ |
149 | BUG_ON(cmd->flags & CMD_WANT_SKB); | 150 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) |
151 | return -EINVAL; | ||
150 | 152 | ||
151 | /* Assign a generic callback if one is not provided */ | 153 | /* Assign a generic callback if one is not provided */ |
152 | if (!cmd->callback) | 154 | if (!cmd->callback) |
@@ -169,10 +171,12 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
169 | int cmd_idx; | 171 | int cmd_idx; |
170 | int ret; | 172 | int ret; |
171 | 173 | ||
172 | lockdep_assert_held(&priv->mutex); | 174 | if (WARN_ON(cmd->flags & CMD_ASYNC)) |
175 | return -EINVAL; | ||
173 | 176 | ||
174 | /* A synchronous command can not have a callback set. */ | 177 | /* A synchronous command can not have a callback set. */ |
175 | BUG_ON((cmd->flags & CMD_ASYNC) || cmd->callback); | 178 | if (WARN_ON(cmd->callback)) |
179 | return -EINVAL; | ||
176 | 180 | ||
177 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | 181 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
178 | get_cmd_string(cmd->id)); | 182 | get_cmd_string(cmd->id)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 5da5761c74b1..9309ff2df4c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -131,6 +131,19 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, | |||
131 | ieee80211_stop_queue(priv->hw, ac); | 131 | ieee80211_stop_queue(priv->hw, ac); |
132 | } | 132 | } |
133 | 133 | ||
134 | static inline void iwl_wake_any_queue(struct iwl_priv *priv, | ||
135 | struct iwl_rxon_context *ctx) | ||
136 | { | ||
137 | u8 ac; | ||
138 | |||
139 | for (ac = 0; ac < AC_NUM; ac++) { | ||
140 | IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n", | ||
141 | ac, (atomic_read(&priv->queue_stop_count[ac]) > 0) | ||
142 | ? "stopped" : "awake"); | ||
143 | iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]); | ||
144 | } | ||
145 | } | ||
146 | |||
134 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue | 147 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue |
135 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue | 148 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue |
136 | 149 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index c2862d4e00e3..d798c2a152d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -61,10 +61,16 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { | |||
61 | { .throughput = 300 * 1024 - 1, .blink_time = 50 }, | 61 | { .throughput = 300 * 1024 - 1, .blink_time = 50 }, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | /* Set led register off */ | ||
65 | void iwlagn_led_enable(struct iwl_priv *priv) | ||
66 | { | ||
67 | iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); | ||
68 | } | ||
69 | |||
64 | /* | 70 | /* |
65 | * Adjust led blink rate to compensate on a MAC Clock difference on every HW | 71 | * Adjust led blink rate to compensate on a MAC Clock difference on every HW |
66 | * Led blink rate analysis showed an average deviation of 0% on 3945, | 72 | * Led blink rate analysis showed an average deviation of 20% on 5000 series |
67 | * 5% on 4965 HW and 20% on 5000 series and up. | 73 | * and up. |
68 | * Need to compensate on the led on/off time per HW according to the deviation | 74 | * Need to compensate on the led on/off time per HW according to the deviation |
69 | * to achieve the desired led frequency | 75 | * to achieve the desired led frequency |
70 | * The calculation is: (100-averageDeviation)/100 * blinkTime | 76 | * The calculation is: (100-averageDeviation)/100 * blinkTime |
@@ -84,6 +90,24 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv, | |||
84 | return (u8)((time * compensation) >> 6); | 90 | return (u8)((time * compensation) >> 6); |
85 | } | 91 | } |
86 | 92 | ||
93 | static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | ||
94 | { | ||
95 | struct iwl_host_cmd cmd = { | ||
96 | .id = REPLY_LEDS_CMD, | ||
97 | .len = sizeof(struct iwl_led_cmd), | ||
98 | .data = led_cmd, | ||
99 | .flags = CMD_ASYNC, | ||
100 | .callback = NULL, | ||
101 | }; | ||
102 | u32 reg; | ||
103 | |||
104 | reg = iwl_read32(priv, CSR_LED_REG); | ||
105 | if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) | ||
106 | iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); | ||
107 | |||
108 | return iwl_send_cmd(priv, &cmd); | ||
109 | } | ||
110 | |||
87 | /* Set led pattern command */ | 111 | /* Set led pattern command */ |
88 | static int iwl_led_cmd(struct iwl_priv *priv, | 112 | static int iwl_led_cmd(struct iwl_priv *priv, |
89 | unsigned long on, | 113 | unsigned long on, |
@@ -108,7 +132,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, | |||
108 | led_cmd.off = iwl_blink_compensation(priv, off, | 132 | led_cmd.off = iwl_blink_compensation(priv, off, |
109 | priv->cfg->base_params->led_compensation); | 133 | priv->cfg->base_params->led_compensation); |
110 | 134 | ||
111 | ret = priv->cfg->ops->led->cmd(priv, &led_cmd); | 135 | ret = iwl_send_led_cmd(priv, &led_cmd); |
112 | if (!ret) { | 136 | if (!ret) { |
113 | priv->blink_on = on; | 137 | priv->blink_on = on; |
114 | priv->blink_off = off; | 138 | priv->blink_off = off; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 05b8e8f7dd4a..1c93dfef6933 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -50,6 +50,7 @@ enum iwl_led_mode { | |||
50 | IWL_LED_BLINK, | 50 | IWL_LED_BLINK, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | void iwlagn_led_enable(struct iwl_priv *priv); | ||
53 | void iwl_leds_init(struct iwl_priv *priv); | 54 | void iwl_leds_init(struct iwl_priv *priv); |
54 | void iwl_leds_exit(struct iwl_priv *priv); | 55 | void iwl_leds_exit(struct iwl_priv *priv); |
55 | 56 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c43c8e66de73..595c930b28ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -188,9 +188,10 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
188 | table = range_0; | 188 | table = range_0; |
189 | } | 189 | } |
190 | 190 | ||
191 | BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); | 191 | if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM)) |
192 | 192 | memset(cmd, 0, sizeof(*cmd)); | |
193 | *cmd = table[lvl].cmd; | 193 | else |
194 | *cmd = table[lvl].cmd; | ||
194 | 195 | ||
195 | if (period == 0) { | 196 | if (period == 0) { |
196 | skip = 0; | 197 | skip = 0; |
@@ -354,16 +355,12 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
354 | 355 | ||
355 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; | 356 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; |
356 | 357 | ||
357 | if (priv->cfg->base_params->broken_powersave) | 358 | if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
358 | iwl_power_sleep_cam_cmd(priv, cmd); | ||
359 | else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) | ||
360 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); | 359 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); |
361 | else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && | 360 | else if (iwl_tt_is_low_power_state(priv)) { |
362 | priv->cfg->ops->lib->tt_ops.tt_power_mode && | ||
363 | priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { | ||
364 | /* in thermal throttling low power state */ | 361 | /* in thermal throttling low power state */ |
365 | iwl_static_sleep_cmd(priv, cmd, | 362 | iwl_static_sleep_cmd(priv, cmd, |
366 | priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); | 363 | iwl_tt_current_power_mode(priv), dtimper); |
367 | } else if (!enabled) | 364 | } else if (!enabled) |
368 | iwl_power_sleep_cam_cmd(priv, cmd); | 365 | iwl_power_sleep_cam_cmd(priv, cmd); |
369 | else if (priv->power_data.debug_sleep_level_override >= 0) | 366 | else if (priv->power_data.debug_sleep_level_override >= 0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index c960195df989..f00d188b2cfc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -107,17 +107,7 @@ | |||
107 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, | 107 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, |
108 | * but one DMA channel may take input from several queues. | 108 | * but one DMA channel may take input from several queues. |
109 | * | 109 | * |
110 | * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows | 110 | * Tx DMA FIFOs have dedicated purposes. |
111 | * (cf. default_queue_to_tx_fifo in iwl-4965.c): | ||
112 | * | ||
113 | * 0 -- EDCA BK (background) frames, lowest priority | ||
114 | * 1 -- EDCA BE (best effort) frames, normal priority | ||
115 | * 2 -- EDCA VI (video) frames, higher priority | ||
116 | * 3 -- EDCA VO (voice) and management frames, highest priority | ||
117 | * 4 -- Commands (e.g. RXON, etc.) | ||
118 | * 5 -- unused (HCCA) | ||
119 | * 6 -- unused (HCCA) | ||
120 | * 7 -- not used by driver (device-internal only) | ||
121 | * | 111 | * |
122 | * For 5000 series and up, they are used differently | 112 | * For 5000 series and up, they are used differently |
123 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): | 113 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): |
@@ -151,7 +141,7 @@ | |||
151 | * Tx completion may end up being out-of-order). | 141 | * Tx completion may end up being out-of-order). |
152 | * | 142 | * |
153 | * The driver must maintain the queue's Byte Count table in host DRAM | 143 | * The driver must maintain the queue's Byte Count table in host DRAM |
154 | * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. | 144 | * for this mode. |
155 | * This mode does not support fragmentation. | 145 | * This mode does not support fragmentation. |
156 | * | 146 | * |
157 | * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. | 147 | * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. |
@@ -164,7 +154,7 @@ | |||
164 | * | 154 | * |
165 | * Driver controls scheduler operation via 3 means: | 155 | * Driver controls scheduler operation via 3 means: |
166 | * 1) Scheduler registers | 156 | * 1) Scheduler registers |
167 | * 2) Shared scheduler data base in internal 4956 SRAM | 157 | * 2) Shared scheduler data base in internal SRAM |
168 | * 3) Shared data in host DRAM | 158 | * 3) Shared data in host DRAM |
169 | * | 159 | * |
170 | * Initialization: | 160 | * Initialization: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c421f566982f..b49819ca2cd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -390,21 +390,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
390 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | 390 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal |
391 | * operation state. | 391 | * operation state. |
392 | */ | 392 | */ |
393 | static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | 393 | static bool iwl_good_ack_health(struct iwl_priv *priv, |
394 | struct statistics_tx *cur) | ||
394 | { | 395 | { |
395 | int actual_delta, expected_delta, ba_timeout_delta; | 396 | int actual_delta, expected_delta, ba_timeout_delta; |
396 | struct statistics_tx *cur, *old; | 397 | struct statistics_tx *old; |
397 | 398 | ||
398 | if (priv->_agn.agg_tids_count) | 399 | if (priv->_agn.agg_tids_count) |
399 | return true; | 400 | return true; |
400 | 401 | ||
401 | if (iwl_bt_statistics(priv)) { | 402 | old = &priv->statistics.tx; |
402 | cur = &pkt->u.stats_bt.tx; | ||
403 | old = &priv->_agn.statistics_bt.tx; | ||
404 | } else { | ||
405 | cur = &pkt->u.stats.tx; | ||
406 | old = &priv->_agn.statistics.tx; | ||
407 | } | ||
408 | 403 | ||
409 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | 404 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - |
410 | le32_to_cpu(old->actual_ack_cnt); | 405 | le32_to_cpu(old->actual_ack_cnt); |
@@ -430,10 +425,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt | |||
430 | * DEBUG is not, these will just compile out. | 425 | * DEBUG is not, these will just compile out. |
431 | */ | 426 | */ |
432 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", | 427 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", |
433 | priv->_agn.delta_statistics.tx.rx_detected_cnt); | 428 | priv->delta_stats.tx.rx_detected_cnt); |
434 | IWL_DEBUG_RADIO(priv, | 429 | IWL_DEBUG_RADIO(priv, |
435 | "ack_or_ba_timeout_collision delta %d\n", | 430 | "ack_or_ba_timeout_collision delta %d\n", |
436 | priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); | 431 | priv->delta_stats.tx.ack_or_ba_timeout_collision); |
437 | #endif | 432 | #endif |
438 | 433 | ||
439 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) | 434 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) |
@@ -450,7 +445,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt | |||
450 | * to improve the throughput. | 445 | * to improve the throughput. |
451 | */ | 446 | */ |
452 | static bool iwl_good_plcp_health(struct iwl_priv *priv, | 447 | static bool iwl_good_plcp_health(struct iwl_priv *priv, |
453 | struct iwl_rx_packet *pkt, unsigned int msecs) | 448 | struct statistics_rx_phy *cur_ofdm, |
449 | struct statistics_rx_ht_phy *cur_ofdm_ht, | ||
450 | unsigned int msecs) | ||
454 | { | 451 | { |
455 | int delta; | 452 | int delta; |
456 | int threshold = priv->cfg->base_params->plcp_delta_threshold; | 453 | int threshold = priv->cfg->base_params->plcp_delta_threshold; |
@@ -460,29 +457,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, | |||
460 | return true; | 457 | return true; |
461 | } | 458 | } |
462 | 459 | ||
463 | if (iwl_bt_statistics(priv)) { | 460 | delta = le32_to_cpu(cur_ofdm->plcp_err) - |
464 | struct statistics_rx_bt *cur, *old; | 461 | le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) + |
465 | 462 | le32_to_cpu(cur_ofdm_ht->plcp_err) - | |
466 | cur = &pkt->u.stats_bt.rx; | 463 | le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err); |
467 | old = &priv->_agn.statistics_bt.rx; | ||
468 | |||
469 | delta = le32_to_cpu(cur->ofdm.plcp_err) - | ||
470 | le32_to_cpu(old->ofdm.plcp_err) + | ||
471 | le32_to_cpu(cur->ofdm_ht.plcp_err) - | ||
472 | le32_to_cpu(old->ofdm_ht.plcp_err); | ||
473 | } else { | ||
474 | struct statistics_rx *cur, *old; | ||
475 | |||
476 | cur = &pkt->u.stats.rx; | ||
477 | old = &priv->_agn.statistics.rx; | ||
478 | 464 | ||
479 | delta = le32_to_cpu(cur->ofdm.plcp_err) - | 465 | /* Can be negative if firmware reset statistics */ |
480 | le32_to_cpu(old->ofdm.plcp_err) + | ||
481 | le32_to_cpu(cur->ofdm_ht.plcp_err) - | ||
482 | le32_to_cpu(old->ofdm_ht.plcp_err); | ||
483 | } | ||
484 | |||
485 | /* Can be negative if firmware reseted statistics */ | ||
486 | if (delta <= 0) | 466 | if (delta <= 0) |
487 | return true; | 467 | return true; |
488 | 468 | ||
@@ -497,44 +477,36 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, | |||
497 | } | 477 | } |
498 | 478 | ||
499 | static void iwl_recover_from_statistics(struct iwl_priv *priv, | 479 | static void iwl_recover_from_statistics(struct iwl_priv *priv, |
500 | struct iwl_rx_packet *pkt) | 480 | struct statistics_rx_phy *cur_ofdm, |
481 | struct statistics_rx_ht_phy *cur_ofdm_ht, | ||
482 | struct statistics_tx *tx, | ||
483 | unsigned long stamp) | ||
501 | { | 484 | { |
502 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; | 485 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; |
503 | unsigned int msecs; | 486 | unsigned int msecs; |
504 | unsigned long stamp; | ||
505 | 487 | ||
506 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 488 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
507 | return; | 489 | return; |
508 | 490 | ||
509 | stamp = jiffies; | ||
510 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | 491 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); |
511 | 492 | ||
512 | /* Only gather statistics and update time stamp when not associated */ | 493 | /* Only gather statistics and update time stamp when not associated */ |
513 | if (!iwl_is_any_associated(priv)) | 494 | if (!iwl_is_any_associated(priv)) |
514 | goto out; | 495 | return; |
515 | 496 | ||
516 | /* Do not check/recover when do not have enough statistics data */ | 497 | /* Do not check/recover when do not have enough statistics data */ |
517 | if (msecs < 99) | 498 | if (msecs < 99) |
518 | return; | 499 | return; |
519 | 500 | ||
520 | if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { | 501 | if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) { |
521 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); | 502 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); |
522 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | 503 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) |
523 | return; | 504 | return; |
524 | } | 505 | } |
525 | 506 | ||
526 | if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) | 507 | if (mod_params->plcp_check && |
508 | !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | ||
527 | iwl_force_reset(priv, IWL_RF_RESET, false); | 509 | iwl_force_reset(priv, IWL_RF_RESET, false); |
528 | |||
529 | out: | ||
530 | if (iwl_bt_statistics(priv)) | ||
531 | memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | ||
532 | sizeof(priv->_agn.statistics_bt)); | ||
533 | else | ||
534 | memcpy(&priv->_agn.statistics, &pkt->u.stats, | ||
535 | sizeof(priv->_agn.statistics)); | ||
536 | |||
537 | priv->rx_statistics_jiffies = stamp; | ||
538 | } | 510 | } |
539 | 511 | ||
540 | /* Calculate noise level, based on measurements during network silence just | 512 | /* Calculate noise level, based on measurements during network silence just |
@@ -548,10 +520,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
548 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; | 520 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; |
549 | int last_rx_noise; | 521 | int last_rx_noise; |
550 | 522 | ||
551 | if (iwl_bt_statistics(priv)) | 523 | rx_info = &priv->statistics.rx_non_phy; |
552 | rx_info = &(priv->_agn.statistics_bt.rx.general.common); | 524 | |
553 | else | ||
554 | rx_info = &(priv->_agn.statistics.rx.general); | ||
555 | bcn_silence_a = | 525 | bcn_silence_a = |
556 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | 526 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; |
557 | bcn_silence_b = | 527 | bcn_silence_b = |
@@ -583,105 +553,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
583 | last_rx_noise); | 553 | last_rx_noise); |
584 | } | 554 | } |
585 | 555 | ||
556 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
586 | /* | 557 | /* |
587 | * based on the assumption of all statistics counter are in DWORD | 558 | * based on the assumption of all statistics counter are in DWORD |
588 | * FIXME: This function is for debugging, do not deal with | 559 | * FIXME: This function is for debugging, do not deal with |
589 | * the case of counters roll-over. | 560 | * the case of counters roll-over. |
590 | */ | 561 | */ |
591 | static void iwl_accumulative_statistics(struct iwl_priv *priv, | 562 | static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta, |
592 | __le32 *stats) | 563 | __le32 *max_delta, __le32 *accum, int size) |
593 | { | 564 | { |
594 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 565 | int i; |
595 | int i, size; | 566 | |
596 | __le32 *prev_stats; | 567 | for (i = 0; |
597 | u32 *accum_stats; | 568 | i < size / sizeof(__le32); |
598 | u32 *delta, *max_delta; | 569 | i++, prev++, cur++, delta++, max_delta++, accum++) { |
599 | struct statistics_general_common *general, *accum_general; | 570 | if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) { |
600 | struct statistics_tx *tx, *accum_tx; | 571 | *delta = cpu_to_le32( |
601 | 572 | le32_to_cpu(*cur) - le32_to_cpu(*prev)); | |
602 | if (iwl_bt_statistics(priv)) { | 573 | le32_add_cpu(accum, le32_to_cpu(*delta)); |
603 | prev_stats = (__le32 *)&priv->_agn.statistics_bt; | 574 | if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta)) |
604 | accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; | ||
605 | size = sizeof(struct iwl_bt_notif_statistics); | ||
606 | general = &priv->_agn.statistics_bt.general.common; | ||
607 | accum_general = &priv->_agn.accum_statistics_bt.general.common; | ||
608 | tx = &priv->_agn.statistics_bt.tx; | ||
609 | accum_tx = &priv->_agn.accum_statistics_bt.tx; | ||
610 | delta = (u32 *)&priv->_agn.delta_statistics_bt; | ||
611 | max_delta = (u32 *)&priv->_agn.max_delta_bt; | ||
612 | } else { | ||
613 | prev_stats = (__le32 *)&priv->_agn.statistics; | ||
614 | accum_stats = (u32 *)&priv->_agn.accum_statistics; | ||
615 | size = sizeof(struct iwl_notif_statistics); | ||
616 | general = &priv->_agn.statistics.general.common; | ||
617 | accum_general = &priv->_agn.accum_statistics.general.common; | ||
618 | tx = &priv->_agn.statistics.tx; | ||
619 | accum_tx = &priv->_agn.accum_statistics.tx; | ||
620 | delta = (u32 *)&priv->_agn.delta_statistics; | ||
621 | max_delta = (u32 *)&priv->_agn.max_delta; | ||
622 | } | ||
623 | for (i = sizeof(__le32); i < size; | ||
624 | i += sizeof(__le32), stats++, prev_stats++, delta++, | ||
625 | max_delta++, accum_stats++) { | ||
626 | if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { | ||
627 | *delta = (le32_to_cpu(*stats) - | ||
628 | le32_to_cpu(*prev_stats)); | ||
629 | *accum_stats += *delta; | ||
630 | if (*delta > *max_delta) | ||
631 | *max_delta = *delta; | 575 | *max_delta = *delta; |
632 | } | 576 | } |
633 | } | 577 | } |
578 | } | ||
634 | 579 | ||
635 | /* reset accumulative statistics for "no-counter" type statistics */ | 580 | static void |
636 | accum_general->temperature = general->temperature; | 581 | iwl_accumulative_statistics(struct iwl_priv *priv, |
637 | accum_general->temperature_m = general->temperature_m; | 582 | struct statistics_general_common *common, |
638 | accum_general->ttl_timestamp = general->ttl_timestamp; | 583 | struct statistics_rx_non_phy *rx_non_phy, |
639 | accum_tx->tx_power.ant_a = tx->tx_power.ant_a; | 584 | struct statistics_rx_phy *rx_ofdm, |
640 | accum_tx->tx_power.ant_b = tx->tx_power.ant_b; | 585 | struct statistics_rx_ht_phy *rx_ofdm_ht, |
641 | accum_tx->tx_power.ant_c = tx->tx_power.ant_c; | 586 | struct statistics_rx_phy *rx_cck, |
642 | #endif | 587 | struct statistics_tx *tx, |
588 | struct statistics_bt_activity *bt_activity) | ||
589 | { | ||
590 | #define ACCUM(_name) \ | ||
591 | accum_stats((__le32 *)&priv->statistics._name, \ | ||
592 | (__le32 *)_name, \ | ||
593 | (__le32 *)&priv->delta_stats._name, \ | ||
594 | (__le32 *)&priv->max_delta_stats._name, \ | ||
595 | (__le32 *)&priv->accum_stats._name, \ | ||
596 | sizeof(*_name)); | ||
597 | |||
598 | ACCUM(common); | ||
599 | ACCUM(rx_non_phy); | ||
600 | ACCUM(rx_ofdm); | ||
601 | ACCUM(rx_ofdm_ht); | ||
602 | ACCUM(rx_cck); | ||
603 | ACCUM(tx); | ||
604 | if (bt_activity) | ||
605 | ACCUM(bt_activity); | ||
606 | #undef ACCUM | ||
607 | } | ||
608 | #else | ||
609 | static inline void | ||
610 | iwl_accumulative_statistics(struct iwl_priv *priv, | ||
611 | struct statistics_general_common *common, | ||
612 | struct statistics_rx_non_phy *rx_non_phy, | ||
613 | struct statistics_rx_phy *rx_ofdm, | ||
614 | struct statistics_rx_ht_phy *rx_ofdm_ht, | ||
615 | struct statistics_rx_phy *rx_cck, | ||
616 | struct statistics_tx *tx, | ||
617 | struct statistics_bt_activity *bt_activity) | ||
618 | { | ||
643 | } | 619 | } |
620 | #endif | ||
644 | 621 | ||
645 | static void iwl_rx_statistics(struct iwl_priv *priv, | 622 | static void iwl_rx_statistics(struct iwl_priv *priv, |
646 | struct iwl_rx_mem_buffer *rxb) | 623 | struct iwl_rx_mem_buffer *rxb) |
647 | { | 624 | { |
625 | unsigned long stamp = jiffies; | ||
648 | const int reg_recalib_period = 60; | 626 | const int reg_recalib_period = 60; |
649 | int change; | 627 | int change; |
650 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 628 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
629 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
630 | __le32 *flag; | ||
631 | struct statistics_general_common *common; | ||
632 | struct statistics_rx_non_phy *rx_non_phy; | ||
633 | struct statistics_rx_phy *rx_ofdm; | ||
634 | struct statistics_rx_ht_phy *rx_ofdm_ht; | ||
635 | struct statistics_rx_phy *rx_cck; | ||
636 | struct statistics_tx *tx; | ||
637 | struct statistics_bt_activity *bt_activity; | ||
638 | |||
639 | len -= sizeof(struct iwl_cmd_header); /* skip header */ | ||
640 | |||
641 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", | ||
642 | len); | ||
643 | |||
644 | if (len == sizeof(struct iwl_bt_notif_statistics)) { | ||
645 | struct iwl_bt_notif_statistics *stats; | ||
646 | stats = &pkt->u.stats_bt; | ||
647 | flag = &stats->flag; | ||
648 | common = &stats->general.common; | ||
649 | rx_non_phy = &stats->rx.general.common; | ||
650 | rx_ofdm = &stats->rx.ofdm; | ||
651 | rx_ofdm_ht = &stats->rx.ofdm_ht; | ||
652 | rx_cck = &stats->rx.cck; | ||
653 | tx = &stats->tx; | ||
654 | bt_activity = &stats->general.activity; | ||
651 | 655 | ||
652 | if (iwl_bt_statistics(priv)) { | 656 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
653 | IWL_DEBUG_RX(priv, | 657 | /* handle this exception directly */ |
654 | "Statistics notification received (%d vs %d).\n", | 658 | priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills; |
655 | (int)sizeof(struct iwl_bt_notif_statistics), | 659 | le32_add_cpu(&priv->statistics.accum_num_bt_kills, |
656 | le32_to_cpu(pkt->len_n_flags) & | 660 | le32_to_cpu(stats->rx.general.num_bt_kills)); |
657 | FH_RSCSR_FRAME_SIZE_MSK); | 661 | #endif |
658 | 662 | } else if (len == sizeof(struct iwl_notif_statistics)) { | |
659 | change = ((priv->_agn.statistics_bt.general.common.temperature != | 663 | struct iwl_notif_statistics *stats; |
660 | pkt->u.stats_bt.general.common.temperature) || | 664 | stats = &pkt->u.stats; |
661 | ((priv->_agn.statistics_bt.flag & | 665 | flag = &stats->flag; |
662 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 666 | common = &stats->general.common; |
663 | (pkt->u.stats_bt.flag & | 667 | rx_non_phy = &stats->rx.general; |
664 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 668 | rx_ofdm = &stats->rx.ofdm; |
665 | 669 | rx_ofdm_ht = &stats->rx.ofdm_ht; | |
666 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); | 670 | rx_cck = &stats->rx.cck; |
671 | tx = &stats->tx; | ||
672 | bt_activity = NULL; | ||
667 | } else { | 673 | } else { |
668 | IWL_DEBUG_RX(priv, | 674 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", |
669 | "Statistics notification received (%d vs %d).\n", | 675 | len, sizeof(struct iwl_bt_notif_statistics), |
670 | (int)sizeof(struct iwl_notif_statistics), | 676 | sizeof(struct iwl_notif_statistics)); |
671 | le32_to_cpu(pkt->len_n_flags) & | 677 | return; |
672 | FH_RSCSR_FRAME_SIZE_MSK); | ||
673 | |||
674 | change = ((priv->_agn.statistics.general.common.temperature != | ||
675 | pkt->u.stats.general.common.temperature) || | ||
676 | ((priv->_agn.statistics.flag & | ||
677 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | ||
678 | (pkt->u.stats.flag & | ||
679 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | ||
680 | |||
681 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | ||
682 | } | 678 | } |
683 | 679 | ||
684 | iwl_recover_from_statistics(priv, pkt); | 680 | change = common->temperature != priv->statistics.common.temperature || |
681 | (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | ||
682 | (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); | ||
683 | |||
684 | iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, | ||
685 | rx_ofdm_ht, rx_cck, tx, bt_activity); | ||
686 | |||
687 | iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); | ||
688 | |||
689 | priv->statistics.flag = *flag; | ||
690 | memcpy(&priv->statistics.common, common, sizeof(*common)); | ||
691 | memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy)); | ||
692 | memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm)); | ||
693 | memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht)); | ||
694 | memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck)); | ||
695 | memcpy(&priv->statistics.tx, tx, sizeof(*tx)); | ||
696 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
697 | if (bt_activity) | ||
698 | memcpy(&priv->statistics.bt_activity, bt_activity, | ||
699 | sizeof(*bt_activity)); | ||
700 | #endif | ||
701 | |||
702 | priv->rx_statistics_jiffies = stamp; | ||
685 | 703 | ||
686 | set_bit(STATUS_STATISTICS, &priv->status); | 704 | set_bit(STATUS_STATISTICS, &priv->status); |
687 | 705 | ||
@@ -708,18 +726,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv, | |||
708 | 726 | ||
709 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | 727 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { |
710 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 728 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
711 | memset(&priv->_agn.accum_statistics, 0, | 729 | memset(&priv->accum_stats, 0, |
712 | sizeof(struct iwl_notif_statistics)); | 730 | sizeof(priv->accum_stats)); |
713 | memset(&priv->_agn.delta_statistics, 0, | 731 | memset(&priv->delta_stats, 0, |
714 | sizeof(struct iwl_notif_statistics)); | 732 | sizeof(priv->delta_stats)); |
715 | memset(&priv->_agn.max_delta, 0, | 733 | memset(&priv->max_delta_stats, 0, |
716 | sizeof(struct iwl_notif_statistics)); | 734 | sizeof(priv->max_delta_stats)); |
717 | memset(&priv->_agn.accum_statistics_bt, 0, | ||
718 | sizeof(struct iwl_bt_notif_statistics)); | ||
719 | memset(&priv->_agn.delta_statistics_bt, 0, | ||
720 | sizeof(struct iwl_bt_notif_statistics)); | ||
721 | memset(&priv->_agn.max_delta_bt, 0, | ||
722 | sizeof(struct iwl_bt_notif_statistics)); | ||
723 | #endif | 735 | #endif |
724 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | 736 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); |
725 | } | 737 | } |
@@ -873,6 +885,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
873 | { | 885 | { |
874 | struct sk_buff *skb; | 886 | struct sk_buff *skb; |
875 | __le16 fc = hdr->frame_control; | 887 | __le16 fc = hdr->frame_control; |
888 | struct iwl_rxon_context *ctx; | ||
876 | 889 | ||
877 | /* We only process data packets if the interface is open */ | 890 | /* We only process data packets if the interface is open */ |
878 | if (unlikely(!priv->is_open)) { | 891 | if (unlikely(!priv->is_open)) { |
@@ -895,6 +908,26 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
895 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 908 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); |
896 | 909 | ||
897 | iwl_update_stats(priv, false, fc, len); | 910 | iwl_update_stats(priv, false, fc, len); |
911 | |||
912 | /* | ||
913 | * Wake any queues that were stopped due to a passive channel tx | ||
914 | * failure. This can happen because the regulatory enforcement in | ||
915 | * the device waits for a beacon before allowing transmission, | ||
916 | * sometimes even after already having transmitted frames for the | ||
917 | * association because the new RXON may reset the information. | ||
918 | */ | ||
919 | if (unlikely(ieee80211_is_beacon(fc))) { | ||
920 | for_each_context(priv, ctx) { | ||
921 | if (!ctx->last_tx_rejected) | ||
922 | continue; | ||
923 | if (compare_ether_addr(hdr->addr3, | ||
924 | ctx->active.bssid_addr)) | ||
925 | continue; | ||
926 | ctx->last_tx_rejected = false; | ||
927 | iwl_wake_any_queue(priv, ctx); | ||
928 | } | ||
929 | } | ||
930 | |||
898 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 931 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
899 | 932 | ||
900 | ieee80211_rx(priv->hw, skb); | 933 | ieee80211_rx(priv->hw, skb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c21515640077..3c8cebde16cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -494,7 +494,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
494 | 494 | ||
495 | priv->num_stations--; | 495 | priv->num_stations--; |
496 | 496 | ||
497 | BUG_ON(priv->num_stations < 0); | 497 | if (WARN_ON(priv->num_stations < 0)) |
498 | priv->num_stations = 0; | ||
498 | 499 | ||
499 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 500 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
500 | 501 | ||
@@ -679,7 +680,8 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) | |||
679 | 680 | ||
680 | priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; | 681 | priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; |
681 | priv->num_stations--; | 682 | priv->num_stations--; |
682 | BUG_ON(priv->num_stations < 0); | 683 | if (WARN_ON(priv->num_stations < 0)) |
684 | priv->num_stations = 0; | ||
683 | kfree(priv->stations[i].lq); | 685 | kfree(priv->stations[i].lq); |
684 | priv->stations[i].lq = NULL; | 686 | priv->stations[i].lq = NULL; |
685 | } | 687 | } |
@@ -775,7 +777,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
775 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 777 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
776 | 778 | ||
777 | iwl_dump_lq_cmd(priv, lq); | 779 | iwl_dump_lq_cmd(priv, lq); |
778 | BUG_ON(init && (cmd.flags & CMD_ASYNC)); | 780 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) |
781 | return -EINVAL; | ||
779 | 782 | ||
780 | if (is_lq_table_valid(priv, ctx, lq)) | 783 | if (is_lq_table_valid(priv, ctx, lq)) |
781 | ret = iwl_send_cmd(priv, &cmd); | 784 | ret = iwl_send_cmd(priv, &cmd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 565980fbb591..80c3565a66ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -232,7 +232,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
232 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | 232 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, |
233 | * Tx queue resumed. | 233 | * Tx queue resumed. |
234 | * | 234 | * |
235 | * See more detailed info in iwl-4965-hw.h. | ||
236 | ***************************************************/ | 235 | ***************************************************/ |
237 | 236 | ||
238 | int iwl_queue_space(const struct iwl_queue *q) | 237 | int iwl_queue_space(const struct iwl_queue *q) |
@@ -264,11 +263,13 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, | |||
264 | 263 | ||
265 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | 264 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap |
266 | * and iwl_queue_dec_wrap are broken. */ | 265 | * and iwl_queue_dec_wrap are broken. */ |
267 | BUG_ON(!is_power_of_2(count)); | 266 | if (WARN_ON(!is_power_of_2(count))) |
267 | return -EINVAL; | ||
268 | 268 | ||
269 | /* slots_num must be power-of-two size, otherwise | 269 | /* slots_num must be power-of-two size, otherwise |
270 | * get_cmd_index is broken. */ | 270 | * get_cmd_index is broken. */ |
271 | BUG_ON(!is_power_of_2(slots_num)); | 271 | if (WARN_ON(!is_power_of_2(slots_num))) |
272 | return -EINVAL; | ||
272 | 273 | ||
273 | q->low_mark = q->n_window / 4; | 274 | q->low_mark = q->n_window / 4; |
274 | if (q->low_mark < 4) | 275 | if (q->low_mark < 4) |
@@ -385,7 +386,9 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
385 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | 386 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); |
386 | 387 | ||
387 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | 388 | /* Initialize queue's high/low-water marks, and head/tail indexes */ |
388 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | 389 | ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); |
390 | if (ret) | ||
391 | return ret; | ||
389 | 392 | ||
390 | /* Tell device where to find queue */ | 393 | /* Tell device where to find queue */ |
391 | priv->cfg->ops->lib->txq_init(priv, txq); | 394 | priv->cfg->ops->lib->txq_init(priv, txq); |
@@ -447,14 +450,19 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
447 | cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); | 450 | cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); |
448 | fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); | 451 | fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); |
449 | 452 | ||
450 | /* If any of the command structures end up being larger than | 453 | /* |
454 | * If any of the command structures end up being larger than | ||
451 | * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then | 455 | * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then |
452 | * we will need to increase the size of the TFD entries | 456 | * we will need to increase the size of the TFD entries |
453 | * Also, check to see if command buffer should not exceed the size | 457 | * Also, check to see if command buffer should not exceed the size |
454 | * of device_cmd and max_cmd_size. */ | 458 | * of device_cmd and max_cmd_size. |
455 | BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && | 459 | */ |
456 | !(cmd->flags & CMD_SIZE_HUGE)); | 460 | if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && |
457 | BUG_ON(fix_size > IWL_MAX_CMD_SIZE); | 461 | !(cmd->flags & CMD_SIZE_HUGE))) |
462 | return -EINVAL; | ||
463 | |||
464 | if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE)) | ||
465 | return -EINVAL; | ||
458 | 466 | ||
459 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { | 467 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { |
460 | IWL_WARN(priv, "Not sending command - %s KILL\n", | 468 | IWL_WARN(priv, "Not sending command - %s KILL\n", |
@@ -462,16 +470,21 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
462 | return -EIO; | 470 | return -EIO; |
463 | } | 471 | } |
464 | 472 | ||
473 | /* | ||
474 | * As we only have a single huge buffer, check that the command | ||
475 | * is synchronous (otherwise buffers could end up being reused). | ||
476 | */ | ||
477 | |||
478 | if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE))) | ||
479 | return -EINVAL; | ||
480 | |||
465 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 481 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
466 | 482 | ||
467 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 483 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
468 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | 484 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
469 | 485 | ||
470 | IWL_ERR(priv, "No space in command queue\n"); | 486 | IWL_ERR(priv, "No space in command queue\n"); |
471 | if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { | 487 | is_ct_kill = iwl_check_for_ct_kill(priv); |
472 | is_ct_kill = | ||
473 | priv->cfg->ops->lib->tt_ops.ct_kill_check(priv); | ||
474 | } | ||
475 | if (!is_ct_kill) { | 488 | if (!is_ct_kill) { |
476 | IWL_ERR(priv, "Restarting adapter due to queue full\n"); | 489 | IWL_ERR(priv, "Restarting adapter due to queue full\n"); |
477 | iwlagn_fw_error(priv, false); | 490 | iwlagn_fw_error(priv, false); |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 73a6e62f5680..e22d761f2ef2 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -115,7 +115,7 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, | |||
115 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | 115 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); |
116 | 116 | ||
117 | /* Clear RD responder bit */ | 117 | /* Clear RD responder bit */ |
118 | RESETHT_EXTCAP_RDG(ht_ext_cap); | 118 | ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; |
119 | 119 | ||
120 | ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); | 120 | ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); |
121 | ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); | 121 | ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); |
@@ -242,9 +242,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | |||
242 | * | 242 | * |
243 | * Handling includes changing the header fields into CPU format. | 243 | * Handling includes changing the header fields into CPU format. |
244 | */ | 244 | */ |
245 | int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, | 245 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) |
246 | struct host_cmd_ds_command *resp, | ||
247 | void *data_buf) | ||
248 | { | 246 | { |
249 | struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; | 247 | struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; |
250 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; | 248 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; |
@@ -298,8 +296,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | |||
298 | * - Setting AMSDU control parameters (for SET only) | 296 | * - Setting AMSDU control parameters (for SET only) |
299 | * - Ensuring correct endian-ness | 297 | * - Ensuring correct endian-ness |
300 | */ | 298 | */ |
301 | int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 299 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
302 | struct host_cmd_ds_command *cmd, | ||
303 | int cmd_action, void *data_buf) | 300 | int cmd_action, void *data_buf) |
304 | { | 301 | { |
305 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = | 302 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = |
@@ -331,8 +328,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | |||
331 | * | 328 | * |
332 | * Handling includes changing the header fields into CPU format. | 329 | * Handling includes changing the header fields into CPU format. |
333 | */ | 330 | */ |
334 | int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 331 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
335 | struct host_cmd_ds_command *resp, | ||
336 | void *data_buf) | 332 | void *data_buf) |
337 | { | 333 | { |
338 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; | 334 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; |
@@ -357,8 +353,7 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | |||
357 | * - Setting HT Tx capability and HT Tx information fields | 353 | * - Setting HT Tx capability and HT Tx information fields |
358 | * - Ensuring correct endian-ness | 354 | * - Ensuring correct endian-ness |
359 | */ | 355 | */ |
360 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | 356 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, |
361 | struct host_cmd_ds_command *cmd, | ||
362 | u16 cmd_action, void *data_buf) | 357 | u16 cmd_action, void *data_buf) |
363 | { | 358 | { |
364 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; | 359 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; |
@@ -541,11 +536,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, | |||
541 | else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) | 536 | else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) |
542 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; | 537 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; |
543 | if (curr_tx_buf_size != tx_buf) | 538 | if (curr_tx_buf_size != tx_buf) |
544 | mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, | 539 | mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, |
545 | HostCmd_ACT_GEN_SET, 0, | 540 | HostCmd_ACT_GEN_SET, 0, &tx_buf); |
546 | NULL, &tx_buf); | ||
547 | |||
548 | return; | ||
549 | } | 541 | } |
550 | 542 | ||
551 | /* | 543 | /* |
@@ -583,8 +575,6 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, | |||
583 | list_del(&tx_ba_tsr_tbl->list); | 575 | list_del(&tx_ba_tsr_tbl->list); |
584 | 576 | ||
585 | kfree(tx_ba_tsr_tbl); | 577 | kfree(tx_ba_tsr_tbl); |
586 | |||
587 | return; | ||
588 | } | 578 | } |
589 | 579 | ||
590 | /* | 580 | /* |
@@ -663,8 +653,6 @@ void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, | |||
663 | list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); | 653 | list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); |
664 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); | 654 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); |
665 | } | 655 | } |
666 | |||
667 | return; | ||
668 | } | 656 | } |
669 | 657 | ||
670 | /* | 658 | /* |
@@ -694,8 +682,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) | |||
694 | memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); | 682 | memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); |
695 | 683 | ||
696 | /* We don't wait for the response of this command */ | 684 | /* We don't wait for the response of this command */ |
697 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, | 685 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, |
698 | 0, 0, NULL, &add_ba_req); | 686 | 0, 0, &add_ba_req); |
699 | 687 | ||
700 | return ret; | 688 | return ret; |
701 | } | 689 | } |
@@ -722,8 +710,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, | |||
722 | memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); | 710 | memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); |
723 | 711 | ||
724 | /* We don't wait for the response of this command */ | 712 | /* We don't wait for the response of this command */ |
725 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, | 713 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, |
726 | HostCmd_ACT_GEN_SET, 0, NULL, &delba); | 714 | HostCmd_ACT_GEN_SET, 0, &delba); |
727 | 715 | ||
728 | return ret; | 716 | return ret; |
729 | } | 717 | } |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 71a853e61b61..02602ff30cbf 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -28,15 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
28 | struct host_cmd_ds_command *resp); | 28 | struct host_cmd_ds_command *resp); |
29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | 29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, |
30 | struct host_cmd_ds_command *resp); | 30 | struct host_cmd_ds_command *resp); |
31 | int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, | 31 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, |
32 | struct host_cmd_ds_command *resp, | ||
33 | void *data_buf); | 32 | void *data_buf); |
34 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | 33 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, |
35 | struct host_cmd_ds_command *cmd, | ||
36 | u16 cmd_action, void *data_buf); | ||
37 | |||
38 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | ||
39 | struct host_cmd_ds_command *cmd, | ||
40 | u16 cmd_action, void *data_buf); | 34 | u16 cmd_action, void *data_buf); |
41 | 35 | ||
42 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | 36 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, |
@@ -67,24 +61,19 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, | |||
67 | struct mwifiex_ds_rx_reorder_tbl *buf); | 61 | struct mwifiex_ds_rx_reorder_tbl *buf); |
68 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | 62 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, |
69 | struct mwifiex_ds_tx_ba_stream_tbl *buf); | 63 | struct mwifiex_ds_tx_ba_stream_tbl *buf); |
70 | int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 64 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
71 | struct host_cmd_ds_command | ||
72 | *resp, | ||
73 | void *data_buf); | 65 | void *data_buf); |
74 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | 66 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, |
75 | struct host_cmd_ds_command *cmd, | 67 | struct host_cmd_ds_command *cmd, |
76 | int cmd_action, void *data_buf); | 68 | int cmd_action, void *data_buf); |
77 | int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 69 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
78 | struct host_cmd_ds_command *cmd, | 70 | int cmd_action, void *data_buf); |
79 | int cmd_action, | ||
80 | void *data_buf); | ||
81 | 71 | ||
82 | /* | 72 | /* |
83 | * This function checks whether AMPDU is allowed or not for a particular TID. | 73 | * This function checks whether AMPDU is allowed or not for a particular TID. |
84 | */ | 74 | */ |
85 | static inline u8 | 75 | static inline u8 |
86 | mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, | 76 | mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) |
87 | struct mwifiex_ra_list_tbl *ptr, int tid) | ||
88 | { | 77 | { |
89 | return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) | 78 | return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) |
90 | ? true : false); | 79 | ? true : false); |
@@ -94,8 +83,7 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, | |||
94 | * This function checks whether AMSDU is allowed or not for a particular TID. | 83 | * This function checks whether AMSDU is allowed or not for a particular TID. |
95 | */ | 84 | */ |
96 | static inline u8 | 85 | static inline u8 |
97 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, | 86 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) |
98 | struct mwifiex_ra_list_tbl *ptr, int tid) | ||
99 | { | 87 | { |
100 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) | 88 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) |
101 | && ((priv->is_data_rate_auto) | 89 | && ((priv->is_data_rate_auto) |
@@ -104,23 +92,21 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, | |||
104 | } | 92 | } |
105 | 93 | ||
106 | /* | 94 | /* |
107 | * This function checks whether a BA stream is available or not. | 95 | * This function checks whether a space is available for new BA stream or not. |
108 | */ | 96 | */ |
109 | static inline u8 | 97 | static inline u8 mwifiex_space_avail_for_new_ba_stream( |
110 | mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) | 98 | struct mwifiex_adapter *adapter) |
111 | { | 99 | { |
112 | struct mwifiex_private *pmpriv = NULL; | 100 | struct mwifiex_private *priv; |
113 | u8 i = 0; | 101 | u8 i; |
114 | u32 ba_stream_num = 0; | 102 | u32 ba_stream_num = 0; |
115 | 103 | ||
116 | for (i = 0; i < priv->adapter->priv_num; i++) { | 104 | for (i = 0; i < adapter->priv_num; i++) { |
117 | pmpriv = priv->adapter->priv[i]; | 105 | priv = adapter->priv[i]; |
118 | if (pmpriv) | 106 | if (priv) |
119 | ba_stream_num += | 107 | ba_stream_num += mwifiex_wmm_list_len( |
120 | mwifiex_wmm_list_len(priv->adapter, | 108 | (struct list_head *) |
121 | (struct list_head | 109 | &priv->tx_ba_stream_tbl_ptr); |
122 | *) &pmpriv-> | ||
123 | tx_ba_stream_tbl_ptr); | ||
124 | } | 110 | } |
125 | 111 | ||
126 | return ((ba_stream_num < | 112 | return ((ba_stream_num < |
@@ -133,8 +119,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) | |||
133 | * Upon successfully locating, both the TID and the RA are returned. | 119 | * Upon successfully locating, both the TID and the RA are returned. |
134 | */ | 120 | */ |
135 | static inline u8 | 121 | static inline u8 |
136 | mwifiex_find_stream_to_delete(struct mwifiex_private *priv, | 122 | mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, |
137 | struct mwifiex_ra_list_tbl *ptr, int ptr_tid, | ||
138 | int *ptid, u8 *ra) | 123 | int *ptid, u8 *ra) |
139 | { | 124 | { |
140 | int tid; | 125 | int tid; |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index c2abced66957..c9fb0627de43 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -44,8 +44,7 @@ | |||
44 | * MSDU => |DA|SA|Length|SNAP|...... ..| | 44 | * MSDU => |DA|SA|Length|SNAP|...... ..| |
45 | */ | 45 | */ |
46 | static int | 46 | static int |
47 | mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, | 47 | mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, |
48 | struct sk_buff *skb_aggr, | ||
49 | struct sk_buff *skb_src, int *pad) | 48 | struct sk_buff *skb_src, int *pad) |
50 | 49 | ||
51 | { | 50 | { |
@@ -324,7 +323,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
324 | 323 | ||
325 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 324 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
326 | ra_list_flags); | 325 | ra_list_flags); |
327 | mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); | 326 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); |
328 | 327 | ||
329 | mwifiex_write_data_complete(adapter, skb_src, 0); | 328 | mwifiex_write_data_complete(adapter, skb_src, 0); |
330 | 329 | ||
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 8e94e620e6f4..a93c03fdea82 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -27,19 +27,6 @@ | |||
27 | #include "11n_rxreorder.h" | 27 | #include "11n_rxreorder.h" |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * This function processes a received packet and forwards | ||
31 | * it to the kernel/upper layer. | ||
32 | */ | ||
33 | static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload) | ||
34 | { | ||
35 | int ret = 0; | ||
36 | struct mwifiex_adapter *adapter = priv->adapter; | ||
37 | |||
38 | ret = mwifiex_process_rx_packet(adapter, (struct sk_buff *) payload); | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * This function dispatches all packets in the Rx reorder table. | 30 | * This function dispatches all packets in the Rx reorder table. |
44 | * | 31 | * |
45 | * There could be holes in the buffer, which are skipped by the function. | 32 | * There could be holes in the buffer, which are skipped by the function. |
@@ -51,7 +38,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
51 | struct mwifiex_rx_reorder_tbl | 38 | struct mwifiex_rx_reorder_tbl |
52 | *rx_reor_tbl_ptr, int start_win) | 39 | *rx_reor_tbl_ptr, int start_win) |
53 | { | 40 | { |
54 | int no_pkt_to_send, i, xchg; | 41 | int no_pkt_to_send, i; |
55 | void *rx_tmp_ptr = NULL; | 42 | void *rx_tmp_ptr = NULL; |
56 | unsigned long flags; | 43 | unsigned long flags; |
57 | 44 | ||
@@ -68,7 +55,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
68 | } | 55 | } |
69 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 56 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
70 | if (rx_tmp_ptr) | 57 | if (rx_tmp_ptr) |
71 | mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); | 58 | mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); |
72 | } | 59 | } |
73 | 60 | ||
74 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); | 61 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); |
@@ -76,8 +63,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
76 | * We don't have a circular buffer, hence use rotation to simulate | 63 | * We don't have a circular buffer, hence use rotation to simulate |
77 | * circular buffer | 64 | * circular buffer |
78 | */ | 65 | */ |
79 | xchg = rx_reor_tbl_ptr->win_size - no_pkt_to_send; | 66 | for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { |
80 | for (i = 0; i < xchg; ++i) { | ||
81 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = | 67 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = |
82 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; | 68 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; |
83 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; | 69 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; |
@@ -114,7 +100,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | |||
114 | rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; | 100 | rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; |
115 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; | 101 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; |
116 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 102 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
117 | mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); | 103 | mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); |
118 | } | 104 | } |
119 | 105 | ||
120 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); | 106 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); |
@@ -309,8 +295,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
309 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); | 295 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
310 | list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); | 296 | list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); |
311 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 297 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
312 | |||
313 | return; | ||
314 | } | 298 | } |
315 | 299 | ||
316 | /* | 300 | /* |
@@ -321,8 +305,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
321 | * - Setting add BA request buffer | 305 | * - Setting add BA request buffer |
322 | * - Ensuring correct endian-ness | 306 | * - Ensuring correct endian-ness |
323 | */ | 307 | */ |
324 | int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, | 308 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) |
325 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
326 | { | 309 | { |
327 | struct host_cmd_ds_11n_addba_req *add_ba_req = | 310 | struct host_cmd_ds_11n_addba_req *add_ba_req = |
328 | (struct host_cmd_ds_11n_addba_req *) | 311 | (struct host_cmd_ds_11n_addba_req *) |
@@ -393,8 +376,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | |||
393 | * - Setting del BA request buffer | 376 | * - Setting del BA request buffer |
394 | * - Ensuring correct endian-ness | 377 | * - Ensuring correct endian-ness |
395 | */ | 378 | */ |
396 | int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, | 379 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) |
397 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
398 | { | 380 | { |
399 | struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) | 381 | struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) |
400 | &cmd->params.del_ba; | 382 | &cmd->params.del_ba; |
@@ -433,7 +415,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
433 | tid, ta); | 415 | tid, ta); |
434 | if (!rx_reor_tbl_ptr) { | 416 | if (!rx_reor_tbl_ptr) { |
435 | if (pkt_type != PKT_TYPE_BAR) | 417 | if (pkt_type != PKT_TYPE_BAR) |
436 | mwifiex_11n_dispatch_pkt(priv, payload); | 418 | mwifiex_process_rx_packet(priv->adapter, payload); |
437 | return 0; | 419 | return 0; |
438 | } | 420 | } |
439 | start_win = rx_reor_tbl_ptr->start_win; | 421 | start_win = rx_reor_tbl_ptr->start_win; |
@@ -609,9 +591,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, | |||
609 | delba.del_ba_param_set |= cpu_to_le16( | 591 | delba.del_ba_param_set |= cpu_to_le16( |
610 | (u16) event->origninator << DELBA_INITIATOR_POS); | 592 | (u16) event->origninator << DELBA_INITIATOR_POS); |
611 | delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); | 593 | delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); |
612 | mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); | 594 | mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); |
613 | |||
614 | return; | ||
615 | } | 595 | } |
616 | 596 | ||
617 | /* | 597 | /* |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 42f569035745..f3ca8c8c18f9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h | |||
@@ -49,14 +49,12 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, | |||
49 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | 49 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, |
50 | struct host_cmd_ds_command | 50 | struct host_cmd_ds_command |
51 | *resp); | 51 | *resp); |
52 | int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, | 52 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, |
53 | struct host_cmd_ds_command *cmd, | ||
54 | void *data_buf); | 53 | void *data_buf); |
55 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | 54 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, |
56 | struct host_cmd_ds_command | 55 | struct host_cmd_ds_command |
57 | *cmd, void *data_buf); | 56 | *cmd, void *data_buf); |
58 | int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, | 57 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, |
59 | struct host_cmd_ds_command *cmd, | ||
60 | void *data_buf); | 58 | void *data_buf); |
61 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); | 59 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); |
62 | struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct | 60 | struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct |
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README index 338377f7093b..b55badef4660 100644 --- a/drivers/net/wireless/mwifiex/README +++ b/drivers/net/wireless/mwifiex/README | |||
@@ -157,7 +157,7 @@ info | |||
157 | mp_wr_bitmap = <SDIO multi-port write bitmap> | 157 | mp_wr_bitmap = <SDIO multi-port write bitmap> |
158 | cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> | 158 | cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> |
159 | event_received = <0/1, no event to process/event received and yet to process> | 159 | event_received = <0/1, no event to process/event received and yet to process> |
160 | ioctl_pending = <number of ioctl pending> | 160 | cmd_pending = <number of cmd pending> |
161 | tx_pending = <number of Tx packet pending> | 161 | tx_pending = <number of Tx packet pending> |
162 | rx_pending = <number of Rx packet pending> | 162 | rx_pending = <number of Rx packet pending> |
163 | 163 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ec0895f4e8d3..b99ae2677d78 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -34,22 +34,17 @@ static int | |||
34 | mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type | 34 | mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type |
35 | channel_type) | 35 | channel_type) |
36 | { | 36 | { |
37 | int channel; | ||
38 | switch (channel_type) { | 37 | switch (channel_type) { |
39 | case NL80211_CHAN_NO_HT: | 38 | case NL80211_CHAN_NO_HT: |
40 | case NL80211_CHAN_HT20: | 39 | case NL80211_CHAN_HT20: |
41 | channel = NO_SEC_CHANNEL; | 40 | return NO_SEC_CHANNEL; |
42 | break; | ||
43 | case NL80211_CHAN_HT40PLUS: | 41 | case NL80211_CHAN_HT40PLUS: |
44 | channel = SEC_CHANNEL_ABOVE; | 42 | return SEC_CHANNEL_ABOVE; |
45 | break; | ||
46 | case NL80211_CHAN_HT40MINUS: | 43 | case NL80211_CHAN_HT40MINUS: |
47 | channel = SEC_CHANNEL_BELOW; | 44 | return SEC_CHANNEL_BELOW; |
48 | break; | ||
49 | default: | 45 | default: |
50 | channel = NO_SEC_CHANNEL; | 46 | return NO_SEC_CHANNEL; |
51 | } | 47 | } |
52 | return channel; | ||
53 | } | 48 | } |
54 | 49 | ||
55 | /* | 50 | /* |
@@ -64,21 +59,16 @@ mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type | |||
64 | static enum nl80211_channel_type | 59 | static enum nl80211_channel_type |
65 | mwifiex_channels_to_cfg80211_channel_type(int channel_type) | 60 | mwifiex_channels_to_cfg80211_channel_type(int channel_type) |
66 | { | 61 | { |
67 | int channel; | ||
68 | switch (channel_type) { | 62 | switch (channel_type) { |
69 | case NO_SEC_CHANNEL: | 63 | case NO_SEC_CHANNEL: |
70 | channel = NL80211_CHAN_HT20; | 64 | return NL80211_CHAN_HT20; |
71 | break; | ||
72 | case SEC_CHANNEL_ABOVE: | 65 | case SEC_CHANNEL_ABOVE: |
73 | channel = NL80211_CHAN_HT40PLUS; | 66 | return NL80211_CHAN_HT40PLUS; |
74 | break; | ||
75 | case SEC_CHANNEL_BELOW: | 67 | case SEC_CHANNEL_BELOW: |
76 | channel = NL80211_CHAN_HT40MINUS; | 68 | return NL80211_CHAN_HT40MINUS; |
77 | break; | ||
78 | default: | 69 | default: |
79 | channel = NL80211_CHAN_HT20; | 70 | return NL80211_CHAN_HT20; |
80 | } | 71 | } |
81 | return channel; | ||
82 | } | 72 | } |
83 | 73 | ||
84 | /* | 74 | /* |
@@ -117,10 +107,8 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, | |||
117 | u8 key_index, bool pairwise, const u8 *mac_addr) | 107 | u8 key_index, bool pairwise, const u8 *mac_addr) |
118 | { | 108 | { |
119 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 109 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
120 | int ret = 0; | ||
121 | 110 | ||
122 | ret = mwifiex_set_encode(priv, NULL, 0, key_index, 1); | 111 | if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { |
123 | if (ret) { | ||
124 | wiphy_err(wiphy, "deleting the crypto keys\n"); | 112 | wiphy_err(wiphy, "deleting the crypto keys\n"); |
125 | return -EFAULT; | 113 | return -EFAULT; |
126 | } | 114 | } |
@@ -137,12 +125,17 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, | |||
137 | enum nl80211_tx_power_setting type, | 125 | enum nl80211_tx_power_setting type, |
138 | int dbm) | 126 | int dbm) |
139 | { | 127 | { |
140 | int ret = 0; | ||
141 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 128 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
129 | struct mwifiex_power_cfg power_cfg; | ||
142 | 130 | ||
143 | ret = mwifiex_set_tx_power(priv, type, dbm); | 131 | if (type == NL80211_TX_POWER_FIXED) { |
132 | power_cfg.is_power_auto = 0; | ||
133 | power_cfg.power_level = dbm; | ||
134 | } else { | ||
135 | power_cfg.is_power_auto = 1; | ||
136 | } | ||
144 | 137 | ||
145 | return ret; | 138 | return mwifiex_set_tx_power(priv, &power_cfg); |
146 | } | 139 | } |
147 | 140 | ||
148 | /* | 141 | /* |
@@ -155,17 +148,17 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
155 | struct net_device *dev, | 148 | struct net_device *dev, |
156 | bool enabled, int timeout) | 149 | bool enabled, int timeout) |
157 | { | 150 | { |
158 | int ret = 0; | ||
159 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 151 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
152 | u32 ps_mode; | ||
160 | 153 | ||
161 | if (timeout) | 154 | if (timeout) |
162 | wiphy_dbg(wiphy, | 155 | wiphy_dbg(wiphy, |
163 | "info: ignoring the timeout value" | 156 | "info: ignoring the timeout value" |
164 | " for IEEE power save\n"); | 157 | " for IEEE power save\n"); |
165 | 158 | ||
166 | ret = mwifiex_drv_set_power(priv, enabled); | 159 | ps_mode = enabled; |
167 | 160 | ||
168 | return ret; | 161 | return mwifiex_drv_set_power(priv, &ps_mode); |
169 | } | 162 | } |
170 | 163 | ||
171 | /* | 164 | /* |
@@ -177,18 +170,15 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | |||
177 | bool multicast) | 170 | bool multicast) |
178 | { | 171 | { |
179 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 172 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
180 | int ret; | ||
181 | 173 | ||
182 | /* Return if WEP key not configured */ | 174 | /* Return if WEP key not configured */ |
183 | if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) | 175 | if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) |
184 | return 0; | 176 | return 0; |
185 | 177 | ||
186 | ret = mwifiex_set_encode(priv, NULL, 0, key_index, 0); | 178 | if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { |
187 | 179 | wiphy_err(wiphy, "set default Tx key index\n"); | |
188 | wiphy_dbg(wiphy, "info: set default Tx key index\n"); | ||
189 | |||
190 | if (ret) | ||
191 | return -EFAULT; | 180 | return -EFAULT; |
181 | } | ||
192 | 182 | ||
193 | return 0; | 183 | return 0; |
194 | } | 184 | } |
@@ -202,15 +192,12 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, | |||
202 | struct key_params *params) | 192 | struct key_params *params) |
203 | { | 193 | { |
204 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 194 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
205 | int ret = 0; | ||
206 | 195 | ||
207 | ret = mwifiex_set_encode(priv, params->key, params->key_len, | 196 | if (mwifiex_set_encode(priv, params->key, params->key_len, |
208 | key_index, 0); | 197 | key_index, 0)) { |
209 | 198 | wiphy_err(wiphy, "crypto keys added\n"); | |
210 | wiphy_dbg(wiphy, "info: crypto keys added\n"); | ||
211 | |||
212 | if (ret) | ||
213 | return -EFAULT; | 199 | return -EFAULT; |
200 | } | ||
214 | 201 | ||
215 | return 0; | 202 | return 0; |
216 | } | 203 | } |
@@ -235,7 +222,6 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
235 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 222 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
236 | struct mwifiex_adapter *adapter = priv->adapter; | 223 | struct mwifiex_adapter *adapter = priv->adapter; |
237 | struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; | 224 | struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; |
238 | int ret = 0; | ||
239 | 225 | ||
240 | /* Set country code */ | 226 | /* Set country code */ |
241 | domain_info->country_code[0] = priv->country_code[0]; | 227 | domain_info->country_code[0] = priv->country_code[0]; |
@@ -290,13 +276,14 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
290 | } | 276 | } |
291 | 277 | ||
292 | domain_info->no_of_triplet = no_of_triplet; | 278 | domain_info->no_of_triplet = no_of_triplet; |
293 | /* Send cmd to FW to set domain info */ | 279 | |
294 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, | 280 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, |
295 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 281 | HostCmd_ACT_GEN_SET, 0, NULL)) { |
296 | if (ret) | ||
297 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); | 282 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); |
283 | return -1; | ||
284 | } | ||
298 | 285 | ||
299 | return ret; | 286 | return 0; |
300 | } | 287 | } |
301 | 288 | ||
302 | /* | 289 | /* |
@@ -346,8 +333,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
346 | enum nl80211_channel_type channel_type) | 333 | enum nl80211_channel_type channel_type) |
347 | { | 334 | { |
348 | struct mwifiex_chan_freq_power cfp; | 335 | struct mwifiex_chan_freq_power cfp; |
349 | int ret = 0; | ||
350 | int status = 0; | ||
351 | struct mwifiex_ds_band_cfg band_cfg; | 336 | struct mwifiex_ds_band_cfg band_cfg; |
352 | u32 config_bands = 0; | 337 | u32 config_bands = 0; |
353 | struct wiphy *wiphy = priv->wdev->wiphy; | 338 | struct wiphy *wiphy = priv->wdev->wiphy; |
@@ -366,15 +351,14 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
366 | band_cfg.config_bands = config_bands; | 351 | band_cfg.config_bands = config_bands; |
367 | band_cfg.adhoc_start_band = config_bands; | 352 | band_cfg.adhoc_start_band = config_bands; |
368 | } | 353 | } |
369 | /* Set channel offset */ | 354 | |
370 | band_cfg.sec_chan_offset = | 355 | band_cfg.sec_chan_offset = |
371 | mwifiex_cfg80211_channel_type_to_mwifiex_channels | 356 | mwifiex_cfg80211_channel_type_to_mwifiex_channels |
372 | (channel_type); | 357 | (channel_type); |
373 | status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, | ||
374 | &band_cfg); | ||
375 | 358 | ||
376 | if (status) | 359 | if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) |
377 | return -EFAULT; | 360 | return -EFAULT; |
361 | |||
378 | mwifiex_send_domain_info_cmd_fw(wiphy); | 362 | mwifiex_send_domain_info_cmd_fw(wiphy); |
379 | } | 363 | } |
380 | 364 | ||
@@ -382,20 +366,16 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
382 | "mode %d\n", config_bands, band_cfg.sec_chan_offset, | 366 | "mode %d\n", config_bands, band_cfg.sec_chan_offset, |
383 | priv->bss_mode); | 367 | priv->bss_mode); |
384 | if (!chan) | 368 | if (!chan) |
385 | return ret; | 369 | return 0; |
386 | 370 | ||
387 | memset(&cfp, 0, sizeof(cfp)); | 371 | memset(&cfp, 0, sizeof(cfp)); |
388 | cfp.freq = chan->center_freq; | 372 | cfp.freq = chan->center_freq; |
389 | /* Convert frequency to channel */ | ||
390 | cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); | 373 | cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); |
391 | 374 | ||
392 | status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); | 375 | if (mwifiex_bss_set_channel(priv, &cfp)) |
393 | if (status) | ||
394 | return -EFAULT; | 376 | return -EFAULT; |
395 | 377 | ||
396 | ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); | 378 | return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); |
397 | |||
398 | return ret; | ||
399 | } | 379 | } |
400 | 380 | ||
401 | /* | 381 | /* |
@@ -422,67 +402,41 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, | |||
422 | /* | 402 | /* |
423 | * This function sets the fragmentation threshold. | 403 | * This function sets the fragmentation threshold. |
424 | * | 404 | * |
425 | * This function creates an IOCTL request, populates it accordingly | 405 | * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE |
426 | * and issues an IOCTL. | ||
427 | * | ||
428 | * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE | ||
429 | * and MWIFIEX_FRAG_MAX_VALUE. | 406 | * and MWIFIEX_FRAG_MAX_VALUE. |
430 | */ | 407 | */ |
431 | static int | 408 | static int |
432 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) | 409 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) |
433 | { | 410 | { |
434 | int ret = 0; | 411 | int ret = 0; |
435 | int status = 0; | ||
436 | struct mwifiex_wait_queue *wait = NULL; | ||
437 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
438 | 412 | ||
439 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE | 413 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE |
440 | || frag_thr > MWIFIEX_FRAG_MAX_VALUE) | 414 | || frag_thr > MWIFIEX_FRAG_MAX_VALUE) |
441 | return -EINVAL; | 415 | return -EINVAL; |
442 | 416 | ||
443 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | 417 | /* Send request to firmware */ |
444 | if (!wait) | 418 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, |
445 | return -ENOMEM; | 419 | HostCmd_ACT_GEN_SET, FRAG_THRESH_I, |
446 | 420 | &frag_thr); | |
447 | status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I, | ||
448 | HostCmd_ACT_GEN_SET, &frag_thr); | ||
449 | |||
450 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
451 | ret = -EFAULT; | ||
452 | 421 | ||
453 | kfree(wait); | ||
454 | return ret; | 422 | return ret; |
455 | } | 423 | } |
456 | 424 | ||
457 | /* | 425 | /* |
458 | * This function sets the RTS threshold. | 426 | * This function sets the RTS threshold. |
459 | * | 427 | |
460 | * This function creates an IOCTL request, populates it accordingly | 428 | * The rts value must lie between MWIFIEX_RTS_MIN_VALUE |
461 | * and issues an IOCTL. | 429 | * and MWIFIEX_RTS_MAX_VALUE. |
462 | */ | 430 | */ |
463 | static int | 431 | static int |
464 | mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) | 432 | mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) |
465 | { | 433 | { |
466 | int ret = 0; | ||
467 | struct mwifiex_wait_queue *wait = NULL; | ||
468 | int status = 0; | ||
469 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
470 | |||
471 | if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) | 434 | if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) |
472 | rts_thr = MWIFIEX_RTS_MAX_VALUE; | 435 | rts_thr = MWIFIEX_RTS_MAX_VALUE; |
473 | 436 | ||
474 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | 437 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, |
475 | if (!wait) | 438 | HostCmd_ACT_GEN_SET, RTS_THRESH_I, |
476 | return -ENOMEM; | 439 | &rts_thr); |
477 | |||
478 | status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I, | ||
479 | HostCmd_ACT_GEN_SET, &rts_thr); | ||
480 | |||
481 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
482 | ret = -EFAULT; | ||
483 | |||
484 | kfree(wait); | ||
485 | return ret; | ||
486 | } | 440 | } |
487 | 441 | ||
488 | /* | 442 | /* |
@@ -498,8 +452,11 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
498 | 452 | ||
499 | int ret = 0; | 453 | int ret = 0; |
500 | 454 | ||
501 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) | 455 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) { |
502 | ret = mwifiex_set_rts(priv, wiphy->rts_threshold); | 456 | ret = mwifiex_set_rts(priv, wiphy->rts_threshold); |
457 | if (ret) | ||
458 | return ret; | ||
459 | } | ||
503 | 460 | ||
504 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) | 461 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) |
505 | ret = mwifiex_set_frag(priv, wiphy->frag_threshold); | 462 | ret = mwifiex_set_frag(priv, wiphy->frag_threshold); |
@@ -518,7 +475,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | |||
518 | { | 475 | { |
519 | int ret = 0; | 476 | int ret = 0; |
520 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 477 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
521 | struct mwifiex_wait_queue *wait = NULL; | ||
522 | 478 | ||
523 | if (priv->bss_mode == type) { | 479 | if (priv->bss_mode == type) { |
524 | wiphy_warn(wiphy, "already set to required type\n"); | 480 | wiphy_warn(wiphy, "already set to required type\n"); |
@@ -545,24 +501,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | |||
545 | return -EINVAL; | 501 | return -EINVAL; |
546 | } | 502 | } |
547 | 503 | ||
548 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | 504 | mwifiex_deauthenticate(priv, NULL); |
549 | if (!wait) | ||
550 | return -ENOMEM; | ||
551 | |||
552 | mwifiex_deauthenticate(priv, wait, NULL); | ||
553 | 505 | ||
554 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; | 506 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; |
555 | 507 | ||
556 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, | 508 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, |
557 | HostCmd_ACT_GEN_SET, 0, wait, NULL); | 509 | HostCmd_ACT_GEN_SET, 0, NULL); |
558 | if (!ret) | ||
559 | ret = -EINPROGRESS; | ||
560 | |||
561 | ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT); | ||
562 | if (ret) | ||
563 | ret = -EFAULT; | ||
564 | 510 | ||
565 | kfree(wait); | ||
566 | return ret; | 511 | return ret; |
567 | } | 512 | } |
568 | 513 | ||
@@ -592,7 +537,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
592 | 537 | ||
593 | /* Get signal information from the firmware */ | 538 | /* Get signal information from the firmware */ |
594 | memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); | 539 | memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); |
595 | if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { | 540 | if (mwifiex_get_signal_info(priv, &signal)) { |
596 | dev_err(priv->adapter->dev, "getting signal information\n"); | 541 | dev_err(priv->adapter->dev, "getting signal information\n"); |
597 | ret = -EFAULT; | 542 | ret = -EFAULT; |
598 | } | 543 | } |
@@ -623,7 +568,6 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
623 | u8 *mac, struct station_info *sinfo) | 568 | u8 *mac, struct station_info *sinfo) |
624 | { | 569 | { |
625 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 570 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
626 | int ret = 0; | ||
627 | 571 | ||
628 | mwifiex_dump_station_info(priv, sinfo); | 572 | mwifiex_dump_station_info(priv, sinfo); |
629 | 573 | ||
@@ -632,10 +576,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
632 | if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) | 576 | if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) |
633 | return -ENOENT; | 577 | return -ENOENT; |
634 | 578 | ||
635 | 579 | return mwifiex_dump_station_info(priv, sinfo); | |
636 | ret = mwifiex_dump_station_info(priv, sinfo); | ||
637 | |||
638 | return ret; | ||
639 | } | 580 | } |
640 | 581 | ||
641 | /* Supported rates to be advertised to the cfg80211 */ | 582 | /* Supported rates to be advertised to the cfg80211 */ |
@@ -750,7 +691,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, | |||
750 | return -EBUSY; | 691 | return -EBUSY; |
751 | 692 | ||
752 | priv->disconnect = 1; | 693 | priv->disconnect = 1; |
753 | if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) | 694 | if (mwifiex_deauthenticate(priv, NULL)) |
754 | return -EFAULT; | 695 | return -EFAULT; |
755 | 696 | ||
756 | wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" | 697 | wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" |
@@ -774,15 +715,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, | |||
774 | */ | 715 | */ |
775 | static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | 716 | static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) |
776 | { | 717 | { |
777 | int ret = 0; | ||
778 | struct ieee80211_channel *chan; | 718 | struct ieee80211_channel *chan; |
779 | struct mwifiex_bss_info bss_info; | 719 | struct mwifiex_bss_info bss_info; |
780 | int ie_len = 0; | 720 | int ie_len = 0; |
781 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; | 721 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; |
782 | 722 | ||
783 | ret = mwifiex_get_bss_info(priv, &bss_info); | 723 | if (mwifiex_get_bss_info(priv, &bss_info)) |
784 | if (ret) | 724 | return -1; |
785 | return ret; | ||
786 | 725 | ||
787 | ie_buf[0] = WLAN_EID_SSID; | 726 | ie_buf[0] = WLAN_EID_SSID; |
788 | ie_buf[1] = bss_info.ssid.ssid_len; | 727 | ie_buf[1] = bss_info.ssid.ssid_len; |
@@ -801,7 +740,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
801 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 740 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
802 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); | 741 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); |
803 | 742 | ||
804 | return ret; | 743 | return 0; |
805 | } | 744 | } |
806 | 745 | ||
807 | /* | 746 | /* |
@@ -830,16 +769,15 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, | |||
830 | struct mwifiex_bssdescriptor *scan_table; | 769 | struct mwifiex_bssdescriptor *scan_table; |
831 | int i, j; | 770 | int i, j; |
832 | struct ieee80211_channel *chan; | 771 | struct ieee80211_channel *chan; |
833 | u8 *ie, *tmp, *ie_buf; | 772 | u8 *ie, *ie_buf; |
834 | u32 ie_len; | 773 | u32 ie_len; |
835 | u64 ts = 0; | ||
836 | u8 *beacon; | 774 | u8 *beacon; |
837 | int beacon_size; | 775 | int beacon_size; |
838 | u8 element_id, element_len; | 776 | u8 element_id, element_len; |
839 | 777 | ||
840 | memset(&scan_resp, 0, sizeof(scan_resp)); | 778 | memset(&scan_resp, 0, sizeof(scan_resp)); |
841 | if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) | 779 | scan_resp.scan_table = (u8 *) priv->adapter->scan_table; |
842 | return -EFAULT; | 780 | scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table; |
843 | 781 | ||
844 | #define MAX_IE_BUF 2048 | 782 | #define MAX_IE_BUF 2048 |
845 | ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); | 783 | ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); |
@@ -914,9 +852,9 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, | |||
914 | case WLAN_EID_BSS_AC_ACCESS_DELAY: | 852 | case WLAN_EID_BSS_AC_ACCESS_DELAY: |
915 | ie[0] = element_id; | 853 | ie[0] = element_id; |
916 | ie[1] = element_len; | 854 | ie[1] = element_len; |
917 | tmp = (u8 *) beacon; | ||
918 | memcpy(&ie[sizeof(struct ieee_types_header)], | 855 | memcpy(&ie[sizeof(struct ieee_types_header)], |
919 | tmp + sizeof(struct ieee_types_header), | 856 | (u8 *) beacon |
857 | + sizeof(struct ieee_types_header), | ||
920 | element_len); | 858 | element_len); |
921 | ie_len += ie[1] + | 859 | ie_len += ie[1] + |
922 | sizeof(struct ieee_types_header); | 860 | sizeof(struct ieee_types_header); |
@@ -933,7 +871,7 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, | |||
933 | scan_table[i].freq); | 871 | scan_table[i].freq); |
934 | cfg80211_inform_bss(priv->wdev->wiphy, chan, | 872 | cfg80211_inform_bss(priv->wdev->wiphy, chan, |
935 | scan_table[i].mac_address, | 873 | scan_table[i].mac_address, |
936 | ts, scan_table[i].cap_info_bitmap, | 874 | 0, scan_table[i].cap_info_bitmap, |
937 | scan_table[i].beacon_period, | 875 | scan_table[i].beacon_period, |
938 | ie_buf, ie_len, | 876 | ie_buf, ie_len, |
939 | scan_table[i].rssi, GFP_KERNEL); | 877 | scan_table[i].rssi, GFP_KERNEL); |
@@ -966,9 +904,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
966 | struct mwifiex_802_11_ssid req_ssid; | 904 | struct mwifiex_802_11_ssid req_ssid; |
967 | struct mwifiex_ssid_bssid ssid_bssid; | 905 | struct mwifiex_ssid_bssid ssid_bssid; |
968 | int ret = 0; | 906 | int ret = 0; |
969 | int auth_type = 0, pairwise_encrypt_mode = 0; | 907 | int auth_type = 0; |
970 | int group_encrypt_mode = 0; | ||
971 | int alg_is_wep = 0; | ||
972 | 908 | ||
973 | memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); | 909 | memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); |
974 | memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); | 910 | memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); |
@@ -986,7 +922,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
986 | } | 922 | } |
987 | 923 | ||
988 | /* disconnect before try to associate */ | 924 | /* disconnect before try to associate */ |
989 | mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); | 925 | mwifiex_deauthenticate(priv, NULL); |
990 | 926 | ||
991 | if (channel) | 927 | if (channel) |
992 | ret = mwifiex_set_rf_channel(priv, channel, | 928 | ret = mwifiex_set_rf_channel(priv, channel, |
@@ -1034,9 +970,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1034 | ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); | 970 | ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); |
1035 | 971 | ||
1036 | if (sme->key) { | 972 | if (sme->key) { |
1037 | alg_is_wep = mwifiex_is_alg_wep(pairwise_encrypt_mode) | 973 | if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) { |
1038 | | mwifiex_is_alg_wep(group_encrypt_mode); | ||
1039 | if (alg_is_wep) { | ||
1040 | dev_dbg(priv->adapter->dev, | 974 | dev_dbg(priv->adapter->dev, |
1041 | "info: setting wep encryption" | 975 | "info: setting wep encryption" |
1042 | " with key len %d\n", sme->key_len); | 976 | " with key len %d\n", sme->key_len); |
@@ -1046,7 +980,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1046 | } | 980 | } |
1047 | done: | 981 | done: |
1048 | /* Do specific SSID scanning */ | 982 | /* Do specific SSID scanning */ |
1049 | if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { | 983 | if (mwifiex_request_scan(priv, &req_ssid)) { |
1050 | dev_err(priv->adapter->dev, "scan error\n"); | 984 | dev_err(priv->adapter->dev, "scan error\n"); |
1051 | return -EFAULT; | 985 | return -EFAULT; |
1052 | } | 986 | } |
@@ -1055,8 +989,7 @@ done: | |||
1055 | memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); | 989 | memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); |
1056 | 990 | ||
1057 | if (mode != NL80211_IFTYPE_ADHOC) { | 991 | if (mode != NL80211_IFTYPE_ADHOC) { |
1058 | if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, | 992 | if (mwifiex_find_best_bss(priv, &ssid_bssid)) |
1059 | &ssid_bssid)) | ||
1060 | return -EFAULT; | 993 | return -EFAULT; |
1061 | /* Inform the BSS information to kernel, otherwise | 994 | /* Inform the BSS information to kernel, otherwise |
1062 | * kernel will give a panic after successful assoc */ | 995 | * kernel will give a panic after successful assoc */ |
@@ -1072,7 +1005,10 @@ done: | |||
1072 | /* Connect to BSS by ESSID */ | 1005 | /* Connect to BSS by ESSID */ |
1073 | memset(&ssid_bssid.bssid, 0, ETH_ALEN); | 1006 | memset(&ssid_bssid.bssid, 0, ETH_ALEN); |
1074 | 1007 | ||
1075 | if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) | 1008 | if (!netif_queue_stopped(priv->netdev)) |
1009 | netif_stop_queue(priv->netdev); | ||
1010 | |||
1011 | if (mwifiex_bss_start(priv, &ssid_bssid)) | ||
1076 | return -EFAULT; | 1012 | return -EFAULT; |
1077 | 1013 | ||
1078 | if (mode == NL80211_IFTYPE_ADHOC) { | 1014 | if (mode == NL80211_IFTYPE_ADHOC) { |
@@ -1176,7 +1112,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1176 | 1112 | ||
1177 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", | 1113 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", |
1178 | priv->cfg_bssid); | 1114 | priv->cfg_bssid); |
1179 | if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) | 1115 | if (mwifiex_deauthenticate(priv, NULL)) |
1180 | return -EFAULT; | 1116 | return -EFAULT; |
1181 | 1117 | ||
1182 | queue_work(priv->workqueue, &priv->cfg_workqueue); | 1118 | queue_work(priv->workqueue, &priv->cfg_workqueue); |
@@ -1451,6 +1387,4 @@ done: | |||
1451 | memset(priv->cfg_bssid, 0, ETH_ALEN); | 1387 | memset(priv->cfg_bssid, 0, ETH_ALEN); |
1452 | priv->disconnect = 0; | 1388 | priv->disconnect = 0; |
1453 | } | 1389 | } |
1454 | |||
1455 | return; | ||
1456 | } | 1390 | } |
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 07187a405fee..d0cada5a29a0 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c | |||
@@ -75,8 +75,7 @@ u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; | |||
75 | * This function maps an index in supported rates table into | 75 | * This function maps an index in supported rates table into |
76 | * the corresponding data rate. | 76 | * the corresponding data rate. |
77 | */ | 77 | */ |
78 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | 78 | u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info) |
79 | u8 ht_info) | ||
80 | { | 79 | { |
81 | u16 mcs_rate[4][8] = { | 80 | u16 mcs_rate[4][8] = { |
82 | {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} | 81 | {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} |
@@ -126,7 +125,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | |||
126 | * This function maps a data rate value into corresponding index in supported | 125 | * This function maps a data rate value into corresponding index in supported |
127 | * rates table. | 126 | * rates table. |
128 | */ | 127 | */ |
129 | u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) | 128 | u8 mwifiex_data_rate_to_index(u32 rate) |
130 | { | 129 | { |
131 | u16 *ptr; | 130 | u16 *ptr; |
132 | 131 | ||
@@ -146,16 +145,12 @@ u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) | |||
146 | */ | 145 | */ |
147 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) | 146 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) |
148 | { | 147 | { |
149 | u32 k; | ||
150 | |||
151 | if (!priv->media_connected) | 148 | if (!priv->media_connected) |
152 | k = mwifiex_get_supported_rates(priv, rates); | 149 | return mwifiex_get_supported_rates(priv, rates); |
153 | else | 150 | else |
154 | k = mwifiex_copy_rates(rates, 0, | 151 | return mwifiex_copy_rates(rates, 0, |
155 | priv->curr_bss_params.data_rates, | 152 | priv->curr_bss_params.data_rates, |
156 | priv->curr_bss_params.num_of_rates); | 153 | priv->curr_bss_params.num_of_rates); |
157 | |||
158 | return k; | ||
159 | } | 154 | } |
160 | 155 | ||
161 | /* | 156 | /* |
@@ -265,9 +260,7 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv) | |||
265 | /* | 260 | /* |
266 | * This function converts rate bitmap into rate index. | 261 | * This function converts rate bitmap into rate index. |
267 | */ | 262 | */ |
268 | int | 263 | int mwifiex_get_rate_index(u16 *rate_bitmap, int size) |
269 | mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap, | ||
270 | int size) | ||
271 | { | 264 | { |
272 | int i; | 265 | int i; |
273 | 266 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a9aeb31af455..776146a104ec 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -36,11 +36,12 @@ | |||
36 | static void | 36 | static void |
37 | mwifiex_init_cmd_node(struct mwifiex_private *priv, | 37 | mwifiex_init_cmd_node(struct mwifiex_private *priv, |
38 | struct cmd_ctrl_node *cmd_node, | 38 | struct cmd_ctrl_node *cmd_node, |
39 | u32 cmd_oid, void *wait_queue, void *data_buf) | 39 | u32 cmd_oid, void *data_buf) |
40 | { | 40 | { |
41 | cmd_node->priv = priv; | 41 | cmd_node->priv = priv; |
42 | cmd_node->cmd_oid = cmd_oid; | 42 | cmd_node->cmd_oid = cmd_oid; |
43 | cmd_node->wq_buf = wait_queue; | 43 | cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; |
44 | priv->adapter->cmd_wait_q_required = false; | ||
44 | cmd_node->data_buf = data_buf; | 45 | cmd_node->data_buf = data_buf; |
45 | cmd_node->cmd_skb = cmd_node->skb; | 46 | cmd_node->cmd_skb = cmd_node->skb; |
46 | } | 47 | } |
@@ -86,39 +87,13 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, | |||
86 | { | 87 | { |
87 | cmd_node->cmd_oid = 0; | 88 | cmd_node->cmd_oid = 0; |
88 | cmd_node->cmd_flag = 0; | 89 | cmd_node->cmd_flag = 0; |
89 | cmd_node->wq_buf = NULL; | ||
90 | cmd_node->data_buf = NULL; | 90 | cmd_node->data_buf = NULL; |
91 | cmd_node->wait_q_enabled = false; | ||
91 | 92 | ||
92 | if (cmd_node->resp_skb) { | 93 | if (cmd_node->resp_skb) { |
93 | mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); | 94 | mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); |
94 | cmd_node->resp_skb = NULL; | 95 | cmd_node->resp_skb = NULL; |
95 | } | 96 | } |
96 | |||
97 | return; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * This function returns a command node from the pending queue which | ||
102 | * matches the given IOCTL request. | ||
103 | */ | ||
104 | static struct cmd_ctrl_node * | ||
105 | mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter, | ||
106 | struct mwifiex_wait_queue *wait_queue) | ||
107 | { | ||
108 | unsigned long flags; | ||
109 | struct cmd_ctrl_node *cmd_node; | ||
110 | |||
111 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | ||
112 | list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { | ||
113 | if (cmd_node->wq_buf == wait_queue) { | ||
114 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, | ||
115 | flags); | ||
116 | return cmd_node; | ||
117 | } | ||
118 | } | ||
119 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | ||
120 | |||
121 | return NULL; | ||
122 | } | 97 | } |
123 | 98 | ||
124 | /* | 99 | /* |
@@ -155,7 +130,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
155 | struct mwifiex_adapter *adapter = priv->adapter; | 130 | struct mwifiex_adapter *adapter = priv->adapter; |
156 | int ret = 0; | 131 | int ret = 0; |
157 | struct host_cmd_ds_command *host_cmd; | 132 | struct host_cmd_ds_command *host_cmd; |
158 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
159 | uint16_t cmd_code; | 133 | uint16_t cmd_code; |
160 | uint16_t cmd_size; | 134 | uint16_t cmd_size; |
161 | struct timeval tstamp; | 135 | struct timeval tstamp; |
@@ -165,15 +139,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
165 | return -1; | 139 | return -1; |
166 | 140 | ||
167 | host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); | 141 | host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); |
168 | if (cmd_node->wq_buf) | ||
169 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | ||
170 | 142 | ||
171 | /* Sanity test */ | 143 | /* Sanity test */ |
172 | if (host_cmd == NULL || host_cmd->size == 0) { | 144 | if (host_cmd == NULL || host_cmd->size == 0) { |
173 | dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" | 145 | dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" |
174 | " or cmd size is 0, not sending\n"); | 146 | " or cmd size is 0, not sending\n"); |
175 | if (wait_queue) | 147 | if (cmd_node->wait_q_enabled) |
176 | wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; | 148 | adapter->cmd_wait_q.status = -1; |
177 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 149 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
178 | return -1; | 150 | return -1; |
179 | } | 151 | } |
@@ -206,10 +178,12 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
206 | cmd_node->cmd_skb->data, | 178 | cmd_node->cmd_skb->data, |
207 | cmd_node->cmd_skb->len, NULL); | 179 | cmd_node->cmd_skb->len, NULL); |
208 | 180 | ||
181 | skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); | ||
182 | |||
209 | if (ret == -1) { | 183 | if (ret == -1) { |
210 | dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); | 184 | dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); |
211 | if (wait_queue) | 185 | if (cmd_node->wait_q_enabled) |
212 | wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; | 186 | adapter->cmd_wait_q.status = -1; |
213 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 187 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
214 | 188 | ||
215 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 189 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
@@ -435,7 +409,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
435 | } | 409 | } |
436 | 410 | ||
437 | /* | 411 | /* |
438 | * This function prepares a command before sending it to the firmware. | 412 | * This function is used to send synchronous command to the firmware. |
413 | * | ||
414 | * it allocates a wait queue for the command and wait for the command | ||
415 | * response. | ||
416 | */ | ||
417 | int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, | ||
418 | u16 cmd_action, u32 cmd_oid, void *data_buf) | ||
419 | { | ||
420 | int ret = 0; | ||
421 | struct mwifiex_adapter *adapter = priv->adapter; | ||
422 | |||
423 | adapter->cmd_wait_q_required = true; | ||
424 | adapter->cmd_wait_q.condition = false; | ||
425 | |||
426 | ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, | ||
427 | data_buf); | ||
428 | if (!ret) | ||
429 | ret = mwifiex_wait_queue_complete(adapter); | ||
430 | |||
431 | return ret; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | * This function prepares a command and asynchronously send it to the firmware. | ||
439 | * | 437 | * |
440 | * Preparation includes - | 438 | * Preparation includes - |
441 | * - Sanity tests to make sure the card is still present or the FW | 439 | * - Sanity tests to make sure the card is still present or the FW |
@@ -445,9 +443,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
445 | * - Fill up the non-default parameters and buffer pointers | 443 | * - Fill up the non-default parameters and buffer pointers |
446 | * - Add the command to pending queue | 444 | * - Add the command to pending queue |
447 | */ | 445 | */ |
448 | int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | 446 | int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, |
449 | u16 cmd_action, u32 cmd_oid, | 447 | u16 cmd_action, u32 cmd_oid, void *data_buf) |
450 | void *wait_queue, void *data_buf) | ||
451 | { | 448 | { |
452 | int ret = 0; | 449 | int ret = 0; |
453 | struct mwifiex_adapter *adapter = priv->adapter; | 450 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -485,7 +482,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
485 | } | 482 | } |
486 | 483 | ||
487 | /* Initialize the command node */ | 484 | /* Initialize the command node */ |
488 | mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); | 485 | mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); |
489 | 486 | ||
490 | if (!cmd_node->cmd_skb) { | 487 | if (!cmd_node->cmd_skb) { |
491 | dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); | 488 | dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); |
@@ -535,18 +532,13 @@ void | |||
535 | mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | 532 | mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, |
536 | struct cmd_ctrl_node *cmd_node) | 533 | struct cmd_ctrl_node *cmd_node) |
537 | { | 534 | { |
538 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
539 | unsigned long flags; | 535 | unsigned long flags; |
540 | 536 | ||
541 | if (cmd_node == NULL) | 537 | if (!cmd_node) |
542 | return; | 538 | return; |
543 | if (cmd_node->wq_buf) { | 539 | |
544 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 540 | if (cmd_node->wait_q_enabled) |
545 | if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) | 541 | mwifiex_complete_cmd(adapter); |
546 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | ||
547 | else | ||
548 | mwifiex_ioctl_complete(adapter, wait_queue, 0); | ||
549 | } | ||
550 | /* Clean the node */ | 542 | /* Clean the node */ |
551 | mwifiex_clean_cmd_node(adapter, cmd_node); | 543 | mwifiex_clean_cmd_node(adapter, cmd_node); |
552 | 544 | ||
@@ -554,8 +546,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | |||
554 | spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); | 546 | spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); |
555 | list_add_tail(&cmd_node->list, &adapter->cmd_free_q); | 547 | list_add_tail(&cmd_node->list, &adapter->cmd_free_q); |
556 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); | 548 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); |
557 | |||
558 | return; | ||
559 | } | 549 | } |
560 | 550 | ||
561 | /* | 551 | /* |
@@ -600,8 +590,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, | |||
600 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | 590 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); |
601 | 591 | ||
602 | dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); | 592 | dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); |
603 | |||
604 | return; | ||
605 | } | 593 | } |
606 | 594 | ||
607 | /* | 595 | /* |
@@ -692,7 +680,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
692 | uint16_t orig_cmdresp_no; | 680 | uint16_t orig_cmdresp_no; |
693 | uint16_t cmdresp_no; | 681 | uint16_t cmdresp_no; |
694 | uint16_t cmdresp_result; | 682 | uint16_t cmdresp_result; |
695 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
696 | struct timeval tstamp; | 683 | struct timeval tstamp; |
697 | unsigned long flags; | 684 | unsigned long flags; |
698 | 685 | ||
@@ -706,10 +693,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
706 | return -1; | 693 | return -1; |
707 | } | 694 | } |
708 | 695 | ||
709 | if (adapter->curr_cmd->wq_buf) | ||
710 | wait_queue = (struct mwifiex_wait_queue *) | ||
711 | adapter->curr_cmd->wq_buf; | ||
712 | |||
713 | adapter->num_cmd_timeout = 0; | 696 | adapter->num_cmd_timeout = 0; |
714 | 697 | ||
715 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; | 698 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; |
@@ -764,8 +747,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
764 | 747 | ||
765 | if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { | 748 | if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { |
766 | dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); | 749 | dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); |
767 | if (wait_queue) | 750 | if (adapter->curr_cmd->wait_q_enabled) |
768 | wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; | 751 | adapter->cmd_wait_q.status = -1; |
769 | 752 | ||
770 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 753 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
771 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 754 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
@@ -781,8 +764,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
781 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); | 764 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); |
782 | } else { | 765 | } else { |
783 | /* handle response */ | 766 | /* handle response */ |
784 | ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, | 767 | ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp); |
785 | wait_queue); | ||
786 | } | 768 | } |
787 | 769 | ||
788 | /* Check init command response */ | 770 | /* Check init command response */ |
@@ -797,10 +779,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
797 | } | 779 | } |
798 | 780 | ||
799 | if (adapter->curr_cmd) { | 781 | if (adapter->curr_cmd) { |
800 | if (wait_queue && (!ret)) | 782 | if (adapter->curr_cmd->wait_q_enabled && (!ret)) |
801 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 783 | adapter->cmd_wait_q.status = 0; |
802 | else if (wait_queue && (ret == -1)) | 784 | else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) |
803 | wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; | 785 | adapter->cmd_wait_q.status = -1; |
804 | 786 | ||
805 | /* Clean up and put current command back to cmd_free_q */ | 787 | /* Clean up and put current command back to cmd_free_q */ |
806 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 788 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
@@ -824,7 +806,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
824 | struct mwifiex_adapter *adapter = | 806 | struct mwifiex_adapter *adapter = |
825 | (struct mwifiex_adapter *) function_context; | 807 | (struct mwifiex_adapter *) function_context; |
826 | struct cmd_ctrl_node *cmd_node = NULL; | 808 | struct cmd_ctrl_node *cmd_node = NULL; |
827 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
828 | struct timeval tstamp; | 809 | struct timeval tstamp; |
829 | 810 | ||
830 | adapter->num_cmd_timeout++; | 811 | adapter->num_cmd_timeout++; |
@@ -834,10 +815,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
834 | return; | 815 | return; |
835 | } | 816 | } |
836 | cmd_node = adapter->curr_cmd; | 817 | cmd_node = adapter->curr_cmd; |
837 | if (cmd_node->wq_buf) { | 818 | if (cmd_node->wait_q_enabled) |
838 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 819 | adapter->cmd_wait_q.status = -ETIMEDOUT; |
839 | wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT; | ||
840 | } | ||
841 | 820 | ||
842 | if (cmd_node) { | 821 | if (cmd_node) { |
843 | adapter->dbg.timeout_cmd_id = | 822 | adapter->dbg.timeout_cmd_id = |
@@ -886,8 +865,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
886 | } | 865 | } |
887 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 866 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
888 | mwifiex_init_fw_complete(adapter); | 867 | mwifiex_init_fw_complete(adapter); |
889 | |||
890 | return; | ||
891 | } | 868 | } |
892 | 869 | ||
893 | /* | 870 | /* |
@@ -901,18 +878,15 @@ void | |||
901 | mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | 878 | mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) |
902 | { | 879 | { |
903 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 880 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
904 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
905 | unsigned long flags; | 881 | unsigned long flags; |
906 | 882 | ||
907 | /* Cancel current cmd */ | 883 | /* Cancel current cmd */ |
908 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { | 884 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { |
909 | wait_queue = | ||
910 | (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf; | ||
911 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 885 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
912 | adapter->curr_cmd->wq_buf = NULL; | 886 | adapter->curr_cmd->wait_q_enabled = false; |
913 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 887 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
914 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 888 | adapter->cmd_wait_q.status = -1; |
915 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | 889 | mwifiex_complete_cmd(adapter); |
916 | } | 890 | } |
917 | /* Cancel all pending command */ | 891 | /* Cancel all pending command */ |
918 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | 892 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); |
@@ -921,12 +895,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
921 | list_del(&cmd_node->list); | 895 | list_del(&cmd_node->list); |
922 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | 896 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); |
923 | 897 | ||
924 | if (cmd_node->wq_buf) { | 898 | if (cmd_node->wait_q_enabled) { |
925 | wait_queue = | 899 | adapter->cmd_wait_q.status = -1; |
926 | (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 900 | mwifiex_complete_cmd(adapter); |
927 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 901 | cmd_node->wait_q_enabled = false; |
928 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | ||
929 | cmd_node->wq_buf = NULL; | ||
930 | } | 902 | } |
931 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 903 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
932 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | 904 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); |
@@ -940,7 +912,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
940 | list_del(&cmd_node->list); | 912 | list_del(&cmd_node->list); |
941 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 913 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
942 | 914 | ||
943 | cmd_node->wq_buf = NULL; | 915 | cmd_node->wait_q_enabled = false; |
944 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 916 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
945 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 917 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
946 | } | 918 | } |
@@ -962,8 +934,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
962 | * are cancelled. | 934 | * are cancelled. |
963 | */ | 935 | */ |
964 | void | 936 | void |
965 | mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | 937 | mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) |
966 | struct mwifiex_wait_queue *wait_queue) | ||
967 | { | 938 | { |
968 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 939 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
969 | unsigned long cmd_flags; | 940 | unsigned long cmd_flags; |
@@ -972,45 +943,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | |||
972 | uint16_t cancel_scan_cmd = false; | 943 | uint16_t cancel_scan_cmd = false; |
973 | 944 | ||
974 | if ((adapter->curr_cmd) && | 945 | if ((adapter->curr_cmd) && |
975 | (adapter->curr_cmd->wq_buf == wait_queue)) { | 946 | (adapter->curr_cmd->wait_q_enabled)) { |
976 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | 947 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); |
977 | cmd_node = adapter->curr_cmd; | 948 | cmd_node = adapter->curr_cmd; |
978 | cmd_node->wq_buf = NULL; | 949 | cmd_node->wait_q_enabled = false; |
979 | cmd_node->cmd_flag |= CMD_F_CANCELED; | 950 | cmd_node->cmd_flag |= CMD_F_CANCELED; |
980 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
981 | } | ||
982 | |||
983 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
984 | while (1) { | ||
985 | cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue); | ||
986 | if (!cmd_node) | ||
987 | break; | ||
988 | |||
989 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, | 951 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, |
990 | cmd_pending_q_flags); | 952 | cmd_pending_q_flags); |
991 | list_del(&cmd_node->list); | 953 | list_del(&cmd_node->list); |
992 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, | 954 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, |
993 | cmd_pending_q_flags); | 955 | cmd_pending_q_flags); |
994 | |||
995 | cmd_node->wq_buf = NULL; | ||
996 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 956 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
957 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
997 | } | 958 | } |
998 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | 959 | |
999 | /* Cancel all pending scan command */ | 960 | /* Cancel all pending scan command */ |
1000 | spin_lock_irqsave(&adapter->scan_pending_q_lock, | 961 | spin_lock_irqsave(&adapter->scan_pending_q_lock, |
1001 | scan_pending_q_flags); | 962 | scan_pending_q_flags); |
1002 | list_for_each_entry_safe(cmd_node, tmp_node, | 963 | list_for_each_entry_safe(cmd_node, tmp_node, |
1003 | &adapter->scan_pending_q, list) { | 964 | &adapter->scan_pending_q, list) { |
1004 | if (cmd_node->wq_buf == wait_queue) { | 965 | list_del(&cmd_node->list); |
1005 | list_del(&cmd_node->list); | 966 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1006 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 967 | scan_pending_q_flags); |
1007 | scan_pending_q_flags); | 968 | cmd_node->wait_q_enabled = false; |
1008 | cmd_node->wq_buf = NULL; | 969 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
1009 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 970 | spin_lock_irqsave(&adapter->scan_pending_q_lock, |
1010 | spin_lock_irqsave(&adapter->scan_pending_q_lock, | 971 | scan_pending_q_flags); |
1011 | scan_pending_q_flags); | 972 | cancel_scan_cmd = true; |
1012 | cancel_scan_cmd = true; | ||
1013 | } | ||
1014 | } | 973 | } |
1015 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 974 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1016 | scan_pending_q_flags); | 975 | scan_pending_q_flags); |
@@ -1020,10 +979,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | |||
1020 | adapter->scan_processing = false; | 979 | adapter->scan_processing = false; |
1021 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | 980 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); |
1022 | } | 981 | } |
1023 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 982 | adapter->cmd_wait_q.status = -1; |
1024 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | 983 | mwifiex_complete_cmd(adapter); |
1025 | |||
1026 | return; | ||
1027 | } | 984 | } |
1028 | 985 | ||
1029 | /* | 986 | /* |
@@ -1127,7 +1084,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) | |||
1127 | adapter->is_hs_configured = false; | 1084 | adapter->is_hs_configured = false; |
1128 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1085 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, |
1129 | MWIFIEX_BSS_ROLE_ANY), false); | 1086 | MWIFIEX_BSS_ROLE_ANY), false); |
1130 | return; | ||
1131 | } | 1087 | } |
1132 | 1088 | ||
1133 | /* | 1089 | /* |
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 63b09692f27d..7ddcb062f103 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c | |||
@@ -129,8 +129,8 @@ static struct mwifiex_debug_data items[] = { | |||
129 | item_addr(event_received), 1}, | 129 | item_addr(event_received), 1}, |
130 | 130 | ||
131 | /* variables defined in struct mwifiex_adapter */ | 131 | /* variables defined in struct mwifiex_adapter */ |
132 | {"ioctl_pending", adapter_item_size(ioctl_pending), | 132 | {"cmd_pending", adapter_item_size(cmd_pending), |
133 | adapter_item_addr(ioctl_pending), 1}, | 133 | adapter_item_addr(cmd_pending), 1}, |
134 | {"tx_pending", adapter_item_size(tx_pending), | 134 | {"tx_pending", adapter_item_size(tx_pending), |
135 | adapter_item_addr(tx_pending), 1}, | 135 | adapter_item_addr(tx_pending), 1}, |
136 | {"rx_pending", adapter_item_size(rx_pending), | 136 | {"rx_pending", adapter_item_size(rx_pending), |
@@ -735,8 +735,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) | |||
735 | MWIFIEX_DFS_ADD_FILE(getlog); | 735 | MWIFIEX_DFS_ADD_FILE(getlog); |
736 | MWIFIEX_DFS_ADD_FILE(regrdwr); | 736 | MWIFIEX_DFS_ADD_FILE(regrdwr); |
737 | MWIFIEX_DFS_ADD_FILE(rdeeprom); | 737 | MWIFIEX_DFS_ADD_FILE(rdeeprom); |
738 | |||
739 | return; | ||
740 | } | 738 | } |
741 | 739 | ||
742 | /* | 740 | /* |
@@ -749,7 +747,6 @@ mwifiex_dev_debugfs_remove(struct mwifiex_private *priv) | |||
749 | return; | 747 | return; |
750 | 748 | ||
751 | debugfs_remove_recursive(priv->dfs_dev_dir); | 749 | debugfs_remove_recursive(priv->dfs_dev_dir); |
752 | return; | ||
753 | } | 750 | } |
754 | 751 | ||
755 | /* | 752 | /* |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index c3c15f9e757e..0e90b0986ed8 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -61,23 +61,6 @@ | |||
61 | 61 | ||
62 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) | 62 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) |
63 | 63 | ||
64 | enum mwifiex_error_code { | ||
65 | MWIFIEX_ERROR_NO_ERROR = 0, | ||
66 | MWIFIEX_ERROR_FW_NOT_READY = 0x00000001, | ||
67 | MWIFIEX_ERROR_FW_BUSY, | ||
68 | MWIFIEX_ERROR_FW_CMDRESP, | ||
69 | MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001, | ||
70 | MWIFIEX_ERROR_PKT_TIMEOUT, | ||
71 | MWIFIEX_ERROR_CMD_INVALID, | ||
72 | MWIFIEX_ERROR_CMD_TIMEOUT, | ||
73 | MWIFIEX_ERROR_CMD_DNLD_FAIL, | ||
74 | MWIFIEX_ERROR_CMD_CANCEL, | ||
75 | MWIFIEX_ERROR_CMD_RESP_FAIL, | ||
76 | MWIFIEX_ERROR_ASSOC_FAIL, | ||
77 | MWIFIEX_ERROR_EVENT_UNKNOWN, | ||
78 | MWIFIEX_ERROR_INVALID_PARAMETER, | ||
79 | }; | ||
80 | |||
81 | enum mwifiex_bss_type { | 64 | enum mwifiex_bss_type { |
82 | MWIFIEX_BSS_TYPE_STA = 0, | 65 | MWIFIEX_BSS_TYPE_STA = 0, |
83 | MWIFIEX_BSS_TYPE_UAP = 1, | 66 | MWIFIEX_BSS_TYPE_UAP = 1, |
@@ -112,12 +95,9 @@ struct mwifiex_802_11_ssid { | |||
112 | }; | 95 | }; |
113 | 96 | ||
114 | struct mwifiex_wait_queue { | 97 | struct mwifiex_wait_queue { |
115 | u32 bss_index; | 98 | wait_queue_head_t wait; |
116 | wait_queue_head_t *wait; | 99 | u16 condition; |
117 | u16 *condition; | ||
118 | u32 start_time; | ||
119 | int status; | 100 | int status; |
120 | u32 enabled; | ||
121 | }; | 101 | }; |
122 | 102 | ||
123 | struct mwifiex_rxinfo { | 103 | struct mwifiex_rxinfo { |
@@ -133,11 +113,11 @@ struct mwifiex_txinfo { | |||
133 | }; | 113 | }; |
134 | 114 | ||
135 | struct mwifiex_bss_attr { | 115 | struct mwifiex_bss_attr { |
136 | u32 bss_type; | 116 | u8 bss_type; |
137 | u32 frame_type; | 117 | u8 frame_type; |
138 | u32 active; | 118 | u8 active; |
139 | u32 bss_priority; | 119 | u8 bss_priority; |
140 | u32 bss_num; | 120 | u8 bss_num; |
141 | }; | 121 | }; |
142 | 122 | ||
143 | enum mwifiex_wmm_ac_e { | 123 | enum mwifiex_wmm_ac_e { |
@@ -146,8 +126,4 @@ enum mwifiex_wmm_ac_e { | |||
146 | WMM_AC_VI, | 126 | WMM_AC_VI, |
147 | WMM_AC_VO | 127 | WMM_AC_VO |
148 | } __packed; | 128 | } __packed; |
149 | |||
150 | struct mwifiex_device { | ||
151 | struct mwifiex_bss_attr bss_attr[MWIFIEX_MAX_BSS_NUM]; | ||
152 | }; | ||
153 | #endif /* !_MWIFIEX_DECL_H_ */ | 129 | #endif /* !_MWIFIEX_DECL_H_ */ |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 2b938115b26a..6d1c4545eda6 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -72,33 +72,12 @@ enum KEY_TYPE_ID { | |||
72 | KEY_TYPE_ID_AES, | 72 | KEY_TYPE_ID_AES, |
73 | KEY_TYPE_ID_WAPI, | 73 | KEY_TYPE_ID_WAPI, |
74 | }; | 74 | }; |
75 | 75 | #define KEY_MCAST BIT(0) | |
76 | enum KEY_INFO_WEP { | 76 | #define KEY_UNICAST BIT(1) |
77 | KEY_INFO_WEP_MCAST = 0x01, | 77 | #define KEY_ENABLED BIT(2) |
78 | KEY_INFO_WEP_UNICAST = 0x02, | ||
79 | KEY_INFO_WEP_ENABLED = 0x04 | ||
80 | }; | ||
81 | |||
82 | enum KEY_INFO_TKIP { | ||
83 | KEY_INFO_TKIP_MCAST = 0x01, | ||
84 | KEY_INFO_TKIP_UNICAST = 0x02, | ||
85 | KEY_INFO_TKIP_ENABLED = 0x04 | ||
86 | }; | ||
87 | |||
88 | enum KEY_INFO_AES { | ||
89 | KEY_INFO_AES_MCAST = 0x01, | ||
90 | KEY_INFO_AES_UNICAST = 0x02, | ||
91 | KEY_INFO_AES_ENABLED = 0x04 | ||
92 | }; | ||
93 | 78 | ||
94 | #define WAPI_KEY_LEN 50 | 79 | #define WAPI_KEY_LEN 50 |
95 | 80 | ||
96 | enum KEY_INFO_WAPI { | ||
97 | KEY_INFO_WAPI_MCAST = 0x01, | ||
98 | KEY_INFO_WAPI_UNICAST = 0x02, | ||
99 | KEY_INFO_WAPI_ENABLED = 0x04 | ||
100 | }; | ||
101 | |||
102 | #define MAX_POLL_TRIES 100 | 81 | #define MAX_POLL_TRIES 100 |
103 | 82 | ||
104 | #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 | 83 | #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 |
@@ -155,7 +134,6 @@ enum MWIFIEX_802_11_WEP_STATUS { | |||
155 | 134 | ||
156 | #define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096 | 135 | #define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096 |
157 | #define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 | 136 | #define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 |
158 | #define NON_GREENFIELD_STAS 0x04 | ||
159 | 137 | ||
160 | #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) | 138 | #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) |
161 | 139 | ||
@@ -180,7 +158,6 @@ enum MWIFIEX_802_11_WEP_STATUS { | |||
180 | #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) | 158 | #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) |
181 | 159 | ||
182 | #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) | 160 | #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) |
183 | #define RESETHT_EXTCAP_RDG(HTExtCap) (HTExtCap &= ~BIT(11)) | ||
184 | #define SETHT_MCS32(x) (x[4] |= 1) | 161 | #define SETHT_MCS32(x) (x[4] |= 1) |
185 | 162 | ||
186 | #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) | 163 | #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 8189862da1f9..fc2c0c5728d9 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -35,7 +35,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
35 | { | 35 | { |
36 | struct mwifiex_adapter *adapter = priv->adapter; | 36 | struct mwifiex_adapter *adapter = priv->adapter; |
37 | struct mwifiex_bss_prio_node *bss_prio; | 37 | struct mwifiex_bss_prio_node *bss_prio; |
38 | int status = 0; | ||
39 | unsigned long flags; | 38 | unsigned long flags; |
40 | 39 | ||
41 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); | 40 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); |
@@ -59,7 +58,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
59 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] | 58 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] |
60 | .bss_prio_lock, flags); | 59 | .bss_prio_lock, flags); |
61 | 60 | ||
62 | return status; | 61 | return 0; |
63 | } | 62 | } |
64 | 63 | ||
65 | /* | 64 | /* |
@@ -72,7 +71,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
72 | static int mwifiex_init_priv(struct mwifiex_private *priv) | 71 | static int mwifiex_init_priv(struct mwifiex_private *priv) |
73 | { | 72 | { |
74 | u32 i; | 73 | u32 i; |
75 | int ret = 0; | ||
76 | 74 | ||
77 | priv->media_connected = false; | 75 | priv->media_connected = false; |
78 | memset(priv->curr_addr, 0xff, ETH_ALEN); | 76 | memset(priv->curr_addr, 0xff, ETH_ALEN); |
@@ -140,9 +138,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) | |||
140 | 138 | ||
141 | priv->scan_block = false; | 139 | priv->scan_block = false; |
142 | 140 | ||
143 | ret = mwifiex_add_bss_prio_tbl(priv); | 141 | return mwifiex_add_bss_prio_tbl(priv); |
144 | |||
145 | return ret; | ||
146 | } | 142 | } |
147 | 143 | ||
148 | /* | 144 | /* |
@@ -300,8 +296,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
300 | adapter->adhoc_awake_period = 0; | 296 | adapter->adhoc_awake_period = 0; |
301 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); | 297 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); |
302 | adapter->arp_filter_size = 0; | 298 | adapter->arp_filter_size = 0; |
303 | |||
304 | return; | ||
305 | } | 299 | } |
306 | 300 | ||
307 | /* | 301 | /* |
@@ -340,8 +334,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter) | |||
340 | adapter->if_ops.cleanup_if(adapter); | 334 | adapter->if_ops.cleanup_if(adapter); |
341 | 335 | ||
342 | dev_kfree_skb_any(adapter->sleep_cfm); | 336 | dev_kfree_skb_any(adapter->sleep_cfm); |
343 | |||
344 | return; | ||
345 | } | 337 | } |
346 | 338 | ||
347 | /* | 339 | /* |
@@ -429,8 +421,6 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) | |||
429 | list_del(&priv->rx_reorder_tbl_ptr); | 421 | list_del(&priv->rx_reorder_tbl_ptr); |
430 | } | 422 | } |
431 | } | 423 | } |
432 | |||
433 | return; | ||
434 | } | 424 | } |
435 | 425 | ||
436 | /* | 426 | /* |
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 703a6d12ebf3..5488e111fd2c 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
@@ -268,14 +268,13 @@ struct mwifiex_debug_info { | |||
268 | }; | 268 | }; |
269 | 269 | ||
270 | #define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 | 270 | #define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 |
271 | #define MWIFIEX_MAX_KEY_LENGTH 32 | ||
272 | #define WAPI_RXPN_LEN 16 | 271 | #define WAPI_RXPN_LEN 16 |
273 | 272 | ||
274 | struct mwifiex_ds_encrypt_key { | 273 | struct mwifiex_ds_encrypt_key { |
275 | u32 key_disable; | 274 | u32 key_disable; |
276 | u32 key_index; | 275 | u32 key_index; |
277 | u32 key_len; | 276 | u32 key_len; |
278 | u8 key_material[MWIFIEX_MAX_KEY_LENGTH]; | 277 | u8 key_material[WLAN_MAX_KEY_LEN]; |
279 | u8 mac_addr[ETH_ALEN]; | 278 | u8 mac_addr[ETH_ALEN]; |
280 | u32 is_wapi_key; | 279 | u32 is_wapi_key; |
281 | u8 wapi_rxpn[WAPI_RXPN_LEN]; | 280 | u8 wapi_rxpn[WAPI_RXPN_LEN]; |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 7a9e0b5962ed..23d2d0b9a527 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -590,11 +590,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
590 | * an association success (0) or failure (non-zero). | 590 | * an association success (0) or failure (non-zero). |
591 | */ | 591 | */ |
592 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | 592 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, |
593 | struct host_cmd_ds_command *resp, void *wq_buf) | 593 | struct host_cmd_ds_command *resp) |
594 | { | 594 | { |
595 | struct mwifiex_adapter *adapter = priv->adapter; | ||
595 | int ret = 0; | 596 | int ret = 0; |
596 | struct mwifiex_wait_queue *wait_queue = | ||
597 | (struct mwifiex_wait_queue *) wq_buf; | ||
598 | struct ieee_types_assoc_rsp *assoc_rsp; | 597 | struct ieee_types_assoc_rsp *assoc_rsp; |
599 | struct mwifiex_bssdescriptor *bss_desc; | 598 | struct mwifiex_bssdescriptor *bss_desc; |
600 | u8 enable_data = true; | 599 | u8 enable_data = true; |
@@ -718,16 +717,11 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
718 | 717 | ||
719 | done: | 718 | done: |
720 | /* Need to indicate IOCTL complete */ | 719 | /* Need to indicate IOCTL complete */ |
721 | if (wait_queue) { | 720 | if (adapter->curr_cmd->wait_q_enabled) { |
722 | if (ret) { | 721 | if (ret) |
723 | if (assoc_rsp->status_code) | 722 | adapter->cmd_wait_q.status = -1; |
724 | wait_queue->status = | 723 | else |
725 | le16_to_cpu(assoc_rsp->status_code); | 724 | adapter->cmd_wait_q.status = 0; |
726 | else | ||
727 | wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; | ||
728 | } else { | ||
729 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | ||
730 | } | ||
731 | } | 725 | } |
732 | 726 | ||
733 | return ret; | 727 | return ret; |
@@ -755,7 +749,7 @@ int | |||
755 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 749 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
756 | struct host_cmd_ds_command *cmd, void *data_buf) | 750 | struct host_cmd_ds_command *cmd, void *data_buf) |
757 | { | 751 | { |
758 | int ret = 0, rsn_ie_len = 0; | 752 | int rsn_ie_len = 0; |
759 | struct mwifiex_adapter *adapter = priv->adapter; | 753 | struct mwifiex_adapter *adapter = priv->adapter; |
760 | struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start = | 754 | struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start = |
761 | &cmd->params.adhoc_start; | 755 | &cmd->params.adhoc_start; |
@@ -885,11 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
885 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); | 879 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); |
886 | if ((adapter->adhoc_start_band & BAND_G) && | 880 | if ((adapter->adhoc_start_band & BAND_G) && |
887 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { | 881 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { |
888 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 882 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
889 | HostCmd_ACT_GEN_SET, | 883 | HostCmd_ACT_GEN_SET, 0, |
890 | 0, NULL, &priv->curr_pkt_filter); | 884 | &priv->curr_pkt_filter)) { |
891 | |||
892 | if (ret) { | ||
893 | dev_err(adapter->dev, | 885 | dev_err(adapter->dev, |
894 | "ADHOC_S_CMD: G Protection config failed\n"); | 886 | "ADHOC_S_CMD: G Protection config failed\n"); |
895 | return -1; | 887 | return -1; |
@@ -1003,7 +995,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
1003 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | 995 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; |
1004 | } | 996 | } |
1005 | ht_info->ht_info.operation_mode = | 997 | ht_info->ht_info.operation_mode = |
1006 | cpu_to_le16(NON_GREENFIELD_STAS); | 998 | cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); |
1007 | ht_info->ht_info.basic_set[0] = 0xff; | 999 | ht_info->ht_info.basic_set[0] = 0xff; |
1008 | pos += sizeof(struct mwifiex_ie_types_htinfo); | 1000 | pos += sizeof(struct mwifiex_ie_types_htinfo); |
1009 | cmd_append_size += | 1001 | cmd_append_size += |
@@ -1045,7 +1037,7 @@ int | |||
1045 | mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | 1037 | mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, |
1046 | struct host_cmd_ds_command *cmd, void *data_buf) | 1038 | struct host_cmd_ds_command *cmd, void *data_buf) |
1047 | { | 1039 | { |
1048 | int ret = 0, rsn_ie_len = 0; | 1040 | int rsn_ie_len = 0; |
1049 | struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = | 1041 | struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = |
1050 | &cmd->params.adhoc_join; | 1042 | &cmd->params.adhoc_join; |
1051 | struct mwifiex_bssdescriptor *bss_desc = | 1043 | struct mwifiex_bssdescriptor *bss_desc = |
@@ -1066,10 +1058,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1066 | priv-> | 1058 | priv-> |
1067 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; | 1059 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; |
1068 | 1060 | ||
1069 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1061 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
1070 | HostCmd_ACT_GEN_SET, 0, NULL, | 1062 | HostCmd_ACT_GEN_SET, 0, |
1071 | &curr_pkt_filter); | 1063 | &curr_pkt_filter)) { |
1072 | if (ret) { | ||
1073 | dev_err(priv->adapter->dev, | 1064 | dev_err(priv->adapter->dev, |
1074 | "ADHOC_J_CMD: G Protection config failed\n"); | 1065 | "ADHOC_J_CMD: G Protection config failed\n"); |
1075 | return -1; | 1066 | return -1; |
@@ -1180,7 +1171,7 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1180 | 1171 | ||
1181 | adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); | 1172 | adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); |
1182 | 1173 | ||
1183 | return ret; | 1174 | return 0; |
1184 | } | 1175 | } |
1185 | 1176 | ||
1186 | /* | 1177 | /* |
@@ -1192,22 +1183,19 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1192 | * saves the beacon buffer. | 1183 | * saves the beacon buffer. |
1193 | */ | 1184 | */ |
1194 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 1185 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
1195 | struct host_cmd_ds_command *resp, void *wq_buf) | 1186 | struct host_cmd_ds_command *resp) |
1196 | { | 1187 | { |
1197 | int ret = 0; | 1188 | int ret = 0; |
1198 | struct mwifiex_wait_queue *wait_queue = | 1189 | struct mwifiex_adapter *adapter = priv->adapter; |
1199 | (struct mwifiex_wait_queue *) wq_buf; | ||
1200 | struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; | 1190 | struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; |
1201 | struct mwifiex_bssdescriptor *bss_desc; | 1191 | struct mwifiex_bssdescriptor *bss_desc; |
1202 | u16 command = le16_to_cpu(resp->command); | ||
1203 | u16 result = le16_to_cpu(resp->result); | ||
1204 | 1192 | ||
1205 | adhoc_result = &resp->params.adhoc_result; | 1193 | adhoc_result = &resp->params.adhoc_result; |
1206 | 1194 | ||
1207 | bss_desc = priv->attempted_bss_desc; | 1195 | bss_desc = priv->attempted_bss_desc; |
1208 | 1196 | ||
1209 | /* Join result code 0 --> SUCCESS */ | 1197 | /* Join result code 0 --> SUCCESS */ |
1210 | if (result) { | 1198 | if (le16_to_cpu(resp->result)) { |
1211 | dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n"); | 1199 | dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n"); |
1212 | if (priv->media_connected) | 1200 | if (priv->media_connected) |
1213 | mwifiex_reset_connect_state(priv); | 1201 | mwifiex_reset_connect_state(priv); |
@@ -1222,7 +1210,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1222 | /* Send a Media Connected event, according to the Spec */ | 1210 | /* Send a Media Connected event, according to the Spec */ |
1223 | priv->media_connected = true; | 1211 | priv->media_connected = true; |
1224 | 1212 | ||
1225 | if (command == HostCmd_CMD_802_11_AD_HOC_START) { | 1213 | if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { |
1226 | dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", | 1214 | dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", |
1227 | bss_desc->ssid.ssid); | 1215 | bss_desc->ssid.ssid); |
1228 | 1216 | ||
@@ -1264,11 +1252,11 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1264 | 1252 | ||
1265 | done: | 1253 | done: |
1266 | /* Need to indicate IOCTL complete */ | 1254 | /* Need to indicate IOCTL complete */ |
1267 | if (wait_queue) { | 1255 | if (adapter->curr_cmd->wait_q_enabled) { |
1268 | if (ret) | 1256 | if (ret) |
1269 | wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; | 1257 | adapter->cmd_wait_q.status = -1; |
1270 | else | 1258 | else |
1271 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 1259 | adapter->cmd_wait_q.status = 0; |
1272 | 1260 | ||
1273 | } | 1261 | } |
1274 | 1262 | ||
@@ -1283,9 +1271,8 @@ done: | |||
1283 | * command to firmware. | 1271 | * command to firmware. |
1284 | */ | 1272 | */ |
1285 | int mwifiex_associate(struct mwifiex_private *priv, | 1273 | int mwifiex_associate(struct mwifiex_private *priv, |
1286 | void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) | 1274 | struct mwifiex_bssdescriptor *bss_desc) |
1287 | { | 1275 | { |
1288 | int ret = 0; | ||
1289 | u8 current_bssid[ETH_ALEN]; | 1276 | u8 current_bssid[ETH_ALEN]; |
1290 | 1277 | ||
1291 | /* Return error if the adapter or table entry is not marked as infra */ | 1278 | /* Return error if the adapter or table entry is not marked as infra */ |
@@ -1301,11 +1288,8 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1301 | retrieval */ | 1288 | retrieval */ |
1302 | priv->assoc_rsp_size = 0; | 1289 | priv->assoc_rsp_size = 0; |
1303 | 1290 | ||
1304 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, | 1291 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, |
1305 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1292 | HostCmd_ACT_GEN_SET, 0, bss_desc); |
1306 | bss_desc); | ||
1307 | |||
1308 | return ret; | ||
1309 | } | 1293 | } |
1310 | 1294 | ||
1311 | /* | 1295 | /* |
@@ -1315,10 +1299,8 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1315 | */ | 1299 | */ |
1316 | int | 1300 | int |
1317 | mwifiex_adhoc_start(struct mwifiex_private *priv, | 1301 | mwifiex_adhoc_start(struct mwifiex_private *priv, |
1318 | void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) | 1302 | struct mwifiex_802_11_ssid *adhoc_ssid) |
1319 | { | 1303 | { |
1320 | int ret = 0; | ||
1321 | |||
1322 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", | 1304 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", |
1323 | priv->adhoc_channel); | 1305 | priv->adhoc_channel); |
1324 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", | 1306 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", |
@@ -1326,11 +1308,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, | |||
1326 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", | 1308 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", |
1327 | priv->curr_bss_params.band); | 1309 | priv->curr_bss_params.band); |
1328 | 1310 | ||
1329 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, | 1311 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, |
1330 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1312 | HostCmd_ACT_GEN_SET, 0, adhoc_ssid); |
1331 | adhoc_ssid); | ||
1332 | |||
1333 | return ret; | ||
1334 | } | 1313 | } |
1335 | 1314 | ||
1336 | /* | 1315 | /* |
@@ -1340,10 +1319,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, | |||
1340 | * if already not connected to the requested SSID. | 1319 | * if already not connected to the requested SSID. |
1341 | */ | 1320 | */ |
1342 | int mwifiex_adhoc_join(struct mwifiex_private *priv, | 1321 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
1343 | void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) | 1322 | struct mwifiex_bssdescriptor *bss_desc) |
1344 | { | 1323 | { |
1345 | int ret = 0; | ||
1346 | |||
1347 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", | 1324 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", |
1348 | priv->curr_bss_params.bss_descriptor.ssid.ssid); | 1325 | priv->curr_bss_params.bss_descriptor.ssid.ssid); |
1349 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", | 1326 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", |
@@ -1369,20 +1346,15 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
1369 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", | 1346 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", |
1370 | priv->curr_bss_params.band); | 1347 | priv->curr_bss_params.band); |
1371 | 1348 | ||
1372 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, | 1349 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, |
1373 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1350 | HostCmd_ACT_GEN_SET, 0, bss_desc); |
1374 | bss_desc); | ||
1375 | |||
1376 | return ret; | ||
1377 | } | 1351 | } |
1378 | 1352 | ||
1379 | /* | 1353 | /* |
1380 | * This function deauthenticates/disconnects from infra network by sending | 1354 | * This function deauthenticates/disconnects from infra network by sending |
1381 | * deauthentication request. | 1355 | * deauthentication request. |
1382 | */ | 1356 | */ |
1383 | static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | 1357 | static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) |
1384 | struct mwifiex_wait_queue *wait, | ||
1385 | u8 *mac) | ||
1386 | { | 1358 | { |
1387 | u8 mac_address[ETH_ALEN]; | 1359 | u8 mac_address[ETH_ALEN]; |
1388 | int ret = 0; | 1360 | int ret = 0; |
@@ -1400,11 +1372,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | |||
1400 | bss_descriptor.mac_address, ETH_ALEN); | 1372 | bss_descriptor.mac_address, ETH_ALEN); |
1401 | } | 1373 | } |
1402 | 1374 | ||
1403 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, | 1375 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, |
1404 | HostCmd_ACT_GEN_SET, 0, wait, &mac_address); | 1376 | HostCmd_ACT_GEN_SET, 0, &mac_address); |
1405 | |||
1406 | if (!ret && wait) | ||
1407 | ret = -EINPROGRESS; | ||
1408 | 1377 | ||
1409 | return ret; | 1378 | return ret; |
1410 | } | 1379 | } |
@@ -1415,26 +1384,23 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | |||
1415 | * In case of infra made, it sends deauthentication request, and | 1384 | * In case of infra made, it sends deauthentication request, and |
1416 | * in case of ad-hoc mode, a stop network request is sent to the firmware. | 1385 | * in case of ad-hoc mode, a stop network request is sent to the firmware. |
1417 | */ | 1386 | */ |
1418 | int mwifiex_deauthenticate(struct mwifiex_private *priv, | 1387 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) |
1419 | struct mwifiex_wait_queue *wait, u8 *mac) | ||
1420 | { | 1388 | { |
1421 | int ret = 0; | 1389 | int ret = 0; |
1422 | 1390 | ||
1423 | if (priv->media_connected) { | 1391 | if (priv->media_connected) { |
1424 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 1392 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
1425 | ret = mwifiex_deauthenticate_infra(priv, wait, mac); | 1393 | ret = mwifiex_deauthenticate_infra(priv, mac); |
1426 | } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | 1394 | } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { |
1427 | ret = mwifiex_prepare_cmd(priv, | 1395 | ret = mwifiex_send_cmd_sync(priv, |
1428 | HostCmd_CMD_802_11_AD_HOC_STOP, | 1396 | HostCmd_CMD_802_11_AD_HOC_STOP, |
1429 | HostCmd_ACT_GEN_SET, 0, wait, NULL); | 1397 | HostCmd_ACT_GEN_SET, 0, NULL); |
1430 | |||
1431 | if (!ret && wait) | ||
1432 | ret = -EINPROGRESS; | ||
1433 | } | 1398 | } |
1434 | } | 1399 | } |
1435 | 1400 | ||
1436 | return ret; | 1401 | return ret; |
1437 | } | 1402 | } |
1403 | EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); | ||
1438 | 1404 | ||
1439 | /* | 1405 | /* |
1440 | * This function converts band to radio type used in channel TLV. | 1406 | * This function converts band to radio type used in channel TLV. |
@@ -1442,21 +1408,15 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, | |||
1442 | u8 | 1408 | u8 |
1443 | mwifiex_band_to_radio_type(u8 band) | 1409 | mwifiex_band_to_radio_type(u8 band) |
1444 | { | 1410 | { |
1445 | u8 ret_radio_type; | ||
1446 | |||
1447 | switch (band) { | 1411 | switch (band) { |
1448 | case BAND_A: | 1412 | case BAND_A: |
1449 | case BAND_AN: | 1413 | case BAND_AN: |
1450 | case BAND_A | BAND_AN: | 1414 | case BAND_A | BAND_AN: |
1451 | ret_radio_type = HostCmd_SCAN_RADIO_TYPE_A; | 1415 | return HostCmd_SCAN_RADIO_TYPE_A; |
1452 | break; | ||
1453 | case BAND_B: | 1416 | case BAND_B: |
1454 | case BAND_G: | 1417 | case BAND_G: |
1455 | case BAND_B | BAND_G: | 1418 | case BAND_B | BAND_G: |
1456 | default: | 1419 | default: |
1457 | ret_radio_type = HostCmd_SCAN_RADIO_TYPE_BG; | 1420 | return HostCmd_SCAN_RADIO_TYPE_BG; |
1458 | break; | ||
1459 | } | 1421 | } |
1460 | |||
1461 | return ret_radio_type; | ||
1462 | } | 1422 | } |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index ed89ca41a902..c5971880e7b3 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -40,14 +40,10 @@ static char fw_name[32] = DEFAULT_FW_NAME; | |||
40 | /* Supported drv_mode table */ | 40 | /* Supported drv_mode table */ |
41 | static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { | 41 | static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { |
42 | { | 42 | { |
43 | /* drv_mode */ | 43 | .drv_mode = DRV_MODE_STA, |
44 | .drv_mode = DRV_MODE_STA, | 44 | .intf_num = ARRAY_SIZE(mwifiex_bss_sta), |
45 | /* intf number */ | 45 | .bss_attr = mwifiex_bss_sta, |
46 | .intf_num = ARRAY_SIZE(mwifiex_bss_sta), | 46 | }, |
47 | /* bss_attr */ | ||
48 | .bss_attr = mwifiex_bss_sta, | ||
49 | } | ||
50 | , | ||
51 | }; | 47 | }; |
52 | 48 | ||
53 | /* | 49 | /* |
@@ -66,14 +62,12 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { | |||
66 | * proper cleanup before exiting. | 62 | * proper cleanup before exiting. |
67 | */ | 63 | */ |
68 | static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | 64 | static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, |
69 | struct mwifiex_device *mdevice, void **padapter) | 65 | struct mwifiex_drv_mode *drv_mode_ptr) |
70 | { | 66 | { |
71 | int ret = 0; | 67 | struct mwifiex_adapter *adapter; |
72 | struct mwifiex_adapter *adapter = NULL; | 68 | int i; |
73 | u8 i = 0; | ||
74 | 69 | ||
75 | adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); | 70 | adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); |
76 | /* Allocate memory for adapter structure */ | ||
77 | if (!adapter) | 71 | if (!adapter) |
78 | return -1; | 72 | return -1; |
79 | 73 | ||
@@ -84,19 +78,17 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
84 | memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops)); | 78 | memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops)); |
85 | 79 | ||
86 | /* card specific initialization has been deferred until now .. */ | 80 | /* card specific initialization has been deferred until now .. */ |
87 | ret = adapter->if_ops.init_if(adapter); | 81 | if (adapter->if_ops.init_if(adapter)) |
88 | if (ret) | ||
89 | goto error; | 82 | goto error; |
90 | 83 | ||
91 | adapter->priv_num = 0; | 84 | adapter->priv_num = 0; |
92 | for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) { | 85 | for (i = 0; i < drv_mode_ptr->intf_num; i++) { |
93 | adapter->priv[i] = NULL; | 86 | adapter->priv[i] = NULL; |
94 | 87 | ||
95 | if (!mdevice->bss_attr[i].active) | 88 | if (!drv_mode_ptr->bss_attr[i].active) |
96 | continue; | 89 | continue; |
97 | 90 | ||
98 | /* For valid bss_attr, | 91 | /* Allocate memory for private structure */ |
99 | allocate memory for private structure */ | ||
100 | adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private), | 92 | adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private), |
101 | GFP_KERNEL); | 93 | GFP_KERNEL); |
102 | if (!adapter->priv[i]) { | 94 | if (!adapter->priv[i]) { |
@@ -106,26 +98,26 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
106 | } | 98 | } |
107 | 99 | ||
108 | adapter->priv_num++; | 100 | adapter->priv_num++; |
109 | memset(adapter->priv[i], 0, | ||
110 | sizeof(struct mwifiex_private)); | ||
111 | adapter->priv[i]->adapter = adapter; | 101 | adapter->priv[i]->adapter = adapter; |
112 | /* Save bss_type, frame_type & bss_priority */ | 102 | /* Save bss_type, frame_type & bss_priority */ |
113 | adapter->priv[i]->bss_type = (u8) mdevice->bss_attr[i].bss_type; | 103 | adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type; |
114 | adapter->priv[i]->frame_type = | 104 | adapter->priv[i]->frame_type = |
115 | (u8) mdevice->bss_attr[i].frame_type; | 105 | drv_mode_ptr->bss_attr[i].frame_type; |
116 | adapter->priv[i]->bss_priority = | 106 | adapter->priv[i]->bss_priority = |
117 | (u8) mdevice->bss_attr[i].bss_priority; | 107 | drv_mode_ptr->bss_attr[i].bss_priority; |
118 | if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA) | 108 | |
109 | if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA) | ||
119 | adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA; | 110 | adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA; |
120 | else if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_UAP) | 111 | else if (drv_mode_ptr->bss_attr[i].bss_type == |
112 | MWIFIEX_BSS_TYPE_UAP) | ||
121 | adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP; | 113 | adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP; |
122 | 114 | ||
123 | /* Save bss_index & bss_num */ | 115 | /* Save bss_index & bss_num */ |
124 | adapter->priv[i]->bss_index = i; | 116 | adapter->priv[i]->bss_index = i; |
125 | adapter->priv[i]->bss_num = mdevice->bss_attr[i].bss_num; | 117 | adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num; |
126 | } | 118 | } |
119 | adapter->drv_mode = drv_mode_ptr; | ||
127 | 120 | ||
128 | /* Initialize lock variables */ | ||
129 | if (mwifiex_init_lock_list(adapter)) | 121 | if (mwifiex_init_lock_list(adapter)) |
130 | goto error; | 122 | goto error; |
131 | 123 | ||
@@ -133,16 +125,13 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
133 | adapter->cmd_timer.function = mwifiex_cmd_timeout_func; | 125 | adapter->cmd_timer.function = mwifiex_cmd_timeout_func; |
134 | adapter->cmd_timer.data = (unsigned long) adapter; | 126 | adapter->cmd_timer.data = (unsigned long) adapter; |
135 | 127 | ||
136 | /* Return pointer of struct mwifiex_adapter */ | ||
137 | *padapter = adapter; | ||
138 | return 0; | 128 | return 0; |
139 | 129 | ||
140 | error: | 130 | error: |
141 | dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); | 131 | dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); |
142 | 132 | ||
143 | /* Free lock variables */ | ||
144 | mwifiex_free_lock_list(adapter); | 133 | mwifiex_free_lock_list(adapter); |
145 | for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) | 134 | for (i = 0; i < drv_mode_ptr->intf_num; i++) |
146 | kfree(adapter->priv[i]); | 135 | kfree(adapter->priv[i]); |
147 | kfree(adapter); | 136 | kfree(adapter); |
148 | 137 | ||
@@ -337,10 +326,9 @@ exit_main_proc: | |||
337 | * and initializing the private structures. | 326 | * and initializing the private structures. |
338 | */ | 327 | */ |
339 | static int | 328 | static int |
340 | mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex) | 329 | mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) |
341 | { | 330 | { |
342 | int i; | 331 | int i; |
343 | struct mwifiex_device device; | ||
344 | struct mwifiex_drv_mode *drv_mode_ptr; | 332 | struct mwifiex_drv_mode *drv_mode_ptr; |
345 | 333 | ||
346 | /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */ | 334 | /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */ |
@@ -357,20 +345,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex) | |||
357 | return -1; | 345 | return -1; |
358 | } | 346 | } |
359 | 347 | ||
360 | memset(&device, 0, sizeof(struct mwifiex_device)); | 348 | if (mwifiex_register(card, if_ops, drv_mode_ptr)) |
361 | |||
362 | for (i = 0; i < drv_mode_ptr->intf_num; i++) { | ||
363 | device.bss_attr[i].bss_type = | ||
364 | drv_mode_ptr->bss_attr[i].bss_type; | ||
365 | device.bss_attr[i].frame_type = | ||
366 | drv_mode_ptr->bss_attr[i].frame_type; | ||
367 | device.bss_attr[i].active = drv_mode_ptr->bss_attr[i].active; | ||
368 | device.bss_attr[i].bss_priority = | ||
369 | drv_mode_ptr->bss_attr[i].bss_priority; | ||
370 | device.bss_attr[i].bss_num = drv_mode_ptr->bss_attr[i].bss_num; | ||
371 | } | ||
372 | |||
373 | if (mwifiex_register(card, if_ops, &device, pmwifiex)) | ||
374 | return -1; | 349 | return -1; |
375 | 350 | ||
376 | return 0; | 351 | return 0; |
@@ -505,7 +480,6 @@ mwifiex_fill_buffer(struct sk_buff *skb) | |||
505 | */ | 480 | */ |
506 | do_gettimeofday(&tv); | 481 | do_gettimeofday(&tv); |
507 | skb->tstamp = timeval_to_ktime(tv); | 482 | skb->tstamp = timeval_to_ktime(tv); |
508 | return; | ||
509 | } | 483 | } |
510 | 484 | ||
511 | /* | 485 | /* |
@@ -597,16 +571,23 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) | |||
597 | { | 571 | { |
598 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 572 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
599 | struct sockaddr *hw_addr = (struct sockaddr *) addr; | 573 | struct sockaddr *hw_addr = (struct sockaddr *) addr; |
574 | int ret = 0; | ||
600 | 575 | ||
601 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); | 576 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); |
602 | 577 | ||
603 | if (mwifiex_request_set_mac_address(priv)) { | 578 | /* Send request to firmware */ |
604 | dev_err(priv->adapter->dev, "set MAC address failed\n"); | 579 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, |
605 | return -EFAULT; | 580 | HostCmd_ACT_GEN_SET, 0, NULL); |
606 | } | 581 | |
582 | if (!ret) | ||
583 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); | ||
584 | else | ||
585 | dev_err(priv->adapter->dev, "set mac address failed: ret=%d" | ||
586 | "\n", ret); | ||
587 | |||
607 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); | 588 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); |
608 | 589 | ||
609 | return 0; | 590 | return ret; |
610 | } | 591 | } |
611 | 592 | ||
612 | /* | 593 | /* |
@@ -615,7 +596,20 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) | |||
615 | static void mwifiex_set_multicast_list(struct net_device *dev) | 596 | static void mwifiex_set_multicast_list(struct net_device *dev) |
616 | { | 597 | { |
617 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 598 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
618 | mwifiex_request_set_multicast_list(priv, dev); | 599 | struct mwifiex_multicast_list mcast_list; |
600 | |||
601 | if (dev->flags & IFF_PROMISC) { | ||
602 | mcast_list.mode = MWIFIEX_PROMISC_MODE; | ||
603 | } else if (dev->flags & IFF_ALLMULTI || | ||
604 | netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { | ||
605 | mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; | ||
606 | } else { | ||
607 | mcast_list.mode = MWIFIEX_MULTICAST_MODE; | ||
608 | if (netdev_mc_count(dev)) | ||
609 | mcast_list.num_multicast_addr = | ||
610 | mwifiex_copy_mcast_addr(&mcast_list, dev); | ||
611 | } | ||
612 | mwifiex_request_set_multicast_list(priv, &mcast_list); | ||
619 | } | 613 | } |
620 | 614 | ||
621 | /* | 615 | /* |
@@ -677,9 +671,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) | |||
677 | { | 671 | { |
678 | dev->netdev_ops = &mwifiex_netdev_ops; | 672 | dev->netdev_ops = &mwifiex_netdev_ops; |
679 | /* Initialize private structure */ | 673 | /* Initialize private structure */ |
680 | init_waitqueue_head(&priv->ioctl_wait_q); | ||
681 | init_waitqueue_head(&priv->cmd_wait_q); | ||
682 | init_waitqueue_head(&priv->w_stats_wait_q); | ||
683 | priv->current_key_index = 0; | 674 | priv->current_key_index = 0; |
684 | priv->media_connected = false; | 675 | priv->media_connected = false; |
685 | memset(&priv->nick_name, 0, sizeof(priv->nick_name)); | 676 | memset(&priv->nick_name, 0, sizeof(priv->nick_name)); |
@@ -803,37 +794,9 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) | |||
803 | wiphy_unregister(priv->wdev->wiphy); | 794 | wiphy_unregister(priv->wdev->wiphy); |
804 | wiphy_free(priv->wdev->wiphy); | 795 | wiphy_free(priv->wdev->wiphy); |
805 | kfree(priv->wdev); | 796 | kfree(priv->wdev); |
806 | |||
807 | return; | ||
808 | } | 797 | } |
809 | 798 | ||
810 | /* | 799 | /* |
811 | * Sends IOCTL request to shutdown firmware. | ||
812 | * | ||
813 | * This function allocates the IOCTL request buffer, fills it | ||
814 | * with requisite parameters and calls the IOCTL handler. | ||
815 | */ | ||
816 | int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option) | ||
817 | { | ||
818 | struct mwifiex_wait_queue *wait = NULL; | ||
819 | int status = 0; | ||
820 | |||
821 | /* Allocate an IOCTL request buffer */ | ||
822 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
823 | if (!wait) | ||
824 | return -ENOMEM; | ||
825 | |||
826 | status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait, | ||
827 | MWIFIEX_FUNC_SHUTDOWN); | ||
828 | |||
829 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
830 | |||
831 | kfree(wait); | ||
832 | return status; | ||
833 | } | ||
834 | EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw); | ||
835 | |||
836 | /* | ||
837 | * This function check if command is pending. | 800 | * This function check if command is pending. |
838 | */ | 801 | */ |
839 | int is_command_pending(struct mwifiex_adapter *adapter) | 802 | int is_command_pending(struct mwifiex_adapter *adapter) |
@@ -905,30 +868,30 @@ int | |||
905 | mwifiex_add_card(void *card, struct semaphore *sem, | 868 | mwifiex_add_card(void *card, struct semaphore *sem, |
906 | struct mwifiex_if_ops *if_ops) | 869 | struct mwifiex_if_ops *if_ops) |
907 | { | 870 | { |
908 | int status = 0; | ||
909 | int i; | 871 | int i; |
910 | struct mwifiex_adapter *adapter = NULL; | 872 | struct mwifiex_adapter *adapter; |
911 | struct mwifiex_drv_mode *drv_mode_info = &mwifiex_drv_mode_tbl[0]; | ||
912 | 873 | ||
913 | if (down_interruptible(sem)) | 874 | if (down_interruptible(sem)) |
914 | goto exit_sem_err; | 875 | goto exit_sem_err; |
915 | 876 | ||
916 | if (mwifiex_init_sw(card, if_ops, (void **) &adapter)) { | 877 | if (mwifiex_init_sw(card, if_ops)) { |
917 | pr_err("%s: software init failed\n", __func__); | 878 | pr_err("%s: software init failed\n", __func__); |
918 | goto err_init_sw; | 879 | goto err_init_sw; |
919 | } | 880 | } |
920 | 881 | ||
921 | adapter->drv_mode = drv_mode_info; | 882 | adapter = g_adapter; |
922 | 883 | ||
923 | adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; | 884 | adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; |
924 | /* PnP and power profile */ | ||
925 | adapter->surprise_removed = false; | 885 | adapter->surprise_removed = false; |
926 | init_waitqueue_head(&adapter->init_wait_q); | 886 | init_waitqueue_head(&adapter->init_wait_q); |
927 | adapter->is_suspended = false; | 887 | adapter->is_suspended = false; |
928 | adapter->hs_activated = false; | 888 | adapter->hs_activated = false; |
929 | init_waitqueue_head(&adapter->hs_activate_wait_q); | 889 | init_waitqueue_head(&adapter->hs_activate_wait_q); |
890 | adapter->cmd_wait_q_required = false; | ||
891 | init_waitqueue_head(&adapter->cmd_wait_q.wait); | ||
892 | adapter->cmd_wait_q.condition = false; | ||
893 | adapter->cmd_wait_q.status = 0; | ||
930 | 894 | ||
931 | /* Create workqueue */ | ||
932 | adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); | 895 | adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); |
933 | if (!adapter->workqueue) | 896 | if (!adapter->workqueue) |
934 | goto err_kmalloc; | 897 | goto err_kmalloc; |
@@ -942,21 +905,18 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
942 | goto err_registerdev; | 905 | goto err_registerdev; |
943 | } | 906 | } |
944 | 907 | ||
945 | /* Init FW and HW */ | ||
946 | if (mwifiex_init_hw_fw(adapter)) { | 908 | if (mwifiex_init_hw_fw(adapter)) { |
947 | pr_err("%s: firmware init failed\n", __func__); | 909 | pr_err("%s: firmware init failed\n", __func__); |
948 | goto err_init_fw; | 910 | goto err_init_fw; |
949 | } | 911 | } |
912 | |||
950 | /* Add interfaces */ | 913 | /* Add interfaces */ |
951 | for (i = 0; i < drv_mode_info->intf_num; i++) { | 914 | for (i = 0; i < adapter->drv_mode->intf_num; i++) { |
952 | if (!mwifiex_add_interface(adapter, i, | 915 | if (!mwifiex_add_interface(adapter, i, |
953 | adapter->drv_mode->bss_attr[i].bss_type)) { | 916 | adapter->drv_mode->bss_attr[i].bss_type)) { |
954 | status = -1; | 917 | goto err_add_intf; |
955 | break; | ||
956 | } | 918 | } |
957 | } | 919 | } |
958 | if (status) | ||
959 | goto err_add_intf; | ||
960 | 920 | ||
961 | up(sem); | 921 | up(sem); |
962 | 922 | ||
@@ -966,7 +926,6 @@ err_add_intf: | |||
966 | for (i = 0; i < adapter->priv_num; i++) | 926 | for (i = 0; i < adapter->priv_num; i++) |
967 | mwifiex_remove_interface(adapter, i); | 927 | mwifiex_remove_interface(adapter, i); |
968 | err_init_fw: | 928 | err_init_fw: |
969 | /* Unregister device */ | ||
970 | pr_debug("info: %s: unregister device\n", __func__); | 929 | pr_debug("info: %s: unregister device\n", __func__); |
971 | adapter->if_ops.unregister_dev(adapter); | 930 | adapter->if_ops.unregister_dev(adapter); |
972 | err_registerdev: | 931 | err_registerdev: |
@@ -977,8 +936,8 @@ err_kmalloc: | |||
977 | (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) { | 936 | (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) { |
978 | pr_debug("info: %s: shutdown mwifiex\n", __func__); | 937 | pr_debug("info: %s: shutdown mwifiex\n", __func__); |
979 | adapter->init_wait_q_woken = false; | 938 | adapter->init_wait_q_woken = false; |
980 | status = mwifiex_shutdown_drv(adapter); | 939 | |
981 | if (status == -EINPROGRESS) | 940 | if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) |
982 | wait_event_interruptible(adapter->init_wait_q, | 941 | wait_event_interruptible(adapter->init_wait_q, |
983 | adapter->init_wait_q_woken); | 942 | adapter->init_wait_q_woken); |
984 | } | 943 | } |
@@ -1007,7 +966,6 @@ EXPORT_SYMBOL_GPL(mwifiex_add_card); | |||
1007 | int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | 966 | int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) |
1008 | { | 967 | { |
1009 | struct mwifiex_private *priv = NULL; | 968 | struct mwifiex_private *priv = NULL; |
1010 | int status; | ||
1011 | int i; | 969 | int i; |
1012 | 970 | ||
1013 | if (down_interruptible(sem)) | 971 | if (down_interruptible(sem)) |
@@ -1031,19 +989,19 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
1031 | 989 | ||
1032 | dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n"); | 990 | dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n"); |
1033 | adapter->init_wait_q_woken = false; | 991 | adapter->init_wait_q_woken = false; |
1034 | status = mwifiex_shutdown_drv(adapter); | 992 | |
1035 | if (status == -EINPROGRESS) | 993 | if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) |
1036 | wait_event_interruptible(adapter->init_wait_q, | 994 | wait_event_interruptible(adapter->init_wait_q, |
1037 | adapter->init_wait_q_woken); | 995 | adapter->init_wait_q_woken); |
1038 | dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); | 996 | dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); |
1039 | if (atomic_read(&adapter->rx_pending) || | 997 | if (atomic_read(&adapter->rx_pending) || |
1040 | atomic_read(&adapter->tx_pending) || | 998 | atomic_read(&adapter->tx_pending) || |
1041 | atomic_read(&adapter->ioctl_pending)) { | 999 | atomic_read(&adapter->cmd_pending)) { |
1042 | dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " | 1000 | dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " |
1043 | "ioctl_pending=%d\n", | 1001 | "cmd_pending=%d\n", |
1044 | atomic_read(&adapter->rx_pending), | 1002 | atomic_read(&adapter->rx_pending), |
1045 | atomic_read(&adapter->tx_pending), | 1003 | atomic_read(&adapter->tx_pending), |
1046 | atomic_read(&adapter->ioctl_pending)); | 1004 | atomic_read(&adapter->cmd_pending)); |
1047 | } | 1005 | } |
1048 | 1006 | ||
1049 | /* Remove interface */ | 1007 | /* Remove interface */ |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 43ff149de9db..1b503038270e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -42,11 +42,8 @@ extern const char driver_version[]; | |||
42 | extern struct mwifiex_adapter *g_adapter; | 42 | extern struct mwifiex_adapter *g_adapter; |
43 | 43 | ||
44 | enum { | 44 | enum { |
45 | MWIFIEX_NO_WAIT, | 45 | MWIFIEX_ASYNC_CMD, |
46 | MWIFIEX_IOCTL_WAIT, | 46 | MWIFIEX_SYNC_CMD |
47 | MWIFIEX_CMD_WAIT, | ||
48 | MWIFIEX_PROC_WAIT, | ||
49 | MWIFIEX_WSTATS_WAIT | ||
50 | }; | 47 | }; |
51 | 48 | ||
52 | #define DRV_MODE_STA 0x1 | 49 | #define DRV_MODE_STA 0x1 |
@@ -468,10 +465,6 @@ struct mwifiex_private { | |||
468 | u32 curr_bcn_size; | 465 | u32 curr_bcn_size; |
469 | /* spin lock for beacon buffer */ | 466 | /* spin lock for beacon buffer */ |
470 | spinlock_t curr_bcn_buf_lock; | 467 | spinlock_t curr_bcn_buf_lock; |
471 | u16 ioctl_wait_q_woken; | ||
472 | wait_queue_head_t ioctl_wait_q; | ||
473 | u16 cmd_wait_q_woken; | ||
474 | wait_queue_head_t cmd_wait_q; | ||
475 | struct wireless_dev *wdev; | 468 | struct wireless_dev *wdev; |
476 | struct mwifiex_chan_freq_power cfp; | 469 | struct mwifiex_chan_freq_power cfp; |
477 | char version_str[128]; | 470 | char version_str[128]; |
@@ -480,8 +473,6 @@ struct mwifiex_private { | |||
480 | #endif | 473 | #endif |
481 | u8 nick_name[16]; | 474 | u8 nick_name[16]; |
482 | struct iw_statistics w_stats; | 475 | struct iw_statistics w_stats; |
483 | u16 w_stats_wait_q_woken; | ||
484 | wait_queue_head_t w_stats_wait_q; | ||
485 | u16 current_key_index; | 476 | u16 current_key_index; |
486 | struct semaphore async_sem; | 477 | struct semaphore async_sem; |
487 | u8 scan_pending_on_block; | 478 | u8 scan_pending_on_block; |
@@ -552,7 +543,7 @@ struct cmd_ctrl_node { | |||
552 | struct sk_buff *cmd_skb; | 543 | struct sk_buff *cmd_skb; |
553 | struct sk_buff *resp_skb; | 544 | struct sk_buff *resp_skb; |
554 | void *data_buf; | 545 | void *data_buf; |
555 | void *wq_buf; | 546 | u32 wait_q_enabled; |
556 | struct sk_buff *skb; | 547 | struct sk_buff *skb; |
557 | }; | 548 | }; |
558 | 549 | ||
@@ -590,7 +581,7 @@ struct mwifiex_adapter { | |||
590 | struct mwifiex_if_ops if_ops; | 581 | struct mwifiex_if_ops if_ops; |
591 | atomic_t rx_pending; | 582 | atomic_t rx_pending; |
592 | atomic_t tx_pending; | 583 | atomic_t tx_pending; |
593 | atomic_t ioctl_pending; | 584 | atomic_t cmd_pending; |
594 | struct workqueue_struct *workqueue; | 585 | struct workqueue_struct *workqueue; |
595 | struct work_struct main_work; | 586 | struct work_struct main_work; |
596 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; | 587 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; |
@@ -684,6 +675,8 @@ struct mwifiex_adapter { | |||
684 | struct mwifiex_dbg dbg; | 675 | struct mwifiex_dbg dbg; |
685 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; | 676 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; |
686 | u32 arp_filter_size; | 677 | u32 arp_filter_size; |
678 | u16 cmd_wait_q_required; | ||
679 | struct mwifiex_wait_queue cmd_wait_q; | ||
687 | }; | 680 | }; |
688 | 681 | ||
689 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); | 682 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); |
@@ -707,29 +700,23 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); | |||
707 | 700 | ||
708 | int mwifiex_process_event(struct mwifiex_adapter *adapter); | 701 | int mwifiex_process_event(struct mwifiex_adapter *adapter); |
709 | 702 | ||
710 | int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, | 703 | int mwifiex_complete_cmd(struct mwifiex_adapter *adapter); |
711 | struct mwifiex_wait_queue *ioctl_wq, | ||
712 | int status); | ||
713 | 704 | ||
714 | int mwifiex_prepare_cmd(struct mwifiex_private *priv, | 705 | int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, |
715 | uint16_t cmd_no, | 706 | u16 cmd_action, u32 cmd_oid, void *data_buf); |
716 | u16 cmd_action, | 707 | |
717 | u32 cmd_oid, | 708 | int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, |
718 | void *wait_queue, void *data_buf); | 709 | u16 cmd_action, u32 cmd_oid, void *data_buf); |
719 | 710 | ||
720 | void mwifiex_cmd_timeout_func(unsigned long function_context); | 711 | void mwifiex_cmd_timeout_func(unsigned long function_context); |
721 | 712 | ||
722 | int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | ||
723 | struct mwifiex_wait_queue *wait_queue, | ||
724 | u32 func_init_shutdown); | ||
725 | int mwifiex_get_debug_info(struct mwifiex_private *, | 713 | int mwifiex_get_debug_info(struct mwifiex_private *, |
726 | struct mwifiex_debug_info *); | 714 | struct mwifiex_debug_info *); |
727 | 715 | ||
728 | int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); | 716 | int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); |
729 | int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); | 717 | int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); |
730 | void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); | 718 | void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); |
731 | void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | 719 | void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); |
732 | struct mwifiex_wait_queue *ioctl_wq); | ||
733 | 720 | ||
734 | void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | 721 | void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, |
735 | struct cmd_ctrl_node *cmd_node); | 722 | struct cmd_ctrl_node *cmd_node); |
@@ -772,24 +759,20 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, | |||
772 | u16 cmd_action, u32 cmd_oid, | 759 | u16 cmd_action, u32 cmd_oid, |
773 | void *data_buf, void *cmd_buf); | 760 | void *data_buf, void *cmd_buf); |
774 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, | 761 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, |
775 | void *cmd_buf, void *ioctl); | 762 | void *cmd_buf); |
776 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, | 763 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, |
777 | struct sk_buff *skb); | 764 | struct sk_buff *skb); |
778 | int mwifiex_process_sta_event(struct mwifiex_private *); | 765 | int mwifiex_process_sta_event(struct mwifiex_private *); |
779 | void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); | 766 | void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); |
780 | int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); | 767 | int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); |
781 | int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, | 768 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
782 | u16 action, | 769 | const struct mwifiex_user_scan_cfg *user_scan_in); |
783 | const struct mwifiex_user_scan_cfg | 770 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, |
784 | *user_scan_in, struct mwifiex_scan_resp *); | ||
785 | int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | ||
786 | struct host_cmd_ds_command *cmd, | ||
787 | void *data_buf); | 771 | void *data_buf); |
788 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | 772 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, |
789 | struct cmd_ctrl_node *cmd_node); | 773 | struct cmd_ctrl_node *cmd_node); |
790 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 774 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
791 | struct host_cmd_ds_command *resp, | 775 | struct host_cmd_ds_command *resp); |
792 | void *wait_queue); | ||
793 | s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, | 776 | s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, |
794 | struct mwifiex_802_11_ssid *ssid, u8 *bssid, | 777 | struct mwifiex_802_11_ssid *ssid, u8 *bssid, |
795 | u32 mode); | 778 | u32 mode); |
@@ -799,23 +782,20 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, | |||
799 | struct mwifiex_ssid_bssid *req_ssid_bssid); | 782 | struct mwifiex_ssid_bssid *req_ssid_bssid); |
800 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 783 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, |
801 | struct mwifiex_802_11_ssid *ssid2); | 784 | struct mwifiex_802_11_ssid *ssid2); |
802 | int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, | 785 | int mwifiex_associate(struct mwifiex_private *priv, |
803 | struct mwifiex_bssdescriptor *bss_desc); | 786 | struct mwifiex_bssdescriptor *bss_desc); |
804 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 787 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
805 | struct host_cmd_ds_command | 788 | struct host_cmd_ds_command |
806 | *cmd, void *data_buf); | 789 | *cmd, void *data_buf); |
807 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | 790 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, |
808 | struct host_cmd_ds_command *resp, | 791 | struct host_cmd_ds_command *resp); |
809 | void *wait_queue); | ||
810 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); | 792 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); |
811 | void mwifiex_2040_coex_event(struct mwifiex_private *priv); | 793 | void mwifiex_2040_coex_event(struct mwifiex_private *priv); |
812 | u8 mwifiex_band_to_radio_type(u8 band); | 794 | u8 mwifiex_band_to_radio_type(u8 band); |
813 | int mwifiex_deauthenticate(struct mwifiex_private *priv, | 795 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); |
814 | struct mwifiex_wait_queue *wait_queue, | 796 | int mwifiex_adhoc_start(struct mwifiex_private *priv, |
815 | u8 *mac); | ||
816 | int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue, | ||
817 | struct mwifiex_802_11_ssid *adhoc_ssid); | 797 | struct mwifiex_802_11_ssid *adhoc_ssid); |
818 | int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, | 798 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
819 | struct mwifiex_bssdescriptor *bss_desc); | 799 | struct mwifiex_bssdescriptor *bss_desc); |
820 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 800 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
821 | struct host_cmd_ds_command *cmd, | 801 | struct host_cmd_ds_command *cmd, |
@@ -824,11 +804,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
824 | struct host_cmd_ds_command *cmd, | 804 | struct host_cmd_ds_command *cmd, |
825 | void *data_buf); | 805 | void *data_buf); |
826 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 806 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
827 | struct host_cmd_ds_command *resp, | 807 | struct host_cmd_ds_command *resp); |
828 | void *wait_queue); | 808 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); |
829 | int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, | ||
830 | struct host_cmd_ds_command *cmd, | ||
831 | void *data_buf); | ||
832 | struct mwifiex_chan_freq_power * | 809 | struct mwifiex_chan_freq_power * |
833 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211( | 810 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211( |
834 | struct mwifiex_private *priv, | 811 | struct mwifiex_private *priv, |
@@ -836,20 +813,16 @@ struct mwifiex_chan_freq_power * | |||
836 | struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( | 813 | struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( |
837 | struct mwifiex_private *priv, | 814 | struct mwifiex_private *priv, |
838 | u8 band, u32 freq); | 815 | u8 band, u32 freq); |
839 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | 816 | u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info); |
840 | u8 ht_info); | ||
841 | u32 mwifiex_find_freq_from_band_chan(u8, u8); | 817 | u32 mwifiex_find_freq_from_band_chan(u8, u8); |
842 | int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, | 818 | int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, |
843 | u8 **buffer); | 819 | u8 **buffer); |
844 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | ||
845 | u8 ht_info); | ||
846 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, | 820 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, |
847 | u8 *rates); | 821 | u8 *rates); |
848 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); | 822 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); |
849 | u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); | 823 | u8 mwifiex_data_rate_to_index(u32 rate); |
850 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); | 824 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); |
851 | int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, | 825 | int mwifiex_get_rate_index(u16 *rateBitmap, int size); |
852 | u16 *rateBitmap, int size); | ||
853 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; | 826 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; |
854 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); | 827 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); |
855 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); | 828 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); |
@@ -899,7 +872,7 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len) | |||
899 | */ | 872 | */ |
900 | static inline struct mwifiex_private * | 873 | static inline struct mwifiex_private * |
901 | mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, | 874 | mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, |
902 | u32 bss_num, u32 bss_type) | 875 | u8 bss_num, u8 bss_type) |
903 | { | 876 | { |
904 | int i; | 877 | int i; |
905 | 878 | ||
@@ -943,52 +916,34 @@ mwifiex_netdev_get_priv(struct net_device *dev) | |||
943 | return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); | 916 | return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); |
944 | } | 917 | } |
945 | 918 | ||
946 | struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue( | ||
947 | struct mwifiex_private *, | ||
948 | u8 wait_option); | ||
949 | struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter | 919 | struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter |
950 | *adapter, u8 bss_index); | 920 | *adapter, u8 bss_index); |
951 | int mwifiex_shutdown_fw(struct mwifiex_private *, u8); | 921 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
952 | 922 | u32 func_init_shutdown); | |
953 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); | 923 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); |
954 | int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); | 924 | int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); |
955 | 925 | ||
956 | void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, | 926 | void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, |
957 | int maxlen); | 927 | int maxlen); |
958 | int mwifiex_request_set_mac_address(struct mwifiex_private *priv); | 928 | int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, |
959 | void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | 929 | struct mwifiex_multicast_list *mcast_list); |
960 | struct net_device *dev); | 930 | int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
961 | int mwifiex_request_ioctl(struct mwifiex_private *priv, | 931 | struct net_device *dev); |
962 | struct mwifiex_wait_queue *req, | 932 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
963 | int, u8 wait_option); | ||
964 | int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *); | ||
965 | int mwifiex_bss_start(struct mwifiex_private *priv, | 933 | int mwifiex_bss_start(struct mwifiex_private *priv, |
966 | u8 wait_option, | ||
967 | struct mwifiex_ssid_bssid *ssid_bssid); | 934 | struct mwifiex_ssid_bssid *ssid_bssid); |
968 | int mwifiex_set_hs_params(struct mwifiex_private *priv, | 935 | int mwifiex_set_hs_params(struct mwifiex_private *priv, |
969 | u16 action, u8 wait_option, | 936 | u16 action, int cmd_type, |
970 | struct mwifiex_ds_hs_cfg *hscfg); | 937 | struct mwifiex_ds_hs_cfg *hscfg); |
971 | int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); | 938 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
972 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 939 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
973 | void mwifiex_process_ioctl_resp(struct mwifiex_private *priv, | ||
974 | struct mwifiex_wait_queue *req); | ||
975 | u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option); | ||
976 | int mwifiex_get_signal_info(struct mwifiex_private *priv, | 940 | int mwifiex_get_signal_info(struct mwifiex_private *priv, |
977 | u8 wait_option, | ||
978 | struct mwifiex_ds_get_signal *signal); | 941 | struct mwifiex_ds_get_signal *signal); |
979 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 942 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, |
980 | struct mwifiex_rate_cfg *rate); | 943 | struct mwifiex_rate_cfg *rate); |
981 | int mwifiex_get_channel_list(struct mwifiex_private *priv, | 944 | int mwifiex_find_best_bss(struct mwifiex_private *priv, |
982 | u8 wait_option, | ||
983 | struct mwifiex_chan_list *chanlist); | ||
984 | int mwifiex_get_scan_table(struct mwifiex_private *priv, | ||
985 | u8 wait_option, | ||
986 | struct mwifiex_scan_resp *scanresp); | ||
987 | int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); | ||
988 | int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, | ||
989 | struct mwifiex_ssid_bssid *ssid_bssid); | 945 | struct mwifiex_ssid_bssid *ssid_bssid); |
990 | int mwifiex_request_scan(struct mwifiex_private *priv, | 946 | int mwifiex_request_scan(struct mwifiex_private *priv, |
991 | u8 wait_option, | ||
992 | struct mwifiex_802_11_ssid *req_ssid); | 947 | struct mwifiex_802_11_ssid *req_ssid); |
993 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 948 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
994 | struct mwifiex_user_scan_cfg *scan_req); | 949 | struct mwifiex_user_scan_cfg *scan_req); |
@@ -1024,27 +979,22 @@ int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index); | |||
1024 | 979 | ||
1025 | int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); | 980 | int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); |
1026 | 981 | ||
1027 | int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); | 982 | int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode); |
1028 | 983 | ||
1029 | int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, | 984 | int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, |
1030 | char *version, int max_len); | 985 | char *version, int max_len); |
1031 | 986 | ||
1032 | int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); | 987 | int mwifiex_set_tx_power(struct mwifiex_private *priv, |
988 | struct mwifiex_power_cfg *power_cfg); | ||
1033 | 989 | ||
1034 | int mwifiex_main_process(struct mwifiex_adapter *); | 990 | int mwifiex_main_process(struct mwifiex_adapter *); |
1035 | 991 | ||
1036 | int mwifiex_bss_ioctl_channel(struct mwifiex_private *, | 992 | int mwifiex_bss_set_channel(struct mwifiex_private *, |
1037 | u16 action, | 993 | struct mwifiex_chan_freq_power *cfp); |
1038 | struct mwifiex_chan_freq_power *cfp); | ||
1039 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, | 994 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, |
1040 | struct mwifiex_wait_queue *, | ||
1041 | struct mwifiex_ssid_bssid *); | 995 | struct mwifiex_ssid_bssid *); |
1042 | int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, | 996 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *, |
1043 | u16 action, | 997 | struct mwifiex_ds_band_cfg *); |
1044 | struct mwifiex_ds_band_cfg *); | ||
1045 | int mwifiex_snmp_mib_ioctl(struct mwifiex_private *, | ||
1046 | struct mwifiex_wait_queue *, | ||
1047 | u32 cmd_oid, u16 action, u32 *value); | ||
1048 | int mwifiex_get_bss_info(struct mwifiex_private *, | 998 | int mwifiex_get_bss_info(struct mwifiex_private *, |
1049 | struct mwifiex_bss_info *); | 999 | struct mwifiex_bss_info *); |
1050 | 1000 | ||
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6bb52d0e6cfa..68d905d58606 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -178,35 +178,27 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | |||
178 | * with requisite parameters and calls the IOCTL handler. | 178 | * with requisite parameters and calls the IOCTL handler. |
179 | */ | 179 | */ |
180 | int mwifiex_find_best_bss(struct mwifiex_private *priv, | 180 | int mwifiex_find_best_bss(struct mwifiex_private *priv, |
181 | u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) | 181 | struct mwifiex_ssid_bssid *ssid_bssid) |
182 | { | 182 | { |
183 | struct mwifiex_wait_queue *wait = NULL; | ||
184 | struct mwifiex_ssid_bssid tmp_ssid_bssid; | 183 | struct mwifiex_ssid_bssid tmp_ssid_bssid; |
185 | int ret = 0; | ||
186 | u8 *mac = NULL; | 184 | u8 *mac = NULL; |
187 | 185 | ||
188 | if (!ssid_bssid) | 186 | if (!ssid_bssid) |
189 | return -1; | 187 | return -1; |
190 | 188 | ||
191 | /* Allocate wait request buffer */ | ||
192 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
193 | if (!wait) | ||
194 | return -ENOMEM; | ||
195 | |||
196 | memcpy(&tmp_ssid_bssid, ssid_bssid, | 189 | memcpy(&tmp_ssid_bssid, ssid_bssid, |
197 | sizeof(struct mwifiex_ssid_bssid)); | 190 | sizeof(struct mwifiex_ssid_bssid)); |
198 | ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); | ||
199 | 191 | ||
200 | if (!ret) { | 192 | if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) { |
201 | memcpy(ssid_bssid, &tmp_ssid_bssid, | 193 | memcpy(ssid_bssid, &tmp_ssid_bssid, |
202 | sizeof(struct mwifiex_ssid_bssid)); | 194 | sizeof(struct mwifiex_ssid_bssid)); |
203 | mac = (u8 *) &ssid_bssid->bssid; | 195 | mac = (u8 *) &ssid_bssid->bssid; |
204 | dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s," | 196 | dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s," |
205 | " %pM\n", ssid_bssid->ssid.ssid, mac); | 197 | " %pM\n", ssid_bssid->ssid.ssid, mac); |
198 | return 0; | ||
206 | } | 199 | } |
207 | 200 | ||
208 | kfree(wait); | 201 | return -1; |
209 | return ret; | ||
210 | } | 202 | } |
211 | 203 | ||
212 | /* | 204 | /* |
@@ -221,22 +213,14 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, | |||
221 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 213 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
222 | struct mwifiex_user_scan_cfg *scan_req) | 214 | struct mwifiex_user_scan_cfg *scan_req) |
223 | { | 215 | { |
224 | struct mwifiex_wait_queue *wait = NULL; | ||
225 | int status = 0; | 216 | int status = 0; |
226 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
227 | 217 | ||
228 | /* Allocate an IOCTL request buffer */ | 218 | priv->adapter->cmd_wait_q.condition = false; |
229 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
230 | if (!wait) | ||
231 | return -ENOMEM; | ||
232 | 219 | ||
233 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, | 220 | status = mwifiex_scan_networks(priv, scan_req); |
234 | scan_req, NULL); | 221 | if (!status) |
222 | status = mwifiex_wait_queue_complete(priv->adapter); | ||
235 | 223 | ||
236 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
237 | |||
238 | if (wait && (status != -EINPROGRESS)) | ||
239 | kfree(wait); | ||
240 | return status; | 224 | return status; |
241 | } | 225 | } |
242 | 226 | ||
@@ -674,7 +658,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
674 | * along with the other TLVs, to the firmware. | 658 | * along with the other TLVs, to the firmware. |
675 | */ | 659 | */ |
676 | static int | 660 | static int |
677 | mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, | 661 | mwifiex_scan_channel_list(struct mwifiex_private *priv, |
678 | u32 max_chan_per_scan, u8 filtered_scan, | 662 | u32 max_chan_per_scan, u8 filtered_scan, |
679 | struct mwifiex_scan_cmd_config *scan_cfg_out, | 663 | struct mwifiex_scan_cmd_config *scan_cfg_out, |
680 | struct mwifiex_ie_types_chan_list_param_set | 664 | struct mwifiex_ie_types_chan_list_param_set |
@@ -808,9 +792,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, | |||
808 | 792 | ||
809 | /* Send the scan command to the firmware with the specified | 793 | /* Send the scan command to the firmware with the specified |
810 | cfg */ | 794 | cfg */ |
811 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, | 795 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, |
812 | HostCmd_ACT_GEN_SET, | 796 | HostCmd_ACT_GEN_SET, 0, |
813 | 0, wait_buf, scan_cfg_out); | 797 | scan_cfg_out); |
814 | if (ret) | 798 | if (ret) |
815 | break; | 799 | break; |
816 | } | 800 | } |
@@ -2076,19 +2060,13 @@ mwifiex_process_scan_results(struct mwifiex_private *priv) | |||
2076 | static u8 | 2060 | static u8 |
2077 | mwifiex_radio_type_to_band(u8 radio_type) | 2061 | mwifiex_radio_type_to_band(u8 radio_type) |
2078 | { | 2062 | { |
2079 | u8 ret_band; | ||
2080 | |||
2081 | switch (radio_type) { | 2063 | switch (radio_type) { |
2082 | case HostCmd_SCAN_RADIO_TYPE_A: | 2064 | case HostCmd_SCAN_RADIO_TYPE_A: |
2083 | ret_band = BAND_A; | 2065 | return BAND_A; |
2084 | break; | ||
2085 | case HostCmd_SCAN_RADIO_TYPE_BG: | 2066 | case HostCmd_SCAN_RADIO_TYPE_BG: |
2086 | default: | 2067 | default: |
2087 | ret_band = BAND_G; | 2068 | return BAND_G; |
2088 | break; | ||
2089 | } | 2069 | } |
2090 | |||
2091 | return ret_band; | ||
2092 | } | 2070 | } |
2093 | 2071 | ||
2094 | /* | 2072 | /* |
@@ -2241,8 +2219,7 @@ static int | |||
2241 | mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, | 2219 | mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, |
2242 | struct mwifiex_802_11_ssid *del_ssid) | 2220 | struct mwifiex_802_11_ssid *del_ssid) |
2243 | { | 2221 | { |
2244 | int ret = -1; | 2222 | s32 table_idx = -1; |
2245 | s32 table_idx; | ||
2246 | 2223 | ||
2247 | dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n", | 2224 | dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n", |
2248 | del_ssid->ssid); | 2225 | del_ssid->ssid); |
@@ -2255,11 +2232,10 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, | |||
2255 | dev_dbg(priv->adapter->dev, | 2232 | dev_dbg(priv->adapter->dev, |
2256 | "info: Scan: Delete SSID Entry: Found Idx = %d\n", | 2233 | "info: Scan: Delete SSID Entry: Found Idx = %d\n", |
2257 | table_idx); | 2234 | table_idx); |
2258 | ret = 0; | ||
2259 | mwifiex_scan_delete_table_entry(priv, table_idx); | 2235 | mwifiex_scan_delete_table_entry(priv, table_idx); |
2260 | } | 2236 | } |
2261 | 2237 | ||
2262 | return ret; | 2238 | return table_idx == -1 ? -1 : 0; |
2263 | } | 2239 | } |
2264 | 2240 | ||
2265 | /* | 2241 | /* |
@@ -2271,9 +2247,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, | |||
2271 | * update the internal driver scan table. | 2247 | * update the internal driver scan table. |
2272 | */ | 2248 | */ |
2273 | int mwifiex_scan_networks(struct mwifiex_private *priv, | 2249 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
2274 | void *wait_buf, u16 action, | 2250 | const struct mwifiex_user_scan_cfg *user_scan_in) |
2275 | const struct mwifiex_user_scan_cfg *user_scan_in, | ||
2276 | struct mwifiex_scan_resp *scan_resp) | ||
2277 | { | 2251 | { |
2278 | int ret = 0; | 2252 | int ret = 0; |
2279 | struct mwifiex_adapter *adapter = priv->adapter; | 2253 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -2288,18 +2262,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2288 | u8 max_chan_per_scan; | 2262 | u8 max_chan_per_scan; |
2289 | unsigned long flags; | 2263 | unsigned long flags; |
2290 | 2264 | ||
2291 | if (action == HostCmd_ACT_GEN_GET) { | 2265 | if (adapter->scan_processing) { |
2292 | if (scan_resp) { | ||
2293 | scan_resp->scan_table = (u8 *) adapter->scan_table; | ||
2294 | scan_resp->num_in_scan_table = | ||
2295 | adapter->num_in_scan_table; | ||
2296 | } else { | ||
2297 | ret = -1; | ||
2298 | } | ||
2299 | return ret; | ||
2300 | } | ||
2301 | |||
2302 | if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { | ||
2303 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); | 2266 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); |
2304 | return ret; | 2267 | return ret; |
2305 | } | 2268 | } |
@@ -2308,7 +2271,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2308 | adapter->scan_processing = true; | 2271 | adapter->scan_processing = true; |
2309 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 2272 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
2310 | 2273 | ||
2311 | if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { | 2274 | if (priv->scan_block) { |
2312 | dev_dbg(adapter->dev, | 2275 | dev_dbg(adapter->dev, |
2313 | "cmd: Scan is blocked during association...\n"); | 2276 | "cmd: Scan is blocked during association...\n"); |
2314 | return ret; | 2277 | return ret; |
@@ -2348,9 +2311,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2348 | adapter->bcn_buf_end = adapter->bcn_buf; | 2311 | adapter->bcn_buf_end = adapter->bcn_buf; |
2349 | } | 2312 | } |
2350 | 2313 | ||
2351 | ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, | 2314 | ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, |
2352 | filtered_scan, &scan_cfg_out->config, | 2315 | &scan_cfg_out->config, chan_list_out, |
2353 | chan_list_out, scan_chan_list); | 2316 | scan_chan_list); |
2354 | 2317 | ||
2355 | /* Get scan command from scan_pending_q and put to cmd_pending_q */ | 2318 | /* Get scan command from scan_pending_q and put to cmd_pending_q */ |
2356 | if (!ret) { | 2319 | if (!ret) { |
@@ -2367,7 +2330,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2367 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 2330 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
2368 | flags); | 2331 | flags); |
2369 | } | 2332 | } |
2370 | ret = -EINPROGRESS; | ||
2371 | } else { | 2333 | } else { |
2372 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 2334 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
2373 | adapter->scan_processing = true; | 2335 | adapter->scan_processing = true; |
@@ -2393,8 +2355,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2393 | * - Setting command ID, and proper size | 2355 | * - Setting command ID, and proper size |
2394 | * - Ensuring correct endian-ness | 2356 | * - Ensuring correct endian-ness |
2395 | */ | 2357 | */ |
2396 | int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | 2358 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) |
2397 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
2398 | { | 2359 | { |
2399 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; | 2360 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; |
2400 | struct mwifiex_scan_cmd_config *scan_cfg; | 2361 | struct mwifiex_scan_cmd_config *scan_cfg; |
@@ -2437,11 +2398,10 @@ int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | |||
2437 | * .-------------------------------------------------------------. | 2398 | * .-------------------------------------------------------------. |
2438 | */ | 2399 | */ |
2439 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 2400 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
2440 | struct host_cmd_ds_command *resp, void *wq_buf) | 2401 | struct host_cmd_ds_command *resp) |
2441 | { | 2402 | { |
2442 | int ret = 0; | 2403 | int ret = 0; |
2443 | struct mwifiex_adapter *adapter = priv->adapter; | 2404 | struct mwifiex_adapter *adapter = priv->adapter; |
2444 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
2445 | struct cmd_ctrl_node *cmd_node = NULL; | 2405 | struct cmd_ctrl_node *cmd_node = NULL; |
2446 | struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; | 2406 | struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; |
2447 | struct mwifiex_bssdescriptor *bss_new_entry = NULL; | 2407 | struct mwifiex_bssdescriptor *bss_new_entry = NULL; |
@@ -2653,13 +2613,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
2653 | mwifiex_process_scan_results(priv); | 2613 | mwifiex_process_scan_results(priv); |
2654 | 2614 | ||
2655 | /* Need to indicate IOCTL complete */ | 2615 | /* Need to indicate IOCTL complete */ |
2656 | wait_queue = (struct mwifiex_wait_queue *) wq_buf; | 2616 | if (adapter->curr_cmd->wait_q_enabled) { |
2657 | if (wait_queue) { | 2617 | adapter->cmd_wait_q.status = 0; |
2658 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 2618 | mwifiex_complete_cmd(adapter); |
2659 | |||
2660 | /* Indicate ioctl complete */ | ||
2661 | mwifiex_ioctl_complete(adapter, | ||
2662 | (struct mwifiex_wait_queue *) wait_queue, 0); | ||
2663 | } | 2619 | } |
2664 | if (priv->report_scan_result) | 2620 | if (priv->report_scan_result) |
2665 | priv->report_scan_result = false; | 2621 | priv->report_scan_result = false; |
@@ -2692,9 +2648,7 @@ done: | |||
2692 | * - Setting background scan flush parameter | 2648 | * - Setting background scan flush parameter |
2693 | * - Ensuring correct endian-ness | 2649 | * - Ensuring correct endian-ness |
2694 | */ | 2650 | */ |
2695 | int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, | 2651 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd) |
2696 | struct host_cmd_ds_command *cmd, | ||
2697 | void *data_buf) | ||
2698 | { | 2652 | { |
2699 | struct host_cmd_ds_802_11_bg_scan_query *bg_query = | 2653 | struct host_cmd_ds_802_11_bg_scan_query *bg_query = |
2700 | &cmd->params.bg_scan_query; | 2654 | &cmd->params.bg_scan_query; |
@@ -2853,6 +2807,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
2853 | struct mwifiex_adapter *adapter = priv->adapter; | 2807 | struct mwifiex_adapter *adapter = priv->adapter; |
2854 | unsigned long flags; | 2808 | unsigned long flags; |
2855 | 2809 | ||
2810 | cmd_node->wait_q_enabled = true; | ||
2856 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 2811 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
2857 | list_add_tail(&cmd_node->list, &adapter->scan_pending_q); | 2812 | list_add_tail(&cmd_node->list, &adapter->scan_pending_q); |
2858 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 2813 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
@@ -2899,9 +2854,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, | |||
2899 | * firmware, filtered on a specific SSID. | 2854 | * firmware, filtered on a specific SSID. |
2900 | */ | 2855 | */ |
2901 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | 2856 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, |
2902 | void *wait_buf, u16 action, | 2857 | struct mwifiex_802_11_ssid *req_ssid) |
2903 | struct mwifiex_802_11_ssid *req_ssid, | ||
2904 | struct mwifiex_scan_resp *scan_resp) | ||
2905 | { | 2858 | { |
2906 | struct mwifiex_adapter *adapter = priv->adapter; | 2859 | struct mwifiex_adapter *adapter = priv->adapter; |
2907 | int ret = 0; | 2860 | int ret = 0; |
@@ -2910,24 +2863,12 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2910 | if (!req_ssid) | 2863 | if (!req_ssid) |
2911 | return -1; | 2864 | return -1; |
2912 | 2865 | ||
2913 | if (action == HostCmd_ACT_GEN_GET) { | 2866 | if (adapter->scan_processing) { |
2914 | if (scan_resp) { | ||
2915 | scan_resp->scan_table = | ||
2916 | (u8 *) &priv->curr_bss_params.bss_descriptor; | ||
2917 | scan_resp->num_in_scan_table = | ||
2918 | adapter->num_in_scan_table; | ||
2919 | } else { | ||
2920 | ret = -1; | ||
2921 | } | ||
2922 | return ret; | ||
2923 | } | ||
2924 | |||
2925 | if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { | ||
2926 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); | 2867 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); |
2927 | return ret; | 2868 | return ret; |
2928 | } | 2869 | } |
2929 | 2870 | ||
2930 | if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { | 2871 | if (priv->scan_block) { |
2931 | dev_dbg(adapter->dev, | 2872 | dev_dbg(adapter->dev, |
2932 | "cmd: Scan is blocked during association...\n"); | 2873 | "cmd: Scan is blocked during association...\n"); |
2933 | return ret; | 2874 | return ret; |
@@ -2945,7 +2886,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2945 | req_ssid->ssid_len); | 2886 | req_ssid->ssid_len); |
2946 | scan_cfg->keep_previous_scan = true; | 2887 | scan_cfg->keep_previous_scan = true; |
2947 | 2888 | ||
2948 | ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); | 2889 | ret = mwifiex_scan_networks(priv, scan_cfg); |
2949 | 2890 | ||
2950 | kfree(scan_cfg); | 2891 | kfree(scan_cfg); |
2951 | return ret; | 2892 | return ret; |
@@ -2960,12 +2901,10 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2960 | * Scan command can be issued for both normal scan and specific SSID | 2901 | * Scan command can be issued for both normal scan and specific SSID |
2961 | * scan, depending upon whether an SSID is provided or not. | 2902 | * scan, depending upon whether an SSID is provided or not. |
2962 | */ | 2903 | */ |
2963 | int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, | 2904 | int mwifiex_request_scan(struct mwifiex_private *priv, |
2964 | struct mwifiex_802_11_ssid *req_ssid) | 2905 | struct mwifiex_802_11_ssid *req_ssid) |
2965 | { | 2906 | { |
2966 | int ret = 0; | 2907 | int ret = 0; |
2967 | struct mwifiex_wait_queue *wait = NULL; | ||
2968 | int status = 0; | ||
2969 | 2908 | ||
2970 | if (down_interruptible(&priv->async_sem)) { | 2909 | if (down_interruptible(&priv->async_sem)) { |
2971 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", | 2910 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", |
@@ -2974,32 +2913,23 @@ int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, | |||
2974 | } | 2913 | } |
2975 | priv->scan_pending_on_block = true; | 2914 | priv->scan_pending_on_block = true; |
2976 | 2915 | ||
2977 | /* Allocate wait request buffer */ | 2916 | priv->adapter->cmd_wait_q.condition = false; |
2978 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
2979 | if (!wait) { | ||
2980 | ret = -1; | ||
2981 | goto done; | ||
2982 | } | ||
2983 | 2917 | ||
2984 | if (req_ssid && req_ssid->ssid_len != 0) | 2918 | if (req_ssid && req_ssid->ssid_len != 0) |
2985 | /* Specific SSID scan */ | 2919 | /* Specific SSID scan */ |
2986 | status = mwifiex_scan_specific_ssid(priv, wait, | 2920 | ret = mwifiex_scan_specific_ssid(priv, req_ssid); |
2987 | HostCmd_ACT_GEN_SET, | ||
2988 | req_ssid, NULL); | ||
2989 | else | 2921 | else |
2990 | /* Normal scan */ | 2922 | /* Normal scan */ |
2991 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, | 2923 | ret = mwifiex_scan_networks(priv, NULL); |
2992 | NULL, NULL); | 2924 | |
2993 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | 2925 | if (!ret) |
2994 | if (status == -1) | 2926 | ret = mwifiex_wait_queue_complete(priv->adapter); |
2995 | ret = -1; | 2927 | |
2996 | done: | ||
2997 | if ((wait) && (status != -EINPROGRESS)) | ||
2998 | kfree(wait); | ||
2999 | if (ret == -1) { | 2928 | if (ret == -1) { |
3000 | priv->scan_pending_on_block = false; | 2929 | priv->scan_pending_on_block = false; |
3001 | up(&priv->async_sem); | 2930 | up(&priv->async_sem); |
3002 | } | 2931 | } |
2932 | |||
3003 | return ret; | 2933 | return ret; |
3004 | } | 2934 | } |
3005 | 2935 | ||
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f21e5cd19839..5148d0e0fad6 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -208,7 +208,7 @@ static int mwifiex_sdio_resume(struct device *dev) | |||
208 | 208 | ||
209 | /* Disable Host Sleep */ | 209 | /* Disable Host Sleep */ |
210 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), | 210 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), |
211 | MWIFIEX_NO_WAIT); | 211 | MWIFIEX_ASYNC_CMD); |
212 | 212 | ||
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
@@ -282,7 +282,7 @@ mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) | |||
282 | */ | 282 | */ |
283 | static int | 283 | static int |
284 | mwifiex_write_data_sync(struct mwifiex_adapter *adapter, | 284 | mwifiex_write_data_sync(struct mwifiex_adapter *adapter, |
285 | u8 *buffer, u32 pkt_len, u32 port, u32 timeout) | 285 | u8 *buffer, u32 pkt_len, u32 port) |
286 | { | 286 | { |
287 | struct sdio_mmc_card *card = adapter->card; | 287 | struct sdio_mmc_card *card = adapter->card; |
288 | int ret = -1; | 288 | int ret = -1; |
@@ -314,9 +314,8 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter, | |||
314 | /* | 314 | /* |
315 | * This function reads multiple data from SDIO card memory. | 315 | * This function reads multiple data from SDIO card memory. |
316 | */ | 316 | */ |
317 | static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, | 317 | static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, |
318 | u8 *buffer, u32 len, | 318 | u32 len, u32 port, u8 claim) |
319 | u32 port, u32 timeout, u8 claim) | ||
320 | { | 319 | { |
321 | struct sdio_mmc_card *card = adapter->card; | 320 | struct sdio_mmc_card *card = adapter->card; |
322 | int ret = -1; | 321 | int ret = -1; |
@@ -348,12 +347,9 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, | |||
348 | */ | 347 | */ |
349 | static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) | 348 | static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) |
350 | { | 349 | { |
351 | int ret; | ||
352 | |||
353 | dev_dbg(adapter->dev, "event: wakeup device...\n"); | 350 | dev_dbg(adapter->dev, "event: wakeup device...\n"); |
354 | ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP); | ||
355 | 351 | ||
356 | return ret; | 352 | return mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP); |
357 | } | 353 | } |
358 | 354 | ||
359 | /* | 355 | /* |
@@ -363,12 +359,9 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) | |||
363 | */ | 359 | */ |
364 | static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) | 360 | static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) |
365 | { | 361 | { |
366 | int ret; | ||
367 | |||
368 | dev_dbg(adapter->dev, "cmd: wakeup device completed\n"); | 362 | dev_dbg(adapter->dev, "cmd: wakeup device completed\n"); |
369 | ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); | ||
370 | 363 | ||
371 | return ret; | 364 | return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); |
372 | } | 365 | } |
373 | 366 | ||
374 | /* | 367 | /* |
@@ -430,8 +423,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, | |||
430 | int ret = 0; | 423 | int ret = 0; |
431 | 424 | ||
432 | do { | 425 | do { |
433 | ret = mwifiex_write_data_sync(adapter, payload, pkt_len, | 426 | ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port); |
434 | port, 0); | ||
435 | if (ret) { | 427 | if (ret) { |
436 | i++; | 428 | i++; |
437 | dev_err(adapter->dev, "host_to_card, write iomem" | 429 | dev_err(adapter->dev, "host_to_card, write iomem" |
@@ -630,7 +622,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, | |||
630 | return -1; | 622 | return -1; |
631 | } | 623 | } |
632 | 624 | ||
633 | ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); | 625 | ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1); |
634 | 626 | ||
635 | if (ret) { | 627 | if (ret) { |
636 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, | 628 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, |
@@ -769,7 +761,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
769 | 761 | ||
770 | ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * | 762 | ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * |
771 | MWIFIEX_SDIO_BLOCK_SIZE, | 763 | MWIFIEX_SDIO_BLOCK_SIZE, |
772 | adapter->ioport, 0); | 764 | adapter->ioport); |
773 | if (ret) { | 765 | if (ret) { |
774 | dev_err(adapter->dev, "FW download, write iomem (%d)" | 766 | dev_err(adapter->dev, "FW download, write iomem (%d)" |
775 | " failed @ %d\n", i, offset); | 767 | " failed @ %d\n", i, offset); |
@@ -842,7 +834,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
842 | unsigned long flags; | 834 | unsigned long flags; |
843 | 835 | ||
844 | if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, | 836 | if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, |
845 | REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, | 837 | REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, |
846 | 0)) { | 838 | 0)) { |
847 | dev_err(adapter->dev, "read mp_regs failed\n"); | 839 | dev_err(adapter->dev, "read mp_regs failed\n"); |
848 | return; | 840 | return; |
@@ -859,8 +851,6 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
859 | adapter->int_status |= sdio_ireg; | 851 | adapter->int_status |= sdio_ireg; |
860 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 852 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
861 | } | 853 | } |
862 | |||
863 | return; | ||
864 | } | 854 | } |
865 | 855 | ||
866 | /* | 856 | /* |
@@ -891,8 +881,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
891 | 881 | ||
892 | mwifiex_interrupt_status(adapter); | 882 | mwifiex_interrupt_status(adapter); |
893 | queue_work(adapter->workqueue, &adapter->main_work); | 883 | queue_work(adapter->workqueue, &adapter->main_work); |
894 | |||
895 | return; | ||
896 | } | 884 | } |
897 | 885 | ||
898 | /* | 886 | /* |
@@ -1054,7 +1042,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1054 | card->mpa_rx.buf_len, | 1042 | card->mpa_rx.buf_len, |
1055 | (adapter->ioport | 0x1000 | | 1043 | (adapter->ioport | 0x1000 | |
1056 | (card->mpa_rx.ports << 4)) + | 1044 | (card->mpa_rx.ports << 4)) + |
1057 | card->mpa_rx.start_port, 0, 1)) | 1045 | card->mpa_rx.start_port, 1)) |
1058 | return -1; | 1046 | return -1; |
1059 | 1047 | ||
1060 | curr_ptr = card->mpa_rx.buf; | 1048 | curr_ptr = card->mpa_rx.buf; |
@@ -1709,13 +1697,9 @@ static struct mwifiex_if_ops sdio_ops = { | |||
1709 | static int | 1697 | static int |
1710 | mwifiex_sdio_init_module(void) | 1698 | mwifiex_sdio_init_module(void) |
1711 | { | 1699 | { |
1712 | int ret; | ||
1713 | |||
1714 | sema_init(&add_remove_card_sem, 1); | 1700 | sema_init(&add_remove_card_sem, 1); |
1715 | 1701 | ||
1716 | ret = sdio_register_driver(&mwifiex_sdio); | 1702 | return sdio_register_driver(&mwifiex_sdio); |
1717 | |||
1718 | return ret; | ||
1719 | } | 1703 | } |
1720 | 1704 | ||
1721 | /* | 1705 | /* |
@@ -1745,13 +1729,12 @@ mwifiex_sdio_cleanup_module(void) | |||
1745 | for (i = 0; i < adapter->priv_num; i++) | 1729 | for (i = 0; i < adapter->priv_num; i++) |
1746 | if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && | 1730 | if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && |
1747 | adapter->priv[i]->media_connected) | 1731 | adapter->priv[i]->media_connected) |
1748 | mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, | 1732 | mwifiex_deauthenticate(adapter->priv[i], NULL); |
1749 | NULL); | ||
1750 | 1733 | ||
1751 | if (!adapter->surprise_removed) | 1734 | if (!adapter->surprise_removed) |
1752 | mwifiex_shutdown_fw(mwifiex_get_priv | 1735 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, |
1753 | (adapter, MWIFIEX_BSS_ROLE_ANY), | 1736 | MWIFIEX_BSS_ROLE_ANY), |
1754 | MWIFIEX_CMD_WAIT); | 1737 | MWIFIEX_FUNC_SHUTDOWN); |
1755 | 1738 | ||
1756 | exit: | 1739 | exit: |
1757 | up(&add_remove_card_sem); | 1740 | up(&add_remove_card_sem); |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6fff26153e26..33c8ba1f5e33 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -190,8 +190,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
190 | * - Ensuring correct endian-ness | 190 | * - Ensuring correct endian-ness |
191 | */ | 191 | */ |
192 | static int | 192 | static int |
193 | mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, | 193 | mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) |
194 | struct host_cmd_ds_command *cmd) | ||
195 | { | 194 | { |
196 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); | 195 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); |
197 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + | 196 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + |
@@ -272,8 +271,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
272 | * (as required) | 271 | * (as required) |
273 | * - Ensuring correct endian-ness | 272 | * - Ensuring correct endian-ness |
274 | */ | 273 | */ |
275 | static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, | 274 | static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, |
276 | struct host_cmd_ds_command *cmd, | ||
277 | u16 cmd_action, void *data_buf) | 275 | u16 cmd_action, void *data_buf) |
278 | { | 276 | { |
279 | struct mwifiex_types_power_group *pg_tlv = NULL; | 277 | struct mwifiex_types_power_group *pg_tlv = NULL; |
@@ -407,8 +405,7 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, | |||
407 | * - Setting MAC multicast address | 405 | * - Setting MAC multicast address |
408 | * - Ensuring correct endian-ness | 406 | * - Ensuring correct endian-ness |
409 | */ | 407 | */ |
410 | static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, | 408 | static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, |
411 | struct host_cmd_ds_command *cmd, | ||
412 | u16 cmd_action, void *data_buf) | 409 | u16 cmd_action, void *data_buf) |
413 | { | 410 | { |
414 | struct mwifiex_multicast_list *mcast_list = | 411 | struct mwifiex_multicast_list *mcast_list = |
@@ -463,8 +460,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, | |||
463 | * - Setting command ID and proper size | 460 | * - Setting command ID and proper size |
464 | * - Ensuring correct endian-ness | 461 | * - Ensuring correct endian-ness |
465 | */ | 462 | */ |
466 | static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, | 463 | static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd) |
467 | struct host_cmd_ds_command *cmd) | ||
468 | { | 464 | { |
469 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); | 465 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); |
470 | cmd->size = cpu_to_le16(S_DS_GEN); | 466 | cmd->size = cpu_to_le16(S_DS_GEN); |
@@ -500,9 +496,8 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
500 | key_param_set->key_type_id = | 496 | key_param_set->key_type_id = |
501 | cpu_to_le16(KEY_TYPE_ID_WEP); | 497 | cpu_to_le16(KEY_TYPE_ID_WEP); |
502 | key_param_set->key_info = | 498 | key_param_set->key_info = |
503 | cpu_to_le16(KEY_INFO_WEP_ENABLED | | 499 | cpu_to_le16(KEY_ENABLED | KEY_UNICAST | |
504 | KEY_INFO_WEP_UNICAST | | 500 | KEY_MCAST); |
505 | KEY_INFO_WEP_MCAST); | ||
506 | key_param_set->key_len = | 501 | key_param_set->key_len = |
507 | cpu_to_le16(priv->wep_key[i].key_length); | 502 | cpu_to_le16(priv->wep_key[i].key_length); |
508 | /* Set WEP key index */ | 503 | /* Set WEP key index */ |
@@ -589,10 +584,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
589 | cpu_to_le16(KEY_TYPE_ID_WAPI); | 584 | cpu_to_le16(KEY_TYPE_ID_WAPI); |
590 | if (cmd_oid == KEY_INFO_ENABLED) | 585 | if (cmd_oid == KEY_INFO_ENABLED) |
591 | key_material->key_param_set.key_info = | 586 | key_material->key_param_set.key_info = |
592 | cpu_to_le16(KEY_INFO_WAPI_ENABLED); | 587 | cpu_to_le16(KEY_ENABLED); |
593 | else | 588 | else |
594 | key_material->key_param_set.key_info = | 589 | key_material->key_param_set.key_info = |
595 | cpu_to_le16(!KEY_INFO_WAPI_ENABLED); | 590 | cpu_to_le16(!KEY_ENABLED); |
596 | 591 | ||
597 | key_material->key_param_set.key[0] = enc_key->key_index; | 592 | key_material->key_param_set.key[0] = enc_key->key_index; |
598 | if (!priv->sec_info.wapi_key_on) | 593 | if (!priv->sec_info.wapi_key_on) |
@@ -604,10 +599,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
604 | if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { | 599 | if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { |
605 | /* WAPI pairwise key: unicast */ | 600 | /* WAPI pairwise key: unicast */ |
606 | key_material->key_param_set.key_info |= | 601 | key_material->key_param_set.key_info |= |
607 | cpu_to_le16(KEY_INFO_WAPI_UNICAST); | 602 | cpu_to_le16(KEY_UNICAST); |
608 | } else { /* WAPI group key: multicast */ | 603 | } else { /* WAPI group key: multicast */ |
609 | key_material->key_param_set.key_info |= | 604 | key_material->key_param_set.key_info |= |
610 | cpu_to_le16(KEY_INFO_WAPI_MCAST); | 605 | cpu_to_le16(KEY_MCAST); |
611 | priv->sec_info.wapi_key_on = true; | 606 | priv->sec_info.wapi_key_on = true; |
612 | } | 607 | } |
613 | 608 | ||
@@ -634,32 +629,32 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
634 | cpu_to_le16(KEY_TYPE_ID_AES); | 629 | cpu_to_le16(KEY_TYPE_ID_AES); |
635 | if (cmd_oid == KEY_INFO_ENABLED) | 630 | if (cmd_oid == KEY_INFO_ENABLED) |
636 | key_material->key_param_set.key_info = | 631 | key_material->key_param_set.key_info = |
637 | cpu_to_le16(KEY_INFO_AES_ENABLED); | 632 | cpu_to_le16(KEY_ENABLED); |
638 | else | 633 | else |
639 | key_material->key_param_set.key_info = | 634 | key_material->key_param_set.key_info = |
640 | cpu_to_le16(!KEY_INFO_AES_ENABLED); | 635 | cpu_to_le16(!KEY_ENABLED); |
641 | 636 | ||
642 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 637 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
643 | /* AES pairwise key: unicast */ | 638 | /* AES pairwise key: unicast */ |
644 | key_material->key_param_set.key_info |= | 639 | key_material->key_param_set.key_info |= |
645 | cpu_to_le16(KEY_INFO_AES_UNICAST); | 640 | cpu_to_le16(KEY_UNICAST); |
646 | else /* AES group key: multicast */ | 641 | else /* AES group key: multicast */ |
647 | key_material->key_param_set.key_info |= | 642 | key_material->key_param_set.key_info |= |
648 | cpu_to_le16(KEY_INFO_AES_MCAST); | 643 | cpu_to_le16(KEY_MCAST); |
649 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { | 644 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { |
650 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); | 645 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); |
651 | key_material->key_param_set.key_type_id = | 646 | key_material->key_param_set.key_type_id = |
652 | cpu_to_le16(KEY_TYPE_ID_TKIP); | 647 | cpu_to_le16(KEY_TYPE_ID_TKIP); |
653 | key_material->key_param_set.key_info = | 648 | key_material->key_param_set.key_info = |
654 | cpu_to_le16(KEY_INFO_TKIP_ENABLED); | 649 | cpu_to_le16(KEY_ENABLED); |
655 | 650 | ||
656 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 651 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
657 | /* TKIP pairwise key: unicast */ | 652 | /* TKIP pairwise key: unicast */ |
658 | key_material->key_param_set.key_info |= | 653 | key_material->key_param_set.key_info |= |
659 | cpu_to_le16(KEY_INFO_TKIP_UNICAST); | 654 | cpu_to_le16(KEY_UNICAST); |
660 | else /* TKIP group key: multicast */ | 655 | else /* TKIP group key: multicast */ |
661 | key_material->key_param_set.key_info |= | 656 | key_material->key_param_set.key_info |= |
662 | cpu_to_le16(KEY_INFO_TKIP_MCAST); | 657 | cpu_to_le16(KEY_MCAST); |
663 | } | 658 | } |
664 | 659 | ||
665 | if (key_material->key_param_set.key_type_id) { | 660 | if (key_material->key_param_set.key_type_id) { |
@@ -778,8 +773,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
778 | * - Setting status to enable or disable (for SET only) | 773 | * - Setting status to enable or disable (for SET only) |
779 | * - Ensuring correct endian-ness | 774 | * - Ensuring correct endian-ness |
780 | */ | 775 | */ |
781 | static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, | 776 | static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, |
782 | struct host_cmd_ds_command *cmd, | ||
783 | u16 cmd_action, void *data_buf) | 777 | u16 cmd_action, void *data_buf) |
784 | { | 778 | { |
785 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = | 779 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = |
@@ -947,7 +941,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
947 | cmd_action); | 941 | cmd_action); |
948 | break; | 942 | break; |
949 | case HostCmd_CMD_MAC_MULTICAST_ADR: | 943 | case HostCmd_CMD_MAC_MULTICAST_ADR: |
950 | ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, | 944 | ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action, |
951 | data_buf); | 945 | data_buf); |
952 | break; | 946 | break; |
953 | case HostCmd_CMD_TX_RATE_CFG: | 947 | case HostCmd_CMD_TX_RATE_CFG: |
@@ -955,7 +949,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
955 | data_buf); | 949 | data_buf); |
956 | break; | 950 | break; |
957 | case HostCmd_CMD_TXPWR_CFG: | 951 | case HostCmd_CMD_TXPWR_CFG: |
958 | ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, | 952 | ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, |
959 | data_buf); | 953 | data_buf); |
960 | break; | 954 | break; |
961 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 955 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
@@ -967,11 +961,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
967 | (struct mwifiex_hs_config_param *) data_buf); | 961 | (struct mwifiex_hs_config_param *) data_buf); |
968 | break; | 962 | break; |
969 | case HostCmd_CMD_802_11_SCAN: | 963 | case HostCmd_CMD_802_11_SCAN: |
970 | ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); | 964 | ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); |
971 | break; | 965 | break; |
972 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: | 966 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: |
973 | ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, | 967 | ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr); |
974 | data_buf); | ||
975 | break; | 968 | break; |
976 | case HostCmd_CMD_802_11_ASSOCIATE: | 969 | case HostCmd_CMD_802_11_ASSOCIATE: |
977 | ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); | 970 | ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); |
@@ -985,14 +978,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
985 | data_buf); | 978 | data_buf); |
986 | break; | 979 | break; |
987 | case HostCmd_CMD_802_11_GET_LOG: | 980 | case HostCmd_CMD_802_11_GET_LOG: |
988 | ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); | 981 | ret = mwifiex_cmd_802_11_get_log(cmd_ptr); |
989 | break; | 982 | break; |
990 | case HostCmd_CMD_802_11_AD_HOC_JOIN: | 983 | case HostCmd_CMD_802_11_AD_HOC_JOIN: |
991 | ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, | 984 | ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, |
992 | data_buf); | 985 | data_buf); |
993 | break; | 986 | break; |
994 | case HostCmd_CMD_802_11_AD_HOC_STOP: | 987 | case HostCmd_CMD_802_11_AD_HOC_STOP: |
995 | ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); | 988 | ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr); |
996 | break; | 989 | break; |
997 | case HostCmd_CMD_RSSI_INFO: | 990 | case HostCmd_CMD_RSSI_INFO: |
998 | ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); | 991 | ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); |
@@ -1037,10 +1030,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1037 | cmd_ptr->size = cpu_to_le16(S_DS_GEN); | 1030 | cmd_ptr->size = cpu_to_le16(S_DS_GEN); |
1038 | break; | 1031 | break; |
1039 | case HostCmd_CMD_11N_ADDBA_REQ: | 1032 | case HostCmd_CMD_11N_ADDBA_REQ: |
1040 | ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); | 1033 | ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf); |
1041 | break; | 1034 | break; |
1042 | case HostCmd_CMD_11N_DELBA: | 1035 | case HostCmd_CMD_11N_DELBA: |
1043 | ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); | 1036 | ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf); |
1044 | break; | 1037 | break; |
1045 | case HostCmd_CMD_11N_ADDBA_RSP: | 1038 | case HostCmd_CMD_11N_ADDBA_RSP: |
1046 | ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); | 1039 | ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); |
@@ -1059,11 +1052,11 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1059 | data_buf); | 1052 | data_buf); |
1060 | break; | 1053 | break; |
1061 | case HostCmd_CMD_AMSDU_AGGR_CTRL: | 1054 | case HostCmd_CMD_AMSDU_AGGR_CTRL: |
1062 | ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, | 1055 | ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action, |
1063 | data_buf); | 1056 | data_buf); |
1064 | break; | 1057 | break; |
1065 | case HostCmd_CMD_11N_CFG: | 1058 | case HostCmd_CMD_11N_CFG: |
1066 | ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, | 1059 | ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, |
1067 | data_buf); | 1060 | data_buf); |
1068 | break; | 1061 | break; |
1069 | case HostCmd_CMD_WMM_GET_STATUS: | 1062 | case HostCmd_CMD_WMM_GET_STATUS: |
@@ -1076,8 +1069,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1076 | ret = 0; | 1069 | ret = 0; |
1077 | break; | 1070 | break; |
1078 | case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: | 1071 | case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: |
1079 | ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, | 1072 | ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, |
1080 | cmd_action, data_buf); | 1073 | data_buf); |
1081 | break; | 1074 | break; |
1082 | case HostCmd_CMD_MAC_REG_ACCESS: | 1075 | case HostCmd_CMD_MAC_REG_ACCESS: |
1083 | case HostCmd_CMD_BBP_REG_ACCESS: | 1076 | case HostCmd_CMD_BBP_REG_ACCESS: |
@@ -1136,65 +1129,66 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1136 | 1129 | ||
1137 | if (first_sta) { | 1130 | if (first_sta) { |
1138 | 1131 | ||
1139 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, | 1132 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, |
1140 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 1133 | HostCmd_ACT_GEN_SET, 0, NULL); |
1141 | if (ret) | 1134 | if (ret) |
1142 | return -1; | 1135 | return -1; |
1143 | /* Read MAC address from HW */ | 1136 | /* Read MAC address from HW */ |
1144 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, | 1137 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC, |
1145 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1138 | HostCmd_ACT_GEN_GET, 0, NULL); |
1146 | if (ret) | 1139 | if (ret) |
1147 | return -1; | 1140 | return -1; |
1148 | 1141 | ||
1149 | /* Reconfigure tx buf size */ | 1142 | /* Reconfigure tx buf size */ |
1150 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, | 1143 | ret = mwifiex_send_cmd_async(priv, |
1151 | HostCmd_ACT_GEN_SET, 0, NULL, | 1144 | HostCmd_CMD_RECONFIGURE_TX_BUFF, |
1152 | &priv->adapter->tx_buf_size); | 1145 | HostCmd_ACT_GEN_SET, 0, |
1146 | &priv->adapter->tx_buf_size); | ||
1153 | if (ret) | 1147 | if (ret) |
1154 | return -1; | 1148 | return -1; |
1155 | 1149 | ||
1156 | /* Enable IEEE PS by default */ | 1150 | /* Enable IEEE PS by default */ |
1157 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; | 1151 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; |
1158 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | 1152 | ret = mwifiex_send_cmd_async(priv, |
1159 | EN_AUTO_PS, BITMAP_STA_PS, NULL, | 1153 | HostCmd_CMD_802_11_PS_MODE_ENH, |
1160 | NULL); | 1154 | EN_AUTO_PS, BITMAP_STA_PS, NULL); |
1161 | if (ret) | 1155 | if (ret) |
1162 | return -1; | 1156 | return -1; |
1163 | } | 1157 | } |
1164 | 1158 | ||
1165 | /* get tx rate */ | 1159 | /* get tx rate */ |
1166 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, | 1160 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG, |
1167 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1161 | HostCmd_ACT_GEN_GET, 0, NULL); |
1168 | if (ret) | 1162 | if (ret) |
1169 | return -1; | 1163 | return -1; |
1170 | priv->data_rate = 0; | 1164 | priv->data_rate = 0; |
1171 | 1165 | ||
1172 | /* get tx power */ | 1166 | /* get tx power */ |
1173 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, | 1167 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, |
1174 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1168 | HostCmd_ACT_GEN_GET, 0, NULL); |
1175 | if (ret) | 1169 | if (ret) |
1176 | return -1; | 1170 | return -1; |
1177 | 1171 | ||
1178 | /* set ibss coalescing_status */ | 1172 | /* set ibss coalescing_status */ |
1179 | ret = mwifiex_prepare_cmd(priv, | 1173 | ret = mwifiex_send_cmd_async(priv, |
1180 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, | 1174 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, |
1181 | HostCmd_ACT_GEN_SET, 0, NULL, &enable); | 1175 | HostCmd_ACT_GEN_SET, 0, &enable); |
1182 | if (ret) | 1176 | if (ret) |
1183 | return -1; | 1177 | return -1; |
1184 | 1178 | ||
1185 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); | 1179 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); |
1186 | amsdu_aggr_ctrl.enable = true; | 1180 | amsdu_aggr_ctrl.enable = true; |
1187 | /* Send request to firmware */ | 1181 | /* Send request to firmware */ |
1188 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, | 1182 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, |
1189 | HostCmd_ACT_GEN_SET, 0, NULL, | 1183 | HostCmd_ACT_GEN_SET, 0, |
1190 | (void *) &amsdu_aggr_ctrl); | 1184 | (void *) &amsdu_aggr_ctrl); |
1191 | if (ret) | 1185 | if (ret) |
1192 | return -1; | 1186 | return -1; |
1193 | /* MAC Control must be the last command in init_fw */ | 1187 | /* MAC Control must be the last command in init_fw */ |
1194 | /* set MAC Control */ | 1188 | /* set MAC Control */ |
1195 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1189 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
1196 | HostCmd_ACT_GEN_SET, 0, NULL, | 1190 | HostCmd_ACT_GEN_SET, 0, |
1197 | &priv->curr_pkt_filter); | 1191 | &priv->curr_pkt_filter); |
1198 | if (ret) | 1192 | if (ret) |
1199 | return -1; | 1193 | return -1; |
1200 | 1194 | ||
@@ -1202,19 +1196,18 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1202 | /* Enable auto deep sleep */ | 1196 | /* Enable auto deep sleep */ |
1203 | auto_ds.auto_ds = DEEP_SLEEP_ON; | 1197 | auto_ds.auto_ds = DEEP_SLEEP_ON; |
1204 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; | 1198 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; |
1205 | ret = mwifiex_prepare_cmd(priv, | 1199 | ret = mwifiex_send_cmd_async(priv, |
1206 | HostCmd_CMD_802_11_PS_MODE_ENH, | 1200 | HostCmd_CMD_802_11_PS_MODE_ENH, |
1207 | EN_AUTO_PS, BITMAP_AUTO_DS, NULL, | 1201 | EN_AUTO_PS, BITMAP_AUTO_DS, |
1208 | &auto_ds); | 1202 | &auto_ds); |
1209 | if (ret) | 1203 | if (ret) |
1210 | return -1; | 1204 | return -1; |
1211 | } | 1205 | } |
1212 | 1206 | ||
1213 | /* Send cmd to FW to enable/disable 11D function */ | 1207 | /* Send cmd to FW to enable/disable 11D function */ |
1214 | state_11d = ENABLE_11D; | 1208 | state_11d = ENABLE_11D; |
1215 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, | 1209 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, |
1216 | HostCmd_ACT_GEN_SET, DOT11D_I, | 1210 | HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); |
1217 | NULL, &state_11d); | ||
1218 | if (ret) | 1211 | if (ret) |
1219 | dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); | 1212 | dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); |
1220 | 1213 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 74add45b99b6..7f4f10b752fb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -41,8 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | static void | 42 | static void |
43 | mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | 43 | mwifiex_process_cmdresp_error(struct mwifiex_private *priv, |
44 | struct host_cmd_ds_command *resp, | 44 | struct host_cmd_ds_command *resp) |
45 | struct mwifiex_wait_queue *wq_buf) | ||
46 | { | 45 | { |
47 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 46 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
48 | struct mwifiex_adapter *adapter = priv->adapter; | 47 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -51,8 +50,9 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
51 | 50 | ||
52 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", | 51 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", |
53 | resp->command, resp->result); | 52 | resp->command, resp->result); |
54 | if (wq_buf) | 53 | |
55 | wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; | 54 | if (adapter->curr_cmd->wait_q_enabled) |
55 | adapter->cmd_wait_q.status = -1; | ||
56 | 56 | ||
57 | switch (le16_to_cpu(resp->command)) { | 57 | switch (le16_to_cpu(resp->command)) { |
58 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 58 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
@@ -103,8 +103,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
103 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 103 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
104 | adapter->curr_cmd = NULL; | 104 | adapter->curr_cmd = NULL; |
105 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 105 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
106 | |||
107 | return; | ||
108 | } | 106 | } |
109 | 107 | ||
110 | /* | 108 | /* |
@@ -282,7 +280,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
282 | struct host_cmd_ds_command *resp, | 280 | struct host_cmd_ds_command *resp, |
283 | void *data_buf) | 281 | void *data_buf) |
284 | { | 282 | { |
285 | struct mwifiex_adapter *adapter = priv->adapter; | ||
286 | struct mwifiex_rate_cfg *ds_rate = NULL; | 283 | struct mwifiex_rate_cfg *ds_rate = NULL; |
287 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; | 284 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; |
288 | struct mwifiex_rate_scope *rate_scope; | 285 | struct mwifiex_rate_scope *rate_scope; |
@@ -328,9 +325,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
328 | if (priv->is_data_rate_auto) | 325 | if (priv->is_data_rate_auto) |
329 | priv->data_rate = 0; | 326 | priv->data_rate = 0; |
330 | else | 327 | else |
331 | ret = mwifiex_prepare_cmd(priv, | 328 | ret = mwifiex_send_cmd_async(priv, |
332 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 329 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
333 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 330 | HostCmd_ACT_GEN_GET, 0, NULL); |
334 | 331 | ||
335 | if (data_buf) { | 332 | if (data_buf) { |
336 | ds_rate = (struct mwifiex_rate_cfg *) data_buf; | 333 | ds_rate = (struct mwifiex_rate_cfg *) data_buf; |
@@ -338,9 +335,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
338 | if (priv->is_data_rate_auto) { | 335 | if (priv->is_data_rate_auto) { |
339 | ds_rate->is_rate_auto = 1; | 336 | ds_rate->is_rate_auto = 1; |
340 | } else { | 337 | } else { |
341 | ds_rate->rate = | 338 | ds_rate->rate = mwifiex_get_rate_index(priv-> |
342 | mwifiex_get_rate_index(adapter, | ||
343 | priv-> | ||
344 | bitmap_rates, | 339 | bitmap_rates, |
345 | sizeof(priv-> | 340 | sizeof(priv-> |
346 | bitmap_rates)); | 341 | bitmap_rates)); |
@@ -516,13 +511,11 @@ static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv, | |||
516 | static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, | 511 | static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, |
517 | struct host_cmd_ds_command *resp) | 512 | struct host_cmd_ds_command *resp) |
518 | { | 513 | { |
519 | struct mwifiex_adapter *adapter = priv->adapter; | ||
520 | |||
521 | priv->tx_rate = resp->params.tx_rate.tx_rate; | 514 | priv->tx_rate = resp->params.tx_rate.tx_rate; |
522 | priv->tx_htinfo = resp->params.tx_rate.ht_info; | 515 | priv->tx_htinfo = resp->params.tx_rate.ht_info; |
523 | if (!priv->is_data_rate_auto) | 516 | if (!priv->is_data_rate_auto) |
524 | priv->data_rate = | 517 | priv->data_rate = |
525 | mwifiex_index_to_data_rate(adapter, priv->tx_rate, | 518 | mwifiex_index_to_data_rate(priv->tx_rate, |
526 | priv->tx_htinfo); | 519 | priv->tx_htinfo); |
527 | 520 | ||
528 | return 0; | 521 | return 0; |
@@ -574,8 +567,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, | |||
574 | &resp->params.key_material; | 567 | &resp->params.key_material; |
575 | 568 | ||
576 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { | 569 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { |
577 | if ((le16_to_cpu(key->key_param_set.key_info) & | 570 | if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { |
578 | KEY_INFO_TKIP_MCAST)) { | ||
579 | dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); | 571 | dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); |
580 | priv->wpa_is_gtk_set = true; | 572 | priv->wpa_is_gtk_set = true; |
581 | priv->scan_block = false; | 573 | priv->scan_block = false; |
@@ -834,19 +826,17 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, | |||
834 | * response handlers based on the command ID. | 826 | * response handlers based on the command ID. |
835 | */ | 827 | */ |
836 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | 828 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, |
837 | u16 cmdresp_no, void *cmd_buf, void *wq_buf) | 829 | u16 cmdresp_no, void *cmd_buf) |
838 | { | 830 | { |
839 | int ret = 0; | 831 | int ret = 0; |
840 | struct mwifiex_adapter *adapter = priv->adapter; | 832 | struct mwifiex_adapter *adapter = priv->adapter; |
841 | struct host_cmd_ds_command *resp = | 833 | struct host_cmd_ds_command *resp = |
842 | (struct host_cmd_ds_command *) cmd_buf; | 834 | (struct host_cmd_ds_command *) cmd_buf; |
843 | struct mwifiex_wait_queue *wait_queue = | ||
844 | (struct mwifiex_wait_queue *) wq_buf; | ||
845 | void *data_buf = adapter->curr_cmd->data_buf; | 835 | void *data_buf = adapter->curr_cmd->data_buf; |
846 | 836 | ||
847 | /* If the command is not successful, cleanup and return failure */ | 837 | /* If the command is not successful, cleanup and return failure */ |
848 | if (resp->result != HostCmd_RESULT_OK) { | 838 | if (resp->result != HostCmd_RESULT_OK) { |
849 | mwifiex_process_cmdresp_error(priv, resp, wait_queue); | 839 | mwifiex_process_cmdresp_error(priv, resp); |
850 | return -1; | 840 | return -1; |
851 | } | 841 | } |
852 | /* Command successful, handle response */ | 842 | /* Command successful, handle response */ |
@@ -866,12 +856,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
866 | ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); | 856 | ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); |
867 | break; | 857 | break; |
868 | case HostCmd_CMD_802_11_SCAN: | 858 | case HostCmd_CMD_802_11_SCAN: |
869 | ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); | 859 | ret = mwifiex_ret_802_11_scan(priv, resp); |
870 | wait_queue = NULL; | 860 | adapter->curr_cmd->wait_q_enabled = false; |
871 | adapter->curr_cmd->wq_buf = NULL; | ||
872 | break; | 861 | break; |
873 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: | 862 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: |
874 | ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); | 863 | ret = mwifiex_ret_802_11_scan(priv, resp); |
875 | dev_dbg(adapter->dev, | 864 | dev_dbg(adapter->dev, |
876 | "info: CMD_RESP: BG_SCAN result is ready!\n"); | 865 | "info: CMD_RESP: BG_SCAN result is ready!\n"); |
877 | break; | 866 | break; |
@@ -885,14 +874,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
885 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); | 874 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); |
886 | break; | 875 | break; |
887 | case HostCmd_CMD_802_11_ASSOCIATE: | 876 | case HostCmd_CMD_802_11_ASSOCIATE: |
888 | ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); | 877 | ret = mwifiex_ret_802_11_associate(priv, resp); |
889 | break; | 878 | break; |
890 | case HostCmd_CMD_802_11_DEAUTHENTICATE: | 879 | case HostCmd_CMD_802_11_DEAUTHENTICATE: |
891 | ret = mwifiex_ret_802_11_deauthenticate(priv, resp); | 880 | ret = mwifiex_ret_802_11_deauthenticate(priv, resp); |
892 | break; | 881 | break; |
893 | case HostCmd_CMD_802_11_AD_HOC_START: | 882 | case HostCmd_CMD_802_11_AD_HOC_START: |
894 | case HostCmd_CMD_802_11_AD_HOC_JOIN: | 883 | case HostCmd_CMD_802_11_AD_HOC_JOIN: |
895 | ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); | 884 | ret = mwifiex_ret_802_11_ad_hoc(priv, resp); |
896 | break; | 885 | break; |
897 | case HostCmd_CMD_802_11_AD_HOC_STOP: | 886 | case HostCmd_CMD_802_11_AD_HOC_STOP: |
898 | ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); | 887 | ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); |
@@ -952,7 +941,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
952 | mp_end_port)); | 941 | mp_end_port)); |
953 | break; | 942 | break; |
954 | case HostCmd_CMD_AMSDU_AGGR_CTRL: | 943 | case HostCmd_CMD_AMSDU_AGGR_CTRL: |
955 | ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); | 944 | ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); |
956 | break; | 945 | break; |
957 | case HostCmd_CMD_WMM_GET_STATUS: | 946 | case HostCmd_CMD_WMM_GET_STATUS: |
958 | ret = mwifiex_ret_wmm_get_status(priv, resp); | 947 | ret = mwifiex_ret_wmm_get_status(priv, resp); |
@@ -971,7 +960,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
971 | case HostCmd_CMD_SET_BSS_MODE: | 960 | case HostCmd_CMD_SET_BSS_MODE: |
972 | break; | 961 | break; |
973 | case HostCmd_CMD_11N_CFG: | 962 | case HostCmd_CMD_11N_CFG: |
974 | ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); | 963 | ret = mwifiex_ret_11n_cfg(resp, data_buf); |
975 | break; | 964 | break; |
976 | default: | 965 | default: |
977 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", | 966 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", |
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 936d7c175e75..fc265cab0907 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -271,8 +271,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
271 | 271 | ||
272 | case EVENT_HS_ACT_REQ: | 272 | case EVENT_HS_ACT_REQ: |
273 | dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); | 273 | dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); |
274 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, | 274 | ret = mwifiex_send_cmd_async(priv, |
275 | 0, 0, NULL, NULL); | 275 | HostCmd_CMD_802_11_HS_CFG_ENH, |
276 | 0, 0, NULL); | ||
276 | break; | 277 | break; |
277 | 278 | ||
278 | case EVENT_MIC_ERR_UNICAST: | 279 | case EVENT_MIC_ERR_UNICAST: |
@@ -303,9 +304,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
303 | sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); | 304 | sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); |
304 | adapter->num_in_scan_table = 0; | 305 | adapter->num_in_scan_table = 0; |
305 | adapter->bcn_buf_end = adapter->bcn_buf; | 306 | adapter->bcn_buf_end = adapter->bcn_buf; |
306 | ret = mwifiex_prepare_cmd(priv, | 307 | ret = mwifiex_send_cmd_async(priv, |
307 | HostCmd_CMD_802_11_BG_SCAN_QUERY, | 308 | HostCmd_CMD_802_11_BG_SCAN_QUERY, |
308 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 309 | HostCmd_ACT_GEN_GET, 0, NULL); |
309 | break; | 310 | break; |
310 | 311 | ||
311 | case EVENT_PORT_RELEASE: | 312 | case EVENT_PORT_RELEASE: |
@@ -314,8 +315,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
314 | 315 | ||
315 | case EVENT_WMM_STATUS_CHANGE: | 316 | case EVENT_WMM_STATUS_CHANGE: |
316 | dev_dbg(adapter->dev, "event: WMM status changed\n"); | 317 | dev_dbg(adapter->dev, "event: WMM status changed\n"); |
317 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, | 318 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, |
318 | 0, 0, NULL, NULL); | 319 | 0, 0, NULL); |
319 | break; | 320 | break; |
320 | 321 | ||
321 | case EVENT_RSSI_LOW: | 322 | case EVENT_RSSI_LOW: |
@@ -353,15 +354,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
353 | break; | 354 | break; |
354 | case EVENT_IBSS_COALESCED: | 355 | case EVENT_IBSS_COALESCED: |
355 | dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); | 356 | dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); |
356 | ret = mwifiex_prepare_cmd(priv, | 357 | ret = mwifiex_send_cmd_async(priv, |
357 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, | 358 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, |
358 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 359 | HostCmd_ACT_GEN_GET, 0, NULL); |
359 | break; | 360 | break; |
360 | case EVENT_ADDBA: | 361 | case EVENT_ADDBA: |
361 | dev_dbg(adapter->dev, "event: ADDBA Request\n"); | 362 | dev_dbg(adapter->dev, "event: ADDBA Request\n"); |
362 | mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, | 363 | mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, |
363 | HostCmd_ACT_GEN_SET, 0, NULL, | 364 | HostCmd_ACT_GEN_SET, 0, |
364 | adapter->event_body); | 365 | adapter->event_body); |
365 | break; | 366 | break; |
366 | case EVENT_DELBA: | 367 | case EVENT_DELBA: |
367 | dev_dbg(adapter->dev, "event: DELBA Request\n"); | 368 | dev_dbg(adapter->dev, "event: DELBA Request\n"); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b163507b1fe0..e7adaab35226 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -33,9 +33,8 @@ | |||
33 | * size, and the calling function must ensure enough memory is | 33 | * size, and the calling function must ensure enough memory is |
34 | * available. | 34 | * available. |
35 | */ | 35 | */ |
36 | static int | 36 | int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
37 | mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | 37 | struct net_device *dev) |
38 | struct net_device *dev) | ||
39 | { | 38 | { |
40 | int i = 0; | 39 | int i = 0; |
41 | struct netdev_hw_addr *ha; | 40 | struct netdev_hw_addr *ha; |
@@ -47,216 +46,51 @@ mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | |||
47 | } | 46 | } |
48 | 47 | ||
49 | /* | 48 | /* |
50 | * Allocate and fills a wait queue with proper parameters. | ||
51 | * | ||
52 | * This function needs to be called before an IOCTL request can be made. | ||
53 | * It can handle the following wait options: | ||
54 | * MWIFIEX_NO_WAIT - Waiting is disabled | ||
55 | * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue | ||
56 | * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue | ||
57 | * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue | ||
58 | */ | ||
59 | struct mwifiex_wait_queue * | ||
60 | mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv, | ||
61 | u8 wait_option) | ||
62 | { | ||
63 | struct mwifiex_wait_queue *wait = NULL; | ||
64 | |||
65 | wait = (struct mwifiex_wait_queue *) | ||
66 | kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC); | ||
67 | if (!wait) { | ||
68 | dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n", | ||
69 | __func__); | ||
70 | return wait; | ||
71 | } | ||
72 | |||
73 | wait->bss_index = priv->bss_index; | ||
74 | |||
75 | switch (wait_option) { | ||
76 | case MWIFIEX_NO_WAIT: | ||
77 | wait->enabled = 0; | ||
78 | break; | ||
79 | case MWIFIEX_IOCTL_WAIT: | ||
80 | priv->ioctl_wait_q_woken = false; | ||
81 | wait->start_time = jiffies; | ||
82 | wait->wait = &priv->ioctl_wait_q; | ||
83 | wait->condition = &priv->ioctl_wait_q_woken; | ||
84 | wait->enabled = 1; | ||
85 | break; | ||
86 | case MWIFIEX_CMD_WAIT: | ||
87 | priv->cmd_wait_q_woken = false; | ||
88 | wait->start_time = jiffies; | ||
89 | wait->wait = &priv->cmd_wait_q; | ||
90 | wait->condition = &priv->cmd_wait_q_woken; | ||
91 | wait->enabled = 1; | ||
92 | break; | ||
93 | case MWIFIEX_WSTATS_WAIT: | ||
94 | priv->w_stats_wait_q_woken = false; | ||
95 | wait->start_time = jiffies; | ||
96 | wait->wait = &priv->w_stats_wait_q; | ||
97 | wait->condition = &priv->w_stats_wait_q_woken; | ||
98 | wait->enabled = 1; | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | return wait; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Wait queue completion handler. | 49 | * Wait queue completion handler. |
107 | * | 50 | * |
108 | * This function waits on a particular wait queue. | 51 | * This function waits on a cmd wait queue. It also cancels the pending |
109 | * For NO_WAIT option, it returns immediately. It also cancels the | 52 | * request after waking up, in case of errors. |
110 | * pending IOCTL request after waking up, in case of errors. | ||
111 | */ | 53 | */ |
112 | static void | 54 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) |
113 | mwifiex_wait_ioctl_complete(struct mwifiex_private *priv, | ||
114 | struct mwifiex_wait_queue *wait, | ||
115 | u8 wait_option) | ||
116 | { | 55 | { |
117 | bool cancel_flag = false; | 56 | bool cancel_flag = false; |
57 | int status = adapter->cmd_wait_q.status; | ||
118 | 58 | ||
119 | switch (wait_option) { | 59 | dev_dbg(adapter->dev, "cmd pending\n"); |
120 | case MWIFIEX_NO_WAIT: | 60 | atomic_inc(&adapter->cmd_pending); |
121 | break; | ||
122 | case MWIFIEX_IOCTL_WAIT: | ||
123 | wait_event_interruptible(priv->ioctl_wait_q, | ||
124 | priv->ioctl_wait_q_woken); | ||
125 | if (!priv->ioctl_wait_q_woken) | ||
126 | cancel_flag = true; | ||
127 | break; | ||
128 | case MWIFIEX_CMD_WAIT: | ||
129 | wait_event_interruptible(priv->cmd_wait_q, | ||
130 | priv->cmd_wait_q_woken); | ||
131 | if (!priv->cmd_wait_q_woken) | ||
132 | cancel_flag = true; | ||
133 | break; | ||
134 | case MWIFIEX_WSTATS_WAIT: | ||
135 | wait_event_interruptible(priv->w_stats_wait_q, | ||
136 | priv->w_stats_wait_q_woken); | ||
137 | if (!priv->w_stats_wait_q_woken) | ||
138 | cancel_flag = true; | ||
139 | break; | ||
140 | } | ||
141 | if (cancel_flag) { | ||
142 | mwifiex_cancel_pending_ioctl(priv->adapter, wait); | ||
143 | dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n", | ||
144 | wait, wait_option); | ||
145 | } | ||
146 | 61 | ||
147 | return; | 62 | /* Status pending, wake up main process */ |
148 | } | 63 | queue_work(adapter->workqueue, &adapter->main_work); |
149 | |||
150 | /* | ||
151 | * The function waits for the request to complete and issues the | ||
152 | * completion handler, if required. | ||
153 | */ | ||
154 | int mwifiex_request_ioctl(struct mwifiex_private *priv, | ||
155 | struct mwifiex_wait_queue *wait, | ||
156 | int status, u8 wait_option) | ||
157 | { | ||
158 | switch (status) { | ||
159 | case -EINPROGRESS: | ||
160 | dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n", | ||
161 | wait, wait_option); | ||
162 | atomic_inc(&priv->adapter->ioctl_pending); | ||
163 | /* Status pending, wake up main process */ | ||
164 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); | ||
165 | |||
166 | /* Wait for completion */ | ||
167 | if (wait_option) { | ||
168 | mwifiex_wait_ioctl_complete(priv, wait, wait_option); | ||
169 | status = wait->status; | ||
170 | } | ||
171 | break; | ||
172 | case 0: | ||
173 | case -1: | ||
174 | case -EBUSY: | ||
175 | default: | ||
176 | break; | ||
177 | } | ||
178 | return status; | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(mwifiex_request_ioctl); | ||
181 | 64 | ||
182 | /* | 65 | /* Wait for completion */ |
183 | * IOCTL request handler to set/get MAC address. | 66 | wait_event_interruptible(adapter->cmd_wait_q.wait, |
184 | * | 67 | adapter->cmd_wait_q.condition); |
185 | * This function prepares the correct firmware command and | 68 | if (!adapter->cmd_wait_q.condition) |
186 | * issues it to get the extended version information. | 69 | cancel_flag = true; |
187 | */ | ||
188 | static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv, | ||
189 | struct mwifiex_wait_queue *wait, | ||
190 | u8 action, u8 *mac) | ||
191 | { | ||
192 | int ret = 0; | ||
193 | 70 | ||
194 | if ((action == HostCmd_ACT_GEN_GET) && mac) { | 71 | if (cancel_flag) { |
195 | memcpy(mac, priv->curr_addr, ETH_ALEN); | 72 | mwifiex_cancel_pending_ioctl(adapter); |
196 | return 0; | 73 | dev_dbg(adapter->dev, "cmd cancel\n"); |
197 | } | 74 | } |
75 | adapter->cmd_wait_q.status = 0; | ||
198 | 76 | ||
199 | /* Send request to firmware */ | ||
200 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS, | ||
201 | action, 0, wait, mac); | ||
202 | if (!ret) | ||
203 | ret = -EINPROGRESS; | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Sends IOCTL request to set MAC address. | ||
210 | * | ||
211 | * This function allocates the IOCTL request buffer, fills it | ||
212 | * with requisite parameters and calls the IOCTL handler. | ||
213 | */ | ||
214 | int mwifiex_request_set_mac_address(struct mwifiex_private *priv) | ||
215 | { | ||
216 | struct mwifiex_wait_queue *wait = NULL; | ||
217 | int status = 0; | ||
218 | u8 wait_option = MWIFIEX_CMD_WAIT; | ||
219 | |||
220 | /* Allocate wait buffer */ | ||
221 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
222 | if (!wait) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET, | ||
226 | NULL); | ||
227 | |||
228 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
229 | if (!status) | ||
230 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); | ||
231 | else | ||
232 | dev_err(priv->adapter->dev, "set mac address failed: status=%d" | ||
233 | " error_code=%#x\n", status, wait->status); | ||
234 | |||
235 | kfree(wait); | ||
236 | return status; | 77 | return status; |
237 | } | 78 | } |
238 | 79 | ||
239 | /* | 80 | /* |
240 | * IOCTL request handler to set multicast list. | ||
241 | * | ||
242 | * This function prepares the correct firmware command and | 81 | * This function prepares the correct firmware command and |
243 | * issues it to set the multicast list. | 82 | * issues it to set the multicast list. |
244 | * | 83 | * |
245 | * This function can be used to enable promiscuous mode, or enable all | 84 | * This function can be used to enable promiscuous mode, or enable all |
246 | * multicast packets, or to enable selective multicast. | 85 | * multicast packets, or to enable selective multicast. |
247 | */ | 86 | */ |
248 | static int | 87 | int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, |
249 | mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | 88 | struct mwifiex_multicast_list *mcast_list) |
250 | struct mwifiex_wait_queue *wait, | ||
251 | u16 action, | ||
252 | struct mwifiex_multicast_list *mcast_list) | ||
253 | { | 89 | { |
254 | int ret = 0; | 90 | int ret = 0; |
255 | u16 old_pkt_filter; | 91 | u16 old_pkt_filter; |
256 | 92 | ||
257 | old_pkt_filter = priv->curr_pkt_filter; | 93 | old_pkt_filter = priv->curr_pkt_filter; |
258 | if (action == HostCmd_ACT_GEN_GET) | ||
259 | return -1; | ||
260 | 94 | ||
261 | if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { | 95 | if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { |
262 | dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); | 96 | dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); |
@@ -281,16 +115,15 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | |||
281 | /* Set multicast addresses to firmware */ | 115 | /* Set multicast addresses to firmware */ |
282 | if (old_pkt_filter == priv->curr_pkt_filter) { | 116 | if (old_pkt_filter == priv->curr_pkt_filter) { |
283 | /* Send request to firmware */ | 117 | /* Send request to firmware */ |
284 | ret = mwifiex_prepare_cmd(priv, | 118 | ret = mwifiex_send_cmd_async(priv, |
285 | HostCmd_CMD_MAC_MULTICAST_ADR, | 119 | HostCmd_CMD_MAC_MULTICAST_ADR, |
286 | action, 0, wait, mcast_list); | 120 | HostCmd_ACT_GEN_SET, 0, |
287 | if (!ret) | 121 | mcast_list); |
288 | ret = -EINPROGRESS; | ||
289 | } else { | 122 | } else { |
290 | /* Send request to firmware */ | 123 | /* Send request to firmware */ |
291 | ret = mwifiex_prepare_cmd(priv, | 124 | ret = mwifiex_send_cmd_async(priv, |
292 | HostCmd_CMD_MAC_MULTICAST_ADR, | 125 | HostCmd_CMD_MAC_MULTICAST_ADR, |
293 | action, 0, NULL, | 126 | HostCmd_ACT_GEN_SET, 0, |
294 | mcast_list); | 127 | mcast_list); |
295 | } | 128 | } |
296 | } | 129 | } |
@@ -300,101 +133,21 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | |||
300 | "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", | 133 | "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", |
301 | old_pkt_filter, priv->curr_pkt_filter); | 134 | old_pkt_filter, priv->curr_pkt_filter); |
302 | if (old_pkt_filter != priv->curr_pkt_filter) { | 135 | if (old_pkt_filter != priv->curr_pkt_filter) { |
303 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, | 136 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
304 | 0, wait, &priv->curr_pkt_filter); | 137 | HostCmd_ACT_GEN_SET, |
305 | if (!ret) | 138 | 0, &priv->curr_pkt_filter); |
306 | ret = -EINPROGRESS; | ||
307 | } | 139 | } |
308 | 140 | ||
309 | return ret; | 141 | return ret; |
310 | } | 142 | } |
311 | 143 | ||
312 | /* | 144 | /* |
313 | * Sends IOCTL request to set multicast list. | ||
314 | * | ||
315 | * This function allocates the IOCTL request buffer, fills it | ||
316 | * with requisite parameters and calls the IOCTL handler. | ||
317 | */ | ||
318 | void | ||
319 | mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | ||
320 | struct net_device *dev) | ||
321 | { | ||
322 | struct mwifiex_wait_queue *wait = NULL; | ||
323 | struct mwifiex_multicast_list mcast_list; | ||
324 | u8 wait_option = MWIFIEX_NO_WAIT; | ||
325 | int status = 0; | ||
326 | |||
327 | /* Allocate wait buffer */ | ||
328 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
329 | if (!wait) | ||
330 | return; | ||
331 | |||
332 | if (dev->flags & IFF_PROMISC) { | ||
333 | mcast_list.mode = MWIFIEX_PROMISC_MODE; | ||
334 | } else if (dev->flags & IFF_ALLMULTI || | ||
335 | netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { | ||
336 | mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; | ||
337 | } else { | ||
338 | mcast_list.mode = MWIFIEX_MULTICAST_MODE; | ||
339 | if (netdev_mc_count(dev)) | ||
340 | mcast_list.num_multicast_addr = | ||
341 | mwifiex_copy_mcast_addr(&mcast_list, dev); | ||
342 | } | ||
343 | status = mwifiex_bss_ioctl_multicast_list(priv, wait, | ||
344 | HostCmd_ACT_GEN_SET, | ||
345 | &mcast_list); | ||
346 | |||
347 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
348 | if (wait && status != -EINPROGRESS) | ||
349 | kfree(wait); | ||
350 | |||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * IOCTL request handler to disconnect from a BSS/IBSS. | ||
356 | */ | ||
357 | static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv, | ||
358 | struct mwifiex_wait_queue *wait, u8 *mac) | ||
359 | { | ||
360 | return mwifiex_deauthenticate(priv, wait, mac); | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * Sends IOCTL request to disconnect from a BSS. | ||
365 | * | ||
366 | * This function allocates the IOCTL request buffer, fills it | ||
367 | * with requisite parameters and calls the IOCTL handler. | ||
368 | */ | ||
369 | int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac) | ||
370 | { | ||
371 | struct mwifiex_wait_queue *wait = NULL; | ||
372 | int status = 0; | ||
373 | |||
374 | /* Allocate wait buffer */ | ||
375 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
376 | if (!wait) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | status = mwifiex_bss_ioctl_stop(priv, wait, mac); | ||
380 | |||
381 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
382 | |||
383 | kfree(wait); | ||
384 | return status; | ||
385 | } | ||
386 | EXPORT_SYMBOL_GPL(mwifiex_disconnect); | ||
387 | |||
388 | /* | ||
389 | * IOCTL request handler to join a BSS/IBSS. | ||
390 | * | ||
391 | * In Ad-Hoc mode, the IBSS is created if not found in scan list. | 145 | * In Ad-Hoc mode, the IBSS is created if not found in scan list. |
392 | * In both Ad-Hoc and infra mode, an deauthentication is performed | 146 | * In both Ad-Hoc and infra mode, an deauthentication is performed |
393 | * first. | 147 | * first. |
394 | */ | 148 | */ |
395 | static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | 149 | int mwifiex_bss_start(struct mwifiex_private *priv, |
396 | struct mwifiex_wait_queue *wait, | 150 | struct mwifiex_ssid_bssid *ssid_bssid) |
397 | struct mwifiex_ssid_bssid *ssid_bssid) | ||
398 | { | 151 | { |
399 | int ret = 0; | 152 | int ret = 0; |
400 | struct mwifiex_adapter *adapter = priv->adapter; | 153 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -406,7 +159,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
406 | 159 | ||
407 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 160 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
408 | /* Infra mode */ | 161 | /* Infra mode */ |
409 | ret = mwifiex_deauthenticate(priv, NULL, NULL); | 162 | ret = mwifiex_deauthenticate(priv, NULL); |
410 | if (ret) | 163 | if (ret) |
411 | return ret; | 164 | return ret; |
412 | 165 | ||
@@ -427,7 +180,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
427 | /* Clear any past association response stored for | 180 | /* Clear any past association response stored for |
428 | * application retrieval */ | 181 | * application retrieval */ |
429 | priv->assoc_rsp_size = 0; | 182 | priv->assoc_rsp_size = 0; |
430 | ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); | 183 | ret = mwifiex_associate(priv, &adapter->scan_table[i]); |
431 | if (ret) | 184 | if (ret) |
432 | return ret; | 185 | return ret; |
433 | } else { | 186 | } else { |
@@ -441,7 +194,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
441 | 194 | ||
442 | /* Exit Adhoc mode first */ | 195 | /* Exit Adhoc mode first */ |
443 | dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); | 196 | dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); |
444 | ret = mwifiex_deauthenticate(priv, NULL, NULL); | 197 | ret = mwifiex_deauthenticate(priv, NULL); |
445 | if (ret) | 198 | if (ret) |
446 | return ret; | 199 | return ret; |
447 | 200 | ||
@@ -460,75 +213,39 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
460 | if (i >= 0) { | 213 | if (i >= 0) { |
461 | dev_dbg(adapter->dev, "info: network found in scan" | 214 | dev_dbg(adapter->dev, "info: network found in scan" |
462 | " list. Joining...\n"); | 215 | " list. Joining...\n"); |
463 | ret = mwifiex_adhoc_join(priv, wait, | 216 | ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); |
464 | &adapter->scan_table[i]); | ||
465 | if (ret) | 217 | if (ret) |
466 | return ret; | 218 | return ret; |
467 | } else { /* i >= 0 */ | 219 | } else { |
468 | dev_dbg(adapter->dev, "info: Network not found in " | 220 | dev_dbg(adapter->dev, "info: Network not found in " |
469 | "the list, creating adhoc with ssid = %s\n", | 221 | "the list, creating adhoc with ssid = %s\n", |
470 | ssid_bssid->ssid.ssid); | 222 | ssid_bssid->ssid.ssid); |
471 | ret = mwifiex_adhoc_start(priv, wait, | 223 | ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid); |
472 | &ssid_bssid->ssid); | ||
473 | if (ret) | 224 | if (ret) |
474 | return ret; | 225 | return ret; |
475 | } | 226 | } |
476 | } | 227 | } |
477 | 228 | ||
478 | if (!ret) | ||
479 | ret = -EINPROGRESS; | ||
480 | |||
481 | return ret; | 229 | return ret; |
482 | } | 230 | } |
483 | 231 | ||
484 | /* | 232 | /* |
485 | * Sends IOCTL request to connect with a BSS. | ||
486 | * | ||
487 | * This function allocates the IOCTL request buffer, fills it | ||
488 | * with requisite parameters and calls the IOCTL handler. | ||
489 | */ | ||
490 | int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option, | ||
491 | struct mwifiex_ssid_bssid *ssid_bssid) | ||
492 | { | ||
493 | struct mwifiex_wait_queue *wait = NULL; | ||
494 | struct mwifiex_ssid_bssid tmp_ssid_bssid; | ||
495 | int status = 0; | ||
496 | |||
497 | /* Stop the O.S. TX queue if needed */ | ||
498 | if (!netif_queue_stopped(priv->netdev)) | ||
499 | netif_stop_queue(priv->netdev); | ||
500 | |||
501 | /* Allocate wait buffer */ | ||
502 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
503 | if (!wait) | ||
504 | return -ENOMEM; | ||
505 | |||
506 | if (ssid_bssid) | ||
507 | memcpy(&tmp_ssid_bssid, ssid_bssid, | ||
508 | sizeof(struct mwifiex_ssid_bssid)); | ||
509 | status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid); | ||
510 | |||
511 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
512 | |||
513 | kfree(wait); | ||
514 | return status; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * IOCTL request handler to set host sleep configuration. | 233 | * IOCTL request handler to set host sleep configuration. |
519 | * | 234 | * |
520 | * This function prepares the correct firmware command and | 235 | * This function prepares the correct firmware command and |
521 | * issues it. | 236 | * issues it. |
522 | */ | 237 | */ |
523 | static int | 238 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, |
524 | mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | 239 | int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) |
525 | struct mwifiex_wait_queue *wait, | 240 | |
526 | u16 action, struct mwifiex_ds_hs_cfg *hs_cfg) | ||
527 | { | 241 | { |
528 | struct mwifiex_adapter *adapter = priv->adapter; | 242 | struct mwifiex_adapter *adapter = priv->adapter; |
529 | int status = 0; | 243 | int status = 0; |
530 | u32 prev_cond = 0; | 244 | u32 prev_cond = 0; |
531 | 245 | ||
246 | if (!hs_cfg) | ||
247 | return -ENOMEM; | ||
248 | |||
532 | switch (action) { | 249 | switch (action) { |
533 | case HostCmd_ACT_GEN_SET: | 250 | case HostCmd_ACT_GEN_SET: |
534 | if (adapter->pps_uapsd_mode) { | 251 | if (adapter->pps_uapsd_mode) { |
@@ -561,12 +278,16 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | |||
561 | status = -1; | 278 | status = -1; |
562 | break; | 279 | break; |
563 | } | 280 | } |
564 | status = mwifiex_prepare_cmd(priv, | 281 | if (cmd_type == MWIFIEX_SYNC_CMD) |
565 | HostCmd_CMD_802_11_HS_CFG_ENH, | 282 | status = mwifiex_send_cmd_sync(priv, |
566 | HostCmd_ACT_GEN_SET, | 283 | HostCmd_CMD_802_11_HS_CFG_ENH, |
567 | 0, wait, &adapter->hs_cfg); | 284 | HostCmd_ACT_GEN_SET, 0, |
568 | if (!status) | 285 | &adapter->hs_cfg); |
569 | status = -EINPROGRESS; | 286 | else |
287 | status = mwifiex_send_cmd_async(priv, | ||
288 | HostCmd_CMD_802_11_HS_CFG_ENH, | ||
289 | HostCmd_ACT_GEN_SET, 0, | ||
290 | &adapter->hs_cfg); | ||
570 | if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) | 291 | if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) |
571 | /* Restore previous condition */ | 292 | /* Restore previous condition */ |
572 | adapter->hs_cfg.conditions = | 293 | adapter->hs_cfg.conditions = |
@@ -592,53 +313,20 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | |||
592 | } | 313 | } |
593 | 314 | ||
594 | /* | 315 | /* |
595 | * Sends IOCTL request to set Host Sleep parameters. | ||
596 | * | ||
597 | * This function allocates the IOCTL request buffer, fills it | ||
598 | * with requisite parameters and calls the IOCTL handler. | ||
599 | */ | ||
600 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | ||
601 | u8 wait_option, | ||
602 | struct mwifiex_ds_hs_cfg *hscfg) | ||
603 | { | ||
604 | int ret = 0; | ||
605 | struct mwifiex_wait_queue *wait = NULL; | ||
606 | |||
607 | if (!hscfg) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | /* Allocate wait buffer */ | ||
611 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
612 | if (!wait) | ||
613 | return -ENOMEM; | ||
614 | |||
615 | ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg); | ||
616 | |||
617 | ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); | ||
618 | |||
619 | if (wait && (ret != -EINPROGRESS)) | ||
620 | kfree(wait); | ||
621 | return ret; | ||
622 | } | ||
623 | |||
624 | /* | ||
625 | * Sends IOCTL request to cancel the existing Host Sleep configuration. | 316 | * Sends IOCTL request to cancel the existing Host Sleep configuration. |
626 | * | 317 | * |
627 | * This function allocates the IOCTL request buffer, fills it | 318 | * This function allocates the IOCTL request buffer, fills it |
628 | * with requisite parameters and calls the IOCTL handler. | 319 | * with requisite parameters and calls the IOCTL handler. |
629 | */ | 320 | */ |
630 | int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) | 321 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) |
631 | { | 322 | { |
632 | int ret = 0; | ||
633 | struct mwifiex_ds_hs_cfg hscfg; | 323 | struct mwifiex_ds_hs_cfg hscfg; |
634 | 324 | ||
635 | /* Cancel Host Sleep */ | ||
636 | hscfg.conditions = HOST_SLEEP_CFG_CANCEL; | 325 | hscfg.conditions = HOST_SLEEP_CFG_CANCEL; |
637 | hscfg.is_invoke_hostcmd = true; | 326 | hscfg.is_invoke_hostcmd = true; |
638 | ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, | ||
639 | wait_option, &hscfg); | ||
640 | 327 | ||
641 | return ret; | 328 | return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, |
329 | cmd_type, &hscfg); | ||
642 | } | 330 | } |
643 | EXPORT_SYMBOL_GPL(mwifiex_cancel_hs); | 331 | EXPORT_SYMBOL_GPL(mwifiex_cancel_hs); |
644 | 332 | ||
@@ -657,7 +345,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
657 | return true; | 345 | return true; |
658 | } | 346 | } |
659 | 347 | ||
660 | /* Enable Host Sleep */ | ||
661 | adapter->hs_activate_wait_q_woken = false; | 348 | adapter->hs_activate_wait_q_woken = false; |
662 | 349 | ||
663 | memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); | 350 | memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); |
@@ -665,8 +352,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
665 | 352 | ||
666 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, | 353 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, |
667 | MWIFIEX_BSS_ROLE_STA), | 354 | MWIFIEX_BSS_ROLE_STA), |
668 | HostCmd_ACT_GEN_SET, | 355 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, |
669 | MWIFIEX_IOCTL_WAIT, &hscfg)) { | 356 | &hscfg)) { |
670 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); | 357 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); |
671 | return false; | 358 | return false; |
672 | } | 359 | } |
@@ -679,69 +366,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
679 | EXPORT_SYMBOL_GPL(mwifiex_enable_hs); | 366 | EXPORT_SYMBOL_GPL(mwifiex_enable_hs); |
680 | 367 | ||
681 | /* | 368 | /* |
682 | * IOCTL request handler to get signal information. | ||
683 | * | ||
684 | * This function prepares the correct firmware command and | ||
685 | * issues it to get the signal (RSSI) information. | ||
686 | * | ||
687 | * This only works in the connected mode. | ||
688 | */ | ||
689 | static int mwifiex_get_info_signal(struct mwifiex_private *priv, | ||
690 | struct mwifiex_wait_queue *wait, | ||
691 | struct mwifiex_ds_get_signal *signal) | ||
692 | { | ||
693 | int ret = 0; | ||
694 | |||
695 | if (!wait) { | ||
696 | dev_err(priv->adapter->dev, "WAIT information is not present\n"); | ||
697 | return -1; | ||
698 | } | ||
699 | |||
700 | /* Signal info can be obtained only if connected */ | ||
701 | if (!priv->media_connected) { | ||
702 | dev_dbg(priv->adapter->dev, | ||
703 | "info: Can not get signal in disconnected state\n"); | ||
704 | return -1; | ||
705 | } | ||
706 | |||
707 | /* Send request to firmware */ | ||
708 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO, | ||
709 | HostCmd_ACT_GEN_GET, 0, wait, signal); | ||
710 | |||
711 | if (!ret) | ||
712 | ret = -EINPROGRESS; | ||
713 | |||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * IOCTL request handler to get statistics. | ||
719 | * | ||
720 | * This function prepares the correct firmware command and | ||
721 | * issues it to get the statistics (RSSI) information. | ||
722 | */ | ||
723 | static int mwifiex_get_info_stats(struct mwifiex_private *priv, | ||
724 | struct mwifiex_wait_queue *wait, | ||
725 | struct mwifiex_ds_get_stats *log) | ||
726 | { | ||
727 | int ret = 0; | ||
728 | |||
729 | if (!wait) { | ||
730 | dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n"); | ||
731 | return -1; | ||
732 | } | ||
733 | |||
734 | /* Send request to firmware */ | ||
735 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG, | ||
736 | HostCmd_ACT_GEN_GET, 0, wait, log); | ||
737 | |||
738 | if (!ret) | ||
739 | ret = -EINPROGRESS; | ||
740 | |||
741 | return ret; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * IOCTL request handler to get BSS information. | 369 | * IOCTL request handler to get BSS information. |
746 | * | 370 | * |
747 | * This function collates the information from different driver structures | 371 | * This function collates the information from different driver structures |
@@ -757,23 +381,17 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
757 | if (!info) | 381 | if (!info) |
758 | return -1; | 382 | return -1; |
759 | 383 | ||
760 | /* Get current BSS info */ | ||
761 | bss_desc = &priv->curr_bss_params.bss_descriptor; | 384 | bss_desc = &priv->curr_bss_params.bss_descriptor; |
762 | 385 | ||
763 | /* BSS mode */ | ||
764 | info->bss_mode = priv->bss_mode; | 386 | info->bss_mode = priv->bss_mode; |
765 | 387 | ||
766 | /* SSID */ | ||
767 | memcpy(&info->ssid, &bss_desc->ssid, | 388 | memcpy(&info->ssid, &bss_desc->ssid, |
768 | sizeof(struct mwifiex_802_11_ssid)); | 389 | sizeof(struct mwifiex_802_11_ssid)); |
769 | 390 | ||
770 | /* BSSID */ | ||
771 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); | 391 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); |
772 | 392 | ||
773 | /* Channel */ | ||
774 | info->bss_chan = bss_desc->channel; | 393 | info->bss_chan = bss_desc->channel; |
775 | 394 | ||
776 | /* Region code */ | ||
777 | info->region_code = adapter->region_code; | 395 | info->region_code = adapter->region_code; |
778 | 396 | ||
779 | /* Scan table index if connected */ | 397 | /* Scan table index if connected */ |
@@ -787,20 +405,15 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
787 | info->scan_table_idx = tbl_idx; | 405 | info->scan_table_idx = tbl_idx; |
788 | } | 406 | } |
789 | 407 | ||
790 | /* Connection status */ | ||
791 | info->media_connected = priv->media_connected; | 408 | info->media_connected = priv->media_connected; |
792 | 409 | ||
793 | /* Tx power information */ | ||
794 | info->max_power_level = priv->max_tx_power_level; | 410 | info->max_power_level = priv->max_tx_power_level; |
795 | info->min_power_level = priv->min_tx_power_level; | 411 | info->min_power_level = priv->min_tx_power_level; |
796 | 412 | ||
797 | /* AdHoc state */ | ||
798 | info->adhoc_state = priv->adhoc_state; | 413 | info->adhoc_state = priv->adhoc_state; |
799 | 414 | ||
800 | /* Last beacon NF */ | ||
801 | info->bcn_nf_last = priv->bcn_nf_last; | 415 | info->bcn_nf_last = priv->bcn_nf_last; |
802 | 416 | ||
803 | /* wep status */ | ||
804 | if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) | 417 | if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) |
805 | info->wep_status = true; | 418 | info->wep_status = true; |
806 | else | 419 | else |
@@ -813,90 +426,20 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
813 | } | 426 | } |
814 | 427 | ||
815 | /* | 428 | /* |
816 | * IOCTL request handler to get extended version information. | 429 | * The function sets band configurations. |
817 | * | 430 | * |
818 | * This function prepares the correct firmware command and | 431 | * it performs extra checks to make sure the Ad-Hoc |
819 | * issues it to get the extended version information. | ||
820 | */ | ||
821 | static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv, | ||
822 | struct mwifiex_wait_queue *wait, | ||
823 | struct mwifiex_ver_ext *ver_ext) | ||
824 | { | ||
825 | int ret = 0; | ||
826 | |||
827 | /* Send request to firmware */ | ||
828 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT, | ||
829 | HostCmd_ACT_GEN_GET, 0, wait, ver_ext); | ||
830 | if (!ret) | ||
831 | ret = -EINPROGRESS; | ||
832 | |||
833 | return ret; | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * IOCTL request handler to set/get SNMP MIB parameters. | ||
838 | * | ||
839 | * This function prepares the correct firmware command and | ||
840 | * issues it. | ||
841 | * | ||
842 | * Currently the following parameters are supported - | ||
843 | * Set/get RTS Threshold | ||
844 | * Set/get fragmentation threshold | ||
845 | * Set/get retry count | ||
846 | */ | ||
847 | int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv, | ||
848 | struct mwifiex_wait_queue *wait, | ||
849 | u32 cmd_oid, u16 action, u32 *value) | ||
850 | { | ||
851 | int ret = 0; | ||
852 | |||
853 | if (!value) | ||
854 | return -1; | ||
855 | |||
856 | /* Send request to firmware */ | ||
857 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, | ||
858 | action, cmd_oid, wait, value); | ||
859 | |||
860 | if (!ret) | ||
861 | ret = -EINPROGRESS; | ||
862 | |||
863 | return ret; | ||
864 | } | ||
865 | |||
866 | /* | ||
867 | * IOCTL request handler to set/get band configurations. | ||
868 | * | ||
869 | * For SET operation, it performs extra checks to make sure the Ad-Hoc | ||
870 | * band and channel are compatible. Otherwise it returns an error. | 432 | * band and channel are compatible. Otherwise it returns an error. |
871 | * | 433 | * |
872 | * For GET operation, this function retrieves the following information - | ||
873 | * - Infra bands | ||
874 | * - Ad-hoc band | ||
875 | * - Ad-hoc channel | ||
876 | * - Secondary channel offset | ||
877 | */ | 434 | */ |
878 | int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, | 435 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, |
879 | u16 action, | 436 | struct mwifiex_ds_band_cfg *radio_cfg) |
880 | struct mwifiex_ds_band_cfg *radio_cfg) | ||
881 | { | 437 | { |
882 | struct mwifiex_adapter *adapter = priv->adapter; | 438 | struct mwifiex_adapter *adapter = priv->adapter; |
883 | u8 infra_band = 0; | 439 | u8 infra_band = 0; |
884 | u8 adhoc_band = 0; | 440 | u8 adhoc_band = 0; |
885 | u32 adhoc_channel = 0; | 441 | u32 adhoc_channel = 0; |
886 | 442 | ||
887 | if (action == HostCmd_ACT_GEN_GET) { | ||
888 | /* Infra Bands */ | ||
889 | radio_cfg->config_bands = adapter->config_bands; | ||
890 | /* Adhoc Band */ | ||
891 | radio_cfg->adhoc_start_band = adapter->adhoc_start_band; | ||
892 | /* Adhoc channel */ | ||
893 | radio_cfg->adhoc_channel = priv->adhoc_channel; | ||
894 | /* Secondary channel offset */ | ||
895 | radio_cfg->sec_chan_offset = adapter->chan_offset; | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | /* For action = SET */ | ||
900 | infra_band = (u8) radio_cfg->config_bands; | 443 | infra_band = (u8) radio_cfg->config_bands; |
901 | adhoc_band = (u8) radio_cfg->adhoc_start_band; | 444 | adhoc_band = (u8) radio_cfg->adhoc_start_band; |
902 | adhoc_channel = radio_cfg->adhoc_channel; | 445 | adhoc_channel = radio_cfg->adhoc_channel; |
@@ -950,8 +493,8 @@ int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, | |||
950 | * This function performs validity checking on channel/frequency | 493 | * This function performs validity checking on channel/frequency |
951 | * compatibility and returns failure if not valid. | 494 | * compatibility and returns failure if not valid. |
952 | */ | 495 | */ |
953 | int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | 496 | int mwifiex_bss_set_channel(struct mwifiex_private *priv, |
954 | struct mwifiex_chan_freq_power *chan) | 497 | struct mwifiex_chan_freq_power *chan) |
955 | { | 498 | { |
956 | struct mwifiex_adapter *adapter = priv->adapter; | 499 | struct mwifiex_adapter *adapter = priv->adapter; |
957 | struct mwifiex_chan_freq_power *cfp = NULL; | 500 | struct mwifiex_chan_freq_power *cfp = NULL; |
@@ -959,16 +502,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | |||
959 | if (!chan) | 502 | if (!chan) |
960 | return -1; | 503 | return -1; |
961 | 504 | ||
962 | if (action == HostCmd_ACT_GEN_GET) { | ||
963 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, | ||
964 | priv->curr_bss_params.band, | ||
965 | (u16) priv->curr_bss_params.bss_descriptor. | ||
966 | channel); | ||
967 | chan->channel = cfp->channel; | ||
968 | chan->freq = cfp->freq; | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | if (!chan->channel && !chan->freq) | 505 | if (!chan->channel && !chan->freq) |
973 | return -1; | 506 | return -1; |
974 | if (adapter->adhoc_start_band & BAND_AN) | 507 | if (adapter->adhoc_start_band & BAND_AN) |
@@ -1024,27 +557,19 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | |||
1024 | * issues it to set or get the ad-hoc channel. | 557 | * issues it to set or get the ad-hoc channel. |
1025 | */ | 558 | */ |
1026 | static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | 559 | static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, |
1027 | struct mwifiex_wait_queue *wait, | ||
1028 | u16 action, u16 *channel) | 560 | u16 action, u16 *channel) |
1029 | { | 561 | { |
1030 | int ret = 0; | ||
1031 | |||
1032 | if (action == HostCmd_ACT_GEN_GET) { | 562 | if (action == HostCmd_ACT_GEN_GET) { |
1033 | if (!priv->media_connected) { | 563 | if (!priv->media_connected) { |
1034 | *channel = priv->adhoc_channel; | 564 | *channel = priv->adhoc_channel; |
1035 | return ret; | 565 | return 0; |
1036 | } | 566 | } |
1037 | } else { | 567 | } else { |
1038 | priv->adhoc_channel = (u8) *channel; | 568 | priv->adhoc_channel = (u8) *channel; |
1039 | } | 569 | } |
1040 | 570 | ||
1041 | /* Send request to firmware */ | 571 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, |
1042 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, | 572 | action, 0, channel); |
1043 | action, 0, wait, channel); | ||
1044 | if (!ret) | ||
1045 | ret = -EINPROGRESS; | ||
1046 | |||
1047 | return ret; | ||
1048 | } | 573 | } |
1049 | 574 | ||
1050 | /* | 575 | /* |
@@ -1054,11 +579,9 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
1054 | * these are provided, just the best BSS (best RSSI) is returned. | 579 | * these are provided, just the best BSS (best RSSI) is returned. |
1055 | */ | 580 | */ |
1056 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, | 581 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, |
1057 | struct mwifiex_wait_queue *wait, | ||
1058 | struct mwifiex_ssid_bssid *ssid_bssid) | 582 | struct mwifiex_ssid_bssid *ssid_bssid) |
1059 | { | 583 | { |
1060 | struct mwifiex_adapter *adapter = priv->adapter; | 584 | struct mwifiex_adapter *adapter = priv->adapter; |
1061 | int ret = 0; | ||
1062 | struct mwifiex_bssdescriptor *bss_desc; | 585 | struct mwifiex_bssdescriptor *bss_desc; |
1063 | u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; | 586 | u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; |
1064 | u8 mac[ETH_ALEN]; | 587 | u8 mac[ETH_ALEN]; |
@@ -1087,10 +610,10 @@ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, | |||
1087 | bss_desc = &adapter->scan_table[i]; | 610 | bss_desc = &adapter->scan_table[i]; |
1088 | memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN); | 611 | memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN); |
1089 | } else { | 612 | } else { |
1090 | ret = mwifiex_find_best_network(priv, ssid_bssid); | 613 | return mwifiex_find_best_network(priv, ssid_bssid); |
1091 | } | 614 | } |
1092 | 615 | ||
1093 | return ret; | 616 | return 0; |
1094 | } | 617 | } |
1095 | 618 | ||
1096 | /* | 619 | /* |
@@ -1114,10 +637,7 @@ int | |||
1114 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | 637 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) |
1115 | { | 638 | { |
1116 | int ret = 0; | 639 | int ret = 0; |
1117 | int status = 0; | ||
1118 | struct mwifiex_bss_info bss_info; | 640 | struct mwifiex_bss_info bss_info; |
1119 | struct mwifiex_wait_queue *wait = NULL; | ||
1120 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1121 | struct mwifiex_ssid_bssid ssid_bssid; | 641 | struct mwifiex_ssid_bssid ssid_bssid; |
1122 | u16 curr_chan = 0; | 642 | u16 curr_chan = 0; |
1123 | 643 | ||
@@ -1127,19 +647,10 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1127 | if (mwifiex_get_bss_info(priv, &bss_info)) | 647 | if (mwifiex_get_bss_info(priv, &bss_info)) |
1128 | return -1; | 648 | return -1; |
1129 | 649 | ||
1130 | /* Allocate wait buffer */ | ||
1131 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1132 | if (!wait) | ||
1133 | return -ENOMEM; | ||
1134 | |||
1135 | /* Get current channel */ | 650 | /* Get current channel */ |
1136 | status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, | 651 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, |
1137 | &curr_chan); | 652 | &curr_chan); |
1138 | 653 | ||
1139 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | ||
1140 | ret = -1; | ||
1141 | goto done; | ||
1142 | } | ||
1143 | if (curr_chan == channel) { | 654 | if (curr_chan == channel) { |
1144 | ret = 0; | 655 | ret = 0; |
1145 | goto done; | 656 | goto done; |
@@ -1154,23 +665,13 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1154 | 665 | ||
1155 | /* Do disonnect */ | 666 | /* Do disonnect */ |
1156 | memset(&ssid_bssid, 0, ETH_ALEN); | 667 | memset(&ssid_bssid, 0, ETH_ALEN); |
1157 | status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); | 668 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); |
1158 | |||
1159 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | ||
1160 | ret = -1; | ||
1161 | goto done; | ||
1162 | } | ||
1163 | 669 | ||
1164 | status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET, | 670 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, |
1165 | (u16 *) &channel); | 671 | (u16 *) &channel); |
1166 | |||
1167 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | ||
1168 | ret = -1; | ||
1169 | goto done; | ||
1170 | } | ||
1171 | 672 | ||
1172 | /* Do specific SSID scanning */ | 673 | /* Do specific SSID scanning */ |
1173 | if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { | 674 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { |
1174 | ret = -1; | 675 | ret = -1; |
1175 | goto done; | 676 | goto done; |
1176 | } | 677 | } |
@@ -1179,13 +680,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1179 | memcpy(&ssid_bssid.ssid, &bss_info.ssid, | 680 | memcpy(&ssid_bssid.ssid, &bss_info.ssid, |
1180 | sizeof(struct mwifiex_802_11_ssid)); | 681 | sizeof(struct mwifiex_802_11_ssid)); |
1181 | 682 | ||
1182 | status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); | 683 | ret = mwifiex_bss_start(priv, &ssid_bssid); |
1183 | |||
1184 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
1185 | ret = -1; | ||
1186 | |||
1187 | done: | 684 | done: |
1188 | kfree(wait); | ||
1189 | return ret; | 685 | return ret; |
1190 | } | 686 | } |
1191 | 687 | ||
@@ -1198,11 +694,9 @@ done: | |||
1198 | * for the band. | 694 | * for the band. |
1199 | */ | 695 | */ |
1200 | static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | 696 | static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, |
1201 | struct mwifiex_wait_queue *wait, | ||
1202 | struct mwifiex_rate_cfg *rate_cfg) | 697 | struct mwifiex_rate_cfg *rate_cfg) |
1203 | { | 698 | { |
1204 | struct mwifiex_adapter *adapter = priv->adapter; | 699 | struct mwifiex_adapter *adapter = priv->adapter; |
1205 | int ret = 0; | ||
1206 | 700 | ||
1207 | rate_cfg->is_rate_auto = priv->is_data_rate_auto; | 701 | rate_cfg->is_rate_auto = priv->is_data_rate_auto; |
1208 | if (!priv->media_connected) { | 702 | if (!priv->media_connected) { |
@@ -1241,15 +735,12 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | |||
1241 | break; | 735 | break; |
1242 | } | 736 | } |
1243 | } else { | 737 | } else { |
1244 | /* Send request to firmware */ | 738 | return mwifiex_send_cmd_sync(priv, |
1245 | ret = mwifiex_prepare_cmd(priv, | 739 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
1246 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 740 | HostCmd_ACT_GEN_GET, 0, NULL); |
1247 | HostCmd_ACT_GEN_GET, 0, wait, NULL); | ||
1248 | if (!ret) | ||
1249 | ret = -EINPROGRESS; | ||
1250 | } | 741 | } |
1251 | 742 | ||
1252 | return ret; | 743 | return 0; |
1253 | } | 744 | } |
1254 | 745 | ||
1255 | /* | 746 | /* |
@@ -1261,7 +752,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | |||
1261 | * The function also performs validation checking on the supplied value. | 752 | * The function also performs validation checking on the supplied value. |
1262 | */ | 753 | */ |
1263 | static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | 754 | static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, |
1264 | struct mwifiex_wait_queue *wait, | ||
1265 | struct mwifiex_rate_cfg *rate_cfg) | 755 | struct mwifiex_rate_cfg *rate_cfg) |
1266 | { | 756 | { |
1267 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 757 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
@@ -1299,8 +789,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1299 | } | 789 | } |
1300 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); | 790 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); |
1301 | 791 | ||
1302 | rate_index = | 792 | rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); |
1303 | mwifiex_data_rate_to_index(adapter, rate_cfg->rate); | ||
1304 | 793 | ||
1305 | /* Only allow b/g rates to be set */ | 794 | /* Only allow b/g rates to be set */ |
1306 | if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && | 795 | if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && |
@@ -1315,11 +804,8 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1315 | } | 804 | } |
1316 | } | 805 | } |
1317 | 806 | ||
1318 | /* Send request to firmware */ | 807 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, |
1319 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, | 808 | HostCmd_ACT_GEN_SET, 0, bitmap_rates); |
1320 | HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); | ||
1321 | if (!ret) | ||
1322 | ret = -EINPROGRESS; | ||
1323 | 809 | ||
1324 | return ret; | 810 | return ret; |
1325 | } | 811 | } |
@@ -1331,7 +817,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1331 | * rate index. | 817 | * rate index. |
1332 | */ | 818 | */ |
1333 | static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, | 819 | static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, |
1334 | struct mwifiex_wait_queue *wait, | ||
1335 | struct mwifiex_rate_cfg *rate_cfg) | 820 | struct mwifiex_rate_cfg *rate_cfg) |
1336 | { | 821 | { |
1337 | int status = 0; | 822 | int status = 0; |
@@ -1340,11 +825,9 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, | |||
1340 | return -1; | 825 | return -1; |
1341 | 826 | ||
1342 | if (rate_cfg->action == HostCmd_ACT_GEN_GET) | 827 | if (rate_cfg->action == HostCmd_ACT_GEN_GET) |
1343 | status = mwifiex_rate_ioctl_get_rate_value( | 828 | status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); |
1344 | priv, wait, rate_cfg); | ||
1345 | else | 829 | else |
1346 | status = mwifiex_rate_ioctl_set_rate_value( | 830 | status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); |
1347 | priv, wait, rate_cfg); | ||
1348 | 831 | ||
1349 | return status; | 832 | return status; |
1350 | } | 833 | } |
@@ -1359,30 +842,21 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
1359 | struct mwifiex_rate_cfg *rate) | 842 | struct mwifiex_rate_cfg *rate) |
1360 | { | 843 | { |
1361 | int ret = 0; | 844 | int ret = 0; |
1362 | struct mwifiex_wait_queue *wait = NULL; | ||
1363 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1364 | |||
1365 | /* Allocate wait buffer */ | ||
1366 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1367 | if (!wait) | ||
1368 | return -ENOMEM; | ||
1369 | 845 | ||
1370 | memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); | 846 | memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); |
1371 | rate->action = HostCmd_ACT_GEN_GET; | 847 | rate->action = HostCmd_ACT_GEN_GET; |
1372 | ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); | 848 | ret = mwifiex_rate_ioctl_cfg(priv, rate); |
1373 | 849 | ||
1374 | ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); | ||
1375 | if (!ret) { | 850 | if (!ret) { |
1376 | if (rate && rate->is_rate_auto) | 851 | if (rate && rate->is_rate_auto) |
1377 | rate->rate = mwifiex_index_to_data_rate(priv->adapter, | 852 | rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, |
1378 | priv->tx_rate, priv->tx_htinfo); | 853 | priv->tx_htinfo); |
1379 | else if (rate) | 854 | else if (rate) |
1380 | rate->rate = priv->data_rate; | 855 | rate->rate = priv->data_rate; |
1381 | } else { | 856 | } else { |
1382 | ret = -1; | 857 | ret = -1; |
1383 | } | 858 | } |
1384 | 859 | ||
1385 | kfree(wait); | ||
1386 | return ret; | 860 | return ret; |
1387 | } | 861 | } |
1388 | 862 | ||
@@ -1398,9 +872,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
1398 | * - Modulation class HTBW20 | 872 | * - Modulation class HTBW20 |
1399 | * - Modulation class HTBW40 | 873 | * - Modulation class HTBW40 |
1400 | */ | 874 | */ |
1401 | static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | 875 | int mwifiex_set_tx_power(struct mwifiex_private *priv, |
1402 | struct mwifiex_wait_queue *wait, | 876 | struct mwifiex_power_cfg *power_cfg) |
1403 | struct mwifiex_power_cfg *power_cfg) | ||
1404 | { | 877 | { |
1405 | int ret = 0; | 878 | int ret = 0; |
1406 | struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; | 879 | struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; |
@@ -1472,13 +945,10 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | |||
1472 | pg->power_max = (s8) dbm; | 945 | pg->power_max = (s8) dbm; |
1473 | pg->ht_bandwidth = HT_BW_40; | 946 | pg->ht_bandwidth = HT_BW_40; |
1474 | } | 947 | } |
1475 | /* Send request to firmware */ | 948 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, |
1476 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, | 949 | HostCmd_ACT_GEN_SET, 0, buf); |
1477 | HostCmd_ACT_GEN_SET, 0, wait, buf); | ||
1478 | if (!ret) | ||
1479 | ret = -EINPROGRESS; | ||
1480 | kfree(buf); | ||
1481 | 950 | ||
951 | kfree(buf); | ||
1482 | return ret; | 952 | return ret; |
1483 | } | 953 | } |
1484 | 954 | ||
@@ -1488,33 +958,23 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | |||
1488 | * This function prepares the correct firmware command and | 958 | * This function prepares the correct firmware command and |
1489 | * issues it. | 959 | * issues it. |
1490 | */ | 960 | */ |
1491 | static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, | 961 | int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) |
1492 | struct mwifiex_wait_queue *wait, | ||
1493 | u32 *ps_mode, u16 action) | ||
1494 | { | 962 | { |
1495 | int ret = 0; | 963 | int ret = 0; |
1496 | struct mwifiex_adapter *adapter = priv->adapter; | 964 | struct mwifiex_adapter *adapter = priv->adapter; |
1497 | u16 sub_cmd; | 965 | u16 sub_cmd; |
1498 | 966 | ||
1499 | if (action == HostCmd_ACT_GEN_SET) { | 967 | if (*ps_mode) |
1500 | if (*ps_mode) | 968 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; |
1501 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; | 969 | else |
1502 | else | 970 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; |
1503 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; | 971 | sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; |
1504 | sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; | 972 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, |
1505 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | 973 | sub_cmd, BITMAP_STA_PS, NULL); |
1506 | sub_cmd, BITMAP_STA_PS, wait, NULL); | 974 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) |
1507 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) | 975 | ret = mwifiex_send_cmd_async(priv, |
1508 | ret = mwifiex_prepare_cmd(priv, | 976 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, |
1509 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, | 977 | 0, NULL); |
1510 | 0, NULL, NULL); | ||
1511 | } else { | ||
1512 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | ||
1513 | GET_PS, 0, wait, NULL); | ||
1514 | } | ||
1515 | |||
1516 | if (!ret) | ||
1517 | ret = -EINPROGRESS; | ||
1518 | 978 | ||
1519 | return ret; | 979 | return ret; |
1520 | } | 980 | } |
@@ -1600,20 +1060,13 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, | |||
1600 | * This function prepares the correct firmware command and | 1060 | * This function prepares the correct firmware command and |
1601 | * issues it. | 1061 | * issues it. |
1602 | */ | 1062 | */ |
1603 | static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, | 1063 | static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, |
1604 | struct mwifiex_wait_queue *wait, | ||
1605 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1064 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1606 | { | 1065 | { |
1607 | int ret = 0; | ||
1608 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1609 | 1066 | ||
1610 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1067 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, |
1611 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1068 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1612 | wait, encrypt_key); | 1069 | encrypt_key); |
1613 | if (!ret) | ||
1614 | ret = -EINPROGRESS; | ||
1615 | |||
1616 | return ret; | ||
1617 | } | 1070 | } |
1618 | 1071 | ||
1619 | /* | 1072 | /* |
@@ -1622,12 +1075,10 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, | |||
1622 | * This function prepares the correct firmware command and | 1075 | * This function prepares the correct firmware command and |
1623 | * issues it, after validation checks. | 1076 | * issues it, after validation checks. |
1624 | */ | 1077 | */ |
1625 | static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | 1078 | static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, |
1626 | struct mwifiex_wait_queue *wait, | ||
1627 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1079 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1628 | { | 1080 | { |
1629 | int ret = 0; | 1081 | int ret = 0; |
1630 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1631 | struct mwifiex_wep_key *wep_key = NULL; | 1082 | struct mwifiex_wep_key *wep_key = NULL; |
1632 | int index; | 1083 | int index; |
1633 | 1084 | ||
@@ -1641,7 +1092,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1641 | /* Copy the required key as the current key */ | 1092 | /* Copy the required key as the current key */ |
1642 | wep_key = &priv->wep_key[index]; | 1093 | wep_key = &priv->wep_key[index]; |
1643 | if (!wep_key->key_length) { | 1094 | if (!wep_key->key_length) { |
1644 | dev_err(adapter->dev, | 1095 | dev_err(priv->adapter->dev, |
1645 | "key not set, so cannot enable it\n"); | 1096 | "key not set, so cannot enable it\n"); |
1646 | return -1; | 1097 | return -1; |
1647 | } | 1098 | } |
@@ -1649,7 +1100,6 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1649 | priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; | 1100 | priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; |
1650 | } else { | 1101 | } else { |
1651 | wep_key = &priv->wep_key[index]; | 1102 | wep_key = &priv->wep_key[index]; |
1652 | /* Cleanup */ | ||
1653 | memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); | 1103 | memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); |
1654 | /* Copy the key in the driver */ | 1104 | /* Copy the key in the driver */ |
1655 | memcpy(wep_key->key_material, | 1105 | memcpy(wep_key->key_material, |
@@ -1661,8 +1111,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1661 | } | 1111 | } |
1662 | if (wep_key->key_length) { | 1112 | if (wep_key->key_length) { |
1663 | /* Send request to firmware */ | 1113 | /* Send request to firmware */ |
1664 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1114 | ret = mwifiex_send_cmd_async(priv, |
1665 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 1115 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1116 | HostCmd_ACT_GEN_SET, 0, NULL); | ||
1666 | if (ret) | 1117 | if (ret) |
1667 | return ret; | 1118 | return ret; |
1668 | } | 1119 | } |
@@ -1671,12 +1122,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1671 | else | 1122 | else |
1672 | priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; | 1123 | priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; |
1673 | 1124 | ||
1674 | /* Send request to firmware */ | 1125 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, |
1675 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1126 | HostCmd_ACT_GEN_SET, 0, |
1676 | HostCmd_ACT_GEN_SET, 0, wait, | 1127 | &priv->curr_pkt_filter); |
1677 | &priv->curr_pkt_filter); | ||
1678 | if (!ret) | ||
1679 | ret = -EINPROGRESS; | ||
1680 | 1128 | ||
1681 | return ret; | 1129 | return ret; |
1682 | } | 1130 | } |
@@ -1691,18 +1139,16 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1691 | * | 1139 | * |
1692 | * This function can also be used to disable a currently set key. | 1140 | * This function can also be used to disable a currently set key. |
1693 | */ | 1141 | */ |
1694 | static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | 1142 | static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, |
1695 | struct mwifiex_wait_queue *wait, | ||
1696 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1143 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1697 | { | 1144 | { |
1698 | int ret = 0; | 1145 | int ret = 0; |
1699 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1700 | u8 remove_key = false; | 1146 | u8 remove_key = false; |
1701 | struct host_cmd_ds_802_11_key_material *ibss_key; | 1147 | struct host_cmd_ds_802_11_key_material *ibss_key; |
1702 | 1148 | ||
1703 | /* Current driver only supports key length of up to 32 bytes */ | 1149 | /* Current driver only supports key length of up to 32 bytes */ |
1704 | if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { | 1150 | if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) { |
1705 | dev_err(adapter->dev, "key length too long\n"); | 1151 | dev_err(priv->adapter->dev, "key length too long\n"); |
1706 | return -1; | 1152 | return -1; |
1707 | } | 1153 | } |
1708 | 1154 | ||
@@ -1713,9 +1159,10 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1713 | */ | 1159 | */ |
1714 | /* Send the key as PTK to firmware */ | 1160 | /* Send the key as PTK to firmware */ |
1715 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; | 1161 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; |
1716 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1162 | ret = mwifiex_send_cmd_async(priv, |
1717 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1163 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1718 | NULL, encrypt_key); | 1164 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1165 | encrypt_key); | ||
1719 | if (ret) | 1166 | if (ret) |
1720 | return ret; | 1167 | return ret; |
1721 | 1168 | ||
@@ -1729,8 +1176,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1729 | sizeof(ibss_key->key_param_set.key_len)); | 1176 | sizeof(ibss_key->key_param_set.key_len)); |
1730 | ibss_key->key_param_set.key_type_id | 1177 | ibss_key->key_param_set.key_type_id |
1731 | = cpu_to_le16(KEY_TYPE_ID_TKIP); | 1178 | = cpu_to_le16(KEY_TYPE_ID_TKIP); |
1732 | ibss_key->key_param_set.key_info | 1179 | ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED); |
1733 | = cpu_to_le16(KEY_INFO_TKIP_ENABLED); | ||
1734 | 1180 | ||
1735 | /* Send the key as GTK to firmware */ | 1181 | /* Send the key as GTK to firmware */ |
1736 | encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; | 1182 | encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; |
@@ -1740,19 +1186,15 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1740 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; | 1186 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; |
1741 | 1187 | ||
1742 | if (remove_key) | 1188 | if (remove_key) |
1743 | /* Send request to firmware */ | 1189 | ret = mwifiex_send_cmd_sync(priv, |
1744 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1190 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1745 | HostCmd_ACT_GEN_SET, | 1191 | HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), |
1746 | !(KEY_INFO_ENABLED), | 1192 | encrypt_key); |
1747 | wait, encrypt_key); | ||
1748 | else | 1193 | else |
1749 | /* Send request to firmware */ | 1194 | ret = mwifiex_send_cmd_sync(priv, |
1750 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1195 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1751 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1196 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1752 | wait, encrypt_key); | 1197 | encrypt_key); |
1753 | |||
1754 | if (!ret) | ||
1755 | ret = -EINPROGRESS; | ||
1756 | 1198 | ||
1757 | return ret; | 1199 | return ret; |
1758 | } | 1200 | } |
@@ -1765,21 +1207,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1765 | */ | 1207 | */ |
1766 | static int | 1208 | static int |
1767 | mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, | 1209 | mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, |
1768 | struct mwifiex_wait_queue *wait, | ||
1769 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1210 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1770 | { | 1211 | { |
1771 | int status = 0; | 1212 | int status = 0; |
1772 | struct mwifiex_adapter *adapter = priv->adapter; | ||
1773 | 1213 | ||
1774 | if (encrypt_key->is_wapi_key) | 1214 | if (encrypt_key->is_wapi_key) |
1775 | status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, | 1215 | status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); |
1776 | encrypt_key); | ||
1777 | else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) | 1216 | else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) |
1778 | status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, | 1217 | status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key); |
1779 | encrypt_key); | ||
1780 | else | 1218 | else |
1781 | status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, | 1219 | status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key); |
1782 | encrypt_key); | ||
1783 | return status; | 1220 | return status; |
1784 | } | 1221 | } |
1785 | 1222 | ||
@@ -1807,94 +1244,30 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, | |||
1807 | } | 1244 | } |
1808 | 1245 | ||
1809 | /* | 1246 | /* |
1810 | * Sends IOCTL request to set Tx power. It can be set to either auto | ||
1811 | * or a fixed value. | ||
1812 | * | ||
1813 | * This function allocates the IOCTL request buffer, fills it | ||
1814 | * with requisite parameters and calls the IOCTL handler. | ||
1815 | */ | ||
1816 | int | ||
1817 | mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm) | ||
1818 | { | ||
1819 | struct mwifiex_power_cfg power_cfg; | ||
1820 | struct mwifiex_wait_queue *wait = NULL; | ||
1821 | int status = 0; | ||
1822 | int ret = 0; | ||
1823 | |||
1824 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1825 | if (!wait) | ||
1826 | return -ENOMEM; | ||
1827 | |||
1828 | if (type == NL80211_TX_POWER_FIXED) { | ||
1829 | power_cfg.is_power_auto = 0; | ||
1830 | power_cfg.power_level = dbm; | ||
1831 | } else { | ||
1832 | power_cfg.is_power_auto = 1; | ||
1833 | } | ||
1834 | status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg); | ||
1835 | |||
1836 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
1837 | |||
1838 | kfree(wait); | ||
1839 | return ret; | ||
1840 | } | ||
1841 | |||
1842 | /* | ||
1843 | * Sends IOCTL request to get scan table. | ||
1844 | * | ||
1845 | * This function allocates the IOCTL request buffer, fills it | ||
1846 | * with requisite parameters and calls the IOCTL handler. | ||
1847 | */ | ||
1848 | int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, | ||
1849 | struct mwifiex_scan_resp *scan_resp) | ||
1850 | { | ||
1851 | struct mwifiex_wait_queue *wait = NULL; | ||
1852 | struct mwifiex_scan_resp scan; | ||
1853 | int status = 0; | ||
1854 | |||
1855 | /* Allocate wait buffer */ | ||
1856 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1857 | if (!wait) | ||
1858 | return -ENOMEM; | ||
1859 | |||
1860 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET, | ||
1861 | NULL, &scan); | ||
1862 | |||
1863 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
1864 | if (!status) { | ||
1865 | if (scan_resp) | ||
1866 | memcpy(scan_resp, &scan, | ||
1867 | sizeof(struct mwifiex_scan_resp)); | ||
1868 | } | ||
1869 | |||
1870 | if (wait && (status != -EINPROGRESS)) | ||
1871 | kfree(wait); | ||
1872 | return status; | ||
1873 | } | ||
1874 | |||
1875 | /* | ||
1876 | * Sends IOCTL request to get signal information. | 1247 | * Sends IOCTL request to get signal information. |
1877 | * | 1248 | * |
1878 | * This function allocates the IOCTL request buffer, fills it | 1249 | * This function allocates the IOCTL request buffer, fills it |
1879 | * with requisite parameters and calls the IOCTL handler. | 1250 | * with requisite parameters and calls the IOCTL handler. |
1880 | */ | 1251 | */ |
1881 | int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | 1252 | int mwifiex_get_signal_info(struct mwifiex_private *priv, |
1882 | struct mwifiex_ds_get_signal *signal) | 1253 | struct mwifiex_ds_get_signal *signal) |
1883 | { | 1254 | { |
1884 | struct mwifiex_ds_get_signal info; | 1255 | struct mwifiex_ds_get_signal info; |
1885 | struct mwifiex_wait_queue *wait = NULL; | ||
1886 | int status = 0; | 1256 | int status = 0; |
1887 | 1257 | ||
1888 | /* Allocate wait buffer */ | 1258 | memset(&info, 0, sizeof(struct mwifiex_ds_get_signal)); |
1889 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1890 | if (!wait) | ||
1891 | return -ENOMEM; | ||
1892 | |||
1893 | info.selector = ALL_RSSI_INFO_MASK; | 1259 | info.selector = ALL_RSSI_INFO_MASK; |
1894 | 1260 | ||
1895 | status = mwifiex_get_info_signal(priv, wait, &info); | 1261 | /* Signal info can be obtained only if connected */ |
1262 | if (!priv->media_connected) { | ||
1263 | dev_dbg(priv->adapter->dev, | ||
1264 | "info: Can not get signal in disconnected state\n"); | ||
1265 | return -1; | ||
1266 | } | ||
1267 | |||
1268 | status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, | ||
1269 | HostCmd_ACT_GEN_GET, 0, signal); | ||
1896 | 1270 | ||
1897 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
1898 | if (!status) { | 1271 | if (!status) { |
1899 | if (signal) | 1272 | if (signal) |
1900 | memcpy(signal, &info, | 1273 | memcpy(signal, &info, |
@@ -1905,8 +1278,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | |||
1905 | priv->w_stats.qual.noise = info.bcn_nf_avg; | 1278 | priv->w_stats.qual.noise = info.bcn_nf_avg; |
1906 | } | 1279 | } |
1907 | 1280 | ||
1908 | if (wait && (status != -EINPROGRESS)) | ||
1909 | kfree(wait); | ||
1910 | return status; | 1281 | return status; |
1911 | } | 1282 | } |
1912 | 1283 | ||
@@ -1919,14 +1290,7 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | |||
1919 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 1290 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
1920 | int key_len, u8 key_index, int disable) | 1291 | int key_len, u8 key_index, int disable) |
1921 | { | 1292 | { |
1922 | struct mwifiex_wait_queue *wait = NULL; | ||
1923 | struct mwifiex_ds_encrypt_key encrypt_key; | 1293 | struct mwifiex_ds_encrypt_key encrypt_key; |
1924 | int status = 0; | ||
1925 | int ret = 0; | ||
1926 | |||
1927 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1928 | if (!wait) | ||
1929 | return -ENOMEM; | ||
1930 | 1294 | ||
1931 | memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); | 1295 | memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); |
1932 | encrypt_key.key_len = key_len; | 1296 | encrypt_key.key_len = key_len; |
@@ -1938,41 +1302,7 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | |||
1938 | encrypt_key.key_disable = true; | 1302 | encrypt_key.key_disable = true; |
1939 | } | 1303 | } |
1940 | 1304 | ||
1941 | status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); | 1305 | return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); |
1942 | |||
1943 | if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) | ||
1944 | ret = -EFAULT; | ||
1945 | |||
1946 | kfree(wait); | ||
1947 | return ret; | ||
1948 | } | ||
1949 | |||
1950 | /* | ||
1951 | * Sends IOCTL request to set power management parameters. | ||
1952 | * | ||
1953 | * This function allocates the IOCTL request buffer, fills it | ||
1954 | * with requisite parameters and calls the IOCTL handler. | ||
1955 | */ | ||
1956 | int | ||
1957 | mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on) | ||
1958 | { | ||
1959 | int ret = 0; | ||
1960 | int status = 0; | ||
1961 | struct mwifiex_wait_queue *wait = NULL; | ||
1962 | u32 ps_mode; | ||
1963 | |||
1964 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1965 | if (!wait) | ||
1966 | return -ENOMEM; | ||
1967 | |||
1968 | ps_mode = power_on; | ||
1969 | status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode, | ||
1970 | HostCmd_ACT_GEN_SET); | ||
1971 | |||
1972 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
1973 | |||
1974 | kfree(wait); | ||
1975 | return ret; | ||
1976 | } | 1306 | } |
1977 | 1307 | ||
1978 | /* | 1308 | /* |
@@ -1985,27 +1315,13 @@ int | |||
1985 | mwifiex_get_ver_ext(struct mwifiex_private *priv) | 1315 | mwifiex_get_ver_ext(struct mwifiex_private *priv) |
1986 | { | 1316 | { |
1987 | struct mwifiex_ver_ext ver_ext; | 1317 | struct mwifiex_ver_ext ver_ext; |
1988 | struct mwifiex_wait_queue *wait = NULL; | ||
1989 | int status = 0; | ||
1990 | int ret = 0; | ||
1991 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1992 | 1318 | ||
1993 | /* Allocate wait buffer */ | ||
1994 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1995 | if (!wait) | ||
1996 | return -ENOMEM; | ||
1997 | |||
1998 | /* get fw version */ | ||
1999 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); | 1319 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); |
2000 | status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); | 1320 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, |
2001 | 1321 | HostCmd_ACT_GEN_GET, 0, &ver_ext)) | |
2002 | ret = mwifiex_request_ioctl(priv, wait, status, wait_option); | 1322 | return -1; |
2003 | |||
2004 | if (ret) | ||
2005 | ret = -1; | ||
2006 | 1323 | ||
2007 | kfree(wait); | 1324 | return 0; |
2008 | return ret; | ||
2009 | } | 1325 | } |
2010 | 1326 | ||
2011 | /* | 1327 | /* |
@@ -2019,21 +1335,12 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2019 | struct mwifiex_ds_get_stats *log) | 1335 | struct mwifiex_ds_get_stats *log) |
2020 | { | 1336 | { |
2021 | int ret = 0; | 1337 | int ret = 0; |
2022 | int status = 0; | ||
2023 | struct mwifiex_wait_queue *wait = NULL; | ||
2024 | struct mwifiex_ds_get_stats get_log; | 1338 | struct mwifiex_ds_get_stats get_log; |
2025 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
2026 | |||
2027 | /* Allocate wait buffer */ | ||
2028 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
2029 | if (!wait) | ||
2030 | return -ENOMEM; | ||
2031 | 1339 | ||
2032 | memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); | 1340 | memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); |
2033 | status = mwifiex_get_info_stats(priv, wait, &get_log); | 1341 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, |
1342 | HostCmd_ACT_GEN_GET, 0, &get_log); | ||
2034 | 1343 | ||
2035 | /* Send IOCTL request to MWIFIEX */ | ||
2036 | ret = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
2037 | if (!ret) { | 1344 | if (!ret) { |
2038 | if (log) | 1345 | if (log) |
2039 | memcpy(log, &get_log, sizeof(struct | 1346 | memcpy(log, &get_log, sizeof(struct |
@@ -2043,7 +1350,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2043 | priv->w_stats.discard.misc = get_log.ack_failure; | 1350 | priv->w_stats.discard.misc = get_log.ack_failure; |
2044 | } | 1351 | } |
2045 | 1352 | ||
2046 | kfree(wait); | ||
2047 | return ret; | 1353 | return ret; |
2048 | } | 1354 | } |
2049 | 1355 | ||
@@ -2061,11 +1367,9 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2061 | * - CAU | 1367 | * - CAU |
2062 | */ | 1368 | */ |
2063 | static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, | 1369 | static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, |
2064 | struct mwifiex_wait_queue *wait, | ||
2065 | struct mwifiex_ds_reg_rw *reg_rw, | 1370 | struct mwifiex_ds_reg_rw *reg_rw, |
2066 | u16 action) | 1371 | u16 action) |
2067 | { | 1372 | { |
2068 | int ret = 0; | ||
2069 | u16 cmd_no; | 1373 | u16 cmd_no; |
2070 | 1374 | ||
2071 | switch (le32_to_cpu(reg_rw->type)) { | 1375 | switch (le32_to_cpu(reg_rw->type)) { |
@@ -2088,13 +1392,8 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, | |||
2088 | return -1; | 1392 | return -1; |
2089 | } | 1393 | } |
2090 | 1394 | ||
2091 | /* Send request to firmware */ | 1395 | return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); |
2092 | ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); | ||
2093 | |||
2094 | if (!ret) | ||
2095 | ret = -EINPROGRESS; | ||
2096 | 1396 | ||
2097 | return ret; | ||
2098 | } | 1397 | } |
2099 | 1398 | ||
2100 | /* | 1399 | /* |
@@ -2107,25 +1406,13 @@ int | |||
2107 | mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, | 1406 | mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, |
2108 | u32 reg_offset, u32 reg_value) | 1407 | u32 reg_offset, u32 reg_value) |
2109 | { | 1408 | { |
2110 | int ret = 0; | ||
2111 | int status = 0; | ||
2112 | struct mwifiex_wait_queue *wait = NULL; | ||
2113 | struct mwifiex_ds_reg_rw reg_rw; | 1409 | struct mwifiex_ds_reg_rw reg_rw; |
2114 | 1410 | ||
2115 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2116 | if (!wait) | ||
2117 | return -ENOMEM; | ||
2118 | |||
2119 | reg_rw.type = cpu_to_le32(reg_type); | 1411 | reg_rw.type = cpu_to_le32(reg_type); |
2120 | reg_rw.offset = cpu_to_le32(reg_offset); | 1412 | reg_rw.offset = cpu_to_le32(reg_offset); |
2121 | reg_rw.value = cpu_to_le32(reg_value); | 1413 | reg_rw.value = cpu_to_le32(reg_value); |
2122 | status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, | ||
2123 | HostCmd_ACT_GEN_SET); | ||
2124 | |||
2125 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
2126 | 1414 | ||
2127 | kfree(wait); | 1415 | return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); |
2128 | return ret; | ||
2129 | } | 1416 | } |
2130 | 1417 | ||
2131 | /* | 1418 | /* |
@@ -2139,50 +1426,18 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, | |||
2139 | u32 reg_offset, u32 *value) | 1426 | u32 reg_offset, u32 *value) |
2140 | { | 1427 | { |
2141 | int ret = 0; | 1428 | int ret = 0; |
2142 | int status = 0; | ||
2143 | struct mwifiex_wait_queue *wait = NULL; | ||
2144 | struct mwifiex_ds_reg_rw reg_rw; | 1429 | struct mwifiex_ds_reg_rw reg_rw; |
2145 | 1430 | ||
2146 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2147 | if (!wait) | ||
2148 | return -ENOMEM; | ||
2149 | |||
2150 | reg_rw.type = cpu_to_le32(reg_type); | 1431 | reg_rw.type = cpu_to_le32(reg_type); |
2151 | reg_rw.offset = cpu_to_le32(reg_offset); | 1432 | reg_rw.offset = cpu_to_le32(reg_offset); |
2152 | status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, | 1433 | ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); |
2153 | HostCmd_ACT_GEN_GET); | ||
2154 | 1434 | ||
2155 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
2156 | if (ret) | 1435 | if (ret) |
2157 | goto done; | 1436 | goto done; |
2158 | 1437 | ||
2159 | *value = le32_to_cpu(reg_rw.value); | 1438 | *value = le32_to_cpu(reg_rw.value); |
2160 | 1439 | ||
2161 | done: | 1440 | done: |
2162 | kfree(wait); | ||
2163 | return ret; | ||
2164 | } | ||
2165 | |||
2166 | /* | ||
2167 | * IOCTL request handler to read EEPROM. | ||
2168 | * | ||
2169 | * This function prepares the correct firmware command and | ||
2170 | * issues it. | ||
2171 | */ | ||
2172 | static int | ||
2173 | mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv, | ||
2174 | struct mwifiex_wait_queue *wait, | ||
2175 | struct mwifiex_ds_read_eeprom *rd_eeprom) | ||
2176 | { | ||
2177 | int ret = 0; | ||
2178 | |||
2179 | /* Send request to firmware */ | ||
2180 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, | ||
2181 | HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom); | ||
2182 | |||
2183 | if (!ret) | ||
2184 | ret = -EINPROGRESS; | ||
2185 | |||
2186 | return ret; | 1441 | return ret; |
2187 | } | 1442 | } |
2188 | 1443 | ||
@@ -2197,25 +1452,17 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, | |||
2197 | u8 *value) | 1452 | u8 *value) |
2198 | { | 1453 | { |
2199 | int ret = 0; | 1454 | int ret = 0; |
2200 | int status = 0; | ||
2201 | struct mwifiex_wait_queue *wait = NULL; | ||
2202 | struct mwifiex_ds_read_eeprom rd_eeprom; | 1455 | struct mwifiex_ds_read_eeprom rd_eeprom; |
2203 | 1456 | ||
2204 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2205 | if (!wait) | ||
2206 | return -ENOMEM; | ||
2207 | |||
2208 | rd_eeprom.offset = cpu_to_le16((u16) offset); | 1457 | rd_eeprom.offset = cpu_to_le16((u16) offset); |
2209 | rd_eeprom.byte_count = cpu_to_le16((u16) bytes); | 1458 | rd_eeprom.byte_count = cpu_to_le16((u16) bytes); |
2210 | status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom); | ||
2211 | 1459 | ||
2212 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | 1460 | /* Send request to firmware */ |
2213 | if (ret) | 1461 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, |
2214 | goto done; | 1462 | HostCmd_ACT_GEN_GET, 0, &rd_eeprom); |
2215 | 1463 | ||
2216 | memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); | 1464 | if (!ret) |
2217 | done: | 1465 | memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); |
2218 | kfree(wait); | ||
2219 | return ret; | 1466 | return ret; |
2220 | } | 1467 | } |
2221 | 1468 | ||
@@ -2344,7 +1591,6 @@ int | |||
2344 | mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) | 1591 | mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) |
2345 | { | 1592 | { |
2346 | struct mwifiex_ds_misc_gen_ie gen_ie; | 1593 | struct mwifiex_ds_misc_gen_ie gen_ie; |
2347 | int status = 0; | ||
2348 | 1594 | ||
2349 | if (ie_len > IW_CUSTOM_MAX) | 1595 | if (ie_len > IW_CUSTOM_MAX) |
2350 | return -EFAULT; | 1596 | return -EFAULT; |
@@ -2352,8 +1598,7 @@ mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) | |||
2352 | gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; | 1598 | gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; |
2353 | gen_ie.len = ie_len; | 1599 | gen_ie.len = ie_len; |
2354 | memcpy(gen_ie.ie_data, ie, ie_len); | 1600 | memcpy(gen_ie.ie_data, ie, ie_len); |
2355 | status = mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET); | 1601 | if (mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET)) |
2356 | if (status) | ||
2357 | return -EFAULT; | 1602 | return -EFAULT; |
2358 | 1603 | ||
2359 | return 0; | 1604 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index e8db6bd021c6..5d37ef160121 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c | |||
@@ -51,7 +51,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, | |||
51 | if (!skb->len) { | 51 | if (!skb->len) { |
52 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", | 52 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", |
53 | skb->len); | 53 | skb->len); |
54 | tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; | 54 | tx_info->status_code = -1; |
55 | return skb->data; | 55 | return skb->data; |
56 | } | 56 | } |
57 | 57 | ||
@@ -180,15 +180,11 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) | |||
180 | { | 180 | { |
181 | struct mwifiex_adapter *adapter = priv->adapter; | 181 | struct mwifiex_adapter *adapter = priv->adapter; |
182 | u8 ret = false; | 182 | u8 ret = false; |
183 | u8 prop_ps = true; | ||
184 | 183 | ||
185 | if (!adapter->sleep_period.period) | 184 | if (!adapter->sleep_period.period) |
186 | return ret; | 185 | return ret; |
187 | if (mwifiex_wmm_lists_empty(adapter)) { | 186 | if (mwifiex_wmm_lists_empty(adapter)) |
188 | if ((priv->curr_bss_params.wmm_uapsd_enabled && | ||
189 | priv->wmm_qosinfo) || prop_ps) | ||
190 | ret = true; | 187 | ret = true; |
191 | } | ||
192 | 188 | ||
193 | if (ret && !adapter->cmd_sent && !adapter->curr_cmd | 189 | if (ret && !adapter->cmd_sent && !adapter->curr_cmd |
194 | && !is_command_pending(adapter)) { | 190 | && !is_command_pending(adapter)) { |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index f06923cb1c4b..ce772e078db8 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -36,7 +36,6 @@ | |||
36 | int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, | 36 | int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, |
37 | struct sk_buff *skb) | 37 | struct sk_buff *skb) |
38 | { | 38 | { |
39 | int ret = 0; | ||
40 | struct mwifiex_private *priv = | 39 | struct mwifiex_private *priv = |
41 | mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 40 | mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
42 | struct rxpd *local_rx_pd; | 41 | struct rxpd *local_rx_pd; |
@@ -50,9 +49,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, | |||
50 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 49 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
51 | 50 | ||
52 | rx_info->bss_index = priv->bss_index; | 51 | rx_info->bss_index = priv->bss_index; |
53 | ret = mwifiex_process_sta_rx_packet(adapter, skb); | ||
54 | 52 | ||
55 | return ret; | 53 | return mwifiex_process_sta_rx_packet(adapter, skb); |
56 | } | 54 | } |
57 | EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); | 55 | EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); |
58 | 56 | ||
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 205022aa52f5..7ab4fb279f8a 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c | |||
@@ -55,18 +55,12 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * IOCTL request handler to send function init/shutdown command | 58 | * This function sends init/shutdown command |
59 | * to firmware. | 59 | * to firmware. |
60 | * | ||
61 | * This function prepares the correct firmware command and | ||
62 | * issues it. | ||
63 | */ | 60 | */ |
64 | int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | 61 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
65 | struct mwifiex_wait_queue *wait, | 62 | u32 func_init_shutdown) |
66 | u32 func_init_shutdown) | ||
67 | { | 63 | { |
68 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
69 | int ret; | ||
70 | u16 cmd; | 64 | u16 cmd; |
71 | 65 | ||
72 | if (func_init_shutdown == MWIFIEX_FUNC_INIT) { | 66 | if (func_init_shutdown == MWIFIEX_FUNC_INIT) { |
@@ -74,19 +68,13 @@ int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | |||
74 | } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { | 68 | } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { |
75 | cmd = HostCmd_CMD_FUNC_SHUTDOWN; | 69 | cmd = HostCmd_CMD_FUNC_SHUTDOWN; |
76 | } else { | 70 | } else { |
77 | dev_err(adapter->dev, "unsupported parameter\n"); | 71 | dev_err(priv->adapter->dev, "unsupported parameter\n"); |
78 | return -1; | 72 | return -1; |
79 | } | 73 | } |
80 | 74 | ||
81 | /* Send command to firmware */ | 75 | return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); |
82 | ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, | ||
83 | 0, wait, NULL); | ||
84 | |||
85 | if (!ret) | ||
86 | ret = -EINPROGRESS; | ||
87 | |||
88 | return ret; | ||
89 | } | 76 | } |
77 | EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); | ||
90 | 78 | ||
91 | /* | 79 | /* |
92 | * IOCTL request handler to set/get debug information. | 80 | * IOCTL request handler to set/get debug information. |
@@ -222,31 +210,18 @@ int mwifiex_recv_complete(struct mwifiex_adapter *adapter, | |||
222 | * corresponding waiting function. Otherwise, it processes the | 210 | * corresponding waiting function. Otherwise, it processes the |
223 | * IOCTL response and frees the response buffer. | 211 | * IOCTL response and frees the response buffer. |
224 | */ | 212 | */ |
225 | int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, | 213 | int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) |
226 | struct mwifiex_wait_queue *wait_queue, | ||
227 | int status) | ||
228 | { | 214 | { |
229 | enum mwifiex_error_code status_code = | 215 | atomic_dec(&adapter->cmd_pending); |
230 | (enum mwifiex_error_code) wait_queue->status; | 216 | dev_dbg(adapter->dev, "cmd completed: status=%d\n", |
231 | 217 | adapter->cmd_wait_q.status); | |
232 | atomic_dec(&adapter->ioctl_pending); | ||
233 | 218 | ||
234 | dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," | 219 | adapter->cmd_wait_q.condition = true; |
235 | " status_code=%#x\n", status, status_code); | ||
236 | 220 | ||
237 | if (wait_queue->enabled) { | 221 | if (adapter->cmd_wait_q.status == -ETIMEDOUT) |
238 | *wait_queue->condition = true; | 222 | dev_err(adapter->dev, "cmd timeout\n"); |
239 | wait_queue->status = status; | 223 | else |
240 | if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) | 224 | wake_up_interruptible(&adapter->cmd_wait_q.wait); |
241 | dev_err(adapter->dev, "cmd timeout\n"); | ||
242 | else | ||
243 | wake_up_interruptible(wait_queue->wait); | ||
244 | } else { | ||
245 | if (status) | ||
246 | dev_err(adapter->dev, "cmd failed: status_code=%#x\n", | ||
247 | status_code); | ||
248 | kfree(wait_queue); | ||
249 | } | ||
250 | 225 | ||
251 | return 0; | 226 | return 0; |
252 | } | 227 | } |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 1cfbc6bed692..c009370f309e 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -177,8 +177,7 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) | |||
177 | * This function map ACs to TIDs. | 177 | * This function map ACs to TIDs. |
178 | */ | 178 | */ |
179 | static void | 179 | static void |
180 | mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, | 180 | mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) |
181 | u8 queue_priority[]) | ||
182 | { | 181 | { |
183 | int i; | 182 | int i; |
184 | 183 | ||
@@ -247,7 +246,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, | |||
247 | } | 246 | } |
248 | } | 247 | } |
249 | 248 | ||
250 | mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); | 249 | mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); |
251 | } | 250 | } |
252 | 251 | ||
253 | /* | 252 | /* |
@@ -416,7 +415,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) | |||
416 | priv = adapter->priv[j]; | 415 | priv = adapter->priv[j]; |
417 | if (priv) { | 416 | if (priv) { |
418 | for (i = 0; i < MAX_NUM_TID; i++) | 417 | for (i = 0; i < MAX_NUM_TID; i++) |
419 | if (!mwifiex_wmm_is_ra_list_empty(adapter, | 418 | if (!mwifiex_wmm_is_ra_list_empty( |
420 | &priv->wmm.tid_tbl_ptr[i].ra_list)) | 419 | &priv->wmm.tid_tbl_ptr[i].ra_list)) |
421 | return false; | 420 | return false; |
422 | } | 421 | } |
@@ -974,7 +973,6 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
974 | struct sk_buff *skb, *skb_next; | 973 | struct sk_buff *skb, *skb_next; |
975 | struct mwifiex_tx_param tx_param; | 974 | struct mwifiex_tx_param tx_param; |
976 | struct mwifiex_adapter *adapter = priv->adapter; | 975 | struct mwifiex_adapter *adapter = priv->adapter; |
977 | int status = 0; | ||
978 | struct mwifiex_txinfo *tx_info; | 976 | struct mwifiex_txinfo *tx_info; |
979 | 977 | ||
980 | if (skb_queue_empty(&ptr->skb_head)) { | 978 | if (skb_queue_empty(&ptr->skb_head)) { |
@@ -1001,9 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
1001 | tx_param.next_pkt_len = ((skb_next) ? skb_next->len + | 999 | tx_param.next_pkt_len = ((skb_next) ? skb_next->len + |
1002 | sizeof(struct txpd) : 0); | 1000 | sizeof(struct txpd) : 0); |
1003 | 1001 | ||
1004 | status = mwifiex_process_tx(priv, skb, &tx_param); | 1002 | if (mwifiex_process_tx(priv, skb, &tx_param) == -EBUSY) { |
1005 | |||
1006 | if (status == -EBUSY) { | ||
1007 | /* Queue the packet back at the head */ | 1003 | /* Queue the packet back at the head */ |
1008 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); | 1004 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); |
1009 | 1005 | ||
@@ -1161,7 +1157,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1161 | if (!ptr) | 1157 | if (!ptr) |
1162 | return -1; | 1158 | return -1; |
1163 | 1159 | ||
1164 | tid = mwifiex_get_tid(priv->adapter, ptr); | 1160 | tid = mwifiex_get_tid(ptr); |
1165 | 1161 | ||
1166 | dev_dbg(adapter->dev, "data: tid=%d\n", tid); | 1162 | dev_dbg(adapter->dev, "data: tid=%d\n", tid); |
1167 | 1163 | ||
@@ -1186,14 +1182,14 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1186 | /* ra_list_spinlock has been freed in | 1182 | /* ra_list_spinlock has been freed in |
1187 | mwifiex_send_single_packet() */ | 1183 | mwifiex_send_single_packet() */ |
1188 | } else { | 1184 | } else { |
1189 | if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { | 1185 | if (mwifiex_is_ampdu_allowed(priv, tid)) { |
1190 | if (mwifiex_is_ba_stream_avail(priv)) { | 1186 | if (mwifiex_space_avail_for_new_ba_stream(adapter)) { |
1191 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1187 | mwifiex_11n_create_tx_ba_stream_tbl(priv, |
1192 | ptr->ra, tid, | 1188 | ptr->ra, tid, |
1193 | BA_STREAM_SETUP_INPROGRESS); | 1189 | BA_STREAM_SETUP_INPROGRESS); |
1194 | mwifiex_send_addba(priv, tid, ptr->ra); | 1190 | mwifiex_send_addba(priv, tid, ptr->ra); |
1195 | } else if (mwifiex_find_stream_to_delete | 1191 | } else if (mwifiex_find_stream_to_delete |
1196 | (priv, ptr, tid, &tid_del, ra)) { | 1192 | (priv, tid, &tid_del, ra)) { |
1197 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1193 | mwifiex_11n_create_tx_ba_stream_tbl(priv, |
1198 | ptr->ra, tid, | 1194 | ptr->ra, tid, |
1199 | BA_STREAM_SETUP_INPROGRESS); | 1195 | BA_STREAM_SETUP_INPROGRESS); |
@@ -1202,7 +1198,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1202 | } | 1198 | } |
1203 | /* Minimum number of AMSDU */ | 1199 | /* Minimum number of AMSDU */ |
1204 | #define MIN_NUM_AMSDU 2 | 1200 | #define MIN_NUM_AMSDU 2 |
1205 | if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && | 1201 | if (mwifiex_is_amsdu_allowed(priv, tid) && |
1206 | (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= | 1202 | (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= |
1207 | MIN_NUM_AMSDU)) | 1203 | MIN_NUM_AMSDU)) |
1208 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, | 1204 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, |
@@ -1232,6 +1228,4 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) | |||
1232 | if (mwifiex_dequeue_tx_packet(adapter)) | 1228 | if (mwifiex_dequeue_tx_packet(adapter)) |
1233 | break; | 1229 | break; |
1234 | } while (true); | 1230 | } while (true); |
1235 | |||
1236 | return; | ||
1237 | } | 1231 | } |
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 241f1b0b77f9..fcea1f68792f 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h | |||
@@ -35,8 +35,7 @@ enum ieee_types_wmm_ecw_bitmasks { | |||
35 | * This function retrieves the TID of the given RA list. | 35 | * This function retrieves the TID of the given RA list. |
36 | */ | 36 | */ |
37 | static inline int | 37 | static inline int |
38 | mwifiex_get_tid(struct mwifiex_adapter *adapter, | 38 | mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr) |
39 | struct mwifiex_ra_list_tbl *ptr) | ||
40 | { | 39 | { |
41 | struct sk_buff *skb; | 40 | struct sk_buff *skb; |
42 | 41 | ||
@@ -52,7 +51,7 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter, | |||
52 | * This function gets the length of a list. | 51 | * This function gets the length of a list. |
53 | */ | 52 | */ |
54 | static inline int | 53 | static inline int |
55 | mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) | 54 | mwifiex_wmm_list_len(struct list_head *head) |
56 | { | 55 | { |
57 | struct list_head *pos; | 56 | struct list_head *pos; |
58 | int count = 0; | 57 | int count = 0; |
@@ -67,8 +66,7 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) | |||
67 | * This function checks if a RA list is empty or not. | 66 | * This function checks if a RA list is empty or not. |
68 | */ | 67 | */ |
69 | static inline u8 | 68 | static inline u8 |
70 | mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, | 69 | mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) |
71 | struct list_head *ra_list_hhead) | ||
72 | { | 70 | { |
73 | struct mwifiex_ra_list_tbl *ra_list; | 71 | struct mwifiex_ra_list_tbl *ra_list; |
74 | int is_list_empty; | 72 | int is_list_empty; |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 8913180a7bd3..28ebaec80be6 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -289,10 +289,17 @@ struct mwl8k_vif { | |||
289 | #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) | 289 | #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) |
290 | #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) | 290 | #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) |
291 | 291 | ||
292 | struct tx_traffic_info { | ||
293 | u32 start_time; | ||
294 | u32 pkts; | ||
295 | }; | ||
296 | |||
297 | #define MWL8K_MAX_TID 8 | ||
292 | struct mwl8k_sta { | 298 | struct mwl8k_sta { |
293 | /* Index into station database. Returned by UPDATE_STADB. */ | 299 | /* Index into station database. Returned by UPDATE_STADB. */ |
294 | u8 peer_id; | 300 | u8 peer_id; |
295 | u8 is_ampdu_allowed; | 301 | u8 is_ampdu_allowed; |
302 | struct tx_traffic_info tx_stats[MWL8K_MAX_TID]; | ||
296 | }; | 303 | }; |
297 | #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) | 304 | #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) |
298 | 305 | ||
@@ -701,7 +708,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) | |||
701 | "helper image\n", pci_name(priv->pdev)); | 708 | "helper image\n", pci_name(priv->pdev)); |
702 | return rc; | 709 | return rc; |
703 | } | 710 | } |
704 | msleep(5); | 711 | msleep(20); |
705 | 712 | ||
706 | rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); | 713 | rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); |
707 | } else { | 714 | } else { |
@@ -823,8 +830,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) | |||
823 | /* | 830 | /* |
824 | * Make sure the packet header is in the DMA header format (4-address | 831 | * Make sure the packet header is in the DMA header format (4-address |
825 | * without QoS), the necessary crypto padding between the header and the | 832 | * without QoS), the necessary crypto padding between the header and the |
826 | * payload has already been provided by mac80211, but it doesn't add tail | 833 | * payload has already been provided by mac80211, but it doesn't add |
827 | * padding when HW crypto is enabled. | 834 | * tail padding when HW crypto is enabled. |
828 | * | 835 | * |
829 | * We have the following trailer padding requirements: | 836 | * We have the following trailer padding requirements: |
830 | * - WEP: 4 trailer bytes (ICV) | 837 | * - WEP: 4 trailer bytes (ICV) |
@@ -1487,9 +1494,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
1487 | 1494 | ||
1488 | if (timeout) { | 1495 | if (timeout) { |
1489 | WARN_ON(priv->pending_tx_pkts); | 1496 | WARN_ON(priv->pending_tx_pkts); |
1490 | if (retry) { | 1497 | if (retry) |
1491 | wiphy_notice(hw->wiphy, "tx rings drained\n"); | 1498 | wiphy_notice(hw->wiphy, "tx rings drained\n"); |
1492 | } | ||
1493 | break; | 1499 | break; |
1494 | } | 1500 | } |
1495 | 1501 | ||
@@ -1649,8 +1655,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1649 | /* Rate control is happening in the firmware. | 1655 | /* Rate control is happening in the firmware. |
1650 | * Ensure no tx rate is being reported. | 1656 | * Ensure no tx rate is being reported. |
1651 | */ | 1657 | */ |
1652 | info->status.rates[0].idx = -1; | 1658 | info->status.rates[0].idx = -1; |
1653 | info->status.rates[0].count = 1; | 1659 | info->status.rates[0].count = 1; |
1654 | 1660 | ||
1655 | if (MWL8K_TXD_SUCCESS(status)) | 1661 | if (MWL8K_TXD_SUCCESS(status)) |
1656 | info->flags |= IEEE80211_TX_STAT_ACK; | 1662 | info->flags |= IEEE80211_TX_STAT_ACK; |
@@ -1688,7 +1694,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) | |||
1688 | } | 1694 | } |
1689 | 1695 | ||
1690 | /* caller must hold priv->stream_lock when calling the stream functions */ | 1696 | /* caller must hold priv->stream_lock when calling the stream functions */ |
1691 | struct mwl8k_ampdu_stream * | 1697 | static struct mwl8k_ampdu_stream * |
1692 | mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) | 1698 | mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) |
1693 | { | 1699 | { |
1694 | struct mwl8k_ampdu_stream *stream; | 1700 | struct mwl8k_ampdu_stream *stream; |
@@ -1755,6 +1761,41 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) | |||
1755 | return NULL; | 1761 | return NULL; |
1756 | } | 1762 | } |
1757 | 1763 | ||
1764 | #define MWL8K_AMPDU_PACKET_THRESHOLD 64 | ||
1765 | static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid) | ||
1766 | { | ||
1767 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | ||
1768 | struct tx_traffic_info *tx_stats; | ||
1769 | |||
1770 | BUG_ON(tid >= MWL8K_MAX_TID); | ||
1771 | tx_stats = &sta_info->tx_stats[tid]; | ||
1772 | |||
1773 | return sta_info->is_ampdu_allowed && | ||
1774 | tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; | ||
1775 | } | ||
1776 | |||
1777 | static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) | ||
1778 | { | ||
1779 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | ||
1780 | struct tx_traffic_info *tx_stats; | ||
1781 | |||
1782 | BUG_ON(tid >= MWL8K_MAX_TID); | ||
1783 | tx_stats = &sta_info->tx_stats[tid]; | ||
1784 | |||
1785 | if (tx_stats->start_time == 0) | ||
1786 | tx_stats->start_time = jiffies; | ||
1787 | |||
1788 | /* reset the packet count after each second elapses. If the number of | ||
1789 | * packets ever exceeds the ampdu_min_traffic threshold, we will allow | ||
1790 | * an ampdu stream to be started. | ||
1791 | */ | ||
1792 | if (jiffies - tx_stats->start_time > HZ) { | ||
1793 | tx_stats->pkts = 0; | ||
1794 | tx_stats->start_time = 0; | ||
1795 | } else | ||
1796 | tx_stats->pkts++; | ||
1797 | } | ||
1798 | |||
1758 | static void | 1799 | static void |
1759 | mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | 1800 | mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) |
1760 | { | 1801 | { |
@@ -1841,6 +1882,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1841 | skb->protocol != cpu_to_be16(ETH_P_PAE) && | 1882 | skb->protocol != cpu_to_be16(ETH_P_PAE) && |
1842 | sta->ht_cap.ht_supported && priv->ap_fw) { | 1883 | sta->ht_cap.ht_supported && priv->ap_fw) { |
1843 | tid = qos & 0xf; | 1884 | tid = qos & 0xf; |
1885 | mwl8k_tx_count_packet(sta, tid); | ||
1844 | spin_lock(&priv->stream_lock); | 1886 | spin_lock(&priv->stream_lock); |
1845 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); | 1887 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); |
1846 | if (stream != NULL) { | 1888 | if (stream != NULL) { |
@@ -1881,7 +1923,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1881 | * prevents sequence number mismatch at the recepient | 1923 | * prevents sequence number mismatch at the recepient |
1882 | * as described above. | 1924 | * as described above. |
1883 | */ | 1925 | */ |
1884 | if (MWL8K_STA(sta)->is_ampdu_allowed) { | 1926 | if (mwl8k_ampdu_allowed(sta, tid)) { |
1885 | stream = mwl8k_add_stream(hw, sta, tid); | 1927 | stream = mwl8k_add_stream(hw, sta, tid); |
1886 | if (stream != NULL) | 1928 | if (stream != NULL) |
1887 | start_ba_session = true; | 1929 | start_ba_session = true; |
@@ -2657,7 +2699,7 @@ struct mwl8k_cmd_tx_power { | |||
2657 | __le16 bw; | 2699 | __le16 bw; |
2658 | __le16 sub_ch; | 2700 | __le16 sub_ch; |
2659 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; | 2701 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; |
2660 | } __attribute__((packed)); | 2702 | } __packed; |
2661 | 2703 | ||
2662 | static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, | 2704 | static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, |
2663 | struct ieee80211_conf *conf, | 2705 | struct ieee80211_conf *conf, |
@@ -3520,13 +3562,13 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, | |||
3520 | #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 | 3562 | #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 |
3521 | #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 | 3563 | #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 |
3522 | 3564 | ||
3523 | enum { | 3565 | enum ba_stream_action_type { |
3524 | MWL8K_BA_CREATE, | 3566 | MWL8K_BA_CREATE, |
3525 | MWL8K_BA_UPDATE, | 3567 | MWL8K_BA_UPDATE, |
3526 | MWL8K_BA_DESTROY, | 3568 | MWL8K_BA_DESTROY, |
3527 | MWL8K_BA_FLUSH, | 3569 | MWL8K_BA_FLUSH, |
3528 | MWL8K_BA_CHECK, | 3570 | MWL8K_BA_CHECK, |
3529 | } ba_stream_action_type; | 3571 | }; |
3530 | 3572 | ||
3531 | 3573 | ||
3532 | struct mwl8k_create_ba_stream { | 3574 | struct mwl8k_create_ba_stream { |
@@ -3780,7 +3822,7 @@ struct mwl8k_cmd_update_encryption { | |||
3780 | __u8 mac_addr[6]; | 3822 | __u8 mac_addr[6]; |
3781 | __u8 encr_type; | 3823 | __u8 encr_type; |
3782 | 3824 | ||
3783 | } __attribute__((packed)); | 3825 | } __packed; |
3784 | 3826 | ||
3785 | struct mwl8k_cmd_set_key { | 3827 | struct mwl8k_cmd_set_key { |
3786 | struct mwl8k_cmd_pkt header; | 3828 | struct mwl8k_cmd_pkt header; |
@@ -3800,7 +3842,7 @@ struct mwl8k_cmd_set_key { | |||
3800 | __le16 tkip_tsc_low; | 3842 | __le16 tkip_tsc_low; |
3801 | __le32 tkip_tsc_high; | 3843 | __le32 tkip_tsc_high; |
3802 | __u8 mac_addr[6]; | 3844 | __u8 mac_addr[6]; |
3803 | } __attribute__((packed)); | 3845 | } __packed; |
3804 | 3846 | ||
3805 | enum { | 3847 | enum { |
3806 | MWL8K_ENCR_ENABLE, | 3848 | MWL8K_ENCR_ENABLE, |
@@ -4285,6 +4327,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
4285 | 4327 | ||
4286 | /* Enable interrupts */ | 4328 | /* Enable interrupts */ |
4287 | iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 4329 | iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
4330 | iowrite32(MWL8K_A2H_EVENTS, | ||
4331 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
4288 | 4332 | ||
4289 | rc = mwl8k_fw_lock(hw); | 4333 | rc = mwl8k_fw_lock(hw); |
4290 | if (!rc) { | 4334 | if (!rc) { |
@@ -4502,7 +4546,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
4502 | struct ieee80211_bss_conf *info, u32 changed) | 4546 | struct ieee80211_bss_conf *info, u32 changed) |
4503 | { | 4547 | { |
4504 | struct mwl8k_priv *priv = hw->priv; | 4548 | struct mwl8k_priv *priv = hw->priv; |
4505 | u32 ap_legacy_rates; | 4549 | u32 ap_legacy_rates = 0; |
4506 | u8 ap_mcs_rates[16]; | 4550 | u8 ap_mcs_rates[16]; |
4507 | int rc; | 4551 | int rc; |
4508 | 4552 | ||
@@ -5283,7 +5327,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) | |||
5283 | iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| | 5327 | iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| |
5284 | MWL8K_A2H_INT_BA_WATCHDOG, | 5328 | MWL8K_A2H_INT_BA_WATCHDOG, |
5285 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); | 5329 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); |
5286 | iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | 5330 | iowrite32(MWL8K_A2H_INT_OPC_DONE, |
5331 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
5287 | 5332 | ||
5288 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 5333 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
5289 | IRQF_SHARED, MWL8K_NAME, hw); | 5334 | IRQF_SHARED, MWL8K_NAME, hw); |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index f630552427b7..c45773108283 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -59,7 +59,6 @@ config RT2800PCI | |||
59 | select RT2800_LIB | 59 | select RT2800_LIB |
60 | select RT2X00_LIB_PCI if PCI | 60 | select RT2X00_LIB_PCI if PCI |
61 | select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X | 61 | select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X |
62 | select RT2X00_LIB_HT | ||
63 | select RT2X00_LIB_FIRMWARE | 62 | select RT2X00_LIB_FIRMWARE |
64 | select RT2X00_LIB_CRYPTO | 63 | select RT2X00_LIB_CRYPTO |
65 | select CRC_CCITT | 64 | select CRC_CCITT |
@@ -74,17 +73,13 @@ config RT2800PCI | |||
74 | if RT2800PCI | 73 | if RT2800PCI |
75 | 74 | ||
76 | config RT2800PCI_RT33XX | 75 | config RT2800PCI_RT33XX |
77 | bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)" | 76 | bool "rt2800pci - Include support for rt33xx devices" |
78 | depends on EXPERIMENTAL | 77 | default y |
79 | default n | ||
80 | ---help--- | 78 | ---help--- |
81 | This adds support for rt33xx wireless chipset family to the | 79 | This adds support for rt33xx wireless chipset family to the |
82 | rt2800pci driver. | 80 | rt2800pci driver. |
83 | Supported chips: RT3390 | 81 | Supported chips: RT3390 |
84 | 82 | ||
85 | Support for these devices is non-functional at the moment and is | ||
86 | intended for testers and developers. | ||
87 | |||
88 | config RT2800PCI_RT35XX | 83 | config RT2800PCI_RT35XX |
89 | bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" | 84 | bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" |
90 | depends on EXPERIMENTAL | 85 | depends on EXPERIMENTAL |
@@ -100,15 +95,12 @@ config RT2800PCI_RT35XX | |||
100 | config RT2800PCI_RT53XX | 95 | config RT2800PCI_RT53XX |
101 | bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" | 96 | bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" |
102 | depends on EXPERIMENTAL | 97 | depends on EXPERIMENTAL |
103 | default n | 98 | default y |
104 | ---help--- | 99 | ---help--- |
105 | This adds support for rt53xx wireless chipset family to the | 100 | This adds support for rt53xx wireless chipset family to the |
106 | rt2800pci driver. | 101 | rt2800pci driver. |
107 | Supported chips: RT5390 | 102 | Supported chips: RT5390 |
108 | 103 | ||
109 | Support for these devices is non-functional at the moment and is | ||
110 | intended for testers and developers. | ||
111 | |||
112 | endif | 104 | endif |
113 | 105 | ||
114 | config RT2500USB | 106 | config RT2500USB |
@@ -140,7 +132,6 @@ config RT2800USB | |||
140 | depends on USB | 132 | depends on USB |
141 | select RT2800_LIB | 133 | select RT2800_LIB |
142 | select RT2X00_LIB_USB | 134 | select RT2X00_LIB_USB |
143 | select RT2X00_LIB_HT | ||
144 | select RT2X00_LIB_FIRMWARE | 135 | select RT2X00_LIB_FIRMWARE |
145 | select RT2X00_LIB_CRYPTO | 136 | select RT2X00_LIB_CRYPTO |
146 | select CRC_CCITT | 137 | select CRC_CCITT |
@@ -153,17 +144,13 @@ config RT2800USB | |||
153 | if RT2800USB | 144 | if RT2800USB |
154 | 145 | ||
155 | config RT2800USB_RT33XX | 146 | config RT2800USB_RT33XX |
156 | bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)" | 147 | bool "rt2800usb - Include support for rt33xx devices" |
157 | depends on EXPERIMENTAL | 148 | default y |
158 | default n | ||
159 | ---help--- | 149 | ---help--- |
160 | This adds support for rt33xx wireless chipset family to the | 150 | This adds support for rt33xx wireless chipset family to the |
161 | rt2800usb driver. | 151 | rt2800usb driver. |
162 | Supported chips: RT3370 | 152 | Supported chips: RT3370 |
163 | 153 | ||
164 | Support for these devices is non-functional at the moment and is | ||
165 | intended for testers and developers. | ||
166 | |||
167 | config RT2800USB_RT35XX | 154 | config RT2800USB_RT35XX |
168 | bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" | 155 | bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" |
169 | depends on EXPERIMENTAL | 156 | depends on EXPERIMENTAL |
@@ -207,9 +194,6 @@ config RT2X00_LIB_USB | |||
207 | config RT2X00_LIB | 194 | config RT2X00_LIB |
208 | tristate | 195 | tristate |
209 | 196 | ||
210 | config RT2X00_LIB_HT | ||
211 | boolean | ||
212 | |||
213 | config RT2X00_LIB_FIRMWARE | 197 | config RT2X00_LIB_FIRMWARE |
214 | boolean | 198 | boolean |
215 | select FW_LOADER | 199 | select FW_LOADER |
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 971339858297..349d5b8284a4 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
@@ -7,7 +7,6 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o | |||
7 | rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o | 7 | rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o |
8 | rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o | 8 | rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o |
9 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o | 9 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o |
10 | rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o | ||
11 | 10 | ||
12 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | 11 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o |
13 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | 12 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 137a24e520da..937f9e8bf05f 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1314,8 +1314,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1314 | } | 1314 | } |
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 1317 | static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
1318 | struct rt2x00_field32 irq_field) | 1318 | struct rt2x00_field32 irq_field) |
1319 | { | 1319 | { |
1320 | u32 reg; | 1320 | u32 reg; |
1321 | 1321 | ||
@@ -1536,13 +1536,13 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1536 | * Detect if this device has an hardware controlled radio. | 1536 | * Detect if this device has an hardware controlled radio. |
1537 | */ | 1537 | */ |
1538 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 1538 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
1539 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 1539 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
1540 | 1540 | ||
1541 | /* | 1541 | /* |
1542 | * Check if the BBP tuning should be enabled. | 1542 | * Check if the BBP tuning should be enabled. |
1543 | */ | 1543 | */ |
1544 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) | 1544 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) |
1545 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 1545 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
1546 | 1546 | ||
1547 | return 0; | 1547 | return 0; |
1548 | } | 1548 | } |
@@ -1640,9 +1640,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1640 | /* | 1640 | /* |
1641 | * This device requires the atim queue and DMA-mapped skbs. | 1641 | * This device requires the atim queue and DMA-mapped skbs. |
1642 | */ | 1642 | */ |
1643 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1643 | __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); |
1644 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 1644 | __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); |
1645 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | 1645 | __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); |
1646 | 1646 | ||
1647 | /* | 1647 | /* |
1648 | * Set the rssi offset. | 1648 | * Set the rssi offset. |
@@ -1720,6 +1720,9 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1720 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1720 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1721 | .rfkill_poll = rt2x00mac_rfkill_poll, | 1721 | .rfkill_poll = rt2x00mac_rfkill_poll, |
1722 | .flush = rt2x00mac_flush, | 1722 | .flush = rt2x00mac_flush, |
1723 | .set_antenna = rt2x00mac_set_antenna, | ||
1724 | .get_antenna = rt2x00mac_get_antenna, | ||
1725 | .get_ringparam = rt2x00mac_get_ringparam, | ||
1723 | }; | 1726 | }; |
1724 | 1727 | ||
1725 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | 1728 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { |
@@ -1740,6 +1743,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1740 | .start_queue = rt2400pci_start_queue, | 1743 | .start_queue = rt2400pci_start_queue, |
1741 | .kick_queue = rt2400pci_kick_queue, | 1744 | .kick_queue = rt2400pci_kick_queue, |
1742 | .stop_queue = rt2400pci_stop_queue, | 1745 | .stop_queue = rt2400pci_stop_queue, |
1746 | .flush_queue = rt2x00pci_flush_queue, | ||
1743 | .write_tx_desc = rt2400pci_write_tx_desc, | 1747 | .write_tx_desc = rt2400pci_write_tx_desc, |
1744 | .write_beacon = rt2400pci_write_beacon, | 1748 | .write_beacon = rt2400pci_write_beacon, |
1745 | .fill_rxdone = rt2400pci_fill_rxdone, | 1749 | .fill_rxdone = rt2400pci_fill_rxdone, |
@@ -1801,10 +1805,11 @@ static const struct rt2x00_ops rt2400pci_ops = { | |||
1801 | * RT2400pci module information. | 1805 | * RT2400pci module information. |
1802 | */ | 1806 | */ |
1803 | static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = { | 1807 | static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = { |
1804 | { PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) }, | 1808 | { PCI_DEVICE(0x1814, 0x0101) }, |
1805 | { 0, } | 1809 | { 0, } |
1806 | }; | 1810 | }; |
1807 | 1811 | ||
1812 | |||
1808 | MODULE_AUTHOR(DRV_PROJECT); | 1813 | MODULE_AUTHOR(DRV_PROJECT); |
1809 | MODULE_VERSION(DRV_VERSION); | 1814 | MODULE_VERSION(DRV_VERSION); |
1810 | MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); | 1815 | MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); |
@@ -1812,10 +1817,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards"); | |||
1812 | MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); | 1817 | MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); |
1813 | MODULE_LICENSE("GPL"); | 1818 | MODULE_LICENSE("GPL"); |
1814 | 1819 | ||
1820 | static int rt2400pci_probe(struct pci_dev *pci_dev, | ||
1821 | const struct pci_device_id *id) | ||
1822 | { | ||
1823 | return rt2x00pci_probe(pci_dev, &rt2400pci_ops); | ||
1824 | } | ||
1825 | |||
1815 | static struct pci_driver rt2400pci_driver = { | 1826 | static struct pci_driver rt2400pci_driver = { |
1816 | .name = KBUILD_MODNAME, | 1827 | .name = KBUILD_MODNAME, |
1817 | .id_table = rt2400pci_device_table, | 1828 | .id_table = rt2400pci_device_table, |
1818 | .probe = rt2x00pci_probe, | 1829 | .probe = rt2400pci_probe, |
1819 | .remove = __devexit_p(rt2x00pci_remove), | 1830 | .remove = __devexit_p(rt2x00pci_remove), |
1820 | .suspend = rt2x00pci_suspend, | 1831 | .suspend = rt2x00pci_suspend, |
1821 | .resume = rt2x00pci_resume, | 1832 | .resume = rt2x00pci_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 198fc0a0d77c..d27d7b8ba3b6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1446,8 +1446,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1446 | } | 1446 | } |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 1449 | static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
1450 | struct rt2x00_field32 irq_field) | 1450 | struct rt2x00_field32 irq_field) |
1451 | { | 1451 | { |
1452 | u32 reg; | 1452 | u32 reg; |
1453 | 1453 | ||
@@ -1687,14 +1687,14 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1687 | * Detect if this device has an hardware controlled radio. | 1687 | * Detect if this device has an hardware controlled radio. |
1688 | */ | 1688 | */ |
1689 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 1689 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
1690 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 1690 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
1691 | 1691 | ||
1692 | /* | 1692 | /* |
1693 | * Check if the BBP tuning should be enabled. | 1693 | * Check if the BBP tuning should be enabled. |
1694 | */ | 1694 | */ |
1695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 1695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); |
1696 | if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) | 1696 | if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) |
1697 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 1697 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
1698 | 1698 | ||
1699 | /* | 1699 | /* |
1700 | * Read the RSSI <-> dBm offset information. | 1700 | * Read the RSSI <-> dBm offset information. |
@@ -1958,9 +1958,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1958 | /* | 1958 | /* |
1959 | * This device requires the atim queue and DMA-mapped skbs. | 1959 | * This device requires the atim queue and DMA-mapped skbs. |
1960 | */ | 1960 | */ |
1961 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1961 | __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); |
1962 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 1962 | __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); |
1963 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | 1963 | __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); |
1964 | 1964 | ||
1965 | /* | 1965 | /* |
1966 | * Set the rssi offset. | 1966 | * Set the rssi offset. |
@@ -2013,6 +2013,9 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
2013 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 2013 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
2014 | .rfkill_poll = rt2x00mac_rfkill_poll, | 2014 | .rfkill_poll = rt2x00mac_rfkill_poll, |
2015 | .flush = rt2x00mac_flush, | 2015 | .flush = rt2x00mac_flush, |
2016 | .set_antenna = rt2x00mac_set_antenna, | ||
2017 | .get_antenna = rt2x00mac_get_antenna, | ||
2018 | .get_ringparam = rt2x00mac_get_ringparam, | ||
2016 | }; | 2019 | }; |
2017 | 2020 | ||
2018 | static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | 2021 | static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { |
@@ -2033,6 +2036,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
2033 | .start_queue = rt2500pci_start_queue, | 2036 | .start_queue = rt2500pci_start_queue, |
2034 | .kick_queue = rt2500pci_kick_queue, | 2037 | .kick_queue = rt2500pci_kick_queue, |
2035 | .stop_queue = rt2500pci_stop_queue, | 2038 | .stop_queue = rt2500pci_stop_queue, |
2039 | .flush_queue = rt2x00pci_flush_queue, | ||
2036 | .write_tx_desc = rt2500pci_write_tx_desc, | 2040 | .write_tx_desc = rt2500pci_write_tx_desc, |
2037 | .write_beacon = rt2500pci_write_beacon, | 2041 | .write_beacon = rt2500pci_write_beacon, |
2038 | .fill_rxdone = rt2500pci_fill_rxdone, | 2042 | .fill_rxdone = rt2500pci_fill_rxdone, |
@@ -2094,7 +2098,7 @@ static const struct rt2x00_ops rt2500pci_ops = { | |||
2094 | * RT2500pci module information. | 2098 | * RT2500pci module information. |
2095 | */ | 2099 | */ |
2096 | static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = { | 2100 | static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = { |
2097 | { PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) }, | 2101 | { PCI_DEVICE(0x1814, 0x0201) }, |
2098 | { 0, } | 2102 | { 0, } |
2099 | }; | 2103 | }; |
2100 | 2104 | ||
@@ -2105,10 +2109,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards"); | |||
2105 | MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); | 2109 | MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); |
2106 | MODULE_LICENSE("GPL"); | 2110 | MODULE_LICENSE("GPL"); |
2107 | 2111 | ||
2112 | static int rt2500pci_probe(struct pci_dev *pci_dev, | ||
2113 | const struct pci_device_id *id) | ||
2114 | { | ||
2115 | return rt2x00pci_probe(pci_dev, &rt2500pci_ops); | ||
2116 | } | ||
2117 | |||
2108 | static struct pci_driver rt2500pci_driver = { | 2118 | static struct pci_driver rt2500pci_driver = { |
2109 | .name = KBUILD_MODNAME, | 2119 | .name = KBUILD_MODNAME, |
2110 | .id_table = rt2500pci_device_table, | 2120 | .id_table = rt2500pci_device_table, |
2111 | .probe = rt2x00pci_probe, | 2121 | .probe = rt2500pci_probe, |
2112 | .remove = __devexit_p(rt2x00pci_remove), | 2122 | .remove = __devexit_p(rt2x00pci_remove), |
2113 | .suspend = rt2x00pci_suspend, | 2123 | .suspend = rt2x00pci_suspend, |
2114 | .resume = rt2x00pci_resume, | 2124 | .resume = rt2x00pci_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index eac788160f55..b21f81231a09 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1519,7 +1519,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1519 | * Detect if this device has an hardware controlled radio. | 1519 | * Detect if this device has an hardware controlled radio. |
1520 | */ | 1520 | */ |
1521 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 1521 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
1522 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 1522 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
1523 | 1523 | ||
1524 | /* | 1524 | /* |
1525 | * Read the RSSI <-> dBm offset information. | 1525 | * Read the RSSI <-> dBm offset information. |
@@ -1790,13 +1790,13 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1790 | /* | 1790 | /* |
1791 | * This device requires the atim queue | 1791 | * This device requires the atim queue |
1792 | */ | 1792 | */ |
1793 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1793 | __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); |
1794 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | 1794 | __set_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags); |
1795 | if (!modparam_nohwcrypt) { | 1795 | if (!modparam_nohwcrypt) { |
1796 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 1796 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
1797 | __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); | 1797 | __set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags); |
1798 | } | 1798 | } |
1799 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | 1799 | __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); |
1800 | 1800 | ||
1801 | /* | 1801 | /* |
1802 | * Set the rssi offset. | 1802 | * Set the rssi offset. |
@@ -1823,6 +1823,9 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1823 | .conf_tx = rt2x00mac_conf_tx, | 1823 | .conf_tx = rt2x00mac_conf_tx, |
1824 | .rfkill_poll = rt2x00mac_rfkill_poll, | 1824 | .rfkill_poll = rt2x00mac_rfkill_poll, |
1825 | .flush = rt2x00mac_flush, | 1825 | .flush = rt2x00mac_flush, |
1826 | .set_antenna = rt2x00mac_set_antenna, | ||
1827 | .get_antenna = rt2x00mac_get_antenna, | ||
1828 | .get_ringparam = rt2x00mac_get_ringparam, | ||
1826 | }; | 1829 | }; |
1827 | 1830 | ||
1828 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | 1831 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { |
@@ -1904,54 +1907,54 @@ static const struct rt2x00_ops rt2500usb_ops = { | |||
1904 | */ | 1907 | */ |
1905 | static struct usb_device_id rt2500usb_device_table[] = { | 1908 | static struct usb_device_id rt2500usb_device_table[] = { |
1906 | /* ASUS */ | 1909 | /* ASUS */ |
1907 | { USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1910 | { USB_DEVICE(0x0b05, 0x1706) }, |
1908 | { USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1911 | { USB_DEVICE(0x0b05, 0x1707) }, |
1909 | /* Belkin */ | 1912 | /* Belkin */ |
1910 | { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1913 | { USB_DEVICE(0x050d, 0x7050) }, |
1911 | { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1914 | { USB_DEVICE(0x050d, 0x7051) }, |
1912 | /* Cisco Systems */ | 1915 | /* Cisco Systems */ |
1913 | { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1916 | { USB_DEVICE(0x13b1, 0x000d) }, |
1914 | { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1917 | { USB_DEVICE(0x13b1, 0x0011) }, |
1915 | { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1918 | { USB_DEVICE(0x13b1, 0x001a) }, |
1916 | /* Conceptronic */ | 1919 | /* Conceptronic */ |
1917 | { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1920 | { USB_DEVICE(0x14b2, 0x3c02) }, |
1918 | /* D-LINK */ | 1921 | /* D-LINK */ |
1919 | { USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1922 | { USB_DEVICE(0x2001, 0x3c00) }, |
1920 | /* Gigabyte */ | 1923 | /* Gigabyte */ |
1921 | { USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1924 | { USB_DEVICE(0x1044, 0x8001) }, |
1922 | { USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1925 | { USB_DEVICE(0x1044, 0x8007) }, |
1923 | /* Hercules */ | 1926 | /* Hercules */ |
1924 | { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1927 | { USB_DEVICE(0x06f8, 0xe000) }, |
1925 | /* Melco */ | 1928 | /* Melco */ |
1926 | { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1929 | { USB_DEVICE(0x0411, 0x005e) }, |
1927 | { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1930 | { USB_DEVICE(0x0411, 0x0066) }, |
1928 | { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1931 | { USB_DEVICE(0x0411, 0x0067) }, |
1929 | { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1932 | { USB_DEVICE(0x0411, 0x008b) }, |
1930 | { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1933 | { USB_DEVICE(0x0411, 0x0097) }, |
1931 | /* MSI */ | 1934 | /* MSI */ |
1932 | { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1935 | { USB_DEVICE(0x0db0, 0x6861) }, |
1933 | { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1936 | { USB_DEVICE(0x0db0, 0x6865) }, |
1934 | { USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1937 | { USB_DEVICE(0x0db0, 0x6869) }, |
1935 | /* Ralink */ | 1938 | /* Ralink */ |
1936 | { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1939 | { USB_DEVICE(0x148f, 0x1706) }, |
1937 | { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1940 | { USB_DEVICE(0x148f, 0x2570) }, |
1938 | { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1941 | { USB_DEVICE(0x148f, 0x9020) }, |
1939 | /* Sagem */ | 1942 | /* Sagem */ |
1940 | { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1943 | { USB_DEVICE(0x079b, 0x004b) }, |
1941 | /* Siemens */ | 1944 | /* Siemens */ |
1942 | { USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1945 | { USB_DEVICE(0x0681, 0x3c06) }, |
1943 | /* SMC */ | 1946 | /* SMC */ |
1944 | { USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1947 | { USB_DEVICE(0x0707, 0xee13) }, |
1945 | /* Spairon */ | 1948 | /* Spairon */ |
1946 | { USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1949 | { USB_DEVICE(0x114b, 0x0110) }, |
1947 | /* SURECOM */ | 1950 | /* SURECOM */ |
1948 | { USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1951 | { USB_DEVICE(0x0769, 0x11f3) }, |
1949 | /* Trust */ | 1952 | /* Trust */ |
1950 | { USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1953 | { USB_DEVICE(0x0eb0, 0x9020) }, |
1951 | /* VTech */ | 1954 | /* VTech */ |
1952 | { USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1955 | { USB_DEVICE(0x0f88, 0x3012) }, |
1953 | /* Zinwell */ | 1956 | /* Zinwell */ |
1954 | { USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) }, | 1957 | { USB_DEVICE(0x5a57, 0x0260) }, |
1955 | { 0, } | 1958 | { 0, } |
1956 | }; | 1959 | }; |
1957 | 1960 | ||
@@ -1962,10 +1965,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards"); | |||
1962 | MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); | 1965 | MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); |
1963 | MODULE_LICENSE("GPL"); | 1966 | MODULE_LICENSE("GPL"); |
1964 | 1967 | ||
1968 | static int rt2500usb_probe(struct usb_interface *usb_intf, | ||
1969 | const struct usb_device_id *id) | ||
1970 | { | ||
1971 | return rt2x00usb_probe(usb_intf, &rt2500usb_ops); | ||
1972 | } | ||
1973 | |||
1965 | static struct usb_driver rt2500usb_driver = { | 1974 | static struct usb_driver rt2500usb_driver = { |
1966 | .name = KBUILD_MODNAME, | 1975 | .name = KBUILD_MODNAME, |
1967 | .id_table = rt2500usb_device_table, | 1976 | .id_table = rt2500usb_device_table, |
1968 | .probe = rt2x00usb_probe, | 1977 | .probe = rt2500usb_probe, |
1969 | .disconnect = rt2x00usb_disconnect, | 1978 | .disconnect = rt2x00usb_disconnect, |
1970 | .suspend = rt2x00usb_suspend, | 1979 | .suspend = rt2x00usb_suspend, |
1971 | .resume = rt2x00usb_resume, | 1980 | .resume = rt2x00usb_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6331c61957a3..5cd096e2ae36 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -730,34 +730,20 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
730 | struct data_queue *queue; | 730 | struct data_queue *queue; |
731 | struct queue_entry *entry; | 731 | struct queue_entry *entry; |
732 | u32 reg; | 732 | u32 reg; |
733 | u8 pid; | 733 | u8 qid; |
734 | int i; | ||
735 | 734 | ||
736 | /* | 735 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { |
737 | * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO | ||
738 | * at most X times and also stop processing once the TX_STA_FIFO_VALID | ||
739 | * flag is not set anymore. | ||
740 | * | ||
741 | * The legacy drivers use X=TX_RING_SIZE but state in a comment | ||
742 | * that the TX_STA_FIFO stack has a size of 16. We stick to our | ||
743 | * tx ring size for now. | ||
744 | */ | ||
745 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { | ||
746 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); | ||
747 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | ||
748 | break; | ||
749 | 736 | ||
750 | /* | 737 | /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus |
751 | * Skip this entry when it contains an invalid | 738 | * qid is guaranteed to be one of the TX QIDs |
752 | * queue identication number. | ||
753 | */ | 739 | */ |
754 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); | 740 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); |
755 | if (pid >= QID_RX) | 741 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
756 | continue; | 742 | if (unlikely(!queue)) { |
757 | 743 | WARNING(rt2x00dev, "Got TX status for an unavailable " | |
758 | queue = rt2x00queue_get_tx_queue(rt2x00dev, pid); | 744 | "queue %u, dropping\n", qid); |
759 | if (unlikely(!queue)) | ||
760 | continue; | 745 | continue; |
746 | } | ||
761 | 747 | ||
762 | /* | 748 | /* |
763 | * Inside each queue, we process each entry in a chronological | 749 | * Inside each queue, we process each entry in a chronological |
@@ -949,25 +935,49 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev, | |||
949 | unsigned int ledmode = | 935 | unsigned int ledmode = |
950 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, | 936 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, |
951 | EEPROM_FREQ_LED_MODE); | 937 | EEPROM_FREQ_LED_MODE); |
938 | u32 reg; | ||
952 | 939 | ||
953 | if (led->type == LED_TYPE_RADIO) { | 940 | /* Check for SoC (SOC devices don't support MCU requests) */ |
954 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | 941 | if (rt2x00_is_soc(led->rt2x00dev)) { |
955 | enabled ? 0x20 : 0); | 942 | rt2800_register_read(led->rt2x00dev, LED_CFG, ®); |
956 | } else if (led->type == LED_TYPE_ASSOC) { | 943 | |
957 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | 944 | /* Set LED Polarity */ |
958 | enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); | 945 | rt2x00_set_field32(®, LED_CFG_LED_POLAR, polarity); |
959 | } else if (led->type == LED_TYPE_QUALITY) { | 946 | |
960 | /* | 947 | /* Set LED Mode */ |
961 | * The brightness is divided into 6 levels (0 - 5), | 948 | if (led->type == LED_TYPE_RADIO) { |
962 | * The specs tell us the following levels: | 949 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, |
963 | * 0, 1 ,3, 7, 15, 31 | 950 | enabled ? 3 : 0); |
964 | * to determine the level in a simple way we can simply | 951 | } else if (led->type == LED_TYPE_ASSOC) { |
965 | * work with bitshifting: | 952 | rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, |
966 | * (1 << level) - 1 | 953 | enabled ? 3 : 0); |
967 | */ | 954 | } else if (led->type == LED_TYPE_QUALITY) { |
968 | rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | 955 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, |
969 | (1 << brightness / (LED_FULL / 6)) - 1, | 956 | enabled ? 3 : 0); |
970 | polarity); | 957 | } |
958 | |||
959 | rt2800_register_write(led->rt2x00dev, LED_CFG, reg); | ||
960 | |||
961 | } else { | ||
962 | if (led->type == LED_TYPE_RADIO) { | ||
963 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
964 | enabled ? 0x20 : 0); | ||
965 | } else if (led->type == LED_TYPE_ASSOC) { | ||
966 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
967 | enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); | ||
968 | } else if (led->type == LED_TYPE_QUALITY) { | ||
969 | /* | ||
970 | * The brightness is divided into 6 levels (0 - 5), | ||
971 | * The specs tell us the following levels: | ||
972 | * 0, 1 ,3, 7, 15, 31 | ||
973 | * to determine the level in a simple way we can simply | ||
974 | * work with bitshifting: | ||
975 | * (1 << level) - 1 | ||
976 | */ | ||
977 | rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
978 | (1 << brightness / (LED_FULL / 6)) - 1, | ||
979 | polarity); | ||
980 | } | ||
971 | } | 981 | } |
972 | } | 982 | } |
973 | 983 | ||
@@ -1221,6 +1231,25 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
1221 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 1231 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
1222 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); | 1232 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); |
1223 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 1233 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
1234 | |||
1235 | if (conf->sync == TSF_SYNC_AP_NONE) { | ||
1236 | /* | ||
1237 | * Tune beacon queue transmit parameters for AP mode | ||
1238 | */ | ||
1239 | rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); | ||
1240 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 0); | ||
1241 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 1); | ||
1242 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); | ||
1243 | rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 0); | ||
1244 | rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); | ||
1245 | } else { | ||
1246 | rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); | ||
1247 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 4); | ||
1248 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 2); | ||
1249 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); | ||
1250 | rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 16); | ||
1251 | rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); | ||
1252 | } | ||
1224 | } | 1253 | } |
1225 | 1254 | ||
1226 | if (flags & CONFIG_UPDATE_MAC) { | 1255 | if (flags & CONFIG_UPDATE_MAC) { |
@@ -1739,8 +1768,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1739 | 1768 | ||
1740 | if (rf->channel <= 14) { | 1769 | if (rf->channel <= 14) { |
1741 | if (!rt2x00_rt(rt2x00dev, RT5390)) { | 1770 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
1742 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, | 1771 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, |
1743 | &rt2x00dev->flags)) { | 1772 | &rt2x00dev->cap_flags)) { |
1744 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 1773 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1745 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1774 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1746 | } else { | 1775 | } else { |
@@ -1751,7 +1780,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1751 | } else { | 1780 | } else { |
1752 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | 1781 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); |
1753 | 1782 | ||
1754 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1783 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) |
1755 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1784 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1756 | else | 1785 | else |
1757 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | 1786 | rt2800_bbp_write(rt2x00dev, 75, 0x50); |
@@ -1984,7 +2013,7 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, | |||
1984 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) | 2013 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) |
1985 | return txpower; | 2014 | return txpower; |
1986 | 2015 | ||
1987 | if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { | 2016 | if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { |
1988 | /* | 2017 | /* |
1989 | * Check if eirp txpower exceed txpower_limit. | 2018 | * Check if eirp txpower exceed txpower_limit. |
1990 | * We use OFDM 6M as criterion and its eirp txpower | 2019 | * We use OFDM 6M as criterion and its eirp txpower |
@@ -2384,7 +2413,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2384 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | 2413 | } else if (rt2800_is_305x_soc(rt2x00dev)) { |
2385 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 2414 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
2386 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | 2415 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
2387 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); | 2416 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); |
2388 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 2417 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
2389 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | 2418 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); |
2390 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2419 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
@@ -3285,8 +3314,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3285 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3314 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
3286 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 3315 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
3287 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 3316 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
3288 | if (!test_bit(CONFIG_EXTERNAL_LNA_BG, | 3317 | if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, |
3289 | &rt2x00dev->flags)) | 3318 | &rt2x00dev->cap_flags)) |
3290 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | 3319 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); |
3291 | } | 3320 | } |
3292 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); | 3321 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); |
@@ -3709,15 +3738,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3709 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | 3738 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
3710 | 3739 | ||
3711 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) | 3740 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) |
3712 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 3741 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
3713 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) | 3742 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) |
3714 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 3743 | __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); |
3715 | 3744 | ||
3716 | /* | 3745 | /* |
3717 | * Detect if this device has an hardware controlled radio. | 3746 | * Detect if this device has an hardware controlled radio. |
3718 | */ | 3747 | */ |
3719 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO)) | 3748 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO)) |
3720 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 3749 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
3721 | 3750 | ||
3722 | /* | 3751 | /* |
3723 | * Store led settings, for correct led behaviour. | 3752 | * Store led settings, for correct led behaviour. |
@@ -3737,7 +3766,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3737 | 3766 | ||
3738 | if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < | 3767 | if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < |
3739 | EIRP_MAX_TX_POWER_LIMIT) | 3768 | EIRP_MAX_TX_POWER_LIMIT) |
3740 | __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags); | 3769 | __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); |
3741 | 3770 | ||
3742 | return 0; | 3771 | return 0; |
3743 | } | 3772 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index adc3534254df..08d3947fcb26 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -66,7 +66,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) | |||
66 | return; | 66 | return; |
67 | 67 | ||
68 | for (i = 0; i < 200; i++) { | 68 | for (i = 0; i < 200; i++) { |
69 | rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); | 69 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); |
70 | 70 | ||
71 | if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || | 71 | if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || |
72 | (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || | 72 | (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || |
@@ -80,8 +80,8 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) | |||
80 | if (i == 200) | 80 | if (i == 200) |
81 | ERROR(rt2x00dev, "MCU request failed, no response from hardware\n"); | 81 | ERROR(rt2x00dev, "MCU request failed, no response from hardware\n"); |
82 | 82 | ||
83 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 83 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
84 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 84 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
85 | } | 85 | } |
86 | 86 | ||
87 | #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) | 87 | #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) |
@@ -105,7 +105,7 @@ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | |||
105 | struct rt2x00_dev *rt2x00dev = eeprom->data; | 105 | struct rt2x00_dev *rt2x00dev = eeprom->data; |
106 | u32 reg; | 106 | u32 reg; |
107 | 107 | ||
108 | rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); | 108 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); |
109 | 109 | ||
110 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); | 110 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); |
111 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); | 111 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); |
@@ -127,7 +127,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
127 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, | 127 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, |
128 | !!eeprom->reg_chip_select); | 128 | !!eeprom->reg_chip_select); |
129 | 129 | ||
130 | rt2800_register_write(rt2x00dev, E2PROM_CSR, reg); | 130 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | 133 | static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) |
@@ -135,7 +135,7 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | |||
135 | struct eeprom_93cx6 eeprom; | 135 | struct eeprom_93cx6 eeprom; |
136 | u32 reg; | 136 | u32 reg; |
137 | 137 | ||
138 | rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); | 138 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); |
139 | 139 | ||
140 | eeprom.data = rt2x00dev; | 140 | eeprom.data = rt2x00dev; |
141 | eeprom.register_read = rt2800pci_eepromregister_read; | 141 | eeprom.register_read = rt2800pci_eepromregister_read; |
@@ -195,9 +195,9 @@ static void rt2800pci_start_queue(struct data_queue *queue) | |||
195 | 195 | ||
196 | switch (queue->qid) { | 196 | switch (queue->qid) { |
197 | case QID_RX: | 197 | case QID_RX: |
198 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 198 | rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
199 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | 199 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); |
200 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 200 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
201 | break; | 201 | break; |
202 | case QID_BEACON: | 202 | case QID_BEACON: |
203 | /* | 203 | /* |
@@ -207,15 +207,15 @@ static void rt2800pci_start_queue(struct data_queue *queue) | |||
207 | tasklet_enable(&rt2x00dev->tbtt_tasklet); | 207 | tasklet_enable(&rt2x00dev->tbtt_tasklet); |
208 | tasklet_enable(&rt2x00dev->pretbtt_tasklet); | 208 | tasklet_enable(&rt2x00dev->pretbtt_tasklet); |
209 | 209 | ||
210 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 210 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
211 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | 211 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); |
212 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | 212 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); |
213 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 213 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); |
214 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 214 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
215 | 215 | ||
216 | rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); | 216 | rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); |
217 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); | 217 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); |
218 | rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); | 218 | rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); |
219 | break; | 219 | break; |
220 | default: | 220 | default: |
221 | break; | 221 | break; |
@@ -233,11 +233,13 @@ static void rt2800pci_kick_queue(struct data_queue *queue) | |||
233 | case QID_AC_BE: | 233 | case QID_AC_BE: |
234 | case QID_AC_BK: | 234 | case QID_AC_BK: |
235 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 235 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
236 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx); | 236 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), |
237 | entry->entry_idx); | ||
237 | break; | 238 | break; |
238 | case QID_MGMT: | 239 | case QID_MGMT: |
239 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 240 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
240 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx); | 241 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5), |
242 | entry->entry_idx); | ||
241 | break; | 243 | break; |
242 | default: | 244 | default: |
243 | break; | 245 | break; |
@@ -251,20 +253,20 @@ static void rt2800pci_stop_queue(struct data_queue *queue) | |||
251 | 253 | ||
252 | switch (queue->qid) { | 254 | switch (queue->qid) { |
253 | case QID_RX: | 255 | case QID_RX: |
254 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 256 | rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
255 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | 257 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); |
256 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 258 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
257 | break; | 259 | break; |
258 | case QID_BEACON: | 260 | case QID_BEACON: |
259 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 261 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
260 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); | 262 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); |
261 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | 263 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); |
262 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 264 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); |
263 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 265 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
264 | 266 | ||
265 | rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); | 267 | rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); |
266 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); | 268 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); |
267 | rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); | 269 | rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); |
268 | 270 | ||
269 | /* | 271 | /* |
270 | * Wait for tbtt tasklets to finish. | 272 | * Wait for tbtt tasklets to finish. |
@@ -295,7 +297,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
295 | */ | 297 | */ |
296 | reg = 0; | 298 | reg = 0; |
297 | rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); | 299 | rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); |
298 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg); | 300 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg); |
299 | 301 | ||
300 | /* | 302 | /* |
301 | * Write firmware to device. | 303 | * Write firmware to device. |
@@ -303,11 +305,11 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
303 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 305 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
304 | data, len); | 306 | data, len); |
305 | 307 | ||
306 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); | 308 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); |
307 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); | 309 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); |
308 | 310 | ||
309 | rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | 311 | rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0); |
310 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 312 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
311 | 313 | ||
312 | return 0; | 314 | return 0; |
313 | } | 315 | } |
@@ -351,7 +353,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) | |||
351 | * Set RX IDX in register to inform hardware that we have | 353 | * Set RX IDX in register to inform hardware that we have |
352 | * handled this entry and it is available for reuse again. | 354 | * handled this entry and it is available for reuse again. |
353 | */ | 355 | */ |
354 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, | 356 | rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, |
355 | entry->entry_idx); | 357 | entry->entry_idx); |
356 | } else { | 358 | } else { |
357 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 359 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
@@ -369,45 +371,51 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
369 | * Initialize registers. | 371 | * Initialize registers. |
370 | */ | 372 | */ |
371 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; | 373 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
372 | rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); | 374 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); |
373 | rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit); | 375 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0, |
374 | rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0); | 376 | rt2x00dev->tx[0].limit); |
375 | rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0); | 377 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0); |
378 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0); | ||
376 | 379 | ||
377 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; | 380 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
378 | rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); | 381 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); |
379 | rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit); | 382 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1, |
380 | rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0); | 383 | rt2x00dev->tx[1].limit); |
381 | rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0); | 384 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0); |
385 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0); | ||
382 | 386 | ||
383 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; | 387 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; |
384 | rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); | 388 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); |
385 | rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit); | 389 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2, |
386 | rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0); | 390 | rt2x00dev->tx[2].limit); |
387 | rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0); | 391 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0); |
392 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0); | ||
388 | 393 | ||
389 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; | 394 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; |
390 | rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); | 395 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); |
391 | rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit); | 396 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3, |
392 | rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0); | 397 | rt2x00dev->tx[3].limit); |
393 | rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0); | 398 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0); |
399 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0); | ||
394 | 400 | ||
395 | entry_priv = rt2x00dev->rx->entries[0].priv_data; | 401 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
396 | rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); | 402 | rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); |
397 | rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit); | 403 | rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, |
398 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1); | 404 | rt2x00dev->rx[0].limit); |
399 | rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0); | 405 | rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, |
406 | rt2x00dev->rx[0].limit - 1); | ||
407 | rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0); | ||
400 | 408 | ||
401 | /* | 409 | /* |
402 | * Enable global DMA configuration | 410 | * Enable global DMA configuration |
403 | */ | 411 | */ |
404 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | 412 | rt2x00pci_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); |
405 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | 413 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); |
406 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | 414 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); |
407 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | 415 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); |
408 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | 416 | rt2x00pci_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); |
409 | 417 | ||
410 | rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0); | 418 | rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0); |
411 | 419 | ||
412 | return 0; | 420 | return 0; |
413 | } | 421 | } |
@@ -427,8 +435,8 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
427 | * should clear the register to assure a clean state. | 435 | * should clear the register to assure a clean state. |
428 | */ | 436 | */ |
429 | if (state == STATE_RADIO_IRQ_ON) { | 437 | if (state == STATE_RADIO_IRQ_ON) { |
430 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 438 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
431 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 439 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
432 | 440 | ||
433 | /* | 441 | /* |
434 | * Enable tasklets. The beacon related tasklets are | 442 | * Enable tasklets. The beacon related tasklets are |
@@ -440,7 +448,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
440 | } | 448 | } |
441 | 449 | ||
442 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 450 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); |
443 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 451 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
444 | rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); | 452 | rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); |
445 | rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); | 453 | rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); |
446 | rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); | 454 | rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); |
@@ -459,7 +467,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
459 | rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); | 467 | rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); |
460 | rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); | 468 | rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); |
461 | rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); | 469 | rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); |
462 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 470 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); |
463 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 471 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); |
464 | 472 | ||
465 | if (state == STATE_RADIO_IRQ_OFF) { | 473 | if (state == STATE_RADIO_IRQ_OFF) { |
@@ -480,7 +488,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
480 | /* | 488 | /* |
481 | * Reset DMA indexes | 489 | * Reset DMA indexes |
482 | */ | 490 | */ |
483 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | 491 | rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, ®); |
484 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); | 492 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); |
485 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); | 493 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); |
486 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); | 494 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); |
@@ -488,26 +496,26 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
488 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); | 496 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); |
489 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); | 497 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); |
490 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); | 498 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); |
491 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | 499 | rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg); |
492 | 500 | ||
493 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 501 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
494 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 502 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
495 | 503 | ||
496 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 504 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
497 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | 505 | rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); |
498 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 506 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
499 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 507 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
500 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | 508 | rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg); |
501 | } | 509 | } |
502 | 510 | ||
503 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | 511 | rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); |
504 | 512 | ||
505 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 513 | rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
506 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | 514 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); |
507 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | 515 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); |
508 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 516 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
509 | 517 | ||
510 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | 518 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); |
511 | 519 | ||
512 | return 0; | 520 | return 0; |
513 | } | 521 | } |
@@ -525,8 +533,8 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
525 | { | 533 | { |
526 | if (rt2x00_is_soc(rt2x00dev)) { | 534 | if (rt2x00_is_soc(rt2x00dev)) { |
527 | rt2800_disable_radio(rt2x00dev); | 535 | rt2800_disable_radio(rt2x00dev); |
528 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | 536 | rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0); |
529 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | 537 | rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0); |
530 | } | 538 | } |
531 | } | 539 | } |
532 | 540 | ||
@@ -537,8 +545,10 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
537 | rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); | 545 | rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); |
538 | rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); | 546 | rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); |
539 | } else if (state == STATE_SLEEP) { | 547 | } else if (state == STATE_SLEEP) { |
540 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); | 548 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, |
541 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); | 549 | 0xffffffff); |
550 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, | ||
551 | 0xffffffff); | ||
542 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); | 552 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); |
543 | } | 553 | } |
544 | 554 | ||
@@ -768,8 +778,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
768 | return !max_tx_done; | 778 | return !max_tx_done; |
769 | } | 779 | } |
770 | 780 | ||
771 | static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 781 | static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
772 | struct rt2x00_field32 irq_field) | 782 | struct rt2x00_field32 irq_field) |
773 | { | 783 | { |
774 | u32 reg; | 784 | u32 reg; |
775 | 785 | ||
@@ -778,9 +788,9 @@ static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | |||
778 | * access needs locking. | 788 | * access needs locking. |
779 | */ | 789 | */ |
780 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 790 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
781 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 791 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
782 | rt2x00_set_field32(®, irq_field, 1); | 792 | rt2x00_set_field32(®, irq_field, 1); |
783 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 793 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); |
784 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 794 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
785 | } | 795 | } |
786 | 796 | ||
@@ -851,7 +861,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) | |||
851 | * need to lock the kfifo. | 861 | * need to lock the kfifo. |
852 | */ | 862 | */ |
853 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { | 863 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { |
854 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); | 864 | rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status); |
855 | 865 | ||
856 | if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) | 866 | if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) |
857 | break; | 867 | break; |
@@ -873,8 +883,8 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
873 | u32 reg, mask; | 883 | u32 reg, mask; |
874 | 884 | ||
875 | /* Read status and ACK all interrupts */ | 885 | /* Read status and ACK all interrupts */ |
876 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 886 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
877 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 887 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
878 | 888 | ||
879 | if (!reg) | 889 | if (!reg) |
880 | return IRQ_NONE; | 890 | return IRQ_NONE; |
@@ -914,9 +924,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
914 | * the tasklet will reenable the appropriate interrupts. | 924 | * the tasklet will reenable the appropriate interrupts. |
915 | */ | 925 | */ |
916 | spin_lock(&rt2x00dev->irqmask_lock); | 926 | spin_lock(&rt2x00dev->irqmask_lock); |
917 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 927 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
918 | reg &= mask; | 928 | reg &= mask; |
919 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 929 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); |
920 | spin_unlock(&rt2x00dev->irqmask_lock); | 930 | spin_unlock(&rt2x00dev->irqmask_lock); |
921 | 931 | ||
922 | return IRQ_HANDLED; | 932 | return IRQ_HANDLED; |
@@ -966,28 +976,28 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
966 | * This device has multiple filters for control frames | 976 | * This device has multiple filters for control frames |
967 | * and has a separate filter for PS Poll frames. | 977 | * and has a separate filter for PS Poll frames. |
968 | */ | 978 | */ |
969 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); | 979 | __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); |
970 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags); | 980 | __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags); |
971 | 981 | ||
972 | /* | 982 | /* |
973 | * This device has a pre tbtt interrupt and thus fetches | 983 | * This device has a pre tbtt interrupt and thus fetches |
974 | * a new beacon directly prior to transmission. | 984 | * a new beacon directly prior to transmission. |
975 | */ | 985 | */ |
976 | __set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags); | 986 | __set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags); |
977 | 987 | ||
978 | /* | 988 | /* |
979 | * This device requires firmware. | 989 | * This device requires firmware. |
980 | */ | 990 | */ |
981 | if (!rt2x00_is_soc(rt2x00dev)) | 991 | if (!rt2x00_is_soc(rt2x00dev)) |
982 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 992 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); |
983 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 993 | __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); |
984 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); | 994 | __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags); |
985 | __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); | 995 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); |
986 | __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags); | 996 | __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags); |
987 | if (!modparam_nohwcrypt) | 997 | if (!modparam_nohwcrypt) |
988 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 998 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
989 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 999 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
990 | __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); | 1000 | __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); |
991 | 1001 | ||
992 | /* | 1002 | /* |
993 | * Set the rssi offset. | 1003 | * Set the rssi offset. |
@@ -1018,6 +1028,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { | |||
1018 | .ampdu_action = rt2800_ampdu_action, | 1028 | .ampdu_action = rt2800_ampdu_action, |
1019 | .flush = rt2x00mac_flush, | 1029 | .flush = rt2x00mac_flush, |
1020 | .get_survey = rt2800_get_survey, | 1030 | .get_survey = rt2800_get_survey, |
1031 | .get_ringparam = rt2x00mac_get_ringparam, | ||
1021 | }; | 1032 | }; |
1022 | 1033 | ||
1023 | static const struct rt2800_ops rt2800pci_rt2800_ops = { | 1034 | static const struct rt2800_ops rt2800pci_rt2800_ops = { |
@@ -1057,6 +1068,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1057 | .start_queue = rt2800pci_start_queue, | 1068 | .start_queue = rt2800pci_start_queue, |
1058 | .kick_queue = rt2800pci_kick_queue, | 1069 | .kick_queue = rt2800pci_kick_queue, |
1059 | .stop_queue = rt2800pci_stop_queue, | 1070 | .stop_queue = rt2800pci_stop_queue, |
1071 | .flush_queue = rt2x00pci_flush_queue, | ||
1060 | .write_tx_desc = rt2800pci_write_tx_desc, | 1072 | .write_tx_desc = rt2800pci_write_tx_desc, |
1061 | .write_tx_data = rt2800_write_tx_data, | 1073 | .write_tx_data = rt2800_write_tx_data, |
1062 | .write_beacon = rt2800_write_beacon, | 1074 | .write_beacon = rt2800_write_beacon, |
@@ -1116,36 +1128,36 @@ static const struct rt2x00_ops rt2800pci_ops = { | |||
1116 | */ | 1128 | */ |
1117 | #ifdef CONFIG_PCI | 1129 | #ifdef CONFIG_PCI |
1118 | static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | 1130 | static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { |
1119 | { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1131 | { PCI_DEVICE(0x1814, 0x0601) }, |
1120 | { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1132 | { PCI_DEVICE(0x1814, 0x0681) }, |
1121 | { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1133 | { PCI_DEVICE(0x1814, 0x0701) }, |
1122 | { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1134 | { PCI_DEVICE(0x1814, 0x0781) }, |
1123 | { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1135 | { PCI_DEVICE(0x1814, 0x3090) }, |
1124 | { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1136 | { PCI_DEVICE(0x1814, 0x3091) }, |
1125 | { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1137 | { PCI_DEVICE(0x1814, 0x3092) }, |
1126 | { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1138 | { PCI_DEVICE(0x1432, 0x7708) }, |
1127 | { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1139 | { PCI_DEVICE(0x1432, 0x7727) }, |
1128 | { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1140 | { PCI_DEVICE(0x1432, 0x7728) }, |
1129 | { PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1141 | { PCI_DEVICE(0x1432, 0x7738) }, |
1130 | { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1142 | { PCI_DEVICE(0x1432, 0x7748) }, |
1131 | { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1143 | { PCI_DEVICE(0x1432, 0x7758) }, |
1132 | { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1144 | { PCI_DEVICE(0x1432, 0x7768) }, |
1133 | { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1145 | { PCI_DEVICE(0x1462, 0x891a) }, |
1134 | { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1146 | { PCI_DEVICE(0x1a3b, 0x1059) }, |
1135 | #ifdef CONFIG_RT2800PCI_RT33XX | 1147 | #ifdef CONFIG_RT2800PCI_RT33XX |
1136 | { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1148 | { PCI_DEVICE(0x1814, 0x3390) }, |
1137 | #endif | 1149 | #endif |
1138 | #ifdef CONFIG_RT2800PCI_RT35XX | 1150 | #ifdef CONFIG_RT2800PCI_RT35XX |
1139 | { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1151 | { PCI_DEVICE(0x1432, 0x7711) }, |
1140 | { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1152 | { PCI_DEVICE(0x1432, 0x7722) }, |
1141 | { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1153 | { PCI_DEVICE(0x1814, 0x3060) }, |
1142 | { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1154 | { PCI_DEVICE(0x1814, 0x3062) }, |
1143 | { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1155 | { PCI_DEVICE(0x1814, 0x3562) }, |
1144 | { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1156 | { PCI_DEVICE(0x1814, 0x3592) }, |
1145 | { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1157 | { PCI_DEVICE(0x1814, 0x3593) }, |
1146 | #endif | 1158 | #endif |
1147 | #ifdef CONFIG_RT2800PCI_RT53XX | 1159 | #ifdef CONFIG_RT2800PCI_RT53XX |
1148 | { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1160 | { PCI_DEVICE(0x1814, 0x5390) }, |
1149 | #endif | 1161 | #endif |
1150 | { 0, } | 1162 | { 0, } |
1151 | }; | 1163 | }; |
@@ -1181,10 +1193,16 @@ static struct platform_driver rt2800soc_driver = { | |||
1181 | #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ | 1193 | #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ |
1182 | 1194 | ||
1183 | #ifdef CONFIG_PCI | 1195 | #ifdef CONFIG_PCI |
1196 | static int rt2800pci_probe(struct pci_dev *pci_dev, | ||
1197 | const struct pci_device_id *id) | ||
1198 | { | ||
1199 | return rt2x00pci_probe(pci_dev, &rt2800pci_ops); | ||
1200 | } | ||
1201 | |||
1184 | static struct pci_driver rt2800pci_driver = { | 1202 | static struct pci_driver rt2800pci_driver = { |
1185 | .name = KBUILD_MODNAME, | 1203 | .name = KBUILD_MODNAME, |
1186 | .id_table = rt2800pci_device_table, | 1204 | .id_table = rt2800pci_device_table, |
1187 | .probe = rt2x00pci_probe, | 1205 | .probe = rt2800pci_probe, |
1188 | .remove = __devexit_p(rt2x00pci_remove), | 1206 | .remove = __devexit_p(rt2x00pci_remove), |
1189 | .suspend = rt2x00pci_suspend, | 1207 | .suspend = rt2x00pci_suspend, |
1190 | .resume = rt2x00pci_resume, | 1208 | .resume = rt2x00pci_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6ba31a0e8f78..0d4e8fa3e1f8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -59,16 +59,16 @@ static void rt2800usb_start_queue(struct data_queue *queue) | |||
59 | 59 | ||
60 | switch (queue->qid) { | 60 | switch (queue->qid) { |
61 | case QID_RX: | 61 | case QID_RX: |
62 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 62 | rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
63 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | 63 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); |
64 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 64 | rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
65 | break; | 65 | break; |
66 | case QID_BEACON: | 66 | case QID_BEACON: |
67 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 67 | rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
68 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | 68 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); |
69 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | 69 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); |
70 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 70 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); |
71 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 71 | rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
72 | break; | 72 | break; |
73 | default: | 73 | default: |
74 | break; | 74 | break; |
@@ -82,16 +82,16 @@ static void rt2800usb_stop_queue(struct data_queue *queue) | |||
82 | 82 | ||
83 | switch (queue->qid) { | 83 | switch (queue->qid) { |
84 | case QID_RX: | 84 | case QID_RX: |
85 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 85 | rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
86 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | 86 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); |
87 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 87 | rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
88 | break; | 88 | break; |
89 | case QID_BEACON: | 89 | case QID_BEACON: |
90 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 90 | rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
91 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); | 91 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); |
92 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | 92 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); |
93 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 93 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); |
94 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 94 | rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
95 | break; | 95 | break; |
96 | default: | 96 | default: |
97 | break; | 97 | break; |
@@ -99,6 +99,62 @@ static void rt2800usb_stop_queue(struct data_queue *queue) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * test if there is an entry in any TX queue for which DMA is done | ||
103 | * but the TX status has not been returned yet | ||
104 | */ | ||
105 | static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) | ||
106 | { | ||
107 | struct data_queue *queue; | ||
108 | |||
109 | tx_queue_for_each(rt2x00dev, queue) { | ||
110 | if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != | ||
111 | rt2x00queue_get_entry(queue, Q_INDEX_DONE)) | ||
112 | return true; | ||
113 | } | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | ||
118 | int urb_status, u32 tx_status) | ||
119 | { | ||
120 | if (urb_status) { | ||
121 | WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ | ||
126 | if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { | ||
127 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { | ||
128 | WARNING(rt2x00dev, "TX status FIFO overrun, " | ||
129 | "drop tx status report.\n"); | ||
130 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | ||
131 | } else | ||
132 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | ||
133 | rt2800usb_tx_sta_fifo_read_completed); | ||
134 | } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { | ||
135 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | ||
136 | } else if (rt2800usb_txstatus_pending(rt2x00dev)) { | ||
137 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) | ||
142 | { | ||
143 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
144 | |||
145 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | ||
146 | rt2800usb_tx_sta_fifo_read_completed); | ||
147 | } | ||
148 | |||
149 | static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) | ||
150 | { | ||
151 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | ||
152 | |||
153 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | ||
154 | rt2800usb_tx_sta_fifo_read_completed); | ||
155 | } | ||
156 | |||
157 | /* | ||
102 | * Firmware functions | 158 | * Firmware functions |
103 | */ | 159 | */ |
104 | static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 160 | static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
@@ -129,11 +185,11 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
129 | /* | 185 | /* |
130 | * Write firmware to device. | 186 | * Write firmware to device. |
131 | */ | 187 | */ |
132 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 188 | rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
133 | data + offset, length); | 189 | data + offset, length); |
134 | 190 | ||
135 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 191 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
136 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 192 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
137 | 193 | ||
138 | /* | 194 | /* |
139 | * Send firmware request to device to load firmware, | 195 | * Send firmware request to device to load firmware, |
@@ -148,7 +204,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
148 | } | 204 | } |
149 | 205 | ||
150 | msleep(10); | 206 | msleep(10); |
151 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 207 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
152 | 208 | ||
153 | return 0; | 209 | return 0; |
154 | } | 210 | } |
@@ -166,22 +222,22 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
166 | if (rt2800_wait_csr_ready(rt2x00dev)) | 222 | if (rt2800_wait_csr_ready(rt2x00dev)) |
167 | return -EBUSY; | 223 | return -EBUSY; |
168 | 224 | ||
169 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | 225 | rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); |
170 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); | 226 | rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); |
171 | 227 | ||
172 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | 228 | rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); |
173 | 229 | ||
174 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 230 | rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
175 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | 231 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); |
176 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | 232 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); |
177 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 233 | rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
178 | 234 | ||
179 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | 235 | rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); |
180 | 236 | ||
181 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | 237 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, |
182 | USB_MODE_RESET, REGISTER_TIMEOUT); | 238 | USB_MODE_RESET, REGISTER_TIMEOUT); |
183 | 239 | ||
184 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | 240 | rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); |
185 | 241 | ||
186 | return 0; | 242 | return 0; |
187 | } | 243 | } |
@@ -193,7 +249,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
193 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) | 249 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) |
194 | return -EIO; | 250 | return -EIO; |
195 | 251 | ||
196 | rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); | 252 | rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, ®); |
197 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); | 253 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); |
198 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); | 254 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); |
199 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); | 255 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); |
@@ -206,7 +262,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
206 | / 1024) - 3); | 262 | / 1024) - 3); |
207 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); | 263 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); |
208 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); | 264 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); |
209 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); | 265 | rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg); |
210 | 266 | ||
211 | return rt2800_enable_radio(rt2x00dev); | 267 | return rt2800_enable_radio(rt2x00dev); |
212 | } | 268 | } |
@@ -282,12 +338,12 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
282 | unsigned int i; | 338 | unsigned int i; |
283 | u32 reg; | 339 | u32 reg; |
284 | 340 | ||
285 | rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); | 341 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
286 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { | 342 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { |
287 | WARNING(rt2x00dev, "TX HW queue 0 timed out," | 343 | WARNING(rt2x00dev, "TX HW queue 0 timed out," |
288 | " invoke forced kick\n"); | 344 | " invoke forced kick\n"); |
289 | 345 | ||
290 | rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); | 346 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); |
291 | 347 | ||
292 | for (i = 0; i < 10; i++) { | 348 | for (i = 0; i < 10; i++) { |
293 | udelay(10); | 349 | udelay(10); |
@@ -295,15 +351,15 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
295 | break; | 351 | break; |
296 | } | 352 | } |
297 | 353 | ||
298 | rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); | 354 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); |
299 | } | 355 | } |
300 | 356 | ||
301 | rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); | 357 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
302 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { | 358 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { |
303 | WARNING(rt2x00dev, "TX HW queue 1 timed out," | 359 | WARNING(rt2x00dev, "TX HW queue 1 timed out," |
304 | " invoke forced kick\n"); | 360 | " invoke forced kick\n"); |
305 | 361 | ||
306 | rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); | 362 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); |
307 | 363 | ||
308 | for (i = 0; i < 10; i++) { | 364 | for (i = 0; i < 10; i++) { |
309 | udelay(10); | 365 | udelay(10); |
@@ -311,7 +367,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
311 | break; | 367 | break; |
312 | } | 368 | } |
313 | 369 | ||
314 | rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); | 370 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); |
315 | } | 371 | } |
316 | 372 | ||
317 | rt2x00usb_watchdog(rt2x00dev); | 373 | rt2x00usb_watchdog(rt2x00dev); |
@@ -420,13 +476,24 @@ static void rt2800usb_work_txdone(struct work_struct *work) | |||
420 | while (!rt2x00queue_empty(queue)) { | 476 | while (!rt2x00queue_empty(queue)) { |
421 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 477 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
422 | 478 | ||
423 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | 479 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
424 | !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | 480 | break; |
481 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | ||
482 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
483 | else if (rt2x00queue_status_timeout(entry)) | ||
484 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
485 | else | ||
425 | break; | 486 | break; |
426 | |||
427 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
428 | } | 487 | } |
429 | } | 488 | } |
489 | |||
490 | /* | ||
491 | * The hw may delay sending the packet after DMA complete | ||
492 | * if the medium is busy, thus the TX_STA_FIFO entry is | ||
493 | * also delayed -> use a timer to retrieve it. | ||
494 | */ | ||
495 | if (rt2800usb_txstatus_pending(rt2x00dev)) | ||
496 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); | ||
430 | } | 497 | } |
431 | 498 | ||
432 | /* | 499 | /* |
@@ -553,18 +620,23 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
553 | * This device has multiple filters for control frames | 620 | * This device has multiple filters for control frames |
554 | * and has a separate filter for PS Poll frames. | 621 | * and has a separate filter for PS Poll frames. |
555 | */ | 622 | */ |
556 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); | 623 | __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); |
557 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags); | 624 | __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags); |
558 | 625 | ||
559 | /* | 626 | /* |
560 | * This device requires firmware. | 627 | * This device requires firmware. |
561 | */ | 628 | */ |
562 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 629 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); |
563 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); | 630 | __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags); |
564 | if (!modparam_nohwcrypt) | 631 | if (!modparam_nohwcrypt) |
565 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 632 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
566 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 633 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
567 | __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); | 634 | __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); |
635 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); | ||
636 | |||
637 | setup_timer(&rt2x00dev->txstatus_timer, | ||
638 | rt2800usb_tx_sta_fifo_timeout, | ||
639 | (unsigned long) rt2x00dev); | ||
568 | 640 | ||
569 | /* | 641 | /* |
570 | * Set the rssi offset. | 642 | * Set the rssi offset. |
@@ -601,6 +673,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { | |||
601 | .ampdu_action = rt2800_ampdu_action, | 673 | .ampdu_action = rt2800_ampdu_action, |
602 | .flush = rt2x00mac_flush, | 674 | .flush = rt2x00mac_flush, |
603 | .get_survey = rt2800_get_survey, | 675 | .get_survey = rt2800_get_survey, |
676 | .get_ringparam = rt2x00mac_get_ringparam, | ||
604 | }; | 677 | }; |
605 | 678 | ||
606 | static const struct rt2800_ops rt2800usb_rt2800_ops = { | 679 | static const struct rt2800_ops rt2800usb_rt2800_ops = { |
@@ -635,6 +708,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
635 | .kick_queue = rt2x00usb_kick_queue, | 708 | .kick_queue = rt2x00usb_kick_queue, |
636 | .stop_queue = rt2800usb_stop_queue, | 709 | .stop_queue = rt2800usb_stop_queue, |
637 | .flush_queue = rt2x00usb_flush_queue, | 710 | .flush_queue = rt2x00usb_flush_queue, |
711 | .tx_dma_done = rt2800usb_tx_dma_done, | ||
638 | .write_tx_desc = rt2800usb_write_tx_desc, | 712 | .write_tx_desc = rt2800usb_write_tx_desc, |
639 | .write_tx_data = rt2800usb_write_tx_data, | 713 | .write_tx_data = rt2800usb_write_tx_data, |
640 | .write_beacon = rt2800_write_beacon, | 714 | .write_beacon = rt2800_write_beacon, |
@@ -695,295 +769,332 @@ static const struct rt2x00_ops rt2800usb_ops = { | |||
695 | */ | 769 | */ |
696 | static struct usb_device_id rt2800usb_device_table[] = { | 770 | static struct usb_device_id rt2800usb_device_table[] = { |
697 | /* Abocom */ | 771 | /* Abocom */ |
698 | { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, | 772 | { USB_DEVICE(0x07b8, 0x2870) }, |
699 | { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, | 773 | { USB_DEVICE(0x07b8, 0x2770) }, |
700 | { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 774 | { USB_DEVICE(0x07b8, 0x3070) }, |
701 | { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 775 | { USB_DEVICE(0x07b8, 0x3071) }, |
702 | { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 776 | { USB_DEVICE(0x07b8, 0x3072) }, |
703 | { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, | 777 | { USB_DEVICE(0x1482, 0x3c09) }, |
704 | /* AirTies */ | 778 | /* AirTies */ |
705 | { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, | 779 | { USB_DEVICE(0x1eda, 0x2012) }, |
780 | { USB_DEVICE(0x1eda, 0x2310) }, | ||
706 | /* Allwin */ | 781 | /* Allwin */ |
707 | { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 782 | { USB_DEVICE(0x8516, 0x2070) }, |
708 | { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, | 783 | { USB_DEVICE(0x8516, 0x2770) }, |
709 | { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, | 784 | { USB_DEVICE(0x8516, 0x2870) }, |
710 | { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 785 | { USB_DEVICE(0x8516, 0x3070) }, |
711 | { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 786 | { USB_DEVICE(0x8516, 0x3071) }, |
712 | { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 787 | { USB_DEVICE(0x8516, 0x3072) }, |
788 | /* Alpha Networks */ | ||
789 | { USB_DEVICE(0x14b2, 0x3c06) }, | ||
790 | { USB_DEVICE(0x14b2, 0x3c07) }, | ||
791 | { USB_DEVICE(0x14b2, 0x3c09) }, | ||
792 | { USB_DEVICE(0x14b2, 0x3c12) }, | ||
793 | { USB_DEVICE(0x14b2, 0x3c23) }, | ||
794 | { USB_DEVICE(0x14b2, 0x3c25) }, | ||
795 | { USB_DEVICE(0x14b2, 0x3c27) }, | ||
796 | { USB_DEVICE(0x14b2, 0x3c28) }, | ||
797 | { USB_DEVICE(0x14b2, 0x3c2c) }, | ||
713 | /* Amit */ | 798 | /* Amit */ |
714 | { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, | 799 | { USB_DEVICE(0x15c5, 0x0008) }, |
715 | /* Askey */ | 800 | /* Askey */ |
716 | { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) }, | 801 | { USB_DEVICE(0x1690, 0x0740) }, |
717 | /* ASUS */ | 802 | /* ASUS */ |
718 | { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, | 803 | { USB_DEVICE(0x0b05, 0x1731) }, |
719 | { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, | 804 | { USB_DEVICE(0x0b05, 0x1732) }, |
720 | { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, | 805 | { USB_DEVICE(0x0b05, 0x1742) }, |
721 | { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, | 806 | { USB_DEVICE(0x0b05, 0x1784) }, |
722 | { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) }, | 807 | { USB_DEVICE(0x1761, 0x0b05) }, |
723 | /* AzureWave */ | 808 | /* AzureWave */ |
724 | { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, | 809 | { USB_DEVICE(0x13d3, 0x3247) }, |
725 | { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, | 810 | { USB_DEVICE(0x13d3, 0x3273) }, |
726 | { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, | 811 | { USB_DEVICE(0x13d3, 0x3305) }, |
727 | { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, | 812 | { USB_DEVICE(0x13d3, 0x3307) }, |
728 | { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, | 813 | { USB_DEVICE(0x13d3, 0x3321) }, |
729 | /* Belkin */ | 814 | /* Belkin */ |
730 | { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, | 815 | { USB_DEVICE(0x050d, 0x8053) }, |
731 | { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 816 | { USB_DEVICE(0x050d, 0x805c) }, |
732 | { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 817 | { USB_DEVICE(0x050d, 0x815c) }, |
733 | { USB_DEVICE(0x050d, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 818 | { USB_DEVICE(0x050d, 0x825b) }, |
734 | { USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 819 | { USB_DEVICE(0x050d, 0x935a) }, |
735 | { USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 820 | { USB_DEVICE(0x050d, 0x935b) }, |
736 | /* Buffalo */ | 821 | /* Buffalo */ |
737 | { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, | 822 | { USB_DEVICE(0x0411, 0x00e8) }, |
738 | { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 823 | { USB_DEVICE(0x0411, 0x016f) }, |
739 | /* Conceptronic */ | 824 | { USB_DEVICE(0x0411, 0x01a2) }, |
740 | { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
741 | { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
742 | { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
743 | { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
744 | { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
745 | { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
746 | { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
747 | { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
748 | /* Corega */ | 825 | /* Corega */ |
749 | { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 826 | { USB_DEVICE(0x07aa, 0x002f) }, |
750 | { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 827 | { USB_DEVICE(0x07aa, 0x003c) }, |
751 | { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 828 | { USB_DEVICE(0x07aa, 0x003f) }, |
752 | { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, | 829 | { USB_DEVICE(0x18c5, 0x0012) }, |
753 | /* D-Link */ | 830 | /* D-Link */ |
754 | { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, | 831 | { USB_DEVICE(0x07d1, 0x3c09) }, |
755 | { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 832 | { USB_DEVICE(0x07d1, 0x3c0a) }, |
756 | { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 833 | { USB_DEVICE(0x07d1, 0x3c0d) }, |
757 | { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 834 | { USB_DEVICE(0x07d1, 0x3c0e) }, |
758 | { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 835 | { USB_DEVICE(0x07d1, 0x3c0f) }, |
759 | { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, | 836 | { USB_DEVICE(0x07d1, 0x3c11) }, |
760 | { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, | 837 | { USB_DEVICE(0x07d1, 0x3c16) }, |
761 | /* Draytek */ | 838 | /* Draytek */ |
762 | { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) }, | 839 | { USB_DEVICE(0x07fa, 0x7712) }, |
763 | /* Edimax */ | 840 | /* Edimax */ |
764 | { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, | 841 | { USB_DEVICE(0x7392, 0x7711) }, |
765 | { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, | 842 | { USB_DEVICE(0x7392, 0x7717) }, |
766 | { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, | 843 | { USB_DEVICE(0x7392, 0x7718) }, |
767 | /* Encore */ | 844 | /* Encore */ |
768 | { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, | 845 | { USB_DEVICE(0x203d, 0x1480) }, |
769 | { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, | 846 | { USB_DEVICE(0x203d, 0x14a9) }, |
770 | /* EnGenius */ | 847 | /* EnGenius */ |
771 | { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, | 848 | { USB_DEVICE(0x1740, 0x9701) }, |
772 | { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, | 849 | { USB_DEVICE(0x1740, 0x9702) }, |
773 | { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, | 850 | { USB_DEVICE(0x1740, 0x9703) }, |
774 | { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, | 851 | { USB_DEVICE(0x1740, 0x9705) }, |
775 | { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, | 852 | { USB_DEVICE(0x1740, 0x9706) }, |
776 | { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, | 853 | { USB_DEVICE(0x1740, 0x9707) }, |
777 | { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, | 854 | { USB_DEVICE(0x1740, 0x9708) }, |
778 | { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, | 855 | { USB_DEVICE(0x1740, 0x9709) }, |
856 | /* Gemtek */ | ||
857 | { USB_DEVICE(0x15a9, 0x0012) }, | ||
779 | /* Gigabyte */ | 858 | /* Gigabyte */ |
780 | { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 859 | { USB_DEVICE(0x1044, 0x800b) }, |
781 | { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 860 | { USB_DEVICE(0x1044, 0x800d) }, |
782 | /* Hawking */ | 861 | /* Hawking */ |
783 | { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, | 862 | { USB_DEVICE(0x0e66, 0x0001) }, |
784 | { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, | 863 | { USB_DEVICE(0x0e66, 0x0003) }, |
785 | { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, | 864 | { USB_DEVICE(0x0e66, 0x0009) }, |
786 | { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 865 | { USB_DEVICE(0x0e66, 0x000b) }, |
787 | { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) }, | 866 | { USB_DEVICE(0x0e66, 0x0013) }, |
788 | { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, | 867 | { USB_DEVICE(0x0e66, 0x0017) }, |
789 | { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) }, | 868 | { USB_DEVICE(0x0e66, 0x0018) }, |
790 | /* I-O DATA */ | 869 | /* I-O DATA */ |
791 | { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, | 870 | { USB_DEVICE(0x04bb, 0x0945) }, |
792 | { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, | 871 | { USB_DEVICE(0x04bb, 0x0947) }, |
793 | { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, | 872 | { USB_DEVICE(0x04bb, 0x0948) }, |
794 | /* Linksys */ | 873 | /* Linksys */ |
795 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 874 | { USB_DEVICE(0x13b1, 0x0031) }, |
796 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 875 | { USB_DEVICE(0x1737, 0x0070) }, |
876 | { USB_DEVICE(0x1737, 0x0071) }, | ||
797 | /* Logitec */ | 877 | /* Logitec */ |
798 | { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, | 878 | { USB_DEVICE(0x0789, 0x0162) }, |
799 | { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, | 879 | { USB_DEVICE(0x0789, 0x0163) }, |
800 | { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) }, | 880 | { USB_DEVICE(0x0789, 0x0164) }, |
801 | { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) }, | 881 | { USB_DEVICE(0x0789, 0x0166) }, |
802 | /* Motorola */ | 882 | /* Motorola */ |
803 | { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, | 883 | { USB_DEVICE(0x100d, 0x9031) }, |
804 | /* MSI */ | 884 | /* MSI */ |
805 | { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, | 885 | { USB_DEVICE(0x0db0, 0x3820) }, |
806 | { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, | 886 | { USB_DEVICE(0x0db0, 0x3821) }, |
807 | { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) }, | 887 | { USB_DEVICE(0x0db0, 0x3822) }, |
808 | { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, | 888 | { USB_DEVICE(0x0db0, 0x3870) }, |
809 | { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) }, | 889 | { USB_DEVICE(0x0db0, 0x3871) }, |
810 | { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, | 890 | { USB_DEVICE(0x0db0, 0x6899) }, |
811 | { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 891 | { USB_DEVICE(0x0db0, 0x821a) }, |
812 | { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 892 | { USB_DEVICE(0x0db0, 0x822a) }, |
813 | { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 893 | { USB_DEVICE(0x0db0, 0x822b) }, |
814 | { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 894 | { USB_DEVICE(0x0db0, 0x822c) }, |
815 | { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 895 | { USB_DEVICE(0x0db0, 0x870a) }, |
816 | { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 896 | { USB_DEVICE(0x0db0, 0x871a) }, |
817 | { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 897 | { USB_DEVICE(0x0db0, 0x871b) }, |
818 | { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 898 | { USB_DEVICE(0x0db0, 0x871c) }, |
819 | { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 899 | { USB_DEVICE(0x0db0, 0x899a) }, |
820 | /* Para */ | 900 | /* Para */ |
821 | { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, | 901 | { USB_DEVICE(0x20b8, 0x8888) }, |
822 | /* Pegatron */ | 902 | /* Pegatron */ |
823 | { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 903 | { USB_DEVICE(0x1d4d, 0x000c) }, |
824 | { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 904 | { USB_DEVICE(0x1d4d, 0x000e) }, |
825 | { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, | 905 | { USB_DEVICE(0x1d4d, 0x0011) }, |
826 | /* Philips */ | 906 | /* Philips */ |
827 | { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 907 | { USB_DEVICE(0x0471, 0x200f) }, |
828 | /* Planex */ | 908 | /* Planex */ |
829 | { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) }, | 909 | { USB_DEVICE(0x2019, 0xab25) }, |
830 | { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) }, | 910 | { USB_DEVICE(0x2019, 0xed06) }, |
831 | /* Quanta */ | 911 | /* Quanta */ |
832 | { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, | 912 | { USB_DEVICE(0x1a32, 0x0304) }, |
833 | /* Ralink */ | 913 | /* Ralink */ |
834 | { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 914 | { USB_DEVICE(0x148f, 0x2070) }, |
835 | { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, | 915 | { USB_DEVICE(0x148f, 0x2770) }, |
836 | { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, | 916 | { USB_DEVICE(0x148f, 0x2870) }, |
837 | { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 917 | { USB_DEVICE(0x148f, 0x3070) }, |
838 | { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 918 | { USB_DEVICE(0x148f, 0x3071) }, |
839 | { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 919 | { USB_DEVICE(0x148f, 0x3072) }, |
840 | /* Samsung */ | 920 | /* Samsung */ |
841 | { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) }, | 921 | { USB_DEVICE(0x04e8, 0x2018) }, |
842 | /* Siemens */ | 922 | /* Siemens */ |
843 | { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) }, | 923 | { USB_DEVICE(0x129b, 0x1828) }, |
844 | /* Sitecom */ | 924 | /* Sitecom */ |
845 | { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, | 925 | { USB_DEVICE(0x0df6, 0x0017) }, |
846 | { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 926 | { USB_DEVICE(0x0df6, 0x002b) }, |
847 | { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 927 | { USB_DEVICE(0x0df6, 0x002c) }, |
848 | { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 928 | { USB_DEVICE(0x0df6, 0x002d) }, |
849 | { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, | 929 | { USB_DEVICE(0x0df6, 0x0039) }, |
850 | { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 930 | { USB_DEVICE(0x0df6, 0x003b) }, |
851 | { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 931 | { USB_DEVICE(0x0df6, 0x003d) }, |
852 | { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 932 | { USB_DEVICE(0x0df6, 0x003e) }, |
853 | { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 933 | { USB_DEVICE(0x0df6, 0x003f) }, |
854 | { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, | 934 | { USB_DEVICE(0x0df6, 0x0040) }, |
855 | { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, | 935 | { USB_DEVICE(0x0df6, 0x0042) }, |
856 | { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, | 936 | { USB_DEVICE(0x0df6, 0x0047) }, |
857 | { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, | 937 | { USB_DEVICE(0x0df6, 0x0048) }, |
938 | { USB_DEVICE(0x0df6, 0x0051) }, | ||
939 | { USB_DEVICE(0x0df6, 0x005f) }, | ||
858 | /* SMC */ | 940 | /* SMC */ |
859 | { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, | 941 | { USB_DEVICE(0x083a, 0x6618) }, |
860 | { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, | 942 | { USB_DEVICE(0x083a, 0x7511) }, |
861 | { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) }, | 943 | { USB_DEVICE(0x083a, 0x7512) }, |
862 | { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 944 | { USB_DEVICE(0x083a, 0x7522) }, |
863 | { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 945 | { USB_DEVICE(0x083a, 0x8522) }, |
864 | { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, | 946 | { USB_DEVICE(0x083a, 0xa618) }, |
865 | { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, | 947 | { USB_DEVICE(0x083a, 0xa701) }, |
866 | { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, | 948 | { USB_DEVICE(0x083a, 0xa702) }, |
867 | { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) }, | 949 | { USB_DEVICE(0x083a, 0xa703) }, |
868 | { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 950 | { USB_DEVICE(0x083a, 0xb522) }, |
869 | /* Sparklan */ | 951 | /* Sparklan */ |
870 | { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, | 952 | { USB_DEVICE(0x15a9, 0x0006) }, |
871 | /* Sweex */ | 953 | /* Sweex */ |
872 | { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, | 954 | { USB_DEVICE(0x177f, 0x0302) }, |
873 | /* U-Media*/ | 955 | /* U-Media */ |
874 | { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 956 | { USB_DEVICE(0x157e, 0x300e) }, |
957 | { USB_DEVICE(0x157e, 0x3013) }, | ||
875 | /* ZCOM */ | 958 | /* ZCOM */ |
876 | { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, | 959 | { USB_DEVICE(0x0cde, 0x0022) }, |
877 | { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, | 960 | { USB_DEVICE(0x0cde, 0x0025) }, |
878 | /* Zinwell */ | 961 | /* Zinwell */ |
879 | { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, | 962 | { USB_DEVICE(0x5a57, 0x0280) }, |
880 | { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, | 963 | { USB_DEVICE(0x5a57, 0x0282) }, |
881 | { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, | 964 | { USB_DEVICE(0x5a57, 0x0283) }, |
882 | { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, | 965 | { USB_DEVICE(0x5a57, 0x5257) }, |
883 | /* Zyxel */ | 966 | /* Zyxel */ |
884 | { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, | 967 | { USB_DEVICE(0x0586, 0x3416) }, |
885 | { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, | 968 | { USB_DEVICE(0x0586, 0x3418) }, |
969 | { USB_DEVICE(0x0586, 0x341e) }, | ||
970 | { USB_DEVICE(0x0586, 0x343e) }, | ||
886 | #ifdef CONFIG_RT2800USB_RT33XX | 971 | #ifdef CONFIG_RT2800USB_RT33XX |
887 | /* Ralink */ | 972 | /* Ralink */ |
888 | { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, | 973 | { USB_DEVICE(0x148f, 0x3370) }, |
889 | { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 974 | { USB_DEVICE(0x148f, 0x8070) }, |
890 | /* Sitecom */ | 975 | /* Sitecom */ |
891 | { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, | 976 | { USB_DEVICE(0x0df6, 0x0050) }, |
892 | #endif | 977 | #endif |
893 | #ifdef CONFIG_RT2800USB_RT35XX | 978 | #ifdef CONFIG_RT2800USB_RT35XX |
894 | /* Allwin */ | 979 | /* Allwin */ |
895 | { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, | 980 | { USB_DEVICE(0x8516, 0x3572) }, |
896 | /* Askey */ | 981 | /* Askey */ |
897 | { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) }, | 982 | { USB_DEVICE(0x1690, 0x0744) }, |
898 | /* Cisco */ | 983 | /* Cisco */ |
899 | { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) }, | 984 | { USB_DEVICE(0x167b, 0x4001) }, |
900 | /* EnGenius */ | 985 | /* EnGenius */ |
901 | { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, | 986 | { USB_DEVICE(0x1740, 0x9801) }, |
902 | /* I-O DATA */ | 987 | /* I-O DATA */ |
903 | { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, | 988 | { USB_DEVICE(0x04bb, 0x0944) }, |
989 | /* Linksys */ | ||
990 | { USB_DEVICE(0x13b1, 0x002f) }, | ||
991 | { USB_DEVICE(0x1737, 0x0079) }, | ||
904 | /* Ralink */ | 992 | /* Ralink */ |
905 | { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, | 993 | { USB_DEVICE(0x148f, 0x3572) }, |
906 | /* Sitecom */ | 994 | /* Sitecom */ |
907 | { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 995 | { USB_DEVICE(0x0df6, 0x0041) }, |
908 | /* Toshiba */ | 996 | /* Toshiba */ |
909 | { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) }, | 997 | { USB_DEVICE(0x0930, 0x0a07) }, |
910 | /* Zinwell */ | 998 | /* Zinwell */ |
911 | { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, | 999 | { USB_DEVICE(0x5a57, 0x0284) }, |
912 | #endif | 1000 | #endif |
913 | #ifdef CONFIG_RT2800USB_UNKNOWN | 1001 | #ifdef CONFIG_RT2800USB_UNKNOWN |
914 | /* | 1002 | /* |
915 | * Unclear what kind of devices these are (they aren't supported by the | 1003 | * Unclear what kind of devices these are (they aren't supported by the |
916 | * vendor linux driver). | 1004 | * vendor linux driver). |
917 | */ | 1005 | */ |
1006 | /* Abocom */ | ||
1007 | { USB_DEVICE(0x07b8, 0x3073) }, | ||
1008 | { USB_DEVICE(0x07b8, 0x3074) }, | ||
1009 | /* Alpha Networks */ | ||
1010 | { USB_DEVICE(0x14b2, 0x3c08) }, | ||
1011 | { USB_DEVICE(0x14b2, 0x3c11) }, | ||
918 | /* Amigo */ | 1012 | /* Amigo */ |
919 | { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1013 | { USB_DEVICE(0x0e0b, 0x9031) }, |
920 | { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1014 | { USB_DEVICE(0x0e0b, 0x9041) }, |
921 | /* ASUS */ | 1015 | /* ASUS */ |
922 | { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1016 | { USB_DEVICE(0x0b05, 0x166a) }, |
923 | { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1017 | { USB_DEVICE(0x0b05, 0x1760) }, |
924 | { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1018 | { USB_DEVICE(0x0b05, 0x1761) }, |
1019 | { USB_DEVICE(0x0b05, 0x1790) }, | ||
1020 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
925 | /* AzureWave */ | 1021 | /* AzureWave */ |
926 | { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1022 | { USB_DEVICE(0x13d3, 0x3262) }, |
927 | { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1023 | { USB_DEVICE(0x13d3, 0x3284) }, |
928 | { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1024 | { USB_DEVICE(0x13d3, 0x3322) }, |
929 | /* Belkin */ | 1025 | /* Belkin */ |
930 | { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1026 | { USB_DEVICE(0x050d, 0x1003) }, |
1027 | { USB_DEVICE(0x050d, 0x825a) }, | ||
931 | /* Buffalo */ | 1028 | /* Buffalo */ |
932 | { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1029 | { USB_DEVICE(0x0411, 0x012e) }, |
933 | { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1030 | { USB_DEVICE(0x0411, 0x0148) }, |
934 | { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1031 | { USB_DEVICE(0x0411, 0x0150) }, |
935 | { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1032 | { USB_DEVICE(0x0411, 0x015d) }, |
936 | /* Conceptronic */ | ||
937 | { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
938 | { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
939 | /* Corega */ | 1033 | /* Corega */ |
940 | { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1034 | { USB_DEVICE(0x07aa, 0x0041) }, |
941 | { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1035 | { USB_DEVICE(0x07aa, 0x0042) }, |
942 | { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1036 | { USB_DEVICE(0x18c5, 0x0008) }, |
943 | /* D-Link */ | 1037 | /* D-Link */ |
944 | { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1038 | { USB_DEVICE(0x07d1, 0x3c0b) }, |
945 | { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1039 | { USB_DEVICE(0x07d1, 0x3c13) }, |
946 | { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1040 | { USB_DEVICE(0x07d1, 0x3c15) }, |
947 | { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1041 | { USB_DEVICE(0x07d1, 0x3c17) }, |
1042 | { USB_DEVICE(0x2001, 0x3c17) }, | ||
948 | /* Edimax */ | 1043 | /* Edimax */ |
949 | { USB_DEVICE(0x7392, 0x4085), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1044 | { USB_DEVICE(0x7392, 0x4085) }, |
1045 | { USB_DEVICE(0x7392, 0x7722) }, | ||
950 | /* Encore */ | 1046 | /* Encore */ |
951 | { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1047 | { USB_DEVICE(0x203d, 0x14a1) }, |
952 | /* Gemtek */ | 1048 | /* Gemtek */ |
953 | { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1049 | { USB_DEVICE(0x15a9, 0x0010) }, |
954 | /* Gigabyte */ | 1050 | /* Gigabyte */ |
955 | { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1051 | { USB_DEVICE(0x1044, 0x800c) }, |
1052 | /* Huawei */ | ||
1053 | { USB_DEVICE(0x148f, 0xf101) }, | ||
1054 | /* I-O DATA */ | ||
1055 | { USB_DEVICE(0x04bb, 0x094b) }, | ||
956 | /* LevelOne */ | 1056 | /* LevelOne */ |
957 | { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1057 | { USB_DEVICE(0x1740, 0x0605) }, |
958 | { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1058 | { USB_DEVICE(0x1740, 0x0615) }, |
959 | /* Linksys */ | 1059 | /* Linksys */ |
960 | { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1060 | { USB_DEVICE(0x1737, 0x0077) }, |
961 | { USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1061 | { USB_DEVICE(0x1737, 0x0078) }, |
962 | { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1062 | /* Logitec */ |
1063 | { USB_DEVICE(0x0789, 0x0168) }, | ||
1064 | { USB_DEVICE(0x0789, 0x0169) }, | ||
963 | /* Motorola */ | 1065 | /* Motorola */ |
964 | { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1066 | { USB_DEVICE(0x100d, 0x9032) }, |
965 | /* Ovislink */ | 1067 | /* Ovislink */ |
966 | { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1068 | { USB_DEVICE(0x1b75, 0x3071) }, |
967 | { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1069 | { USB_DEVICE(0x1b75, 0x3072) }, |
968 | /* Pegatron */ | 1070 | /* Pegatron */ |
969 | { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1071 | { USB_DEVICE(0x05a6, 0x0101) }, |
970 | { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1072 | { USB_DEVICE(0x1d4d, 0x0002) }, |
971 | { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1073 | { USB_DEVICE(0x1d4d, 0x0010) }, |
972 | /* Planex */ | 1074 | /* Planex */ |
973 | { USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1075 | { USB_DEVICE(0x2019, 0x5201) }, |
974 | { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1076 | { USB_DEVICE(0x2019, 0xab24) }, |
975 | /* Qcom */ | 1077 | /* Qcom */ |
976 | { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1078 | { USB_DEVICE(0x18e8, 0x6259) }, |
1079 | /* RadioShack */ | ||
1080 | { USB_DEVICE(0x08b9, 0x1197) }, | ||
1081 | /* Sitecom */ | ||
1082 | { USB_DEVICE(0x0df6, 0x003c) }, | ||
1083 | { USB_DEVICE(0x0df6, 0x004a) }, | ||
1084 | { USB_DEVICE(0x0df6, 0x004d) }, | ||
1085 | { USB_DEVICE(0x0df6, 0x0053) }, | ||
1086 | { USB_DEVICE(0x0df6, 0x0060) }, | ||
1087 | { USB_DEVICE(0x0df6, 0x0062) }, | ||
977 | /* SMC */ | 1088 | /* SMC */ |
978 | { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1089 | { USB_DEVICE(0x083a, 0xa512) }, |
979 | { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1090 | { USB_DEVICE(0x083a, 0xc522) }, |
980 | { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1091 | { USB_DEVICE(0x083a, 0xd522) }, |
981 | { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1092 | { USB_DEVICE(0x083a, 0xf511) }, |
982 | /* Sweex */ | 1093 | /* Sweex */ |
983 | { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1094 | { USB_DEVICE(0x177f, 0x0153) }, |
984 | { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1095 | { USB_DEVICE(0x177f, 0x0313) }, |
985 | /* Zyxel */ | 1096 | /* Zyxel */ |
986 | { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1097 | { USB_DEVICE(0x0586, 0x341a) }, |
987 | #endif | 1098 | #endif |
988 | { 0, } | 1099 | { 0, } |
989 | }; | 1100 | }; |
@@ -996,10 +1107,16 @@ MODULE_DEVICE_TABLE(usb, rt2800usb_device_table); | |||
996 | MODULE_FIRMWARE(FIRMWARE_RT2870); | 1107 | MODULE_FIRMWARE(FIRMWARE_RT2870); |
997 | MODULE_LICENSE("GPL"); | 1108 | MODULE_LICENSE("GPL"); |
998 | 1109 | ||
1110 | static int rt2800usb_probe(struct usb_interface *usb_intf, | ||
1111 | const struct usb_device_id *id) | ||
1112 | { | ||
1113 | return rt2x00usb_probe(usb_intf, &rt2800usb_ops); | ||
1114 | } | ||
1115 | |||
999 | static struct usb_driver rt2800usb_driver = { | 1116 | static struct usb_driver rt2800usb_driver = { |
1000 | .name = KBUILD_MODNAME, | 1117 | .name = KBUILD_MODNAME, |
1001 | .id_table = rt2800usb_device_table, | 1118 | .id_table = rt2800usb_device_table, |
1002 | .probe = rt2x00usb_probe, | 1119 | .probe = rt2800usb_probe, |
1003 | .disconnect = rt2x00usb_disconnect, | 1120 | .disconnect = rt2x00usb_disconnect, |
1004 | .suspend = rt2x00usb_suspend, | 1121 | .suspend = rt2x00usb_suspend, |
1005 | .resume = rt2x00usb_resume, | 1122 | .resume = rt2x00usb_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index a2bd5feb9d5c..9d1a158e2c33 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
38 | #include <linux/input-polldev.h> | 38 | #include <linux/input-polldev.h> |
39 | #include <linux/kfifo.h> | 39 | #include <linux/kfifo.h> |
40 | #include <linux/timer.h> | ||
40 | 41 | ||
41 | #include <net/mac80211.h> | 42 | #include <net/mac80211.h> |
42 | 43 | ||
@@ -570,7 +571,8 @@ struct rt2x00lib_ops { | |||
570 | void (*start_queue) (struct data_queue *queue); | 571 | void (*start_queue) (struct data_queue *queue); |
571 | void (*kick_queue) (struct data_queue *queue); | 572 | void (*kick_queue) (struct data_queue *queue); |
572 | void (*stop_queue) (struct data_queue *queue); | 573 | void (*stop_queue) (struct data_queue *queue); |
573 | void (*flush_queue) (struct data_queue *queue); | 574 | void (*flush_queue) (struct data_queue *queue, bool drop); |
575 | void (*tx_dma_done) (struct queue_entry *entry); | ||
574 | 576 | ||
575 | /* | 577 | /* |
576 | * TX control handlers | 578 | * TX control handlers |
@@ -643,11 +645,11 @@ struct rt2x00_ops { | |||
643 | }; | 645 | }; |
644 | 646 | ||
645 | /* | 647 | /* |
646 | * rt2x00 device flags | 648 | * rt2x00 state flags |
647 | */ | 649 | */ |
648 | enum rt2x00_flags { | 650 | enum rt2x00_state_flags { |
649 | /* | 651 | /* |
650 | * Device state flags | 652 | * Device flags |
651 | */ | 653 | */ |
652 | DEVICE_STATE_PRESENT, | 654 | DEVICE_STATE_PRESENT, |
653 | DEVICE_STATE_REGISTERED_HW, | 655 | DEVICE_STATE_REGISTERED_HW, |
@@ -657,42 +659,47 @@ enum rt2x00_flags { | |||
657 | DEVICE_STATE_SCANNING, | 659 | DEVICE_STATE_SCANNING, |
658 | 660 | ||
659 | /* | 661 | /* |
660 | * Driver requirements | ||
661 | */ | ||
662 | DRIVER_REQUIRE_FIRMWARE, | ||
663 | DRIVER_REQUIRE_BEACON_GUARD, | ||
664 | DRIVER_REQUIRE_ATIM_QUEUE, | ||
665 | DRIVER_REQUIRE_DMA, | ||
666 | DRIVER_REQUIRE_COPY_IV, | ||
667 | DRIVER_REQUIRE_L2PAD, | ||
668 | DRIVER_REQUIRE_TXSTATUS_FIFO, | ||
669 | DRIVER_REQUIRE_TASKLET_CONTEXT, | ||
670 | DRIVER_REQUIRE_SW_SEQNO, | ||
671 | DRIVER_REQUIRE_HT_TX_DESC, | ||
672 | |||
673 | /* | ||
674 | * Driver features | ||
675 | */ | ||
676 | CONFIG_SUPPORT_HW_BUTTON, | ||
677 | CONFIG_SUPPORT_HW_CRYPTO, | ||
678 | CONFIG_SUPPORT_POWER_LIMIT, | ||
679 | DRIVER_SUPPORT_CONTROL_FILTERS, | ||
680 | DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, | ||
681 | DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, | ||
682 | DRIVER_SUPPORT_LINK_TUNING, | ||
683 | |||
684 | /* | ||
685 | * Driver configuration | 662 | * Driver configuration |
686 | */ | 663 | */ |
687 | CONFIG_FRAME_TYPE, | ||
688 | CONFIG_RF_SEQUENCE, | ||
689 | CONFIG_EXTERNAL_LNA_A, | ||
690 | CONFIG_EXTERNAL_LNA_BG, | ||
691 | CONFIG_DOUBLE_ANTENNA, | ||
692 | CONFIG_CHANNEL_HT40, | 664 | CONFIG_CHANNEL_HT40, |
693 | }; | 665 | }; |
694 | 666 | ||
695 | /* | 667 | /* |
668 | * rt2x00 capability flags | ||
669 | */ | ||
670 | enum rt2x00_capability_flags { | ||
671 | /* | ||
672 | * Requirements | ||
673 | */ | ||
674 | REQUIRE_FIRMWARE, | ||
675 | REQUIRE_BEACON_GUARD, | ||
676 | REQUIRE_ATIM_QUEUE, | ||
677 | REQUIRE_DMA, | ||
678 | REQUIRE_COPY_IV, | ||
679 | REQUIRE_L2PAD, | ||
680 | REQUIRE_TXSTATUS_FIFO, | ||
681 | REQUIRE_TASKLET_CONTEXT, | ||
682 | REQUIRE_SW_SEQNO, | ||
683 | REQUIRE_HT_TX_DESC, | ||
684 | |||
685 | /* | ||
686 | * Capabilities | ||
687 | */ | ||
688 | CAPABILITY_HW_BUTTON, | ||
689 | CAPABILITY_HW_CRYPTO, | ||
690 | CAPABILITY_POWER_LIMIT, | ||
691 | CAPABILITY_CONTROL_FILTERS, | ||
692 | CAPABILITY_CONTROL_FILTER_PSPOLL, | ||
693 | CAPABILITY_PRE_TBTT_INTERRUPT, | ||
694 | CAPABILITY_LINK_TUNING, | ||
695 | CAPABILITY_FRAME_TYPE, | ||
696 | CAPABILITY_RF_SEQUENCE, | ||
697 | CAPABILITY_EXTERNAL_LNA_A, | ||
698 | CAPABILITY_EXTERNAL_LNA_BG, | ||
699 | CAPABILITY_DOUBLE_ANTENNA, | ||
700 | }; | ||
701 | |||
702 | /* | ||
696 | * rt2x00 device structure. | 703 | * rt2x00 device structure. |
697 | */ | 704 | */ |
698 | struct rt2x00_dev { | 705 | struct rt2x00_dev { |
@@ -738,13 +745,20 @@ struct rt2x00_dev { | |||
738 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 745 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
739 | 746 | ||
740 | /* | 747 | /* |
741 | * Device flags. | 748 | * Device state flags. |
742 | * In these flags the current status and some | 749 | * In these flags the current status is stored. |
743 | * of the device capabilities are stored. | 750 | * Access to these flags should occur atomically. |
744 | */ | 751 | */ |
745 | unsigned long flags; | 752 | unsigned long flags; |
746 | 753 | ||
747 | /* | 754 | /* |
755 | * Device capabiltiy flags. | ||
756 | * In these flags the device/driver capabilities are stored. | ||
757 | * Access to these flags should occur non-atomically. | ||
758 | */ | ||
759 | unsigned long cap_flags; | ||
760 | |||
761 | /* | ||
748 | * Device information, Bus IRQ and name (PCI, SoC) | 762 | * Device information, Bus IRQ and name (PCI, SoC) |
749 | */ | 763 | */ |
750 | int irq; | 764 | int irq; |
@@ -911,6 +925,11 @@ struct rt2x00_dev { | |||
911 | DECLARE_KFIFO_PTR(txstatus_fifo, u32); | 925 | DECLARE_KFIFO_PTR(txstatus_fifo, u32); |
912 | 926 | ||
913 | /* | 927 | /* |
928 | * Timer to ensure tx status reports are read (rt2800usb). | ||
929 | */ | ||
930 | struct timer_list txstatus_timer; | ||
931 | |||
932 | /* | ||
914 | * Tasklet for processing tx status reports (rt2800pci). | 933 | * Tasklet for processing tx status reports (rt2800pci). |
915 | */ | 934 | */ |
916 | struct tasklet_struct txstatus_tasklet; | 935 | struct tasklet_struct txstatus_tasklet; |
@@ -1235,6 +1254,10 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1235 | const struct ieee80211_tx_queue_params *params); | 1254 | const struct ieee80211_tx_queue_params *params); |
1236 | void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); | 1255 | void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); |
1237 | void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); | 1256 | void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); |
1257 | int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); | ||
1258 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); | ||
1259 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, | ||
1260 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | ||
1238 | 1261 | ||
1239 | /* | 1262 | /* |
1240 | * Driver allocation handlers. | 1263 | * Driver allocation handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 9416e36de29e..f78726404592 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -109,15 +109,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
109 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); | 109 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); |
110 | } | 110 | } |
111 | 111 | ||
112 | static inline | ||
113 | enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant, | ||
114 | enum antenna default_ant) | ||
115 | { | ||
116 | if (current_ant != ANTENNA_SW_DIVERSITY) | ||
117 | return current_ant; | ||
118 | return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B; | ||
119 | } | ||
120 | |||
121 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 112 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
122 | struct antenna_setup config) | 113 | struct antenna_setup config) |
123 | { | 114 | { |
@@ -126,19 +117,35 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
126 | struct antenna_setup *active = &rt2x00dev->link.ant.active; | 117 | struct antenna_setup *active = &rt2x00dev->link.ant.active; |
127 | 118 | ||
128 | /* | 119 | /* |
129 | * Failsafe: Make sure we are not sending the | 120 | * When the caller tries to send the SW diversity, |
130 | * ANTENNA_SW_DIVERSITY state to the driver. | 121 | * we must update the ANTENNA_RX_DIVERSITY flag to |
131 | * If that happens, fallback to hardware defaults, | 122 | * enable the antenna diversity in the link tuner. |
132 | * or our own default. | 123 | * |
124 | * Secondly, we must guarentee we never send the | ||
125 | * software antenna diversity command to the driver. | ||
133 | */ | 126 | */ |
134 | if (!(ant->flags & ANTENNA_RX_DIVERSITY)) | 127 | if (!(ant->flags & ANTENNA_RX_DIVERSITY)) { |
135 | config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); | 128 | if (config.rx == ANTENNA_SW_DIVERSITY) { |
136 | else if (config.rx == ANTENNA_SW_DIVERSITY) | 129 | ant->flags |= ANTENNA_RX_DIVERSITY; |
130 | |||
131 | if (def->rx == ANTENNA_SW_DIVERSITY) | ||
132 | config.rx = ANTENNA_B; | ||
133 | else | ||
134 | config.rx = def->rx; | ||
135 | } | ||
136 | } else if (config.rx == ANTENNA_SW_DIVERSITY) | ||
137 | config.rx = active->rx; | 137 | config.rx = active->rx; |
138 | 138 | ||
139 | if (!(ant->flags & ANTENNA_TX_DIVERSITY)) | 139 | if (!(ant->flags & ANTENNA_TX_DIVERSITY)) { |
140 | config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); | 140 | if (config.tx == ANTENNA_SW_DIVERSITY) { |
141 | else if (config.tx == ANTENNA_SW_DIVERSITY) | 141 | ant->flags |= ANTENNA_TX_DIVERSITY; |
142 | |||
143 | if (def->tx == ANTENNA_SW_DIVERSITY) | ||
144 | config.tx = ANTENNA_B; | ||
145 | else | ||
146 | config.tx = def->tx; | ||
147 | } | ||
148 | } else if (config.tx == ANTENNA_SW_DIVERSITY) | ||
142 | config.tx = active->tx; | 149 | config.tx = active->tx; |
143 | 150 | ||
144 | /* | 151 | /* |
@@ -163,6 +170,34 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
163 | rt2x00queue_start_queue(rt2x00dev->rx); | 170 | rt2x00queue_start_queue(rt2x00dev->rx); |
164 | } | 171 | } |
165 | 172 | ||
173 | static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
174 | struct ieee80211_conf *conf) | ||
175 | { | ||
176 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
177 | int center_channel; | ||
178 | u16 i; | ||
179 | |||
180 | /* | ||
181 | * Initialize center channel to current channel. | ||
182 | */ | ||
183 | center_channel = spec->channels[conf->channel->hw_value].channel; | ||
184 | |||
185 | /* | ||
186 | * Adjust center channel to HT40+ and HT40- operation. | ||
187 | */ | ||
188 | if (conf_is_ht40_plus(conf)) | ||
189 | center_channel += 2; | ||
190 | else if (conf_is_ht40_minus(conf)) | ||
191 | center_channel -= (center_channel == 14) ? 1 : 2; | ||
192 | |||
193 | for (i = 0; i < spec->num_channels; i++) | ||
194 | if (spec->channels[i].channel == center_channel) | ||
195 | return i; | ||
196 | |||
197 | WARN_ON(1); | ||
198 | return conf->channel->hw_value; | ||
199 | } | ||
200 | |||
166 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 201 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
167 | struct ieee80211_conf *conf, | 202 | struct ieee80211_conf *conf, |
168 | unsigned int ieee80211_flags) | 203 | unsigned int ieee80211_flags) |
@@ -176,10 +211,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
176 | 211 | ||
177 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { | 212 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
178 | if (conf_is_ht40(conf)) { | 213 | if (conf_is_ht40(conf)) { |
179 | __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); | 214 | set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); |
180 | hw_value = rt2x00ht_center_channel(rt2x00dev, conf); | 215 | hw_value = rt2x00ht_center_channel(rt2x00dev, conf); |
181 | } else { | 216 | } else { |
182 | __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); | 217 | clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); |
183 | hw_value = conf->channel->hw_value; | 218 | hw_value = conf->channel->hw_value; |
184 | } | 219 | } |
185 | 220 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 3f5688fbf3f7..1bb9d46077ff 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -52,7 +52,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
54 | 54 | ||
55 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !hw_key) | 55 | if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) |
56 | return; | 56 | return; |
57 | 57 | ||
58 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); | 58 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); |
@@ -80,7 +80,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, | |||
80 | struct ieee80211_key_conf *key = tx_info->control.hw_key; | 80 | struct ieee80211_key_conf *key = tx_info->control.hw_key; |
81 | unsigned int overhead = 0; | 81 | unsigned int overhead = 0; |
82 | 82 | ||
83 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !key) | 83 | if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !key) |
84 | return overhead; | 84 | return overhead; |
85 | 85 | ||
86 | /* | 86 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 66166ef037f5..78787fcc919e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -63,7 +63,8 @@ struct rt2x00debug_intf { | |||
63 | * - driver folder | 63 | * - driver folder |
64 | * - driver file | 64 | * - driver file |
65 | * - chipset file | 65 | * - chipset file |
66 | * - device flags file | 66 | * - device state flags file |
67 | * - device capability flags file | ||
67 | * - register folder | 68 | * - register folder |
68 | * - csr offset/value files | 69 | * - csr offset/value files |
69 | * - eeprom offset/value files | 70 | * - eeprom offset/value files |
@@ -78,6 +79,7 @@ struct rt2x00debug_intf { | |||
78 | struct dentry *driver_entry; | 79 | struct dentry *driver_entry; |
79 | struct dentry *chipset_entry; | 80 | struct dentry *chipset_entry; |
80 | struct dentry *dev_flags; | 81 | struct dentry *dev_flags; |
82 | struct dentry *cap_flags; | ||
81 | struct dentry *register_folder; | 83 | struct dentry *register_folder; |
82 | struct dentry *csr_off_entry; | 84 | struct dentry *csr_off_entry; |
83 | struct dentry *csr_val_entry; | 85 | struct dentry *csr_val_entry; |
@@ -553,6 +555,35 @@ static const struct file_operations rt2x00debug_fop_dev_flags = { | |||
553 | .llseek = default_llseek, | 555 | .llseek = default_llseek, |
554 | }; | 556 | }; |
555 | 557 | ||
558 | static ssize_t rt2x00debug_read_cap_flags(struct file *file, | ||
559 | char __user *buf, | ||
560 | size_t length, | ||
561 | loff_t *offset) | ||
562 | { | ||
563 | struct rt2x00debug_intf *intf = file->private_data; | ||
564 | char line[16]; | ||
565 | size_t size; | ||
566 | |||
567 | if (*offset) | ||
568 | return 0; | ||
569 | |||
570 | size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); | ||
571 | |||
572 | if (copy_to_user(buf, line, size)) | ||
573 | return -EFAULT; | ||
574 | |||
575 | *offset += size; | ||
576 | return size; | ||
577 | } | ||
578 | |||
579 | static const struct file_operations rt2x00debug_fop_cap_flags = { | ||
580 | .owner = THIS_MODULE, | ||
581 | .read = rt2x00debug_read_cap_flags, | ||
582 | .open = rt2x00debug_file_open, | ||
583 | .release = rt2x00debug_file_release, | ||
584 | .llseek = default_llseek, | ||
585 | }; | ||
586 | |||
556 | static struct dentry *rt2x00debug_create_file_driver(const char *name, | 587 | static struct dentry *rt2x00debug_create_file_driver(const char *name, |
557 | struct rt2x00debug_intf | 588 | struct rt2x00debug_intf |
558 | *intf, | 589 | *intf, |
@@ -652,6 +683,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
652 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) | 683 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) |
653 | goto exit; | 684 | goto exit; |
654 | 685 | ||
686 | intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR, | ||
687 | intf->driver_folder, intf, | ||
688 | &rt2x00debug_fop_cap_flags); | ||
689 | if (IS_ERR(intf->cap_flags) || !intf->cap_flags) | ||
690 | goto exit; | ||
691 | |||
655 | intf->register_folder = | 692 | intf->register_folder = |
656 | debugfs_create_dir("register", intf->driver_folder); | 693 | debugfs_create_dir("register", intf->driver_folder); |
657 | if (IS_ERR(intf->register_folder) || !intf->register_folder) | 694 | if (IS_ERR(intf->register_folder) || !intf->register_folder) |
@@ -705,7 +742,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
705 | intf, &rt2x00debug_fop_queue_stats); | 742 | intf, &rt2x00debug_fop_queue_stats); |
706 | 743 | ||
707 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 744 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
708 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 745 | if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) |
709 | intf->crypto_stats_entry = | 746 | intf->crypto_stats_entry = |
710 | debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, | 747 | debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, |
711 | intf, &rt2x00debug_fop_crypto_stats); | 748 | intf, &rt2x00debug_fop_crypto_stats); |
@@ -743,6 +780,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
743 | debugfs_remove(intf->csr_off_entry); | 780 | debugfs_remove(intf->csr_off_entry); |
744 | debugfs_remove(intf->register_folder); | 781 | debugfs_remove(intf->register_folder); |
745 | debugfs_remove(intf->dev_flags); | 782 | debugfs_remove(intf->dev_flags); |
783 | debugfs_remove(intf->cap_flags); | ||
746 | debugfs_remove(intf->chipset_entry); | 784 | debugfs_remove(intf->chipset_entry); |
747 | debugfs_remove(intf->driver_entry); | 785 | debugfs_remove(intf->driver_entry); |
748 | debugfs_remove(intf->driver_folder); | 786 | debugfs_remove(intf->driver_folder); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9bffe8438d1f..7776d9f1f297 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -200,7 +200,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
200 | * here as they will fetch the next beacon directly prior to | 200 | * here as they will fetch the next beacon directly prior to |
201 | * transmission. | 201 | * transmission. |
202 | */ | 202 | */ |
203 | if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags)) | 203 | if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags)) |
204 | return; | 204 | return; |
205 | 205 | ||
206 | /* fetch next beacon */ | 206 | /* fetch next beacon */ |
@@ -225,7 +225,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | |||
225 | void rt2x00lib_dmastart(struct queue_entry *entry) | 225 | void rt2x00lib_dmastart(struct queue_entry *entry) |
226 | { | 226 | { |
227 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 227 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
228 | rt2x00queue_index_inc(entry->queue, Q_INDEX); | 228 | rt2x00queue_index_inc(entry, Q_INDEX); |
229 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); | 230 | EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); |
231 | 231 | ||
@@ -233,7 +233,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry) | |||
233 | { | 233 | { |
234 | set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags); | 234 | set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags); |
235 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 235 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
236 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); | 236 | rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE); |
237 | } | 237 | } |
238 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | 238 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); |
239 | 239 | ||
@@ -271,7 +271,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
271 | /* | 271 | /* |
272 | * Remove L2 padding which was added during | 272 | * Remove L2 padding which was added during |
273 | */ | 273 | */ |
274 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 274 | if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) |
275 | rt2x00queue_remove_l2pad(entry->skb, header_length); | 275 | rt2x00queue_remove_l2pad(entry->skb, header_length); |
276 | 276 | ||
277 | /* | 277 | /* |
@@ -280,7 +280,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
280 | * mac80211 will expect the same data to be present it the | 280 | * mac80211 will expect the same data to be present it the |
281 | * frame as it was passed to us. | 281 | * frame as it was passed to us. |
282 | */ | 282 | */ |
283 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 283 | if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) |
284 | rt2x00crypto_tx_insert_iv(entry->skb, header_length); | 284 | rt2x00crypto_tx_insert_iv(entry->skb, header_length); |
285 | 285 | ||
286 | /* | 286 | /* |
@@ -377,7 +377,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
377 | * send the status report back. | 377 | * send the status report back. |
378 | */ | 378 | */ |
379 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { | 379 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { |
380 | if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags)) | 380 | if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags)) |
381 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); | 381 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); |
382 | else | 382 | else |
383 | ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); | 383 | ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); |
@@ -392,7 +392,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
392 | 392 | ||
393 | rt2x00dev->ops->lib->clear_entry(entry); | 393 | rt2x00dev->ops->lib->clear_entry(entry); |
394 | 394 | ||
395 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 395 | rt2x00queue_index_inc(entry, Q_INDEX_DONE); |
396 | 396 | ||
397 | /* | 397 | /* |
398 | * If the data queue was below the threshold before the txdone | 398 | * If the data queue was below the threshold before the txdone |
@@ -559,7 +559,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry) | |||
559 | 559 | ||
560 | submit_entry: | 560 | submit_entry: |
561 | entry->flags = 0; | 561 | entry->flags = 0; |
562 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 562 | rt2x00queue_index_inc(entry, Q_INDEX_DONE); |
563 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && | 563 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && |
564 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 564 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
565 | rt2x00dev->ops->lib->clear_entry(entry); | 565 | rt2x00dev->ops->lib->clear_entry(entry); |
@@ -806,15 +806,15 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
806 | /* | 806 | /* |
807 | * Take TX headroom required for alignment into account. | 807 | * Take TX headroom required for alignment into account. |
808 | */ | 808 | */ |
809 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 809 | if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) |
810 | rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; | 810 | rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; |
811 | else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) | 811 | else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) |
812 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; | 812 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; |
813 | 813 | ||
814 | /* | 814 | /* |
815 | * Allocate tx status FIFO for driver use. | 815 | * Allocate tx status FIFO for driver use. |
816 | */ | 816 | */ |
817 | if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) { | 817 | if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) { |
818 | /* | 818 | /* |
819 | * Allocate the txstatus fifo. In the worst case the tx | 819 | * Allocate the txstatus fifo. In the worst case the tx |
820 | * status fifo has to hold the tx status of all entries | 820 | * status fifo has to hold the tx status of all entries |
@@ -1071,6 +1071,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1071 | /* | 1071 | /* |
1072 | * Stop all work. | 1072 | * Stop all work. |
1073 | */ | 1073 | */ |
1074 | del_timer_sync(&rt2x00dev->txstatus_timer); | ||
1074 | cancel_work_sync(&rt2x00dev->intf_work); | 1075 | cancel_work_sync(&rt2x00dev->intf_work); |
1075 | if (rt2x00_is_usb(rt2x00dev)) { | 1076 | if (rt2x00_is_usb(rt2x00dev)) { |
1076 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1077 | cancel_work_sync(&rt2x00dev->rxdone_work); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index be0ff78c1b16..f316aad30612 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -99,7 +99,7 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | |||
99 | { | 99 | { |
100 | int retval; | 100 | int retval; |
101 | 101 | ||
102 | if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) | 102 | if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags)) |
103 | return 0; | 103 | return 0; |
104 | 104 | ||
105 | if (!rt2x00dev->fw) { | 105 | if (!rt2x00dev->fw) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c deleted file mode 100644 index e8c0c3e92c2f..000000000000 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 HT specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | ||
33 | struct txentry_desc *txdesc, | ||
34 | const struct rt2x00_rate *hwrate) | ||
35 | { | ||
36 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
37 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
38 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
39 | |||
40 | if (tx_info->control.sta) | ||
41 | txdesc->u.ht.mpdu_density = | ||
42 | tx_info->control.sta->ht_cap.ampdu_density; | ||
43 | |||
44 | txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ | ||
45 | |||
46 | /* | ||
47 | * Only one STBC stream is supported for now. | ||
48 | */ | ||
49 | if (tx_info->flags & IEEE80211_TX_CTL_STBC) | ||
50 | txdesc->u.ht.stbc = 1; | ||
51 | |||
52 | /* | ||
53 | * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the | ||
54 | * mcs rate to be used | ||
55 | */ | ||
56 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | ||
57 | txdesc->u.ht.mcs = txrate->idx; | ||
58 | |||
59 | /* | ||
60 | * MIMO PS should be set to 1 for STA's using dynamic SM PS | ||
61 | * when using more then one tx stream (>MCS7). | ||
62 | */ | ||
63 | if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && | ||
64 | ((tx_info->control.sta->ht_cap.cap & | ||
65 | IEEE80211_HT_CAP_SM_PS) >> | ||
66 | IEEE80211_HT_CAP_SM_PS_SHIFT) == | ||
67 | WLAN_HT_CAP_SM_PS_DYNAMIC) | ||
68 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); | ||
69 | } else { | ||
70 | txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); | ||
71 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
72 | txdesc->u.ht.mcs |= 0x08; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * This frame is eligible for an AMPDU, however, don't aggregate | ||
77 | * frames that are intended to probe a specific tx rate. | ||
78 | */ | ||
79 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && | ||
80 | !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) | ||
81 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); | ||
82 | |||
83 | /* | ||
84 | * Set 40Mhz mode if necessary (for legacy rates this will | ||
85 | * duplicate the frame to both channels). | ||
86 | */ | ||
87 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || | ||
88 | txrate->flags & IEEE80211_TX_RC_DUP_DATA) | ||
89 | __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); | ||
90 | if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
91 | __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); | ||
92 | |||
93 | /* | ||
94 | * Determine IFS values | ||
95 | * - Use TXOP_BACKOFF for management frames | ||
96 | * - Use TXOP_SIFS for fragment bursts | ||
97 | * - Use TXOP_HTTXOP for everything else | ||
98 | * | ||
99 | * Note: rt2800 devices won't use CTS protection (if used) | ||
100 | * for frames not transmitted with TXOP_HTTXOP | ||
101 | */ | ||
102 | if (ieee80211_is_mgmt(hdr->frame_control)) | ||
103 | txdesc->u.ht.txop = TXOP_BACKOFF; | ||
104 | else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) | ||
105 | txdesc->u.ht.txop = TXOP_SIFS; | ||
106 | else | ||
107 | txdesc->u.ht.txop = TXOP_HTTXOP; | ||
108 | } | ||
109 | |||
110 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
111 | struct ieee80211_conf *conf) | ||
112 | { | ||
113 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
114 | int center_channel; | ||
115 | u16 i; | ||
116 | |||
117 | /* | ||
118 | * Initialize center channel to current channel. | ||
119 | */ | ||
120 | center_channel = spec->channels[conf->channel->hw_value].channel; | ||
121 | |||
122 | /* | ||
123 | * Adjust center channel to HT40+ and HT40- operation. | ||
124 | */ | ||
125 | if (conf_is_ht40_plus(conf)) | ||
126 | center_channel += 2; | ||
127 | else if (conf_is_ht40_minus(conf)) | ||
128 | center_channel -= (center_channel == 14) ? 1 : 2; | ||
129 | |||
130 | for (i = 0; i < spec->num_channels; i++) | ||
131 | if (spec->channels[i].channel == center_channel) | ||
132 | return i; | ||
133 | |||
134 | WARN_ON(1); | ||
135 | return conf->channel->hw_value; | ||
136 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 88f2f9275528..322cc4f3de5d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -175,14 +175,14 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, | |||
175 | 175 | ||
176 | /** | 176 | /** |
177 | * rt2x00queue_index_inc - Index incrementation function | 177 | * rt2x00queue_index_inc - Index incrementation function |
178 | * @queue: Queue (&struct data_queue) to perform the action on. | 178 | * @entry: Queue entry (&struct queue_entry) to perform the action on. |
179 | * @index: Index type (&enum queue_index) to perform the action on. | 179 | * @index: Index type (&enum queue_index) to perform the action on. |
180 | * | 180 | * |
181 | * This function will increase the requested index on the queue, | 181 | * This function will increase the requested index on the entry's queue, |
182 | * it will grab the appropriate locks and handle queue overflow events by | 182 | * it will grab the appropriate locks and handle queue overflow events by |
183 | * resetting the index to the start of the queue. | 183 | * resetting the index to the start of the queue. |
184 | */ | 184 | */ |
185 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | 185 | void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index); |
186 | 186 | ||
187 | /** | 187 | /** |
188 | * rt2x00queue_init_queues - Initialize all data queues | 188 | * rt2x00queue_init_queues - Initialize all data queues |
@@ -388,41 +388,17 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, | |||
388 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | 388 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ |
389 | 389 | ||
390 | /* | 390 | /* |
391 | * HT handlers. | ||
392 | */ | ||
393 | #ifdef CONFIG_RT2X00_LIB_HT | ||
394 | void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | ||
395 | struct txentry_desc *txdesc, | ||
396 | const struct rt2x00_rate *hwrate); | ||
397 | |||
398 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
399 | struct ieee80211_conf *conf); | ||
400 | #else | ||
401 | static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | ||
402 | struct txentry_desc *txdesc, | ||
403 | const struct rt2x00_rate *hwrate) | ||
404 | { | ||
405 | } | ||
406 | |||
407 | static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
408 | struct ieee80211_conf *conf) | ||
409 | { | ||
410 | return conf->channel->hw_value; | ||
411 | } | ||
412 | #endif /* CONFIG_RT2X00_LIB_HT */ | ||
413 | |||
414 | /* | ||
415 | * RFkill handlers. | 391 | * RFkill handlers. |
416 | */ | 392 | */ |
417 | static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | 393 | static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) |
418 | { | 394 | { |
419 | if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | 395 | if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags)) |
420 | wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy); | 396 | wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy); |
421 | } | 397 | } |
422 | 398 | ||
423 | static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | 399 | static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) |
424 | { | 400 | { |
425 | if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | 401 | if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags)) |
426 | wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy); | 402 | wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy); |
427 | } | 403 | } |
428 | 404 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 1435976b8779..ea10b0068f82 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -192,17 +192,7 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | |||
192 | /* | 192 | /* |
193 | * Determine if software diversity is enabled for | 193 | * Determine if software diversity is enabled for |
194 | * either the TX or RX antenna (or both). | 194 | * either the TX or RX antenna (or both). |
195 | * Always perform this check since within the link | ||
196 | * tuner interval the configuration might have changed. | ||
197 | */ | 195 | */ |
198 | ant->flags &= ~ANTENNA_RX_DIVERSITY; | ||
199 | ant->flags &= ~ANTENNA_TX_DIVERSITY; | ||
200 | |||
201 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) | ||
202 | ant->flags |= ANTENNA_RX_DIVERSITY; | ||
203 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | ||
204 | ant->flags |= ANTENNA_TX_DIVERSITY; | ||
205 | |||
206 | if (!(ant->flags & ANTENNA_RX_DIVERSITY) && | 196 | if (!(ant->flags & ANTENNA_RX_DIVERSITY) && |
207 | !(ant->flags & ANTENNA_TX_DIVERSITY)) { | 197 | !(ant->flags & ANTENNA_TX_DIVERSITY)) { |
208 | ant->flags = 0; | 198 | ant->flags = 0; |
@@ -383,7 +373,7 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
383 | * do not support link tuning at all, while other devices can disable | 373 | * do not support link tuning at all, while other devices can disable |
384 | * the feature from the EEPROM. | 374 | * the feature from the EEPROM. |
385 | */ | 375 | */ |
386 | if (test_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags)) | 376 | if (test_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags)) |
387 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); | 377 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); |
388 | 378 | ||
389 | /* | 379 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 661c6baad2b9..93bec140e598 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -119,7 +119,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
119 | * Use the ATIM queue if appropriate and present. | 119 | * Use the ATIM queue if appropriate and present. |
120 | */ | 120 | */ |
121 | if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && | 121 | if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && |
122 | test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | 122 | test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) |
123 | qid = QID_ATIM; | 123 | qid = QID_ATIM; |
124 | 124 | ||
125 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | 125 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
@@ -158,7 +158,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
158 | return; | 158 | return; |
159 | 159 | ||
160 | exit_fail: | 160 | exit_fail: |
161 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 161 | rt2x00queue_pause_queue(queue); |
162 | dev_kfree_skb_any(skb); | 162 | dev_kfree_skb_any(skb); |
163 | } | 163 | } |
164 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); | 164 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); |
@@ -411,11 +411,11 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
411 | * of different types, but has no a separate filter for PS Poll frames, | 411 | * of different types, but has no a separate filter for PS Poll frames, |
412 | * FIF_CONTROL flag implies FIF_PSPOLL. | 412 | * FIF_CONTROL flag implies FIF_PSPOLL. |
413 | */ | 413 | */ |
414 | if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) { | 414 | if (!test_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags)) { |
415 | if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL) | 415 | if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL) |
416 | *total_flags |= FIF_CONTROL | FIF_PSPOLL; | 416 | *total_flags |= FIF_CONTROL | FIF_PSPOLL; |
417 | } | 417 | } |
418 | if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) { | 418 | if (!test_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags)) { |
419 | if (*total_flags & FIF_CONTROL) | 419 | if (*total_flags & FIF_CONTROL) |
420 | *total_flags |= FIF_PSPOLL; | 420 | *total_flags |= FIF_PSPOLL; |
421 | } | 421 | } |
@@ -496,7 +496,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
496 | 496 | ||
497 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 497 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
498 | return 0; | 498 | return 0; |
499 | else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 499 | else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) |
500 | return -EOPNOTSUPP; | 500 | return -EOPNOTSUPP; |
501 | else if (key->keylen > 32) | 501 | else if (key->keylen > 32) |
502 | return -ENOSPC; | 502 | return -ENOSPC; |
@@ -562,7 +562,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_key); | |||
562 | void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) | 562 | void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) |
563 | { | 563 | { |
564 | struct rt2x00_dev *rt2x00dev = hw->priv; | 564 | struct rt2x00_dev *rt2x00dev = hw->priv; |
565 | __set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); | 565 | set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); |
566 | rt2x00link_stop_tuner(rt2x00dev); | 566 | rt2x00link_stop_tuner(rt2x00dev); |
567 | } | 567 | } |
568 | EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); | 568 | EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); |
@@ -570,7 +570,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); | |||
570 | void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw) | 570 | void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw) |
571 | { | 571 | { |
572 | struct rt2x00_dev *rt2x00dev = hw->priv; | 572 | struct rt2x00_dev *rt2x00dev = hw->priv; |
573 | __clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); | 573 | clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); |
574 | rt2x00link_start_tuner(rt2x00dev); | 574 | rt2x00link_start_tuner(rt2x00dev); |
575 | } | 575 | } |
576 | EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete); | 576 | EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete); |
@@ -737,3 +737,84 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) | |||
737 | rt2x00queue_flush_queue(queue, drop); | 737 | rt2x00queue_flush_queue(queue, drop); |
738 | } | 738 | } |
739 | EXPORT_SYMBOL_GPL(rt2x00mac_flush); | 739 | EXPORT_SYMBOL_GPL(rt2x00mac_flush); |
740 | |||
741 | int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) | ||
742 | { | ||
743 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
744 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
745 | struct antenna_setup *def = &rt2x00dev->default_ant; | ||
746 | struct antenna_setup setup; | ||
747 | |||
748 | // The antenna value is not supposed to be 0, | ||
749 | // or exceed the maximum number of antenna's. | ||
750 | if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3)) | ||
751 | return -EINVAL; | ||
752 | |||
753 | // When the client tried to configure the antenna to or from | ||
754 | // diversity mode, we must reset the default antenna as well | ||
755 | // as that controls the diversity switch. | ||
756 | if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3) | ||
757 | ant->flags &= ~ANTENNA_TX_DIVERSITY; | ||
758 | if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3) | ||
759 | ant->flags &= ~ANTENNA_RX_DIVERSITY; | ||
760 | |||
761 | // If diversity is being enabled, check if we need hardware | ||
762 | // or software diversity. In the latter case, reset the value, | ||
763 | // and make sure we update the antenna flags to have the | ||
764 | // link tuner pick up the diversity tuning. | ||
765 | if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) { | ||
766 | tx_ant = ANTENNA_SW_DIVERSITY; | ||
767 | ant->flags |= ANTENNA_TX_DIVERSITY; | ||
768 | } | ||
769 | |||
770 | if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) { | ||
771 | rx_ant = ANTENNA_SW_DIVERSITY; | ||
772 | ant->flags |= ANTENNA_RX_DIVERSITY; | ||
773 | } | ||
774 | |||
775 | setup.tx = tx_ant; | ||
776 | setup.rx = rx_ant; | ||
777 | |||
778 | rt2x00lib_config_antenna(rt2x00dev, setup); | ||
779 | |||
780 | return 0; | ||
781 | } | ||
782 | EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna); | ||
783 | |||
784 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | ||
785 | { | ||
786 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
787 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
788 | struct antenna_setup *active = &rt2x00dev->link.ant.active; | ||
789 | |||
790 | // When software diversity is active, we must report this to the | ||
791 | // client and not the current active antenna state. | ||
792 | if (ant->flags & ANTENNA_TX_DIVERSITY) | ||
793 | *tx_ant = ANTENNA_HW_DIVERSITY; | ||
794 | else | ||
795 | *tx_ant = active->tx; | ||
796 | |||
797 | if (ant->flags & ANTENNA_RX_DIVERSITY) | ||
798 | *rx_ant = ANTENNA_HW_DIVERSITY; | ||
799 | else | ||
800 | *rx_ant = active->rx; | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna); | ||
805 | |||
806 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, | ||
807 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) | ||
808 | { | ||
809 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
810 | struct data_queue *queue; | ||
811 | |||
812 | tx_queue_for_each(rt2x00dev, queue) { | ||
813 | *tx += queue->length; | ||
814 | *tx_max += queue->limit; | ||
815 | } | ||
816 | |||
817 | *rx = rt2x00dev->rx->length; | ||
818 | *rx_max = rt2x00dev->rx->limit; | ||
819 | } | ||
820 | EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 9649bd0cd718..17148bb24426 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -99,6 +99,15 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
99 | } | 99 | } |
100 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 100 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
101 | 101 | ||
102 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) | ||
103 | { | ||
104 | unsigned int i; | ||
105 | |||
106 | for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) | ||
107 | msleep(10); | ||
108 | } | ||
109 | EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); | ||
110 | |||
102 | /* | 111 | /* |
103 | * Device initialization handlers. | 112 | * Device initialization handlers. |
104 | */ | 113 | */ |
@@ -242,9 +251,8 @@ exit: | |||
242 | return -ENOMEM; | 251 | return -ENOMEM; |
243 | } | 252 | } |
244 | 253 | ||
245 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | 254 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) |
246 | { | 255 | { |
247 | struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data; | ||
248 | struct ieee80211_hw *hw; | 256 | struct ieee80211_hw *hw; |
249 | struct rt2x00_dev *rt2x00dev; | 257 | struct rt2x00_dev *rt2x00dev; |
250 | int retval; | 258 | int retval; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 07961b8b369a..e2c99f2b9a14 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -107,6 +107,16 @@ struct queue_entry_priv_pci { | |||
107 | */ | 107 | */ |
108 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 108 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); |
109 | 109 | ||
110 | /** | ||
111 | * rt2x00pci_flush_queue - Flush data queue | ||
112 | * @queue: Data queue to stop | ||
113 | * @drop: True to drop all pending frames. | ||
114 | * | ||
115 | * This will wait for a maximum of 100ms, waiting for the queues | ||
116 | * to become empty. | ||
117 | */ | ||
118 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); | ||
119 | |||
110 | /* | 120 | /* |
111 | * Device initialization handlers. | 121 | * Device initialization handlers. |
112 | */ | 122 | */ |
@@ -116,7 +126,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); | |||
116 | /* | 126 | /* |
117 | * PCI driver handlers. | 127 | * PCI driver handlers. |
118 | */ | 128 | */ |
119 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); | 129 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); |
120 | void rt2x00pci_remove(struct pci_dev *pci_dev); | 130 | void rt2x00pci_remove(struct pci_dev *pci_dev); |
121 | #ifdef CONFIG_PM | 131 | #ifdef CONFIG_PM |
122 | int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state); | 132 | int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 94b8bbb7ad80..ab8c16f8bcaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -60,7 +60,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) | |||
60 | * at least 8 bytes bytes available in headroom for IV/EIV | 60 | * at least 8 bytes bytes available in headroom for IV/EIV |
61 | * and 8 bytes for ICV data as tailroon. | 61 | * and 8 bytes for ICV data as tailroon. |
62 | */ | 62 | */ |
63 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 63 | if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) { |
64 | head_size += 8; | 64 | head_size += 8; |
65 | tail_size += 8; | 65 | tail_size += 8; |
66 | } | 66 | } |
@@ -86,7 +86,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) | |||
86 | memset(skbdesc, 0, sizeof(*skbdesc)); | 86 | memset(skbdesc, 0, sizeof(*skbdesc)); |
87 | skbdesc->entry = entry; | 87 | skbdesc->entry = entry; |
88 | 88 | ||
89 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { | 89 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) { |
90 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, | 90 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, |
91 | skb->data, | 91 | skb->data, |
92 | skb->len, | 92 | skb->len, |
@@ -213,7 +213,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
213 | 213 | ||
214 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | 214 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); |
215 | 215 | ||
216 | if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags)) | 216 | if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags)) |
217 | return; | 217 | return; |
218 | 218 | ||
219 | /* | 219 | /* |
@@ -302,6 +302,85 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
302 | } | 302 | } |
303 | } | 303 | } |
304 | 304 | ||
305 | static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, | ||
306 | struct txentry_desc *txdesc, | ||
307 | const struct rt2x00_rate *hwrate) | ||
308 | { | ||
309 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
310 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
311 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
312 | |||
313 | if (tx_info->control.sta) | ||
314 | txdesc->u.ht.mpdu_density = | ||
315 | tx_info->control.sta->ht_cap.ampdu_density; | ||
316 | |||
317 | txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ | ||
318 | |||
319 | /* | ||
320 | * Only one STBC stream is supported for now. | ||
321 | */ | ||
322 | if (tx_info->flags & IEEE80211_TX_CTL_STBC) | ||
323 | txdesc->u.ht.stbc = 1; | ||
324 | |||
325 | /* | ||
326 | * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the | ||
327 | * mcs rate to be used | ||
328 | */ | ||
329 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | ||
330 | txdesc->u.ht.mcs = txrate->idx; | ||
331 | |||
332 | /* | ||
333 | * MIMO PS should be set to 1 for STA's using dynamic SM PS | ||
334 | * when using more then one tx stream (>MCS7). | ||
335 | */ | ||
336 | if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && | ||
337 | ((tx_info->control.sta->ht_cap.cap & | ||
338 | IEEE80211_HT_CAP_SM_PS) >> | ||
339 | IEEE80211_HT_CAP_SM_PS_SHIFT) == | ||
340 | WLAN_HT_CAP_SM_PS_DYNAMIC) | ||
341 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); | ||
342 | } else { | ||
343 | txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); | ||
344 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
345 | txdesc->u.ht.mcs |= 0x08; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * This frame is eligible for an AMPDU, however, don't aggregate | ||
350 | * frames that are intended to probe a specific tx rate. | ||
351 | */ | ||
352 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && | ||
353 | !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) | ||
354 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); | ||
355 | |||
356 | /* | ||
357 | * Set 40Mhz mode if necessary (for legacy rates this will | ||
358 | * duplicate the frame to both channels). | ||
359 | */ | ||
360 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || | ||
361 | txrate->flags & IEEE80211_TX_RC_DUP_DATA) | ||
362 | __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); | ||
363 | if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
364 | __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); | ||
365 | |||
366 | /* | ||
367 | * Determine IFS values | ||
368 | * - Use TXOP_BACKOFF for management frames except beacons | ||
369 | * - Use TXOP_SIFS for fragment bursts | ||
370 | * - Use TXOP_HTTXOP for everything else | ||
371 | * | ||
372 | * Note: rt2800 devices won't use CTS protection (if used) | ||
373 | * for frames not transmitted with TXOP_HTTXOP | ||
374 | */ | ||
375 | if (ieee80211_is_mgmt(hdr->frame_control) && | ||
376 | !ieee80211_is_beacon(hdr->frame_control)) | ||
377 | txdesc->u.ht.txop = TXOP_BACKOFF; | ||
378 | else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) | ||
379 | txdesc->u.ht.txop = TXOP_SIFS; | ||
380 | else | ||
381 | txdesc->u.ht.txop = TXOP_HTTXOP; | ||
382 | } | ||
383 | |||
305 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 384 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
306 | struct txentry_desc *txdesc) | 385 | struct txentry_desc *txdesc) |
307 | { | 386 | { |
@@ -396,8 +475,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
396 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | 475 | rt2x00crypto_create_tx_descriptor(entry, txdesc); |
397 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); | 476 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); |
398 | 477 | ||
399 | if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags)) | 478 | if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) |
400 | rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); | 479 | rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate); |
401 | else | 480 | else |
402 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); | 481 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); |
403 | } | 482 | } |
@@ -436,7 +515,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, | |||
436 | /* | 515 | /* |
437 | * Map the skb to DMA. | 516 | * Map the skb to DMA. |
438 | */ | 517 | */ |
439 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) | 518 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) |
440 | rt2x00queue_map_txskb(entry); | 519 | rt2x00queue_map_txskb(entry); |
441 | 520 | ||
442 | return 0; | 521 | return 0; |
@@ -529,7 +608,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
529 | */ | 608 | */ |
530 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && | 609 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && |
531 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { | 610 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { |
532 | if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags)) | 611 | if (test_bit(REQUIRE_COPY_IV, &queue->rt2x00dev->cap_flags)) |
533 | rt2x00crypto_tx_copy_iv(skb, &txdesc); | 612 | rt2x00crypto_tx_copy_iv(skb, &txdesc); |
534 | else | 613 | else |
535 | rt2x00crypto_tx_remove_iv(skb, &txdesc); | 614 | rt2x00crypto_tx_remove_iv(skb, &txdesc); |
@@ -543,9 +622,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
543 | * PCI and USB devices, while header alignment only is valid | 622 | * PCI and USB devices, while header alignment only is valid |
544 | * for PCI devices. | 623 | * for PCI devices. |
545 | */ | 624 | */ |
546 | if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags)) | 625 | if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) |
547 | rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); | 626 | rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); |
548 | else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) | 627 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) |
549 | rt2x00queue_align_frame(entry->skb); | 628 | rt2x00queue_align_frame(entry->skb); |
550 | 629 | ||
551 | /* | 630 | /* |
@@ -561,7 +640,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
561 | 640 | ||
562 | set_bit(ENTRY_DATA_PENDING, &entry->flags); | 641 | set_bit(ENTRY_DATA_PENDING, &entry->flags); |
563 | 642 | ||
564 | rt2x00queue_index_inc(queue, Q_INDEX); | 643 | rt2x00queue_index_inc(entry, Q_INDEX); |
565 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | 644 | rt2x00queue_write_tx_descriptor(entry, &txdesc); |
566 | rt2x00queue_kick_tx_queue(queue, &txdesc); | 645 | rt2x00queue_kick_tx_queue(queue, &txdesc); |
567 | 646 | ||
@@ -650,10 +729,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
650 | return ret; | 729 | return ret; |
651 | } | 730 | } |
652 | 731 | ||
653 | void rt2x00queue_for_each_entry(struct data_queue *queue, | 732 | bool rt2x00queue_for_each_entry(struct data_queue *queue, |
654 | enum queue_index start, | 733 | enum queue_index start, |
655 | enum queue_index end, | 734 | enum queue_index end, |
656 | void (*fn)(struct queue_entry *entry)) | 735 | void *data, |
736 | bool (*fn)(struct queue_entry *entry, | ||
737 | void *data)) | ||
657 | { | 738 | { |
658 | unsigned long irqflags; | 739 | unsigned long irqflags; |
659 | unsigned int index_start; | 740 | unsigned int index_start; |
@@ -664,7 +745,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, | |||
664 | ERROR(queue->rt2x00dev, | 745 | ERROR(queue->rt2x00dev, |
665 | "Entry requested from invalid index range (%d - %d)\n", | 746 | "Entry requested from invalid index range (%d - %d)\n", |
666 | start, end); | 747 | start, end); |
667 | return; | 748 | return true; |
668 | } | 749 | } |
669 | 750 | ||
670 | /* | 751 | /* |
@@ -683,15 +764,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, | |||
683 | * send out all frames in the correct order. | 764 | * send out all frames in the correct order. |
684 | */ | 765 | */ |
685 | if (index_start < index_end) { | 766 | if (index_start < index_end) { |
686 | for (i = index_start; i < index_end; i++) | 767 | for (i = index_start; i < index_end; i++) { |
687 | fn(&queue->entries[i]); | 768 | if (fn(&queue->entries[i], data)) |
769 | return true; | ||
770 | } | ||
688 | } else { | 771 | } else { |
689 | for (i = index_start; i < queue->limit; i++) | 772 | for (i = index_start; i < queue->limit; i++) { |
690 | fn(&queue->entries[i]); | 773 | if (fn(&queue->entries[i], data)) |
774 | return true; | ||
775 | } | ||
691 | 776 | ||
692 | for (i = 0; i < index_end; i++) | 777 | for (i = 0; i < index_end; i++) { |
693 | fn(&queue->entries[i]); | 778 | if (fn(&queue->entries[i], data)) |
779 | return true; | ||
780 | } | ||
694 | } | 781 | } |
782 | |||
783 | return false; | ||
695 | } | 784 | } |
696 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | 785 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); |
697 | 786 | ||
@@ -717,8 +806,9 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | |||
717 | } | 806 | } |
718 | EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); | 807 | EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); |
719 | 808 | ||
720 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | 809 | void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) |
721 | { | 810 | { |
811 | struct data_queue *queue = entry->queue; | ||
722 | unsigned long irqflags; | 812 | unsigned long irqflags; |
723 | 813 | ||
724 | if (unlikely(index >= Q_INDEX_MAX)) { | 814 | if (unlikely(index >= Q_INDEX_MAX)) { |
@@ -733,7 +823,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
733 | if (queue->index[index] >= queue->limit) | 823 | if (queue->index[index] >= queue->limit) |
734 | queue->index[index] = 0; | 824 | queue->index[index] = 0; |
735 | 825 | ||
736 | queue->last_action[index] = jiffies; | 826 | entry->last_action = jiffies; |
737 | 827 | ||
738 | if (index == Q_INDEX) { | 828 | if (index == Q_INDEX) { |
739 | queue->length++; | 829 | queue->length++; |
@@ -838,7 +928,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); | |||
838 | 928 | ||
839 | void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) | 929 | void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) |
840 | { | 930 | { |
841 | unsigned int i; | ||
842 | bool started; | 931 | bool started; |
843 | bool tx_queue = | 932 | bool tx_queue = |
844 | (queue->qid == QID_AC_VO) || | 933 | (queue->qid == QID_AC_VO) || |
@@ -873,20 +962,12 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) | |||
873 | } | 962 | } |
874 | 963 | ||
875 | /* | 964 | /* |
876 | * Check if driver supports flushing, we can only guarantee | 965 | * Check if driver supports flushing, if that is the case we can |
877 | * full support for flushing if the driver is able | 966 | * defer the flushing to the driver. Otherwise we must use the |
878 | * to cancel all pending frames (drop = true). | 967 | * alternative which just waits for the queue to become empty. |
879 | */ | 968 | */ |
880 | if (drop && queue->rt2x00dev->ops->lib->flush_queue) | 969 | if (likely(queue->rt2x00dev->ops->lib->flush_queue)) |
881 | queue->rt2x00dev->ops->lib->flush_queue(queue); | 970 | queue->rt2x00dev->ops->lib->flush_queue(queue, drop); |
882 | |||
883 | /* | ||
884 | * When we don't want to drop any frames, or when | ||
885 | * the driver doesn't fully flush the queue correcly, | ||
886 | * we must wait for the queue to become empty. | ||
887 | */ | ||
888 | for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++) | ||
889 | msleep(10); | ||
890 | 971 | ||
891 | /* | 972 | /* |
892 | * The queue flush has failed... | 973 | * The queue flush has failed... |
@@ -959,10 +1040,8 @@ static void rt2x00queue_reset(struct data_queue *queue) | |||
959 | queue->count = 0; | 1040 | queue->count = 0; |
960 | queue->length = 0; | 1041 | queue->length = 0; |
961 | 1042 | ||
962 | for (i = 0; i < Q_INDEX_MAX; i++) { | 1043 | for (i = 0; i < Q_INDEX_MAX; i++) |
963 | queue->index[i] = 0; | 1044 | queue->index[i] = 0; |
964 | queue->last_action[i] = jiffies; | ||
965 | } | ||
966 | 1045 | ||
967 | spin_unlock_irqrestore(&queue->index_lock, irqflags); | 1046 | spin_unlock_irqrestore(&queue->index_lock, irqflags); |
968 | } | 1047 | } |
@@ -1069,7 +1148,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
1069 | if (status) | 1148 | if (status) |
1070 | goto exit; | 1149 | goto exit; |
1071 | 1150 | ||
1072 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { | 1151 | if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) { |
1073 | status = rt2x00queue_alloc_entries(rt2x00dev->atim, | 1152 | status = rt2x00queue_alloc_entries(rt2x00dev->atim, |
1074 | rt2x00dev->ops->atim); | 1153 | rt2x00dev->ops->atim); |
1075 | if (status) | 1154 | if (status) |
@@ -1121,7 +1200,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
1121 | struct data_queue *queue; | 1200 | struct data_queue *queue; |
1122 | enum data_queue_qid qid; | 1201 | enum data_queue_qid qid; |
1123 | unsigned int req_atim = | 1202 | unsigned int req_atim = |
1124 | !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1203 | !!test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); |
1125 | 1204 | ||
1126 | /* | 1205 | /* |
1127 | * We need the following queues: | 1206 | * We need the following queues: |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 5db6a99fce7d..167d45873dca 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -364,6 +364,7 @@ enum queue_entry_flags { | |||
364 | * struct queue_entry: Entry inside the &struct data_queue | 364 | * struct queue_entry: Entry inside the &struct data_queue |
365 | * | 365 | * |
366 | * @flags: Entry flags, see &enum queue_entry_flags. | 366 | * @flags: Entry flags, see &enum queue_entry_flags. |
367 | * @last_action: Timestamp of last change. | ||
367 | * @queue: The data queue (&struct data_queue) to which this entry belongs. | 368 | * @queue: The data queue (&struct data_queue) to which this entry belongs. |
368 | * @skb: The buffer which is currently being transmitted (for TX queue), | 369 | * @skb: The buffer which is currently being transmitted (for TX queue), |
369 | * or used to directly receive data in (for RX queue). | 370 | * or used to directly receive data in (for RX queue). |
@@ -373,6 +374,7 @@ enum queue_entry_flags { | |||
373 | */ | 374 | */ |
374 | struct queue_entry { | 375 | struct queue_entry { |
375 | unsigned long flags; | 376 | unsigned long flags; |
377 | unsigned long last_action; | ||
376 | 378 | ||
377 | struct data_queue *queue; | 379 | struct data_queue *queue; |
378 | 380 | ||
@@ -463,7 +465,6 @@ struct data_queue { | |||
463 | unsigned short threshold; | 465 | unsigned short threshold; |
464 | unsigned short length; | 466 | unsigned short length; |
465 | unsigned short index[Q_INDEX_MAX]; | 467 | unsigned short index[Q_INDEX_MAX]; |
466 | unsigned long last_action[Q_INDEX_MAX]; | ||
467 | 468 | ||
468 | unsigned short txop; | 469 | unsigned short txop; |
469 | unsigned short aifs; | 470 | unsigned short aifs; |
@@ -580,16 +581,22 @@ struct data_queue_desc { | |||
580 | * @queue: Pointer to @data_queue | 581 | * @queue: Pointer to @data_queue |
581 | * @start: &enum queue_index Pointer to start index | 582 | * @start: &enum queue_index Pointer to start index |
582 | * @end: &enum queue_index Pointer to end index | 583 | * @end: &enum queue_index Pointer to end index |
584 | * @data: Data to pass to the callback function | ||
583 | * @fn: The function to call for each &struct queue_entry | 585 | * @fn: The function to call for each &struct queue_entry |
584 | * | 586 | * |
585 | * This will walk through all entries in the queue, in chronological | 587 | * This will walk through all entries in the queue, in chronological |
586 | * order. This means it will start at the current @start pointer | 588 | * order. This means it will start at the current @start pointer |
587 | * and will walk through the queue until it reaches the @end pointer. | 589 | * and will walk through the queue until it reaches the @end pointer. |
590 | * | ||
591 | * If fn returns true for an entry rt2x00queue_for_each_entry will stop | ||
592 | * processing and return true as well. | ||
588 | */ | 593 | */ |
589 | void rt2x00queue_for_each_entry(struct data_queue *queue, | 594 | bool rt2x00queue_for_each_entry(struct data_queue *queue, |
590 | enum queue_index start, | 595 | enum queue_index start, |
591 | enum queue_index end, | 596 | enum queue_index end, |
592 | void (*fn)(struct queue_entry *entry)); | 597 | void *data, |
598 | bool (*fn)(struct queue_entry *entry, | ||
599 | void *data)); | ||
593 | 600 | ||
594 | /** | 601 | /** |
595 | * rt2x00queue_empty - Check if the queue is empty. | 602 | * rt2x00queue_empty - Check if the queue is empty. |
@@ -629,22 +636,24 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) | |||
629 | 636 | ||
630 | /** | 637 | /** |
631 | * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports | 638 | * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports |
632 | * @queue: Queue to check. | 639 | * @entry: Queue entry to check. |
633 | */ | 640 | */ |
634 | static inline int rt2x00queue_status_timeout(struct data_queue *queue) | 641 | static inline int rt2x00queue_status_timeout(struct queue_entry *entry) |
635 | { | 642 | { |
636 | return time_after(queue->last_action[Q_INDEX_DMA_DONE], | 643 | if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
637 | queue->last_action[Q_INDEX_DONE] + (HZ / 10)); | 644 | return false; |
645 | return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); | ||
638 | } | 646 | } |
639 | 647 | ||
640 | /** | 648 | /** |
641 | * rt2x00queue_timeout - Check if a timeout occurred for DMA transfers | 649 | * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers |
642 | * @queue: Queue to check. | 650 | * @entry: Queue entry to check. |
643 | */ | 651 | */ |
644 | static inline int rt2x00queue_dma_timeout(struct data_queue *queue) | 652 | static inline int rt2x00queue_dma_timeout(struct queue_entry *entry) |
645 | { | 653 | { |
646 | return time_after(queue->last_action[Q_INDEX], | 654 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
647 | queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); | 655 | return false; |
656 | return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); | ||
648 | } | 657 | } |
649 | 658 | ||
650 | /** | 659 | /** |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 36f388f97d65..cb208d589ff8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -165,6 +165,56 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
165 | } | 165 | } |
166 | EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); | 166 | EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); |
167 | 167 | ||
168 | |||
169 | struct rt2x00_async_read_data { | ||
170 | __le32 reg; | ||
171 | struct usb_ctrlrequest cr; | ||
172 | struct rt2x00_dev *rt2x00dev; | ||
173 | void (*callback)(struct rt2x00_dev *,int,u32); | ||
174 | }; | ||
175 | |||
176 | static void rt2x00usb_register_read_async_cb(struct urb *urb) | ||
177 | { | ||
178 | struct rt2x00_async_read_data *rd = urb->context; | ||
179 | rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg)); | ||
180 | kfree(urb->context); | ||
181 | } | ||
182 | |||
183 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | ||
184 | const unsigned int offset, | ||
185 | void (*callback)(struct rt2x00_dev*,int,u32)) | ||
186 | { | ||
187 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
188 | struct urb *urb; | ||
189 | struct rt2x00_async_read_data *rd; | ||
190 | |||
191 | rd = kmalloc(sizeof(*rd), GFP_ATOMIC); | ||
192 | if (!rd) | ||
193 | return; | ||
194 | |||
195 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
196 | if (!urb) { | ||
197 | kfree(rd); | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | rd->rt2x00dev = rt2x00dev; | ||
202 | rd->callback = callback; | ||
203 | rd->cr.bRequestType = USB_VENDOR_REQUEST_IN; | ||
204 | rd->cr.bRequest = USB_MULTI_READ; | ||
205 | rd->cr.wValue = 0; | ||
206 | rd->cr.wIndex = cpu_to_le16(offset); | ||
207 | rd->cr.wLength = cpu_to_le16(sizeof(u32)); | ||
208 | |||
209 | usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
210 | (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg), | ||
211 | rt2x00usb_register_read_async_cb, rd); | ||
212 | if (usb_submit_urb(urb, GFP_ATOMIC) < 0) | ||
213 | kfree(rd); | ||
214 | usb_free_urb(urb); | ||
215 | } | ||
216 | EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async); | ||
217 | |||
168 | /* | 218 | /* |
169 | * TX data handlers. | 219 | * TX data handlers. |
170 | */ | 220 | */ |
@@ -212,6 +262,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
212 | if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 262 | if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
213 | return; | 263 | return; |
214 | 264 | ||
265 | if (rt2x00dev->ops->lib->tx_dma_done) | ||
266 | rt2x00dev->ops->lib->tx_dma_done(entry); | ||
267 | |||
215 | /* | 268 | /* |
216 | * Report the frame as DMA done | 269 | * Report the frame as DMA done |
217 | */ | 270 | */ |
@@ -227,10 +280,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
227 | * Schedule the delayed work for reading the TX status | 280 | * Schedule the delayed work for reading the TX status |
228 | * from the device. | 281 | * from the device. |
229 | */ | 282 | */ |
230 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 283 | if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) || |
284 | !kfifo_is_empty(&rt2x00dev->txstatus_fifo)) | ||
285 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | ||
231 | } | 286 | } |
232 | 287 | ||
233 | static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | 288 | static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) |
234 | { | 289 | { |
235 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 290 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
236 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 291 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
@@ -240,7 +295,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | |||
240 | 295 | ||
241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || | 296 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || |
242 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | 297 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
243 | return; | 298 | return true; |
244 | 299 | ||
245 | /* | 300 | /* |
246 | * USB devices cannot blindly pass the skb->len as the | 301 | * USB devices cannot blindly pass the skb->len as the |
@@ -261,6 +316,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | |||
261 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | 316 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
262 | rt2x00lib_dmadone(entry); | 317 | rt2x00lib_dmadone(entry); |
263 | } | 318 | } |
319 | |||
320 | return false; | ||
264 | } | 321 | } |
265 | 322 | ||
266 | /* | 323 | /* |
@@ -323,7 +380,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
323 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); | 380 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); |
324 | } | 381 | } |
325 | 382 | ||
326 | static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | 383 | static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data) |
327 | { | 384 | { |
328 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 385 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
329 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 386 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
@@ -332,7 +389,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | |||
332 | 389 | ||
333 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | 390 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
334 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | 391 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
335 | return; | 392 | return true; |
336 | 393 | ||
337 | rt2x00lib_dmastart(entry); | 394 | rt2x00lib_dmastart(entry); |
338 | 395 | ||
@@ -348,6 +405,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | |||
348 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | 405 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
349 | rt2x00lib_dmadone(entry); | 406 | rt2x00lib_dmadone(entry); |
350 | } | 407 | } |
408 | |||
409 | return false; | ||
351 | } | 410 | } |
352 | 411 | ||
353 | void rt2x00usb_kick_queue(struct data_queue *queue) | 412 | void rt2x00usb_kick_queue(struct data_queue *queue) |
@@ -358,12 +417,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
358 | case QID_AC_BE: | 417 | case QID_AC_BE: |
359 | case QID_AC_BK: | 418 | case QID_AC_BK: |
360 | if (!rt2x00queue_empty(queue)) | 419 | if (!rt2x00queue_empty(queue)) |
361 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 420 | rt2x00queue_for_each_entry(queue, |
421 | Q_INDEX_DONE, | ||
422 | Q_INDEX, | ||
423 | NULL, | ||
362 | rt2x00usb_kick_tx_entry); | 424 | rt2x00usb_kick_tx_entry); |
363 | break; | 425 | break; |
364 | case QID_RX: | 426 | case QID_RX: |
365 | if (!rt2x00queue_full(queue)) | 427 | if (!rt2x00queue_full(queue)) |
366 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 428 | rt2x00queue_for_each_entry(queue, |
429 | Q_INDEX_DONE, | ||
430 | Q_INDEX, | ||
431 | NULL, | ||
367 | rt2x00usb_kick_rx_entry); | 432 | rt2x00usb_kick_rx_entry); |
368 | break; | 433 | break; |
369 | default: | 434 | default: |
@@ -372,14 +437,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
372 | } | 437 | } |
373 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); | 438 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); |
374 | 439 | ||
375 | static void rt2x00usb_flush_entry(struct queue_entry *entry) | 440 | static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) |
376 | { | 441 | { |
377 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 442 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
378 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 443 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
379 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; | 444 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
380 | 445 | ||
381 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 446 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
382 | return; | 447 | return true; |
383 | 448 | ||
384 | usb_kill_urb(entry_priv->urb); | 449 | usb_kill_urb(entry_priv->urb); |
385 | 450 | ||
@@ -387,17 +452,20 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry) | |||
387 | * Kill guardian urb (if required by driver). | 452 | * Kill guardian urb (if required by driver). |
388 | */ | 453 | */ |
389 | if ((entry->queue->qid == QID_BEACON) && | 454 | if ((entry->queue->qid == QID_BEACON) && |
390 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) | 455 | (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) |
391 | usb_kill_urb(bcn_priv->guardian_urb); | 456 | usb_kill_urb(bcn_priv->guardian_urb); |
457 | |||
458 | return false; | ||
392 | } | 459 | } |
393 | 460 | ||
394 | void rt2x00usb_flush_queue(struct data_queue *queue) | 461 | void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) |
395 | { | 462 | { |
396 | struct work_struct *completion; | 463 | struct work_struct *completion; |
397 | unsigned int i; | 464 | unsigned int i; |
398 | 465 | ||
399 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 466 | if (drop) |
400 | rt2x00usb_flush_entry); | 467 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, |
468 | rt2x00usb_flush_entry); | ||
401 | 469 | ||
402 | /* | 470 | /* |
403 | * Obtain the queue completion handler | 471 | * Obtain the queue completion handler |
@@ -416,7 +484,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) | |||
416 | return; | 484 | return; |
417 | } | 485 | } |
418 | 486 | ||
419 | for (i = 0; i < 20; i++) { | 487 | for (i = 0; i < 10; i++) { |
420 | /* | 488 | /* |
421 | * Check if the driver is already done, otherwise we | 489 | * Check if the driver is already done, otherwise we |
422 | * have to sleep a little while to give the driver/hw | 490 | * have to sleep a little while to give the driver/hw |
@@ -456,15 +524,31 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | |||
456 | queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); | 524 | queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); |
457 | } | 525 | } |
458 | 526 | ||
527 | static int rt2x00usb_status_timeout(struct data_queue *queue) | ||
528 | { | ||
529 | struct queue_entry *entry; | ||
530 | |||
531 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
532 | return rt2x00queue_status_timeout(entry); | ||
533 | } | ||
534 | |||
535 | static int rt2x00usb_dma_timeout(struct data_queue *queue) | ||
536 | { | ||
537 | struct queue_entry *entry; | ||
538 | |||
539 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE); | ||
540 | return rt2x00queue_dma_timeout(entry); | ||
541 | } | ||
542 | |||
459 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | 543 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) |
460 | { | 544 | { |
461 | struct data_queue *queue; | 545 | struct data_queue *queue; |
462 | 546 | ||
463 | tx_queue_for_each(rt2x00dev, queue) { | 547 | tx_queue_for_each(rt2x00dev, queue) { |
464 | if (!rt2x00queue_empty(queue)) { | 548 | if (!rt2x00queue_empty(queue)) { |
465 | if (rt2x00queue_dma_timeout(queue)) | 549 | if (rt2x00usb_dma_timeout(queue)) |
466 | rt2x00usb_watchdog_tx_dma(queue); | 550 | rt2x00usb_watchdog_tx_dma(queue); |
467 | if (rt2x00queue_status_timeout(queue)) | 551 | if (rt2x00usb_status_timeout(queue)) |
468 | rt2x00usb_watchdog_tx_status(queue); | 552 | rt2x00usb_watchdog_tx_status(queue); |
469 | } | 553 | } |
470 | } | 554 | } |
@@ -489,7 +573,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) | |||
489 | entry->flags = 0; | 573 | entry->flags = 0; |
490 | 574 | ||
491 | if (entry->queue->qid == QID_RX) | 575 | if (entry->queue->qid == QID_RX) |
492 | rt2x00usb_kick_rx_entry(entry); | 576 | rt2x00usb_kick_rx_entry(entry, NULL); |
493 | } | 577 | } |
494 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 578 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |
495 | 579 | ||
@@ -583,7 +667,7 @@ static int rt2x00usb_alloc_entries(struct data_queue *queue) | |||
583 | * then we are done. | 667 | * then we are done. |
584 | */ | 668 | */ |
585 | if (queue->qid != QID_BEACON || | 669 | if (queue->qid != QID_BEACON || |
586 | !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | 670 | !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) |
587 | return 0; | 671 | return 0; |
588 | 672 | ||
589 | for (i = 0; i < queue->limit; i++) { | 673 | for (i = 0; i < queue->limit; i++) { |
@@ -618,7 +702,7 @@ static void rt2x00usb_free_entries(struct data_queue *queue) | |||
618 | * then we are done. | 702 | * then we are done. |
619 | */ | 703 | */ |
620 | if (queue->qid != QID_BEACON || | 704 | if (queue->qid != QID_BEACON || |
621 | !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | 705 | !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) |
622 | return; | 706 | return; |
623 | 707 | ||
624 | for (i = 0; i < queue->limit; i++) { | 708 | for (i = 0; i < queue->limit; i++) { |
@@ -707,10 +791,9 @@ exit: | |||
707 | } | 791 | } |
708 | 792 | ||
709 | int rt2x00usb_probe(struct usb_interface *usb_intf, | 793 | int rt2x00usb_probe(struct usb_interface *usb_intf, |
710 | const struct usb_device_id *id) | 794 | const struct rt2x00_ops *ops) |
711 | { | 795 | { |
712 | struct usb_device *usb_dev = interface_to_usbdev(usb_intf); | 796 | struct usb_device *usb_dev = interface_to_usbdev(usb_intf); |
713 | struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info; | ||
714 | struct ieee80211_hw *hw; | 797 | struct ieee80211_hw *hw; |
715 | struct rt2x00_dev *rt2x00dev; | 798 | struct rt2x00_dev *rt2x00dev; |
716 | int retval; | 799 | int retval; |
@@ -735,6 +818,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
735 | 818 | ||
736 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); | 819 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); |
737 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); | 820 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); |
821 | init_timer(&rt2x00dev->txstatus_timer); | ||
738 | 822 | ||
739 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 823 | retval = rt2x00usb_alloc_reg(rt2x00dev); |
740 | if (retval) | 824 | if (retval) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index e11c759ac9ed..64be34f612f6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -35,12 +35,6 @@ | |||
35 | }) | 35 | }) |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * This variable should be used with the | ||
39 | * usb_driver structure initialization. | ||
40 | */ | ||
41 | #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) | ||
42 | |||
43 | /* | ||
44 | * For USB vendor requests we need to pass a timeout | 38 | * For USB vendor requests we need to pass a timeout |
45 | * time in ms, for this we use the REGISTER_TIMEOUT, | 39 | * time in ms, for this we use the REGISTER_TIMEOUT, |
46 | * however when loading firmware a higher value is | 40 | * however when loading firmware a higher value is |
@@ -345,6 +339,21 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
345 | const struct rt2x00_field32 field, | 339 | const struct rt2x00_field32 field, |
346 | u32 *reg); | 340 | u32 *reg); |
347 | 341 | ||
342 | /** | ||
343 | * rt2x00usb_register_read_async - Asynchronously read 32bit register word | ||
344 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
345 | * @offset: Register offset | ||
346 | * @callback: Functon to call when read completes. | ||
347 | * | ||
348 | * Submit a control URB to read a 32bit register. This safe to | ||
349 | * be called from atomic context. The callback will be called | ||
350 | * when the URB completes. Otherwise the function is similar | ||
351 | * to rt2x00usb_register_read(). | ||
352 | */ | ||
353 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | ||
354 | const unsigned int offset, | ||
355 | void (*callback)(struct rt2x00_dev*,int,u32)); | ||
356 | |||
348 | /* | 357 | /* |
349 | * Radio handlers | 358 | * Radio handlers |
350 | */ | 359 | */ |
@@ -389,11 +398,13 @@ void rt2x00usb_kick_queue(struct data_queue *queue); | |||
389 | /** | 398 | /** |
390 | * rt2x00usb_flush_queue - Flush data queue | 399 | * rt2x00usb_flush_queue - Flush data queue |
391 | * @queue: Data queue to stop | 400 | * @queue: Data queue to stop |
401 | * @drop: True to drop all pending frames. | ||
392 | * | 402 | * |
393 | * This will walk through all entries of the queue and kill all | 403 | * This will walk through all entries of the queue and will optionally |
394 | * URB's which were send to the device. | 404 | * kill all URB's which were send to the device, or at least wait until |
405 | * they have been returned from the device.. | ||
395 | */ | 406 | */ |
396 | void rt2x00usb_flush_queue(struct data_queue *queue); | 407 | void rt2x00usb_flush_queue(struct data_queue *queue, bool drop); |
397 | 408 | ||
398 | /** | 409 | /** |
399 | * rt2x00usb_watchdog - Watchdog for USB communication | 410 | * rt2x00usb_watchdog - Watchdog for USB communication |
@@ -416,7 +427,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | |||
416 | * USB driver handlers. | 427 | * USB driver handlers. |
417 | */ | 428 | */ |
418 | int rt2x00usb_probe(struct usb_interface *usb_intf, | 429 | int rt2x00usb_probe(struct usb_interface *usb_intf, |
419 | const struct usb_device_id *id); | 430 | const struct rt2x00_ops *ops); |
420 | void rt2x00usb_disconnect(struct usb_interface *usb_intf); | 431 | void rt2x00usb_disconnect(struct usb_interface *usb_intf); |
421 | #ifdef CONFIG_PM | 432 | #ifdef CONFIG_PM |
422 | int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state); | 433 | int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 8ee1514a7943..9d35ec16a3a5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -683,7 +683,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
683 | 683 | ||
684 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529)); | 684 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529)); |
685 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 685 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
686 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | 686 | !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); |
687 | 687 | ||
688 | /* | 688 | /* |
689 | * Configure the RX antenna. | 689 | * Configure the RX antenna. |
@@ -811,10 +811,10 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, | |||
811 | 811 | ||
812 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | 812 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
813 | sel = antenna_sel_a; | 813 | sel = antenna_sel_a; |
814 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 814 | lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
815 | } else { | 815 | } else { |
816 | sel = antenna_sel_bg; | 816 | sel = antenna_sel_bg; |
817 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 817 | lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); |
818 | } | 818 | } |
819 | 819 | ||
820 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | 820 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) |
@@ -834,7 +834,7 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, | |||
834 | else if (rt2x00_rf(rt2x00dev, RF2527)) | 834 | else if (rt2x00_rf(rt2x00dev, RF2527)) |
835 | rt61pci_config_antenna_2x(rt2x00dev, ant); | 835 | rt61pci_config_antenna_2x(rt2x00dev, ant); |
836 | else if (rt2x00_rf(rt2x00dev, RF2529)) { | 836 | else if (rt2x00_rf(rt2x00dev, RF2529)) { |
837 | if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) | 837 | if (test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) |
838 | rt61pci_config_antenna_2x(rt2x00dev, ant); | 838 | rt61pci_config_antenna_2x(rt2x00dev, ant); |
839 | else | 839 | else |
840 | rt61pci_config_antenna_2529(rt2x00dev, ant); | 840 | rt61pci_config_antenna_2529(rt2x00dev, ant); |
@@ -848,13 +848,13 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, | |||
848 | short lna_gain = 0; | 848 | short lna_gain = 0; |
849 | 849 | ||
850 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { | 850 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { |
851 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | 851 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) |
852 | lna_gain += 14; | 852 | lna_gain += 14; |
853 | 853 | ||
854 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | 854 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); |
855 | lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | 855 | lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); |
856 | } else { | 856 | } else { |
857 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 857 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) |
858 | lna_gain += 14; | 858 | lna_gain += 14; |
859 | 859 | ||
860 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | 860 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); |
@@ -1050,14 +1050,14 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, | |||
1050 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | 1050 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
1051 | low_bound = 0x28; | 1051 | low_bound = 0x28; |
1052 | up_bound = 0x48; | 1052 | up_bound = 0x48; |
1053 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1053 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { |
1054 | low_bound += 0x10; | 1054 | low_bound += 0x10; |
1055 | up_bound += 0x10; | 1055 | up_bound += 0x10; |
1056 | } | 1056 | } |
1057 | } else { | 1057 | } else { |
1058 | low_bound = 0x20; | 1058 | low_bound = 0x20; |
1059 | up_bound = 0x40; | 1059 | up_bound = 0x40; |
1060 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | 1060 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { |
1061 | low_bound += 0x10; | 1061 | low_bound += 0x10; |
1062 | up_bound += 0x10; | 1062 | up_bound += 0x10; |
1063 | } | 1063 | } |
@@ -2260,8 +2260,8 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) | |||
2260 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); | 2260 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); |
2261 | } | 2261 | } |
2262 | 2262 | ||
2263 | static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 2263 | static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
2264 | struct rt2x00_field32 irq_field) | 2264 | struct rt2x00_field32 irq_field) |
2265 | { | 2265 | { |
2266 | u32 reg; | 2266 | u32 reg; |
2267 | 2267 | ||
@@ -2537,7 +2537,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2537 | * Determine number of antennas. | 2537 | * Determine number of antennas. |
2538 | */ | 2538 | */ |
2539 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) | 2539 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) |
2540 | __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); | 2540 | __set_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags); |
2541 | 2541 | ||
2542 | /* | 2542 | /* |
2543 | * Identify default antenna configuration. | 2543 | * Identify default antenna configuration. |
@@ -2551,20 +2551,20 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2551 | * Read the Frame type. | 2551 | * Read the Frame type. |
2552 | */ | 2552 | */ |
2553 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) | 2553 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) |
2554 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | 2554 | __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags); |
2555 | 2555 | ||
2556 | /* | 2556 | /* |
2557 | * Detect if this device has a hardware controlled radio. | 2557 | * Detect if this device has a hardware controlled radio. |
2558 | */ | 2558 | */ |
2559 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 2559 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
2560 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 2560 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
2561 | 2561 | ||
2562 | /* | 2562 | /* |
2563 | * Read frequency offset and RF programming sequence. | 2563 | * Read frequency offset and RF programming sequence. |
2564 | */ | 2564 | */ |
2565 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | 2565 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); |
2566 | if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) | 2566 | if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) |
2567 | __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags); | 2567 | __set_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags); |
2568 | 2568 | ||
2569 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | 2569 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); |
2570 | 2570 | ||
@@ -2574,9 +2574,9 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2574 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 2574 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); |
2575 | 2575 | ||
2576 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | 2576 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) |
2577 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 2577 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
2578 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | 2578 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) |
2579 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 2579 | __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); |
2580 | 2580 | ||
2581 | /* | 2581 | /* |
2582 | * When working with a RF2529 chip without double antenna, | 2582 | * When working with a RF2529 chip without double antenna, |
@@ -2584,7 +2584,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2584 | * eeprom word. | 2584 | * eeprom word. |
2585 | */ | 2585 | */ |
2586 | if (rt2x00_rf(rt2x00dev, RF2529) && | 2586 | if (rt2x00_rf(rt2x00dev, RF2529) && |
2587 | !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { | 2587 | !test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) { |
2588 | rt2x00dev->default_ant.rx = | 2588 | rt2x00dev->default_ant.rx = |
2589 | ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); | 2589 | ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); |
2590 | rt2x00dev->default_ant.tx = | 2590 | rt2x00dev->default_ant.tx = |
@@ -2799,7 +2799,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2799 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 2799 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2800 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | 2800 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2801 | 2801 | ||
2802 | if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { | 2802 | if (!test_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags)) { |
2803 | spec->num_channels = 14; | 2803 | spec->num_channels = 14; |
2804 | spec->channels = rf_vals_noseq; | 2804 | spec->channels = rf_vals_noseq; |
2805 | } else { | 2805 | } else { |
@@ -2869,16 +2869,16 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2869 | * This device has multiple filters for control frames, | 2869 | * This device has multiple filters for control frames, |
2870 | * but has no a separate filter for PS Poll frames. | 2870 | * but has no a separate filter for PS Poll frames. |
2871 | */ | 2871 | */ |
2872 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); | 2872 | __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); |
2873 | 2873 | ||
2874 | /* | 2874 | /* |
2875 | * This device requires firmware and DMA mapped skbs. | 2875 | * This device requires firmware and DMA mapped skbs. |
2876 | */ | 2876 | */ |
2877 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2877 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); |
2878 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 2878 | __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); |
2879 | if (!modparam_nohwcrypt) | 2879 | if (!modparam_nohwcrypt) |
2880 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 2880 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
2881 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 2881 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
2882 | 2882 | ||
2883 | /* | 2883 | /* |
2884 | * Set the rssi offset. | 2884 | * Set the rssi offset. |
@@ -2979,6 +2979,9 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2979 | .get_tsf = rt61pci_get_tsf, | 2979 | .get_tsf = rt61pci_get_tsf, |
2980 | .rfkill_poll = rt2x00mac_rfkill_poll, | 2980 | .rfkill_poll = rt2x00mac_rfkill_poll, |
2981 | .flush = rt2x00mac_flush, | 2981 | .flush = rt2x00mac_flush, |
2982 | .set_antenna = rt2x00mac_set_antenna, | ||
2983 | .get_antenna = rt2x00mac_get_antenna, | ||
2984 | .get_ringparam = rt2x00mac_get_ringparam, | ||
2982 | }; | 2985 | }; |
2983 | 2986 | ||
2984 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2987 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
@@ -3003,6 +3006,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
3003 | .start_queue = rt61pci_start_queue, | 3006 | .start_queue = rt61pci_start_queue, |
3004 | .kick_queue = rt61pci_kick_queue, | 3007 | .kick_queue = rt61pci_kick_queue, |
3005 | .stop_queue = rt61pci_stop_queue, | 3008 | .stop_queue = rt61pci_stop_queue, |
3009 | .flush_queue = rt2x00pci_flush_queue, | ||
3006 | .write_tx_desc = rt61pci_write_tx_desc, | 3010 | .write_tx_desc = rt61pci_write_tx_desc, |
3007 | .write_beacon = rt61pci_write_beacon, | 3011 | .write_beacon = rt61pci_write_beacon, |
3008 | .clear_beacon = rt61pci_clear_beacon, | 3012 | .clear_beacon = rt61pci_clear_beacon, |
@@ -3060,11 +3064,11 @@ static const struct rt2x00_ops rt61pci_ops = { | |||
3060 | */ | 3064 | */ |
3061 | static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = { | 3065 | static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = { |
3062 | /* RT2561s */ | 3066 | /* RT2561s */ |
3063 | { PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) }, | 3067 | { PCI_DEVICE(0x1814, 0x0301) }, |
3064 | /* RT2561 v2 */ | 3068 | /* RT2561 v2 */ |
3065 | { PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) }, | 3069 | { PCI_DEVICE(0x1814, 0x0302) }, |
3066 | /* RT2661 */ | 3070 | /* RT2661 */ |
3067 | { PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) }, | 3071 | { PCI_DEVICE(0x1814, 0x0401) }, |
3068 | { 0, } | 3072 | { 0, } |
3069 | }; | 3073 | }; |
3070 | 3074 | ||
@@ -3079,10 +3083,16 @@ MODULE_FIRMWARE(FIRMWARE_RT2561s); | |||
3079 | MODULE_FIRMWARE(FIRMWARE_RT2661); | 3083 | MODULE_FIRMWARE(FIRMWARE_RT2661); |
3080 | MODULE_LICENSE("GPL"); | 3084 | MODULE_LICENSE("GPL"); |
3081 | 3085 | ||
3086 | static int rt61pci_probe(struct pci_dev *pci_dev, | ||
3087 | const struct pci_device_id *id) | ||
3088 | { | ||
3089 | return rt2x00pci_probe(pci_dev, &rt61pci_ops); | ||
3090 | } | ||
3091 | |||
3082 | static struct pci_driver rt61pci_driver = { | 3092 | static struct pci_driver rt61pci_driver = { |
3083 | .name = KBUILD_MODNAME, | 3093 | .name = KBUILD_MODNAME, |
3084 | .id_table = rt61pci_device_table, | 3094 | .id_table = rt61pci_device_table, |
3085 | .probe = rt2x00pci_probe, | 3095 | .probe = rt61pci_probe, |
3086 | .remove = __devexit_p(rt2x00pci_remove), | 3096 | .remove = __devexit_p(rt2x00pci_remove), |
3087 | .suspend = rt2x00pci_suspend, | 3097 | .suspend = rt2x00pci_suspend, |
3088 | .resume = rt2x00pci_resume, | 3098 | .resume = rt2x00pci_resume, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6593059f9c7e..a6ce7d6cbdfa 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -595,7 +595,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
595 | switch (ant->rx) { | 595 | switch (ant->rx) { |
596 | case ANTENNA_HW_DIVERSITY: | 596 | case ANTENNA_HW_DIVERSITY: |
597 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 597 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
598 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 598 | temp = !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags) |
599 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); | 599 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
600 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 600 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
601 | break; | 601 | break; |
@@ -636,7 +636,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
636 | 636 | ||
637 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | 637 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); |
638 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 638 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
639 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | 639 | !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); |
640 | 640 | ||
641 | /* | 641 | /* |
642 | * Configure the RX antenna. | 642 | * Configure the RX antenna. |
@@ -709,10 +709,10 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev, | |||
709 | 709 | ||
710 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | 710 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
711 | sel = antenna_sel_a; | 711 | sel = antenna_sel_a; |
712 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 712 | lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
713 | } else { | 713 | } else { |
714 | sel = antenna_sel_bg; | 714 | sel = antenna_sel_bg; |
715 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 715 | lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); |
716 | } | 716 | } |
717 | 717 | ||
718 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | 718 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) |
@@ -740,7 +740,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev, | |||
740 | short lna_gain = 0; | 740 | short lna_gain = 0; |
741 | 741 | ||
742 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { | 742 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { |
743 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | 743 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) |
744 | lna_gain += 14; | 744 | lna_gain += 14; |
745 | 745 | ||
746 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | 746 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); |
@@ -930,7 +930,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, | |||
930 | low_bound = 0x28; | 930 | low_bound = 0x28; |
931 | up_bound = 0x48; | 931 | up_bound = 0x48; |
932 | 932 | ||
933 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 933 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { |
934 | low_bound += 0x10; | 934 | low_bound += 0x10; |
935 | up_bound += 0x10; | 935 | up_bound += 0x10; |
936 | } | 936 | } |
@@ -946,7 +946,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, | |||
946 | up_bound = 0x1c; | 946 | up_bound = 0x1c; |
947 | } | 947 | } |
948 | 948 | ||
949 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | 949 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { |
950 | low_bound += 0x14; | 950 | low_bound += 0x14; |
951 | up_bound += 0x10; | 951 | up_bound += 0x10; |
952 | } | 952 | } |
@@ -1661,7 +1661,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | 1663 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
1664 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1664 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { |
1665 | if (lna == 3 || lna == 2) | 1665 | if (lna == 3 || lna == 2) |
1666 | offset += 10; | 1666 | offset += 10; |
1667 | } else { | 1667 | } else { |
@@ -1899,13 +1899,13 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1899 | * Read the Frame type. | 1899 | * Read the Frame type. |
1900 | */ | 1900 | */ |
1901 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) | 1901 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) |
1902 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | 1902 | __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags); |
1903 | 1903 | ||
1904 | /* | 1904 | /* |
1905 | * Detect if this device has an hardware controlled radio. | 1905 | * Detect if this device has an hardware controlled radio. |
1906 | */ | 1906 | */ |
1907 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 1907 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
1908 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 1908 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
1909 | 1909 | ||
1910 | /* | 1910 | /* |
1911 | * Read frequency offset. | 1911 | * Read frequency offset. |
@@ -1919,8 +1919,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1919 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 1919 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); |
1920 | 1920 | ||
1921 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) { | 1921 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) { |
1922 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 1922 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
1923 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 1923 | __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); |
1924 | } | 1924 | } |
1925 | 1925 | ||
1926 | /* | 1926 | /* |
@@ -2200,15 +2200,15 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2200 | * This device has multiple filters for control frames, | 2200 | * This device has multiple filters for control frames, |
2201 | * but has no a separate filter for PS Poll frames. | 2201 | * but has no a separate filter for PS Poll frames. |
2202 | */ | 2202 | */ |
2203 | __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); | 2203 | __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); |
2204 | 2204 | ||
2205 | /* | 2205 | /* |
2206 | * This device requires firmware. | 2206 | * This device requires firmware. |
2207 | */ | 2207 | */ |
2208 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2208 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); |
2209 | if (!modparam_nohwcrypt) | 2209 | if (!modparam_nohwcrypt) |
2210 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 2210 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
2211 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 2211 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
2212 | 2212 | ||
2213 | /* | 2213 | /* |
2214 | * Set the rssi offset. | 2214 | * Set the rssi offset. |
@@ -2310,6 +2310,9 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2310 | .get_tsf = rt73usb_get_tsf, | 2310 | .get_tsf = rt73usb_get_tsf, |
2311 | .rfkill_poll = rt2x00mac_rfkill_poll, | 2311 | .rfkill_poll = rt2x00mac_rfkill_poll, |
2312 | .flush = rt2x00mac_flush, | 2312 | .flush = rt2x00mac_flush, |
2313 | .set_antenna = rt2x00mac_set_antenna, | ||
2314 | .get_antenna = rt2x00mac_get_antenna, | ||
2315 | .get_ringparam = rt2x00mac_get_ringparam, | ||
2313 | }; | 2316 | }; |
2314 | 2317 | ||
2315 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2318 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
@@ -2388,113 +2391,113 @@ static const struct rt2x00_ops rt73usb_ops = { | |||
2388 | */ | 2391 | */ |
2389 | static struct usb_device_id rt73usb_device_table[] = { | 2392 | static struct usb_device_id rt73usb_device_table[] = { |
2390 | /* AboCom */ | 2393 | /* AboCom */ |
2391 | { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) }, | 2394 | { USB_DEVICE(0x07b8, 0xb21b) }, |
2392 | { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) }, | 2395 | { USB_DEVICE(0x07b8, 0xb21c) }, |
2393 | { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) }, | 2396 | { USB_DEVICE(0x07b8, 0xb21d) }, |
2394 | { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) }, | 2397 | { USB_DEVICE(0x07b8, 0xb21e) }, |
2395 | { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) }, | 2398 | { USB_DEVICE(0x07b8, 0xb21f) }, |
2396 | /* AL */ | 2399 | /* AL */ |
2397 | { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) }, | 2400 | { USB_DEVICE(0x14b2, 0x3c10) }, |
2398 | /* Amigo */ | 2401 | /* Amigo */ |
2399 | { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, | 2402 | { USB_DEVICE(0x148f, 0x9021) }, |
2400 | { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, | 2403 | { USB_DEVICE(0x0eb0, 0x9021) }, |
2401 | /* AMIT */ | 2404 | /* AMIT */ |
2402 | { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) }, | 2405 | { USB_DEVICE(0x18c5, 0x0002) }, |
2403 | /* Askey */ | 2406 | /* Askey */ |
2404 | { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) }, | 2407 | { USB_DEVICE(0x1690, 0x0722) }, |
2405 | /* ASUS */ | 2408 | /* ASUS */ |
2406 | { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, | 2409 | { USB_DEVICE(0x0b05, 0x1723) }, |
2407 | { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, | 2410 | { USB_DEVICE(0x0b05, 0x1724) }, |
2408 | /* Belkin */ | 2411 | /* Belkin */ |
2409 | { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, | 2412 | { USB_DEVICE(0x050d, 0x705a) }, |
2410 | { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, | 2413 | { USB_DEVICE(0x050d, 0x905b) }, |
2411 | { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, | 2414 | { USB_DEVICE(0x050d, 0x905c) }, |
2412 | /* Billionton */ | 2415 | /* Billionton */ |
2413 | { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) }, | 2416 | { USB_DEVICE(0x1631, 0xc019) }, |
2414 | { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, | 2417 | { USB_DEVICE(0x08dd, 0x0120) }, |
2415 | /* Buffalo */ | 2418 | /* Buffalo */ |
2416 | { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, | 2419 | { USB_DEVICE(0x0411, 0x00d8) }, |
2417 | { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) }, | 2420 | { USB_DEVICE(0x0411, 0x00d9) }, |
2418 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | 2421 | { USB_DEVICE(0x0411, 0x00f4) }, |
2419 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, | 2422 | { USB_DEVICE(0x0411, 0x0116) }, |
2420 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, | 2423 | { USB_DEVICE(0x0411, 0x0119) }, |
2421 | { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, | 2424 | { USB_DEVICE(0x0411, 0x0137) }, |
2422 | /* CEIVA */ | 2425 | /* CEIVA */ |
2423 | { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, | 2426 | { USB_DEVICE(0x178d, 0x02be) }, |
2424 | /* CNet */ | 2427 | /* CNet */ |
2425 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, | 2428 | { USB_DEVICE(0x1371, 0x9022) }, |
2426 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2429 | { USB_DEVICE(0x1371, 0x9032) }, |
2427 | /* Conceptronic */ | 2430 | /* Conceptronic */ |
2428 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, | 2431 | { USB_DEVICE(0x14b2, 0x3c22) }, |
2429 | /* Corega */ | 2432 | /* Corega */ |
2430 | { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, | 2433 | { USB_DEVICE(0x07aa, 0x002e) }, |
2431 | /* D-Link */ | 2434 | /* D-Link */ |
2432 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | 2435 | { USB_DEVICE(0x07d1, 0x3c03) }, |
2433 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | 2436 | { USB_DEVICE(0x07d1, 0x3c04) }, |
2434 | { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, | 2437 | { USB_DEVICE(0x07d1, 0x3c06) }, |
2435 | { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, | 2438 | { USB_DEVICE(0x07d1, 0x3c07) }, |
2436 | /* Edimax */ | 2439 | /* Edimax */ |
2437 | { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, | 2440 | { USB_DEVICE(0x7392, 0x7318) }, |
2438 | { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) }, | 2441 | { USB_DEVICE(0x7392, 0x7618) }, |
2439 | /* EnGenius */ | 2442 | /* EnGenius */ |
2440 | { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) }, | 2443 | { USB_DEVICE(0x1740, 0x3701) }, |
2441 | /* Gemtek */ | 2444 | /* Gemtek */ |
2442 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, | 2445 | { USB_DEVICE(0x15a9, 0x0004) }, |
2443 | /* Gigabyte */ | 2446 | /* Gigabyte */ |
2444 | { USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) }, | 2447 | { USB_DEVICE(0x1044, 0x8008) }, |
2445 | { USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) }, | 2448 | { USB_DEVICE(0x1044, 0x800a) }, |
2446 | /* Huawei-3Com */ | 2449 | /* Huawei-3Com */ |
2447 | { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) }, | 2450 | { USB_DEVICE(0x1472, 0x0009) }, |
2448 | /* Hercules */ | 2451 | /* Hercules */ |
2449 | { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) }, | 2452 | { USB_DEVICE(0x06f8, 0xe002) }, |
2450 | { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) }, | 2453 | { USB_DEVICE(0x06f8, 0xe010) }, |
2451 | { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) }, | 2454 | { USB_DEVICE(0x06f8, 0xe020) }, |
2452 | /* Linksys */ | 2455 | /* Linksys */ |
2453 | { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, | 2456 | { USB_DEVICE(0x13b1, 0x0020) }, |
2454 | { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, | 2457 | { USB_DEVICE(0x13b1, 0x0023) }, |
2455 | { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, | 2458 | { USB_DEVICE(0x13b1, 0x0028) }, |
2456 | /* MSI */ | 2459 | /* MSI */ |
2457 | { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, | 2460 | { USB_DEVICE(0x0db0, 0x4600) }, |
2458 | { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, | 2461 | { USB_DEVICE(0x0db0, 0x6877) }, |
2459 | { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, | 2462 | { USB_DEVICE(0x0db0, 0x6874) }, |
2460 | { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, | 2463 | { USB_DEVICE(0x0db0, 0xa861) }, |
2461 | { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, | 2464 | { USB_DEVICE(0x0db0, 0xa874) }, |
2462 | /* Ovislink */ | 2465 | /* Ovislink */ |
2463 | { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, | 2466 | { USB_DEVICE(0x1b75, 0x7318) }, |
2464 | /* Ralink */ | 2467 | /* Ralink */ |
2465 | { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, | 2468 | { USB_DEVICE(0x04bb, 0x093d) }, |
2466 | { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, | 2469 | { USB_DEVICE(0x148f, 0x2573) }, |
2467 | { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, | 2470 | { USB_DEVICE(0x148f, 0x2671) }, |
2468 | { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) }, | 2471 | { USB_DEVICE(0x0812, 0x3101) }, |
2469 | /* Qcom */ | 2472 | /* Qcom */ |
2470 | { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, | 2473 | { USB_DEVICE(0x18e8, 0x6196) }, |
2471 | { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, | 2474 | { USB_DEVICE(0x18e8, 0x6229) }, |
2472 | { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) }, | 2475 | { USB_DEVICE(0x18e8, 0x6238) }, |
2473 | /* Samsung */ | 2476 | /* Samsung */ |
2474 | { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) }, | 2477 | { USB_DEVICE(0x04e8, 0x4471) }, |
2475 | /* Senao */ | 2478 | /* Senao */ |
2476 | { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) }, | 2479 | { USB_DEVICE(0x1740, 0x7100) }, |
2477 | /* Sitecom */ | 2480 | /* Sitecom */ |
2478 | { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) }, | 2481 | { USB_DEVICE(0x0df6, 0x0024) }, |
2479 | { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) }, | 2482 | { USB_DEVICE(0x0df6, 0x0027) }, |
2480 | { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) }, | 2483 | { USB_DEVICE(0x0df6, 0x002f) }, |
2481 | { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, | 2484 | { USB_DEVICE(0x0df6, 0x90ac) }, |
2482 | { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, | 2485 | { USB_DEVICE(0x0df6, 0x9712) }, |
2483 | /* Surecom */ | 2486 | /* Surecom */ |
2484 | { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, | 2487 | { USB_DEVICE(0x0769, 0x31f3) }, |
2485 | /* Tilgin */ | 2488 | /* Tilgin */ |
2486 | { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) }, | 2489 | { USB_DEVICE(0x6933, 0x5001) }, |
2487 | /* Philips */ | 2490 | /* Philips */ |
2488 | { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) }, | 2491 | { USB_DEVICE(0x0471, 0x200a) }, |
2489 | /* Planex */ | 2492 | /* Planex */ |
2490 | { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, | 2493 | { USB_DEVICE(0x2019, 0xab01) }, |
2491 | { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, | 2494 | { USB_DEVICE(0x2019, 0xab50) }, |
2492 | /* WideTell */ | 2495 | /* WideTell */ |
2493 | { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, | 2496 | { USB_DEVICE(0x7167, 0x3840) }, |
2494 | /* Zcom */ | 2497 | /* Zcom */ |
2495 | { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, | 2498 | { USB_DEVICE(0x0cde, 0x001c) }, |
2496 | /* ZyXEL */ | 2499 | /* ZyXEL */ |
2497 | { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) }, | 2500 | { USB_DEVICE(0x0586, 0x3415) }, |
2498 | { 0, } | 2501 | { 0, } |
2499 | }; | 2502 | }; |
2500 | 2503 | ||
@@ -2506,10 +2509,16 @@ MODULE_DEVICE_TABLE(usb, rt73usb_device_table); | |||
2506 | MODULE_FIRMWARE(FIRMWARE_RT2571); | 2509 | MODULE_FIRMWARE(FIRMWARE_RT2571); |
2507 | MODULE_LICENSE("GPL"); | 2510 | MODULE_LICENSE("GPL"); |
2508 | 2511 | ||
2512 | static int rt73usb_probe(struct usb_interface *usb_intf, | ||
2513 | const struct usb_device_id *id) | ||
2514 | { | ||
2515 | return rt2x00usb_probe(usb_intf, &rt73usb_ops); | ||
2516 | } | ||
2517 | |||
2509 | static struct usb_driver rt73usb_driver = { | 2518 | static struct usb_driver rt73usb_driver = { |
2510 | .name = KBUILD_MODNAME, | 2519 | .name = KBUILD_MODNAME, |
2511 | .id_table = rt73usb_device_table, | 2520 | .id_table = rt73usb_device_table, |
2512 | .probe = rt2x00usb_probe, | 2521 | .probe = rt73usb_probe, |
2513 | .disconnect = rt2x00usb_disconnect, | 2522 | .disconnect = rt2x00usb_disconnect, |
2514 | .suspend = rt2x00usb_suspend, | 2523 | .suspend = rt2x00usb_suspend, |
2515 | .resume = rt2x00usb_resume, | 2524 | .resume = rt2x00usb_resume, |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 4803f54842e4..b259f807ad27 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -251,14 +251,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) | |||
251 | bool blocked; | 251 | bool blocked; |
252 | u8 valid = 0; | 252 | u8 valid = 0; |
253 | 253 | ||
254 | radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); | 254 | /*set init state to on */ |
255 | rtlpriv->rfkill.rfkill_state = 1; | ||
256 | wiphy_rfkill_set_hw_state(hw->wiphy, 0); | ||
255 | 257 | ||
256 | /*set init state to that of switch */ | 258 | radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); |
257 | rtlpriv->rfkill.rfkill_state = radio_state; | ||
258 | printk(KERN_INFO "rtlwifi: wireless switch is %s\n", | ||
259 | rtlpriv->rfkill.rfkill_state ? "on" : "off"); | ||
260 | 259 | ||
261 | if (valid) { | 260 | if (valid) { |
261 | printk(KERN_INFO "rtlwifi: wireless switch is %s\n", | ||
262 | rtlpriv->rfkill.rfkill_state ? "on" : "off"); | ||
263 | |||
262 | rtlpriv->rfkill.rfkill_state = radio_state; | 264 | rtlpriv->rfkill.rfkill_state = radio_state; |
263 | 265 | ||
264 | blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; | 266 | blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index fbde52d83424..c3dd4cc678ba 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1785,7 +1785,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
1785 | 1785 | ||
1786 | rtl_pci_deinit(hw); | 1786 | rtl_pci_deinit(hw); |
1787 | rtl_deinit_core(hw); | 1787 | rtl_deinit_core(hw); |
1788 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | 1788 | if (rtlpriv->cfg->ops->deinit_sw_leds) |
1789 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | ||
1789 | _rtl_pci_io_handler_release(hw); | 1790 | _rtl_pci_io_handler_release(hw); |
1790 | rtlpriv->cfg->ops->deinit_sw_vars(hw); | 1791 | rtlpriv->cfg->ops->deinit_sw_vars(hw); |
1791 | 1792 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bb023274414c..c228b9ee3711 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -634,7 +634,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
634 | u8 thermalvalue, delta, delta_lck, delta_iqk; | 634 | u8 thermalvalue, delta, delta_lck, delta_iqk; |
635 | long ele_a, ele_d, temp_cck, val_x, value32; | 635 | long ele_a, ele_d, temp_cck, val_x, value32; |
636 | long val_y, ele_c; | 636 | long val_y, ele_c; |
637 | u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; | 637 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; |
638 | int i; | 638 | int i; |
639 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 639 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
640 | u8 txpwr_level[2] = {0, 0}; | 640 | u8 txpwr_level[2] = {0, 0}; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index f107660f545d..bc9d24134ac4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -293,7 +293,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, | |||
293 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 293 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
294 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 294 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
295 | u8 boxnum; | 295 | u8 boxnum; |
296 | u16 box_reg, box_extreg; | 296 | u16 box_reg = 0, box_extreg = 0; |
297 | u8 u1b_tmp; | 297 | u8 u1b_tmp; |
298 | bool isfw_read = false; | 298 | bool isfw_read = false; |
299 | bool bwrite_sucess = false; | 299 | bool bwrite_sucess = false; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 7b1da8d7508f..d21b934b5c33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c | |||
@@ -32,6 +32,14 @@ | |||
32 | #include "reg.h" | 32 | #include "reg.h" |
33 | #include "led.h" | 33 | #include "led.h" |
34 | 34 | ||
35 | static void _rtl92ce_init_led(struct ieee80211_hw *hw, | ||
36 | struct rtl_led *pled, enum rtl_led_pin ledpin) | ||
37 | { | ||
38 | pled->hw = hw; | ||
39 | pled->ledpin = ledpin; | ||
40 | pled->ledon = false; | ||
41 | } | ||
42 | |||
35 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | 43 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) |
36 | { | 44 | { |
37 | u8 ledcfg; | 45 | u8 ledcfg; |
@@ -97,10 +105,10 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
97 | 105 | ||
98 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) | 106 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) |
99 | { | 107 | { |
100 | } | 108 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); |
101 | 109 | ||
102 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) | 110 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); |
103 | { | 111 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); |
104 | } | 112 | } |
105 | 113 | ||
106 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, | 114 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 10da3018f4b7..94332b3af5b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h | |||
@@ -31,7 +31,6 @@ | |||
31 | #define __RTL92CE_LED_H__ | 31 | #define __RTL92CE_LED_H__ |
32 | 32 | ||
33 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); | 33 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); |
34 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); | ||
35 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | 34 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); |
36 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | 35 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); |
37 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | 36 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 669b1168dbec..e301b12e281a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | |||
@@ -202,7 +202,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, | |||
202 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 202 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
203 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 203 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
204 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 204 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
205 | u8 i, chnlgroup, pwr_diff_limit[4]; | 205 | u8 i, chnlgroup = 0, pwr_diff_limit[4]; |
206 | u32 writeVal, customer_limit, rf; | 206 | u32 writeVal, customer_limit, rf; |
207 | 207 | ||
208 | for (rf = 0; rf < 2; rf++) { | 208 | for (rf = 0; rf < 2; rf++) { |
@@ -447,7 +447,7 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | |||
447 | { | 447 | { |
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 448 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
450 | u32 u4_regvalue; | 450 | u32 u4_regvalue = 0; |
451 | u8 rfpath; | 451 | u8 rfpath; |
452 | bool rtstatus; | 452 | bool rtstatus; |
453 | struct bb_reg_def *pphyreg; | 453 | struct bb_reg_def *pphyreg; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b1cc4d44f534..f4e2f3dcccae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -131,7 +131,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
131 | .enable_hw_sec = rtl92ce_enable_hw_security_config, | 131 | .enable_hw_sec = rtl92ce_enable_hw_security_config, |
132 | .set_key = rtl92ce_set_key, | 132 | .set_key = rtl92ce_set_key, |
133 | .init_sw_leds = rtl92ce_init_sw_leds, | 133 | .init_sw_leds = rtl92ce_init_sw_leds, |
134 | .deinit_sw_leds = rtl92ce_deinit_sw_leds, | ||
135 | .get_bbreg = rtl92c_phy_query_bb_reg, | 134 | .get_bbreg = rtl92c_phy_query_bb_reg, |
136 | .set_bbreg = rtl92c_phy_set_bb_reg, | 135 | .set_bbreg = rtl92c_phy_set_bb_reg, |
137 | .get_rfreg = rtl92ce_phy_query_rf_reg, | 136 | .get_rfreg = rtl92ce_phy_query_rf_reg, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 9444e76838cf..e43be2547827 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -921,7 +921,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, | |||
921 | u8 out_ep_num, | 921 | u8 out_ep_num, |
922 | u8 queue_sel) | 922 | u8 queue_sel) |
923 | { | 923 | { |
924 | u8 hq_sele; | 924 | u8 hq_sele = 0; |
925 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 925 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
926 | 926 | ||
927 | switch (out_ep_num) { | 927 | switch (out_ep_num) { |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 1832c27c520c..216b1d8a862f 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -410,6 +410,16 @@ | |||
410 | * notification. This event is used to indicate that an unprotected | 410 | * notification. This event is used to indicate that an unprotected |
411 | * disassociation frame was dropped when MFP is in use. | 411 | * disassociation frame was dropped when MFP is in use. |
412 | * | 412 | * |
413 | * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a | ||
414 | * beacon or probe response from a compatible mesh peer. This is only | ||
415 | * sent while no station information (sta_info) exists for the new peer | ||
416 | * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On | ||
417 | * reception of this notification, userspace may decide to create a new | ||
418 | * station (@NL80211_CMD_NEW_STATION). To stop this notification from | ||
419 | * reoccurring, the userspace authentication daemon may want to create the | ||
420 | * new station with the AUTHENTICATED flag unset and maybe change it later | ||
421 | * depending on the authentication result. | ||
422 | * | ||
413 | * @NL80211_CMD_MAX: highest used command number | 423 | * @NL80211_CMD_MAX: highest used command number |
414 | * @__NL80211_CMD_AFTER_LAST: internal use | 424 | * @__NL80211_CMD_AFTER_LAST: internal use |
415 | */ | 425 | */ |
@@ -522,6 +532,8 @@ enum nl80211_commands { | |||
522 | NL80211_CMD_UNPROT_DEAUTHENTICATE, | 532 | NL80211_CMD_UNPROT_DEAUTHENTICATE, |
523 | NL80211_CMD_UNPROT_DISASSOCIATE, | 533 | NL80211_CMD_UNPROT_DISASSOCIATE, |
524 | 534 | ||
535 | NL80211_CMD_NEW_PEER_CANDIDATE, | ||
536 | |||
525 | /* add new commands above here */ | 537 | /* add new commands above here */ |
526 | 538 | ||
527 | /* used to define NL80211_CMD_MAX below */ | 539 | /* used to define NL80211_CMD_MAX below */ |
@@ -545,6 +557,7 @@ enum nl80211_commands { | |||
545 | /* source-level API compatibility */ | 557 | /* source-level API compatibility */ |
546 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG | 558 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG |
547 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG | 559 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG |
560 | #define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE | ||
548 | 561 | ||
549 | /** | 562 | /** |
550 | * enum nl80211_attrs - nl80211 netlink attributes | 563 | * enum nl80211_attrs - nl80211 netlink attributes |
@@ -886,6 +899,9 @@ enum nl80211_commands { | |||
886 | * changed once the mesh is active. | 899 | * changed once the mesh is active. |
887 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute | 900 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute |
888 | * containing attributes from &enum nl80211_meshconf_params. | 901 | * containing attributes from &enum nl80211_meshconf_params. |
902 | * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver | ||
903 | * allows auth frames in a mesh to be passed to userspace for processing via | ||
904 | * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. | ||
889 | * | 905 | * |
890 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 906 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
891 | * @__NL80211_ATTR_AFTER_LAST: internal use | 907 | * @__NL80211_ATTR_AFTER_LAST: internal use |
@@ -1074,6 +1090,8 @@ enum nl80211_attrs { | |||
1074 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, | 1090 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, |
1075 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 1091 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
1076 | 1092 | ||
1093 | NL80211_ATTR_SUPPORT_MESH_AUTH, | ||
1094 | |||
1077 | /* add attributes here, update the policy in nl80211.c */ | 1095 | /* add attributes here, update the policy in nl80211.c */ |
1078 | 1096 | ||
1079 | __NL80211_ATTR_AFTER_LAST, | 1097 | __NL80211_ATTR_AFTER_LAST, |
@@ -1168,6 +1186,7 @@ enum nl80211_iftype { | |||
1168 | * with short barker preamble | 1186 | * with short barker preamble |
1169 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable | 1187 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable |
1170 | * @NL80211_STA_FLAG_MFP: station uses management frame protection | 1188 | * @NL80211_STA_FLAG_MFP: station uses management frame protection |
1189 | * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated | ||
1171 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined | 1190 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined |
1172 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use | 1191 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use |
1173 | */ | 1192 | */ |
@@ -1177,6 +1196,7 @@ enum nl80211_sta_flags { | |||
1177 | NL80211_STA_FLAG_SHORT_PREAMBLE, | 1196 | NL80211_STA_FLAG_SHORT_PREAMBLE, |
1178 | NL80211_STA_FLAG_WME, | 1197 | NL80211_STA_FLAG_WME, |
1179 | NL80211_STA_FLAG_MFP, | 1198 | NL80211_STA_FLAG_MFP, |
1199 | NL80211_STA_FLAG_AUTHENTICATED, | ||
1180 | 1200 | ||
1181 | /* keep last */ | 1201 | /* keep last */ |
1182 | __NL80211_STA_FLAG_AFTER_LAST, | 1202 | __NL80211_STA_FLAG_AFTER_LAST, |
@@ -1277,6 +1297,7 @@ enum nl80211_sta_bss_param { | |||
1277 | * attribute, like NL80211_STA_INFO_TX_BITRATE. | 1297 | * attribute, like NL80211_STA_INFO_TX_BITRATE. |
1278 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute | 1298 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute |
1279 | * containing info as possible, see &enum nl80211_sta_bss_param | 1299 | * containing info as possible, see &enum nl80211_sta_bss_param |
1300 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected | ||
1280 | * @__NL80211_STA_INFO_AFTER_LAST: internal | 1301 | * @__NL80211_STA_INFO_AFTER_LAST: internal |
1281 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | 1302 | * @NL80211_STA_INFO_MAX: highest possible station info attribute |
1282 | */ | 1303 | */ |
@@ -1297,6 +1318,7 @@ enum nl80211_sta_info { | |||
1297 | NL80211_STA_INFO_SIGNAL_AVG, | 1318 | NL80211_STA_INFO_SIGNAL_AVG, |
1298 | NL80211_STA_INFO_RX_BITRATE, | 1319 | NL80211_STA_INFO_RX_BITRATE, |
1299 | NL80211_STA_INFO_BSS_PARAM, | 1320 | NL80211_STA_INFO_BSS_PARAM, |
1321 | NL80211_STA_INFO_CONNECTED_TIME, | ||
1300 | 1322 | ||
1301 | /* keep last */ | 1323 | /* keep last */ |
1302 | __NL80211_STA_INFO_AFTER_LAST, | 1324 | __NL80211_STA_INFO_AFTER_LAST, |
@@ -1719,9 +1741,12 @@ enum nl80211_meshconf_params { | |||
1719 | * vendor specific path metric or disable it to use the default Airtime | 1741 | * vendor specific path metric or disable it to use the default Airtime |
1720 | * metric. | 1742 | * metric. |
1721 | * | 1743 | * |
1722 | * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information | 1744 | * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a |
1723 | * element that vendors will use to identify the path selection methods and | 1745 | * robust security network ie, or a vendor specific information element that |
1724 | * metrics in use. | 1746 | * vendors will use to identify the path selection methods and metrics in use. |
1747 | * | ||
1748 | * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication | ||
1749 | * daemon will be authenticating mesh candidates. | ||
1725 | * | 1750 | * |
1726 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number | 1751 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number |
1727 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use | 1752 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use |
@@ -1730,7 +1755,8 @@ enum nl80211_mesh_setup_params { | |||
1730 | __NL80211_MESH_SETUP_INVALID, | 1755 | __NL80211_MESH_SETUP_INVALID, |
1731 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, | 1756 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, |
1732 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, | 1757 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, |
1733 | NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE, | 1758 | NL80211_MESH_SETUP_IE, |
1759 | NL80211_MESH_SETUP_USERSPACE_AUTH, | ||
1734 | 1760 | ||
1735 | /* keep last */ | 1761 | /* keep last */ |
1736 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, | 1762 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, |
diff --git a/include/linux/rfkill-regulator.h b/include/linux/rfkill-regulator.h new file mode 100644 index 000000000000..aca36bc83315 --- /dev/null +++ b/include/linux/rfkill-regulator.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * rfkill-regulator.c - Regulator consumer driver for rfkill | ||
3 | * | ||
4 | * Copyright (C) 2009 Guiming Zhuo <gmzhuo@gmail.com> | ||
5 | * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #ifndef __LINUX_RFKILL_REGULATOR_H | ||
14 | #define __LINUX_RFKILL_REGULATOR_H | ||
15 | |||
16 | /* | ||
17 | * Use "vrfkill" as supply id when declaring the regulator consumer: | ||
18 | * | ||
19 | * static struct regulator_consumer_supply pcap_regulator_V6_consumers [] = { | ||
20 | * { .dev_name = "rfkill-regulator.0", .supply = "vrfkill" }, | ||
21 | * }; | ||
22 | * | ||
23 | * If you have several regulator driven rfkill, you can append a numerical id to | ||
24 | * .dev_name as done above, and use the same id when declaring the platform | ||
25 | * device: | ||
26 | * | ||
27 | * static struct rfkill_regulator_platform_data ezx_rfkill_bt_data = { | ||
28 | * .name = "ezx-bluetooth", | ||
29 | * .type = RFKILL_TYPE_BLUETOOTH, | ||
30 | * }; | ||
31 | * | ||
32 | * static struct platform_device a910_rfkill = { | ||
33 | * .name = "rfkill-regulator", | ||
34 | * .id = 0, | ||
35 | * .dev = { | ||
36 | * .platform_data = &ezx_rfkill_bt_data, | ||
37 | * }, | ||
38 | * }; | ||
39 | */ | ||
40 | |||
41 | #include <linux/rfkill.h> | ||
42 | |||
43 | struct rfkill_regulator_platform_data { | ||
44 | char *name; /* the name for the rfkill switch */ | ||
45 | enum rfkill_type type; /* the type as specified in rfkill.h */ | ||
46 | }; | ||
47 | |||
48 | #endif /* __LINUX_RFKILL_REGULATOR_H */ | ||
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 2b9ca0d5c4a0..7a215a7f9e39 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -276,10 +276,52 @@ struct l2cap_conn_param_update_rsp { | |||
276 | #define L2CAP_CONN_PARAM_ACCEPTED 0x0000 | 276 | #define L2CAP_CONN_PARAM_ACCEPTED 0x0000 |
277 | #define L2CAP_CONN_PARAM_REJECTED 0x0001 | 277 | #define L2CAP_CONN_PARAM_REJECTED 0x0001 |
278 | 278 | ||
279 | /* ----- L2CAP connections ----- */ | 279 | /* ----- L2CAP channels and connections ----- */ |
280 | struct l2cap_chan_list { | 280 | struct srej_list { |
281 | struct sock *head; | 281 | __u8 tx_seq; |
282 | rwlock_t lock; | 282 | struct list_head list; |
283 | }; | ||
284 | |||
285 | struct l2cap_chan { | ||
286 | struct sock *sk; | ||
287 | __u8 ident; | ||
288 | |||
289 | __u8 conf_req[64]; | ||
290 | __u8 conf_len; | ||
291 | __u8 num_conf_req; | ||
292 | __u8 num_conf_rsp; | ||
293 | |||
294 | __u16 conn_state; | ||
295 | |||
296 | __u8 next_tx_seq; | ||
297 | __u8 expected_ack_seq; | ||
298 | __u8 expected_tx_seq; | ||
299 | __u8 buffer_seq; | ||
300 | __u8 buffer_seq_srej; | ||
301 | __u8 srej_save_reqseq; | ||
302 | __u8 frames_sent; | ||
303 | __u8 unacked_frames; | ||
304 | __u8 retry_count; | ||
305 | __u8 num_acked; | ||
306 | __u16 sdu_len; | ||
307 | __u16 partial_sdu_len; | ||
308 | struct sk_buff *sdu; | ||
309 | |||
310 | __u8 remote_tx_win; | ||
311 | __u8 remote_max_tx; | ||
312 | __u16 remote_mps; | ||
313 | |||
314 | struct timer_list retrans_timer; | ||
315 | struct timer_list monitor_timer; | ||
316 | struct timer_list ack_timer; | ||
317 | struct sk_buff *tx_send_head; | ||
318 | struct sk_buff_head tx_q; | ||
319 | struct sk_buff_head srej_q; | ||
320 | struct sk_buff_head busy_q; | ||
321 | struct work_struct busy_work; | ||
322 | struct list_head srej_l; | ||
323 | |||
324 | struct list_head list; | ||
283 | }; | 325 | }; |
284 | 326 | ||
285 | struct l2cap_conn { | 327 | struct l2cap_conn { |
@@ -305,29 +347,16 @@ struct l2cap_conn { | |||
305 | 347 | ||
306 | __u8 disc_reason; | 348 | __u8 disc_reason; |
307 | 349 | ||
308 | struct l2cap_chan_list chan_list; | 350 | struct list_head chan_l; |
309 | }; | 351 | rwlock_t chan_lock; |
310 | |||
311 | struct sock_del_list { | ||
312 | struct sock *sk; | ||
313 | struct list_head list; | ||
314 | }; | 352 | }; |
315 | 353 | ||
316 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 | 354 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 |
317 | #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 | 355 | #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 |
318 | #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 | 356 | #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 |
319 | 357 | ||
320 | /* ----- L2CAP channel and socket info ----- */ | 358 | /* ----- L2CAP socket info ----- */ |
321 | #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) | 359 | #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) |
322 | #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) | ||
323 | #define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue) | ||
324 | #define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue) | ||
325 | #define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list) | ||
326 | |||
327 | struct srej_list { | ||
328 | __u8 tx_seq; | ||
329 | struct list_head list; | ||
330 | }; | ||
331 | 360 | ||
332 | struct l2cap_pinfo { | 361 | struct l2cap_pinfo { |
333 | struct bt_sock bt; | 362 | struct bt_sock bt; |
@@ -339,8 +368,6 @@ struct l2cap_pinfo { | |||
339 | __u16 omtu; | 368 | __u16 omtu; |
340 | __u16 flush_to; | 369 | __u16 flush_to; |
341 | __u8 mode; | 370 | __u8 mode; |
342 | __u8 num_conf_req; | ||
343 | __u8 num_conf_rsp; | ||
344 | 371 | ||
345 | __u8 fcs; | 372 | __u8 fcs; |
346 | __u8 sec_level; | 373 | __u8 sec_level; |
@@ -348,49 +375,18 @@ struct l2cap_pinfo { | |||
348 | __u8 force_reliable; | 375 | __u8 force_reliable; |
349 | __u8 flushable; | 376 | __u8 flushable; |
350 | 377 | ||
351 | __u8 conf_req[64]; | ||
352 | __u8 conf_len; | ||
353 | __u8 conf_state; | 378 | __u8 conf_state; |
354 | __u16 conn_state; | ||
355 | |||
356 | __u8 next_tx_seq; | ||
357 | __u8 expected_ack_seq; | ||
358 | __u8 expected_tx_seq; | ||
359 | __u8 buffer_seq; | ||
360 | __u8 buffer_seq_srej; | ||
361 | __u8 srej_save_reqseq; | ||
362 | __u8 frames_sent; | ||
363 | __u8 unacked_frames; | ||
364 | __u8 retry_count; | ||
365 | __u8 num_acked; | ||
366 | __u16 sdu_len; | ||
367 | __u16 partial_sdu_len; | ||
368 | struct sk_buff *sdu; | ||
369 | |||
370 | __u8 ident; | ||
371 | 379 | ||
372 | __u8 tx_win; | 380 | __u8 tx_win; |
373 | __u8 max_tx; | 381 | __u8 max_tx; |
374 | __u8 remote_tx_win; | ||
375 | __u8 remote_max_tx; | ||
376 | __u16 retrans_timeout; | 382 | __u16 retrans_timeout; |
377 | __u16 monitor_timeout; | 383 | __u16 monitor_timeout; |
378 | __u16 remote_mps; | ||
379 | __u16 mps; | 384 | __u16 mps; |
380 | 385 | ||
381 | __le16 sport; | 386 | __le16 sport; |
382 | 387 | ||
383 | struct timer_list retrans_timer; | ||
384 | struct timer_list monitor_timer; | ||
385 | struct timer_list ack_timer; | ||
386 | struct sk_buff_head tx_queue; | ||
387 | struct sk_buff_head srej_queue; | ||
388 | struct sk_buff_head busy_queue; | ||
389 | struct work_struct busy_work; | ||
390 | struct srej_list srej_l; | ||
391 | struct l2cap_conn *conn; | 388 | struct l2cap_conn *conn; |
392 | struct sock *next_c; | 389 | struct l2cap_chan *chan; |
393 | struct sock *prev_c; | ||
394 | }; | 390 | }; |
395 | 391 | ||
396 | #define L2CAP_CONF_REQ_SENT 0x01 | 392 | #define L2CAP_CONF_REQ_SENT 0x01 |
@@ -417,24 +413,23 @@ struct l2cap_pinfo { | |||
417 | #define L2CAP_CONN_RNR_SENT 0x0200 | 413 | #define L2CAP_CONN_RNR_SENT 0x0200 |
418 | #define L2CAP_CONN_SAR_RETRY 0x0400 | 414 | #define L2CAP_CONN_SAR_RETRY 0x0400 |
419 | 415 | ||
420 | #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ | 416 | #define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \ |
421 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); | 417 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); |
422 | #define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \ | 418 | #define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \ |
423 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); | 419 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); |
424 | #define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \ | 420 | #define __mod_ack_timer() mod_timer(&chan->ack_timer, \ |
425 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); | 421 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); |
426 | 422 | ||
427 | static inline int l2cap_tx_window_full(struct sock *sk) | 423 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) |
428 | { | 424 | { |
429 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
430 | int sub; | 425 | int sub; |
431 | 426 | ||
432 | sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64; | 427 | sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64; |
433 | 428 | ||
434 | if (sub < 0) | 429 | if (sub < 0) |
435 | sub += 64; | 430 | sub += 64; |
436 | 431 | ||
437 | return sub == pi->remote_tx_win; | 432 | return sub == ch->remote_tx_win; |
438 | } | 433 | } |
439 | 434 | ||
440 | #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) | 435 | #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) |
@@ -450,18 +445,17 @@ extern struct bt_sock_list l2cap_sk_list; | |||
450 | int l2cap_init_sockets(void); | 445 | int l2cap_init_sockets(void); |
451 | void l2cap_cleanup_sockets(void); | 446 | void l2cap_cleanup_sockets(void); |
452 | 447 | ||
453 | u8 l2cap_get_ident(struct l2cap_conn *conn); | ||
454 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); | 448 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); |
455 | int l2cap_build_conf_req(struct sock *sk, void *data); | 449 | void __l2cap_connect_rsp_defer(struct sock *sk); |
456 | int __l2cap_wait_ack(struct sock *sk); | 450 | int __l2cap_wait_ack(struct sock *sk); |
457 | 451 | ||
458 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); | 452 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); |
459 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len); | 453 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len); |
460 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); | 454 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); |
461 | int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len); | 455 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); |
462 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb); | 456 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb); |
463 | void l2cap_streaming_send(struct sock *sk); | 457 | void l2cap_streaming_send(struct l2cap_chan *chan); |
464 | int l2cap_ertm_send(struct sock *sk); | 458 | int l2cap_ertm_send(struct l2cap_chan *chan); |
465 | 459 | ||
466 | void l2cap_sock_set_timer(struct sock *sk, long timeout); | 460 | void l2cap_sock_set_timer(struct sock *sk, long timeout); |
467 | void l2cap_sock_clear_timer(struct sock *sk); | 461 | void l2cap_sock_clear_timer(struct sock *sk); |
@@ -470,8 +464,8 @@ void l2cap_sock_kill(struct sock *sk); | |||
470 | void l2cap_sock_init(struct sock *sk, struct sock *parent); | 464 | void l2cap_sock_init(struct sock *sk, struct sock *parent); |
471 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | 465 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
472 | int proto, gfp_t prio); | 466 | int proto, gfp_t prio); |
473 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err); | 467 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); |
474 | void l2cap_chan_del(struct sock *sk, int err); | 468 | void l2cap_chan_del(struct l2cap_chan *chan, int err); |
475 | int l2cap_do_connect(struct sock *sk); | 469 | int l2cap_do_connect(struct sock *sk); |
476 | 470 | ||
477 | #endif /* __L2CAP_H */ | 471 | #endif /* __L2CAP_H */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ba7384acf4e0..d30eada7c6cd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -423,6 +423,7 @@ struct station_parameters { | |||
423 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled | 423 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled |
424 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled | 424 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled |
425 | * @STATION_INFO_BSS_PARAM: @bss_param filled | 425 | * @STATION_INFO_BSS_PARAM: @bss_param filled |
426 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled | ||
426 | */ | 427 | */ |
427 | enum station_info_flags { | 428 | enum station_info_flags { |
428 | STATION_INFO_INACTIVE_TIME = 1<<0, | 429 | STATION_INFO_INACTIVE_TIME = 1<<0, |
@@ -441,6 +442,7 @@ enum station_info_flags { | |||
441 | STATION_INFO_SIGNAL_AVG = 1<<13, | 442 | STATION_INFO_SIGNAL_AVG = 1<<13, |
442 | STATION_INFO_RX_BITRATE = 1<<14, | 443 | STATION_INFO_RX_BITRATE = 1<<14, |
443 | STATION_INFO_BSS_PARAM = 1<<15, | 444 | STATION_INFO_BSS_PARAM = 1<<15, |
445 | STATION_INFO_CONNECTED_TIME = 1<<16 | ||
444 | }; | 446 | }; |
445 | 447 | ||
446 | /** | 448 | /** |
@@ -511,6 +513,7 @@ struct sta_bss_parameters { | |||
511 | * Station information filled by driver for get_station() and dump_station. | 513 | * Station information filled by driver for get_station() and dump_station. |
512 | * | 514 | * |
513 | * @filled: bitflag of flags from &enum station_info_flags | 515 | * @filled: bitflag of flags from &enum station_info_flags |
516 | * @connected_time: time(in secs) since a station is last connected | ||
514 | * @inactive_time: time since last station activity (tx/rx) in milliseconds | 517 | * @inactive_time: time since last station activity (tx/rx) in milliseconds |
515 | * @rx_bytes: bytes received from this station | 518 | * @rx_bytes: bytes received from this station |
516 | * @tx_bytes: bytes transmitted to this station | 519 | * @tx_bytes: bytes transmitted to this station |
@@ -533,6 +536,7 @@ struct sta_bss_parameters { | |||
533 | */ | 536 | */ |
534 | struct station_info { | 537 | struct station_info { |
535 | u32 filled; | 538 | u32 filled; |
539 | u32 connected_time; | ||
536 | u32 inactive_time; | 540 | u32 inactive_time; |
537 | u32 rx_bytes; | 541 | u32 rx_bytes; |
538 | u32 tx_bytes; | 542 | u32 tx_bytes; |
@@ -689,8 +693,9 @@ struct mesh_config { | |||
689 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes | 693 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes |
690 | * @path_sel_proto: which path selection protocol to use | 694 | * @path_sel_proto: which path selection protocol to use |
691 | * @path_metric: which metric to use | 695 | * @path_metric: which metric to use |
692 | * @vendor_ie: vendor information elements (optional) | 696 | * @ie: vendor information elements (optional) |
693 | * @vendor_ie_len: length of vendor information elements | 697 | * @ie_len: length of vendor information elements |
698 | * @is_secure: or not | ||
694 | * | 699 | * |
695 | * These parameters are fixed when the mesh is created. | 700 | * These parameters are fixed when the mesh is created. |
696 | */ | 701 | */ |
@@ -699,8 +704,9 @@ struct mesh_setup { | |||
699 | u8 mesh_id_len; | 704 | u8 mesh_id_len; |
700 | u8 path_sel_proto; | 705 | u8 path_sel_proto; |
701 | u8 path_metric; | 706 | u8 path_metric; |
702 | const u8 *vendor_ie; | 707 | const u8 *ie; |
703 | u8 vendor_ie_len; | 708 | u8 ie_len; |
709 | bool is_secure; | ||
704 | }; | 710 | }; |
705 | 711 | ||
706 | /** | 712 | /** |
@@ -1451,6 +1457,8 @@ struct cfg80211_ops { | |||
1451 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. | 1457 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. |
1452 | * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate | 1458 | * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate |
1453 | * unicast and multicast TX keys. | 1459 | * unicast and multicast TX keys. |
1460 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing | ||
1461 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. | ||
1454 | */ | 1462 | */ |
1455 | enum wiphy_flags { | 1463 | enum wiphy_flags { |
1456 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 1464 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -1463,6 +1471,7 @@ enum wiphy_flags { | |||
1463 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), | 1471 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), |
1464 | WIPHY_FLAG_IBSS_RSN = BIT(8), | 1472 | WIPHY_FLAG_IBSS_RSN = BIT(8), |
1465 | WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), | 1473 | WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), |
1474 | WIPHY_FLAG_MESH_AUTH = BIT(10), | ||
1466 | }; | 1475 | }; |
1467 | 1476 | ||
1468 | struct mac_address { | 1477 | struct mac_address { |
@@ -2484,6 +2493,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, | |||
2484 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); | 2493 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); |
2485 | 2494 | ||
2486 | /** | 2495 | /** |
2496 | * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate | ||
2497 | * | ||
2498 | * @dev: network device | ||
2499 | * @macaddr: the MAC address of the new candidate | ||
2500 | * @ie: information elements advertised by the peer candidate | ||
2501 | * @ie_len: lenght of the information elements buffer | ||
2502 | * @gfp: allocation flags | ||
2503 | * | ||
2504 | * This function notifies cfg80211 that the mesh peer candidate has been | ||
2505 | * detected, most likely via a beacon or, less likely, via a probe response. | ||
2506 | * cfg80211 then sends a notification to userspace. | ||
2507 | */ | ||
2508 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | ||
2509 | const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); | ||
2510 | |||
2511 | /** | ||
2487 | * DOC: RFkill integration | 2512 | * DOC: RFkill integration |
2488 | * | 2513 | * |
2489 | * RFkill integration in cfg80211 is almost invisible to drivers, | 2514 | * RFkill integration in cfg80211 is almost invisible to drivers, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 025d4cc7bbf8..d23dd6c1329c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1819,6 +1819,9 @@ enum ieee80211_ampdu_mlme_action { | |||
1819 | * @set_ringparam: Set tx and rx ring sizes. | 1819 | * @set_ringparam: Set tx and rx ring sizes. |
1820 | * | 1820 | * |
1821 | * @get_ringparam: Get tx and rx ring current and maximum sizes. | 1821 | * @get_ringparam: Get tx and rx ring current and maximum sizes. |
1822 | * | ||
1823 | * @tx_frames_pending: Check if there is any pending frame in the hardware | ||
1824 | * queues before entering power save. | ||
1822 | */ | 1825 | */ |
1823 | struct ieee80211_ops { | 1826 | struct ieee80211_ops { |
1824 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); | 1827 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); |
@@ -1906,6 +1909,7 @@ struct ieee80211_ops { | |||
1906 | int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); | 1909 | int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); |
1907 | void (*get_ringparam)(struct ieee80211_hw *hw, | 1910 | void (*get_ringparam)(struct ieee80211_hw *hw, |
1908 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | 1911 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); |
1912 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); | ||
1909 | }; | 1913 | }; |
1910 | 1914 | ||
1911 | /** | 1915 | /** |
@@ -2223,6 +2227,18 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta, | |||
2223 | #define IEEE80211_TX_STATUS_HEADROOM 13 | 2227 | #define IEEE80211_TX_STATUS_HEADROOM 13 |
2224 | 2228 | ||
2225 | /** | 2229 | /** |
2230 | * ieee80211_sta_set_tim - set the TIM bit for a sleeping station | ||
2231 | * | ||
2232 | * If a driver buffers frames for a powersave station instead of passing | ||
2233 | * them back to mac80211 for retransmission, the station needs to be told | ||
2234 | * to wake up using the TIM bitmap in the beacon. | ||
2235 | * | ||
2236 | * This function sets the station's TIM bit - it will be cleared when the | ||
2237 | * station wakes up. | ||
2238 | */ | ||
2239 | void ieee80211_sta_set_tim(struct ieee80211_sta *sta); | ||
2240 | |||
2241 | /** | ||
2226 | * ieee80211_tx_status - transmit status callback | 2242 | * ieee80211_tx_status - transmit status callback |
2227 | * | 2243 | * |
2228 | * Call this function for all transmitted frames after they have been | 2244 | * Call this function for all transmitted frames after they have been |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 7a3398d9cd65..c7eb073fe633 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2497,6 +2497,9 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, | |||
2497 | 2497 | ||
2498 | hci_dev_lock(hdev); | 2498 | hci_dev_lock(hdev); |
2499 | 2499 | ||
2500 | if (!test_bit(HCI_MGMT, &hdev->flags)) | ||
2501 | goto unlock; | ||
2502 | |||
2500 | data = hci_find_remote_oob_data(hdev, &ev->bdaddr); | 2503 | data = hci_find_remote_oob_data(hdev, &ev->bdaddr); |
2501 | if (data) { | 2504 | if (data) { |
2502 | struct hci_cp_remote_oob_data_reply cp; | 2505 | struct hci_cp_remote_oob_data_reply cp; |
@@ -2515,6 +2518,7 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, | |||
2515 | &cp); | 2518 | &cp); |
2516 | } | 2519 | } |
2517 | 2520 | ||
2521 | unlock: | ||
2518 | hci_dev_unlock(hdev); | 2522 | hci_dev_unlock(hdev); |
2519 | } | 2523 | } |
2520 | 2524 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c3cebed205cc..d47de2b04b2e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -70,108 +70,101 @@ static void l2cap_busy_work(struct work_struct *work); | |||
70 | 70 | ||
71 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 71 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
72 | u8 code, u8 ident, u16 dlen, void *data); | 72 | u8 code, u8 ident, u16 dlen, void *data); |
73 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); | ||
73 | 74 | ||
74 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | 75 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); |
75 | 76 | ||
76 | /* ---- L2CAP channels ---- */ | 77 | /* ---- L2CAP channels ---- */ |
77 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) | 78 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) |
78 | { | 79 | { |
79 | struct sock *s; | 80 | struct l2cap_chan *c; |
80 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | 81 | |
82 | list_for_each_entry(c, &conn->chan_l, list) { | ||
83 | struct sock *s = c->sk; | ||
81 | if (l2cap_pi(s)->dcid == cid) | 84 | if (l2cap_pi(s)->dcid == cid) |
82 | break; | 85 | return c; |
83 | } | 86 | } |
84 | return s; | 87 | return NULL; |
88 | |||
85 | } | 89 | } |
86 | 90 | ||
87 | static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | 91 | static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) |
88 | { | 92 | { |
89 | struct sock *s; | 93 | struct l2cap_chan *c; |
90 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | 94 | |
95 | list_for_each_entry(c, &conn->chan_l, list) { | ||
96 | struct sock *s = c->sk; | ||
91 | if (l2cap_pi(s)->scid == cid) | 97 | if (l2cap_pi(s)->scid == cid) |
92 | break; | 98 | return c; |
93 | } | 99 | } |
94 | return s; | 100 | return NULL; |
95 | } | 101 | } |
96 | 102 | ||
97 | /* Find channel with given SCID. | 103 | /* Find channel with given SCID. |
98 | * Returns locked socket */ | 104 | * Returns locked socket */ |
99 | static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | 105 | static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) |
100 | { | 106 | { |
101 | struct sock *s; | 107 | struct l2cap_chan *c; |
102 | read_lock(&l->lock); | 108 | |
103 | s = __l2cap_get_chan_by_scid(l, cid); | 109 | read_lock(&conn->chan_lock); |
104 | if (s) | 110 | c = __l2cap_get_chan_by_scid(conn, cid); |
105 | bh_lock_sock(s); | 111 | if (c) |
106 | read_unlock(&l->lock); | 112 | bh_lock_sock(c->sk); |
107 | return s; | 113 | read_unlock(&conn->chan_lock); |
114 | return c; | ||
108 | } | 115 | } |
109 | 116 | ||
110 | static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | 117 | static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) |
111 | { | 118 | { |
112 | struct sock *s; | 119 | struct l2cap_chan *c; |
113 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | 120 | |
114 | if (l2cap_pi(s)->ident == ident) | 121 | list_for_each_entry(c, &conn->chan_l, list) { |
115 | break; | 122 | if (c->ident == ident) |
123 | return c; | ||
116 | } | 124 | } |
117 | return s; | 125 | return NULL; |
118 | } | 126 | } |
119 | 127 | ||
120 | static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | 128 | static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) |
121 | { | 129 | { |
122 | struct sock *s; | 130 | struct l2cap_chan *c; |
123 | read_lock(&l->lock); | 131 | |
124 | s = __l2cap_get_chan_by_ident(l, ident); | 132 | read_lock(&conn->chan_lock); |
125 | if (s) | 133 | c = __l2cap_get_chan_by_ident(conn, ident); |
126 | bh_lock_sock(s); | 134 | if (c) |
127 | read_unlock(&l->lock); | 135 | bh_lock_sock(c->sk); |
128 | return s; | 136 | read_unlock(&conn->chan_lock); |
137 | return c; | ||
129 | } | 138 | } |
130 | 139 | ||
131 | static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) | 140 | static u16 l2cap_alloc_cid(struct l2cap_conn *conn) |
132 | { | 141 | { |
133 | u16 cid = L2CAP_CID_DYN_START; | 142 | u16 cid = L2CAP_CID_DYN_START; |
134 | 143 | ||
135 | for (; cid < L2CAP_CID_DYN_END; cid++) { | 144 | for (; cid < L2CAP_CID_DYN_END; cid++) { |
136 | if (!__l2cap_get_chan_by_scid(l, cid)) | 145 | if (!__l2cap_get_chan_by_scid(conn, cid)) |
137 | return cid; | 146 | return cid; |
138 | } | 147 | } |
139 | 148 | ||
140 | return 0; | 149 | return 0; |
141 | } | 150 | } |
142 | 151 | ||
143 | static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk) | 152 | static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) |
144 | { | 153 | { |
145 | sock_hold(sk); | 154 | struct l2cap_chan *chan; |
146 | |||
147 | if (l->head) | ||
148 | l2cap_pi(l->head)->prev_c = sk; | ||
149 | 155 | ||
150 | l2cap_pi(sk)->next_c = l->head; | 156 | chan = kzalloc(sizeof(*chan), GFP_ATOMIC); |
151 | l2cap_pi(sk)->prev_c = NULL; | 157 | if (!chan) |
152 | l->head = sk; | 158 | return NULL; |
153 | } | ||
154 | |||
155 | static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) | ||
156 | { | ||
157 | struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c; | ||
158 | |||
159 | write_lock_bh(&l->lock); | ||
160 | if (sk == l->head) | ||
161 | l->head = next; | ||
162 | 159 | ||
163 | if (next) | 160 | chan->sk = sk; |
164 | l2cap_pi(next)->prev_c = prev; | ||
165 | if (prev) | ||
166 | l2cap_pi(prev)->next_c = next; | ||
167 | write_unlock_bh(&l->lock); | ||
168 | 161 | ||
169 | __sock_put(sk); | 162 | return chan; |
170 | } | 163 | } |
171 | 164 | ||
172 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) | 165 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
173 | { | 166 | { |
174 | struct l2cap_chan_list *l = &conn->chan_list; | 167 | struct sock *sk = chan->sk; |
175 | 168 | ||
176 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 169 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
177 | l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | 170 | l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); |
@@ -188,7 +181,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) | |||
188 | l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA; | 181 | l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA; |
189 | } else { | 182 | } else { |
190 | /* Alloc CID for connection-oriented socket */ | 183 | /* Alloc CID for connection-oriented socket */ |
191 | l2cap_pi(sk)->scid = l2cap_alloc_cid(l); | 184 | l2cap_pi(sk)->scid = l2cap_alloc_cid(conn); |
192 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | 185 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; |
193 | } | 186 | } |
194 | } else if (sk->sk_type == SOCK_DGRAM) { | 187 | } else if (sk->sk_type == SOCK_DGRAM) { |
@@ -203,23 +196,30 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) | |||
203 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | 196 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; |
204 | } | 197 | } |
205 | 198 | ||
206 | __l2cap_chan_link(l, sk); | 199 | sock_hold(sk); |
200 | |||
201 | list_add(&chan->list, &conn->chan_l); | ||
207 | } | 202 | } |
208 | 203 | ||
209 | /* Delete channel. | 204 | /* Delete channel. |
210 | * Must be called on the locked socket. */ | 205 | * Must be called on the locked socket. */ |
211 | void l2cap_chan_del(struct sock *sk, int err) | 206 | void l2cap_chan_del(struct l2cap_chan *chan, int err) |
212 | { | 207 | { |
208 | struct sock *sk = chan->sk; | ||
213 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 209 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
214 | struct sock *parent = bt_sk(sk)->parent; | 210 | struct sock *parent = bt_sk(sk)->parent; |
215 | 211 | ||
216 | l2cap_sock_clear_timer(sk); | 212 | l2cap_sock_clear_timer(sk); |
217 | 213 | ||
218 | BT_DBG("sk %p, conn %p, err %d", sk, conn, err); | 214 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); |
219 | 215 | ||
220 | if (conn) { | 216 | if (conn) { |
221 | /* Unlink from channel list */ | 217 | /* Delete from channel list */ |
222 | l2cap_chan_unlink(&conn->chan_list, sk); | 218 | write_lock_bh(&conn->chan_lock); |
219 | list_del(&chan->list); | ||
220 | write_unlock_bh(&conn->chan_lock); | ||
221 | __sock_put(sk); | ||
222 | |||
223 | l2cap_pi(sk)->conn = NULL; | 223 | l2cap_pi(sk)->conn = NULL; |
224 | hci_conn_put(conn->hcon); | 224 | hci_conn_put(conn->hcon); |
225 | } | 225 | } |
@@ -236,23 +236,30 @@ void l2cap_chan_del(struct sock *sk, int err) | |||
236 | } else | 236 | } else |
237 | sk->sk_state_change(sk); | 237 | sk->sk_state_change(sk); |
238 | 238 | ||
239 | skb_queue_purge(TX_QUEUE(sk)); | 239 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE && |
240 | l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE)) | ||
241 | goto free; | ||
242 | |||
243 | skb_queue_purge(&chan->tx_q); | ||
240 | 244 | ||
241 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | 245 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
242 | struct srej_list *l, *tmp; | 246 | struct srej_list *l, *tmp; |
243 | 247 | ||
244 | del_timer(&l2cap_pi(sk)->retrans_timer); | 248 | del_timer(&chan->retrans_timer); |
245 | del_timer(&l2cap_pi(sk)->monitor_timer); | 249 | del_timer(&chan->monitor_timer); |
246 | del_timer(&l2cap_pi(sk)->ack_timer); | 250 | del_timer(&chan->ack_timer); |
247 | 251 | ||
248 | skb_queue_purge(SREJ_QUEUE(sk)); | 252 | skb_queue_purge(&chan->srej_q); |
249 | skb_queue_purge(BUSY_QUEUE(sk)); | 253 | skb_queue_purge(&chan->busy_q); |
250 | 254 | ||
251 | list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { | 255 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { |
252 | list_del(&l->list); | 256 | list_del(&l->list); |
253 | kfree(l); | 257 | kfree(l); |
254 | } | 258 | } |
255 | } | 259 | } |
260 | |||
261 | free: | ||
262 | kfree(chan); | ||
256 | } | 263 | } |
257 | 264 | ||
258 | static inline u8 l2cap_get_auth_type(struct sock *sk) | 265 | static inline u8 l2cap_get_auth_type(struct sock *sk) |
@@ -338,10 +345,11 @@ void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *d | |||
338 | hci_send_acl(conn->hcon, skb, flags); | 345 | hci_send_acl(conn->hcon, skb, flags); |
339 | } | 346 | } |
340 | 347 | ||
341 | static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | 348 | static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) |
342 | { | 349 | { |
343 | struct sk_buff *skb; | 350 | struct sk_buff *skb; |
344 | struct l2cap_hdr *lh; | 351 | struct l2cap_hdr *lh; |
352 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
345 | struct l2cap_conn *conn = pi->conn; | 353 | struct l2cap_conn *conn = pi->conn; |
346 | struct sock *sk = (struct sock *)pi; | 354 | struct sock *sk = (struct sock *)pi; |
347 | int count, hlen = L2CAP_HDR_SIZE + 2; | 355 | int count, hlen = L2CAP_HDR_SIZE + 2; |
@@ -353,19 +361,19 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
353 | if (pi->fcs == L2CAP_FCS_CRC16) | 361 | if (pi->fcs == L2CAP_FCS_CRC16) |
354 | hlen += 2; | 362 | hlen += 2; |
355 | 363 | ||
356 | BT_DBG("pi %p, control 0x%2.2x", pi, control); | 364 | BT_DBG("chan %p, control 0x%2.2x", chan, control); |
357 | 365 | ||
358 | count = min_t(unsigned int, conn->mtu, hlen); | 366 | count = min_t(unsigned int, conn->mtu, hlen); |
359 | control |= L2CAP_CTRL_FRAME_TYPE; | 367 | control |= L2CAP_CTRL_FRAME_TYPE; |
360 | 368 | ||
361 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | 369 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { |
362 | control |= L2CAP_CTRL_FINAL; | 370 | control |= L2CAP_CTRL_FINAL; |
363 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | 371 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; |
364 | } | 372 | } |
365 | 373 | ||
366 | if (pi->conn_state & L2CAP_CONN_SEND_PBIT) { | 374 | if (chan->conn_state & L2CAP_CONN_SEND_PBIT) { |
367 | control |= L2CAP_CTRL_POLL; | 375 | control |= L2CAP_CTRL_POLL; |
368 | pi->conn_state &= ~L2CAP_CONN_SEND_PBIT; | 376 | chan->conn_state &= ~L2CAP_CONN_SEND_PBIT; |
369 | } | 377 | } |
370 | 378 | ||
371 | skb = bt_skb_alloc(count, GFP_ATOMIC); | 379 | skb = bt_skb_alloc(count, GFP_ATOMIC); |
@@ -390,17 +398,17 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
390 | hci_send_acl(pi->conn->hcon, skb, flags); | 398 | hci_send_acl(pi->conn->hcon, skb, flags); |
391 | } | 399 | } |
392 | 400 | ||
393 | static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) | 401 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) |
394 | { | 402 | { |
395 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 403 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
396 | control |= L2CAP_SUPER_RCV_NOT_READY; | 404 | control |= L2CAP_SUPER_RCV_NOT_READY; |
397 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 405 | chan->conn_state |= L2CAP_CONN_RNR_SENT; |
398 | } else | 406 | } else |
399 | control |= L2CAP_SUPER_RCV_READY; | 407 | control |= L2CAP_SUPER_RCV_READY; |
400 | 408 | ||
401 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 409 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
402 | 410 | ||
403 | l2cap_send_sframe(pi, control); | 411 | l2cap_send_sframe(chan, control); |
404 | } | 412 | } |
405 | 413 | ||
406 | static inline int __l2cap_no_conn_pending(struct sock *sk) | 414 | static inline int __l2cap_no_conn_pending(struct sock *sk) |
@@ -408,8 +416,9 @@ static inline int __l2cap_no_conn_pending(struct sock *sk) | |||
408 | return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND); | 416 | return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND); |
409 | } | 417 | } |
410 | 418 | ||
411 | static void l2cap_do_start(struct sock *sk) | 419 | static void l2cap_do_start(struct l2cap_chan *chan) |
412 | { | 420 | { |
421 | struct sock *sk = chan->sk; | ||
413 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 422 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
414 | 423 | ||
415 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 424 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { |
@@ -421,11 +430,11 @@ static void l2cap_do_start(struct sock *sk) | |||
421 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 430 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
422 | req.psm = l2cap_pi(sk)->psm; | 431 | req.psm = l2cap_pi(sk)->psm; |
423 | 432 | ||
424 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 433 | chan->ident = l2cap_get_ident(conn); |
425 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 434 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; |
426 | 435 | ||
427 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 436 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
428 | L2CAP_CONN_REQ, sizeof(req), &req); | 437 | sizeof(req), &req); |
429 | } | 438 | } |
430 | } else { | 439 | } else { |
431 | struct l2cap_info_req req; | 440 | struct l2cap_info_req req; |
@@ -458,19 +467,20 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
458 | } | 467 | } |
459 | } | 468 | } |
460 | 469 | ||
461 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) | 470 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) |
462 | { | 471 | { |
472 | struct sock *sk; | ||
463 | struct l2cap_disconn_req req; | 473 | struct l2cap_disconn_req req; |
464 | 474 | ||
465 | if (!conn) | 475 | if (!conn) |
466 | return; | 476 | return; |
467 | 477 | ||
468 | skb_queue_purge(TX_QUEUE(sk)); | 478 | sk = chan->sk; |
469 | 479 | ||
470 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | 480 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
471 | del_timer(&l2cap_pi(sk)->retrans_timer); | 481 | del_timer(&chan->retrans_timer); |
472 | del_timer(&l2cap_pi(sk)->monitor_timer); | 482 | del_timer(&chan->monitor_timer); |
473 | del_timer(&l2cap_pi(sk)->ack_timer); | 483 | del_timer(&chan->ack_timer); |
474 | } | 484 | } |
475 | 485 | ||
476 | req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); | 486 | req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); |
@@ -485,17 +495,15 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) | |||
485 | /* ---- L2CAP connections ---- */ | 495 | /* ---- L2CAP connections ---- */ |
486 | static void l2cap_conn_start(struct l2cap_conn *conn) | 496 | static void l2cap_conn_start(struct l2cap_conn *conn) |
487 | { | 497 | { |
488 | struct l2cap_chan_list *l = &conn->chan_list; | 498 | struct l2cap_chan *chan, *tmp; |
489 | struct sock_del_list del, *tmp1, *tmp2; | ||
490 | struct sock *sk; | ||
491 | 499 | ||
492 | BT_DBG("conn %p", conn); | 500 | BT_DBG("conn %p", conn); |
493 | 501 | ||
494 | INIT_LIST_HEAD(&del.list); | 502 | read_lock(&conn->chan_lock); |
495 | 503 | ||
496 | read_lock(&l->lock); | 504 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { |
505 | struct sock *sk = chan->sk; | ||
497 | 506 | ||
498 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | ||
499 | bh_lock_sock(sk); | 507 | bh_lock_sock(sk); |
500 | 508 | ||
501 | if (sk->sk_type != SOCK_SEQPACKET && | 509 | if (sk->sk_type != SOCK_SEQPACKET && |
@@ -517,10 +525,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
517 | conn->feat_mask) | 525 | conn->feat_mask) |
518 | && l2cap_pi(sk)->conf_state & | 526 | && l2cap_pi(sk)->conf_state & |
519 | L2CAP_CONF_STATE2_DEVICE) { | 527 | L2CAP_CONF_STATE2_DEVICE) { |
520 | tmp1 = kzalloc(sizeof(struct sock_del_list), | 528 | /* __l2cap_sock_close() calls list_del(chan) |
521 | GFP_ATOMIC); | 529 | * so release the lock */ |
522 | tmp1->sk = sk; | 530 | read_unlock_bh(&conn->chan_lock); |
523 | list_add_tail(&tmp1->list, &del.list); | 531 | __l2cap_sock_close(sk, ECONNRESET); |
532 | read_lock_bh(&conn->chan_lock); | ||
524 | bh_unlock_sock(sk); | 533 | bh_unlock_sock(sk); |
525 | continue; | 534 | continue; |
526 | } | 535 | } |
@@ -528,11 +537,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
528 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 537 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
529 | req.psm = l2cap_pi(sk)->psm; | 538 | req.psm = l2cap_pi(sk)->psm; |
530 | 539 | ||
531 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 540 | chan->ident = l2cap_get_ident(conn); |
532 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 541 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; |
533 | 542 | ||
534 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 543 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
535 | L2CAP_CONN_REQ, sizeof(req), &req); | 544 | sizeof(req), &req); |
536 | 545 | ||
537 | } else if (sk->sk_state == BT_CONNECT2) { | 546 | } else if (sk->sk_state == BT_CONNECT2) { |
538 | struct l2cap_conn_rsp rsp; | 547 | struct l2cap_conn_rsp rsp; |
@@ -557,8 +566,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
557 | rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); | 566 | rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); |
558 | } | 567 | } |
559 | 568 | ||
560 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 569 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
561 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 570 | sizeof(rsp), &rsp); |
562 | 571 | ||
563 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || | 572 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || |
564 | rsp.result != L2CAP_CR_SUCCESS) { | 573 | rsp.result != L2CAP_CR_SUCCESS) { |
@@ -568,22 +577,14 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
568 | 577 | ||
569 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 578 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
570 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 579 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
571 | l2cap_build_conf_req(sk, buf), buf); | 580 | l2cap_build_conf_req(chan, buf), buf); |
572 | l2cap_pi(sk)->num_conf_req++; | 581 | chan->num_conf_req++; |
573 | } | 582 | } |
574 | 583 | ||
575 | bh_unlock_sock(sk); | 584 | bh_unlock_sock(sk); |
576 | } | 585 | } |
577 | 586 | ||
578 | read_unlock(&l->lock); | 587 | read_unlock(&conn->chan_lock); |
579 | |||
580 | list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { | ||
581 | bh_lock_sock(tmp1->sk); | ||
582 | __l2cap_sock_close(tmp1->sk, ECONNRESET); | ||
583 | bh_unlock_sock(tmp1->sk); | ||
584 | list_del(&tmp1->list); | ||
585 | kfree(tmp1); | ||
586 | } | ||
587 | } | 588 | } |
588 | 589 | ||
589 | /* Find socket with cid and source bdaddr. | 590 | /* Find socket with cid and source bdaddr. |
@@ -591,7 +592,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
591 | */ | 592 | */ |
592 | static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) | 593 | static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) |
593 | { | 594 | { |
594 | struct sock *s, *sk = NULL, *sk1 = NULL; | 595 | struct sock *sk = NULL, *sk1 = NULL; |
595 | struct hlist_node *node; | 596 | struct hlist_node *node; |
596 | 597 | ||
597 | read_lock(&l2cap_sk_list.lock); | 598 | read_lock(&l2cap_sk_list.lock); |
@@ -610,18 +611,16 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) | |||
610 | sk1 = sk; | 611 | sk1 = sk; |
611 | } | 612 | } |
612 | } | 613 | } |
613 | s = node ? sk : sk1; | 614 | |
614 | if (s) | ||
615 | bh_lock_sock(s); | ||
616 | read_unlock(&l2cap_sk_list.lock); | 615 | read_unlock(&l2cap_sk_list.lock); |
617 | 616 | ||
618 | return s; | 617 | return node ? sk : sk1; |
619 | } | 618 | } |
620 | 619 | ||
621 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 620 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
622 | { | 621 | { |
623 | struct l2cap_chan_list *list = &conn->chan_list; | 622 | struct sock *parent, *sk; |
624 | struct sock *parent, *uninitialized_var(sk); | 623 | struct l2cap_chan *chan; |
625 | 624 | ||
626 | BT_DBG(""); | 625 | BT_DBG(""); |
627 | 626 | ||
@@ -631,6 +630,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
631 | if (!parent) | 630 | if (!parent) |
632 | return; | 631 | return; |
633 | 632 | ||
633 | bh_lock_sock(parent); | ||
634 | |||
634 | /* Check for backlog size */ | 635 | /* Check for backlog size */ |
635 | if (sk_acceptq_is_full(parent)) { | 636 | if (sk_acceptq_is_full(parent)) { |
636 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | 637 | BT_DBG("backlog full %d", parent->sk_ack_backlog); |
@@ -641,24 +642,33 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
641 | if (!sk) | 642 | if (!sk) |
642 | goto clean; | 643 | goto clean; |
643 | 644 | ||
644 | write_lock_bh(&list->lock); | 645 | chan = l2cap_chan_alloc(sk); |
646 | if (!chan) { | ||
647 | l2cap_sock_kill(sk); | ||
648 | goto clean; | ||
649 | } | ||
650 | |||
651 | write_lock_bh(&conn->chan_lock); | ||
645 | 652 | ||
646 | hci_conn_hold(conn->hcon); | 653 | hci_conn_hold(conn->hcon); |
647 | 654 | ||
648 | l2cap_sock_init(sk, parent); | 655 | l2cap_sock_init(sk, parent); |
656 | |||
649 | bacpy(&bt_sk(sk)->src, conn->src); | 657 | bacpy(&bt_sk(sk)->src, conn->src); |
650 | bacpy(&bt_sk(sk)->dst, conn->dst); | 658 | bacpy(&bt_sk(sk)->dst, conn->dst); |
651 | 659 | ||
652 | bt_accept_enqueue(parent, sk); | 660 | bt_accept_enqueue(parent, sk); |
653 | 661 | ||
654 | __l2cap_chan_add(conn, sk); | 662 | __l2cap_chan_add(conn, chan); |
663 | |||
664 | l2cap_pi(sk)->chan = chan; | ||
655 | 665 | ||
656 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 666 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
657 | 667 | ||
658 | sk->sk_state = BT_CONNECTED; | 668 | sk->sk_state = BT_CONNECTED; |
659 | parent->sk_data_ready(parent, 0); | 669 | parent->sk_data_ready(parent, 0); |
660 | 670 | ||
661 | write_unlock_bh(&list->lock); | 671 | write_unlock_bh(&conn->chan_lock); |
662 | 672 | ||
663 | clean: | 673 | clean: |
664 | bh_unlock_sock(parent); | 674 | bh_unlock_sock(parent); |
@@ -666,17 +676,18 @@ clean: | |||
666 | 676 | ||
667 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 677 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
668 | { | 678 | { |
669 | struct l2cap_chan_list *l = &conn->chan_list; | 679 | struct l2cap_chan *chan; |
670 | struct sock *sk; | ||
671 | 680 | ||
672 | BT_DBG("conn %p", conn); | 681 | BT_DBG("conn %p", conn); |
673 | 682 | ||
674 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) | 683 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) |
675 | l2cap_le_conn_ready(conn); | 684 | l2cap_le_conn_ready(conn); |
676 | 685 | ||
677 | read_lock(&l->lock); | 686 | read_lock(&conn->chan_lock); |
687 | |||
688 | list_for_each_entry(chan, &conn->chan_l, list) { | ||
689 | struct sock *sk = chan->sk; | ||
678 | 690 | ||
679 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | ||
680 | bh_lock_sock(sk); | 691 | bh_lock_sock(sk); |
681 | 692 | ||
682 | if (conn->hcon->type == LE_LINK) { | 693 | if (conn->hcon->type == LE_LINK) { |
@@ -691,30 +702,31 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
691 | sk->sk_state = BT_CONNECTED; | 702 | sk->sk_state = BT_CONNECTED; |
692 | sk->sk_state_change(sk); | 703 | sk->sk_state_change(sk); |
693 | } else if (sk->sk_state == BT_CONNECT) | 704 | } else if (sk->sk_state == BT_CONNECT) |
694 | l2cap_do_start(sk); | 705 | l2cap_do_start(chan); |
695 | 706 | ||
696 | bh_unlock_sock(sk); | 707 | bh_unlock_sock(sk); |
697 | } | 708 | } |
698 | 709 | ||
699 | read_unlock(&l->lock); | 710 | read_unlock(&conn->chan_lock); |
700 | } | 711 | } |
701 | 712 | ||
702 | /* Notify sockets that we cannot guaranty reliability anymore */ | 713 | /* Notify sockets that we cannot guaranty reliability anymore */ |
703 | static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | 714 | static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) |
704 | { | 715 | { |
705 | struct l2cap_chan_list *l = &conn->chan_list; | 716 | struct l2cap_chan *chan; |
706 | struct sock *sk; | ||
707 | 717 | ||
708 | BT_DBG("conn %p", conn); | 718 | BT_DBG("conn %p", conn); |
709 | 719 | ||
710 | read_lock(&l->lock); | 720 | read_lock(&conn->chan_lock); |
721 | |||
722 | list_for_each_entry(chan, &conn->chan_l, list) { | ||
723 | struct sock *sk = chan->sk; | ||
711 | 724 | ||
712 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | ||
713 | if (l2cap_pi(sk)->force_reliable) | 725 | if (l2cap_pi(sk)->force_reliable) |
714 | sk->sk_err = err; | 726 | sk->sk_err = err; |
715 | } | 727 | } |
716 | 728 | ||
717 | read_unlock(&l->lock); | 729 | read_unlock(&conn->chan_lock); |
718 | } | 730 | } |
719 | 731 | ||
720 | static void l2cap_info_timeout(unsigned long arg) | 732 | static void l2cap_info_timeout(unsigned long arg) |
@@ -754,7 +766,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
754 | conn->feat_mask = 0; | 766 | conn->feat_mask = 0; |
755 | 767 | ||
756 | spin_lock_init(&conn->lock); | 768 | spin_lock_init(&conn->lock); |
757 | rwlock_init(&conn->chan_list.lock); | 769 | rwlock_init(&conn->chan_lock); |
770 | |||
771 | INIT_LIST_HEAD(&conn->chan_l); | ||
758 | 772 | ||
759 | if (hcon->type != LE_LINK) | 773 | if (hcon->type != LE_LINK) |
760 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 774 | setup_timer(&conn->info_timer, l2cap_info_timeout, |
@@ -768,6 +782,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
768 | static void l2cap_conn_del(struct hci_conn *hcon, int err) | 782 | static void l2cap_conn_del(struct hci_conn *hcon, int err) |
769 | { | 783 | { |
770 | struct l2cap_conn *conn = hcon->l2cap_data; | 784 | struct l2cap_conn *conn = hcon->l2cap_data; |
785 | struct l2cap_chan *chan, *l; | ||
771 | struct sock *sk; | 786 | struct sock *sk; |
772 | 787 | ||
773 | if (!conn) | 788 | if (!conn) |
@@ -778,9 +793,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
778 | kfree_skb(conn->rx_skb); | 793 | kfree_skb(conn->rx_skb); |
779 | 794 | ||
780 | /* Kill channels */ | 795 | /* Kill channels */ |
781 | while ((sk = conn->chan_list.head)) { | 796 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { |
797 | sk = chan->sk; | ||
782 | bh_lock_sock(sk); | 798 | bh_lock_sock(sk); |
783 | l2cap_chan_del(sk, err); | 799 | l2cap_chan_del(chan, err); |
784 | bh_unlock_sock(sk); | 800 | bh_unlock_sock(sk); |
785 | l2cap_sock_kill(sk); | 801 | l2cap_sock_kill(sk); |
786 | } | 802 | } |
@@ -792,12 +808,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
792 | kfree(conn); | 808 | kfree(conn); |
793 | } | 809 | } |
794 | 810 | ||
795 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) | 811 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
796 | { | 812 | { |
797 | struct l2cap_chan_list *l = &conn->chan_list; | 813 | write_lock_bh(&conn->chan_lock); |
798 | write_lock_bh(&l->lock); | 814 | __l2cap_chan_add(conn, chan); |
799 | __l2cap_chan_add(conn, sk); | 815 | write_unlock_bh(&conn->chan_lock); |
800 | write_unlock_bh(&l->lock); | ||
801 | } | 816 | } |
802 | 817 | ||
803 | /* ---- Socket interface ---- */ | 818 | /* ---- Socket interface ---- */ |
@@ -837,6 +852,7 @@ int l2cap_do_connect(struct sock *sk) | |||
837 | bdaddr_t *src = &bt_sk(sk)->src; | 852 | bdaddr_t *src = &bt_sk(sk)->src; |
838 | bdaddr_t *dst = &bt_sk(sk)->dst; | 853 | bdaddr_t *dst = &bt_sk(sk)->dst; |
839 | struct l2cap_conn *conn; | 854 | struct l2cap_conn *conn; |
855 | struct l2cap_chan *chan; | ||
840 | struct hci_conn *hcon; | 856 | struct hci_conn *hcon; |
841 | struct hci_dev *hdev; | 857 | struct hci_dev *hdev; |
842 | __u8 auth_type; | 858 | __u8 auth_type; |
@@ -872,10 +888,19 @@ int l2cap_do_connect(struct sock *sk) | |||
872 | goto done; | 888 | goto done; |
873 | } | 889 | } |
874 | 890 | ||
891 | chan = l2cap_chan_alloc(sk); | ||
892 | if (!chan) { | ||
893 | hci_conn_put(hcon); | ||
894 | err = -ENOMEM; | ||
895 | goto done; | ||
896 | } | ||
897 | |||
875 | /* Update source addr of the socket */ | 898 | /* Update source addr of the socket */ |
876 | bacpy(src, conn->src); | 899 | bacpy(src, conn->src); |
877 | 900 | ||
878 | l2cap_chan_add(conn, sk); | 901 | l2cap_chan_add(conn, chan); |
902 | |||
903 | l2cap_pi(sk)->chan = chan; | ||
879 | 904 | ||
880 | sk->sk_state = BT_CONNECT; | 905 | sk->sk_state = BT_CONNECT; |
881 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 906 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
@@ -887,7 +912,7 @@ int l2cap_do_connect(struct sock *sk) | |||
887 | if (l2cap_check_security(sk)) | 912 | if (l2cap_check_security(sk)) |
888 | sk->sk_state = BT_CONNECTED; | 913 | sk->sk_state = BT_CONNECTED; |
889 | } else | 914 | } else |
890 | l2cap_do_start(sk); | 915 | l2cap_do_start(chan); |
891 | } | 916 | } |
892 | 917 | ||
893 | err = 0; | 918 | err = 0; |
@@ -905,7 +930,7 @@ int __l2cap_wait_ack(struct sock *sk) | |||
905 | int timeo = HZ/5; | 930 | int timeo = HZ/5; |
906 | 931 | ||
907 | add_wait_queue(sk_sleep(sk), &wait); | 932 | add_wait_queue(sk_sleep(sk), &wait); |
908 | while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) { | 933 | while ((l2cap_pi(sk)->chan->unacked_frames > 0 && l2cap_pi(sk)->conn)) { |
909 | set_current_state(TASK_INTERRUPTIBLE); | 934 | set_current_state(TASK_INTERRUPTIBLE); |
910 | 935 | ||
911 | if (!timeo) | 936 | if (!timeo) |
@@ -931,57 +956,59 @@ int __l2cap_wait_ack(struct sock *sk) | |||
931 | 956 | ||
932 | static void l2cap_monitor_timeout(unsigned long arg) | 957 | static void l2cap_monitor_timeout(unsigned long arg) |
933 | { | 958 | { |
934 | struct sock *sk = (void *) arg; | 959 | struct l2cap_chan *chan = (void *) arg; |
960 | struct sock *sk = chan->sk; | ||
935 | 961 | ||
936 | BT_DBG("sk %p", sk); | 962 | BT_DBG("chan %p", chan); |
937 | 963 | ||
938 | bh_lock_sock(sk); | 964 | bh_lock_sock(sk); |
939 | if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { | 965 | if (chan->retry_count >= chan->remote_max_tx) { |
940 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); | 966 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, ECONNABORTED); |
941 | bh_unlock_sock(sk); | 967 | bh_unlock_sock(sk); |
942 | return; | 968 | return; |
943 | } | 969 | } |
944 | 970 | ||
945 | l2cap_pi(sk)->retry_count++; | 971 | chan->retry_count++; |
946 | __mod_monitor_timer(); | 972 | __mod_monitor_timer(); |
947 | 973 | ||
948 | l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); | 974 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
949 | bh_unlock_sock(sk); | 975 | bh_unlock_sock(sk); |
950 | } | 976 | } |
951 | 977 | ||
952 | static void l2cap_retrans_timeout(unsigned long arg) | 978 | static void l2cap_retrans_timeout(unsigned long arg) |
953 | { | 979 | { |
954 | struct sock *sk = (void *) arg; | 980 | struct l2cap_chan *chan = (void *) arg; |
981 | struct sock *sk = chan->sk; | ||
955 | 982 | ||
956 | BT_DBG("sk %p", sk); | 983 | BT_DBG("chan %p", chan); |
957 | 984 | ||
958 | bh_lock_sock(sk); | 985 | bh_lock_sock(sk); |
959 | l2cap_pi(sk)->retry_count = 1; | 986 | chan->retry_count = 1; |
960 | __mod_monitor_timer(); | 987 | __mod_monitor_timer(); |
961 | 988 | ||
962 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; | 989 | chan->conn_state |= L2CAP_CONN_WAIT_F; |
963 | 990 | ||
964 | l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); | 991 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
965 | bh_unlock_sock(sk); | 992 | bh_unlock_sock(sk); |
966 | } | 993 | } |
967 | 994 | ||
968 | static void l2cap_drop_acked_frames(struct sock *sk) | 995 | static void l2cap_drop_acked_frames(struct l2cap_chan *chan) |
969 | { | 996 | { |
970 | struct sk_buff *skb; | 997 | struct sk_buff *skb; |
971 | 998 | ||
972 | while ((skb = skb_peek(TX_QUEUE(sk))) && | 999 | while ((skb = skb_peek(&chan->tx_q)) && |
973 | l2cap_pi(sk)->unacked_frames) { | 1000 | chan->unacked_frames) { |
974 | if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq) | 1001 | if (bt_cb(skb)->tx_seq == chan->expected_ack_seq) |
975 | break; | 1002 | break; |
976 | 1003 | ||
977 | skb = skb_dequeue(TX_QUEUE(sk)); | 1004 | skb = skb_dequeue(&chan->tx_q); |
978 | kfree_skb(skb); | 1005 | kfree_skb(skb); |
979 | 1006 | ||
980 | l2cap_pi(sk)->unacked_frames--; | 1007 | chan->unacked_frames--; |
981 | } | 1008 | } |
982 | 1009 | ||
983 | if (!l2cap_pi(sk)->unacked_frames) | 1010 | if (!chan->unacked_frames) |
984 | del_timer(&l2cap_pi(sk)->retrans_timer); | 1011 | del_timer(&chan->retrans_timer); |
985 | } | 1012 | } |
986 | 1013 | ||
987 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | 1014 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb) |
@@ -1000,15 +1027,16 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | |||
1000 | hci_send_acl(hcon, skb, flags); | 1027 | hci_send_acl(hcon, skb, flags); |
1001 | } | 1028 | } |
1002 | 1029 | ||
1003 | void l2cap_streaming_send(struct sock *sk) | 1030 | void l2cap_streaming_send(struct l2cap_chan *chan) |
1004 | { | 1031 | { |
1032 | struct sock *sk = chan->sk; | ||
1005 | struct sk_buff *skb; | 1033 | struct sk_buff *skb; |
1006 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1034 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1007 | u16 control, fcs; | 1035 | u16 control, fcs; |
1008 | 1036 | ||
1009 | while ((skb = skb_dequeue(TX_QUEUE(sk)))) { | 1037 | while ((skb = skb_dequeue(&chan->tx_q))) { |
1010 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); | 1038 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); |
1011 | control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1039 | control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; |
1012 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); | 1040 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); |
1013 | 1041 | ||
1014 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1042 | if (pi->fcs == L2CAP_FCS_CRC16) { |
@@ -1018,17 +1046,18 @@ void l2cap_streaming_send(struct sock *sk) | |||
1018 | 1046 | ||
1019 | l2cap_do_send(sk, skb); | 1047 | l2cap_do_send(sk, skb); |
1020 | 1048 | ||
1021 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; | 1049 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; |
1022 | } | 1050 | } |
1023 | } | 1051 | } |
1024 | 1052 | ||
1025 | static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | 1053 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) |
1026 | { | 1054 | { |
1055 | struct sock *sk = chan->sk; | ||
1027 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1056 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1028 | struct sk_buff *skb, *tx_skb; | 1057 | struct sk_buff *skb, *tx_skb; |
1029 | u16 control, fcs; | 1058 | u16 control, fcs; |
1030 | 1059 | ||
1031 | skb = skb_peek(TX_QUEUE(sk)); | 1060 | skb = skb_peek(&chan->tx_q); |
1032 | if (!skb) | 1061 | if (!skb) |
1033 | return; | 1062 | return; |
1034 | 1063 | ||
@@ -1036,14 +1065,14 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1036 | if (bt_cb(skb)->tx_seq == tx_seq) | 1065 | if (bt_cb(skb)->tx_seq == tx_seq) |
1037 | break; | 1066 | break; |
1038 | 1067 | ||
1039 | if (skb_queue_is_last(TX_QUEUE(sk), skb)) | 1068 | if (skb_queue_is_last(&chan->tx_q, skb)) |
1040 | return; | 1069 | return; |
1041 | 1070 | ||
1042 | } while ((skb = skb_queue_next(TX_QUEUE(sk), skb))); | 1071 | } while ((skb = skb_queue_next(&chan->tx_q, skb))); |
1043 | 1072 | ||
1044 | if (pi->remote_max_tx && | 1073 | if (chan->remote_max_tx && |
1045 | bt_cb(skb)->retries == pi->remote_max_tx) { | 1074 | bt_cb(skb)->retries == chan->remote_max_tx) { |
1046 | l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); | 1075 | l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); |
1047 | return; | 1076 | return; |
1048 | } | 1077 | } |
1049 | 1078 | ||
@@ -1051,12 +1080,12 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1051 | bt_cb(skb)->retries++; | 1080 | bt_cb(skb)->retries++; |
1052 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1081 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1053 | 1082 | ||
1054 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | 1083 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { |
1055 | control |= L2CAP_CTRL_FINAL; | 1084 | control |= L2CAP_CTRL_FINAL; |
1056 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | 1085 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; |
1057 | } | 1086 | } |
1058 | 1087 | ||
1059 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1088 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1060 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1089 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1061 | 1090 | ||
1062 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1091 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
@@ -1069,9 +1098,10 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1069 | l2cap_do_send(sk, tx_skb); | 1098 | l2cap_do_send(sk, tx_skb); |
1070 | } | 1099 | } |
1071 | 1100 | ||
1072 | int l2cap_ertm_send(struct sock *sk) | 1101 | int l2cap_ertm_send(struct l2cap_chan *chan) |
1073 | { | 1102 | { |
1074 | struct sk_buff *skb, *tx_skb; | 1103 | struct sk_buff *skb, *tx_skb; |
1104 | struct sock *sk = chan->sk; | ||
1075 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1105 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1076 | u16 control, fcs; | 1106 | u16 control, fcs; |
1077 | int nsent = 0; | 1107 | int nsent = 0; |
@@ -1079,11 +1109,11 @@ int l2cap_ertm_send(struct sock *sk) | |||
1079 | if (sk->sk_state != BT_CONNECTED) | 1109 | if (sk->sk_state != BT_CONNECTED) |
1080 | return -ENOTCONN; | 1110 | return -ENOTCONN; |
1081 | 1111 | ||
1082 | while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { | 1112 | while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { |
1083 | 1113 | ||
1084 | if (pi->remote_max_tx && | 1114 | if (chan->remote_max_tx && |
1085 | bt_cb(skb)->retries == pi->remote_max_tx) { | 1115 | bt_cb(skb)->retries == chan->remote_max_tx) { |
1086 | l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); | 1116 | l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); |
1087 | break; | 1117 | break; |
1088 | } | 1118 | } |
1089 | 1119 | ||
@@ -1094,12 +1124,12 @@ int l2cap_ertm_send(struct sock *sk) | |||
1094 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1124 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1095 | control &= L2CAP_CTRL_SAR; | 1125 | control &= L2CAP_CTRL_SAR; |
1096 | 1126 | ||
1097 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | 1127 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { |
1098 | control |= L2CAP_CTRL_FINAL; | 1128 | control |= L2CAP_CTRL_FINAL; |
1099 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | 1129 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; |
1100 | } | 1130 | } |
1101 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1131 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1102 | | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1132 | | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1103 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1133 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1104 | 1134 | ||
1105 | 1135 | ||
@@ -1112,18 +1142,18 @@ int l2cap_ertm_send(struct sock *sk) | |||
1112 | 1142 | ||
1113 | __mod_retrans_timer(); | 1143 | __mod_retrans_timer(); |
1114 | 1144 | ||
1115 | bt_cb(skb)->tx_seq = pi->next_tx_seq; | 1145 | bt_cb(skb)->tx_seq = chan->next_tx_seq; |
1116 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; | 1146 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; |
1117 | 1147 | ||
1118 | if (bt_cb(skb)->retries == 1) | 1148 | if (bt_cb(skb)->retries == 1) |
1119 | pi->unacked_frames++; | 1149 | chan->unacked_frames++; |
1120 | 1150 | ||
1121 | pi->frames_sent++; | 1151 | chan->frames_sent++; |
1122 | 1152 | ||
1123 | if (skb_queue_is_last(TX_QUEUE(sk), skb)) | 1153 | if (skb_queue_is_last(&chan->tx_q, skb)) |
1124 | sk->sk_send_head = NULL; | 1154 | chan->tx_send_head = NULL; |
1125 | else | 1155 | else |
1126 | sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); | 1156 | chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); |
1127 | 1157 | ||
1128 | nsent++; | 1158 | nsent++; |
1129 | } | 1159 | } |
@@ -1131,41 +1161,39 @@ int l2cap_ertm_send(struct sock *sk) | |||
1131 | return nsent; | 1161 | return nsent; |
1132 | } | 1162 | } |
1133 | 1163 | ||
1134 | static int l2cap_retransmit_frames(struct sock *sk) | 1164 | static int l2cap_retransmit_frames(struct l2cap_chan *chan) |
1135 | { | 1165 | { |
1136 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1137 | int ret; | 1166 | int ret; |
1138 | 1167 | ||
1139 | if (!skb_queue_empty(TX_QUEUE(sk))) | 1168 | if (!skb_queue_empty(&chan->tx_q)) |
1140 | sk->sk_send_head = TX_QUEUE(sk)->next; | 1169 | chan->tx_send_head = chan->tx_q.next; |
1141 | 1170 | ||
1142 | pi->next_tx_seq = pi->expected_ack_seq; | 1171 | chan->next_tx_seq = chan->expected_ack_seq; |
1143 | ret = l2cap_ertm_send(sk); | 1172 | ret = l2cap_ertm_send(chan); |
1144 | return ret; | 1173 | return ret; |
1145 | } | 1174 | } |
1146 | 1175 | ||
1147 | static void l2cap_send_ack(struct l2cap_pinfo *pi) | 1176 | static void l2cap_send_ack(struct l2cap_chan *chan) |
1148 | { | 1177 | { |
1149 | struct sock *sk = (struct sock *)pi; | ||
1150 | u16 control = 0; | 1178 | u16 control = 0; |
1151 | 1179 | ||
1152 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1180 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
1153 | 1181 | ||
1154 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 1182 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
1155 | control |= L2CAP_SUPER_RCV_NOT_READY; | 1183 | control |= L2CAP_SUPER_RCV_NOT_READY; |
1156 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 1184 | chan->conn_state |= L2CAP_CONN_RNR_SENT; |
1157 | l2cap_send_sframe(pi, control); | 1185 | l2cap_send_sframe(chan, control); |
1158 | return; | 1186 | return; |
1159 | } | 1187 | } |
1160 | 1188 | ||
1161 | if (l2cap_ertm_send(sk) > 0) | 1189 | if (l2cap_ertm_send(chan) > 0) |
1162 | return; | 1190 | return; |
1163 | 1191 | ||
1164 | control |= L2CAP_SUPER_RCV_READY; | 1192 | control |= L2CAP_SUPER_RCV_READY; |
1165 | l2cap_send_sframe(pi, control); | 1193 | l2cap_send_sframe(chan, control); |
1166 | } | 1194 | } |
1167 | 1195 | ||
1168 | static void l2cap_send_srejtail(struct sock *sk) | 1196 | static void l2cap_send_srejtail(struct l2cap_chan *chan) |
1169 | { | 1197 | { |
1170 | struct srej_list *tail; | 1198 | struct srej_list *tail; |
1171 | u16 control; | 1199 | u16 control; |
@@ -1173,10 +1201,10 @@ static void l2cap_send_srejtail(struct sock *sk) | |||
1173 | control = L2CAP_SUPER_SELECT_REJECT; | 1201 | control = L2CAP_SUPER_SELECT_REJECT; |
1174 | control |= L2CAP_CTRL_FINAL; | 1202 | control |= L2CAP_CTRL_FINAL; |
1175 | 1203 | ||
1176 | tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list); | 1204 | tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); |
1177 | control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1205 | control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
1178 | 1206 | ||
1179 | l2cap_send_sframe(l2cap_pi(sk), control); | 1207 | l2cap_send_sframe(chan, control); |
1180 | } | 1208 | } |
1181 | 1209 | ||
1182 | static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) | 1210 | static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) |
@@ -1313,9 +1341,9 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz | |||
1313 | return skb; | 1341 | return skb; |
1314 | } | 1342 | } |
1315 | 1343 | ||
1316 | int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) | 1344 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1317 | { | 1345 | { |
1318 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1346 | struct sock *sk = chan->sk; |
1319 | struct sk_buff *skb; | 1347 | struct sk_buff *skb; |
1320 | struct sk_buff_head sar_queue; | 1348 | struct sk_buff_head sar_queue; |
1321 | u16 control; | 1349 | u16 control; |
@@ -1323,20 +1351,20 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) | |||
1323 | 1351 | ||
1324 | skb_queue_head_init(&sar_queue); | 1352 | skb_queue_head_init(&sar_queue); |
1325 | control = L2CAP_SDU_START; | 1353 | control = L2CAP_SDU_START; |
1326 | skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len); | 1354 | skb = l2cap_create_iframe_pdu(sk, msg, chan->remote_mps, control, len); |
1327 | if (IS_ERR(skb)) | 1355 | if (IS_ERR(skb)) |
1328 | return PTR_ERR(skb); | 1356 | return PTR_ERR(skb); |
1329 | 1357 | ||
1330 | __skb_queue_tail(&sar_queue, skb); | 1358 | __skb_queue_tail(&sar_queue, skb); |
1331 | len -= pi->remote_mps; | 1359 | len -= chan->remote_mps; |
1332 | size += pi->remote_mps; | 1360 | size += chan->remote_mps; |
1333 | 1361 | ||
1334 | while (len > 0) { | 1362 | while (len > 0) { |
1335 | size_t buflen; | 1363 | size_t buflen; |
1336 | 1364 | ||
1337 | if (len > pi->remote_mps) { | 1365 | if (len > chan->remote_mps) { |
1338 | control = L2CAP_SDU_CONTINUE; | 1366 | control = L2CAP_SDU_CONTINUE; |
1339 | buflen = pi->remote_mps; | 1367 | buflen = chan->remote_mps; |
1340 | } else { | 1368 | } else { |
1341 | control = L2CAP_SDU_END; | 1369 | control = L2CAP_SDU_END; |
1342 | buflen = len; | 1370 | buflen = len; |
@@ -1352,9 +1380,9 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) | |||
1352 | len -= buflen; | 1380 | len -= buflen; |
1353 | size += buflen; | 1381 | size += buflen; |
1354 | } | 1382 | } |
1355 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); | 1383 | skb_queue_splice_tail(&sar_queue, &chan->tx_q); |
1356 | if (sk->sk_send_head == NULL) | 1384 | if (chan->tx_send_head == NULL) |
1357 | sk->sk_send_head = sar_queue.next; | 1385 | chan->tx_send_head = sar_queue.next; |
1358 | 1386 | ||
1359 | return size; | 1387 | return size; |
1360 | } | 1388 | } |
@@ -1385,14 +1413,14 @@ static void l2cap_chan_ready(struct sock *sk) | |||
1385 | /* Copy frame to all raw sockets on that connection */ | 1413 | /* Copy frame to all raw sockets on that connection */ |
1386 | static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | 1414 | static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) |
1387 | { | 1415 | { |
1388 | struct l2cap_chan_list *l = &conn->chan_list; | ||
1389 | struct sk_buff *nskb; | 1416 | struct sk_buff *nskb; |
1390 | struct sock *sk; | 1417 | struct l2cap_chan *chan; |
1391 | 1418 | ||
1392 | BT_DBG("conn %p", conn); | 1419 | BT_DBG("conn %p", conn); |
1393 | 1420 | ||
1394 | read_lock(&l->lock); | 1421 | read_lock(&conn->chan_lock); |
1395 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 1422 | list_for_each_entry(chan, &conn->chan_l, list) { |
1423 | struct sock *sk = chan->sk; | ||
1396 | if (sk->sk_type != SOCK_RAW) | 1424 | if (sk->sk_type != SOCK_RAW) |
1397 | continue; | 1425 | continue; |
1398 | 1426 | ||
@@ -1406,7 +1434,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1406 | if (sock_queue_rcv_skb(sk, nskb)) | 1434 | if (sock_queue_rcv_skb(sk, nskb)) |
1407 | kfree_skb(nskb); | 1435 | kfree_skb(nskb); |
1408 | } | 1436 | } |
1409 | read_unlock(&l->lock); | 1437 | read_unlock(&conn->chan_lock); |
1410 | } | 1438 | } |
1411 | 1439 | ||
1412 | /* ---- L2CAP signalling commands ---- */ | 1440 | /* ---- L2CAP signalling commands ---- */ |
@@ -1538,32 +1566,35 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
1538 | 1566 | ||
1539 | static void l2cap_ack_timeout(unsigned long arg) | 1567 | static void l2cap_ack_timeout(unsigned long arg) |
1540 | { | 1568 | { |
1541 | struct sock *sk = (void *) arg; | 1569 | struct l2cap_chan *chan = (void *) arg; |
1542 | 1570 | ||
1543 | bh_lock_sock(sk); | 1571 | bh_lock_sock(chan->sk); |
1544 | l2cap_send_ack(l2cap_pi(sk)); | 1572 | l2cap_send_ack(chan); |
1545 | bh_unlock_sock(sk); | 1573 | bh_unlock_sock(chan->sk); |
1546 | } | 1574 | } |
1547 | 1575 | ||
1548 | static inline void l2cap_ertm_init(struct sock *sk) | 1576 | static inline void l2cap_ertm_init(struct l2cap_chan *chan) |
1549 | { | 1577 | { |
1550 | l2cap_pi(sk)->expected_ack_seq = 0; | 1578 | struct sock *sk = chan->sk; |
1551 | l2cap_pi(sk)->unacked_frames = 0; | 1579 | |
1552 | l2cap_pi(sk)->buffer_seq = 0; | 1580 | chan->expected_ack_seq = 0; |
1553 | l2cap_pi(sk)->num_acked = 0; | 1581 | chan->unacked_frames = 0; |
1554 | l2cap_pi(sk)->frames_sent = 0; | 1582 | chan->buffer_seq = 0; |
1583 | chan->num_acked = 0; | ||
1584 | chan->frames_sent = 0; | ||
1555 | 1585 | ||
1556 | setup_timer(&l2cap_pi(sk)->retrans_timer, | 1586 | setup_timer(&chan->retrans_timer, l2cap_retrans_timeout, |
1557 | l2cap_retrans_timeout, (unsigned long) sk); | 1587 | (unsigned long) chan); |
1558 | setup_timer(&l2cap_pi(sk)->monitor_timer, | 1588 | setup_timer(&chan->monitor_timer, l2cap_monitor_timeout, |
1559 | l2cap_monitor_timeout, (unsigned long) sk); | 1589 | (unsigned long) chan); |
1560 | setup_timer(&l2cap_pi(sk)->ack_timer, | 1590 | setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); |
1561 | l2cap_ack_timeout, (unsigned long) sk); | ||
1562 | 1591 | ||
1563 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 1592 | skb_queue_head_init(&chan->srej_q); |
1564 | __skb_queue_head_init(BUSY_QUEUE(sk)); | 1593 | skb_queue_head_init(&chan->busy_q); |
1565 | 1594 | ||
1566 | INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); | 1595 | INIT_LIST_HEAD(&chan->srej_l); |
1596 | |||
1597 | INIT_WORK(&chan->busy_work, l2cap_busy_work); | ||
1567 | 1598 | ||
1568 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; | 1599 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; |
1569 | } | 1600 | } |
@@ -1581,16 +1612,16 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
1581 | } | 1612 | } |
1582 | } | 1613 | } |
1583 | 1614 | ||
1584 | int l2cap_build_conf_req(struct sock *sk, void *data) | 1615 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) |
1585 | { | 1616 | { |
1586 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1617 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
1587 | struct l2cap_conf_req *req = data; | 1618 | struct l2cap_conf_req *req = data; |
1588 | struct l2cap_conf_rfc rfc = { .mode = pi->mode }; | 1619 | struct l2cap_conf_rfc rfc = { .mode = pi->mode }; |
1589 | void *ptr = req->data; | 1620 | void *ptr = req->data; |
1590 | 1621 | ||
1591 | BT_DBG("sk %p", sk); | 1622 | BT_DBG("chan %p", chan); |
1592 | 1623 | ||
1593 | if (pi->num_conf_req || pi->num_conf_rsp) | 1624 | if (chan->num_conf_req || chan->num_conf_rsp) |
1594 | goto done; | 1625 | goto done; |
1595 | 1626 | ||
1596 | switch (pi->mode) { | 1627 | switch (pi->mode) { |
@@ -1679,20 +1710,20 @@ done: | |||
1679 | return ptr - data; | 1710 | return ptr - data; |
1680 | } | 1711 | } |
1681 | 1712 | ||
1682 | static int l2cap_parse_conf_req(struct sock *sk, void *data) | 1713 | static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) |
1683 | { | 1714 | { |
1684 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1715 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
1685 | struct l2cap_conf_rsp *rsp = data; | 1716 | struct l2cap_conf_rsp *rsp = data; |
1686 | void *ptr = rsp->data; | 1717 | void *ptr = rsp->data; |
1687 | void *req = pi->conf_req; | 1718 | void *req = chan->conf_req; |
1688 | int len = pi->conf_len; | 1719 | int len = chan->conf_len; |
1689 | int type, hint, olen; | 1720 | int type, hint, olen; |
1690 | unsigned long val; | 1721 | unsigned long val; |
1691 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; | 1722 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
1692 | u16 mtu = L2CAP_DEFAULT_MTU; | 1723 | u16 mtu = L2CAP_DEFAULT_MTU; |
1693 | u16 result = L2CAP_CONF_SUCCESS; | 1724 | u16 result = L2CAP_CONF_SUCCESS; |
1694 | 1725 | ||
1695 | BT_DBG("sk %p", sk); | 1726 | BT_DBG("chan %p", chan); |
1696 | 1727 | ||
1697 | while (len >= L2CAP_CONF_OPT_SIZE) { | 1728 | while (len >= L2CAP_CONF_OPT_SIZE) { |
1698 | len -= l2cap_get_conf_opt(&req, &type, &olen, &val); | 1729 | len -= l2cap_get_conf_opt(&req, &type, &olen, &val); |
@@ -1733,7 +1764,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) | |||
1733 | } | 1764 | } |
1734 | } | 1765 | } |
1735 | 1766 | ||
1736 | if (pi->num_conf_rsp || pi->num_conf_req > 1) | 1767 | if (chan->num_conf_rsp || chan->num_conf_req > 1) |
1737 | goto done; | 1768 | goto done; |
1738 | 1769 | ||
1739 | switch (pi->mode) { | 1770 | switch (pi->mode) { |
@@ -1756,7 +1787,7 @@ done: | |||
1756 | result = L2CAP_CONF_UNACCEPT; | 1787 | result = L2CAP_CONF_UNACCEPT; |
1757 | rfc.mode = pi->mode; | 1788 | rfc.mode = pi->mode; |
1758 | 1789 | ||
1759 | if (pi->num_conf_rsp == 1) | 1790 | if (chan->num_conf_rsp == 1) |
1760 | return -ECONNREFUSED; | 1791 | return -ECONNREFUSED; |
1761 | 1792 | ||
1762 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 1793 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
@@ -1783,13 +1814,13 @@ done: | |||
1783 | break; | 1814 | break; |
1784 | 1815 | ||
1785 | case L2CAP_MODE_ERTM: | 1816 | case L2CAP_MODE_ERTM: |
1786 | pi->remote_tx_win = rfc.txwin_size; | 1817 | chan->remote_tx_win = rfc.txwin_size; |
1787 | pi->remote_max_tx = rfc.max_transmit; | 1818 | chan->remote_max_tx = rfc.max_transmit; |
1788 | 1819 | ||
1789 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) | 1820 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) |
1790 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1821 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
1791 | 1822 | ||
1792 | pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 1823 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); |
1793 | 1824 | ||
1794 | rfc.retrans_timeout = | 1825 | rfc.retrans_timeout = |
1795 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); | 1826 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); |
@@ -1807,7 +1838,7 @@ done: | |||
1807 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) | 1838 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) |
1808 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1839 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
1809 | 1840 | ||
1810 | pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 1841 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); |
1811 | 1842 | ||
1812 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 1843 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
1813 | 1844 | ||
@@ -1916,6 +1947,31 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla | |||
1916 | return ptr - data; | 1947 | return ptr - data; |
1917 | } | 1948 | } |
1918 | 1949 | ||
1950 | void __l2cap_connect_rsp_defer(struct sock *sk) | ||
1951 | { | ||
1952 | struct l2cap_conn_rsp rsp; | ||
1953 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
1954 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
1955 | u8 buf[128]; | ||
1956 | |||
1957 | sk->sk_state = BT_CONFIG; | ||
1958 | |||
1959 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
1960 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
1961 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | ||
1962 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
1963 | l2cap_send_cmd(conn, chan->ident, | ||
1964 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
1965 | |||
1966 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) | ||
1967 | return; | ||
1968 | |||
1969 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
1970 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
1971 | l2cap_build_conf_req(chan, buf), buf); | ||
1972 | chan->num_conf_req++; | ||
1973 | } | ||
1974 | |||
1919 | static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) | 1975 | static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) |
1920 | { | 1976 | { |
1921 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1977 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
@@ -1973,9 +2029,9 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
1973 | 2029 | ||
1974 | static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 2030 | static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) |
1975 | { | 2031 | { |
1976 | struct l2cap_chan_list *list = &conn->chan_list; | ||
1977 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 2032 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
1978 | struct l2cap_conn_rsp rsp; | 2033 | struct l2cap_conn_rsp rsp; |
2034 | struct l2cap_chan *chan = NULL; | ||
1979 | struct sock *parent, *sk = NULL; | 2035 | struct sock *parent, *sk = NULL; |
1980 | int result, status = L2CAP_CS_NO_INFO; | 2036 | int result, status = L2CAP_CS_NO_INFO; |
1981 | 2037 | ||
@@ -2013,11 +2069,17 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2013 | if (!sk) | 2069 | if (!sk) |
2014 | goto response; | 2070 | goto response; |
2015 | 2071 | ||
2016 | write_lock_bh(&list->lock); | 2072 | chan = l2cap_chan_alloc(sk); |
2073 | if (!chan) { | ||
2074 | l2cap_sock_kill(sk); | ||
2075 | goto response; | ||
2076 | } | ||
2077 | |||
2078 | write_lock_bh(&conn->chan_lock); | ||
2017 | 2079 | ||
2018 | /* Check if we already have channel with that dcid */ | 2080 | /* Check if we already have channel with that dcid */ |
2019 | if (__l2cap_get_chan_by_dcid(list, scid)) { | 2081 | if (__l2cap_get_chan_by_dcid(conn, scid)) { |
2020 | write_unlock_bh(&list->lock); | 2082 | write_unlock_bh(&conn->chan_lock); |
2021 | sock_set_flag(sk, SOCK_ZAPPED); | 2083 | sock_set_flag(sk, SOCK_ZAPPED); |
2022 | l2cap_sock_kill(sk); | 2084 | l2cap_sock_kill(sk); |
2023 | goto response; | 2085 | goto response; |
@@ -2033,12 +2095,15 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2033 | 2095 | ||
2034 | bt_accept_enqueue(parent, sk); | 2096 | bt_accept_enqueue(parent, sk); |
2035 | 2097 | ||
2036 | __l2cap_chan_add(conn, sk); | 2098 | __l2cap_chan_add(conn, chan); |
2099 | |||
2100 | l2cap_pi(sk)->chan = chan; | ||
2101 | |||
2037 | dcid = l2cap_pi(sk)->scid; | 2102 | dcid = l2cap_pi(sk)->scid; |
2038 | 2103 | ||
2039 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 2104 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
2040 | 2105 | ||
2041 | l2cap_pi(sk)->ident = cmd->ident; | 2106 | chan->ident = cmd->ident; |
2042 | 2107 | ||
2043 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { | 2108 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { |
2044 | if (l2cap_check_security(sk)) { | 2109 | if (l2cap_check_security(sk)) { |
@@ -2063,7 +2128,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2063 | status = L2CAP_CS_NO_INFO; | 2128 | status = L2CAP_CS_NO_INFO; |
2064 | } | 2129 | } |
2065 | 2130 | ||
2066 | write_unlock_bh(&list->lock); | 2131 | write_unlock_bh(&conn->chan_lock); |
2067 | 2132 | ||
2068 | response: | 2133 | response: |
2069 | bh_unlock_sock(parent); | 2134 | bh_unlock_sock(parent); |
@@ -2089,13 +2154,13 @@ sendresp: | |||
2089 | L2CAP_INFO_REQ, sizeof(info), &info); | 2154 | L2CAP_INFO_REQ, sizeof(info), &info); |
2090 | } | 2155 | } |
2091 | 2156 | ||
2092 | if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && | 2157 | if (chan && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && |
2093 | result == L2CAP_CR_SUCCESS) { | 2158 | result == L2CAP_CR_SUCCESS) { |
2094 | u8 buf[128]; | 2159 | u8 buf[128]; |
2095 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2160 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
2096 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2161 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2097 | l2cap_build_conf_req(sk, buf), buf); | 2162 | l2cap_build_conf_req(chan, buf), buf); |
2098 | l2cap_pi(sk)->num_conf_req++; | 2163 | chan->num_conf_req++; |
2099 | } | 2164 | } |
2100 | 2165 | ||
2101 | return 0; | 2166 | return 0; |
@@ -2105,6 +2170,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2105 | { | 2170 | { |
2106 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; | 2171 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; |
2107 | u16 scid, dcid, result, status; | 2172 | u16 scid, dcid, result, status; |
2173 | struct l2cap_chan *chan; | ||
2108 | struct sock *sk; | 2174 | struct sock *sk; |
2109 | u8 req[128]; | 2175 | u8 req[128]; |
2110 | 2176 | ||
@@ -2116,19 +2182,21 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2116 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); | 2182 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); |
2117 | 2183 | ||
2118 | if (scid) { | 2184 | if (scid) { |
2119 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); | 2185 | chan = l2cap_get_chan_by_scid(conn, scid); |
2120 | if (!sk) | 2186 | if (!chan) |
2121 | return -EFAULT; | 2187 | return -EFAULT; |
2122 | } else { | 2188 | } else { |
2123 | sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); | 2189 | chan = l2cap_get_chan_by_ident(conn, cmd->ident); |
2124 | if (!sk) | 2190 | if (!chan) |
2125 | return -EFAULT; | 2191 | return -EFAULT; |
2126 | } | 2192 | } |
2127 | 2193 | ||
2194 | sk = chan->sk; | ||
2195 | |||
2128 | switch (result) { | 2196 | switch (result) { |
2129 | case L2CAP_CR_SUCCESS: | 2197 | case L2CAP_CR_SUCCESS: |
2130 | sk->sk_state = BT_CONFIG; | 2198 | sk->sk_state = BT_CONFIG; |
2131 | l2cap_pi(sk)->ident = 0; | 2199 | chan->ident = 0; |
2132 | l2cap_pi(sk)->dcid = dcid; | 2200 | l2cap_pi(sk)->dcid = dcid; |
2133 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; | 2201 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; |
2134 | 2202 | ||
@@ -2138,8 +2206,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2138 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2206 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
2139 | 2207 | ||
2140 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2208 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2141 | l2cap_build_conf_req(sk, req), req); | 2209 | l2cap_build_conf_req(chan, req), req); |
2142 | l2cap_pi(sk)->num_conf_req++; | 2210 | chan->num_conf_req++; |
2143 | break; | 2211 | break; |
2144 | 2212 | ||
2145 | case L2CAP_CR_PEND: | 2213 | case L2CAP_CR_PEND: |
@@ -2155,7 +2223,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2155 | break; | 2223 | break; |
2156 | } | 2224 | } |
2157 | 2225 | ||
2158 | l2cap_chan_del(sk, ECONNREFUSED); | 2226 | l2cap_chan_del(chan, ECONNREFUSED); |
2159 | break; | 2227 | break; |
2160 | } | 2228 | } |
2161 | 2229 | ||
@@ -2179,6 +2247,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2179 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; | 2247 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; |
2180 | u16 dcid, flags; | 2248 | u16 dcid, flags; |
2181 | u8 rsp[64]; | 2249 | u8 rsp[64]; |
2250 | struct l2cap_chan *chan; | ||
2182 | struct sock *sk; | 2251 | struct sock *sk; |
2183 | int len; | 2252 | int len; |
2184 | 2253 | ||
@@ -2187,10 +2256,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2187 | 2256 | ||
2188 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); | 2257 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); |
2189 | 2258 | ||
2190 | sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); | 2259 | chan = l2cap_get_chan_by_scid(conn, dcid); |
2191 | if (!sk) | 2260 | if (!chan) |
2192 | return -ENOENT; | 2261 | return -ENOENT; |
2193 | 2262 | ||
2263 | sk = chan->sk; | ||
2264 | |||
2194 | if (sk->sk_state != BT_CONFIG) { | 2265 | if (sk->sk_state != BT_CONFIG) { |
2195 | struct l2cap_cmd_rej rej; | 2266 | struct l2cap_cmd_rej rej; |
2196 | 2267 | ||
@@ -2202,7 +2273,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2202 | 2273 | ||
2203 | /* Reject if config buffer is too small. */ | 2274 | /* Reject if config buffer is too small. */ |
2204 | len = cmd_len - sizeof(*req); | 2275 | len = cmd_len - sizeof(*req); |
2205 | if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { | 2276 | if (chan->conf_len + len > sizeof(chan->conf_req)) { |
2206 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2277 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2207 | l2cap_build_conf_rsp(sk, rsp, | 2278 | l2cap_build_conf_rsp(sk, rsp, |
2208 | L2CAP_CONF_REJECT, flags), rsp); | 2279 | L2CAP_CONF_REJECT, flags), rsp); |
@@ -2210,8 +2281,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2210 | } | 2281 | } |
2211 | 2282 | ||
2212 | /* Store config. */ | 2283 | /* Store config. */ |
2213 | memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len); | 2284 | memcpy(chan->conf_req + chan->conf_len, req->data, len); |
2214 | l2cap_pi(sk)->conf_len += len; | 2285 | chan->conf_len += len; |
2215 | 2286 | ||
2216 | if (flags & 0x0001) { | 2287 | if (flags & 0x0001) { |
2217 | /* Incomplete config. Send empty response. */ | 2288 | /* Incomplete config. Send empty response. */ |
@@ -2222,17 +2293,17 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2222 | } | 2293 | } |
2223 | 2294 | ||
2224 | /* Complete config. */ | 2295 | /* Complete config. */ |
2225 | len = l2cap_parse_conf_req(sk, rsp); | 2296 | len = l2cap_parse_conf_req(chan, rsp); |
2226 | if (len < 0) { | 2297 | if (len < 0) { |
2227 | l2cap_send_disconn_req(conn, sk, ECONNRESET); | 2298 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2228 | goto unlock; | 2299 | goto unlock; |
2229 | } | 2300 | } |
2230 | 2301 | ||
2231 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); | 2302 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); |
2232 | l2cap_pi(sk)->num_conf_rsp++; | 2303 | chan->num_conf_rsp++; |
2233 | 2304 | ||
2234 | /* Reset config buffer. */ | 2305 | /* Reset config buffer. */ |
2235 | l2cap_pi(sk)->conf_len = 0; | 2306 | chan->conf_len = 0; |
2236 | 2307 | ||
2237 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) | 2308 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) |
2238 | goto unlock; | 2309 | goto unlock; |
@@ -2242,11 +2313,11 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2242 | 2313 | ||
2243 | sk->sk_state = BT_CONNECTED; | 2314 | sk->sk_state = BT_CONNECTED; |
2244 | 2315 | ||
2245 | l2cap_pi(sk)->next_tx_seq = 0; | 2316 | chan->next_tx_seq = 0; |
2246 | l2cap_pi(sk)->expected_tx_seq = 0; | 2317 | chan->expected_tx_seq = 0; |
2247 | __skb_queue_head_init(TX_QUEUE(sk)); | 2318 | skb_queue_head_init(&chan->tx_q); |
2248 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 2319 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2249 | l2cap_ertm_init(sk); | 2320 | l2cap_ertm_init(chan); |
2250 | 2321 | ||
2251 | l2cap_chan_ready(sk); | 2322 | l2cap_chan_ready(sk); |
2252 | goto unlock; | 2323 | goto unlock; |
@@ -2256,8 +2327,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2256 | u8 buf[64]; | 2327 | u8 buf[64]; |
2257 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2328 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
2258 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2329 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2259 | l2cap_build_conf_req(sk, buf), buf); | 2330 | l2cap_build_conf_req(chan, buf), buf); |
2260 | l2cap_pi(sk)->num_conf_req++; | 2331 | chan->num_conf_req++; |
2261 | } | 2332 | } |
2262 | 2333 | ||
2263 | unlock: | 2334 | unlock: |
@@ -2269,6 +2340,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2269 | { | 2340 | { |
2270 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; | 2341 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; |
2271 | u16 scid, flags, result; | 2342 | u16 scid, flags, result; |
2343 | struct l2cap_chan *chan; | ||
2272 | struct sock *sk; | 2344 | struct sock *sk; |
2273 | int len = cmd->len - sizeof(*rsp); | 2345 | int len = cmd->len - sizeof(*rsp); |
2274 | 2346 | ||
@@ -2279,21 +2351,23 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2279 | BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", | 2351 | BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", |
2280 | scid, flags, result); | 2352 | scid, flags, result); |
2281 | 2353 | ||
2282 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); | 2354 | chan = l2cap_get_chan_by_scid(conn, scid); |
2283 | if (!sk) | 2355 | if (!chan) |
2284 | return 0; | 2356 | return 0; |
2285 | 2357 | ||
2358 | sk = chan->sk; | ||
2359 | |||
2286 | switch (result) { | 2360 | switch (result) { |
2287 | case L2CAP_CONF_SUCCESS: | 2361 | case L2CAP_CONF_SUCCESS: |
2288 | l2cap_conf_rfc_get(sk, rsp->data, len); | 2362 | l2cap_conf_rfc_get(sk, rsp->data, len); |
2289 | break; | 2363 | break; |
2290 | 2364 | ||
2291 | case L2CAP_CONF_UNACCEPT: | 2365 | case L2CAP_CONF_UNACCEPT: |
2292 | if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { | 2366 | if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { |
2293 | char req[64]; | 2367 | char req[64]; |
2294 | 2368 | ||
2295 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { | 2369 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { |
2296 | l2cap_send_disconn_req(conn, sk, ECONNRESET); | 2370 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2297 | goto done; | 2371 | goto done; |
2298 | } | 2372 | } |
2299 | 2373 | ||
@@ -2302,13 +2376,13 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2302 | len = l2cap_parse_conf_rsp(sk, rsp->data, | 2376 | len = l2cap_parse_conf_rsp(sk, rsp->data, |
2303 | len, req, &result); | 2377 | len, req, &result); |
2304 | if (len < 0) { | 2378 | if (len < 0) { |
2305 | l2cap_send_disconn_req(conn, sk, ECONNRESET); | 2379 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2306 | goto done; | 2380 | goto done; |
2307 | } | 2381 | } |
2308 | 2382 | ||
2309 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 2383 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
2310 | L2CAP_CONF_REQ, len, req); | 2384 | L2CAP_CONF_REQ, len, req); |
2311 | l2cap_pi(sk)->num_conf_req++; | 2385 | chan->num_conf_req++; |
2312 | if (result != L2CAP_CONF_SUCCESS) | 2386 | if (result != L2CAP_CONF_SUCCESS) |
2313 | goto done; | 2387 | goto done; |
2314 | break; | 2388 | break; |
@@ -2317,7 +2391,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2317 | default: | 2391 | default: |
2318 | sk->sk_err = ECONNRESET; | 2392 | sk->sk_err = ECONNRESET; |
2319 | l2cap_sock_set_timer(sk, HZ * 5); | 2393 | l2cap_sock_set_timer(sk, HZ * 5); |
2320 | l2cap_send_disconn_req(conn, sk, ECONNRESET); | 2394 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2321 | goto done; | 2395 | goto done; |
2322 | } | 2396 | } |
2323 | 2397 | ||
@@ -2330,11 +2404,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2330 | set_default_fcs(l2cap_pi(sk)); | 2404 | set_default_fcs(l2cap_pi(sk)); |
2331 | 2405 | ||
2332 | sk->sk_state = BT_CONNECTED; | 2406 | sk->sk_state = BT_CONNECTED; |
2333 | l2cap_pi(sk)->next_tx_seq = 0; | 2407 | chan->next_tx_seq = 0; |
2334 | l2cap_pi(sk)->expected_tx_seq = 0; | 2408 | chan->expected_tx_seq = 0; |
2335 | __skb_queue_head_init(TX_QUEUE(sk)); | 2409 | skb_queue_head_init(&chan->tx_q); |
2336 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 2410 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2337 | l2cap_ertm_init(sk); | 2411 | l2cap_ertm_init(chan); |
2338 | 2412 | ||
2339 | l2cap_chan_ready(sk); | 2413 | l2cap_chan_ready(sk); |
2340 | } | 2414 | } |
@@ -2349,6 +2423,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2349 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; | 2423 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; |
2350 | struct l2cap_disconn_rsp rsp; | 2424 | struct l2cap_disconn_rsp rsp; |
2351 | u16 dcid, scid; | 2425 | u16 dcid, scid; |
2426 | struct l2cap_chan *chan; | ||
2352 | struct sock *sk; | 2427 | struct sock *sk; |
2353 | 2428 | ||
2354 | scid = __le16_to_cpu(req->scid); | 2429 | scid = __le16_to_cpu(req->scid); |
@@ -2356,10 +2431,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2356 | 2431 | ||
2357 | BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); | 2432 | BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); |
2358 | 2433 | ||
2359 | sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); | 2434 | chan = l2cap_get_chan_by_scid(conn, dcid); |
2360 | if (!sk) | 2435 | if (!chan) |
2361 | return 0; | 2436 | return 0; |
2362 | 2437 | ||
2438 | sk = chan->sk; | ||
2439 | |||
2363 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2440 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
2364 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2441 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
2365 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); | 2442 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); |
@@ -2375,7 +2452,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2375 | return 0; | 2452 | return 0; |
2376 | } | 2453 | } |
2377 | 2454 | ||
2378 | l2cap_chan_del(sk, ECONNRESET); | 2455 | l2cap_chan_del(chan, ECONNRESET); |
2379 | bh_unlock_sock(sk); | 2456 | bh_unlock_sock(sk); |
2380 | 2457 | ||
2381 | l2cap_sock_kill(sk); | 2458 | l2cap_sock_kill(sk); |
@@ -2386,6 +2463,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2386 | { | 2463 | { |
2387 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; | 2464 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; |
2388 | u16 dcid, scid; | 2465 | u16 dcid, scid; |
2466 | struct l2cap_chan *chan; | ||
2389 | struct sock *sk; | 2467 | struct sock *sk; |
2390 | 2468 | ||
2391 | scid = __le16_to_cpu(rsp->scid); | 2469 | scid = __le16_to_cpu(rsp->scid); |
@@ -2393,10 +2471,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2393 | 2471 | ||
2394 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); | 2472 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); |
2395 | 2473 | ||
2396 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); | 2474 | chan = l2cap_get_chan_by_scid(conn, scid); |
2397 | if (!sk) | 2475 | if (!chan) |
2398 | return 0; | 2476 | return 0; |
2399 | 2477 | ||
2478 | sk = chan->sk; | ||
2479 | |||
2400 | /* don't delete l2cap channel if sk is owned by user */ | 2480 | /* don't delete l2cap channel if sk is owned by user */ |
2401 | if (sock_owned_by_user(sk)) { | 2481 | if (sock_owned_by_user(sk)) { |
2402 | sk->sk_state = BT_DISCONN; | 2482 | sk->sk_state = BT_DISCONN; |
@@ -2406,7 +2486,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2406 | return 0; | 2486 | return 0; |
2407 | } | 2487 | } |
2408 | 2488 | ||
2409 | l2cap_chan_del(sk, 0); | 2489 | l2cap_chan_del(chan, 0); |
2410 | bh_unlock_sock(sk); | 2490 | bh_unlock_sock(sk); |
2411 | 2491 | ||
2412 | l2cap_sock_kill(sk); | 2492 | l2cap_sock_kill(sk); |
@@ -2709,49 +2789,47 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) | |||
2709 | return 0; | 2789 | return 0; |
2710 | } | 2790 | } |
2711 | 2791 | ||
2712 | static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) | 2792 | static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) |
2713 | { | 2793 | { |
2714 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2715 | u16 control = 0; | 2794 | u16 control = 0; |
2716 | 2795 | ||
2717 | pi->frames_sent = 0; | 2796 | chan->frames_sent = 0; |
2718 | 2797 | ||
2719 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 2798 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
2720 | 2799 | ||
2721 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 2800 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
2722 | control |= L2CAP_SUPER_RCV_NOT_READY; | 2801 | control |= L2CAP_SUPER_RCV_NOT_READY; |
2723 | l2cap_send_sframe(pi, control); | 2802 | l2cap_send_sframe(chan, control); |
2724 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 2803 | chan->conn_state |= L2CAP_CONN_RNR_SENT; |
2725 | } | 2804 | } |
2726 | 2805 | ||
2727 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) | 2806 | if (chan->conn_state & L2CAP_CONN_REMOTE_BUSY) |
2728 | l2cap_retransmit_frames(sk); | 2807 | l2cap_retransmit_frames(chan); |
2729 | 2808 | ||
2730 | l2cap_ertm_send(sk); | 2809 | l2cap_ertm_send(chan); |
2731 | 2810 | ||
2732 | if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && | 2811 | if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) && |
2733 | pi->frames_sent == 0) { | 2812 | chan->frames_sent == 0) { |
2734 | control |= L2CAP_SUPER_RCV_READY; | 2813 | control |= L2CAP_SUPER_RCV_READY; |
2735 | l2cap_send_sframe(pi, control); | 2814 | l2cap_send_sframe(chan, control); |
2736 | } | 2815 | } |
2737 | } | 2816 | } |
2738 | 2817 | ||
2739 | static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) | 2818 | static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar) |
2740 | { | 2819 | { |
2741 | struct sk_buff *next_skb; | 2820 | struct sk_buff *next_skb; |
2742 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2743 | int tx_seq_offset, next_tx_seq_offset; | 2821 | int tx_seq_offset, next_tx_seq_offset; |
2744 | 2822 | ||
2745 | bt_cb(skb)->tx_seq = tx_seq; | 2823 | bt_cb(skb)->tx_seq = tx_seq; |
2746 | bt_cb(skb)->sar = sar; | 2824 | bt_cb(skb)->sar = sar; |
2747 | 2825 | ||
2748 | next_skb = skb_peek(SREJ_QUEUE(sk)); | 2826 | next_skb = skb_peek(&chan->srej_q); |
2749 | if (!next_skb) { | 2827 | if (!next_skb) { |
2750 | __skb_queue_tail(SREJ_QUEUE(sk), skb); | 2828 | __skb_queue_tail(&chan->srej_q, skb); |
2751 | return 0; | 2829 | return 0; |
2752 | } | 2830 | } |
2753 | 2831 | ||
2754 | tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; | 2832 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; |
2755 | if (tx_seq_offset < 0) | 2833 | if (tx_seq_offset < 0) |
2756 | tx_seq_offset += 64; | 2834 | tx_seq_offset += 64; |
2757 | 2835 | ||
@@ -2760,53 +2838,53 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s | |||
2760 | return -EINVAL; | 2838 | return -EINVAL; |
2761 | 2839 | ||
2762 | next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - | 2840 | next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - |
2763 | pi->buffer_seq) % 64; | 2841 | chan->buffer_seq) % 64; |
2764 | if (next_tx_seq_offset < 0) | 2842 | if (next_tx_seq_offset < 0) |
2765 | next_tx_seq_offset += 64; | 2843 | next_tx_seq_offset += 64; |
2766 | 2844 | ||
2767 | if (next_tx_seq_offset > tx_seq_offset) { | 2845 | if (next_tx_seq_offset > tx_seq_offset) { |
2768 | __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); | 2846 | __skb_queue_before(&chan->srej_q, next_skb, skb); |
2769 | return 0; | 2847 | return 0; |
2770 | } | 2848 | } |
2771 | 2849 | ||
2772 | if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb)) | 2850 | if (skb_queue_is_last(&chan->srej_q, next_skb)) |
2773 | break; | 2851 | break; |
2774 | 2852 | ||
2775 | } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb))); | 2853 | } while ((next_skb = skb_queue_next(&chan->srej_q, next_skb))); |
2776 | 2854 | ||
2777 | __skb_queue_tail(SREJ_QUEUE(sk), skb); | 2855 | __skb_queue_tail(&chan->srej_q, skb); |
2778 | 2856 | ||
2779 | return 0; | 2857 | return 0; |
2780 | } | 2858 | } |
2781 | 2859 | ||
2782 | static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) | 2860 | static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
2783 | { | 2861 | { |
2784 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2862 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
2785 | struct sk_buff *_skb; | 2863 | struct sk_buff *_skb; |
2786 | int err; | 2864 | int err; |
2787 | 2865 | ||
2788 | switch (control & L2CAP_CTRL_SAR) { | 2866 | switch (control & L2CAP_CTRL_SAR) { |
2789 | case L2CAP_SDU_UNSEGMENTED: | 2867 | case L2CAP_SDU_UNSEGMENTED: |
2790 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) | 2868 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) |
2791 | goto drop; | 2869 | goto drop; |
2792 | 2870 | ||
2793 | err = sock_queue_rcv_skb(sk, skb); | 2871 | err = sock_queue_rcv_skb(chan->sk, skb); |
2794 | if (!err) | 2872 | if (!err) |
2795 | return err; | 2873 | return err; |
2796 | 2874 | ||
2797 | break; | 2875 | break; |
2798 | 2876 | ||
2799 | case L2CAP_SDU_START: | 2877 | case L2CAP_SDU_START: |
2800 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) | 2878 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) |
2801 | goto drop; | 2879 | goto drop; |
2802 | 2880 | ||
2803 | pi->sdu_len = get_unaligned_le16(skb->data); | 2881 | chan->sdu_len = get_unaligned_le16(skb->data); |
2804 | 2882 | ||
2805 | if (pi->sdu_len > pi->imtu) | 2883 | if (chan->sdu_len > pi->imtu) |
2806 | goto disconnect; | 2884 | goto disconnect; |
2807 | 2885 | ||
2808 | pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); | 2886 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); |
2809 | if (!pi->sdu) | 2887 | if (!chan->sdu) |
2810 | return -ENOMEM; | 2888 | return -ENOMEM; |
2811 | 2889 | ||
2812 | /* pull sdu_len bytes only after alloc, because of Local Busy | 2890 | /* pull sdu_len bytes only after alloc, because of Local Busy |
@@ -2814,63 +2892,63 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c | |||
2814 | * only once, i.e., when alloc does not fail */ | 2892 | * only once, i.e., when alloc does not fail */ |
2815 | skb_pull(skb, 2); | 2893 | skb_pull(skb, 2); |
2816 | 2894 | ||
2817 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 2895 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
2818 | 2896 | ||
2819 | pi->conn_state |= L2CAP_CONN_SAR_SDU; | 2897 | chan->conn_state |= L2CAP_CONN_SAR_SDU; |
2820 | pi->partial_sdu_len = skb->len; | 2898 | chan->partial_sdu_len = skb->len; |
2821 | break; | 2899 | break; |
2822 | 2900 | ||
2823 | case L2CAP_SDU_CONTINUE: | 2901 | case L2CAP_SDU_CONTINUE: |
2824 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | 2902 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) |
2825 | goto disconnect; | 2903 | goto disconnect; |
2826 | 2904 | ||
2827 | if (!pi->sdu) | 2905 | if (!chan->sdu) |
2828 | goto disconnect; | 2906 | goto disconnect; |
2829 | 2907 | ||
2830 | pi->partial_sdu_len += skb->len; | 2908 | chan->partial_sdu_len += skb->len; |
2831 | if (pi->partial_sdu_len > pi->sdu_len) | 2909 | if (chan->partial_sdu_len > chan->sdu_len) |
2832 | goto drop; | 2910 | goto drop; |
2833 | 2911 | ||
2834 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 2912 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
2835 | 2913 | ||
2836 | break; | 2914 | break; |
2837 | 2915 | ||
2838 | case L2CAP_SDU_END: | 2916 | case L2CAP_SDU_END: |
2839 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | 2917 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) |
2840 | goto disconnect; | 2918 | goto disconnect; |
2841 | 2919 | ||
2842 | if (!pi->sdu) | 2920 | if (!chan->sdu) |
2843 | goto disconnect; | 2921 | goto disconnect; |
2844 | 2922 | ||
2845 | if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) { | 2923 | if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { |
2846 | pi->partial_sdu_len += skb->len; | 2924 | chan->partial_sdu_len += skb->len; |
2847 | 2925 | ||
2848 | if (pi->partial_sdu_len > pi->imtu) | 2926 | if (chan->partial_sdu_len > pi->imtu) |
2849 | goto drop; | 2927 | goto drop; |
2850 | 2928 | ||
2851 | if (pi->partial_sdu_len != pi->sdu_len) | 2929 | if (chan->partial_sdu_len != chan->sdu_len) |
2852 | goto drop; | 2930 | goto drop; |
2853 | 2931 | ||
2854 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 2932 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
2855 | } | 2933 | } |
2856 | 2934 | ||
2857 | _skb = skb_clone(pi->sdu, GFP_ATOMIC); | 2935 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); |
2858 | if (!_skb) { | 2936 | if (!_skb) { |
2859 | pi->conn_state |= L2CAP_CONN_SAR_RETRY; | 2937 | chan->conn_state |= L2CAP_CONN_SAR_RETRY; |
2860 | return -ENOMEM; | 2938 | return -ENOMEM; |
2861 | } | 2939 | } |
2862 | 2940 | ||
2863 | err = sock_queue_rcv_skb(sk, _skb); | 2941 | err = sock_queue_rcv_skb(chan->sk, _skb); |
2864 | if (err < 0) { | 2942 | if (err < 0) { |
2865 | kfree_skb(_skb); | 2943 | kfree_skb(_skb); |
2866 | pi->conn_state |= L2CAP_CONN_SAR_RETRY; | 2944 | chan->conn_state |= L2CAP_CONN_SAR_RETRY; |
2867 | return err; | 2945 | return err; |
2868 | } | 2946 | } |
2869 | 2947 | ||
2870 | pi->conn_state &= ~L2CAP_CONN_SAR_RETRY; | 2948 | chan->conn_state &= ~L2CAP_CONN_SAR_RETRY; |
2871 | pi->conn_state &= ~L2CAP_CONN_SAR_SDU; | 2949 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; |
2872 | 2950 | ||
2873 | kfree_skb(pi->sdu); | 2951 | kfree_skb(chan->sdu); |
2874 | break; | 2952 | break; |
2875 | } | 2953 | } |
2876 | 2954 | ||
@@ -2878,51 +2956,50 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c | |||
2878 | return 0; | 2956 | return 0; |
2879 | 2957 | ||
2880 | drop: | 2958 | drop: |
2881 | kfree_skb(pi->sdu); | 2959 | kfree_skb(chan->sdu); |
2882 | pi->sdu = NULL; | 2960 | chan->sdu = NULL; |
2883 | 2961 | ||
2884 | disconnect: | 2962 | disconnect: |
2885 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 2963 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
2886 | kfree_skb(skb); | 2964 | kfree_skb(skb); |
2887 | return 0; | 2965 | return 0; |
2888 | } | 2966 | } |
2889 | 2967 | ||
2890 | static int l2cap_try_push_rx_skb(struct sock *sk) | 2968 | static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) |
2891 | { | 2969 | { |
2892 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2893 | struct sk_buff *skb; | 2970 | struct sk_buff *skb; |
2894 | u16 control; | 2971 | u16 control; |
2895 | int err; | 2972 | int err; |
2896 | 2973 | ||
2897 | while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { | 2974 | while ((skb = skb_dequeue(&chan->busy_q))) { |
2898 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 2975 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; |
2899 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); | 2976 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); |
2900 | if (err < 0) { | 2977 | if (err < 0) { |
2901 | skb_queue_head(BUSY_QUEUE(sk), skb); | 2978 | skb_queue_head(&chan->busy_q, skb); |
2902 | return -EBUSY; | 2979 | return -EBUSY; |
2903 | } | 2980 | } |
2904 | 2981 | ||
2905 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | 2982 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
2906 | } | 2983 | } |
2907 | 2984 | ||
2908 | if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) | 2985 | if (!(chan->conn_state & L2CAP_CONN_RNR_SENT)) |
2909 | goto done; | 2986 | goto done; |
2910 | 2987 | ||
2911 | control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 2988 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
2912 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; | 2989 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; |
2913 | l2cap_send_sframe(pi, control); | 2990 | l2cap_send_sframe(chan, control); |
2914 | l2cap_pi(sk)->retry_count = 1; | 2991 | chan->retry_count = 1; |
2915 | 2992 | ||
2916 | del_timer(&pi->retrans_timer); | 2993 | del_timer(&chan->retrans_timer); |
2917 | __mod_monitor_timer(); | 2994 | __mod_monitor_timer(); |
2918 | 2995 | ||
2919 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; | 2996 | chan->conn_state |= L2CAP_CONN_WAIT_F; |
2920 | 2997 | ||
2921 | done: | 2998 | done: |
2922 | pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; | 2999 | chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; |
2923 | pi->conn_state &= ~L2CAP_CONN_RNR_SENT; | 3000 | chan->conn_state &= ~L2CAP_CONN_RNR_SENT; |
2924 | 3001 | ||
2925 | BT_DBG("sk %p, Exit local busy", sk); | 3002 | BT_DBG("chan %p, Exit local busy", chan); |
2926 | 3003 | ||
2927 | return 0; | 3004 | return 0; |
2928 | } | 3005 | } |
@@ -2930,21 +3007,21 @@ done: | |||
2930 | static void l2cap_busy_work(struct work_struct *work) | 3007 | static void l2cap_busy_work(struct work_struct *work) |
2931 | { | 3008 | { |
2932 | DECLARE_WAITQUEUE(wait, current); | 3009 | DECLARE_WAITQUEUE(wait, current); |
2933 | struct l2cap_pinfo *pi = | 3010 | struct l2cap_chan *chan = |
2934 | container_of(work, struct l2cap_pinfo, busy_work); | 3011 | container_of(work, struct l2cap_chan, busy_work); |
2935 | struct sock *sk = (struct sock *)pi; | 3012 | struct sock *sk = chan->sk; |
2936 | int n_tries = 0, timeo = HZ/5, err; | 3013 | int n_tries = 0, timeo = HZ/5, err; |
2937 | struct sk_buff *skb; | 3014 | struct sk_buff *skb; |
2938 | 3015 | ||
2939 | lock_sock(sk); | 3016 | lock_sock(sk); |
2940 | 3017 | ||
2941 | add_wait_queue(sk_sleep(sk), &wait); | 3018 | add_wait_queue(sk_sleep(sk), &wait); |
2942 | while ((skb = skb_peek(BUSY_QUEUE(sk)))) { | 3019 | while ((skb = skb_peek(&chan->busy_q))) { |
2943 | set_current_state(TASK_INTERRUPTIBLE); | 3020 | set_current_state(TASK_INTERRUPTIBLE); |
2944 | 3021 | ||
2945 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { | 3022 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { |
2946 | err = -EBUSY; | 3023 | err = -EBUSY; |
2947 | l2cap_send_disconn_req(pi->conn, sk, EBUSY); | 3024 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, EBUSY); |
2948 | break; | 3025 | break; |
2949 | } | 3026 | } |
2950 | 3027 | ||
@@ -2964,7 +3041,7 @@ static void l2cap_busy_work(struct work_struct *work) | |||
2964 | if (err) | 3041 | if (err) |
2965 | break; | 3042 | break; |
2966 | 3043 | ||
2967 | if (l2cap_try_push_rx_skb(sk) == 0) | 3044 | if (l2cap_try_push_rx_skb(chan) == 0) |
2968 | break; | 3045 | break; |
2969 | } | 3046 | } |
2970 | 3047 | ||
@@ -2974,48 +3051,47 @@ static void l2cap_busy_work(struct work_struct *work) | |||
2974 | release_sock(sk); | 3051 | release_sock(sk); |
2975 | } | 3052 | } |
2976 | 3053 | ||
2977 | static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) | 3054 | static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
2978 | { | 3055 | { |
2979 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2980 | int sctrl, err; | 3056 | int sctrl, err; |
2981 | 3057 | ||
2982 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 3058 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
2983 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3059 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
2984 | __skb_queue_tail(BUSY_QUEUE(sk), skb); | 3060 | __skb_queue_tail(&chan->busy_q, skb); |
2985 | return l2cap_try_push_rx_skb(sk); | 3061 | return l2cap_try_push_rx_skb(chan); |
2986 | 3062 | ||
2987 | 3063 | ||
2988 | } | 3064 | } |
2989 | 3065 | ||
2990 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); | 3066 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); |
2991 | if (err >= 0) { | 3067 | if (err >= 0) { |
2992 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | 3068 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
2993 | return err; | 3069 | return err; |
2994 | } | 3070 | } |
2995 | 3071 | ||
2996 | /* Busy Condition */ | 3072 | /* Busy Condition */ |
2997 | BT_DBG("sk %p, Enter local busy", sk); | 3073 | BT_DBG("chan %p, Enter local busy", chan); |
2998 | 3074 | ||
2999 | pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; | 3075 | chan->conn_state |= L2CAP_CONN_LOCAL_BUSY; |
3000 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3076 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
3001 | __skb_queue_tail(BUSY_QUEUE(sk), skb); | 3077 | __skb_queue_tail(&chan->busy_q, skb); |
3002 | 3078 | ||
3003 | sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3079 | sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
3004 | sctrl |= L2CAP_SUPER_RCV_NOT_READY; | 3080 | sctrl |= L2CAP_SUPER_RCV_NOT_READY; |
3005 | l2cap_send_sframe(pi, sctrl); | 3081 | l2cap_send_sframe(chan, sctrl); |
3006 | 3082 | ||
3007 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 3083 | chan->conn_state |= L2CAP_CONN_RNR_SENT; |
3008 | 3084 | ||
3009 | del_timer(&pi->ack_timer); | 3085 | del_timer(&chan->ack_timer); |
3010 | 3086 | ||
3011 | queue_work(_busy_wq, &pi->busy_work); | 3087 | queue_work(_busy_wq, &chan->busy_work); |
3012 | 3088 | ||
3013 | return err; | 3089 | return err; |
3014 | } | 3090 | } |
3015 | 3091 | ||
3016 | static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) | 3092 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
3017 | { | 3093 | { |
3018 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3094 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
3019 | struct sk_buff *_skb; | 3095 | struct sk_buff *_skb; |
3020 | int err = -EINVAL; | 3096 | int err = -EINVAL; |
3021 | 3097 | ||
@@ -3026,80 +3102,80 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, | |||
3026 | 3102 | ||
3027 | switch (control & L2CAP_CTRL_SAR) { | 3103 | switch (control & L2CAP_CTRL_SAR) { |
3028 | case L2CAP_SDU_UNSEGMENTED: | 3104 | case L2CAP_SDU_UNSEGMENTED: |
3029 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) { | 3105 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) { |
3030 | kfree_skb(pi->sdu); | 3106 | kfree_skb(chan->sdu); |
3031 | break; | 3107 | break; |
3032 | } | 3108 | } |
3033 | 3109 | ||
3034 | err = sock_queue_rcv_skb(sk, skb); | 3110 | err = sock_queue_rcv_skb(chan->sk, skb); |
3035 | if (!err) | 3111 | if (!err) |
3036 | return 0; | 3112 | return 0; |
3037 | 3113 | ||
3038 | break; | 3114 | break; |
3039 | 3115 | ||
3040 | case L2CAP_SDU_START: | 3116 | case L2CAP_SDU_START: |
3041 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) { | 3117 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) { |
3042 | kfree_skb(pi->sdu); | 3118 | kfree_skb(chan->sdu); |
3043 | break; | 3119 | break; |
3044 | } | 3120 | } |
3045 | 3121 | ||
3046 | pi->sdu_len = get_unaligned_le16(skb->data); | 3122 | chan->sdu_len = get_unaligned_le16(skb->data); |
3047 | skb_pull(skb, 2); | 3123 | skb_pull(skb, 2); |
3048 | 3124 | ||
3049 | if (pi->sdu_len > pi->imtu) { | 3125 | if (chan->sdu_len > pi->imtu) { |
3050 | err = -EMSGSIZE; | 3126 | err = -EMSGSIZE; |
3051 | break; | 3127 | break; |
3052 | } | 3128 | } |
3053 | 3129 | ||
3054 | pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); | 3130 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); |
3055 | if (!pi->sdu) { | 3131 | if (!chan->sdu) { |
3056 | err = -ENOMEM; | 3132 | err = -ENOMEM; |
3057 | break; | 3133 | break; |
3058 | } | 3134 | } |
3059 | 3135 | ||
3060 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 3136 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3061 | 3137 | ||
3062 | pi->conn_state |= L2CAP_CONN_SAR_SDU; | 3138 | chan->conn_state |= L2CAP_CONN_SAR_SDU; |
3063 | pi->partial_sdu_len = skb->len; | 3139 | chan->partial_sdu_len = skb->len; |
3064 | err = 0; | 3140 | err = 0; |
3065 | break; | 3141 | break; |
3066 | 3142 | ||
3067 | case L2CAP_SDU_CONTINUE: | 3143 | case L2CAP_SDU_CONTINUE: |
3068 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | 3144 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) |
3069 | break; | 3145 | break; |
3070 | 3146 | ||
3071 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 3147 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3072 | 3148 | ||
3073 | pi->partial_sdu_len += skb->len; | 3149 | chan->partial_sdu_len += skb->len; |
3074 | if (pi->partial_sdu_len > pi->sdu_len) | 3150 | if (chan->partial_sdu_len > chan->sdu_len) |
3075 | kfree_skb(pi->sdu); | 3151 | kfree_skb(chan->sdu); |
3076 | else | 3152 | else |
3077 | err = 0; | 3153 | err = 0; |
3078 | 3154 | ||
3079 | break; | 3155 | break; |
3080 | 3156 | ||
3081 | case L2CAP_SDU_END: | 3157 | case L2CAP_SDU_END: |
3082 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | 3158 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) |
3083 | break; | 3159 | break; |
3084 | 3160 | ||
3085 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | 3161 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3086 | 3162 | ||
3087 | pi->conn_state &= ~L2CAP_CONN_SAR_SDU; | 3163 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; |
3088 | pi->partial_sdu_len += skb->len; | 3164 | chan->partial_sdu_len += skb->len; |
3089 | 3165 | ||
3090 | if (pi->partial_sdu_len > pi->imtu) | 3166 | if (chan->partial_sdu_len > pi->imtu) |
3091 | goto drop; | 3167 | goto drop; |
3092 | 3168 | ||
3093 | if (pi->partial_sdu_len == pi->sdu_len) { | 3169 | if (chan->partial_sdu_len == chan->sdu_len) { |
3094 | _skb = skb_clone(pi->sdu, GFP_ATOMIC); | 3170 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); |
3095 | err = sock_queue_rcv_skb(sk, _skb); | 3171 | err = sock_queue_rcv_skb(chan->sk, _skb); |
3096 | if (err < 0) | 3172 | if (err < 0) |
3097 | kfree_skb(_skb); | 3173 | kfree_skb(_skb); |
3098 | } | 3174 | } |
3099 | err = 0; | 3175 | err = 0; |
3100 | 3176 | ||
3101 | drop: | 3177 | drop: |
3102 | kfree_skb(pi->sdu); | 3178 | kfree_skb(chan->sdu); |
3103 | break; | 3179 | break; |
3104 | } | 3180 | } |
3105 | 3181 | ||
@@ -3107,31 +3183,30 @@ drop: | |||
3107 | return err; | 3183 | return err; |
3108 | } | 3184 | } |
3109 | 3185 | ||
3110 | static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) | 3186 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) |
3111 | { | 3187 | { |
3112 | struct sk_buff *skb; | 3188 | struct sk_buff *skb; |
3113 | u16 control; | 3189 | u16 control; |
3114 | 3190 | ||
3115 | while ((skb = skb_peek(SREJ_QUEUE(sk)))) { | 3191 | while ((skb = skb_peek(&chan->srej_q))) { |
3116 | if (bt_cb(skb)->tx_seq != tx_seq) | 3192 | if (bt_cb(skb)->tx_seq != tx_seq) |
3117 | break; | 3193 | break; |
3118 | 3194 | ||
3119 | skb = skb_dequeue(SREJ_QUEUE(sk)); | 3195 | skb = skb_dequeue(&chan->srej_q); |
3120 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3196 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; |
3121 | l2cap_ertm_reassembly_sdu(sk, skb, control); | 3197 | l2cap_ertm_reassembly_sdu(chan, skb, control); |
3122 | l2cap_pi(sk)->buffer_seq_srej = | 3198 | chan->buffer_seq_srej = |
3123 | (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; | 3199 | (chan->buffer_seq_srej + 1) % 64; |
3124 | tx_seq = (tx_seq + 1) % 64; | 3200 | tx_seq = (tx_seq + 1) % 64; |
3125 | } | 3201 | } |
3126 | } | 3202 | } |
3127 | 3203 | ||
3128 | static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq) | 3204 | static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) |
3129 | { | 3205 | { |
3130 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3131 | struct srej_list *l, *tmp; | 3206 | struct srej_list *l, *tmp; |
3132 | u16 control; | 3207 | u16 control; |
3133 | 3208 | ||
3134 | list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { | 3209 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { |
3135 | if (l->tx_seq == tx_seq) { | 3210 | if (l->tx_seq == tx_seq) { |
3136 | list_del(&l->list); | 3211 | list_del(&l->list); |
3137 | kfree(l); | 3212 | kfree(l); |
@@ -3139,34 +3214,33 @@ static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq) | |||
3139 | } | 3214 | } |
3140 | control = L2CAP_SUPER_SELECT_REJECT; | 3215 | control = L2CAP_SUPER_SELECT_REJECT; |
3141 | control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3216 | control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
3142 | l2cap_send_sframe(pi, control); | 3217 | l2cap_send_sframe(chan, control); |
3143 | list_del(&l->list); | 3218 | list_del(&l->list); |
3144 | list_add_tail(&l->list, SREJ_LIST(sk)); | 3219 | list_add_tail(&l->list, &chan->srej_l); |
3145 | } | 3220 | } |
3146 | } | 3221 | } |
3147 | 3222 | ||
3148 | static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) | 3223 | static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) |
3149 | { | 3224 | { |
3150 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3151 | struct srej_list *new; | 3225 | struct srej_list *new; |
3152 | u16 control; | 3226 | u16 control; |
3153 | 3227 | ||
3154 | while (tx_seq != pi->expected_tx_seq) { | 3228 | while (tx_seq != chan->expected_tx_seq) { |
3155 | control = L2CAP_SUPER_SELECT_REJECT; | 3229 | control = L2CAP_SUPER_SELECT_REJECT; |
3156 | control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3230 | control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
3157 | l2cap_send_sframe(pi, control); | 3231 | l2cap_send_sframe(chan, control); |
3158 | 3232 | ||
3159 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); | 3233 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); |
3160 | new->tx_seq = pi->expected_tx_seq; | 3234 | new->tx_seq = chan->expected_tx_seq; |
3161 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | 3235 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; |
3162 | list_add_tail(&new->list, SREJ_LIST(sk)); | 3236 | list_add_tail(&new->list, &chan->srej_l); |
3163 | } | 3237 | } |
3164 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | 3238 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; |
3165 | } | 3239 | } |
3166 | 3240 | ||
3167 | static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) | 3241 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) |
3168 | { | 3242 | { |
3169 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3243 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
3170 | u8 tx_seq = __get_txseq(rx_control); | 3244 | u8 tx_seq = __get_txseq(rx_control); |
3171 | u8 req_seq = __get_reqseq(rx_control); | 3245 | u8 req_seq = __get_reqseq(rx_control); |
3172 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3246 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; |
@@ -3174,72 +3248,72 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3174 | int num_to_ack = (pi->tx_win/6) + 1; | 3248 | int num_to_ack = (pi->tx_win/6) + 1; |
3175 | int err = 0; | 3249 | int err = 0; |
3176 | 3250 | ||
3177 | BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq, | 3251 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, |
3178 | rx_control); | 3252 | tx_seq, rx_control); |
3179 | 3253 | ||
3180 | if (L2CAP_CTRL_FINAL & rx_control && | 3254 | if (L2CAP_CTRL_FINAL & rx_control && |
3181 | l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { | 3255 | chan->conn_state & L2CAP_CONN_WAIT_F) { |
3182 | del_timer(&pi->monitor_timer); | 3256 | del_timer(&chan->monitor_timer); |
3183 | if (pi->unacked_frames > 0) | 3257 | if (chan->unacked_frames > 0) |
3184 | __mod_retrans_timer(); | 3258 | __mod_retrans_timer(); |
3185 | pi->conn_state &= ~L2CAP_CONN_WAIT_F; | 3259 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; |
3186 | } | 3260 | } |
3187 | 3261 | ||
3188 | pi->expected_ack_seq = req_seq; | 3262 | chan->expected_ack_seq = req_seq; |
3189 | l2cap_drop_acked_frames(sk); | 3263 | l2cap_drop_acked_frames(chan); |
3190 | 3264 | ||
3191 | if (tx_seq == pi->expected_tx_seq) | 3265 | if (tx_seq == chan->expected_tx_seq) |
3192 | goto expected; | 3266 | goto expected; |
3193 | 3267 | ||
3194 | tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; | 3268 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; |
3195 | if (tx_seq_offset < 0) | 3269 | if (tx_seq_offset < 0) |
3196 | tx_seq_offset += 64; | 3270 | tx_seq_offset += 64; |
3197 | 3271 | ||
3198 | /* invalid tx_seq */ | 3272 | /* invalid tx_seq */ |
3199 | if (tx_seq_offset >= pi->tx_win) { | 3273 | if (tx_seq_offset >= pi->tx_win) { |
3200 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 3274 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
3201 | goto drop; | 3275 | goto drop; |
3202 | } | 3276 | } |
3203 | 3277 | ||
3204 | if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY) | 3278 | if (chan->conn_state == L2CAP_CONN_LOCAL_BUSY) |
3205 | goto drop; | 3279 | goto drop; |
3206 | 3280 | ||
3207 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 3281 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { |
3208 | struct srej_list *first; | 3282 | struct srej_list *first; |
3209 | 3283 | ||
3210 | first = list_first_entry(SREJ_LIST(sk), | 3284 | first = list_first_entry(&chan->srej_l, |
3211 | struct srej_list, list); | 3285 | struct srej_list, list); |
3212 | if (tx_seq == first->tx_seq) { | 3286 | if (tx_seq == first->tx_seq) { |
3213 | l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); | 3287 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); |
3214 | l2cap_check_srej_gap(sk, tx_seq); | 3288 | l2cap_check_srej_gap(chan, tx_seq); |
3215 | 3289 | ||
3216 | list_del(&first->list); | 3290 | list_del(&first->list); |
3217 | kfree(first); | 3291 | kfree(first); |
3218 | 3292 | ||
3219 | if (list_empty(SREJ_LIST(sk))) { | 3293 | if (list_empty(&chan->srej_l)) { |
3220 | pi->buffer_seq = pi->buffer_seq_srej; | 3294 | chan->buffer_seq = chan->buffer_seq_srej; |
3221 | pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; | 3295 | chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; |
3222 | l2cap_send_ack(pi); | 3296 | l2cap_send_ack(chan); |
3223 | BT_DBG("sk %p, Exit SREJ_SENT", sk); | 3297 | BT_DBG("chan %p, Exit SREJ_SENT", chan); |
3224 | } | 3298 | } |
3225 | } else { | 3299 | } else { |
3226 | struct srej_list *l; | 3300 | struct srej_list *l; |
3227 | 3301 | ||
3228 | /* duplicated tx_seq */ | 3302 | /* duplicated tx_seq */ |
3229 | if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0) | 3303 | if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) |
3230 | goto drop; | 3304 | goto drop; |
3231 | 3305 | ||
3232 | list_for_each_entry(l, SREJ_LIST(sk), list) { | 3306 | list_for_each_entry(l, &chan->srej_l, list) { |
3233 | if (l->tx_seq == tx_seq) { | 3307 | if (l->tx_seq == tx_seq) { |
3234 | l2cap_resend_srejframe(sk, tx_seq); | 3308 | l2cap_resend_srejframe(chan, tx_seq); |
3235 | return 0; | 3309 | return 0; |
3236 | } | 3310 | } |
3237 | } | 3311 | } |
3238 | l2cap_send_srejframe(sk, tx_seq); | 3312 | l2cap_send_srejframe(chan, tx_seq); |
3239 | } | 3313 | } |
3240 | } else { | 3314 | } else { |
3241 | expected_tx_seq_offset = | 3315 | expected_tx_seq_offset = |
3242 | (pi->expected_tx_seq - pi->buffer_seq) % 64; | 3316 | (chan->expected_tx_seq - chan->buffer_seq) % 64; |
3243 | if (expected_tx_seq_offset < 0) | 3317 | if (expected_tx_seq_offset < 0) |
3244 | expected_tx_seq_offset += 64; | 3318 | expected_tx_seq_offset += 64; |
3245 | 3319 | ||
@@ -3247,51 +3321,51 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3247 | if (tx_seq_offset < expected_tx_seq_offset) | 3321 | if (tx_seq_offset < expected_tx_seq_offset) |
3248 | goto drop; | 3322 | goto drop; |
3249 | 3323 | ||
3250 | pi->conn_state |= L2CAP_CONN_SREJ_SENT; | 3324 | chan->conn_state |= L2CAP_CONN_SREJ_SENT; |
3251 | 3325 | ||
3252 | BT_DBG("sk %p, Enter SREJ", sk); | 3326 | BT_DBG("chan %p, Enter SREJ", chan); |
3253 | 3327 | ||
3254 | INIT_LIST_HEAD(SREJ_LIST(sk)); | 3328 | INIT_LIST_HEAD(&chan->srej_l); |
3255 | pi->buffer_seq_srej = pi->buffer_seq; | 3329 | chan->buffer_seq_srej = chan->buffer_seq; |
3256 | 3330 | ||
3257 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 3331 | __skb_queue_head_init(&chan->srej_q); |
3258 | __skb_queue_head_init(BUSY_QUEUE(sk)); | 3332 | __skb_queue_head_init(&chan->busy_q); |
3259 | l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); | 3333 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); |
3260 | 3334 | ||
3261 | pi->conn_state |= L2CAP_CONN_SEND_PBIT; | 3335 | chan->conn_state |= L2CAP_CONN_SEND_PBIT; |
3262 | 3336 | ||
3263 | l2cap_send_srejframe(sk, tx_seq); | 3337 | l2cap_send_srejframe(chan, tx_seq); |
3264 | 3338 | ||
3265 | del_timer(&pi->ack_timer); | 3339 | del_timer(&chan->ack_timer); |
3266 | } | 3340 | } |
3267 | return 0; | 3341 | return 0; |
3268 | 3342 | ||
3269 | expected: | 3343 | expected: |
3270 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | 3344 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; |
3271 | 3345 | ||
3272 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 3346 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { |
3273 | bt_cb(skb)->tx_seq = tx_seq; | 3347 | bt_cb(skb)->tx_seq = tx_seq; |
3274 | bt_cb(skb)->sar = sar; | 3348 | bt_cb(skb)->sar = sar; |
3275 | __skb_queue_tail(SREJ_QUEUE(sk), skb); | 3349 | __skb_queue_tail(&chan->srej_q, skb); |
3276 | return 0; | 3350 | return 0; |
3277 | } | 3351 | } |
3278 | 3352 | ||
3279 | err = l2cap_push_rx_skb(sk, skb, rx_control); | 3353 | err = l2cap_push_rx_skb(chan, skb, rx_control); |
3280 | if (err < 0) | 3354 | if (err < 0) |
3281 | return 0; | 3355 | return 0; |
3282 | 3356 | ||
3283 | if (rx_control & L2CAP_CTRL_FINAL) { | 3357 | if (rx_control & L2CAP_CTRL_FINAL) { |
3284 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | 3358 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) |
3285 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | 3359 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; |
3286 | else | 3360 | else |
3287 | l2cap_retransmit_frames(sk); | 3361 | l2cap_retransmit_frames(chan); |
3288 | } | 3362 | } |
3289 | 3363 | ||
3290 | __mod_ack_timer(); | 3364 | __mod_ack_timer(); |
3291 | 3365 | ||
3292 | pi->num_acked = (pi->num_acked + 1) % num_to_ack; | 3366 | chan->num_acked = (chan->num_acked + 1) % num_to_ack; |
3293 | if (pi->num_acked == num_to_ack - 1) | 3367 | if (chan->num_acked == num_to_ack - 1) |
3294 | l2cap_send_ack(pi); | 3368 | l2cap_send_ack(chan); |
3295 | 3369 | ||
3296 | return 0; | 3370 | return 0; |
3297 | 3371 | ||
@@ -3300,165 +3374,160 @@ drop: | |||
3300 | return 0; | 3374 | return 0; |
3301 | } | 3375 | } |
3302 | 3376 | ||
3303 | static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | 3377 | static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) |
3304 | { | 3378 | { |
3305 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3379 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, __get_reqseq(rx_control), |
3306 | |||
3307 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), | ||
3308 | rx_control); | 3380 | rx_control); |
3309 | 3381 | ||
3310 | pi->expected_ack_seq = __get_reqseq(rx_control); | 3382 | chan->expected_ack_seq = __get_reqseq(rx_control); |
3311 | l2cap_drop_acked_frames(sk); | 3383 | l2cap_drop_acked_frames(chan); |
3312 | 3384 | ||
3313 | if (rx_control & L2CAP_CTRL_POLL) { | 3385 | if (rx_control & L2CAP_CTRL_POLL) { |
3314 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | 3386 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; |
3315 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 3387 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { |
3316 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 3388 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3317 | (pi->unacked_frames > 0)) | 3389 | (chan->unacked_frames > 0)) |
3318 | __mod_retrans_timer(); | 3390 | __mod_retrans_timer(); |
3319 | 3391 | ||
3320 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3392 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3321 | l2cap_send_srejtail(sk); | 3393 | l2cap_send_srejtail(chan); |
3322 | } else { | 3394 | } else { |
3323 | l2cap_send_i_or_rr_or_rnr(sk); | 3395 | l2cap_send_i_or_rr_or_rnr(chan); |
3324 | } | 3396 | } |
3325 | 3397 | ||
3326 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3398 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3327 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3399 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3328 | 3400 | ||
3329 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | 3401 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) |
3330 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | 3402 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; |
3331 | else | 3403 | else |
3332 | l2cap_retransmit_frames(sk); | 3404 | l2cap_retransmit_frames(chan); |
3333 | 3405 | ||
3334 | } else { | 3406 | } else { |
3335 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 3407 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3336 | (pi->unacked_frames > 0)) | 3408 | (chan->unacked_frames > 0)) |
3337 | __mod_retrans_timer(); | 3409 | __mod_retrans_timer(); |
3338 | 3410 | ||
3339 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3411 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3340 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) | 3412 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) |
3341 | l2cap_send_ack(pi); | 3413 | l2cap_send_ack(chan); |
3342 | else | 3414 | else |
3343 | l2cap_ertm_send(sk); | 3415 | l2cap_ertm_send(chan); |
3344 | } | 3416 | } |
3345 | } | 3417 | } |
3346 | 3418 | ||
3347 | static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control) | 3419 | static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control) |
3348 | { | 3420 | { |
3349 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3350 | u8 tx_seq = __get_reqseq(rx_control); | 3421 | u8 tx_seq = __get_reqseq(rx_control); |
3351 | 3422 | ||
3352 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | 3423 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3353 | 3424 | ||
3354 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3425 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3355 | 3426 | ||
3356 | pi->expected_ack_seq = tx_seq; | 3427 | chan->expected_ack_seq = tx_seq; |
3357 | l2cap_drop_acked_frames(sk); | 3428 | l2cap_drop_acked_frames(chan); |
3358 | 3429 | ||
3359 | if (rx_control & L2CAP_CTRL_FINAL) { | 3430 | if (rx_control & L2CAP_CTRL_FINAL) { |
3360 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | 3431 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) |
3361 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | 3432 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; |
3362 | else | 3433 | else |
3363 | l2cap_retransmit_frames(sk); | 3434 | l2cap_retransmit_frames(chan); |
3364 | } else { | 3435 | } else { |
3365 | l2cap_retransmit_frames(sk); | 3436 | l2cap_retransmit_frames(chan); |
3366 | 3437 | ||
3367 | if (pi->conn_state & L2CAP_CONN_WAIT_F) | 3438 | if (chan->conn_state & L2CAP_CONN_WAIT_F) |
3368 | pi->conn_state |= L2CAP_CONN_REJ_ACT; | 3439 | chan->conn_state |= L2CAP_CONN_REJ_ACT; |
3369 | } | 3440 | } |
3370 | } | 3441 | } |
3371 | static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) | 3442 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) |
3372 | { | 3443 | { |
3373 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3374 | u8 tx_seq = __get_reqseq(rx_control); | 3444 | u8 tx_seq = __get_reqseq(rx_control); |
3375 | 3445 | ||
3376 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | 3446 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3377 | 3447 | ||
3378 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3448 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3379 | 3449 | ||
3380 | if (rx_control & L2CAP_CTRL_POLL) { | 3450 | if (rx_control & L2CAP_CTRL_POLL) { |
3381 | pi->expected_ack_seq = tx_seq; | 3451 | chan->expected_ack_seq = tx_seq; |
3382 | l2cap_drop_acked_frames(sk); | 3452 | l2cap_drop_acked_frames(chan); |
3383 | 3453 | ||
3384 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | 3454 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; |
3385 | l2cap_retransmit_one_frame(sk, tx_seq); | 3455 | l2cap_retransmit_one_frame(chan, tx_seq); |
3386 | 3456 | ||
3387 | l2cap_ertm_send(sk); | 3457 | l2cap_ertm_send(chan); |
3388 | 3458 | ||
3389 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { | 3459 | if (chan->conn_state & L2CAP_CONN_WAIT_F) { |
3390 | pi->srej_save_reqseq = tx_seq; | 3460 | chan->srej_save_reqseq = tx_seq; |
3391 | pi->conn_state |= L2CAP_CONN_SREJ_ACT; | 3461 | chan->conn_state |= L2CAP_CONN_SREJ_ACT; |
3392 | } | 3462 | } |
3393 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3463 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3394 | if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && | 3464 | if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) && |
3395 | pi->srej_save_reqseq == tx_seq) | 3465 | chan->srej_save_reqseq == tx_seq) |
3396 | pi->conn_state &= ~L2CAP_CONN_SREJ_ACT; | 3466 | chan->conn_state &= ~L2CAP_CONN_SREJ_ACT; |
3397 | else | 3467 | else |
3398 | l2cap_retransmit_one_frame(sk, tx_seq); | 3468 | l2cap_retransmit_one_frame(chan, tx_seq); |
3399 | } else { | 3469 | } else { |
3400 | l2cap_retransmit_one_frame(sk, tx_seq); | 3470 | l2cap_retransmit_one_frame(chan, tx_seq); |
3401 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { | 3471 | if (chan->conn_state & L2CAP_CONN_WAIT_F) { |
3402 | pi->srej_save_reqseq = tx_seq; | 3472 | chan->srej_save_reqseq = tx_seq; |
3403 | pi->conn_state |= L2CAP_CONN_SREJ_ACT; | 3473 | chan->conn_state |= L2CAP_CONN_SREJ_ACT; |
3404 | } | 3474 | } |
3405 | } | 3475 | } |
3406 | } | 3476 | } |
3407 | 3477 | ||
3408 | static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) | 3478 | static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control) |
3409 | { | 3479 | { |
3410 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3411 | u8 tx_seq = __get_reqseq(rx_control); | 3480 | u8 tx_seq = __get_reqseq(rx_control); |
3412 | 3481 | ||
3413 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | 3482 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3414 | 3483 | ||
3415 | pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; | 3484 | chan->conn_state |= L2CAP_CONN_REMOTE_BUSY; |
3416 | pi->expected_ack_seq = tx_seq; | 3485 | chan->expected_ack_seq = tx_seq; |
3417 | l2cap_drop_acked_frames(sk); | 3486 | l2cap_drop_acked_frames(chan); |
3418 | 3487 | ||
3419 | if (rx_control & L2CAP_CTRL_POLL) | 3488 | if (rx_control & L2CAP_CTRL_POLL) |
3420 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | 3489 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; |
3421 | 3490 | ||
3422 | if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { | 3491 | if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) { |
3423 | del_timer(&pi->retrans_timer); | 3492 | del_timer(&chan->retrans_timer); |
3424 | if (rx_control & L2CAP_CTRL_POLL) | 3493 | if (rx_control & L2CAP_CTRL_POLL) |
3425 | l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL); | 3494 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); |
3426 | return; | 3495 | return; |
3427 | } | 3496 | } |
3428 | 3497 | ||
3429 | if (rx_control & L2CAP_CTRL_POLL) | 3498 | if (rx_control & L2CAP_CTRL_POLL) |
3430 | l2cap_send_srejtail(sk); | 3499 | l2cap_send_srejtail(chan); |
3431 | else | 3500 | else |
3432 | l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY); | 3501 | l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY); |
3433 | } | 3502 | } |
3434 | 3503 | ||
3435 | static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) | 3504 | static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) |
3436 | { | 3505 | { |
3437 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); | 3506 | BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); |
3438 | 3507 | ||
3439 | if (L2CAP_CTRL_FINAL & rx_control && | 3508 | if (L2CAP_CTRL_FINAL & rx_control && |
3440 | l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { | 3509 | chan->conn_state & L2CAP_CONN_WAIT_F) { |
3441 | del_timer(&l2cap_pi(sk)->monitor_timer); | 3510 | del_timer(&chan->monitor_timer); |
3442 | if (l2cap_pi(sk)->unacked_frames > 0) | 3511 | if (chan->unacked_frames > 0) |
3443 | __mod_retrans_timer(); | 3512 | __mod_retrans_timer(); |
3444 | l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F; | 3513 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; |
3445 | } | 3514 | } |
3446 | 3515 | ||
3447 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { | 3516 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { |
3448 | case L2CAP_SUPER_RCV_READY: | 3517 | case L2CAP_SUPER_RCV_READY: |
3449 | l2cap_data_channel_rrframe(sk, rx_control); | 3518 | l2cap_data_channel_rrframe(chan, rx_control); |
3450 | break; | 3519 | break; |
3451 | 3520 | ||
3452 | case L2CAP_SUPER_REJECT: | 3521 | case L2CAP_SUPER_REJECT: |
3453 | l2cap_data_channel_rejframe(sk, rx_control); | 3522 | l2cap_data_channel_rejframe(chan, rx_control); |
3454 | break; | 3523 | break; |
3455 | 3524 | ||
3456 | case L2CAP_SUPER_SELECT_REJECT: | 3525 | case L2CAP_SUPER_SELECT_REJECT: |
3457 | l2cap_data_channel_srejframe(sk, rx_control); | 3526 | l2cap_data_channel_srejframe(chan, rx_control); |
3458 | break; | 3527 | break; |
3459 | 3528 | ||
3460 | case L2CAP_SUPER_RCV_NOT_READY: | 3529 | case L2CAP_SUPER_RCV_NOT_READY: |
3461 | l2cap_data_channel_rnrframe(sk, rx_control); | 3530 | l2cap_data_channel_rnrframe(chan, rx_control); |
3462 | break; | 3531 | break; |
3463 | } | 3532 | } |
3464 | 3533 | ||
@@ -3468,6 +3537,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3468 | 3537 | ||
3469 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | 3538 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) |
3470 | { | 3539 | { |
3540 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
3471 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3541 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3472 | u16 control; | 3542 | u16 control; |
3473 | u8 req_seq; | 3543 | u8 req_seq; |
@@ -3492,41 +3562,41 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3492 | len -= 2; | 3562 | len -= 2; |
3493 | 3563 | ||
3494 | if (len > pi->mps) { | 3564 | if (len > pi->mps) { |
3495 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 3565 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
3496 | goto drop; | 3566 | goto drop; |
3497 | } | 3567 | } |
3498 | 3568 | ||
3499 | req_seq = __get_reqseq(control); | 3569 | req_seq = __get_reqseq(control); |
3500 | req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; | 3570 | req_seq_offset = (req_seq - chan->expected_ack_seq) % 64; |
3501 | if (req_seq_offset < 0) | 3571 | if (req_seq_offset < 0) |
3502 | req_seq_offset += 64; | 3572 | req_seq_offset += 64; |
3503 | 3573 | ||
3504 | next_tx_seq_offset = | 3574 | next_tx_seq_offset = |
3505 | (pi->next_tx_seq - pi->expected_ack_seq) % 64; | 3575 | (chan->next_tx_seq - chan->expected_ack_seq) % 64; |
3506 | if (next_tx_seq_offset < 0) | 3576 | if (next_tx_seq_offset < 0) |
3507 | next_tx_seq_offset += 64; | 3577 | next_tx_seq_offset += 64; |
3508 | 3578 | ||
3509 | /* check for invalid req-seq */ | 3579 | /* check for invalid req-seq */ |
3510 | if (req_seq_offset > next_tx_seq_offset) { | 3580 | if (req_seq_offset > next_tx_seq_offset) { |
3511 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 3581 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
3512 | goto drop; | 3582 | goto drop; |
3513 | } | 3583 | } |
3514 | 3584 | ||
3515 | if (__is_iframe(control)) { | 3585 | if (__is_iframe(control)) { |
3516 | if (len < 0) { | 3586 | if (len < 0) { |
3517 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 3587 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
3518 | goto drop; | 3588 | goto drop; |
3519 | } | 3589 | } |
3520 | 3590 | ||
3521 | l2cap_data_channel_iframe(sk, control, skb); | 3591 | l2cap_data_channel_iframe(chan, control, skb); |
3522 | } else { | 3592 | } else { |
3523 | if (len != 0) { | 3593 | if (len != 0) { |
3524 | BT_ERR("%d", len); | 3594 | BT_ERR("%d", len); |
3525 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | 3595 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); |
3526 | goto drop; | 3596 | goto drop; |
3527 | } | 3597 | } |
3528 | 3598 | ||
3529 | l2cap_data_channel_sframe(sk, control, skb); | 3599 | l2cap_data_channel_sframe(chan, control, skb); |
3530 | } | 3600 | } |
3531 | 3601 | ||
3532 | return 0; | 3602 | return 0; |
@@ -3538,21 +3608,23 @@ drop: | |||
3538 | 3608 | ||
3539 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) | 3609 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) |
3540 | { | 3610 | { |
3611 | struct l2cap_chan *chan; | ||
3541 | struct sock *sk; | 3612 | struct sock *sk; |
3542 | struct l2cap_pinfo *pi; | 3613 | struct l2cap_pinfo *pi; |
3543 | u16 control; | 3614 | u16 control; |
3544 | u8 tx_seq; | 3615 | u8 tx_seq; |
3545 | int len; | 3616 | int len; |
3546 | 3617 | ||
3547 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | 3618 | chan = l2cap_get_chan_by_scid(conn, cid); |
3548 | if (!sk) { | 3619 | if (!chan) { |
3549 | BT_DBG("unknown cid 0x%4.4x", cid); | 3620 | BT_DBG("unknown cid 0x%4.4x", cid); |
3550 | goto drop; | 3621 | goto drop; |
3551 | } | 3622 | } |
3552 | 3623 | ||
3624 | sk = chan->sk; | ||
3553 | pi = l2cap_pi(sk); | 3625 | pi = l2cap_pi(sk); |
3554 | 3626 | ||
3555 | BT_DBG("sk %p, len %d", sk, skb->len); | 3627 | BT_DBG("chan %p, len %d", chan, skb->len); |
3556 | 3628 | ||
3557 | if (sk->sk_state != BT_CONNECTED) | 3629 | if (sk->sk_state != BT_CONNECTED) |
3558 | goto drop; | 3630 | goto drop; |
@@ -3600,17 +3672,17 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3600 | 3672 | ||
3601 | tx_seq = __get_txseq(control); | 3673 | tx_seq = __get_txseq(control); |
3602 | 3674 | ||
3603 | if (pi->expected_tx_seq == tx_seq) | 3675 | if (chan->expected_tx_seq == tx_seq) |
3604 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | 3676 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; |
3605 | else | 3677 | else |
3606 | pi->expected_tx_seq = (tx_seq + 1) % 64; | 3678 | chan->expected_tx_seq = (tx_seq + 1) % 64; |
3607 | 3679 | ||
3608 | l2cap_streaming_reassembly_sdu(sk, skb, control); | 3680 | l2cap_streaming_reassembly_sdu(chan, skb, control); |
3609 | 3681 | ||
3610 | goto done; | 3682 | goto done; |
3611 | 3683 | ||
3612 | default: | 3684 | default: |
3613 | BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode); | 3685 | BT_DBG("chan %p: bad mode 0x%2.2x", chan, pi->mode); |
3614 | break; | 3686 | break; |
3615 | } | 3687 | } |
3616 | 3688 | ||
@@ -3654,6 +3726,36 @@ done: | |||
3654 | return 0; | 3726 | return 0; |
3655 | } | 3727 | } |
3656 | 3728 | ||
3729 | static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) | ||
3730 | { | ||
3731 | struct sock *sk; | ||
3732 | |||
3733 | sk = l2cap_get_sock_by_scid(0, cid, conn->src); | ||
3734 | if (!sk) | ||
3735 | goto drop; | ||
3736 | |||
3737 | bh_lock_sock(sk); | ||
3738 | |||
3739 | BT_DBG("sk %p, len %d", sk, skb->len); | ||
3740 | |||
3741 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) | ||
3742 | goto drop; | ||
3743 | |||
3744 | if (l2cap_pi(sk)->imtu < skb->len) | ||
3745 | goto drop; | ||
3746 | |||
3747 | if (!sock_queue_rcv_skb(sk, skb)) | ||
3748 | goto done; | ||
3749 | |||
3750 | drop: | ||
3751 | kfree_skb(skb); | ||
3752 | |||
3753 | done: | ||
3754 | if (sk) | ||
3755 | bh_unlock_sock(sk); | ||
3756 | return 0; | ||
3757 | } | ||
3758 | |||
3657 | static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | 3759 | static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) |
3658 | { | 3760 | { |
3659 | struct l2cap_hdr *lh = (void *) skb->data; | 3761 | struct l2cap_hdr *lh = (void *) skb->data; |
@@ -3683,6 +3785,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
3683 | l2cap_conless_channel(conn, psm, skb); | 3785 | l2cap_conless_channel(conn, psm, skb); |
3684 | break; | 3786 | break; |
3685 | 3787 | ||
3788 | case L2CAP_CID_LE_DATA: | ||
3789 | l2cap_att_channel(conn, cid, skb); | ||
3790 | break; | ||
3791 | |||
3686 | default: | 3792 | default: |
3687 | l2cap_data_channel(conn, cid, skb); | 3793 | l2cap_data_channel(conn, cid, skb); |
3688 | break; | 3794 | break; |
@@ -3786,20 +3892,19 @@ static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) | |||
3786 | 3892 | ||
3787 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | 3893 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) |
3788 | { | 3894 | { |
3789 | struct l2cap_chan_list *l; | ||
3790 | struct l2cap_conn *conn = hcon->l2cap_data; | 3895 | struct l2cap_conn *conn = hcon->l2cap_data; |
3791 | struct sock *sk; | 3896 | struct l2cap_chan *chan; |
3792 | 3897 | ||
3793 | if (!conn) | 3898 | if (!conn) |
3794 | return 0; | 3899 | return 0; |
3795 | 3900 | ||
3796 | l = &conn->chan_list; | ||
3797 | |||
3798 | BT_DBG("conn %p", conn); | 3901 | BT_DBG("conn %p", conn); |
3799 | 3902 | ||
3800 | read_lock(&l->lock); | 3903 | read_lock(&conn->chan_lock); |
3904 | |||
3905 | list_for_each_entry(chan, &conn->chan_l, list) { | ||
3906 | struct sock *sk = chan->sk; | ||
3801 | 3907 | ||
3802 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | ||
3803 | bh_lock_sock(sk); | 3908 | bh_lock_sock(sk); |
3804 | 3909 | ||
3805 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { | 3910 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { |
@@ -3820,10 +3925,10 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3820 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 3925 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
3821 | req.psm = l2cap_pi(sk)->psm; | 3926 | req.psm = l2cap_pi(sk)->psm; |
3822 | 3927 | ||
3823 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 3928 | chan->ident = l2cap_get_ident(conn); |
3824 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 3929 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; |
3825 | 3930 | ||
3826 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 3931 | l2cap_send_cmd(conn, chan->ident, |
3827 | L2CAP_CONN_REQ, sizeof(req), &req); | 3932 | L2CAP_CONN_REQ, sizeof(req), &req); |
3828 | } else { | 3933 | } else { |
3829 | l2cap_sock_clear_timer(sk); | 3934 | l2cap_sock_clear_timer(sk); |
@@ -3846,14 +3951,14 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3846 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 3951 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
3847 | rsp.result = cpu_to_le16(result); | 3952 | rsp.result = cpu_to_le16(result); |
3848 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 3953 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
3849 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 3954 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
3850 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 3955 | sizeof(rsp), &rsp); |
3851 | } | 3956 | } |
3852 | 3957 | ||
3853 | bh_unlock_sock(sk); | 3958 | bh_unlock_sock(sk); |
3854 | } | 3959 | } |
3855 | 3960 | ||
3856 | read_unlock(&l->lock); | 3961 | read_unlock(&conn->chan_lock); |
3857 | 3962 | ||
3858 | return 0; | 3963 | return 0; |
3859 | } | 3964 | } |
@@ -3872,7 +3977,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
3872 | 3977 | ||
3873 | if (!(flags & ACL_CONT)) { | 3978 | if (!(flags & ACL_CONT)) { |
3874 | struct l2cap_hdr *hdr; | 3979 | struct l2cap_hdr *hdr; |
3875 | struct sock *sk; | 3980 | struct l2cap_chan *chan; |
3876 | u16 cid; | 3981 | u16 cid; |
3877 | int len; | 3982 | int len; |
3878 | 3983 | ||
@@ -3910,18 +4015,21 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
3910 | goto drop; | 4015 | goto drop; |
3911 | } | 4016 | } |
3912 | 4017 | ||
3913 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | 4018 | chan = l2cap_get_chan_by_scid(conn, cid); |
3914 | 4019 | ||
3915 | if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { | 4020 | if (chan && chan->sk) { |
3916 | BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", | 4021 | struct sock *sk = chan->sk; |
3917 | len, l2cap_pi(sk)->imtu); | ||
3918 | bh_unlock_sock(sk); | ||
3919 | l2cap_conn_unreliable(conn, ECOMM); | ||
3920 | goto drop; | ||
3921 | } | ||
3922 | 4022 | ||
3923 | if (sk) | 4023 | if (l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { |
4024 | BT_ERR("Frame exceeding recv MTU (len %d, " | ||
4025 | "MTU %d)", len, | ||
4026 | l2cap_pi(sk)->imtu); | ||
4027 | bh_unlock_sock(sk); | ||
4028 | l2cap_conn_unreliable(conn, ECOMM); | ||
4029 | goto drop; | ||
4030 | } | ||
3924 | bh_unlock_sock(sk); | 4031 | bh_unlock_sock(sk); |
4032 | } | ||
3925 | 4033 | ||
3926 | /* Allocate skb for the complete frame (with header) */ | 4034 | /* Allocate skb for the complete frame (with header) */ |
3927 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); | 4035 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 299fe56a9668..47394a178bd5 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -269,7 +269,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
269 | goto done; | 269 | goto done; |
270 | } | 270 | } |
271 | 271 | ||
272 | if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) { | 272 | if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->scid) { |
273 | bdaddr_t *src = &bt_sk(sk)->src; | 273 | bdaddr_t *src = &bt_sk(sk)->src; |
274 | u16 psm; | 274 | u16 psm; |
275 | 275 | ||
@@ -757,35 +757,37 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
757 | case L2CAP_MODE_ERTM: | 757 | case L2CAP_MODE_ERTM: |
758 | case L2CAP_MODE_STREAMING: | 758 | case L2CAP_MODE_STREAMING: |
759 | /* Entire SDU fits into one PDU */ | 759 | /* Entire SDU fits into one PDU */ |
760 | if (len <= pi->remote_mps) { | 760 | if (len <= pi->chan->remote_mps) { |
761 | control = L2CAP_SDU_UNSEGMENTED; | 761 | control = L2CAP_SDU_UNSEGMENTED; |
762 | skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); | 762 | skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); |
763 | if (IS_ERR(skb)) { | 763 | if (IS_ERR(skb)) { |
764 | err = PTR_ERR(skb); | 764 | err = PTR_ERR(skb); |
765 | goto done; | 765 | goto done; |
766 | } | 766 | } |
767 | __skb_queue_tail(TX_QUEUE(sk), skb); | 767 | __skb_queue_tail(&pi->chan->tx_q, skb); |
768 | 768 | ||
769 | if (sk->sk_send_head == NULL) | 769 | if (pi->chan->tx_send_head == NULL) |
770 | sk->sk_send_head = skb; | 770 | pi->chan->tx_send_head = skb; |
771 | 771 | ||
772 | } else { | 772 | } else { |
773 | /* Segment SDU into multiples PDUs */ | 773 | /* Segment SDU into multiples PDUs */ |
774 | err = l2cap_sar_segment_sdu(sk, msg, len); | 774 | err = l2cap_sar_segment_sdu(pi->chan, msg, len); |
775 | if (err < 0) | 775 | if (err < 0) |
776 | goto done; | 776 | goto done; |
777 | } | 777 | } |
778 | 778 | ||
779 | if (pi->mode == L2CAP_MODE_STREAMING) { | 779 | if (pi->mode == L2CAP_MODE_STREAMING) { |
780 | l2cap_streaming_send(sk); | 780 | l2cap_streaming_send(pi->chan); |
781 | } else { | 781 | err = len; |
782 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 782 | break; |
783 | (pi->conn_state & L2CAP_CONN_WAIT_F)) { | 783 | } |
784 | err = len; | 784 | |
785 | break; | 785 | if ((pi->chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
786 | } | 786 | (pi->chan->conn_state & L2CAP_CONN_WAIT_F)) { |
787 | err = l2cap_ertm_send(sk); | 787 | err = len; |
788 | break; | ||
788 | } | 789 | } |
790 | err = l2cap_ertm_send(pi->chan); | ||
789 | 791 | ||
790 | if (err >= 0) | 792 | if (err >= 0) |
791 | err = len; | 793 | err = len; |
@@ -808,29 +810,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
808 | lock_sock(sk); | 810 | lock_sock(sk); |
809 | 811 | ||
810 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 812 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { |
811 | struct l2cap_conn_rsp rsp; | 813 | __l2cap_connect_rsp_defer(sk); |
812 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
813 | u8 buf[128]; | ||
814 | |||
815 | sk->sk_state = BT_CONFIG; | ||
816 | |||
817 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
818 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
819 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | ||
820 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
821 | l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, | ||
822 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
823 | |||
824 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { | ||
825 | release_sock(sk); | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
830 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
831 | l2cap_build_conf_req(sk, buf), buf); | ||
832 | l2cap_pi(sk)->num_conf_req++; | ||
833 | |||
834 | release_sock(sk); | 814 | release_sock(sk); |
835 | return 0; | 815 | return 0; |
836 | } | 816 | } |
@@ -886,6 +866,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) | |||
886 | void __l2cap_sock_close(struct sock *sk, int reason) | 866 | void __l2cap_sock_close(struct sock *sk, int reason) |
887 | { | 867 | { |
888 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 868 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
869 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
889 | 870 | ||
890 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | 871 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); |
891 | 872 | ||
@@ -900,9 +881,9 @@ void __l2cap_sock_close(struct sock *sk, int reason) | |||
900 | sk->sk_type == SOCK_STREAM) && | 881 | sk->sk_type == SOCK_STREAM) && |
901 | conn->hcon->type == ACL_LINK) { | 882 | conn->hcon->type == ACL_LINK) { |
902 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 883 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
903 | l2cap_send_disconn_req(conn, sk, reason); | 884 | l2cap_send_disconn_req(conn, chan, reason); |
904 | } else | 885 | } else |
905 | l2cap_chan_del(sk, reason); | 886 | l2cap_chan_del(chan, reason); |
906 | break; | 887 | break; |
907 | 888 | ||
908 | case BT_CONNECT2: | 889 | case BT_CONNECT2: |
@@ -921,16 +902,16 @@ void __l2cap_sock_close(struct sock *sk, int reason) | |||
921 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 902 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
922 | rsp.result = cpu_to_le16(result); | 903 | rsp.result = cpu_to_le16(result); |
923 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 904 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
924 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 905 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
925 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 906 | sizeof(rsp), &rsp); |
926 | } | 907 | } |
927 | 908 | ||
928 | l2cap_chan_del(sk, reason); | 909 | l2cap_chan_del(chan, reason); |
929 | break; | 910 | break; |
930 | 911 | ||
931 | case BT_CONNECT: | 912 | case BT_CONNECT: |
932 | case BT_DISCONN: | 913 | case BT_DISCONN: |
933 | l2cap_chan_del(sk, reason); | 914 | l2cap_chan_del(chan, reason); |
934 | break; | 915 | break; |
935 | 916 | ||
936 | default: | 917 | default: |
@@ -1035,12 +1016,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
1035 | } | 1016 | } |
1036 | 1017 | ||
1037 | /* Default config options */ | 1018 | /* Default config options */ |
1038 | pi->conf_len = 0; | ||
1039 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 1019 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
1040 | skb_queue_head_init(TX_QUEUE(sk)); | ||
1041 | skb_queue_head_init(SREJ_QUEUE(sk)); | ||
1042 | skb_queue_head_init(BUSY_QUEUE(sk)); | ||
1043 | INIT_LIST_HEAD(SREJ_LIST(sk)); | ||
1044 | } | 1020 | } |
1045 | 1021 | ||
1046 | static struct proto l2cap_proto = { | 1022 | static struct proto l2cap_proto = { |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bf5d28da46e6..a6d191f2a0fe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -330,6 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in | |||
330 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 330 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) |
331 | { | 331 | { |
332 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 332 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
333 | struct timespec uptime; | ||
333 | 334 | ||
334 | sinfo->generation = sdata->local->sta_generation; | 335 | sinfo->generation = sdata->local->sta_generation; |
335 | 336 | ||
@@ -343,7 +344,11 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
343 | STATION_INFO_TX_BITRATE | | 344 | STATION_INFO_TX_BITRATE | |
344 | STATION_INFO_RX_BITRATE | | 345 | STATION_INFO_RX_BITRATE | |
345 | STATION_INFO_RX_DROP_MISC | | 346 | STATION_INFO_RX_DROP_MISC | |
346 | STATION_INFO_BSS_PARAM; | 347 | STATION_INFO_BSS_PARAM | |
348 | STATION_INFO_CONNECTED_TIME; | ||
349 | |||
350 | do_posix_clock_monotonic_gettime(&uptime); | ||
351 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | ||
347 | 352 | ||
348 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 353 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
349 | sinfo->rx_bytes = sta->rx_bytes; | 354 | sinfo->rx_bytes = sta->rx_bytes; |
@@ -686,6 +691,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
686 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 691 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
687 | sta->flags |= WLAN_STA_MFP; | 692 | sta->flags |= WLAN_STA_MFP; |
688 | } | 693 | } |
694 | |||
695 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | ||
696 | sta->flags &= ~WLAN_STA_AUTH; | ||
697 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) | ||
698 | sta->flags |= WLAN_STA_AUTH; | ||
699 | } | ||
689 | spin_unlock_irqrestore(&sta->flaglock, flags); | 700 | spin_unlock_irqrestore(&sta->flaglock, flags); |
690 | 701 | ||
691 | /* | 702 | /* |
@@ -1034,26 +1045,26 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, | |||
1034 | u8 *new_ie; | 1045 | u8 *new_ie; |
1035 | const u8 *old_ie; | 1046 | const u8 *old_ie; |
1036 | 1047 | ||
1037 | /* first allocate the new vendor information element */ | 1048 | /* allocate information elements */ |
1038 | new_ie = NULL; | 1049 | new_ie = NULL; |
1039 | old_ie = ifmsh->vendor_ie; | 1050 | old_ie = ifmsh->ie; |
1040 | 1051 | ||
1041 | ifmsh->vendor_ie_len = setup->vendor_ie_len; | 1052 | if (setup->ie_len) { |
1042 | if (setup->vendor_ie_len) { | 1053 | new_ie = kmemdup(setup->ie, setup->ie_len, |
1043 | new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len, | ||
1044 | GFP_KERNEL); | 1054 | GFP_KERNEL); |
1045 | if (!new_ie) | 1055 | if (!new_ie) |
1046 | return -ENOMEM; | 1056 | return -ENOMEM; |
1047 | } | 1057 | } |
1058 | ifmsh->ie_len = setup->ie_len; | ||
1059 | ifmsh->ie = new_ie; | ||
1060 | kfree(old_ie); | ||
1048 | 1061 | ||
1049 | /* now copy the rest of the setup parameters */ | 1062 | /* now copy the rest of the setup parameters */ |
1050 | ifmsh->mesh_id_len = setup->mesh_id_len; | 1063 | ifmsh->mesh_id_len = setup->mesh_id_len; |
1051 | memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); | 1064 | memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); |
1052 | ifmsh->mesh_pp_id = setup->path_sel_proto; | 1065 | ifmsh->mesh_pp_id = setup->path_sel_proto; |
1053 | ifmsh->mesh_pm_id = setup->path_metric; | 1066 | ifmsh->mesh_pm_id = setup->path_metric; |
1054 | ifmsh->vendor_ie = new_ie; | 1067 | ifmsh->is_secure = setup->is_secure; |
1055 | |||
1056 | kfree(old_ie); | ||
1057 | 1068 | ||
1058 | return 0; | 1069 | return 0; |
1059 | } | 1070 | } |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c04a1396cf8d..a01d2137fddc 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, | |||
92 | } | 92 | } |
93 | STA_OPS(inactive_ms); | 93 | STA_OPS(inactive_ms); |
94 | 94 | ||
95 | |||
96 | static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf, | ||
97 | size_t count, loff_t *ppos) | ||
98 | { | ||
99 | struct sta_info *sta = file->private_data; | ||
100 | struct timespec uptime; | ||
101 | struct tm result; | ||
102 | long connected_time_secs; | ||
103 | char buf[100]; | ||
104 | int res; | ||
105 | do_posix_clock_monotonic_gettime(&uptime); | ||
106 | connected_time_secs = uptime.tv_sec - sta->last_connected; | ||
107 | time_to_tm(connected_time_secs, 0, &result); | ||
108 | result.tm_year -= 70; | ||
109 | result.tm_mday -= 1; | ||
110 | res = scnprintf(buf, sizeof(buf), | ||
111 | "years - %ld\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n", | ||
112 | result.tm_year, result.tm_mon, result.tm_mday, | ||
113 | result.tm_hour, result.tm_min, result.tm_sec); | ||
114 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
115 | } | ||
116 | STA_OPS(connected_time); | ||
117 | |||
118 | |||
119 | |||
95 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, | 120 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, |
96 | size_t count, loff_t *ppos) | 121 | size_t count, loff_t *ppos) |
97 | { | 122 | { |
@@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
324 | DEBUGFS_ADD(flags); | 349 | DEBUGFS_ADD(flags); |
325 | DEBUGFS_ADD(num_ps_buf_frames); | 350 | DEBUGFS_ADD(num_ps_buf_frames); |
326 | DEBUGFS_ADD(inactive_ms); | 351 | DEBUGFS_ADD(inactive_ms); |
352 | DEBUGFS_ADD(connected_time); | ||
327 | DEBUGFS_ADD(last_seq_ctrl); | 353 | DEBUGFS_ADD(last_seq_ctrl); |
328 | DEBUGFS_ADD(agg_status); | 354 | DEBUGFS_ADD(agg_status); |
329 | DEBUGFS_ADD(dev); | 355 | DEBUGFS_ADD(dev); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 9c0d62bb0ea3..00a0685f2403 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -552,4 +552,17 @@ static inline void drv_get_ringparam(struct ieee80211_local *local, | |||
552 | trace_drv_return_void(local); | 552 | trace_drv_return_void(local); |
553 | } | 553 | } |
554 | 554 | ||
555 | static inline bool drv_tx_frames_pending(struct ieee80211_local *local) | ||
556 | { | ||
557 | bool ret = false; | ||
558 | |||
559 | might_sleep(); | ||
560 | |||
561 | trace_drv_tx_frames_pending(local); | ||
562 | if (local->ops->tx_frames_pending) | ||
563 | ret = local->ops->tx_frames_pending(&local->hw); | ||
564 | trace_drv_return_bool(local, ret); | ||
565 | |||
566 | return ret; | ||
567 | } | ||
555 | #endif /* __MAC80211_DRIVER_OPS */ | 568 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 45aab80738e2..c8c934d48b7a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -74,6 +74,21 @@ TRACE_EVENT(drv_return_int, | |||
74 | TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) | 74 | TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) |
75 | ); | 75 | ); |
76 | 76 | ||
77 | TRACE_EVENT(drv_return_bool, | ||
78 | TP_PROTO(struct ieee80211_local *local, bool ret), | ||
79 | TP_ARGS(local, ret), | ||
80 | TP_STRUCT__entry( | ||
81 | LOCAL_ENTRY | ||
82 | __field(bool, ret) | ||
83 | ), | ||
84 | TP_fast_assign( | ||
85 | LOCAL_ASSIGN; | ||
86 | __entry->ret = ret; | ||
87 | ), | ||
88 | TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ? | ||
89 | "true" : "false") | ||
90 | ); | ||
91 | |||
77 | TRACE_EVENT(drv_return_u64, | 92 | TRACE_EVENT(drv_return_u64, |
78 | TP_PROTO(struct ieee80211_local *local, u64 ret), | 93 | TP_PROTO(struct ieee80211_local *local, u64 ret), |
79 | TP_ARGS(local, ret), | 94 | TP_ARGS(local, ret), |
@@ -964,6 +979,11 @@ TRACE_EVENT(drv_get_ringparam, | |||
964 | ) | 979 | ) |
965 | ); | 980 | ); |
966 | 981 | ||
982 | DEFINE_EVENT(local_only_evt, drv_tx_frames_pending, | ||
983 | TP_PROTO(struct ieee80211_local *local), | ||
984 | TP_ARGS(local) | ||
985 | ); | ||
986 | |||
967 | DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, | 987 | DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, |
968 | TP_PROTO(struct ieee80211_local *local), | 988 | TP_PROTO(struct ieee80211_local *local), |
969 | TP_ARGS(local) | 989 | TP_ARGS(local) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 89ce1e329b5d..a77849970914 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -488,8 +488,9 @@ struct ieee80211_if_mesh { | |||
488 | struct mesh_config mshcfg; | 488 | struct mesh_config mshcfg; |
489 | u32 mesh_seqnum; | 489 | u32 mesh_seqnum; |
490 | bool accepting_plinks; | 490 | bool accepting_plinks; |
491 | const u8 *vendor_ie; | 491 | const u8 *ie; |
492 | u8 vendor_ie_len; | 492 | u8 ie_len; |
493 | bool is_secure; | ||
493 | }; | 494 | }; |
494 | 495 | ||
495 | #ifdef CONFIG_MAC80211_MESH | 496 | #ifdef CONFIG_MAC80211_MESH |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index dc50fc3153e5..0ab2a8df312d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -545,7 +545,9 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | |||
545 | }, | 545 | }, |
546 | [NL80211_IFTYPE_MESH_POINT] = { | 546 | [NL80211_IFTYPE_MESH_POINT] = { |
547 | .tx = 0xffff, | 547 | .tx = 0xffff, |
548 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4), | 548 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | |
549 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
550 | BIT(IEEE80211_STYPE_DEAUTH >> 4), | ||
549 | }, | 551 | }, |
550 | }; | 552 | }; |
551 | 553 | ||
@@ -760,6 +762,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
760 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | 762 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); |
761 | #endif | 763 | #endif |
762 | 764 | ||
765 | /* if the underlying driver supports mesh, mac80211 will (at least) | ||
766 | * provide routing of mesh authentication frames to userspace */ | ||
767 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) | ||
768 | local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH; | ||
769 | |||
763 | /* mac80211 supports control port protocol changing */ | 770 | /* mac80211 supports control port protocol changing */ |
764 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | 771 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; |
765 | 772 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2a57cc02c618..11207979e2e2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -279,9 +279,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
279 | MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; | 279 | MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; |
280 | *pos++ = 0x00; | 280 | *pos++ = 0x00; |
281 | 281 | ||
282 | if (sdata->u.mesh.vendor_ie) { | 282 | if (sdata->u.mesh.ie) { |
283 | int len = sdata->u.mesh.vendor_ie_len; | 283 | int len = sdata->u.mesh.ie_len; |
284 | const u8 *data = sdata->u.mesh.vendor_ie; | 284 | const u8 *data = sdata->u.mesh.ie; |
285 | if (skb_tailroom(skb) > len) | 285 | if (skb_tailroom(skb) > len) |
286 | memcpy(skb_put(skb, len), data, len); | 286 | memcpy(skb_put(skb, len), data, len); |
287 | } | 287 | } |
@@ -573,6 +573,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
573 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 573 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
574 | &elems); | 574 | &elems); |
575 | 575 | ||
576 | /* ignore beacons from secure mesh peers if our security is off */ | ||
577 | if (elems.rsn_len && !sdata->u.mesh.is_secure) | ||
578 | return; | ||
579 | |||
576 | if (elems.ds_params && elems.ds_params_len == 1) | 580 | if (elems.ds_params && elems.ds_params_len == 1) |
577 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); | 581 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); |
578 | else | 582 | else |
@@ -586,9 +590,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
586 | if (elems.mesh_id && elems.mesh_config && | 590 | if (elems.mesh_id && elems.mesh_config && |
587 | mesh_matches_local(&elems, sdata)) { | 591 | mesh_matches_local(&elems, sdata)) { |
588 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); | 592 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); |
589 | 593 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems); | |
590 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, | ||
591 | mesh_peer_accepts_plinks(&elems)); | ||
592 | } | 594 | } |
593 | } | 595 | } |
594 | 596 | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index b99e230fe31c..10acf1cc8082 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -226,7 +226,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | |||
226 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); | 226 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); |
227 | /* Mesh plinks */ | 227 | /* Mesh plinks */ |
228 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, | 228 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, |
229 | struct ieee80211_sub_if_data *sdata, bool add); | 229 | struct ieee80211_sub_if_data *sdata, |
230 | struct ieee802_11_elems *ie); | ||
230 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); | 231 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); |
231 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); | 232 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); |
232 | void mesh_plink_broken(struct sta_info *sta); | 233 | void mesh_plink_broken(struct sta_info *sta); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 336ca9d0c5c4..35c715adaae2 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -65,42 +65,37 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
65 | __mesh_table_free(tbl); | 65 | __mesh_table_free(tbl); |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | 68 | static int mesh_table_grow(struct mesh_table *oldtbl, |
69 | struct mesh_table *newtbl) | ||
69 | { | 70 | { |
70 | struct mesh_table *newtbl; | ||
71 | struct hlist_head *oldhash; | 71 | struct hlist_head *oldhash; |
72 | struct hlist_node *p, *q; | 72 | struct hlist_node *p, *q; |
73 | int i; | 73 | int i; |
74 | 74 | ||
75 | if (atomic_read(&tbl->entries) | 75 | if (atomic_read(&oldtbl->entries) |
76 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) | 76 | < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) |
77 | goto endgrow; | 77 | return -EAGAIN; |
78 | 78 | ||
79 | newtbl = mesh_table_alloc(tbl->size_order + 1); | ||
80 | if (!newtbl) | ||
81 | goto endgrow; | ||
82 | 79 | ||
83 | newtbl->free_node = tbl->free_node; | 80 | newtbl->free_node = oldtbl->free_node; |
84 | newtbl->mean_chain_len = tbl->mean_chain_len; | 81 | newtbl->mean_chain_len = oldtbl->mean_chain_len; |
85 | newtbl->copy_node = tbl->copy_node; | 82 | newtbl->copy_node = oldtbl->copy_node; |
86 | atomic_set(&newtbl->entries, atomic_read(&tbl->entries)); | 83 | atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries)); |
87 | 84 | ||
88 | oldhash = tbl->hash_buckets; | 85 | oldhash = oldtbl->hash_buckets; |
89 | for (i = 0; i <= tbl->hash_mask; i++) | 86 | for (i = 0; i <= oldtbl->hash_mask; i++) |
90 | hlist_for_each(p, &oldhash[i]) | 87 | hlist_for_each(p, &oldhash[i]) |
91 | if (tbl->copy_node(p, newtbl) < 0) | 88 | if (oldtbl->copy_node(p, newtbl) < 0) |
92 | goto errcopy; | 89 | goto errcopy; |
93 | 90 | ||
94 | return newtbl; | 91 | return 0; |
95 | 92 | ||
96 | errcopy: | 93 | errcopy: |
97 | for (i = 0; i <= newtbl->hash_mask; i++) { | 94 | for (i = 0; i <= newtbl->hash_mask; i++) { |
98 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | 95 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) |
99 | tbl->free_node(p, 0); | 96 | oldtbl->free_node(p, 0); |
100 | } | 97 | } |
101 | __mesh_table_free(newtbl); | 98 | return -ENOMEM; |
102 | endgrow: | ||
103 | return NULL; | ||
104 | } | 99 | } |
105 | 100 | ||
106 | 101 | ||
@@ -334,10 +329,13 @@ void mesh_mpath_table_grow(void) | |||
334 | { | 329 | { |
335 | struct mesh_table *oldtbl, *newtbl; | 330 | struct mesh_table *oldtbl, *newtbl; |
336 | 331 | ||
332 | newtbl = mesh_table_alloc(mesh_paths->size_order + 1); | ||
333 | if (!newtbl) | ||
334 | return; | ||
337 | write_lock(&pathtbl_resize_lock); | 335 | write_lock(&pathtbl_resize_lock); |
338 | oldtbl = mesh_paths; | 336 | oldtbl = mesh_paths; |
339 | newtbl = mesh_table_grow(mesh_paths); | 337 | if (mesh_table_grow(mesh_paths, newtbl) < 0) { |
340 | if (!newtbl) { | 338 | __mesh_table_free(newtbl); |
341 | write_unlock(&pathtbl_resize_lock); | 339 | write_unlock(&pathtbl_resize_lock); |
342 | return; | 340 | return; |
343 | } | 341 | } |
@@ -352,10 +350,13 @@ void mesh_mpp_table_grow(void) | |||
352 | { | 350 | { |
353 | struct mesh_table *oldtbl, *newtbl; | 351 | struct mesh_table *oldtbl, *newtbl; |
354 | 352 | ||
353 | newtbl = mesh_table_alloc(mpp_paths->size_order + 1); | ||
354 | if (!newtbl) | ||
355 | return; | ||
355 | write_lock(&pathtbl_resize_lock); | 356 | write_lock(&pathtbl_resize_lock); |
356 | oldtbl = mpp_paths; | 357 | oldtbl = mpp_paths; |
357 | newtbl = mesh_table_grow(mpp_paths); | 358 | if (mesh_table_grow(mpp_paths, newtbl) < 0) { |
358 | if (!newtbl) { | 359 | __mesh_table_free(newtbl); |
359 | write_unlock(&pathtbl_resize_lock); | 360 | write_unlock(&pathtbl_resize_lock); |
360 | return; | 361 | return; |
361 | } | 362 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 44b53931ba5e..84e5b056af02 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | if (!sta) | 105 | if (!sta) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | sta->flags = WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH; |
109 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
110 | rate_control_rate_init(sta); | 110 | rate_control_rate_init(sta); |
111 | 111 | ||
@@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
161 | __le16 reason) { | 161 | __le16 reason) { |
162 | struct ieee80211_local *local = sdata->local; | 162 | struct ieee80211_local *local = sdata->local; |
163 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + | 163 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + |
164 | sdata->u.mesh.vendor_ie_len); | 164 | sdata->u.mesh.ie_len); |
165 | struct ieee80211_mgmt *mgmt; | 165 | struct ieee80211_mgmt *mgmt; |
166 | bool include_plid = false; | 166 | bool include_plid = false; |
167 | static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; | 167 | static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; |
@@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, | 240 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, |
241 | bool peer_accepting_plinks) | 241 | struct ieee80211_sub_if_data *sdata, |
242 | struct ieee802_11_elems *elems) | ||
242 | { | 243 | { |
243 | struct ieee80211_local *local = sdata->local; | 244 | struct ieee80211_local *local = sdata->local; |
244 | struct sta_info *sta; | 245 | struct sta_info *sta; |
@@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data | |||
248 | sta = sta_info_get(sdata, hw_addr); | 249 | sta = sta_info_get(sdata, hw_addr); |
249 | if (!sta) { | 250 | if (!sta) { |
250 | rcu_read_unlock(); | 251 | rcu_read_unlock(); |
251 | 252 | /* Userspace handles peer allocation when security is enabled | |
252 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | 253 | * */ |
254 | if (sdata->u.mesh.is_secure) | ||
255 | cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, | ||
256 | elems->ie_start, elems->total_len, | ||
257 | GFP_KERNEL); | ||
258 | else | ||
259 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | ||
253 | if (!sta) | 260 | if (!sta) |
254 | return; | 261 | return; |
255 | if (sta_info_insert_rcu(sta)) { | 262 | if (sta_info_insert_rcu(sta)) { |
@@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data | |||
260 | 267 | ||
261 | sta->last_rx = jiffies; | 268 | sta->last_rx = jiffies; |
262 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 269 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
263 | if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && | 270 | if (mesh_peer_accepts_plinks(elems) && |
271 | sta->plink_state == PLINK_LISTEN && | ||
264 | sdata->u.mesh.accepting_plinks && | 272 | sdata->u.mesh.accepting_plinks && |
265 | sdata->u.mesh.mshcfg.auto_open_plinks) | 273 | sdata->u.mesh.mshcfg.auto_open_plinks) |
266 | mesh_plink_open(sta); | 274 | mesh_plink_open(sta); |
@@ -372,6 +380,9 @@ int mesh_plink_open(struct sta_info *sta) | |||
372 | __le16 llid; | 380 | __le16 llid; |
373 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 381 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
374 | 382 | ||
383 | if (!test_sta_flags(sta, WLAN_STA_AUTH)) | ||
384 | return -EPERM; | ||
385 | |||
375 | spin_lock_bh(&sta->lock); | 386 | spin_lock_bh(&sta->lock); |
376 | get_random_bytes(&llid, 2); | 387 | get_random_bytes(&llid, 2); |
377 | sta->llid = llid; | 388 | sta->llid = llid; |
@@ -449,6 +460,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
449 | mpl_dbg("Mesh plink: missing necessary peer link ie\n"); | 460 | mpl_dbg("Mesh plink: missing necessary peer link ie\n"); |
450 | return; | 461 | return; |
451 | } | 462 | } |
463 | if (elems.rsn_len && !sdata->u.mesh.is_secure) { | ||
464 | mpl_dbg("Mesh plink: can't establish link with secure peer\n"); | ||
465 | return; | ||
466 | } | ||
452 | 467 | ||
453 | ftype = mgmt->u.action.u.plink_action.action_code; | 468 | ftype = mgmt->u.action.u.plink_action.action_code; |
454 | ie_len = elems.peer_link_len; | 469 | ie_len = elems.peer_link_len; |
@@ -480,6 +495,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
480 | return; | 495 | return; |
481 | } | 496 | } |
482 | 497 | ||
498 | if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { | ||
499 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | ||
500 | rcu_read_unlock(); | ||
501 | return; | ||
502 | } | ||
503 | |||
483 | if (sta && sta->plink_state == PLINK_BLOCKED) { | 504 | if (sta && sta->plink_state == PLINK_BLOCKED) { |
484 | rcu_read_unlock(); | 505 | rcu_read_unlock(); |
485 | return; | 506 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 865fed4cc18b..a41f234bd486 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
761 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 761 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
762 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { | 762 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { |
763 | netif_tx_stop_all_queues(sdata->dev); | 763 | netif_tx_stop_all_queues(sdata->dev); |
764 | /* | ||
765 | * Flush all the frames queued in the driver before | ||
766 | * going to power save | ||
767 | */ | ||
768 | drv_flush(local, false); | ||
769 | ieee80211_send_nullfunc(local, sdata, 1); | ||
770 | 764 | ||
771 | /* Flush once again to get the tx status of nullfunc frame */ | 765 | if (drv_tx_frames_pending(local)) |
772 | drv_flush(local, false); | 766 | mod_timer(&local->dynamic_ps_timer, jiffies + |
767 | msecs_to_jiffies( | ||
768 | local->hw.conf.dynamic_ps_timeout)); | ||
769 | else { | ||
770 | ieee80211_send_nullfunc(local, sdata, 1); | ||
771 | /* Flush to get the tx status of nullfunc frame */ | ||
772 | drv_flush(local, false); | ||
773 | } | ||
773 | } | 774 | } |
774 | 775 | ||
775 | if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && | 776 | if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1f0b010904b8..a864890e4d03 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -143,7 +143,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
143 | if (status->flag & RX_FLAG_HT) { | 143 | if (status->flag & RX_FLAG_HT) { |
144 | /* | 144 | /* |
145 | * MCS information is a separate field in radiotap, | 145 | * MCS information is a separate field in radiotap, |
146 | * added below. | 146 | * added below. The byte here is needed as padding |
147 | * for the channel though, so initialise it to 0. | ||
147 | */ | 148 | */ |
148 | *pos = 0; | 149 | *pos = 0; |
149 | } else { | 150 | } else { |
@@ -502,7 +503,8 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
502 | 503 | ||
503 | if (ieee80211_is_probe_req(hdr->frame_control) || | 504 | if (ieee80211_is_probe_req(hdr->frame_control) || |
504 | ieee80211_is_probe_resp(hdr->frame_control) || | 505 | ieee80211_is_probe_resp(hdr->frame_control) || |
505 | ieee80211_is_beacon(hdr->frame_control)) | 506 | ieee80211_is_beacon(hdr->frame_control) || |
507 | ieee80211_is_auth(hdr->frame_control)) | ||
506 | return RX_CONTINUE; | 508 | return RX_CONTINUE; |
507 | 509 | ||
508 | return RX_DROP_MONITOR; | 510 | return RX_DROP_MONITOR; |
@@ -1585,7 +1587,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1585 | } | 1587 | } |
1586 | 1588 | ||
1587 | static int | 1589 | static int |
1588 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | 1590 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) |
1589 | { | 1591 | { |
1590 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1592 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1591 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1593 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
@@ -1593,6 +1595,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1593 | struct ethhdr *ehdr; | 1595 | struct ethhdr *ehdr; |
1594 | int ret; | 1596 | int ret; |
1595 | 1597 | ||
1598 | *port_control = false; | ||
1596 | if (ieee80211_has_a4(hdr->frame_control) && | 1599 | if (ieee80211_has_a4(hdr->frame_control) && |
1597 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) | 1600 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1598 | return -1; | 1601 | return -1; |
@@ -1611,11 +1614,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1611 | return -1; | 1614 | return -1; |
1612 | 1615 | ||
1613 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); | 1616 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); |
1614 | if (ret < 0 || !check_port_control) | 1617 | if (ret < 0) |
1615 | return ret; | 1618 | return ret; |
1616 | 1619 | ||
1617 | ehdr = (struct ethhdr *) rx->skb->data; | 1620 | ehdr = (struct ethhdr *) rx->skb->data; |
1618 | if (ehdr->h_proto != rx->sdata->control_port_protocol) | 1621 | if (ehdr->h_proto == rx->sdata->control_port_protocol) |
1622 | *port_control = true; | ||
1623 | else if (check_port_control) | ||
1619 | return -1; | 1624 | return -1; |
1620 | 1625 | ||
1621 | return 0; | 1626 | return 0; |
@@ -1916,6 +1921,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1916 | struct net_device *dev = sdata->dev; | 1921 | struct net_device *dev = sdata->dev; |
1917 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1922 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1918 | __le16 fc = hdr->frame_control; | 1923 | __le16 fc = hdr->frame_control; |
1924 | bool port_control; | ||
1919 | int err; | 1925 | int err; |
1920 | 1926 | ||
1921 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) | 1927 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) |
@@ -1932,13 +1938,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1932 | sdata->vif.type == NL80211_IFTYPE_AP) | 1938 | sdata->vif.type == NL80211_IFTYPE_AP) |
1933 | return RX_DROP_MONITOR; | 1939 | return RX_DROP_MONITOR; |
1934 | 1940 | ||
1935 | err = __ieee80211_data_to_8023(rx); | 1941 | err = __ieee80211_data_to_8023(rx, &port_control); |
1936 | if (unlikely(err)) | 1942 | if (unlikely(err)) |
1937 | return RX_DROP_UNUSABLE; | 1943 | return RX_DROP_UNUSABLE; |
1938 | 1944 | ||
1939 | if (!ieee80211_frame_allowed(rx, fc)) | 1945 | if (!ieee80211_frame_allowed(rx, fc)) |
1940 | return RX_DROP_MONITOR; | 1946 | return RX_DROP_MONITOR; |
1941 | 1947 | ||
1948 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | ||
1949 | unlikely(port_control) && sdata->bss) { | ||
1950 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | ||
1951 | u.ap); | ||
1952 | dev = sdata->dev; | ||
1953 | rx->sdata = sdata; | ||
1954 | } | ||
1955 | |||
1942 | rx->skb->dev = dev; | 1956 | rx->skb->dev = dev; |
1943 | 1957 | ||
1944 | dev->stats.rx_packets++; | 1958 | dev->stats.rx_packets++; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 52d4b1a695c9..a03d8a312875 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -228,6 +228,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
228 | { | 228 | { |
229 | struct ieee80211_local *local = sdata->local; | 229 | struct ieee80211_local *local = sdata->local; |
230 | struct sta_info *sta; | 230 | struct sta_info *sta; |
231 | struct timespec uptime; | ||
231 | int i; | 232 | int i; |
232 | 233 | ||
233 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); | 234 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); |
@@ -245,6 +246,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
245 | sta->sdata = sdata; | 246 | sta->sdata = sdata; |
246 | sta->last_rx = jiffies; | 247 | sta->last_rx = jiffies; |
247 | 248 | ||
249 | do_posix_clock_monotonic_gettime(&uptime); | ||
250 | sta->last_connected = uptime.tv_sec; | ||
248 | ewma_init(&sta->avg_signal, 1024, 8); | 251 | ewma_init(&sta->avg_signal, 1024, 8); |
249 | 252 | ||
250 | if (sta_prepare_rate_control(local, sta, gfp)) { | 253 | if (sta_prepare_rate_control(local, sta, gfp)) { |
@@ -609,7 +612,8 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
609 | #endif | 612 | #endif |
610 | dev_kfree_skb(skb); | 613 | dev_kfree_skb(skb); |
611 | 614 | ||
612 | if (skb_queue_empty(&sta->ps_tx_buf)) | 615 | if (skb_queue_empty(&sta->ps_tx_buf) && |
616 | !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF)) | ||
613 | sta_info_clear_tim_bit(sta); | 617 | sta_info_clear_tim_bit(sta); |
614 | } | 618 | } |
615 | 619 | ||
@@ -893,6 +897,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
893 | struct ieee80211_local *local = sdata->local; | 897 | struct ieee80211_local *local = sdata->local; |
894 | int sent, buffered; | 898 | int sent, buffered; |
895 | 899 | ||
900 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | ||
896 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 901 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
897 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); | 902 | drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); |
898 | 903 | ||
@@ -985,3 +990,12 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
985 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); | 990 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); |
986 | } | 991 | } |
987 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 992 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
993 | |||
994 | void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta) | ||
995 | { | ||
996 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | ||
997 | |||
998 | set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); | ||
999 | sta_info_set_tim_bit(sta); | ||
1000 | } | ||
1001 | EXPORT_SYMBOL(ieee80211_sta_set_tim); | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 87b18ba1e0e9..aa0adcbf3a93 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -43,6 +43,8 @@ | |||
43 | * be in the queues | 43 | * be in the queues |
44 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping | 44 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping |
45 | * station in power-save mode, reply when the driver unblocks. | 45 | * station in power-save mode, reply when the driver unblocks. |
46 | * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal | ||
47 | * buffers. Automatically cleared on station wake-up. | ||
46 | */ | 48 | */ |
47 | enum ieee80211_sta_info_flags { | 49 | enum ieee80211_sta_info_flags { |
48 | WLAN_STA_AUTH = 1<<0, | 50 | WLAN_STA_AUTH = 1<<0, |
@@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags { | |||
58 | WLAN_STA_BLOCK_BA = 1<<11, | 60 | WLAN_STA_BLOCK_BA = 1<<11, |
59 | WLAN_STA_PS_DRIVER = 1<<12, | 61 | WLAN_STA_PS_DRIVER = 1<<12, |
60 | WLAN_STA_PSPOLL = 1<<13, | 62 | WLAN_STA_PSPOLL = 1<<13, |
63 | WLAN_STA_PS_DRIVER_BUF = 1<<14, | ||
61 | }; | 64 | }; |
62 | 65 | ||
63 | #define STA_TID_NUM 16 | 66 | #define STA_TID_NUM 16 |
@@ -226,6 +229,7 @@ enum plink_state { | |||
226 | * @rx_bytes: Number of bytes received from this STA | 229 | * @rx_bytes: Number of bytes received from this STA |
227 | * @wep_weak_iv_count: number of weak WEP IVs received from this station | 230 | * @wep_weak_iv_count: number of weak WEP IVs received from this station |
228 | * @last_rx: time (in jiffies) when last frame was received from this STA | 231 | * @last_rx: time (in jiffies) when last frame was received from this STA |
232 | * @last_connected: time (in seconds) when a station got connected | ||
229 | * @num_duplicates: number of duplicate frames received from this STA | 233 | * @num_duplicates: number of duplicate frames received from this STA |
230 | * @rx_fragments: number of received MPDUs | 234 | * @rx_fragments: number of received MPDUs |
231 | * @rx_dropped: number of dropped MPDUs from this STA | 235 | * @rx_dropped: number of dropped MPDUs from this STA |
@@ -295,6 +299,7 @@ struct sta_info { | |||
295 | unsigned long rx_packets, rx_bytes; | 299 | unsigned long rx_packets, rx_bytes; |
296 | unsigned long wep_weak_iv_count; | 300 | unsigned long wep_weak_iv_count; |
297 | unsigned long last_rx; | 301 | unsigned long last_rx; |
302 | long last_connected; | ||
298 | unsigned long num_duplicates; | 303 | unsigned long num_duplicates; |
299 | unsigned long rx_fragments; | 304 | unsigned long rx_fragments; |
300 | unsigned long rx_dropped; | 305 | unsigned long rx_dropped; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ce4596ed1268..17b10be31f55 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2262,7 +2262,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2262 | 2262 | ||
2263 | /* headroom, head length, tail length and maximum TIM length */ | 2263 | /* headroom, head length, tail length and maximum TIM length */ |
2264 | skb = dev_alloc_skb(local->tx_headroom + 400 + | 2264 | skb = dev_alloc_skb(local->tx_headroom + 400 + |
2265 | sdata->u.mesh.vendor_ie_len); | 2265 | sdata->u.mesh.ie_len); |
2266 | if (!skb) | 2266 | if (!skb) |
2267 | goto out; | 2267 | goto out; |
2268 | 2268 | ||
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 7fce6dfd2180..48464ca13b24 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
@@ -22,3 +22,14 @@ config RFKILL_INPUT | |||
22 | depends on RFKILL | 22 | depends on RFKILL |
23 | depends on INPUT = y || RFKILL = INPUT | 23 | depends on INPUT = y || RFKILL = INPUT |
24 | default y if !EXPERT | 24 | default y if !EXPERT |
25 | |||
26 | config RFKILL_REGULATOR | ||
27 | tristate "Generic rfkill regulator driver" | ||
28 | depends on RFKILL || !RFKILL | ||
29 | depends on REGULATOR | ||
30 | help | ||
31 | This options enable controlling radio transmitters connected to | ||
32 | voltage regulator using the regulator framework. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the module will | ||
35 | be called rfkill-regulator. | ||
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile index 662105352691..d9a5a58ffd8c 100644 --- a/net/rfkill/Makefile +++ b/net/rfkill/Makefile | |||
@@ -5,3 +5,4 @@ | |||
5 | rfkill-y += core.o | 5 | rfkill-y += core.o |
6 | rfkill-$(CONFIG_RFKILL_INPUT) += input.o | 6 | rfkill-$(CONFIG_RFKILL_INPUT) += input.o |
7 | obj-$(CONFIG_RFKILL) += rfkill.o | 7 | obj-$(CONFIG_RFKILL) += rfkill.o |
8 | obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o | ||
diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c new file mode 100644 index 000000000000..18dc512a10f3 --- /dev/null +++ b/net/rfkill/rfkill-regulator.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * rfkill-regulator.c - Regulator consumer driver for rfkill | ||
3 | * | ||
4 | * Copyright (C) 2009 Guiming Zhuo <gmzhuo@gmail.com> | ||
5 | * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it> | ||
6 | * | ||
7 | * Implementation inspired by leds-regulator driver. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/regulator/consumer.h> | ||
20 | #include <linux/rfkill.h> | ||
21 | #include <linux/rfkill-regulator.h> | ||
22 | |||
23 | struct rfkill_regulator_data { | ||
24 | struct rfkill *rf_kill; | ||
25 | bool reg_enabled; | ||
26 | |||
27 | struct regulator *vcc; | ||
28 | }; | ||
29 | |||
30 | static int rfkill_regulator_set_block(void *data, bool blocked) | ||
31 | { | ||
32 | struct rfkill_regulator_data *rfkill_data = data; | ||
33 | |||
34 | pr_debug("%s: blocked: %d\n", __func__, blocked); | ||
35 | |||
36 | if (blocked) { | ||
37 | if (rfkill_data->reg_enabled) { | ||
38 | regulator_disable(rfkill_data->vcc); | ||
39 | rfkill_data->reg_enabled = 0; | ||
40 | } | ||
41 | } else { | ||
42 | if (!rfkill_data->reg_enabled) { | ||
43 | regulator_enable(rfkill_data->vcc); | ||
44 | rfkill_data->reg_enabled = 1; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__, | ||
49 | regulator_is_enabled(rfkill_data->vcc)); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | struct rfkill_ops rfkill_regulator_ops = { | ||
55 | .set_block = rfkill_regulator_set_block, | ||
56 | }; | ||
57 | |||
58 | static int __devinit rfkill_regulator_probe(struct platform_device *pdev) | ||
59 | { | ||
60 | struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data; | ||
61 | struct rfkill_regulator_data *rfkill_data; | ||
62 | struct regulator *vcc; | ||
63 | struct rfkill *rf_kill; | ||
64 | int ret = 0; | ||
65 | |||
66 | if (pdata == NULL) { | ||
67 | dev_err(&pdev->dev, "no platform data\n"); | ||
68 | return -ENODEV; | ||
69 | } | ||
70 | |||
71 | if (pdata->name == NULL || pdata->type == 0) { | ||
72 | dev_err(&pdev->dev, "invalid name or type in platform data\n"); | ||
73 | return -EINVAL; | ||
74 | } | ||
75 | |||
76 | vcc = regulator_get_exclusive(&pdev->dev, "vrfkill"); | ||
77 | if (IS_ERR(vcc)) { | ||
78 | dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); | ||
79 | ret = PTR_ERR(vcc); | ||
80 | goto out; | ||
81 | } | ||
82 | |||
83 | rfkill_data = kzalloc(sizeof(*rfkill_data), GFP_KERNEL); | ||
84 | if (rfkill_data == NULL) { | ||
85 | ret = -ENOMEM; | ||
86 | goto err_data_alloc; | ||
87 | } | ||
88 | |||
89 | rf_kill = rfkill_alloc(pdata->name, &pdev->dev, | ||
90 | pdata->type, | ||
91 | &rfkill_regulator_ops, rfkill_data); | ||
92 | if (rf_kill == NULL) { | ||
93 | dev_err(&pdev->dev, "Cannot alloc rfkill device\n"); | ||
94 | ret = -ENOMEM; | ||
95 | goto err_rfkill_alloc; | ||
96 | } | ||
97 | |||
98 | if (regulator_is_enabled(vcc)) { | ||
99 | dev_dbg(&pdev->dev, "Regulator already enabled\n"); | ||
100 | rfkill_data->reg_enabled = 1; | ||
101 | } | ||
102 | rfkill_data->vcc = vcc; | ||
103 | rfkill_data->rf_kill = rf_kill; | ||
104 | |||
105 | ret = rfkill_register(rf_kill); | ||
106 | if (ret) { | ||
107 | dev_err(&pdev->dev, "Cannot register rfkill device\n"); | ||
108 | goto err_rfkill_register; | ||
109 | } | ||
110 | |||
111 | platform_set_drvdata(pdev, rfkill_data); | ||
112 | dev_info(&pdev->dev, "%s initialized\n", pdata->name); | ||
113 | |||
114 | return 0; | ||
115 | |||
116 | err_rfkill_register: | ||
117 | rfkill_destroy(rf_kill); | ||
118 | err_rfkill_alloc: | ||
119 | kfree(rfkill_data); | ||
120 | err_data_alloc: | ||
121 | regulator_put(vcc); | ||
122 | out: | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static int __devexit rfkill_regulator_remove(struct platform_device *pdev) | ||
127 | { | ||
128 | struct rfkill_regulator_data *rfkill_data = platform_get_drvdata(pdev); | ||
129 | struct rfkill *rf_kill = rfkill_data->rf_kill; | ||
130 | |||
131 | rfkill_unregister(rf_kill); | ||
132 | rfkill_destroy(rf_kill); | ||
133 | regulator_put(rfkill_data->vcc); | ||
134 | kfree(rfkill_data); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static struct platform_driver rfkill_regulator_driver = { | ||
140 | .probe = rfkill_regulator_probe, | ||
141 | .remove = __devexit_p(rfkill_regulator_remove), | ||
142 | .driver = { | ||
143 | .name = "rfkill-regulator", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | static int __init rfkill_regulator_init(void) | ||
149 | { | ||
150 | return platform_driver_register(&rfkill_regulator_driver); | ||
151 | } | ||
152 | module_init(rfkill_regulator_init); | ||
153 | |||
154 | static void __exit rfkill_regulator_exit(void) | ||
155 | { | ||
156 | platform_driver_unregister(&rfkill_regulator_driver); | ||
157 | } | ||
158 | module_exit(rfkill_regulator_exit); | ||
159 | |||
160 | MODULE_AUTHOR("Guiming Zhuo <gmzhuo@gmail.com>"); | ||
161 | MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | ||
162 | MODULE_DESCRIPTION("Regulator consumer driver for rfkill"); | ||
163 | MODULE_LICENSE("GPL"); | ||
164 | MODULE_ALIAS("platform:rfkill-regulator"); | ||
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 73e39c171ffb..5c116083eeca 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/ieee80211.h> | 1 | #include <linux/ieee80211.h> |
2 | #include <net/cfg80211.h> | 2 | #include <net/cfg80211.h> |
3 | #include "nl80211.h" | ||
3 | #include "core.h" | 4 | #include "core.h" |
4 | 5 | ||
5 | /* Default values, timeouts in ms */ | 6 | /* Default values, timeouts in ms */ |
@@ -53,8 +54,9 @@ const struct mesh_config default_mesh_config = { | |||
53 | const struct mesh_setup default_mesh_setup = { | 54 | const struct mesh_setup default_mesh_setup = { |
54 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, | 55 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, |
55 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, | 56 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, |
56 | .vendor_ie = NULL, | 57 | .ie = NULL, |
57 | .vendor_ie_len = 0, | 58 | .ie_len = 0, |
59 | .is_secure = false, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 62 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, |
@@ -72,6 +74,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
72 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 74 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
73 | return -EOPNOTSUPP; | 75 | return -EOPNOTSUPP; |
74 | 76 | ||
77 | if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && | ||
78 | setup->is_secure) | ||
79 | return -EOPNOTSUPP; | ||
80 | |||
75 | if (wdev->mesh_id_len) | 81 | if (wdev->mesh_id_len) |
76 | return -EALREADY; | 82 | return -EALREADY; |
77 | 83 | ||
@@ -105,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
105 | return err; | 111 | return err; |
106 | } | 112 | } |
107 | 113 | ||
114 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | ||
115 | const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) | ||
116 | { | ||
117 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
118 | |||
119 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | ||
120 | return; | ||
121 | |||
122 | nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, | ||
123 | macaddr, ie, ie_len, gfp); | ||
124 | } | ||
125 | EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); | ||
126 | |||
108 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 127 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
109 | struct net_device *dev) | 128 | struct net_device *dev) |
110 | { | 129 | { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 297d7ce4117b..0efa7fd01150 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
124 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, | 124 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, |
125 | 125 | ||
126 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, | 126 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, |
127 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, | ||
127 | 128 | ||
128 | [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, | 129 | [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, |
129 | .len = NL80211_HT_CAPABILITY_LEN }, | 130 | .len = NL80211_HT_CAPABILITY_LEN }, |
@@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
594 | 595 | ||
595 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) | 596 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) |
596 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); | 597 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); |
598 | if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) | ||
599 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); | ||
597 | 600 | ||
598 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, | 601 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, |
599 | sizeof(u32) * dev->wiphy.n_cipher_suites, | 602 | sizeof(u32) * dev->wiphy.n_cipher_suites, |
@@ -1922,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { | |||
1922 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, | 1925 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, |
1923 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, | 1926 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, |
1924 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, | 1927 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, |
1928 | [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, | ||
1925 | }; | 1929 | }; |
1926 | 1930 | ||
1927 | static int parse_station_flags(struct genl_info *info, | 1931 | static int parse_station_flags(struct genl_info *info, |
@@ -2016,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
2016 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); | 2020 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); |
2017 | if (!sinfoattr) | 2021 | if (!sinfoattr) |
2018 | goto nla_put_failure; | 2022 | goto nla_put_failure; |
2023 | if (sinfo->filled & STATION_INFO_CONNECTED_TIME) | ||
2024 | NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, | ||
2025 | sinfo->connected_time); | ||
2019 | if (sinfo->filled & STATION_INFO_INACTIVE_TIME) | 2026 | if (sinfo->filled & STATION_INFO_INACTIVE_TIME) |
2020 | NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, | 2027 | NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, |
2021 | sinfo->inactive_time); | 2028 | sinfo->inactive_time); |
@@ -2281,7 +2288,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
2281 | err = -EINVAL; | 2288 | err = -EINVAL; |
2282 | if (params.supported_rates) | 2289 | if (params.supported_rates) |
2283 | err = -EINVAL; | 2290 | err = -EINVAL; |
2284 | if (params.sta_flags_mask) | 2291 | if (params.sta_flags_mask & |
2292 | ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | | ||
2293 | BIT(NL80211_STA_FLAG_AUTHORIZED))) | ||
2285 | err = -EINVAL; | 2294 | err = -EINVAL; |
2286 | break; | 2295 | break; |
2287 | default: | 2296 | default: |
@@ -2343,11 +2352,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
2343 | params.ht_capa = | 2352 | params.ht_capa = |
2344 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 2353 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
2345 | 2354 | ||
2355 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | ||
2356 | params.plink_action = | ||
2357 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | ||
2358 | |||
2346 | if (parse_station_flags(info, ¶ms)) | 2359 | if (parse_station_flags(info, ¶ms)) |
2347 | return -EINVAL; | 2360 | return -EINVAL; |
2348 | 2361 | ||
2349 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2362 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2350 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 2363 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
2364 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | ||
2351 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2365 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2352 | return -EINVAL; | 2366 | return -EINVAL; |
2353 | 2367 | ||
@@ -2823,7 +2837,8 @@ static const struct nla_policy | |||
2823 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { | 2837 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { |
2824 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, | 2838 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, |
2825 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, | 2839 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, |
2826 | [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, | 2840 | [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, |
2841 | [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, | ||
2827 | .len = IEEE80211_MAX_DATA_LEN }, | 2842 | .len = IEEE80211_MAX_DATA_LEN }, |
2828 | }; | 2843 | }; |
2829 | 2844 | ||
@@ -2925,14 +2940,16 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, | |||
2925 | IEEE80211_PATH_METRIC_VENDOR : | 2940 | IEEE80211_PATH_METRIC_VENDOR : |
2926 | IEEE80211_PATH_METRIC_AIRTIME; | 2941 | IEEE80211_PATH_METRIC_AIRTIME; |
2927 | 2942 | ||
2928 | if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { | 2943 | |
2944 | if (tb[NL80211_MESH_SETUP_IE]) { | ||
2929 | struct nlattr *ieattr = | 2945 | struct nlattr *ieattr = |
2930 | tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; | 2946 | tb[NL80211_MESH_SETUP_IE]; |
2931 | if (!is_valid_ie_attr(ieattr)) | 2947 | if (!is_valid_ie_attr(ieattr)) |
2932 | return -EINVAL; | 2948 | return -EINVAL; |
2933 | setup->vendor_ie = nla_data(ieattr); | 2949 | setup->ie = nla_data(ieattr); |
2934 | setup->vendor_ie_len = nla_len(ieattr); | 2950 | setup->ie_len = nla_len(ieattr); |
2935 | } | 2951 | } |
2952 | setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); | ||
2936 | 2953 | ||
2937 | return 0; | 2954 | return 0; |
2938 | } | 2955 | } |
@@ -5804,6 +5821,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
5804 | nlmsg_free(msg); | 5821 | nlmsg_free(msg); |
5805 | } | 5822 | } |
5806 | 5823 | ||
5824 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | ||
5825 | struct net_device *netdev, | ||
5826 | const u8 *macaddr, const u8* ie, u8 ie_len, | ||
5827 | gfp_t gfp) | ||
5828 | { | ||
5829 | struct sk_buff *msg; | ||
5830 | void *hdr; | ||
5831 | |||
5832 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | ||
5833 | if (!msg) | ||
5834 | return; | ||
5835 | |||
5836 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); | ||
5837 | if (!hdr) { | ||
5838 | nlmsg_free(msg); | ||
5839 | return; | ||
5840 | } | ||
5841 | |||
5842 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
5843 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
5844 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr); | ||
5845 | if (ie_len && ie) | ||
5846 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); | ||
5847 | |||
5848 | if (genlmsg_end(msg, hdr) < 0) { | ||
5849 | nlmsg_free(msg); | ||
5850 | return; | ||
5851 | } | ||
5852 | |||
5853 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
5854 | nl80211_mlme_mcgrp.id, gfp); | ||
5855 | return; | ||
5856 | |||
5857 | nla_put_failure: | ||
5858 | genlmsg_cancel(msg, hdr); | ||
5859 | nlmsg_free(msg); | ||
5860 | } | ||
5861 | |||
5807 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | 5862 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, |
5808 | struct net_device *netdev, const u8 *addr, | 5863 | struct net_device *netdev, const u8 *addr, |
5809 | enum nl80211_key_type key_type, int key_id, | 5864 | enum nl80211_key_type key_type, int key_id, |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index dcac5cd6f017..f2af6955a665 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | |||
50 | struct net_device *netdev, u16 reason, | 50 | struct net_device *netdev, u16 reason, |
51 | const u8 *ie, size_t ie_len, bool from_ap); | 51 | const u8 *ie, size_t ie_len, bool from_ap); |
52 | 52 | ||
53 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | ||
54 | struct net_device *netdev, | ||
55 | const u8 *macaddr, const u8* ie, u8 ie_len, | ||
56 | gfp_t gfp); | ||
53 | void | 57 | void |
54 | nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | 58 | nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, |
55 | struct net_device *netdev, const u8 *addr, | 59 | struct net_device *netdev, const u8 *addr, |