Commit 1fe79d7f authored by Kalle Valo's avatar Kalle Valo

Merge tag 'iwlwifi-next-for-kalle-2017-08-18' of...

Merge tag 'iwlwifi-next-for-kalle-2017-08-18' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Third set of iwlwifi patches for 4.14

* Work for the upcoming A000 device family continues;
* Improvements in debugging;
* A couple of improvements in block-ack sessions;
* Some fixes for channel switch;
* A workaround for a HW data bug;
* Some FW API updates;
* General fixes and cleanups here and there.
parents 38ef6235 8fe34b06
...@@ -76,13 +76,19 @@ ...@@ -76,13 +76,19 @@
#define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" #define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" #define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
#define IWL_A000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" #define IWL_A000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
#define IWL_A000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-"
#define IWL_A000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
#define IWL_A000_HR_MODULE_FIRMWARE(api) \ #define IWL_A000_HR_MODULE_FIRMWARE(api) \
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode" IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_JF_MODULE_FIRMWARE(api) \ #define IWL_A000_JF_MODULE_FIRMWARE(api) \
IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode" IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_HR_QNJ_MODULE_FIRMWARE(api) \ #define IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode" IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_JF_B0_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_HR_A0_FW_PRE "-" __stringify(api) ".ucode"
#define NVM_HW_SECTION_NUM_FAMILY_A000 10 #define NVM_HW_SECTION_NUM_FAMILY_A000 10
...@@ -171,7 +177,7 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = { ...@@ -171,7 +177,7 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
}; };
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = { const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = {
.name = "Intel(R) Dual Band Wireless AX a000", .name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_HR_F0_FW_PRE, .fw_name_pre = IWL_A000_HR_F0_FW_PRE,
IWL_DEVICE_A000, IWL_DEVICE_A000,
...@@ -181,6 +187,28 @@ const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = { ...@@ -181,6 +187,28 @@ const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
}; };
const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_JF_B0_FW_PRE,
IWL_DEVICE_A000,
.ht_params = &iwl_a000_ht_params,
.nvm_ver = IWL_A000_NVM_VERSION,
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_HR_A0_FW_PRE,
IWL_DEVICE_A000,
.ht_params = &iwl_a000_ht_params,
.nvm_ver = IWL_A000_NVM_VERSION,
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_HR_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
...@@ -76,7 +76,6 @@ enum iwl_bt_coex_lut_type { ...@@ -76,7 +76,6 @@ enum iwl_bt_coex_lut_type {
BT_COEX_INVALID_LUT = 0xff, BT_COEX_INVALID_LUT = 0xff,
}; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */ }; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
#define BT_COEX_CORUN_LUT_SIZE (32)
#define BT_REDUCED_TX_POWER_BIT BIT(7) #define BT_REDUCED_TX_POWER_BIT BIT(7)
enum iwl_bt_coex_mode { enum iwl_bt_coex_mode {
...@@ -106,18 +105,6 @@ struct iwl_bt_coex_cmd { ...@@ -106,18 +105,6 @@ struct iwl_bt_coex_cmd {
__le32 enabled_modules; __le32 enabled_modules;
} __packed; /* BT_COEX_CMD_API_S_VER_6 */ } __packed; /* BT_COEX_CMD_API_S_VER_6 */
/**
* struct iwl_bt_coex_corun_lut_update - bt coex update the corun lut
* @corun_lut20: co-running 20 MHz LUT configuration
* @corun_lut40: co-running 40 MHz LUT configuration
*
* The structure is used for the BT_COEX_UPDATE_CORUN_LUT command.
*/
struct iwl_bt_coex_corun_lut_update_cmd {
__le32 corun_lut20[BT_COEX_CORUN_LUT_SIZE];
__le32 corun_lut40[BT_COEX_CORUN_LUT_SIZE];
} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
/** /**
* struct iwl_bt_coex_reduced_txp_update_cmd * struct iwl_bt_coex_reduced_txp_update_cmd
* @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
...@@ -191,6 +178,7 @@ enum iwl_bt_mxbox_dw3 { ...@@ -191,6 +178,7 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, ACL_STATE, 3, 1), BT_MBOX(3, ACL_STATE, 3, 1),
BT_MBOX(3, MSTR_STATE, 4, 1), BT_MBOX(3, MSTR_STATE, 4, 1),
BT_MBOX(3, OBX_STATE, 5, 1), BT_MBOX(3, OBX_STATE, 5, 1),
BT_MBOX(3, A2DP_SRC, 6, 1),
BT_MBOX(3, OPEN_CON_2, 8, 2), BT_MBOX(3, OPEN_CON_2, 8, 2),
BT_MBOX(3, TRAFFIC_LOAD, 10, 2), BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
BT_MBOX(3, CHL_SEQN_LSB, 12, 1), BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
...@@ -200,10 +188,21 @@ enum iwl_bt_mxbox_dw3 { ...@@ -200,10 +188,21 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, UPDATE_REQUEST, 21, 1), BT_MBOX(3, UPDATE_REQUEST, 21, 1),
}; };
enum iwl_bt_mxbox_dw4 {
BT_MBOX(4, ATS_BT_INTERVAL, 0, 7),
BT_MBOX(4, ATS_BT_ACTIVE_MAX_TH, 7, 7),
};
#define BT_MBOX_MSG(_notif, _num, _field) \ #define BT_MBOX_MSG(_notif, _num, _field) \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS) >> BT_MBOX##_num##_##_field##_POS)
#define BT_MBOX_PRINT(_num, _field, _end) \
pos += scnprintf(buf + pos, bufsz - pos, \
"\t%s: %d%s", \
#_field, \
BT_MBOX_MSG(notif, _num, _field), \
true ? "\n" : ", ");
enum iwl_bt_activity_grading { enum iwl_bt_activity_grading {
BT_OFF = 0, BT_OFF = 0,
BT_ON_NO_CONNECTION = 1, BT_ON_NO_CONNECTION = 1,
...@@ -233,6 +232,31 @@ enum iwl_bt_ci_compliance { ...@@ -233,6 +232,31 @@ enum iwl_bt_ci_compliance {
* @reserved: reserved * @reserved: reserved
*/ */
struct iwl_bt_coex_profile_notif { struct iwl_bt_coex_profile_notif {
__le32 mbox_msg[8];
__le32 msg_idx;
__le32 bt_ci_compliance;
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
u8 ttc_status;
u8 rrc_status;
__le16 reserved;
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_5 */
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
* @mbox_msg: message from BT to WiFi
* @msg_idx: the index of the message
* @bt_ci_compliance: enum %iwl_bt_ci_compliance
* @primary_ch_lut: LUT used for primary channel &enum iwl_bt_coex_lut_type
* @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type
* @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading
* @ttc_status: is TTC enabled - one bit per PHY
* @rrc_status: is RRC enabled - one bit per PHY
* @reserved: reserved
*/
struct iwl_bt_coex_profile_notif_v4 {
__le32 mbox_msg[4]; __le32 mbox_msg[4];
__le32 msg_idx; __le32 msg_idx;
__le32 bt_ci_compliance; __le32 bt_ci_compliance;
......
...@@ -135,12 +135,6 @@ enum iwl_legacy_cmds { ...@@ -135,12 +135,6 @@ enum iwl_legacy_cmds {
*/ */
DBG_CFG = 0x9, DBG_CFG = 0x9,
/**
* @ANTENNA_COUPLING_NOTIFICATION:
* Antenna coupling data, &struct iwl_mvm_antenna_coupling_notif
*/
ANTENNA_COUPLING_NOTIFICATION = 0xa,
/** /**
* @SCAN_ITERATION_COMPLETE_UMAC: * @SCAN_ITERATION_COMPLETE_UMAC:
* Firmware indicates a scan iteration completed, using * Firmware indicates a scan iteration completed, using
...@@ -523,12 +517,6 @@ enum iwl_legacy_cmds { ...@@ -523,12 +517,6 @@ enum iwl_legacy_cmds {
*/ */
BT_CONFIG = 0x9b, BT_CONFIG = 0x9b,
/**
* @BT_COEX_UPDATE_CORUN_LUT:
* &struct iwl_bt_coex_corun_lut_update_cmd
*/
BT_COEX_UPDATE_CORUN_LUT = 0x5b,
/** /**
* @BT_COEX_UPDATE_REDUCED_TXP: * @BT_COEX_UPDATE_REDUCED_TXP:
* &struct iwl_bt_coex_reduced_txp_update_cmd * &struct iwl_bt_coex_reduced_txp_update_cmd
......
...@@ -181,12 +181,4 @@ struct iwl_dc2dc_config_resp { ...@@ -181,12 +181,4 @@ struct iwl_dc2dc_config_resp {
__le32 dc2dc_freq_tune1; __le32 dc2dc_freq_tune1;
} __packed; /* DC2DC_CONFIG_RESP_API_S_VER_1 */ } __packed; /* DC2DC_CONFIG_RESP_API_S_VER_1 */
/**
* struct iwl_mvm_antenna_coupling_notif - antenna coupling notification
* @isolation: antenna isolation value
*/
struct iwl_mvm_antenna_coupling_notif {
__le32 isolation;
} __packed;
#endif /* __iwl_fw_api_config_h__ */ #endif /* __iwl_fw_api_config_h__ */
...@@ -409,7 +409,8 @@ enum iwl_tx_status { ...@@ -409,7 +409,8 @@ enum iwl_tx_status {
* @AGG_TX_STATE_BT_PRIO: * @AGG_TX_STATE_BT_PRIO:
* @AGG_TX_STATE_FEW_BYTES: * @AGG_TX_STATE_FEW_BYTES:
* @AGG_TX_STATE_ABORT: * @AGG_TX_STATE_ABORT:
* @AGG_TX_STATE_LAST_SENT_TTL: * @AGG_TX_STATE_TX_ON_AIR_DROP: TX_ON_AIR signal drop without underrun or
* BT detection
* @AGG_TX_STATE_LAST_SENT_TRY_CNT: * @AGG_TX_STATE_LAST_SENT_TRY_CNT:
* @AGG_TX_STATE_LAST_SENT_BT_KILL: * @AGG_TX_STATE_LAST_SENT_BT_KILL:
* @AGG_TX_STATE_SCD_QUERY: * @AGG_TX_STATE_SCD_QUERY:
...@@ -433,7 +434,7 @@ enum iwl_tx_agg_status { ...@@ -433,7 +434,7 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_BT_PRIO = 0x002, AGG_TX_STATE_BT_PRIO = 0x002,
AGG_TX_STATE_FEW_BYTES = 0x004, AGG_TX_STATE_FEW_BYTES = 0x004,
AGG_TX_STATE_ABORT = 0x008, AGG_TX_STATE_ABORT = 0x008,
AGG_TX_STATE_LAST_SENT_TTL = 0x010, AGG_TX_STATE_TX_ON_AIR_DROP = 0x010,
AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020, AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020,
AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040, AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040,
AGG_TX_STATE_SCD_QUERY = 0x080, AGG_TX_STATE_SCD_QUERY = 0x080,
...@@ -445,10 +446,6 @@ enum iwl_tx_agg_status { ...@@ -445,10 +446,6 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS, AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS,
}; };
#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL| \
AGG_TX_STATE_LAST_SENT_TRY_CNT| \
AGG_TX_STATE_LAST_SENT_BT_KILL)
/* /*
* The mask below describes a status where we are absolutely sure that the MPDU * The mask below describes a status where we are absolutely sure that the MPDU
* wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've * wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've
......
...@@ -246,6 +246,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; ...@@ -246,6 +246,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement. * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement.
* @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2 * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2
* @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_ATS_COEX_EXTERNAL: the coex notification is enlared to
* include information about ACL time sharing.
* *
* @NUM_IWL_UCODE_TLV_API: number of bits used * @NUM_IWL_UCODE_TLV_API: number of bits used
*/ */
...@@ -262,6 +264,7 @@ enum iwl_ucode_tlv_api { ...@@ -262,6 +264,7 @@ enum iwl_ucode_tlv_api {
/* API Set 1 */ /* API Set 1 */
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_COEX_ATS_EXTERNAL = (__force iwl_ucode_tlv_api_t)37,
NUM_IWL_UCODE_TLV_API NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__ #ifdef __CHECKER__
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH * Copyright(c) 2015 - 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
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 - 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
...@@ -161,6 +162,15 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, ...@@ -161,6 +162,15 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
} }
IWL_EXPORT_SYMBOL(iwl_init_notification_wait); IWL_EXPORT_SYMBOL(iwl_init_notification_wait);
void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry)
{
spin_lock_bh(&notif_wait->notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
}
IWL_EXPORT_SYMBOL(iwl_remove_notification);
int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry, struct iwl_notification_wait *wait_entry,
unsigned long timeout) unsigned long timeout)
...@@ -171,9 +181,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, ...@@ -171,9 +181,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
wait_entry->triggered || wait_entry->aborted, wait_entry->triggered || wait_entry->aborted,
timeout); timeout);
spin_lock_bh(&notif_wait->notif_wait_lock); iwl_remove_notification(notif_wait, wait_entry);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
if (wait_entry->aborted) if (wait_entry->aborted)
return -EIO; return -EIO;
...@@ -184,12 +192,3 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, ...@@ -184,12 +192,3 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
return 0; return 0;
} }
IWL_EXPORT_SYMBOL(iwl_wait_notification); IWL_EXPORT_SYMBOL(iwl_wait_notification);
void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry)
{
spin_lock_bh(&notif_wait->notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
}
IWL_EXPORT_SYMBOL(iwl_remove_notification);
...@@ -148,7 +148,7 @@ struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt) ...@@ -148,7 +148,7 @@ struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt)
rsp->regulatory.channel_profile, rsp->regulatory.channel_profile,
nvm->valid_tx_ant & fwrt->fw->valid_tx_ant, nvm->valid_tx_ant & fwrt->fw->valid_tx_ant,
nvm->valid_rx_ant & fwrt->fw->valid_rx_ant, nvm->valid_rx_ant & fwrt->fw->valid_rx_ant,
rsp->regulatory.lar_enabled && lar_fw_supported); nvm->lar_enabled, false);
iwl_free_resp(&hcmd); iwl_free_resp(&hcmd);
return nvm; return nvm;
......
...@@ -463,7 +463,9 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr; ...@@ -463,7 +463,9 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr;
extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb; extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb;
extern const struct iwl_cfg iwla000_2ac_cfg_jf; extern const struct iwl_cfg iwla000_2ac_cfg_jf;
extern const struct iwl_cfg iwla000_2ax_cfg_hr; extern const struct iwl_cfg iwla000_2ax_cfg_hr;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr; extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0;
#endif /* CONFIG_IWLMVM */ #endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */ #endif /* __IWL_CONFIG_H__ */
...@@ -354,11 +354,16 @@ enum { ...@@ -354,11 +354,16 @@ enum {
#define CSR_HW_REV_TYPE_135 (0x0000120) #define CSR_HW_REV_TYPE_135 (0x0000120)
#define CSR_HW_REV_TYPE_7265D (0x0000210) #define CSR_HW_REV_TYPE_7265D (0x0000210)
#define CSR_HW_REV_TYPE_NONE (0x00001F0) #define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
/* RF_ID value */ /* RF_ID value */
#define CSR_HW_RF_ID_TYPE_JF (0x00105100) #define CSR_HW_RF_ID_TYPE_JF (0x00105100)
#define CSR_HW_RF_ID_TYPE_HR (0x0010A000) #define CSR_HW_RF_ID_TYPE_HR (0x0010A000)
#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109000) #define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00)
/* HW_RF CHIP ID */
#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF)
/* EEPROM REG */ /* EEPROM REG */
#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) #define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
......
...@@ -487,9 +487,9 @@ static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data, ...@@ -487,9 +487,9 @@ static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
int i; int i;
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) { if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
IWL_ERR(drv, IWL_WARN(drv,
"api flags index %d larger than supported by driver\n", "api flags index %d larger than supported by driver\n",
api_index); api_index);
return; return;
} }
...@@ -508,9 +508,9 @@ static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data, ...@@ -508,9 +508,9 @@ static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
int i; int i;
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) { if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
IWL_ERR(drv, IWL_WARN(drv,
"capa flags index %d larger than supported by driver\n", "capa flags index %d larger than supported by driver\n",
api_index); api_index);
return; return;
} }
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
/* NVM offsets (in words) definitions */ /* NVM offsets (in words) definitions */
enum wkp_nvm_offsets { enum wkp_nvm_offsets {
/* NVM HW-Section offset (in words) definitions */ /* NVM HW-Section offset (in words) definitions */
SUBSYSTEM_ID = 0x0A,
HW_ADDR = 0x15, HW_ADDR = 0x15,
/* NVM SW-Section offset (in words) definitions */ /* NVM SW-Section offset (in words) definitions */
...@@ -183,22 +184,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { ...@@ -183,22 +184,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
* @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
* on same channel on 2.4 or same UNII band on 5.2 * on same channel on 2.4 or same UNII band on 5.2
* @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) * @NVM_CHANNEL_UNIFORM: uniform spreading required
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) * @NVM_CHANNEL_20MHZ: 20 MHz channel okay
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) * @NVM_CHANNEL_40MHZ: 40 MHz channel okay
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) * @NVM_CHANNEL_80MHZ: 80 MHz channel okay
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay
* @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
*/ */
enum iwl_nvm_channel_flags { enum iwl_nvm_channel_flags {
NVM_CHANNEL_VALID = BIT(0), NVM_CHANNEL_VALID = BIT(0),
NVM_CHANNEL_IBSS = BIT(1), NVM_CHANNEL_IBSS = BIT(1),
NVM_CHANNEL_ACTIVE = BIT(3), NVM_CHANNEL_ACTIVE = BIT(3),
NVM_CHANNEL_RADAR = BIT(4), NVM_CHANNEL_RADAR = BIT(4),
NVM_CHANNEL_INDOOR_ONLY = BIT(5), NVM_CHANNEL_INDOOR_ONLY = BIT(5),
NVM_CHANNEL_GO_CONCURRENT = BIT(6), NVM_CHANNEL_GO_CONCURRENT = BIT(6),
NVM_CHANNEL_WIDE = BIT(8), NVM_CHANNEL_UNIFORM = BIT(7),
NVM_CHANNEL_40MHZ = BIT(9), NVM_CHANNEL_20MHZ = BIT(8),
NVM_CHANNEL_80MHZ = BIT(10), NVM_CHANNEL_40MHZ = BIT(9),
NVM_CHANNEL_160MHZ = BIT(11), NVM_CHANNEL_80MHZ = BIT(10),
NVM_CHANNEL_160MHZ = BIT(11),
NVM_CHANNEL_DC_HIGH = BIT(12),
}; };
#define CHECK_AND_PRINT_I(x) \ #define CHECK_AND_PRINT_I(x) \
...@@ -254,13 +259,12 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, ...@@ -254,13 +259,12 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, struct iwl_nvm_data *data,
const __le16 * const nvm_ch_flags, const __le16 * const nvm_ch_flags,
bool lar_supported) bool lar_supported, bool no_wide_in_5ghz)
{ {
int ch_idx; int ch_idx;
int n_channels = 0; int n_channels = 0;
struct ieee80211_channel *channel; struct ieee80211_channel *channel;
u16 ch_flags; u16 ch_flags;
bool is_5ghz;
int num_of_ch, num_2ghz_channels; int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan; const u8 *nvm_chan;
...@@ -275,12 +279,20 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -275,12 +279,20 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
} }
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
bool is_5ghz = (ch_idx >= num_2ghz_channels);
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
if (ch_idx >= num_2ghz_channels && if (is_5ghz && !data->sku_cap_band_52GHz_enable)
!data->sku_cap_band_52GHz_enable)
continue; continue;
/* workaround to disable wide channels in 5GHz */
if (no_wide_in_5ghz && is_5ghz) {
ch_flags &= ~(NVM_CHANNEL_40MHZ |
NVM_CHANNEL_80MHZ |
NVM_CHANNEL_160MHZ);
}
if (ch_flags & NVM_CHANNEL_160MHZ) if (ch_flags & NVM_CHANNEL_160MHZ)
data->vht160_supported = true; data->vht160_supported = true;
...@@ -303,8 +315,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -303,8 +315,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
n_channels++; n_channels++;
channel->hw_value = nvm_chan[ch_idx]; channel->hw_value = nvm_chan[ch_idx];
channel->band = (ch_idx < num_2ghz_channels) ? channel->band = is_5ghz ?
NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
channel->center_freq = channel->center_freq =
ieee80211_channel_to_frequency( ieee80211_channel_to_frequency(
channel->hw_value, channel->band); channel->hw_value, channel->band);
...@@ -316,7 +328,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -316,7 +328,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
* is not used in mvm, and is used for backwards compatibility * is not used in mvm, and is used for backwards compatibility
*/ */
channel->max_power = IWL_DEFAULT_MAX_TX_POWER; channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
is_5ghz = channel->band == NL80211_BAND_5GHZ;
/* don't put limitations in case we're using LAR */ /* don't put limitations in case we're using LAR */
if (!lar_supported) if (!lar_supported)
...@@ -327,7 +338,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -327,7 +338,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
channel->flags = 0; channel->flags = 0;
IWL_DEBUG_EEPROM(dev, IWL_DEBUG_EEPROM(dev,
"Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
channel->hw_value, channel->hw_value,
is_5ghz ? "5.2" : "2.4", is_5ghz ? "5.2" : "2.4",
ch_flags, ch_flags,
...@@ -337,10 +348,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -337,10 +348,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
CHECK_AND_PRINT_I(RADAR), CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(INDOOR_ONLY), CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT), CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(WIDE), CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ), CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ), CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ), CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(DC_HIGH),
channel->max_power, channel->max_power,
((ch_flags & NVM_CHANNEL_IBSS) && ((ch_flags & NVM_CHANNEL_IBSS) &&
!(ch_flags & NVM_CHANNEL_RADAR)) !(ch_flags & NVM_CHANNEL_RADAR))
...@@ -432,14 +445,15 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, ...@@ -432,14 +445,15 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags, struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
u8 tx_chains, u8 rx_chains, bool lar_supported) u8 tx_chains, u8 rx_chains, bool lar_supported,
bool no_wide_in_5ghz)
{ {
int n_channels; int n_channels;
int n_used = 0; int n_used = 0;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags, n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
lar_supported); lar_supported, no_wide_in_5ghz);
sband = &data->bands[NL80211_BAND_2GHZ]; sband = &data->bands[NL80211_BAND_2GHZ];
sband->band = NL80211_BAND_2GHZ; sband->band = NL80211_BAND_2GHZ;
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
...@@ -568,7 +582,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans, ...@@ -568,7 +582,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
const struct iwl_cfg *cfg, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, struct iwl_nvm_data *data,
const __le16 *mac_override, const __le16 *mac_override,
const __le16 *nvm_hw) const __be16 *nvm_hw)
{ {
const u8 *hw_addr; const u8 *hw_addr;
...@@ -615,7 +629,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans, ...@@ -615,7 +629,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
static int iwl_set_hw_address(struct iwl_trans *trans, static int iwl_set_hw_address(struct iwl_trans *trans,
const struct iwl_cfg *cfg, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_hw, struct iwl_nvm_data *data, const __be16 *nvm_hw,
const __le16 *mac_override) const __le16 *mac_override)
{ {
if (cfg->mac_addr_from_csr) { if (cfg->mac_addr_from_csr) {
...@@ -645,9 +659,41 @@ static int iwl_set_hw_address(struct iwl_trans *trans, ...@@ -645,9 +659,41 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
return 0; return 0;
} }
static bool
iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
const __be16 *nvm_hw)
{
/*
* Workaround a bug in Indonesia SKUs where the regulatory in
* some 7000-family OTPs erroneously allow wide channels in
* 5GHz. To check for Indonesia, we take the SKU value from
* bits 1-4 in the subsystem ID and check if it is either 5 or
* 9. In those cases, we need to force-disable wide channels
* in 5GHz otherwise the FW will throw a sysassert when we try
* to use them.
*/
if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/*
* Unlike the other sections in the NVM, the hw
* section uses big-endian.
*/
u16 subsystem_id = be16_to_cpup(nvm_hw + SUBSYSTEM_ID);
u8 sku = (subsystem_id & 0x1e) >> 1;
if (sku == 5 || sku == 9) {
IWL_DEBUG_EEPROM(dev,
"disabling wide channels in 5GHz (0x%0x %d)\n",
subsystem_id, sku);
return true;
}
}
return false;
}
struct iwl_nvm_data * struct iwl_nvm_data *
iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw, const __be16 *nvm_hw, const __le16 *nvm_sw,
const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku, const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported) u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
...@@ -655,6 +701,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -655,6 +701,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
struct device *dev = trans->dev; struct device *dev = trans->dev;
struct iwl_nvm_data *data; struct iwl_nvm_data *data;
bool lar_enabled; bool lar_enabled;
bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
u32 sku, radio_cfg; u32 sku, radio_cfg;
u16 lar_config; u16 lar_config;
const __le16 *ch_section; const __le16 *ch_section;
...@@ -725,7 +772,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -725,7 +772,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
} }
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains, iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
lar_fw_supported && lar_enabled); lar_fw_supported && lar_enabled, no_wide_in_5ghz);
data->calib_version = 255; data->calib_version = 255;
return data; return data;
...@@ -865,22 +912,25 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, ...@@ -865,22 +912,25 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
prev_center_freq = center_freq; prev_center_freq = center_freq;
IWL_DEBUG_DEV(dev, IWL_DL_LAR, IWL_DEBUG_DEV(dev, IWL_DL_LAR,
"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): Ad-Hoc %ssupported\n", "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x): %s\n",
center_freq, center_freq,
band == NL80211_BAND_5GHZ ? "5.2" : "2.4", band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
CHECK_AND_PRINT_I(VALID), CHECK_AND_PRINT_I(VALID),
CHECK_AND_PRINT_I(IBSS),
CHECK_AND_PRINT_I(ACTIVE), CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR), CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(WIDE), CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ), CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ), CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ), CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(INDOOR_ONLY), CHECK_AND_PRINT_I(DC_HIGH),
CHECK_AND_PRINT_I(GO_CONCURRENT),
ch_flags, ch_flags,
((ch_flags & NVM_CHANNEL_ACTIVE) && ((ch_flags & NVM_CHANNEL_ACTIVE) &&
!(ch_flags & NVM_CHANNEL_RADAR)) !(ch_flags & NVM_CHANNEL_RADAR))
? "" : "not "); ? "Ad-Hoc" : "");
} }
regd->n_reg_rules = valid_rules; regd->n_reg_rules = valid_rules;
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
*/ */
struct iwl_nvm_data * struct iwl_nvm_data *
iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw, const __be16 *nvm_hw, const __le16 *nvm_sw,
const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku, const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported); u8 tx_chains, u8 rx_chains, bool lar_fw_supported);
...@@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct iwl_trans *trans, ...@@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
*/ */
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags, struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
u8 tx_chains, u8 rx_chains, bool lar_supported); u8 tx_chains, u8 rx_chains, bool lar_supported,
bool no_wide_in_5ghz);
/** /**
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
......
...@@ -95,7 +95,6 @@ ...@@ -95,7 +95,6 @@
#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62 #define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65 #define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1 #define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 0
#define IWL_MVM_BT_COEX_MPLUT 1 #define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_BT_COEX_RRC 1 #define IWL_MVM_BT_COEX_RRC 1
#define IWL_MVM_BT_COEX_TTC 1 #define IWL_MVM_BT_COEX_TTC 1
...@@ -137,6 +136,7 @@ ...@@ -137,6 +136,7 @@
#define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */ #define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */
#define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */ #define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */
#define IWL_MVM_RS_AGG_DISABLE_START 3 #define IWL_MVM_RS_AGG_DISABLE_START 3
#define IWL_MVM_RS_AGG_START_THRESHOLD 10 /* num frames per second */
#define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */ #define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */
#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ #define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */
#define IWL_MVM_RS_TPC_TX_POWER_STEP 3 #define IWL_MVM_RS_TPC_TX_POWER_STEP 3
......
...@@ -469,20 +469,9 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf, ...@@ -469,20 +469,9 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
return ret ?: count; return ret ?: count;
} }
#define BT_MBOX_MSG(_notif, _num, _field) \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
#define BT_MBOX_PRINT(_num, _field, _end) \
pos += scnprintf(buf + pos, bufsz - pos, \
"\t%s: %d%s", \
#_field, \
BT_MBOX_MSG(notif, _num, _field), \
true ? "\n" : ", ");
static static
int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf, int iwl_mvm_coex_dump_mbox(struct iwl_mvm *mvm,
struct iwl_bt_coex_profile_notif *notif, char *buf,
int pos, int bufsz) int pos, int bufsz)
{ {
pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
...@@ -526,6 +515,7 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf, ...@@ -526,6 +515,7 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
BT_MBOX_PRINT(3, SCO_STATE, false); BT_MBOX_PRINT(3, SCO_STATE, false);
BT_MBOX_PRINT(3, SNIFF_STATE, false); BT_MBOX_PRINT(3, SNIFF_STATE, false);
BT_MBOX_PRINT(3, A2DP_STATE, false); BT_MBOX_PRINT(3, A2DP_STATE, false);
BT_MBOX_PRINT(3, A2DP_SRC, false);
BT_MBOX_PRINT(3, ACL_STATE, false); BT_MBOX_PRINT(3, ACL_STATE, false);
BT_MBOX_PRINT(3, MSTR_STATE, false); BT_MBOX_PRINT(3, MSTR_STATE, false);
BT_MBOX_PRINT(3, OBX_STATE, false); BT_MBOX_PRINT(3, OBX_STATE, false);
...@@ -535,7 +525,12 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf, ...@@ -535,7 +525,12 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
BT_MBOX_PRINT(3, INBAND_P, false); BT_MBOX_PRINT(3, INBAND_P, false);
BT_MBOX_PRINT(3, MSG_TYPE_2, false); BT_MBOX_PRINT(3, MSG_TYPE_2, false);
BT_MBOX_PRINT(3, SSN_2, false); BT_MBOX_PRINT(3, SSN_2, false);
BT_MBOX_PRINT(3, UPDATE_REQUEST, true); BT_MBOX_PRINT(3, UPDATE_REQUEST, !iwl_mvm_has_new_ats_coex_api(mvm));
if (iwl_mvm_has_new_ats_coex_api(mvm)) {
BT_MBOX_PRINT(4, ATS_BT_INTERVAL, false);
BT_MBOX_PRINT(4, ATS_BT_ACTIVE_MAX_TH, true);
}
return pos; return pos;
} }
...@@ -554,7 +549,7 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, ...@@ -554,7 +549,7 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz); pos += iwl_mvm_coex_dump_mbox(mvm, notif, buf, pos, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n", pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n",
notif->bt_ci_compliance); notif->bt_ci_compliance);
...@@ -565,9 +560,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, ...@@ -565,9 +560,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
pos += scnprintf(buf + pos, pos += scnprintf(buf + pos,
bufsz - pos, "bt_activity_grading = %d\n", bufsz - pos, "bt_activity_grading = %d\n",
le32_to_cpu(notif->bt_activity_grading)); le32_to_cpu(notif->bt_activity_grading));
pos += scnprintf(buf + pos, bufsz - pos,
"antenna isolation = %d CORUN LUT index = %d\n",
mvm->last_ant_isol, mvm->last_corun_lut);
pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n", pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n",
notif->rrc_status & 0xF); notif->rrc_status & 0xF);
pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n", pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n",
...@@ -577,8 +569,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, ...@@ -577,8 +569,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
IWL_MVM_BT_COEX_SYNC2SCO); IWL_MVM_BT_COEX_SYNC2SCO);
pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n", pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n",
IWL_MVM_BT_COEX_MPLUT); IWL_MVM_BT_COEX_MPLUT);
pos += scnprintf(buf + pos, bufsz - pos, "corunning = %d\n",
IWL_MVM_BT_COEX_CORUNNING);
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
......
...@@ -388,7 +388,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -388,7 +388,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
} }
if (IWL_MVM_PARSE_NVM && read_nvm) { if (IWL_MVM_PARSE_NVM && read_nvm) {
ret = iwl_nvm_init(mvm, true); ret = iwl_nvm_init(mvm);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret); IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto error; goto error;
...@@ -475,22 +475,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -475,22 +475,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT); ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret); IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret);
goto error; goto remove_notif;
} }
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) { if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
ret = iwl_mvm_send_bt_init_conf(mvm); ret = iwl_mvm_send_bt_init_conf(mvm);
if (ret) if (ret)
goto error; goto remove_notif;
} }
/* Read the NVM only at driver load time, no need to do this twice */ /* Read the NVM only at driver load time, no need to do this twice */
if (read_nvm) { if (read_nvm) {
/* Read nvm */ ret = iwl_nvm_init(mvm);
ret = iwl_nvm_init(mvm, true);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret); IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto error; goto remove_notif;
} }
} }
...@@ -498,8 +497,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -498,8 +497,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if (mvm->nvm_file_name) if (mvm->nvm_file_name)
iwl_mvm_load_nvm_to_nic(mvm); iwl_mvm_load_nvm_to_nic(mvm);
ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
WARN_ON(ret);
/* /*
* abort after reading the nvm in case RF Kill is on, we will complete * abort after reading the nvm in case RF Kill is on, we will complete
...@@ -508,9 +506,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -508,9 +506,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if (iwl_mvm_is_radio_hw_killed(mvm)) { if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, IWL_DEBUG_RF_KILL(mvm,
"jump over all phy activities due to RF kill\n"); "jump over all phy activities due to RF kill\n");
iwl_remove_notification(&mvm->notif_wait, &calib_wait); goto remove_notif;
ret = 1;
goto out;
} }
mvm->calibrating = true; mvm->calibrating = true;
...@@ -518,17 +514,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -518,17 +514,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
/* Send TX valid antennas before triggering calibrations */ /* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
if (ret) if (ret)
goto error; goto remove_notif;
/*
* Send phy configurations command to init uCode
* to start the 16.0 uCode init image internal calibrations.
*/
ret = iwl_send_phy_cfg_cmd(mvm); ret = iwl_send_phy_cfg_cmd(mvm);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n", IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret); ret);
goto error; goto remove_notif;
} }
/* /*
...@@ -536,15 +528,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -536,15 +528,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
* just wait for the calibration complete notification. * just wait for the calibration complete notification.
*/ */
ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
MVM_UCODE_CALIB_TIMEOUT); MVM_UCODE_CALIB_TIMEOUT);
if (!ret)
goto out;
if (ret && iwl_mvm_is_radio_hw_killed(mvm)) { if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n"); IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
ret = 1; ret = 0;
} else {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret);
} }
goto out; goto out;
error: remove_notif:
iwl_remove_notification(&mvm->notif_wait, &calib_wait); iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out: out:
mvm->calibrating = false; mvm->calibrating = false;
...@@ -997,6 +995,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) ...@@ -997,6 +995,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
{ {
return 0; return 0;
} }
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a,
int prof_b)
{
return -ENOENT;
}
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
return -ENOENT;
}
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
static int iwl_mvm_sar_init(struct iwl_mvm *mvm) static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
...@@ -1043,9 +1052,6 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) ...@@ -1043,9 +1052,6 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
/* this can't happen */
if (WARN_ON(ret > 0))
ret = -ERFKILL;
return ret; return ret;
} }
......
...@@ -2023,8 +2023,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, ...@@ -2023,8 +2023,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
* We received a beacon from the associated AP so * We received a beacon from the associated AP so
* remove the session protection. * remove the session protection.
*/ */
iwl_mvm_remove_time_event(mvm, mvmvif, iwl_mvm_stop_session_protection(mvm, vif);
&mvmvif->time_event_data);
iwl_mvm_sf_update(mvm, vif, false); iwl_mvm_sf_update(mvm, vif, false);
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
...@@ -3876,11 +3875,16 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, ...@@ -3876,11 +3875,16 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
/* Schedule the time event to a bit before beacon 1, /* Schedule the time event to a bit before beacon 1,
* to make sure we're in the new channel when the * to make sure we're in the new channel when the
* GO/AP arrives. * GO/AP arrives. In case count <= 1 immediately schedule the
* TE (this might result with some packet loss or connection
* loss).
*/ */
apply_time = chsw->device_timestamp + if (chsw->count <= 1)
((vif->bss_conf.beacon_int * (chsw->count - 1) - apply_time = 0;
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024); else
apply_time = chsw->device_timestamp +
((vif->bss_conf.beacon_int * (chsw->count - 1) -
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
if (chsw->block_tx) if (chsw->block_tx)
iwl_mvm_csa_client_absent(mvm, vif); iwl_mvm_csa_client_absent(mvm, vif);
......
...@@ -924,8 +924,6 @@ struct iwl_mvm { ...@@ -924,8 +924,6 @@ struct iwl_mvm {
struct iwl_bt_coex_profile_notif last_bt_notif; struct iwl_bt_coex_profile_notif last_bt_notif;
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd; struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
u32 last_ant_isol;
u8 last_corun_lut;
u8 bt_tx_prio; u8 bt_tx_prio;
enum iwl_bt_force_ant_mode bt_force_ant_mode; enum iwl_bt_force_ant_mode bt_force_ant_mode;
...@@ -1175,13 +1173,6 @@ static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm) ...@@ -1175,13 +1173,6 @@ static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC); IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC);
} }
static inline bool iwl_mvm_bt_is_plcr_supported(struct iwl_mvm *mvm)
{
return fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BT_COEX_PLCR) &&
IWL_MVM_BT_COEX_CORUNNING;
}
static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm) static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm)
{ {
return fw_has_capa(&mvm->fw->ucode_capa, return fw_has_capa(&mvm->fw->ucode_capa,
...@@ -1251,6 +1242,12 @@ static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) ...@@ -1251,6 +1242,12 @@ static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
IWL_UCODE_TLV_API_NEW_RX_STATS); IWL_UCODE_TLV_API_NEW_RX_STATS);
} }
static inline bool iwl_mvm_has_new_ats_coex_api(struct iwl_mvm *mvm)
{
return fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL);
}
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)
{ {
...@@ -1376,7 +1373,7 @@ int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear); ...@@ -1376,7 +1373,7 @@ int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear);
void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm); void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
/* NVM */ /* NVM */
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); int iwl_nvm_init(struct iwl_mvm *mvm);
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm); int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm); int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm);
...@@ -1828,21 +1825,7 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif, ...@@ -1828,21 +1825,7 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
u32 duration, u32 timeout); u32 duration, u32 timeout);
bool iwl_mvm_lqm_active(struct iwl_mvm *mvm); bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
#ifdef CONFIG_ACPI
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b); int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm); int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
#else
static inline
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
{
return -ENOENT;
}
static inline
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
return -ENOENT;
}
#endif /* CONFIG_ACPI */
#endif /* __IWL_MVM_H__ */ #endif /* __IWL_MVM_H__ */
...@@ -292,7 +292,8 @@ static struct iwl_nvm_data * ...@@ -292,7 +292,8 @@ static struct iwl_nvm_data *
iwl_parse_nvm_sections(struct iwl_mvm *mvm) iwl_parse_nvm_sections(struct iwl_mvm *mvm)
{ {
struct iwl_nvm_section *sections = mvm->nvm_sections; struct iwl_nvm_section *sections = mvm->nvm_sections;
const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku; const __be16 *hw;
const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
bool lar_enabled; bool lar_enabled;
/* Checking for required sections */ /* Checking for required sections */
...@@ -326,10 +327,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) ...@@ -326,10 +327,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
} }
} }
if (WARN_ON(!mvm->cfg)) hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
return NULL;
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
...@@ -546,7 +544,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm) ...@@ -546,7 +544,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
return ret; return ret;
} }
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) int iwl_nvm_init(struct iwl_mvm *mvm)
{ {
int ret, section; int ret, section;
u32 size_read = 0; u32 size_read = 0;
...@@ -557,63 +555,61 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) ...@@ -557,63 +555,61 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
return -EINVAL; return -EINVAL;
/* load NVM values from nic */ /* load NVM values from nic */
if (read_nvm_from_nic) { /* Read From FW NVM */
/* Read From FW NVM */ IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, GFP_KERNEL);
GFP_KERNEL); if (!nvm_buffer)
if (!nvm_buffer) return -ENOMEM;
return -ENOMEM; for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) { /* we override the constness for initial read */
/* we override the constness for initial read */ ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
ret = iwl_nvm_read_section(mvm, section, nvm_buffer, size_read);
size_read); if (ret < 0)
if (ret < 0) continue;
continue; size_read += ret;
size_read += ret; temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); if (!temp) {
if (!temp) { ret = -ENOMEM;
ret = -ENOMEM; break;
break; }
}
iwl_mvm_nvm_fixups(mvm, section, temp, ret); iwl_mvm_nvm_fixups(mvm, section, temp, ret);
mvm->nvm_sections[section].data = temp; mvm->nvm_sections[section].data = temp;
mvm->nvm_sections[section].length = ret; mvm->nvm_sections[section].length = ret;
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
switch (section) { switch (section) {
case NVM_SECTION_TYPE_SW: case NVM_SECTION_TYPE_SW:
mvm->nvm_sw_blob.data = temp; mvm->nvm_sw_blob.data = temp;
mvm->nvm_sw_blob.size = ret; mvm->nvm_sw_blob.size = ret;
break; break;
case NVM_SECTION_TYPE_CALIBRATION: case NVM_SECTION_TYPE_CALIBRATION:
mvm->nvm_calib_blob.data = temp; mvm->nvm_calib_blob.data = temp;
mvm->nvm_calib_blob.size = ret; mvm->nvm_calib_blob.size = ret;
break; break;
case NVM_SECTION_TYPE_PRODUCTION: case NVM_SECTION_TYPE_PRODUCTION:
mvm->nvm_prod_blob.data = temp; mvm->nvm_prod_blob.data = temp;
mvm->nvm_prod_blob.size = ret; mvm->nvm_prod_blob.size = ret;
break; break;
case NVM_SECTION_TYPE_PHY_SKU: case NVM_SECTION_TYPE_PHY_SKU:
mvm->nvm_phy_sku_blob.data = temp; mvm->nvm_phy_sku_blob.data = temp;
mvm->nvm_phy_sku_blob.size = ret; mvm->nvm_phy_sku_blob.size = ret;
break;
default:
if (section == mvm->cfg->nvm_hw_section_num) {
mvm->nvm_hw_blob.data = temp;
mvm->nvm_hw_blob.size = ret;
break; break;
default:
if (section == mvm->cfg->nvm_hw_section_num) {
mvm->nvm_hw_blob.data = temp;
mvm->nvm_hw_blob.size = ret;
break;
}
} }
#endif
} }
if (!size_read) #endif
IWL_ERR(mvm, "OTP is blank\n");
kfree(nvm_buffer);
} }
if (!size_read)
IWL_ERR(mvm, "OTP is blank\n");
kfree(nvm_buffer);
/* Only if PNVM selected in the mod param - load external NVM */ /* Only if PNVM selected in the mod param - load external NVM */
if (mvm->nvm_file_name) { if (mvm->nvm_file_name) {
......
...@@ -256,8 +256,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { ...@@ -256,8 +256,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER_ASYNC_LOCKED), RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
RX_HANDLER_ASYNC_LOCKED), RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
iwl_mvm_rx_ant_coupling_notif, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID, RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
iwl_mvm_window_status_notif, RX_HANDLER_SYNC), iwl_mvm_window_status_notif, RX_HANDLER_SYNC),
...@@ -325,7 +323,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { ...@@ -325,7 +323,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(INIT_COMPLETE_NOTIF), HCMD_NAME(INIT_COMPLETE_NOTIF),
HCMD_NAME(PHY_CONTEXT_CMD), HCMD_NAME(PHY_CONTEXT_CMD),
HCMD_NAME(DBG_CFG), HCMD_NAME(DBG_CFG),
HCMD_NAME(ANTENNA_COUPLING_NOTIFICATION),
HCMD_NAME(SCAN_CFG_CMD), HCMD_NAME(SCAN_CFG_CMD),
HCMD_NAME(SCAN_REQ_UMAC), HCMD_NAME(SCAN_REQ_UMAC),
HCMD_NAME(SCAN_ABORT_UMAC), HCMD_NAME(SCAN_ABORT_UMAC),
...@@ -357,7 +354,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { ...@@ -357,7 +354,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(SCAN_OFFLOAD_ABORT_CMD), HCMD_NAME(SCAN_OFFLOAD_ABORT_CMD),
HCMD_NAME(HOT_SPOT_CMD), HCMD_NAME(HOT_SPOT_CMD),
HCMD_NAME(SCAN_OFFLOAD_PROFILES_QUERY_CMD), HCMD_NAME(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
HCMD_NAME(BT_COEX_UPDATE_CORUN_LUT),
HCMD_NAME(BT_COEX_UPDATE_REDUCED_TXP), HCMD_NAME(BT_COEX_UPDATE_REDUCED_TXP),
HCMD_NAME(BT_COEX_CI), HCMD_NAME(BT_COEX_CI),
HCMD_NAME(PHY_CONFIGURATION_CMD), HCMD_NAME(PHY_CONFIGURATION_CMD),
...@@ -388,6 +384,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { ...@@ -388,6 +384,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC), HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
HCMD_NAME(REPLY_RX_PHY_CMD), HCMD_NAME(REPLY_RX_PHY_CMD),
HCMD_NAME(REPLY_RX_MPDU_CMD), HCMD_NAME(REPLY_RX_MPDU_CMD),
HCMD_NAME(FRAME_RELEASE),
HCMD_NAME(BA_NOTIF), HCMD_NAME(BA_NOTIF),
HCMD_NAME(MCC_UPDATE_CMD), HCMD_NAME(MCC_UPDATE_CMD),
HCMD_NAME(MCC_CHUB_UPDATE_CMD), HCMD_NAME(MCC_CHUB_UPDATE_CMD),
...@@ -755,7 +752,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -755,7 +752,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
iwl_mvm_stop_device(mvm); iwl_mvm_stop_device(mvm);
iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
/* returns 0 if successful, 1 if success but in rfkill */
if (err < 0) { if (err < 0) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
goto out_free; goto out_free;
......
...@@ -622,7 +622,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, ...@@ -622,7 +622,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid); sta->addr, tid);
ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
/* start BA session until the peer sends del BA */
ret = ieee80211_start_tx_ba_session(sta, tid, 0);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
/* /*
* driver and mac80211 is out of sync * driver and mac80211 is out of sync
...@@ -636,15 +638,31 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, ...@@ -636,15 +638,31 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
return ret; return ret;
} }
static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid, static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
struct iwl_lq_sta *lq_data, u8 tid, struct iwl_lq_sta *lq_sta,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
if (tid < IWL_MAX_TID_COUNT) struct iwl_mvm_tid_data *tid_data;
rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
else /*
* In AP mode, tid can be equal to IWL_MAX_TID_COUNT
* when the frame is not QoS
*/
if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) {
IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n", IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",
tid, IWL_MAX_TID_COUNT); tid, IWL_MAX_TID_COUNT);
return;
} else if (tid == IWL_MAX_TID_COUNT) {
return;
}
tid_data = &mvmsta->tid_data[tid];
if ((tid_data->state == IWL_AGG_OFF) &&
(lq_sta->tx_agg_tid_en & BIT(tid)) &&
(tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta);
}
} }
static inline int get_num_of_ant_from_rate(u32 rate_n_flags) static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
...@@ -753,8 +771,38 @@ static int rs_collect_tpc_data(struct iwl_mvm *mvm, ...@@ -753,8 +771,38 @@ static int rs_collect_tpc_data(struct iwl_mvm *mvm,
window); window);
} }
static void rs_update_tid_tpt_stats(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvmsta,
u8 tid, int successes)
{
struct iwl_mvm_tid_data *tid_data;
if (tid >= IWL_MAX_TID_COUNT)
return;
tid_data = &mvmsta->tid_data[tid];
/*
* Measure if there're enough successful transmits per second.
* These statistics are used only to decide if we can start a
* BA session, so it should be updated only when A-MPDU is
* off.
*/
if (tid_data->state != IWL_AGG_OFF)
return;
if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) ||
(tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
tid_data->tx_count_last = tid_data->tx_count;
tid_data->tx_count = 0;
tid_data->tpt_meas_start = jiffies;
} else {
tid_data->tx_count += successes;
}
}
static int rs_collect_tlc_data(struct iwl_mvm *mvm, static int rs_collect_tlc_data(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_sta, struct iwl_mvm_sta *mvmsta, u8 tid,
struct iwl_scale_tbl_info *tbl, struct iwl_scale_tbl_info *tbl,
int scale_index, int attempts, int successes) int scale_index, int attempts, int successes)
{ {
...@@ -764,12 +812,14 @@ static int rs_collect_tlc_data(struct iwl_mvm *mvm, ...@@ -764,12 +812,14 @@ static int rs_collect_tlc_data(struct iwl_mvm *mvm,
return -EINVAL; return -EINVAL;
if (tbl->column != RS_COLUMN_INVALID) { if (tbl->column != RS_COLUMN_INVALID) {
struct lq_sta_pers *pers = &lq_sta->pers; struct lq_sta_pers *pers = &mvmsta->lq_sta.pers;
pers->tx_stats[tbl->column][scale_index].total += attempts; pers->tx_stats[tbl->column][scale_index].total += attempts;
pers->tx_stats[tbl->column][scale_index].success += successes; pers->tx_stats[tbl->column][scale_index].success += successes;
} }
rs_update_tid_tpt_stats(mvm, mvmsta, tid, successes);
/* Select window for current tx bit rate */ /* Select window for current tx bit rate */
window = &(tbl->win[scale_index]); window = &(tbl->win[scale_index]);
return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes, return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
...@@ -1211,12 +1261,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1211,12 +1261,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (time_after(jiffies, if (time_after(jiffies,
(unsigned long)(lq_sta->last_tx + (unsigned long)(lq_sta->last_tx +
(IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) { (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
int t;
IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
for (t = 0; t < IWL_MAX_TID_COUNT; t++)
ieee80211_stop_tx_ba_session(sta, t);
iwl_mvm_rs_rate_init(mvm, sta, info->band, false); iwl_mvm_rs_rate_init(mvm, sta, info->band, false);
return; return;
} }
...@@ -1312,7 +1357,8 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1312,7 +1357,8 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (info->status.ampdu_ack_len == 0) if (info->status.ampdu_ack_len == 0)
info->status.ampdu_len = 1; info->status.ampdu_len = 1;
rs_collect_tlc_data(mvm, lq_sta, curr_tbl, lq_rate.index, rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl,
lq_rate.index,
info->status.ampdu_len, info->status.ampdu_len,
info->status.ampdu_ack_len); info->status.ampdu_ack_len);
...@@ -1351,7 +1397,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1351,7 +1397,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
lq_rate.index, 1, lq_rate.index, 1,
i < retries ? 0 : legacy_success, i < retries ? 0 : legacy_success,
reduced_txp); reduced_txp);
rs_collect_tlc_data(mvm, lq_sta, tmp_tbl, rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
lq_rate.index, 1, lq_rate.index, 1,
i < retries ? 0 : legacy_success); i < retries ? 0 : legacy_success);
} }
...@@ -1673,14 +1719,14 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1673,14 +1719,14 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct iwl_scale_tbl_info *tbl, struct iwl_scale_tbl_info *tbl,
enum rs_action scale_action) enum rs_action scale_action)
{ {
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
tbl->rate.index < IWL_RATE_MCS_5_INDEX || tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
scale_action == RS_ACTION_DOWNSCALE) scale_action == RS_ACTION_DOWNSCALE)
sta_priv->tlc_amsdu = false; mvmsta->tlc_amsdu = false;
else else
sta_priv->tlc_amsdu = true; mvmsta->tlc_amsdu = true;
} }
/* /*
...@@ -2228,11 +2274,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -2228,11 +2274,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
u16 high_low; u16 high_low;
s32 sr; s32 sr;
u8 prev_agg = lq_sta->is_agg; u8 prev_agg = lq_sta->is_agg;
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_tid_data *tid_data;
struct rs_rate *rate; struct rs_rate *rate;
lq_sta->is_agg = !!sta_priv->agg_tids; lq_sta->is_agg = !!mvmsta->agg_tids;
/* /*
* Select rate-scale / modulation-mode table to work with in * Select rate-scale / modulation-mode table to work with in
...@@ -2480,44 +2525,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -2480,44 +2525,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
} }
} }
if (!ndp)
rs_tl_turn_on_agg(mvm, mvmsta, tid, lq_sta, sta);
if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) { if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
/* If the "active" (non-search) mode was legacy,
* and we've tried switching antennas,
* but we haven't been able to try HT modes (not available),
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(&tbl1->rate)) { rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta);
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
if (tid != IWL_MAX_TID_COUNT) {
tid_data = &sta_priv->tid_data[tid];
if (tid_data->state != IWL_AGG_OFF) {
IWL_DEBUG_RATE(mvm,
"Stop aggregation on tid %d\n",
tid);
ieee80211_stop_tx_ba_session(sta, tid);
}
}
rs_set_stay_in_table(mvm, 1, lq_sta);
} else {
/* If we're in an HT mode, and all 3 mode switch actions
* have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != IWL_MAX_TID_COUNT)) {
tid_data = &sta_priv->tid_data[tid];
if (tid_data->state == IWL_AGG_OFF && !ndp) {
IWL_DEBUG_RATE(mvm,
"try to aggregate tid %d\n",
tid);
rs_tl_turn_on_agg(mvm, tid,
lq_sta, sta);
}
}
rs_set_stay_in_table(mvm, 0, lq_sta);
}
} }
} }
...@@ -2900,10 +2913,10 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, ...@@ -2900,10 +2913,10 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
gfp_t gfp) gfp_t gfp)
{ {
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate; struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta; struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
...@@ -2917,7 +2930,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, ...@@ -2917,7 +2930,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
lq_sta->pers.last_rssi = S8_MIN; lq_sta->pers.last_rssi = S8_MIN;
return &sta_priv->lq_sta; return &mvmsta->lq_sta;
} }
static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
...@@ -3109,8 +3122,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -3109,8 +3122,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_hw *hw = mvm->hw; struct ieee80211_hw *hw = mvm->hw;
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta; struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
unsigned long supp; /* must be unsigned long for for_each_set_bit */ unsigned long supp; /* must be unsigned long for for_each_set_bit */
...@@ -3119,8 +3132,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -3119,8 +3132,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
sband = hw->wiphy->bands[band]; sband = hw->wiphy->bands[band];
lq_sta->lq.sta_id = sta_priv->sta_id; lq_sta->lq.sta_id = mvmsta->sta_id;
sta_priv->tlc_amsdu = false; mvmsta->tlc_amsdu = false;
for (j = 0; j < LQ_SIZE; j++) for (j = 0; j < LQ_SIZE; j++)
rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
...@@ -3130,7 +3143,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -3130,7 +3143,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
IWL_DEBUG_RATE(mvm, IWL_DEBUG_RATE(mvm,
"LQ: *** rate scale station global init for station %d ***\n", "LQ: *** rate scale station global init for station %d ***\n",
sta_priv->sta_id); mvmsta->sta_id);
/* TODO: what is a good starting rate for STA? About middle? Maybe not /* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from * the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately * previous packets? Need to have IEEE 802.1X auth succeed immediately
......
...@@ -636,8 +636,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, ...@@ -636,8 +636,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
baid_data = rcu_dereference(mvm->baid_map[baid]); baid_data = rcu_dereference(mvm->baid_map[baid]);
if (!baid_data) { if (!baid_data) {
WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN), WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
"Received baid %d, but no data exists for this BAID\n", "Received baid %d, but no data exists for this BAID - reorder data 0x%x\n",
baid); baid, reorder);
return false; return false;
} }
...@@ -758,7 +758,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm, ...@@ -758,7 +758,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
data = rcu_dereference(mvm->baid_map[baid]); data = rcu_dereference(mvm->baid_map[baid]);
if (!data) { if (!data) {
WARN_ON(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN)); WARN(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN),
"OLD_SN isn't set, but no data exists for baid %d - reorder data 0x%x\n",
baid, reorder_data);
goto out; goto out;
} }
......
...@@ -316,6 +316,10 @@ enum iwl_mvm_agg_state { ...@@ -316,6 +316,10 @@ enum iwl_mvm_agg_state {
* @is_tid_active: has this TID sent traffic in the last * @is_tid_active: has this TID sent traffic in the last
* %IWL_MVM_DQA_QUEUE_TIMEOUT time period. If %txq_id is invalid, this * %IWL_MVM_DQA_QUEUE_TIMEOUT time period. If %txq_id is invalid, this
* field should be ignored. * field should be ignored.
* @tpt_meas_start: time of the throughput measurements start, is reset every HZ
* @tx_count_last: number of frames transmitted during the last second
* @tx_count: counts the number of frames transmitted since the last reset of
* tpt_meas_start
*/ */
struct iwl_mvm_tid_data { struct iwl_mvm_tid_data {
struct sk_buff_head deferred_tx_frames; struct sk_buff_head deferred_tx_frames;
...@@ -330,6 +334,9 @@ struct iwl_mvm_tid_data { ...@@ -330,6 +334,9 @@ struct iwl_mvm_tid_data {
u16 ssn; u16 ssn;
u16 tx_time; u16 tx_time;
bool is_tid_active; bool is_tid_active;
unsigned long tpt_meas_start;
u32 tx_count_last;
u32 tx_count;
}; };
struct iwl_mvm_key_pn { struct iwl_mvm_key_pn {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 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
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 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
...@@ -726,8 +728,21 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm, ...@@ -726,8 +728,21 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
{ {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
u32 id;
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock);
id = te_data->id;
spin_unlock_bh(&mvm->time_event_lock);
if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
IWL_DEBUG_TE(mvm,
"don't remove TE with id=%u (not session protection)\n",
id);
return;
}
iwl_mvm_remove_time_event(mvm, mvmvif, te_data); iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
} }
...@@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, ...@@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
if (te_data->running) { if (te_data->running) {
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n"); u32 id;
return -EBUSY;
spin_lock_bh(&mvm->time_event_lock);
id = te_data->id;
spin_unlock_bh(&mvm->time_event_lock);
if (id == TE_CHANNEL_SWITCH_PERIOD) {
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
return -EBUSY;
}
/*
* Remove the session protection time event to allow the
* channel switch. If we got here, we just heard a beacon so
* the session protection is not needed anymore anyway.
*/
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
} }
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
......
...@@ -1331,6 +1331,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -1331,6 +1331,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
while (!skb_queue_empty(&skbs)) { while (!skb_queue_empty(&skbs)) {
struct sk_buff *skb = __skb_dequeue(&skbs); struct sk_buff *skb = __skb_dequeue(&skbs);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
bool flushed = false;
skb_freed++; skb_freed++;
...@@ -1344,6 +1345,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -1344,6 +1345,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
case TX_STATUS_DIRECT_DONE: case TX_STATUS_DIRECT_DONE:
info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_ACK;
break; break;
case TX_STATUS_FAIL_FIFO_FLUSHED:
case TX_STATUS_FAIL_DRAIN_FLOW:
flushed = true;
break;
case TX_STATUS_FAIL_DEST_PS: case TX_STATUS_FAIL_DEST_PS:
/* the FW should have stopped the queue and not /* the FW should have stopped the queue and not
* return this status * return this status
...@@ -1366,7 +1371,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -1366,7 +1371,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/* Single frame failure in an AMPDU queue => send BAR */ /* Single frame failure in an AMPDU queue => send BAR */
if (info->flags & IEEE80211_TX_CTL_AMPDU && if (info->flags & IEEE80211_TX_CTL_AMPDU &&
!(info->flags & IEEE80211_TX_STAT_ACK) && !(info->flags & IEEE80211_TX_STAT_ACK) &&
!(info->flags & IEEE80211_TX_STAT_TX_FILTERED)) !(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed)
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags &= ~IEEE80211_TX_CTL_AMPDU;
...@@ -1515,7 +1520,7 @@ static const char *iwl_get_agg_tx_status(u16 status) ...@@ -1515,7 +1520,7 @@ static const char *iwl_get_agg_tx_status(u16 status)
AGG_TX_STATE_(BT_PRIO); AGG_TX_STATE_(BT_PRIO);
AGG_TX_STATE_(FEW_BYTES); AGG_TX_STATE_(FEW_BYTES);
AGG_TX_STATE_(ABORT); AGG_TX_STATE_(ABORT);
AGG_TX_STATE_(LAST_SENT_TTL); AGG_TX_STATE_(TX_ON_AIR_DROP);
AGG_TX_STATE_(LAST_SENT_TRY_CNT); AGG_TX_STATE_(LAST_SENT_TRY_CNT);
AGG_TX_STATE_(LAST_SENT_BT_KILL); AGG_TX_STATE_(LAST_SENT_BT_KILL);
AGG_TX_STATE_(SCD_QUERY); AGG_TX_STATE_(SCD_QUERY);
......
...@@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, ...@@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
ctxt_info->hcmd_cfg.cmd_queue_addr = ctxt_info->hcmd_cfg.cmd_queue_addr =
cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr); cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
ctxt_info->hcmd_cfg.cmd_queue_size = ctxt_info->hcmd_cfg.cmd_queue_size =
TFD_QUEUE_CB_SIZE(TFD_QUEUE_SIZE_MAX); TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);
/* allocate ucode sections in dram and set addresses */ /* allocate ucode sections in dram and set addresses */
ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info); ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info);
......
...@@ -430,6 +430,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { ...@@ -430,6 +430,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)},
/* 8000 Series */ /* 8000 Series */
{IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
...@@ -690,12 +691,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -690,12 +691,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_trans->cfg = cfg_7265d; iwl_trans->cfg = cfg_7265d;
} }
if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb) { if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb &&
if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_JF) iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
cfg = &iwla000_2ac_cfg_jf; u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
else if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR) u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
cfg = &iwla000_2ac_cfg_hr; u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR);
if (rf_id_chp == jf_chp_id) {
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
cfg = &iwla000_2ax_cfg_qnj_jf_b0;
else
cfg = &iwla000_2ac_cfg_jf;
} else if (rf_id_chp == hr_chp_id) {
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
cfg = &iwla000_2ax_cfg_qnj_hr_a0;
else
cfg = &iwla000_2ac_cfg_hr;
}
iwl_trans->cfg = cfg; iwl_trans->cfg = cfg;
} }
#endif #endif
......
...@@ -661,10 +661,16 @@ static inline void iwl_pcie_sw_reset(struct iwl_trans *trans) ...@@ -661,10 +661,16 @@ static inline void iwl_pcie_sw_reset(struct iwl_trans *trans)
usleep_range(5000, 6000); usleep_range(5000, 6000);
} }
static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq *q, u32 index)
{
return index & (q->n_window - 1);
}
static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie, static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie,
struct iwl_txq *txq, int idx) struct iwl_txq *txq, int idx)
{ {
return txq->tfds + trans_pcie->tfd_size * idx; return txq->tfds + trans_pcie->tfd_size * iwl_pcie_get_cmd_index(txq,
idx);
} }
static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
...@@ -726,11 +732,6 @@ static inline bool iwl_queue_used(const struct iwl_txq *q, int i) ...@@ -726,11 +732,6 @@ static inline bool iwl_queue_used(const struct iwl_txq *q, int i)
!(i < q->read_ptr && i >= q->write_ptr); !(i < q->read_ptr && i >= q->write_ptr);
} }
static inline u8 get_cmd_index(struct iwl_txq *q, u32 index)
{
return index & (q->n_window - 1);
}
static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) static inline bool iwl_is_rfkill_set(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);
......
...@@ -1176,7 +1176,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, ...@@ -1176,7 +1176,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
sequence = le16_to_cpu(pkt->hdr.sequence); sequence = le16_to_cpu(pkt->hdr.sequence);
index = SEQ_TO_INDEX(sequence); index = SEQ_TO_INDEX(sequence);
cmd_index = get_cmd_index(txq, index); cmd_index = iwl_pcie_get_cmd_index(txq, index);
if (rxq->id == 0) if (rxq->id == 0)
iwl_op_mode_rx(trans->op_mode, &rxq->napi, iwl_op_mode_rx(trans->op_mode, &rxq->napi,
......
...@@ -2835,7 +2835,7 @@ static struct iwl_trans_dump_data ...@@ -2835,7 +2835,7 @@ static struct iwl_trans_dump_data
spin_lock_bh(&cmdq->lock); spin_lock_bh(&cmdq->lock);
ptr = cmdq->write_ptr; ptr = cmdq->write_ptr;
for (i = 0; i < cmdq->n_window; i++) { for (i = 0; i < cmdq->n_window; i++) {
u8 idx = get_cmd_index(cmdq, ptr); u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr);
u32 caplen, cmdlen; u32 caplen, cmdlen;
cmdlen = iwl_trans_pcie_get_cmdlen(trans, cmdq->tfds + cmdlen = iwl_trans_pcie_get_cmdlen(trans, cmdq->tfds +
...@@ -3145,7 +3145,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3145,7 +3145,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS); hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
if (hw_status & UMAG_GEN_HW_IS_FPGA) if (hw_status & UMAG_GEN_HW_IS_FPGA)
trans->cfg = &iwla000_2ax_cfg_qnj_hr; trans->cfg = &iwla000_2ax_cfg_qnj_hr_f0;
else else
trans->cfg = &iwla000_2ac_cfg_hr; trans->cfg = &iwla000_2ac_cfg_hr;
} }
......
...@@ -88,14 +88,14 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt, ...@@ -88,14 +88,14 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt,
int num_tbs) int num_tbs)
{ {
struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr; struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr;
int write_ptr = txq->write_ptr; int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
u8 filled_tfd_size, num_fetch_chunks; u8 filled_tfd_size, num_fetch_chunks;
u16 len = byte_cnt; u16 len = byte_cnt;
__le16 bc_ent; __le16 bc_ent;
len = DIV_ROUND_UP(len, 4); len = DIV_ROUND_UP(len, 4);
if (WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX)) if (WARN_ON(len > 0xFFF || idx >= txq->n_window))
return; return;
filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) + filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) +
...@@ -111,7 +111,7 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt, ...@@ -111,7 +111,7 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt,
num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1; num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12)); bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
scd_bc_tbl->tfd_offset[write_ptr] = bc_ent; scd_bc_tbl->tfd_offset[idx] = bc_ent;
} }
/* /*
...@@ -176,16 +176,12 @@ static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) ...@@ -176,16 +176,12 @@ static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
/* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and /* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
* idx is bounded by n_window * idx is bounded by n_window
*/ */
int rd_ptr = txq->read_ptr; int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
int idx = get_cmd_index(txq, rd_ptr);
lockdep_assert_held(&txq->lock); lockdep_assert_held(&txq->lock);
/* We have only q->n_window txq->entries, but we use
* TFD_QUEUE_SIZE_MAX tfds
*/
iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta, iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta,
iwl_pcie_get_tfd(trans_pcie, txq, rd_ptr)); iwl_pcie_get_tfd(trans_pcie, txq, idx));
/* free SKB */ /* free SKB */
if (txq->entries) { if (txq->entries) {
...@@ -373,8 +369,9 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, ...@@ -373,8 +369,9 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(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);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
struct iwl_tfh_tfd *tfd = struct iwl_tfh_tfd *tfd =
iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); iwl_pcie_get_tfd(trans_pcie, txq, idx);
dma_addr_t tb_phys; dma_addr_t tb_phys;
bool amsdu; bool amsdu;
int i, len, tb1_len, tb2_len, hdr_len; int i, len, tb1_len, tb2_len, hdr_len;
...@@ -386,10 +383,10 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, ...@@ -386,10 +383,10 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
(*ieee80211_get_qos_ctl(hdr) & (*ieee80211_get_qos_ctl(hdr) &
IEEE80211_QOS_CTL_A_MSDU_PRESENT); IEEE80211_QOS_CTL_A_MSDU_PRESENT);
tb_phys = iwl_pcie_get_first_tb_dma(txq, txq->write_ptr); tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);
/* The first TB points to bi-directional DMA data */ /* The first TB points to bi-directional DMA data */
if (!amsdu) if (!amsdu)
memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr,
IWL_FIRST_TB_SIZE); IWL_FIRST_TB_SIZE);
iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE); iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);
...@@ -431,7 +428,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, ...@@ -431,7 +428,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
* building the A-MSDU might have changed this data, so memcpy * building the A-MSDU might have changed this data, so memcpy
* it now * it now
*/ */
memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr,
IWL_FIRST_TB_SIZE); IWL_FIRST_TB_SIZE);
return tfd; return tfd;
} }
...@@ -484,6 +481,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -484,6 +481,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload; struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload;
struct iwl_cmd_meta *out_meta; struct iwl_cmd_meta *out_meta;
struct iwl_txq *txq = trans_pcie->txq[txq_id]; struct iwl_txq *txq = trans_pcie->txq[txq_id];
int idx;
void *tfd; void *tfd;
if (WARN_ONCE(!test_bit(txq_id, trans_pcie->queue_used), if (WARN_ONCE(!test_bit(txq_id, trans_pcie->queue_used),
...@@ -497,16 +495,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -497,16 +495,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
spin_lock(&txq->lock); spin_lock(&txq->lock);
idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
/* Set up driver data for this TFD */ /* Set up driver data for this TFD */
txq->entries[txq->write_ptr].skb = skb; txq->entries[idx].skb = skb;
txq->entries[txq->write_ptr].cmd = dev_cmd; txq->entries[idx].cmd = dev_cmd;
dev_cmd->hdr.sequence = dev_cmd->hdr.sequence =
cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
INDEX_TO_SEQ(txq->write_ptr))); INDEX_TO_SEQ(idx)));
/* Set up first empty entry in queue's array of Tx/cmd buffers */ /* Set up first empty entry in queue's array of Tx/cmd buffers */
out_meta = &txq->entries[txq->write_ptr].meta; out_meta = &txq->entries[idx].meta;
out_meta->flags = 0; out_meta->flags = 0;
tfd = iwl_pcie_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta); tfd = iwl_pcie_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta);
...@@ -562,7 +562,7 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, ...@@ -562,7 +562,7 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
unsigned long flags; unsigned long flags;
void *dup_buf = NULL; void *dup_buf = NULL;
dma_addr_t phys_addr; dma_addr_t phys_addr;
int idx, i, cmd_pos; int i, cmd_pos, idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
u16 copy_size, cmd_size, tb0_size; u16 copy_size, cmd_size, tb0_size;
bool had_nocopy = false; bool had_nocopy = false;
u8 group_id = iwl_cmd_groupid(cmd->id); u8 group_id = iwl_cmd_groupid(cmd->id);
...@@ -651,7 +651,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, ...@@ -651,7 +651,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf; goto free_dup_buf;
} }
idx = get_cmd_index(txq, txq->write_ptr);
out_cmd = txq->entries[idx].cmd; out_cmd = txq->entries[idx].cmd;
out_meta = &txq->entries[idx].meta; out_meta = &txq->entries[idx].meta;
...@@ -938,7 +937,7 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id) ...@@ -938,7 +937,7 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
txq_id, txq->read_ptr); txq_id, txq->read_ptr);
if (txq_id != trans_pcie->cmd_queue) { if (txq_id != trans_pcie->cmd_queue) {
int idx = get_cmd_index(txq, txq->read_ptr); int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
struct sk_buff *skb = txq->entries[idx].skb; struct sk_buff *skb = txq->entries[idx].skb;
if (WARN_ON_ONCE(!skb)) if (WARN_ON_ONCE(!skb))
...@@ -1070,7 +1069,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1070,7 +1069,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
cmd->tfdq_addr = cpu_to_le64(txq->dma_addr); cmd->tfdq_addr = cpu_to_le64(txq->dma_addr);
cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma);
cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(TFD_QUEUE_SIZE_MAX)); cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(TFD_TX_CMD_SLOTS));
ret = iwl_trans_send_cmd(trans, &hcmd); ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret) if (ret)
......
...@@ -106,7 +106,7 @@ static int iwl_queue_init(struct iwl_txq *q, int slots_num) ...@@ -106,7 +106,7 @@ static int iwl_queue_init(struct iwl_txq *q, int slots_num)
q->n_window = slots_num; q->n_window = slots_num;
/* slots_num must be power-of-two size, otherwise /* slots_num must be power-of-two size, otherwise
* get_cmd_index is broken. */ * iwl_pcie_get_cmd_index is broken. */
if (WARN_ON(!is_power_of_2(slots_num))) if (WARN_ON(!is_power_of_2(slots_num)))
return -EINVAL; return -EINVAL;
...@@ -428,7 +428,7 @@ void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) ...@@ -428,7 +428,7 @@ void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
* idx is bounded by n_window * idx is bounded by n_window
*/ */
int rd_ptr = txq->read_ptr; int rd_ptr = txq->read_ptr;
int idx = get_cmd_index(txq, rd_ptr); int idx = iwl_pcie_get_cmd_index(txq, rd_ptr);
lockdep_assert_held(&txq->lock); lockdep_assert_held(&txq->lock);
...@@ -1100,7 +1100,8 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, ...@@ -1100,7 +1100,8 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
for (; for (;
txq->read_ptr != tfd_num; txq->read_ptr != tfd_num;
txq->read_ptr = iwl_queue_inc_wrap(txq->read_ptr)) { txq->read_ptr = iwl_queue_inc_wrap(txq->read_ptr)) {
struct sk_buff *skb = txq->entries[txq->read_ptr].skb; int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
struct sk_buff *skb = txq->entries[idx].skb;
if (WARN_ON_ONCE(!skb)) if (WARN_ON_ONCE(!skb))
continue; continue;
...@@ -1109,7 +1110,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, ...@@ -1109,7 +1110,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
__skb_queue_tail(skbs, skb); __skb_queue_tail(skbs, skb);
txq->entries[txq->read_ptr].skb = NULL; txq->entries[idx].skb = NULL;
if (!trans->cfg->use_tfh) if (!trans->cfg->use_tfh)
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
...@@ -1559,7 +1560,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, ...@@ -1559,7 +1560,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf; goto free_dup_buf;
} }
idx = get_cmd_index(txq, txq->write_ptr); idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
out_cmd = txq->entries[idx].cmd; out_cmd = txq->entries[idx].cmd;
out_meta = &txq->entries[idx].meta; out_meta = &txq->entries[idx].meta;
...@@ -1751,7 +1752,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, ...@@ -1751,7 +1752,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
spin_lock_bh(&txq->lock); spin_lock_bh(&txq->lock);
cmd_index = get_cmd_index(txq, index); cmd_index = iwl_pcie_get_cmd_index(txq, index);
cmd = txq->entries[cmd_index].cmd; cmd = txq->entries[cmd_index].cmd;
meta = &txq->entries[cmd_index].meta; meta = &txq->entries[cmd_index].meta;
group_id = cmd->hdr.group_id; group_id = cmd->hdr.group_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment