diff options
| author | John W. Linville <linville@tuxdriver.com> | 2013-03-08 15:53:47 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2013-03-08 15:53:47 -0500 |
| commit | cd309ab39351cfd5d0a310bd3d0eb76d0b31f66d (patch) | |
| tree | 0a9bccc45ca1a02597ab35caca8c2fe92889f0b2 | |
| parent | 3d5c203272b25c4391397247cdb0059a04fccddf (diff) | |
| parent | 25b9ea5c797b5d78f8ceced9ad9c7a7daf0db19c (diff) | |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
85 files changed, 2000 insertions, 696 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ba319cba3f1e..56c2040a955b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
| @@ -6,7 +6,6 @@ config IWLWIFI | |||
| 6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
| 7 | select LEDS_TRIGGERS | 7 | select LEDS_TRIGGERS |
| 8 | select MAC80211_LEDS | 8 | select MAC80211_LEDS |
| 9 | select IWLDVM | ||
| 10 | ---help--- | 9 | ---help--- |
| 11 | Select to build the driver supporting the: | 10 | Select to build the driver supporting the: |
| 12 | 11 | ||
| @@ -45,6 +44,7 @@ config IWLWIFI | |||
| 45 | config IWLDVM | 44 | config IWLDVM |
| 46 | tristate "Intel Wireless WiFi DVM Firmware support" | 45 | tristate "Intel Wireless WiFi DVM Firmware support" |
| 47 | depends on IWLWIFI | 46 | depends on IWLWIFI |
| 47 | default IWLWIFI | ||
| 48 | help | 48 | help |
| 49 | This is the driver supporting the DVM firmware which is | 49 | This is the driver supporting the DVM firmware which is |
| 50 | currently the only firmware available for existing devices. | 50 | currently the only firmware available for existing devices. |
| @@ -58,6 +58,15 @@ config IWLMVM | |||
| 58 | 58 | ||
| 59 | Say yes if you have such a device. | 59 | Say yes if you have such a device. |
| 60 | 60 | ||
| 61 | # don't call it _MODULE -- will confuse Kconfig/fixdep/... | ||
| 62 | config IWLWIFI_OPMODE_MODULAR | ||
| 63 | bool | ||
| 64 | default y if IWLDVM=m | ||
| 65 | default y if IWLMVM=m | ||
| 66 | |||
| 67 | comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" | ||
| 68 | depends on IWLWIFI && IWLDVM=n && IWLMVM=n | ||
| 69 | |||
| 61 | menu "Debugging Options" | 70 | menu "Debugging Options" |
| 62 | depends on IWLWIFI | 71 | depends on IWLWIFI |
| 63 | 72 | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 6c7800044a04..3b5613ea458b 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
| @@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o | |||
| 7 | iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o | 7 | iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o |
| 8 | iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o | 8 | iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o |
| 9 | iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o | 9 | iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o |
| 10 | iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o | 10 | iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o |
| 11 | iwlwifi-objs += pcie/7000.o | ||
| 12 | 11 | ||
| 13 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 12 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
| 14 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o | 13 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 41ec27cb6efe..019d433900ef 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 6468de8634b0..d6c4cf2ad7c5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index 65e920cab2b7..cfddde194940 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 84e2c0fcfef6..95ca026ecc9d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp { | |||
| 1526 | __le16 scd_ssn; | 1526 | __le16 scd_ssn; |
| 1527 | u8 txed; /* number of frames sent */ | 1527 | u8 txed; /* number of frames sent */ |
| 1528 | u8 txed_2_done; /* number of frames acked */ | 1528 | u8 txed_2_done; /* number of frames acked */ |
| 1529 | __le16 reserved1; | ||
| 1529 | } __packed; | 1530 | } __packed; |
| 1530 | 1531 | ||
| 1531 | /* | 1532 | /* |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 20806cae11b7..7b8178be119f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * USA | 19 | * USA |
| 20 | * | 20 | * |
| 21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
| 22 | * in the file called LICENSE.GPL. | 22 | * in the file called COPYING. |
| 23 | * | 23 | * |
| 24 | * Contact Information: | 24 | * Contact Information: |
| 25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file, | |||
| 2324 | return count; | 2324 | return count; |
| 2325 | } | 2325 | } |
| 2326 | 2326 | ||
| 2327 | static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | ||
| 2328 | const char __user *user_buf, | ||
| 2329 | size_t count, loff_t *ppos) | ||
| 2330 | { | ||
| 2331 | struct iwl_priv *priv = file->private_data; | ||
| 2332 | bool restart_fw = iwlwifi_mod_params.restart_fw; | ||
| 2333 | int ret; | ||
| 2334 | |||
| 2335 | iwlwifi_mod_params.restart_fw = true; | ||
| 2336 | |||
| 2337 | mutex_lock(&priv->mutex); | ||
| 2338 | |||
| 2339 | /* take the return value to make compiler happy - it will fail anyway */ | ||
| 2340 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL); | ||
| 2341 | |||
| 2342 | mutex_unlock(&priv->mutex); | ||
| 2343 | |||
| 2344 | iwlwifi_mod_params.restart_fw = restart_fw; | ||
| 2345 | |||
| 2346 | return count; | ||
| 2347 | } | ||
| 2348 | |||
| 2327 | DEBUGFS_READ_FILE_OPS(ucode_rx_stats); | 2349 | DEBUGFS_READ_FILE_OPS(ucode_rx_stats); |
| 2328 | DEBUGFS_READ_FILE_OPS(ucode_tx_stats); | 2350 | DEBUGFS_READ_FILE_OPS(ucode_tx_stats); |
| 2329 | DEBUGFS_READ_FILE_OPS(ucode_general_stats); | 2351 | DEBUGFS_READ_FILE_OPS(ucode_general_stats); |
| @@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); | |||
| 2343 | DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); | 2365 | DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); |
| 2344 | DEBUGFS_READ_FILE_OPS(reply_tx_error); | 2366 | DEBUGFS_READ_FILE_OPS(reply_tx_error); |
| 2345 | DEBUGFS_WRITE_FILE_OPS(echo_test); | 2367 | DEBUGFS_WRITE_FILE_OPS(echo_test); |
| 2368 | DEBUGFS_WRITE_FILE_OPS(fw_restart); | ||
| 2346 | #ifdef CONFIG_IWLWIFI_DEBUG | 2369 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 2347 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); | 2370 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); |
| 2348 | #endif | 2371 | #endif |
| @@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) | |||
| 2400 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 2423 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); |
| 2401 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 2424 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); |
| 2402 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2425 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); |
| 2426 | DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR); | ||
| 2403 | #ifdef CONFIG_IWLWIFI_DEBUG | 2427 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 2404 | DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); | 2428 | DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); |
| 2405 | #endif | 2429 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 86ea5f4c3939..cddf77c36b36 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * USA | 19 | * USA |
| 20 | * | 20 | * |
| 21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
| 22 | * in the file called LICENSE.GPL. | 22 | * in the file called COPYING. |
| 23 | * | 23 | * |
| 24 | * Contact Information: | 24 | * Contact Information: |
| 25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 3a4aa5239c45..d69b55866714 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * USA | 19 | * USA |
| 20 | * | 20 | * |
| 21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
| 22 | * in the file called LICENSE.GPL. | 22 | * in the file called COPYING. |
| 23 | * | 23 | * |
| 24 | * Contact Information: | 24 | * Contact Information: |
| 25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index 94ef33838bc6..b775769f8322 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
| @@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
| 151 | sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); | 151 | sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); |
| 152 | 152 | ||
| 153 | if (!(flags & CMD_ASYNC)) { | 153 | if (!(flags & CMD_ASYNC)) { |
| 154 | cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; | 154 | cmd.flags |= CMD_WANT_SKB; |
| 155 | might_sleep(); | 155 | might_sleep(); |
| 156 | } | 156 | } |
| 157 | 157 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index dc6f965a123a..b89b9d9b9969 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index d499a0366fa6..cc1e0c1a6f48 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * USA | 19 | * USA |
| 20 | * | 20 | * |
| 21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
| 22 | * in the file called LICENSE.GPL. | 22 | * in the file called COPYING. |
| 23 | * | 23 | * |
| 24 | * Contact Information: | 24 | * Contact Information: |
| 25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 736fe9bb140e..166019afc2d0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * USA | 19 | * USA |
| 20 | * | 20 | * |
| 21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
| 22 | * in the file called LICENSE.GPL. | 22 | * in the file called COPYING. |
| 23 | * | 23 | * |
| 24 | * Contact Information: | 24 | * Contact Information: |
| 25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ff3389757281..c080ae3070b2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
| 30 | #include "iwl-csr.h" | 30 | #include "iwl-csr.h" |
| 31 | #include "iwl-agn-hw.h" | 31 | #include "iwl-agn-hw.h" |
| 32 | #include "cfg.h" | ||
| 33 | 32 | ||
| 34 | /* Highest firmware API version supported */ | 33 | /* Highest firmware API version supported */ |
| 35 | #define IWL1000_UCODE_API_MAX 5 | 34 | #define IWL1000_UCODE_API_MAX 5 |
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e7de33128b16..a6ddd2f9fba0 100644 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
| 29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
| 30 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
| 31 | #include "cfg.h" | ||
| 32 | #include "dvm/commands.h" /* needed for BT for now */ | 31 | #include "dvm/commands.h" /* needed for BT for now */ |
| 33 | 32 | ||
| 34 | /* Highest firmware API version supported */ | 33 | /* Highest firmware API version supported */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5096f7c96ab6..403f3f224bf6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
| 30 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
| 31 | #include "iwl-csr.h" | 31 | #include "iwl-csr.h" |
| 32 | #include "cfg.h" | ||
| 33 | 32 | ||
| 34 | /* Highest firmware API version supported */ | 33 | /* Highest firmware API version supported */ |
| 35 | #define IWL5000_UCODE_API_MAX 5 | 34 | #define IWL5000_UCODE_API_MAX 5 |
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 801ff49796dd..b5ab8d1bcac0 100644 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
| 29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
| 30 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
| 31 | #include "cfg.h" | ||
| 32 | #include "dvm/commands.h" /* needed for BT for now */ | 31 | #include "dvm/commands.h" /* needed for BT for now */ |
| 33 | 32 | ||
| 34 | /* Highest firmware API version supported */ | 33 | /* Highest firmware API version supported */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 6e35b2b72332..50263e87fe15 100644 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
| @@ -1,34 +1,70 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 3 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| 4 | * redistributing this file, you may do so under either license. | ||
| 4 | * | 5 | * |
| 5 | * This program is free software; you can redistribute it and/or modify it | 6 | * GPL LICENSE SUMMARY |
| 6 | * under the terms of version 2 of the GNU General Public License as | 7 | * |
| 8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 8 | * | 13 | * |
| 9 | * This program is distributed in the hope that it will be useful, but WITHOUT | 14 | * This program is distributed in the hope that it will be useful, but |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 | * more details. | 17 | * General Public License for more details. |
| 13 | * | 18 | * |
| 14 | * You should have received a copy of the GNU General Public License along with | 19 | * You should have received a copy of the GNU General Public License |
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | 20 | * along with this program; if not, write to the Free Software |
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
| 22 | * USA | ||
| 17 | * | 23 | * |
| 18 | * The full GNU General Public License is included in this distribution in the | 24 | * The full GNU General Public License is included in this distribution |
| 19 | * file called LICENSE. | 25 | * in the file called COPYING. |
| 20 | * | 26 | * |
| 21 | * Contact Information: | 27 | * Contact Information: |
| 22 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| 23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
| 24 | * | 30 | * |
| 31 | * BSD LICENSE | ||
| 32 | * | ||
| 33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | ||
| 34 | * All rights reserved. | ||
| 35 | * | ||
| 36 | * Redistribution and use in source and binary forms, with or without | ||
| 37 | * modification, are permitted provided that the following conditions | ||
| 38 | * are met: | ||
| 39 | * | ||
| 40 | * * Redistributions of source code must retain the above copyright | ||
| 41 | * notice, this list of conditions and the following disclaimer. | ||
| 42 | * * Redistributions in binary form must reproduce the above copyright | ||
| 43 | * notice, this list of conditions and the following disclaimer in | ||
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | ||
| 46 | * * Neither the name Intel Corporation nor the names of its | ||
| 47 | * contributors may be used to endorse or promote products derived | ||
| 48 | * from this software without specific prior written permission. | ||
| 49 | * | ||
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 61 | * | ||
| 25 | *****************************************************************************/ | 62 | *****************************************************************************/ |
| 26 | 63 | ||
| 27 | #include <linux/module.h> | 64 | #include <linux/module.h> |
| 28 | #include <linux/stringify.h> | 65 | #include <linux/stringify.h> |
| 29 | #include "iwl-config.h" | 66 | #include "iwl-config.h" |
| 30 | #include "iwl-agn-hw.h" | 67 | #include "iwl-agn-hw.h" |
| 31 | #include "cfg.h" | ||
| 32 | 68 | ||
| 33 | /* Highest firmware API version supported */ | 69 | /* Highest firmware API version supported */ |
| 34 | #define IWL7260_UCODE_API_MAX 6 | 70 | #define IWL7260_UCODE_API_MAX 6 |
| @@ -70,7 +106,6 @@ static const struct iwl_base_params iwl7000_base_params = { | |||
| 70 | }; | 106 | }; |
| 71 | 107 | ||
| 72 | static const struct iwl_ht_params iwl7000_ht_params = { | 108 | static const struct iwl_ht_params iwl7000_ht_params = { |
| 73 | .ht_greenfield_support = true, | ||
| 74 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 109 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
| 75 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | 110 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), |
| 76 | }; | 111 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index e9975c54c276..6d73f943cefa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 743b48343358..c38aa8f77554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -275,4 +275,51 @@ struct iwl_cfg { | |||
| 275 | const bool temp_offset_v2; | 275 | const bool temp_offset_v2; |
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| 278 | /* | ||
| 279 | * This list declares the config structures for all devices. | ||
| 280 | */ | ||
| 281 | extern const struct iwl_cfg iwl5300_agn_cfg; | ||
| 282 | extern const struct iwl_cfg iwl5100_agn_cfg; | ||
| 283 | extern const struct iwl_cfg iwl5350_agn_cfg; | ||
| 284 | extern const struct iwl_cfg iwl5100_bgn_cfg; | ||
| 285 | extern const struct iwl_cfg iwl5100_abg_cfg; | ||
| 286 | extern const struct iwl_cfg iwl5150_agn_cfg; | ||
| 287 | extern const struct iwl_cfg iwl5150_abg_cfg; | ||
| 288 | extern const struct iwl_cfg iwl6005_2agn_cfg; | ||
| 289 | extern const struct iwl_cfg iwl6005_2abg_cfg; | ||
| 290 | extern const struct iwl_cfg iwl6005_2bg_cfg; | ||
| 291 | extern const struct iwl_cfg iwl6005_2agn_sff_cfg; | ||
| 292 | extern const struct iwl_cfg iwl6005_2agn_d_cfg; | ||
| 293 | extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; | ||
| 294 | extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; | ||
| 295 | extern const struct iwl_cfg iwl1030_bgn_cfg; | ||
| 296 | extern const struct iwl_cfg iwl1030_bg_cfg; | ||
| 297 | extern const struct iwl_cfg iwl6030_2agn_cfg; | ||
| 298 | extern const struct iwl_cfg iwl6030_2abg_cfg; | ||
| 299 | extern const struct iwl_cfg iwl6030_2bgn_cfg; | ||
| 300 | extern const struct iwl_cfg iwl6030_2bg_cfg; | ||
| 301 | extern const struct iwl_cfg iwl6000i_2agn_cfg; | ||
| 302 | extern const struct iwl_cfg iwl6000i_2abg_cfg; | ||
| 303 | extern const struct iwl_cfg iwl6000i_2bg_cfg; | ||
| 304 | extern const struct iwl_cfg iwl6000_3agn_cfg; | ||
| 305 | extern const struct iwl_cfg iwl6050_2agn_cfg; | ||
| 306 | extern const struct iwl_cfg iwl6050_2abg_cfg; | ||
| 307 | extern const struct iwl_cfg iwl6150_bgn_cfg; | ||
| 308 | extern const struct iwl_cfg iwl6150_bg_cfg; | ||
| 309 | extern const struct iwl_cfg iwl1000_bgn_cfg; | ||
| 310 | extern const struct iwl_cfg iwl1000_bg_cfg; | ||
| 311 | extern const struct iwl_cfg iwl100_bgn_cfg; | ||
| 312 | extern const struct iwl_cfg iwl100_bg_cfg; | ||
| 313 | extern const struct iwl_cfg iwl130_bgn_cfg; | ||
| 314 | extern const struct iwl_cfg iwl130_bg_cfg; | ||
| 315 | extern const struct iwl_cfg iwl2000_2bgn_cfg; | ||
| 316 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; | ||
| 317 | extern const struct iwl_cfg iwl2030_2bgn_cfg; | ||
| 318 | extern const struct iwl_cfg iwl6035_2agn_cfg; | ||
| 319 | extern const struct iwl_cfg iwl105_bgn_cfg; | ||
| 320 | extern const struct iwl_cfg iwl105_bgn_d_cfg; | ||
| 321 | extern const struct iwl_cfg iwl135_bgn_cfg; | ||
| 322 | extern const struct iwl_cfg iwl7260_2ac_cfg; | ||
| 323 | extern const struct iwl_cfg iwl3160_ac_cfg; | ||
| 324 | |||
| 278 | #endif /* __IWL_CONFIG_H__ */ | 325 | #endif /* __IWL_CONFIG_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index df3463a38704..20e845d4da04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 87535a67de76..8a44f594528d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -66,6 +66,7 @@ | |||
| 66 | #include <linux/device.h> | 66 | #include <linux/device.h> |
| 67 | #include <linux/interrupt.h> | 67 | #include <linux/interrupt.h> |
| 68 | #include <linux/export.h> | 68 | #include <linux/export.h> |
| 69 | #include "iwl-drv.h" | ||
| 69 | #include "iwl-debug.h" | 70 | #include "iwl-debug.h" |
| 70 | #include "iwl-devtrace.h" | 71 | #include "iwl-devtrace.h" |
| 71 | 72 | ||
| @@ -85,11 +86,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ | |||
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | __iwl_fn(warn) | 88 | __iwl_fn(warn) |
| 88 | EXPORT_SYMBOL_GPL(__iwl_warn); | 89 | IWL_EXPORT_SYMBOL(__iwl_warn); |
| 89 | __iwl_fn(info) | 90 | __iwl_fn(info) |
| 90 | EXPORT_SYMBOL_GPL(__iwl_info); | 91 | IWL_EXPORT_SYMBOL(__iwl_info); |
| 91 | __iwl_fn(crit) | 92 | __iwl_fn(crit) |
| 92 | EXPORT_SYMBOL_GPL(__iwl_crit); | 93 | IWL_EXPORT_SYMBOL(__iwl_crit); |
| 93 | 94 | ||
| 94 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | 95 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, |
| 95 | const char *fmt, ...) | 96 | const char *fmt, ...) |
| @@ -110,7 +111,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | |||
| 110 | trace_iwlwifi_err(&vaf); | 111 | trace_iwlwifi_err(&vaf); |
| 111 | va_end(args); | 112 | va_end(args); |
| 112 | } | 113 | } |
| 113 | EXPORT_SYMBOL_GPL(__iwl_err); | 114 | IWL_EXPORT_SYMBOL(__iwl_err); |
| 114 | 115 | ||
| 115 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 116 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
| 116 | void __iwl_dbg(struct device *dev, | 117 | void __iwl_dbg(struct device *dev, |
| @@ -133,5 +134,5 @@ void __iwl_dbg(struct device *dev, | |||
| 133 | trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); | 134 | trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); |
| 134 | va_end(args); | 135 | va_end(args); |
| 135 | } | 136 | } |
| 136 | EXPORT_SYMBOL_GPL(__iwl_dbg); | 137 | IWL_EXPORT_SYMBOL(__iwl_dbg); |
| 137 | #endif | 138 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9a0f45ec9e01..4491c1c72cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
| @@ -298,7 +298,7 @@ TRACE_EVENT(iwlwifi_dbg, | |||
| 298 | MAX_MSG_LEN, vaf->fmt, | 298 | MAX_MSG_LEN, vaf->fmt, |
| 299 | *vaf->va) >= MAX_MSG_LEN); | 299 | *vaf->va) >= MAX_MSG_LEN); |
| 300 | ), | 300 | ), |
| 301 | TP_printk("%s", (char *)__get_dynamic_array(msg)) | 301 | TP_printk("%s", __get_str(msg)) |
| 302 | ); | 302 | ); |
| 303 | 303 | ||
| 304 | #undef TRACE_SYSTEM | 304 | #undef TRACE_SYSTEM |
| @@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data, | |||
| 349 | TRACE_EVENT(iwlwifi_dev_hcmd, | 349 | TRACE_EVENT(iwlwifi_dev_hcmd, |
| 350 | TP_PROTO(const struct device *dev, | 350 | TP_PROTO(const struct device *dev, |
| 351 | struct iwl_host_cmd *cmd, u16 total_size, | 351 | struct iwl_host_cmd *cmd, u16 total_size, |
| 352 | const void *hdr, size_t hdr_len), | 352 | struct iwl_cmd_header *hdr), |
| 353 | TP_ARGS(dev, cmd, total_size, hdr, hdr_len), | 353 | TP_ARGS(dev, cmd, total_size, hdr), |
| 354 | TP_STRUCT__entry( | 354 | TP_STRUCT__entry( |
| 355 | DEV_ENTRY | 355 | DEV_ENTRY |
| 356 | __dynamic_array(u8, hcmd, total_size) | 356 | __dynamic_array(u8, hcmd, total_size) |
| 357 | __field(u32, flags) | 357 | __field(u32, flags) |
| 358 | ), | 358 | ), |
| 359 | TP_fast_assign( | 359 | TP_fast_assign( |
| 360 | int i, offset = hdr_len; | 360 | int i, offset = sizeof(*hdr); |
| 361 | 361 | ||
| 362 | DEV_ASSIGN; | 362 | DEV_ASSIGN; |
| 363 | __entry->flags = cmd->flags; | 363 | __entry->flags = cmd->flags; |
| 364 | memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); | 364 | memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); |
| 365 | 365 | ||
| 366 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 366 | for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { |
| 367 | if (!cmd->len[i]) | 367 | if (!cmd->len[i]) |
| 368 | continue; | 368 | continue; |
| 369 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | ||
| 370 | continue; | ||
| 371 | memcpy((u8 *)__get_dynamic_array(hcmd) + offset, | 369 | memcpy((u8 *)__get_dynamic_array(hcmd) + offset, |
| 372 | cmd->data[i], cmd->len[i]); | 370 | cmd->data[i], cmd->len[i]); |
| 373 | offset += cmd->len[i]; | 371 | offset += cmd->len[i]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 6f228bb2b844..3ce4e9d5082d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -1102,8 +1102,7 @@ void iwl_drv_stop(struct iwl_drv *drv) | |||
| 1102 | 1102 | ||
| 1103 | /* shared module parameters */ | 1103 | /* shared module parameters */ |
| 1104 | struct iwl_mod_params iwlwifi_mod_params = { | 1104 | struct iwl_mod_params iwlwifi_mod_params = { |
| 1105 | .amsdu_size_8K = 1, | 1105 | .restart_fw = true, |
| 1106 | .restart_fw = 1, | ||
| 1107 | .plcp_check = true, | 1106 | .plcp_check = true, |
| 1108 | .bt_coex_active = true, | 1107 | .bt_coex_active = true, |
| 1109 | .power_level = IWL_POWER_INDEX_1, | 1108 | .power_level = IWL_POWER_INDEX_1, |
| @@ -1112,7 +1111,7 @@ struct iwl_mod_params iwlwifi_mod_params = { | |||
| 1112 | .wd_disable = true, | 1111 | .wd_disable = true, |
| 1113 | /* the rest are 0 by default */ | 1112 | /* the rest are 0 by default */ |
| 1114 | }; | 1113 | }; |
| 1115 | EXPORT_SYMBOL_GPL(iwlwifi_mod_params); | 1114 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); |
| 1116 | 1115 | ||
| 1117 | int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) | 1116 | int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) |
| 1118 | { | 1117 | { |
| @@ -1136,7 +1135,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) | |||
| 1136 | mutex_unlock(&iwlwifi_opmode_table_mtx); | 1135 | mutex_unlock(&iwlwifi_opmode_table_mtx); |
| 1137 | return -EIO; | 1136 | return -EIO; |
| 1138 | } | 1137 | } |
| 1139 | EXPORT_SYMBOL_GPL(iwl_opmode_register); | 1138 | IWL_EXPORT_SYMBOL(iwl_opmode_register); |
| 1140 | 1139 | ||
| 1141 | void iwl_opmode_deregister(const char *name) | 1140 | void iwl_opmode_deregister(const char *name) |
| 1142 | { | 1141 | { |
| @@ -1158,7 +1157,7 @@ void iwl_opmode_deregister(const char *name) | |||
| 1158 | } | 1157 | } |
| 1159 | mutex_unlock(&iwlwifi_opmode_table_mtx); | 1158 | mutex_unlock(&iwlwifi_opmode_table_mtx); |
| 1160 | } | 1159 | } |
| 1161 | EXPORT_SYMBOL_GPL(iwl_opmode_deregister); | 1160 | IWL_EXPORT_SYMBOL(iwl_opmode_deregister); |
| 1162 | 1161 | ||
| 1163 | static int __init iwl_drv_init(void) | 1162 | static int __init iwl_drv_init(void) |
| 1164 | { | 1163 | { |
| @@ -1207,9 +1206,9 @@ MODULE_PARM_DESC(11n_disable, | |||
| 1207 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1206 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); |
| 1208 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, | 1207 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, |
| 1209 | int, S_IRUGO); | 1208 | int, S_IRUGO); |
| 1210 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | 1209 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); |
| 1211 | module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); | 1210 | module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO); |
| 1212 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); | 1211 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); |
| 1213 | 1212 | ||
| 1214 | module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, | 1213 | module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, |
| 1215 | int, S_IRUGO); | 1214 | int, S_IRUGO); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 594a5c71b272..7d1450916308 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -63,6 +63,8 @@ | |||
| 63 | #ifndef __iwl_drv_h__ | 63 | #ifndef __iwl_drv_h__ |
| 64 | #define __iwl_drv_h__ | 64 | #define __iwl_drv_h__ |
| 65 | 65 | ||
| 66 | #include <linux/module.h> | ||
| 67 | |||
| 66 | /* for all modules */ | 68 | /* for all modules */ |
| 67 | #define DRV_NAME "iwlwifi" | 69 | #define DRV_NAME "iwlwifi" |
| 68 | #define IWLWIFI_VERSION "in-tree:" | 70 | #define IWLWIFI_VERSION "in-tree:" |
| @@ -123,4 +125,17 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, | |||
| 123 | */ | 125 | */ |
| 124 | void iwl_drv_stop(struct iwl_drv *drv); | 126 | void iwl_drv_stop(struct iwl_drv *drv); |
| 125 | 127 | ||
| 128 | /* | ||
| 129 | * exported symbol management | ||
| 130 | * | ||
| 131 | * The driver can be split into multiple modules, in which case some symbols | ||
| 132 | * must be exported for the sub-modules. However, if it's not split and | ||
| 133 | * everything is built-in, then we can avoid that. | ||
| 134 | */ | ||
| 135 | #ifdef CONFIG_IWLWIFI_OPMODE_MODULAR | ||
| 136 | #define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym) | ||
| 137 | #else | ||
| 138 | #define IWL_EXPORT_SYMBOL(sym) | ||
| 139 | #endif | ||
| 140 | |||
| 126 | #endif /* __iwl_drv_h__ */ | 141 | #endif /* __iwl_drv_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 034f2ff4f43d..600c9fdd7f71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <linux/types.h> | 62 | #include <linux/types.h> |
| 63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
| 64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
| 65 | #include "iwl-drv.h" | ||
| 65 | #include "iwl-modparams.h" | 66 | #include "iwl-modparams.h" |
| 66 | #include "iwl-eeprom-parse.h" | 67 | #include "iwl-eeprom-parse.h" |
| 67 | 68 | ||
| @@ -749,7 +750,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, | |||
| 749 | } | 750 | } |
| 750 | 751 | ||
| 751 | ht_info->ht_supported = true; | 752 | ht_info->ht_supported = true; |
| 752 | ht_info->cap = 0; | 753 | ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; |
| 753 | 754 | ||
| 754 | if (iwlwifi_mod_params.amsdu_size_8K) | 755 | if (iwlwifi_mod_params.amsdu_size_8K) |
| 755 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | 756 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
| @@ -909,7 +910,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | |||
| 909 | kfree(data); | 910 | kfree(data); |
| 910 | return NULL; | 911 | return NULL; |
| 911 | } | 912 | } |
| 912 | EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); | 913 | IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data); |
| 913 | 914 | ||
| 914 | /* helper functions */ | 915 | /* helper functions */ |
| 915 | int iwl_nvm_check_version(struct iwl_nvm_data *data, | 916 | int iwl_nvm_check_version(struct iwl_nvm_data *data, |
| @@ -928,4 +929,4 @@ int iwl_nvm_check_version(struct iwl_nvm_data *data, | |||
| 928 | data->calib_version, trans->cfg->nvm_calib_ver); | 929 | data->calib_version, trans->cfg->nvm_calib_ver); |
| 929 | return -EINVAL; | 930 | return -EINVAL; |
| 930 | } | 931 | } |
| 931 | EXPORT_SYMBOL_GPL(iwl_nvm_check_version); | 932 | IWL_EXPORT_SYMBOL(iwl_nvm_check_version); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index 683fe6a8c58f..37f115390b19 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index ef4806f27cf8..e5f2e362ab0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -63,6 +63,7 @@ | |||
| 63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
| 64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
| 65 | 65 | ||
| 66 | #include "iwl-drv.h" | ||
| 66 | #include "iwl-debug.h" | 67 | #include "iwl-debug.h" |
| 67 | #include "iwl-eeprom-read.h" | 68 | #include "iwl-eeprom-read.h" |
| 68 | #include "iwl-io.h" | 69 | #include "iwl-io.h" |
| @@ -460,4 +461,4 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) | |||
| 460 | 461 | ||
| 461 | return ret; | 462 | return ret; |
| 462 | } | 463 | } |
| 463 | EXPORT_SYMBOL_GPL(iwl_read_eeprom); | 464 | IWL_EXPORT_SYMBOL(iwl_read_eeprom); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h index b2588c5cbf93..8e941f8bd7d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index f5592fb3b1ed..484d318245fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 90873eca35f7..8b6c6fd95ed0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index b545178e46e3..435618574240 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -73,12 +73,14 @@ | |||
| 73 | * treats good CRC threshold as a boolean | 73 | * treats good CRC threshold as a boolean |
| 74 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | 74 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). |
| 75 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | 75 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. |
| 76 | * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS | ||
| 76 | */ | 77 | */ |
| 77 | enum iwl_ucode_tlv_flag { | 78 | enum iwl_ucode_tlv_flag { |
| 78 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | 79 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), |
| 79 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | 80 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), |
| 80 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | 81 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), |
| 81 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | 82 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), |
| 83 | IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), | ||
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | /* The default calibrate table size if not specified by firmware file */ | 86 | /* The default calibrate table size if not specified by firmware file */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 276410d82de4..305c81f2c2b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
| 30 | #include <linux/export.h> | 30 | #include <linux/export.h> |
| 31 | 31 | ||
| 32 | #include "iwl-drv.h" | ||
| 32 | #include "iwl-io.h" | 33 | #include "iwl-io.h" |
| 33 | #include "iwl-csr.h" | 34 | #include "iwl-csr.h" |
| 34 | #include "iwl-debug.h" | 35 | #include "iwl-debug.h" |
| @@ -49,7 +50,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
| 49 | 50 | ||
| 50 | return -ETIMEDOUT; | 51 | return -ETIMEDOUT; |
| 51 | } | 52 | } |
| 52 | EXPORT_SYMBOL_GPL(iwl_poll_bit); | 53 | IWL_EXPORT_SYMBOL(iwl_poll_bit); |
| 53 | 54 | ||
| 54 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 55 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
| 55 | { | 56 | { |
| @@ -62,7 +63,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | |||
| 62 | 63 | ||
| 63 | return value; | 64 | return value; |
| 64 | } | 65 | } |
| 65 | EXPORT_SYMBOL_GPL(iwl_read_direct32); | 66 | IWL_EXPORT_SYMBOL(iwl_read_direct32); |
| 66 | 67 | ||
| 67 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | 68 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) |
| 68 | { | 69 | { |
| @@ -73,7 +74,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
| 73 | iwl_trans_release_nic_access(trans, &flags); | 74 | iwl_trans_release_nic_access(trans, &flags); |
| 74 | } | 75 | } |
| 75 | } | 76 | } |
| 76 | EXPORT_SYMBOL_GPL(iwl_write_direct32); | 77 | IWL_EXPORT_SYMBOL(iwl_write_direct32); |
| 77 | 78 | ||
| 78 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 79 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
| 79 | int timeout) | 80 | int timeout) |
| @@ -89,7 +90,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
| 89 | 90 | ||
| 90 | return -ETIMEDOUT; | 91 | return -ETIMEDOUT; |
| 91 | } | 92 | } |
| 92 | EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); | 93 | IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); |
| 93 | 94 | ||
| 94 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) | 95 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) |
| 95 | { | 96 | { |
| @@ -115,7 +116,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) | |||
| 115 | } | 116 | } |
| 116 | return val; | 117 | return val; |
| 117 | } | 118 | } |
| 118 | EXPORT_SYMBOL_GPL(iwl_read_prph); | 119 | IWL_EXPORT_SYMBOL(iwl_read_prph); |
| 119 | 120 | ||
| 120 | void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | 121 | void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) |
| 121 | { | 122 | { |
| @@ -126,7 +127,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | |||
| 126 | iwl_trans_release_nic_access(trans, &flags); | 127 | iwl_trans_release_nic_access(trans, &flags); |
| 127 | } | 128 | } |
| 128 | } | 129 | } |
| 129 | EXPORT_SYMBOL_GPL(iwl_write_prph); | 130 | IWL_EXPORT_SYMBOL(iwl_write_prph); |
| 130 | 131 | ||
| 131 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | 132 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) |
| 132 | { | 133 | { |
| @@ -138,7 +139,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
| 138 | iwl_trans_release_nic_access(trans, &flags); | 139 | iwl_trans_release_nic_access(trans, &flags); |
| 139 | } | 140 | } |
| 140 | } | 141 | } |
| 141 | EXPORT_SYMBOL_GPL(iwl_set_bits_prph); | 142 | IWL_EXPORT_SYMBOL(iwl_set_bits_prph); |
| 142 | 143 | ||
| 143 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | 144 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, |
| 144 | u32 bits, u32 mask) | 145 | u32 bits, u32 mask) |
| @@ -151,7 +152,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | |||
| 151 | iwl_trans_release_nic_access(trans, &flags); | 152 | iwl_trans_release_nic_access(trans, &flags); |
| 152 | } | 153 | } |
| 153 | } | 154 | } |
| 154 | EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); | 155 | IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); |
| 155 | 156 | ||
| 156 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | 157 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) |
| 157 | { | 158 | { |
| @@ -164,4 +165,4 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
| 164 | iwl_trans_release_nic_access(trans, &flags); | 165 | iwl_trans_release_nic_access(trans, &flags); |
| 165 | } | 166 | } |
| 166 | } | 167 | } |
| 167 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); | 168 | IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index e5e3a79eae2f..3cc39ffe8ba5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -91,7 +91,7 @@ enum iwl_power_level { | |||
| 91 | * @sw_crypto: using hardware encryption, default = 0 | 91 | * @sw_crypto: using hardware encryption, default = 0 |
| 92 | * @disable_11n: disable 11n capabilities, default = 0, | 92 | * @disable_11n: disable 11n capabilities, default = 0, |
| 93 | * use IWL_DISABLE_HT_* constants | 93 | * use IWL_DISABLE_HT_* constants |
| 94 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 | 94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
| 95 | * @restart_fw: restart firmware, default = 1 | 95 | * @restart_fw: restart firmware, default = 1 |
| 96 | * @plcp_check: enable plcp health check, default = true | 96 | * @plcp_check: enable plcp health check, default = true |
| 97 | * @wd_disable: enable stuck queue check, default = 0 | 97 | * @wd_disable: enable stuck queue check, default = 0 |
| @@ -109,7 +109,7 @@ struct iwl_mod_params { | |||
| 109 | int sw_crypto; | 109 | int sw_crypto; |
| 110 | unsigned int disable_11n; | 110 | unsigned int disable_11n; |
| 111 | int amsdu_size_8K; | 111 | int amsdu_size_8K; |
| 112 | int restart_fw; | 112 | bool restart_fw; |
| 113 | bool plcp_check; | 113 | bool plcp_check; |
| 114 | int wd_disable; | 114 | int wd_disable; |
| 115 | bool bt_coex_active; | 115 | bool bt_coex_active; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index c3affbc62cdf..940b8a9d5285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -63,6 +63,7 @@ | |||
| 63 | #include <linux/sched.h> | 63 | #include <linux/sched.h> |
| 64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
| 65 | 65 | ||
| 66 | #include "iwl-drv.h" | ||
| 66 | #include "iwl-notif-wait.h" | 67 | #include "iwl-notif-wait.h" |
| 67 | 68 | ||
| 68 | 69 | ||
| @@ -72,7 +73,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) | |||
| 72 | INIT_LIST_HEAD(¬if_wait->notif_waits); | 73 | INIT_LIST_HEAD(¬if_wait->notif_waits); |
| 73 | init_waitqueue_head(¬if_wait->notif_waitq); | 74 | init_waitqueue_head(¬if_wait->notif_waitq); |
| 74 | } | 75 | } |
| 75 | EXPORT_SYMBOL_GPL(iwl_notification_wait_init); | 76 | IWL_EXPORT_SYMBOL(iwl_notification_wait_init); |
| 76 | 77 | ||
| 77 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | 78 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, |
| 78 | struct iwl_rx_packet *pkt) | 79 | struct iwl_rx_packet *pkt) |
| @@ -117,7 +118,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | |||
| 117 | if (triggered) | 118 | if (triggered) |
| 118 | wake_up_all(¬if_wait->notif_waitq); | 119 | wake_up_all(¬if_wait->notif_waitq); |
| 119 | } | 120 | } |
| 120 | EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); | 121 | IWL_EXPORT_SYMBOL(iwl_notification_wait_notify); |
| 121 | 122 | ||
| 122 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | 123 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) |
| 123 | { | 124 | { |
| @@ -130,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | |||
| 130 | 131 | ||
| 131 | wake_up_all(¬if_wait->notif_waitq); | 132 | wake_up_all(¬if_wait->notif_waitq); |
| 132 | } | 133 | } |
| 133 | EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); | 134 | IWL_EXPORT_SYMBOL(iwl_abort_notification_waits); |
| 134 | 135 | ||
| 135 | void | 136 | void |
| 136 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | 137 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, |
| @@ -154,7 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | |||
| 154 | list_add(&wait_entry->list, ¬if_wait->notif_waits); | 155 | list_add(&wait_entry->list, ¬if_wait->notif_waits); |
| 155 | spin_unlock_bh(¬if_wait->notif_wait_lock); | 156 | spin_unlock_bh(¬if_wait->notif_wait_lock); |
| 156 | } | 157 | } |
| 157 | EXPORT_SYMBOL_GPL(iwl_init_notification_wait); | 158 | IWL_EXPORT_SYMBOL(iwl_init_notification_wait); |
| 158 | 159 | ||
| 159 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | 160 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, |
| 160 | struct iwl_notification_wait *wait_entry, | 161 | struct iwl_notification_wait *wait_entry, |
| @@ -178,7 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | |||
| 178 | return -ETIMEDOUT; | 179 | return -ETIMEDOUT; |
| 179 | return 0; | 180 | return 0; |
| 180 | } | 181 | } |
| 181 | EXPORT_SYMBOL_GPL(iwl_wait_notification); | 182 | IWL_EXPORT_SYMBOL(iwl_wait_notification); |
| 182 | 183 | ||
| 183 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | 184 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, |
| 184 | struct iwl_notification_wait *wait_entry) | 185 | struct iwl_notification_wait *wait_entry) |
| @@ -187,4 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | |||
| 187 | list_del(&wait_entry->list); | 188 | list_del(&wait_entry->list); |
| 188 | spin_unlock_bh(¬if_wait->notif_wait_lock); | 189 | spin_unlock_bh(¬if_wait->notif_wait_lock); |
| 189 | } | 190 | } |
| 190 | EXPORT_SYMBOL_GPL(iwl_remove_notification); | 191 | IWL_EXPORT_SYMBOL(iwl_remove_notification); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index c2ce764463a3..2e2f1c8c99f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index a70213bdb83c..6199a0a597a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <linux/types.h> | 62 | #include <linux/types.h> |
| 63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
| 64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
| 65 | #include "iwl-drv.h" | ||
| 65 | #include "iwl-modparams.h" | 66 | #include "iwl-modparams.h" |
| 66 | #include "iwl-nvm-parse.h" | 67 | #include "iwl-nvm-parse.h" |
| 67 | 68 | ||
| @@ -149,6 +150,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { | |||
| 149 | * @NVM_CHANNEL_DFS: dynamic freq selection candidate | 150 | * @NVM_CHANNEL_DFS: dynamic freq selection candidate |
| 150 | * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) | 151 | * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) |
| 151 | * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) | 152 | * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) |
| 153 | * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) | ||
| 154 | * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) | ||
| 152 | */ | 155 | */ |
| 153 | enum iwl_nvm_channel_flags { | 156 | enum iwl_nvm_channel_flags { |
| 154 | NVM_CHANNEL_VALID = BIT(0), | 157 | NVM_CHANNEL_VALID = BIT(0), |
| @@ -158,6 +161,8 @@ enum iwl_nvm_channel_flags { | |||
| 158 | NVM_CHANNEL_DFS = BIT(7), | 161 | NVM_CHANNEL_DFS = BIT(7), |
| 159 | NVM_CHANNEL_WIDE = BIT(8), | 162 | NVM_CHANNEL_WIDE = BIT(8), |
| 160 | NVM_CHANNEL_40MHZ = BIT(9), | 163 | NVM_CHANNEL_40MHZ = BIT(9), |
| 164 | NVM_CHANNEL_80MHZ = BIT(10), | ||
| 165 | NVM_CHANNEL_160MHZ = BIT(11), | ||
| 161 | }; | 166 | }; |
| 162 | 167 | ||
| 163 | #define CHECK_AND_PRINT_I(x) \ | 168 | #define CHECK_AND_PRINT_I(x) \ |
| @@ -210,6 +215,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 210 | else | 215 | else |
| 211 | channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; | 216 | channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; |
| 212 | } | 217 | } |
| 218 | if (!(ch_flags & NVM_CHANNEL_80MHZ)) | ||
| 219 | channel->flags |= IEEE80211_CHAN_NO_80MHZ; | ||
| 220 | if (!(ch_flags & NVM_CHANNEL_160MHZ)) | ||
| 221 | channel->flags |= IEEE80211_CHAN_NO_160MHZ; | ||
| 213 | 222 | ||
| 214 | if (!(ch_flags & NVM_CHANNEL_IBSS)) | 223 | if (!(ch_flags & NVM_CHANNEL_IBSS)) |
| 215 | channel->flags |= IEEE80211_CHAN_NO_IBSS; | 224 | channel->flags |= IEEE80211_CHAN_NO_IBSS; |
| @@ -245,6 +254,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 245 | return n_channels; | 254 | return n_channels; |
| 246 | } | 255 | } |
| 247 | 256 | ||
| 257 | static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, | ||
| 258 | struct iwl_nvm_data *data, | ||
| 259 | struct ieee80211_sta_vht_cap *vht_cap) | ||
| 260 | { | ||
| 261 | /* For now, assume new devices with NVM are VHT capable */ | ||
| 262 | |||
| 263 | vht_cap->vht_supported = true; | ||
| 264 | |||
| 265 | vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
| 266 | IEEE80211_VHT_CAP_RXSTBC_1 | | ||
| 267 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | | ||
| 268 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; | ||
| 269 | |||
| 270 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
| 271 | vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; | ||
| 272 | |||
| 273 | vht_cap->vht_mcs.rx_mcs_map = | ||
| 274 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | | ||
| 275 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | | ||
| 276 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | | ||
| 277 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | | ||
| 278 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | | ||
| 279 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | | ||
| 280 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | | ||
| 281 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); | ||
| 282 | |||
| 283 | if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { | ||
| 284 | vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | | ||
| 285 | IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; | ||
| 286 | /* this works because NOT_SUPPORTED == 3 */ | ||
| 287 | vht_cap->vht_mcs.rx_mcs_map |= | ||
| 288 | cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2); | ||
| 289 | } | ||
| 290 | |||
| 291 | vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; | ||
| 292 | } | ||
| 293 | |||
| 248 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | 294 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, |
| 249 | struct iwl_nvm_data *data, const __le16 *nvm_sw) | 295 | struct iwl_nvm_data *data, const __le16 *nvm_sw) |
| 250 | { | 296 | { |
| @@ -268,6 +314,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | |||
| 268 | n_used += iwl_init_sband_channels(data, sband, n_channels, | 314 | n_used += iwl_init_sband_channels(data, sband, n_channels, |
| 269 | IEEE80211_BAND_5GHZ); | 315 | IEEE80211_BAND_5GHZ); |
| 270 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); | 316 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); |
| 317 | iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); | ||
| 271 | 318 | ||
| 272 | if (n_channels != n_used) | 319 | if (n_channels != n_used) |
| 273 | IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", | 320 | IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", |
| @@ -343,4 +390,4 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
| 343 | 390 | ||
| 344 | return data; | 391 | return data; |
| 345 | } | 392 | } |
| 346 | EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); | 393 | IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index b2692bd287fa..e57fb989661e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 4a680019e117..98c7aa7346da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 14fc8d39fc28..25745daa0d5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -65,6 +65,7 @@ | |||
| 65 | #include <linux/string.h> | 65 | #include <linux/string.h> |
| 66 | #include <linux/export.h> | 66 | #include <linux/export.h> |
| 67 | 67 | ||
| 68 | #include "iwl-drv.h" | ||
| 68 | #include "iwl-phy-db.h" | 69 | #include "iwl-phy-db.h" |
| 69 | #include "iwl-debug.h" | 70 | #include "iwl-debug.h" |
| 70 | #include "iwl-op-mode.h" | 71 | #include "iwl-op-mode.h" |
| @@ -136,12 +137,6 @@ struct iwl_calib_res_notif_phy_db { | |||
| 136 | u8 data[]; | 137 | u8 data[]; |
| 137 | } __packed; | 138 | } __packed; |
| 138 | 139 | ||
| 139 | #define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587) | ||
| 140 | static inline void iwl_phy_db_test_pic(__le32 pic) | ||
| 141 | { | ||
| 142 | WARN_ON(IWL_PHY_DB_STATIC_PIC != pic); | ||
| 143 | } | ||
| 144 | |||
| 145 | struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) | 140 | struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) |
| 146 | { | 141 | { |
| 147 | struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), | 142 | struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), |
| @@ -155,7 +150,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) | |||
| 155 | /* TODO: add default values of the phy db. */ | 150 | /* TODO: add default values of the phy db. */ |
| 156 | return phy_db; | 151 | return phy_db; |
| 157 | } | 152 | } |
| 158 | EXPORT_SYMBOL(iwl_phy_db_init); | 153 | IWL_EXPORT_SYMBOL(iwl_phy_db_init); |
| 159 | 154 | ||
| 160 | /* | 155 | /* |
| 161 | * get phy db section: returns a pointer to a phy db section specified by | 156 | * get phy db section: returns a pointer to a phy db section specified by |
| @@ -221,7 +216,7 @@ void iwl_phy_db_free(struct iwl_phy_db *phy_db) | |||
| 221 | 216 | ||
| 222 | kfree(phy_db); | 217 | kfree(phy_db); |
| 223 | } | 218 | } |
| 224 | EXPORT_SYMBOL(iwl_phy_db_free); | 219 | IWL_EXPORT_SYMBOL(iwl_phy_db_free); |
| 225 | 220 | ||
| 226 | int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, | 221 | int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, |
| 227 | gfp_t alloc_ctx) | 222 | gfp_t alloc_ctx) |
| @@ -260,18 +255,13 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, | |||
| 260 | (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; | 255 | (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; |
| 261 | } | 256 | } |
| 262 | 257 | ||
| 263 | /* Test PIC */ | ||
| 264 | if (type != IWL_PHY_DB_CFG) | ||
| 265 | iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) + | ||
| 266 | (size / sizeof(__le32)) - 1)); | ||
| 267 | |||
| 268 | IWL_DEBUG_INFO(phy_db->trans, | 258 | IWL_DEBUG_INFO(phy_db->trans, |
| 269 | "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", | 259 | "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", |
| 270 | __func__, __LINE__, type, size); | 260 | __func__, __LINE__, type, size); |
| 271 | 261 | ||
| 272 | return 0; | 262 | return 0; |
| 273 | } | 263 | } |
| 274 | EXPORT_SYMBOL(iwl_phy_db_set_section); | 264 | IWL_EXPORT_SYMBOL(iwl_phy_db_set_section); |
| 275 | 265 | ||
| 276 | static int is_valid_channel(u16 ch_id) | 266 | static int is_valid_channel(u16 ch_id) |
| 277 | { | 267 | { |
| @@ -372,11 +362,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, | |||
| 372 | *size = entry->size; | 362 | *size = entry->size; |
| 373 | } | 363 | } |
| 374 | 364 | ||
| 375 | /* Test PIC */ | ||
| 376 | if (type != IWL_PHY_DB_CFG) | ||
| 377 | iwl_phy_db_test_pic(*(((__le32 *)*data) + | ||
| 378 | (*size / sizeof(__le32)) - 1)); | ||
| 379 | |||
| 380 | IWL_DEBUG_INFO(phy_db->trans, | 365 | IWL_DEBUG_INFO(phy_db->trans, |
| 381 | "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", | 366 | "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", |
| 382 | __func__, __LINE__, type, *size); | 367 | __func__, __LINE__, type, *size); |
| @@ -511,4 +496,4 @@ int iwl_send_phy_db_data(struct iwl_phy_db *phy_db) | |||
| 511 | "Finished sending phy db non channel data\n"); | 496 | "Finished sending phy db non channel data\n"); |
| 512 | return 0; | 497 | return 0; |
| 513 | } | 498 | } |
| 514 | EXPORT_SYMBOL(iwl_send_phy_db_data); | 499 | IWL_EXPORT_SYMBOL(iwl_send_phy_db_data); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h index d0e43d96ab38..ce983af79644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index f76e9cad7757..386f2a7c87cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index ce0c67b425ee..efff2986b5b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -64,6 +64,7 @@ | |||
| 64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
| 65 | #include <net/netlink.h> | 65 | #include <net/netlink.h> |
| 66 | 66 | ||
| 67 | #include "iwl-drv.h" | ||
| 67 | #include "iwl-io.h" | 68 | #include "iwl-io.h" |
| 68 | #include "iwl-fh.h" | 69 | #include "iwl-fh.h" |
| 69 | #include "iwl-prph.h" | 70 | #include "iwl-prph.h" |
| @@ -653,7 +654,7 @@ int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, | |||
| 653 | } | 654 | } |
| 654 | return 0; | 655 | return 0; |
| 655 | } | 656 | } |
| 656 | EXPORT_SYMBOL_GPL(iwl_test_parse); | 657 | IWL_EXPORT_SYMBOL(iwl_test_parse); |
| 657 | 658 | ||
| 658 | /* | 659 | /* |
| 659 | * Handle test commands. | 660 | * Handle test commands. |
| @@ -715,7 +716,7 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb) | |||
| 715 | } | 716 | } |
| 716 | return result; | 717 | return result; |
| 717 | } | 718 | } |
| 718 | EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); | 719 | IWL_EXPORT_SYMBOL(iwl_test_handle_cmd); |
| 719 | 720 | ||
| 720 | static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, | 721 | static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, |
| 721 | struct netlink_callback *cb) | 722 | struct netlink_callback *cb) |
| @@ -803,7 +804,7 @@ int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, | |||
| 803 | } | 804 | } |
| 804 | return result; | 805 | return result; |
| 805 | } | 806 | } |
| 806 | EXPORT_SYMBOL_GPL(iwl_test_dump); | 807 | IWL_EXPORT_SYMBOL(iwl_test_dump); |
| 807 | 808 | ||
| 808 | /* | 809 | /* |
| 809 | * Multicast a spontaneous messages from the device to the user space. | 810 | * Multicast a spontaneous messages from the device to the user space. |
| @@ -849,4 +850,4 @@ void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) | |||
| 849 | if (tst->notify) | 850 | if (tst->notify) |
| 850 | iwl_test_send_rx(tst, rxb); | 851 | iwl_test_send_rx(tst, rxb); |
| 851 | } | 852 | } |
| 852 | EXPORT_SYMBOL_GPL(iwl_test_rx); | 853 | IWL_EXPORT_SYMBOL(iwl_test_rx); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h index 7fbf4d717caa..8fbd21704840 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.h +++ b/drivers/net/wireless/iwlwifi/iwl-test.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index a963f45c6849..98f48a9afc98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 00bdc5b00af3..7f9c254292a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -183,19 +183,13 @@ struct iwl_rx_packet { | |||
| 183 | * @CMD_ASYNC: Return right away and don't want for the response | 183 | * @CMD_ASYNC: Return right away and don't want for the response |
| 184 | * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the | 184 | * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the |
| 185 | * response. The caller needs to call iwl_free_resp when done. | 185 | * response. The caller needs to call iwl_free_resp when done. |
| 186 | * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the | ||
| 187 | * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be | ||
| 188 | * copied. The pointer passed to the response handler is in the transport | ||
| 189 | * ownership and don't need to be freed by the op_mode. This also means | ||
| 190 | * that the pointer is invalidated after the op_mode's handler returns. | ||
| 191 | * @CMD_ON_DEMAND: This command is sent by the test mode pipe. | 186 | * @CMD_ON_DEMAND: This command is sent by the test mode pipe. |
| 192 | */ | 187 | */ |
| 193 | enum CMD_MODE { | 188 | enum CMD_MODE { |
| 194 | CMD_SYNC = 0, | 189 | CMD_SYNC = 0, |
| 195 | CMD_ASYNC = BIT(0), | 190 | CMD_ASYNC = BIT(0), |
| 196 | CMD_WANT_SKB = BIT(1), | 191 | CMD_WANT_SKB = BIT(1), |
| 197 | CMD_WANT_HCMD = BIT(2), | 192 | CMD_ON_DEMAND = BIT(2), |
| 198 | CMD_ON_DEMAND = BIT(3), | ||
| 199 | }; | 193 | }; |
| 200 | 194 | ||
| 201 | #define DEF_CMD_PAYLOAD_SIZE 320 | 195 | #define DEF_CMD_PAYLOAD_SIZE 320 |
| @@ -214,7 +208,11 @@ struct iwl_device_cmd { | |||
| 214 | 208 | ||
| 215 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) | 209 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) |
| 216 | 210 | ||
| 217 | #define IWL_MAX_CMD_TFDS 2 | 211 | /* |
| 212 | * number of transfer buffers (fragments) per transmit frame descriptor; | ||
| 213 | * this is just the driver's idea, the hardware supports 20 | ||
| 214 | */ | ||
| 215 | #define IWL_MAX_CMD_TBS_PER_TFD 2 | ||
| 218 | 216 | ||
| 219 | /** | 217 | /** |
| 220 | * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command | 218 | * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command |
| @@ -251,15 +249,15 @@ enum iwl_hcmd_dataflag { | |||
| 251 | * @id: id of the host command | 249 | * @id: id of the host command |
| 252 | */ | 250 | */ |
| 253 | struct iwl_host_cmd { | 251 | struct iwl_host_cmd { |
| 254 | const void *data[IWL_MAX_CMD_TFDS]; | 252 | const void *data[IWL_MAX_CMD_TBS_PER_TFD]; |
| 255 | struct iwl_rx_packet *resp_pkt; | 253 | struct iwl_rx_packet *resp_pkt; |
| 256 | unsigned long _rx_page_addr; | 254 | unsigned long _rx_page_addr; |
| 257 | u32 _rx_page_order; | 255 | u32 _rx_page_order; |
| 258 | int handler_status; | 256 | int handler_status; |
| 259 | 257 | ||
| 260 | u32 flags; | 258 | u32 flags; |
| 261 | u16 len[IWL_MAX_CMD_TFDS]; | 259 | u16 len[IWL_MAX_CMD_TBS_PER_TFD]; |
| 262 | u8 dataflags[IWL_MAX_CMD_TFDS]; | 260 | u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD]; |
| 263 | u8 id; | 261 | u8 id; |
| 264 | }; | 262 | }; |
| 265 | 263 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile index 807b250ec396..2acc44b40986 100644 --- a/drivers/net/wireless/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/iwlwifi/mvm/Makefile | |||
| @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o | |||
| 2 | iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o | 2 | iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o |
| 3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o | 3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o |
| 4 | iwlmvm-y += scan.o time-event.o rs.o | 4 | iwlmvm-y += scan.o time-event.o rs.o |
| 5 | iwlmvm-y += power.o | 5 | iwlmvm-y += power.o bt-coex.o |
| 6 | iwlmvm-y += led.o | 6 | iwlmvm-y += led.o |
| 7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o | 7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o |
| 8 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o | 8 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o |
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c index 73d24aacb90a..93fd1457954b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/binding.c +++ b/drivers/net/wireless/iwlwifi/mvm/binding.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c new file mode 100644 index 000000000000..47954deb6493 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
| @@ -0,0 +1,347 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
| 4 | * redistributing this file, you may do so under either license. | ||
| 5 | * | ||
| 6 | * GPL LICENSE SUMMARY | ||
| 7 | * | ||
| 8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
| 22 | * USA | ||
| 23 | * | ||
| 24 | * The full GNU General Public License is included in this distribution | ||
| 25 | * in the file called COPYING. | ||
| 26 | * | ||
| 27 | * Contact Information: | ||
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
| 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 30 | * | ||
| 31 | * BSD LICENSE | ||
| 32 | * | ||
| 33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | ||
| 34 | * All rights reserved. | ||
| 35 | * | ||
| 36 | * Redistribution and use in source and binary forms, with or without | ||
| 37 | * modification, are permitted provided that the following conditions | ||
| 38 | * are met: | ||
| 39 | * | ||
| 40 | * * Redistributions of source code must retain the above copyright | ||
| 41 | * notice, this list of conditions and the following disclaimer. | ||
| 42 | * * Redistributions in binary form must reproduce the above copyright | ||
| 43 | * notice, this list of conditions and the following disclaimer in | ||
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | ||
| 46 | * * Neither the name Intel Corporation nor the names of its | ||
| 47 | * contributors may be used to endorse or promote products derived | ||
| 48 | * from this software without specific prior written permission. | ||
| 49 | * | ||
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 61 | * | ||
| 62 | *****************************************************************************/ | ||
| 63 | |||
| 64 | #include "fw-api-bt-coex.h" | ||
| 65 | #include "iwl-modparams.h" | ||
| 66 | #include "mvm.h" | ||
| 67 | #include "iwl-debug.h" | ||
| 68 | |||
| 69 | #define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ | ||
| 70 | [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ | ||
| 71 | ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS)) | ||
| 72 | |||
| 73 | static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | ||
| 74 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1, | ||
| 75 | BT_COEX_PRIO_TBL_PRIO_BYPASS, 0), | ||
| 76 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2, | ||
| 77 | BT_COEX_PRIO_TBL_PRIO_BYPASS, 1), | ||
| 78 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1, | ||
| 79 | BT_COEX_PRIO_TBL_PRIO_LOW, 0), | ||
| 80 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2, | ||
| 81 | BT_COEX_PRIO_TBL_PRIO_LOW, 1), | ||
| 82 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1, | ||
| 83 | BT_COEX_PRIO_TBL_PRIO_HIGH, 0), | ||
| 84 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2, | ||
| 85 | BT_COEX_PRIO_TBL_PRIO_HIGH, 1), | ||
| 86 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM, | ||
| 87 | BT_COEX_PRIO_TBL_DISABLED, 0), | ||
| 88 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52, | ||
| 89 | BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0), | ||
| 90 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24, | ||
| 91 | BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0), | ||
| 92 | EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE, | ||
| 93 | BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0), | ||
| 94 | 0, 0, 0, 0, 0, 0, | ||
| 95 | }; | ||
| 96 | |||
| 97 | #undef EVENT_PRIO_ANT | ||
| 98 | |||
| 99 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) | ||
| 100 | { | ||
| 101 | return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, | ||
| 102 | sizeof(struct iwl_bt_coex_prio_tbl_cmd), | ||
| 103 | &iwl_bt_prio_tbl); | ||
| 104 | } | ||
| 105 | |||
| 106 | static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type) | ||
| 107 | { | ||
| 108 | struct iwl_bt_coex_prot_env_cmd env_cmd; | ||
| 109 | int ret; | ||
| 110 | |||
| 111 | env_cmd.action = action; | ||
| 112 | env_cmd.type = type; | ||
| 113 | ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC, | ||
| 114 | sizeof(env_cmd), &env_cmd); | ||
| 115 | if (ret) | ||
| 116 | IWL_ERR(mvm, "failed to send BT env command\n"); | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | enum iwl_bt_kill_msk { | ||
| 121 | BT_KILL_MSK_DEFAULT, | ||
| 122 | BT_KILL_MSK_SCO_HID_A2DP, | ||
| 123 | BT_KILL_MSK_REDUCED_TXPOW, | ||
| 124 | BT_KILL_MSK_MAX, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { | ||
| 128 | 0xffffffff, | ||
| 129 | 0xfffffc00, | ||
| 130 | 0, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { | ||
| 134 | 0xffffffff, | ||
| 135 | 0xfffffc00, | ||
| 136 | 0, | ||
| 137 | }; | ||
| 138 | |||
| 139 | #define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) | ||
| 140 | |||
| 141 | /* Tight Coex */ | ||
| 142 | static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = { | ||
| 143 | cpu_to_le32(0xaaaaaaaa), | ||
| 144 | cpu_to_le32(0xaaaaaaaa), | ||
| 145 | cpu_to_le32(0xaeaaaaaa), | ||
| 146 | cpu_to_le32(0xaaaaaaaa), | ||
| 147 | cpu_to_le32(0xcc00ff28), | ||
| 148 | cpu_to_le32(0x0000aaaa), | ||
| 149 | cpu_to_le32(0xcc00aaaa), | ||
| 150 | cpu_to_le32(0x0000aaaa), | ||
| 151 | cpu_to_le32(0xc0004000), | ||
| 152 | cpu_to_le32(0x00000000), | ||
| 153 | cpu_to_le32(0xf0005000), | ||
| 154 | cpu_to_le32(0xf0005000), | ||
| 155 | }; | ||
| 156 | |||
| 157 | /* Loose Coex */ | ||
| 158 | static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { | ||
| 159 | cpu_to_le32(0xaaaaaaaa), | ||
| 160 | cpu_to_le32(0xaaaaaaaa), | ||
| 161 | cpu_to_le32(0xaeaaaaaa), | ||
| 162 | cpu_to_le32(0xaaaaaaaa), | ||
| 163 | cpu_to_le32(0xcc00ff28), | ||
| 164 | cpu_to_le32(0x0000aaaa), | ||
| 165 | cpu_to_le32(0xcc00aaaa), | ||
| 166 | cpu_to_le32(0x0000aaaa), | ||
| 167 | cpu_to_le32(0x00000000), | ||
| 168 | cpu_to_le32(0x00000000), | ||
| 169 | cpu_to_le32(0xf0005000), | ||
| 170 | cpu_to_le32(0xf0005000), | ||
| 171 | }; | ||
| 172 | |||
| 173 | /* Full concurrency */ | ||
| 174 | static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { | ||
| 175 | cpu_to_le32(0xaaaaaaaa), | ||
| 176 | cpu_to_le32(0xaaaaaaaa), | ||
| 177 | cpu_to_le32(0xaaaaaaaa), | ||
| 178 | cpu_to_le32(0xaaaaaaaa), | ||
| 179 | cpu_to_le32(0xaaaaaaaa), | ||
| 180 | cpu_to_le32(0xaaaaaaaa), | ||
| 181 | cpu_to_le32(0xaaaaaaaa), | ||
| 182 | cpu_to_le32(0xaaaaaaaa), | ||
| 183 | cpu_to_le32(0x00000000), | ||
| 184 | cpu_to_le32(0x00000000), | ||
| 185 | cpu_to_le32(0x00000000), | ||
| 186 | cpu_to_le32(0x00000000), | ||
| 187 | }; | ||
| 188 | |||
| 189 | /* BT Antenna Coupling Threshold (dB) */ | ||
| 190 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | ||
| 191 | |||
| 192 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | ||
| 193 | { | ||
| 194 | struct iwl_bt_coex_cmd cmd = { | ||
| 195 | .max_kill = 5, | ||
| 196 | .bt3_time_t7_value = 1, | ||
| 197 | .bt3_prio_sample_time = 2, | ||
| 198 | .bt3_timer_t2_value = 0xc, | ||
| 199 | }; | ||
| 200 | int ret; | ||
| 201 | |||
| 202 | cmd.flags = iwlwifi_mod_params.bt_coex_active ? | ||
| 203 | BT_COEX_NW : BT_COEX_DISABLE; | ||
| 204 | cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? | ||
| 205 | BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0; | ||
| 206 | cmd.flags |= BT_SYNC_2_BT_DISABLE; | ||
| 207 | |||
| 208 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | | ||
| 209 | BT_VALID_BT_PRIO_BOOST | | ||
| 210 | BT_VALID_MAX_KILL | | ||
| 211 | BT_VALID_3W_TMRS | | ||
| 212 | BT_VALID_KILL_ACK | | ||
| 213 | BT_VALID_KILL_CTS | | ||
| 214 | BT_VALID_REDUCED_TX_POWER | | ||
| 215 | BT_VALID_LUT); | ||
| 216 | |||
| 217 | if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) | ||
| 218 | memcpy(&cmd.decision_lut, iwl_loose_lookup, | ||
| 219 | sizeof(iwl_tight_lookup)); | ||
| 220 | else | ||
| 221 | memcpy(&cmd.decision_lut, iwl_tight_lookup, | ||
| 222 | sizeof(iwl_tight_lookup)); | ||
| 223 | |||
| 224 | cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); | ||
| 225 | cmd.kill_ack_msk = | ||
| 226 | cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); | ||
| 227 | cmd.kill_cts_msk = | ||
| 228 | cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); | ||
| 229 | |||
| 230 | /* go to CALIB state in internal BT-Coex state machine */ | ||
| 231 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, | ||
| 232 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||
| 233 | if (ret) | ||
| 234 | return ret; | ||
| 235 | |||
| 236 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE, | ||
| 237 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||
| 238 | if (ret) | ||
| 239 | return ret; | ||
| 240 | |||
| 241 | return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, | ||
| 242 | sizeof(cmd), &cmd); | ||
| 243 | } | ||
| 244 | |||
| 245 | struct iwl_bt_notif_iterator_data { | ||
| 246 | struct iwl_mvm *mvm; | ||
| 247 | struct iwl_bt_coex_profile_notif *notif; | ||
| 248 | }; | ||
| 249 | |||
| 250 | static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | ||
| 251 | struct ieee80211_vif *vif) | ||
| 252 | { | ||
| 253 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 254 | struct iwl_bt_notif_iterator_data *data = _data; | ||
| 255 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 256 | enum ieee80211_smps_mode smps_mode; | ||
| 257 | enum ieee80211_band band; | ||
| 258 | |||
| 259 | if (vif->type != NL80211_IFTYPE_STATION) | ||
| 260 | return; | ||
| 261 | |||
| 262 | rcu_read_lock(); | ||
| 263 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
| 264 | if (chanctx_conf && chanctx_conf->def.chan) | ||
| 265 | band = chanctx_conf->def.chan->band; | ||
| 266 | else | ||
| 267 | band = -1; | ||
| 268 | rcu_read_unlock(); | ||
| 269 | |||
| 270 | if (band != IEEE80211_BAND_2GHZ) | ||
| 271 | return; | ||
| 272 | |||
| 273 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
| 274 | |||
| 275 | if (data->notif->bt_status) | ||
| 276 | smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
| 277 | |||
| 278 | if (data->notif->bt_traffic_load) | ||
| 279 | smps_mode = IEEE80211_SMPS_STATIC; | ||
| 280 | |||
| 281 | IWL_DEBUG_COEX(data->mvm, | ||
| 282 | "mac %d: bt_status %d traffic_load %d smps_req %d\n", | ||
| 283 | mvmvif->id, data->notif->bt_status, | ||
| 284 | data->notif->bt_traffic_load, smps_mode); | ||
| 285 | |||
| 286 | ieee80211_request_smps(vif, smps_mode); | ||
| 287 | } | ||
| 288 | |||
| 289 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | ||
| 290 | struct iwl_rx_cmd_buffer *rxb, | ||
| 291 | struct iwl_device_cmd *dev_cmd) | ||
| 292 | { | ||
| 293 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
| 294 | struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; | ||
| 295 | struct iwl_bt_notif_iterator_data data = { | ||
| 296 | .mvm = mvm, | ||
| 297 | .notif = notif, | ||
| 298 | }; | ||
| 299 | struct iwl_bt_coex_cmd cmd = {}; | ||
| 300 | enum iwl_bt_kill_msk bt_kill_msk; | ||
| 301 | |||
| 302 | IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); | ||
| 303 | IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); | ||
| 304 | IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn); | ||
| 305 | IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load); | ||
| 306 | IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n", | ||
| 307 | notif->bt_agg_traffic_load); | ||
| 308 | IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); | ||
| 309 | |||
| 310 | /* remember this notification for future use: rssi fluctuations */ | ||
| 311 | memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); | ||
| 312 | |||
| 313 | ieee80211_iterate_active_interfaces_atomic( | ||
| 314 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
| 315 | iwl_mvm_bt_notif_iterator, &data); | ||
| 316 | |||
| 317 | /* Low latency BT profile is active: give higher prio to BT */ | ||
| 318 | if (BT_MBOX_MSG(notif, 3, SCO_STATE) || | ||
| 319 | BT_MBOX_MSG(notif, 3, A2DP_STATE) || | ||
| 320 | BT_MBOX_MSG(notif, 3, SNIFF_STATE)) | ||
| 321 | bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; | ||
| 322 | else | ||
| 323 | bt_kill_msk = BT_KILL_MSK_DEFAULT; | ||
| 324 | |||
| 325 | /* Don't send HCMD if there is no update */ | ||
| 326 | if (bt_kill_msk == mvm->bt_kill_msk) | ||
| 327 | return 0; | ||
| 328 | |||
| 329 | IWL_DEBUG_COEX(mvm, | ||
| 330 | "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n", | ||
| 331 | bt_kill_msk, | ||
| 332 | BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", | ||
| 333 | BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", | ||
| 334 | BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); | ||
| 335 | |||
| 336 | mvm->bt_kill_msk = bt_kill_msk; | ||
| 337 | cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); | ||
| 338 | cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); | ||
| 339 | |||
| 340 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); | ||
| 341 | |||
| 342 | if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) | ||
| 343 | IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); | ||
| 344 | |||
| 345 | /* This handler is ASYNC */ | ||
| 346 | return 0; | ||
| 347 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c64d864799cd..d4578cefe445 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -61,8 +61,11 @@ | |||
| 61 | * | 61 | * |
| 62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
| 63 | 63 | ||
| 64 | #include <linux/etherdevice.h> | ||
| 65 | #include <linux/ip.h> | ||
| 64 | #include <net/cfg80211.h> | 66 | #include <net/cfg80211.h> |
| 65 | #include <net/ipv6.h> | 67 | #include <net/ipv6.h> |
| 68 | #include <net/tcp.h> | ||
| 66 | #include "iwl-modparams.h" | 69 | #include "iwl-modparams.h" |
| 67 | #include "fw-api.h" | 70 | #include "fw-api.h" |
| 68 | #include "mvm.h" | 71 | #include "mvm.h" |
| @@ -192,6 +195,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 192 | sizeof(wkc), &wkc); | 195 | sizeof(wkc), &wkc); |
| 193 | data->error = ret != 0; | 196 | data->error = ret != 0; |
| 194 | 197 | ||
| 198 | mvm->ptk_ivlen = key->iv_len; | ||
| 199 | mvm->ptk_icvlen = key->icv_len; | ||
| 200 | mvm->gtk_ivlen = key->iv_len; | ||
| 201 | mvm->gtk_icvlen = key->icv_len; | ||
| 202 | |||
| 195 | /* don't upload key again */ | 203 | /* don't upload key again */ |
| 196 | goto out_unlock; | 204 | goto out_unlock; |
| 197 | } | 205 | } |
| @@ -304,9 +312,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 304 | */ | 312 | */ |
| 305 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { | 313 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
| 306 | key->hw_key_idx = 0; | 314 | key->hw_key_idx = 0; |
| 315 | mvm->ptk_ivlen = key->iv_len; | ||
| 316 | mvm->ptk_icvlen = key->icv_len; | ||
| 307 | } else { | 317 | } else { |
| 308 | data->gtk_key_idx++; | 318 | data->gtk_key_idx++; |
| 309 | key->hw_key_idx = data->gtk_key_idx; | 319 | key->hw_key_idx = data->gtk_key_idx; |
| 320 | mvm->gtk_ivlen = key->iv_len; | ||
| 321 | mvm->gtk_icvlen = key->icv_len; | ||
| 310 | } | 322 | } |
| 311 | 323 | ||
| 312 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); | 324 | ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); |
| @@ -392,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, | |||
| 392 | sizeof(cmd), &cmd); | 404 | sizeof(cmd), &cmd); |
| 393 | } | 405 | } |
| 394 | 406 | ||
| 407 | enum iwl_mvm_tcp_packet_type { | ||
| 408 | MVM_TCP_TX_SYN, | ||
| 409 | MVM_TCP_RX_SYNACK, | ||
| 410 | MVM_TCP_TX_DATA, | ||
| 411 | MVM_TCP_RX_ACK, | ||
| 412 | MVM_TCP_RX_WAKE, | ||
| 413 | MVM_TCP_TX_FIN, | ||
| 414 | }; | ||
| 415 | |||
| 416 | static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr) | ||
| 417 | { | ||
| 418 | __sum16 check = tcp_v4_check(len, saddr, daddr, 0); | ||
| 419 | return cpu_to_le16(be16_to_cpu((__force __be16)check)); | ||
| 420 | } | ||
| 421 | |||
| 422 | static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm, | ||
| 423 | struct ieee80211_vif *vif, | ||
| 424 | struct cfg80211_wowlan_tcp *tcp, | ||
| 425 | void *_pkt, u8 *mask, | ||
| 426 | __le16 *pseudo_hdr_csum, | ||
| 427 | enum iwl_mvm_tcp_packet_type ptype) | ||
| 428 | { | ||
| 429 | struct { | ||
| 430 | struct ethhdr eth; | ||
| 431 | struct iphdr ip; | ||
| 432 | struct tcphdr tcp; | ||
| 433 | u8 data[]; | ||
| 434 | } __packed *pkt = _pkt; | ||
| 435 | u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); | ||
| 436 | int i; | ||
| 437 | |||
| 438 | pkt->eth.h_proto = cpu_to_be16(ETH_P_IP), | ||
| 439 | pkt->ip.version = 4; | ||
| 440 | pkt->ip.ihl = 5; | ||
| 441 | pkt->ip.protocol = IPPROTO_TCP; | ||
| 442 | |||
| 443 | switch (ptype) { | ||
| 444 | case MVM_TCP_TX_SYN: | ||
| 445 | case MVM_TCP_TX_DATA: | ||
| 446 | case MVM_TCP_TX_FIN: | ||
| 447 | memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN); | ||
| 448 | memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN); | ||
| 449 | pkt->ip.ttl = 128; | ||
| 450 | pkt->ip.saddr = tcp->src; | ||
| 451 | pkt->ip.daddr = tcp->dst; | ||
| 452 | pkt->tcp.source = cpu_to_be16(tcp->src_port); | ||
| 453 | pkt->tcp.dest = cpu_to_be16(tcp->dst_port); | ||
| 454 | /* overwritten for TX SYN later */ | ||
| 455 | pkt->tcp.doff = sizeof(struct tcphdr) / 4; | ||
| 456 | pkt->tcp.window = cpu_to_be16(65000); | ||
| 457 | break; | ||
| 458 | case MVM_TCP_RX_SYNACK: | ||
| 459 | case MVM_TCP_RX_ACK: | ||
| 460 | case MVM_TCP_RX_WAKE: | ||
| 461 | memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN); | ||
| 462 | memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN); | ||
| 463 | pkt->ip.saddr = tcp->dst; | ||
| 464 | pkt->ip.daddr = tcp->src; | ||
| 465 | pkt->tcp.source = cpu_to_be16(tcp->dst_port); | ||
| 466 | pkt->tcp.dest = cpu_to_be16(tcp->src_port); | ||
| 467 | break; | ||
| 468 | default: | ||
| 469 | WARN_ON(1); | ||
| 470 | return; | ||
| 471 | } | ||
| 472 | |||
| 473 | switch (ptype) { | ||
| 474 | case MVM_TCP_TX_SYN: | ||
| 475 | /* firmware assumes 8 option bytes - 8 NOPs for now */ | ||
| 476 | memset(pkt->data, 0x01, 8); | ||
| 477 | ip_tot_len += 8; | ||
| 478 | pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4; | ||
| 479 | pkt->tcp.syn = 1; | ||
| 480 | break; | ||
| 481 | case MVM_TCP_TX_DATA: | ||
| 482 | ip_tot_len += tcp->payload_len; | ||
| 483 | memcpy(pkt->data, tcp->payload, tcp->payload_len); | ||
| 484 | pkt->tcp.psh = 1; | ||
| 485 | pkt->tcp.ack = 1; | ||
| 486 | break; | ||
| 487 | case MVM_TCP_TX_FIN: | ||
| 488 | pkt->tcp.fin = 1; | ||
| 489 | pkt->tcp.ack = 1; | ||
| 490 | break; | ||
| 491 | case MVM_TCP_RX_SYNACK: | ||
| 492 | pkt->tcp.syn = 1; | ||
| 493 | pkt->tcp.ack = 1; | ||
| 494 | break; | ||
| 495 | case MVM_TCP_RX_ACK: | ||
| 496 | pkt->tcp.ack = 1; | ||
| 497 | break; | ||
| 498 | case MVM_TCP_RX_WAKE: | ||
| 499 | ip_tot_len += tcp->wake_len; | ||
| 500 | pkt->tcp.psh = 1; | ||
| 501 | pkt->tcp.ack = 1; | ||
| 502 | memcpy(pkt->data, tcp->wake_data, tcp->wake_len); | ||
| 503 | break; | ||
| 504 | } | ||
| 505 | |||
| 506 | switch (ptype) { | ||
| 507 | case MVM_TCP_TX_SYN: | ||
| 508 | case MVM_TCP_TX_DATA: | ||
| 509 | case MVM_TCP_TX_FIN: | ||
| 510 | pkt->ip.tot_len = cpu_to_be16(ip_tot_len); | ||
| 511 | pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl); | ||
| 512 | break; | ||
| 513 | case MVM_TCP_RX_WAKE: | ||
| 514 | for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) { | ||
| 515 | u8 tmp = tcp->wake_mask[i]; | ||
| 516 | mask[i + 6] |= tmp << 6; | ||
| 517 | if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8)) | ||
| 518 | mask[i + 7] = tmp >> 2; | ||
| 519 | } | ||
| 520 | /* fall through for ethernet/IP/TCP headers mask */ | ||
| 521 | case MVM_TCP_RX_SYNACK: | ||
| 522 | case MVM_TCP_RX_ACK: | ||
| 523 | mask[0] = 0xff; /* match ethernet */ | ||
| 524 | /* | ||
| 525 | * match ethernet, ip.version, ip.ihl | ||
| 526 | * the ip.ihl half byte is really masked out by firmware | ||
| 527 | */ | ||
| 528 | mask[1] = 0x7f; | ||
| 529 | mask[2] = 0x80; /* match ip.protocol */ | ||
| 530 | mask[3] = 0xfc; /* match ip.saddr, ip.daddr */ | ||
| 531 | mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */ | ||
| 532 | mask[5] = 0x80; /* match tcp flags */ | ||
| 533 | /* leave rest (0 or set for MVM_TCP_RX_WAKE) */ | ||
| 534 | break; | ||
| 535 | }; | ||
| 536 | |||
| 537 | *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr), | ||
| 538 | pkt->ip.saddr, pkt->ip.daddr); | ||
| 539 | } | ||
| 540 | |||
| 541 | static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, | ||
| 542 | struct ieee80211_vif *vif, | ||
| 543 | struct cfg80211_wowlan_tcp *tcp) | ||
| 544 | { | ||
| 545 | struct iwl_wowlan_remote_wake_config *cfg; | ||
| 546 | struct iwl_host_cmd cmd = { | ||
| 547 | .id = REMOTE_WAKE_CONFIG_CMD, | ||
| 548 | .len = { sizeof(*cfg), }, | ||
| 549 | .dataflags = { IWL_HCMD_DFL_NOCOPY, }, | ||
| 550 | .flags = CMD_SYNC, | ||
| 551 | }; | ||
| 552 | int ret; | ||
| 553 | |||
| 554 | if (!tcp) | ||
| 555 | return 0; | ||
| 556 | |||
| 557 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); | ||
| 558 | if (!cfg) | ||
| 559 | return -ENOMEM; | ||
| 560 | cmd.data[0] = cfg; | ||
| 561 | |||
| 562 | cfg->max_syn_retries = 10; | ||
| 563 | cfg->max_data_retries = 10; | ||
| 564 | cfg->tcp_syn_ack_timeout = 1; /* seconds */ | ||
| 565 | cfg->tcp_ack_timeout = 1; /* seconds */ | ||
| 566 | |||
| 567 | /* SYN (TX) */ | ||
| 568 | iwl_mvm_build_tcp_packet( | ||
| 569 | mvm, vif, tcp, cfg->syn_tx.data, NULL, | ||
| 570 | &cfg->syn_tx.info.tcp_pseudo_header_checksum, | ||
| 571 | MVM_TCP_TX_SYN); | ||
| 572 | cfg->syn_tx.info.tcp_payload_length = 0; | ||
| 573 | |||
| 574 | /* SYN/ACK (RX) */ | ||
| 575 | iwl_mvm_build_tcp_packet( | ||
| 576 | mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask, | ||
| 577 | &cfg->synack_rx.info.tcp_pseudo_header_checksum, | ||
| 578 | MVM_TCP_RX_SYNACK); | ||
| 579 | cfg->synack_rx.info.tcp_payload_length = 0; | ||
| 580 | |||
| 581 | /* KEEPALIVE/ACK (TX) */ | ||
| 582 | iwl_mvm_build_tcp_packet( | ||
| 583 | mvm, vif, tcp, cfg->keepalive_tx.data, NULL, | ||
| 584 | &cfg->keepalive_tx.info.tcp_pseudo_header_checksum, | ||
| 585 | MVM_TCP_TX_DATA); | ||
| 586 | cfg->keepalive_tx.info.tcp_payload_length = | ||
| 587 | cpu_to_le16(tcp->payload_len); | ||
| 588 | cfg->sequence_number_offset = tcp->payload_seq.offset; | ||
| 589 | /* length must be 0..4, the field is little endian */ | ||
| 590 | cfg->sequence_number_length = tcp->payload_seq.len; | ||
| 591 | cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start); | ||
| 592 | cfg->keepalive_interval = cpu_to_le16(tcp->data_interval); | ||
| 593 | if (tcp->payload_tok.len) { | ||
| 594 | cfg->token_offset = tcp->payload_tok.offset; | ||
| 595 | cfg->token_length = tcp->payload_tok.len; | ||
| 596 | cfg->num_tokens = | ||
| 597 | cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len); | ||
| 598 | memcpy(cfg->tokens, tcp->payload_tok.token_stream, | ||
| 599 | tcp->tokens_size); | ||
| 600 | } else { | ||
| 601 | /* set tokens to max value to almost never run out */ | ||
| 602 | cfg->num_tokens = cpu_to_le16(65535); | ||
| 603 | } | ||
| 604 | |||
| 605 | /* ACK (RX) */ | ||
| 606 | iwl_mvm_build_tcp_packet( | ||
| 607 | mvm, vif, tcp, cfg->keepalive_ack_rx.data, | ||
| 608 | cfg->keepalive_ack_rx.rx_mask, | ||
| 609 | &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum, | ||
| 610 | MVM_TCP_RX_ACK); | ||
| 611 | cfg->keepalive_ack_rx.info.tcp_payload_length = 0; | ||
| 612 | |||
| 613 | /* WAKEUP (RX) */ | ||
| 614 | iwl_mvm_build_tcp_packet( | ||
| 615 | mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask, | ||
| 616 | &cfg->wake_rx.info.tcp_pseudo_header_checksum, | ||
| 617 | MVM_TCP_RX_WAKE); | ||
| 618 | cfg->wake_rx.info.tcp_payload_length = | ||
| 619 | cpu_to_le16(tcp->wake_len); | ||
| 620 | |||
| 621 | /* FIN */ | ||
| 622 | iwl_mvm_build_tcp_packet( | ||
| 623 | mvm, vif, tcp, cfg->fin_tx.data, NULL, | ||
| 624 | &cfg->fin_tx.info.tcp_pseudo_header_checksum, | ||
| 625 | MVM_TCP_TX_FIN); | ||
| 626 | cfg->fin_tx.info.tcp_payload_length = 0; | ||
| 627 | |||
| 628 | ret = iwl_mvm_send_cmd(mvm, &cmd); | ||
| 629 | kfree(cfg); | ||
| 630 | |||
| 631 | return ret; | ||
| 632 | } | ||
| 633 | |||
| 395 | struct iwl_d3_iter_data { | 634 | struct iwl_d3_iter_data { |
| 396 | struct iwl_mvm *mvm; | 635 | struct iwl_mvm *mvm; |
| 397 | struct ieee80211_vif *vif; | 636 | struct ieee80211_vif *vif; |
| @@ -630,6 +869,22 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 630 | d3_cfg_cmd.wakeup_flags |= | 869 | d3_cfg_cmd.wakeup_flags |= |
| 631 | cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); | 870 | cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); |
| 632 | 871 | ||
| 872 | if (wowlan->tcp) { | ||
| 873 | /* | ||
| 874 | * The firmware currently doesn't really look at these, only | ||
| 875 | * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that | ||
| 876 | * reason bit since losing the connection to the AP implies | ||
| 877 | * losing the TCP connection. | ||
| 878 | * Set the flags anyway as long as they exist, in case this | ||
| 879 | * will be changed in the firmware. | ||
| 880 | */ | ||
| 881 | wowlan_config_cmd.wakeup_filter |= | ||
| 882 | cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | | ||
| 883 | IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | | ||
| 884 | IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | | ||
| 885 | IWL_WOWLAN_WAKEUP_LINK_CHANGE); | ||
| 886 | } | ||
| 887 | |||
| 633 | iwl_mvm_cancel_scan(mvm); | 888 | iwl_mvm_cancel_scan(mvm); |
| 634 | 889 | ||
| 635 | iwl_trans_stop_device(mvm->trans); | 890 | iwl_trans_stop_device(mvm->trans); |
| @@ -649,6 +904,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 649 | /* We reprogram keys and shouldn't allocate new key indices */ | 904 | /* We reprogram keys and shouldn't allocate new key indices */ |
| 650 | memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); | 905 | memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); |
| 651 | 906 | ||
| 907 | mvm->ptk_ivlen = 0; | ||
| 908 | mvm->ptk_icvlen = 0; | ||
| 909 | mvm->ptk_ivlen = 0; | ||
| 910 | mvm->ptk_icvlen = 0; | ||
| 911 | |||
| 652 | /* | 912 | /* |
| 653 | * The D3 firmware still hardcodes the AP station ID for the | 913 | * The D3 firmware still hardcodes the AP station ID for the |
| 654 | * BSS we're associated with as 0. As a result, we have to move | 914 | * BSS we're associated with as 0. As a result, we have to move |
| @@ -740,6 +1000,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 740 | if (ret) | 1000 | if (ret) |
| 741 | goto out; | 1001 | goto out; |
| 742 | 1002 | ||
| 1003 | ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); | ||
| 1004 | if (ret) | ||
| 1005 | goto out; | ||
| 1006 | |||
| 743 | /* must be last -- this switches firmware state */ | 1007 | /* must be last -- this switches firmware state */ |
| 744 | ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, | 1008 | ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, |
| 745 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | 1009 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); |
| @@ -783,7 +1047,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, | |||
| 783 | struct iwl_wowlan_status *status; | 1047 | struct iwl_wowlan_status *status; |
| 784 | u32 reasons; | 1048 | u32 reasons; |
| 785 | int ret, len; | 1049 | int ret, len; |
| 786 | bool pkt8023 = false; | ||
| 787 | struct sk_buff *pkt = NULL; | 1050 | struct sk_buff *pkt = NULL; |
| 788 | 1051 | ||
| 789 | iwl_trans_read_mem_bytes(mvm->trans, base, | 1052 | iwl_trans_read_mem_bytes(mvm->trans, base, |
| @@ -824,7 +1087,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, | |||
| 824 | status = (void *)cmd.resp_pkt->data; | 1087 | status = (void *)cmd.resp_pkt->data; |
| 825 | 1088 | ||
| 826 | if (len - sizeof(struct iwl_cmd_header) != | 1089 | if (len - sizeof(struct iwl_cmd_header) != |
| 827 | sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { | 1090 | sizeof(*status) + |
| 1091 | ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { | ||
| 828 | IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); | 1092 | IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); |
| 829 | goto out; | 1093 | goto out; |
| 830 | } | 1094 | } |
| @@ -836,61 +1100,105 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, | |||
| 836 | goto report; | 1100 | goto report; |
| 837 | } | 1101 | } |
| 838 | 1102 | ||
| 839 | if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { | 1103 | if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) |
| 840 | wakeup.magic_pkt = true; | 1104 | wakeup.magic_pkt = true; |
| 841 | pkt8023 = true; | ||
| 842 | } | ||
| 843 | 1105 | ||
| 844 | if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { | 1106 | if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) |
| 845 | wakeup.pattern_idx = | 1107 | wakeup.pattern_idx = |
| 846 | le16_to_cpu(status->pattern_number); | 1108 | le16_to_cpu(status->pattern_number); |
| 847 | pkt8023 = true; | ||
| 848 | } | ||
| 849 | 1109 | ||
| 850 | if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | | 1110 | if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | |
| 851 | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) | 1111 | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) |
| 852 | wakeup.disconnect = true; | 1112 | wakeup.disconnect = true; |
| 853 | 1113 | ||
| 854 | if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { | 1114 | if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) |
| 855 | wakeup.gtk_rekey_failure = true; | 1115 | wakeup.gtk_rekey_failure = true; |
| 856 | pkt8023 = true; | ||
| 857 | } | ||
| 858 | 1116 | ||
| 859 | if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { | 1117 | if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) |
| 860 | wakeup.rfkill_release = true; | 1118 | wakeup.rfkill_release = true; |
| 861 | pkt8023 = true; | ||
| 862 | } | ||
| 863 | 1119 | ||
| 864 | if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { | 1120 | if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) |
| 865 | wakeup.eap_identity_req = true; | 1121 | wakeup.eap_identity_req = true; |
| 866 | pkt8023 = true; | ||
| 867 | } | ||
| 868 | 1122 | ||
| 869 | if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { | 1123 | if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) |
| 870 | wakeup.four_way_handshake = true; | 1124 | wakeup.four_way_handshake = true; |
| 871 | pkt8023 = true; | 1125 | |
| 872 | } | 1126 | if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) |
| 1127 | wakeup.tcp_connlost = true; | ||
| 1128 | |||
| 1129 | if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) | ||
| 1130 | wakeup.tcp_nomoretokens = true; | ||
| 1131 | |||
| 1132 | if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) | ||
| 1133 | wakeup.tcp_match = true; | ||
| 873 | 1134 | ||
| 874 | if (status->wake_packet_bufsize) { | 1135 | if (status->wake_packet_bufsize) { |
| 875 | u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); | 1136 | int pktsize = le32_to_cpu(status->wake_packet_bufsize); |
| 876 | u32 pktlen = le32_to_cpu(status->wake_packet_length); | 1137 | int pktlen = le32_to_cpu(status->wake_packet_length); |
| 1138 | const u8 *pktdata = status->wake_packet; | ||
| 1139 | struct ieee80211_hdr *hdr = (void *)pktdata; | ||
| 1140 | int truncated = pktlen - pktsize; | ||
| 1141 | |||
| 1142 | /* this would be a firmware bug */ | ||
| 1143 | if (WARN_ON_ONCE(truncated < 0)) | ||
| 1144 | truncated = 0; | ||
| 1145 | |||
| 1146 | if (ieee80211_is_data(hdr->frame_control)) { | ||
| 1147 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
| 1148 | int ivlen = 0, icvlen = 4; /* also FCS */ | ||
| 877 | 1149 | ||
| 878 | if (pkt8023) { | ||
| 879 | pkt = alloc_skb(pktsize, GFP_KERNEL); | 1150 | pkt = alloc_skb(pktsize, GFP_KERNEL); |
| 880 | if (!pkt) | 1151 | if (!pkt) |
| 881 | goto report; | 1152 | goto report; |
| 882 | memcpy(skb_put(pkt, pktsize), status->wake_packet, | 1153 | |
| 883 | pktsize); | 1154 | memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen); |
| 1155 | pktdata += hdrlen; | ||
| 1156 | pktsize -= hdrlen; | ||
| 1157 | |||
| 1158 | if (ieee80211_has_protected(hdr->frame_control)) { | ||
| 1159 | if (is_multicast_ether_addr(hdr->addr1)) { | ||
| 1160 | ivlen = mvm->gtk_ivlen; | ||
| 1161 | icvlen += mvm->gtk_icvlen; | ||
| 1162 | } else { | ||
| 1163 | ivlen = mvm->ptk_ivlen; | ||
| 1164 | icvlen += mvm->ptk_icvlen; | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | /* if truncated, FCS/ICV is (partially) gone */ | ||
| 1169 | if (truncated >= icvlen) { | ||
| 1170 | icvlen = 0; | ||
| 1171 | truncated -= icvlen; | ||
| 1172 | } else { | ||
| 1173 | icvlen -= truncated; | ||
| 1174 | truncated = 0; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | pktsize -= ivlen + icvlen; | ||
| 1178 | pktdata += ivlen; | ||
| 1179 | |||
| 1180 | memcpy(skb_put(pkt, pktsize), pktdata, pktsize); | ||
| 1181 | |||
| 884 | if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) | 1182 | if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) |
| 885 | goto report; | 1183 | goto report; |
| 886 | wakeup.packet = pkt->data; | 1184 | wakeup.packet = pkt->data; |
| 887 | wakeup.packet_present_len = pkt->len; | 1185 | wakeup.packet_present_len = pkt->len; |
| 888 | wakeup.packet_len = pkt->len - (pktlen - pktsize); | 1186 | wakeup.packet_len = pkt->len - truncated; |
| 889 | wakeup.packet_80211 = false; | 1187 | wakeup.packet_80211 = false; |
| 890 | } else { | 1188 | } else { |
| 1189 | int fcslen = 4; | ||
| 1190 | |||
| 1191 | if (truncated >= 4) { | ||
| 1192 | truncated -= 4; | ||
| 1193 | fcslen = 0; | ||
| 1194 | } else { | ||
| 1195 | fcslen -= truncated; | ||
| 1196 | truncated = 0; | ||
| 1197 | } | ||
| 1198 | pktsize -= fcslen; | ||
| 891 | wakeup.packet = status->wake_packet; | 1199 | wakeup.packet = status->wake_packet; |
| 892 | wakeup.packet_present_len = pktsize; | 1200 | wakeup.packet_present_len = pktsize; |
| 893 | wakeup.packet_len = pktlen; | 1201 | wakeup.packet_len = pktlen - truncated; |
| 894 | wakeup.packet_80211 = true; | 1202 | wakeup.packet_80211 = true; |
| 895 | } | 1203 | } |
| 896 | } | 1204 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index c1bdb5582126..b080b4ba5458 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx { | |||
| 69 | struct ieee80211_vif *vif; | 69 | struct ieee80211_vif *vif; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) | ||
| 73 | { | ||
| 74 | file->private_data = inode->i_private; | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, | 72 | static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, |
| 79 | const char __user *user_buf, | 73 | const char __user *user_buf, |
| 80 | size_t count, loff_t *ppos) | 74 | size_t count, loff_t *ppos) |
| @@ -306,10 +300,130 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, | |||
| 306 | return count; | 300 | return count; |
| 307 | } | 301 | } |
| 308 | 302 | ||
| 303 | #define BT_MBOX_MSG(_notif, _num, _field) \ | ||
| 304 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ | ||
| 305 | >> BT_MBOX##_num##_##_field##_POS) | ||
| 306 | |||
| 307 | |||
| 308 | #define BT_MBOX_PRINT(_num, _field, _end) \ | ||
| 309 | pos += scnprintf(buf + pos, bufsz - pos, \ | ||
| 310 | "\t%s: %d%s", \ | ||
| 311 | #_field, \ | ||
| 312 | BT_MBOX_MSG(notif, _num, _field), \ | ||
| 313 | true ? "\n" : ", "); | ||
| 314 | |||
| 315 | static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, | ||
| 316 | size_t count, loff_t *ppos) | ||
| 317 | { | ||
| 318 | struct iwl_mvm *mvm = file->private_data; | ||
| 319 | struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; | ||
| 320 | char *buf; | ||
| 321 | int ret, pos = 0, bufsz = sizeof(char) * 1024; | ||
| 322 | |||
| 323 | buf = kmalloc(bufsz, GFP_KERNEL); | ||
| 324 | if (!buf) | ||
| 325 | return -ENOMEM; | ||
| 326 | |||
| 327 | mutex_lock(&mvm->mutex); | ||
| 328 | |||
| 329 | pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); | ||
| 330 | |||
| 331 | BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); | ||
| 332 | BT_MBOX_PRINT(0, LE_PROF1, false); | ||
| 333 | BT_MBOX_PRINT(0, LE_PROF2, false); | ||
| 334 | BT_MBOX_PRINT(0, LE_PROF_OTHER, false); | ||
| 335 | BT_MBOX_PRINT(0, CHL_SEQ_N, false); | ||
| 336 | BT_MBOX_PRINT(0, INBAND_S, false); | ||
| 337 | BT_MBOX_PRINT(0, LE_MIN_RSSI, false); | ||
| 338 | BT_MBOX_PRINT(0, LE_SCAN, false); | ||
| 339 | BT_MBOX_PRINT(0, LE_ADV, false); | ||
| 340 | BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false); | ||
| 341 | BT_MBOX_PRINT(0, OPEN_CON_1, true); | ||
| 342 | |||
| 343 | pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n"); | ||
| 344 | |||
| 345 | BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false); | ||
| 346 | BT_MBOX_PRINT(1, IP_SR, false); | ||
| 347 | BT_MBOX_PRINT(1, LE_MSTR, false); | ||
| 348 | BT_MBOX_PRINT(1, AGGR_TRFC_LD, false); | ||
| 349 | BT_MBOX_PRINT(1, MSG_TYPE, false); | ||
| 350 | BT_MBOX_PRINT(1, SSN, true); | ||
| 351 | |||
| 352 | pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n"); | ||
| 353 | |||
| 354 | BT_MBOX_PRINT(2, SNIFF_ACT, false); | ||
| 355 | BT_MBOX_PRINT(2, PAG, false); | ||
| 356 | BT_MBOX_PRINT(2, INQUIRY, false); | ||
| 357 | BT_MBOX_PRINT(2, CONN, false); | ||
| 358 | BT_MBOX_PRINT(2, SNIFF_INTERVAL, false); | ||
| 359 | BT_MBOX_PRINT(2, DISC, false); | ||
| 360 | BT_MBOX_PRINT(2, SCO_TX_ACT, false); | ||
| 361 | BT_MBOX_PRINT(2, SCO_RX_ACT, false); | ||
| 362 | BT_MBOX_PRINT(2, ESCO_RE_TX, false); | ||
| 363 | BT_MBOX_PRINT(2, SCO_DURATION, true); | ||
| 364 | |||
| 365 | pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n"); | ||
| 366 | |||
| 367 | BT_MBOX_PRINT(3, SCO_STATE, false); | ||
| 368 | BT_MBOX_PRINT(3, SNIFF_STATE, false); | ||
| 369 | BT_MBOX_PRINT(3, A2DP_STATE, false); | ||
| 370 | BT_MBOX_PRINT(3, ACL_STATE, false); | ||
| 371 | BT_MBOX_PRINT(3, MSTR_STATE, false); | ||
| 372 | BT_MBOX_PRINT(3, OBX_STATE, false); | ||
| 373 | BT_MBOX_PRINT(3, OPEN_CON_2, false); | ||
| 374 | BT_MBOX_PRINT(3, TRAFFIC_LOAD, false); | ||
| 375 | BT_MBOX_PRINT(3, CHL_SEQN_LSB, false); | ||
| 376 | BT_MBOX_PRINT(3, INBAND_P, false); | ||
| 377 | BT_MBOX_PRINT(3, MSG_TYPE_2, false); | ||
| 378 | BT_MBOX_PRINT(3, SSN_2, false); | ||
| 379 | BT_MBOX_PRINT(3, UPDATE_REQUEST, true); | ||
| 380 | |||
| 381 | pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", | ||
| 382 | notif->bt_status); | ||
| 383 | pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", | ||
| 384 | notif->bt_open_conn); | ||
| 385 | pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", | ||
| 386 | notif->bt_traffic_load); | ||
| 387 | pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", | ||
| 388 | notif->bt_agg_traffic_load); | ||
| 389 | pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", | ||
| 390 | notif->bt_ci_compliance); | ||
| 391 | |||
| 392 | mutex_unlock(&mvm->mutex); | ||
| 393 | |||
| 394 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
| 395 | kfree(buf); | ||
| 396 | |||
| 397 | return ret; | ||
| 398 | } | ||
| 399 | #undef BT_MBOX_PRINT | ||
| 400 | |||
| 401 | static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | ||
| 402 | const char __user *user_buf, | ||
| 403 | size_t count, loff_t *ppos) | ||
| 404 | { | ||
| 405 | struct iwl_mvm *mvm = file->private_data; | ||
| 406 | bool restart_fw = iwlwifi_mod_params.restart_fw; | ||
| 407 | int ret; | ||
| 408 | |||
| 409 | iwlwifi_mod_params.restart_fw = true; | ||
| 410 | |||
| 411 | mutex_lock(&mvm->mutex); | ||
| 412 | |||
| 413 | /* take the return value to make compiler happy - it will fail anyway */ | ||
| 414 | ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL); | ||
| 415 | |||
| 416 | mutex_unlock(&mvm->mutex); | ||
| 417 | |||
| 418 | iwlwifi_mod_params.restart_fw = restart_fw; | ||
| 419 | |||
| 420 | return count; | ||
| 421 | } | ||
| 422 | |||
| 309 | #define MVM_DEBUGFS_READ_FILE_OPS(name) \ | 423 | #define MVM_DEBUGFS_READ_FILE_OPS(name) \ |
| 310 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 424 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ |
| 311 | .read = iwl_dbgfs_##name##_read, \ | 425 | .read = iwl_dbgfs_##name##_read, \ |
| 312 | .open = iwl_dbgfs_open_file_generic, \ | 426 | .open = simple_open, \ |
| 313 | .llseek = generic_file_llseek, \ | 427 | .llseek = generic_file_llseek, \ |
| 314 | } | 428 | } |
| 315 | 429 | ||
| @@ -317,14 +431,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ | |||
| 317 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 431 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ |
| 318 | .write = iwl_dbgfs_##name##_write, \ | 432 | .write = iwl_dbgfs_##name##_write, \ |
| 319 | .read = iwl_dbgfs_##name##_read, \ | 433 | .read = iwl_dbgfs_##name##_read, \ |
| 320 | .open = iwl_dbgfs_open_file_generic, \ | 434 | .open = simple_open, \ |
| 321 | .llseek = generic_file_llseek, \ | 435 | .llseek = generic_file_llseek, \ |
| 322 | }; | 436 | }; |
| 323 | 437 | ||
| 324 | #define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ | 438 | #define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ |
| 325 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 439 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ |
| 326 | .write = iwl_dbgfs_##name##_write, \ | 440 | .write = iwl_dbgfs_##name##_write, \ |
| 327 | .open = iwl_dbgfs_open_file_generic, \ | 441 | .open = simple_open, \ |
| 328 | .llseek = generic_file_llseek, \ | 442 | .llseek = generic_file_llseek, \ |
| 329 | }; | 443 | }; |
| 330 | 444 | ||
| @@ -345,8 +459,10 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); | |||
| 345 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); | 459 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); |
| 346 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); | 460 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); |
| 347 | MVM_DEBUGFS_READ_FILE_OPS(stations); | 461 | MVM_DEBUGFS_READ_FILE_OPS(stations); |
| 462 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); | ||
| 348 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); | 463 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); |
| 349 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); | 464 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); |
| 465 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); | ||
| 350 | 466 | ||
| 351 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | 467 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) |
| 352 | { | 468 | { |
| @@ -358,8 +474,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
| 358 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); | 474 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); |
| 359 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); | 475 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); |
| 360 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); | 476 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); |
| 477 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); | ||
| 361 | MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); | 478 | MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); |
| 362 | MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); | 479 | MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); |
| 480 | MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); | ||
| 363 | 481 | ||
| 364 | /* | 482 | /* |
| 365 | * Create a symlink with mac80211. It will be removed when mac80211 | 483 | * Create a symlink with mac80211. It will be removed when mac80211 |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h new file mode 100644 index 000000000000..05c61d6f384e --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h | |||
| @@ -0,0 +1,319 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
| 4 | * redistributing this file, you may do so under either license. | ||
| 5 | * | ||
| 6 | * GPL LICENSE SUMMARY | ||
| 7 | * | ||
| 8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
| 22 | * USA | ||
| 23 | * | ||
| 24 | * The full GNU General Public License is included in this distribution | ||
| 25 | * in the file called COPYING. | ||
| 26 | * | ||
| 27 | * Contact Information: | ||
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
| 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 30 | * | ||
| 31 | * BSD LICENSE | ||
| 32 | * | ||
| 33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | ||
| 34 | * All rights reserved. | ||
| 35 | * | ||
| 36 | * Redistribution and use in source and binary forms, with or without | ||
| 37 | * modification, are permitted provided that the following conditions | ||
| 38 | * are met: | ||
| 39 | * | ||
| 40 | * * Redistributions of source code must retain the above copyright | ||
| 41 | * notice, this list of conditions and the following disclaimer. | ||
| 42 | * * Redistributions in binary form must reproduce the above copyright | ||
| 43 | * notice, this list of conditions and the following disclaimer in | ||
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | ||
| 46 | * * Neither the name Intel Corporation nor the names of its | ||
| 47 | * contributors may be used to endorse or promote products derived | ||
| 48 | * from this software without specific prior written permission. | ||
| 49 | * | ||
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 61 | *****************************************************************************/ | ||
| 62 | |||
| 63 | #ifndef __fw_api_bt_coex_h__ | ||
| 64 | #define __fw_api_bt_coex_h__ | ||
| 65 | |||
| 66 | #include <linux/types.h> | ||
| 67 | #include <linux/bitops.h> | ||
| 68 | |||
| 69 | #define BITS(nb) (BIT(nb) - 1) | ||
| 70 | |||
| 71 | /** | ||
| 72 | * enum iwl_bt_coex_flags - flags for BT_COEX command | ||
| 73 | * @BT_CH_PRIMARY_EN: | ||
| 74 | * @BT_CH_SECONDARY_EN: | ||
| 75 | * @BT_NOTIF_COEX_OFF: | ||
| 76 | * @BT_COEX_MODE_POS: | ||
| 77 | * @BT_COEX_MODE_MSK: | ||
| 78 | * @BT_COEX_DISABLE: | ||
| 79 | * @BT_COEX_2W: | ||
| 80 | * @BT_COEX_3W: | ||
| 81 | * @BT_COEX_NW: | ||
| 82 | * @BT_USE_DEFAULTS: | ||
| 83 | * @BT_SYNC_2_BT_DISABLE: | ||
| 84 | * @BT_COEX_CORUNNING_TBL_EN: | ||
| 85 | */ | ||
| 86 | enum iwl_bt_coex_flags { | ||
| 87 | BT_CH_PRIMARY_EN = BIT(0), | ||
| 88 | BT_CH_SECONDARY_EN = BIT(1), | ||
| 89 | BT_NOTIF_COEX_OFF = BIT(2), | ||
| 90 | BT_COEX_MODE_POS = 3, | ||
| 91 | BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS, | ||
| 92 | BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS, | ||
| 93 | BT_COEX_2W = 0x1 << BT_COEX_MODE_POS, | ||
| 94 | BT_COEX_3W = 0x2 << BT_COEX_MODE_POS, | ||
| 95 | BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, | ||
| 96 | BT_USE_DEFAULTS = BIT(6), | ||
| 97 | BT_SYNC_2_BT_DISABLE = BIT(7), | ||
| 98 | /* | ||
| 99 | * For future use - when the flags will be enlarged | ||
| 100 | * BT_COEX_CORUNNING_TBL_EN = BIT(8), | ||
| 101 | */ | ||
| 102 | }; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * indicates what has changed in the BT_COEX command. | ||
| 106 | */ | ||
| 107 | enum iwl_bt_coex_valid_bit_msk { | ||
| 108 | BT_VALID_ENABLE = BIT(0), | ||
| 109 | BT_VALID_BT_PRIO_BOOST = BIT(1), | ||
| 110 | BT_VALID_MAX_KILL = BIT(2), | ||
| 111 | BT_VALID_3W_TMRS = BIT(3), | ||
| 112 | BT_VALID_KILL_ACK = BIT(4), | ||
| 113 | BT_VALID_KILL_CTS = BIT(5), | ||
| 114 | BT_VALID_REDUCED_TX_POWER = BIT(6), | ||
| 115 | BT_VALID_LUT = BIT(7), | ||
| 116 | BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8), | ||
| 117 | BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9), | ||
| 118 | BT_VALID_MULTI_PRIO_LUT = BIT(10), | ||
| 119 | BT_VALID_TRM_KICK_FILTER = BIT(11), | ||
| 120 | BT_VALID_CORUN_LUT_20 = BIT(12), | ||
| 121 | BT_VALID_CORUN_LUT_40 = BIT(13), | ||
| 122 | BT_VALID_ANT_ISOLATION = BIT(14), | ||
| 123 | BT_VALID_ANT_ISOLATION_THRS = BIT(15), | ||
| 124 | /* | ||
| 125 | * For future use - when the valid flags will be enlarged | ||
| 126 | * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), | ||
| 127 | * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), | ||
| 128 | */ | ||
| 129 | }; | ||
| 130 | |||
| 131 | /** | ||
| 132 | * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames. | ||
| 133 | * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames | ||
| 134 | * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames | ||
| 135 | * | ||
| 136 | * This mechanism allows to have BT and WiFi run concurrently. Since WiFi | ||
| 137 | * reduces its Tx power, it can work along with BT, hence reducing the amount | ||
| 138 | * of WiFi frames being killed by BT. | ||
| 139 | */ | ||
| 140 | enum iwl_bt_reduced_tx_power { | ||
| 141 | BT_REDUCED_TX_POWER_CTL = BIT(0), | ||
| 142 | BT_REDUCED_TX_POWER_DATA = BIT(1), | ||
| 143 | }; | ||
| 144 | |||
| 145 | #define BT_COEX_LUT_SIZE (12) | ||
| 146 | |||
| 147 | /** | ||
| 148 | * struct iwl_bt_coex_cmd - bt coex configuration command | ||
| 149 | * @flags:&enum iwl_bt_coex_flags | ||
| 150 | * @lead_time: | ||
| 151 | * @max_kill: | ||
| 152 | * @bt3_time_t7_value: | ||
| 153 | * @kill_ack_msk: | ||
| 154 | * @kill_cts_msk: | ||
| 155 | * @bt3_prio_sample_time: | ||
| 156 | * @bt3_timer_t2_value: | ||
| 157 | * @bt4_reaction_time: | ||
| 158 | * @decision_lut[12]: | ||
| 159 | * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power | ||
| 160 | * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk | ||
| 161 | * @bt_prio_boost: values for PTA boost register | ||
| 162 | * @wifi_tx_prio_boost: SW boost of wifi tx priority | ||
| 163 | * @wifi_rx_prio_boost: SW boost of wifi rx priority | ||
| 164 | * | ||
| 165 | * The structure is used for the BT_COEX command. | ||
| 166 | */ | ||
| 167 | struct iwl_bt_coex_cmd { | ||
| 168 | u8 flags; | ||
| 169 | u8 lead_time; | ||
| 170 | u8 max_kill; | ||
| 171 | u8 bt3_time_t7_value; | ||
| 172 | __le32 kill_ack_msk; | ||
| 173 | __le32 kill_cts_msk; | ||
| 174 | u8 bt3_prio_sample_time; | ||
| 175 | u8 bt3_timer_t2_value; | ||
| 176 | __le16 bt4_reaction_time; | ||
| 177 | __le32 decision_lut[BT_COEX_LUT_SIZE]; | ||
| 178 | u8 bt_reduced_tx_power; | ||
| 179 | u8 reserved; | ||
| 180 | __le16 valid_bit_msk; | ||
| 181 | __le32 bt_prio_boost; | ||
| 182 | u8 reserved2; | ||
| 183 | u8 wifi_tx_prio_boost; | ||
| 184 | __le16 wifi_rx_prio_boost; | ||
| 185 | } __packed; /* BT_COEX_CMD_API_S_VER_3 */ | ||
| 186 | |||
| 187 | #define BT_MBOX(n_dw, _msg, _pos, _nbits) \ | ||
| 188 | BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ | ||
| 189 | BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS | ||
| 190 | |||
| 191 | enum iwl_bt_mxbox_dw0 { | ||
| 192 | BT_MBOX(0, LE_SLAVE_LAT, 0, 3), | ||
| 193 | BT_MBOX(0, LE_PROF1, 3, 1), | ||
| 194 | BT_MBOX(0, LE_PROF2, 4, 1), | ||
| 195 | BT_MBOX(0, LE_PROF_OTHER, 5, 1), | ||
| 196 | BT_MBOX(0, CHL_SEQ_N, 8, 4), | ||
| 197 | BT_MBOX(0, INBAND_S, 13, 1), | ||
| 198 | BT_MBOX(0, LE_MIN_RSSI, 16, 4), | ||
| 199 | BT_MBOX(0, LE_SCAN, 20, 1), | ||
| 200 | BT_MBOX(0, LE_ADV, 21, 1), | ||
| 201 | BT_MBOX(0, LE_MAX_TX_POWER, 24, 4), | ||
| 202 | BT_MBOX(0, OPEN_CON_1, 28, 2), | ||
| 203 | }; | ||
| 204 | |||
| 205 | enum iwl_bt_mxbox_dw1 { | ||
| 206 | BT_MBOX(1, BR_MAX_TX_POWER, 0, 4), | ||
| 207 | BT_MBOX(1, IP_SR, 4, 1), | ||
| 208 | BT_MBOX(1, LE_MSTR, 5, 1), | ||
| 209 | BT_MBOX(1, AGGR_TRFC_LD, 8, 6), | ||
| 210 | BT_MBOX(1, MSG_TYPE, 16, 3), | ||
| 211 | BT_MBOX(1, SSN, 19, 2), | ||
| 212 | }; | ||
| 213 | |||
| 214 | enum iwl_bt_mxbox_dw2 { | ||
| 215 | BT_MBOX(2, SNIFF_ACT, 0, 3), | ||
| 216 | BT_MBOX(2, PAG, 3, 1), | ||
| 217 | BT_MBOX(2, INQUIRY, 4, 1), | ||
| 218 | BT_MBOX(2, CONN, 5, 1), | ||
| 219 | BT_MBOX(2, SNIFF_INTERVAL, 8, 5), | ||
| 220 | BT_MBOX(2, DISC, 13, 1), | ||
| 221 | BT_MBOX(2, SCO_TX_ACT, 16, 2), | ||
| 222 | BT_MBOX(2, SCO_RX_ACT, 18, 2), | ||
| 223 | BT_MBOX(2, ESCO_RE_TX, 20, 2), | ||
| 224 | BT_MBOX(2, SCO_DURATION, 24, 6), | ||
| 225 | }; | ||
| 226 | |||
| 227 | enum iwl_bt_mxbox_dw3 { | ||
| 228 | BT_MBOX(3, SCO_STATE, 0, 1), | ||
| 229 | BT_MBOX(3, SNIFF_STATE, 1, 1), | ||
| 230 | BT_MBOX(3, A2DP_STATE, 2, 1), | ||
| 231 | BT_MBOX(3, ACL_STATE, 3, 1), | ||
| 232 | BT_MBOX(3, MSTR_STATE, 4, 1), | ||
| 233 | BT_MBOX(3, OBX_STATE, 5, 1), | ||
| 234 | BT_MBOX(3, OPEN_CON_2, 8, 2), | ||
| 235 | BT_MBOX(3, TRAFFIC_LOAD, 10, 2), | ||
| 236 | BT_MBOX(3, CHL_SEQN_LSB, 12, 1), | ||
| 237 | BT_MBOX(3, INBAND_P, 13, 1), | ||
| 238 | BT_MBOX(3, MSG_TYPE_2, 16, 3), | ||
| 239 | BT_MBOX(3, SSN_2, 19, 2), | ||
| 240 | BT_MBOX(3, UPDATE_REQUEST, 21, 1), | ||
| 241 | }; | ||
| 242 | |||
| 243 | #define BT_MBOX_MSG(_notif, _num, _field) \ | ||
| 244 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ | ||
| 245 | >> BT_MBOX##_num##_##_field##_POS) | ||
| 246 | |||
| 247 | /** | ||
| 248 | * struct iwl_bt_coex_profile_notif - notification about BT coex | ||
| 249 | * @mbox_msg: message from BT to WiFi | ||
| 250 | * @:bt_status: 0 - off, 1 - on | ||
| 251 | * @:bt_open_conn: number of BT connections open | ||
| 252 | * @:bt_traffic_load: load of BT traffic | ||
| 253 | * @:bt_agg_traffic_load: aggregated load of BT traffic | ||
| 254 | * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant | ||
| 255 | */ | ||
| 256 | struct iwl_bt_coex_profile_notif { | ||
| 257 | __le32 mbox_msg[4]; | ||
| 258 | u8 bt_status; | ||
| 259 | u8 bt_open_conn; | ||
| 260 | u8 bt_traffic_load; | ||
| 261 | u8 bt_agg_traffic_load; | ||
| 262 | u8 bt_ci_compliance; | ||
| 263 | u8 reserved[3]; | ||
| 264 | } __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ | ||
| 265 | |||
| 266 | enum iwl_bt_coex_prio_table_event { | ||
| 267 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, | ||
| 268 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, | ||
| 269 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, | ||
| 270 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, | ||
| 271 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, | ||
| 272 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, | ||
| 273 | BT_COEX_PRIO_TBL_EVT_DTIM = 6, | ||
| 274 | BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, | ||
| 275 | BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, | ||
| 276 | BT_COEX_PRIO_TBL_EVT_IDLE = 9, | ||
| 277 | BT_COEX_PRIO_TBL_EVT_MAX = 16, | ||
| 278 | }; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */ | ||
| 279 | |||
| 280 | enum iwl_bt_coex_prio_table_prio { | ||
| 281 | BT_COEX_PRIO_TBL_DISABLED = 0, | ||
| 282 | BT_COEX_PRIO_TBL_PRIO_LOW = 1, | ||
| 283 | BT_COEX_PRIO_TBL_PRIO_HIGH = 2, | ||
| 284 | BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, | ||
| 285 | BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, | ||
| 286 | BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, | ||
| 287 | BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6, | ||
| 288 | BT_COEX_PRIO_TBL_MAX = 8, | ||
| 289 | }; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */ | ||
| 290 | |||
| 291 | #define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0) | ||
| 292 | #define BT_COEX_PRIO_TBL_PRIO_POS (1) | ||
| 293 | #define BT_COEX_PRIO_TBL_RESERVED_POS (4) | ||
| 294 | |||
| 295 | /** | ||
| 296 | * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex | ||
| 297 | * @prio_tbl: | ||
| 298 | */ | ||
| 299 | struct iwl_bt_coex_prio_tbl_cmd { | ||
| 300 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; | ||
| 301 | } __packed; | ||
| 302 | |||
| 303 | enum iwl_bt_coex_env_action { | ||
| 304 | BT_COEX_ENV_CLOSE = 0, | ||
| 305 | BT_COEX_ENV_OPEN = 1, | ||
| 306 | }; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */ | ||
| 307 | |||
| 308 | /** | ||
| 309 | * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope | ||
| 310 | * @action: enum %iwl_bt_coex_env_action | ||
| 311 | * @type: enum %iwl_bt_coex_prio_table_event | ||
| 312 | */ | ||
| 313 | struct iwl_bt_coex_prot_env_cmd { | ||
| 314 | u8 action; /* 0 = closed, 1 = open */ | ||
| 315 | u8 type; /* 0 .. 15 */ | ||
| 316 | u8 reserved[2]; | ||
| 317 | } __packed; | ||
| 318 | |||
| 319 | #endif /* __fw_api_bt_coex_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index cf6f9a02fb74..51e015d1dfb2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason { | |||
| 258 | IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), | 258 | IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), |
| 259 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), | 259 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), |
| 260 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), | 260 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), |
| 261 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), | 261 | /* BIT(11) reserved */ |
| 262 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), | 262 | IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), |
| 263 | }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ | 263 | }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ |
| 264 | 264 | ||
| @@ -277,6 +277,55 @@ struct iwl_wowlan_status { | |||
| 277 | u8 wake_packet[]; /* can be truncated from _length to _bufsize */ | 277 | u8 wake_packet[]; /* can be truncated from _length to _bufsize */ |
| 278 | } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ | 278 | } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ |
| 279 | 279 | ||
| 280 | #define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 | ||
| 281 | #define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 | ||
| 282 | #define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 | ||
| 283 | |||
| 284 | struct iwl_tcp_packet_info { | ||
| 285 | __le16 tcp_pseudo_header_checksum; | ||
| 286 | __le16 tcp_payload_length; | ||
| 287 | } __packed; /* TCP_PACKET_INFO_API_S_VER_2 */ | ||
| 288 | |||
| 289 | struct iwl_tcp_packet { | ||
| 290 | struct iwl_tcp_packet_info info; | ||
| 291 | u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; | ||
| 292 | u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN]; | ||
| 293 | } __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ | ||
| 294 | |||
| 295 | struct iwl_remote_wake_packet { | ||
| 296 | struct iwl_tcp_packet_info info; | ||
| 297 | u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; | ||
| 298 | u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN]; | ||
| 299 | } __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ | ||
| 300 | |||
| 301 | struct iwl_wowlan_remote_wake_config { | ||
| 302 | __le32 connection_max_time; /* unused */ | ||
| 303 | /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */ | ||
| 304 | u8 max_syn_retries; | ||
| 305 | u8 max_data_retries; | ||
| 306 | u8 tcp_syn_ack_timeout; | ||
| 307 | u8 tcp_ack_timeout; | ||
| 308 | |||
| 309 | struct iwl_tcp_packet syn_tx; | ||
| 310 | struct iwl_tcp_packet synack_rx; | ||
| 311 | struct iwl_tcp_packet keepalive_ack_rx; | ||
| 312 | struct iwl_tcp_packet fin_tx; | ||
| 313 | |||
| 314 | struct iwl_remote_wake_packet keepalive_tx; | ||
| 315 | struct iwl_remote_wake_packet wake_rx; | ||
| 316 | |||
| 317 | /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */ | ||
| 318 | u8 sequence_number_offset; | ||
| 319 | u8 sequence_number_length; | ||
| 320 | u8 token_offset; | ||
| 321 | u8 token_length; | ||
| 322 | /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */ | ||
| 323 | __le32 initial_sequence_number; | ||
| 324 | __le16 keepalive_interval; | ||
| 325 | __le16 num_tokens; | ||
| 326 | u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS]; | ||
| 327 | } __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */ | ||
| 328 | |||
| 280 | /* TODO: NetDetect API */ | 329 | /* TODO: NetDetect API */ |
| 281 | 330 | ||
| 282 | #endif /* __fw_api_d3_h__ */ | 331 | #endif /* __fw_api_d3_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index ae39b7dfda7b..d68640ea41d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index be36b7604b7f..127051891e9b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index aa3474d08231..fdd33bc0a594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 670ac8f95e26..b60d14151721 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 0acb53dda22d..a30691a8a85b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h index 2677914bf0a6..6d53850c5448 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 23eebda848b0..f8d7e88234e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -70,6 +70,7 @@ | |||
| 70 | #include "fw-api-mac.h" | 70 | #include "fw-api-mac.h" |
| 71 | #include "fw-api-power.h" | 71 | #include "fw-api-power.h" |
| 72 | #include "fw-api-d3.h" | 72 | #include "fw-api-d3.h" |
| 73 | #include "fw-api-bt-coex.h" | ||
| 73 | 74 | ||
| 74 | /* queue and FIFO numbers by usage */ | 75 | /* queue and FIFO numbers by usage */ |
| 75 | enum { | 76 | enum { |
| @@ -152,6 +153,7 @@ enum { | |||
| 152 | 153 | ||
| 153 | BEACON_TEMPLATE_CMD = 0x91, | 154 | BEACON_TEMPLATE_CMD = 0x91, |
| 154 | TX_ANT_CONFIGURATION_CMD = 0x98, | 155 | TX_ANT_CONFIGURATION_CMD = 0x98, |
| 156 | BT_CONFIG = 0x9b, | ||
| 155 | STATISTICS_NOTIFICATION = 0x9d, | 157 | STATISTICS_NOTIFICATION = 0x9d, |
| 156 | 158 | ||
| 157 | /* RF-KILL commands and notifications */ | 159 | /* RF-KILL commands and notifications */ |
| @@ -162,6 +164,11 @@ enum { | |||
| 162 | REPLY_RX_MPDU_CMD = 0xc1, | 164 | REPLY_RX_MPDU_CMD = 0xc1, |
| 163 | BA_NOTIF = 0xc5, | 165 | BA_NOTIF = 0xc5, |
| 164 | 166 | ||
| 167 | /* BT Coex */ | ||
| 168 | BT_COEX_PRIO_TABLE = 0xcc, | ||
| 169 | BT_COEX_PROT_ENV = 0xcd, | ||
| 170 | BT_PROFILE_NOTIFICATION = 0xce, | ||
| 171 | |||
| 165 | REPLY_DEBUG_CMD = 0xf0, | 172 | REPLY_DEBUG_CMD = 0xf0, |
| 166 | DEBUG_LOG_MSG = 0xf7, | 173 | DEBUG_LOG_MSG = 0xf7, |
| 167 | 174 | ||
| @@ -762,18 +769,20 @@ struct iwl_phy_context_cmd { | |||
| 762 | #define IWL_RX_INFO_PHY_CNT 8 | 769 | #define IWL_RX_INFO_PHY_CNT 8 |
| 763 | #define IWL_RX_INFO_AGC_IDX 1 | 770 | #define IWL_RX_INFO_AGC_IDX 1 |
| 764 | #define IWL_RX_INFO_RSSI_AB_IDX 2 | 771 | #define IWL_RX_INFO_RSSI_AB_IDX 2 |
| 765 | #define IWL_RX_INFO_RSSI_C_IDX 3 | 772 | #define IWL_OFDM_AGC_A_MSK 0x0000007f |
| 766 | #define IWL_OFDM_AGC_DB_MSK 0xfe00 | 773 | #define IWL_OFDM_AGC_A_POS 0 |
| 767 | #define IWL_OFDM_AGC_DB_POS 9 | 774 | #define IWL_OFDM_AGC_B_MSK 0x00003f80 |
| 775 | #define IWL_OFDM_AGC_B_POS 7 | ||
| 776 | #define IWL_OFDM_AGC_CODE_MSK 0x3fe00000 | ||
| 777 | #define IWL_OFDM_AGC_CODE_POS 20 | ||
| 768 | #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff | 778 | #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff |
| 769 | #define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 | ||
| 770 | #define IWL_OFDM_RSSI_A_POS 0 | 779 | #define IWL_OFDM_RSSI_A_POS 0 |
| 780 | #define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 | ||
| 781 | #define IWL_OFDM_RSSI_ALLBAND_A_POS 8 | ||
| 771 | #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 | 782 | #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 |
| 772 | #define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 | ||
| 773 | #define IWL_OFDM_RSSI_B_POS 16 | 783 | #define IWL_OFDM_RSSI_B_POS 16 |
| 774 | #define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff | 784 | #define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 |
| 775 | #define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 | 785 | #define IWL_OFDM_RSSI_ALLBAND_B_POS 24 |
| 776 | #define IWL_OFDM_RSSI_C_POS 0 | ||
| 777 | 786 | ||
| 778 | /** | 787 | /** |
| 779 | * struct iwl_rx_phy_info - phy info | 788 | * struct iwl_rx_phy_info - phy info |
| @@ -792,6 +801,7 @@ struct iwl_phy_context_cmd { | |||
| 792 | * @byte_count: frame's byte-count | 801 | * @byte_count: frame's byte-count |
| 793 | * @frame_time: frame's time on the air, based on byte count and frame rate | 802 | * @frame_time: frame's time on the air, based on byte count and frame rate |
| 794 | * calculation | 803 | * calculation |
| 804 | * @mac_active_msk: what MACs were active when the frame was received | ||
| 795 | * | 805 | * |
| 796 | * Before each Rx, the device sends this data. It contains PHY information | 806 | * Before each Rx, the device sends this data. It contains PHY information |
| 797 | * about the reception of the packet. | 807 | * about the reception of the packet. |
| @@ -809,7 +819,7 @@ struct iwl_rx_phy_info { | |||
| 809 | __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; | 819 | __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; |
| 810 | __le32 rate_n_flags; | 820 | __le32 rate_n_flags; |
| 811 | __le32 byte_count; | 821 | __le32 byte_count; |
| 812 | __le16 reserved2; | 822 | __le16 mac_active_msk; |
| 813 | __le16 frame_time; | 823 | __le16 frame_time; |
| 814 | } __packed; | 824 | } __packed; |
| 815 | 825 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d3d959db03a9..1006b3204e7b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -79,17 +79,8 @@ | |||
| 79 | #define UCODE_VALID_OK cpu_to_le32(0x1) | 79 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
| 80 | 80 | ||
| 81 | /* Default calibration values for WkP - set to INIT image w/o running */ | 81 | /* Default calibration values for WkP - set to INIT image w/o running */ |
| 82 | static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f, | ||
| 83 | 0x00, 0x18, 0x00 }; | ||
| 84 | static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, | ||
| 85 | 0x7f, 0x7f, 0x7f }; | ||
| 86 | static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 }; | ||
| 87 | static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00, | ||
| 88 | 0x00 }; | ||
| 89 | static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 }; | ||
| 90 | static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; | 82 | static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; |
| 91 | static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; | 83 | static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; |
| 92 | static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 }; | ||
| 93 | 84 | ||
| 94 | struct iwl_calib_default_data { | 85 | struct iwl_calib_default_data { |
| 95 | u16 size; | 86 | u16 size; |
| @@ -99,12 +90,7 @@ struct iwl_calib_default_data { | |||
| 99 | #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} | 90 | #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} |
| 100 | 91 | ||
| 101 | static const struct iwl_calib_default_data wkp_calib_default_data[12] = { | 92 | static const struct iwl_calib_default_data wkp_calib_default_data[12] = { |
| 102 | [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc), | ||
| 103 | [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter), | ||
| 104 | [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo), | ||
| 105 | [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq), | ||
| 106 | [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), | 93 | [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), |
| 107 | [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq), | ||
| 108 | [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), | 94 | [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), |
| 109 | }; | 95 | }; |
| 110 | 96 | ||
| @@ -241,20 +227,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, | |||
| 241 | 227 | ||
| 242 | return 0; | 228 | return 0; |
| 243 | } | 229 | } |
| 244 | #define IWL_HW_REV_ID_RAINBOW 0x2 | ||
| 245 | #define IWL_PROJ_TYPE_LHP 0x5 | ||
| 246 | |||
| 247 | static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm) | ||
| 248 | { | ||
| 249 | struct iwl_nvm_data *data = mvm->nvm_data; | ||
| 250 | /* Temp calls to static definitions, will be changed to CSR calls */ | ||
| 251 | u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW; | ||
| 252 | u8 project_type = IWL_PROJ_TYPE_LHP; | ||
| 253 | |||
| 254 | return data->radio_cfg_dash | (data->radio_cfg_step << 2) | | ||
| 255 | (hw_rev_id << 4) | ((project_type & 0x7f) << 6) | | ||
| 256 | (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20); | ||
| 257 | } | ||
| 258 | 230 | ||
| 259 | static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) | 231 | static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) |
| 260 | { | 232 | { |
| @@ -262,7 +234,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) | |||
| 262 | enum iwl_ucode_type ucode_type = mvm->cur_ucode; | 234 | enum iwl_ucode_type ucode_type = mvm->cur_ucode; |
| 263 | 235 | ||
| 264 | /* Set parameters */ | 236 | /* Set parameters */ |
| 265 | phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); | 237 | phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); |
| 266 | phy_cfg_cmd.calib_control.event_trigger = | 238 | phy_cfg_cmd.calib_control.event_trigger = |
| 267 | mvm->fw->default_calib[ucode_type].event_trigger; | 239 | mvm->fw->default_calib[ucode_type].event_trigger; |
| 268 | phy_cfg_cmd.calib_control.flow_trigger = | 240 | phy_cfg_cmd.calib_control.flow_trigger = |
| @@ -275,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) | |||
| 275 | sizeof(phy_cfg_cmd), &phy_cfg_cmd); | 247 | sizeof(phy_cfg_cmd), &phy_cfg_cmd); |
| 276 | } | 248 | } |
| 277 | 249 | ||
| 278 | /* Starting with the new PHY DB implementation - New calibs are enabled */ | ||
| 279 | /* Value - 0x405e7 */ | ||
| 280 | #define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\ | ||
| 281 | IWL_CALIB_CFG_TEMPERATURE_IDX |\ | ||
| 282 | IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ | ||
| 283 | IWL_CALIB_CFG_DC_IDX |\ | ||
| 284 | IWL_CALIB_CFG_BB_FILTER_IDX |\ | ||
| 285 | IWL_CALIB_CFG_LO_LEAKAGE_IDX |\ | ||
| 286 | IWL_CALIB_CFG_TX_IQ_IDX |\ | ||
| 287 | IWL_CALIB_CFG_RX_IQ_IDX |\ | ||
| 288 | IWL_CALIB_CFG_AGC_IDX) | ||
| 289 | |||
| 290 | #define IWL_CALIB_DEFAULT_EVENT_INIT 0x0 | ||
| 291 | |||
| 292 | /* Value 0x41567 */ | ||
| 293 | #define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\ | ||
| 294 | IWL_CALIB_CFG_TEMPERATURE_IDX |\ | ||
| 295 | IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ | ||
| 296 | IWL_CALIB_CFG_BB_FILTER_IDX |\ | ||
| 297 | IWL_CALIB_CFG_DC_IDX |\ | ||
| 298 | IWL_CALIB_CFG_TX_IQ_IDX |\ | ||
| 299 | IWL_CALIB_CFG_RX_IQ_IDX |\ | ||
| 300 | IWL_CALIB_CFG_SENSITIVITY_IDX |\ | ||
| 301 | IWL_CALIB_CFG_AGC_IDX) | ||
| 302 | |||
| 303 | #define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\ | ||
| 304 | IWL_CALIB_CFG_TEMPERATURE_IDX |\ | ||
| 305 | IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ | ||
| 306 | IWL_CALIB_CFG_TX_PWR_IDX |\ | ||
| 307 | IWL_CALIB_CFG_DC_IDX |\ | ||
| 308 | IWL_CALIB_CFG_TX_IQ_IDX |\ | ||
| 309 | IWL_CALIB_CFG_SENSITIVITY_IDX) | ||
| 310 | |||
| 311 | /* | ||
| 312 | * Sets the calibrations trigger values that will be sent to the FW for runtime | ||
| 313 | * and init calibrations. | ||
| 314 | * The ones given in the FW TLV are not correct. | ||
| 315 | */ | ||
| 316 | static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm) | ||
| 317 | { | ||
| 318 | struct iwl_tlv_calib_ctrl default_calib; | ||
| 319 | |||
| 320 | /* | ||
| 321 | * WkP FW TLV calib bits are wrong, overwrite them. | ||
| 322 | * This defines the dynamic calibrations which are implemented in the | ||
| 323 | * uCode both for init(flow) calculation and event driven calibs. | ||
| 324 | */ | ||
| 325 | |||
| 326 | /* Init Image */ | ||
| 327 | default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT); | ||
| 328 | default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT); | ||
| 329 | |||
| 330 | if (default_calib.event_trigger != | ||
| 331 | mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger) | ||
| 332 | IWL_ERR(mvm, | ||
| 333 | "Updating the event calib for INIT image: 0x%x -> 0x%x\n", | ||
| 334 | mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger, | ||
| 335 | default_calib.event_trigger); | ||
| 336 | if (default_calib.flow_trigger != | ||
| 337 | mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger) | ||
| 338 | IWL_ERR(mvm, | ||
| 339 | "Updating the flow calib for INIT image: 0x%x -> 0x%x\n", | ||
| 340 | mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger, | ||
| 341 | default_calib.flow_trigger); | ||
| 342 | |||
| 343 | memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT], | ||
| 344 | &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); | ||
| 345 | IWL_ERR(mvm, | ||
| 346 | "Setting uCode init calibrations event 0x%x, trigger 0x%x\n", | ||
| 347 | default_calib.event_trigger, | ||
| 348 | default_calib.flow_trigger); | ||
| 349 | |||
| 350 | /* Run time image */ | ||
| 351 | default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN); | ||
| 352 | default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN); | ||
| 353 | |||
| 354 | if (default_calib.event_trigger != | ||
| 355 | mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger) | ||
| 356 | IWL_ERR(mvm, | ||
| 357 | "Updating the event calib for RT image: 0x%x -> 0x%x\n", | ||
| 358 | mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger, | ||
| 359 | default_calib.event_trigger); | ||
| 360 | if (default_calib.flow_trigger != | ||
| 361 | mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger) | ||
| 362 | IWL_ERR(mvm, | ||
| 363 | "Updating the flow calib for RT image: 0x%x -> 0x%x\n", | ||
| 364 | mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger, | ||
| 365 | default_calib.flow_trigger); | ||
| 366 | |||
| 367 | memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR], | ||
| 368 | &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); | ||
| 369 | IWL_ERR(mvm, | ||
| 370 | "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n", | ||
| 371 | default_calib.event_trigger, | ||
| 372 | default_calib.flow_trigger); | ||
| 373 | } | ||
| 374 | |||
| 375 | static int iwl_set_default_calibrations(struct iwl_mvm *mvm) | 250 | static int iwl_set_default_calibrations(struct iwl_mvm *mvm) |
| 376 | { | 251 | { |
| 377 | u8 cmd_raw[16]; /* holds the variable size commands */ | 252 | u8 cmd_raw[16]; /* holds the variable size commands */ |
| @@ -434,6 +309,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) | |||
| 434 | goto error; | 309 | goto error; |
| 435 | } | 310 | } |
| 436 | 311 | ||
| 312 | ret = iwl_send_bt_prio_tbl(mvm); | ||
| 313 | if (ret) | ||
| 314 | goto error; | ||
| 315 | |||
| 437 | if (read_nvm) { | 316 | if (read_nvm) { |
| 438 | /* Read nvm */ | 317 | /* Read nvm */ |
| 439 | ret = iwl_nvm_init(mvm); | 318 | ret = iwl_nvm_init(mvm); |
| @@ -446,8 +325,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) | |||
| 446 | ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); | 325 | ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); |
| 447 | WARN_ON(ret); | 326 | WARN_ON(ret); |
| 448 | 327 | ||
| 449 | /* Override the calibrations from TLV and the const of fw */ | 328 | /* Send TX valid antennas before triggering calibrations */ |
| 450 | iwl_set_default_calib_trigger(mvm); | 329 | ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); |
| 330 | if (ret) | ||
| 331 | goto error; | ||
| 451 | 332 | ||
| 452 | /* WkP doesn't have all calibrations, need to set default values */ | 333 | /* WkP doesn't have all calibrations, need to set default values */ |
| 453 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { | 334 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { |
| @@ -537,6 +418,14 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
| 537 | if (ret) | 418 | if (ret) |
| 538 | goto error; | 419 | goto error; |
| 539 | 420 | ||
| 421 | ret = iwl_send_bt_prio_tbl(mvm); | ||
| 422 | if (ret) | ||
| 423 | goto error; | ||
| 424 | |||
| 425 | ret = iwl_send_bt_init_conf(mvm); | ||
| 426 | if (ret) | ||
| 427 | goto error; | ||
| 428 | |||
| 540 | /* Send phy db control command and then phy db calibration*/ | 429 | /* Send phy db control command and then phy db calibration*/ |
| 541 | ret = iwl_send_phy_db_data(mvm->phy_db); | 430 | ret = iwl_send_phy_db_data(mvm->phy_db); |
| 542 | if (ret) | 431 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c index 011906e73a05..2269a9e5cc67 100644 --- a/drivers/net/wireless/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/iwlwifi/mvm/led.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 341dbc0237ea..2779235daa35 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
| 553 | if (vif->bss_conf.qos) | 553 | if (vif->bss_conf.qos) |
| 554 | cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); | 554 | cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); |
| 555 | 555 | ||
| 556 | /* Don't use cts to self as the fw doesn't support it currently. */ | ||
| 556 | if (vif->bss_conf.use_cts_prot) | 557 | if (vif->bss_conf.use_cts_prot) |
| 557 | cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | | 558 | cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); |
| 558 | MAC_PROT_FLG_SELF_CTS_EN); | ||
| 559 | 559 | ||
| 560 | /* | 560 | /* |
| 561 | * I think that we should enable these 2 flags regardless the HT PROT | 561 | * I think that we should enable these 2 flags regardless the HT PROT |
| @@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm, | |||
| 651 | /* Fill the common data for all mac context types */ | 651 | /* Fill the common data for all mac context types */ |
| 652 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 652 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 653 | 653 | ||
| 654 | /* Allow beacons to pass through as long as we are not associated,or we | ||
| 655 | * do not have dtim period information */ | ||
| 656 | if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period) | ||
| 657 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON); | ||
| 658 | else | ||
| 659 | cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); | ||
| 660 | |||
| 654 | /* Fill the data specific for station mode */ | 661 | /* Fill the data specific for station mode */ |
| 655 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); | 662 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); |
| 656 | 663 | ||
| @@ -714,7 +721,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, | |||
| 714 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 721 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 715 | 722 | ||
| 716 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); | 723 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); |
| 717 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); | 724 | |
| 725 | /* Override the filter flags to accept only probe requests */ | ||
| 726 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); | ||
| 718 | 727 | ||
| 719 | /* | 728 | /* |
| 720 | * This flag should be set to true when the P2P Device is | 729 | * This flag should be set to true when the P2P Device is |
| @@ -846,10 +855,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, | |||
| 846 | */ | 855 | */ |
| 847 | static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, | 856 | static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, |
| 848 | struct ieee80211_vif *vif, | 857 | struct ieee80211_vif *vif, |
| 849 | struct iwl_mac_data_ap *ctxt_ap) | 858 | struct iwl_mac_data_ap *ctxt_ap, |
| 859 | bool add) | ||
| 850 | { | 860 | { |
| 851 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 861 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 852 | u32 curr_dev_time; | ||
| 853 | 862 | ||
| 854 | ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); | 863 | ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); |
| 855 | ctxt_ap->bi_reciprocal = | 864 | ctxt_ap->bi_reciprocal = |
| @@ -861,10 +870,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, | |||
| 861 | vif->bss_conf.dtim_period)); | 870 | vif->bss_conf.dtim_period)); |
| 862 | 871 | ||
| 863 | ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); | 872 | ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); |
| 864 | curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); | ||
| 865 | ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time); | ||
| 866 | 873 | ||
| 867 | ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); | 874 | /* |
| 875 | * Only read the system time when the MAC is being added, when we | ||
| 876 | * just modify the MAC then we should keep the time -- the firmware | ||
| 877 | * can otherwise have a "jumping" TBTT. | ||
| 878 | */ | ||
| 879 | if (add) | ||
| 880 | mvmvif->ap_beacon_time = | ||
| 881 | iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); | ||
| 882 | |||
| 883 | ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); | ||
| 884 | |||
| 885 | ctxt_ap->beacon_tsf = 0; /* unused */ | ||
| 868 | 886 | ||
| 869 | /* TODO: Assume that the beacon id == mac context id */ | 887 | /* TODO: Assume that the beacon id == mac context id */ |
| 870 | ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); | 888 | ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); |
| @@ -881,8 +899,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, | |||
| 881 | /* Fill the common data for all mac context types */ | 899 | /* Fill the common data for all mac context types */ |
| 882 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 900 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 883 | 901 | ||
| 902 | /* Also enable probe requests to pass */ | ||
| 903 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); | ||
| 904 | |||
| 884 | /* Fill the data specific for ap mode */ | 905 | /* Fill the data specific for ap mode */ |
| 885 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); | 906 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, |
| 907 | action == FW_CTXT_ACTION_ADD); | ||
| 886 | 908 | ||
| 887 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); | 909 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); |
| 888 | } | 910 | } |
| @@ -899,7 +921,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
| 899 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 921 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 900 | 922 | ||
| 901 | /* Fill the data specific for GO mode */ | 923 | /* Fill the data specific for GO mode */ |
| 902 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); | 924 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, |
| 925 | action == FW_CTXT_ACTION_ADD); | ||
| 903 | 926 | ||
| 904 | cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); | 927 | cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); |
| 905 | cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); | 928 | cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 23460f4a4c75..14dd5ee9a01e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -65,7 +65,9 @@ | |||
| 65 | #include <linux/skbuff.h> | 65 | #include <linux/skbuff.h> |
| 66 | #include <linux/netdevice.h> | 66 | #include <linux/netdevice.h> |
| 67 | #include <linux/etherdevice.h> | 67 | #include <linux/etherdevice.h> |
| 68 | #include <linux/ip.h> | ||
| 68 | #include <net/mac80211.h> | 69 | #include <net/mac80211.h> |
| 70 | #include <net/tcp.h> | ||
| 69 | 71 | ||
| 70 | #include "iwl-op-mode.h" | 72 | #include "iwl-op-mode.h" |
| 71 | #include "iwl-io.h" | 73 | #include "iwl-io.h" |
| @@ -102,10 +104,33 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { | |||
| 102 | }, | 104 | }, |
| 103 | }; | 105 | }; |
| 104 | 106 | ||
| 107 | #ifdef CONFIG_PM_SLEEP | ||
| 108 | static const struct nl80211_wowlan_tcp_data_token_feature | ||
| 109 | iwl_mvm_wowlan_tcp_token_feature = { | ||
| 110 | .min_len = 0, | ||
| 111 | .max_len = 255, | ||
| 112 | .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = { | ||
| 116 | .tok = &iwl_mvm_wowlan_tcp_token_feature, | ||
| 117 | .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN - | ||
| 118 | sizeof(struct ethhdr) - | ||
| 119 | sizeof(struct iphdr) - | ||
| 120 | sizeof(struct tcphdr), | ||
| 121 | .data_interval_max = 65535, /* __le16 in API */ | ||
| 122 | .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN - | ||
| 123 | sizeof(struct ethhdr) - | ||
| 124 | sizeof(struct iphdr) - | ||
| 125 | sizeof(struct tcphdr), | ||
| 126 | .seq = true, | ||
| 127 | }; | ||
| 128 | #endif | ||
| 129 | |||
| 105 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | 130 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) |
| 106 | { | 131 | { |
| 107 | struct ieee80211_hw *hw = mvm->hw; | 132 | struct ieee80211_hw *hw = mvm->hw; |
| 108 | int num_mac, ret; | 133 | int num_mac, ret, i; |
| 109 | 134 | ||
| 110 | /* Tell mac80211 our characteristics */ | 135 | /* Tell mac80211 our characteristics */ |
| 111 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 136 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
| @@ -156,11 +181,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 156 | memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); | 181 | memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); |
| 157 | hw->wiphy->addresses = mvm->addresses; | 182 | hw->wiphy->addresses = mvm->addresses; |
| 158 | hw->wiphy->n_addresses = 1; | 183 | hw->wiphy->n_addresses = 1; |
| 159 | num_mac = mvm->nvm_data->n_hw_addrs; | 184 | |
| 160 | if (num_mac > 1) { | 185 | /* Extract additional MAC addresses if available */ |
| 161 | memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, | 186 | num_mac = (mvm->nvm_data->n_hw_addrs > 1) ? |
| 187 | min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1; | ||
| 188 | |||
| 189 | for (i = 1; i < num_mac; i++) { | ||
| 190 | memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr, | ||
| 162 | ETH_ALEN); | 191 | ETH_ALEN); |
| 163 | mvm->addresses[1].addr[5]++; | 192 | mvm->addresses[i].addr[5]++; |
| 164 | hw->wiphy->n_addresses++; | 193 | hw->wiphy->n_addresses++; |
| 165 | } | 194 | } |
| 166 | 195 | ||
| @@ -206,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 206 | hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; | 235 | hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; |
| 207 | hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; | 236 | hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; |
| 208 | hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; | 237 | hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; |
| 238 | hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; | ||
| 209 | } | 239 | } |
| 210 | #endif | 240 | #endif |
| 211 | 241 | ||
| @@ -273,12 +303,18 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 273 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); | 303 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); |
| 274 | break; | 304 | break; |
| 275 | case IEEE80211_AMPDU_TX_START: | 305 | case IEEE80211_AMPDU_TX_START: |
| 306 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { | ||
| 307 | ret = -EINVAL; | ||
| 308 | break; | ||
| 309 | } | ||
| 276 | ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); | 310 | ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); |
| 277 | break; | 311 | break; |
| 278 | case IEEE80211_AMPDU_TX_STOP_CONT: | 312 | case IEEE80211_AMPDU_TX_STOP_CONT: |
| 313 | ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); | ||
| 314 | break; | ||
| 279 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | 315 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
| 280 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | 316 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
| 281 | ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); | 317 | ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid); |
| 282 | break; | 318 | break; |
| 283 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 319 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
| 284 | ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); | 320 | ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); |
| @@ -557,11 +593,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 557 | return ret; | 593 | return ret; |
| 558 | } | 594 | } |
| 559 | 595 | ||
| 560 | static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | 596 | static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, |
| 561 | struct ieee80211_vif *vif) | 597 | struct ieee80211_vif *vif) |
| 562 | { | 598 | { |
| 563 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
| 564 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 565 | u32 tfd_msk = 0, ac; | 599 | u32 tfd_msk = 0, ac; |
| 566 | 600 | ||
| 567 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 601 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
| @@ -594,12 +628,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 594 | */ | 628 | */ |
| 595 | flush_work(&mvm->sta_drained_wk); | 629 | flush_work(&mvm->sta_drained_wk); |
| 596 | } | 630 | } |
| 631 | } | ||
| 632 | |||
| 633 | static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | ||
| 634 | struct ieee80211_vif *vif) | ||
| 635 | { | ||
| 636 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
| 637 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 638 | |||
| 639 | iwl_mvm_prepare_mac_removal(mvm, vif); | ||
| 597 | 640 | ||
| 598 | mutex_lock(&mvm->mutex); | 641 | mutex_lock(&mvm->mutex); |
| 599 | 642 | ||
| 600 | /* | 643 | /* |
| 601 | * For AP/GO interface, the tear down of the resources allocated to the | 644 | * For AP/GO interface, the tear down of the resources allocated to the |
| 602 | * interface should be handled as part of the bss_info_changed flow. | 645 | * interface is be handled as part of the stop_ap flow. |
| 603 | */ | 646 | */ |
| 604 | if (vif->type == NL80211_IFTYPE_AP) { | 647 | if (vif->type == NL80211_IFTYPE_AP) { |
| 605 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | 648 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); |
| @@ -763,6 +806,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 763 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 806 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
| 764 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 807 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 765 | 808 | ||
| 809 | iwl_mvm_prepare_mac_removal(mvm, vif); | ||
| 810 | |||
| 766 | mutex_lock(&mvm->mutex); | 811 | mutex_lock(&mvm->mutex); |
| 767 | 812 | ||
| 768 | mvmvif->ap_active = false; | 813 | mvmvif->ap_active = false; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4e339ccfa800..203eb85e03d3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -79,8 +79,9 @@ | |||
| 79 | #include "fw-api.h" | 79 | #include "fw-api.h" |
| 80 | 80 | ||
| 81 | #define IWL_INVALID_MAC80211_QUEUE 0xff | 81 | #define IWL_INVALID_MAC80211_QUEUE 0xff |
| 82 | #define IWL_MVM_MAX_ADDRESSES 2 | 82 | #define IWL_MVM_MAX_ADDRESSES 5 |
| 83 | #define IWL_RSSI_OFFSET 44 | 83 | /* RSSI offset for WkP */ |
| 84 | #define IWL_RSSI_OFFSET 50 | ||
| 84 | 85 | ||
| 85 | enum iwl_mvm_tx_fifo { | 86 | enum iwl_mvm_tx_fifo { |
| 86 | IWL_MVM_TX_FIFO_BK = 0, | 87 | IWL_MVM_TX_FIFO_BK = 0, |
| @@ -173,6 +174,8 @@ struct iwl_mvm_vif { | |||
| 173 | bool uploaded; | 174 | bool uploaded; |
| 174 | bool ap_active; | 175 | bool ap_active; |
| 175 | 176 | ||
| 177 | u32 ap_beacon_time; | ||
| 178 | |||
| 176 | enum iwl_tsf_id tsf_id; | 179 | enum iwl_tsf_id tsf_id; |
| 177 | 180 | ||
| 178 | /* | 181 | /* |
| @@ -327,6 +330,14 @@ struct iwl_mvm { | |||
| 327 | struct led_classdev led; | 330 | struct led_classdev led; |
| 328 | 331 | ||
| 329 | struct ieee80211_vif *p2p_device_vif; | 332 | struct ieee80211_vif *p2p_device_vif; |
| 333 | |||
| 334 | #ifdef CONFIG_PM_SLEEP | ||
| 335 | int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; | ||
| 336 | #endif | ||
| 337 | |||
| 338 | /* BT-Coex */ | ||
| 339 | u8 bt_kill_msk; | ||
| 340 | struct iwl_bt_coex_profile_notif last_bt_notif; | ||
| 330 | }; | 341 | }; |
| 331 | 342 | ||
| 332 | /* Extract MVM priv from op_mode and _hw */ | 343 | /* Extract MVM priv from op_mode and _hw */ |
| @@ -497,4 +508,11 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, | |||
| 497 | void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, | 508 | void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, |
| 498 | struct ieee80211_vif *vif, int idx); | 509 | struct ieee80211_vif *vif, int idx); |
| 499 | 510 | ||
| 511 | /* BT Coex */ | ||
| 512 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); | ||
| 513 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm); | ||
| 514 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | ||
| 515 | struct iwl_rx_cmd_buffer *rxb, | ||
| 516 | struct iwl_device_cmd *cmd); | ||
| 517 | |||
| 500 | #endif /* __IWL_MVM_H__ */ | 518 | #endif /* __IWL_MVM_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 20016bcbdeab..93e3d0f174cc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -74,6 +74,9 @@ static const int nvm_to_read[] = { | |||
| 74 | NVM_SECTION_TYPE_PRODUCTION, | 74 | NVM_SECTION_TYPE_PRODUCTION, |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | /* Default NVM size to read */ | ||
| 78 | #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); | ||
| 79 | |||
| 77 | /* used to simplify the shared operations on NCM_ACCESS_CMD versions */ | 80 | /* used to simplify the shared operations on NCM_ACCESS_CMD versions */ |
| 78 | union iwl_nvm_access_cmd { | 81 | union iwl_nvm_access_cmd { |
| 79 | struct iwl_nvm_access_cmd_ver1 ver1; | 82 | struct iwl_nvm_access_cmd_ver1 ver1; |
| @@ -193,9 +196,9 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, | |||
| 193 | int ret; | 196 | int ret; |
| 194 | bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; | 197 | bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; |
| 195 | 198 | ||
| 196 | length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) | 199 | /* Set nvm section read length */ |
| 197 | - sizeof(union iwl_nvm_access_cmd) | 200 | length = IWL_NVM_DEFAULT_CHUNK_SIZE; |
| 198 | - sizeof(struct iwl_rx_packet); | 201 | |
| 199 | /* | 202 | /* |
| 200 | * if length is greater than EEPROM size, truncate it because uCode | 203 | * if length is greater than EEPROM size, truncate it because uCode |
| 201 | * doesn't check it by itself, and exit the loop when reached. | 204 | * doesn't check it by itself, and exit the loop when reached. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index aa59adf87db3..828bdddd07e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -230,6 +230,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { | |||
| 230 | RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), | 230 | RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), |
| 231 | RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), | 231 | RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), |
| 232 | 232 | ||
| 233 | RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), | ||
| 234 | |||
| 233 | RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), | 235 | RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), |
| 234 | RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), | 236 | RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), |
| 235 | 237 | ||
| @@ -293,6 +295,11 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { | |||
| 293 | CMD(NET_DETECT_PROFILES_CMD), | 295 | CMD(NET_DETECT_PROFILES_CMD), |
| 294 | CMD(NET_DETECT_HOTSPOTS_CMD), | 296 | CMD(NET_DETECT_HOTSPOTS_CMD), |
| 295 | CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), | 297 | CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), |
| 298 | CMD(CARD_STATE_NOTIFICATION), | ||
| 299 | CMD(BT_COEX_PRIO_TABLE), | ||
| 300 | CMD(BT_COEX_PROT_ENV), | ||
| 301 | CMD(BT_PROFILE_NOTIFICATION), | ||
| 302 | CMD(BT_CONFIG), | ||
| 296 | }; | 303 | }; |
| 297 | #undef CMD | 304 | #undef CMD |
| 298 | 305 | ||
| @@ -363,8 +370,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
| 363 | trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); | 370 | trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); |
| 364 | trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; | 371 | trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; |
| 365 | 372 | ||
| 366 | /* TODO: this should really be a TLV */ | 373 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) |
| 367 | if (cfg->device_family == IWL_DEVICE_FAMILY_7000) | ||
| 368 | trans_cfg.bc_table_dword = true; | 374 | trans_cfg.bc_table_dword = true; |
| 369 | 375 | ||
| 370 | if (!iwlwifi_mod_params.wd_disable) | 376 | if (!iwlwifi_mod_params.wd_disable) |
| @@ -624,12 +630,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | |||
| 624 | ieee80211_free_txskb(mvm->hw, skb); | 630 | ieee80211_free_txskb(mvm->hw, skb); |
| 625 | } | 631 | } |
| 626 | 632 | ||
| 627 | static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) | 633 | static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) |
| 628 | { | 634 | { |
| 629 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
| 630 | |||
| 631 | iwl_mvm_dump_nic_error_log(mvm); | ||
| 632 | |||
| 633 | iwl_abort_notification_waits(&mvm->notif_wait); | 635 | iwl_abort_notification_waits(&mvm->notif_wait); |
| 634 | 636 | ||
| 635 | /* | 637 | /* |
| @@ -663,9 +665,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) | |||
| 663 | } | 665 | } |
| 664 | } | 666 | } |
| 665 | 667 | ||
| 668 | static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) | ||
| 669 | { | ||
| 670 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
| 671 | |||
| 672 | iwl_mvm_dump_nic_error_log(mvm); | ||
| 673 | |||
| 674 | iwl_mvm_nic_restart(mvm); | ||
| 675 | } | ||
| 676 | |||
| 666 | static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) | 677 | static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) |
| 667 | { | 678 | { |
| 679 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
| 680 | |||
| 668 | WARN_ON(1); | 681 | WARN_ON(1); |
| 682 | iwl_mvm_nic_restart(mvm); | ||
| 669 | } | 683 | } |
| 670 | 684 | ||
| 671 | static const struct iwl_op_mode_ops iwl_mvm_ops = { | 685 | static const struct iwl_op_mode_ops iwl_mvm_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index b428448f8ddf..0d537e035ef0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5a92a4978795..efb9a6f3faac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 925628468146..df85c49dc599 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 56b636d9ab30..a01a6612677e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
| @@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | |||
| 680 | */ | 680 | */ |
| 681 | static bool rs_use_green(struct ieee80211_sta *sta) | 681 | static bool rs_use_green(struct ieee80211_sta *sta) |
| 682 | { | 682 | { |
| 683 | struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; | 683 | /* |
| 684 | 684 | * There's a bug somewhere in this code that causes the | |
| 685 | bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & | 685 | * scaling to get stuck because GF+SGI can't be combined |
| 686 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | 686 | * in SISO rates. Until we find that bug, disable GF, it |
| 687 | 687 | * has only limited benefit and we still interoperate with | |
| 688 | return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; | 688 | * GF APs since we can always receive GF transmissions. |
| 689 | */ | ||
| 690 | return false; | ||
| 689 | } | 691 | } |
| 690 | 692 | ||
| 691 | /** | 693 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 3f40ab05bbd8..4dfc21a3e83e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, | |||
| 131 | static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | 131 | static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, |
| 132 | struct iwl_rx_phy_info *phy_info) | 132 | struct iwl_rx_phy_info *phy_info) |
| 133 | { | 133 | { |
| 134 | u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; | 134 | int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; |
| 135 | int rssi_all_band_a, rssi_all_band_b; | ||
| 136 | u32 agc_a, agc_b, max_agc; | ||
| 135 | u32 val; | 137 | u32 val; |
| 136 | 138 | ||
| 137 | /* Find max rssi among 3 possible receivers. | 139 | /* Find max rssi among 2 possible receivers. |
| 138 | * These values are measured by the Digital Signal Processor (DSP). | 140 | * These values are measured by the Digital Signal Processor (DSP). |
| 139 | * They should stay fairly constant even as the signal strength varies, | 141 | * They should stay fairly constant even as the signal strength varies, |
| 140 | * if the radio's Automatic Gain Control (AGC) is working right. | 142 | * if the radio's Automatic Gain Control (AGC) is working right. |
| 141 | * AGC value (see below) will provide the "interesting" info. | 143 | * AGC value (see below) will provide the "interesting" info. |
| 142 | */ | 144 | */ |
| 145 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); | ||
| 146 | agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; | ||
| 147 | agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; | ||
| 148 | max_agc = max_t(u32, agc_a, agc_b); | ||
| 149 | |||
| 143 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); | 150 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); |
| 144 | rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; | 151 | rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; |
| 145 | rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; | 152 | rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; |
| 146 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); | 153 | rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >> |
| 147 | rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; | 154 | IWL_OFDM_RSSI_ALLBAND_A_POS; |
| 148 | 155 | rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >> | |
| 149 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); | 156 | IWL_OFDM_RSSI_ALLBAND_B_POS; |
| 150 | agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS; | ||
| 151 | 157 | ||
| 152 | max_rssi = max_t(u32, rssi_a, rssi_b); | 158 | /* |
| 153 | max_rssi = max_t(u32, max_rssi, rssi_c); | 159 | * dBm = rssi dB - agc dB - constant. |
| 160 | * Higher AGC (higher radio gain) means lower signal. | ||
| 161 | */ | ||
| 162 | rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a; | ||
| 163 | rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b; | ||
| 164 | max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm); | ||
| 154 | 165 | ||
| 155 | IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", | 166 | IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", |
| 156 | rssi_a, rssi_b, rssi_c, max_rssi, agc_db); | 167 | rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); |
| 157 | 168 | ||
| 158 | /* dBm = max_rssi dB - agc dB - constant. | 169 | return max_rssi_dbm; |
| 159 | * Higher AGC (higher radio gain) means lower signal. */ | ||
| 160 | return max_rssi - agc_db - IWL_RSSI_OFFSET; | ||
| 161 | } | 170 | } |
| 162 | 171 | ||
| 163 | /* | 172 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 9b21b92aa8d1..0d3c76b29242 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 52aecf20d0df..4d872d69577f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 101 | } | 101 | } |
| 102 | add_sta_cmd.add_modify = update ? 1 : 0; | 102 | add_sta_cmd.add_modify = update ? 1 : 0; |
| 103 | 103 | ||
| 104 | /* STA_FLG_FAT_EN_MSK ? */ | 104 | add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK | |
| 105 | /* STA_FLG_MIMO_EN_MSK ? */ | 105 | STA_FLG_MIMO_EN_MSK); |
| 106 | |||
| 107 | switch (sta->bandwidth) { | ||
| 108 | case IEEE80211_STA_RX_BW_160: | ||
| 109 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ); | ||
| 110 | /* fall through */ | ||
| 111 | case IEEE80211_STA_RX_BW_80: | ||
| 112 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ); | ||
| 113 | /* fall through */ | ||
| 114 | case IEEE80211_STA_RX_BW_40: | ||
| 115 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ); | ||
| 116 | /* fall through */ | ||
| 117 | case IEEE80211_STA_RX_BW_20: | ||
| 118 | if (sta->ht_cap.ht_supported) | ||
| 119 | add_sta_cmd.station_flags |= | ||
| 120 | cpu_to_le32(STA_FLG_FAT_EN_20MHZ); | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | |||
| 124 | switch (sta->rx_nss) { | ||
| 125 | case 1: | ||
| 126 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); | ||
| 127 | break; | ||
| 128 | case 2: | ||
| 129 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2); | ||
| 130 | break; | ||
| 131 | case 3 ... 8: | ||
| 132 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3); | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | |||
| 136 | switch (sta->smps_mode) { | ||
| 137 | case IEEE80211_SMPS_AUTOMATIC: | ||
| 138 | case IEEE80211_SMPS_NUM_MODES: | ||
| 139 | WARN_ON(1); | ||
| 140 | break; | ||
| 141 | case IEEE80211_SMPS_STATIC: | ||
| 142 | /* override NSS */ | ||
| 143 | add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK); | ||
| 144 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); | ||
| 145 | break; | ||
| 146 | case IEEE80211_SMPS_DYNAMIC: | ||
| 147 | add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT); | ||
| 148 | break; | ||
| 149 | case IEEE80211_SMPS_OFF: | ||
| 150 | /* nothing */ | ||
| 151 | break; | ||
| 152 | } | ||
| 106 | 153 | ||
| 107 | if (sta->ht_cap.ht_supported) { | 154 | if (sta->ht_cap.ht_supported) { |
| 108 | add_sta_cmd.station_flags_msk |= | 155 | add_sta_cmd.station_flags_msk |= |
| @@ -340,6 +387,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, | |||
| 340 | 387 | ||
| 341 | if (vif->type == NL80211_IFTYPE_STATION && | 388 | if (vif->type == NL80211_IFTYPE_STATION && |
| 342 | mvmvif->ap_sta_id == mvm_sta->sta_id) { | 389 | mvmvif->ap_sta_id == mvm_sta->sta_id) { |
| 390 | /* flush its queues here since we are freeing mvm_sta */ | ||
| 391 | ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); | ||
| 392 | |||
| 343 | /* | 393 | /* |
| 344 | * Put a non-NULL since the fw station isn't removed. | 394 | * Put a non-NULL since the fw station isn't removed. |
| 345 | * It will be removed after the MAC will be set as | 395 | * It will be removed after the MAC will be set as |
| @@ -348,9 +398,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, | |||
| 348 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], | 398 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], |
| 349 | ERR_PTR(-EINVAL)); | 399 | ERR_PTR(-EINVAL)); |
| 350 | 400 | ||
| 351 | /* flush its queues here since we are freeing mvm_sta */ | ||
| 352 | ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); | ||
| 353 | |||
| 354 | /* if we are associated - we can't remove the AP STA now */ | 401 | /* if we are associated - we can't remove the AP STA now */ |
| 355 | if (vif->bss_conf.assoc) | 402 | if (vif->bss_conf.assoc) |
| 356 | return ret; | 403 | return ret; |
| @@ -770,6 +817,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 770 | u16 txq_id; | 817 | u16 txq_id; |
| 771 | int err; | 818 | int err; |
| 772 | 819 | ||
| 820 | |||
| 821 | /* | ||
| 822 | * If mac80211 is cleaning its state, then say that we finished since | ||
| 823 | * our state has been cleared anyway. | ||
| 824 | */ | ||
| 825 | if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | ||
| 826 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
| 827 | return 0; | ||
| 828 | } | ||
| 829 | |||
| 773 | spin_lock_bh(&mvmsta->lock); | 830 | spin_lock_bh(&mvmsta->lock); |
| 774 | 831 | ||
| 775 | txq_id = tid_data->txq_id; | 832 | txq_id = tid_data->txq_id; |
| @@ -824,6 +881,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 824 | return err; | 881 | return err; |
| 825 | } | 882 | } |
| 826 | 883 | ||
| 884 | int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 885 | struct ieee80211_sta *sta, u16 tid) | ||
| 886 | { | ||
| 887 | struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; | ||
| 888 | struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; | ||
| 889 | u16 txq_id; | ||
| 890 | |||
| 891 | /* | ||
| 892 | * First set the agg state to OFF to avoid calling | ||
| 893 | * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty. | ||
| 894 | */ | ||
| 895 | spin_lock_bh(&mvmsta->lock); | ||
| 896 | txq_id = tid_data->txq_id; | ||
| 897 | IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", | ||
| 898 | mvmsta->sta_id, tid, txq_id, tid_data->state); | ||
| 899 | tid_data->state = IWL_AGG_OFF; | ||
| 900 | spin_unlock_bh(&mvmsta->lock); | ||
| 901 | |||
| 902 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | ||
| 903 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | ||
| 904 | |||
| 905 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | ||
| 906 | mvm->queue_to_mac80211[tid_data->txq_id] = | ||
| 907 | IWL_INVALID_MAC80211_QUEUE; | ||
| 908 | |||
| 909 | return 0; | ||
| 910 | } | ||
| 911 | |||
| 827 | static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) | 912 | static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) |
| 828 | { | 913 | { |
| 829 | int i; | 914 | int i; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 896f88ac8145..b0352df981e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -348,6 +348,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 348 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); | 348 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); |
| 349 | int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 349 | int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
| 350 | struct ieee80211_sta *sta, u16 tid); | 350 | struct ieee80211_sta *sta, u16 tid); |
| 351 | int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 352 | struct ieee80211_sta *sta, u16 tid); | ||
| 351 | 353 | ||
| 352 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); | 354 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); |
| 353 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | 355 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index e437e02c7149..c2c7f5176027 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 64fb57a5ab43..b36424eda361 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 56df249b215e..0556d5e16f4e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 607 | 607 | ||
| 608 | /* Single frame failure in an AMPDU queue => send BAR */ | 608 | /* Single frame failure in an AMPDU queue => send BAR */ |
| 609 | if (txq_id >= IWL_FIRST_AMPDU_QUEUE && | 609 | if (txq_id >= IWL_FIRST_AMPDU_QUEUE && |
| 610 | !(info->flags & IEEE80211_TX_STAT_ACK)) { | 610 | !(info->flags & IEEE80211_TX_STAT_ACK)) |
| 611 | /* there must be only one skb in the skb_list */ | ||
| 612 | WARN_ON_ONCE(skb_freed > 1 || | ||
| 613 | !skb_queue_empty(&skbs)); | ||
| 614 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 611 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
| 615 | } | ||
| 616 | 612 | ||
| 617 | /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ | 613 | /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ |
| 618 | if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { | 614 | if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 000e842c2edd..e308ad93aa9e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h deleted file mode 100644 index c6f8e83c3551..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/cfg.h +++ /dev/null | |||
| @@ -1,115 +0,0 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
| 4 | * redistributing this file, you may do so under either license. | ||
| 5 | * | ||
| 6 | * GPL LICENSE SUMMARY | ||
| 7 | * | ||
| 8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
| 22 | * USA | ||
| 23 | * | ||
| 24 | * The full GNU General Public License is included in this distribution | ||
| 25 | * in the file called LICENSE.GPL. | ||
| 26 | * | ||
| 27 | * Contact Information: | ||
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
| 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 30 | * | ||
| 31 | * BSD LICENSE | ||
| 32 | * | ||
| 33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | ||
| 34 | * All rights reserved. | ||
| 35 | * | ||
| 36 | * Redistribution and use in source and binary forms, with or without | ||
| 37 | * modification, are permitted provided that the following conditions | ||
| 38 | * are met: | ||
| 39 | * | ||
| 40 | * * Redistributions of source code must retain the above copyright | ||
| 41 | * notice, this list of conditions and the following disclaimer. | ||
| 42 | * * Redistributions in binary form must reproduce the above copyright | ||
| 43 | * notice, this list of conditions and the following disclaimer in | ||
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | ||
| 46 | * * Neither the name Intel Corporation nor the names of its | ||
| 47 | * contributors may be used to endorse or promote products derived | ||
| 48 | * from this software without specific prior written permission. | ||
| 49 | * | ||
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 61 | * | ||
| 62 | *****************************************************************************/ | ||
| 63 | #ifndef __iwl_pci_h__ | ||
| 64 | #define __iwl_pci_h__ | ||
| 65 | |||
| 66 | |||
| 67 | /* | ||
| 68 | * This file declares the config structures for all devices. | ||
| 69 | */ | ||
| 70 | |||
| 71 | extern const struct iwl_cfg iwl5300_agn_cfg; | ||
| 72 | extern const struct iwl_cfg iwl5100_agn_cfg; | ||
| 73 | extern const struct iwl_cfg iwl5350_agn_cfg; | ||
| 74 | extern const struct iwl_cfg iwl5100_bgn_cfg; | ||
| 75 | extern const struct iwl_cfg iwl5100_abg_cfg; | ||
| 76 | extern const struct iwl_cfg iwl5150_agn_cfg; | ||
| 77 | extern const struct iwl_cfg iwl5150_abg_cfg; | ||
| 78 | extern const struct iwl_cfg iwl6005_2agn_cfg; | ||
| 79 | extern const struct iwl_cfg iwl6005_2abg_cfg; | ||
| 80 | extern const struct iwl_cfg iwl6005_2bg_cfg; | ||
| 81 | extern const struct iwl_cfg iwl6005_2agn_sff_cfg; | ||
| 82 | extern const struct iwl_cfg iwl6005_2agn_d_cfg; | ||
| 83 | extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; | ||
| 84 | extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; | ||
| 85 | extern const struct iwl_cfg iwl1030_bgn_cfg; | ||
| 86 | extern const struct iwl_cfg iwl1030_bg_cfg; | ||
| 87 | extern const struct iwl_cfg iwl6030_2agn_cfg; | ||
| 88 | extern const struct iwl_cfg iwl6030_2abg_cfg; | ||
| 89 | extern const struct iwl_cfg iwl6030_2bgn_cfg; | ||
| 90 | extern const struct iwl_cfg iwl6030_2bg_cfg; | ||
| 91 | extern const struct iwl_cfg iwl6000i_2agn_cfg; | ||
| 92 | extern const struct iwl_cfg iwl6000i_2abg_cfg; | ||
| 93 | extern const struct iwl_cfg iwl6000i_2bg_cfg; | ||
| 94 | extern const struct iwl_cfg iwl6000_3agn_cfg; | ||
| 95 | extern const struct iwl_cfg iwl6050_2agn_cfg; | ||
| 96 | extern const struct iwl_cfg iwl6050_2abg_cfg; | ||
| 97 | extern const struct iwl_cfg iwl6150_bgn_cfg; | ||
| 98 | extern const struct iwl_cfg iwl6150_bg_cfg; | ||
| 99 | extern const struct iwl_cfg iwl1000_bgn_cfg; | ||
| 100 | extern const struct iwl_cfg iwl1000_bg_cfg; | ||
| 101 | extern const struct iwl_cfg iwl100_bgn_cfg; | ||
| 102 | extern const struct iwl_cfg iwl100_bg_cfg; | ||
| 103 | extern const struct iwl_cfg iwl130_bgn_cfg; | ||
| 104 | extern const struct iwl_cfg iwl130_bg_cfg; | ||
| 105 | extern const struct iwl_cfg iwl2000_2bgn_cfg; | ||
| 106 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; | ||
| 107 | extern const struct iwl_cfg iwl2030_2bgn_cfg; | ||
| 108 | extern const struct iwl_cfg iwl6035_2agn_cfg; | ||
| 109 | extern const struct iwl_cfg iwl105_bgn_cfg; | ||
| 110 | extern const struct iwl_cfg iwl105_bgn_d_cfg; | ||
| 111 | extern const struct iwl_cfg iwl135_bgn_cfg; | ||
| 112 | extern const struct iwl_cfg iwl7260_2ac_cfg; | ||
| 113 | extern const struct iwl_cfg iwl3160_ac_cfg; | ||
| 114 | |||
| 115 | #endif /* __iwl_pci_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 7bc0fb9128dd..46ca91f77c9c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -69,8 +69,6 @@ | |||
| 69 | 69 | ||
| 70 | #include "iwl-trans.h" | 70 | #include "iwl-trans.h" |
| 71 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
| 72 | |||
| 73 | #include "cfg.h" | ||
| 74 | #include "internal.h" | 72 | #include "internal.h" |
| 75 | 73 | ||
| 76 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 74 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index aa2a39a637dd..148843e7f34f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
| @@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) | |||
| 137 | struct iwl_cmd_meta { | 137 | struct iwl_cmd_meta { |
| 138 | /* only for SYNC commands, iff the reply skb is wanted */ | 138 | /* only for SYNC commands, iff the reply skb is wanted */ |
| 139 | struct iwl_host_cmd *source; | 139 | struct iwl_host_cmd *source; |
| 140 | |||
| 141 | DEFINE_DMA_UNMAP_ADDR(mapping); | ||
| 142 | DEFINE_DMA_UNMAP_LEN(len); | ||
| 143 | |||
| 144 | u32 flags; | 140 | u32 flags; |
| 145 | }; | 141 | }; |
| 146 | 142 | ||
| @@ -182,19 +178,39 @@ struct iwl_queue { | |||
| 182 | #define TFD_TX_CMD_SLOTS 256 | 178 | #define TFD_TX_CMD_SLOTS 256 |
| 183 | #define TFD_CMD_SLOTS 32 | 179 | #define TFD_CMD_SLOTS 32 |
| 184 | 180 | ||
| 181 | /* | ||
| 182 | * The FH will write back to the first TB only, so we need | ||
| 183 | * to copy some data into the buffer regardless of whether | ||
| 184 | * it should be mapped or not. This indicates how big the | ||
| 185 | * first TB must be to include the scratch buffer. Since | ||
| 186 | * the scratch is 4 bytes at offset 12, it's 16 now. If we | ||
| 187 | * make it bigger then allocations will be bigger and copy | ||
| 188 | * slower, so that's probably not useful. | ||
| 189 | */ | ||
| 190 | #define IWL_HCMD_SCRATCHBUF_SIZE 16 | ||
| 191 | |||
| 185 | struct iwl_pcie_txq_entry { | 192 | struct iwl_pcie_txq_entry { |
| 186 | struct iwl_device_cmd *cmd; | 193 | struct iwl_device_cmd *cmd; |
| 187 | struct iwl_device_cmd *copy_cmd; | ||
| 188 | struct sk_buff *skb; | 194 | struct sk_buff *skb; |
| 189 | /* buffer to free after command completes */ | 195 | /* buffer to free after command completes */ |
| 190 | const void *free_buf; | 196 | const void *free_buf; |
| 191 | struct iwl_cmd_meta meta; | 197 | struct iwl_cmd_meta meta; |
| 192 | }; | 198 | }; |
| 193 | 199 | ||
| 200 | struct iwl_pcie_txq_scratch_buf { | ||
| 201 | struct iwl_cmd_header hdr; | ||
| 202 | u8 buf[8]; | ||
| 203 | __le32 scratch; | ||
| 204 | }; | ||
| 205 | |||
| 194 | /** | 206 | /** |
| 195 | * struct iwl_txq - Tx Queue for DMA | 207 | * struct iwl_txq - Tx Queue for DMA |
| 196 | * @q: generic Rx/Tx queue descriptor | 208 | * @q: generic Rx/Tx queue descriptor |
| 197 | * @tfds: transmit frame descriptors (DMA memory) | 209 | * @tfds: transmit frame descriptors (DMA memory) |
| 210 | * @scratchbufs: start of command headers, including scratch buffers, for | ||
| 211 | * the writeback -- this is DMA memory and an array holding one buffer | ||
| 212 | * for each command on the queue | ||
| 213 | * @scratchbufs_dma: DMA address for the scratchbufs start | ||
| 198 | * @entries: transmit entries (driver state) | 214 | * @entries: transmit entries (driver state) |
| 199 | * @lock: queue lock | 215 | * @lock: queue lock |
| 200 | * @stuck_timer: timer that fires if queue gets stuck | 216 | * @stuck_timer: timer that fires if queue gets stuck |
| @@ -208,6 +224,8 @@ struct iwl_pcie_txq_entry { | |||
| 208 | struct iwl_txq { | 224 | struct iwl_txq { |
| 209 | struct iwl_queue q; | 225 | struct iwl_queue q; |
| 210 | struct iwl_tfd *tfds; | 226 | struct iwl_tfd *tfds; |
| 227 | struct iwl_pcie_txq_scratch_buf *scratchbufs; | ||
| 228 | dma_addr_t scratchbufs_dma; | ||
| 211 | struct iwl_pcie_txq_entry *entries; | 229 | struct iwl_pcie_txq_entry *entries; |
| 212 | spinlock_t lock; | 230 | spinlock_t lock; |
| 213 | struct timer_list stuck_timer; | 231 | struct timer_list stuck_timer; |
| @@ -216,6 +234,13 @@ struct iwl_txq { | |||
| 216 | u8 active; | 234 | u8 active; |
| 217 | }; | 235 | }; |
| 218 | 236 | ||
| 237 | static inline dma_addr_t | ||
| 238 | iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) | ||
| 239 | { | ||
| 240 | return txq->scratchbufs_dma + | ||
| 241 | sizeof(struct iwl_pcie_txq_scratch_buf) * idx; | ||
| 242 | } | ||
| 243 | |||
| 219 | /** | 244 | /** |
| 220 | * struct iwl_trans_pcie - PCIe transport specific data | 245 | * struct iwl_trans_pcie - PCIe transport specific data |
| 221 | * @rxq: all the RX queue data | 246 | * @rxq: all the RX queue data |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index b0ae06d2456f..567e67ad1f61 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
| @@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
| 637 | index = SEQ_TO_INDEX(sequence); | 637 | index = SEQ_TO_INDEX(sequence); |
| 638 | cmd_index = get_cmd_index(&txq->q, index); | 638 | cmd_index = get_cmd_index(&txq->q, index); |
| 639 | 639 | ||
| 640 | if (reclaim) { | 640 | if (reclaim) |
| 641 | struct iwl_pcie_txq_entry *ent; | 641 | cmd = txq->entries[cmd_index].cmd; |
| 642 | ent = &txq->entries[cmd_index]; | 642 | else |
| 643 | cmd = ent->copy_cmd; | ||
| 644 | WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); | ||
| 645 | } else { | ||
| 646 | cmd = NULL; | 643 | cmd = NULL; |
| 647 | } | ||
| 648 | 644 | ||
| 649 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | 645 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); |
| 650 | 646 | ||
| 651 | if (reclaim) { | 647 | if (reclaim) { |
| 652 | /* The original command isn't needed any more */ | ||
| 653 | kfree(txq->entries[cmd_index].copy_cmd); | ||
| 654 | txq->entries[cmd_index].copy_cmd = NULL; | ||
| 655 | /* nor is the duplicated part of the command */ | ||
| 656 | kfree(txq->entries[cmd_index].free_buf); | 648 | kfree(txq->entries[cmd_index].free_buf); |
| 657 | txq->entries[cmd_index].free_buf = NULL; | 649 | txq->entries[cmd_index].free_buf = NULL; |
| 658 | } | 650 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 17bedc50e753..6649e377e9cd 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * USA | 22 | * USA |
| 23 | * | 23 | * |
| 24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. | 25 | * in the file called COPYING. |
| 26 | * | 26 | * |
| 27 | * Contact Information: | 27 | * Contact Information: |
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
| @@ -715,7 +715,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) | |||
| 715 | 715 | ||
| 716 | static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) | 716 | static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) |
| 717 | { | 717 | { |
| 718 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); | 718 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, |
| 719 | ((reg & 0x000FFFFF) | (3 << 24))); | ||
| 719 | return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); | 720 | return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); |
| 720 | } | 721 | } |
| 721 | 722 | ||
| @@ -723,7 +724,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, | |||
| 723 | u32 val) | 724 | u32 val) |
| 724 | { | 725 | { |
| 725 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, | 726 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, |
| 726 | ((addr & 0x0000FFFF) | (3 << 24))); | 727 | ((addr & 0x000FFFFF) | (3 << 24))); |
| 727 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); | 728 | iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); |
| 728 | } | 729 | } |
| 729 | 730 | ||
| @@ -1370,28 +1371,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
| 1370 | return ret; | 1371 | return ret; |
| 1371 | } | 1372 | } |
| 1372 | 1373 | ||
| 1373 | static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | ||
| 1374 | const char __user *user_buf, | ||
| 1375 | size_t count, loff_t *ppos) | ||
| 1376 | { | ||
| 1377 | struct iwl_trans *trans = file->private_data; | ||
| 1378 | |||
| 1379 | if (!trans->op_mode) | ||
| 1380 | return -EAGAIN; | ||
| 1381 | |||
| 1382 | local_bh_disable(); | ||
| 1383 | iwl_op_mode_nic_error(trans->op_mode); | ||
| 1384 | local_bh_enable(); | ||
| 1385 | |||
| 1386 | return count; | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 1374 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
| 1390 | DEBUGFS_READ_FILE_OPS(fh_reg); | 1375 | DEBUGFS_READ_FILE_OPS(fh_reg); |
| 1391 | DEBUGFS_READ_FILE_OPS(rx_queue); | 1376 | DEBUGFS_READ_FILE_OPS(rx_queue); |
| 1392 | DEBUGFS_READ_FILE_OPS(tx_queue); | 1377 | DEBUGFS_READ_FILE_OPS(tx_queue); |
| 1393 | DEBUGFS_WRITE_FILE_OPS(csr); | 1378 | DEBUGFS_WRITE_FILE_OPS(csr); |
| 1394 | DEBUGFS_WRITE_FILE_OPS(fw_restart); | ||
| 1395 | 1379 | ||
| 1396 | /* | 1380 | /* |
| 1397 | * Create the debugfs files and directories | 1381 | * Create the debugfs files and directories |
| @@ -1405,7 +1389,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | |||
| 1405 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); | 1389 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); |
| 1406 | DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); | 1390 | DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); |
| 1407 | DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); | 1391 | DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); |
| 1408 | DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); | ||
| 1409 | return 0; | 1392 | return 0; |
| 1410 | 1393 | ||
| 1411 | err: | 1394 | err: |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index ad7441dfa6fb..84f4634634bc 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
| @@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | for (i = q->read_ptr; i != q->write_ptr; | 193 | for (i = q->read_ptr; i != q->write_ptr; |
| 194 | i = iwl_queue_inc_wrap(i, q->n_bd)) { | 194 | i = iwl_queue_inc_wrap(i, q->n_bd)) |
| 195 | struct iwl_tx_cmd *tx_cmd = | ||
| 196 | (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; | ||
| 197 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, | 195 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, |
| 198 | get_unaligned_le32(&tx_cmd->scratch)); | 196 | le32_to_cpu(txq->scratchbufs[i].scratch)); |
| 199 | } | ||
| 200 | 197 | ||
| 201 | iwl_op_mode_nic_error(trans->op_mode); | 198 | iwl_op_mode_nic_error(trans->op_mode); |
| 202 | } | 199 | } |
| @@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) | |||
| 367 | } | 364 | } |
| 368 | 365 | ||
| 369 | static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, | 366 | static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, |
| 370 | struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, | 367 | struct iwl_cmd_meta *meta, |
| 371 | enum dma_data_direction dma_dir) | 368 | struct iwl_tfd *tfd) |
| 372 | { | 369 | { |
| 373 | int i; | 370 | int i; |
| 374 | int num_tbs; | 371 | int num_tbs; |
| @@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, | |||
| 382 | return; | 379 | return; |
| 383 | } | 380 | } |
| 384 | 381 | ||
| 385 | /* Unmap tx_cmd */ | 382 | /* first TB is never freed - it's the scratchbuf data */ |
| 386 | if (num_tbs) | ||
| 387 | dma_unmap_single(trans->dev, | ||
| 388 | dma_unmap_addr(meta, mapping), | ||
| 389 | dma_unmap_len(meta, len), | ||
| 390 | DMA_BIDIRECTIONAL); | ||
| 391 | 383 | ||
| 392 | /* Unmap chunks, if any. */ | ||
| 393 | for (i = 1; i < num_tbs; i++) | 384 | for (i = 1; i < num_tbs; i++) |
| 394 | dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), | 385 | dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), |
| 395 | iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); | 386 | iwl_pcie_tfd_tb_get_len(tfd, i), |
| 387 | DMA_TO_DEVICE); | ||
| 396 | 388 | ||
| 397 | tfd->num_tbs = 0; | 389 | tfd->num_tbs = 0; |
| 398 | } | 390 | } |
| @@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, | |||
| 406 | * Does NOT advance any TFD circular buffer read/write indexes | 398 | * Does NOT advance any TFD circular buffer read/write indexes |
| 407 | * Does NOT free the TFD itself (which is within circular buffer) | 399 | * Does NOT free the TFD itself (which is within circular buffer) |
| 408 | */ | 400 | */ |
| 409 | static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, | 401 | static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) |
| 410 | enum dma_data_direction dma_dir) | ||
| 411 | { | 402 | { |
| 412 | struct iwl_tfd *tfd_tmp = txq->tfds; | 403 | struct iwl_tfd *tfd_tmp = txq->tfds; |
| 413 | 404 | ||
| @@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, | |||
| 418 | lockdep_assert_held(&txq->lock); | 409 | lockdep_assert_held(&txq->lock); |
| 419 | 410 | ||
| 420 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ | 411 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ |
| 421 | iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], | 412 | iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); |
| 422 | dma_dir); | ||
| 423 | 413 | ||
| 424 | /* free SKB */ | 414 | /* free SKB */ |
| 425 | if (txq->entries) { | 415 | if (txq->entries) { |
| @@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, | |||
| 479 | { | 469 | { |
| 480 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 470 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 481 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | 471 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
| 472 | size_t scratchbuf_sz; | ||
| 482 | int i; | 473 | int i; |
| 483 | 474 | ||
| 484 | if (WARN_ON(txq->entries || txq->tfds)) | 475 | if (WARN_ON(txq->entries || txq->tfds)) |
| @@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, | |||
| 514 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); | 505 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); |
| 515 | goto error; | 506 | goto error; |
| 516 | } | 507 | } |
| 508 | |||
| 509 | BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); | ||
| 510 | BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != | ||
| 511 | sizeof(struct iwl_cmd_header) + | ||
| 512 | offsetof(struct iwl_tx_cmd, scratch)); | ||
| 513 | |||
| 514 | scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num; | ||
| 515 | |||
| 516 | txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz, | ||
| 517 | &txq->scratchbufs_dma, | ||
| 518 | GFP_KERNEL); | ||
| 519 | if (!txq->scratchbufs) | ||
| 520 | goto err_free_tfds; | ||
| 521 | |||
| 517 | txq->q.id = txq_id; | 522 | txq->q.id = txq_id; |
| 518 | 523 | ||
| 519 | return 0; | 524 | return 0; |
| 525 | err_free_tfds: | ||
| 526 | dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr); | ||
| 520 | error: | 527 | error: |
| 521 | if (txq->entries && txq_id == trans_pcie->cmd_queue) | 528 | if (txq->entries && txq_id == trans_pcie->cmd_queue) |
| 522 | for (i = 0; i < slots_num; i++) | 529 | for (i = 0; i < slots_num; i++) |
| @@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) | |||
| 565 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 572 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 566 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | 573 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; |
| 567 | struct iwl_queue *q = &txq->q; | 574 | struct iwl_queue *q = &txq->q; |
| 568 | enum dma_data_direction dma_dir; | ||
| 569 | 575 | ||
| 570 | if (!q->n_bd) | 576 | if (!q->n_bd) |
| 571 | return; | 577 | return; |
| 572 | 578 | ||
| 573 | /* In the command queue, all the TBs are mapped as BIDI | ||
| 574 | * so unmap them as such. | ||
| 575 | */ | ||
| 576 | if (txq_id == trans_pcie->cmd_queue) | ||
| 577 | dma_dir = DMA_BIDIRECTIONAL; | ||
| 578 | else | ||
| 579 | dma_dir = DMA_TO_DEVICE; | ||
| 580 | |||
| 581 | spin_lock_bh(&txq->lock); | 579 | spin_lock_bh(&txq->lock); |
| 582 | while (q->write_ptr != q->read_ptr) { | 580 | while (q->write_ptr != q->read_ptr) { |
| 583 | iwl_pcie_txq_free_tfd(trans, txq, dma_dir); | 581 | iwl_pcie_txq_free_tfd(trans, txq); |
| 584 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 582 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
| 585 | } | 583 | } |
| 586 | spin_unlock_bh(&txq->lock); | 584 | spin_unlock_bh(&txq->lock); |
| @@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
| 610 | if (txq_id == trans_pcie->cmd_queue) | 608 | if (txq_id == trans_pcie->cmd_queue) |
| 611 | for (i = 0; i < txq->q.n_window; i++) { | 609 | for (i = 0; i < txq->q.n_window; i++) { |
| 612 | kfree(txq->entries[i].cmd); | 610 | kfree(txq->entries[i].cmd); |
| 613 | kfree(txq->entries[i].copy_cmd); | ||
| 614 | kfree(txq->entries[i].free_buf); | 611 | kfree(txq->entries[i].free_buf); |
| 615 | } | 612 | } |
| 616 | 613 | ||
| @@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
| 619 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * | 616 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * |
| 620 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 617 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); |
| 621 | txq->q.dma_addr = 0; | 618 | txq->q.dma_addr = 0; |
| 619 | |||
| 620 | dma_free_coherent(dev, | ||
| 621 | sizeof(*txq->scratchbufs) * txq->q.n_window, | ||
| 622 | txq->scratchbufs, txq->scratchbufs_dma); | ||
| 622 | } | 623 | } |
| 623 | 624 | ||
| 624 | kfree(txq->entries); | 625 | kfree(txq->entries); |
| @@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | |||
| 962 | 963 | ||
| 963 | iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); | 964 | iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); |
| 964 | 965 | ||
| 965 | iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); | 966 | iwl_pcie_txq_free_tfd(trans, txq); |
| 966 | } | 967 | } |
| 967 | 968 | ||
| 968 | iwl_pcie_txq_progress(trans_pcie, txq); | 969 | iwl_pcie_txq_progress(trans_pcie, txq); |
| @@ -1152,20 +1153,37 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1152 | void *dup_buf = NULL; | 1153 | void *dup_buf = NULL; |
| 1153 | dma_addr_t phys_addr; | 1154 | dma_addr_t phys_addr; |
| 1154 | int idx; | 1155 | int idx; |
| 1155 | u16 copy_size, cmd_size; | 1156 | u16 copy_size, cmd_size, scratch_size; |
| 1156 | bool had_nocopy = false; | 1157 | bool had_nocopy = false; |
| 1157 | int i; | 1158 | int i; |
| 1158 | u32 cmd_pos; | 1159 | u32 cmd_pos; |
| 1160 | const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; | ||
| 1161 | u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; | ||
| 1159 | 1162 | ||
| 1160 | copy_size = sizeof(out_cmd->hdr); | 1163 | copy_size = sizeof(out_cmd->hdr); |
| 1161 | cmd_size = sizeof(out_cmd->hdr); | 1164 | cmd_size = sizeof(out_cmd->hdr); |
| 1162 | 1165 | ||
| 1163 | /* need one for the header if the first is NOCOPY */ | 1166 | /* need one for the header if the first is NOCOPY */ |
| 1164 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); | 1167 | BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1); |
| 1168 | |||
| 1169 | for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { | ||
| 1170 | cmddata[i] = cmd->data[i]; | ||
| 1171 | cmdlen[i] = cmd->len[i]; | ||
| 1165 | 1172 | ||
| 1166 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | ||
| 1167 | if (!cmd->len[i]) | 1173 | if (!cmd->len[i]) |
| 1168 | continue; | 1174 | continue; |
| 1175 | |||
| 1176 | /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ | ||
| 1177 | if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { | ||
| 1178 | int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; | ||
| 1179 | |||
| 1180 | if (copy > cmdlen[i]) | ||
| 1181 | copy = cmdlen[i]; | ||
| 1182 | cmdlen[i] -= copy; | ||
| 1183 | cmddata[i] += copy; | ||
| 1184 | copy_size += copy; | ||
| 1185 | } | ||
| 1186 | |||
| 1169 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { | 1187 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { |
| 1170 | had_nocopy = true; | 1188 | had_nocopy = true; |
| 1171 | if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { | 1189 | if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { |
| @@ -1185,7 +1203,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1185 | goto free_dup_buf; | 1203 | goto free_dup_buf; |
| 1186 | } | 1204 | } |
| 1187 | 1205 | ||
| 1188 | dup_buf = kmemdup(cmd->data[i], cmd->len[i], | 1206 | dup_buf = kmemdup(cmddata[i], cmdlen[i], |
| 1189 | GFP_ATOMIC); | 1207 | GFP_ATOMIC); |
| 1190 | if (!dup_buf) | 1208 | if (!dup_buf) |
| 1191 | return -ENOMEM; | 1209 | return -ENOMEM; |
| @@ -1195,7 +1213,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1195 | idx = -EINVAL; | 1213 | idx = -EINVAL; |
| 1196 | goto free_dup_buf; | 1214 | goto free_dup_buf; |
| 1197 | } | 1215 | } |
| 1198 | copy_size += cmd->len[i]; | 1216 | copy_size += cmdlen[i]; |
| 1199 | } | 1217 | } |
| 1200 | cmd_size += cmd->len[i]; | 1218 | cmd_size += cmd->len[i]; |
| 1201 | } | 1219 | } |
| @@ -1242,30 +1260,30 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1242 | 1260 | ||
| 1243 | /* and copy the data that needs to be copied */ | 1261 | /* and copy the data that needs to be copied */ |
| 1244 | cmd_pos = offsetof(struct iwl_device_cmd, payload); | 1262 | cmd_pos = offsetof(struct iwl_device_cmd, payload); |
| 1245 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 1263 | copy_size = sizeof(out_cmd->hdr); |
| 1246 | if (!cmd->len[i]) | 1264 | for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { |
| 1265 | int copy = 0; | ||
| 1266 | |||
| 1267 | if (!cmd->len) | ||
| 1247 | continue; | 1268 | continue; |
| 1248 | if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | | ||
| 1249 | IWL_HCMD_DFL_DUP)) | ||
| 1250 | break; | ||
| 1251 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); | ||
| 1252 | cmd_pos += cmd->len[i]; | ||
| 1253 | } | ||
| 1254 | 1269 | ||
| 1255 | WARN_ON_ONCE(txq->entries[idx].copy_cmd); | 1270 | /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ |
| 1271 | if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { | ||
| 1272 | copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; | ||
| 1256 | 1273 | ||
| 1257 | /* | 1274 | if (copy > cmd->len[i]) |
| 1258 | * since out_cmd will be the source address of the FH, it will write | 1275 | copy = cmd->len[i]; |
| 1259 | * the retry count there. So when the user needs to receivce the HCMD | 1276 | } |
| 1260 | * that corresponds to the response in the response handler, it needs | 1277 | |
| 1261 | * to set CMD_WANT_HCMD. | 1278 | /* copy everything if not nocopy/dup */ |
| 1262 | */ | 1279 | if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | |
| 1263 | if (cmd->flags & CMD_WANT_HCMD) { | 1280 | IWL_HCMD_DFL_DUP))) |
| 1264 | txq->entries[idx].copy_cmd = | 1281 | copy = cmd->len[i]; |
| 1265 | kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); | 1282 | |
| 1266 | if (unlikely(!txq->entries[idx].copy_cmd)) { | 1283 | if (copy) { |
| 1267 | idx = -ENOMEM; | 1284 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); |
| 1268 | goto out; | 1285 | cmd_pos += copy; |
| 1286 | copy_size += copy; | ||
| 1269 | } | 1287 | } |
| 1270 | } | 1288 | } |
| 1271 | 1289 | ||
| @@ -1275,22 +1293,35 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1275 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), | 1293 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), |
| 1276 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); | 1294 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); |
| 1277 | 1295 | ||
| 1278 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 1296 | /* start the TFD with the scratchbuf */ |
| 1279 | DMA_BIDIRECTIONAL); | 1297 | scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE); |
| 1280 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | 1298 | memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); |
| 1281 | idx = -ENOMEM; | 1299 | iwl_pcie_txq_build_tfd(trans, txq, |
| 1282 | goto out; | 1300 | iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), |
| 1283 | } | 1301 | scratch_size, 1); |
| 1284 | 1302 | ||
| 1285 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 1303 | /* map first command fragment, if any remains */ |
| 1286 | dma_unmap_len_set(out_meta, len, copy_size); | 1304 | if (copy_size > scratch_size) { |
| 1305 | phys_addr = dma_map_single(trans->dev, | ||
| 1306 | ((u8 *)&out_cmd->hdr) + scratch_size, | ||
| 1307 | copy_size - scratch_size, | ||
| 1308 | DMA_TO_DEVICE); | ||
| 1309 | if (dma_mapping_error(trans->dev, phys_addr)) { | ||
| 1310 | iwl_pcie_tfd_unmap(trans, out_meta, | ||
| 1311 | &txq->tfds[q->write_ptr]); | ||
| 1312 | idx = -ENOMEM; | ||
| 1313 | goto out; | ||
| 1314 | } | ||
| 1287 | 1315 | ||
| 1288 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); | 1316 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, |
| 1317 | copy_size - scratch_size, 0); | ||
| 1318 | } | ||
| 1289 | 1319 | ||
| 1290 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 1320 | /* map the remaining (adjusted) nocopy/dup fragments */ |
| 1291 | const void *data = cmd->data[i]; | 1321 | for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { |
| 1322 | const void *data = cmddata[i]; | ||
| 1292 | 1323 | ||
| 1293 | if (!cmd->len[i]) | 1324 | if (!cmdlen[i]) |
| 1294 | continue; | 1325 | continue; |
| 1295 | if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | | 1326 | if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | |
| 1296 | IWL_HCMD_DFL_DUP))) | 1327 | IWL_HCMD_DFL_DUP))) |
| @@ -1298,16 +1329,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1298 | if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) | 1329 | if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) |
| 1299 | data = dup_buf; | 1330 | data = dup_buf; |
| 1300 | phys_addr = dma_map_single(trans->dev, (void *)data, | 1331 | phys_addr = dma_map_single(trans->dev, (void *)data, |
| 1301 | cmd->len[i], DMA_BIDIRECTIONAL); | 1332 | cmdlen[i], DMA_TO_DEVICE); |
| 1302 | if (dma_mapping_error(trans->dev, phys_addr)) { | 1333 | if (dma_mapping_error(trans->dev, phys_addr)) { |
| 1303 | iwl_pcie_tfd_unmap(trans, out_meta, | 1334 | iwl_pcie_tfd_unmap(trans, out_meta, |
| 1304 | &txq->tfds[q->write_ptr], | 1335 | &txq->tfds[q->write_ptr]); |
| 1305 | DMA_BIDIRECTIONAL); | ||
| 1306 | idx = -ENOMEM; | 1336 | idx = -ENOMEM; |
| 1307 | goto out; | 1337 | goto out; |
| 1308 | } | 1338 | } |
| 1309 | 1339 | ||
| 1310 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); | 1340 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); |
| 1311 | } | 1341 | } |
| 1312 | 1342 | ||
| 1313 | out_meta->flags = cmd->flags; | 1343 | out_meta->flags = cmd->flags; |
| @@ -1317,8 +1347,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
| 1317 | 1347 | ||
| 1318 | txq->need_update = 1; | 1348 | txq->need_update = 1; |
| 1319 | 1349 | ||
| 1320 | trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, | 1350 | trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); |
| 1321 | &out_cmd->hdr, copy_size); | ||
| 1322 | 1351 | ||
| 1323 | /* start timer if queue currently empty */ | 1352 | /* start timer if queue currently empty */ |
| 1324 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) | 1353 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) |
| @@ -1377,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
| 1377 | cmd = txq->entries[cmd_index].cmd; | 1406 | cmd = txq->entries[cmd_index].cmd; |
| 1378 | meta = &txq->entries[cmd_index].meta; | 1407 | meta = &txq->entries[cmd_index].meta; |
| 1379 | 1408 | ||
| 1380 | iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); | 1409 | iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]); |
| 1381 | 1410 | ||
| 1382 | /* Input error checking is done when commands are added to queue. */ | 1411 | /* Input error checking is done when commands are added to queue. */ |
| 1383 | if (meta->flags & CMD_WANT_SKB) { | 1412 | if (meta->flags & CMD_WANT_SKB) { |
| @@ -1556,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1556 | struct iwl_cmd_meta *out_meta; | 1585 | struct iwl_cmd_meta *out_meta; |
| 1557 | struct iwl_txq *txq; | 1586 | struct iwl_txq *txq; |
| 1558 | struct iwl_queue *q; | 1587 | struct iwl_queue *q; |
| 1559 | dma_addr_t phys_addr = 0; | 1588 | dma_addr_t tb0_phys, tb1_phys, scratch_phys; |
| 1560 | dma_addr_t txcmd_phys; | 1589 | void *tb1_addr; |
| 1561 | dma_addr_t scratch_phys; | 1590 | u16 len, tb1_len, tb2_len; |
| 1562 | u16 len, firstlen, secondlen; | ||
| 1563 | u8 wait_write_ptr = 0; | 1591 | u8 wait_write_ptr = 0; |
| 1564 | __le16 fc = hdr->frame_control; | 1592 | __le16 fc = hdr->frame_control; |
| 1565 | u8 hdr_len = ieee80211_hdrlen(fc); | 1593 | u8 hdr_len = ieee80211_hdrlen(fc); |
| @@ -1597,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1597 | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | 1625 | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | |
| 1598 | INDEX_TO_SEQ(q->write_ptr))); | 1626 | INDEX_TO_SEQ(q->write_ptr))); |
| 1599 | 1627 | ||
| 1628 | tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr); | ||
| 1629 | scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + | ||
| 1630 | offsetof(struct iwl_tx_cmd, scratch); | ||
| 1631 | |||
| 1632 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | ||
| 1633 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | ||
| 1634 | |||
| 1600 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | 1635 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ |
| 1601 | out_meta = &txq->entries[q->write_ptr].meta; | 1636 | out_meta = &txq->entries[q->write_ptr].meta; |
| 1602 | 1637 | ||
| 1603 | /* | 1638 | /* |
| 1604 | * Use the first empty entry in this queue's command buffer array | 1639 | * The second TB (tb1) points to the remainder of the TX command |
| 1605 | * to contain the Tx command and MAC header concatenated together | 1640 | * and the 802.11 header - dword aligned size |
| 1606 | * (payload data will be in another buffer). | 1641 | * (This calculation modifies the TX command, so do it before the |
| 1607 | * Size of this varies, due to varying MAC header length. | 1642 | * setup of the first TB) |
| 1608 | * If end is not dword aligned, we'll have 2 extra bytes at the end | ||
| 1609 | * of the MAC header (device reads on dword boundaries). | ||
| 1610 | * We'll tell device about this padding later. | ||
| 1611 | */ | 1643 | */ |
| 1612 | len = sizeof(struct iwl_tx_cmd) + | 1644 | len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + |
| 1613 | sizeof(struct iwl_cmd_header) + hdr_len; | 1645 | hdr_len - IWL_HCMD_SCRATCHBUF_SIZE; |
| 1614 | firstlen = (len + 3) & ~3; | 1646 | tb1_len = (len + 3) & ~3; |
| 1615 | 1647 | ||
| 1616 | /* Tell NIC about any 2-byte padding after MAC header */ | 1648 | /* Tell NIC about any 2-byte padding after MAC header */ |
| 1617 | if (firstlen != len) | 1649 | if (tb1_len != len) |
| 1618 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | 1650 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; |
| 1619 | 1651 | ||
| 1620 | /* Physical address of this Tx command's header (not MAC header!), | 1652 | /* The first TB points to the scratchbuf data - min_copy bytes */ |
| 1621 | * within command buffer array. */ | 1653 | memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, |
| 1622 | txcmd_phys = dma_map_single(trans->dev, | 1654 | IWL_HCMD_SCRATCHBUF_SIZE); |
| 1623 | &dev_cmd->hdr, firstlen, | 1655 | iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, |
| 1624 | DMA_BIDIRECTIONAL); | 1656 | IWL_HCMD_SCRATCHBUF_SIZE, 1); |
| 1625 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | ||
| 1626 | goto out_err; | ||
| 1627 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
| 1628 | dma_unmap_len_set(out_meta, len, firstlen); | ||
| 1629 | 1657 | ||
| 1630 | if (!ieee80211_has_morefrags(fc)) { | 1658 | /* there must be data left over for TB1 or this code must be changed */ |
| 1631 | txq->need_update = 1; | 1659 | BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); |
| 1632 | } else { | 1660 | |
| 1633 | wait_write_ptr = 1; | 1661 | /* map the data for TB1 */ |
| 1634 | txq->need_update = 0; | 1662 | tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE; |
| 1635 | } | 1663 | tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); |
| 1664 | if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) | ||
| 1665 | goto out_err; | ||
| 1666 | iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); | ||
| 1636 | 1667 | ||
| 1637 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 1668 | /* |
| 1638 | * if any (802.11 null frames have no payload). */ | 1669 | * Set up TFD's third entry to point directly to remainder |
| 1639 | secondlen = skb->len - hdr_len; | 1670 | * of skb, if any (802.11 null frames have no payload). |
| 1640 | if (secondlen > 0) { | 1671 | */ |
| 1641 | phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, | 1672 | tb2_len = skb->len - hdr_len; |
| 1642 | secondlen, DMA_TO_DEVICE); | 1673 | if (tb2_len > 0) { |
| 1643 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | 1674 | dma_addr_t tb2_phys = dma_map_single(trans->dev, |
| 1644 | dma_unmap_single(trans->dev, | 1675 | skb->data + hdr_len, |
| 1645 | dma_unmap_addr(out_meta, mapping), | 1676 | tb2_len, DMA_TO_DEVICE); |
| 1646 | dma_unmap_len(out_meta, len), | 1677 | if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { |
| 1647 | DMA_BIDIRECTIONAL); | 1678 | iwl_pcie_tfd_unmap(trans, out_meta, |
| 1679 | &txq->tfds[q->write_ptr]); | ||
| 1648 | goto out_err; | 1680 | goto out_err; |
| 1649 | } | 1681 | } |
| 1682 | iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); | ||
| 1650 | } | 1683 | } |
| 1651 | 1684 | ||
| 1652 | /* Attach buffers to TFD */ | ||
| 1653 | iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); | ||
| 1654 | if (secondlen > 0) | ||
| 1655 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); | ||
| 1656 | |||
| 1657 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | ||
| 1658 | offsetof(struct iwl_tx_cmd, scratch); | ||
| 1659 | |||
| 1660 | /* take back ownership of DMA buffer to enable update */ | ||
| 1661 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, | ||
| 1662 | DMA_BIDIRECTIONAL); | ||
| 1663 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | ||
| 1664 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | ||
| 1665 | |||
| 1666 | /* Set up entry for this TFD in Tx byte-count array */ | 1685 | /* Set up entry for this TFD in Tx byte-count array */ |
| 1667 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1686 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
| 1668 | 1687 | ||
| 1669 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | ||
| 1670 | DMA_BIDIRECTIONAL); | ||
| 1671 | |||
| 1672 | trace_iwlwifi_dev_tx(trans->dev, skb, | 1688 | trace_iwlwifi_dev_tx(trans->dev, skb, |
| 1673 | &txq->tfds[txq->q.write_ptr], | 1689 | &txq->tfds[txq->q.write_ptr], |
| 1674 | sizeof(struct iwl_tfd), | 1690 | sizeof(struct iwl_tfd), |
| 1675 | &dev_cmd->hdr, firstlen, | 1691 | &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len, |
| 1676 | skb->data + hdr_len, secondlen); | 1692 | skb->data + hdr_len, tb2_len); |
| 1677 | trace_iwlwifi_dev_tx_data(trans->dev, skb, | 1693 | trace_iwlwifi_dev_tx_data(trans->dev, skb, |
| 1678 | skb->data + hdr_len, secondlen); | 1694 | skb->data + hdr_len, tb2_len); |
| 1695 | |||
| 1696 | if (!ieee80211_has_morefrags(fc)) { | ||
| 1697 | txq->need_update = 1; | ||
| 1698 | } else { | ||
| 1699 | wait_write_ptr = 1; | ||
| 1700 | txq->need_update = 0; | ||
| 1701 | } | ||
| 1679 | 1702 | ||
| 1680 | /* start timer if queue currently empty */ | 1703 | /* start timer if queue currently empty */ |
| 1681 | if (txq->need_update && q->read_ptr == q->write_ptr && | 1704 | if (txq->need_update && q->read_ptr == q->write_ptr && |
