Fixes for 4.12:
* Some memory leaks; * IBSS support; * Some bugzilla bugs; * Some runtime PM fixes; * Rate-scaling issues; * Some locking problems; -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlk1qXIACgkQoUecoho8 xfrwog/9HEQ/YhS5hcPagIYN///AZ3BXGE12KZV/9fN5yP+OSiKkH7gD16HTteTt uMzV2NJSCwv7RpV1wb7HE5qgpSNEfMYG0yR4kbjR7SFKGS8O45qut8aOrcYrg03C Yhj6ac058jbF3SnVFPGG2l+t9YZNfs43eJ+bWaKuWUm98zv5MCE9JbEhBGcLLf/3 8B8LuoVhssoiX3k6dWox1cuaJcWJf1ARdPxJlM/QXur6uEui/DG8KidOoMHTW8Q0 zspVreT3dFbCd+hZlz5iN1Hhub0HbHn6/ictGeTxYWx/hoAPEyWnAUM+ug72t6ol Re6F1sz1YfF9YatfItdjFpBfCA4GtVXOwy6pvv91Ah4vB6dUHQbkWjvKI4XLUBTG K+dndU5RvRT0J7y7HxZQgkAtVqiIwaNZKCXQUT5ZgfJJ7lSCAxJa1JDc7Ol5XkyP /PE62yd/0trFBHyFq/Oq8kldLSt+lVKa7ia3R7BVtgyH/w2w+XZ3QxXzIMtP5BM+ O+NBHHLP7rSFkynpO2F4SFg+6L6EiPZZFC11+PN9VFxXCrkuAzZ9kV3OceBFJC7L KqA/US0UayuyaaJJP+sM5KeFy8igsXE0qazGnYztW3LSWp6e7iIsu7e/coxU7gU7 m7FG5BbE7Vmt0QqyirVi+umV6nLI4rV38v09s8r78DZXpj5tmTY= =Z9/C -----END PGP SIGNATURE----- Merge tag 'iwlwifi-for-kalle-2017-06-05' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes Fixes for 4.12: * Some memory leaks; * IBSS support; * Some bugzilla bugs; * Some runtime PM fixes; * Rate-scaling issues; * Some locking problems;
This commit is contained in:
commit
dc89481bb4
@ -79,8 +79,8 @@
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MIN 17
|
||||
#define IWL7265_UCODE_API_MIN 17
|
||||
#define IWL7265D_UCODE_API_MIN 17
|
||||
#define IWL3168_UCODE_API_MIN 20
|
||||
#define IWL7265D_UCODE_API_MIN 22
|
||||
#define IWL3168_UCODE_API_MIN 22
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL7260_NVM_VERSION 0x0a1d
|
||||
|
@ -74,8 +74,8 @@
|
||||
#define IWL8265_UCODE_API_MAX 30
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MIN 17
|
||||
#define IWL8265_UCODE_API_MIN 20
|
||||
#define IWL8000_UCODE_API_MIN 22
|
||||
#define IWL8265_UCODE_API_MIN 22
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
|
@ -370,6 +370,7 @@
|
||||
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
|
||||
|
||||
#define DBGC_IN_SAMPLE (0xa03c00)
|
||||
#define DBGC_OUT_CTRL (0xa03c0c)
|
||||
|
||||
/* enable the ID buf for read */
|
||||
#define WFPM_PS_CTL_CLR 0xA0300C
|
||||
|
@ -307,6 +307,11 @@ enum {
|
||||
/* Bit 1-3: LQ command color. Used to match responses to LQ commands */
|
||||
#define LQ_FLAG_COLOR_POS 1
|
||||
#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS)
|
||||
#define LQ_FLAG_COLOR_GET(_f) (((_f) & LQ_FLAG_COLOR_MSK) >>\
|
||||
LQ_FLAG_COLOR_POS)
|
||||
#define LQ_FLAGS_COLOR_INC(_c) ((((_c) + 1) << LQ_FLAG_COLOR_POS) &\
|
||||
LQ_FLAG_COLOR_MSK)
|
||||
#define LQ_FLAG_COLOR_SET(_f, _c) ((_c) | ((_f) & ~LQ_FLAG_COLOR_MSK))
|
||||
|
||||
/* Bit 4-5: Tx RTS BW Signalling
|
||||
* (0) No RTS BW signalling
|
||||
|
@ -519,8 +519,11 @@ struct agg_tx_status {
|
||||
* bit-7 invalid rate indication
|
||||
*/
|
||||
#define TX_RES_INIT_RATE_INDEX_MSK 0x0f
|
||||
#define TX_RES_RATE_TABLE_COLOR_POS 4
|
||||
#define TX_RES_RATE_TABLE_COLOR_MSK 0x70
|
||||
#define TX_RES_INV_RATE_INDEX_MSK 0x80
|
||||
#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\
|
||||
TX_RES_RATE_TABLE_COLOR_POS)
|
||||
|
||||
#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f)
|
||||
#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
|
||||
|
@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
|
||||
iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
else
|
||||
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
|
||||
}
|
||||
|
||||
int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
|
||||
{
|
||||
u8 *ptr;
|
||||
@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
|
||||
/* EARLY START - firmware's configuration is hard coded */
|
||||
if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
|
||||
!mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
|
||||
conf_id == FW_DBG_START_FROM_ALIVE) {
|
||||
iwl_mvm_restart_early_start(mvm);
|
||||
conf_id == FW_DBG_START_FROM_ALIVE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mvm->fw->dbg_conf_tlv[conf_id])
|
||||
return -EINVAL;
|
||||
|
@ -1040,7 +1040,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
|
||||
struct iwl_mac_beacon_cmd_v6 beacon_cmd_v6;
|
||||
struct iwl_mac_beacon_cmd_v7 beacon_cmd;
|
||||
} u = {};
|
||||
struct iwl_mac_beacon_cmd beacon_cmd;
|
||||
struct iwl_mac_beacon_cmd beacon_cmd = {};
|
||||
struct ieee80211_tx_info *info;
|
||||
u32 beacon_skb_len;
|
||||
u32 rate, tx_flags;
|
||||
|
@ -1730,8 +1730,11 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
|
||||
*/
|
||||
static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
|
||||
{
|
||||
u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE :
|
||||
IWL_MVM_CMD_QUEUE;
|
||||
|
||||
return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
|
||||
~BIT(IWL_MVM_CMD_QUEUE));
|
||||
~BIT(cmd_queue));
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -1753,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
iwl_free_fw_paging(mvm);
|
||||
mvm->ucode_loaded = false;
|
||||
mvm->fw_dbg_conf = FW_DBG_INVALID;
|
||||
iwl_trans_stop_device(mvm->trans);
|
||||
}
|
||||
|
||||
|
@ -1149,22 +1149,38 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* stop recording */
|
||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
/* stop recording */
|
||||
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
|
||||
iwl_mvm_fw_error_dump(mvm);
|
||||
|
||||
/* start recording again if the firmware is not crashed */
|
||||
if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
|
||||
mvm->fw->dbg_dest_tlv)
|
||||
iwl_clear_bits_prph(mvm->trans,
|
||||
MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
} else {
|
||||
u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE);
|
||||
u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL);
|
||||
|
||||
/* stop recording */
|
||||
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
|
||||
/* wait before we collect the data till the DBGC stop */
|
||||
udelay(100);
|
||||
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
|
||||
/* wait before we collect the data till the DBGC stop */
|
||||
udelay(500);
|
||||
|
||||
iwl_mvm_fw_error_dump(mvm);
|
||||
|
||||
/* start recording again if the firmware is not crashed */
|
||||
if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
|
||||
mvm->fw->dbg_dest_tlv) {
|
||||
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample);
|
||||
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
iwl_mvm_fw_error_dump(mvm);
|
||||
|
||||
/* start recording again if the firmware is not crashed */
|
||||
WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
|
||||
mvm->fw->dbg_dest_tlv &&
|
||||
iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -1083,34 +1083,6 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
|
||||
rs_get_lower_rate_in_column(lq_sta, rate);
|
||||
}
|
||||
|
||||
/* Check if both rates are identical
|
||||
* allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B
|
||||
* with a rate indicating STBC/BFER and ANT_AB.
|
||||
*/
|
||||
static inline bool rs_rate_equal(struct rs_rate *a,
|
||||
struct rs_rate *b,
|
||||
bool allow_ant_mismatch)
|
||||
|
||||
{
|
||||
bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) &&
|
||||
(a->bfer == b->bfer);
|
||||
|
||||
if (allow_ant_mismatch) {
|
||||
if (a->stbc || a->bfer) {
|
||||
WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d",
|
||||
a->stbc, a->bfer, a->ant);
|
||||
ant_match |= (b->ant == ANT_A || b->ant == ANT_B);
|
||||
} else if (b->stbc || b->bfer) {
|
||||
WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d",
|
||||
b->stbc, b->bfer, b->ant);
|
||||
ant_match |= (a->ant == ANT_A || a->ant == ANT_B);
|
||||
}
|
||||
}
|
||||
|
||||
return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) &&
|
||||
(a->ldpc == b->ldpc) && (a->index == b->index) && ant_match;
|
||||
}
|
||||
|
||||
/* Check if both rates share the same column */
|
||||
static inline bool rs_rate_column_match(struct rs_rate *a,
|
||||
struct rs_rate *b)
|
||||
@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
u32 lq_hwrate;
|
||||
struct rs_rate lq_rate, tx_resp_rate;
|
||||
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
|
||||
u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
|
||||
u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
|
||||
u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
|
||||
u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
|
||||
u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
|
||||
bool allow_ant_mismatch = fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_LQ_SS_PARAMS);
|
||||
|
||||
/* Treat uninitialized rate scaling data same as non-existing. */
|
||||
if (!lq_sta) {
|
||||
@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
|
||||
|
||||
/* Here we actually compare this rate to the latest LQ command */
|
||||
if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
|
||||
if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"initial tx resp rate 0x%x does not match 0x%x\n",
|
||||
tx_resp_hwrate, lq_hwrate);
|
||||
"tx resp color 0x%x does not match 0x%x\n",
|
||||
lq_color, LQ_FLAG_COLOR_GET(table->flags));
|
||||
|
||||
/*
|
||||
* Since rates mis-match, the last LQ command may have failed.
|
||||
@ -3326,6 +3298,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
u8 valid_tx_ant = 0;
|
||||
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
|
||||
bool toggle_ant = false;
|
||||
u32 color;
|
||||
|
||||
memcpy(&rate, initial_rate, sizeof(rate));
|
||||
|
||||
@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
num_rates, num_retries, valid_tx_ant,
|
||||
toggle_ant);
|
||||
|
||||
/* update the color of the LQ command (as a counter at bits 1-3) */
|
||||
color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags));
|
||||
lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color);
|
||||
}
|
||||
|
||||
struct rs_bfer_active_iter_data {
|
||||
|
@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -357,6 +358,20 @@ struct iwl_lq_sta {
|
||||
} pers;
|
||||
};
|
||||
|
||||
/* ieee80211_tx_info's status_driver_data[0] is packed with lq color and txp
|
||||
* Note, it's iwlmvm <-> mac80211 interface.
|
||||
* bits 0-7: reduced tx power
|
||||
* bits 8-10: LQ command's color
|
||||
*/
|
||||
#define RS_DRV_DATA_TXP_MSK 0xff
|
||||
#define RS_DRV_DATA_LQ_COLOR_POS 8
|
||||
#define RS_DRV_DATA_LQ_COLOR_MSK (7 << RS_DRV_DATA_LQ_COLOR_POS)
|
||||
#define RS_DRV_DATA_LQ_COLOR_GET(_f) (((_f) & RS_DRV_DATA_LQ_COLOR_MSK) >>\
|
||||
RS_DRV_DATA_LQ_COLOR_POS)
|
||||
#define RS_DRV_DATA_PACK(_c, _p) ((void *)(uintptr_t)\
|
||||
(((uintptr_t)_p) |\
|
||||
((_c) << RS_DRV_DATA_LQ_COLOR_POS)))
|
||||
|
||||
/* Initialize station's rate scaling information after adding station */
|
||||
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
enum nl80211_band band, bool init);
|
||||
|
@ -2120,7 +2120,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
if (!iwl_mvm_is_dqa_supported(mvm))
|
||||
return 0;
|
||||
|
||||
if (WARN_ON(vif->type != NL80211_IFTYPE_AP))
|
||||
if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
|
||||
vif->type != NL80211_IFTYPE_ADHOC))
|
||||
return -ENOTSUPP;
|
||||
|
||||
/*
|
||||
@ -2155,6 +2156,16 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
mvmvif->cab_queue = queue;
|
||||
} else if (!fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_STA_TYPE)) {
|
||||
/*
|
||||
* In IBSS, ieee80211_check_queues() sets the cab_queue to be
|
||||
* invalid, so make sure we use the queue we want.
|
||||
* Note that this is done here as we want to avoid making DQA
|
||||
* changes in mac80211 layer.
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
|
||||
mvmvif->cab_queue = vif->cab_queue;
|
||||
}
|
||||
iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0,
|
||||
&cfg, timeout);
|
||||
}
|
||||
@ -3321,18 +3332,15 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
|
||||
|
||||
/* Get the station from the mvm local station table */
|
||||
mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
|
||||
if (!mvm_sta) {
|
||||
IWL_ERR(mvm, "Failed to find station\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
sta_id = mvm_sta->sta_id;
|
||||
if (mvm_sta)
|
||||
sta_id = mvm_sta->sta_id;
|
||||
|
||||
IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
|
||||
keyconf->keyidx, sta_id);
|
||||
|
||||
if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
|
||||
if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
|
||||
return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
|
||||
|
||||
if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
|
||||
|
@ -313,6 +313,7 @@ enum iwl_mvm_agg_state {
|
||||
* This is basically (last acked packet++).
|
||||
* @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
|
||||
* Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
|
||||
* @lq_color: the color of the LQ command as it appears in tx response.
|
||||
* @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed.
|
||||
* @state: state of the BA agreement establishment / tear down.
|
||||
* @txq_id: Tx queue used by the BA session / DQA
|
||||
@ -331,6 +332,7 @@ struct iwl_mvm_tid_data {
|
||||
u16 next_reclaimed;
|
||||
/* The rest is Tx AGG related */
|
||||
u32 rate_n_flags;
|
||||
u8 lq_color;
|
||||
bool amsdu_in_ampdu_allowed;
|
||||
enum iwl_mvm_agg_state state;
|
||||
u16 txq_id;
|
||||
|
@ -790,11 +790,13 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
|
||||
int ret;
|
||||
|
||||
if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
|
@ -1323,6 +1323,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct sk_buff_head skbs;
|
||||
u8 skb_freed = 0;
|
||||
u8 lq_color;
|
||||
u16 next_reclaimed, seq_ctl;
|
||||
bool is_ndp = false;
|
||||
|
||||
@ -1405,8 +1406,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
info->status.tx_time =
|
||||
le16_to_cpu(tx_resp->wireless_media_time);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1);
|
||||
lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info);
|
||||
info->status.status_driver_data[0] =
|
||||
(void *)(uintptr_t)tx_resp->reduced_tpc;
|
||||
RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc);
|
||||
|
||||
ieee80211_tx_status(mvm->hw, skb);
|
||||
}
|
||||
@ -1638,6 +1640,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
||||
le32_to_cpu(tx_resp->initial_rate);
|
||||
mvmsta->tid_data[tid].tx_time =
|
||||
le16_to_cpu(tx_resp->wireless_media_time);
|
||||
mvmsta->tid_data[tid].lq_color =
|
||||
(tx_resp->tlc_info & TX_RES_RATE_TABLE_COLOR_MSK) >>
|
||||
TX_RES_RATE_TABLE_COLOR_POS;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
@ -1707,6 +1712,11 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
||||
iwl_mvm_check_ratid_empty(mvm, sta, tid);
|
||||
|
||||
freed = 0;
|
||||
|
||||
/* pack lq color from tid_data along the reduced txp */
|
||||
ba_info->status.status_driver_data[0] =
|
||||
RS_DRV_DATA_PACK(tid_data->lq_color,
|
||||
ba_info->status.status_driver_data[0]);
|
||||
ba_info->status.status_driver_data[1] = (void *)(uintptr_t)rate;
|
||||
|
||||
skb_queue_walk(&reclaimed_skbs, skb) {
|
||||
|
@ -2803,7 +2803,8 @@ static struct iwl_trans_dump_data
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3)
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
|
||||
(trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
|
||||
return iwl_pci_fw_enter_d0i3(trans);
|
||||
|
||||
return 0;
|
||||
@ -2811,7 +2812,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
|
||||
|
||||
static void iwl_trans_pcie_resume(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3)
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
|
||||
(trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
|
||||
iwl_pci_fw_exit_d0i3(trans);
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
@ -906,7 +906,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
||||
|
||||
if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
goto error_free_resp;
|
||||
}
|
||||
|
||||
rsp = (void *)hcmd.resp_pkt->data;
|
||||
@ -915,13 +915,13 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
||||
if (qid > ARRAY_SIZE(trans_pcie->txq)) {
|
||||
WARN_ONCE(1, "queue index %d unsupported", qid);
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
goto error_free_resp;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(qid, trans_pcie->queue_used)) {
|
||||
WARN_ONCE(1, "queue %d already used", qid);
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
goto error_free_resp;
|
||||
}
|
||||
|
||||
txq->id = qid;
|
||||
@ -934,8 +934,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
||||
(txq->write_ptr) | (qid << 16));
|
||||
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
|
||||
|
||||
iwl_free_resp(&hcmd);
|
||||
return qid;
|
||||
|
||||
error_free_resp:
|
||||
iwl_free_resp(&hcmd);
|
||||
error:
|
||||
iwl_pcie_gen2_txq_free_memory(trans, txq);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user