mirror of
https://github.com/torvalds/linux.git
synced 2024-12-30 14:52:05 +00:00
* more work on d0i3 power state
* enhancements to the firmware debugging infrastructure * support for 2 concurrent channel contexts * fixes / cleanups in the rate control * general cleanups -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUoq8jAAoJEC0Llv5uNjIBvI8QAKHh50//nq9RELVEbB07fSnn MX4+WGYkF1y9AfhqHOCtXi2/97Tw5S3qQXZEhB369nT0b3MdDKI3jJDJPmY5VDoL fUZdAh49cZyP+1DZFlGOOjIH2nID5vL8E3Pbe+ZQaEycioDL9nn1wNsdGrrQ7YYJ GGLIW8+ast65/VFSuC2h4T5OV/vkkqvrtTcUwhWLEw7IYE5z1PnDP33MPvlAHQtA WuG+Iq0Hsb+gBexwcYHytVKkgJc3/7DhJeLIN/tWb+mEn2ygosUpzJm8Z54qzVmr W28FvukswwBwMbf5N/FeTvuvG7uaatHo2IcGnTph+j0GXB6IbJbOW+O+OOOjTl4o 1Gq+H7XtHd8gxqHX1vBljzz406vi5fbrdSeZaFs5YYCkGjYTBv3Xhaa9n6kzGp1k I6iB7oPDSUj2E+M0kpalQLpLOYur5I13nt8dV57Hq5rZSdr/SAIdWZapTblLG046 7mAg+hCuMjN2LODNAFgviqZlhz6EPS8f6DfuVrc5J7j6lyxhH2t8gO3/ZMVR/bU7 BNrSj7UNpvh0+U0YhxosIboU7AZNlufXuXukk3Q5TFWgQ1SeCzMU87sKAm/si89+ O6tgIpImHcofV7KDygv3i3ucEg7rzZbW9HAnGHFEuiRbJLZfa3kPwj0ULic+o9bc 4pISXjv0iPGYq1QUhygB =gLE1 -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next * more work on d0i3 power state * enhancements to the firmware debugging infrastructure * support for 2 concurrent channel contexts * fixes / cleanups in the rate control * general cleanups
This commit is contained in:
commit
64bb1b944b
@ -64,22 +64,8 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* module name, copyright, version, etc.
|
||||
*/
|
||||
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
#define VD "d"
|
||||
#else
|
||||
#define VD
|
||||
#endif
|
||||
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD
|
||||
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@ -1011,13 +997,11 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
if (priv->lib->bt_params)
|
||||
iwlagn_bt_setup_deferred_work(priv);
|
||||
|
||||
init_timer(&priv->statistics_periodic);
|
||||
priv->statistics_periodic.data = (unsigned long)priv;
|
||||
priv->statistics_periodic.function = iwl_bg_statistics_periodic;
|
||||
setup_timer(&priv->statistics_periodic, iwl_bg_statistics_periodic,
|
||||
(unsigned long)priv);
|
||||
|
||||
init_timer(&priv->ucode_trace);
|
||||
priv->ucode_trace.data = (unsigned long)priv;
|
||||
priv->ucode_trace.function = iwl_bg_ucode_trace;
|
||||
setup_timer(&priv->ucode_trace, iwl_bg_ucode_trace,
|
||||
(unsigned long)priv);
|
||||
}
|
||||
|
||||
void iwl_cancel_deferred_work(struct iwl_priv *priv)
|
||||
|
@ -612,15 +612,10 @@ void iwl_tt_initialize(struct iwl_priv *priv)
|
||||
memset(tt, 0, sizeof(struct iwl_tt_mgmt));
|
||||
|
||||
tt->state = IWL_TI_0;
|
||||
init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
|
||||
priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
|
||||
priv->thermal_throttle.ct_kill_exit_tm.function =
|
||||
iwl_tt_check_exit_ct_kill;
|
||||
init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
|
||||
priv->thermal_throttle.ct_kill_waiting_tm.data =
|
||||
(unsigned long)priv;
|
||||
priv->thermal_throttle.ct_kill_waiting_tm.function =
|
||||
iwl_tt_ready_for_ct_kill;
|
||||
setup_timer(&priv->thermal_throttle.ct_kill_exit_tm,
|
||||
iwl_tt_check_exit_ct_kill, (unsigned long)priv);
|
||||
setup_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
|
||||
iwl_tt_ready_for_ct_kill, (unsigned long)priv);
|
||||
/* setup deferred ct kill work */
|
||||
INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
|
||||
INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
|
||||
|
@ -92,6 +92,12 @@
|
||||
#define IWL7265D_NVM_VERSION 0x0c11
|
||||
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* DCCM offsets and lengths */
|
||||
#define IWL7000_DCCM_OFFSET 0x800000
|
||||
#define IWL7260_DCCM_LEN 0x14000
|
||||
#define IWL3160_DCCM_LEN 0x10000
|
||||
#define IWL7265_DCCM_LEN 0x17A00
|
||||
|
||||
#define IWL7260_FW_PRE "iwlwifi-7260-"
|
||||
#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
@ -138,7 +144,8 @@ static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.dccm_offset = IWL7000_DCCM_OFFSET
|
||||
|
||||
const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7260",
|
||||
@ -149,6 +156,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
@ -161,6 +169,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
.high_temp = true,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
@ -172,6 +181,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_n_cfg = {
|
||||
@ -183,6 +193,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
@ -193,6 +204,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
@ -203,6 +215,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_n_cfg = {
|
||||
@ -213,6 +226,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
|
||||
static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = {
|
||||
@ -240,6 +254,7 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
|
||||
.nvm_ver = IWL3165_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3165_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
@ -250,6 +265,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
@ -260,6 +276,7 @@ const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_n_cfg = {
|
||||
@ -270,6 +287,7 @@ const struct iwl_cfg iwl7265_n_cfg = {
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_2ac_cfg = {
|
||||
@ -280,6 +298,7 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_2n_cfg = {
|
||||
@ -290,6 +309,7 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_n_cfg = {
|
||||
@ -300,6 +320,7 @@ const struct iwl_cfg iwl7265d_n_cfg = {
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
|
||||
|
@ -81,12 +81,19 @@
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL8260_DCCM_OFFSET 0x800000
|
||||
#define IWL8260_DCCM_LEN 0x18000
|
||||
#define IWL8260_SMEM_OFFSET 0x400000
|
||||
#define IWL8260_SMEM_LEN 0x68000
|
||||
|
||||
#define IWL8000_FW_PRE "iwlwifi-8000"
|
||||
#define IWL8000_MODULE_FIRMWARE(api) \
|
||||
IWL8000_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin"
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000A "iwl_nvm_8000.bin"
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000B.bin"
|
||||
|
||||
/* Max SDIO RX aggregation size of the ADDBA request/response */
|
||||
#define MAX_RX_AGG_SIZE_8260_SDIO 28
|
||||
@ -124,7 +131,11 @@ static const struct iwl_ht_params iwl8000_ht_params = {
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
|
||||
.d0i3 = true, \
|
||||
.non_shared_ant = ANT_A
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL8260_DCCM_OFFSET, \
|
||||
.dccm_len = IWL8260_DCCM_LEN, \
|
||||
.smem_offset = IWL8260_SMEM_OFFSET, \
|
||||
.smem_len = IWL8260_SMEM_LEN
|
||||
|
||||
const struct iwl_cfg iwl8260_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 8260",
|
||||
@ -153,6 +164,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
|
||||
.default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A,
|
||||
.max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
|
||||
.disable_dummy_notification = true,
|
||||
.max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO,
|
||||
@ -167,6 +179,7 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = {
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
|
||||
.default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A,
|
||||
.max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
|
||||
.bt_shared_single_ant = true,
|
||||
.disable_dummy_notification = true,
|
||||
|
@ -261,6 +261,10 @@ struct iwl_pwr_tx_backoff {
|
||||
* station can receive in HT
|
||||
* @max_vht_ampdu_exponent: the exponent of the max length of A-MPDU that the
|
||||
* station can receive in VHT
|
||||
* @dccm_offset: offset from which DCCM begins
|
||||
* @dccm_len: length of DCCM (including runtime stack CCM)
|
||||
* @smem_offset: offset from which the SMEM begins
|
||||
* @smem_len: the length of SMEM
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt. hardware features.
|
||||
* API differences in uCode shouldn't be handled here but through TLVs
|
||||
@ -298,11 +302,16 @@ struct iwl_cfg {
|
||||
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
|
||||
bool no_power_up_nic_in_init;
|
||||
const char *default_nvm_file;
|
||||
const char *default_nvm_file_8000A;
|
||||
unsigned int max_rx_agg_size;
|
||||
bool disable_dummy_notification;
|
||||
unsigned int max_tx_agg_size;
|
||||
unsigned int max_ht_ampdu_exponent;
|
||||
unsigned int max_vht_ampdu_exponent;
|
||||
const u32 dccm_offset;
|
||||
const u32 dccm_len;
|
||||
const u32 smem_offset;
|
||||
const u32 smem_len;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -370,7 +379,6 @@ extern const struct iwl_cfg iwl7265d_n_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2n_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
|
||||
extern const struct iwl_cfg iwl4265_2ac_sdio_cfg;
|
||||
extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
|
@ -184,6 +184,7 @@
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */
|
||||
#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */
|
||||
#define CSR_HW_IF_CONFIG_REG_ENABLE_PME (0x10000000)
|
||||
#define CSR_HW_IF_CONFIG_REG_PERSIST_MODE (0x40000000) /* PERSISTENCE */
|
||||
|
||||
#define CSR_MBOX_SET_REG_OS_ALIVE BIT(5)
|
||||
|
@ -84,21 +84,8 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* module name, copyright, version, etc.
|
||||
*/
|
||||
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
#define VD "d"
|
||||
#else
|
||||
#define VD
|
||||
#endif
|
||||
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@ -250,9 +237,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
||||
/*
|
||||
* Starting 8000B - FW name format has changed. This overwrites the
|
||||
* previous name and uses the new format.
|
||||
*
|
||||
* TODO:
|
||||
* Once there is only one supported step for 8000 family - delete this!
|
||||
*/
|
||||
if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
|
||||
char rev_step[2] = {
|
||||
@ -263,13 +247,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
||||
if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
|
||||
rev_step[0] = 0;
|
||||
|
||||
/*
|
||||
* If hw_rev wasn't set yet - default as B-step. If it IS A-step
|
||||
* we'll reload that FW later instead.
|
||||
*/
|
||||
if (drv->trans->hw_rev == 0)
|
||||
rev_step[0] = 'B';
|
||||
|
||||
snprintf(drv->firmware_name, sizeof(drv->firmware_name),
|
||||
"%s%s-%s.ucode", name_pre, rev_step, tag);
|
||||
}
|
||||
@ -926,6 +903,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
IWL_UCODE_REGULAR_USNIFFER,
|
||||
tlv_len);
|
||||
break;
|
||||
case IWL_UCODE_TLV_SDIO_ADMA_ADDR:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
drv->fw.sdio_adma_addr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||
break;
|
||||
@ -1082,7 +1065,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
u32 api_ver;
|
||||
int i;
|
||||
bool load_module = false;
|
||||
u32 hw_rev = drv->trans->hw_rev;
|
||||
|
||||
fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
|
||||
fw->ucode_capa.standard_phy_calibration_size =
|
||||
@ -1275,50 +1257,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
op->name, err);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* We may have loaded the wrong FW file in 8000 HW family if it is an
|
||||
* A-step card, and if drv->trans->hw_rev wasn't properly read when
|
||||
* the FW file had been loaded. (This might happen in SDIO.) In such a
|
||||
* case - unload and reload the correct file.
|
||||
*
|
||||
* TODO:
|
||||
* Once there is only one supported step for 8000 family - delete this!
|
||||
*/
|
||||
if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
|
||||
CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP &&
|
||||
drv->trans->hw_rev != hw_rev) {
|
||||
char firmware_name[32];
|
||||
|
||||
/* Free previous FW resources */
|
||||
if (drv->op_mode)
|
||||
_iwl_op_mode_stop(drv);
|
||||
iwl_dealloc_ucode(drv);
|
||||
|
||||
/* Build name of correct-step FW */
|
||||
snprintf(firmware_name, sizeof(firmware_name),
|
||||
strrchr(drv->firmware_name, '-'));
|
||||
snprintf(drv->firmware_name, sizeof(drv->firmware_name),
|
||||
"%s%s", drv->cfg->fw_name_pre, firmware_name);
|
||||
|
||||
/* Clear data before loading correct FW */
|
||||
list_del(&drv->list);
|
||||
|
||||
/* Request correct FW file this time */
|
||||
IWL_DEBUG_INFO(drv, "attempting to load A-step FW %s\n",
|
||||
drv->firmware_name);
|
||||
err = request_firmware(&ucode_raw, drv->firmware_name,
|
||||
drv->trans->dev);
|
||||
if (err) {
|
||||
IWL_ERR(drv, "Failed swapping FW!\n");
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
/* Redo callback function - this time with right FW */
|
||||
iwl_req_fw_callback(ucode_raw, context);
|
||||
}
|
||||
|
||||
kfree(pieces);
|
||||
return;
|
||||
|
||||
try_again:
|
||||
@ -1430,6 +1368,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
|
||||
.bt_coex_active = true,
|
||||
.power_level = IWL_POWER_INDEX_1,
|
||||
.wd_disable = true,
|
||||
.d0i3_disable = true,
|
||||
#ifndef CONFIG_IWLWIFI_UAPSD
|
||||
.uapsd_disable = true,
|
||||
#endif /* CONFIG_IWLWIFI_UAPSD */
|
||||
@ -1492,7 +1431,7 @@ static int __init iwl_drv_init(void)
|
||||
for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++)
|
||||
INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv);
|
||||
|
||||
pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
pr_info(DRV_DESCRIPTION "\n");
|
||||
pr_info(DRV_COPYRIGHT "\n");
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
@ -1546,6 +1485,10 @@ MODULE_PARM_DESC(wd_disable,
|
||||
module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(nvm_file, "NVM file name");
|
||||
|
||||
module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable,
|
||||
bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
|
||||
|
||||
module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
|
||||
bool, S_IRUGO);
|
||||
#ifdef CONFIG_IWLWIFI_UAPSD
|
||||
|
@ -68,7 +68,6 @@
|
||||
|
||||
/* for all modules */
|
||||
#define DRV_NAME "iwlwifi"
|
||||
#define IWLWIFI_VERSION "in-tree:"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
|
@ -71,7 +71,6 @@
|
||||
|
||||
/**
|
||||
* enum iwl_fw_error_dump_type - types of data in the dump file
|
||||
* @IWL_FW_ERROR_DUMP_SRAM:
|
||||
* @IWL_FW_ERROR_DUMP_CSR: Control Status Registers - from offset 0
|
||||
* @IWL_FW_ERROR_DUMP_RXF:
|
||||
* @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
|
||||
@ -82,9 +81,10 @@
|
||||
* @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several
|
||||
* sections like this in a single file.
|
||||
* @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
|
||||
* @IWL_FW_ERROR_DUMP_MEM: chunk of memory
|
||||
*/
|
||||
enum iwl_fw_error_dump_type {
|
||||
IWL_FW_ERROR_DUMP_SRAM = 0,
|
||||
/* 0 is deprecated */
|
||||
IWL_FW_ERROR_DUMP_CSR = 1,
|
||||
IWL_FW_ERROR_DUMP_RXF = 2,
|
||||
IWL_FW_ERROR_DUMP_TXCMD = 3,
|
||||
@ -93,6 +93,7 @@ enum iwl_fw_error_dump_type {
|
||||
IWL_FW_ERROR_DUMP_PRPH = 6,
|
||||
IWL_FW_ERROR_DUMP_TXF = 7,
|
||||
IWL_FW_ERROR_DUMP_FH_REGS = 8,
|
||||
IWL_FW_ERROR_DUMP_MEM = 9,
|
||||
|
||||
IWL_FW_ERROR_DUMP_MAX,
|
||||
};
|
||||
@ -180,6 +181,23 @@ struct iwl_fw_error_dump_prph {
|
||||
__le32 data[];
|
||||
};
|
||||
|
||||
enum iwl_fw_error_dump_mem_type {
|
||||
IWL_FW_ERROR_DUMP_MEM_SRAM,
|
||||
IWL_FW_ERROR_DUMP_MEM_SMEM,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_mem - chunk of memory
|
||||
* @type: %enum iwl_fw_error_dump_mem_type
|
||||
* @offset: the offset from which the memory was read
|
||||
* @data: the content of the memory
|
||||
*/
|
||||
struct iwl_fw_error_dump_mem {
|
||||
__le32 type;
|
||||
__le32 offset;
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* iwl_fw_error_next_data - advance fw error dump data pointer
|
||||
* @data: previous data block
|
||||
|
@ -132,6 +132,7 @@ enum iwl_ucode_tlv_type {
|
||||
IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
|
||||
IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
|
||||
IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
|
||||
IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
|
||||
IWL_UCODE_TLV_FW_DBG_DEST = 38,
|
||||
IWL_UCODE_TLV_FW_DBG_CONF = 39,
|
||||
};
|
||||
|
@ -152,6 +152,8 @@ struct iwl_fw_cscheme_list {
|
||||
* @mvm_fw: indicates this is MVM firmware
|
||||
* @cipher_scheme: optional external cipher scheme.
|
||||
* @human_readable: human readable version
|
||||
* @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
|
||||
* we get the ALIVE from the uCode
|
||||
* @dbg_dest_tlv: points to the destination TLV for debug
|
||||
* @dbg_conf_tlv: array of pointers to configuration TLVs for debug
|
||||
* @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
|
||||
@ -181,6 +183,8 @@ struct iwl_fw {
|
||||
struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
|
||||
u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
|
||||
|
||||
u32 sdio_adma_addr;
|
||||
|
||||
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_MAX];
|
||||
|
@ -103,6 +103,7 @@ enum iwl_disable_11n {
|
||||
* @power_level: power level, default = 1
|
||||
* @debug_level: levels are IWL_DL_*
|
||||
* @ant_coupling: antenna coupling in dB, default = 0
|
||||
* @d0i3_disable: disable d0i3, default = 1,
|
||||
* @fw_monitor: allow to use firmware monitor
|
||||
*/
|
||||
struct iwl_mod_params {
|
||||
@ -121,6 +122,7 @@ struct iwl_mod_params {
|
||||
int ant_coupling;
|
||||
char *nvm_file;
|
||||
bool uapsd_disable;
|
||||
bool d0i3_disable;
|
||||
bool fw_monitor;
|
||||
};
|
||||
|
||||
|
@ -468,6 +468,8 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
|
||||
data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
|
||||
data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
|
||||
data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
|
||||
data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(radio_cfg);
|
||||
data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
|
||||
}
|
||||
|
||||
static void iwl_set_hw_address(const struct iwl_cfg *cfg,
|
||||
@ -592,6 +594,10 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
|
||||
radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
|
||||
iwl_set_radio_cfg(cfg, data, radio_cfg);
|
||||
if (data->valid_tx_ant)
|
||||
tx_chains &= data->valid_tx_ant;
|
||||
if (data->valid_rx_ant)
|
||||
rx_chains &= data->valid_rx_ant;
|
||||
|
||||
sku = iwl_get_sku(cfg, nvm_sw);
|
||||
data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
|
||||
|
@ -99,6 +99,7 @@
|
||||
|
||||
#define APMG_PCIDEV_STT_VAL_PERSIST_DIS (0x00000200)
|
||||
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
|
||||
#define APMG_PCIDEV_STT_VAL_WAKE_ME (0x00004000)
|
||||
|
||||
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
|
||||
|
||||
@ -365,11 +366,15 @@ enum secure_load_status_reg {
|
||||
#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
|
||||
|
||||
/* FW monitor */
|
||||
#define MON_BUFF_SAMPLE_CTL (0xa03c00)
|
||||
#define MON_BUFF_BASE_ADDR (0xa03c3c)
|
||||
#define MON_BUFF_END_ADDR (0xa03c40)
|
||||
#define MON_BUFF_WRPTR (0xa03c44)
|
||||
#define MON_BUFF_CYCLE_CNT (0xa03c48)
|
||||
|
||||
#define DBGC_IN_SAMPLE (0xa03c00)
|
||||
#define DBGC_OUT_CTRL (0xa03c0c)
|
||||
|
||||
/* FW chicken bits */
|
||||
#define LMPM_CHICK 0xA01FF8
|
||||
enum {
|
||||
|
@ -382,6 +382,8 @@ enum iwl_trans_status {
|
||||
* are considered stuck and will trigger device restart
|
||||
* @command_names: array of command names, must be 256 entries
|
||||
* (one for each command); for debugging only
|
||||
* @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
|
||||
* we get the ALIVE from the uCode
|
||||
*/
|
||||
struct iwl_trans_config {
|
||||
struct iwl_op_mode *op_mode;
|
||||
@ -396,6 +398,8 @@ struct iwl_trans_config {
|
||||
bool scd_set_active;
|
||||
unsigned int queue_watchdog_timeout;
|
||||
const char *const *command_names;
|
||||
|
||||
u32 sdio_adma_addr;
|
||||
};
|
||||
|
||||
struct iwl_trans_dump_data {
|
||||
@ -551,6 +555,21 @@ enum iwl_trans_state {
|
||||
IWL_TRANS_FW_ALIVE = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_d0i3_mode - d0i3 mode
|
||||
*
|
||||
* @IWL_D0I3_MODE_OFF - d0i3 is disabled
|
||||
* @IWL_D0I3_MODE_ON_IDLE - enter d0i3 when device is idle
|
||||
* (e.g. no active references)
|
||||
* @IWL_D0I3_MODE_ON_SUSPEND - enter d0i3 only on suspend
|
||||
* (in case of 'any' trigger)
|
||||
*/
|
||||
enum iwl_d0i3_mode {
|
||||
IWL_D0I3_MODE_OFF = 0,
|
||||
IWL_D0I3_MODE_ON_IDLE,
|
||||
IWL_D0I3_MODE_ON_SUSPEND,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_trans - transport common data
|
||||
*
|
||||
@ -612,6 +631,8 @@ struct iwl_trans {
|
||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
|
||||
u8 dbg_dest_reg_num;
|
||||
|
||||
enum iwl_d0i3_mode d0i3_mode;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
char trans_specific[0] __aligned(sizeof(void *));
|
||||
|
@ -989,7 +989,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_bt_iterator_data *data = _data;
|
||||
struct iwl_mvm *mvm = data->mvm;
|
||||
|
||||
@ -1025,7 +1025,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
|
||||
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
enum ieee80211_rssi_event rssi_event)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_bt_iterator_data data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
|
@ -1034,7 +1034,7 @@ int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
|
||||
static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_bt_iterator_data *data = _data;
|
||||
struct iwl_mvm *mvm = data->mvm;
|
||||
|
||||
@ -1070,7 +1070,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
|
||||
void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
enum ieee80211_rssi_event rssi_event)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_bt_iterator_data data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
|
@ -102,5 +102,33 @@
|
||||
#define IWL_MVM_QUOTA_THRESHOLD 8
|
||||
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
|
||||
#define IWL_MVM_RS_DISABLE_MIMO 0
|
||||
#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
|
||||
#define IWL_MVM_RS_LEGACY_RETRIES_PER_RATE 1
|
||||
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
|
||||
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
|
||||
#define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES 3
|
||||
#define IWL_MVM_RS_INITIAL_SISO_NUM_RATES 3
|
||||
#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 16
|
||||
#define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16
|
||||
#define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES 3
|
||||
#define IWL_MVM_RS_SECONDARY_SISO_RETRIES 1
|
||||
#define IWL_MVM_RS_RATE_MIN_FAILURE_TH 3
|
||||
#define IWL_MVM_RS_RATE_MIN_SUCCESS_TH 8
|
||||
#define IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */
|
||||
#define IWL_MVM_RS_IDLE_TIMEOUT 5 /* Seconds */
|
||||
#define IWL_MVM_RS_MISSED_RATE_MAX 15
|
||||
#define IWL_MVM_RS_LEGACY_FAILURE_LIMIT 160
|
||||
#define IWL_MVM_RS_LEGACY_SUCCESS_LIMIT 480
|
||||
#define IWL_MVM_RS_LEGACY_TABLE_COUNT 160
|
||||
#define IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT 400
|
||||
#define IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT 4500
|
||||
#define IWL_MVM_RS_NON_LEGACY_TABLE_COUNT 1500
|
||||
#define IWL_MVM_RS_SR_FORCE_DECREASE 15 /* 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_DISABLE_START 3
|
||||
#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
|
||||
|
||||
#endif /* __MVM_CONSTANTS_H */
|
||||
|
@ -793,7 +793,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *ap_sta)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
|
||||
|
||||
/* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
|
||||
|
||||
@ -1137,12 +1137,43 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_notification_wait wait_d3;
|
||||
static const u8 d3_notif[] = { D3_CONFIG_CMD };
|
||||
int ret;
|
||||
|
||||
iwl_init_notification_wait(&mvm->notif_wait, &wait_d3,
|
||||
d3_notif, ARRAY_SIZE(d3_notif),
|
||||
NULL, NULL);
|
||||
|
||||
ret = iwl_mvm_enter_d0i3(mvm->hw->priv);
|
||||
if (ret)
|
||||
goto remove_notif;
|
||||
|
||||
ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ);
|
||||
WARN_ON_ONCE(ret);
|
||||
return ret;
|
||||
|
||||
remove_notif:
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_d3);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
iwl_trans_suspend(mvm->trans);
|
||||
if (iwl_mvm_is_d0i3_supported(mvm)) {
|
||||
if (wowlan->any) {
|
||||
/* 'any' trigger means d0i3 usage */
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
|
||||
int ret = iwl_mvm_enter_d0i3_sync(mvm);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->d0i3_suspend_mutex);
|
||||
__set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
@ -1626,7 +1657,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
|
||||
if (IS_ERR_OR_NULL(ap_sta))
|
||||
goto out_free;
|
||||
|
||||
mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
|
||||
mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
u16 seq = status.qos_seq_ctr[i];
|
||||
/* firmware stores last-used value, we store next value */
|
||||
@ -1876,8 +1907,20 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
|
||||
|
||||
iwl_trans_resume(mvm->trans);
|
||||
|
||||
if (iwl_mvm_is_d0i3_supported(mvm))
|
||||
if (mvm->hw->wiphy->wowlan_config->any) {
|
||||
/* 'any' trigger means d0i3 usage */
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
|
||||
int ret = iwl_mvm_exit_d0i3(hw->priv);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* d0i3 exit will be deferred until reconfig_complete.
|
||||
* make sure there we are out of d0i3.
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __iwl_mvm_resume(mvm, false);
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (!IS_ERR_OR_NULL(sta)) {
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
pos += scnprintf(buf+pos, bufsz-pos,
|
||||
"ap_sta_id %d - reduced Tx power %d\n",
|
||||
|
@ -933,7 +933,7 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
|
||||
return -EINVAL;
|
||||
if (scan_rx_ant > ANT_ABC)
|
||||
return -EINVAL;
|
||||
if (scan_rx_ant & ~mvm->fw->valid_rx_ant)
|
||||
if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
|
||||
return -EINVAL;
|
||||
|
||||
if (mvm->scan_rx_ant != scan_rx_ant) {
|
||||
@ -945,6 +945,56 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
enum iwl_fw_dbg_conf conf;
|
||||
char buf[8];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
int pos = 0;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
conf = mvm->fw_dbg_conf;
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int ret, conf_id;
|
||||
|
||||
ret = kstrtoint(buf, 0, &conf_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (WARN_ON(conf_id >= FW_DBG_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = iwl_mvm_start_fw_dbg_conf(mvm, conf_id);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_mvm_fw_dbg_collect(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
|
||||
@ -1459,6 +1509,8 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
|
||||
@ -1500,6 +1552,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
||||
S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
|
||||
|
@ -653,8 +653,11 @@ enum iwl_scan_channel_flags {
|
||||
};
|
||||
|
||||
/* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
|
||||
* @flags: enum iwl_scan_channel_flgs
|
||||
* @non_ebs_ratio: how many regular scan iteration before EBS
|
||||
* @flags: enum iwl_scan_channel_flags
|
||||
* @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is
|
||||
* involved.
|
||||
* 1 - EBS is disabled.
|
||||
* 2 - every second scan will be full scan(and so on).
|
||||
*/
|
||||
struct iwl_scan_channel_opt {
|
||||
__le16 flags;
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */
|
||||
#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-eeprom-parse.h"
|
||||
|
||||
#include "mvm.h"
|
||||
@ -269,7 +270,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
|
||||
enum iwl_ucode_type ucode_type = mvm->cur_ucode;
|
||||
|
||||
/* Set parameters */
|
||||
phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
|
||||
phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
|
||||
phy_cfg_cmd.calib_control.event_trigger =
|
||||
mvm->fw->default_calib[ucode_type].event_trigger;
|
||||
phy_cfg_cmd.calib_control.flow_trigger =
|
||||
@ -346,7 +347,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
mvm->calibrating = true;
|
||||
|
||||
/* Send TX valid antennas before triggering calibrations */
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
@ -399,8 +400,26 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm,
|
||||
enum iwl_fw_dbg_conf conf_id)
|
||||
void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
|
||||
{
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* stop recording */
|
||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
} else {
|
||||
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
|
||||
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
|
||||
}
|
||||
|
||||
iwl_mvm_fw_error_dump(mvm);
|
||||
|
||||
/* start recording again */
|
||||
WARN_ON_ONCE(mvm->fw->dbg_dest_tlv &&
|
||||
iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
|
||||
}
|
||||
|
||||
int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
|
||||
{
|
||||
u8 *ptr;
|
||||
int ret;
|
||||
@ -489,7 +508,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
mvm->fw_dbg_conf = FW_DBG_INVALID;
|
||||
iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
@ -584,7 +603,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
@ -975,7 +975,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
|
||||
beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags);
|
||||
|
||||
mvm->mgmt_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
|
||||
mvm->mgmt_last_antenna_idx);
|
||||
|
||||
beacon_cmd.tx.rate_n_flags =
|
||||
|
@ -85,6 +85,7 @@
|
||||
#include "testmode.h"
|
||||
#include "iwl-fw-error-dump.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-csr.h"
|
||||
|
||||
static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
|
||||
{
|
||||
@ -105,7 +106,7 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
|
||||
|
||||
static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
|
||||
{
|
||||
.num_different_channels = 1,
|
||||
.num_different_channels = 2,
|
||||
.max_interfaces = 3,
|
||||
.limits = iwl_mvm_limits,
|
||||
.n_limits = ARRAY_SIZE(iwl_mvm_limits),
|
||||
@ -377,6 +378,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
|
||||
hw->wiphy->max_remain_on_channel_duration = 10000;
|
||||
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
|
||||
/* we can compensate an offset of up to 3 channels = 15 MHz */
|
||||
hw->wiphy->max_adj_channel_rssi_comp = 3 * 5;
|
||||
|
||||
/* Extract MAC address */
|
||||
memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
|
||||
@ -459,15 +462,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
device_can_wakeup(mvm->trans->dev)) {
|
||||
mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
|
||||
hw->wiphy->wowlan = &mvm->wowlan;
|
||||
} else if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
}
|
||||
|
||||
if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
mvm->trans->ops->d3_suspend &&
|
||||
mvm->trans->ops->d3_resume &&
|
||||
device_can_wakeup(mvm->trans->dev)) {
|
||||
mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
|
||||
WIPHY_WOWLAN_DISCONNECT |
|
||||
WIPHY_WOWLAN_EAP_IDENTITY_REQ |
|
||||
WIPHY_WOWLAN_RFKILL_RELEASE |
|
||||
WIPHY_WOWLAN_NET_DETECT;
|
||||
mvm->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT |
|
||||
WIPHY_WOWLAN_DISCONNECT |
|
||||
WIPHY_WOWLAN_EAP_IDENTITY_REQ |
|
||||
WIPHY_WOWLAN_RFKILL_RELEASE |
|
||||
WIPHY_WOWLAN_NET_DETECT;
|
||||
if (!iwlwifi_mod_params.sw_crypto)
|
||||
mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
|
||||
WIPHY_WOWLAN_GTK_REKEY_FAILURE |
|
||||
@ -766,22 +771,37 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct iwl_fw_error_dump_data *dump_data;
|
||||
struct iwl_fw_error_dump_info *dump_info;
|
||||
struct iwl_fw_error_dump_mem *dump_mem;
|
||||
struct iwl_mvm_dump_ptrs *fw_error_dump;
|
||||
const struct fw_img *img;
|
||||
u32 sram_len, sram_ofs;
|
||||
u32 file_len, rxf_len;
|
||||
unsigned long flags;
|
||||
int reg_val;
|
||||
u32 smem_len = mvm->cfg->smem_len;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* W/A for 8000 HW family A-step */
|
||||
if (mvm->cfg->smem_len &&
|
||||
mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
|
||||
CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
|
||||
smem_len = 0x38000;
|
||||
|
||||
fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
|
||||
if (!fw_error_dump)
|
||||
return;
|
||||
|
||||
img = &mvm->fw->img[mvm->cur_ucode];
|
||||
sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
|
||||
sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
|
||||
/* SRAM - include stack CCM if driver knows the values for it */
|
||||
if (!mvm->cfg->dccm_offset || !mvm->cfg->dccm_len) {
|
||||
const struct fw_img *img;
|
||||
|
||||
img = &mvm->fw->img[mvm->cur_ucode];
|
||||
sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
|
||||
sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
|
||||
} else {
|
||||
sram_ofs = mvm->cfg->dccm_offset;
|
||||
sram_len = mvm->cfg->dccm_len;
|
||||
}
|
||||
|
||||
/* reading buffer size */
|
||||
reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
|
||||
@ -792,10 +812,14 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
|
||||
file_len = sizeof(*dump_file) +
|
||||
sizeof(*dump_data) * 3 +
|
||||
sram_len +
|
||||
sram_len + sizeof(*dump_mem) +
|
||||
rxf_len +
|
||||
sizeof(*dump_info);
|
||||
|
||||
/* Make room for the SMEM, if it exists */
|
||||
if (smem_len)
|
||||
file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
|
||||
|
||||
dump_file = vzalloc(file_len);
|
||||
if (!dump_file) {
|
||||
kfree(fw_error_dump);
|
||||
@ -814,6 +838,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
|
||||
cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
|
||||
cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
|
||||
dump_info->hw_step = cpu_to_le32(CSR_HW_REV_STEP(mvm->trans->hw_rev));
|
||||
memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
|
||||
sizeof(dump_info->fw_human_readable));
|
||||
strncpy(dump_info->dev_human_readable, mvm->cfg->name,
|
||||
@ -840,11 +865,25 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
}
|
||||
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
|
||||
dump_data->len = cpu_to_le32(sram_len);
|
||||
iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
|
||||
dump_mem->offset = cpu_to_le32(sram_ofs);
|
||||
iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_mem->data,
|
||||
sram_len);
|
||||
|
||||
if (smem_len) {
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SMEM);
|
||||
dump_mem->offset = cpu_to_le32(mvm->cfg->smem_offset);
|
||||
iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->smem_offset,
|
||||
dump_mem->data, smem_len);
|
||||
}
|
||||
|
||||
fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
|
||||
fw_error_dump->op_mode_len = file_len;
|
||||
if (fw_error_dump->trans_ptr)
|
||||
@ -864,6 +903,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status))
|
||||
iwl_mvm_fw_error_dump(mvm);
|
||||
|
||||
/* cleanup all stale references (scan, roc), but keep the
|
||||
* ucode_down ref until reconfig is complete
|
||||
*/
|
||||
iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
iwl_trans_stop_device(mvm->trans);
|
||||
|
||||
mvm->scan_status = IWL_MVM_SCAN_NONE;
|
||||
@ -893,10 +937,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
|
||||
ieee80211_wake_queues(mvm->hw);
|
||||
|
||||
/* cleanup all stale references (scan, roc), but keep the
|
||||
* ucode_down ref until reconfig is complete */
|
||||
iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
/* clear any stale d0i3 state */
|
||||
clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
|
||||
@ -933,6 +973,19 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
/* Some hw restart cleanups must not hold the mutex */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/*
|
||||
* Make sure we are out of d0i3. This is needed
|
||||
* to make sure the reference accounting is correct
|
||||
* (and there is no stale d0i3_exit_work).
|
||||
*/
|
||||
wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3,
|
||||
&mvm->status),
|
||||
HZ);
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
@ -982,6 +1035,13 @@ static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
|
||||
IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
|
||||
_iwl_mvm_exit_d0i3(mvm);
|
||||
}
|
||||
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND)
|
||||
if (!wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3,
|
||||
&mvm->status),
|
||||
HZ))
|
||||
WARN_ONCE(1, "D0i3 exit on resume timed out\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2088,7 +2148,7 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/*
|
||||
* This is called before mac80211 does RCU synchronisation,
|
||||
@ -3103,7 +3163,7 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
|
||||
bool set)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
if (!mvm_sta || !mvm_sta->vif) {
|
||||
IWL_ERR(mvm, "Station is not associated to a vif\n");
|
||||
|
@ -850,6 +850,8 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
|
||||
static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return mvm->trans->cfg->d0i3 &&
|
||||
mvm->trans->d0i3_mode != IWL_D0I3_MODE_OFF &&
|
||||
!iwlwifi_mod_params.d0i3_disable &&
|
||||
(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
|
||||
}
|
||||
|
||||
@ -937,6 +939,33 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
|
||||
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
|
||||
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
|
||||
|
||||
static inline u8 iwl_mvm_get_valid_tx_ant(struct iwl_mvm *mvm)
|
||||
{
|
||||
return mvm->nvm_data && mvm->nvm_data->valid_tx_ant ?
|
||||
mvm->fw->valid_tx_ant & mvm->nvm_data->valid_tx_ant :
|
||||
mvm->fw->valid_tx_ant;
|
||||
}
|
||||
|
||||
static inline u8 iwl_mvm_get_valid_rx_ant(struct iwl_mvm *mvm)
|
||||
{
|
||||
return mvm->nvm_data && mvm->nvm_data->valid_rx_ant ?
|
||||
mvm->fw->valid_rx_ant & mvm->nvm_data->valid_rx_ant :
|
||||
mvm->fw->valid_rx_ant;
|
||||
}
|
||||
|
||||
static inline u32 iwl_mvm_get_phy_config(struct iwl_mvm *mvm)
|
||||
{
|
||||
u32 phy_config = ~(FW_PHY_CFG_TX_CHAIN |
|
||||
FW_PHY_CFG_RX_CHAIN);
|
||||
u32 valid_rx_ant = iwl_mvm_get_valid_rx_ant(mvm);
|
||||
u32 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
|
||||
|
||||
phy_config |= valid_tx_ant << FW_PHY_CFG_TX_CHAIN_POS |
|
||||
valid_rx_ant << FW_PHY_CFG_RX_CHAIN_POS;
|
||||
|
||||
return mvm->fw->phy_config & phy_config;
|
||||
}
|
||||
|
||||
int iwl_mvm_up(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
|
||||
|
||||
@ -1159,6 +1188,8 @@ void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
|
||||
int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
|
||||
bool iwl_mvm_ref_taken(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
|
||||
int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode);
|
||||
int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode);
|
||||
int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
|
||||
|
||||
/* BT Coex */
|
||||
@ -1344,4 +1375,7 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
|
||||
void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
|
||||
|
||||
int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id);
|
||||
void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm);
|
||||
|
||||
#endif /* __IWL_MVM_H__ */
|
||||
|
@ -84,15 +84,8 @@
|
||||
#include "time-event.h"
|
||||
#include "iwl-fw-error-dump.h"
|
||||
|
||||
/*
|
||||
* module name, copyright, version, etc.
|
||||
*/
|
||||
#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
|
||||
|
||||
#define DRV_VERSION IWLWIFI_VERSION
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@ -146,13 +139,14 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
|
||||
u32 reg_val = 0;
|
||||
u32 phy_config = iwl_mvm_get_phy_config(mvm);
|
||||
|
||||
radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >>
|
||||
FW_PHY_CFG_RADIO_TYPE_POS;
|
||||
radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >>
|
||||
FW_PHY_CFG_RADIO_STEP_POS;
|
||||
radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >>
|
||||
FW_PHY_CFG_RADIO_DASH_POS;
|
||||
radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
|
||||
FW_PHY_CFG_RADIO_TYPE_POS;
|
||||
radio_cfg_step = (phy_config & FW_PHY_CFG_RADIO_STEP) >>
|
||||
FW_PHY_CFG_RADIO_STEP_POS;
|
||||
radio_cfg_dash = (phy_config & FW_PHY_CFG_RADIO_DASH) >>
|
||||
FW_PHY_CFG_RADIO_DASH_POS;
|
||||
|
||||
/* SKU control */
|
||||
reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
|
||||
@ -487,6 +481,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
|
||||
trans_cfg.scd_set_active = true;
|
||||
|
||||
trans_cfg.sdio_adma_addr = fw->sdio_adma_addr;
|
||||
|
||||
snprintf(mvm->hw->wiphy->fw_version,
|
||||
sizeof(mvm->hw->wiphy->fw_version),
|
||||
"%s", fw->fw_version);
|
||||
@ -517,10 +513,15 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
min_backoff = calc_min_backoff(trans, cfg);
|
||||
iwl_mvm_tt_initialize(mvm, min_backoff);
|
||||
/* set the nvm_file_name according to priority */
|
||||
if (iwlwifi_mod_params.nvm_file)
|
||||
if (iwlwifi_mod_params.nvm_file) {
|
||||
mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
|
||||
else
|
||||
mvm->nvm_file_name = mvm->cfg->default_nvm_file;
|
||||
} else {
|
||||
if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
|
||||
(CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
|
||||
mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A;
|
||||
else
|
||||
mvm->nvm_file_name = mvm->cfg->default_nvm_file;
|
||||
}
|
||||
|
||||
if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name,
|
||||
"not allowing power-up and not having nvm_file\n"))
|
||||
@ -1031,7 +1032,8 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
|
||||
|
||||
int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
|
||||
@ -1047,6 +1049,7 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
|
||||
};
|
||||
struct iwl_d3_manager_config d3_cfg_cmd = {
|
||||
.min_sleep_time = cpu_to_le32(1000),
|
||||
.wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
|
||||
};
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
|
||||
@ -1146,7 +1149,7 @@ void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
|
||||
|
||||
if (mvm->d0i3_offloading && qos_seq) {
|
||||
/* update qos seq numbers if offloading was enabled */
|
||||
mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv;
|
||||
mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
u16 seq = le16_to_cpu(qos_seq[i]);
|
||||
/* firmware stores last-used one, we store next one */
|
||||
@ -1245,7 +1248,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
||||
int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
|
||||
|
@ -176,7 +176,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
|
||||
cmd->rxchain_info |= cpu_to_le32(active_cnt <<
|
||||
PHY_RX_CHAIN_MIMO_CNT_POS);
|
||||
|
||||
cmd->txchain_info = cpu_to_le32(mvm->fw->valid_tx_ant);
|
||||
cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -42,25 +42,12 @@
|
||||
|
||||
#define RS_NAME "iwl-mvm-rs"
|
||||
|
||||
#define NUM_TRY_BEFORE_ANT_TOGGLE 1
|
||||
#define RS_LEGACY_RETRIES_PER_RATE 1
|
||||
#define RS_HT_VHT_RETRIES_PER_RATE 2
|
||||
#define RS_HT_VHT_RETRIES_PER_RATE_TW 1
|
||||
#define RS_INITIAL_MIMO_NUM_RATES 3
|
||||
#define RS_INITIAL_SISO_NUM_RATES 3
|
||||
#define RS_INITIAL_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
|
||||
#define RS_SECONDARY_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
|
||||
#define RS_SECONDARY_SISO_NUM_RATES 3
|
||||
#define RS_SECONDARY_SISO_RETRIES 1
|
||||
|
||||
#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
|
||||
#define IWL_RATE_MIN_FAILURE_TH 3 /* min failures to calc tpt */
|
||||
#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
|
||||
|
||||
/* max allowed rate miss before sync LQ cmd */
|
||||
#define IWL_MISSED_RATE_MAX 15
|
||||
#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
|
||||
#define RS_IDLE_TIMEOUT (5*HZ)
|
||||
/* Calculations of success ratio are done in fixed point where 12800 is 100%.
|
||||
* Use this macro when dealing with thresholds consts set as a percentage
|
||||
*/
|
||||
#define RS_PERCENT(x) (128 * x)
|
||||
|
||||
static u8 rs_ht_to_legacy[] = {
|
||||
[IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
|
||||
@ -173,7 +160,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
if (sta->smps_mode == IEEE80211_SMPS_STATIC)
|
||||
return false;
|
||||
|
||||
if (num_of_ant(mvm->fw->valid_tx_ant) < 2)
|
||||
if (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) < 2)
|
||||
return false;
|
||||
|
||||
if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
|
||||
@ -613,7 +600,8 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
|
||||
* at this rate. window->data contains the bitmask of successful
|
||||
* packets.
|
||||
*/
|
||||
static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
|
||||
static int _rs_collect_tx_data(struct iwl_mvm *mvm,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
int scale_index, int attempts, int successes,
|
||||
struct iwl_rate_scale_data *window)
|
||||
{
|
||||
@ -668,8 +656,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
|
||||
fail_count = window->counter - window->success_counter;
|
||||
|
||||
/* Calculate average throughput, if we have enough history. */
|
||||
if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
|
||||
(window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
|
||||
if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) ||
|
||||
(window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH))
|
||||
window->average_tpt = (window->success_ratio * tpt + 64) / 128;
|
||||
else
|
||||
window->average_tpt = IWL_INVALID_VALUE;
|
||||
@ -677,7 +665,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
|
||||
static int rs_collect_tx_data(struct iwl_mvm *mvm,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
int scale_index, int attempts, int successes,
|
||||
u8 reduced_txp)
|
||||
@ -698,7 +687,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
|
||||
/* Select window for current tx bit rate */
|
||||
window = &(tbl->win[scale_index]);
|
||||
|
||||
ret = _rs_collect_tx_data(tbl, scale_index, attempts, successes,
|
||||
ret = _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
|
||||
window);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -707,7 +696,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
|
||||
return -EINVAL;
|
||||
|
||||
window = &tbl->tpc_win[reduced_txp];
|
||||
return _rs_collect_tx_data(tbl, scale_index, attempts, successes,
|
||||
return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
|
||||
window);
|
||||
}
|
||||
|
||||
@ -1004,7 +993,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
|
||||
}
|
||||
|
||||
if (num_of_ant(rate->ant) > 1)
|
||||
rate->ant = first_antenna(mvm->fw->valid_tx_ant);
|
||||
rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
|
||||
|
||||
/* Relevant in both switching to SISO or Legacy */
|
||||
rate->sgi = false;
|
||||
@ -1125,7 +1114,8 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
}
|
||||
|
||||
if (time_after(jiffies,
|
||||
(unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) {
|
||||
(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");
|
||||
@ -1158,7 +1148,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
* ... driver.
|
||||
*/
|
||||
lq_sta->missed_rate_counter++;
|
||||
if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
|
||||
if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
|
||||
lq_sta->missed_rate_counter = 0;
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Too many rates mismatch. Send sync LQ. rs_state %d\n",
|
||||
@ -1213,7 +1203,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
|
||||
ucode_rate = le32_to_cpu(table->rs_table[0]);
|
||||
rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
|
||||
rs_collect_tx_data(lq_sta, curr_tbl, rate.index,
|
||||
rs_collect_tx_data(mvm, lq_sta, curr_tbl, rate.index,
|
||||
info->status.ampdu_len,
|
||||
info->status.ampdu_ack_len,
|
||||
reduced_txp);
|
||||
@ -1249,7 +1239,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
else
|
||||
continue;
|
||||
|
||||
rs_collect_tx_data(lq_sta, tmp_tbl, rate.index, 1,
|
||||
rs_collect_tx_data(mvm, lq_sta, tmp_tbl, rate.index, 1,
|
||||
i < retries ? 0 : legacy_success,
|
||||
reduced_txp);
|
||||
}
|
||||
@ -1303,13 +1293,13 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
|
||||
IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
|
||||
lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
|
||||
if (is_legacy) {
|
||||
lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
|
||||
lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
|
||||
lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
|
||||
lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT;
|
||||
lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT;
|
||||
lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT;
|
||||
} else {
|
||||
lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
|
||||
lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
|
||||
lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
|
||||
lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT;
|
||||
lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT;
|
||||
lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT;
|
||||
}
|
||||
lq_sta->table_count = 0;
|
||||
lq_sta->total_failed = 0;
|
||||
@ -1318,6 +1308,13 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
|
||||
lq_sta->visited_columns = 0;
|
||||
}
|
||||
|
||||
static inline int rs_get_max_rate_from_mask(unsigned long rate_mask)
|
||||
{
|
||||
if (rate_mask)
|
||||
return find_last_bit(&rate_mask, BITS_PER_LONG);
|
||||
return IWL_RATE_INVALID;
|
||||
}
|
||||
|
||||
static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
|
||||
const struct rs_tx_column *column)
|
||||
{
|
||||
@ -1420,7 +1417,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
|
||||
u32 target_tpt;
|
||||
int rate_idx;
|
||||
|
||||
if (success_ratio > RS_SR_NO_DECREASE) {
|
||||
if (success_ratio > IWL_MVM_RS_SR_NO_DECREASE) {
|
||||
target_tpt = 100 * expected_current_tpt;
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n",
|
||||
@ -1488,7 +1485,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
|
||||
flush_interval_passed =
|
||||
time_after(jiffies,
|
||||
(unsigned long)(lq_sta->flush_timer +
|
||||
RS_STAY_IN_COLUMN_TIMEOUT));
|
||||
(IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * HZ)));
|
||||
|
||||
/*
|
||||
* Check if we should allow search for new modulation mode.
|
||||
@ -1567,7 +1564,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
||||
const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
|
||||
const struct rs_tx_column *next_col;
|
||||
allow_column_func_t allow_func;
|
||||
u8 valid_ants = mvm->fw->valid_tx_ant;
|
||||
u8 valid_ants = iwl_mvm_get_valid_tx_ant(mvm);
|
||||
const u16 *expected_tpt_tbl;
|
||||
u16 tpt, max_expected_tpt;
|
||||
|
||||
@ -1613,8 +1610,12 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
||||
continue;
|
||||
|
||||
max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
|
||||
if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID))
|
||||
if (max_rate == IWL_RATE_INVALID) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Skip column %d: no rate is allowed in this column\n",
|
||||
next_col_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
max_expected_tpt = expected_tpt_tbl[max_rate];
|
||||
if (tpt >= max_expected_tpt) {
|
||||
@ -1724,7 +1725,8 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
|
||||
{
|
||||
enum rs_action action = RS_ACTION_STAY;
|
||||
|
||||
if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
|
||||
if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) ||
|
||||
(current_tpt == 0)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Decrease rate because of low SR\n");
|
||||
return RS_ACTION_DOWNSCALE;
|
||||
@ -1783,7 +1785,7 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
|
||||
|
||||
out:
|
||||
if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
|
||||
if (sr >= RS_SR_NO_DECREASE) {
|
||||
if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"SR is above NO DECREASE. Avoid downscale\n");
|
||||
action = RS_ACTION_STAY;
|
||||
@ -1825,11 +1827,11 @@ static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,
|
||||
int *weaker, int *stronger)
|
||||
{
|
||||
*weaker = index + TPC_TX_POWER_STEP;
|
||||
*weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP;
|
||||
if (*weaker > TPC_MAX_REDUCTION)
|
||||
*weaker = TPC_INVALID;
|
||||
|
||||
*stronger = index - TPC_TX_POWER_STEP;
|
||||
*stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP;
|
||||
if (*stronger < 0)
|
||||
*stronger = TPC_INVALID;
|
||||
}
|
||||
@ -1885,7 +1887,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
/* Too many failures, increase txp */
|
||||
if (sr <= TPC_SR_FORCE_INCREASE || current_tpt == 0) {
|
||||
if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) ||
|
||||
current_tpt == 0) {
|
||||
IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n");
|
||||
return TPC_ACTION_NO_RESTIRCTION;
|
||||
}
|
||||
@ -1908,7 +1911,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
/* next, increase if needed */
|
||||
if (sr < TPC_SR_NO_INCREASE && strong != TPC_INVALID) {
|
||||
if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) &&
|
||||
strong != TPC_INVALID) {
|
||||
if (weak_tpt == IWL_INVALID_VALUE &&
|
||||
strong_tpt != IWL_INVALID_VALUE &&
|
||||
current_tpt < strong_tpt) {
|
||||
@ -1935,7 +1939,7 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct ieee80211_vif *vif = mvm_sta->vif;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
enum ieee80211_band band;
|
||||
@ -2044,7 +2048,7 @@ 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 = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_tid_data *tid_data;
|
||||
struct rs_rate *rate;
|
||||
|
||||
@ -2106,8 +2110,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
||||
* in current association (use new rate found above).
|
||||
*/
|
||||
fail_count = window->counter - window->success_counter;
|
||||
if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
|
||||
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
|
||||
if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) &&
|
||||
(window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"(%s: %d): Test Window: succ %d total %d\n",
|
||||
rs_pretty_lq_type(rate->type),
|
||||
@ -2385,7 +2389,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
|
||||
int i, nentries;
|
||||
s8 best_rssi = S8_MIN;
|
||||
u8 best_ant = ANT_NONE;
|
||||
u8 valid_tx_ant = mvm->fw->valid_tx_ant;
|
||||
u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
|
||||
const struct rs_init_rate_info *initial_rates;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {
|
||||
@ -2530,7 +2534,7 @@ 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 = (struct iwl_mvm_sta *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *sta_priv = 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;
|
||||
@ -2683,14 +2687,11 @@ 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;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
|
||||
struct ieee80211_supported_band *sband;
|
||||
unsigned long supp; /* must be unsigned long for for_each_set_bit */
|
||||
|
||||
sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
|
||||
lq_sta = &sta_priv->lq_sta;
|
||||
|
||||
/* clear all non-persistent lq data */
|
||||
memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
|
||||
|
||||
@ -2712,7 +2713,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
* previous packets? Need to have IEEE 802.1X auth succeed immediately
|
||||
* after assoc.. */
|
||||
|
||||
lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
|
||||
lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX;
|
||||
lq_sta->band = sband->band;
|
||||
/*
|
||||
* active legacy rates as per supported rates bitmap
|
||||
@ -2745,7 +2746,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
lq_sta->ldpc = true;
|
||||
|
||||
if (mvm->cfg->ht_params->stbc &&
|
||||
(num_of_ant(mvm->fw->valid_tx_ant) > 1) &&
|
||||
(num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
|
||||
(ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
|
||||
lq_sta->stbc = true;
|
||||
} else {
|
||||
@ -2757,7 +2758,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
lq_sta->ldpc = true;
|
||||
|
||||
if (mvm->cfg->ht_params->stbc &&
|
||||
(num_of_ant(mvm->fw->valid_tx_ant) > 1) &&
|
||||
(num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
|
||||
(vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
|
||||
lq_sta->stbc = true;
|
||||
}
|
||||
@ -2765,12 +2766,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
if (IWL_MVM_RS_DISABLE_MIMO)
|
||||
lq_sta->active_mimo2_rate = 0;
|
||||
|
||||
lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate,
|
||||
BITS_PER_LONG);
|
||||
lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate,
|
||||
BITS_PER_LONG);
|
||||
lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate,
|
||||
BITS_PER_LONG);
|
||||
lq_sta->max_legacy_rate_idx =
|
||||
rs_get_max_rate_from_mask(lq_sta->active_legacy_rate);
|
||||
lq_sta->max_siso_rate_idx =
|
||||
rs_get_max_rate_from_mask(lq_sta->active_siso_rate);
|
||||
lq_sta->max_mimo2_rate_idx =
|
||||
rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n",
|
||||
@ -2785,7 +2786,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
|
||||
/* These values will be overridden later */
|
||||
lq_sta->lq.single_stream_ant_msk =
|
||||
first_antenna(mvm->fw->valid_tx_ant);
|
||||
first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
|
||||
lq_sta->lq.dual_stream_ant_msk = ANT_AB;
|
||||
|
||||
/* as default allow aggregation for all tids */
|
||||
@ -2913,18 +2914,18 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
|
||||
memcpy(&rate, initial_rate, sizeof(rate));
|
||||
|
||||
valid_tx_ant = mvm->fw->valid_tx_ant;
|
||||
valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
|
||||
rate.stbc = rs_stbc_allow(mvm, sta, lq_sta);
|
||||
|
||||
if (is_siso(&rate)) {
|
||||
num_rates = RS_INITIAL_SISO_NUM_RATES;
|
||||
num_retries = RS_HT_VHT_RETRIES_PER_RATE;
|
||||
num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
|
||||
} else if (is_mimo(&rate)) {
|
||||
num_rates = RS_INITIAL_MIMO_NUM_RATES;
|
||||
num_retries = RS_HT_VHT_RETRIES_PER_RATE;
|
||||
num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
|
||||
} else {
|
||||
num_rates = RS_INITIAL_LEGACY_NUM_RATES;
|
||||
num_retries = RS_LEGACY_RETRIES_PER_RATE;
|
||||
num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
|
||||
toggle_ant = true;
|
||||
}
|
||||
|
||||
@ -2935,12 +2936,12 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
rs_get_lower_rate_down_column(lq_sta, &rate);
|
||||
|
||||
if (is_siso(&rate)) {
|
||||
num_rates = RS_SECONDARY_SISO_NUM_RATES;
|
||||
num_retries = RS_SECONDARY_SISO_RETRIES;
|
||||
num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES;
|
||||
lq_cmd->mimo_delim = index;
|
||||
} else if (is_legacy(&rate)) {
|
||||
num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
|
||||
num_retries = RS_LEGACY_RETRIES_PER_RATE;
|
||||
num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
|
||||
} else {
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
@ -2953,8 +2954,8 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
|
||||
rs_get_lower_rate_down_column(lq_sta, &rate);
|
||||
|
||||
num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
|
||||
num_retries = RS_LEGACY_RETRIES_PER_RATE;
|
||||
num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
|
||||
num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
|
||||
|
||||
rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
|
||||
num_rates, num_retries, valid_tx_ant,
|
||||
@ -2971,9 +2972,9 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
|
||||
lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
|
||||
lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START;
|
||||
lq_cmd->agg_time_limit =
|
||||
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
|
||||
cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT);
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
if (lq_sta->pers.dbg_fixed_rate) {
|
||||
@ -3167,9 +3168,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
||||
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
|
||||
lq_sta->pers.dbg_fixed_rate);
|
||||
desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
|
||||
(mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "",
|
||||
(mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "",
|
||||
(mvm->fw->valid_tx_ant & ANT_C) ? "ANT_C" : "");
|
||||
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
|
||||
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
|
||||
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
|
||||
desc += sprintf(buff+desc, "lq type %s\n",
|
||||
(is_legacy(rate)) ? "legacy" :
|
||||
is_vht(rate) ? "VHT" : "HT");
|
||||
|
@ -137,42 +137,10 @@ enum {
|
||||
|
||||
#define IWL_INVALID_VALUE -1
|
||||
|
||||
#define IWL_MIN_RSSI_VAL -100
|
||||
#define IWL_MAX_RSSI_VAL 0
|
||||
|
||||
/* These values specify how many Tx frame attempts before
|
||||
* searching for a new modulation mode */
|
||||
#define IWL_LEGACY_FAILURE_LIMIT 160
|
||||
#define IWL_LEGACY_SUCCESS_LIMIT 480
|
||||
#define IWL_LEGACY_TABLE_COUNT 160
|
||||
|
||||
#define IWL_NONE_LEGACY_FAILURE_LIMIT 400
|
||||
#define IWL_NONE_LEGACY_SUCCESS_LIMIT 4500
|
||||
#define IWL_NONE_LEGACY_TABLE_COUNT 1500
|
||||
|
||||
/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
|
||||
#define IWL_RS_GOOD_RATIO 12800 /* 100% */
|
||||
#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
|
||||
#define IWL_RATE_HIGH_TH 10880 /* 85% */
|
||||
#define IWL_RATE_INCREASE_TH 6400 /* 50% */
|
||||
#define RS_SR_FORCE_DECREASE 1920 /* 15% */
|
||||
#define RS_SR_NO_DECREASE 10880 /* 85% */
|
||||
|
||||
#define TPC_SR_FORCE_INCREASE 9600 /* 75% */
|
||||
#define TPC_SR_NO_INCREASE 10880 /* 85% */
|
||||
#define TPC_TX_POWER_STEP 3
|
||||
#define TPC_MAX_REDUCTION 15
|
||||
#define TPC_NO_REDUCTION 0
|
||||
#define TPC_INVALID 0xff
|
||||
|
||||
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
|
||||
#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
|
||||
#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
|
||||
|
||||
#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
|
||||
#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
|
||||
#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
|
||||
|
||||
#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
|
||||
#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
|
||||
#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
|
||||
@ -181,14 +149,7 @@ enum {
|
||||
|
||||
/* load per tid defines for A-MPDU activation */
|
||||
#define IWL_AGG_TPT_THREHOLD 0
|
||||
#define IWL_AGG_LOAD_THRESHOLD 10
|
||||
#define IWL_AGG_ALL_TID 0xff
|
||||
#define TID_QUEUE_CELL_SPACING 50 /*mS */
|
||||
#define TID_QUEUE_MAX_SIZE 20
|
||||
#define TID_ROUND_VALUE 5 /* mS */
|
||||
|
||||
#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
|
||||
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
|
||||
|
||||
enum iwl_table_type {
|
||||
LQ_NONE,
|
||||
|
@ -72,6 +72,8 @@
|
||||
|
||||
#define IWL_PLCP_QUIET_THRESH 1
|
||||
#define IWL_ACTIVE_QUIET_TIME 10
|
||||
#define IWL_DENSE_EBS_SCAN_RATIO 5
|
||||
#define IWL_SPARSE_EBS_SCAN_RATIO 1
|
||||
|
||||
struct iwl_mvm_scan_params {
|
||||
u32 max_out_time;
|
||||
@ -97,7 +99,7 @@ static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (mvm->scan_rx_ant != ANT_NONE)
|
||||
return mvm->scan_rx_ant;
|
||||
return mvm->fw->valid_rx_ant;
|
||||
return iwl_mvm_get_valid_rx_ant(mvm);
|
||||
}
|
||||
|
||||
static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
|
||||
@ -128,7 +130,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
|
||||
u32 tx_ant;
|
||||
|
||||
mvm->scan_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
|
||||
mvm->scan_last_antenna_idx);
|
||||
tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||
|
||||
@ -282,11 +284,11 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
bool *global_bound = data;
|
||||
int *global_cnt = data;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
|
||||
mvmvif->phy_ctxt->id < MAX_PHYS)
|
||||
*global_bound = true;
|
||||
*global_cnt += 1;
|
||||
}
|
||||
|
||||
static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
||||
@ -294,16 +296,16 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
||||
int n_ssids, u32 flags,
|
||||
struct iwl_mvm_scan_params *params)
|
||||
{
|
||||
bool global_bound = false;
|
||||
int global_cnt = 0;
|
||||
enum ieee80211_band band;
|
||||
u8 frag_passive_dwell = 0;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_scan_condition_iterator,
|
||||
&global_bound);
|
||||
&global_cnt);
|
||||
|
||||
if (!global_bound)
|
||||
if (!global_cnt)
|
||||
goto not_bound;
|
||||
|
||||
params->suspend_time = 30;
|
||||
@ -314,7 +316,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
||||
IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
|
||||
params->suspend_time = 105;
|
||||
params->max_out_time = 70;
|
||||
frag_passive_dwell = 20;
|
||||
/*
|
||||
* If there is more than one active interface make
|
||||
* passive scan more fragmented.
|
||||
*/
|
||||
frag_passive_dwell = (global_cnt < 2) ? 40 : 20;
|
||||
} else {
|
||||
params->suspend_time = 120;
|
||||
params->max_out_time = 120;
|
||||
@ -1296,10 +1302,14 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
|
||||
cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
cmd->channel_opt[0].non_ebs_ratio =
|
||||
cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
|
||||
cmd->channel_opt[1].flags =
|
||||
cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
cmd->channel_opt[1].non_ebs_ratio =
|
||||
cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
|
||||
}
|
||||
|
||||
if (iwl_mvm_rrm_scan_needed(mvm))
|
||||
@ -1603,7 +1613,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
||||
SCAN_CONFIG_FLAG_SET_MAC_ADDR |
|
||||
SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
|
||||
SCAN_CONFIG_N_CHANNELS(num_channels));
|
||||
scan_config->tx_chains = cpu_to_le32(mvm->fw->valid_tx_ant);
|
||||
scan_config->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
|
||||
scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
|
||||
scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm);
|
||||
scan_config->out_of_channel_time = cpu_to_le32(170);
|
||||
|
@ -99,7 +99,7 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
|
||||
int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
bool update)
|
||||
{
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_add_sta_cmd add_sta_cmd = {
|
||||
.sta_id = mvm_sta->sta_id,
|
||||
.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color),
|
||||
@ -259,7 +259,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
int i, ret, sta_id;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@ -481,7 +481,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@ -774,7 +774,7 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
int tid, u16 ssn, bool start)
|
||||
{
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_add_sta_cmd cmd = {};
|
||||
int ret;
|
||||
u32 status;
|
||||
@ -834,7 +834,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
int tid, u8 queue, bool start)
|
||||
{
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_add_sta_cmd cmd = {};
|
||||
int ret;
|
||||
u32 status;
|
||||
@ -1144,10 +1144,10 @@ static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
|
||||
static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (sta) {
|
||||
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
return mvm_sta->sta_id;
|
||||
}
|
||||
@ -1280,7 +1280,7 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (sta)
|
||||
return sta->addr;
|
||||
|
@ -69,6 +69,7 @@
|
||||
|
||||
static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
|
||||
u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
|
||||
|
||||
if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
|
||||
@ -77,12 +78,15 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
|
||||
IWL_ERR(mvm, "Enter CT Kill\n");
|
||||
iwl_mvm_set_hw_ctkill_state(mvm, true);
|
||||
|
||||
tt->throttle = false;
|
||||
tt->dynamic_smps = false;
|
||||
|
||||
/* Don't schedule an exit work if we're in test mode, since
|
||||
* the temperature will not change unless we manually set it
|
||||
* again (or disable testing).
|
||||
*/
|
||||
if (!mvm->temperature_test)
|
||||
schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
|
||||
schedule_delayed_work(&tt->ct_kill_exit,
|
||||
round_jiffies_relative(duration * HZ));
|
||||
}
|
||||
|
||||
@ -452,6 +456,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff)
|
||||
tt->params = &iwl7000_tt_params;
|
||||
|
||||
tt->throttle = false;
|
||||
tt->dynamic_smps = false;
|
||||
tt->min_backoff = min_backoff;
|
||||
INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
|
||||
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
|
||||
|
||||
mvm->mgmt_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
|
||||
mvm->mgmt_last_antenna_idx);
|
||||
|
||||
if (info->band == IEEE80211_BAND_2GHZ &&
|
||||
|
@ -620,7 +620,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
|
||||
if (num_of_ant(mvm->fw->valid_rx_ant) == 1)
|
||||
if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
@ -662,7 +662,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (num_of_ant(mvm->fw->valid_rx_ant) == 1)
|
||||
if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
|
||||
return false;
|
||||
|
||||
if (!mvm->cfg->rx_with_siso_diversity)
|
||||
|
@ -318,6 +318,11 @@ struct iwl_trans_pcie {
|
||||
/*protect hw register */
|
||||
spinlock_t reg_lock;
|
||||
bool cmd_in_flight;
|
||||
bool ref_cmd_in_flight;
|
||||
|
||||
/* protect ref counter */
|
||||
spinlock_t ref_lock;
|
||||
u32 ref_count;
|
||||
|
||||
dma_addr_t fw_mon_phys;
|
||||
struct page *fw_mon_page;
|
||||
@ -381,6 +386,9 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
struct sk_buff_head *skbs);
|
||||
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
|
||||
|
||||
void iwl_trans_pcie_ref(struct iwl_trans *trans);
|
||||
void iwl_trans_pcie_unref(struct iwl_trans *trans);
|
||||
|
||||
static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
|
||||
{
|
||||
struct iwl_tfd_tb *tb = &tfd->tbs[idx];
|
||||
|
@ -443,10 +443,25 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_pcie_apm_stop(struct iwl_trans *trans)
|
||||
static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
|
||||
{
|
||||
IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
|
||||
|
||||
if (op_mode_leave) {
|
||||
if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
|
||||
iwl_pcie_apm_init(trans);
|
||||
|
||||
/* inform ME that we are leaving */
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000)
|
||||
iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_WAKE_ME);
|
||||
else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
||||
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_PREPARE |
|
||||
CSR_HW_IF_CONFIG_REG_ENABLE_PME);
|
||||
mdelay(5);
|
||||
}
|
||||
|
||||
clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
|
||||
|
||||
/* Stop device's DMA activity */
|
||||
@ -893,6 +908,9 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trans->dbg_dest_tlv)
|
||||
iwl_pcie_apply_destination(trans);
|
||||
|
||||
/* Notify FW loading is done */
|
||||
iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
|
||||
|
||||
@ -916,6 +934,7 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
|
||||
static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
const struct fw_img *fw, bool run_in_rfkill)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int ret;
|
||||
bool hw_rfkill;
|
||||
|
||||
@ -945,6 +964,9 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init ref_count to 1 (should be cleared when ucode is loaded) */
|
||||
trans_pcie->ref_count = 1;
|
||||
|
||||
/* make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
|
||||
@ -1010,7 +1032,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_pcie_apm_stop(trans);
|
||||
iwl_pcie_apm_stop(trans, false);
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
||||
@ -1192,7 +1214,7 @@ static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans)
|
||||
iwl_disable_interrupts(trans);
|
||||
spin_unlock(&trans_pcie->irq_lock);
|
||||
|
||||
iwl_pcie_apm_stop(trans);
|
||||
iwl_pcie_apm_stop(trans, true);
|
||||
|
||||
spin_lock(&trans_pcie->irq_lock);
|
||||
iwl_disable_interrupts(trans);
|
||||
@ -1540,6 +1562,38 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
|
||||
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_ref(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
unsigned long flags;
|
||||
|
||||
if (iwlwifi_mod_params.d0i3_disable)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->ref_lock, flags);
|
||||
IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
|
||||
trans_pcie->ref_count++;
|
||||
spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_unref(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
unsigned long flags;
|
||||
|
||||
if (iwlwifi_mod_params.d0i3_disable)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->ref_lock, flags);
|
||||
IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
|
||||
if (WARN_ON_ONCE(trans_pcie->ref_count == 0)) {
|
||||
spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
|
||||
return;
|
||||
}
|
||||
trans_pcie->ref_count--;
|
||||
spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
|
||||
}
|
||||
|
||||
static const char *get_csr_string(int cmd)
|
||||
{
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
@ -2264,6 +2318,9 @@ static const struct iwl_trans_ops trans_ops_pcie = {
|
||||
.release_nic_access = iwl_trans_pcie_release_nic_access,
|
||||
.set_bits_mask = iwl_trans_pcie_set_bits_mask,
|
||||
|
||||
.ref = iwl_trans_pcie_ref,
|
||||
.unref = iwl_trans_pcie_unref,
|
||||
|
||||
.dump_data = iwl_trans_pcie_dump_data,
|
||||
};
|
||||
|
||||
@ -2404,6 +2461,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
trans_pcie->inta_mask = CSR_INI_SET_MASK;
|
||||
trans->d0i3_mode = IWL_D0I3_MODE_ON_SUSPEND;
|
||||
|
||||
return trans;
|
||||
|
||||
|
@ -985,17 +985,31 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
|
||||
if (iwl_queue_space(&txq->q) > txq->q.low_mark)
|
||||
iwl_wake_queue(trans, txq);
|
||||
|
||||
if (q->read_ptr == q->write_ptr) {
|
||||
IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", q->id);
|
||||
iwl_trans_pcie_unref(trans);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&txq->lock);
|
||||
}
|
||||
|
||||
static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans)
|
||||
static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
|
||||
const struct iwl_host_cmd *cmd)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&trans_pcie->reg_lock);
|
||||
|
||||
if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
|
||||
!trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = true;
|
||||
IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
|
||||
iwl_trans_pcie_ref(trans);
|
||||
}
|
||||
|
||||
if (trans_pcie->cmd_in_flight)
|
||||
return 0;
|
||||
|
||||
@ -1036,6 +1050,12 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
|
||||
|
||||
lockdep_assert_held(&trans_pcie->reg_lock);
|
||||
|
||||
if (trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = false;
|
||||
IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
|
||||
iwl_trans_pcie_unref(trans);
|
||||
}
|
||||
|
||||
if (WARN_ON(!trans_pcie->cmd_in_flight))
|
||||
return 0;
|
||||
|
||||
@ -1473,7 +1493,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
|
||||
mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
|
||||
ret = iwl_pcie_set_cmd_in_flight(trans);
|
||||
ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
|
||||
if (ret < 0) {
|
||||
idx = ret;
|
||||
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
|
||||
@ -1819,9 +1839,13 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
wait_write_ptr = ieee80211_has_morefrags(fc);
|
||||
|
||||
/* start timer if queue currently empty */
|
||||
if (txq->need_update && q->read_ptr == q->write_ptr &&
|
||||
trans_pcie->wd_timeout)
|
||||
mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
|
||||
if (q->read_ptr == q->write_ptr) {
|
||||
if (txq->need_update && trans_pcie->wd_timeout)
|
||||
mod_timer(&txq->stuck_timer,
|
||||
jiffies + trans_pcie->wd_timeout);
|
||||
IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
|
||||
iwl_trans_pcie_ref(trans);
|
||||
}
|
||||
|
||||
/* Tell device the write index *just past* this latest filled TFD */
|
||||
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);
|
||||
|
Loading…
Reference in New Issue
Block a user