Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

+2005 -701
+10 -1
drivers/net/wireless/iwlwifi/Kconfig
··· 6 6 select LEDS_CLASS 7 7 select LEDS_TRIGGERS 8 8 select MAC80211_LEDS 9 - select IWLDVM 10 9 ---help--- 11 10 Select to build the driver supporting the: 12 11 ··· 44 45 config IWLDVM 45 46 tristate "Intel Wireless WiFi DVM Firmware support" 46 47 depends on IWLWIFI 48 + default IWLWIFI 47 49 help 48 50 This is the driver supporting the DVM firmware which is 49 51 currently the only firmware available for existing devices. ··· 57 57 currently only available for 7000 series devices. 58 58 59 59 Say yes if you have such a device. 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 60 69 61 70 menu "Debugging Options" 62 71 depends on IWLWIFI
+1 -2
drivers/net/wireless/iwlwifi/Makefile
··· 7 7 iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o 8 8 iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o 9 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 11 - iwlwifi-objs += pcie/7000.o 10 + iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o 12 11 13 12 iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 14 13 iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
+1 -1
drivers/net/wireless/iwlwifi/dvm/agn.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/calib.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/calib.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+2 -1
drivers/net/wireless/iwlwifi/dvm/commands.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 1526 1526 __le16 scd_ssn; 1527 1527 u8 txed; /* number of frames sent */ 1528 1528 u8 txed_2_done; /* number of frames acked */ 1529 + __le16 reserved1; 1529 1530 } __packed; 1530 1531 1531 1532 /*
+25 -1
drivers/net/wireless/iwlwifi/dvm/debugfs.c
··· 19 19 * USA 20 20 * 21 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 24 * Contact Information: 25 25 * Intel Linux Wireless <ilw@linux.intel.com> ··· 2324 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 2349 DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 2328 2350 DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 2329 2351 DEBUGFS_READ_FILE_OPS(ucode_general_stats); ··· 2365 2343 DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2366 2344 DEBUGFS_READ_FILE_OPS(reply_tx_error); 2367 2345 DEBUGFS_WRITE_FILE_OPS(echo_test); 2346 + DEBUGFS_WRITE_FILE_OPS(fw_restart); 2368 2347 #ifdef CONFIG_IWLWIFI_DEBUG 2369 2348 DEBUGFS_READ_WRITE_FILE_OPS(log_event); 2370 2349 #endif ··· 2423 2400 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2424 2401 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2425 2402 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); 2403 + DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR); 2426 2404 #ifdef CONFIG_IWLWIFI_DEBUG 2427 2405 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); 2428 2406 #endif
+1 -1
drivers/net/wireless/iwlwifi/dvm/lib.c
··· 19 19 * USA 20 20 * 21 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 24 * Contact Information: 25 25 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/scan.c
··· 19 19 * USA 20 20 * 21 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 24 * Contact Information: 25 25 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/sta.c
··· 151 151 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); 152 152 153 153 if (!(flags & CMD_ASYNC)) { 154 - cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; 154 + cmd.flags |= CMD_WANT_SKB; 155 155 might_sleep(); 156 156 } 157 157
+1 -1
drivers/net/wireless/iwlwifi/dvm/testmode.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/tx.c
··· 19 19 * USA 20 20 * 21 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 24 * Contact Information: 25 25 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/dvm/ucode.c
··· 19 19 * USA 20 20 * 21 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 24 * Contact Information: 25 25 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-agn-hw.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+48 -1
drivers/net/wireless/iwlwifi/iwl-config.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 274 274 const bool internal_wimax_coex; 275 275 const bool temp_offset_v2; 276 276 }; 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; 277 324 278 325 #endif /* __IWL_CONFIG_H__ */
+1 -1
drivers/net/wireless/iwlwifi/iwl-csr.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+7 -6
drivers/net/wireless/iwlwifi/iwl-debug.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 66 66 #include <linux/device.h> 67 67 #include <linux/interrupt.h> 68 68 #include <linux/export.h> 69 + #include "iwl-drv.h" 69 70 #include "iwl-debug.h" 70 71 #include "iwl-devtrace.h" 71 72 ··· 86 85 } 87 86 88 87 __iwl_fn(warn) 89 - EXPORT_SYMBOL_GPL(__iwl_warn); 88 + IWL_EXPORT_SYMBOL(__iwl_warn); 90 89 __iwl_fn(info) 91 - EXPORT_SYMBOL_GPL(__iwl_info); 90 + IWL_EXPORT_SYMBOL(__iwl_info); 92 91 __iwl_fn(crit) 93 - EXPORT_SYMBOL_GPL(__iwl_crit); 92 + IWL_EXPORT_SYMBOL(__iwl_crit); 94 93 95 94 void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, 96 95 const char *fmt, ...) ··· 111 110 trace_iwlwifi_err(&vaf); 112 111 va_end(args); 113 112 } 114 - EXPORT_SYMBOL_GPL(__iwl_err); 113 + IWL_EXPORT_SYMBOL(__iwl_err); 115 114 116 115 #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) 117 116 void __iwl_dbg(struct device *dev, ··· 134 133 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); 135 134 va_end(args); 136 135 } 137 - EXPORT_SYMBOL_GPL(__iwl_dbg); 136 + IWL_EXPORT_SYMBOL(__iwl_dbg); 138 137 #endif
+6 -8
drivers/net/wireless/iwlwifi/iwl-devtrace.h
··· 298 298 MAX_MSG_LEN, vaf->fmt, 299 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 304 #undef TRACE_SYSTEM ··· 349 349 TRACE_EVENT(iwlwifi_dev_hcmd, 350 350 TP_PROTO(const struct device *dev, 351 351 struct iwl_host_cmd *cmd, u16 total_size, 352 - const void *hdr, size_t hdr_len), 353 - TP_ARGS(dev, cmd, total_size, hdr, hdr_len), 352 + struct iwl_cmd_header *hdr), 353 + TP_ARGS(dev, cmd, total_size, hdr), 354 354 TP_STRUCT__entry( 355 355 DEV_ENTRY 356 356 __dynamic_array(u8, hcmd, total_size) 357 357 __field(u32, flags) 358 358 ), 359 359 TP_fast_assign( 360 - int i, offset = hdr_len; 360 + int i, offset = sizeof(*hdr); 361 361 362 362 DEV_ASSIGN; 363 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 367 if (!cmd->len[i]) 368 - continue; 369 - if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) 370 368 continue; 371 369 memcpy((u8 *)__get_dynamic_array(hcmd) + offset, 372 370 cmd->data[i], cmd->len[i]);
+8 -9
drivers/net/wireless/iwlwifi/iwl-drv.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 1102 1102 1103 1103 /* shared module parameters */ 1104 1104 struct iwl_mod_params iwlwifi_mod_params = { 1105 - .amsdu_size_8K = 1, 1106 - .restart_fw = 1, 1105 + .restart_fw = true, 1107 1106 .plcp_check = true, 1108 1107 .bt_coex_active = true, 1109 1108 .power_level = IWL_POWER_INDEX_1, ··· 1111 1112 .wd_disable = true, 1112 1113 /* the rest are 0 by default */ 1113 1114 }; 1114 - EXPORT_SYMBOL_GPL(iwlwifi_mod_params); 1115 + IWL_EXPORT_SYMBOL(iwlwifi_mod_params); 1115 1116 1116 1117 int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) 1117 1118 { ··· 1135 1136 mutex_unlock(&iwlwifi_opmode_table_mtx); 1136 1137 return -EIO; 1137 1138 } 1138 - EXPORT_SYMBOL_GPL(iwl_opmode_register); 1139 + IWL_EXPORT_SYMBOL(iwl_opmode_register); 1139 1140 1140 1141 void iwl_opmode_deregister(const char *name) 1141 1142 { ··· 1157 1158 } 1158 1159 mutex_unlock(&iwlwifi_opmode_table_mtx); 1159 1160 } 1160 - EXPORT_SYMBOL_GPL(iwl_opmode_deregister); 1161 + IWL_EXPORT_SYMBOL(iwl_opmode_deregister); 1161 1162 1162 1163 static int __init iwl_drv_init(void) 1163 1164 { ··· 1206 1207 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); 1207 1208 module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, 1208 1209 int, S_IRUGO); 1209 - MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); 1210 - module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); 1211 - MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 1210 + MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); 1211 + 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 (default true)"); 1212 1213 1213 1214 module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, 1214 1215 int, S_IRUGO);
+16 -1
drivers/net/wireless/iwlwifi/iwl-drv.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 62 62 63 63 #ifndef __iwl_drv_h__ 64 64 #define __iwl_drv_h__ 65 + 66 + #include <linux/module.h> 65 67 66 68 /* for all modules */ 67 69 #define DRV_NAME "iwlwifi" ··· 124 122 * call this function and then do the bus related operations only. 125 123 */ 126 124 void iwl_drv_stop(struct iwl_drv *drv); 125 + 126 + /* 127 + * exported symbol management 128 + * 129 + * The driver can be split into multiple modules, in which case some symbols 130 + * must be exported for the sub-modules. However, if it's not split and 131 + * everything is built-in, then we can avoid that. 132 + */ 133 + #ifdef CONFIG_IWLWIFI_OPMODE_MODULAR 134 + #define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym) 135 + #else 136 + #define IWL_EXPORT_SYMBOL(sym) 137 + #endif 127 138 128 139 #endif /* __iwl_drv_h__ */
+5 -4
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 62 62 #include <linux/types.h> 63 63 #include <linux/slab.h> 64 64 #include <linux/export.h> 65 + #include "iwl-drv.h" 65 66 #include "iwl-modparams.h" 66 67 #include "iwl-eeprom-parse.h" 67 68 ··· 750 749 } 751 750 752 751 ht_info->ht_supported = true; 753 - ht_info->cap = 0; 752 + ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; 754 753 755 754 if (iwlwifi_mod_params.amsdu_size_8K) 756 755 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; ··· 910 909 kfree(data); 911 910 return NULL; 912 911 } 913 - EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); 912 + IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data); 914 913 915 914 /* helper functions */ 916 915 int iwl_nvm_check_version(struct iwl_nvm_data *data, ··· 929 928 data->calib_version, trans->cfg->nvm_calib_ver); 930 929 return -EINVAL; 931 930 } 932 - EXPORT_SYMBOL_GPL(iwl_nvm_check_version); 931 + IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
+1 -1
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+3 -2
drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 63 63 #include <linux/slab.h> 64 64 #include <linux/export.h> 65 65 66 + #include "iwl-drv.h" 66 67 #include "iwl-debug.h" 67 68 #include "iwl-eeprom-read.h" 68 69 #include "iwl-io.h" ··· 461 460 462 461 return ret; 463 462 } 464 - EXPORT_SYMBOL_GPL(iwl_read_eeprom); 463 + IWL_EXPORT_SYMBOL(iwl_read_eeprom);
+1 -1
drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-fh.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-fw-file.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+3 -1
drivers/net/wireless/iwlwifi/iwl-fw.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 73 73 * treats good CRC threshold as a boolean 74 74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 75 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 78 enum iwl_ucode_tlv_flag { 78 79 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 79 80 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), 80 81 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 81 82 IWL_UCODE_TLV_FLAGS_P2P = BIT(3), 83 + IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), 82 84 }; 83 85 84 86 /* The default calibrate table size if not specified by firmware file */
+10 -9
drivers/net/wireless/iwlwifi/iwl-io.c
··· 29 29 #include <linux/device.h> 30 30 #include <linux/export.h> 31 31 32 + #include "iwl-drv.h" 32 33 #include "iwl-io.h" 33 34 #include "iwl-csr.h" 34 35 #include "iwl-debug.h" ··· 50 49 51 50 return -ETIMEDOUT; 52 51 } 53 - EXPORT_SYMBOL_GPL(iwl_poll_bit); 52 + IWL_EXPORT_SYMBOL(iwl_poll_bit); 54 53 55 54 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) 56 55 { ··· 63 62 64 63 return value; 65 64 } 66 - EXPORT_SYMBOL_GPL(iwl_read_direct32); 65 + IWL_EXPORT_SYMBOL(iwl_read_direct32); 67 66 68 67 void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) 69 68 { ··· 74 73 iwl_trans_release_nic_access(trans, &flags); 75 74 } 76 75 } 77 - EXPORT_SYMBOL_GPL(iwl_write_direct32); 76 + IWL_EXPORT_SYMBOL(iwl_write_direct32); 78 77 79 78 int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, 80 79 int timeout) ··· 90 89 91 90 return -ETIMEDOUT; 92 91 } 93 - EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); 92 + IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); 94 93 95 94 static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) 96 95 { ··· 116 115 } 117 116 return val; 118 117 } 119 - EXPORT_SYMBOL_GPL(iwl_read_prph); 118 + IWL_EXPORT_SYMBOL(iwl_read_prph); 120 119 121 120 void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) 122 121 { ··· 127 126 iwl_trans_release_nic_access(trans, &flags); 128 127 } 129 128 } 130 - EXPORT_SYMBOL_GPL(iwl_write_prph); 129 + IWL_EXPORT_SYMBOL(iwl_write_prph); 131 130 132 131 void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 133 132 { ··· 139 138 iwl_trans_release_nic_access(trans, &flags); 140 139 } 141 140 } 142 - EXPORT_SYMBOL_GPL(iwl_set_bits_prph); 141 + IWL_EXPORT_SYMBOL(iwl_set_bits_prph); 143 142 144 143 void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, 145 144 u32 bits, u32 mask) ··· 152 151 iwl_trans_release_nic_access(trans, &flags); 153 152 } 154 153 } 155 - EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); 154 + IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); 156 155 157 156 void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 158 157 { ··· 165 164 iwl_trans_release_nic_access(trans, &flags); 166 165 } 167 166 } 168 - EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); 167 + IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
+3 -3
drivers/net/wireless/iwlwifi/iwl-modparams.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 91 91 * @sw_crypto: using hardware encryption, default = 0 92 92 * @disable_11n: disable 11n capabilities, default = 0, 93 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 95 * @restart_fw: restart firmware, default = 1 96 96 * @plcp_check: enable plcp health check, default = true 97 97 * @wd_disable: enable stuck queue check, default = 0 ··· 109 109 int sw_crypto; 110 110 unsigned int disable_11n; 111 111 int amsdu_size_8K; 112 - int restart_fw; 112 + bool restart_fw; 113 113 bool plcp_check; 114 114 int wd_disable; 115 115 bool bt_coex_active;
+8 -7
drivers/net/wireless/iwlwifi/iwl-notif-wait.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 63 63 #include <linux/sched.h> 64 64 #include <linux/export.h> 65 65 66 + #include "iwl-drv.h" 66 67 #include "iwl-notif-wait.h" 67 68 68 69 ··· 73 72 INIT_LIST_HEAD(&notif_wait->notif_waits); 74 73 init_waitqueue_head(&notif_wait->notif_waitq); 75 74 } 76 - EXPORT_SYMBOL_GPL(iwl_notification_wait_init); 75 + IWL_EXPORT_SYMBOL(iwl_notification_wait_init); 77 76 78 77 void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, 79 78 struct iwl_rx_packet *pkt) ··· 118 117 if (triggered) 119 118 wake_up_all(&notif_wait->notif_waitq); 120 119 } 121 - EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); 120 + IWL_EXPORT_SYMBOL(iwl_notification_wait_notify); 122 121 123 122 void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) 124 123 { ··· 131 130 132 131 wake_up_all(&notif_wait->notif_waitq); 133 132 } 134 - EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); 133 + IWL_EXPORT_SYMBOL(iwl_abort_notification_waits); 135 134 136 135 void 137 136 iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, ··· 155 154 list_add(&wait_entry->list, &notif_wait->notif_waits); 156 155 spin_unlock_bh(&notif_wait->notif_wait_lock); 157 156 } 158 - EXPORT_SYMBOL_GPL(iwl_init_notification_wait); 157 + IWL_EXPORT_SYMBOL(iwl_init_notification_wait); 159 158 160 159 int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, 161 160 struct iwl_notification_wait *wait_entry, ··· 179 178 return -ETIMEDOUT; 180 179 return 0; 181 180 } 182 - EXPORT_SYMBOL_GPL(iwl_wait_notification); 181 + IWL_EXPORT_SYMBOL(iwl_wait_notification); 183 182 184 183 void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, 185 184 struct iwl_notification_wait *wait_entry) ··· 188 187 list_del(&wait_entry->list); 189 188 spin_unlock_bh(&notif_wait->notif_wait_lock); 190 189 } 191 - EXPORT_SYMBOL_GPL(iwl_remove_notification); 190 + IWL_EXPORT_SYMBOL(iwl_remove_notification);
+1 -1
drivers/net/wireless/iwlwifi/iwl-notif-wait.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+49 -2
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 62 62 #include <linux/types.h> 63 63 #include <linux/slab.h> 64 64 #include <linux/export.h> 65 + #include "iwl-drv.h" 65 66 #include "iwl-modparams.h" 66 67 #include "iwl-nvm-parse.h" 67 68 ··· 150 149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate 151 150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) 152 151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) 152 + * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) 153 + * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) 153 154 */ 154 155 enum iwl_nvm_channel_flags { 155 156 NVM_CHANNEL_VALID = BIT(0), ··· 161 158 NVM_CHANNEL_DFS = BIT(7), 162 159 NVM_CHANNEL_WIDE = BIT(8), 163 160 NVM_CHANNEL_40MHZ = BIT(9), 161 + NVM_CHANNEL_80MHZ = BIT(10), 162 + NVM_CHANNEL_160MHZ = BIT(11), 164 163 }; 165 164 166 165 #define CHECK_AND_PRINT_I(x) \ ··· 215 210 else 216 211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 217 212 } 213 + if (!(ch_flags & NVM_CHANNEL_80MHZ)) 214 + channel->flags |= IEEE80211_CHAN_NO_80MHZ; 215 + if (!(ch_flags & NVM_CHANNEL_160MHZ)) 216 + channel->flags |= IEEE80211_CHAN_NO_160MHZ; 218 217 219 218 if (!(ch_flags & NVM_CHANNEL_IBSS)) 220 219 channel->flags |= IEEE80211_CHAN_NO_IBSS; ··· 254 245 return n_channels; 255 246 } 256 247 248 + static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, 249 + struct iwl_nvm_data *data, 250 + struct ieee80211_sta_vht_cap *vht_cap) 251 + { 252 + /* For now, assume new devices with NVM are VHT capable */ 253 + 254 + vht_cap->vht_supported = true; 255 + 256 + vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | 257 + IEEE80211_VHT_CAP_RXSTBC_1 | 258 + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 259 + 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; 260 + 261 + if (iwlwifi_mod_params.amsdu_size_8K) 262 + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 263 + 264 + vht_cap->vht_mcs.rx_mcs_map = 265 + cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | 266 + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | 267 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | 268 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | 269 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | 270 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | 271 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 272 + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); 273 + 274 + if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { 275 + vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | 276 + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; 277 + /* this works because NOT_SUPPORTED == 3 */ 278 + vht_cap->vht_mcs.rx_mcs_map |= 279 + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2); 280 + } 281 + 282 + vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; 283 + } 284 + 257 285 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 258 286 struct iwl_nvm_data *data, const __le16 *nvm_sw) 259 287 { ··· 314 268 n_used += iwl_init_sband_channels(data, sband, n_channels, 315 269 IEEE80211_BAND_5GHZ); 316 270 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 271 + iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); 317 272 318 273 if (n_channels != n_used) 319 274 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", ··· 390 343 391 344 return data; 392 345 } 393 - EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); 346 + IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
+1 -1
drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-op-mode.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+6 -21
drivers/net/wireless/iwlwifi/iwl-phy-db.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 65 65 #include <linux/string.h> 66 66 #include <linux/export.h> 67 67 68 + #include "iwl-drv.h" 68 69 #include "iwl-phy-db.h" 69 70 #include "iwl-debug.h" 70 71 #include "iwl-op-mode.h" ··· 137 136 u8 data[]; 138 137 } __packed; 139 138 140 - #define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587) 141 - static inline void iwl_phy_db_test_pic(__le32 pic) 142 - { 143 - WARN_ON(IWL_PHY_DB_STATIC_PIC != pic); 144 - } 145 - 146 139 struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) 147 140 { 148 141 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), ··· 150 155 /* TODO: add default values of the phy db. */ 151 156 return phy_db; 152 157 } 153 - EXPORT_SYMBOL(iwl_phy_db_init); 158 + IWL_EXPORT_SYMBOL(iwl_phy_db_init); 154 159 155 160 /* 156 161 * get phy db section: returns a pointer to a phy db section specified by ··· 216 221 217 222 kfree(phy_db); 218 223 } 219 - EXPORT_SYMBOL(iwl_phy_db_free); 224 + IWL_EXPORT_SYMBOL(iwl_phy_db_free); 220 225 221 226 int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, 222 227 gfp_t alloc_ctx) ··· 255 260 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; 256 261 } 257 262 258 - /* Test PIC */ 259 - if (type != IWL_PHY_DB_CFG) 260 - iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) + 261 - (size / sizeof(__le32)) - 1)); 262 - 263 263 IWL_DEBUG_INFO(phy_db->trans, 264 264 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", 265 265 __func__, __LINE__, type, size); 266 266 267 267 return 0; 268 268 } 269 - EXPORT_SYMBOL(iwl_phy_db_set_section); 269 + IWL_EXPORT_SYMBOL(iwl_phy_db_set_section); 270 270 271 271 static int is_valid_channel(u16 ch_id) 272 272 { ··· 361 371 *data = entry->data; 362 372 *size = entry->size; 363 373 } 364 - 365 - /* Test PIC */ 366 - if (type != IWL_PHY_DB_CFG) 367 - iwl_phy_db_test_pic(*(((__le32 *)*data) + 368 - (*size / sizeof(__le32)) - 1)); 369 374 370 375 IWL_DEBUG_INFO(phy_db->trans, 371 376 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", ··· 496 511 "Finished sending phy db non channel data\n"); 497 512 return 0; 498 513 } 499 - EXPORT_SYMBOL(iwl_send_phy_db_data); 514 + IWL_EXPORT_SYMBOL(iwl_send_phy_db_data);
+1 -1
drivers/net/wireless/iwlwifi/iwl-phy-db.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-prph.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+6 -5
drivers/net/wireless/iwlwifi/iwl-test.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 64 64 #include <linux/export.h> 65 65 #include <net/netlink.h> 66 66 67 + #include "iwl-drv.h" 67 68 #include "iwl-io.h" 68 69 #include "iwl-fh.h" 69 70 #include "iwl-prph.h" ··· 654 653 } 655 654 return 0; 656 655 } 657 - EXPORT_SYMBOL_GPL(iwl_test_parse); 656 + IWL_EXPORT_SYMBOL(iwl_test_parse); 658 657 659 658 /* 660 659 * Handle test commands. ··· 716 715 } 717 716 return result; 718 717 } 719 - EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); 718 + IWL_EXPORT_SYMBOL(iwl_test_handle_cmd); 720 719 721 720 static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, 722 721 struct netlink_callback *cb) ··· 804 803 } 805 804 return result; 806 805 } 807 - EXPORT_SYMBOL_GPL(iwl_test_dump); 806 + IWL_EXPORT_SYMBOL(iwl_test_dump); 808 807 809 808 /* 810 809 * Multicast a spontaneous messages from the device to the user space. ··· 850 849 if (tst->notify) 851 850 iwl_test_send_rx(tst, rxb); 852 851 } 853 - EXPORT_SYMBOL_GPL(iwl_test_rx); 852 + IWL_EXPORT_SYMBOL(iwl_test_rx);
+1 -1
drivers/net/wireless/iwlwifi/iwl-test.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/iwl-testmode.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+10 -12
drivers/net/wireless/iwlwifi/iwl-trans.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 183 183 * @CMD_ASYNC: Return right away and don't want for the response 184 184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the 185 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 186 * @CMD_ON_DEMAND: This command is sent by the test mode pipe. 192 187 */ 193 188 enum CMD_MODE { 194 189 CMD_SYNC = 0, 195 190 CMD_ASYNC = BIT(0), 196 191 CMD_WANT_SKB = BIT(1), 197 - CMD_WANT_HCMD = BIT(2), 198 - CMD_ON_DEMAND = BIT(3), 192 + CMD_ON_DEMAND = BIT(2), 199 193 }; 200 194 201 195 #define DEF_CMD_PAYLOAD_SIZE 320 ··· 208 214 209 215 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) 210 216 211 - #define IWL_MAX_CMD_TFDS 2 217 + /* 218 + * number of transfer buffers (fragments) per transmit frame descriptor; 219 + * this is just the driver's idea, the hardware supports 20 220 + */ 221 + #define IWL_MAX_CMD_TBS_PER_TFD 2 212 222 213 223 /** 214 224 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command ··· 249 251 * @id: id of the host command 250 252 */ 251 253 struct iwl_host_cmd { 252 - const void *data[IWL_MAX_CMD_TFDS]; 254 + const void *data[IWL_MAX_CMD_TBS_PER_TFD]; 253 255 struct iwl_rx_packet *resp_pkt; 254 256 unsigned long _rx_page_addr; 255 257 u32 _rx_page_order; 256 258 int handler_status; 257 259 258 260 u32 flags; 259 - u16 len[IWL_MAX_CMD_TFDS]; 260 - u8 dataflags[IWL_MAX_CMD_TFDS]; 261 + u16 len[IWL_MAX_CMD_TBS_PER_TFD]; 262 + u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD]; 261 263 u8 id; 262 264 }; 263 265
+1 -1
drivers/net/wireless/iwlwifi/mvm/Makefile
··· 2 2 iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 3 3 iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 4 4 iwlmvm-y += scan.o time-event.o rs.o 5 - iwlmvm-y += power.o 5 + iwlmvm-y += power.o bt-coex.o 6 6 iwlmvm-y += led.o 7 7 iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 8 8 iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
+1 -1
drivers/net/wireless/iwlwifi/mvm/binding.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+347
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
··· 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 + }
+336 -28
drivers/net/wireless/iwlwifi/mvm/d3.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 61 61 * 62 62 *****************************************************************************/ 63 63 64 + #include <linux/etherdevice.h> 65 + #include <linux/ip.h> 64 66 #include <net/cfg80211.h> 65 67 #include <net/ipv6.h> 68 + #include <net/tcp.h> 66 69 #include "iwl-modparams.h" 67 70 #include "fw-api.h" 68 71 #include "mvm.h" ··· 195 192 sizeof(wkc), &wkc); 196 193 data->error = ret != 0; 197 194 195 + mvm->ptk_ivlen = key->iv_len; 196 + mvm->ptk_icvlen = key->icv_len; 197 + mvm->gtk_ivlen = key->iv_len; 198 + mvm->gtk_icvlen = key->icv_len; 199 + 198 200 /* don't upload key again */ 199 201 goto out_unlock; 200 202 } ··· 312 304 */ 313 305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 314 306 key->hw_key_idx = 0; 307 + mvm->ptk_ivlen = key->iv_len; 308 + mvm->ptk_icvlen = key->icv_len; 315 309 } else { 316 310 data->gtk_key_idx++; 317 311 key->hw_key_idx = data->gtk_key_idx; 312 + mvm->gtk_ivlen = key->iv_len; 313 + mvm->gtk_icvlen = key->icv_len; 318 314 } 319 315 320 316 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); ··· 402 390 403 391 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC, 404 392 sizeof(cmd), &cmd); 393 + } 394 + 395 + enum iwl_mvm_tcp_packet_type { 396 + MVM_TCP_TX_SYN, 397 + MVM_TCP_RX_SYNACK, 398 + MVM_TCP_TX_DATA, 399 + MVM_TCP_RX_ACK, 400 + MVM_TCP_RX_WAKE, 401 + MVM_TCP_TX_FIN, 402 + }; 403 + 404 + static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr) 405 + { 406 + __sum16 check = tcp_v4_check(len, saddr, daddr, 0); 407 + return cpu_to_le16(be16_to_cpu((__force __be16)check)); 408 + } 409 + 410 + static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm, 411 + struct ieee80211_vif *vif, 412 + struct cfg80211_wowlan_tcp *tcp, 413 + void *_pkt, u8 *mask, 414 + __le16 *pseudo_hdr_csum, 415 + enum iwl_mvm_tcp_packet_type ptype) 416 + { 417 + struct { 418 + struct ethhdr eth; 419 + struct iphdr ip; 420 + struct tcphdr tcp; 421 + u8 data[]; 422 + } __packed *pkt = _pkt; 423 + u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 424 + int i; 425 + 426 + pkt->eth.h_proto = cpu_to_be16(ETH_P_IP), 427 + pkt->ip.version = 4; 428 + pkt->ip.ihl = 5; 429 + pkt->ip.protocol = IPPROTO_TCP; 430 + 431 + switch (ptype) { 432 + case MVM_TCP_TX_SYN: 433 + case MVM_TCP_TX_DATA: 434 + case MVM_TCP_TX_FIN: 435 + memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN); 436 + memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN); 437 + pkt->ip.ttl = 128; 438 + pkt->ip.saddr = tcp->src; 439 + pkt->ip.daddr = tcp->dst; 440 + pkt->tcp.source = cpu_to_be16(tcp->src_port); 441 + pkt->tcp.dest = cpu_to_be16(tcp->dst_port); 442 + /* overwritten for TX SYN later */ 443 + pkt->tcp.doff = sizeof(struct tcphdr) / 4; 444 + pkt->tcp.window = cpu_to_be16(65000); 445 + break; 446 + case MVM_TCP_RX_SYNACK: 447 + case MVM_TCP_RX_ACK: 448 + case MVM_TCP_RX_WAKE: 449 + memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN); 450 + memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN); 451 + pkt->ip.saddr = tcp->dst; 452 + pkt->ip.daddr = tcp->src; 453 + pkt->tcp.source = cpu_to_be16(tcp->dst_port); 454 + pkt->tcp.dest = cpu_to_be16(tcp->src_port); 455 + break; 456 + default: 457 + WARN_ON(1); 458 + return; 459 + } 460 + 461 + switch (ptype) { 462 + case MVM_TCP_TX_SYN: 463 + /* firmware assumes 8 option bytes - 8 NOPs for now */ 464 + memset(pkt->data, 0x01, 8); 465 + ip_tot_len += 8; 466 + pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4; 467 + pkt->tcp.syn = 1; 468 + break; 469 + case MVM_TCP_TX_DATA: 470 + ip_tot_len += tcp->payload_len; 471 + memcpy(pkt->data, tcp->payload, tcp->payload_len); 472 + pkt->tcp.psh = 1; 473 + pkt->tcp.ack = 1; 474 + break; 475 + case MVM_TCP_TX_FIN: 476 + pkt->tcp.fin = 1; 477 + pkt->tcp.ack = 1; 478 + break; 479 + case MVM_TCP_RX_SYNACK: 480 + pkt->tcp.syn = 1; 481 + pkt->tcp.ack = 1; 482 + break; 483 + case MVM_TCP_RX_ACK: 484 + pkt->tcp.ack = 1; 485 + break; 486 + case MVM_TCP_RX_WAKE: 487 + ip_tot_len += tcp->wake_len; 488 + pkt->tcp.psh = 1; 489 + pkt->tcp.ack = 1; 490 + memcpy(pkt->data, tcp->wake_data, tcp->wake_len); 491 + break; 492 + } 493 + 494 + switch (ptype) { 495 + case MVM_TCP_TX_SYN: 496 + case MVM_TCP_TX_DATA: 497 + case MVM_TCP_TX_FIN: 498 + pkt->ip.tot_len = cpu_to_be16(ip_tot_len); 499 + pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl); 500 + break; 501 + case MVM_TCP_RX_WAKE: 502 + for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) { 503 + u8 tmp = tcp->wake_mask[i]; 504 + mask[i + 6] |= tmp << 6; 505 + if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8)) 506 + mask[i + 7] = tmp >> 2; 507 + } 508 + /* fall through for ethernet/IP/TCP headers mask */ 509 + case MVM_TCP_RX_SYNACK: 510 + case MVM_TCP_RX_ACK: 511 + mask[0] = 0xff; /* match ethernet */ 512 + /* 513 + * match ethernet, ip.version, ip.ihl 514 + * the ip.ihl half byte is really masked out by firmware 515 + */ 516 + mask[1] = 0x7f; 517 + mask[2] = 0x80; /* match ip.protocol */ 518 + mask[3] = 0xfc; /* match ip.saddr, ip.daddr */ 519 + mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */ 520 + mask[5] = 0x80; /* match tcp flags */ 521 + /* leave rest (0 or set for MVM_TCP_RX_WAKE) */ 522 + break; 523 + }; 524 + 525 + *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr), 526 + pkt->ip.saddr, pkt->ip.daddr); 527 + } 528 + 529 + static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, 530 + struct ieee80211_vif *vif, 531 + struct cfg80211_wowlan_tcp *tcp) 532 + { 533 + struct iwl_wowlan_remote_wake_config *cfg; 534 + struct iwl_host_cmd cmd = { 535 + .id = REMOTE_WAKE_CONFIG_CMD, 536 + .len = { sizeof(*cfg), }, 537 + .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 538 + .flags = CMD_SYNC, 539 + }; 540 + int ret; 541 + 542 + if (!tcp) 543 + return 0; 544 + 545 + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 546 + if (!cfg) 547 + return -ENOMEM; 548 + cmd.data[0] = cfg; 549 + 550 + cfg->max_syn_retries = 10; 551 + cfg->max_data_retries = 10; 552 + cfg->tcp_syn_ack_timeout = 1; /* seconds */ 553 + cfg->tcp_ack_timeout = 1; /* seconds */ 554 + 555 + /* SYN (TX) */ 556 + iwl_mvm_build_tcp_packet( 557 + mvm, vif, tcp, cfg->syn_tx.data, NULL, 558 + &cfg->syn_tx.info.tcp_pseudo_header_checksum, 559 + MVM_TCP_TX_SYN); 560 + cfg->syn_tx.info.tcp_payload_length = 0; 561 + 562 + /* SYN/ACK (RX) */ 563 + iwl_mvm_build_tcp_packet( 564 + mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask, 565 + &cfg->synack_rx.info.tcp_pseudo_header_checksum, 566 + MVM_TCP_RX_SYNACK); 567 + cfg->synack_rx.info.tcp_payload_length = 0; 568 + 569 + /* KEEPALIVE/ACK (TX) */ 570 + iwl_mvm_build_tcp_packet( 571 + mvm, vif, tcp, cfg->keepalive_tx.data, NULL, 572 + &cfg->keepalive_tx.info.tcp_pseudo_header_checksum, 573 + MVM_TCP_TX_DATA); 574 + cfg->keepalive_tx.info.tcp_payload_length = 575 + cpu_to_le16(tcp->payload_len); 576 + cfg->sequence_number_offset = tcp->payload_seq.offset; 577 + /* length must be 0..4, the field is little endian */ 578 + cfg->sequence_number_length = tcp->payload_seq.len; 579 + cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start); 580 + cfg->keepalive_interval = cpu_to_le16(tcp->data_interval); 581 + if (tcp->payload_tok.len) { 582 + cfg->token_offset = tcp->payload_tok.offset; 583 + cfg->token_length = tcp->payload_tok.len; 584 + cfg->num_tokens = 585 + cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len); 586 + memcpy(cfg->tokens, tcp->payload_tok.token_stream, 587 + tcp->tokens_size); 588 + } else { 589 + /* set tokens to max value to almost never run out */ 590 + cfg->num_tokens = cpu_to_le16(65535); 591 + } 592 + 593 + /* ACK (RX) */ 594 + iwl_mvm_build_tcp_packet( 595 + mvm, vif, tcp, cfg->keepalive_ack_rx.data, 596 + cfg->keepalive_ack_rx.rx_mask, 597 + &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum, 598 + MVM_TCP_RX_ACK); 599 + cfg->keepalive_ack_rx.info.tcp_payload_length = 0; 600 + 601 + /* WAKEUP (RX) */ 602 + iwl_mvm_build_tcp_packet( 603 + mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask, 604 + &cfg->wake_rx.info.tcp_pseudo_header_checksum, 605 + MVM_TCP_RX_WAKE); 606 + cfg->wake_rx.info.tcp_payload_length = 607 + cpu_to_le16(tcp->wake_len); 608 + 609 + /* FIN */ 610 + iwl_mvm_build_tcp_packet( 611 + mvm, vif, tcp, cfg->fin_tx.data, NULL, 612 + &cfg->fin_tx.info.tcp_pseudo_header_checksum, 613 + MVM_TCP_TX_FIN); 614 + cfg->fin_tx.info.tcp_payload_length = 0; 615 + 616 + ret = iwl_mvm_send_cmd(mvm, &cmd); 617 + kfree(cfg); 618 + 619 + return ret; 405 620 } 406 621 407 622 struct iwl_d3_iter_data { ··· 869 630 d3_cfg_cmd.wakeup_flags |= 870 631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 871 632 633 + if (wowlan->tcp) { 634 + /* 635 + * The firmware currently doesn't really look at these, only 636 + * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that 637 + * reason bit since losing the connection to the AP implies 638 + * losing the TCP connection. 639 + * Set the flags anyway as long as they exist, in case this 640 + * will be changed in the firmware. 641 + */ 642 + wowlan_config_cmd.wakeup_filter |= 643 + cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | 644 + IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | 645 + IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | 646 + IWL_WOWLAN_WAKEUP_LINK_CHANGE); 647 + } 648 + 872 649 iwl_mvm_cancel_scan(mvm); 873 650 874 651 iwl_trans_stop_device(mvm->trans); ··· 903 648 904 649 /* We reprogram keys and shouldn't allocate new key indices */ 905 650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 651 + 652 + mvm->ptk_ivlen = 0; 653 + mvm->ptk_icvlen = 0; 654 + mvm->ptk_ivlen = 0; 655 + mvm->ptk_icvlen = 0; 906 656 907 657 /* 908 658 * The D3 firmware still hardcodes the AP station ID for the ··· 1000 740 if (ret) 1001 741 goto out; 1002 742 743 + ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); 744 + if (ret) 745 + goto out; 746 + 1003 747 /* must be last -- this switches firmware state */ 1004 748 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1005 749 sizeof(d3_cfg_cmd), &d3_cfg_cmd); ··· 1047 783 struct iwl_wowlan_status *status; 1048 784 u32 reasons; 1049 785 int ret, len; 1050 - bool pkt8023 = false; 1051 786 struct sk_buff *pkt = NULL; 1052 787 1053 788 iwl_trans_read_mem_bytes(mvm->trans, base, ··· 1087 824 status = (void *)cmd.resp_pkt->data; 1088 825 1089 826 if (len - sizeof(struct iwl_cmd_header) != 1090 - sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { 827 + sizeof(*status) + 828 + ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { 1091 829 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1092 830 goto out; 1093 831 } ··· 1100 836 goto report; 1101 837 } 1102 838 1103 - if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { 839 + if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) 1104 840 wakeup.magic_pkt = true; 1105 - pkt8023 = true; 1106 - } 1107 841 1108 - if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { 842 + if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) 1109 843 wakeup.pattern_idx = 1110 844 le16_to_cpu(status->pattern_number); 1111 - pkt8023 = true; 1112 - } 1113 845 1114 846 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 1115 847 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 1116 848 wakeup.disconnect = true; 1117 849 1118 - if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { 850 + if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) 1119 851 wakeup.gtk_rekey_failure = true; 1120 - pkt8023 = true; 1121 - } 1122 852 1123 - if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { 853 + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) 1124 854 wakeup.rfkill_release = true; 1125 - pkt8023 = true; 1126 - } 1127 855 1128 - if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { 856 + if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) 1129 857 wakeup.eap_identity_req = true; 1130 - pkt8023 = true; 1131 - } 1132 858 1133 - if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { 859 + if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) 1134 860 wakeup.four_way_handshake = true; 1135 - pkt8023 = true; 1136 - } 861 + 862 + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) 863 + wakeup.tcp_connlost = true; 864 + 865 + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) 866 + wakeup.tcp_nomoretokens = true; 867 + 868 + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) 869 + wakeup.tcp_match = true; 1137 870 1138 871 if (status->wake_packet_bufsize) { 1139 - u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); 1140 - u32 pktlen = le32_to_cpu(status->wake_packet_length); 872 + int pktsize = le32_to_cpu(status->wake_packet_bufsize); 873 + int pktlen = le32_to_cpu(status->wake_packet_length); 874 + const u8 *pktdata = status->wake_packet; 875 + struct ieee80211_hdr *hdr = (void *)pktdata; 876 + int truncated = pktlen - pktsize; 1141 877 1142 - if (pkt8023) { 878 + /* this would be a firmware bug */ 879 + if (WARN_ON_ONCE(truncated < 0)) 880 + truncated = 0; 881 + 882 + if (ieee80211_is_data(hdr->frame_control)) { 883 + int hdrlen = ieee80211_hdrlen(hdr->frame_control); 884 + int ivlen = 0, icvlen = 4; /* also FCS */ 885 + 1143 886 pkt = alloc_skb(pktsize, GFP_KERNEL); 1144 887 if (!pkt) 1145 888 goto report; 1146 - memcpy(skb_put(pkt, pktsize), status->wake_packet, 1147 - pktsize); 889 + 890 + memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen); 891 + pktdata += hdrlen; 892 + pktsize -= hdrlen; 893 + 894 + if (ieee80211_has_protected(hdr->frame_control)) { 895 + if (is_multicast_ether_addr(hdr->addr1)) { 896 + ivlen = mvm->gtk_ivlen; 897 + icvlen += mvm->gtk_icvlen; 898 + } else { 899 + ivlen = mvm->ptk_ivlen; 900 + icvlen += mvm->ptk_icvlen; 901 + } 902 + } 903 + 904 + /* if truncated, FCS/ICV is (partially) gone */ 905 + if (truncated >= icvlen) { 906 + icvlen = 0; 907 + truncated -= icvlen; 908 + } else { 909 + icvlen -= truncated; 910 + truncated = 0; 911 + } 912 + 913 + pktsize -= ivlen + icvlen; 914 + pktdata += ivlen; 915 + 916 + memcpy(skb_put(pkt, pktsize), pktdata, pktsize); 917 + 1148 918 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 1149 919 goto report; 1150 920 wakeup.packet = pkt->data; 1151 921 wakeup.packet_present_len = pkt->len; 1152 - wakeup.packet_len = pkt->len - (pktlen - pktsize); 922 + wakeup.packet_len = pkt->len - truncated; 1153 923 wakeup.packet_80211 = false; 1154 924 } else { 925 + int fcslen = 4; 926 + 927 + if (truncated >= 4) { 928 + truncated -= 4; 929 + fcslen = 0; 930 + } else { 931 + fcslen -= truncated; 932 + truncated = 0; 933 + } 934 + pktsize -= fcslen; 1155 935 wakeup.packet = status->wake_packet; 1156 936 wakeup.packet_present_len = pktsize; 1157 - wakeup.packet_len = pktlen; 937 + wakeup.packet_len = pktlen - truncated; 1158 938 wakeup.packet_80211 = true; 1159 939 } 1160 940 }
+128 -10
drivers/net/wireless/iwlwifi/mvm/debugfs.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 68 68 struct iwl_mvm *mvm; 69 69 struct ieee80211_vif *vif; 70 70 }; 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 71 78 72 static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, 79 73 const char __user *user_buf, ··· 300 306 return count; 301 307 } 302 308 309 + #define BT_MBOX_MSG(_notif, _num, _field) \ 310 + ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ 311 + >> BT_MBOX##_num##_##_field##_POS) 312 + 313 + 314 + #define BT_MBOX_PRINT(_num, _field, _end) \ 315 + pos += scnprintf(buf + pos, bufsz - pos, \ 316 + "\t%s: %d%s", \ 317 + #_field, \ 318 + BT_MBOX_MSG(notif, _num, _field), \ 319 + true ? "\n" : ", "); 320 + 321 + static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, 322 + size_t count, loff_t *ppos) 323 + { 324 + struct iwl_mvm *mvm = file->private_data; 325 + struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; 326 + char *buf; 327 + int ret, pos = 0, bufsz = sizeof(char) * 1024; 328 + 329 + buf = kmalloc(bufsz, GFP_KERNEL); 330 + if (!buf) 331 + return -ENOMEM; 332 + 333 + mutex_lock(&mvm->mutex); 334 + 335 + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); 336 + 337 + BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); 338 + BT_MBOX_PRINT(0, LE_PROF1, false); 339 + BT_MBOX_PRINT(0, LE_PROF2, false); 340 + BT_MBOX_PRINT(0, LE_PROF_OTHER, false); 341 + BT_MBOX_PRINT(0, CHL_SEQ_N, false); 342 + BT_MBOX_PRINT(0, INBAND_S, false); 343 + BT_MBOX_PRINT(0, LE_MIN_RSSI, false); 344 + BT_MBOX_PRINT(0, LE_SCAN, false); 345 + BT_MBOX_PRINT(0, LE_ADV, false); 346 + BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false); 347 + BT_MBOX_PRINT(0, OPEN_CON_1, true); 348 + 349 + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n"); 350 + 351 + BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false); 352 + BT_MBOX_PRINT(1, IP_SR, false); 353 + BT_MBOX_PRINT(1, LE_MSTR, false); 354 + BT_MBOX_PRINT(1, AGGR_TRFC_LD, false); 355 + BT_MBOX_PRINT(1, MSG_TYPE, false); 356 + BT_MBOX_PRINT(1, SSN, true); 357 + 358 + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n"); 359 + 360 + BT_MBOX_PRINT(2, SNIFF_ACT, false); 361 + BT_MBOX_PRINT(2, PAG, false); 362 + BT_MBOX_PRINT(2, INQUIRY, false); 363 + BT_MBOX_PRINT(2, CONN, false); 364 + BT_MBOX_PRINT(2, SNIFF_INTERVAL, false); 365 + BT_MBOX_PRINT(2, DISC, false); 366 + BT_MBOX_PRINT(2, SCO_TX_ACT, false); 367 + BT_MBOX_PRINT(2, SCO_RX_ACT, false); 368 + BT_MBOX_PRINT(2, ESCO_RE_TX, false); 369 + BT_MBOX_PRINT(2, SCO_DURATION, true); 370 + 371 + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n"); 372 + 373 + BT_MBOX_PRINT(3, SCO_STATE, false); 374 + BT_MBOX_PRINT(3, SNIFF_STATE, false); 375 + BT_MBOX_PRINT(3, A2DP_STATE, false); 376 + BT_MBOX_PRINT(3, ACL_STATE, false); 377 + BT_MBOX_PRINT(3, MSTR_STATE, false); 378 + BT_MBOX_PRINT(3, OBX_STATE, false); 379 + BT_MBOX_PRINT(3, OPEN_CON_2, false); 380 + BT_MBOX_PRINT(3, TRAFFIC_LOAD, false); 381 + BT_MBOX_PRINT(3, CHL_SEQN_LSB, false); 382 + BT_MBOX_PRINT(3, INBAND_P, false); 383 + BT_MBOX_PRINT(3, MSG_TYPE_2, false); 384 + BT_MBOX_PRINT(3, SSN_2, false); 385 + BT_MBOX_PRINT(3, UPDATE_REQUEST, true); 386 + 387 + pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", 388 + notif->bt_status); 389 + pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", 390 + notif->bt_open_conn); 391 + pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", 392 + notif->bt_traffic_load); 393 + pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", 394 + notif->bt_agg_traffic_load); 395 + pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", 396 + notif->bt_ci_compliance); 397 + 398 + mutex_unlock(&mvm->mutex); 399 + 400 + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 401 + kfree(buf); 402 + 403 + return ret; 404 + } 405 + #undef BT_MBOX_PRINT 406 + 407 + static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 408 + const char __user *user_buf, 409 + size_t count, loff_t *ppos) 410 + { 411 + struct iwl_mvm *mvm = file->private_data; 412 + bool restart_fw = iwlwifi_mod_params.restart_fw; 413 + int ret; 414 + 415 + iwlwifi_mod_params.restart_fw = true; 416 + 417 + mutex_lock(&mvm->mutex); 418 + 419 + /* take the return value to make compiler happy - it will fail anyway */ 420 + ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL); 421 + 422 + mutex_unlock(&mvm->mutex); 423 + 424 + iwlwifi_mod_params.restart_fw = restart_fw; 425 + 426 + return count; 427 + } 428 + 303 429 #define MVM_DEBUGFS_READ_FILE_OPS(name) \ 304 430 static const struct file_operations iwl_dbgfs_##name##_ops = { \ 305 431 .read = iwl_dbgfs_##name##_read, \ 306 - .open = iwl_dbgfs_open_file_generic, \ 432 + .open = simple_open, \ 307 433 .llseek = generic_file_llseek, \ 308 434 } 309 435 ··· 431 317 static const struct file_operations iwl_dbgfs_##name##_ops = { \ 432 318 .write = iwl_dbgfs_##name##_write, \ 433 319 .read = iwl_dbgfs_##name##_read, \ 434 - .open = iwl_dbgfs_open_file_generic, \ 320 + .open = simple_open, \ 435 321 .llseek = generic_file_llseek, \ 436 322 }; 437 323 438 324 #define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ 439 325 static const struct file_operations iwl_dbgfs_##name##_ops = { \ 440 326 .write = iwl_dbgfs_##name##_write, \ 441 - .open = iwl_dbgfs_open_file_generic, \ 327 + .open = simple_open, \ 442 328 .llseek = generic_file_llseek, \ 443 329 }; 444 330 ··· 459 345 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 460 346 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 461 347 MVM_DEBUGFS_READ_FILE_OPS(stations); 348 + MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 462 349 MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 463 350 MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 351 + MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 464 352 465 353 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 466 354 { ··· 474 358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 475 359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 476 360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 361 + MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); 477 362 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 478 363 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 364 + MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 479 365 480 366 /* 481 367 * Create a symlink with mac80211. It will be removed when mac80211
+319
drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
··· 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__ */
+51 -2
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 258 258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), 259 259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), 260 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 262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), 263 263 }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ 264 264 ··· 276 276 __le32 wake_packet_bufsize; 277 277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */ 278 278 } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ 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 */ 279 328 280 329 /* TODO: NetDetect API */ 281 330
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+20 -10
drivers/net/wireless/iwlwifi/mvm/fw-api.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 70 70 #include "fw-api-mac.h" 71 71 #include "fw-api-power.h" 72 72 #include "fw-api-d3.h" 73 + #include "fw-api-bt-coex.h" 73 74 74 75 /* queue and FIFO numbers by usage */ 75 76 enum { ··· 153 152 154 153 BEACON_TEMPLATE_CMD = 0x91, 155 154 TX_ANT_CONFIGURATION_CMD = 0x98, 155 + BT_CONFIG = 0x9b, 156 156 STATISTICS_NOTIFICATION = 0x9d, 157 157 158 158 /* RF-KILL commands and notifications */ ··· 163 161 REPLY_RX_PHY_CMD = 0xc0, 164 162 REPLY_RX_MPDU_CMD = 0xc1, 165 163 BA_NOTIF = 0xc5, 164 + 165 + /* BT Coex */ 166 + BT_COEX_PRIO_TABLE = 0xcc, 167 + BT_COEX_PROT_ENV = 0xcd, 168 + BT_PROFILE_NOTIFICATION = 0xce, 166 169 167 170 REPLY_DEBUG_CMD = 0xf0, 168 171 DEBUG_LOG_MSG = 0xf7, ··· 769 762 #define IWL_RX_INFO_PHY_CNT 8 770 763 #define IWL_RX_INFO_AGC_IDX 1 771 764 #define IWL_RX_INFO_RSSI_AB_IDX 2 772 - #define IWL_RX_INFO_RSSI_C_IDX 3 773 - #define IWL_OFDM_AGC_DB_MSK 0xfe00 774 - #define IWL_OFDM_AGC_DB_POS 9 765 + #define IWL_OFDM_AGC_A_MSK 0x0000007f 766 + #define IWL_OFDM_AGC_A_POS 0 767 + #define IWL_OFDM_AGC_B_MSK 0x00003f80 768 + #define IWL_OFDM_AGC_B_POS 7 769 + #define IWL_OFDM_AGC_CODE_MSK 0x3fe00000 770 + #define IWL_OFDM_AGC_CODE_POS 20 775 771 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff 776 - #define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 777 772 #define IWL_OFDM_RSSI_A_POS 0 773 + #define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 774 + #define IWL_OFDM_RSSI_ALLBAND_A_POS 8 778 775 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 779 - #define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 780 776 #define IWL_OFDM_RSSI_B_POS 16 781 - #define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff 782 - #define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 783 - #define IWL_OFDM_RSSI_C_POS 0 777 + #define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 778 + #define IWL_OFDM_RSSI_ALLBAND_B_POS 24 784 779 785 780 /** 786 781 * struct iwl_rx_phy_info - phy info ··· 801 792 * @byte_count: frame's byte-count 802 793 * @frame_time: frame's time on the air, based on byte count and frame rate 803 794 * calculation 795 + * @mac_active_msk: what MACs were active when the frame was received 804 796 * 805 797 * Before each Rx, the device sends this data. It contains PHY information 806 798 * about the reception of the packet. ··· 819 809 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; 820 810 __le32 rate_n_flags; 821 811 __le32 byte_count; 822 - __le16 reserved2; 812 + __le16 mac_active_msk; 823 813 __le16 frame_time; 824 814 } __packed; 825 815
+18 -129
drivers/net/wireless/iwlwifi/mvm/fw.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 79 79 #define UCODE_VALID_OK cpu_to_le32(0x1) 80 80 81 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 82 static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; 91 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 85 struct iwl_calib_default_data { 95 86 u16 size; ··· 90 99 #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} 91 100 92 101 static const struct iwl_calib_default_data wkp_calib_default_data[12] = { 93 - [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc), 94 - [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter), 95 - [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo), 96 - [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq), 97 102 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), 98 - [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq), 99 103 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), 100 104 }; 101 105 ··· 227 241 228 242 return 0; 229 243 } 230 - #define IWL_HW_REV_ID_RAINBOW 0x2 231 - #define IWL_PROJ_TYPE_LHP 0x5 232 - 233 - static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm) 234 - { 235 - struct iwl_nvm_data *data = mvm->nvm_data; 236 - /* Temp calls to static definitions, will be changed to CSR calls */ 237 - u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW; 238 - u8 project_type = IWL_PROJ_TYPE_LHP; 239 - 240 - return data->radio_cfg_dash | (data->radio_cfg_step << 2) | 241 - (hw_rev_id << 4) | ((project_type & 0x7f) << 6) | 242 - (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20); 243 - } 244 244 245 245 static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) 246 246 { ··· 234 262 enum iwl_ucode_type ucode_type = mvm->cur_ucode; 235 263 236 264 /* Set parameters */ 237 - phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); 265 + phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); 238 266 phy_cfg_cmd.calib_control.event_trigger = 239 267 mvm->fw->default_calib[ucode_type].event_trigger; 240 268 phy_cfg_cmd.calib_control.flow_trigger = ··· 245 273 246 274 return iwl_mvm_send_cmd_pdu(mvm, PHY_CONFIGURATION_CMD, CMD_SYNC, 247 275 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 248 - } 249 - 250 - /* Starting with the new PHY DB implementation - New calibs are enabled */ 251 - /* Value - 0x405e7 */ 252 - #define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\ 253 - IWL_CALIB_CFG_TEMPERATURE_IDX |\ 254 - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ 255 - IWL_CALIB_CFG_DC_IDX |\ 256 - IWL_CALIB_CFG_BB_FILTER_IDX |\ 257 - IWL_CALIB_CFG_LO_LEAKAGE_IDX |\ 258 - IWL_CALIB_CFG_TX_IQ_IDX |\ 259 - IWL_CALIB_CFG_RX_IQ_IDX |\ 260 - IWL_CALIB_CFG_AGC_IDX) 261 - 262 - #define IWL_CALIB_DEFAULT_EVENT_INIT 0x0 263 - 264 - /* Value 0x41567 */ 265 - #define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\ 266 - IWL_CALIB_CFG_TEMPERATURE_IDX |\ 267 - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ 268 - IWL_CALIB_CFG_BB_FILTER_IDX |\ 269 - IWL_CALIB_CFG_DC_IDX |\ 270 - IWL_CALIB_CFG_TX_IQ_IDX |\ 271 - IWL_CALIB_CFG_RX_IQ_IDX |\ 272 - IWL_CALIB_CFG_SENSITIVITY_IDX |\ 273 - IWL_CALIB_CFG_AGC_IDX) 274 - 275 - #define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\ 276 - IWL_CALIB_CFG_TEMPERATURE_IDX |\ 277 - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ 278 - IWL_CALIB_CFG_TX_PWR_IDX |\ 279 - IWL_CALIB_CFG_DC_IDX |\ 280 - IWL_CALIB_CFG_TX_IQ_IDX |\ 281 - IWL_CALIB_CFG_SENSITIVITY_IDX) 282 - 283 - /* 284 - * Sets the calibrations trigger values that will be sent to the FW for runtime 285 - * and init calibrations. 286 - * The ones given in the FW TLV are not correct. 287 - */ 288 - static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm) 289 - { 290 - struct iwl_tlv_calib_ctrl default_calib; 291 - 292 - /* 293 - * WkP FW TLV calib bits are wrong, overwrite them. 294 - * This defines the dynamic calibrations which are implemented in the 295 - * uCode both for init(flow) calculation and event driven calibs. 296 - */ 297 - 298 - /* Init Image */ 299 - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT); 300 - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT); 301 - 302 - if (default_calib.event_trigger != 303 - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger) 304 - IWL_ERR(mvm, 305 - "Updating the event calib for INIT image: 0x%x -> 0x%x\n", 306 - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger, 307 - default_calib.event_trigger); 308 - if (default_calib.flow_trigger != 309 - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger) 310 - IWL_ERR(mvm, 311 - "Updating the flow calib for INIT image: 0x%x -> 0x%x\n", 312 - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger, 313 - default_calib.flow_trigger); 314 - 315 - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT], 316 - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); 317 - IWL_ERR(mvm, 318 - "Setting uCode init calibrations event 0x%x, trigger 0x%x\n", 319 - default_calib.event_trigger, 320 - default_calib.flow_trigger); 321 - 322 - /* Run time image */ 323 - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN); 324 - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN); 325 - 326 - if (default_calib.event_trigger != 327 - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger) 328 - IWL_ERR(mvm, 329 - "Updating the event calib for RT image: 0x%x -> 0x%x\n", 330 - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger, 331 - default_calib.event_trigger); 332 - if (default_calib.flow_trigger != 333 - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger) 334 - IWL_ERR(mvm, 335 - "Updating the flow calib for RT image: 0x%x -> 0x%x\n", 336 - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger, 337 - default_calib.flow_trigger); 338 - 339 - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR], 340 - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); 341 - IWL_ERR(mvm, 342 - "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n", 343 - default_calib.event_trigger, 344 - default_calib.flow_trigger); 345 276 } 346 277 347 278 static int iwl_set_default_calibrations(struct iwl_mvm *mvm) ··· 309 434 goto error; 310 435 } 311 436 437 + ret = iwl_send_bt_prio_tbl(mvm); 438 + if (ret) 439 + goto error; 440 + 312 441 if (read_nvm) { 313 442 /* Read nvm */ 314 443 ret = iwl_nvm_init(mvm); ··· 325 446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 447 WARN_ON(ret); 327 448 328 - /* Override the calibrations from TLV and the const of fw */ 329 - iwl_set_default_calib_trigger(mvm); 449 + /* Send TX valid antennas before triggering calibrations */ 450 + ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 451 + if (ret) 452 + goto error; 330 453 331 454 /* WkP doesn't have all calibrations, need to set default values */ 332 455 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { ··· 415 534 } 416 535 417 536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 537 + if (ret) 538 + goto error; 539 + 540 + ret = iwl_send_bt_prio_tbl(mvm); 541 + if (ret) 542 + goto error; 543 + 544 + ret = iwl_send_bt_init_conf(mvm); 418 545 if (ret) 419 546 goto error; 420 547
+1 -1
drivers/net/wireless/iwlwifi/mvm/led.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+34 -11
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 553 553 if (vif->bss_conf.qos) 554 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 557 if (vif->bss_conf.use_cts_prot) 557 - cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | 558 - MAC_PROT_FLG_SELF_CTS_EN); 558 + cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 559 559 560 560 /* 561 561 * I think that we should enable these 2 flags regardless the HT PROT ··· 651 651 /* Fill the common data for all mac context types */ 652 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 661 /* Fill the data specific for station mode */ 655 662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 656 663 ··· 721 714 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 722 715 723 716 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 724 - cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); 717 + 718 + /* Override the filter flags to accept only probe requests */ 719 + cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); 725 720 726 721 /* 727 722 * This flag should be set to true when the P2P Device is ··· 855 846 */ 856 847 static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, 857 848 struct ieee80211_vif *vif, 858 - struct iwl_mac_data_ap *ctxt_ap) 849 + struct iwl_mac_data_ap *ctxt_ap, 850 + bool add) 859 851 { 860 852 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 861 - u32 curr_dev_time; 862 853 863 854 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 864 855 ctxt_ap->bi_reciprocal = ··· 870 861 vif->bss_conf.dtim_period)); 871 862 872 863 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 873 - curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); 874 - ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time); 875 864 876 - ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); 865 + /* 866 + * Only read the system time when the MAC is being added, when we 867 + * just modify the MAC then we should keep the time -- the firmware 868 + * can otherwise have a "jumping" TBTT. 869 + */ 870 + if (add) 871 + mvmvif->ap_beacon_time = 872 + iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); 873 + 874 + ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); 875 + 876 + ctxt_ap->beacon_tsf = 0; /* unused */ 877 877 878 878 /* TODO: Assume that the beacon id == mac context id */ 879 879 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); ··· 899 881 /* Fill the common data for all mac context types */ 900 882 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 901 883 884 + /* Also enable probe requests to pass */ 885 + cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); 886 + 902 887 /* Fill the data specific for ap mode */ 903 - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); 888 + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, 889 + action == FW_CTXT_ACTION_ADD); 904 890 905 891 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 906 892 } ··· 921 899 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 922 900 923 901 /* Fill the data specific for GO mode */ 924 - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); 902 + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, 903 + action == FW_CTXT_ACTION_ADD); 925 904 926 905 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); 927 906 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
+57 -12
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 65 65 #include <linux/skbuff.h> 66 66 #include <linux/netdevice.h> 67 67 #include <linux/etherdevice.h> 68 + #include <linux/ip.h> 68 69 #include <net/mac80211.h> 70 + #include <net/tcp.h> 69 71 70 72 #include "iwl-op-mode.h" 71 73 #include "iwl-io.h" ··· 104 102 }, 105 103 }; 106 104 105 + #ifdef CONFIG_PM_SLEEP 106 + static const struct nl80211_wowlan_tcp_data_token_feature 107 + iwl_mvm_wowlan_tcp_token_feature = { 108 + .min_len = 0, 109 + .max_len = 255, 110 + .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS, 111 + }; 112 + 113 + static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = { 114 + .tok = &iwl_mvm_wowlan_tcp_token_feature, 115 + .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN - 116 + sizeof(struct ethhdr) - 117 + sizeof(struct iphdr) - 118 + sizeof(struct tcphdr), 119 + .data_interval_max = 65535, /* __le16 in API */ 120 + .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN - 121 + sizeof(struct ethhdr) - 122 + sizeof(struct iphdr) - 123 + sizeof(struct tcphdr), 124 + .seq = true, 125 + }; 126 + #endif 127 + 107 128 int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 108 129 { 109 130 struct ieee80211_hw *hw = mvm->hw; 110 - int num_mac, ret; 131 + int num_mac, ret, i; 111 132 112 133 /* Tell mac80211 our characteristics */ 113 134 hw->flags = IEEE80211_HW_SIGNAL_DBM | ··· 181 156 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 182 157 hw->wiphy->addresses = mvm->addresses; 183 158 hw->wiphy->n_addresses = 1; 184 - num_mac = mvm->nvm_data->n_hw_addrs; 185 - if (num_mac > 1) { 186 - memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, 159 + 160 + /* Extract additional MAC addresses if available */ 161 + num_mac = (mvm->nvm_data->n_hw_addrs > 1) ? 162 + min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1; 163 + 164 + for (i = 1; i < num_mac; i++) { 165 + memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr, 187 166 ETH_ALEN); 188 - mvm->addresses[1].addr[5]++; 167 + mvm->addresses[i].addr[5]++; 189 168 hw->wiphy->n_addresses++; 190 169 } 191 170 ··· 235 206 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 236 207 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 237 208 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 209 + hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; 238 210 } 239 211 #endif 240 212 ··· 303 273 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); 304 274 break; 305 275 case IEEE80211_AMPDU_TX_START: 276 + if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { 277 + ret = -EINVAL; 278 + break; 279 + } 306 280 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); 307 281 break; 308 282 case IEEE80211_AMPDU_TX_STOP_CONT: 283 + ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); 284 + break; 309 285 case IEEE80211_AMPDU_TX_STOP_FLUSH: 310 286 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 311 - ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); 287 + ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid); 312 288 break; 313 289 case IEEE80211_AMPDU_TX_OPERATIONAL: 314 290 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); ··· 593 557 return ret; 594 558 } 595 559 596 - static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, 597 - struct ieee80211_vif *vif) 560 + static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, 561 + struct ieee80211_vif *vif) 598 562 { 599 - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 600 - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 601 563 u32 tfd_msk = 0, ac; 602 564 603 565 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ··· 628 594 */ 629 595 flush_work(&mvm->sta_drained_wk); 630 596 } 597 + } 598 + 599 + static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, 600 + struct ieee80211_vif *vif) 601 + { 602 + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 603 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 604 + 605 + iwl_mvm_prepare_mac_removal(mvm, vif); 631 606 632 607 mutex_lock(&mvm->mutex); 633 608 634 609 /* 635 610 * For AP/GO interface, the tear down of the resources allocated to the 636 - * interface should be handled as part of the bss_info_changed flow. 611 + * interface is be handled as part of the stop_ap flow. 637 612 */ 638 613 if (vif->type == NL80211_IFTYPE_AP) { 639 614 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); ··· 805 762 { 806 763 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 807 764 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 765 + 766 + iwl_mvm_prepare_mac_removal(mvm, vif); 808 767 809 768 mutex_lock(&mvm->mutex); 810 769
+21 -3
drivers/net/wireless/iwlwifi/mvm/mvm.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 79 79 #include "fw-api.h" 80 80 81 81 #define IWL_INVALID_MAC80211_QUEUE 0xff 82 - #define IWL_MVM_MAX_ADDRESSES 2 83 - #define IWL_RSSI_OFFSET 44 82 + #define IWL_MVM_MAX_ADDRESSES 5 83 + /* RSSI offset for WkP */ 84 + #define IWL_RSSI_OFFSET 50 84 85 85 86 enum iwl_mvm_tx_fifo { 86 87 IWL_MVM_TX_FIFO_BK = 0, ··· 173 172 174 173 bool uploaded; 175 174 bool ap_active; 175 + 176 + u32 ap_beacon_time; 176 177 177 178 enum iwl_tsf_id tsf_id; 178 179 ··· 330 327 struct led_classdev led; 331 328 332 329 struct ieee80211_vif *p2p_device_vif; 330 + 331 + #ifdef CONFIG_PM_SLEEP 332 + int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 333 + #endif 334 + 335 + /* BT-Coex */ 336 + u8 bt_kill_msk; 337 + struct iwl_bt_coex_profile_notif last_bt_notif; 333 338 }; 334 339 335 340 /* Extract MVM priv from op_mode and _hw */ ··· 507 496 struct inet6_dev *idev); 508 497 void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 509 498 struct ieee80211_vif *vif, int idx); 499 + 500 + /* BT Coex */ 501 + int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); 502 + int iwl_send_bt_init_conf(struct iwl_mvm *mvm); 503 + int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, 504 + struct iwl_rx_cmd_buffer *rxb, 505 + struct iwl_device_cmd *cmd); 510 506 511 507 #endif /* __IWL_MVM_H__ */
+7 -4
drivers/net/wireless/iwlwifi/mvm/nvm.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 73 73 NVM_SECTION_TYPE_CALIBRATION, 74 74 NVM_SECTION_TYPE_PRODUCTION, 75 75 }; 76 + 77 + /* Default NVM size to read */ 78 + #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 76 79 77 80 /* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 78 81 union iwl_nvm_access_cmd { ··· 196 193 int ret; 197 194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; 198 195 199 - length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) 200 - - sizeof(union iwl_nvm_access_cmd) 201 - - sizeof(struct iwl_rx_packet); 196 + /* Set nvm section read length */ 197 + length = IWL_NVM_DEFAULT_CHUNK_SIZE; 198 + 202 199 /* 203 200 * if length is greater than EEPROM size, truncate it because uCode 204 201 * doesn't check it by itself, and exit the loop when reached.
+22 -8
drivers/net/wireless/iwlwifi/mvm/ops.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 230 230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 231 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 235 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 234 236 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 235 237 ··· 295 293 CMD(NET_DETECT_PROFILES_CMD), 296 294 CMD(NET_DETECT_HOTSPOTS_CMD), 297 295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 296 + CMD(CARD_STATE_NOTIFICATION), 297 + CMD(BT_COEX_PRIO_TABLE), 298 + CMD(BT_COEX_PROT_ENV), 299 + CMD(BT_PROFILE_NOTIFICATION), 300 + CMD(BT_CONFIG), 298 301 }; 299 302 #undef CMD 300 303 ··· 370 363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 371 364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 372 365 373 - /* TODO: this should really be a TLV */ 374 - if (cfg->device_family == IWL_DEVICE_FAMILY_7000) 366 + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) 375 367 trans_cfg.bc_table_dword = true; 376 368 377 369 if (!iwlwifi_mod_params.wd_disable) ··· 630 624 ieee80211_free_txskb(mvm->hw, skb); 631 625 } 632 626 633 - static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 627 + static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) 634 628 { 635 - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 636 - 637 - iwl_mvm_dump_nic_error_log(mvm); 638 - 639 629 iwl_abort_notification_waits(&mvm->notif_wait); 640 630 641 631 /* ··· 665 663 } 666 664 } 667 665 666 + static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 667 + { 668 + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 669 + 670 + iwl_mvm_dump_nic_error_log(mvm); 671 + 672 + iwl_mvm_nic_restart(mvm); 673 + } 674 + 668 675 static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) 669 676 { 677 + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 678 + 670 679 WARN_ON(1); 680 + iwl_mvm_nic_restart(mvm); 671 681 } 672 682 673 683 static const struct iwl_op_mode_ops iwl_mvm_ops = {
+1 -1
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/power.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/quota.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+8 -6
drivers/net/wireless/iwlwifi/mvm/rs.c
··· 680 680 */ 681 681 static bool rs_use_green(struct ieee80211_sta *sta) 682 682 { 683 - struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 684 - 685 - bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & 686 - IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 687 - 688 - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; 683 + /* 684 + * There's a bug somewhere in this code that causes the 685 + * scaling to get stuck because GF+SGI can't be combined 686 + * in SISO rates. Until we find that bug, disable GF, it 687 + * has only limited benefit and we still interoperate with 688 + * GF APs since we can always receive GF transmissions. 689 + */ 690 + return false; 689 691 } 690 692 691 693 /**
+24 -15
drivers/net/wireless/iwlwifi/mvm/rx.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 131 131 static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, 132 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 137 u32 val; 136 138 137 - /* Find max rssi among 3 possible receivers. 139 + /* Find max rssi among 2 possible receivers. 138 140 * These values are measured by the Digital Signal Processor (DSP). 139 141 * They should stay fairly constant even as the signal strength varies, 140 142 * if the radio's Automatic Gain Control (AGC) is working right. 141 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 150 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); 144 151 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; 145 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]); 147 - rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; 153 + rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >> 154 + IWL_OFDM_RSSI_ALLBAND_A_POS; 155 + rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >> 156 + IWL_OFDM_RSSI_ALLBAND_B_POS; 148 157 149 - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); 150 - agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS; 158 + /* 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); 151 165 152 - max_rssi = max_t(u32, rssi_a, rssi_b); 153 - max_rssi = max_t(u32, max_rssi, rssi_c); 166 + IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", 167 + rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); 154 168 155 - IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", 156 - rssi_a, rssi_b, rssi_c, max_rssi, agc_db); 157 - 158 - /* dBm = max_rssi dB - agc dB - constant. 159 - * Higher AGC (higher radio gain) means lower signal. */ 160 - return max_rssi - agc_db - IWL_RSSI_OFFSET; 169 + return max_rssi_dbm; 161 170 } 162 171 163 172 /*
+1 -1
drivers/net/wireless/iwlwifi/mvm/scan.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+91 -6
drivers/net/wireless/iwlwifi/mvm/sta.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 101 101 } 102 102 add_sta_cmd.add_modify = update ? 1 : 0; 103 103 104 - /* STA_FLG_FAT_EN_MSK ? */ 105 - /* STA_FLG_MIMO_EN_MSK ? */ 104 + add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_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 154 if (sta->ht_cap.ht_supported) { 108 155 add_sta_cmd.station_flags_msk |= ··· 387 340 388 341 if (vif->type == NL80211_IFTYPE_STATION && 389 342 mvmvif->ap_sta_id == mvm_sta->sta_id) { 343 + /* flush its queues here since we are freeing mvm_sta */ 344 + ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); 345 + 390 346 /* 391 347 * Put a non-NULL since the fw station isn't removed. 392 348 * It will be removed after the MAC will be set as ··· 397 347 */ 398 348 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 399 349 ERR_PTR(-EINVAL)); 400 - 401 - /* flush its queues here since we are freeing mvm_sta */ 402 - ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); 403 350 404 351 /* if we are associated - we can't remove the AP STA now */ 405 352 if (vif->bss_conf.assoc) ··· 817 770 u16 txq_id; 818 771 int err; 819 772 773 + 774 + /* 775 + * If mac80211 is cleaning its state, then say that we finished since 776 + * our state has been cleared anyway. 777 + */ 778 + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 779 + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 780 + return 0; 781 + } 782 + 820 783 spin_lock_bh(&mvmsta->lock); 821 784 822 785 txq_id = tid_data->txq_id; ··· 879 822 spin_unlock_bh(&mvmsta->lock); 880 823 881 824 return err; 825 + } 826 + 827 + int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 828 + struct ieee80211_sta *sta, u16 tid) 829 + { 830 + struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 831 + struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 832 + u16 txq_id; 833 + 834 + /* 835 + * First set the agg state to OFF to avoid calling 836 + * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty. 837 + */ 838 + spin_lock_bh(&mvmsta->lock); 839 + txq_id = tid_data->txq_id; 840 + IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", 841 + mvmsta->sta_id, tid, txq_id, tid_data->state); 842 + tid_data->state = IWL_AGG_OFF; 843 + spin_unlock_bh(&mvmsta->lock); 844 + 845 + if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) 846 + IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); 847 + 848 + iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); 849 + mvm->queue_to_mac80211[tid_data->txq_id] = 850 + IWL_INVALID_MAC80211_QUEUE; 851 + 852 + return 0; 882 853 } 883 854 884 855 static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
+3 -1
drivers/net/wireless/iwlwifi/mvm/sta.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 347 347 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 348 348 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 349 349 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 350 + struct ieee80211_sta *sta, u16 tid); 351 + int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 350 352 struct ieee80211_sta *sta, u16 tid); 351 353 352 354 int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
+1 -1
drivers/net/wireless/iwlwifi/mvm/time-event.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+1 -1
drivers/net/wireless/iwlwifi/mvm/time-event.h
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
+2 -6
drivers/net/wireless/iwlwifi/mvm/tx.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 607 607 608 608 /* Single frame failure in an AMPDU queue => send BAR */ 609 609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE && 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)); 610 + !(info->flags & IEEE80211_TX_STAT_ACK)) 614 611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 615 - } 616 612 617 613 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ 618 614 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
+1 -1
drivers/net/wireless/iwlwifi/mvm/utils.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com>
-1
drivers/net/wireless/iwlwifi/pcie/1000.c drivers/net/wireless/iwlwifi/iwl-1000.c
··· 29 29 #include "iwl-config.h" 30 30 #include "iwl-csr.h" 31 31 #include "iwl-agn-hw.h" 32 - #include "cfg.h" 33 32 34 33 /* Highest firmware API version supported */ 35 34 #define IWL1000_UCODE_API_MAX 5
-1
drivers/net/wireless/iwlwifi/pcie/2000.c drivers/net/wireless/iwlwifi/iwl-2000.c
··· 28 28 #include <linux/stringify.h> 29 29 #include "iwl-config.h" 30 30 #include "iwl-agn-hw.h" 31 - #include "cfg.h" 32 31 #include "dvm/commands.h" /* needed for BT for now */ 33 32 34 33 /* Highest firmware API version supported */
-1
drivers/net/wireless/iwlwifi/pcie/5000.c drivers/net/wireless/iwlwifi/iwl-5000.c
··· 29 29 #include "iwl-config.h" 30 30 #include "iwl-agn-hw.h" 31 31 #include "iwl-csr.h" 32 - #include "cfg.h" 33 32 34 33 /* Highest firmware API version supported */ 35 34 #define IWL5000_UCODE_API_MAX 5
-1
drivers/net/wireless/iwlwifi/pcie/6000.c drivers/net/wireless/iwlwifi/iwl-6000.c
··· 28 28 #include <linux/stringify.h> 29 29 #include "iwl-config.h" 30 30 #include "iwl-agn-hw.h" 31 - #include "cfg.h" 32 31 #include "dvm/commands.h" /* needed for BT for now */ 33 32 34 33 /* Highest firmware API version supported */
+49 -14
drivers/net/wireless/iwlwifi/pcie/7000.c drivers/net/wireless/iwlwifi/iwl-7000.c
··· 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 - * under the terms of version 2 of the GNU General Public License as 6 + * GPL LICENSE SUMMARY 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 12 * published by the Free Software Foundation. 8 13 * 9 - * This program is distributed in the hope that it will be useful, but WITHOUT 10 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 - * more details. 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. 13 18 * 14 - * You should have received a copy of the GNU General Public License along with 15 - * this program; if not, write to the Free Software Foundation, Inc., 16 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 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 17 23 * 18 - * The full GNU General Public License is included in this distribution in the 19 - * file called LICENSE. 24 + * The full GNU General Public License is included in this distribution 25 + * in the file called COPYING. 20 26 * 21 27 * Contact Information: 22 28 * Intel Linux Wireless <ilw@linux.intel.com> 23 29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 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. 24 61 * 25 62 *****************************************************************************/ 26 63 ··· 65 28 #include <linux/stringify.h> 66 29 #include "iwl-config.h" 67 30 #include "iwl-agn-hw.h" 68 - #include "cfg.h" 69 31 70 32 /* Highest firmware API version supported */ 71 33 #define IWL7260_UCODE_API_MAX 6 ··· 106 70 }; 107 71 108 72 static const struct iwl_ht_params iwl7000_ht_params = { 109 - .ht_greenfield_support = true, 110 73 .use_rts_for_aggregation = true, /* use rts/cts protection */ 111 74 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 112 75 };
-115
drivers/net/wireless/iwlwifi/pcie/cfg.h
··· 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__ */
+1 -3
drivers/net/wireless/iwlwifi/pcie/drv.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 69 69 70 70 #include "iwl-trans.h" 71 71 #include "iwl-drv.h" 72 - 73 - #include "cfg.h" 74 72 #include "internal.h" 75 73 76 74 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
+30 -5
drivers/net/wireless/iwlwifi/pcie/internal.h
··· 137 137 struct iwl_cmd_meta { 138 138 /* only for SYNC commands, iff the reply skb is wanted */ 139 139 struct iwl_host_cmd *source; 140 - 141 - DEFINE_DMA_UNMAP_ADDR(mapping); 142 - DEFINE_DMA_UNMAP_LEN(len); 143 - 144 140 u32 flags; 145 141 }; 146 142 ··· 178 182 #define TFD_TX_CMD_SLOTS 256 179 183 #define TFD_CMD_SLOTS 32 180 184 185 + /* 186 + * The FH will write back to the first TB only, so we need 187 + * to copy some data into the buffer regardless of whether 188 + * it should be mapped or not. This indicates how big the 189 + * first TB must be to include the scratch buffer. Since 190 + * the scratch is 4 bytes at offset 12, it's 16 now. If we 191 + * make it bigger then allocations will be bigger and copy 192 + * slower, so that's probably not useful. 193 + */ 194 + #define IWL_HCMD_SCRATCHBUF_SIZE 16 195 + 181 196 struct iwl_pcie_txq_entry { 182 197 struct iwl_device_cmd *cmd; 183 - struct iwl_device_cmd *copy_cmd; 184 198 struct sk_buff *skb; 185 199 /* buffer to free after command completes */ 186 200 const void *free_buf; 187 201 struct iwl_cmd_meta meta; 188 202 }; 189 203 204 + struct iwl_pcie_txq_scratch_buf { 205 + struct iwl_cmd_header hdr; 206 + u8 buf[8]; 207 + __le32 scratch; 208 + }; 209 + 190 210 /** 191 211 * struct iwl_txq - Tx Queue for DMA 192 212 * @q: generic Rx/Tx queue descriptor 193 213 * @tfds: transmit frame descriptors (DMA memory) 214 + * @scratchbufs: start of command headers, including scratch buffers, for 215 + * the writeback -- this is DMA memory and an array holding one buffer 216 + * for each command on the queue 217 + * @scratchbufs_dma: DMA address for the scratchbufs start 194 218 * @entries: transmit entries (driver state) 195 219 * @lock: queue lock 196 220 * @stuck_timer: timer that fires if queue gets stuck ··· 224 208 struct iwl_txq { 225 209 struct iwl_queue q; 226 210 struct iwl_tfd *tfds; 211 + struct iwl_pcie_txq_scratch_buf *scratchbufs; 212 + dma_addr_t scratchbufs_dma; 227 213 struct iwl_pcie_txq_entry *entries; 228 214 spinlock_t lock; 229 215 struct timer_list stuck_timer; ··· 233 215 u8 need_update; 234 216 u8 active; 235 217 }; 218 + 219 + static inline dma_addr_t 220 + iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) 221 + { 222 + return txq->scratchbufs_dma + 223 + sizeof(struct iwl_pcie_txq_scratch_buf) * idx; 224 + } 236 225 237 226 /** 238 227 * struct iwl_trans_pcie - PCIe transport specific data
+3 -11
drivers/net/wireless/iwlwifi/pcie/rx.c
··· 637 637 index = SEQ_TO_INDEX(sequence); 638 638 cmd_index = get_cmd_index(&txq->q, index); 639 639 640 - if (reclaim) { 641 - struct iwl_pcie_txq_entry *ent; 642 - ent = &txq->entries[cmd_index]; 643 - cmd = ent->copy_cmd; 644 - WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); 645 - } else { 640 + if (reclaim) 641 + cmd = txq->entries[cmd_index].cmd; 642 + else 646 643 cmd = NULL; 647 - } 648 644 649 645 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); 650 646 651 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 648 kfree(txq->entries[cmd_index].free_buf); 657 649 txq->entries[cmd_index].free_buf = NULL; 658 650 }
+4 -21
drivers/net/wireless/iwlwifi/pcie/trans.c
··· 22 22 * USA 23 23 * 24 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 27 * Contact Information: 28 28 * Intel Linux Wireless <ilw@linux.intel.com> ··· 715 715 716 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 720 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); 720 721 } 721 722 ··· 724 723 u32 val) 725 724 { 726 725 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, 727 - ((addr & 0x0000FFFF) | (3 << 24))); 726 + ((addr & 0x000FFFFF) | (3 << 24))); 728 727 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); 729 728 } 730 729 ··· 1371 1370 return ret; 1372 1371 } 1373 1372 1374 - static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 1375 - const char __user *user_buf, 1376 - size_t count, loff_t *ppos) 1377 - { 1378 - struct iwl_trans *trans = file->private_data; 1379 - 1380 - if (!trans->op_mode) 1381 - return -EAGAIN; 1382 - 1383 - local_bh_disable(); 1384 - iwl_op_mode_nic_error(trans->op_mode); 1385 - local_bh_enable(); 1386 - 1387 - return count; 1388 - } 1389 - 1390 1373 DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 1391 1374 DEBUGFS_READ_FILE_OPS(fh_reg); 1392 1375 DEBUGFS_READ_FILE_OPS(rx_queue); 1393 1376 DEBUGFS_READ_FILE_OPS(tx_queue); 1394 1377 DEBUGFS_WRITE_FILE_OPS(csr); 1395 - DEBUGFS_WRITE_FILE_OPS(fw_restart); 1396 1378 1397 1379 /* 1398 1380 * Create the debugfs files and directories ··· 1389 1405 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); 1390 1406 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); 1391 1407 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); 1392 - DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); 1393 1408 return 0; 1394 1409 1395 1410 err:
+166 -143
drivers/net/wireless/iwlwifi/pcie/tx.c
··· 191 191 } 192 192 193 193 for (i = q->read_ptr; i != q->write_ptr; 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; 194 + i = iwl_queue_inc_wrap(i, q->n_bd)) 197 195 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 198 - get_unaligned_le32(&tx_cmd->scratch)); 199 - } 196 + le32_to_cpu(txq->scratchbufs[i].scratch)); 200 197 201 198 iwl_op_mode_nic_error(trans->op_mode); 202 199 } ··· 364 367 } 365 368 366 369 static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, 367 - struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, 368 - enum dma_data_direction dma_dir) 370 + struct iwl_cmd_meta *meta, 371 + struct iwl_tfd *tfd) 369 372 { 370 373 int i; 371 374 int num_tbs; ··· 379 382 return; 380 383 } 381 384 382 - /* Unmap tx_cmd */ 383 - if (num_tbs) 384 - dma_unmap_single(trans->dev, 385 - dma_unmap_addr(meta, mapping), 386 - dma_unmap_len(meta, len), 387 - DMA_BIDIRECTIONAL); 385 + /* first TB is never freed - it's the scratchbuf data */ 388 386 389 - /* Unmap chunks, if any. */ 390 387 for (i = 1; i < num_tbs; i++) 391 388 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), 392 - iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); 389 + iwl_pcie_tfd_tb_get_len(tfd, i), 390 + DMA_TO_DEVICE); 393 391 394 392 tfd->num_tbs = 0; 395 393 } ··· 398 406 * Does NOT advance any TFD circular buffer read/write indexes 399 407 * Does NOT free the TFD itself (which is within circular buffer) 400 408 */ 401 - static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, 402 - enum dma_data_direction dma_dir) 409 + static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) 403 410 { 404 411 struct iwl_tfd *tfd_tmp = txq->tfds; 405 412 ··· 409 418 lockdep_assert_held(&txq->lock); 410 419 411 420 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ 412 - iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], 413 - dma_dir); 421 + iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); 414 422 415 423 /* free SKB */ 416 424 if (txq->entries) { ··· 469 479 { 470 480 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 471 481 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; 482 + size_t scratchbuf_sz; 472 483 int i; 473 484 474 485 if (WARN_ON(txq->entries || txq->tfds)) ··· 505 514 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); 506 515 goto error; 507 516 } 517 + 518 + BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); 519 + BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != 520 + sizeof(struct iwl_cmd_header) + 521 + offsetof(struct iwl_tx_cmd, scratch)); 522 + 523 + scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num; 524 + 525 + txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz, 526 + &txq->scratchbufs_dma, 527 + GFP_KERNEL); 528 + if (!txq->scratchbufs) 529 + goto err_free_tfds; 530 + 508 531 txq->q.id = txq_id; 509 532 510 533 return 0; 534 + err_free_tfds: 535 + dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr); 511 536 error: 512 537 if (txq->entries && txq_id == trans_pcie->cmd_queue) 513 538 for (i = 0; i < slots_num; i++) ··· 572 565 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 573 566 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 574 567 struct iwl_queue *q = &txq->q; 575 - enum dma_data_direction dma_dir; 576 568 577 569 if (!q->n_bd) 578 570 return; 579 571 580 - /* In the command queue, all the TBs are mapped as BIDI 581 - * so unmap them as such. 582 - */ 583 - if (txq_id == trans_pcie->cmd_queue) 584 - dma_dir = DMA_BIDIRECTIONAL; 585 - else 586 - dma_dir = DMA_TO_DEVICE; 587 - 588 572 spin_lock_bh(&txq->lock); 589 573 while (q->write_ptr != q->read_ptr) { 590 - iwl_pcie_txq_free_tfd(trans, txq, dma_dir); 574 + iwl_pcie_txq_free_tfd(trans, txq); 591 575 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 592 576 } 593 577 spin_unlock_bh(&txq->lock); ··· 608 610 if (txq_id == trans_pcie->cmd_queue) 609 611 for (i = 0; i < txq->q.n_window; i++) { 610 612 kfree(txq->entries[i].cmd); 611 - kfree(txq->entries[i].copy_cmd); 612 613 kfree(txq->entries[i].free_buf); 613 614 } 614 615 ··· 616 619 dma_free_coherent(dev, sizeof(struct iwl_tfd) * 617 620 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 618 621 txq->q.dma_addr = 0; 622 + 623 + dma_free_coherent(dev, 624 + sizeof(*txq->scratchbufs) * txq->q.n_window, 625 + txq->scratchbufs, txq->scratchbufs_dma); 619 626 } 620 627 621 628 kfree(txq->entries); ··· 963 962 964 963 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); 965 964 966 - iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); 965 + iwl_pcie_txq_free_tfd(trans, txq); 967 966 } 968 967 969 968 iwl_pcie_txq_progress(trans_pcie, txq); ··· 1153 1152 void *dup_buf = NULL; 1154 1153 dma_addr_t phys_addr; 1155 1154 int idx; 1156 - u16 copy_size, cmd_size; 1155 + u16 copy_size, cmd_size, scratch_size; 1157 1156 bool had_nocopy = false; 1158 1157 int i; 1159 1158 u32 cmd_pos; 1159 + const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; 1160 + u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; 1160 1161 1161 1162 copy_size = sizeof(out_cmd->hdr); 1162 1163 cmd_size = sizeof(out_cmd->hdr); 1163 1164 1164 1165 /* need one for the header if the first is NOCOPY */ 1165 - BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); 1166 + BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1); 1166 1167 1167 - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1168 + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { 1169 + cmddata[i] = cmd->data[i]; 1170 + cmdlen[i] = cmd->len[i]; 1171 + 1168 1172 if (!cmd->len[i]) 1169 1173 continue; 1174 + 1175 + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ 1176 + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { 1177 + int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; 1178 + 1179 + if (copy > cmdlen[i]) 1180 + copy = cmdlen[i]; 1181 + cmdlen[i] -= copy; 1182 + cmddata[i] += copy; 1183 + copy_size += copy; 1184 + } 1185 + 1170 1186 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { 1171 1187 had_nocopy = true; 1172 1188 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { ··· 1203 1185 goto free_dup_buf; 1204 1186 } 1205 1187 1206 - dup_buf = kmemdup(cmd->data[i], cmd->len[i], 1188 + dup_buf = kmemdup(cmddata[i], cmdlen[i], 1207 1189 GFP_ATOMIC); 1208 1190 if (!dup_buf) 1209 1191 return -ENOMEM; ··· 1213 1195 idx = -EINVAL; 1214 1196 goto free_dup_buf; 1215 1197 } 1216 - copy_size += cmd->len[i]; 1198 + copy_size += cmdlen[i]; 1217 1199 } 1218 1200 cmd_size += cmd->len[i]; 1219 1201 } ··· 1260 1242 1261 1243 /* and copy the data that needs to be copied */ 1262 1244 cmd_pos = offsetof(struct iwl_device_cmd, payload); 1263 - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1264 - if (!cmd->len[i]) 1245 + copy_size = sizeof(out_cmd->hdr); 1246 + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { 1247 + int copy = 0; 1248 + 1249 + if (!cmd->len) 1265 1250 continue; 1266 - if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1267 - IWL_HCMD_DFL_DUP)) 1268 - break; 1269 - memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); 1270 - cmd_pos += cmd->len[i]; 1271 - } 1272 1251 1273 - WARN_ON_ONCE(txq->entries[idx].copy_cmd); 1252 + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ 1253 + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { 1254 + copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; 1274 1255 1275 - /* 1276 - * since out_cmd will be the source address of the FH, it will write 1277 - * the retry count there. So when the user needs to receivce the HCMD 1278 - * that corresponds to the response in the response handler, it needs 1279 - * to set CMD_WANT_HCMD. 1280 - */ 1281 - if (cmd->flags & CMD_WANT_HCMD) { 1282 - txq->entries[idx].copy_cmd = 1283 - kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); 1284 - if (unlikely(!txq->entries[idx].copy_cmd)) { 1285 - idx = -ENOMEM; 1286 - goto out; 1256 + if (copy > cmd->len[i]) 1257 + copy = cmd->len[i]; 1258 + } 1259 + 1260 + /* copy everything if not nocopy/dup */ 1261 + if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1262 + IWL_HCMD_DFL_DUP))) 1263 + copy = cmd->len[i]; 1264 + 1265 + if (copy) { 1266 + memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); 1267 + cmd_pos += copy; 1268 + copy_size += copy; 1287 1269 } 1288 1270 } 1289 1271 ··· 1293 1275 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), 1294 1276 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); 1295 1277 1296 - phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, 1297 - DMA_BIDIRECTIONAL); 1298 - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1299 - idx = -ENOMEM; 1300 - goto out; 1278 + /* start the TFD with the scratchbuf */ 1279 + scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE); 1280 + memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); 1281 + iwl_pcie_txq_build_tfd(trans, txq, 1282 + iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), 1283 + scratch_size, 1); 1284 + 1285 + /* map first command fragment, if any remains */ 1286 + if (copy_size > scratch_size) { 1287 + phys_addr = dma_map_single(trans->dev, 1288 + ((u8 *)&out_cmd->hdr) + scratch_size, 1289 + copy_size - scratch_size, 1290 + DMA_TO_DEVICE); 1291 + if (dma_mapping_error(trans->dev, phys_addr)) { 1292 + iwl_pcie_tfd_unmap(trans, out_meta, 1293 + &txq->tfds[q->write_ptr]); 1294 + idx = -ENOMEM; 1295 + goto out; 1296 + } 1297 + 1298 + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, 1299 + copy_size - scratch_size, 0); 1301 1300 } 1302 1301 1303 - dma_unmap_addr_set(out_meta, mapping, phys_addr); 1304 - dma_unmap_len_set(out_meta, len, copy_size); 1302 + /* map the remaining (adjusted) nocopy/dup fragments */ 1303 + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { 1304 + const void *data = cmddata[i]; 1305 1305 1306 - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); 1307 - 1308 - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1309 - const void *data = cmd->data[i]; 1310 - 1311 - if (!cmd->len[i]) 1306 + if (!cmdlen[i]) 1312 1307 continue; 1313 1308 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1314 1309 IWL_HCMD_DFL_DUP))) ··· 1329 1298 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) 1330 1299 data = dup_buf; 1331 1300 phys_addr = dma_map_single(trans->dev, (void *)data, 1332 - cmd->len[i], DMA_BIDIRECTIONAL); 1301 + cmdlen[i], DMA_TO_DEVICE); 1333 1302 if (dma_mapping_error(trans->dev, phys_addr)) { 1334 1303 iwl_pcie_tfd_unmap(trans, out_meta, 1335 - &txq->tfds[q->write_ptr], 1336 - DMA_BIDIRECTIONAL); 1304 + &txq->tfds[q->write_ptr]); 1337 1305 idx = -ENOMEM; 1338 1306 goto out; 1339 1307 } 1340 1308 1341 - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); 1309 + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); 1342 1310 } 1343 1311 1344 1312 out_meta->flags = cmd->flags; ··· 1347 1317 1348 1318 txq->need_update = 1; 1349 1319 1350 - trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, 1351 - &out_cmd->hdr, copy_size); 1320 + trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); 1352 1321 1353 1322 /* start timer if queue currently empty */ 1354 1323 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) ··· 1406 1377 cmd = txq->entries[cmd_index].cmd; 1407 1378 meta = &txq->entries[cmd_index].meta; 1408 1379 1409 - iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); 1380 + iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]); 1410 1381 1411 1382 /* Input error checking is done when commands are added to queue. */ 1412 1383 if (meta->flags & CMD_WANT_SKB) { ··· 1585 1556 struct iwl_cmd_meta *out_meta; 1586 1557 struct iwl_txq *txq; 1587 1558 struct iwl_queue *q; 1588 - dma_addr_t phys_addr = 0; 1589 - dma_addr_t txcmd_phys; 1590 - dma_addr_t scratch_phys; 1591 - u16 len, firstlen, secondlen; 1559 + dma_addr_t tb0_phys, tb1_phys, scratch_phys; 1560 + void *tb1_addr; 1561 + u16 len, tb1_len, tb2_len; 1592 1562 u8 wait_write_ptr = 0; 1593 1563 __le16 fc = hdr->frame_control; 1594 1564 u8 hdr_len = ieee80211_hdrlen(fc); ··· 1625 1597 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1626 1598 INDEX_TO_SEQ(q->write_ptr))); 1627 1599 1600 + tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr); 1601 + scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + 1602 + offsetof(struct iwl_tx_cmd, scratch); 1603 + 1604 + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); 1605 + tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); 1606 + 1628 1607 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 1629 1608 out_meta = &txq->entries[q->write_ptr].meta; 1630 1609 1631 1610 /* 1632 - * Use the first empty entry in this queue's command buffer array 1633 - * to contain the Tx command and MAC header concatenated together 1634 - * (payload data will be in another buffer). 1635 - * Size of this varies, due to varying MAC header length. 1636 - * If end is not dword aligned, we'll have 2 extra bytes at the end 1637 - * of the MAC header (device reads on dword boundaries). 1638 - * We'll tell device about this padding later. 1611 + * The second TB (tb1) points to the remainder of the TX command 1612 + * and the 802.11 header - dword aligned size 1613 + * (This calculation modifies the TX command, so do it before the 1614 + * setup of the first TB) 1639 1615 */ 1640 - len = sizeof(struct iwl_tx_cmd) + 1641 - sizeof(struct iwl_cmd_header) + hdr_len; 1642 - firstlen = (len + 3) & ~3; 1616 + len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + 1617 + hdr_len - IWL_HCMD_SCRATCHBUF_SIZE; 1618 + tb1_len = (len + 3) & ~3; 1643 1619 1644 1620 /* Tell NIC about any 2-byte padding after MAC header */ 1645 - if (firstlen != len) 1621 + if (tb1_len != len) 1646 1622 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; 1647 1623 1648 - /* Physical address of this Tx command's header (not MAC header!), 1649 - * within command buffer array. */ 1650 - txcmd_phys = dma_map_single(trans->dev, 1651 - &dev_cmd->hdr, firstlen, 1652 - DMA_BIDIRECTIONAL); 1653 - if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) 1624 + /* The first TB points to the scratchbuf data - min_copy bytes */ 1625 + memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, 1626 + IWL_HCMD_SCRATCHBUF_SIZE); 1627 + iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, 1628 + IWL_HCMD_SCRATCHBUF_SIZE, 1); 1629 + 1630 + /* there must be data left over for TB1 or this code must be changed */ 1631 + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); 1632 + 1633 + /* map the data for TB1 */ 1634 + tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE; 1635 + tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); 1636 + if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) 1654 1637 goto out_err; 1655 - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); 1656 - dma_unmap_len_set(out_meta, len, firstlen); 1638 + iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); 1639 + 1640 + /* 1641 + * Set up TFD's third entry to point directly to remainder 1642 + * of skb, if any (802.11 null frames have no payload). 1643 + */ 1644 + tb2_len = skb->len - hdr_len; 1645 + if (tb2_len > 0) { 1646 + dma_addr_t tb2_phys = dma_map_single(trans->dev, 1647 + skb->data + hdr_len, 1648 + tb2_len, DMA_TO_DEVICE); 1649 + if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { 1650 + iwl_pcie_tfd_unmap(trans, out_meta, 1651 + &txq->tfds[q->write_ptr]); 1652 + goto out_err; 1653 + } 1654 + iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); 1655 + } 1656 + 1657 + /* Set up entry for this TFD in Tx byte-count array */ 1658 + iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); 1659 + 1660 + trace_iwlwifi_dev_tx(trans->dev, skb, 1661 + &txq->tfds[txq->q.write_ptr], 1662 + sizeof(struct iwl_tfd), 1663 + &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len, 1664 + skb->data + hdr_len, tb2_len); 1665 + trace_iwlwifi_dev_tx_data(trans->dev, skb, 1666 + skb->data + hdr_len, tb2_len); 1657 1667 1658 1668 if (!ieee80211_has_morefrags(fc)) { 1659 1669 txq->need_update = 1; ··· 1699 1633 wait_write_ptr = 1; 1700 1634 txq->need_update = 0; 1701 1635 } 1702 - 1703 - /* Set up TFD's 2nd entry to point directly to remainder of skb, 1704 - * if any (802.11 null frames have no payload). */ 1705 - secondlen = skb->len - hdr_len; 1706 - if (secondlen > 0) { 1707 - phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, 1708 - secondlen, DMA_TO_DEVICE); 1709 - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1710 - dma_unmap_single(trans->dev, 1711 - dma_unmap_addr(out_meta, mapping), 1712 - dma_unmap_len(out_meta, len), 1713 - DMA_BIDIRECTIONAL); 1714 - goto out_err; 1715 - } 1716 - } 1717 - 1718 - /* Attach buffers to TFD */ 1719 - iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); 1720 - if (secondlen > 0) 1721 - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); 1722 - 1723 - scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + 1724 - offsetof(struct iwl_tx_cmd, scratch); 1725 - 1726 - /* take back ownership of DMA buffer to enable update */ 1727 - dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, 1728 - DMA_BIDIRECTIONAL); 1729 - tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); 1730 - tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); 1731 - 1732 - /* Set up entry for this TFD in Tx byte-count array */ 1733 - iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); 1734 - 1735 - dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, 1736 - DMA_BIDIRECTIONAL); 1737 - 1738 - trace_iwlwifi_dev_tx(trans->dev, skb, 1739 - &txq->tfds[txq->q.write_ptr], 1740 - sizeof(struct iwl_tfd), 1741 - &dev_cmd->hdr, firstlen, 1742 - skb->data + hdr_len, secondlen); 1743 - trace_iwlwifi_dev_tx_data(trans->dev, skb, 1744 - skb->data + hdr_len, secondlen); 1745 1636 1746 1637 /* start timer if queue currently empty */ 1747 1638 if (txq->need_update && q->read_ptr == q->write_ptr &&