mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 08:02:07 +00:00
Third batch of updates for v4.16
* Small cleanups in the new rate-scaling code; * Some improvements in debugging; * New FW API changes; * Fix a bug where we got a false-positive warning; * Fix forced quota debugfs functionality; -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlo6j9kACgkQoUecoho8 xfrjDxAAm4JLAERLr8ntPzNRh3PdOf53aXUttm5X02jArbKLzz+Na+bnSrWGyIeP 4LrkJKVoE8/k9ku/mQoDIlD3RPXIrVj8skWGGvg0u7azJLT9icW0F6IWHeAXS251 lW6bBqNJ0uShRQ7VKRETvZaAs+kcEkdUiqLvtQ27PGSUxoKgjUepV0bMAdYO5kX/ XCkoszpVXbXsjfcPdhcuW1dLi+sRk11a73up0Gk0a+idP8NzUBx7QtTo77OH8+w6 BGdFuYOlB8MdpoACUmRh5XmRSv5NqX4/jGbWNjcXya6MoB8bLLGfYZAKGwNpfWcA k160Z9ah9ZYEgS5OQ3RSItJZo215dFiKY+Gvkv3NMjSBcpfSV3EX4GC5zaWsW782 L2Hgs9ylSyMLDAjRKfd8rJER+rfCaj+4YvL/QPLL+DfJtLRQiQNGZSJWuQTi9IQf yCtpg4n2XMGiQZzUEHsA3LOhBS6k35y80CQt9djpWFqb4SeKub0y0616Vk+f9+4p TEvOYEYeyvd32o5Z+CfiJHzma1btWgD2XD1KzcSbMzEffFACH3NXcuYTtE9mNz8A datricRtqmESe2Rm0MgxjOY0PZB+HdfyD0pa3OrToRfQvJQSw7/JVHKBJUNTmbeV /K1HBXntlzIwEUxkZL8YZ4bt9mdu2E6oOJx2SWXc0TWNkXBYyNE= =gWyv -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2017-12-20' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Third batch of updates for v4.16 * Small cleanups in the new rate-scaling code; * Some improvements in debugging; * New FW API changes; * Fix a bug where we got a false-positive warning; * Fix forced quota debugfs functionality;
This commit is contained in:
commit
a08e61d274
@ -15,6 +15,7 @@ iwlwifi-objs += fw/notif-wait.o
|
|||||||
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
|
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
|
||||||
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
|
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
|
||||||
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
|
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
|
||||||
|
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += fw/debugfs.o
|
||||||
|
|
||||||
iwlwifi-objs += $(iwlwifi-m)
|
iwlwifi-objs += $(iwlwifi-m)
|
||||||
|
|
||||||
|
@ -250,10 +250,12 @@ struct iwl_mfu_assert_dump_notif {
|
|||||||
* The ids for different type of markers to insert into the usniffer logs
|
* The ids for different type of markers to insert into the usniffer logs
|
||||||
*
|
*
|
||||||
* @MARKER_ID_TX_FRAME_LATENCY: TX latency marker
|
* @MARKER_ID_TX_FRAME_LATENCY: TX latency marker
|
||||||
|
* @MARKER_ID_SYNC_CLOCK: sync FW time and systime
|
||||||
*/
|
*/
|
||||||
enum iwl_mvm_marker_id {
|
enum iwl_mvm_marker_id {
|
||||||
MARKER_ID_TX_FRAME_LATENCY = 1,
|
MARKER_ID_TX_FRAME_LATENCY = 1,
|
||||||
}; /* MARKER_ID_API_E_VER_1 */
|
MARKER_ID_SYNC_CLOCK = 2,
|
||||||
|
}; /* MARKER_ID_API_E_VER_2 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_mvm_marker - mark info into the usniffer logs
|
* struct iwl_mvm_marker - mark info into the usniffer logs
|
||||||
|
@ -67,6 +67,10 @@
|
|||||||
* enum iwl_mac_conf_subcmd_ids - mac configuration command IDs
|
* enum iwl_mac_conf_subcmd_ids - mac configuration command IDs
|
||||||
*/
|
*/
|
||||||
enum iwl_mac_conf_subcmd_ids {
|
enum iwl_mac_conf_subcmd_ids {
|
||||||
|
/**
|
||||||
|
* @LOW_LATENCY_CMD: &struct iwl_mac_low_latency_cmd
|
||||||
|
*/
|
||||||
|
LOW_LATENCY_CMD = 0x3,
|
||||||
/**
|
/**
|
||||||
* @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
|
* @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
|
||||||
*/
|
*/
|
||||||
@ -82,4 +86,19 @@ struct iwl_channel_switch_noa_notif {
|
|||||||
__le32 id_and_color;
|
__le32 id_and_color;
|
||||||
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
|
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_mac_low_latency_cmd - set/clear mac to 'low-latency mode'
|
||||||
|
*
|
||||||
|
* @mac_id: MAC ID to whom to apply the low-latency configurations
|
||||||
|
* @low_latency_rx: 1/0 to set/clear Rx low latency direction
|
||||||
|
* @low_latency_tx: 1/0 to set/clear Tx low latency direction
|
||||||
|
* @reserved: reserved for alignment purposes
|
||||||
|
*/
|
||||||
|
struct iwl_mac_low_latency_cmd {
|
||||||
|
__le32 mac_id;
|
||||||
|
u8 low_latency_rx;
|
||||||
|
u8 low_latency_tx;
|
||||||
|
__le16 reserved;
|
||||||
|
} __packed; /* MAC_LOW_LATENCY_API_S_VER_1 */
|
||||||
|
|
||||||
#endif /* __iwl_fw_api_mac_cfg_h__ */
|
#endif /* __iwl_fw_api_mac_cfg_h__ */
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
* @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER
|
* @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER
|
||||||
* @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM
|
* @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_cfg_flags_enum {
|
enum iwl_tlc_mng_cfg_flags {
|
||||||
IWL_TLC_MNG_CFG_FLAGS_CCK_MSK = BIT(0),
|
IWL_TLC_MNG_CFG_FLAGS_CCK_MSK = BIT(0),
|
||||||
IWL_TLC_MNG_CFG_FLAGS_DD_MSK = BIT(1),
|
IWL_TLC_MNG_CFG_FLAGS_DD_MSK = BIT(1),
|
||||||
IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(2),
|
IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(2),
|
||||||
@ -81,14 +81,14 @@ enum iwl_tlc_mng_cfg_flags_enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_cfg_cw_enum - channel width options
|
* enum iwl_tlc_mng_cfg_cw - channel width options
|
||||||
* @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel
|
* @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel
|
||||||
* @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel
|
* @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel
|
||||||
* @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel
|
* @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel
|
||||||
* @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel
|
* @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel
|
||||||
* @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value
|
* @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_cfg_cw_enum {
|
enum iwl_tlc_mng_cfg_cw {
|
||||||
IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ,
|
IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ,
|
||||||
IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ,
|
IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ,
|
||||||
IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ,
|
IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ,
|
||||||
@ -97,25 +97,25 @@ enum iwl_tlc_mng_cfg_cw_enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_cfg_chains_enum - possible chains
|
* enum iwl_tlc_mng_cfg_chains - possible chains
|
||||||
* @IWL_TLC_MNG_CHAIN_A_MSK: chain A
|
* @IWL_TLC_MNG_CHAIN_A_MSK: chain A
|
||||||
* @IWL_TLC_MNG_CHAIN_B_MSK: chain B
|
* @IWL_TLC_MNG_CHAIN_B_MSK: chain B
|
||||||
* @IWL_TLC_MNG_CHAIN_C_MSK: chain C
|
* @IWL_TLC_MNG_CHAIN_C_MSK: chain C
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_cfg_chains_enum {
|
enum iwl_tlc_mng_cfg_chains {
|
||||||
IWL_TLC_MNG_CHAIN_A_MSK = BIT(0),
|
IWL_TLC_MNG_CHAIN_A_MSK = BIT(0),
|
||||||
IWL_TLC_MNG_CHAIN_B_MSK = BIT(1),
|
IWL_TLC_MNG_CHAIN_B_MSK = BIT(1),
|
||||||
IWL_TLC_MNG_CHAIN_C_MSK = BIT(2),
|
IWL_TLC_MNG_CHAIN_C_MSK = BIT(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_cfg_gi_enum - guard interval options
|
* enum iwl_tlc_mng_cfg_gi - guard interval options
|
||||||
* @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ
|
* @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ
|
||||||
* @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ
|
* @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ
|
||||||
* @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ
|
* @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ
|
||||||
* @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ
|
* @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_cfg_gi_enum {
|
enum iwl_tlc_mng_cfg_gi {
|
||||||
IWL_TLC_MNG_SGI_20MHZ_MSK = BIT(0),
|
IWL_TLC_MNG_SGI_20MHZ_MSK = BIT(0),
|
||||||
IWL_TLC_MNG_SGI_40MHZ_MSK = BIT(1),
|
IWL_TLC_MNG_SGI_40MHZ_MSK = BIT(1),
|
||||||
IWL_TLC_MNG_SGI_80MHZ_MSK = BIT(2),
|
IWL_TLC_MNG_SGI_80MHZ_MSK = BIT(2),
|
||||||
@ -123,7 +123,7 @@ enum iwl_tlc_mng_cfg_gi_enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_cfg_mode_enum - supported modes
|
* enum iwl_tlc_mng_cfg_mode - supported modes
|
||||||
* @IWL_TLC_MNG_MODE_CCK: enable CCK
|
* @IWL_TLC_MNG_MODE_CCK: enable CCK
|
||||||
* @IWL_TLC_MNG_MODE_OFDM_NON_HT: enable OFDM (non HT)
|
* @IWL_TLC_MNG_MODE_OFDM_NON_HT: enable OFDM (non HT)
|
||||||
* @IWL_TLC_MNG_MODE_NON_HT: enable non HT
|
* @IWL_TLC_MNG_MODE_NON_HT: enable non HT
|
||||||
@ -133,7 +133,7 @@ enum iwl_tlc_mng_cfg_gi_enum {
|
|||||||
* @IWL_TLC_MNG_MODE_INVALID: invalid value
|
* @IWL_TLC_MNG_MODE_INVALID: invalid value
|
||||||
* @IWL_TLC_MNG_MODE_NUM: a count of possible modes
|
* @IWL_TLC_MNG_MODE_NUM: a count of possible modes
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_cfg_mode_enum {
|
enum iwl_tlc_mng_cfg_mode {
|
||||||
IWL_TLC_MNG_MODE_CCK = 0,
|
IWL_TLC_MNG_MODE_CCK = 0,
|
||||||
IWL_TLC_MNG_MODE_OFDM_NON_HT = IWL_TLC_MNG_MODE_CCK,
|
IWL_TLC_MNG_MODE_OFDM_NON_HT = IWL_TLC_MNG_MODE_CCK,
|
||||||
IWL_TLC_MNG_MODE_NON_HT = IWL_TLC_MNG_MODE_CCK,
|
IWL_TLC_MNG_MODE_NON_HT = IWL_TLC_MNG_MODE_CCK,
|
||||||
@ -145,14 +145,14 @@ enum iwl_tlc_mng_cfg_mode_enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_vht_he_types_enum - VHT HE types
|
* enum iwl_tlc_mng_vht_he_types - VHT HE types
|
||||||
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user
|
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user
|
||||||
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended
|
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended
|
||||||
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users
|
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users
|
||||||
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based
|
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based
|
||||||
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types
|
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_vht_he_types_enum {
|
enum iwl_tlc_mng_vht_he_types {
|
||||||
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0,
|
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0,
|
||||||
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT,
|
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT,
|
||||||
IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU,
|
IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU,
|
||||||
@ -163,7 +163,7 @@ enum iwl_tlc_mng_vht_he_types_enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_tlc_mng_ht_rates_enum - HT/VHT rates
|
* enum iwl_tlc_mng_ht_rates - HT/VHT rates
|
||||||
* @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0
|
* @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0
|
||||||
* @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1
|
* @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1
|
||||||
* @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2
|
* @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2
|
||||||
@ -176,7 +176,7 @@ enum iwl_tlc_mng_vht_he_types_enum {
|
|||||||
* @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9
|
* @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9
|
||||||
* @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT
|
* @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT
|
||||||
*/
|
*/
|
||||||
enum iwl_tlc_mng_ht_rates_enum {
|
enum iwl_tlc_mng_ht_rates {
|
||||||
IWL_TLC_MNG_HT_RATE_MCS0 = 0,
|
IWL_TLC_MNG_HT_RATE_MCS0 = 0,
|
||||||
IWL_TLC_MNG_HT_RATE_MCS1,
|
IWL_TLC_MNG_HT_RATE_MCS1,
|
||||||
IWL_TLC_MNG_HT_RATE_MCS2,
|
IWL_TLC_MNG_HT_RATE_MCS2,
|
||||||
@ -198,13 +198,13 @@ enum iwl_tlc_mng_ht_rates_enum {
|
|||||||
* @sta_id: station id
|
* @sta_id: station id
|
||||||
* @reserved1: reserved
|
* @reserved1: reserved
|
||||||
* @max_supp_ch_width: channel width
|
* @max_supp_ch_width: channel width
|
||||||
* @flags: bitmask of %IWL_TLC_MNG_CONFIG_FLAGS_ENABLE_\*
|
* @flags: bitmask of &enum iwl_tlc_mng_cfg_flags
|
||||||
* @chains: bitmask of %IWL_TLC_MNG_CHAIN_\*
|
* @chains: bitmask of &enum iwl_tlc_mng_cfg_chains
|
||||||
* @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported
|
* @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported
|
||||||
* @valid_vht_he_types: bitmap of %IWL_TLC_MNG_VALID_VHT_HE_TYPES_\*
|
* @valid_vht_he_types: bitmap of &enum iwl_tlc_mng_vht_he_types
|
||||||
* @non_ht_supp_rates: bitmap of supported legacy rates
|
* @non_ht_supp_rates: bitmap of supported legacy rates
|
||||||
* @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
|
* @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
|
||||||
* @mode: modulation type %IWL_TLC_MNG_MODE_\*
|
* @mode: &enum iwl_tlc_mng_cfg_mode
|
||||||
* @reserved2: reserved
|
* @reserved2: reserved
|
||||||
* @he_supp_rates: bitmap of supported HE rates
|
* @he_supp_rates: bitmap of supported HE rates
|
||||||
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
||||||
|
195
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
Normal file
195
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
* redistributing this file, you may do so under either license.
|
||||||
|
*
|
||||||
|
* GPL LICENSE SUMMARY
|
||||||
|
*
|
||||||
|
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program.
|
||||||
|
*
|
||||||
|
* The full GNU General Public License is included in this distribution
|
||||||
|
* in the file called COPYING.
|
||||||
|
*
|
||||||
|
* Contact Information:
|
||||||
|
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||||
|
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||||
|
*
|
||||||
|
* BSD LICENSE
|
||||||
|
*
|
||||||
|
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name Intel Corporation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "api/commands.h"
|
||||||
|
#include "debugfs.h"
|
||||||
|
|
||||||
|
#define FWRT_DEBUGFS_READ_FILE_OPS(name) \
|
||||||
|
static ssize_t iwl_dbgfs_##name##_read(struct iwl_fw_runtime *fwrt, \
|
||||||
|
char *buf, size_t count, \
|
||||||
|
loff_t *ppos); \
|
||||||
|
static const struct file_operations iwl_dbgfs_##name##_ops = { \
|
||||||
|
.read = iwl_dbgfs_##name##_read, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \
|
||||||
|
static ssize_t iwl_dbgfs_##name##_write(struct iwl_fw_runtime *fwrt, \
|
||||||
|
char *buf, size_t count, \
|
||||||
|
loff_t *ppos); \
|
||||||
|
static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
|
||||||
|
const char __user *user_buf, \
|
||||||
|
size_t count, loff_t *ppos) \
|
||||||
|
{ \
|
||||||
|
struct iwl_fw_runtime *fwrt = file->private_data; \
|
||||||
|
char buf[buflen] = {}; \
|
||||||
|
size_t buf_size = min(count, sizeof(buf) - 1); \
|
||||||
|
\
|
||||||
|
if (copy_from_user(buf, user_buf, buf_size)) \
|
||||||
|
return -EFAULT; \
|
||||||
|
\
|
||||||
|
return iwl_dbgfs_##name##_write(fwrt, buf, buf_size, ppos); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen) \
|
||||||
|
FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \
|
||||||
|
static const struct file_operations iwl_dbgfs_##name##_ops = { \
|
||||||
|
.write = _iwl_dbgfs_##name##_write, \
|
||||||
|
.read = iwl_dbgfs_##name##_read, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FWRT_DEBUGFS_WRITE_FILE_OPS(name, buflen) \
|
||||||
|
FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \
|
||||||
|
static const struct file_operations iwl_dbgfs_##name##_ops = { \
|
||||||
|
.write = _iwl_dbgfs_##name##_write, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
|
||||||
|
if (!debugfs_create_file(alias, mode, parent, fwrt, \
|
||||||
|
&iwl_dbgfs_##name##_ops)) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
#define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \
|
||||||
|
FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
|
||||||
|
|
||||||
|
static int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
|
||||||
|
{
|
||||||
|
struct iwl_mvm_marker marker = {
|
||||||
|
.dw_len = sizeof(struct iwl_mvm_marker) / 4,
|
||||||
|
.marker_id = MARKER_ID_SYNC_CLOCK,
|
||||||
|
|
||||||
|
/* the real timestamp is taken from the ftrace clock
|
||||||
|
* this is for finding the match between fw and kernel logs
|
||||||
|
*/
|
||||||
|
.timestamp = cpu_to_le64(fwrt->timestamp.seq++),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iwl_host_cmd hcmd = {
|
||||||
|
.id = MARKER_CMD,
|
||||||
|
.flags = CMD_ASYNC,
|
||||||
|
.data[0] = &marker,
|
||||||
|
.len[0] = sizeof(marker),
|
||||||
|
};
|
||||||
|
|
||||||
|
return iwl_trans_send_cmd(fwrt->trans, &hcmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iwl_fw_timestamp_marker_wk(struct work_struct *work)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct iwl_fw_runtime *fwrt =
|
||||||
|
container_of(work, struct iwl_fw_runtime, timestamp.wk.work);
|
||||||
|
unsigned long delay = fwrt->timestamp.delay;
|
||||||
|
|
||||||
|
ret = iwl_fw_send_timestamp_marker_cmd(fwrt);
|
||||||
|
if (!ret && delay)
|
||||||
|
schedule_delayed_work(&fwrt->timestamp.wk,
|
||||||
|
round_jiffies_relative(delay));
|
||||||
|
else
|
||||||
|
IWL_INFO(fwrt,
|
||||||
|
"stopping timestamp_marker, ret: %d, delay: %u\n",
|
||||||
|
ret, jiffies_to_msecs(delay) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt,
|
||||||
|
char *buf, size_t count,
|
||||||
|
loff_t *ppos)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u32 delay;
|
||||||
|
|
||||||
|
ret = kstrtou32(buf, 10, &delay);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
IWL_INFO(fwrt,
|
||||||
|
"starting timestamp_marker trigger with delay: %us\n",
|
||||||
|
delay);
|
||||||
|
|
||||||
|
iwl_fw_cancel_timestamp(fwrt);
|
||||||
|
|
||||||
|
fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000);
|
||||||
|
|
||||||
|
schedule_delayed_work(&fwrt->timestamp.wk,
|
||||||
|
round_jiffies_relative(fwrt->timestamp.delay));
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
FWRT_DEBUGFS_WRITE_FILE_OPS(timestamp_marker, 10);
|
||||||
|
|
||||||
|
int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct dentry *dbgfs_dir)
|
||||||
|
{
|
||||||
|
INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk);
|
||||||
|
FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, S_IWUSR);
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
87
drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
Normal file
87
drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
* redistributing this file, you may do so under either license.
|
||||||
|
*
|
||||||
|
* GPL LICENSE SUMMARY
|
||||||
|
*
|
||||||
|
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program.
|
||||||
|
*
|
||||||
|
* The full GNU General Public License is included in this distribution
|
||||||
|
* in the file called COPYING.
|
||||||
|
*
|
||||||
|
* Contact Information:
|
||||||
|
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||||
|
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||||
|
*
|
||||||
|
* BSD LICENSE
|
||||||
|
*
|
||||||
|
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name Intel Corporation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
|
int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct dentry *dbgfs_dir);
|
||||||
|
|
||||||
|
static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt)
|
||||||
|
{
|
||||||
|
fwrt->timestamp.delay = 0;
|
||||||
|
cancel_delayed_work_sync(&fwrt->timestamp.wk);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct dentry *dbgfs_dir)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {}
|
||||||
|
|
||||||
|
#endif /* CONFIG_IWLWIFI_DEBUGFS */
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@ -34,7 +34,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -248,6 +248,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
|||||||
* @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
|
* @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
|
||||||
* @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field
|
* @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field
|
||||||
* indicating low latency direction.
|
* indicating low latency direction.
|
||||||
|
* @IWL_UCODE_TLV_API_DEPRECATE_TTAK: RX status flag TTAK ok (bit 7) is
|
||||||
|
* deprecated.
|
||||||
*
|
*
|
||||||
* @NUM_IWL_UCODE_TLV_API: number of bits used
|
* @NUM_IWL_UCODE_TLV_API: number of bits used
|
||||||
*/
|
*/
|
||||||
@ -266,6 +268,7 @@ enum iwl_ucode_tlv_api {
|
|||||||
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34,
|
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34,
|
||||||
IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35,
|
IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35,
|
||||||
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38,
|
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38,
|
||||||
|
IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41,
|
||||||
|
|
||||||
NUM_IWL_UCODE_TLV_API
|
NUM_IWL_UCODE_TLV_API
|
||||||
#ifdef __CHECKER__
|
#ifdef __CHECKER__
|
||||||
@ -311,6 +314,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||||||
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
|
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
|
||||||
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
|
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
|
||||||
* @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm
|
* @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm
|
||||||
|
* @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related
|
||||||
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
|
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
|
||||||
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
|
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
|
||||||
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
|
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
|
||||||
@ -366,6 +370,7 @@ enum iwl_ucode_tlv_capa {
|
|||||||
IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40,
|
IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40,
|
||||||
IWL_UCODE_TLV_CAPA_D0I3_END_FIRST = (__force iwl_ucode_tlv_capa_t)41,
|
IWL_UCODE_TLV_CAPA_D0I3_END_FIRST = (__force iwl_ucode_tlv_capa_t)41,
|
||||||
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43,
|
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43,
|
||||||
|
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44,
|
||||||
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
|
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
|
||||||
IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65,
|
IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65,
|
||||||
IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67,
|
IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67,
|
||||||
@ -540,7 +545,7 @@ struct iwl_fw_dbg_mem_seg_tlv {
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_fw_dbg_dest_tlv - configures the destination of the debug data
|
* struct iwl_fw_dbg_dest_tlv_v1 - configures the destination of the debug data
|
||||||
*
|
*
|
||||||
* @version: version of the TLV - currently 0
|
* @version: version of the TLV - currently 0
|
||||||
* @monitor_mode: &enum iwl_fw_dbg_monitor_mode
|
* @monitor_mode: &enum iwl_fw_dbg_monitor_mode
|
||||||
@ -555,7 +560,7 @@ struct iwl_fw_dbg_mem_seg_tlv {
|
|||||||
*
|
*
|
||||||
* This parses IWL_UCODE_TLV_FW_DBG_DEST
|
* This parses IWL_UCODE_TLV_FW_DBG_DEST
|
||||||
*/
|
*/
|
||||||
struct iwl_fw_dbg_dest_tlv {
|
struct iwl_fw_dbg_dest_tlv_v1 {
|
||||||
u8 version;
|
u8 version;
|
||||||
u8 monitor_mode;
|
u8 monitor_mode;
|
||||||
u8 size_power;
|
u8 size_power;
|
||||||
@ -569,6 +574,26 @@ struct iwl_fw_dbg_dest_tlv {
|
|||||||
struct iwl_fw_dbg_reg_op reg_ops[0];
|
struct iwl_fw_dbg_reg_op reg_ops[0];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* Mask of the register for defining the LDBG MAC2SMEM buffer SMEM size */
|
||||||
|
#define IWL_LDBG_M2S_BUF_SIZE_MSK 0x0fff0000
|
||||||
|
/* Mask of the register for defining the LDBG MAC2SMEM SMEM base address */
|
||||||
|
#define IWL_LDBG_M2S_BUF_BA_MSK 0x00000fff
|
||||||
|
/* The smem buffer chunks are in units of 256 bits */
|
||||||
|
#define IWL_M2S_UNIT_SIZE 0x100
|
||||||
|
|
||||||
|
struct iwl_fw_dbg_dest_tlv {
|
||||||
|
u8 version;
|
||||||
|
u8 monitor_mode;
|
||||||
|
u8 size_power;
|
||||||
|
u8 reserved;
|
||||||
|
__le32 cfg_reg;
|
||||||
|
__le32 write_ptr_reg;
|
||||||
|
__le32 wrap_count;
|
||||||
|
u8 base_shift;
|
||||||
|
u8 size_shift;
|
||||||
|
struct iwl_fw_dbg_reg_op reg_ops[0];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct iwl_fw_dbg_conf_hcmd {
|
struct iwl_fw_dbg_conf_hcmd {
|
||||||
u8 id;
|
u8 id;
|
||||||
u8 reserved;
|
u8 reserved;
|
||||||
|
@ -284,7 +284,7 @@ struct iwl_fw {
|
|||||||
struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS];
|
struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS];
|
||||||
u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
|
u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
|
||||||
|
|
||||||
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
|
||||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||||
|
@ -58,10 +58,12 @@
|
|||||||
#include "iwl-drv.h"
|
#include "iwl-drv.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "dbg.h"
|
#include "dbg.h"
|
||||||
|
#include "debugfs.h"
|
||||||
|
|
||||||
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
||||||
const struct iwl_fw *fw,
|
const struct iwl_fw *fw,
|
||||||
const struct iwl_fw_runtime_ops *ops, void *ops_ctx)
|
const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
|
||||||
|
struct dentry *dbgfs_dir)
|
||||||
{
|
{
|
||||||
memset(fwrt, 0, sizeof(*fwrt));
|
memset(fwrt, 0, sizeof(*fwrt));
|
||||||
fwrt->trans = trans;
|
fwrt->trans = trans;
|
||||||
@ -71,5 +73,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
|||||||
fwrt->ops = ops;
|
fwrt->ops = ops;
|
||||||
fwrt->ops_ctx = ops_ctx;
|
fwrt->ops_ctx = ops_ctx;
|
||||||
INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk);
|
INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk);
|
||||||
|
iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
|
||||||
}
|
}
|
||||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
|
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
|
||||||
|
|
||||||
|
void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt)
|
||||||
|
{
|
||||||
|
iwl_fw_cancel_timestamp(fwrt);
|
||||||
|
}
|
||||||
|
IWL_EXPORT_SYMBOL(iwl_fw_runtime_exit);
|
||||||
|
@ -134,11 +134,21 @@ struct iwl_fw_runtime {
|
|||||||
/* ts of the beginning of a non-collect fw dbg data period */
|
/* ts of the beginning of a non-collect fw dbg data period */
|
||||||
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
||||||
} dump;
|
} dump;
|
||||||
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
|
struct {
|
||||||
|
struct delayed_work wk;
|
||||||
|
u32 delay;
|
||||||
|
u64 seq;
|
||||||
|
} timestamp;
|
||||||
|
#endif /* CONFIG_IWLWIFI_DEBUGFS */
|
||||||
};
|
};
|
||||||
|
|
||||||
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
||||||
const struct iwl_fw *fw,
|
const struct iwl_fw *fw,
|
||||||
const struct iwl_fw_runtime_ops *ops, void *ops_ctx);
|
const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
|
||||||
|
struct dentry *dbgfs_dir);
|
||||||
|
|
||||||
|
void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt);
|
||||||
|
|
||||||
static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
|
static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
|
||||||
enum iwl_ucode_type cur_fw_img)
|
enum iwl_ucode_type cur_fw_img)
|
||||||
|
@ -95,7 +95,7 @@ TRACE_EVENT(iwlwifi_dev_tx,
|
|||||||
TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, hdr_len),
|
TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, hdr_len),
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
DEV_ENTRY
|
DEV_ENTRY
|
||||||
|
__field(void *, skbaddr)
|
||||||
__field(size_t, framelen)
|
__field(size_t, framelen)
|
||||||
__dynamic_array(u8, tfd, tfdlen)
|
__dynamic_array(u8, tfd, tfdlen)
|
||||||
|
|
||||||
@ -110,6 +110,7 @@ TRACE_EVENT(iwlwifi_dev_tx,
|
|||||||
),
|
),
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
DEV_ASSIGN;
|
DEV_ASSIGN;
|
||||||
|
__entry->skbaddr = skb;
|
||||||
__entry->framelen = buf0_len;
|
__entry->framelen = buf0_len;
|
||||||
if (hdr_len > 0)
|
if (hdr_len > 0)
|
||||||
__entry->framelen += skb->len - hdr_len;
|
__entry->framelen += skb->len - hdr_len;
|
||||||
@ -120,9 +121,9 @@ TRACE_EVENT(iwlwifi_dev_tx,
|
|||||||
__get_dynamic_array(buf1),
|
__get_dynamic_array(buf1),
|
||||||
skb->len - hdr_len);
|
skb->len - hdr_len);
|
||||||
),
|
),
|
||||||
TP_printk("[%s] TX %.2x (%zu bytes)",
|
TP_printk("[%s] TX %.2x (%zu bytes) skbaddr=%p",
|
||||||
__get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
|
__get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
|
||||||
__entry->framelen)
|
__entry->framelen, __entry->skbaddr)
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(iwlwifi_dev_ucode_error,
|
TRACE_EVENT(iwlwifi_dev_ucode_error,
|
||||||
|
@ -296,7 +296,12 @@ struct iwl_firmware_pieces {
|
|||||||
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
|
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
|
||||||
|
|
||||||
/* FW debug data parsed for driver usage */
|
/* FW debug data parsed for driver usage */
|
||||||
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
bool dbg_dest_tlv_init;
|
||||||
|
u8 *dbg_dest_ver;
|
||||||
|
union {
|
||||||
|
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||||
|
struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv_v1;
|
||||||
|
};
|
||||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||||
@ -930,21 +935,49 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IWL_UCODE_TLV_FW_DBG_DEST: {
|
case IWL_UCODE_TLV_FW_DBG_DEST: {
|
||||||
struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
|
struct iwl_fw_dbg_dest_tlv *dest = NULL;
|
||||||
|
struct iwl_fw_dbg_dest_tlv_v1 *dest_v1 = NULL;
|
||||||
|
u8 mon_mode;
|
||||||
|
|
||||||
if (pieces->dbg_dest_tlv) {
|
pieces->dbg_dest_ver = (u8 *)tlv_data;
|
||||||
|
if (*pieces->dbg_dest_ver == 1) {
|
||||||
|
dest = (void *)tlv_data;
|
||||||
|
} else if (*pieces->dbg_dest_ver == 0) {
|
||||||
|
dest_v1 = (void *)tlv_data;
|
||||||
|
} else {
|
||||||
|
IWL_ERR(drv,
|
||||||
|
"The version is %d, and it is invalid\n",
|
||||||
|
*pieces->dbg_dest_ver);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pieces->dbg_dest_tlv_init) {
|
||||||
IWL_ERR(drv,
|
IWL_ERR(drv,
|
||||||
"dbg destination ignored, already exists\n");
|
"dbg destination ignored, already exists\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pieces->dbg_dest_tlv = dest;
|
pieces->dbg_dest_tlv_init = true;
|
||||||
IWL_INFO(drv, "Found debug destination: %s\n",
|
|
||||||
get_fw_dbg_mode_string(dest->monitor_mode));
|
if (dest_v1) {
|
||||||
|
pieces->dbg_dest_tlv_v1 = dest_v1;
|
||||||
|
mon_mode = dest_v1->monitor_mode;
|
||||||
|
} else {
|
||||||
|
pieces->dbg_dest_tlv = dest;
|
||||||
|
mon_mode = dest->monitor_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
IWL_INFO(drv, "Found debug destination: %s\n",
|
||||||
|
get_fw_dbg_mode_string(mon_mode));
|
||||||
|
|
||||||
|
drv->fw.dbg_dest_reg_num = (dest_v1) ?
|
||||||
|
tlv_len -
|
||||||
|
offsetof(struct iwl_fw_dbg_dest_tlv_v1,
|
||||||
|
reg_ops) :
|
||||||
|
tlv_len -
|
||||||
|
offsetof(struct iwl_fw_dbg_dest_tlv,
|
||||||
|
reg_ops);
|
||||||
|
|
||||||
drv->fw.dbg_dest_reg_num =
|
|
||||||
tlv_len - offsetof(struct iwl_fw_dbg_dest_tlv,
|
|
||||||
reg_ops);
|
|
||||||
drv->fw.dbg_dest_reg_num /=
|
drv->fw.dbg_dest_reg_num /=
|
||||||
sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]);
|
sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]);
|
||||||
|
|
||||||
@ -953,7 +986,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||||||
case IWL_UCODE_TLV_FW_DBG_CONF: {
|
case IWL_UCODE_TLV_FW_DBG_CONF: {
|
||||||
struct iwl_fw_dbg_conf_tlv *conf = (void *)tlv_data;
|
struct iwl_fw_dbg_conf_tlv *conf = (void *)tlv_data;
|
||||||
|
|
||||||
if (!pieces->dbg_dest_tlv) {
|
if (!pieces->dbg_dest_tlv_init) {
|
||||||
IWL_ERR(drv,
|
IWL_ERR(drv,
|
||||||
"Ignore dbg config %d - no destination configured\n",
|
"Ignore dbg config %d - no destination configured\n",
|
||||||
conf->id);
|
conf->id);
|
||||||
@ -1340,15 +1373,51 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||||||
if (iwl_alloc_ucode(drv, pieces, i))
|
if (iwl_alloc_ucode(drv, pieces, i))
|
||||||
goto out_free_fw;
|
goto out_free_fw;
|
||||||
|
|
||||||
if (pieces->dbg_dest_tlv) {
|
if (pieces->dbg_dest_tlv_init) {
|
||||||
drv->fw.dbg_dest_tlv =
|
size_t dbg_dest_size = sizeof(*drv->fw.dbg_dest_tlv) +
|
||||||
kmemdup(pieces->dbg_dest_tlv,
|
sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]) *
|
||||||
sizeof(*pieces->dbg_dest_tlv) +
|
drv->fw.dbg_dest_reg_num;
|
||||||
sizeof(pieces->dbg_dest_tlv->reg_ops[0]) *
|
|
||||||
drv->fw.dbg_dest_reg_num, GFP_KERNEL);
|
drv->fw.dbg_dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL);
|
||||||
|
|
||||||
if (!drv->fw.dbg_dest_tlv)
|
if (!drv->fw.dbg_dest_tlv)
|
||||||
goto out_free_fw;
|
goto out_free_fw;
|
||||||
|
|
||||||
|
if (*pieces->dbg_dest_ver == 0) {
|
||||||
|
memcpy(drv->fw.dbg_dest_tlv, pieces->dbg_dest_tlv_v1,
|
||||||
|
dbg_dest_size);
|
||||||
|
} else {
|
||||||
|
struct iwl_fw_dbg_dest_tlv_v1 *dest_tlv =
|
||||||
|
drv->fw.dbg_dest_tlv;
|
||||||
|
|
||||||
|
dest_tlv->version = pieces->dbg_dest_tlv->version;
|
||||||
|
dest_tlv->monitor_mode =
|
||||||
|
pieces->dbg_dest_tlv->monitor_mode;
|
||||||
|
dest_tlv->size_power =
|
||||||
|
pieces->dbg_dest_tlv->size_power;
|
||||||
|
dest_tlv->wrap_count =
|
||||||
|
pieces->dbg_dest_tlv->wrap_count;
|
||||||
|
dest_tlv->write_ptr_reg =
|
||||||
|
pieces->dbg_dest_tlv->write_ptr_reg;
|
||||||
|
dest_tlv->base_shift =
|
||||||
|
pieces->dbg_dest_tlv->base_shift;
|
||||||
|
memcpy(dest_tlv->reg_ops,
|
||||||
|
pieces->dbg_dest_tlv->reg_ops,
|
||||||
|
sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]) *
|
||||||
|
drv->fw.dbg_dest_reg_num);
|
||||||
|
|
||||||
|
/* In version 1 of the destination tlv, which is
|
||||||
|
* relevant for internal buffer exclusively,
|
||||||
|
* the base address is part of given with the length
|
||||||
|
* of the buffer, and the size shift is give instead of
|
||||||
|
* end shift. We now store these values in base_reg,
|
||||||
|
* and end shift, and when dumping the data we'll
|
||||||
|
* manipulate it for extracting both the length and
|
||||||
|
* base address */
|
||||||
|
dest_tlv->base_reg = pieces->dbg_dest_tlv->cfg_reg;
|
||||||
|
dest_tlv->end_shift =
|
||||||
|
pieces->dbg_dest_tlv->size_shift;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) {
|
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) {
|
||||||
|
@ -579,6 +579,7 @@ struct iwl_trans_ops {
|
|||||||
void (*configure)(struct iwl_trans *trans,
|
void (*configure)(struct iwl_trans *trans,
|
||||||
const struct iwl_trans_config *trans_cfg);
|
const struct iwl_trans_config *trans_cfg);
|
||||||
void (*set_pmi)(struct iwl_trans *trans, bool state);
|
void (*set_pmi)(struct iwl_trans *trans, bool state);
|
||||||
|
void (*sw_reset)(struct iwl_trans *trans);
|
||||||
bool (*grab_nic_access)(struct iwl_trans *trans, unsigned long *flags);
|
bool (*grab_nic_access)(struct iwl_trans *trans, unsigned long *flags);
|
||||||
void (*release_nic_access)(struct iwl_trans *trans,
|
void (*release_nic_access)(struct iwl_trans *trans,
|
||||||
unsigned long *flags);
|
unsigned long *flags);
|
||||||
@ -744,7 +745,7 @@ struct iwl_trans {
|
|||||||
struct lockdep_map sync_cmd_lockdep_map;
|
struct lockdep_map sync_cmd_lockdep_map;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
|
||||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||||
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
||||||
u8 dbg_dest_reg_num;
|
u8 dbg_dest_reg_num;
|
||||||
@ -1124,6 +1125,12 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
|
|||||||
trans->ops->set_pmi(trans, state);
|
trans->ops->set_pmi(trans, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void iwl_trans_sw_reset(struct iwl_trans *trans)
|
||||||
|
{
|
||||||
|
if (trans->ops->sw_reset)
|
||||||
|
trans->ops->sw_reset(trans);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
|
iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
|
||||||
{
|
{
|
||||||
|
@ -1221,7 +1221,7 @@ static ssize_t iwl_dbgfs_cont_recording_write(struct iwl_mvm *mvm,
|
|||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct iwl_trans *trans = mvm->trans;
|
struct iwl_trans *trans = mvm->trans;
|
||||||
const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
|
const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv;
|
||||||
struct iwl_continuous_record_cmd cont_rec = {};
|
struct iwl_continuous_record_cmd cont_rec = {};
|
||||||
int ret, rec_mode;
|
int ret, rec_mode;
|
||||||
|
|
||||||
@ -1914,7 +1914,7 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
|
|||||||
{
|
{
|
||||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||||
|
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
|
if (iwl_mvm_has_tlc_offload(mvm))
|
||||||
MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, S_IRUSR);
|
MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, S_IRUSR);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -421,7 +421,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||||||
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
|
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
|
||||||
ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
|
ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
|
||||||
|
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) {
|
if (iwl_mvm_has_tlc_offload(mvm)) {
|
||||||
ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
|
ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
|
||||||
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
|
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
|
||||||
}
|
}
|
||||||
@ -460,7 +460,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||||||
/* this is the case for CCK frames, it's better (only 8) for OFDM */
|
/* this is the case for CCK frames, it's better (only 8) for OFDM */
|
||||||
hw->radiotap_timestamp.accuracy = 22;
|
hw->radiotap_timestamp.accuracy = 22;
|
||||||
|
|
||||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
|
if (!iwl_mvm_has_tlc_offload(mvm))
|
||||||
hw->rate_control_algorithm = RS_NAME;
|
hw->rate_control_algorithm = RS_NAME;
|
||||||
|
|
||||||
hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
|
hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
|
||||||
@ -3801,7 +3801,7 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
|
|||||||
mvm->noa_duration = noa_duration;
|
mvm->noa_duration = noa_duration;
|
||||||
mvm->noa_vif = vif;
|
mvm->noa_vif = vif;
|
||||||
|
|
||||||
return iwl_mvm_update_quotas(mvm, false, NULL);
|
return iwl_mvm_update_quotas(mvm, true, NULL);
|
||||||
case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
|
case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
|
||||||
/* must be associated client vif - ignore authorized */
|
/* must be associated client vif - ignore authorized */
|
||||||
if (!vif || vif->type != NL80211_IFTYPE_STATION ||
|
if (!vif || vif->type != NL80211_IFTYPE_STATION ||
|
||||||
|
@ -1278,6 +1278,12 @@ static inline bool iwl_mvm_has_quota_low_latency(struct iwl_mvm *mvm)
|
|||||||
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY);
|
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool iwl_mvm_has_tlc_offload(const struct iwl_mvm *mvm)
|
||||||
|
{
|
||||||
|
return fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct agg_tx_status *
|
static inline struct agg_tx_status *
|
||||||
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
|
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
|
||||||
{
|
{
|
||||||
|
@ -602,7 +602,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||||||
mvm->fw = fw;
|
mvm->fw = fw;
|
||||||
mvm->hw = hw;
|
mvm->hw = hw;
|
||||||
|
|
||||||
iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm);
|
iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm,
|
||||||
|
dbgfs_dir);
|
||||||
|
|
||||||
mvm->init_status = 0;
|
mvm->init_status = 0;
|
||||||
|
|
||||||
@ -801,6 +802,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||||||
iwl_mvm_leds_exit(mvm);
|
iwl_mvm_leds_exit(mvm);
|
||||||
iwl_mvm_thermal_exit(mvm);
|
iwl_mvm_thermal_exit(mvm);
|
||||||
out_free:
|
out_free:
|
||||||
|
iwl_fw_runtime_exit(&mvm->fwrt);
|
||||||
iwl_fw_flush_dump(&mvm->fwrt);
|
iwl_fw_flush_dump(&mvm->fwrt);
|
||||||
|
|
||||||
if (iwlmvm_mod_params.init_dbg)
|
if (iwlmvm_mod_params.init_dbg)
|
||||||
@ -841,7 +843,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
|||||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
|
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
|
||||||
kfree(mvm->d3_resume_sram);
|
kfree(mvm->d3_resume_sram);
|
||||||
#endif
|
#endif
|
||||||
|
iwl_fw_runtime_exit(&mvm->fwrt);
|
||||||
iwl_trans_op_mode_leave(mvm->trans);
|
iwl_trans_op_mode_leave(mvm->trans);
|
||||||
|
|
||||||
iwl_phy_db_free(mvm->phy_db);
|
iwl_phy_db_free(mvm->phy_db);
|
||||||
|
@ -202,6 +202,10 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
|||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
|
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* update all upon completion */
|
/* update all upon completion */
|
||||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4052,7 +4052,7 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
|
|||||||
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
enum nl80211_band band, bool init)
|
enum nl80211_band band, bool init)
|
||||||
{
|
{
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
|
if (iwl_mvm_has_tlc_offload(mvm))
|
||||||
rs_fw_rate_init(mvm, sta, band);
|
rs_fw_rate_init(mvm, sta, band);
|
||||||
else
|
else
|
||||||
rs_drv_rate_init(mvm, sta, band, init);
|
rs_drv_rate_init(mvm, sta, band, init);
|
||||||
@ -4096,7 +4096,7 @@ static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
|||||||
int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
|
if (iwl_mvm_has_tlc_offload(mvm))
|
||||||
return rs_fw_tx_protection(mvm, mvmsta, enable);
|
return rs_fw_tx_protection(mvm, mvmsta, enable);
|
||||||
else
|
else
|
||||||
return rs_drv_tx_protection(mvm, mvmsta, enable);
|
return rs_drv_tx_protection(mvm, mvmsta, enable);
|
||||||
|
@ -222,7 +222,9 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
|
|||||||
|
|
||||||
case RX_MPDU_RES_STATUS_SEC_TKIP_ENC:
|
case RX_MPDU_RES_STATUS_SEC_TKIP_ENC:
|
||||||
/* Don't drop the frame and decrypt it in SW */
|
/* Don't drop the frame and decrypt it in SW */
|
||||||
if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
|
if (!fw_has_api(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_API_DEPRECATE_TTAK) &&
|
||||||
|
!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
|
||||||
return 0;
|
return 0;
|
||||||
*crypt_len = IEEE80211_TKIP_IV_LEN;
|
*crypt_len = IEEE80211_TKIP_IV_LEN;
|
||||||
/* fall through if TTAK OK */
|
/* fall through if TTAK OK */
|
||||||
|
@ -261,7 +261,9 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
|||||||
return 0;
|
return 0;
|
||||||
case IWL_RX_MPDU_STATUS_SEC_TKIP:
|
case IWL_RX_MPDU_STATUS_SEC_TKIP:
|
||||||
/* Don't drop the frame and decrypt it in SW */
|
/* Don't drop the frame and decrypt it in SW */
|
||||||
if (!(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK))
|
if (!fw_has_api(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_API_DEPRECATE_TTAK) &&
|
||||||
|
!(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*crypt_len = IEEE80211_TKIP_IV_LEN;
|
*crypt_len = IEEE80211_TKIP_IV_LEN;
|
||||||
|
@ -1443,7 +1443,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
|||||||
* if rs is registered with mac80211, then "add station" will be handled
|
* if rs is registered with mac80211, then "add station" will be handled
|
||||||
* via the corresponding ops, otherwise need to notify rate scaling here
|
* via the corresponding ops, otherwise need to notify rate scaling here
|
||||||
*/
|
*/
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
|
if (iwl_mvm_has_tlc_offload(mvm))
|
||||||
iwl_mvm_rs_add_sta(mvm, mvm_sta);
|
iwl_mvm_rs_add_sta(mvm, mvm_sta);
|
||||||
|
|
||||||
update_fw:
|
update_fw:
|
||||||
@ -2586,8 +2586,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||||||
* When FW supports TLC_OFFLOAD, it also implements Tx aggregation
|
* When FW supports TLC_OFFLOAD, it also implements Tx aggregation
|
||||||
* manager, so this function should never be called in this case.
|
* manager, so this function should never be called in this case.
|
||||||
*/
|
*/
|
||||||
if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa,
|
if (WARN_ON_ONCE(iwl_mvm_has_tlc_offload(mvm)))
|
||||||
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)))
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE)
|
BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE)
|
||||||
|
@ -888,10 +888,9 @@ static void iwl_mvm_tx_add_stream(struct iwl_mvm *mvm,
|
|||||||
/*
|
/*
|
||||||
* The first deferred frame should've stopped the MAC queues, so we
|
* The first deferred frame should've stopped the MAC queues, so we
|
||||||
* should never get a second deferred frame for the RA/TID.
|
* should never get a second deferred frame for the RA/TID.
|
||||||
|
* In case of GSO the first packet may have been split, so don't warn.
|
||||||
*/
|
*/
|
||||||
if (!WARN(skb_queue_len(deferred_tx_frames) != 1,
|
if (skb_queue_len(deferred_tx_frames) == 1) {
|
||||||
"RATID %d/%d has %d deferred frames\n", mvm_sta->sta_id, tid,
|
|
||||||
skb_queue_len(deferred_tx_frames))) {
|
|
||||||
iwl_mvm_stop_mac_queues(mvm, BIT(mac_queue));
|
iwl_mvm_stop_mac_queues(mvm, BIT(mac_queue));
|
||||||
schedule_work(&mvm->add_stream_wk);
|
schedule_work(&mvm->add_stream_wk);
|
||||||
}
|
}
|
||||||
@ -1719,8 +1718,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
|||||||
ba_info->band = chanctx_conf->def.chan->band;
|
ba_info->band = chanctx_conf->def.chan->band;
|
||||||
iwl_mvm_hwrate_to_tx_status(rate, ba_info);
|
iwl_mvm_hwrate_to_tx_status(rate, ba_info);
|
||||||
|
|
||||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
if (!iwl_mvm_has_tlc_offload(mvm)) {
|
||||||
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)) {
|
|
||||||
IWL_DEBUG_TX_REPLY(mvm,
|
IWL_DEBUG_TX_REPLY(mvm,
|
||||||
"No reclaim. Update rs directly\n");
|
"No reclaim. Update rs directly\n");
|
||||||
iwl_mvm_rs_tx_status(mvm, sta, tid, ba_info, false);
|
iwl_mvm_rs_tx_status(mvm, sta, tid, ba_info, false);
|
||||||
|
@ -516,8 +516,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base)
|
|||||||
IWL_ERR(trans, "HW error, resetting before reading\n");
|
IWL_ERR(trans, "HW error, resetting before reading\n");
|
||||||
|
|
||||||
/* reset the device */
|
/* reset the device */
|
||||||
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
iwl_trans_sw_reset(trans);
|
||||||
usleep_range(5000, 6000);
|
|
||||||
|
|
||||||
/* set INIT_DONE flag */
|
/* set INIT_DONE flag */
|
||||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||||
@ -913,8 +912,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (WARN_ON(lq->sta_id == IWL_MVM_INVALID_STA ||
|
if (WARN_ON(lq->sta_id == IWL_MVM_INVALID_STA ||
|
||||||
fw_has_capa(&mvm->fw->ucode_capa,
|
iwl_mvm_has_tlc_offload(mvm)))
|
||||||
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD)))
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return iwl_mvm_send_cmd(mvm, &cmd);
|
return iwl_mvm_send_cmd(mvm, &cmd);
|
||||||
@ -1033,12 +1031,34 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||||||
{
|
{
|
||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
int res;
|
int res;
|
||||||
|
bool low_latency;
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
if (iwl_mvm_vif_low_latency(mvmvif) == prev)
|
low_latency = iwl_mvm_vif_low_latency(mvmvif);
|
||||||
|
|
||||||
|
if (low_latency == prev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA)) {
|
||||||
|
struct iwl_mac_low_latency_cmd cmd = {
|
||||||
|
.mac_id = cpu_to_le32(mvmvif->id)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (low_latency) {
|
||||||
|
/* currently we don't care about the direction */
|
||||||
|
cmd.low_latency_rx = 1;
|
||||||
|
cmd.low_latency_tx = 1;
|
||||||
|
}
|
||||||
|
res = iwl_mvm_send_cmd_pdu(mvm,
|
||||||
|
iwl_cmd_id(LOW_LATENCY_CMD,
|
||||||
|
MAC_CONF_GROUP, 0),
|
||||||
|
0, sizeof(cmd), &cmd);
|
||||||
|
if (res)
|
||||||
|
IWL_ERR(mvm, "Failed to send low latency command\n");
|
||||||
|
}
|
||||||
|
|
||||||
res = iwl_mvm_update_quotas(mvm, false, NULL);
|
res = iwl_mvm_update_quotas(mvm, false, NULL);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
@ -658,13 +658,6 @@ static inline void iwl_enable_fw_load_int(struct iwl_trans *trans)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void iwl_pcie_sw_reset(struct iwl_trans *trans)
|
|
||||||
{
|
|
||||||
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
|
|
||||||
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
|
||||||
usleep_range(5000, 6000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq *q, u32 index)
|
static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq *q, u32 index)
|
||||||
{
|
{
|
||||||
return index & (q->n_window - 1);
|
return index & (q->n_window - 1);
|
||||||
|
@ -137,7 +137,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
|
|||||||
/* Stop device's DMA activity */
|
/* Stop device's DMA activity */
|
||||||
iwl_pcie_apm_stop_master(trans);
|
iwl_pcie_apm_stop_master(trans);
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_sw_reset(trans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear "initialization complete" bit to move adapter from
|
* Clear "initialization complete" bit to move adapter from
|
||||||
@ -192,7 +192,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
|||||||
/* Stop the device, and put it in low power state */
|
/* Stop the device, and put it in low power state */
|
||||||
iwl_pcie_gen2_apm_stop(trans, false);
|
iwl_pcie_gen2_apm_stop(trans, false);
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_sw_reset(trans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Upon stop, the IVAR table gets erased, so msi-x won't
|
* Upon stop, the IVAR table gets erased, so msi-x won't
|
||||||
|
@ -176,6 +176,13 @@ out:
|
|||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
|
||||||
|
{
|
||||||
|
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
|
||||||
|
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
||||||
|
usleep_range(5000, 6000);
|
||||||
|
}
|
||||||
|
|
||||||
static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
|
static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
@ -446,7 +453,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
|
|||||||
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
|
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
|
||||||
CSR_GP_CNTRL_REG_FLAG_XTAL_ON);
|
CSR_GP_CNTRL_REG_FLAG_XTAL_ON);
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set "initialization complete" bit to move adapter from
|
* Set "initialization complete" bit to move adapter from
|
||||||
@ -487,7 +494,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
|
|||||||
apmg_xtal_cfg_reg |
|
apmg_xtal_cfg_reg |
|
||||||
SHR_APMG_XTAL_CFG_XTAL_ON_REQ);
|
SHR_APMG_XTAL_CFG_XTAL_ON_REQ);
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
/* Enable LP XTAL by indirect access through CSR */
|
/* Enable LP XTAL by indirect access through CSR */
|
||||||
apmg_gp1_reg = iwl_trans_pcie_read_shr(trans, SHR_APMG_GP1_REG);
|
apmg_gp1_reg = iwl_trans_pcie_read_shr(trans, SHR_APMG_GP1_REG);
|
||||||
@ -580,7 +587,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear "initialization complete" bit to move adapter from
|
* Clear "initialization complete" bit to move adapter from
|
||||||
@ -915,14 +922,9 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
|
|||||||
void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
|
const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (dest->version)
|
|
||||||
IWL_ERR(trans,
|
|
||||||
"DBG DEST version is %d - expect issues\n",
|
|
||||||
dest->version);
|
|
||||||
|
|
||||||
IWL_INFO(trans, "Applying debug destination %s\n",
|
IWL_INFO(trans, "Applying debug destination %s\n",
|
||||||
get_fw_dbg_mode_string(dest->monitor_mode));
|
get_fw_dbg_mode_string(dest->monitor_mode));
|
||||||
|
|
||||||
@ -1270,7 +1272,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
|||||||
/* Stop the device, and put it in low power state */
|
/* Stop the device, and put it in low power state */
|
||||||
iwl_pcie_apm_stop(trans, false);
|
iwl_pcie_apm_stop(trans, false);
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Upon stop, the IVAR table gets erased, so msi-x won't
|
* Upon stop, the IVAR table gets erased, so msi-x won't
|
||||||
@ -1744,7 +1746,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
iwl_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
err = iwl_pcie_apm_init(trans);
|
err = iwl_pcie_apm_init(trans);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2816,8 +2818,17 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
|||||||
* Update pointers to reflect actual values after
|
* Update pointers to reflect actual values after
|
||||||
* shifting
|
* shifting
|
||||||
*/
|
*/
|
||||||
base = iwl_read_prph(trans, base) <<
|
if (trans->dbg_dest_tlv->version) {
|
||||||
trans->dbg_dest_tlv->base_shift;
|
base = (iwl_read_prph(trans, base) &
|
||||||
|
IWL_LDBG_M2S_BUF_BA_MSK) <<
|
||||||
|
trans->dbg_dest_tlv->base_shift;
|
||||||
|
base *= IWL_M2S_UNIT_SIZE;
|
||||||
|
base += trans->cfg->smem_offset;
|
||||||
|
} else {
|
||||||
|
base = iwl_read_prph(trans, base) <<
|
||||||
|
trans->dbg_dest_tlv->base_shift;
|
||||||
|
}
|
||||||
|
|
||||||
iwl_trans_read_mem(trans, base, fw_mon_data->data,
|
iwl_trans_read_mem(trans, base, fw_mon_data->data,
|
||||||
monitor_len / sizeof(u32));
|
monitor_len / sizeof(u32));
|
||||||
} else if (trans->dbg_dest_tlv->monitor_mode == MARBH_MODE) {
|
} else if (trans->dbg_dest_tlv->monitor_mode == MARBH_MODE) {
|
||||||
@ -2865,21 +2876,36 @@ static struct iwl_trans_dump_data
|
|||||||
trans_pcie->fw_mon_size;
|
trans_pcie->fw_mon_size;
|
||||||
monitor_len = trans_pcie->fw_mon_size;
|
monitor_len = trans_pcie->fw_mon_size;
|
||||||
} else if (trans->dbg_dest_tlv) {
|
} else if (trans->dbg_dest_tlv) {
|
||||||
u32 base, end;
|
u32 base, end, cfg_reg;
|
||||||
|
|
||||||
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
if (trans->dbg_dest_tlv->version == 1) {
|
||||||
end = le32_to_cpu(trans->dbg_dest_tlv->end_reg);
|
cfg_reg = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||||
|
cfg_reg = iwl_read_prph(trans, cfg_reg);
|
||||||
|
base = (cfg_reg & IWL_LDBG_M2S_BUF_BA_MSK) <<
|
||||||
|
trans->dbg_dest_tlv->base_shift;
|
||||||
|
base *= IWL_M2S_UNIT_SIZE;
|
||||||
|
base += trans->cfg->smem_offset;
|
||||||
|
|
||||||
base = iwl_read_prph(trans, base) <<
|
monitor_len =
|
||||||
trans->dbg_dest_tlv->base_shift;
|
(cfg_reg & IWL_LDBG_M2S_BUF_SIZE_MSK) >>
|
||||||
end = iwl_read_prph(trans, end) <<
|
trans->dbg_dest_tlv->end_shift;
|
||||||
trans->dbg_dest_tlv->end_shift;
|
monitor_len *= IWL_M2S_UNIT_SIZE;
|
||||||
|
} else {
|
||||||
|
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||||
|
end = le32_to_cpu(trans->dbg_dest_tlv->end_reg);
|
||||||
|
|
||||||
/* Make "end" point to the actual end */
|
base = iwl_read_prph(trans, base) <<
|
||||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000 ||
|
trans->dbg_dest_tlv->base_shift;
|
||||||
trans->dbg_dest_tlv->monitor_mode == MARBH_MODE)
|
end = iwl_read_prph(trans, end) <<
|
||||||
end += (1 << trans->dbg_dest_tlv->end_shift);
|
trans->dbg_dest_tlv->end_shift;
|
||||||
monitor_len = end - base;
|
|
||||||
|
/* Make "end" point to the actual end */
|
||||||
|
if (trans->cfg->device_family >=
|
||||||
|
IWL_DEVICE_FAMILY_8000 ||
|
||||||
|
trans->dbg_dest_tlv->monitor_mode == MARBH_MODE)
|
||||||
|
end += (1 << trans->dbg_dest_tlv->end_shift);
|
||||||
|
monitor_len = end - base;
|
||||||
|
}
|
||||||
len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
|
len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
|
||||||
monitor_len;
|
monitor_len;
|
||||||
} else {
|
} else {
|
||||||
@ -3025,6 +3051,7 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
|
|||||||
.write_mem = iwl_trans_pcie_write_mem, \
|
.write_mem = iwl_trans_pcie_write_mem, \
|
||||||
.configure = iwl_trans_pcie_configure, \
|
.configure = iwl_trans_pcie_configure, \
|
||||||
.set_pmi = iwl_trans_pcie_set_pmi, \
|
.set_pmi = iwl_trans_pcie_set_pmi, \
|
||||||
|
.sw_reset = iwl_trans_pcie_sw_reset, \
|
||||||
.grab_nic_access = iwl_trans_pcie_grab_nic_access, \
|
.grab_nic_access = iwl_trans_pcie_grab_nic_access, \
|
||||||
.release_nic_access = iwl_trans_pcie_release_nic_access, \
|
.release_nic_access = iwl_trans_pcie_release_nic_access, \
|
||||||
.set_bits_mask = iwl_trans_pcie_set_bits_mask, \
|
.set_bits_mask = iwl_trans_pcie_set_bits_mask, \
|
||||||
|
Loading…
Reference in New Issue
Block a user