···66 select LEDS_CLASS77 select LEDS_TRIGGERS88 select MAC80211_LEDS99- select IWLDVM109 ---help---1110 Select to build the driver supporting the:1211···4445config IWLDVM4546 tristate "Intel Wireless WiFi DVM Firmware support"4647 depends on IWLWIFI4848+ default IWLWIFI4749 help4850 This is the driver supporting the DVM firmware which is4951 currently the only firmware available for existing devices.···5757 currently only available for 7000 series devices.58585959 Say yes if you have such a device.6060+6161+# don't call it _MODULE -- will confuse Kconfig/fixdep/...6262+config IWLWIFI_OPMODE_MODULAR6363+ bool6464+ default y if IWLDVM=m6565+ default y if IWLMVM=m6666+6767+comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"6868+ depends on IWLWIFI && IWLDVM=n && IWLMVM=n60696170menu "Debugging Options"6271 depends on IWLWIFI
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/dvm/calib.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/dvm/calib.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+2-1
drivers/net/wireless/iwlwifi/dvm/commands.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···15261526 __le16 scd_ssn;15271527 u8 txed; /* number of frames sent */15281528 u8 txed_2_done; /* number of frames acked */15291529+ __le16 reserved1;15291530} __packed;1530153115311532/*
+25-1
drivers/net/wireless/iwlwifi/dvm/debugfs.c
···1919 * USA2020 *2121 * The full GNU General Public License is included in this distribution2222- * in the file called LICENSE.GPL.2222+ * in the file called COPYING.2323 *2424 * Contact Information:2525 * Intel Linux Wireless <ilw@linux.intel.com>···23242324 return count;23252325}2326232623272327+static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,23282328+ const char __user *user_buf,23292329+ size_t count, loff_t *ppos)23302330+{23312331+ struct iwl_priv *priv = file->private_data;23322332+ bool restart_fw = iwlwifi_mod_params.restart_fw;23332333+ int ret;23342334+23352335+ iwlwifi_mod_params.restart_fw = true;23362336+23372337+ mutex_lock(&priv->mutex);23382338+23392339+ /* take the return value to make compiler happy - it will fail anyway */23402340+ ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL);23412341+23422342+ mutex_unlock(&priv->mutex);23432343+23442344+ iwlwifi_mod_params.restart_fw = restart_fw;23452345+23462346+ return count;23472347+}23482348+23272349DEBUGFS_READ_FILE_OPS(ucode_rx_stats);23282350DEBUGFS_READ_FILE_OPS(ucode_tx_stats);23292351DEBUGFS_READ_FILE_OPS(ucode_general_stats);···23652343DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);23662344DEBUGFS_READ_FILE_OPS(reply_tx_error);23672345DEBUGFS_WRITE_FILE_OPS(echo_test);23462346+DEBUGFS_WRITE_FILE_OPS(fw_restart);23682347#ifdef CONFIG_IWLWIFI_DEBUG23692348DEBUGFS_READ_WRITE_FILE_OPS(log_event);23702349#endif···24232400 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);24242401 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);24252402 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);24032403+ DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR);24262404#ifdef CONFIG_IWLWIFI_DEBUG24272405 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR);24282406#endif
+1-1
drivers/net/wireless/iwlwifi/dvm/lib.c
···1919 * USA2020 *2121 * The full GNU General Public License is included in this distribution2222- * in the file called LICENSE.GPL.2222+ * in the file called COPYING.2323 *2424 * Contact Information:2525 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/dvm/scan.c
···1919 * USA2020 *2121 * The full GNU General Public License is included in this distribution2222- * in the file called LICENSE.GPL.2222+ * in the file called COPYING.2323 *2424 * Contact Information:2525 * Intel Linux Wireless <ilw@linux.intel.com>
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/dvm/tx.c
···1919 * USA2020 *2121 * The full GNU General Public License is included in this distribution2222- * in the file called LICENSE.GPL.2222+ * in the file called COPYING.2323 *2424 * Contact Information:2525 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/dvm/ucode.c
···1919 * USA2020 *2121 * The full GNU General Public License is included in this distribution2222- * in the file called LICENSE.GPL.2222+ * in the file called COPYING.2323 *2424 * Contact Information:2525 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-agn-hw.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+7-6
drivers/net/wireless/iwlwifi/iwl-debug.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6666#include <linux/device.h>6767#include <linux/interrupt.h>6868#include <linux/export.h>6969+#include "iwl-drv.h"6970#include "iwl-debug.h"7071#include "iwl-devtrace.h"7172···8685}87868887__iwl_fn(warn)8989-EXPORT_SYMBOL_GPL(__iwl_warn);8888+IWL_EXPORT_SYMBOL(__iwl_warn);9089__iwl_fn(info)9191-EXPORT_SYMBOL_GPL(__iwl_info);9090+IWL_EXPORT_SYMBOL(__iwl_info);9291__iwl_fn(crit)9393-EXPORT_SYMBOL_GPL(__iwl_crit);9292+IWL_EXPORT_SYMBOL(__iwl_crit);94939594void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,9695 const char *fmt, ...)···111110 trace_iwlwifi_err(&vaf);112111 va_end(args);113112}114114-EXPORT_SYMBOL_GPL(__iwl_err);113113+IWL_EXPORT_SYMBOL(__iwl_err);115114116115#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)117116void __iwl_dbg(struct device *dev,···134133 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);135134 va_end(args);136135}137137-EXPORT_SYMBOL_GPL(__iwl_dbg);136136+IWL_EXPORT_SYMBOL(__iwl_dbg);138137#endif
+6-8
drivers/net/wireless/iwlwifi/iwl-devtrace.h
···298298 MAX_MSG_LEN, vaf->fmt,299299 *vaf->va) >= MAX_MSG_LEN);300300 ),301301- TP_printk("%s", (char *)__get_dynamic_array(msg))301301+ TP_printk("%s", __get_str(msg))302302);303303304304#undef TRACE_SYSTEM···349349TRACE_EVENT(iwlwifi_dev_hcmd,350350 TP_PROTO(const struct device *dev,351351 struct iwl_host_cmd *cmd, u16 total_size,352352- const void *hdr, size_t hdr_len),353353- TP_ARGS(dev, cmd, total_size, hdr, hdr_len),352352+ struct iwl_cmd_header *hdr),353353+ TP_ARGS(dev, cmd, total_size, hdr),354354 TP_STRUCT__entry(355355 DEV_ENTRY356356 __dynamic_array(u8, hcmd, total_size)357357 __field(u32, flags)358358 ),359359 TP_fast_assign(360360- int i, offset = hdr_len;360360+ int i, offset = sizeof(*hdr);361361362362 DEV_ASSIGN;363363 __entry->flags = cmd->flags;364364- memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);364364+ memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));365365366366- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {366366+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {367367 if (!cmd->len[i])368368- continue;369369- if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))370368 continue;371369 memcpy((u8 *)__get_dynamic_array(hcmd) + offset,372370 cmd->data[i], cmd->len[i]);
+8-9
drivers/net/wireless/iwlwifi/iwl-drv.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···1102110211031103/* shared module parameters */11041104struct iwl_mod_params iwlwifi_mod_params = {11051105- .amsdu_size_8K = 1,11061106- .restart_fw = 1,11051105+ .restart_fw = true,11071106 .plcp_check = true,11081107 .bt_coex_active = true,11091108 .power_level = IWL_POWER_INDEX_1,···11111112 .wd_disable = true,11121113 /* the rest are 0 by default */11131114};11141114-EXPORT_SYMBOL_GPL(iwlwifi_mod_params);11151115+IWL_EXPORT_SYMBOL(iwlwifi_mod_params);1115111611161117int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)11171118{···11351136 mutex_unlock(&iwlwifi_opmode_table_mtx);11361137 return -EIO;11371138}11381138-EXPORT_SYMBOL_GPL(iwl_opmode_register);11391139+IWL_EXPORT_SYMBOL(iwl_opmode_register);1139114011401141void iwl_opmode_deregister(const char *name)11411142{···11571158 }11581159 mutex_unlock(&iwlwifi_opmode_table_mtx);11591160}11601160-EXPORT_SYMBOL_GPL(iwl_opmode_deregister);11611161+IWL_EXPORT_SYMBOL(iwl_opmode_deregister);1161116211621163static int __init iwl_drv_init(void)11631164{···12061207 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");12071208module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,12081209 int, S_IRUGO);12091209-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");12101210-module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);12111211-MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");12101210+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");12111211+module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO);12121212+MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");1212121312131214module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,12141215 int, S_IRUGO);
+16-1
drivers/net/wireless/iwlwifi/iwl-drv.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···62626363#ifndef __iwl_drv_h__6464#define __iwl_drv_h__6565+6666+#include <linux/module.h>65676668/* for all modules */6769#define DRV_NAME "iwlwifi"···124122 * call this function and then do the bus related operations only.125123 */126124void iwl_drv_stop(struct iwl_drv *drv);125125+126126+/*127127+ * exported symbol management128128+ *129129+ * The driver can be split into multiple modules, in which case some symbols130130+ * must be exported for the sub-modules. However, if it's not split and131131+ * everything is built-in, then we can avoid that.132132+ */133133+#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR134134+#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym)135135+#else136136+#define IWL_EXPORT_SYMBOL(sym)137137+#endif127138128139#endif /* __iwl_drv_h__ */
+5-4
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6262#include <linux/types.h>6363#include <linux/slab.h>6464#include <linux/export.h>6565+#include "iwl-drv.h"6566#include "iwl-modparams.h"6667#include "iwl-eeprom-parse.h"6768···750749 }751750752751 ht_info->ht_supported = true;753753- ht_info->cap = 0;752752+ ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40;754753755754 if (iwlwifi_mod_params.amsdu_size_8K)756755 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;···910909 kfree(data);911910 return NULL;912911}913913-EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data);912912+IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);914913915914/* helper functions */916915int iwl_nvm_check_version(struct iwl_nvm_data *data,···929928 data->calib_version, trans->cfg->nvm_calib_ver);930929 return -EINVAL;931930}932932-EXPORT_SYMBOL_GPL(iwl_nvm_check_version);931931+IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
+1-1
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+3-2
drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6363#include <linux/slab.h>6464#include <linux/export.h>65656666+#include "iwl-drv.h"6667#include "iwl-debug.h"6768#include "iwl-eeprom-read.h"6869#include "iwl-io.h"···461460462461 return ret;463462}464464-EXPORT_SYMBOL_GPL(iwl_read_eeprom);463463+IWL_EXPORT_SYMBOL(iwl_read_eeprom);
+1-1
drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-fh.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-fw-file.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+3-1
drivers/net/wireless/iwlwifi/iwl-fw.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···7373 * treats good CRC threshold as a boolean7474 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).7575 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.7676+ * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS7677 */7778enum iwl_ucode_tlv_flag {7879 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),7980 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),8081 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),8182 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),8383+ IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),8284};83858486/* The default calibrate table size if not specified by firmware file */
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···9191 * @sw_crypto: using hardware encryption, default = 09292 * @disable_11n: disable 11n capabilities, default = 0,9393 * use IWL_DISABLE_HT_* constants9494- * @amsdu_size_8K: enable 8K amsdu size, default = 19494+ * @amsdu_size_8K: enable 8K amsdu size, default = 09595 * @restart_fw: restart firmware, default = 19696 * @plcp_check: enable plcp health check, default = true9797 * @wd_disable: enable stuck queue check, default = 0···109109 int sw_crypto;110110 unsigned int disable_11n;111111 int amsdu_size_8K;112112- int restart_fw;112112+ bool restart_fw;113113 bool plcp_check;114114 int wd_disable;115115 bool bt_coex_active;
+8-7
drivers/net/wireless/iwlwifi/iwl-notif-wait.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6363#include <linux/sched.h>6464#include <linux/export.h>65656666+#include "iwl-drv.h"6667#include "iwl-notif-wait.h"67686869···7372 INIT_LIST_HEAD(¬if_wait->notif_waits);7473 init_waitqueue_head(¬if_wait->notif_waitq);7574}7676-EXPORT_SYMBOL_GPL(iwl_notification_wait_init);7575+IWL_EXPORT_SYMBOL(iwl_notification_wait_init);77767877void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,7978 struct iwl_rx_packet *pkt)···118117 if (triggered)119118 wake_up_all(¬if_wait->notif_waitq);120119}121121-EXPORT_SYMBOL_GPL(iwl_notification_wait_notify);120120+IWL_EXPORT_SYMBOL(iwl_notification_wait_notify);122121123122void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)124123{···131130132131 wake_up_all(¬if_wait->notif_waitq);133132}134134-EXPORT_SYMBOL_GPL(iwl_abort_notification_waits);133133+IWL_EXPORT_SYMBOL(iwl_abort_notification_waits);135134136135void137136iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,···155154 list_add(&wait_entry->list, ¬if_wait->notif_waits);156155 spin_unlock_bh(¬if_wait->notif_wait_lock);157156}158158-EXPORT_SYMBOL_GPL(iwl_init_notification_wait);157157+IWL_EXPORT_SYMBOL(iwl_init_notification_wait);159158160159int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,161160 struct iwl_notification_wait *wait_entry,···179178 return -ETIMEDOUT;180179 return 0;181180}182182-EXPORT_SYMBOL_GPL(iwl_wait_notification);181181+IWL_EXPORT_SYMBOL(iwl_wait_notification);183182184183void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,185184 struct iwl_notification_wait *wait_entry)···188187 list_del(&wait_entry->list);189188 spin_unlock_bh(¬if_wait->notif_wait_lock);190189}191191-EXPORT_SYMBOL_GPL(iwl_remove_notification);190190+IWL_EXPORT_SYMBOL(iwl_remove_notification);
+1-1
drivers/net/wireless/iwlwifi/iwl-notif-wait.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+49-2
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6262#include <linux/types.h>6363#include <linux/slab.h>6464#include <linux/export.h>6565+#include "iwl-drv.h"6566#include "iwl-modparams.h"6667#include "iwl-nvm-parse.h"6768···150149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate151150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)152151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)152152+ * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)153153+ * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)153154 */154155enum iwl_nvm_channel_flags {155156 NVM_CHANNEL_VALID = BIT(0),···161158 NVM_CHANNEL_DFS = BIT(7),162159 NVM_CHANNEL_WIDE = BIT(8),163160 NVM_CHANNEL_40MHZ = BIT(9),161161+ NVM_CHANNEL_80MHZ = BIT(10),162162+ NVM_CHANNEL_160MHZ = BIT(11),164163};165164166165#define CHECK_AND_PRINT_I(x) \···215210 else216211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;217212 }213213+ if (!(ch_flags & NVM_CHANNEL_80MHZ))214214+ channel->flags |= IEEE80211_CHAN_NO_80MHZ;215215+ if (!(ch_flags & NVM_CHANNEL_160MHZ))216216+ channel->flags |= IEEE80211_CHAN_NO_160MHZ;218217219218 if (!(ch_flags & NVM_CHANNEL_IBSS))220219 channel->flags |= IEEE80211_CHAN_NO_IBSS;···254245 return n_channels;255246}256247248248+static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,249249+ struct iwl_nvm_data *data,250250+ struct ieee80211_sta_vht_cap *vht_cap)251251+{252252+ /* For now, assume new devices with NVM are VHT capable */253253+254254+ vht_cap->vht_supported = true;255255+256256+ vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |257257+ IEEE80211_VHT_CAP_RXSTBC_1 |258258+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |259259+ 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;260260+261261+ if (iwlwifi_mod_params.amsdu_size_8K)262262+ vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;263263+264264+ vht_cap->vht_mcs.rx_mcs_map =265265+ cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |266266+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |267267+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |268268+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |269269+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |270270+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |271271+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |272272+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);273273+274274+ if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {275275+ vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |276276+ IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;277277+ /* this works because NOT_SUPPORTED == 3 */278278+ vht_cap->vht_mcs.rx_mcs_map |=279279+ cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);280280+ }281281+282282+ vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;283283+}284284+257285static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,258286 struct iwl_nvm_data *data, const __le16 *nvm_sw)259287{···314268 n_used += iwl_init_sband_channels(data, sband, n_channels,315269 IEEE80211_BAND_5GHZ);316270 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);271271+ iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);317272318273 if (n_channels != n_used)319274 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",···390343391344 return data;392345}393393-EXPORT_SYMBOL_GPL(iwl_parse_nvm_data);346346+IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
+1-1
drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-op-mode.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+6-21
drivers/net/wireless/iwlwifi/iwl-phy-db.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6565#include <linux/string.h>6666#include <linux/export.h>67676868+#include "iwl-drv.h"6869#include "iwl-phy-db.h"6970#include "iwl-debug.h"7071#include "iwl-op-mode.h"···137136 u8 data[];138137} __packed;139138140140-#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)141141-static inline void iwl_phy_db_test_pic(__le32 pic)142142-{143143- WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);144144-}145145-146139struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)147140{148141 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),···150155 /* TODO: add default values of the phy db. */151156 return phy_db;152157}153153-EXPORT_SYMBOL(iwl_phy_db_init);158158+IWL_EXPORT_SYMBOL(iwl_phy_db_init);154159155160/*156161 * get phy db section: returns a pointer to a phy db section specified by···216221217222 kfree(phy_db);218223}219219-EXPORT_SYMBOL(iwl_phy_db_free);224224+IWL_EXPORT_SYMBOL(iwl_phy_db_free);220225221226int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,222227 gfp_t alloc_ctx)···255260 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;256261 }257262258258- /* Test PIC */259259- if (type != IWL_PHY_DB_CFG)260260- iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +261261- (size / sizeof(__le32)) - 1));262262-263263 IWL_DEBUG_INFO(phy_db->trans,264264 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",265265 __func__, __LINE__, type, size);266266267267 return 0;268268}269269-EXPORT_SYMBOL(iwl_phy_db_set_section);269269+IWL_EXPORT_SYMBOL(iwl_phy_db_set_section);270270271271static int is_valid_channel(u16 ch_id)272272{···361371 *data = entry->data;362372 *size = entry->size;363373 }364364-365365- /* Test PIC */366366- if (type != IWL_PHY_DB_CFG)367367- iwl_phy_db_test_pic(*(((__le32 *)*data) +368368- (*size / sizeof(__le32)) - 1));369374370375 IWL_DEBUG_INFO(phy_db->trans,371376 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",···496511 "Finished sending phy db non channel data\n");497512 return 0;498513}499499-EXPORT_SYMBOL(iwl_send_phy_db_data);514514+IWL_EXPORT_SYMBOL(iwl_send_phy_db_data);
+1-1
drivers/net/wireless/iwlwifi/iwl-phy-db.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-prph.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+6-5
drivers/net/wireless/iwlwifi/iwl-test.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6464#include <linux/export.h>6565#include <net/netlink.h>66666767+#include "iwl-drv.h"6768#include "iwl-io.h"6869#include "iwl-fh.h"6970#include "iwl-prph.h"···654653 }655654 return 0;656655}657657-EXPORT_SYMBOL_GPL(iwl_test_parse);656656+IWL_EXPORT_SYMBOL(iwl_test_parse);658657659658/*660659 * Handle test commands.···716715 }717716 return result;718717}719719-EXPORT_SYMBOL_GPL(iwl_test_handle_cmd);718718+IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);720719721720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,722721 struct netlink_callback *cb)···804803 }805804 return result;806805}807807-EXPORT_SYMBOL_GPL(iwl_test_dump);806806+IWL_EXPORT_SYMBOL(iwl_test_dump);808807809808/*810809 * Multicast a spontaneous messages from the device to the user space.···850849 if (tst->notify)851850 iwl_test_send_rx(tst, rxb);852851}853853-EXPORT_SYMBOL_GPL(iwl_test_rx);852852+IWL_EXPORT_SYMBOL(iwl_test_rx);
+1-1
drivers/net/wireless/iwlwifi/iwl-test.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/iwl-testmode.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+10-12
drivers/net/wireless/iwlwifi/iwl-trans.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···183183 * @CMD_ASYNC: Return right away and don't want for the response184184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the185185 * response. The caller needs to call iwl_free_resp when done.186186- * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the187187- * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be188188- * copied. The pointer passed to the response handler is in the transport189189- * ownership and don't need to be freed by the op_mode. This also means190190- * that the pointer is invalidated after the op_mode's handler returns.191186 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.192187 */193188enum CMD_MODE {194189 CMD_SYNC = 0,195190 CMD_ASYNC = BIT(0),196191 CMD_WANT_SKB = BIT(1),197197- CMD_WANT_HCMD = BIT(2),198198- CMD_ON_DEMAND = BIT(3),192192+ CMD_ON_DEMAND = BIT(2),199193};200194201195#define DEF_CMD_PAYLOAD_SIZE 320···208214209215#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))210216211211-#define IWL_MAX_CMD_TFDS 2217217+/*218218+ * number of transfer buffers (fragments) per transmit frame descriptor;219219+ * this is just the driver's idea, the hardware supports 20220220+ */221221+#define IWL_MAX_CMD_TBS_PER_TFD 2212222213223/**214224 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command···249251 * @id: id of the host command250252 */251253struct iwl_host_cmd {252252- const void *data[IWL_MAX_CMD_TFDS];254254+ const void *data[IWL_MAX_CMD_TBS_PER_TFD];253255 struct iwl_rx_packet *resp_pkt;254256 unsigned long _rx_page_addr;255257 u32 _rx_page_order;256258 int handler_status;257259258260 u32 flags;259259- u16 len[IWL_MAX_CMD_TFDS];260260- u8 dataflags[IWL_MAX_CMD_TFDS];261261+ u16 len[IWL_MAX_CMD_TBS_PER_TFD];262262+ u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];261263 u8 id;262264};263265
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+347
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
···11+/******************************************************************************22+ *33+ * This file is provided under a dual BSD/GPLv2 license. When using or44+ * redistributing this file, you may do so under either license.55+ *66+ * GPL LICENSE SUMMARY77+ *88+ * Copyright(c) 2013 Intel Corporation. All rights reserved.99+ *1010+ * This program is free software; you can redistribute it and/or modify1111+ * it under the terms of version 2 of the GNU General Public License as1212+ * published by the Free Software Foundation.1313+ *1414+ * This program is distributed in the hope that it will be useful, but1515+ * WITHOUT ANY WARRANTY; without even the implied warranty of1616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1717+ * General Public License for more details.1818+ *1919+ * You should have received a copy of the GNU General Public License2020+ * along with this program; if not, write to the Free Software2121+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,2222+ * USA2323+ *2424+ * The full GNU General Public License is included in this distribution2525+ * in the file called COPYING.2626+ *2727+ * Contact Information:2828+ * Intel Linux Wireless <ilw@linux.intel.com>2929+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64973030+ *3131+ * BSD LICENSE3232+ *3333+ * Copyright(c) 2013 Intel Corporation. All rights reserved.3434+ * All rights reserved.3535+ *3636+ * Redistribution and use in source and binary forms, with or without3737+ * modification, are permitted provided that the following conditions3838+ * are met:3939+ *4040+ * * Redistributions of source code must retain the above copyright4141+ * notice, this list of conditions and the following disclaimer.4242+ * * Redistributions in binary form must reproduce the above copyright4343+ * notice, this list of conditions and the following disclaimer in4444+ * the documentation and/or other materials provided with the4545+ * distribution.4646+ * * Neither the name Intel Corporation nor the names of its4747+ * contributors may be used to endorse or promote products derived4848+ * from this software without specific prior written permission.4949+ *5050+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS5151+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT5252+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR5353+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT5454+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,5555+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT5656+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,5757+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY5858+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT5959+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE6060+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.6161+ *6262+ *****************************************************************************/6363+6464+#include "fw-api-bt-coex.h"6565+#include "iwl-modparams.h"6666+#include "mvm.h"6767+#include "iwl-debug.h"6868+6969+#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \7070+ [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \7171+ ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))7272+7373+static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {7474+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,7575+ BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),7676+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,7777+ BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),7878+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,7979+ BT_COEX_PRIO_TBL_PRIO_LOW, 0),8080+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,8181+ BT_COEX_PRIO_TBL_PRIO_LOW, 1),8282+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,8383+ BT_COEX_PRIO_TBL_PRIO_HIGH, 0),8484+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,8585+ BT_COEX_PRIO_TBL_PRIO_HIGH, 1),8686+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,8787+ BT_COEX_PRIO_TBL_DISABLED, 0),8888+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,8989+ BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),9090+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,9191+ BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),9292+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,9393+ BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),9494+ 0, 0, 0, 0, 0, 0,9595+};9696+9797+#undef EVENT_PRIO_ANT9898+9999+int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)100100+{101101+ return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,102102+ sizeof(struct iwl_bt_coex_prio_tbl_cmd),103103+ &iwl_bt_prio_tbl);104104+}105105+106106+static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type)107107+{108108+ struct iwl_bt_coex_prot_env_cmd env_cmd;109109+ int ret;110110+111111+ env_cmd.action = action;112112+ env_cmd.type = type;113113+ ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,114114+ sizeof(env_cmd), &env_cmd);115115+ if (ret)116116+ IWL_ERR(mvm, "failed to send BT env command\n");117117+ return ret;118118+}119119+120120+enum iwl_bt_kill_msk {121121+ BT_KILL_MSK_DEFAULT,122122+ BT_KILL_MSK_SCO_HID_A2DP,123123+ BT_KILL_MSK_REDUCED_TXPOW,124124+ BT_KILL_MSK_MAX,125125+};126126+127127+static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {128128+ 0xffffffff,129129+ 0xfffffc00,130130+ 0,131131+};132132+133133+static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {134134+ 0xffffffff,135135+ 0xfffffc00,136136+ 0,137137+};138138+139139+#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)140140+141141+/* Tight Coex */142142+static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {143143+ cpu_to_le32(0xaaaaaaaa),144144+ cpu_to_le32(0xaaaaaaaa),145145+ cpu_to_le32(0xaeaaaaaa),146146+ cpu_to_le32(0xaaaaaaaa),147147+ cpu_to_le32(0xcc00ff28),148148+ cpu_to_le32(0x0000aaaa),149149+ cpu_to_le32(0xcc00aaaa),150150+ cpu_to_le32(0x0000aaaa),151151+ cpu_to_le32(0xc0004000),152152+ cpu_to_le32(0x00000000),153153+ cpu_to_le32(0xf0005000),154154+ cpu_to_le32(0xf0005000),155155+};156156+157157+/* Loose Coex */158158+static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {159159+ cpu_to_le32(0xaaaaaaaa),160160+ cpu_to_le32(0xaaaaaaaa),161161+ cpu_to_le32(0xaeaaaaaa),162162+ cpu_to_le32(0xaaaaaaaa),163163+ cpu_to_le32(0xcc00ff28),164164+ cpu_to_le32(0x0000aaaa),165165+ cpu_to_le32(0xcc00aaaa),166166+ cpu_to_le32(0x0000aaaa),167167+ cpu_to_le32(0x00000000),168168+ cpu_to_le32(0x00000000),169169+ cpu_to_le32(0xf0005000),170170+ cpu_to_le32(0xf0005000),171171+};172172+173173+/* Full concurrency */174174+static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {175175+ cpu_to_le32(0xaaaaaaaa),176176+ cpu_to_le32(0xaaaaaaaa),177177+ cpu_to_le32(0xaaaaaaaa),178178+ cpu_to_le32(0xaaaaaaaa),179179+ cpu_to_le32(0xaaaaaaaa),180180+ cpu_to_le32(0xaaaaaaaa),181181+ cpu_to_le32(0xaaaaaaaa),182182+ cpu_to_le32(0xaaaaaaaa),183183+ cpu_to_le32(0x00000000),184184+ cpu_to_le32(0x00000000),185185+ cpu_to_le32(0x00000000),186186+ cpu_to_le32(0x00000000),187187+};188188+189189+/* BT Antenna Coupling Threshold (dB) */190190+#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)191191+192192+int iwl_send_bt_init_conf(struct iwl_mvm *mvm)193193+{194194+ struct iwl_bt_coex_cmd cmd = {195195+ .max_kill = 5,196196+ .bt3_time_t7_value = 1,197197+ .bt3_prio_sample_time = 2,198198+ .bt3_timer_t2_value = 0xc,199199+ };200200+ int ret;201201+202202+ cmd.flags = iwlwifi_mod_params.bt_coex_active ?203203+ BT_COEX_NW : BT_COEX_DISABLE;204204+ cmd.flags |= iwlwifi_mod_params.bt_ch_announce ?205205+ BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0;206206+ cmd.flags |= BT_SYNC_2_BT_DISABLE;207207+208208+ cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |209209+ BT_VALID_BT_PRIO_BOOST |210210+ BT_VALID_MAX_KILL |211211+ BT_VALID_3W_TMRS |212212+ BT_VALID_KILL_ACK |213213+ BT_VALID_KILL_CTS |214214+ BT_VALID_REDUCED_TX_POWER |215215+ BT_VALID_LUT);216216+217217+ if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD)218218+ memcpy(&cmd.decision_lut, iwl_loose_lookup,219219+ sizeof(iwl_tight_lookup));220220+ else221221+ memcpy(&cmd.decision_lut, iwl_tight_lookup,222222+ sizeof(iwl_tight_lookup));223223+224224+ cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);225225+ cmd.kill_ack_msk =226226+ cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);227227+ cmd.kill_cts_msk =228228+ cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);229229+230230+ /* go to CALIB state in internal BT-Coex state machine */231231+ ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,232232+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);233233+ if (ret)234234+ return ret;235235+236236+ ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,237237+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);238238+ if (ret)239239+ return ret;240240+241241+ return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,242242+ sizeof(cmd), &cmd);243243+}244244+245245+struct iwl_bt_notif_iterator_data {246246+ struct iwl_mvm *mvm;247247+ struct iwl_bt_coex_profile_notif *notif;248248+};249249+250250+static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,251251+ struct ieee80211_vif *vif)252252+{253253+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);254254+ struct iwl_bt_notif_iterator_data *data = _data;255255+ struct ieee80211_chanctx_conf *chanctx_conf;256256+ enum ieee80211_smps_mode smps_mode;257257+ enum ieee80211_band band;258258+259259+ if (vif->type != NL80211_IFTYPE_STATION)260260+ return;261261+262262+ rcu_read_lock();263263+ chanctx_conf = rcu_dereference(vif->chanctx_conf);264264+ if (chanctx_conf && chanctx_conf->def.chan)265265+ band = chanctx_conf->def.chan->band;266266+ else267267+ band = -1;268268+ rcu_read_unlock();269269+270270+ if (band != IEEE80211_BAND_2GHZ)271271+ return;272272+273273+ smps_mode = IEEE80211_SMPS_AUTOMATIC;274274+275275+ if (data->notif->bt_status)276276+ smps_mode = IEEE80211_SMPS_DYNAMIC;277277+278278+ if (data->notif->bt_traffic_load)279279+ smps_mode = IEEE80211_SMPS_STATIC;280280+281281+ IWL_DEBUG_COEX(data->mvm,282282+ "mac %d: bt_status %d traffic_load %d smps_req %d\n",283283+ mvmvif->id, data->notif->bt_status,284284+ data->notif->bt_traffic_load, smps_mode);285285+286286+ ieee80211_request_smps(vif, smps_mode);287287+}288288+289289+int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,290290+ struct iwl_rx_cmd_buffer *rxb,291291+ struct iwl_device_cmd *dev_cmd)292292+{293293+ struct iwl_rx_packet *pkt = rxb_addr(rxb);294294+ struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;295295+ struct iwl_bt_notif_iterator_data data = {296296+ .mvm = mvm,297297+ .notif = notif,298298+ };299299+ struct iwl_bt_coex_cmd cmd = {};300300+ enum iwl_bt_kill_msk bt_kill_msk;301301+302302+ IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");303303+ IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");304304+ IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);305305+ IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);306306+ IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",307307+ notif->bt_agg_traffic_load);308308+ IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);309309+310310+ /* remember this notification for future use: rssi fluctuations */311311+ memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));312312+313313+ ieee80211_iterate_active_interfaces_atomic(314314+ mvm->hw, IEEE80211_IFACE_ITER_NORMAL,315315+ iwl_mvm_bt_notif_iterator, &data);316316+317317+ /* Low latency BT profile is active: give higher prio to BT */318318+ if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||319319+ BT_MBOX_MSG(notif, 3, A2DP_STATE) ||320320+ BT_MBOX_MSG(notif, 3, SNIFF_STATE))321321+ bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;322322+ else323323+ bt_kill_msk = BT_KILL_MSK_DEFAULT;324324+325325+ /* Don't send HCMD if there is no update */326326+ if (bt_kill_msk == mvm->bt_kill_msk)327327+ return 0;328328+329329+ IWL_DEBUG_COEX(mvm,330330+ "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n",331331+ bt_kill_msk,332332+ BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",333333+ BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",334334+ BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");335335+336336+ mvm->bt_kill_msk = bt_kill_msk;337337+ cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);338338+ cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);339339+340340+ cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);341341+342342+ if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd))343343+ IWL_ERR(mvm, "Failed to sent BT Coex CMD\n");344344+345345+ /* This handler is ASYNC */346346+ return 0;347347+}
+336-28
drivers/net/wireless/iwlwifi/mvm/d3.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6161 *6262 *****************************************************************************/63636464+#include <linux/etherdevice.h>6565+#include <linux/ip.h>6466#include <net/cfg80211.h>6567#include <net/ipv6.h>6868+#include <net/tcp.h>6669#include "iwl-modparams.h"6770#include "fw-api.h"6871#include "mvm.h"···195192 sizeof(wkc), &wkc);196193 data->error = ret != 0;197194195195+ mvm->ptk_ivlen = key->iv_len;196196+ mvm->ptk_icvlen = key->icv_len;197197+ mvm->gtk_ivlen = key->iv_len;198198+ mvm->gtk_icvlen = key->icv_len;199199+198200 /* don't upload key again */199201 goto out_unlock;200202 }···312304 */313305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {314306 key->hw_key_idx = 0;307307+ mvm->ptk_ivlen = key->iv_len;308308+ mvm->ptk_icvlen = key->icv_len;315309 } else {316310 data->gtk_key_idx++;317311 key->hw_key_idx = data->gtk_key_idx;312312+ mvm->gtk_ivlen = key->iv_len;313313+ mvm->gtk_icvlen = key->icv_len;318314 }319315320316 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);···402390403391 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC,404392 sizeof(cmd), &cmd);393393+}394394+395395+enum iwl_mvm_tcp_packet_type {396396+ MVM_TCP_TX_SYN,397397+ MVM_TCP_RX_SYNACK,398398+ MVM_TCP_TX_DATA,399399+ MVM_TCP_RX_ACK,400400+ MVM_TCP_RX_WAKE,401401+ MVM_TCP_TX_FIN,402402+};403403+404404+static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr)405405+{406406+ __sum16 check = tcp_v4_check(len, saddr, daddr, 0);407407+ return cpu_to_le16(be16_to_cpu((__force __be16)check));408408+}409409+410410+static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm,411411+ struct ieee80211_vif *vif,412412+ struct cfg80211_wowlan_tcp *tcp,413413+ void *_pkt, u8 *mask,414414+ __le16 *pseudo_hdr_csum,415415+ enum iwl_mvm_tcp_packet_type ptype)416416+{417417+ struct {418418+ struct ethhdr eth;419419+ struct iphdr ip;420420+ struct tcphdr tcp;421421+ u8 data[];422422+ } __packed *pkt = _pkt;423423+ u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);424424+ int i;425425+426426+ pkt->eth.h_proto = cpu_to_be16(ETH_P_IP),427427+ pkt->ip.version = 4;428428+ pkt->ip.ihl = 5;429429+ pkt->ip.protocol = IPPROTO_TCP;430430+431431+ switch (ptype) {432432+ case MVM_TCP_TX_SYN:433433+ case MVM_TCP_TX_DATA:434434+ case MVM_TCP_TX_FIN:435435+ memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN);436436+ memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN);437437+ pkt->ip.ttl = 128;438438+ pkt->ip.saddr = tcp->src;439439+ pkt->ip.daddr = tcp->dst;440440+ pkt->tcp.source = cpu_to_be16(tcp->src_port);441441+ pkt->tcp.dest = cpu_to_be16(tcp->dst_port);442442+ /* overwritten for TX SYN later */443443+ pkt->tcp.doff = sizeof(struct tcphdr) / 4;444444+ pkt->tcp.window = cpu_to_be16(65000);445445+ break;446446+ case MVM_TCP_RX_SYNACK:447447+ case MVM_TCP_RX_ACK:448448+ case MVM_TCP_RX_WAKE:449449+ memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN);450450+ memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN);451451+ pkt->ip.saddr = tcp->dst;452452+ pkt->ip.daddr = tcp->src;453453+ pkt->tcp.source = cpu_to_be16(tcp->dst_port);454454+ pkt->tcp.dest = cpu_to_be16(tcp->src_port);455455+ break;456456+ default:457457+ WARN_ON(1);458458+ return;459459+ }460460+461461+ switch (ptype) {462462+ case MVM_TCP_TX_SYN:463463+ /* firmware assumes 8 option bytes - 8 NOPs for now */464464+ memset(pkt->data, 0x01, 8);465465+ ip_tot_len += 8;466466+ pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4;467467+ pkt->tcp.syn = 1;468468+ break;469469+ case MVM_TCP_TX_DATA:470470+ ip_tot_len += tcp->payload_len;471471+ memcpy(pkt->data, tcp->payload, tcp->payload_len);472472+ pkt->tcp.psh = 1;473473+ pkt->tcp.ack = 1;474474+ break;475475+ case MVM_TCP_TX_FIN:476476+ pkt->tcp.fin = 1;477477+ pkt->tcp.ack = 1;478478+ break;479479+ case MVM_TCP_RX_SYNACK:480480+ pkt->tcp.syn = 1;481481+ pkt->tcp.ack = 1;482482+ break;483483+ case MVM_TCP_RX_ACK:484484+ pkt->tcp.ack = 1;485485+ break;486486+ case MVM_TCP_RX_WAKE:487487+ ip_tot_len += tcp->wake_len;488488+ pkt->tcp.psh = 1;489489+ pkt->tcp.ack = 1;490490+ memcpy(pkt->data, tcp->wake_data, tcp->wake_len);491491+ break;492492+ }493493+494494+ switch (ptype) {495495+ case MVM_TCP_TX_SYN:496496+ case MVM_TCP_TX_DATA:497497+ case MVM_TCP_TX_FIN:498498+ pkt->ip.tot_len = cpu_to_be16(ip_tot_len);499499+ pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl);500500+ break;501501+ case MVM_TCP_RX_WAKE:502502+ for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) {503503+ u8 tmp = tcp->wake_mask[i];504504+ mask[i + 6] |= tmp << 6;505505+ if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8))506506+ mask[i + 7] = tmp >> 2;507507+ }508508+ /* fall through for ethernet/IP/TCP headers mask */509509+ case MVM_TCP_RX_SYNACK:510510+ case MVM_TCP_RX_ACK:511511+ mask[0] = 0xff; /* match ethernet */512512+ /*513513+ * match ethernet, ip.version, ip.ihl514514+ * the ip.ihl half byte is really masked out by firmware515515+ */516516+ mask[1] = 0x7f;517517+ mask[2] = 0x80; /* match ip.protocol */518518+ mask[3] = 0xfc; /* match ip.saddr, ip.daddr */519519+ mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */520520+ mask[5] = 0x80; /* match tcp flags */521521+ /* leave rest (0 or set for MVM_TCP_RX_WAKE) */522522+ break;523523+ };524524+525525+ *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr),526526+ pkt->ip.saddr, pkt->ip.daddr);527527+}528528+529529+static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm,530530+ struct ieee80211_vif *vif,531531+ struct cfg80211_wowlan_tcp *tcp)532532+{533533+ struct iwl_wowlan_remote_wake_config *cfg;534534+ struct iwl_host_cmd cmd = {535535+ .id = REMOTE_WAKE_CONFIG_CMD,536536+ .len = { sizeof(*cfg), },537537+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },538538+ .flags = CMD_SYNC,539539+ };540540+ int ret;541541+542542+ if (!tcp)543543+ return 0;544544+545545+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);546546+ if (!cfg)547547+ return -ENOMEM;548548+ cmd.data[0] = cfg;549549+550550+ cfg->max_syn_retries = 10;551551+ cfg->max_data_retries = 10;552552+ cfg->tcp_syn_ack_timeout = 1; /* seconds */553553+ cfg->tcp_ack_timeout = 1; /* seconds */554554+555555+ /* SYN (TX) */556556+ iwl_mvm_build_tcp_packet(557557+ mvm, vif, tcp, cfg->syn_tx.data, NULL,558558+ &cfg->syn_tx.info.tcp_pseudo_header_checksum,559559+ MVM_TCP_TX_SYN);560560+ cfg->syn_tx.info.tcp_payload_length = 0;561561+562562+ /* SYN/ACK (RX) */563563+ iwl_mvm_build_tcp_packet(564564+ mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,565565+ &cfg->synack_rx.info.tcp_pseudo_header_checksum,566566+ MVM_TCP_RX_SYNACK);567567+ cfg->synack_rx.info.tcp_payload_length = 0;568568+569569+ /* KEEPALIVE/ACK (TX) */570570+ iwl_mvm_build_tcp_packet(571571+ mvm, vif, tcp, cfg->keepalive_tx.data, NULL,572572+ &cfg->keepalive_tx.info.tcp_pseudo_header_checksum,573573+ MVM_TCP_TX_DATA);574574+ cfg->keepalive_tx.info.tcp_payload_length =575575+ cpu_to_le16(tcp->payload_len);576576+ cfg->sequence_number_offset = tcp->payload_seq.offset;577577+ /* length must be 0..4, the field is little endian */578578+ cfg->sequence_number_length = tcp->payload_seq.len;579579+ cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start);580580+ cfg->keepalive_interval = cpu_to_le16(tcp->data_interval);581581+ if (tcp->payload_tok.len) {582582+ cfg->token_offset = tcp->payload_tok.offset;583583+ cfg->token_length = tcp->payload_tok.len;584584+ cfg->num_tokens =585585+ cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len);586586+ memcpy(cfg->tokens, tcp->payload_tok.token_stream,587587+ tcp->tokens_size);588588+ } else {589589+ /* set tokens to max value to almost never run out */590590+ cfg->num_tokens = cpu_to_le16(65535);591591+ }592592+593593+ /* ACK (RX) */594594+ iwl_mvm_build_tcp_packet(595595+ mvm, vif, tcp, cfg->keepalive_ack_rx.data,596596+ cfg->keepalive_ack_rx.rx_mask,597597+ &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,598598+ MVM_TCP_RX_ACK);599599+ cfg->keepalive_ack_rx.info.tcp_payload_length = 0;600600+601601+ /* WAKEUP (RX) */602602+ iwl_mvm_build_tcp_packet(603603+ mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,604604+ &cfg->wake_rx.info.tcp_pseudo_header_checksum,605605+ MVM_TCP_RX_WAKE);606606+ cfg->wake_rx.info.tcp_payload_length =607607+ cpu_to_le16(tcp->wake_len);608608+609609+ /* FIN */610610+ iwl_mvm_build_tcp_packet(611611+ mvm, vif, tcp, cfg->fin_tx.data, NULL,612612+ &cfg->fin_tx.info.tcp_pseudo_header_checksum,613613+ MVM_TCP_TX_FIN);614614+ cfg->fin_tx.info.tcp_payload_length = 0;615615+616616+ ret = iwl_mvm_send_cmd(mvm, &cmd);617617+ kfree(cfg);618618+619619+ return ret;405620}406621407622struct iwl_d3_iter_data {···869630 d3_cfg_cmd.wakeup_flags |=870631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);871632633633+ if (wowlan->tcp) {634634+ /*635635+ * The firmware currently doesn't really look at these, only636636+ * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that637637+ * reason bit since losing the connection to the AP implies638638+ * losing the TCP connection.639639+ * Set the flags anyway as long as they exist, in case this640640+ * will be changed in the firmware.641641+ */642642+ wowlan_config_cmd.wakeup_filter |=643643+ cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |644644+ IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |645645+ IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |646646+ IWL_WOWLAN_WAKEUP_LINK_CHANGE);647647+ }648648+872649 iwl_mvm_cancel_scan(mvm);873650874651 iwl_trans_stop_device(mvm->trans);···903648904649 /* We reprogram keys and shouldn't allocate new key indices */905650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));651651+652652+ mvm->ptk_ivlen = 0;653653+ mvm->ptk_icvlen = 0;654654+ mvm->ptk_ivlen = 0;655655+ mvm->ptk_icvlen = 0;906656907657 /*908658 * The D3 firmware still hardcodes the AP station ID for the···1000740 if (ret)1001741 goto out;1002742743743+ ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp);744744+ if (ret)745745+ goto out;746746+1003747 /* must be last -- this switches firmware state */1004748 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,1005749 sizeof(d3_cfg_cmd), &d3_cfg_cmd);···1047783 struct iwl_wowlan_status *status;1048784 u32 reasons;1049785 int ret, len;10501050- bool pkt8023 = false;1051786 struct sk_buff *pkt = NULL;10527871053788 iwl_trans_read_mem_bytes(mvm->trans, base,···1087824 status = (void *)cmd.resp_pkt->data;10888251089826 if (len - sizeof(struct iwl_cmd_header) !=10901090- sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) {827827+ sizeof(*status) +828828+ ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {1091829 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");1092830 goto out;1093831 }···1100836 goto report;1101837 }110283811031103- if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {839839+ if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)1104840 wakeup.magic_pkt = true;11051105- pkt8023 = true;11061106- }110784111081108- if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {842842+ if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)1109843 wakeup.pattern_idx =1110844 le16_to_cpu(status->pattern_number);11111111- pkt8023 = true;11121112- }11138451114846 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |1115847 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))1116848 wakeup.disconnect = true;111784911181118- if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {850850+ if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)1119851 wakeup.gtk_rekey_failure = true;11201120- pkt8023 = true;11211121- }112285211231123- if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {853853+ if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)1124854 wakeup.rfkill_release = true;11251125- pkt8023 = true;11261126- }112785511281128- if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {856856+ if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)1129857 wakeup.eap_identity_req = true;11301130- pkt8023 = true;11311131- }113285811331133- if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {859859+ if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)1134860 wakeup.four_way_handshake = true;11351135- pkt8023 = true;11361136- }861861+862862+ if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)863863+ wakeup.tcp_connlost = true;864864+865865+ if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)866866+ wakeup.tcp_nomoretokens = true;867867+868868+ if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)869869+ wakeup.tcp_match = true;11378701138871 if (status->wake_packet_bufsize) {11391139- u32 pktsize = le32_to_cpu(status->wake_packet_bufsize);11401140- u32 pktlen = le32_to_cpu(status->wake_packet_length);872872+ int pktsize = le32_to_cpu(status->wake_packet_bufsize);873873+ int pktlen = le32_to_cpu(status->wake_packet_length);874874+ const u8 *pktdata = status->wake_packet;875875+ struct ieee80211_hdr *hdr = (void *)pktdata;876876+ int truncated = pktlen - pktsize;114187711421142- if (pkt8023) {878878+ /* this would be a firmware bug */879879+ if (WARN_ON_ONCE(truncated < 0))880880+ truncated = 0;881881+882882+ if (ieee80211_is_data(hdr->frame_control)) {883883+ int hdrlen = ieee80211_hdrlen(hdr->frame_control);884884+ int ivlen = 0, icvlen = 4; /* also FCS */885885+1143886 pkt = alloc_skb(pktsize, GFP_KERNEL);1144887 if (!pkt)1145888 goto report;11461146- memcpy(skb_put(pkt, pktsize), status->wake_packet,11471147- pktsize);889889+890890+ memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);891891+ pktdata += hdrlen;892892+ pktsize -= hdrlen;893893+894894+ if (ieee80211_has_protected(hdr->frame_control)) {895895+ if (is_multicast_ether_addr(hdr->addr1)) {896896+ ivlen = mvm->gtk_ivlen;897897+ icvlen += mvm->gtk_icvlen;898898+ } else {899899+ ivlen = mvm->ptk_ivlen;900900+ icvlen += mvm->ptk_icvlen;901901+ }902902+ }903903+904904+ /* if truncated, FCS/ICV is (partially) gone */905905+ if (truncated >= icvlen) {906906+ icvlen = 0;907907+ truncated -= icvlen;908908+ } else {909909+ icvlen -= truncated;910910+ truncated = 0;911911+ }912912+913913+ pktsize -= ivlen + icvlen;914914+ pktdata += ivlen;915915+916916+ memcpy(skb_put(pkt, pktsize), pktdata, pktsize);917917+1148918 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))1149919 goto report;1150920 wakeup.packet = pkt->data;1151921 wakeup.packet_present_len = pkt->len;11521152- wakeup.packet_len = pkt->len - (pktlen - pktsize);922922+ wakeup.packet_len = pkt->len - truncated;1153923 wakeup.packet_80211 = false;1154924 } else {925925+ int fcslen = 4;926926+927927+ if (truncated >= 4) {928928+ truncated -= 4;929929+ fcslen = 0;930930+ } else {931931+ fcslen -= truncated;932932+ truncated = 0;933933+ }934934+ pktsize -= fcslen;1155935 wakeup.packet = status->wake_packet;1156936 wakeup.packet_present_len = pktsize;11571157- wakeup.packet_len = pktlen;937937+ wakeup.packet_len = pktlen - truncated;1158938 wakeup.packet_80211 = true;1159939 }1160940 }
···11+/******************************************************************************22+ *33+ * This file is provided under a dual BSD/GPLv2 license. When using or44+ * redistributing this file, you may do so under either license.55+ *66+ * GPL LICENSE SUMMARY77+ *88+ * Copyright(c) 2013 Intel Corporation. All rights reserved.99+ *1010+ * This program is free software; you can redistribute it and/or modify1111+ * it under the terms of version 2 of the GNU General Public License as1212+ * published by the Free Software Foundation.1313+ *1414+ * This program is distributed in the hope that it will be useful, but1515+ * WITHOUT ANY WARRANTY; without even the implied warranty of1616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1717+ * General Public License for more details.1818+ *1919+ * You should have received a copy of the GNU General Public License2020+ * along with this program; if not, write to the Free Software2121+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,2222+ * USA2323+ *2424+ * The full GNU General Public License is included in this distribution2525+ * in the file called COPYING.2626+ *2727+ * Contact Information:2828+ * Intel Linux Wireless <ilw@linux.intel.com>2929+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64973030+ *3131+ * BSD LICENSE3232+ *3333+ * Copyright(c) 2013 Intel Corporation. All rights reserved.3434+ * All rights reserved.3535+ *3636+ * Redistribution and use in source and binary forms, with or without3737+ * modification, are permitted provided that the following conditions3838+ * are met:3939+ *4040+ * * Redistributions of source code must retain the above copyright4141+ * notice, this list of conditions and the following disclaimer.4242+ * * Redistributions in binary form must reproduce the above copyright4343+ * notice, this list of conditions and the following disclaimer in4444+ * the documentation and/or other materials provided with the4545+ * distribution.4646+ * * Neither the name Intel Corporation nor the names of its4747+ * contributors may be used to endorse or promote products derived4848+ * from this software without specific prior written permission.4949+ *5050+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS5151+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT5252+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR5353+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT5454+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,5555+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT5656+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,5757+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY5858+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT5959+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE6060+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.6161+ *****************************************************************************/6262+6363+#ifndef __fw_api_bt_coex_h__6464+#define __fw_api_bt_coex_h__6565+6666+#include <linux/types.h>6767+#include <linux/bitops.h>6868+6969+#define BITS(nb) (BIT(nb) - 1)7070+7171+/**7272+ * enum iwl_bt_coex_flags - flags for BT_COEX command7373+ * @BT_CH_PRIMARY_EN:7474+ * @BT_CH_SECONDARY_EN:7575+ * @BT_NOTIF_COEX_OFF:7676+ * @BT_COEX_MODE_POS:7777+ * @BT_COEX_MODE_MSK:7878+ * @BT_COEX_DISABLE:7979+ * @BT_COEX_2W:8080+ * @BT_COEX_3W:8181+ * @BT_COEX_NW:8282+ * @BT_USE_DEFAULTS:8383+ * @BT_SYNC_2_BT_DISABLE:8484+ * @BT_COEX_CORUNNING_TBL_EN:8585+ */8686+enum iwl_bt_coex_flags {8787+ BT_CH_PRIMARY_EN = BIT(0),8888+ BT_CH_SECONDARY_EN = BIT(1),8989+ BT_NOTIF_COEX_OFF = BIT(2),9090+ BT_COEX_MODE_POS = 3,9191+ BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,9292+ BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS,9393+ BT_COEX_2W = 0x1 << BT_COEX_MODE_POS,9494+ BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,9595+ BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,9696+ BT_USE_DEFAULTS = BIT(6),9797+ BT_SYNC_2_BT_DISABLE = BIT(7),9898+ /*9999+ * For future use - when the flags will be enlarged100100+ * BT_COEX_CORUNNING_TBL_EN = BIT(8),101101+ */102102+};103103+104104+/*105105+ * indicates what has changed in the BT_COEX command.106106+ */107107+enum iwl_bt_coex_valid_bit_msk {108108+ BT_VALID_ENABLE = BIT(0),109109+ BT_VALID_BT_PRIO_BOOST = BIT(1),110110+ BT_VALID_MAX_KILL = BIT(2),111111+ BT_VALID_3W_TMRS = BIT(3),112112+ BT_VALID_KILL_ACK = BIT(4),113113+ BT_VALID_KILL_CTS = BIT(5),114114+ BT_VALID_REDUCED_TX_POWER = BIT(6),115115+ BT_VALID_LUT = BIT(7),116116+ BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8),117117+ BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9),118118+ BT_VALID_MULTI_PRIO_LUT = BIT(10),119119+ BT_VALID_TRM_KICK_FILTER = BIT(11),120120+ BT_VALID_CORUN_LUT_20 = BIT(12),121121+ BT_VALID_CORUN_LUT_40 = BIT(13),122122+ BT_VALID_ANT_ISOLATION = BIT(14),123123+ BT_VALID_ANT_ISOLATION_THRS = BIT(15),124124+ /*125125+ * For future use - when the valid flags will be enlarged126126+ * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),127127+ * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),128128+ */129129+};130130+131131+/**132132+ * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames.133133+ * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames134134+ * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames135135+ *136136+ * This mechanism allows to have BT and WiFi run concurrently. Since WiFi137137+ * reduces its Tx power, it can work along with BT, hence reducing the amount138138+ * of WiFi frames being killed by BT.139139+ */140140+enum iwl_bt_reduced_tx_power {141141+ BT_REDUCED_TX_POWER_CTL = BIT(0),142142+ BT_REDUCED_TX_POWER_DATA = BIT(1),143143+};144144+145145+#define BT_COEX_LUT_SIZE (12)146146+147147+/**148148+ * struct iwl_bt_coex_cmd - bt coex configuration command149149+ * @flags:&enum iwl_bt_coex_flags150150+ * @lead_time:151151+ * @max_kill:152152+ * @bt3_time_t7_value:153153+ * @kill_ack_msk:154154+ * @kill_cts_msk:155155+ * @bt3_prio_sample_time:156156+ * @bt3_timer_t2_value:157157+ * @bt4_reaction_time:158158+ * @decision_lut[12]:159159+ * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power160160+ * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk161161+ * @bt_prio_boost: values for PTA boost register162162+ * @wifi_tx_prio_boost: SW boost of wifi tx priority163163+ * @wifi_rx_prio_boost: SW boost of wifi rx priority164164+ *165165+ * The structure is used for the BT_COEX command.166166+ */167167+struct iwl_bt_coex_cmd {168168+ u8 flags;169169+ u8 lead_time;170170+ u8 max_kill;171171+ u8 bt3_time_t7_value;172172+ __le32 kill_ack_msk;173173+ __le32 kill_cts_msk;174174+ u8 bt3_prio_sample_time;175175+ u8 bt3_timer_t2_value;176176+ __le16 bt4_reaction_time;177177+ __le32 decision_lut[BT_COEX_LUT_SIZE];178178+ u8 bt_reduced_tx_power;179179+ u8 reserved;180180+ __le16 valid_bit_msk;181181+ __le32 bt_prio_boost;182182+ u8 reserved2;183183+ u8 wifi_tx_prio_boost;184184+ __le16 wifi_rx_prio_boost;185185+} __packed; /* BT_COEX_CMD_API_S_VER_3 */186186+187187+#define BT_MBOX(n_dw, _msg, _pos, _nbits) \188188+ BT_MBOX##n_dw##_##_msg##_POS = (_pos), \189189+ BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS190190+191191+enum iwl_bt_mxbox_dw0 {192192+ BT_MBOX(0, LE_SLAVE_LAT, 0, 3),193193+ BT_MBOX(0, LE_PROF1, 3, 1),194194+ BT_MBOX(0, LE_PROF2, 4, 1),195195+ BT_MBOX(0, LE_PROF_OTHER, 5, 1),196196+ BT_MBOX(0, CHL_SEQ_N, 8, 4),197197+ BT_MBOX(0, INBAND_S, 13, 1),198198+ BT_MBOX(0, LE_MIN_RSSI, 16, 4),199199+ BT_MBOX(0, LE_SCAN, 20, 1),200200+ BT_MBOX(0, LE_ADV, 21, 1),201201+ BT_MBOX(0, LE_MAX_TX_POWER, 24, 4),202202+ BT_MBOX(0, OPEN_CON_1, 28, 2),203203+};204204+205205+enum iwl_bt_mxbox_dw1 {206206+ BT_MBOX(1, BR_MAX_TX_POWER, 0, 4),207207+ BT_MBOX(1, IP_SR, 4, 1),208208+ BT_MBOX(1, LE_MSTR, 5, 1),209209+ BT_MBOX(1, AGGR_TRFC_LD, 8, 6),210210+ BT_MBOX(1, MSG_TYPE, 16, 3),211211+ BT_MBOX(1, SSN, 19, 2),212212+};213213+214214+enum iwl_bt_mxbox_dw2 {215215+ BT_MBOX(2, SNIFF_ACT, 0, 3),216216+ BT_MBOX(2, PAG, 3, 1),217217+ BT_MBOX(2, INQUIRY, 4, 1),218218+ BT_MBOX(2, CONN, 5, 1),219219+ BT_MBOX(2, SNIFF_INTERVAL, 8, 5),220220+ BT_MBOX(2, DISC, 13, 1),221221+ BT_MBOX(2, SCO_TX_ACT, 16, 2),222222+ BT_MBOX(2, SCO_RX_ACT, 18, 2),223223+ BT_MBOX(2, ESCO_RE_TX, 20, 2),224224+ BT_MBOX(2, SCO_DURATION, 24, 6),225225+};226226+227227+enum iwl_bt_mxbox_dw3 {228228+ BT_MBOX(3, SCO_STATE, 0, 1),229229+ BT_MBOX(3, SNIFF_STATE, 1, 1),230230+ BT_MBOX(3, A2DP_STATE, 2, 1),231231+ BT_MBOX(3, ACL_STATE, 3, 1),232232+ BT_MBOX(3, MSTR_STATE, 4, 1),233233+ BT_MBOX(3, OBX_STATE, 5, 1),234234+ BT_MBOX(3, OPEN_CON_2, 8, 2),235235+ BT_MBOX(3, TRAFFIC_LOAD, 10, 2),236236+ BT_MBOX(3, CHL_SEQN_LSB, 12, 1),237237+ BT_MBOX(3, INBAND_P, 13, 1),238238+ BT_MBOX(3, MSG_TYPE_2, 16, 3),239239+ BT_MBOX(3, SSN_2, 19, 2),240240+ BT_MBOX(3, UPDATE_REQUEST, 21, 1),241241+};242242+243243+#define BT_MBOX_MSG(_notif, _num, _field) \244244+ ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\245245+ >> BT_MBOX##_num##_##_field##_POS)246246+247247+/**248248+ * struct iwl_bt_coex_profile_notif - notification about BT coex249249+ * @mbox_msg: message from BT to WiFi250250+ * @:bt_status: 0 - off, 1 - on251251+ * @:bt_open_conn: number of BT connections open252252+ * @:bt_traffic_load: load of BT traffic253253+ * @:bt_agg_traffic_load: aggregated load of BT traffic254254+ * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant255255+ */256256+struct iwl_bt_coex_profile_notif {257257+ __le32 mbox_msg[4];258258+ u8 bt_status;259259+ u8 bt_open_conn;260260+ u8 bt_traffic_load;261261+ u8 bt_agg_traffic_load;262262+ u8 bt_ci_compliance;263263+ u8 reserved[3];264264+} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */265265+266266+enum iwl_bt_coex_prio_table_event {267267+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,268268+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,269269+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,270270+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3,271271+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,272272+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,273273+ BT_COEX_PRIO_TBL_EVT_DTIM = 6,274274+ BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,275275+ BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,276276+ BT_COEX_PRIO_TBL_EVT_IDLE = 9,277277+ BT_COEX_PRIO_TBL_EVT_MAX = 16,278278+}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */279279+280280+enum iwl_bt_coex_prio_table_prio {281281+ BT_COEX_PRIO_TBL_DISABLED = 0,282282+ BT_COEX_PRIO_TBL_PRIO_LOW = 1,283283+ BT_COEX_PRIO_TBL_PRIO_HIGH = 2,284284+ BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,285285+ BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,286286+ BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,287287+ BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6,288288+ BT_COEX_PRIO_TBL_MAX = 8,289289+}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */290290+291291+#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0)292292+#define BT_COEX_PRIO_TBL_PRIO_POS (1)293293+#define BT_COEX_PRIO_TBL_RESERVED_POS (4)294294+295295+/**296296+ * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex297297+ * @prio_tbl:298298+ */299299+struct iwl_bt_coex_prio_tbl_cmd {300300+ u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];301301+} __packed;302302+303303+enum iwl_bt_coex_env_action {304304+ BT_COEX_ENV_CLOSE = 0,305305+ BT_COEX_ENV_OPEN = 1,306306+}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */307307+308308+/**309309+ * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope310310+ * @action: enum %iwl_bt_coex_env_action311311+ * @type: enum %iwl_bt_coex_prio_table_event312312+ */313313+struct iwl_bt_coex_prot_env_cmd {314314+ u8 action; /* 0 = closed, 1 = open */315315+ u8 type; /* 0 .. 15 */316316+ u8 reserved[2];317317+} __packed;318318+319319+#endif /* __fw_api_bt_coex_h__ */
+51-2
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···258258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),259259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),260260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),261261- IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11),261261+ /* BIT(11) reserved */262262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),263263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */264264···276276 __le32 wake_packet_bufsize;277277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */278278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */279279+280280+#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64281281+#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128282282+#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048283283+284284+struct iwl_tcp_packet_info {285285+ __le16 tcp_pseudo_header_checksum;286286+ __le16 tcp_payload_length;287287+} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */288288+289289+struct iwl_tcp_packet {290290+ struct iwl_tcp_packet_info info;291291+ u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];292292+ u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN];293293+} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */294294+295295+struct iwl_remote_wake_packet {296296+ struct iwl_tcp_packet_info info;297297+ u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];298298+ u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN];299299+} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */300300+301301+struct iwl_wowlan_remote_wake_config {302302+ __le32 connection_max_time; /* unused */303303+ /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */304304+ u8 max_syn_retries;305305+ u8 max_data_retries;306306+ u8 tcp_syn_ack_timeout;307307+ u8 tcp_ack_timeout;308308+309309+ struct iwl_tcp_packet syn_tx;310310+ struct iwl_tcp_packet synack_rx;311311+ struct iwl_tcp_packet keepalive_ack_rx;312312+ struct iwl_tcp_packet fin_tx;313313+314314+ struct iwl_remote_wake_packet keepalive_tx;315315+ struct iwl_remote_wake_packet wake_rx;316316+317317+ /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */318318+ u8 sequence_number_offset;319319+ u8 sequence_number_length;320320+ u8 token_offset;321321+ u8 token_length;322322+ /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */323323+ __le32 initial_sequence_number;324324+ __le16 keepalive_interval;325325+ __le16 num_tokens;326326+ u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS];327327+} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */279328280329/* TODO: NetDetect API */281330
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+20-10
drivers/net/wireless/iwlwifi/mvm/fw-api.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···7070#include "fw-api-mac.h"7171#include "fw-api-power.h"7272#include "fw-api-d3.h"7373+#include "fw-api-bt-coex.h"73747475/* queue and FIFO numbers by usage */7576enum {···153152154153 BEACON_TEMPLATE_CMD = 0x91,155154 TX_ANT_CONFIGURATION_CMD = 0x98,155155+ BT_CONFIG = 0x9b,156156 STATISTICS_NOTIFICATION = 0x9d,157157158158 /* RF-KILL commands and notifications */···163161 REPLY_RX_PHY_CMD = 0xc0,164162 REPLY_RX_MPDU_CMD = 0xc1,165163 BA_NOTIF = 0xc5,164164+165165+ /* BT Coex */166166+ BT_COEX_PRIO_TABLE = 0xcc,167167+ BT_COEX_PROT_ENV = 0xcd,168168+ BT_PROFILE_NOTIFICATION = 0xce,166169167170 REPLY_DEBUG_CMD = 0xf0,168171 DEBUG_LOG_MSG = 0xf7,···769762#define IWL_RX_INFO_PHY_CNT 8770763#define IWL_RX_INFO_AGC_IDX 1771764#define IWL_RX_INFO_RSSI_AB_IDX 2772772-#define IWL_RX_INFO_RSSI_C_IDX 3773773-#define IWL_OFDM_AGC_DB_MSK 0xfe00774774-#define IWL_OFDM_AGC_DB_POS 9765765+#define IWL_OFDM_AGC_A_MSK 0x0000007f766766+#define IWL_OFDM_AGC_A_POS 0767767+#define IWL_OFDM_AGC_B_MSK 0x00003f80768768+#define IWL_OFDM_AGC_B_POS 7769769+#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000770770+#define IWL_OFDM_AGC_CODE_POS 20775771#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff776776-#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00777772#define IWL_OFDM_RSSI_A_POS 0773773+#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00774774+#define IWL_OFDM_RSSI_ALLBAND_A_POS 8778775#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000779779-#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000780776#define IWL_OFDM_RSSI_B_POS 16781781-#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff782782-#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00783783-#define IWL_OFDM_RSSI_C_POS 0777777+#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000778778+#define IWL_OFDM_RSSI_ALLBAND_B_POS 24784779785780/**786781 * struct iwl_rx_phy_info - phy info···801792 * @byte_count: frame's byte-count802793 * @frame_time: frame's time on the air, based on byte count and frame rate803794 * calculation795795+ * @mac_active_msk: what MACs were active when the frame was received804796 *805797 * Before each Rx, the device sends this data. It contains PHY information806798 * about the reception of the packet.···819809 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];820810 __le32 rate_n_flags;821811 __le32 byte_count;822822- __le16 reserved2;812812+ __le16 mac_active_msk;823813 __le16 frame_time;824814} __packed;825815
+18-129
drivers/net/wireless/iwlwifi/mvm/fw.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···7979#define UCODE_VALID_OK cpu_to_le32(0x1)80808181/* Default calibration values for WkP - set to INIT image w/o running */8282-static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,8383- 0x00, 0x18, 0x00 };8484-static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,8585- 0x7f, 0x7f, 0x7f };8686-static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };8787-static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,8888- 0x00 };8989-static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };9082static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };9183static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };9292-static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };93849485struct iwl_calib_default_data {9586 u16 size;···9099#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}9110092101static const struct iwl_calib_default_data wkp_calib_default_data[12] = {9393- [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),9494- [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),9595- [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),9696- [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),97102 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),9898- [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),99103 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),100104};101105···227241228242 return 0;229243}230230-#define IWL_HW_REV_ID_RAINBOW 0x2231231-#define IWL_PROJ_TYPE_LHP 0x5232232-233233-static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)234234-{235235- struct iwl_nvm_data *data = mvm->nvm_data;236236- /* Temp calls to static definitions, will be changed to CSR calls */237237- u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;238238- u8 project_type = IWL_PROJ_TYPE_LHP;239239-240240- return data->radio_cfg_dash | (data->radio_cfg_step << 2) |241241- (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |242242- (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);243243-}244244245245static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)246246{···234262 enum iwl_ucode_type ucode_type = mvm->cur_ucode;235263236264 /* Set parameters */237237- phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));265265+ phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);238266 phy_cfg_cmd.calib_control.event_trigger =239267 mvm->fw->default_calib[ucode_type].event_trigger;240268 phy_cfg_cmd.calib_control.flow_trigger =···245273246274 return iwl_mvm_send_cmd_pdu(mvm, PHY_CONFIGURATION_CMD, CMD_SYNC,247275 sizeof(phy_cfg_cmd), &phy_cfg_cmd);248248-}249249-250250-/* Starting with the new PHY DB implementation - New calibs are enabled */251251-/* Value - 0x405e7 */252252-#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\253253- IWL_CALIB_CFG_TEMPERATURE_IDX |\254254- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\255255- IWL_CALIB_CFG_DC_IDX |\256256- IWL_CALIB_CFG_BB_FILTER_IDX |\257257- IWL_CALIB_CFG_LO_LEAKAGE_IDX |\258258- IWL_CALIB_CFG_TX_IQ_IDX |\259259- IWL_CALIB_CFG_RX_IQ_IDX |\260260- IWL_CALIB_CFG_AGC_IDX)261261-262262-#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0263263-264264-/* Value 0x41567 */265265-#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\266266- IWL_CALIB_CFG_TEMPERATURE_IDX |\267267- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\268268- IWL_CALIB_CFG_BB_FILTER_IDX |\269269- IWL_CALIB_CFG_DC_IDX |\270270- IWL_CALIB_CFG_TX_IQ_IDX |\271271- IWL_CALIB_CFG_RX_IQ_IDX |\272272- IWL_CALIB_CFG_SENSITIVITY_IDX |\273273- IWL_CALIB_CFG_AGC_IDX)274274-275275-#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\276276- IWL_CALIB_CFG_TEMPERATURE_IDX |\277277- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\278278- IWL_CALIB_CFG_TX_PWR_IDX |\279279- IWL_CALIB_CFG_DC_IDX |\280280- IWL_CALIB_CFG_TX_IQ_IDX |\281281- IWL_CALIB_CFG_SENSITIVITY_IDX)282282-283283-/*284284- * Sets the calibrations trigger values that will be sent to the FW for runtime285285- * and init calibrations.286286- * The ones given in the FW TLV are not correct.287287- */288288-static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)289289-{290290- struct iwl_tlv_calib_ctrl default_calib;291291-292292- /*293293- * WkP FW TLV calib bits are wrong, overwrite them.294294- * This defines the dynamic calibrations which are implemented in the295295- * uCode both for init(flow) calculation and event driven calibs.296296- */297297-298298- /* Init Image */299299- default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);300300- default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);301301-302302- if (default_calib.event_trigger !=303303- mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)304304- IWL_ERR(mvm,305305- "Updating the event calib for INIT image: 0x%x -> 0x%x\n",306306- mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,307307- default_calib.event_trigger);308308- if (default_calib.flow_trigger !=309309- mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)310310- IWL_ERR(mvm,311311- "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",312312- mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,313313- default_calib.flow_trigger);314314-315315- memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],316316- &default_calib, sizeof(struct iwl_tlv_calib_ctrl));317317- IWL_ERR(mvm,318318- "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",319319- default_calib.event_trigger,320320- default_calib.flow_trigger);321321-322322- /* Run time image */323323- default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);324324- default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);325325-326326- if (default_calib.event_trigger !=327327- mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)328328- IWL_ERR(mvm,329329- "Updating the event calib for RT image: 0x%x -> 0x%x\n",330330- mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,331331- default_calib.event_trigger);332332- if (default_calib.flow_trigger !=333333- mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)334334- IWL_ERR(mvm,335335- "Updating the flow calib for RT image: 0x%x -> 0x%x\n",336336- mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,337337- default_calib.flow_trigger);338338-339339- memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],340340- &default_calib, sizeof(struct iwl_tlv_calib_ctrl));341341- IWL_ERR(mvm,342342- "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",343343- default_calib.event_trigger,344344- default_calib.flow_trigger);345276}346277347278static int iwl_set_default_calibrations(struct iwl_mvm *mvm)···309434 goto error;310435 }311436437437+ ret = iwl_send_bt_prio_tbl(mvm);438438+ if (ret)439439+ goto error;440440+312441 if (read_nvm) {313442 /* Read nvm */314443 ret = iwl_nvm_init(mvm);···325446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);326447 WARN_ON(ret);327448328328- /* Override the calibrations from TLV and the const of fw */329329- iwl_set_default_calib_trigger(mvm);449449+ /* Send TX valid antennas before triggering calibrations */450450+ ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);451451+ if (ret)452452+ goto error;330453331454 /* WkP doesn't have all calibrations, need to set default values */332455 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {···415534 }416535417536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);537537+ if (ret)538538+ goto error;539539+540540+ ret = iwl_send_bt_prio_tbl(mvm);541541+ if (ret)542542+ goto error;543543+544544+ ret = iwl_send_bt_init_conf(mvm);418545 if (ret)419546 goto error;420547
+1-1
drivers/net/wireless/iwlwifi/mvm/led.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+34-11
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···553553 if (vif->bss_conf.qos)554554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);555555556556+ /* Don't use cts to self as the fw doesn't support it currently. */556557 if (vif->bss_conf.use_cts_prot)557557- cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT |558558- MAC_PROT_FLG_SELF_CTS_EN);558558+ cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);559559560560 /*561561 * I think that we should enable these 2 flags regardless the HT PROT···651651 /* Fill the common data for all mac context types */652652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);653653654654+ /* Allow beacons to pass through as long as we are not associated,or we655655+ * do not have dtim period information */656656+ if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period)657657+ cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);658658+ else659659+ cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);660660+654661 /* Fill the data specific for station mode */655662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);656663···721714 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);722715723716 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);724724- cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC);717717+718718+ /* Override the filter flags to accept only probe requests */719719+ cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);725720726721 /*727722 * This flag should be set to true when the P2P Device is···855846 */856847static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,857848 struct ieee80211_vif *vif,858858- struct iwl_mac_data_ap *ctxt_ap)849849+ struct iwl_mac_data_ap *ctxt_ap,850850+ bool add)859851{860852 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);861861- u32 curr_dev_time;862853863854 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);864855 ctxt_ap->bi_reciprocal =···870861 vif->bss_conf.dtim_period));871862872863 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);873873- curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);874874- ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);875864876876- ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time);865865+ /*866866+ * Only read the system time when the MAC is being added, when we867867+ * just modify the MAC then we should keep the time -- the firmware868868+ * can otherwise have a "jumping" TBTT.869869+ */870870+ if (add)871871+ mvmvif->ap_beacon_time =872872+ iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);873873+874874+ ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);875875+876876+ ctxt_ap->beacon_tsf = 0; /* unused */877877878878 /* TODO: Assume that the beacon id == mac context id */879879 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);···899881 /* Fill the common data for all mac context types */900882 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);901883884884+ /* Also enable probe requests to pass */885885+ cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);886886+902887 /* Fill the data specific for ap mode */903903- iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap);888888+ iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,889889+ action == FW_CTXT_ACTION_ADD);904890905891 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);906892}···921899 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);922900923901 /* Fill the data specific for GO mode */924924- iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap);902902+ iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,903903+ action == FW_CTXT_ACTION_ADD);925904926905 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);927906 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
+57-12
drivers/net/wireless/iwlwifi/mvm/mac80211.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···6565#include <linux/skbuff.h>6666#include <linux/netdevice.h>6767#include <linux/etherdevice.h>6868+#include <linux/ip.h>6869#include <net/mac80211.h>7070+#include <net/tcp.h>69717072#include "iwl-op-mode.h"7173#include "iwl-io.h"···104102 },105103};106104105105+#ifdef CONFIG_PM_SLEEP106106+static const struct nl80211_wowlan_tcp_data_token_feature107107+iwl_mvm_wowlan_tcp_token_feature = {108108+ .min_len = 0,109109+ .max_len = 255,110110+ .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,111111+};112112+113113+static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {114114+ .tok = &iwl_mvm_wowlan_tcp_token_feature,115115+ .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -116116+ sizeof(struct ethhdr) -117117+ sizeof(struct iphdr) -118118+ sizeof(struct tcphdr),119119+ .data_interval_max = 65535, /* __le16 in API */120120+ .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -121121+ sizeof(struct ethhdr) -122122+ sizeof(struct iphdr) -123123+ sizeof(struct tcphdr),124124+ .seq = true,125125+};126126+#endif127127+107128int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)108129{109130 struct ieee80211_hw *hw = mvm->hw;110110- int num_mac, ret;131131+ int num_mac, ret, i;111132112133 /* Tell mac80211 our characteristics */113134 hw->flags = IEEE80211_HW_SIGNAL_DBM |···181156 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);182157 hw->wiphy->addresses = mvm->addresses;183158 hw->wiphy->n_addresses = 1;184184- num_mac = mvm->nvm_data->n_hw_addrs;185185- if (num_mac > 1) {186186- memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr,159159+160160+ /* Extract additional MAC addresses if available */161161+ num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?162162+ min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;163163+164164+ for (i = 1; i < num_mac; i++) {165165+ memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,187166 ETH_ALEN);188188- mvm->addresses[1].addr[5]++;167167+ mvm->addresses[i].addr[5]++;189168 hw->wiphy->n_addresses++;190169 }191170···235206 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;236207 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;237208 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;209209+ hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;238210 }239211#endif240212···303273 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);304274 break;305275 case IEEE80211_AMPDU_TX_START:276276+ if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {277277+ ret = -EINVAL;278278+ break;279279+ }306280 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);307281 break;308282 case IEEE80211_AMPDU_TX_STOP_CONT:283283+ ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);284284+ break;309285 case IEEE80211_AMPDU_TX_STOP_FLUSH:310286 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:311311- ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);287287+ ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);312288 break;313289 case IEEE80211_AMPDU_TX_OPERATIONAL:314290 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);···593557 return ret;594558}595559596596-static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,597597- struct ieee80211_vif *vif)560560+static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,561561+ struct ieee80211_vif *vif)598562{599599- struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);600600- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);601563 u32 tfd_msk = 0, ac;602564603565 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)···628594 */629595 flush_work(&mvm->sta_drained_wk);630596 }597597+}598598+599599+static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,600600+ struct ieee80211_vif *vif)601601+{602602+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);603603+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);604604+605605+ iwl_mvm_prepare_mac_removal(mvm, vif);631606632607 mutex_lock(&mvm->mutex);633608634609 /*635610 * For AP/GO interface, the tear down of the resources allocated to the636636- * interface should be handled as part of the bss_info_changed flow.611611+ * interface is be handled as part of the stop_ap flow.637612 */638613 if (vif->type == NL80211_IFTYPE_AP) {639614 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);···805762{806763 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);807764 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);765765+766766+ iwl_mvm_prepare_mac_removal(mvm, vif);808767809768 mutex_lock(&mvm->mutex);810769
+21-3
drivers/net/wireless/iwlwifi/mvm/mvm.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···7979#include "fw-api.h"80808181#define IWL_INVALID_MAC80211_QUEUE 0xff8282-#define IWL_MVM_MAX_ADDRESSES 28383-#define IWL_RSSI_OFFSET 448282+#define IWL_MVM_MAX_ADDRESSES 58383+/* RSSI offset for WkP */8484+#define IWL_RSSI_OFFSET 5084858586enum iwl_mvm_tx_fifo {8687 IWL_MVM_TX_FIFO_BK = 0,···173172174173 bool uploaded;175174 bool ap_active;175175+176176+ u32 ap_beacon_time;176177177178 enum iwl_tsf_id tsf_id;178179···330327 struct led_classdev led;331328332329 struct ieee80211_vif *p2p_device_vif;330330+331331+#ifdef CONFIG_PM_SLEEP332332+ int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;333333+#endif334334+335335+ /* BT-Coex */336336+ u8 bt_kill_msk;337337+ struct iwl_bt_coex_profile_notif last_bt_notif;333338};334339335340/* Extract MVM priv from op_mode and _hw */···507496 struct inet6_dev *idev);508497void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,509498 struct ieee80211_vif *vif, int idx);499499+500500+/* BT Coex */501501+int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);502502+int iwl_send_bt_init_conf(struct iwl_mvm *mvm);503503+int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,504504+ struct iwl_rx_cmd_buffer *rxb,505505+ struct iwl_device_cmd *cmd);510506511507#endif /* __IWL_MVM_H__ */
+7-4
drivers/net/wireless/iwlwifi/mvm/nvm.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···7373 NVM_SECTION_TYPE_CALIBRATION,7474 NVM_SECTION_TYPE_PRODUCTION,7575};7676+7777+/* Default NVM size to read */7878+#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);76797780/* used to simplify the shared operations on NCM_ACCESS_CMD versions */7881union iwl_nvm_access_cmd {···196193 int ret;197194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;198195199199- length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024))200200- - sizeof(union iwl_nvm_access_cmd)201201- - sizeof(struct iwl_rx_packet);196196+ /* Set nvm section read length */197197+ length = IWL_NVM_DEFAULT_CHUNK_SIZE;198198+202199 /*203200 * if length is greater than EEPROM size, truncate it because uCode204201 * doesn't check it by itself, and exit the loop when reached.
+22-8
drivers/net/wireless/iwlwifi/mvm/ops.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···230230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),231231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),232232233233+ RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),234234+233235 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),234236 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),235237···295293 CMD(NET_DETECT_PROFILES_CMD),296294 CMD(NET_DETECT_HOTSPOTS_CMD),297295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),296296+ CMD(CARD_STATE_NOTIFICATION),297297+ CMD(BT_COEX_PRIO_TABLE),298298+ CMD(BT_COEX_PROT_ENV),299299+ CMD(BT_PROFILE_NOTIFICATION),300300+ CMD(BT_CONFIG),298301};299302#undef CMD300303···370363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);371364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;372365373373- /* TODO: this should really be a TLV */374374- if (cfg->device_family == IWL_DEVICE_FAMILY_7000)366366+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)375367 trans_cfg.bc_table_dword = true;376368377369 if (!iwlwifi_mod_params.wd_disable)···630624 ieee80211_free_txskb(mvm->hw, skb);631625}632626633633-static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)627627+static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)634628{635635- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);636636-637637- iwl_mvm_dump_nic_error_log(mvm);638638-639629 iwl_abort_notification_waits(&mvm->notif_wait);640630641631 /*···665663 }666664}667665666666+static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)667667+{668668+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);669669+670670+ iwl_mvm_dump_nic_error_log(mvm);671671+672672+ iwl_mvm_nic_restart(mvm);673673+}674674+668675static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)669676{677677+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);678678+670679 WARN_ON(1);680680+ iwl_mvm_nic_restart(mvm);671681}672682673683static const struct iwl_op_mode_ops iwl_mvm_ops = {
+1-1
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/power.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/quota.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+8-6
drivers/net/wireless/iwlwifi/mvm/rs.c
···680680 */681681static bool rs_use_green(struct ieee80211_sta *sta)682682{683683- struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;684684-685685- bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode &686686- IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);687687-688688- return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green;683683+ /*684684+ * There's a bug somewhere in this code that causes the685685+ * scaling to get stuck because GF+SGI can't be combined686686+ * in SISO rates. Until we find that bug, disable GF, it687687+ * has only limited benefit and we still interoperate with688688+ * GF APs since we can always receive GF transmissions.689689+ */690690+ return false;689691}690692691693/**
+24-15
drivers/net/wireless/iwlwifi/mvm/rx.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···131131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,132132 struct iwl_rx_phy_info *phy_info)133133{134134- u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;134134+ int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;135135+ int rssi_all_band_a, rssi_all_band_b;136136+ u32 agc_a, agc_b, max_agc;135137 u32 val;136138137137- /* Find max rssi among 3 possible receivers.139139+ /* Find max rssi among 2 possible receivers.138140 * These values are measured by the Digital Signal Processor (DSP).139141 * They should stay fairly constant even as the signal strength varies,140142 * if the radio's Automatic Gain Control (AGC) is working right.141143 * AGC value (see below) will provide the "interesting" info.142144 */145145+ val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);146146+ agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;147147+ agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;148148+ max_agc = max_t(u32, agc_a, agc_b);149149+143150 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);144151 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;145152 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;146146- val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);147147- rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;153153+ rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>154154+ IWL_OFDM_RSSI_ALLBAND_A_POS;155155+ rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>156156+ IWL_OFDM_RSSI_ALLBAND_B_POS;148157149149- val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);150150- agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;158158+ /*159159+ * dBm = rssi dB - agc dB - constant.160160+ * Higher AGC (higher radio gain) means lower signal.161161+ */162162+ rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;163163+ rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;164164+ max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);151165152152- max_rssi = max_t(u32, rssi_a, rssi_b);153153- max_rssi = max_t(u32, max_rssi, rssi_c);166166+ IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",167167+ rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);154168155155- IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",156156- rssi_a, rssi_b, rssi_c, max_rssi, agc_db);157157-158158- /* dBm = max_rssi dB - agc dB - constant.159159- * Higher AGC (higher radio gain) means lower signal. */160160- return max_rssi - agc_db - IWL_RSSI_OFFSET;169169+ return max_rssi_dbm;161170}162171163172/*
+1-1
drivers/net/wireless/iwlwifi/mvm/scan.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+91-6
drivers/net/wireless/iwlwifi/mvm/sta.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···101101 }102102 add_sta_cmd.add_modify = update ? 1 : 0;103103104104- /* STA_FLG_FAT_EN_MSK ? */105105- /* STA_FLG_MIMO_EN_MSK ? */104104+ add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |105105+ STA_FLG_MIMO_EN_MSK);106106+107107+ switch (sta->bandwidth) {108108+ case IEEE80211_STA_RX_BW_160:109109+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ);110110+ /* fall through */111111+ case IEEE80211_STA_RX_BW_80:112112+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ);113113+ /* fall through */114114+ case IEEE80211_STA_RX_BW_40:115115+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ);116116+ /* fall through */117117+ case IEEE80211_STA_RX_BW_20:118118+ if (sta->ht_cap.ht_supported)119119+ add_sta_cmd.station_flags |=120120+ cpu_to_le32(STA_FLG_FAT_EN_20MHZ);121121+ break;122122+ }123123+124124+ switch (sta->rx_nss) {125125+ case 1:126126+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);127127+ break;128128+ case 2:129129+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2);130130+ break;131131+ case 3 ... 8:132132+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3);133133+ break;134134+ }135135+136136+ switch (sta->smps_mode) {137137+ case IEEE80211_SMPS_AUTOMATIC:138138+ case IEEE80211_SMPS_NUM_MODES:139139+ WARN_ON(1);140140+ break;141141+ case IEEE80211_SMPS_STATIC:142142+ /* override NSS */143143+ add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK);144144+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);145145+ break;146146+ case IEEE80211_SMPS_DYNAMIC:147147+ add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT);148148+ break;149149+ case IEEE80211_SMPS_OFF:150150+ /* nothing */151151+ break;152152+ }106153107154 if (sta->ht_cap.ht_supported) {108155 add_sta_cmd.station_flags_msk |=···387340388341 if (vif->type == NL80211_IFTYPE_STATION &&389342 mvmvif->ap_sta_id == mvm_sta->sta_id) {343343+ /* flush its queues here since we are freeing mvm_sta */344344+ ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);345345+390346 /*391347 * Put a non-NULL since the fw station isn't removed.392348 * It will be removed after the MAC will be set as···397347 */398348 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],399349 ERR_PTR(-EINVAL));400400-401401- /* flush its queues here since we are freeing mvm_sta */402402- ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);403350404351 /* if we are associated - we can't remove the AP STA now */405352 if (vif->bss_conf.assoc)···817770 u16 txq_id;818771 int err;819772773773+774774+ /*775775+ * If mac80211 is cleaning its state, then say that we finished since776776+ * our state has been cleared anyway.777777+ */778778+ if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {779779+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);780780+ return 0;781781+ }782782+820783 spin_lock_bh(&mvmsta->lock);821784822785 txq_id = tid_data->txq_id;···879822 spin_unlock_bh(&mvmsta->lock);880823881824 return err;825825+}826826+827827+int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,828828+ struct ieee80211_sta *sta, u16 tid)829829+{830830+ struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;831831+ struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];832832+ u16 txq_id;833833+834834+ /*835835+ * First set the agg state to OFF to avoid calling836836+ * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.837837+ */838838+ spin_lock_bh(&mvmsta->lock);839839+ txq_id = tid_data->txq_id;840840+ IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",841841+ mvmsta->sta_id, tid, txq_id, tid_data->state);842842+ tid_data->state = IWL_AGG_OFF;843843+ spin_unlock_bh(&mvmsta->lock);844844+845845+ if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))846846+ IWL_ERR(mvm, "Couldn't flush the AGG queue\n");847847+848848+ iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);849849+ mvm->queue_to_mac80211[tid_data->txq_id] =850850+ IWL_INVALID_MAC80211_QUEUE;851851+852852+ return 0;882853}883854884855static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
+3-1
drivers/net/wireless/iwlwifi/mvm/sta.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···347347int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,348348 struct ieee80211_sta *sta, u16 tid, u8 buf_size);349349int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,350350+ struct ieee80211_sta *sta, u16 tid);351351+int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,350352 struct ieee80211_sta *sta, u16 tid);351353352354int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
+1-1
drivers/net/wireless/iwlwifi/mvm/time-event.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+1-1
drivers/net/wireless/iwlwifi/mvm/time-event.h
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
+2-6
drivers/net/wireless/iwlwifi/mvm/tx.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···607607608608 /* Single frame failure in an AMPDU queue => send BAR */609609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&610610- !(info->flags & IEEE80211_TX_STAT_ACK)) {611611- /* there must be only one skb in the skb_list */612612- WARN_ON_ONCE(skb_freed > 1 ||613613- !skb_queue_empty(&skbs));610610+ !(info->flags & IEEE80211_TX_STAT_ACK))614611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;615615- }616612617613 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */618614 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
+1-1
drivers/net/wireless/iwlwifi/mvm/utils.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>
···2828#include <linux/stringify.h>2929#include "iwl-config.h"3030#include "iwl-agn-hw.h"3131-#include "cfg.h"3231#include "dvm/commands.h" /* needed for BT for now */33323433/* Highest firmware API version supported */
···2828#include <linux/stringify.h>2929#include "iwl-config.h"3030#include "iwl-agn-hw.h"3131-#include "cfg.h"3231#include "dvm/commands.h" /* needed for BT for now */33323433/* Highest firmware API version supported */
···11/******************************************************************************22 *33- * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.33+ * This file is provided under a dual BSD/GPLv2 license. When using or44+ * redistributing this file, you may do so under either license.45 *55- * This program is free software; you can redistribute it and/or modify it66- * under the terms of version 2 of the GNU General Public License as66+ * GPL LICENSE SUMMARY77+ *88+ * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.99+ *1010+ * This program is free software; you can redistribute it and/or modify1111+ * it under the terms of version 2 of the GNU General Public License as712 * published by the Free Software Foundation.813 *99- * This program is distributed in the hope that it will be useful, but WITHOUT1010- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1111- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1212- * more details.1414+ * This program is distributed in the hope that it will be useful, but1515+ * WITHOUT ANY WARRANTY; without even the implied warranty of1616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1717+ * General Public License for more details.1318 *1414- * You should have received a copy of the GNU General Public License along with1515- * this program; if not, write to the Free Software Foundation, Inc.,1616- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA1919+ * You should have received a copy of the GNU General Public License2020+ * along with this program; if not, write to the Free Software2121+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,2222+ * USA1723 *1818- * The full GNU General Public License is included in this distribution in the1919- * file called LICENSE.2424+ * The full GNU General Public License is included in this distribution2525+ * in the file called COPYING.2026 *2127 * Contact Information:2228 * Intel Linux Wireless <ilw@linux.intel.com>2329 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64973030+ *3131+ * BSD LICENSE3232+ *3333+ * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.3434+ * All rights reserved.3535+ *3636+ * Redistribution and use in source and binary forms, with or without3737+ * modification, are permitted provided that the following conditions3838+ * are met:3939+ *4040+ * * Redistributions of source code must retain the above copyright4141+ * notice, this list of conditions and the following disclaimer.4242+ * * Redistributions in binary form must reproduce the above copyright4343+ * notice, this list of conditions and the following disclaimer in4444+ * the documentation and/or other materials provided with the4545+ * distribution.4646+ * * Neither the name Intel Corporation nor the names of its4747+ * contributors may be used to endorse or promote products derived4848+ * from this software without specific prior written permission.4949+ *5050+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS5151+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT5252+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR5353+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT5454+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,5555+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT5656+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,5757+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY5858+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT5959+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE6060+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2461 *2562 *****************************************************************************/2663···6528#include <linux/stringify.h>6629#include "iwl-config.h"6730#include "iwl-agn-hw.h"6868-#include "cfg.h"69317032/* Highest firmware API version supported */7133#define IWL7260_UCODE_API_MAX 6···10670};1077110872static const struct iwl_ht_params iwl7000_ht_params = {109109- .ht_greenfield_support = true,11073 .use_rts_for_aggregation = true, /* use rts/cts protection */11174 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),11275};
-115
drivers/net/wireless/iwlwifi/pcie/cfg.h
···11-/******************************************************************************22- *33- * This file is provided under a dual BSD/GPLv2 license. When using or44- * redistributing this file, you may do so under either license.55- *66- * GPL LICENSE SUMMARY77- *88- * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.99- *1010- * This program is free software; you can redistribute it and/or modify1111- * it under the terms of version 2 of the GNU General Public License as1212- * published by the Free Software Foundation.1313- *1414- * This program is distributed in the hope that it will be useful, but1515- * WITHOUT ANY WARRANTY; without even the implied warranty of1616- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1717- * General Public License for more details.1818- *1919- * You should have received a copy of the GNU General Public License2020- * along with this program; if not, write to the Free Software2121- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,2222- * USA2323- *2424- * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2626- *2727- * Contact Information:2828- * Intel Linux Wireless <ilw@linux.intel.com>2929- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64973030- *3131- * BSD LICENSE3232- *3333- * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.3434- * All rights reserved.3535- *3636- * Redistribution and use in source and binary forms, with or without3737- * modification, are permitted provided that the following conditions3838- * are met:3939- *4040- * * Redistributions of source code must retain the above copyright4141- * notice, this list of conditions and the following disclaimer.4242- * * Redistributions in binary form must reproduce the above copyright4343- * notice, this list of conditions and the following disclaimer in4444- * the documentation and/or other materials provided with the4545- * distribution.4646- * * Neither the name Intel Corporation nor the names of its4747- * contributors may be used to endorse or promote products derived4848- * from this software without specific prior written permission.4949- *5050- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS5151- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT5252- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR5353- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT5454- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,5555- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT5656- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,5757- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY5858- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT5959- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE6060- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.6161- *6262- *****************************************************************************/6363-#ifndef __iwl_pci_h__6464-#define __iwl_pci_h__6565-6666-6767-/*6868- * This file declares the config structures for all devices.6969- */7070-7171-extern const struct iwl_cfg iwl5300_agn_cfg;7272-extern const struct iwl_cfg iwl5100_agn_cfg;7373-extern const struct iwl_cfg iwl5350_agn_cfg;7474-extern const struct iwl_cfg iwl5100_bgn_cfg;7575-extern const struct iwl_cfg iwl5100_abg_cfg;7676-extern const struct iwl_cfg iwl5150_agn_cfg;7777-extern const struct iwl_cfg iwl5150_abg_cfg;7878-extern const struct iwl_cfg iwl6005_2agn_cfg;7979-extern const struct iwl_cfg iwl6005_2abg_cfg;8080-extern const struct iwl_cfg iwl6005_2bg_cfg;8181-extern const struct iwl_cfg iwl6005_2agn_sff_cfg;8282-extern const struct iwl_cfg iwl6005_2agn_d_cfg;8383-extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;8484-extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;8585-extern const struct iwl_cfg iwl1030_bgn_cfg;8686-extern const struct iwl_cfg iwl1030_bg_cfg;8787-extern const struct iwl_cfg iwl6030_2agn_cfg;8888-extern const struct iwl_cfg iwl6030_2abg_cfg;8989-extern const struct iwl_cfg iwl6030_2bgn_cfg;9090-extern const struct iwl_cfg iwl6030_2bg_cfg;9191-extern const struct iwl_cfg iwl6000i_2agn_cfg;9292-extern const struct iwl_cfg iwl6000i_2abg_cfg;9393-extern const struct iwl_cfg iwl6000i_2bg_cfg;9494-extern const struct iwl_cfg iwl6000_3agn_cfg;9595-extern const struct iwl_cfg iwl6050_2agn_cfg;9696-extern const struct iwl_cfg iwl6050_2abg_cfg;9797-extern const struct iwl_cfg iwl6150_bgn_cfg;9898-extern const struct iwl_cfg iwl6150_bg_cfg;9999-extern const struct iwl_cfg iwl1000_bgn_cfg;100100-extern const struct iwl_cfg iwl1000_bg_cfg;101101-extern const struct iwl_cfg iwl100_bgn_cfg;102102-extern const struct iwl_cfg iwl100_bg_cfg;103103-extern const struct iwl_cfg iwl130_bgn_cfg;104104-extern const struct iwl_cfg iwl130_bg_cfg;105105-extern const struct iwl_cfg iwl2000_2bgn_cfg;106106-extern const struct iwl_cfg iwl2000_2bgn_d_cfg;107107-extern const struct iwl_cfg iwl2030_2bgn_cfg;108108-extern const struct iwl_cfg iwl6035_2agn_cfg;109109-extern const struct iwl_cfg iwl105_bgn_cfg;110110-extern const struct iwl_cfg iwl105_bgn_d_cfg;111111-extern const struct iwl_cfg iwl135_bgn_cfg;112112-extern const struct iwl_cfg iwl7260_2ac_cfg;113113-extern const struct iwl_cfg iwl3160_ac_cfg;114114-115115-#endif /* __iwl_pci_h__ */
+1-3
drivers/net/wireless/iwlwifi/pcie/drv.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···69697070#include "iwl-trans.h"7171#include "iwl-drv.h"7272-7373-#include "cfg.h"7472#include "internal.h"75737674#define IWL_PCI_DEVICE(dev, subdev, cfg) \
+30-5
drivers/net/wireless/iwlwifi/pcie/internal.h
···137137struct iwl_cmd_meta {138138 /* only for SYNC commands, iff the reply skb is wanted */139139 struct iwl_host_cmd *source;140140-141141- DEFINE_DMA_UNMAP_ADDR(mapping);142142- DEFINE_DMA_UNMAP_LEN(len);143143-144140 u32 flags;145141};146142···178182#define TFD_TX_CMD_SLOTS 256179183#define TFD_CMD_SLOTS 32180184185185+/*186186+ * The FH will write back to the first TB only, so we need187187+ * to copy some data into the buffer regardless of whether188188+ * it should be mapped or not. This indicates how big the189189+ * first TB must be to include the scratch buffer. Since190190+ * the scratch is 4 bytes at offset 12, it's 16 now. If we191191+ * make it bigger then allocations will be bigger and copy192192+ * slower, so that's probably not useful.193193+ */194194+#define IWL_HCMD_SCRATCHBUF_SIZE 16195195+181196struct iwl_pcie_txq_entry {182197 struct iwl_device_cmd *cmd;183183- struct iwl_device_cmd *copy_cmd;184198 struct sk_buff *skb;185199 /* buffer to free after command completes */186200 const void *free_buf;187201 struct iwl_cmd_meta meta;188202};189203204204+struct iwl_pcie_txq_scratch_buf {205205+ struct iwl_cmd_header hdr;206206+ u8 buf[8];207207+ __le32 scratch;208208+};209209+190210/**191211 * struct iwl_txq - Tx Queue for DMA192212 * @q: generic Rx/Tx queue descriptor193213 * @tfds: transmit frame descriptors (DMA memory)214214+ * @scratchbufs: start of command headers, including scratch buffers, for215215+ * the writeback -- this is DMA memory and an array holding one buffer216216+ * for each command on the queue217217+ * @scratchbufs_dma: DMA address for the scratchbufs start194218 * @entries: transmit entries (driver state)195219 * @lock: queue lock196220 * @stuck_timer: timer that fires if queue gets stuck···224208struct iwl_txq {225209 struct iwl_queue q;226210 struct iwl_tfd *tfds;211211+ struct iwl_pcie_txq_scratch_buf *scratchbufs;212212+ dma_addr_t scratchbufs_dma;227213 struct iwl_pcie_txq_entry *entries;228214 spinlock_t lock;229215 struct timer_list stuck_timer;···233215 u8 need_update;234216 u8 active;235217};218218+219219+static inline dma_addr_t220220+iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)221221+{222222+ return txq->scratchbufs_dma +223223+ sizeof(struct iwl_pcie_txq_scratch_buf) * idx;224224+}236225237226/**238227 * struct iwl_trans_pcie - PCIe transport specific data
+3-11
drivers/net/wireless/iwlwifi/pcie/rx.c
···637637 index = SEQ_TO_INDEX(sequence);638638 cmd_index = get_cmd_index(&txq->q, index);639639640640- if (reclaim) {641641- struct iwl_pcie_txq_entry *ent;642642- ent = &txq->entries[cmd_index];643643- cmd = ent->copy_cmd;644644- WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);645645- } else {640640+ if (reclaim)641641+ cmd = txq->entries[cmd_index].cmd;642642+ else646643 cmd = NULL;647647- }648644649645 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);650646651647 if (reclaim) {652652- /* The original command isn't needed any more */653653- kfree(txq->entries[cmd_index].copy_cmd);654654- txq->entries[cmd_index].copy_cmd = NULL;655655- /* nor is the duplicated part of the command */656648 kfree(txq->entries[cmd_index].free_buf);657649 txq->entries[cmd_index].free_buf = NULL;658650 }
+4-21
drivers/net/wireless/iwlwifi/pcie/trans.c
···2222 * USA2323 *2424 * The full GNU General Public License is included in this distribution2525- * in the file called LICENSE.GPL.2525+ * in the file called COPYING.2626 *2727 * Contact Information:2828 * Intel Linux Wireless <ilw@linux.intel.com>···715715716716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg)717717{718718- iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));718718+ iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR,719719+ ((reg & 0x000FFFFF) | (3 << 24)));719720 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT);720721}721722···724723 u32 val)725724{726725 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR,727727- ((addr & 0x0000FFFF) | (3 << 24)));726726+ ((addr & 0x000FFFFF) | (3 << 24)));728727 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val);729728}730729···13711370 return ret;13721371}1373137213741374-static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,13751375- const char __user *user_buf,13761376- size_t count, loff_t *ppos)13771377-{13781378- struct iwl_trans *trans = file->private_data;13791379-13801380- if (!trans->op_mode)13811381- return -EAGAIN;13821382-13831383- local_bh_disable();13841384- iwl_op_mode_nic_error(trans->op_mode);13851385- local_bh_enable();13861386-13871387- return count;13881388-}13891389-13901373DEBUGFS_READ_WRITE_FILE_OPS(interrupt);13911374DEBUGFS_READ_FILE_OPS(fh_reg);13921375DEBUGFS_READ_FILE_OPS(rx_queue);13931376DEBUGFS_READ_FILE_OPS(tx_queue);13941377DEBUGFS_WRITE_FILE_OPS(csr);13951395-DEBUGFS_WRITE_FILE_OPS(fw_restart);1396137813971379/*13981380 * Create the debugfs files and directories···13891405 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);13901406 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);13911407 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);13921392- DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);13931408 return 0;1394140913951410err:
+166-143
drivers/net/wireless/iwlwifi/pcie/tx.c
···191191 }192192193193 for (i = q->read_ptr; i != q->write_ptr;194194- i = iwl_queue_inc_wrap(i, q->n_bd)) {195195- struct iwl_tx_cmd *tx_cmd =196196- (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;194194+ i = iwl_queue_inc_wrap(i, q->n_bd))197195 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,198198- get_unaligned_le32(&tx_cmd->scratch));199199- }196196+ le32_to_cpu(txq->scratchbufs[i].scratch));200197201198 iwl_op_mode_nic_error(trans->op_mode);202199}···364367}365368366369static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,367367- struct iwl_cmd_meta *meta, struct iwl_tfd *tfd,368368- enum dma_data_direction dma_dir)370370+ struct iwl_cmd_meta *meta,371371+ struct iwl_tfd *tfd)369372{370373 int i;371374 int num_tbs;···379382 return;380383 }381384382382- /* Unmap tx_cmd */383383- if (num_tbs)384384- dma_unmap_single(trans->dev,385385- dma_unmap_addr(meta, mapping),386386- dma_unmap_len(meta, len),387387- DMA_BIDIRECTIONAL);385385+ /* first TB is never freed - it's the scratchbuf data */388386389389- /* Unmap chunks, if any. */390387 for (i = 1; i < num_tbs; i++)391388 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),392392- iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir);389389+ iwl_pcie_tfd_tb_get_len(tfd, i),390390+ DMA_TO_DEVICE);393391394392 tfd->num_tbs = 0;395393}···398406 * Does NOT advance any TFD circular buffer read/write indexes399407 * Does NOT free the TFD itself (which is within circular buffer)400408 */401401-static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,402402- enum dma_data_direction dma_dir)409409+static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)403410{404411 struct iwl_tfd *tfd_tmp = txq->tfds;405412···409418 lockdep_assert_held(&txq->lock);410419411420 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */412412- iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr],413413- dma_dir);421421+ iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);414422415423 /* free SKB */416424 if (txq->entries) {···469479{470480 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);471481 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;482482+ size_t scratchbuf_sz;472483 int i;473484474485 if (WARN_ON(txq->entries || txq->tfds))···505514 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);506515 goto error;507516 }517517+518518+ BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));519519+ BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=520520+ sizeof(struct iwl_cmd_header) +521521+ offsetof(struct iwl_tx_cmd, scratch));522522+523523+ scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;524524+525525+ txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,526526+ &txq->scratchbufs_dma,527527+ GFP_KERNEL);528528+ if (!txq->scratchbufs)529529+ goto err_free_tfds;530530+508531 txq->q.id = txq_id;509532510533 return 0;534534+err_free_tfds:535535+ dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);511536error:512537 if (txq->entries && txq_id == trans_pcie->cmd_queue)513538 for (i = 0; i < slots_num; i++)···572565 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);573566 struct iwl_txq *txq = &trans_pcie->txq[txq_id];574567 struct iwl_queue *q = &txq->q;575575- enum dma_data_direction dma_dir;576568577569 if (!q->n_bd)578570 return;579571580580- /* In the command queue, all the TBs are mapped as BIDI581581- * so unmap them as such.582582- */583583- if (txq_id == trans_pcie->cmd_queue)584584- dma_dir = DMA_BIDIRECTIONAL;585585- else586586- dma_dir = DMA_TO_DEVICE;587587-588572 spin_lock_bh(&txq->lock);589573 while (q->write_ptr != q->read_ptr) {590590- iwl_pcie_txq_free_tfd(trans, txq, dma_dir);574574+ iwl_pcie_txq_free_tfd(trans, txq);591575 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);592576 }593577 spin_unlock_bh(&txq->lock);···608610 if (txq_id == trans_pcie->cmd_queue)609611 for (i = 0; i < txq->q.n_window; i++) {610612 kfree(txq->entries[i].cmd);611611- kfree(txq->entries[i].copy_cmd);612613 kfree(txq->entries[i].free_buf);613614 }614615···616619 dma_free_coherent(dev, sizeof(struct iwl_tfd) *617620 txq->q.n_bd, txq->tfds, txq->q.dma_addr);618621 txq->q.dma_addr = 0;622622+623623+ dma_free_coherent(dev,624624+ sizeof(*txq->scratchbufs) * txq->q.n_window,625625+ txq->scratchbufs, txq->scratchbufs_dma);619626 }620627621628 kfree(txq->entries);···963962964963 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);965964966966- iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE);965965+ iwl_pcie_txq_free_tfd(trans, txq);967966 }968967969968 iwl_pcie_txq_progress(trans_pcie, txq);···11531152 void *dup_buf = NULL;11541153 dma_addr_t phys_addr;11551154 int idx;11561156- u16 copy_size, cmd_size;11551155+ u16 copy_size, cmd_size, scratch_size;11571156 bool had_nocopy = false;11581157 int i;11591158 u32 cmd_pos;11591159+ const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];11601160+ u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];1160116111611162 copy_size = sizeof(out_cmd->hdr);11621163 cmd_size = sizeof(out_cmd->hdr);1163116411641165 /* need one for the header if the first is NOCOPY */11651165- BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);11661166+ BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);1166116711671167- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {11681168+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {11691169+ cmddata[i] = cmd->data[i];11701170+ cmdlen[i] = cmd->len[i];11711171+11681172 if (!cmd->len[i])11691173 continue;11741174+11751175+ /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */11761176+ if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {11771177+ int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;11781178+11791179+ if (copy > cmdlen[i])11801180+ copy = cmdlen[i];11811181+ cmdlen[i] -= copy;11821182+ cmddata[i] += copy;11831183+ copy_size += copy;11841184+ }11851185+11701186 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {11711187 had_nocopy = true;11721188 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {···12031185 goto free_dup_buf;12041186 }1205118712061206- dup_buf = kmemdup(cmd->data[i], cmd->len[i],11881188+ dup_buf = kmemdup(cmddata[i], cmdlen[i],12071189 GFP_ATOMIC);12081190 if (!dup_buf)12091191 return -ENOMEM;···12131195 idx = -EINVAL;12141196 goto free_dup_buf;12151197 }12161216- copy_size += cmd->len[i];11981198+ copy_size += cmdlen[i];12171199 }12181200 cmd_size += cmd->len[i];12191201 }···1260124212611243 /* and copy the data that needs to be copied */12621244 cmd_pos = offsetof(struct iwl_device_cmd, payload);12631263- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {12641264- if (!cmd->len[i])12451245+ copy_size = sizeof(out_cmd->hdr);12461246+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {12471247+ int copy = 0;12481248+12491249+ if (!cmd->len)12651250 continue;12661266- if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |12671267- IWL_HCMD_DFL_DUP))12681268- break;12691269- memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);12701270- cmd_pos += cmd->len[i];12711271- }1272125112731273- WARN_ON_ONCE(txq->entries[idx].copy_cmd);12521252+ /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */12531253+ if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {12541254+ copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;1274125512751275- /*12761276- * since out_cmd will be the source address of the FH, it will write12771277- * the retry count there. So when the user needs to receivce the HCMD12781278- * that corresponds to the response in the response handler, it needs12791279- * to set CMD_WANT_HCMD.12801280- */12811281- if (cmd->flags & CMD_WANT_HCMD) {12821282- txq->entries[idx].copy_cmd =12831283- kmemdup(out_cmd, cmd_pos, GFP_ATOMIC);12841284- if (unlikely(!txq->entries[idx].copy_cmd)) {12851285- idx = -ENOMEM;12861286- goto out;12561256+ if (copy > cmd->len[i])12571257+ copy = cmd->len[i];12581258+ }12591259+12601260+ /* copy everything if not nocopy/dup */12611261+ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |12621262+ IWL_HCMD_DFL_DUP)))12631263+ copy = cmd->len[i];12641264+12651265+ if (copy) {12661266+ memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);12671267+ cmd_pos += copy;12681268+ copy_size += copy;12871269 }12881270 }12891271···12931275 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),12941276 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);1295127712961296- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,12971297- DMA_BIDIRECTIONAL);12981298- if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {12991299- idx = -ENOMEM;13001300- goto out;12781278+ /* start the TFD with the scratchbuf */12791279+ scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);12801280+ memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);12811281+ iwl_pcie_txq_build_tfd(trans, txq,12821282+ iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),12831283+ scratch_size, 1);12841284+12851285+ /* map first command fragment, if any remains */12861286+ if (copy_size > scratch_size) {12871287+ phys_addr = dma_map_single(trans->dev,12881288+ ((u8 *)&out_cmd->hdr) + scratch_size,12891289+ copy_size - scratch_size,12901290+ DMA_TO_DEVICE);12911291+ if (dma_mapping_error(trans->dev, phys_addr)) {12921292+ iwl_pcie_tfd_unmap(trans, out_meta,12931293+ &txq->tfds[q->write_ptr]);12941294+ idx = -ENOMEM;12951295+ goto out;12961296+ }12971297+12981298+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr,12991299+ copy_size - scratch_size, 0);13011300 }1302130113031303- dma_unmap_addr_set(out_meta, mapping, phys_addr);13041304- dma_unmap_len_set(out_meta, len, copy_size);13021302+ /* map the remaining (adjusted) nocopy/dup fragments */13031303+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {13041304+ const void *data = cmddata[i];1305130513061306- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);13071307-13081308- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {13091309- const void *data = cmd->data[i];13101310-13111311- if (!cmd->len[i])13061306+ if (!cmdlen[i])13121307 continue;13131308 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |13141309 IWL_HCMD_DFL_DUP)))···13291298 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)13301299 data = dup_buf;13311300 phys_addr = dma_map_single(trans->dev, (void *)data,13321332- cmd->len[i], DMA_BIDIRECTIONAL);13011301+ cmdlen[i], DMA_TO_DEVICE);13331302 if (dma_mapping_error(trans->dev, phys_addr)) {13341303 iwl_pcie_tfd_unmap(trans, out_meta,13351335- &txq->tfds[q->write_ptr],13361336- DMA_BIDIRECTIONAL);13041304+ &txq->tfds[q->write_ptr]);13371305 idx = -ENOMEM;13381306 goto out;13391307 }1340130813411341- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);13091309+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);13421310 }1343131113441312 out_meta->flags = cmd->flags;···1347131713481318 txq->need_update = 1;1349131913501350- trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,13511351- &out_cmd->hdr, copy_size);13201320+ trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);1352132113531322 /* start timer if queue currently empty */13541323 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)···14061377 cmd = txq->entries[cmd_index].cmd;14071378 meta = &txq->entries[cmd_index].meta;1408137914091409- iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);13801380+ iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);1410138114111382 /* Input error checking is done when commands are added to queue. */14121383 if (meta->flags & CMD_WANT_SKB) {···15851556 struct iwl_cmd_meta *out_meta;15861557 struct iwl_txq *txq;15871558 struct iwl_queue *q;15881588- dma_addr_t phys_addr = 0;15891589- dma_addr_t txcmd_phys;15901590- dma_addr_t scratch_phys;15911591- u16 len, firstlen, secondlen;15591559+ dma_addr_t tb0_phys, tb1_phys, scratch_phys;15601560+ void *tb1_addr;15611561+ u16 len, tb1_len, tb2_len;15921562 u8 wait_write_ptr = 0;15931563 __le16 fc = hdr->frame_control;15941564 u8 hdr_len = ieee80211_hdrlen(fc);···16251597 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |16261598 INDEX_TO_SEQ(q->write_ptr)));1627159916001600+ tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);16011601+ scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +16021602+ offsetof(struct iwl_tx_cmd, scratch);16031603+16041604+ tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);16051605+ tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);16061606+16281607 /* Set up first empty entry in queue's array of Tx/cmd buffers */16291608 out_meta = &txq->entries[q->write_ptr].meta;1630160916311610 /*16321632- * Use the first empty entry in this queue's command buffer array16331633- * to contain the Tx command and MAC header concatenated together16341634- * (payload data will be in another buffer).16351635- * Size of this varies, due to varying MAC header length.16361636- * If end is not dword aligned, we'll have 2 extra bytes at the end16371637- * of the MAC header (device reads on dword boundaries).16381638- * We'll tell device about this padding later.16111611+ * The second TB (tb1) points to the remainder of the TX command16121612+ * and the 802.11 header - dword aligned size16131613+ * (This calculation modifies the TX command, so do it before the16141614+ * setup of the first TB)16391615 */16401640- len = sizeof(struct iwl_tx_cmd) +16411641- sizeof(struct iwl_cmd_header) + hdr_len;16421642- firstlen = (len + 3) & ~3;16161616+ len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +16171617+ hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;16181618+ tb1_len = (len + 3) & ~3;1643161916441620 /* Tell NIC about any 2-byte padding after MAC header */16451645- if (firstlen != len)16211621+ if (tb1_len != len)16461622 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;1647162316481648- /* Physical address of this Tx command's header (not MAC header!),16491649- * within command buffer array. */16501650- txcmd_phys = dma_map_single(trans->dev,16511651- &dev_cmd->hdr, firstlen,16521652- DMA_BIDIRECTIONAL);16531653- if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))16241624+ /* The first TB points to the scratchbuf data - min_copy bytes */16251625+ memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,16261626+ IWL_HCMD_SCRATCHBUF_SIZE);16271627+ iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,16281628+ IWL_HCMD_SCRATCHBUF_SIZE, 1);16291629+16301630+ /* there must be data left over for TB1 or this code must be changed */16311631+ BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);16321632+16331633+ /* map the data for TB1 */16341634+ tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;16351635+ tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);16361636+ if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))16541637 goto out_err;16551655- dma_unmap_addr_set(out_meta, mapping, txcmd_phys);16561656- dma_unmap_len_set(out_meta, len, firstlen);16381638+ iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);16391639+16401640+ /*16411641+ * Set up TFD's third entry to point directly to remainder16421642+ * of skb, if any (802.11 null frames have no payload).16431643+ */16441644+ tb2_len = skb->len - hdr_len;16451645+ if (tb2_len > 0) {16461646+ dma_addr_t tb2_phys = dma_map_single(trans->dev,16471647+ skb->data + hdr_len,16481648+ tb2_len, DMA_TO_DEVICE);16491649+ if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {16501650+ iwl_pcie_tfd_unmap(trans, out_meta,16511651+ &txq->tfds[q->write_ptr]);16521652+ goto out_err;16531653+ }16541654+ iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);16551655+ }16561656+16571657+ /* Set up entry for this TFD in Tx byte-count array */16581658+ iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));16591659+16601660+ trace_iwlwifi_dev_tx(trans->dev, skb,16611661+ &txq->tfds[txq->q.write_ptr],16621662+ sizeof(struct iwl_tfd),16631663+ &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,16641664+ skb->data + hdr_len, tb2_len);16651665+ trace_iwlwifi_dev_tx_data(trans->dev, skb,16661666+ skb->data + hdr_len, tb2_len);1657166716581668 if (!ieee80211_has_morefrags(fc)) {16591669 txq->need_update = 1;···16991633 wait_write_ptr = 1;17001634 txq->need_update = 0;17011635 }17021702-17031703- /* Set up TFD's 2nd entry to point directly to remainder of skb,17041704- * if any (802.11 null frames have no payload). */17051705- secondlen = skb->len - hdr_len;17061706- if (secondlen > 0) {17071707- phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,17081708- secondlen, DMA_TO_DEVICE);17091709- if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {17101710- dma_unmap_single(trans->dev,17111711- dma_unmap_addr(out_meta, mapping),17121712- dma_unmap_len(out_meta, len),17131713- DMA_BIDIRECTIONAL);17141714- goto out_err;17151715- }17161716- }17171717-17181718- /* Attach buffers to TFD */17191719- iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);17201720- if (secondlen > 0)17211721- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);17221722-17231723- scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +17241724- offsetof(struct iwl_tx_cmd, scratch);17251725-17261726- /* take back ownership of DMA buffer to enable update */17271727- dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,17281728- DMA_BIDIRECTIONAL);17291729- tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);17301730- tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);17311731-17321732- /* Set up entry for this TFD in Tx byte-count array */17331733- iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));17341734-17351735- dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,17361736- DMA_BIDIRECTIONAL);17371737-17381738- trace_iwlwifi_dev_tx(trans->dev, skb,17391739- &txq->tfds[txq->q.write_ptr],17401740- sizeof(struct iwl_tfd),17411741- &dev_cmd->hdr, firstlen,17421742- skb->data + hdr_len, secondlen);17431743- trace_iwlwifi_dev_tx_data(trans->dev, skb,17441744- skb->data + hdr_len, secondlen);1745163617461637 /* start timer if queue currently empty */17471638 if (txq->need_update && q->read_ptr == q->write_ptr &&