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. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlmX9zkACgkQoUecoho8 xfrQgw/8CgsYFCQO9jbXDT9M84rPXRzr6WdCZZwOirPs4CHVByLq8r6I2J5BGsBR 46JZXKG6TU1jdikyybjUbz9QqYL+xl54FF/gwvsRe4qxdQhrpt9yDQFOQtfwhR+b NHkHjJ7qmX/H5mcn4attySmAwROHueO0rSnlijCUucgv48w1PHgMouZO3cg5RxIR qOpVP8AHn3X/jIgYiwXGd0gUduz19UJZXwAlGVerV1g7/9cN488/9HSFLEck15CU yspOx97zpi9vWpcFnUKsOSpDOkbFpXcawMXLwKT6ktLWdwSDdDcMpW3VWt9SHcjl zcxIcvglMHbmM7+FdSlGVNTV46fa9TReE7ovfYtj6OxtoO9NV0VenH7rdFIuJIox KOghzAZHnfPpgPomNkBDZlvRJMsuA++ubftcB7MPq0RFwIC9zawjMCP2HZQXijQg WTSOFY3raRL7UJtI1NLKZEAcTJGybHNYWZoyf4PF4VFbz2omBC8bXXpV4wxIUBNh CVw8ak/bXHgoJM3N11EZ5ApC1oGWgetiMpAENxupU+qDG4dH+5NBEldMSK6Cr2hM S+/uBfaDto+Jgd9V/gPiQSvbPPZ/E3LnjjHiFG1FunkcME66aVIt1e4r9su6CBJj GKvp90pXD0rpowxUtgRjqDjYpMbb64cm37ZlLXJ9Hwu7mxPnGcM= =WhZY -----END PGP SIGNATURE----- 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.
This commit is contained in:
Коммит
1fe79d7f35
|
@ -76,13 +76,19 @@
|
|||
#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_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) \
|
||||
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_A000_JF_MODULE_FIRMWARE(api) \
|
||||
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"
|
||||
#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
|
||||
|
||||
|
@ -171,7 +177,7 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
|
|||
.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",
|
||||
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
|
@ -181,6 +187,28 @@ const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
|
|||
.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_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 {
|
|||
BT_COEX_INVALID_LUT = 0xff,
|
||||
}; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
|
||||
|
||||
#define BT_COEX_CORUN_LUT_SIZE (32)
|
||||
#define BT_REDUCED_TX_POWER_BIT BIT(7)
|
||||
|
||||
enum iwl_bt_coex_mode {
|
||||
|
@ -106,18 +105,6 @@ struct iwl_bt_coex_cmd {
|
|||
__le32 enabled_modules;
|
||||
} __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
|
||||
* @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
|
||||
|
@ -191,6 +178,7 @@ enum iwl_bt_mxbox_dw3 {
|
|||
BT_MBOX(3, ACL_STATE, 3, 1),
|
||||
BT_MBOX(3, MSTR_STATE, 4, 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, TRAFFIC_LOAD, 10, 2),
|
||||
BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
|
||||
|
@ -200,10 +188,21 @@ enum iwl_bt_mxbox_dw3 {
|
|||
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) \
|
||||
((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" : ", ");
|
||||
enum iwl_bt_activity_grading {
|
||||
BT_OFF = 0,
|
||||
BT_ON_NO_CONNECTION = 1,
|
||||
|
@ -233,6 +232,31 @@ enum iwl_bt_ci_compliance {
|
|||
* @reserved: reserved
|
||||
*/
|
||||
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 msg_idx;
|
||||
__le32 bt_ci_compliance;
|
||||
|
|
|
@ -135,12 +135,6 @@ enum iwl_legacy_cmds {
|
|||
*/
|
||||
DBG_CFG = 0x9,
|
||||
|
||||
/**
|
||||
* @ANTENNA_COUPLING_NOTIFICATION:
|
||||
* Antenna coupling data, &struct iwl_mvm_antenna_coupling_notif
|
||||
*/
|
||||
ANTENNA_COUPLING_NOTIFICATION = 0xa,
|
||||
|
||||
/**
|
||||
* @SCAN_ITERATION_COMPLETE_UMAC:
|
||||
* Firmware indicates a scan iteration completed, using
|
||||
|
@ -523,12 +517,6 @@ enum iwl_legacy_cmds {
|
|||
*/
|
||||
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:
|
||||
* &struct iwl_bt_coex_reduced_txp_update_cmd
|
||||
|
|
|
@ -181,12 +181,4 @@ struct iwl_dc2dc_config_resp {
|
|||
__le32 dc2dc_freq_tune1;
|
||||
} __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__ */
|
||||
|
|
|
@ -409,7 +409,8 @@ enum iwl_tx_status {
|
|||
* @AGG_TX_STATE_BT_PRIO:
|
||||
* @AGG_TX_STATE_FEW_BYTES:
|
||||
* @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_BT_KILL:
|
||||
* @AGG_TX_STATE_SCD_QUERY:
|
||||
|
@ -433,7 +434,7 @@ enum iwl_tx_agg_status {
|
|||
AGG_TX_STATE_BT_PRIO = 0x002,
|
||||
AGG_TX_STATE_FEW_BYTES = 0x004,
|
||||
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_BT_KILL = 0x040,
|
||||
AGG_TX_STATE_SCD_QUERY = 0x080,
|
||||
|
@ -445,10 +446,6 @@ enum iwl_tx_agg_status {
|
|||
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
|
||||
* 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;
|
|||
* @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_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
|
||||
*/
|
||||
|
@ -262,6 +264,7 @@ enum iwl_ucode_tlv_api {
|
|||
/* API Set 1 */
|
||||
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_COEX_ATS_EXTERNAL = (__force iwl_ucode_tlv_api_t)37,
|
||||
|
||||
NUM_IWL_UCODE_TLV_API
|
||||
#ifdef __CHECKER__
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -32,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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,
|
|||
}
|
||||
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(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_wait->notif_wait_lock);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_remove_notification);
|
||||
|
||||
int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
unsigned long timeout)
|
||||
|
@ -171,9 +181,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
|
|||
wait_entry->triggered || wait_entry->aborted,
|
||||
timeout);
|
||||
|
||||
spin_lock_bh(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_wait->notif_wait_lock);
|
||||
iwl_remove_notification(notif_wait, wait_entry);
|
||||
|
||||
if (wait_entry->aborted)
|
||||
return -EIO;
|
||||
|
@ -184,12 +192,3 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
|
|||
return 0;
|
||||
}
|
||||
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(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_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)
|
|||
rsp->regulatory.channel_profile,
|
||||
nvm->valid_tx_ant & fwrt->fw->valid_tx_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);
|
||||
return nvm;
|
||||
|
|
|
@ -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_jf;
|
||||
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 /* __IWL_CONFIG_H__ */
|
||||
|
|
|
@ -354,11 +354,16 @@ enum {
|
|||
#define CSR_HW_REV_TYPE_135 (0x0000120)
|
||||
#define CSR_HW_REV_TYPE_7265D (0x0000210)
|
||||
#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 */
|
||||
#define CSR_HW_RF_ID_TYPE_JF (0x00105100)
|
||||
#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 */
|
||||
#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,
|
|||
int i;
|
||||
|
||||
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
|
||||
IWL_ERR(drv,
|
||||
"api flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
IWL_WARN(drv,
|
||||
"api flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -508,9 +508,9 @@ static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
|||
int i;
|
||||
|
||||
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
|
||||
IWL_ERR(drv,
|
||||
"capa flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
IWL_WARN(drv,
|
||||
"capa flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
/* NVM offsets (in words) definitions */
|
||||
enum wkp_nvm_offsets {
|
||||
/* NVM HW-Section offset (in words) definitions */
|
||||
SUBSYSTEM_ID = 0x0A,
|
||||
HW_ADDR = 0x15,
|
||||
|
||||
/* NVM SW-Section offset (in words) definitions */
|
||||
|
@ -183,22 +184,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
|
|||
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
|
||||
* @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
|
||||
* @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
|
||||
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
|
||||
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
|
||||
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
|
||||
* @NVM_CHANNEL_UNIFORM: uniform spreading required
|
||||
* @NVM_CHANNEL_20MHZ: 20 MHz channel okay
|
||||
* @NVM_CHANNEL_40MHZ: 40 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 {
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_WIDE = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_UNIFORM = BIT(7),
|
||||
NVM_CHANNEL_20MHZ = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
};
|
||||
|
||||
#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,
|
|||
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 * const nvm_ch_flags,
|
||||
bool lar_supported)
|
||||
bool lar_supported, bool no_wide_in_5ghz)
|
||||
{
|
||||
int ch_idx;
|
||||
int n_channels = 0;
|
||||
struct ieee80211_channel *channel;
|
||||
u16 ch_flags;
|
||||
bool is_5ghz;
|
||||
int num_of_ch, num_2ghz_channels;
|
||||
const u8 *nvm_chan;
|
||||
|
||||
|
@ -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++) {
|
||||
bool is_5ghz = (ch_idx >= num_2ghz_channels);
|
||||
|
||||
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
|
||||
|
||||
if (ch_idx >= num_2ghz_channels &&
|
||||
!data->sku_cap_band_52GHz_enable)
|
||||
if (is_5ghz && !data->sku_cap_band_52GHz_enable)
|
||||
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)
|
||||
data->vht160_supported = true;
|
||||
|
||||
|
@ -303,8 +315,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
n_channels++;
|
||||
|
||||
channel->hw_value = nvm_chan[ch_idx];
|
||||
channel->band = (ch_idx < num_2ghz_channels) ?
|
||||
NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
|
||||
channel->band = is_5ghz ?
|
||||
NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
|
||||
channel->center_freq =
|
||||
ieee80211_channel_to_frequency(
|
||||
channel->hw_value, channel->band);
|
||||
|
@ -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
|
||||
*/
|
||||
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 */
|
||||
if (!lar_supported)
|
||||
|
@ -327,7 +338,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
channel->flags = 0;
|
||||
|
||||
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,
|
||||
is_5ghz ? "5.2" : "2.4",
|
||||
ch_flags,
|
||||
|
@ -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(INDOOR_ONLY),
|
||||
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(80MHZ),
|
||||
CHECK_AND_PRINT_I(160MHZ),
|
||||
CHECK_AND_PRINT_I(DC_HIGH),
|
||||
channel->max_power,
|
||||
((ch_flags & NVM_CHANNEL_IBSS) &&
|
||||
!(ch_flags & NVM_CHANNEL_RADAR))
|
||||
|
@ -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,
|
||||
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_used = 0;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
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->band = NL80211_BAND_2GHZ;
|
||||
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
|
||||
|
@ -568,7 +582,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
|
|||
const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *mac_override,
|
||||
const __le16 *nvm_hw)
|
||||
const __be16 *nvm_hw)
|
||||
{
|
||||
const u8 *hw_addr;
|
||||
|
||||
|
@ -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,
|
||||
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)
|
||||
{
|
||||
if (cfg->mac_addr_from_csr) {
|
||||
|
@ -645,9 +659,41 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
|
|||
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 *
|
||||
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 *mac_override, const __le16 *phy_sku,
|
||||
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,
|
|||
struct device *dev = trans->dev;
|
||||
struct iwl_nvm_data *data;
|
||||
bool lar_enabled;
|
||||
bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
|
||||
u32 sku, radio_cfg;
|
||||
u16 lar_config;
|
||||
const __le16 *ch_section;
|
||||
|
@ -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,
|
||||
lar_fw_supported && lar_enabled);
|
||||
lar_fw_supported && lar_enabled, no_wide_in_5ghz);
|
||||
data->calib_version = 255;
|
||||
|
||||
return data;
|
||||
|
@ -865,22 +912,25 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
|||
prev_center_freq = center_freq;
|
||||
|
||||
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,
|
||||
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
|
||||
CHECK_AND_PRINT_I(VALID),
|
||||
CHECK_AND_PRINT_I(IBSS),
|
||||
CHECK_AND_PRINT_I(ACTIVE),
|
||||
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(80MHZ),
|
||||
CHECK_AND_PRINT_I(160MHZ),
|
||||
CHECK_AND_PRINT_I(INDOOR_ONLY),
|
||||
CHECK_AND_PRINT_I(GO_CONCURRENT),
|
||||
CHECK_AND_PRINT_I(DC_HIGH),
|
||||
ch_flags,
|
||||
((ch_flags & NVM_CHANNEL_ACTIVE) &&
|
||||
!(ch_flags & NVM_CHANNEL_RADAR))
|
||||
? "" : "not ");
|
||||
? "Ad-Hoc" : "");
|
||||
}
|
||||
|
||||
regd->n_reg_rules = valid_rules;
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
*/
|
||||
struct iwl_nvm_data *
|
||||
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 *mac_override, const __le16 *phy_sku,
|
||||
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,
|
|||
*/
|
||||
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
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
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -33,6 +34,7 @@
|
|||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -148,215 +150,6 @@ static const __le64 iwl_ci_mask[][3] = {
|
|||
},
|
||||
};
|
||||
|
||||
struct corunning_block_luts {
|
||||
u8 range;
|
||||
__le32 lut20[BT_COEX_CORUN_LUT_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* Ranges for the antenna coupling calibration / co-running block LUT:
|
||||
* LUT0: [ 0, 12[
|
||||
* LUT1: [12, 20[
|
||||
* LUT2: [20, 21[
|
||||
* LUT3: [21, 23[
|
||||
* LUT4: [23, 27[
|
||||
* LUT5: [27, 30[
|
||||
* LUT6: [30, 32[
|
||||
* LUT7: [32, 33[
|
||||
* LUT8: [33, - [
|
||||
*/
|
||||
static const struct corunning_block_luts antenna_coupling_ranges[] = {
|
||||
{
|
||||
.range = 0,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 12,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 20,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 21,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 23,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 27,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 30,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 32,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
{
|
||||
.range = 33,
|
||||
.lut20 = {
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static enum iwl_bt_coex_lut_type
|
||||
iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -437,9 +230,6 @@ int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm)
|
|||
bt_cmd.enabled_modules |=
|
||||
cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
|
||||
|
||||
if (iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
|
||||
|
||||
if (iwl_mvm_is_mplut_supported(mvm))
|
||||
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_MPLUT_ENABLED);
|
||||
|
||||
|
@ -724,17 +514,36 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
|||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
|
||||
|
||||
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
|
||||
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
|
||||
IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
|
||||
le32_to_cpu(notif->primary_ch_lut));
|
||||
IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
|
||||
le32_to_cpu(notif->secondary_ch_lut));
|
||||
IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
|
||||
le32_to_cpu(notif->bt_activity_grading));
|
||||
if (!iwl_mvm_has_new_ats_coex_api(mvm)) {
|
||||
struct iwl_bt_coex_profile_notif_v4 *v4 = (void *)pkt->data;
|
||||
|
||||
mvm->last_bt_notif.mbox_msg[0] = v4->mbox_msg[0];
|
||||
mvm->last_bt_notif.mbox_msg[1] = v4->mbox_msg[1];
|
||||
mvm->last_bt_notif.mbox_msg[2] = v4->mbox_msg[2];
|
||||
mvm->last_bt_notif.mbox_msg[3] = v4->mbox_msg[3];
|
||||
mvm->last_bt_notif.msg_idx = v4->msg_idx;
|
||||
mvm->last_bt_notif.bt_ci_compliance = v4->bt_ci_compliance;
|
||||
mvm->last_bt_notif.primary_ch_lut = v4->primary_ch_lut;
|
||||
mvm->last_bt_notif.secondary_ch_lut = v4->secondary_ch_lut;
|
||||
mvm->last_bt_notif.bt_activity_grading =
|
||||
v4->bt_activity_grading;
|
||||
mvm->last_bt_notif.ttc_status = v4->ttc_status;
|
||||
mvm->last_bt_notif.rrc_status = v4->rrc_status;
|
||||
} else {
|
||||
/* save this notification for future use: rssi fluctuations */
|
||||
memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
|
||||
}
|
||||
|
||||
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
|
||||
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n",
|
||||
mvm->last_bt_notif.bt_ci_compliance);
|
||||
IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
|
||||
le32_to_cpu(mvm->last_bt_notif.primary_ch_lut));
|
||||
IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
|
||||
le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut));
|
||||
IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
|
||||
le32_to_cpu(mvm->last_bt_notif.bt_activity_grading));
|
||||
|
||||
/* remember this notification for future use: rssi fluctuations */
|
||||
memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
|
||||
|
||||
iwl_mvm_bt_coex_notif_handle(mvm);
|
||||
}
|
||||
|
@ -908,59 +717,3 @@ void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
|
|||
{
|
||||
iwl_mvm_bt_coex_notif_handle(mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_mvm_antenna_coupling_notif *notif = (void *)pkt->data;
|
||||
u32 ant_isolation = le32_to_cpu(notif->isolation);
|
||||
struct iwl_bt_coex_corun_lut_update_cmd cmd = {};
|
||||
u8 __maybe_unused lower_bound, upper_bound;
|
||||
u8 lut;
|
||||
|
||||
if (!iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
return;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* Ignore updates if we are in force mode */
|
||||
if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
|
||||
return;
|
||||
|
||||
if (ant_isolation == mvm->last_ant_isol)
|
||||
return;
|
||||
|
||||
for (lut = 0; lut < ARRAY_SIZE(antenna_coupling_ranges) - 1; lut++)
|
||||
if (ant_isolation < antenna_coupling_ranges[lut + 1].range)
|
||||
break;
|
||||
|
||||
lower_bound = antenna_coupling_ranges[lut].range;
|
||||
|
||||
if (lut < ARRAY_SIZE(antenna_coupling_ranges) - 1)
|
||||
upper_bound = antenna_coupling_ranges[lut + 1].range;
|
||||
else
|
||||
upper_bound = antenna_coupling_ranges[lut].range;
|
||||
|
||||
IWL_DEBUG_COEX(mvm, "Antenna isolation=%d in range [%d,%d[, lut=%d\n",
|
||||
ant_isolation, lower_bound, upper_bound, lut);
|
||||
|
||||
mvm->last_ant_isol = ant_isolation;
|
||||
|
||||
if (mvm->last_corun_lut == lut)
|
||||
return;
|
||||
|
||||
mvm->last_corun_lut = lut;
|
||||
|
||||
/* For the moment, use the same LUT for 20GHz and 40GHz */
|
||||
memcpy(&cmd.corun_lut20, antenna_coupling_ranges[lut].lut20,
|
||||
sizeof(cmd.corun_lut20));
|
||||
|
||||
memcpy(&cmd.corun_lut40, antenna_coupling_ranges[lut].lut20,
|
||||
sizeof(cmd.corun_lut40));
|
||||
|
||||
if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_CORUN_LUT, 0,
|
||||
sizeof(cmd), &cmd))
|
||||
IWL_ERR(mvm,
|
||||
"failed to send BT_COEX_UPDATE_CORUN_LUT command\n");
|
||||
}
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
#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_SYNC2SCO 1
|
||||
#define IWL_MVM_BT_COEX_CORUNNING 0
|
||||
#define IWL_MVM_BT_COEX_MPLUT 1
|
||||
#define IWL_MVM_BT_COEX_RRC 1
|
||||
#define IWL_MVM_BT_COEX_TTC 1
|
||||
|
@ -137,6 +136,7 @@
|
|||
#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_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_NO_INCREASE 85 /* percent */
|
||||
#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,
|
|||
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
|
||||
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)
|
||||
{
|
||||
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,
|
|||
BT_MBOX_PRINT(3, SCO_STATE, false);
|
||||
BT_MBOX_PRINT(3, SNIFF_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, MSTR_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,
|
|||
BT_MBOX_PRINT(3, INBAND_P, false);
|
||||
BT_MBOX_PRINT(3, MSG_TYPE_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;
|
||||
}
|
||||
|
@ -554,7 +549,7 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
|
|||
|
||||
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",
|
||||
notif->bt_ci_compliance);
|
||||
|
@ -565,9 +560,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
|
|||
pos += scnprintf(buf + pos,
|
||||
bufsz - pos, "bt_activity_grading = %d\n",
|
||||
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",
|
||||
notif->rrc_status & 0xF);
|
||||
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,
|
|||
IWL_MVM_BT_COEX_SYNC2SCO);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n",
|
||||
IWL_MVM_BT_COEX_MPLUT);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "corunning = %d\n",
|
||||
IWL_MVM_BT_COEX_CORUNNING);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
ret = iwl_nvm_init(mvm, true);
|
||||
ret = iwl_nvm_init(mvm);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
|
||||
goto error;
|
||||
|
@ -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);
|
||||
if (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) {
|
||||
ret = iwl_mvm_send_bt_init_conf(mvm);
|
||||
if (ret)
|
||||
goto error;
|
||||
goto remove_notif;
|
||||
}
|
||||
|
||||
/* Read the NVM only at driver load time, no need to do this twice */
|
||||
if (read_nvm) {
|
||||
/* Read nvm */
|
||||
ret = iwl_nvm_init(mvm, true);
|
||||
ret = iwl_nvm_init(mvm);
|
||||
if (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)
|
|||
if (mvm->nvm_file_name)
|
||||
iwl_mvm_load_nvm_to_nic(mvm);
|
||||
|
||||
ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
|
||||
WARN_ON(ret);
|
||||
WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
|
||||
|
||||
/*
|
||||
* 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)
|
|||
if (iwl_mvm_is_radio_hw_killed(mvm)) {
|
||||
IWL_DEBUG_RF_KILL(mvm,
|
||||
"jump over all phy activities due to RF kill\n");
|
||||
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
|
||||
ret = 1;
|
||||
goto out;
|
||||
goto remove_notif;
|
||||
}
|
||||
|
||||
mvm->calibrating = true;
|
||||
|
@ -518,17 +514,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||
/* Send TX valid antennas before triggering calibrations */
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
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);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
|
||||
ret);
|
||||
goto error;
|
||||
goto remove_notif;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -536,15 +528,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||
* just wait for the calibration complete notification.
|
||||
*/
|
||||
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");
|
||||
ret = 1;
|
||||
ret = 0;
|
||||
} else {
|
||||
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
error:
|
||||
remove_notif:
|
||||
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
|
||||
out:
|
||||
mvm->calibrating = false;
|
||||
|
@ -997,6 +995,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
|||
{
|
||||
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 */
|
||||
|
||||
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)
|
|||
|
||||
if (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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* remove the session protection.
|
||||
*/
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif,
|
||||
&mvmvif->time_event_data);
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
|
||||
iwl_mvm_sf_update(mvm, vif, false);
|
||||
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,
|
|||
|
||||
/* Schedule the time event to a bit before beacon 1,
|
||||
* 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 +
|
||||
((vif->bss_conf.beacon_int * (chsw->count - 1) -
|
||||
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
|
||||
if (chsw->count <= 1)
|
||||
apply_time = 0;
|
||||
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)
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
|
|
|
@ -924,8 +924,6 @@ struct iwl_mvm {
|
|||
struct iwl_bt_coex_profile_notif last_bt_notif;
|
||||
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
|
||||
|
||||
u32 last_ant_isol;
|
||||
u8 last_corun_lut;
|
||||
u8 bt_tx_prio;
|
||||
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)
|
|||
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)
|
||||
{
|
||||
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)
|
|||
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 *
|
||||
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);
|
|||
void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
|
||||
|
||||
/* 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_read_external_nvm(struct iwl_mvm *mvm);
|
||||
|
||||
|
@ -1828,21 +1825,7 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
|
|||
u32 duration, u32 timeout);
|
||||
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_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__ */
|
||||
|
|
|
@ -292,7 +292,8 @@ static struct iwl_nvm_data *
|
|||
iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
||||
{
|
||||
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;
|
||||
|
||||
/* Checking for required sections */
|
||||
|
@ -326,10 +327,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
|||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(!mvm->cfg))
|
||||
return NULL;
|
||||
|
||||
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
|
||||
hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
|
||||
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
|
||||
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].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)
|
|||
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;
|
||||
u32 size_read = 0;
|
||||
|
@ -557,63 +555,61 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
|
|||
return -EINVAL;
|
||||
|
||||
/* load NVM values from nic */
|
||||
if (read_nvm_from_nic) {
|
||||
/* Read From FW NVM */
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
|
||||
/* Read From FW NVM */
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
|
||||
|
||||
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
|
||||
GFP_KERNEL);
|
||||
if (!nvm_buffer)
|
||||
return -ENOMEM;
|
||||
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
|
||||
/* we override the constness for initial read */
|
||||
ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
|
||||
size_read);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
size_read += ret;
|
||||
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
|
||||
if (!temp) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
|
||||
GFP_KERNEL);
|
||||
if (!nvm_buffer)
|
||||
return -ENOMEM;
|
||||
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
|
||||
/* we override the constness for initial read */
|
||||
ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
|
||||
size_read);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
size_read += ret;
|
||||
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
|
||||
if (!temp) {
|
||||
ret = -ENOMEM;
|
||||
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].length = ret;
|
||||
mvm->nvm_sections[section].data = temp;
|
||||
mvm->nvm_sections[section].length = ret;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
switch (section) {
|
||||
case NVM_SECTION_TYPE_SW:
|
||||
mvm->nvm_sw_blob.data = temp;
|
||||
mvm->nvm_sw_blob.size = ret;
|
||||
switch (section) {
|
||||
case NVM_SECTION_TYPE_SW:
|
||||
mvm->nvm_sw_blob.data = temp;
|
||||
mvm->nvm_sw_blob.size = ret;
|
||||
break;
|
||||
case NVM_SECTION_TYPE_CALIBRATION:
|
||||
mvm->nvm_calib_blob.data = temp;
|
||||
mvm->nvm_calib_blob.size = ret;
|
||||
break;
|
||||
case NVM_SECTION_TYPE_PRODUCTION:
|
||||
mvm->nvm_prod_blob.data = temp;
|
||||
mvm->nvm_prod_blob.size = ret;
|
||||
break;
|
||||
case NVM_SECTION_TYPE_PHY_SKU:
|
||||
mvm->nvm_phy_sku_blob.data = temp;
|
||||
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;
|
||||
case NVM_SECTION_TYPE_CALIBRATION:
|
||||
mvm->nvm_calib_blob.data = temp;
|
||||
mvm->nvm_calib_blob.size = ret;
|
||||
break;
|
||||
case NVM_SECTION_TYPE_PRODUCTION:
|
||||
mvm->nvm_prod_blob.data = temp;
|
||||
mvm->nvm_prod_blob.size = ret;
|
||||
break;
|
||||
case NVM_SECTION_TYPE_PHY_SKU:
|
||||
mvm->nvm_phy_sku_blob.data = temp;
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!size_read)
|
||||
IWL_ERR(mvm, "OTP is blank\n");
|
||||
kfree(nvm_buffer);
|
||||
#endif
|
||||
}
|
||||
if (!size_read)
|
||||
IWL_ERR(mvm, "OTP is blank\n");
|
||||
kfree(nvm_buffer);
|
||||
|
||||
/* Only if PNVM selected in the mod param - load external NVM */
|
||||
if (mvm->nvm_file_name) {
|
||||
|
|
|
@ -256,8 +256,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
|||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
|
||||
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,
|
||||
iwl_mvm_window_status_notif, RX_HANDLER_SYNC),
|
||||
|
@ -325,7 +323,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
|||
HCMD_NAME(INIT_COMPLETE_NOTIF),
|
||||
HCMD_NAME(PHY_CONTEXT_CMD),
|
||||
HCMD_NAME(DBG_CFG),
|
||||
HCMD_NAME(ANTENNA_COUPLING_NOTIFICATION),
|
||||
HCMD_NAME(SCAN_CFG_CMD),
|
||||
HCMD_NAME(SCAN_REQ_UMAC),
|
||||
HCMD_NAME(SCAN_ABORT_UMAC),
|
||||
|
@ -357,7 +354,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
|||
HCMD_NAME(SCAN_OFFLOAD_ABORT_CMD),
|
||||
HCMD_NAME(HOT_SPOT_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_CI),
|
||||
HCMD_NAME(PHY_CONFIGURATION_CMD),
|
||||
|
@ -388,6 +384,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
|||
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
|
||||
HCMD_NAME(REPLY_RX_PHY_CMD),
|
||||
HCMD_NAME(REPLY_RX_MPDU_CMD),
|
||||
HCMD_NAME(FRAME_RELEASE),
|
||||
HCMD_NAME(BA_NOTIF),
|
||||
HCMD_NAME(MCC_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,
|
|||
iwl_mvm_stop_device(mvm);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
/* returns 0 if successful, 1 if success but in rfkill */
|
||||
if (err < 0) {
|
||||
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
|
||||
goto out_free;
|
||||
|
|
|
@ -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",
|
||||
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) {
|
||||
/*
|
||||
* driver and mac80211 is out of sync
|
||||
|
@ -636,15 +638,31 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid,
|
||||
struct iwl_lq_sta *lq_data,
|
||||
static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
||||
u8 tid, struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if (tid < IWL_MAX_TID_COUNT)
|
||||
rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
|
||||
else
|
||||
struct iwl_mvm_tid_data *tid_data;
|
||||
|
||||
/*
|
||||
* 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",
|
||||
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)
|
||||
|
@ -753,8 +771,38 @@ static int rs_collect_tpc_data(struct iwl_mvm *mvm,
|
|||
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,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_mvm_sta *mvmsta, u8 tid,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
int scale_index, int attempts, int successes)
|
||||
{
|
||||
|
@ -764,12 +812,14 @@ static int rs_collect_tlc_data(struct iwl_mvm *mvm,
|
|||
return -EINVAL;
|
||||
|
||||
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].success += successes;
|
||||
}
|
||||
|
||||
rs_update_tid_tpt_stats(mvm, mvmsta, tid, successes);
|
||||
|
||||
/* Select window for current tx bit rate */
|
||||
window = &(tbl->win[scale_index]);
|
||||
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,
|
|||
if (time_after(jiffies,
|
||||
(unsigned long)(lq_sta->last_tx +
|
||||
(IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
|
||||
int t;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -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)
|
||||
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_ack_len);
|
||||
|
||||
|
@ -1351,7 +1397,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
lq_rate.index, 1,
|
||||
i < retries ? 0 : legacy_success,
|
||||
reduced_txp);
|
||||
rs_collect_tlc_data(mvm, lq_sta, tmp_tbl,
|
||||
rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
|
||||
lq_rate.index, 1,
|
||||
i < retries ? 0 : legacy_success);
|
||||
}
|
||||
|
@ -1673,14 +1719,14 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
struct iwl_scale_tbl_info *tbl,
|
||||
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)) ||
|
||||
tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
|
||||
scale_action == RS_ACTION_DOWNSCALE)
|
||||
sta_priv->tlc_amsdu = false;
|
||||
mvmsta->tlc_amsdu = false;
|
||||
else
|
||||
sta_priv->tlc_amsdu = true;
|
||||
mvmsta->tlc_amsdu = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2228,11 +2274,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
|||
u16 high_low;
|
||||
s32 sr;
|
||||
u8 prev_agg = lq_sta->is_agg;
|
||||
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_tid_data *tid_data;
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
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
|
||||
|
@ -2480,44 +2525,12 @@ lq_update:
|
|||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
if (is_legacy(&tbl1->rate)) {
|
||||
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
|
||||
if (!ndp)
|
||||
rs_tl_turn_on_agg(mvm, mvmsta, tid, lq_sta, sta);
|
||||
|
||||
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);
|
||||
}
|
||||
if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
|
||||
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_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,
|
||||
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_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");
|
||||
|
||||
|
@ -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));
|
||||
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,
|
||||
|
@ -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_sta_ht_cap *ht_cap = &sta->ht_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_lq_sta *lq_sta = &sta_priv->lq_sta;
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
|
||||
struct ieee80211_supported_band *sband;
|
||||
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,
|
|||
|
||||
sband = hw->wiphy->bands[band];
|
||||
|
||||
lq_sta->lq.sta_id = sta_priv->sta_id;
|
||||
sta_priv->tlc_amsdu = false;
|
||||
lq_sta->lq.sta_id = mvmsta->sta_id;
|
||||
mvmsta->tlc_amsdu = false;
|
||||
|
||||
for (j = 0; j < LQ_SIZE; 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,
|
|||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"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
|
||||
* the lowest or the highest rate.. Could consider using RSSI from
|
||||
* previous packets? Need to have IEEE 802.1X auth succeed immediately
|
||||
|
|
|
@ -636,8 +636,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
|||
baid_data = rcu_dereference(mvm->baid_map[baid]);
|
||||
if (!baid_data) {
|
||||
WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
|
||||
"Received baid %d, but no data exists for this BAID\n",
|
||||
baid);
|
||||
"Received baid %d, but no data exists for this BAID - reorder data 0x%x\n",
|
||||
baid, reorder);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -758,7 +758,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
|
|||
|
||||
data = rcu_dereference(mvm->baid_map[baid]);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,10 @@ enum iwl_mvm_agg_state {
|
|||
* @is_tid_active: has this TID sent traffic in the last
|
||||
* %IWL_MVM_DQA_QUEUE_TIMEOUT time period. If %txq_id is invalid, this
|
||||
* 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 sk_buff_head deferred_tx_frames;
|
||||
|
@ -330,6 +334,9 @@ struct iwl_mvm_tid_data {
|
|||
u16 ssn;
|
||||
u16 tx_time;
|
||||
bool is_tid_active;
|
||||
unsigned long tpt_meas_start;
|
||||
u32 tx_count_last;
|
||||
u32 tx_count;
|
||||
};
|
||||
|
||||
struct iwl_mvm_key_pn {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -33,6 +34,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||
u32 id;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
|
|||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (te_data->running) {
|
||||
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
|
||||
return -EBUSY;
|
||||
u32 id;
|
||||
|
||||
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);
|
||||
|
|
|
@ -1331,6 +1331,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||
while (!skb_queue_empty(&skbs)) {
|
||||
struct sk_buff *skb = __skb_dequeue(&skbs);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
bool flushed = false;
|
||||
|
||||
skb_freed++;
|
||||
|
||||
|
@ -1344,6 +1345,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||
case TX_STATUS_DIRECT_DONE:
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
break;
|
||||
case TX_STATUS_FAIL_FIFO_FLUSHED:
|
||||
case TX_STATUS_FAIL_DRAIN_FLOW:
|
||||
flushed = true;
|
||||
break;
|
||||
case TX_STATUS_FAIL_DEST_PS:
|
||||
/* the FW should have stopped the queue and not
|
||||
* return this status
|
||||
|
@ -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 */
|
||||
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
|
||||
!(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_CTL_AMPDU;
|
||||
|
||||
|
@ -1515,7 +1520,7 @@ static const char *iwl_get_agg_tx_status(u16 status)
|
|||
AGG_TX_STATE_(BT_PRIO);
|
||||
AGG_TX_STATE_(FEW_BYTES);
|
||||
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_BT_KILL);
|
||||
AGG_TX_STATE_(SCD_QUERY);
|
||||
|
|
|
@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
|
|||
ctxt_info->hcmd_cfg.cmd_queue_addr =
|
||||
cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
|
||||
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 */
|
||||
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[] = {
|
|||
{IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)},
|
||||
|
||||
/* 8000 Series */
|
||||
{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)
|
|||
iwl_trans->cfg = cfg_7265d;
|
||||
}
|
||||
|
||||
if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb) {
|
||||
if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_JF)
|
||||
cfg = &iwla000_2ac_cfg_jf;
|
||||
else if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR)
|
||||
cfg = &iwla000_2ac_cfg_hr;
|
||||
if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb &&
|
||||
iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
|
||||
u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
|
||||
u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -661,10 +661,16 @@ static inline void iwl_pcie_sw_reset(struct iwl_trans *trans)
|
|||
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,
|
||||
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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
|||
|
||||
sequence = le16_to_cpu(pkt->hdr.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)
|
||||
iwl_op_mode_rx(trans->op_mode, &rxq->napi,
|
||||
|
|
|
@ -2835,7 +2835,7 @@ static struct iwl_trans_dump_data
|
|||
spin_lock_bh(&cmdq->lock);
|
||||
ptr = cmdq->write_ptr;
|
||||
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;
|
||||
|
||||
cmdlen = iwl_trans_pcie_get_cmdlen(trans, cmdq->tfds +
|
||||
|
@ -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);
|
||||
if (hw_status & UMAG_GEN_HW_IS_FPGA)
|
||||
trans->cfg = &iwla000_2ax_cfg_qnj_hr;
|
||||
trans->cfg = &iwla000_2ax_cfg_qnj_hr_f0;
|
||||
else
|
||||
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,
|
|||
int num_tbs)
|
||||
{
|
||||
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;
|
||||
u16 len = byte_cnt;
|
||||
__le16 bc_ent;
|
||||
|
||||
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;
|
||||
|
||||
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,
|
|||
num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
|
||||
|
||||
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)
|
|||
/* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
|
||||
* idx is bounded by n_window
|
||||
*/
|
||||
int rd_ptr = txq->read_ptr;
|
||||
int idx = get_cmd_index(txq, rd_ptr);
|
||||
int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
|
||||
|
||||
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_get_tfd(trans_pcie, txq, rd_ptr));
|
||||
iwl_pcie_get_tfd(trans_pcie, txq, idx));
|
||||
|
||||
/* free SKB */
|
||||
if (txq->entries) {
|
||||
|
@ -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 ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
|
||||
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;
|
||||
bool amsdu;
|
||||
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,
|
|||
(*ieee80211_get_qos_ctl(hdr) &
|
||||
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 */
|
||||
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_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,
|
|||
* building the A-MSDU might have changed this data, so memcpy
|
||||
* 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);
|
||||
return tfd;
|
||||
}
|
||||
|
@ -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_cmd_meta *out_meta;
|
||||
struct iwl_txq *txq = trans_pcie->txq[txq_id];
|
||||
int idx;
|
||||
void *tfd;
|
||||
|
||||
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,
|
|||
|
||||
spin_lock(&txq->lock);
|
||||
|
||||
idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
|
||||
|
||||
/* Set up driver data for this TFD */
|
||||
txq->entries[txq->write_ptr].skb = skb;
|
||||
txq->entries[txq->write_ptr].cmd = dev_cmd;
|
||||
txq->entries[idx].skb = skb;
|
||||
txq->entries[idx].cmd = dev_cmd;
|
||||
|
||||
dev_cmd->hdr.sequence =
|
||||
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 */
|
||||
out_meta = &txq->entries[txq->write_ptr].meta;
|
||||
out_meta = &txq->entries[idx].meta;
|
||||
out_meta->flags = 0;
|
||||
|
||||
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,
|
|||
unsigned long flags;
|
||||
void *dup_buf = NULL;
|
||||
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;
|
||||
bool had_nocopy = false;
|
||||
u8 group_id = iwl_cmd_groupid(cmd->id);
|
||||
|
@ -651,7 +651,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
|
|||
goto free_dup_buf;
|
||||
}
|
||||
|
||||
idx = get_cmd_index(txq, txq->write_ptr);
|
||||
out_cmd = txq->entries[idx].cmd;
|
||||
out_meta = &txq->entries[idx].meta;
|
||||
|
||||
|
@ -938,7 +937,7 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
|
|||
txq_id, txq->read_ptr);
|
||||
|
||||
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;
|
||||
|
||||
if (WARN_ON_ONCE(!skb))
|
||||
|
@ -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->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);
|
||||
if (ret)
|
||||
|
|
|
@ -106,7 +106,7 @@ static int iwl_queue_init(struct iwl_txq *q, int slots_num)
|
|||
q->n_window = slots_num;
|
||||
|
||||
/* 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)))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -428,7 +428,7 @@ void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
|
|||
* idx is bounded by n_window
|
||||
*/
|
||||
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);
|
||||
|
||||
|
@ -1100,7 +1100,8 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
|||
for (;
|
||||
txq->read_ptr != tfd_num;
|
||||
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))
|
||||
continue;
|
||||
|
@ -1109,7 +1110,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
|||
|
||||
__skb_queue_tail(skbs, skb);
|
||||
|
||||
txq->entries[txq->read_ptr].skb = NULL;
|
||||
txq->entries[idx].skb = NULL;
|
||||
|
||||
if (!trans->cfg->use_tfh)
|
||||
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
|
||||
|
@ -1559,7 +1560,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
|
|||
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_meta = &txq->entries[idx].meta;
|
||||
|
||||
|
@ -1751,7 +1752,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
|
|||
|
||||
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;
|
||||
meta = &txq->entries[cmd_index].meta;
|
||||
group_id = cmd->hdr.group_id;
|
||||
|
|
Загрузка…
Ссылка в новой задаче