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, |
