pull request: iwlwifi-next 2014-07-22
Hi John,
here is a pull request for 3.17.
I have the usual amount of BT Coex stuff. Arik continues to work on TDLS and Ariej contributes a few things for HS2.0. I added a few more things to the firmware debugging infrastructure. Eran fixes a small bug - pretty normal content.
I merged iwlwifi-fixes to avoid a conflict. I also merged wireless-next because I needed some bits from mac80211. Let me know if this causes you any trouble!
The following changes since commit a006827a152c3f4d09324157096c8f89cf7ddca3:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next (2014-07-22 13:49:34 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git for-john
for you to fetch changes up to f697267f827516fba4d0c325ed1db1e72f402f11:
----------------------------------------------------------------
Ariej Marjieh (3):
iwlwifi: mvm: Enabling Aux Queue
iwlwifi: mvm: Define AUX ROC Command
iwlwifi: mvm: add Aux ROC request/response flow
Arik Nemtsov (1):
iwlwifi: mvm: teardown TDLS peers during chan-switch and AP DCM
Eliad Peller (3):
iwlwifi: mvm: pass beacons from foreign APs
iwlwifi: mvm: add some missing iwl_mvm_ref_sync() calls
iwlwifi: mvm: wait for handlers when stopping scans
Emmanuel Grumbach (13):
iwlwifi: mvm: fix merge damage
iwlwifi: mvm: BT Coex - fix TLC with old API
iwlwifi: fix Kconfig issues
iwlwifi: mvm: use C99 initializers for add_sta
iwlwifi: mvm: BT Coex - fix the ACK / CTS kill mask
iwlwifi: mvm: BT Coex - don't change AP SMPS mode
iwlwifi: fix inconsistency about power_save module parameter
iwlwifi: split fw-error-dump between transport and mvm
iwlwifi: dump periphery registers to fw-error-dump
iwlwifi: dump CSRs to fw-error-dump
iwlwifi: mvm: reset beacon filtering and BT Coex data upon FW restart Merge branch 'iwlwifi-fixes' into iwlwifi-next
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
Eran Harary (2):
iwlwifi: mvm: minor change in debug print
iwlwifi: mvm: update smart fifo / beacon filtering upon association
Eytan Lifshitz (1):
iwlwifi: mvm: fix wrong offset while reading from NVM
Oren Givon (1):
iwlwifi: add max RX aggregation size
drivers/net/wireless/iwlwifi/Kconfig | 25 +-- drivers/net/wireless/iwlwifi/iwl-8000.c | 4 + drivers/net/wireless/iwlwifi/iwl-config.h | 2 + drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 17 +- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +-- drivers/net/wireless/iwlwifi/mvm/coex.c | 193 ++++++++++------------ drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 119 +++----------- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 104 +++++++++--- drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h | 2 + drivers/net/wireless/iwlwifi/mvm/fw-api.h | 67 ++++++++ drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 15 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 383 +++++++++++++++++++++++++++++++++----------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 52 +++++- drivers/net/wireless/iwlwifi/mvm/nvm.c | 4 +- drivers/net/wireless/iwlwifi/mvm/ops.c | 14 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 24 +-- drivers/net/wireless/iwlwifi/mvm/time-event.c | 89 ++++++++-- drivers/net/wireless/iwlwifi/mvm/tt.c | 12 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 10 ++ drivers/net/wireless/iwlwifi/pcie/trans.c | 202 ++++++++++++++++++++++- 21 files changed, 966 insertions(+), 395 deletions(-)
PATCH 1/20 iwlwifi: mvm: BT Coex - fix TLC with old API
From: Emmanuel Grumbach <[email protected]>
A copy paste issue broke the rate control when a firmware with the old API is used.
--- drivers/net/wireless/iwlwifi/mvm/coex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/mvm/coex.c +1 -1
@@ -1150,7 +1150,7 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,enum iwl_bt_coex_lut_type lut_type;if (!(mvm->fw->ucode_capa.api[0 ] &IWL_UCODE_TLV_API_BT_COEX_SPLIT )) -return iwl_mvm_coex_agg_time_limit_old (mvm, sta); +return iwl_mvm_bt_coex_is_mimo_allowed_old (mvm, sta);if (IWL_COEX_IS_TTC_ON (mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))return true;
Signature · 1 line
1.8.3.2
PATCH 2/20 iwlwifi: add max RX aggregation size
In reply to Emmanuel GrumbachFrom: Oren Givon <[email protected]>
Allow to configure the maximal Rx AMPDU size per device.
--- drivers/net/wireless/iwlwifi/iwl-8000.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-config.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +++ 3 files changed, 9 insertions(+)
drivers/net/wireless/iwlwifi/iwl-8000.c +4 -0
@@ -85,6 +85,9 @@#define NVM_HW_SECTION_NUM_FAMILY_8000 10#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin" +/* Max SDIO RX aggregation size of the ADDBA request/response */ +#define MAX_RX_AGG_SIZE_8260_SDIO 28 +static const struct iwl_base_params iwl8000_base_params = { .eeprom_size =OTP_LOW_IMAGE_SIZE_FAMILY_8000 , .num_of_queues =IWLAGN_NUM_QUEUES ,
@@ -129,6 +132,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, + .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, };MODULE_FIRMWARE (IWL8000_MODULE_FIRMWARE (IWL8000_UCODE_API_OK ));
drivers/net/wireless/iwlwifi/iwl-config.h +2 -0
@@ -240,6 +240,7 @@ struct iwl_pwr_tx_backoff {* @d0i3: device uses d0i3 instead of d3 * @nvm_hw_section_num: the ID of the HW NVM section * @pwr_tx_backoffs: translation table between power limits and backoffs +* @max_rx_agg_size: max RX aggregation size of the ADDBA request/response * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs
@@ -276,6 +277,7 @@ struct iwl_cfg {const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;bool no_power_up_nic_in_init;const char *default_nvm_file; +unsigned int max_rx_agg_size; };/*
drivers/net/wireless/iwlwifi/mvm/ops.c +3 -0
@@ -391,6 +391,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,if (!hw)return NULL ; +if (cfg->max_rx_agg_size) + hw->max_rx_aggregation_subframes = cfg->max_rx_agg_size; + op_mode = hw->priv; op_mode->ops = &iwl_mvm_ops;
Signature · 1 line
1.8.3.2
PATCH 3/20 iwlwifi: fix Kconfig issues
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Randy fixes a few issues in iwlwifi's Kconfig. Because of this, 'Debugging options' was not indented under iwlwifi using menuconfig.
I added a few other fixes on the way, like the link to the website and added 7265 in the supported NICs.
--- drivers/net/wireless/iwlwifi/Kconfig | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/net/wireless/iwlwifi/Kconfig +13 -12
@@ -20,16 +20,17 @@ config IWLWIFI Intel 2000 Series Wi-Fi Adapters Intel 7260 Wi-Fi Adapter Intel 3160 Wi-Fi Adapter + Intel 7265 Wi-Fi Adapter This driver uses the kernel's mac80211 subsystem. - In order to use this driver, you will need a microcode (uCode) + In order to use this driver, you will need a firmware image for it. You can obtain the microcode from: - <http://intellinuxwireless.org/>. + <http://wireless.kernel.org/en/users/Drivers/iwlwifi>. - The microcode is typically installed in /lib/firmware. You can + The firmware is typically installed in /lib/firmware. You can look in the hotplug script /etc/hotplug/firmware.agent to determine which directory FIRMWARE_DIR is set to when the script runs.
@@ -39,9 +40,10 @@ config IWLWIFI say M here and read <file:Documentation/kbuild/modules.txt>. The module will be called iwlwifi. +if IWLWIFI + config IWLWIFI_LEDS bool - depends on IWLWIFI depends on LEDS_CLASS=y || LEDS_CLASS=IWLWIFI select LEDS_TRIGGERS select MAC80211_LEDS
@@ -49,7 +51,7 @@ config IWLWIFI_LEDS config IWLDVM tristate "Intel Wireless WiFi DVM Firmware support" - depends on IWLWIFI + depends on m default IWLWIFI help This is the driver that supports the DVM firmware which is
@@ -58,7 +60,7 @@ config IWLDVM config IWLMVM tristate "Intel Wireless WiFi MVM Firmware support" - depends on IWLWIFI + depends on m help This is the driver that supports the MVM firmware which is currently only available for 7260 and 3160 devices.
@@ -70,7 +72,7 @@ config IWLWIFI_OPMODE_MODULAR default y if IWLMVM=m comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" - depends on IWLWIFI && IWLDVM=n && IWLMVM=n + depends on IWLDVM=n && IWLMVM=n config IWLWIFI_BCAST_FILTERING bool "Enable broadcast filtering"
@@ -86,11 +88,9 @@ config IWLWIFI_BCAST_FILTERING expect incoming broadcasts for their normal operations. menu "Debugging Options" - depends on IWLWIFI config IWLWIFI_DEBUG bool "Enable full debugging output in the iwlwifi driver" - depends on IWLWIFI ---help--- This option will enable debug tracing output for the iwlwifi drivers
@@ -115,7 +115,7 @@ config IWLWIFI_DEBUG config IWLWIFI_DEBUGFS bool "iwlwifi debugfs support" - depends on IWLWIFI && MAC80211_DEBUGFS + depends on MAC80211_DEBUGFS ---help--- Enable creation of debugfs files for the iwlwifi drivers. This is a low-impact option that allows getting insight into the
@@ -123,13 +123,12 @@ config IWLWIFI_DEBUGFS config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE bool "Experimental uCode support" - depends on IWLWIFI && IWLWIFI_DEBUG + depends on IWLWIFI_DEBUG ---help--- Enable use of experimental ucode for testing and debugging. config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" - depends on IWLWIFI depends on EVENT_TRACING help Say Y here to trace all commands, including TX frames and IO
@@ -145,3 +144,5 @@ config IWLWIFI_DEVICE_TRACING If unsure, say Y so we can help you better when problems occur. endmenu + +endif
Signature · 1 line
1.8.3.2
PATCH 4/20 iwlwifi: mvm: use C99 initializers for add_sta
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Instead of code the fixed values, use a C99 initializer.
--- drivers/net/wireless/iwlwifi/mvm/sta.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/net/wireless/iwlwifi/mvm/sta.c +7 -9
@@ -98,23 +98,21 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, bool update) {struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; -struct iwl_mvm_add_sta_cmd add_sta_cmd; +struct iwl_mvm_add_sta_cmd add_sta_cmd = { + .sta_id = mvm_sta->sta_id, + .mac_id_n_color =cpu_to_le32 (mvm_sta->mac_id_n_color), + .add_modify = update ?1 :0 , + .station_flags_msk =cpu_to_le32 (STA_FLG_FAT_EN_MSK | +STA_FLG_MIMO_EN_MSK ), + };int ret;u32 status;u32 agg_size =0 , mpdu_dens =0 ; -memset (&add_sta_cmd,0 ,sizeof (add_sta_cmd)); - - add_sta_cmd.sta_id = mvm_sta->sta_id; - add_sta_cmd.mac_id_n_color =cpu_to_le32 (mvm_sta->mac_id_n_color);if (!update) { add_sta_cmd.tfd_queue_msk =cpu_to_le32 (mvm_sta->tfd_queue_msk);memcpy (&add_sta_cmd.addr, sta->addr,ETH_ALEN ); } - add_sta_cmd.add_modify = update ?1 :0 ; - - add_sta_cmd.station_flags_msk |=cpu_to_le32 (STA_FLG_FAT_EN_MSK | -STA_FLG_MIMO_EN_MSK );switch (sta->bandwidth) {case IEEE80211_STA_RX_BW_160 :
Signature · 1 line
1.8.3.2
PATCH 5/20 iwlwifi: mvm: fix wrong offset while reading from NVM
In reply to Emmanuel GrumbachFrom: Eytan Lifshitz <[email protected]>
As part of thermal throttling, some data is being read from NVM. The offset is in words, but was addressed as in octets. fixed.
--- drivers/net/wireless/iwlwifi/mvm/tt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/iwlwifi/mvm/tt.c +3 -3
@@ -140,9 +140,9 @@ static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)/* TODO: move parsing to NVM code */ calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION ].data; - ptat = calib[OTP_DTS_DIODE_DEVIATION ]; - pa1 = calib[OTP_DTS_DIODE_DEVIATION +1 ]; - pa2 = calib[OTP_DTS_DIODE_DEVIATION +2 ]; + ptat = calib[OTP_DTS_DIODE_DEVIATION *2 ]; + pa1 = calib[OTP_DTS_DIODE_DEVIATION *2 +1 ]; + pa2 = calib[OTP_DTS_DIODE_DEVIATION *2 +2 ];/* get the median: */ if (ptat > pa1) {
Signature · 1 line
1.8.3.2
PATCH 6/20 iwlwifi: mvm: add some missing iwl_mvm_ref_sync() calls
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
Add iwl_mvm_ref_sync() calls (with new ref types) to flows that might access the device directly.
These calls make sure the device is out of d0i3, and the bus is available for direct access.
Since some of these functions are reentrant, convert the refs_bitmap to a ref counter, so multiple refs of the same type could be taken concurrently.
--- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 43 +++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 66 ++++++++++++++++++++++++----- drivers/net/wireless/iwlwifi/mvm/mvm.h | 15 ++++++- drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +- drivers/net/wireless/iwlwifi/mvm/tt.c | 6 +++ 5 files changed, 110 insertions(+), 23 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +34 -9
@@ -830,8 +830,14 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,static ssize_t iwl_dbgfs_fw_nmi_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { +int ret =iwl_mvm_ref_sync (mvm,IWL_MVM_REF_NMI ); +if (ret) +return ret; +iwl_force_nmi (mvm->trans); +iwl_mvm_unref (mvm,IWL_MVM_REF_NMI ); +return count; }
@@ -1115,11 +1121,11 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, }#endif -#define PRINT_MVM_REF (ref) do { \ - if (test_bit(ref, mvm->ref_bitmap)) \ - pos += scnprintf(buf + pos, bufsz - pos, \ - "\t(0x%lx) %s\n", \ - BIT(ref), #ref); \ +#define PRINT_MVM_REF (ref) do { \ + if (mvm->refs[ref]) \ + pos += scnprintf(buf + pos, bufsz - pos, \ + "\t(0x%lx): %d %s\n", \ + BIT(ref), mvm->refs[ref], #ref); \ } while (0) static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
@@ -1127,12 +1133,17 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_mvm *mvm = file->private_data; -int pos =0 ; +int i, pos =0 ;char buf[256 ];const size_t bufsz =sizeof (buf); +u32 refs =0 ; + +for (i =0 ; i <IWL_MVM_REF_COUNT ; i++) +if (mvm->refs[i]) + refs |=BIT (i); - pos +=scnprintf (buf + pos, bufsz - pos,"taken mvm refs: 0x%lx\n" , - mvm->ref_bitmap[0 ]); + pos +=scnprintf (buf + pos, bufsz - pos,"taken mvm refs: 0x%x\n" , + refs);PRINT_MVM_REF (IWL_MVM_REF_UCODE_DOWN );PRINT_MVM_REF (IWL_MVM_REF_SCAN );
@@ -1158,7 +1169,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,mutex_lock (&mvm->mutex); - taken =test_bit (IWL_MVM_REF_USER , mvm->ref_bitmap); + taken = mvm->refs[IWL_MVM_REF_USER ];if (value ==1 && !taken)iwl_mvm_ref (mvm,IWL_MVM_REF_USER );else if (value ==0 && taken)
@@ -1194,14 +1205,21 @@ iwl_dbgfs_prph_reg_read(struct file *file,int pos =0 ;char buf[32 ];const size_t bufsz =sizeof (buf); +int ret;if (!mvm->dbgfs_prph_reg_addr)return -EINVAL ; + ret =iwl_mvm_ref_sync (mvm,IWL_MVM_REF_PRPH_READ ); +if (ret) +return ret; + pos +=scnprintf (buf + pos, bufsz - pos,"Reg 0x%x: (0x%x)\n" , mvm->dbgfs_prph_reg_addr,iwl_read_prph (mvm->trans, mvm->dbgfs_prph_reg_addr)); +iwl_mvm_unref (mvm,IWL_MVM_REF_PRPH_READ ); +return simple_read_from_buffer (user_buf, count, ppos, buf, pos); }
@@ -1211,6 +1229,7 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf, {u8 args;u32 value; +int ret; args =sscanf (buf,"%i %i" , &mvm->dbgfs_prph_reg_addr, &value);/* if we only want to set the reg address - nothing more to do */
@@ -1221,7 +1240,13 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,if (args !=2 )return -EINVAL ; + ret =iwl_mvm_ref_sync (mvm,IWL_MVM_REF_PRPH_WRITE ); +if (ret) +return ret; +iwl_write_prph (mvm->trans, mvm->dbgfs_prph_reg_addr, value); + +iwl_mvm_unref (mvm,IWL_MVM_REF_PRPH_WRITE ); out:return count; }
drivers/net/wireless/iwlwifi/mvm/mac80211.c +55 -11
135 lines not on this page · raw message
drivers/net/wireless/iwlwifi/mvm/mvm.h +13 -2
@@ -249,6 +249,15 @@ enum iwl_mvm_ref_type {IWL_MVM_REF_TX ,IWL_MVM_REF_TX_AGG ,IWL_MVM_REF_ADD_IF , +IWL_MVM_REF_START_AP , +IWL_MVM_REF_BSS_CHANGED , +IWL_MVM_REF_PREPARE_TX , +IWL_MVM_REF_PROTECT_TDLS , +IWL_MVM_REF_CHECK_CTKILL , +IWL_MVM_REF_PRPH_READ , +IWL_MVM_REF_PRPH_WRITE , +IWL_MVM_REF_NMI , +IWL_MVM_REF_TM_CMD ,IWL_MVM_REF_EXIT_WORK , IWL_MVM_REF_COUNT,
@@ -606,8 +615,9 @@ struct iwl_mvm {*/ unsigned long fw_key_table[BITS_TO_LONGS (STA_KEY_MAX_NUM )]; -/* A bitmap of reference types taken by the driver. */ -unsigned long ref_bitmap[BITS_TO_LONGS (IWL_MVM_REF_COUNT )]; +/* references taken by the driver and spinlock protecting them */ +spinlock_t refs_lock; +u8 refs[IWL_MVM_REF_COUNT ];u8 vif_count;
@@ -988,6 +998,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,/* D0i3 */ void iwl_mvm_ref (struct iwl_mvm *mvm,enum iwl_mvm_ref_type ref_type);void iwl_mvm_unref (struct iwl_mvm *mvm,enum iwl_mvm_ref_type ref_type); +int iwl_mvm_ref_sync (struct iwl_mvm *mvm,enum iwl_mvm_ref_type ref_type);void iwl_mvm_d0i3_enable_tx (struct iwl_mvm *mvm,__le16 *qos_seq);int _iwl_mvm_exit_d0i3 (struct iwl_mvm *mvm);
drivers/net/wireless/iwlwifi/mvm/ops.c +2 -1
@@ -428,6 +428,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,INIT_WORK (&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);spin_lock_init (&mvm->d0i3_tx_lock); +spin_lock_init (&mvm->refs_lock);skb_queue_head_init (&mvm->d0i3_tx);init_waitqueue_head (&mvm->d0i3_exit_waitq);
@@ -542,7 +543,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,memset (&mvm->rx_stats,0 ,sizeof (struct mvm_statistics_rx ));/* rpm starts with a taken ref. only set the appropriate bit here. */ -set_bit (IWL_MVM_REF_UCODE_DOWN , mvm->ref_bitmap); + mvm->refs[IWL_MVM_REF_UCODE_DOWN ] =1 ;return op_mode;
drivers/net/wireless/iwlwifi/mvm/tt.c +6 -0
@@ -338,10 +338,16 @@ static void check_exit_ctkill(struct work_struct *work) duration = tt->params->ct_kill_duration; +/* make sure the device is available for direct read/writes */ +if (iwl_mvm_ref_sync (mvm,IWL_MVM_REF_CHECK_CTKILL )) + goto reschedule; +iwl_trans_start_hw (mvm->trans); temp =check_nic_temperature (mvm);iwl_trans_stop_device (mvm->trans); +iwl_mvm_unref (mvm,IWL_MVM_REF_CHECK_CTKILL ); +if (temp <MIN_TEMPERATURE || temp >MAX_TEMPERATURE ) {IWL_DEBUG_TEMP (mvm,"Failed to measure NIC temperature\n" ); goto reschedule;
Signature · 1 line
1.8.3.2
PATCH 7/20 iwlwifi: mvm: Enabling Aux Queue
In reply to Emmanuel GrumbachFrom: Ariej Marjieh <[email protected]>
Enabling the Aux queue and mapping it to FIFO 5. Defining the Aux queue for the Aux station.
--- drivers/net/wireless/iwlwifi/mvm/sta.c | 8 ++++++-- drivers/net/wireless/iwlwifi/mvm/tx.c | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/sta.c +6 -2
@@ -526,8 +526,12 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)lockdep_assert_held (&mvm->mutex); -/* Add the aux station, but without any queues */ - ret =iwl_mvm_allocate_int_sta (mvm, &mvm->aux_sta,0 , +/* Map Aux queue to fifo - needs to happen before adding Aux station */ +iwl_trans_ac_txq_enable (mvm->trans, mvm->aux_queue, +IWL_MVM_TX_FIFO_MCAST ); + +/* Allocate aux station and assign to it the aux queue */ + ret =iwl_mvm_allocate_int_sta (mvm, &mvm->aux_sta,BIT (mvm->aux_queue),NL80211_IFTYPE_UNSPECIFIED );if (ret)return ret;
drivers/net/wireless/iwlwifi/mvm/tx.c +10 -0
@@ -311,6 +311,16 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)return -1 ;/* +* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used +* in 2 different types of vifs, P2P & STATION. P2P uses the offchannel +* queue. STATION (HS2.0) uses the auxiliary context of the FW, +* and hence needs to be sent on the aux queue +*/ +if (IEEE80211_SKB_CB (skb)->hw_queue ==IWL_MVM_OFFCHANNEL_QUEUE && + info->control.vif->type ==NL80211_IFTYPE_STATION ) +IEEE80211_SKB_CB (skb)->hw_queue = mvm->aux_queue; + +/* * If the interface on which frame is sent is the P2P_DEVICE * or an AP/GO interface use the broadcast station associated * with it; otherwise use the AUX station.
Signature · 1 line
1.8.3.2
PATCH 8/20 iwlwifi: mvm: Define AUX ROC Command
In reply to Emmanuel GrumbachFrom: Ariej Marjieh <[email protected]>
Add new AUX ROC command that is intended for HS2.0 purposes. It is used to send ANQP requests on a specific channel.
This command requests the firmware to trigger a time event and remain on a certain channel for a given duration. Triggering the time event is done by using the Aux Framework in the firmware, and makes use of the Aux station (similarly to scan).
--- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 67 +++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
drivers/net/wireless/iwlwifi/mvm/fw-api.h +67 -0
@@ -133,6 +133,7 @@ enum {/* Scan offload */ SCAN_OFFLOAD_REQUEST_CMD =0x51 ,SCAN_OFFLOAD_ABORT_CMD =0x52 , +HOT_SPOT_CMD =0x53 ,SCAN_OFFLOAD_COMPLETE =0x6D ,SCAN_OFFLOAD_UPDATE_PROFILES_CMD =0x6E , SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
@@ -910,6 +911,72 @@ struct iwl_phy_context_cmd {__le32 dsp_cfg_flags; } __packed;/* PHY_CONTEXT_CMD_API_VER_1 */ +/* +* Aux ROC command +* +* Command requests the firmware to create a time event for a certain duration +* and remain on the given channel. This is done by using the Aux framework in +* the FW. +* The command was first used for Hot Spot issues - but can be used regardless +* to Hot Spot. +* +* ( HOT_SPOT_CMD 0x53 ) +* +* @id_and_color: ID and color of the MAC +* @action: action to perform, one of FW_CTXT_ACTION_* +* @event_unique_id: If the action FW_CTXT_ACTION_REMOVE then the +* event_unique_id should be the id of the time event assigned by ucode. +* Otherwise ignore the event_unique_id. +* @sta_id_and_color: station id and color, resumed during "Remain On Channel" +* activity. +* @channel_info: channel info +* @node_addr: Our MAC Address +* @reserved: reserved for alignment +* @apply_time: GP2 value to start (should always be the current GP2 value) +* @apply_time_max_delay: Maximum apply time delay value in TU. Defines max +* time by which start of the event is allowed to be postponed. +* @duration: event duration in TU To calculate event duration: +* timeEventDuration = min(duration, remainingQuota) +*/ +struct iwl_hs20_roc_req { +/* COMMON_INDEX_HDR_API_S_VER_1 hdr */ +__le32 id_and_color; +__le32 action; +__le32 event_unique_id; +__le32 sta_id_and_color; +struct iwl_fw_channel_info channel_info; +u8 node_addr[ETH_ALEN ]; +__le16 reserved; +__le32 apply_time; +__le32 apply_time_max_delay; +__le32 duration; +} __packed;/* HOT_SPOT_CMD_API_S_VER_1 */ + +/* +* values for AUX ROC result values +*/ +enum iwl_mvm_hot_spot { +HOT_SPOT_RSP_STATUS_OK , +HOT_SPOT_RSP_STATUS_TOO_MANY_EVENTS , +HOT_SPOT_MAX_NUM_OF_SESSIONS , +}; + +/* +* Aux ROC command response +* +* In response to iwl_hs20_roc_req the FW sends this command to notify the +* driver the uid of the timevent. +* +* ( HOT_SPOT_CMD 0x53 ) +* +* @event_unique_id: Unique ID of time event assigned by ucode +* @status: Return status 0 is success, all the rest used for specific errors +*/ +struct iwl_hs20_roc_res { +__le32 event_unique_id; +__le32 status; +} __packed;/* HOT_SPOT_RSP_API_S_VER_1 */ +#define IWL_RX_INFO_PHY_CNT 8#define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1#define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff
Signature · 1 line
1.8.3.2
PATCH 9/20 iwlwifi: mvm: add Aux ROC request/response flow
In reply to Emmanuel GrumbachFrom: Ariej Marjieh <[email protected]>
The Remain On Channel framework added to the firmare is a bit like time events. It allows the driver to request the firmware to be on a certain channel for a certain time. Unlike the time events, the ROC infrastructure doesn't need a MAC context in the firmware - it uses a generic context called "auxiliary framework".
This is useful for any offchannel activity that is not bound to a specific MAC.
The flow is synchronized much like with time events:
1) The driver receives an action frame from the wpa_supplicant via nl80211 that requests to be sent offchannel.
2) The driver sends an Aux ROC command (0x53) to the firmware.
3) The firmware responds with the unique id of the time event.
4) When time event starts, the driver puts the frame in the Aux queue.
Special care needs to be taken when the time events ends:
the queue needs to be cleaned-up.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 126 +++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/mvm/mvm.h | 7 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 + drivers/net/wireless/iwlwifi/mvm/time-event.c | 89 +++++++++++++++--- 4 files changed, 208 insertions(+), 16 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +124 -2
@@ -2310,6 +2310,119 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw, } +static bool iwl_mvm_rx_aux_roc (struct iwl_notif_wait_data *notif_wait, +struct iwl_rx_packet *pkt,void *data) +{ +struct iwl_mvm *mvm = + container_of(notif_wait, struct iwl_mvm, notif_wait); +struct iwl_hs20_roc_res *resp; +int resp_len =iwl_rx_packet_payload_len (pkt); +struct iwl_mvm_time_event_data *te_data = data; + +if (WARN_ON (pkt->hdr.cmd !=HOT_SPOT_CMD )) +return true; + +if (WARN_ON_ONCE (resp_len !=sizeof (*resp))) { +IWL_ERR (mvm,"Invalid HOT_SPOT_CMD response\n" ); +return true; + } + + resp = (void *)pkt->data; + +IWL_DEBUG_TE (mvm, +"Aux ROC: Recieved response from ucode: status=%d uid=%d\n" , + resp->status, resp->event_unique_id); + + te_data->uid =le32_to_cpu (resp->event_unique_id); +IWL_DEBUG_TE (mvm,"TIME_EVENT_CMD response - UID = 0x%x\n" , + te_data->uid); + +spin_lock_bh (&mvm->time_event_lock); +list_add_tail (&te_data->list, &mvm->aux_roc_te_list); +spin_unlock_bh (&mvm->time_event_lock); + +return true; +} + +#define AUX_ROC_MAX_DELAY_ON_CHANNEL 5000 +static int iwl_mvm_send_aux_roc_cmd (struct iwl_mvm *mvm, +struct ieee80211_channel *channel, +struct ieee80211_vif *vif, +int duration) +{ +int res, time_reg =DEVICE_SYSTEM_TIME_REG ; +struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif); +struct iwl_mvm_time_event_data *te_data = &mvmvif->hs_time_event_data; +static const u8 time_event_response[] = {HOT_SPOT_CMD }; +struct iwl_notification_wait wait_time_event; +struct iwl_hs20_roc_req aux_roc_req = { + .action =cpu_to_le32 (FW_CTXT_ACTION_ADD ), + .id_and_color = +cpu_to_le32 (FW_CMD_ID_AND_COLOR (MAC_INDEX_AUX ,0 )), + .sta_id_and_color =cpu_to_le32 (mvm->aux_sta.sta_id), +/* Set the channel info data */ + .channel_info.band = (channel->band ==IEEE80211_BAND_2GHZ ) ? +PHY_BAND_24 :PHY_BAND_5 , + .channel_info.channel = channel->hw_value, + .channel_info.width =PHY_VHT_CHANNEL_MODE20 , +/* Set the time and duration */ + .apply_time =cpu_to_le32 (iwl_read_prph (mvm->trans, time_reg)), + .apply_time_max_delay = +cpu_to_le32 (MSEC_TO_TU (AUX_ROC_MAX_DELAY_ON_CHANNEL )), + .duration =cpu_to_le32 (MSEC_TO_TU (duration)), + }; + +/* Set the node address */ +memcpy (aux_roc_req.node_addr, vif->addr,ETH_ALEN ); + + te_data->vif = vif; + te_data->duration = duration; + te_data->id =HOT_SPOT_CMD ; + +lockdep_assert_held (&mvm->mutex); + +spin_lock_bh (&mvm->time_event_lock); +list_add_tail (&te_data->list, &mvm->time_event_list); +spin_unlock_bh (&mvm->time_event_lock); + +/* +* Use a notification wait, which really just processes the +* command response and doesn't wait for anything, in order +* to be able to process the response and get the UID inside +* the RX path. Using CMD_WANT_SKB doesn't work because it +* stores the buffer and then wakes up this thread, by which +* time another notification (that the time event started) +* might already be processed unsuccessfully. +*/ +iwl_init_notification_wait (&mvm->notif_wait, &wait_time_event, + time_event_response, +ARRAY_SIZE (time_event_response), + iwl_mvm_rx_aux_roc, te_data); + + res =iwl_mvm_send_cmd_pdu (mvm,HOT_SPOT_CMD ,0 ,sizeof (aux_roc_req), + &aux_roc_req); + +if (res) { +IWL_ERR (mvm,"Couldn't send HOT_SPOT_CMD: %d\n" , res); +iwl_remove_notification (&mvm->notif_wait, &wait_time_event); + goto out_clear_te; + } + +/* No need to wait for anything, so just pass 1 (0 isn't valid) */ + res =iwl_wait_notification (&mvm->notif_wait, &wait_time_event,1 ); +/* should never fail */ +WARN_ON_ONCE (res); + +if (res) { + out_clear_te: +spin_lock_bh (&mvm->time_event_lock); +iwl_mvm_te_clear_data (mvm, te_data); +spin_unlock_bh (&mvm->time_event_lock); + } + +return res; +} + static int iwl_mvm_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *channel,
@@ -2325,8 +2438,17 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,IWL_DEBUG_MAC80211 (mvm,"enter (%d, %d, %d)\n" , channel->hw_value, duration, type); -if (vif->type !=NL80211_IFTYPE_P2P_DEVICE ) { -IWL_ERR (mvm,"vif isn't a P2P_DEVICE: %d\n" , vif->type); +switch (vif->type) { +case NL80211_IFTYPE_STATION : +/* Use aux roc framework (HS20) */ + ret =iwl_mvm_send_aux_roc_cmd (mvm, channel, + vif, duration); +return ret; +case NL80211_IFTYPE_P2P_DEVICE : +/* handle below */ +break ; +default : +IWL_ERR (mvm,"vif isn't P2P_DEVICE: %d\n" , vif->type);return -EINVAL ; }
drivers/net/wireless/iwlwifi/mvm/mvm.h +7 -0
@@ -82,6 +82,8 @@/* RSSI offset for WkP */ #define IWL_RSSI_OFFSET 50#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8 +/* A TimeUnit is 1024 microsecond */ +#define MSEC_TO_TU (_msec) (_msec*1000/1024)/* * The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0"
@@ -336,6 +338,7 @@ struct iwl_mvm_vif {*/ struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS ];struct iwl_mvm_time_event_data time_event_data; +struct iwl_mvm_time_event_data hs_time_event_data;struct iwl_mvm_int_sta bcast_sta;
@@ -669,6 +672,9 @@ struct iwl_mvm {u8 bt_tx_prio;enum iwl_bt_force_ant_mode bt_force_ant_mode; +/* Aux ROC */ +struct list_head aux_roc_te_list; +/* Thermal Throttling and CTkill */ struct iwl_mvm_tt_mgmt thermal_throttle;s32 temperature;/* Celsius */
@@ -707,6 +713,7 @@ enum iwl_mvm_status {IWL_MVM_STATUS_ROC_RUNNING ,IWL_MVM_STATUS_IN_HW_RESTART ,IWL_MVM_STATUS_IN_D0I3 , + IWL_MVM_STATUS_ROC_AUX_RUNNING, };static inline bool iwl_mvm_is_radio_killed (struct iwl_mvm *mvm)
drivers/net/wireless/iwlwifi/mvm/ops.c +2 -0
@@ -289,6 +289,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {CMD (MATCH_FOUND_NOTIFICATION ),CMD (SCAN_OFFLOAD_REQUEST_CMD ),CMD (SCAN_OFFLOAD_ABORT_CMD ), +CMD (HOT_SPOT_CMD ),CMD (SCAN_OFFLOAD_COMPLETE ),CMD (SCAN_OFFLOAD_UPDATE_PROFILES_CMD ), CMD(SCAN_ITERATION_COMPLETE),
@@ -419,6 +420,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,mutex_init (&mvm->d0i3_suspend_mutex);spin_lock_init (&mvm->async_handlers_lock);INIT_LIST_HEAD (&mvm->time_event_list); +INIT_LIST_HEAD (&mvm->aux_roc_te_list);INIT_LIST_HEAD (&mvm->async_handlers_list);spin_lock_init (&mvm->time_event_lock);
drivers/net/wireless/iwlwifi/mvm/time-event.c +75 -14
128 lines not on this page · raw message
Signature · 1 line
1.8.3.2
PATCH 10/20 iwlwifi: mvm: BT Coex - fix the ACK / CTS kill mask
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
According to new requirements, the ACK / CTS kill mask is not related to reduced TX power anymore. This allows to remove the code that tracked reduced TX power enablement across different interfaces.
The ACK / CTS kill mask is now fetch from a table. It depends on the Activity grading (activity from BT) and on the Look Up Table (LUT) type.
--- drivers/net/wireless/iwlwifi/mvm/coex.c | 170 +++++++++++-------------- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 102 +++------------ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 21 ++- drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h | 2 + drivers/net/wireless/iwlwifi/mvm/mvm.h | 13 +- 5 files changed, 115 insertions(+), 193 deletions(-)
drivers/net/wireless/iwlwifi/mvm/coex.c +75 -95
@@ -72,16 +72,56 @@#define BT_ANTENNA_COUPLING_THRESHOLD (30) -const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX ] = { - [BT_KILL_MSK_DEFAULT ] =0xffff0000 , - [BT_KILL_MSK_SCO_HID_A2DP ] =0xffffffff , - [BT_KILL_MSK_REDUCED_TXPOW ] =0 , +const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX ] = { + [BT_KILL_MSK_DEFAULT ] =0xfffffc00 , + [BT_KILL_MSK_NEVER ] =0xffffffff , + [BT_KILL_MSK_ALWAYS ] =0 , }; -const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX ] = { - [BT_KILL_MSK_DEFAULT ] =0xffff0000 , - [BT_KILL_MSK_SCO_HID_A2DP ] =0xffffffff , - [BT_KILL_MSK_REDUCED_TXPOW ] =0 , +const u8 iwl_bt_cts_kill_msk[BT_MAX_AG ][BT_COEX_MAX_LUT ] = { + { +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , + }, + { +BT_KILL_MSK_NEVER , +BT_KILL_MSK_NEVER , +BT_KILL_MSK_NEVER , + }, + { +BT_KILL_MSK_NEVER , +BT_KILL_MSK_NEVER , +BT_KILL_MSK_NEVER , + }, + { +BT_KILL_MSK_DEFAULT , +BT_KILL_MSK_NEVER , +BT_KILL_MSK_DEFAULT , + }, +}; + +const u8 iwl_bt_ack_kill_msk[BT_MAX_AG ][BT_COEX_MAX_LUT ] = { + { +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , + }, + { +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , + }, + { +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_ALWAYS , + }, + { +BT_KILL_MSK_DEFAULT , +BT_KILL_MSK_ALWAYS , +BT_KILL_MSK_DEFAULT , + }, };static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE ] = {
@@ -611,54 +651,43 @@ send_cmd:return ret; } -static int iwl_mvm_bt_udpate_sw_boost (struct iwl_mvm *mvm, -bool reduced_tx_power) +static int iwl_mvm_bt_udpate_sw_boost (struct iwl_mvm *mvm) { -enum iwl_bt_kill_msk bt_kill_msk; -struct iwl_bt_coex_sw_boost_update_cmd cmd = {};struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; +u32 primary_lut =le32_to_cpu (notif->primary_ch_lut); +u32 secondary_lut =le32_to_cpu (notif->secondary_ch_lut); +u32 ag =le32_to_cpu (notif->bt_activity_grading); +struct iwl_bt_coex_sw_boost_update_cmd cmd = {}; +u8 ack_kill_msk[NUM_PHY_CTX ] = {}; +u8 cts_kill_msk[NUM_PHY_CTX ] = {}; +int i;lockdep_assert_held (&mvm->mutex); -if (reduced_tx_power) { -/* Reduced Tx power has precedence on the type of the profile */ - bt_kill_msk =BT_KILL_MSK_REDUCED_TXPOW ; - }else { -/* Low latency BT profile is active: give higher prio to BT */ -if (BT_MBOX_MSG (notif,3 ,SCO_STATE ) || -BT_MBOX_MSG (notif,3 ,A2DP_STATE ) || -BT_MBOX_MSG (notif,3 ,SNIFF_STATE )) - bt_kill_msk =BT_KILL_MSK_SCO_HID_A2DP ; -else - bt_kill_msk =BT_KILL_MSK_DEFAULT ; - } + ack_kill_msk[0 ] = iwl_bt_ack_kill_msk[ag][primary_lut]; + cts_kill_msk[0 ] = iwl_bt_cts_kill_msk[ag][primary_lut]; -IWL_DEBUG_COEX (mvm, -"Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n" , - bt_kill_msk, -BT_MBOX_MSG (notif,3 ,SCO_STATE ) ?"" :"in" , -BT_MBOX_MSG (notif,3 ,A2DP_STATE ) ?"" :"in" , -BT_MBOX_MSG (notif,3 ,SNIFF_STATE ) ?"" :"in" ); + ack_kill_msk[1 ] = iwl_bt_ack_kill_msk[ag][secondary_lut]; + cts_kill_msk[1 ] = iwl_bt_cts_kill_msk[ag][secondary_lut];/* Don't send HCMD if there is no update */ -if (bt_kill_msk == mvm->bt_kill_msk) +if (!memcmp (ack_kill_msk, mvm->bt_ack_kill_msk,sizeof (ack_kill_msk)) || + !memcmp (cts_kill_msk, mvm->bt_cts_kill_msk,sizeof (cts_kill_msk)))return 0 ; - mvm->bt_kill_msk = bt_kill_msk; +memcpy (mvm->bt_ack_kill_msk, ack_kill_msk, +sizeof (mvm->bt_ack_kill_msk)); +memcpy (mvm->bt_cts_kill_msk, cts_kill_msk, +sizeof (mvm->bt_cts_kill_msk)); - cmd.boost_values[0 ].kill_ack_msk = -cpu_to_le32 (iwl_bt_ack_kill_msk[bt_kill_msk]); - cmd.boost_values[0 ].kill_cts_msk = -cpu_to_le32 (iwl_bt_cts_kill_msk[bt_kill_msk]); +BUILD_BUG_ON (ARRAY_SIZE (ack_kill_msk) <ARRAY_SIZE (cmd.boost_values)); - cmd.boost_values[1 ].kill_ack_msk = cmd.boost_values[0 ].kill_ack_msk; - cmd.boost_values[2 ].kill_cts_msk = cmd.boost_values[0 ].kill_cts_msk; - cmd.boost_values[1 ].kill_ack_msk = cmd.boost_values[0 ].kill_ack_msk; - cmd.boost_values[2 ].kill_cts_msk = cmd.boost_values[0 ].kill_cts_msk; - -IWL_DEBUG_COEX (mvm,"ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n" , - iwl_bt_ack_kill_msk[bt_kill_msk], - iwl_bt_cts_kill_msk[bt_kill_msk]); +for (i =0 ; i <ARRAY_SIZE (cmd.boost_values); i++) { + cmd.boost_values[i].kill_ack_msk = +cpu_to_le32 (iwl_bt_ctl_kill_msk[ack_kill_msk[i]]); + cmd.boost_values[i].kill_cts_msk = +cpu_to_le32 (iwl_bt_ctl_kill_msk[cts_kill_msk[i]]); + }return iwl_mvm_send_cmd_pdu (mvm,BT_COEX_UPDATE_SW_BOOST ,0 ,sizeof (cmd), &cmd);
@@ -700,8 +729,6 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,struct iwl_bt_iterator_data {struct iwl_bt_coex_profile_notif *notif;struct iwl_mvm *mvm; -u32 num_bss_ifaces; -bool reduced_tx_power;struct ieee80211_chanctx_conf *primary;struct ieee80211_chanctx_conf *secondary;bool primary_ll;
@@ -737,8 +764,6 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,switch (vif->type) {case NL80211_IFTYPE_STATION : -/* Count BSSes vifs */ - data->num_bss_ifaces++;/* default smps_mode for BSS / P2P client is AUTOMATIC */ smps_mode =IEEE80211_SMPS_AUTOMATIC ;break ;
@@ -750,9 +775,6 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, smps_mode);return ; } - -/* the Ack / Cts kill mask must be default if AP / GO */ - data->reduced_tx_power = false;break ;default :return ;
@@ -766,7 +788,6 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,/* ... relax constraints and disable rssi events */ iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , smps_mode); - data->reduced_tx_power = false;if (vif->type ==NL80211_IFTYPE_STATION ) {iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, false);
@@ -846,7 +867,6 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,if (iwl_get_coex_type (mvm, vif) ==BT_COEX_LOOSE_LUT || mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc ||le32_to_cpu (mvm->last_bt_notif.bt_activity_grading) ==BT_OFF ) { - data->reduced_tx_power = false;iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, false);iwl_mvm_bt_coex_enable_rssi_event (mvm, vif, false,0 );return ;
@@ -861,23 +881,9 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH ) {if (iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, true))IWL_ERR (mvm,"Couldn't send BT_CONFIG cmd\n" ); - -/* -* bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the -* BSS / P2P clients have rssi above threshold. -* We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before -* the iteration, if one interface's rssi isn't good enough, -* bt_kill_msk will be set to default values. -*/ }else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH ) {if (iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, false))IWL_ERR (mvm,"Couldn't send BT_CONFIG cmd\n" ); - -/* -* One interface hasn't rssi above threshold, bt_kill_msk must -* be set to default values. -*/ - data->reduced_tx_power = false; }/* Begin to monitor the RSSI: it may influence the reduced Tx power */
@@ -889,7 +895,6 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)struct iwl_bt_iterator_data data = { .mvm = mvm, .notif = &mvm->last_bt_notif, - .reduced_tx_power = true, };struct iwl_bt_coex_ci_cmd cmd = {};u8 ci_bw_idx;
@@ -959,14 +964,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)memcpy (&mvm->last_bt_ci_cmd, &cmd,sizeof (cmd)); } -/* -* If there are no BSS / P2P client interfaces, reduced Tx Power is -* irrelevant since it is based on the RSSI coming from the beacon. -* Use BT_KILL_MSK_DEFAULT in that case. -*/ - data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; - -if (iwl_mvm_bt_udpate_sw_boost (mvm, data.reduced_tx_power)) +if (iwl_mvm_bt_udpate_sw_boost (mvm))IWL_ERR (mvm,"Failed to update the ctrl_kill_msk\n" ); }
@@ -1035,16 +1033,6 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,return ; mvmsta =iwl_mvm_sta_from_mac80211 (sta); - - data->num_bss_ifaces++; - -/* -* This interface doesn't support reduced Tx power (because of low -* RSSI probably), then set bt_kill_msk to default values. -*/ -if (!mvmsta->bt_reduced_txpower) - data->reduced_tx_power = false; -/* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */ } void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -1053,7 +1041,6 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;struct iwl_bt_iterator_data data = { .mvm = mvm, - .reduced_tx_power = true, };int ret;
@@ -1100,14 +1087,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvm->hw,IEEE80211_IFACE_ITER_NORMAL , iwl_mvm_bt_rssi_iterator, &data); -/* -* If there are no BSS / P2P client interfaces, reduced Tx Power is -* irrelevant since it is based on the RSSI coming from the beacon. -* Use BT_KILL_MSK_DEFAULT in that case. -*/ - data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; - -if (iwl_mvm_bt_udpate_sw_boost (mvm, data.reduced_tx_power)) +if (iwl_mvm_bt_udpate_sw_boost (mvm))IWL_ERR (mvm,"Failed to update the ctrl_kill_msk\n" ); }
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +15 -87
204 lines not on this page · raw message
drivers/net/wireless/iwlwifi/mvm/debugfs.c +15 -6
@@ -514,9 +514,9 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf, pos +=scnprintf (buf+pos, bufsz-pos,"BT Configuration CMD\n" ); pos +=scnprintf (buf+pos, bufsz-pos,"\tACK Kill Mask 0x%08x\n" , - iwl_bt_ack_kill_msk[mvm->bt_kill_msk]); + iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0 ]]); pos +=scnprintf (buf+pos, bufsz-pos,"\tCTS Kill Mask 0x%08x\n" , - iwl_bt_cts_kill_msk[mvm->bt_kill_msk]); + iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0 ]]); }else {struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
@@ -531,10 +531,19 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf, le64_to_cpu(cmd->bt_secondary_ci)); pos +=scnprintf (buf+pos, bufsz-pos,"BT Configuration CMD\n" ); - pos +=scnprintf (buf+pos, bufsz-pos,"\tACK Kill Mask 0x%08x\n" , - iwl_bt_ack_kill_msk[mvm->bt_kill_msk]); - pos +=scnprintf (buf+pos, bufsz-pos,"\tCTS Kill Mask 0x%08x\n" , - iwl_bt_cts_kill_msk[mvm->bt_kill_msk]); + pos +=scnprintf (buf+pos, bufsz-pos, +"\tPrimary: ACK Kill Mask 0x%08x\n" , + iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0 ]]); + pos +=scnprintf (buf+pos, bufsz-pos, +"\tPrimary: CTS Kill Mask 0x%08x\n" , + iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0 ]]); + pos +=scnprintf (buf+pos, bufsz-pos, +"\tSecondary: ACK Kill Mask 0x%08x\n" , + iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[1 ]]); + pos +=scnprintf (buf+pos, bufsz-pos, +"\tSecondary: CTS Kill Mask 0x%08x\n" , + iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[1 ]]); + }mutex_unlock (&mvm->mutex);
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h +2 -0
@@ -385,6 +385,8 @@ enum iwl_bt_activity_grading {BT_ON_NO_CONNECTION =1 ,BT_LOW_TRAFFIC =2 ,BT_HIGH_TRAFFIC =3 , + + BT_MAX_AG, }; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */ enum iwl_bt_ci_compliance {
drivers/net/wireless/iwlwifi/mvm/mvm.h +8 -5
@@ -660,7 +660,8 @@ struct iwl_mvm {wait_queue_head_t d0i3_exit_waitq;/* BT-Coex */ -u8 bt_kill_msk; +u8 bt_ack_kill_msk[NUM_PHY_CTX ]; +u8 bt_cts_kill_msk[NUM_PHY_CTX ];struct iwl_bt_coex_profile_notif_old last_bt_notif_old;struct iwl_bt_coex_ci_cmd_old last_bt_ci_cmd_old;
@@ -1047,12 +1048,14 @@ int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,enum iwl_bt_kill_msk {BT_KILL_MSK_DEFAULT , -BT_KILL_MSK_SCO_HID_A2DP , -BT_KILL_MSK_REDUCED_TXPOW , +BT_KILL_MSK_NEVER , +BT_KILL_MSK_ALWAYS ,BT_KILL_MSK_MAX , }; -extern const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX ]; -extern const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX ]; + +extern const u8 iwl_bt_ack_kill_msk[BT_MAX_AG ][BT_COEX_MAX_LUT ]; +extern const u8 iwl_bt_cts_kill_msk[BT_MAX_AG ][BT_COEX_MAX_LUT ]; +extern const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX ];/* beacon filtering */ #ifdef CONFIG_IWLWIFI_DEBUGFS
Signature · 1 line
1.8.3.2
PATCH 11/20 iwlwifi: mvm: BT Coex - don't change AP SMPS mode
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Leave it to default instead - regardless of the BT activity.
--- drivers/net/wireless/iwlwifi/mvm/coex.c | 21 ++++++++------------- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 17 +++++++---------- 2 files changed, 15 insertions(+), 23 deletions(-)
drivers/net/wireless/iwlwifi/mvm/coex.c +8 -13
@@ -768,13 +768,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, smps_mode =IEEE80211_SMPS_AUTOMATIC ;break ;case NL80211_IFTYPE_AP : -/* default smps_mode for AP / GO is OFF */ - smps_mode =IEEE80211_SMPS_OFF ; -if (!mvmvif->ap_ibss_active) { -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , - smps_mode); +if (!mvmvif->ap_ibss_active)return ; - }break ;default :return ;
@@ -785,10 +780,10 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,/* If channel context is invalid or not on 2.4GHz .. */ if ((!chanctx_conf || chanctx_conf->def.chan->band !=IEEE80211_BAND_2GHZ )) { -/* ... relax constraints and disable rssi events */ -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , - smps_mode);if (vif->type ==NL80211_IFTYPE_STATION ) { +/* ... relax constraints and disable rssi events */ +iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , + smps_mode);iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, false);iwl_mvm_bt_coex_enable_rssi_event (mvm, vif, false,0 );
@@ -800,9 +795,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,if (bt_activity_grading >=BT_HIGH_TRAFFIC ) smps_mode =IEEE80211_SMPS_STATIC ;else if (bt_activity_grading >=BT_LOW_TRAFFIC ) - smps_mode = vif->type ==NL80211_IFTYPE_AP ? -IEEE80211_SMPS_OFF : -IEEE80211_SMPS_DYNAMIC ; + smps_mode =IEEE80211_SMPS_DYNAMIC ;/* relax SMPS contraints for next association */ if (!vif->bss_conf.assoc)
@@ -816,7 +809,9 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,"mac %d: bt_activity_grading %d smps_req %d\n" , mvmvif->id, bt_activity_grading, smps_mode); -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , smps_mode); +if (vif->type ==NL80211_IFTYPE_STATION ) +iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , + smps_mode);/* low latency is always primary */ if (iwl_mvm_vif_low_latency (mvmvif)) {
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +7 -10
@@ -793,13 +793,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, smps_mode =IEEE80211_SMPS_AUTOMATIC ;break ;case NL80211_IFTYPE_AP : -/* default smps_mode for AP / GO is OFF */ - smps_mode =IEEE80211_SMPS_OFF ; -if (!mvmvif->ap_ibss_active) { -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , - smps_mode); +if (!mvmvif->ap_ibss_active)return ; - }break ;default :return ;
@@ -810,10 +805,10 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,/* If channel context is invalid or not on 2.4GHz .. */ if ((!chanctx_conf || chanctx_conf->def.chan->band !=IEEE80211_BAND_2GHZ )) { -/* ... relax constraints and disable rssi events */ -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , - smps_mode);if (vif->type ==NL80211_IFTYPE_STATION ) { +/* ... relax constraints and disable rssi events */ +iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , + smps_mode);iwl_mvm_bt_coex_reduced_txp (mvm, mvmvif->ap_sta_id, false);iwl_mvm_bt_coex_enable_rssi_event (mvm, vif, false,0 );
@@ -838,7 +833,9 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, mvmvif->id, data->notif->bt_status, bt_activity_grading, smps_mode); -iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , smps_mode); +if (vif->type ==NL80211_IFTYPE_STATION ) +iwl_mvm_update_smps (mvm, vif,IWL_MVM_SMPS_REQ_BT_COEX , + smps_mode);/* low latency is always primary */ if (iwl_mvm_vif_low_latency (mvmvif)) {
Signature · 1 line
1.8.3.2
PATCH 12/20 iwlwifi: mvm: wait for handlers when stopping scans
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
The recent unified scan api change introduced issues when stopping ongoing scans, since both regular and sched scan now use same stopped notification.
When issuing a new scan right after a running one, we get the "old" notification and handle it wrongly as notification for the current scan.
Fix it by introducing a new function that make sure we consume the pending notifications before issuing a new scan.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 86 +++++++++++++++++------------ 1 file changed, 51 insertions(+), 35 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +51 -35
@@ -1718,6 +1718,47 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,iwl_mvm_unref (mvm,IWL_MVM_REF_BSS_CHANGED ); } +static int iwl_mvm_cancel_scan_wait_notif (struct iwl_mvm *mvm, +enum iwl_scan_status scan_type) +{ +int ret; +bool wait_for_handlers = false; + +mutex_lock (&mvm->mutex); + +if (mvm->scan_status != scan_type) { + ret =0 ; +/* make sure there are no pending notifications */ + wait_for_handlers = true; + goto out; + } + +switch (scan_type) { +case IWL_MVM_SCAN_SCHED : + ret =iwl_mvm_scan_offload_stop (mvm, true); +break ; +case IWL_MVM_SCAN_OS : + ret =iwl_mvm_cancel_scan (mvm); +break ; +case IWL_MVM_SCAN_NONE : +default : +WARN_ON_ONCE (1 ); + ret = -EINVAL ; +break ; + } +if (ret) + goto out; + + wait_for_handlers = true; +out: +mutex_unlock (&mvm->mutex); + +/* make sure we consume the completion notification */ +if (wait_for_handlers) +iwl_mvm_wait_for_async_handlers (mvm); + +return ret; +}static int iwl_mvm_mac_hw_scan (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_scan_request *hw_req)
@@ -1730,19 +1771,13 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, req->n_channels > mvm->fw->ucode_capa.n_scan_channels)return -EINVAL ; + ret =iwl_mvm_cancel_scan_wait_notif (mvm,IWL_MVM_SCAN_SCHED ); +if (ret) +return ret; +mutex_lock (&mvm->mutex); -switch (mvm->scan_status) { -case IWL_MVM_SCAN_SCHED : - ret =iwl_mvm_scan_offload_stop (mvm, true); -if (ret) { - ret = -EBUSY ; - goto out; - } -break ; -case IWL_MVM_SCAN_NONE : -break ; -default : +if (mvm->scan_status !=IWL_MVM_SCAN_NONE ) { ret = -EBUSY ; goto out; }
@@ -1758,8 +1793,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,iwl_mvm_unref (mvm,IWL_MVM_REF_SCAN ); out:mutex_unlock (&mvm->mutex); -/* make sure to flush the Rx handler before the next scan arrives */ -iwl_mvm_wait_for_async_handlers (mvm);return ret; }
@@ -2135,6 +2168,10 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,struct iwl_mvm *mvm =IWL_MAC80211_GET_MVM (hw);int ret; + ret =iwl_mvm_cancel_scan_wait_notif (mvm,IWL_MVM_SCAN_OS ); +if (ret) +return ret; +mutex_lock (&mvm->mutex);if (!iwl_mvm_is_idle (mvm)) {
@@ -2142,26 +2179,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, goto out; } -switch (mvm->scan_status) { -case IWL_MVM_SCAN_OS : -IWL_DEBUG_SCAN (mvm,"Stopping previous scan for sched_scan\n" ); - ret =iwl_mvm_cancel_scan (mvm); -if (ret) { - ret = -EBUSY ; - goto out; - } - -/* -* iwl_mvm_rx_scan_complete() will be called soon but will -* not reset the scan status as it won't be IWL_MVM_SCAN_OS -* any more since we queue the next scan immediately (below). -* We make sure it is called before the next scan starts by -* flushing the async-handlers work. -*/ -break ; -case IWL_MVM_SCAN_NONE : -break ; -default : +if (mvm->scan_status !=IWL_MVM_SCAN_NONE ) { ret = -EBUSY ; goto out; }
@@ -2189,8 +2207,6 @@ err: mvm->scan_status =IWL_MVM_SCAN_NONE ; out:mutex_unlock (&mvm->mutex); -/* make sure to flush the Rx handler before the next scan arrives */ -iwl_mvm_wait_for_async_handlers (mvm);return ret; }
Signature · 1 line
1.8.3.2
PATCH 13/20 iwlwifi: mvm: minor change in debug print
In reply to Emmanuel GrumbachFrom: Eran Harary <[email protected]>
Add OTP to the string: "can't parse empty OTP/NVM section" NVM usually refers to nvm_file while the problem can be in the OTP.
--- drivers/net/wireless/iwlwifi/mvm/nvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/nvm.c +2 -2
@@ -265,7 +265,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)if (mvm->trans->cfg->device_family !=IWL_DEVICE_FAMILY_8000 ) {if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW ].data || !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { -IWL_ERR (mvm,"Can't parse empty NVM sections\n" ); +IWL_ERR (mvm,"Can't parse empty OTP/NVM sections\n" );return NULL ; } }else {
@@ -273,7 +273,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW ].data || !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY ].data) {IWL_ERR (mvm, -"Can't parse empty family 8000 NVM sections\n" ); +"Can't parse empty family 8000 OTP/NVM sections\n" );return NULL ; }/* MAC_OVERRIDE or at least HW section must exist */
Signature · 1 line
1.8.3.2
PATCH 14/20 iwlwifi: fix inconsistency about power_save module parameter
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
modinfo and kerneldoc disagreed on the meaning of this field.
--- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-modparams.h +1 -1
@@ -99,7 +99,7 @@ enum iwl_disable_11n {* @wd_disable: disable stuck queue check, default = 1 * @bt_coex_active: enable bt coex, default = true * @led_mode: system default, default = 0 -* @power_save: disable power save, default = false +* @power_save: enable power save, default = false * @power_level: power level, default = 1 * @debug_level: levels are IWL_DL_* * @ant_coupling: antenna coupling in dB, default = 0
Signature · 1 line
1.8.3.2
PATCH 15/20 iwlwifi: split fw-error-dump between transport and mvm
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
The mvm op_mode won't allocate the buffer for the transport any more. The transport allocates its own buffer and mvm is in charge of splicing the buffers in the debugfs hook.
This makes the repartition easier to handle.
--- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 ++++++++------- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 40 +++++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 31 +++++++++++----------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 17 +++++++++++- drivers/net/wireless/iwlwifi/mvm/ops.c | 6 ++++- drivers/net/wireless/iwlwifi/pcie/trans.c | 19 +++++++++----- 6 files changed, 95 insertions(+), 39 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans.h +12 -9
@@ -394,6 +394,11 @@ struct iwl_trans_config {const char *const *command_names; }; +struct iwl_trans_dump_data { +u32 len; +u8 data[]; +}; +struct iwl_trans ;/**
@@ -461,10 +466,8 @@ struct iwl_trans;* @unref: release a reference previously taken with @ref. Note that * initially the reference count is 1, making an initial @unref * necessary to allow low power states. -* @dump_data: fill a data dump with debug data, maybe containing last -* TX'ed commands and similar. When called with a NULL buffer and -* zero buffer length, provide only the (estimated) required buffer -* length. Return the used buffer length. +* @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last +* TX'ed commands and similar. The buffer will be vfree'd by the caller. * Note that the transport must fill in the proper file headers. */ struct iwl_trans_ops {
@@ -518,7 +521,7 @@ struct iwl_trans_ops {void (*unref)(struct iwl_trans *trans);#ifdef CONFIG_IWLWIFI_DEBUGFS -u32 (*dump_data)(struct iwl_trans *trans,void *buf,u32 buflen); +struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans);#endif };
@@ -685,12 +688,12 @@ static inline void iwl_trans_unref(struct iwl_trans *trans) }#ifdef CONFIG_IWLWIFI_DEBUGFS -static inline u32 iwl_trans_dump_data (struct iwl_trans *trans, -void *buf,u32 buflen) +static inline struct iwl_trans_dump_data * +iwl_trans_dump_data (struct iwl_trans *trans) {if (!trans->ops->dump_data) -return 0 ; -return trans->ops->dump_data (trans, buf, buflen); +return NULL ; +return trans->ops->dump_data (trans); }#endif
drivers/net/wireless/iwlwifi/mvm/debugfs.c +35 -5
@@ -146,17 +146,47 @@ static ssize_t iwl_dbgfs_fw_error_dump_read(struct file *file,char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_fw_error_dump_file *dump_file = file->private_data; + struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data; +ssize_t bytes_read =0 ; +ssize_t bytes_read_trans =0 ; + +if (*ppos < dump_ptrs->op_mode_len) + bytes_read += +simple_read_from_buffer (user_buf, count, ppos, + dump_ptrs->op_mode_ptr, + dump_ptrs->op_mode_len); + +if (bytes_read <0 || *ppos < dump_ptrs->op_mode_len) +return bytes_read; + +if (dump_ptrs->trans_ptr) { + *ppos -= dump_ptrs->op_mode_len; + bytes_read_trans = +simple_read_from_buffer (user_buf + bytes_read, + count - bytes_read, ppos, + dump_ptrs->trans_ptr->data, + dump_ptrs->trans_ptr->len); + *ppos += dump_ptrs->op_mode_len; + +if (bytes_read_trans >=0 ) + bytes_read += bytes_read_trans; +else if (!bytes_read) +/* propagate the failure */ +return bytes_read_trans; + } + +return bytes_read; -return simple_read_from_buffer (user_buf, count, ppos, - dump_file, -le32_to_cpu (dump_file->file_len)); }static int iwl_dbgfs_fw_error_dump_release (struct inode *inode,struct file *file) { -vfree (file->private_data); +struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data; + +vfree (dump_ptrs->op_mode_ptr); +vfree (dump_ptrs->trans_ptr); +kfree (dump_ptrs);return 0 ; }
drivers/net/wireless/iwlwifi/mvm/mac80211.c +15 -16
@@ -676,11 +676,11 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)struct iwl_fw_error_dump_file *dump_file;struct iwl_fw_error_dump_data *dump_data;struct iwl_fw_error_dump_info *dump_info; +struct iwl_mvm_dump_ptrs *fw_error_dump;const struct fw_img *img;u32 sram_len, sram_ofs;u32 file_len, rxf_len;unsigned long flags; -u32 trans_len;int reg_val;lockdep_assert_held (&mvm->mutex);
@@ -688,6 +688,10 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)if (mvm->fw_error_dump)return ; + fw_error_dump =kzalloc (sizeof (*mvm->fw_error_dump),GFP_KERNEL ); +if (!fw_error_dump) +return ; + img = &mvm->fw->img[mvm->cur_ucode]; sram_ofs = img->sec[IWL_UCODE_SECTION_DATA ].offset; sram_len = img->sec[IWL_UCODE_SECTION_DATA ].len;
@@ -705,18 +709,15 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) rxf_len +sizeof (*dump_info); - trans_len =iwl_trans_dump_data (mvm->trans,NULL ,0 ); -if (trans_len) - file_len += trans_len; - dump_file =vzalloc (file_len); -if (!dump_file) +if (!dump_file) { +kfree (fw_error_dump);return ; + } - mvm->fw_error_dump = dump_file; + fw_error_dump->op_mode_ptr = dump_file; dump_file->barker =cpu_to_le32 (IWL_FW_ERROR_DUMP_BARKER ); - dump_file->file_len =cpu_to_le32 (file_len); dump_data = (void *)dump_file->data; dump_data->type =cpu_to_le32 (IWL_FW_ERROR_DUMP_DEV_FW_INFO );
@@ -757,14 +758,12 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)iwl_trans_read_mem_bytes (mvm->trans, sram_ofs, dump_data->data, sram_len); -if (trans_len) { -void *buf =iwl_fw_error_next_data (dump_data); -u32 real_trans_len =iwl_trans_dump_data (mvm->trans, buf, - trans_len); - dump_data = (void *)((u8 *)buf + real_trans_len); - dump_file->file_len = -cpu_to_le32 (file_len - trans_len + real_trans_len); - } + fw_error_dump->trans_ptr =iwl_trans_dump_data (mvm->trans); + fw_error_dump->op_mode_len = file_len; +if (fw_error_dump->trans_ptr) + file_len += fw_error_dump->trans_ptr->len; + dump_file->file_len =cpu_to_le32 (file_len); + mvm->fw_error_dump = fw_error_dump; }#endif
drivers/net/wireless/iwlwifi/mvm/mvm.h +16 -1
@@ -128,6 +128,21 @@ struct iwl_mvm_mod_params { };extern struct iwl_mvm_mod_params iwlmvm_mod_params; +/** +* struct iwl_mvm_dump_ptrs - set of pointers needed for the fw-error-dump +* +* @op_mode_ptr: pointer to the buffer coming from the mvm op_mode +* @trans_ptr: pointer to struct %iwl_trans_dump_data which contains the +* transport's data. +* @trans_len: length of the valid data in trans_ptr +* @op_mode_len: length of the valid data in op_mode_ptr +*/ +struct iwl_mvm_dump_ptrs { +struct iwl_trans_dump_data *trans_ptr; +void *op_mode_ptr; +u32 op_mode_len; +}; +struct iwl_mvm_phy_ctxt {u16 id;u16 color;
@@ -626,7 +641,7 @@ struct iwl_mvm {/* -1 for always, 0 for never, >0 for that many times */ s8 restart_fw; -void *fw_error_dump; +struct iwl_mvm_dump_ptrs *fw_error_dump;#ifdef CONFIG_IWLWIFI_LEDS struct led_classdev led;
drivers/net/wireless/iwlwifi/mvm/ops.c +5 -1
@@ -573,7 +573,11 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)ieee80211_unregister_hw (mvm->hw);kfree (mvm->scan_cmd); -vfree (mvm->fw_error_dump); +if (mvm->fw_error_dump) { +vfree (mvm->fw_error_dump->op_mode_ptr); +vfree (mvm->fw_error_dump->trans_ptr); +kfree (mvm->fw_error_dump); + }kfree (mvm->mcast_filter_cmd); mvm->mcast_filter_cmd =NULL ;
drivers/net/wireless/iwlwifi/pcie/trans.c +12 -7
@@ -67,6 +67,7 @@#include <linux/sched.h> #include <linux/bitops.h> #include <linux/gfp.h> +#include <linux/vmalloc.h> #include "iwl-drv.h" #include "iwl-trans.h"
@@ -1773,28 +1774,30 @@ static u32 iwl_trans_pcie_get_cmdlen(struct iwl_tfd *tfd)return cmdlen; } -static u32 iwl_trans_pcie_dump_data (struct iwl_trans *trans, -void *buf,u32 buflen) +static +struct iwl_trans_dump_data *iwl_trans_pcie_dump_data (struct iwl_trans *trans) {struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans);struct iwl_fw_error_dump_data *data;struct iwl_txq *cmdq = &trans_pcie->txq[trans_pcie->cmd_queue];struct iwl_fw_error_dump_txcmd *txcmd; +struct iwl_trans_dump_data *dump_data;u32 len;int i, ptr; - len =sizeof (*data) + + len =sizeof (*dump_data) +sizeof (*data) + cmdq->q.n_window * (sizeof (*txcmd) +TFD_MAX_PAYLOAD_SIZE );if (trans_pcie->fw_mon_page) len +=sizeof (*data) +sizeof (struct iwl_fw_error_dump_fw_mon ) + trans_pcie->fw_mon_size; -if (!buf) -return len; + dump_data =vzalloc (len); +if (!dump_data) +return NULL ; len =0 ; - data = buf; + data = (void *)dump_data->data; data->type =cpu_to_le32 (IWL_FW_ERROR_DUMP_TXCMD ); txcmd = (void *)data->data;spin_lock_bh (&cmdq->lock);
@@ -1852,7 +1855,9 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans, trans_pcie->fw_mon_size; } -return len; + dump_data->len = len; + +return dump_data; }#else static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
Signature · 1 line
1.8.3.2
PATCH 16/20 iwlwifi: dump periphery registers to fw-error-dump
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Use the fw-error-dump infrastructure to dump the periphery registers. Only certain ranges are readable, so dump only these.
--- drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 13 ++ drivers/net/wireless/iwlwifi/pcie/trans.c | 152 ++++++++++++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +13 -0
@@ -77,6 +77,8 @@* @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info * info on the device / firmware. * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor +* @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several +* sections like this in a single file. */ enum iwl_fw_error_dump_type {IWL_FW_ERROR_DUMP_SRAM =0 ,
@@ -85,6 +87,7 @@ enum iwl_fw_error_dump_type {IWL_FW_ERROR_DUMP_TXCMD =3 ,IWL_FW_ERROR_DUMP_DEV_FW_INFO =4 ,IWL_FW_ERROR_DUMP_FW_MONITOR =5 , +IWL_FW_ERROR_DUMP_PRPH =6 , IWL_FW_ERROR_DUMP_MAX, };
@@ -163,6 +166,16 @@ struct iwl_fw_error_dump_fw_mon { } __packed;/** +* struct iwl_fw_error_dump_prph - periphery registers data +* @prph_start: address of the first register in this chunk +* @data: the content of the registers +*/ +struct iwl_fw_error_dump_prph { +__le32 prph_start; +__le32 data[]; +}; + +/** * iwl_fw_error_next_data - advance fw error dump data pointer * @data: previous data block * Returns: next data block
drivers/net/wireless/iwlwifi/pcie/trans.c +151 -1
174 lines not on this page · raw message
Signature · 1 line
1.8.3.2
PATCH 17/20 iwlwifi: dump CSRs to fw-error-dump
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Add the Control Status Registers to the firmware error dump infrastructure.
--- drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 4 +-- drivers/net/wireless/iwlwifi/pcie/trans.c | 33 +++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-)
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +2 -2
@@ -70,7 +70,7 @@/** * enum iwl_fw_error_dump_type - types of data in the dump file * @IWL_FW_ERROR_DUMP_SRAM: -* @IWL_FW_ERROR_DUMP_REG: +* @IWL_FW_ERROR_DUMP_CSR: Control Status Registers - from offset 0 * @IWL_FW_ERROR_DUMP_RXF: * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as * &struct iwl_fw_error_dump_txcmd packets
@@ -82,7 +82,7 @@*/ enum iwl_fw_error_dump_type {IWL_FW_ERROR_DUMP_SRAM =0 , -IWL_FW_ERROR_DUMP_REG =1 , +IWL_FW_ERROR_DUMP_CSR =1 ,IWL_FW_ERROR_DUMP_RXF =2 ,IWL_FW_ERROR_DUMP_TXCMD =3 ,IWL_FW_ERROR_DUMP_DEV_FW_INFO =4 ,
drivers/net/wireless/iwlwifi/pcie/trans.c +32 -1
@@ -1912,6 +1912,27 @@ static u32 iwl_trans_pcie_dump_prph(struct iwl_trans *trans,return prph_len; } +#define IWL_CSR_TO_DUMP (0x250) + +static u32 iwl_trans_pcie_dump_csr (struct iwl_trans *trans, +struct iwl_fw_error_dump_data **data) +{ +u32 csr_len =sizeof (**data) +IWL_CSR_TO_DUMP ; +__le32 *val; +int i; + + (*data)->type =cpu_to_le32 (IWL_FW_ERROR_DUMP_CSR ); + (*data)->len =cpu_to_le32 (IWL_CSR_TO_DUMP ); + val = (void *)(*data)->data; + +for (i =0 ; i <IWL_CSR_TO_DUMP ; i +=4 ) + *val++ =cpu_to_le32 (iwl_trans_pcie_read32 (trans, i)); + + *data =iwl_fw_error_next_data (*data); + +return csr_len; +} +static struct iwl_trans_dump_data *iwl_trans_pcie_dump_data (struct iwl_trans *trans) {
@@ -1923,9 +1944,17 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)u32 len;int i, ptr; - len =sizeof (*dump_data) +sizeof (*data) + +/* transport dump header */ + len =sizeof (*dump_data); + +/* host commands */ + len +=sizeof (*data) + cmdq->q.n_window * (sizeof (*txcmd) +TFD_MAX_PAYLOAD_SIZE ); +/* CSR registers */ + len +=sizeof (*data) +IWL_CSR_TO_DUMP ; + +/* PRPH registers */ for (i =0 ; i <ARRAY_SIZE (iwl_prph_dump_addr); i++) {/* The range includes both boundaries */ int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
@@ -1935,6 +1964,7 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) num_bytes_in_chunk; } +/* FW monitor */ if (trans_pcie->fw_mon_page) len +=sizeof (*data) +sizeof (struct iwl_fw_error_dump_fw_mon ) + trans_pcie->fw_mon_size;
@@ -1973,6 +2003,7 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) data =iwl_fw_error_next_data (data); len +=iwl_trans_pcie_dump_prph (trans, &data); + len +=iwl_trans_pcie_dump_csr (trans, &data);/* data is already pointing to the next section */ if (trans_pcie->fw_mon_page) {
Signature · 1 line
1.8.3.2
PATCH 18/20 iwlwifi: mvm: update smart fifo / beacon filtering upon association
In reply to Emmanuel GrumbachFrom: Eran Harary <[email protected]>
When we associate, we may have heard the beacon before the association. In that case, BSS_CHANGED_BEACON_INFO will be set along with BSS_CHANGED_ASSOC in changes in bss_info_change.
In this case, we didn't update the smart fifo nor beacon filtering leaving those two feature disabled.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +6 -2
@@ -1501,14 +1501,18 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,*/ iwl_mvm_remove_time_event (mvm, mvmvif, &mvmvif->time_event_data); -iwl_mvm_sf_update (mvm, vif, false); -WARN_ON (iwl_mvm_enable_beacon_filter (mvm, vif,0 )); }else if (changes & (BSS_CHANGED_PS |BSS_CHANGED_P2P_PS |BSS_CHANGED_QOS )) { ret =iwl_mvm_power_update_mac (mvm);if (ret)IWL_ERR (mvm,"failed to update power mode\n" ); } + +if (changes &BSS_CHANGED_BEACON_INFO ) { +iwl_mvm_sf_update (mvm, vif, false); +WARN_ON (iwl_mvm_enable_beacon_filter (mvm, vif,0 )); + } +if (changes &BSS_CHANGED_TXPOWER ) {IWL_DEBUG_CALIB (mvm,"Changing TX Power to %d\n" , bss_conf->txpower);
Signature · 1 line
1.8.3.2
PATCH 19/20 iwlwifi: mvm: reset beacon filtering and BT Coex data upon FW restart
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
When the firmware asserts, we restart the device and reset the relevant data we hold in the driver. BT Coex data was not reset and because of that, the driver wouldn't reconfigure the firmware properly after firmware restart. Same for beacon filtering. Fix that.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +7 -0
@@ -668,6 +668,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,spin_unlock_bh (&mvm->time_event_lock); mvmvif->phy_ctxt =NULL ; +memset (&mvmvif->bf_data,0 ,sizeof (mvmvif->bf_data)); }#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -795,6 +796,12 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)iwl_mvm_reset_phy_ctxts (mvm);memset (mvm->fw_key_table,0 ,sizeof (mvm->fw_key_table));memset (mvm->sta_drained,0 ,sizeof (mvm->sta_drained)); +memset (&mvm->last_bt_notif,0 ,sizeof (mvm->last_bt_notif)); +memset (&mvm->last_bt_notif_old,0 ,sizeof (mvm->last_bt_notif_old)); +memset (&mvm->last_bt_ci_cmd,0 ,sizeof (mvm->last_bt_ci_cmd)); +memset (&mvm->last_bt_ci_cmd_old,0 ,sizeof (mvm->last_bt_ci_cmd_old)); +memset (&mvm->bt_ack_kill_msk,0 ,sizeof (mvm->bt_ack_kill_msk)); +memset (&mvm->bt_cts_kill_msk,0 ,sizeof (mvm->bt_cts_kill_msk));ieee80211_wake_queues (mvm->hw);
Signature · 1 line
1.8.3.2
PATCH 20/20 iwlwifi: mvm: teardown TDLS peers during chan-switch and AP DCM
In reply to Emmanuel GrumbachFrom: Arik Nemtsov <[email protected]>
The DCM condition was not checked well for channel switch in both AP and station scenarios. Teardown was also not done for AP/GO DCM. Add the missing checks.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 52 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +30 -22
@@ -1406,6 +1406,28 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm, }#endif +static void iwl_mvm_teardown_tdls_peers (struct iwl_mvm *mvm) +{ +struct ieee80211_sta *sta; +struct iwl_mvm_sta *mvmsta; +int i; + +lockdep_assert_held (&mvm->mutex); + +for (i =0 ; i <IWL_MVM_STATION_COUNT ; i++) { + sta =rcu_dereference_protected (mvm->fw_id_to_mac_id[i], +lockdep_is_held (&mvm->mutex)); +if (!sta ||IS_ERR (sta) || !sta->tdls) +continue ; + + mvmsta =iwl_mvm_sta_from_mac80211 (sta); +ieee80211_tdls_oper_request (mvmsta->vif, sta->addr, +NL80211_TDLS_TEARDOWN , +WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED , +GFP_KERNEL ); + } +} + static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf,
@@ -1600,6 +1622,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,iwl_mvm_bt_coex_vif_change (mvm); +/* we don't support TDLS during DCM */ +if (iwl_mvm_phy_ctx_count (mvm) >1 ) +iwl_mvm_teardown_tdls_peers (mvm); +mutex_unlock (&mvm->mutex);return 0 ;
@@ -1947,28 +1973,6 @@ static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm,iwl_mvm_power_update_mac (mvm); } -static void iwl_mvm_teardown_tdls_peers (struct iwl_mvm *mvm) -{ -struct ieee80211_sta *sta; -struct iwl_mvm_sta *mvmsta; -int i; - -lockdep_assert_held (&mvm->mutex); - -for (i =0 ; i <IWL_MVM_STATION_COUNT ; i++) { - sta =rcu_dereference_protected (mvm->fw_id_to_mac_id[i], -lockdep_is_held (&mvm->mutex)); -if (!sta ||IS_ERR (sta) || !sta->tdls) -continue ; - - mvmsta =iwl_mvm_sta_from_mac80211 (sta); -ieee80211_tdls_oper_request (mvmsta->vif, sta->addr, -NL80211_TDLS_TEARDOWN , -WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED , -GFP_KERNEL ); - } -} - static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -2846,6 +2850,10 @@ static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, goto out_remove; } +/* we don't support TDLS during DCM - can be caused by channel switch */ +if (iwl_mvm_phy_ctx_count (mvm) >1 ) +iwl_mvm_teardown_tdls_peers (mvm); + goto out; out_remove:
Signature · 1 line
1.8.3.2
Quoted 12 lines · Emmanuel Grumbach
Hi John,
here is a pull request for 3.17.
I have the usual amount of BT Coex stuff. Arik continues to work on TDLS and Ariej contributes a few things for HS2.0. I added a few more things to the firmware debugging infrastructure. Eran fixes a small bug - pretty normal content.
I merged iwlwifi-fixes to avoid a conflict. I also merged wireless-next because I needed some bits from mac80211. Let me know if this causes you any trouble!
The following changes since commit
a006827a152c3f4d09324157096c8f89cf7ddca3:
Quoted 8 lines
Merge
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next(2014-07-22 13:49:34 -0400)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.gitfor-johnfor you to fetch changes up to
f697267f827516fba4d0c325ed1db1e72f402f11:
Pulling now...
Signature · 2 lines
John W. Linville Someday the world will need a hero, and you [email protected] might be all we have. Be ready.