提交 7b868fed 编写于 作者: D David S. Miller

Merge tag 'wireless-drivers-for-davem-2017-06-06' of...

Merge tag 'wireless-drivers-for-davem-2017-06-06' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

Kalle Valo says:

====================
wireless-drivers fixes for 4.12

It has been a slow start of cycle and this the first set of fixes for
4.12. Nothing really major here.

wcn36xx

* fix an issue with module reload

brcmfmac

* fix aligment regression on 64 bit systems

iwlwifi

* fixes for memory leaks, runtime PM, memory initialisation and other
  smaller problems

* fix IBSS on devices using DQA mode (7260 and up)

* fix the minimum firmware API requirement for 7265D, 3168, 8000 and
  8265
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -1271,6 +1271,8 @@ static int wcn36xx_remove(struct platform_device *pdev) ...@@ -1271,6 +1271,8 @@ static int wcn36xx_remove(struct platform_device *pdev)
qcom_smem_state_put(wcn->tx_enable_state); qcom_smem_state_put(wcn->tx_enable_state);
qcom_smem_state_put(wcn->tx_rings_empty_state); qcom_smem_state_put(wcn->tx_rings_empty_state);
rpmsg_destroy_ept(wcn->smd_channel);
iounmap(wcn->dxe_base); iounmap(wcn->dxe_base);
iounmap(wcn->ccu_base); iounmap(wcn->ccu_base);
......
...@@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev) ...@@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
/* otherwise, set txglomalign */ /* otherwise, set txglomalign */
value = sdiodev->settings->bus.sdio.sd_sgentry_align; value = sdiodev->settings->bus.sdio.sd_sgentry_align;
/* SDIO ADMA requires at least 32 bit alignment */ /* SDIO ADMA requires at least 32 bit alignment */
value = max_t(u32, value, 4); value = max_t(u32, value, ALIGNMENT);
err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
sizeof(u32)); sizeof(u32));
} }
......
...@@ -79,8 +79,8 @@ ...@@ -79,8 +79,8 @@
/* Lowest firmware API version supported */ /* Lowest firmware API version supported */
#define IWL7260_UCODE_API_MIN 17 #define IWL7260_UCODE_API_MIN 17
#define IWL7265_UCODE_API_MIN 17 #define IWL7265_UCODE_API_MIN 17
#define IWL7265D_UCODE_API_MIN 17 #define IWL7265D_UCODE_API_MIN 22
#define IWL3168_UCODE_API_MIN 20 #define IWL3168_UCODE_API_MIN 22
/* NVM versions */ /* NVM versions */
#define IWL7260_NVM_VERSION 0x0a1d #define IWL7260_NVM_VERSION 0x0a1d
......
...@@ -74,8 +74,8 @@ ...@@ -74,8 +74,8 @@
#define IWL8265_UCODE_API_MAX 30 #define IWL8265_UCODE_API_MAX 30
/* Lowest firmware API version supported */ /* Lowest firmware API version supported */
#define IWL8000_UCODE_API_MIN 17 #define IWL8000_UCODE_API_MIN 22
#define IWL8265_UCODE_API_MIN 20 #define IWL8265_UCODE_API_MIN 22
/* NVM versions */ /* NVM versions */
#define IWL8000_NVM_VERSION 0x0a1d #define IWL8000_NVM_VERSION 0x0a1d
......
...@@ -370,6 +370,7 @@ ...@@ -370,6 +370,7 @@
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c) #define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
#define DBGC_IN_SAMPLE (0xa03c00) #define DBGC_IN_SAMPLE (0xa03c00)
#define DBGC_OUT_CTRL (0xa03c0c)
/* enable the ID buf for read */ /* enable the ID buf for read */
#define WFPM_PS_CTL_CLR 0xA0300C #define WFPM_PS_CTL_CLR 0xA0300C
......
...@@ -307,6 +307,11 @@ enum { ...@@ -307,6 +307,11 @@ enum {
/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ /* Bit 1-3: LQ command color. Used to match responses to LQ commands */
#define LQ_FLAG_COLOR_POS 1 #define LQ_FLAG_COLOR_POS 1
#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) #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 /* Bit 4-5: Tx RTS BW Signalling
* (0) No RTS BW signalling * (0) No RTS BW signalling
......
...@@ -519,8 +519,11 @@ struct agg_tx_status { ...@@ -519,8 +519,11 @@ struct agg_tx_status {
* bit-7 invalid rate indication * bit-7 invalid rate indication
*/ */
#define TX_RES_INIT_RATE_INDEX_MSK 0x0f #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_RATE_TABLE_COLOR_MSK 0x70
#define TX_RES_INV_RATE_INDEX_MSK 0x80 #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_TID(_ra_tid) ((_ra_tid) & 0x0f)
#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4) #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, ...@@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
return 0; 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) int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
{ {
u8 *ptr; u8 *ptr;
...@@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) ...@@ -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 */ /* EARLY START - firmware's configuration is hard coded */
if ((!mvm->fw->dbg_conf_tlv[conf_id] || if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
!mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) && !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
conf_id == FW_DBG_START_FROM_ALIVE) { conf_id == FW_DBG_START_FROM_ALIVE)
iwl_mvm_restart_early_start(mvm);
return 0; return 0;
}
if (!mvm->fw->dbg_conf_tlv[conf_id]) if (!mvm->fw->dbg_conf_tlv[conf_id])
return -EINVAL; return -EINVAL;
......
...@@ -1040,7 +1040,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, ...@@ -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_v6 beacon_cmd_v6;
struct iwl_mac_beacon_cmd_v7 beacon_cmd; struct iwl_mac_beacon_cmd_v7 beacon_cmd;
} u = {}; } u = {};
struct iwl_mac_beacon_cmd beacon_cmd; struct iwl_mac_beacon_cmd beacon_cmd = {};
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
u32 beacon_skb_len; u32 beacon_skb_len;
u32 rate, tx_flags; 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); ...@@ -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) 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) & return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
~BIT(IWL_MVM_CMD_QUEUE)); ~BIT(cmd_queue));
} }
static inline static inline
...@@ -1753,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) ...@@ -1753,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
if (!iwl_mvm_has_new_tx_api(mvm)) if (!iwl_mvm_has_new_tx_api(mvm))
iwl_free_fw_paging(mvm); iwl_free_fw_paging(mvm);
mvm->ucode_loaded = false; mvm->ucode_loaded = false;
mvm->fw_dbg_conf = FW_DBG_INVALID;
iwl_trans_stop_device(mvm->trans); iwl_trans_stop_device(mvm->trans);
} }
......
...@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) ...@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
/* stop recording */
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/* stop recording */
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); 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 { } 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); iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
/* wait before we collect the data till the DBGC stop */
udelay(100); 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); iwl_mvm_fw_error_dump(mvm);
/* start recording again if the firmware is not crashed */ /* start recording again if the firmware is not crashed */
WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
mvm->fw->dbg_dest_tlv && mvm->fw->dbg_dest_tlv) {
iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample);
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl);
}
}
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* *
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* *
* This program is free software; you can redistribute it and/or modify it * 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 * 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, ...@@ -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); 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 */ /* Check if both rates share the same column */
static inline bool rs_rate_column_match(struct rs_rate *a, static inline bool rs_rate_column_match(struct rs_rate *a,
struct rs_rate *b) struct rs_rate *b)
...@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
u32 lq_hwrate; u32 lq_hwrate;
struct rs_rate lq_rate, tx_resp_rate; struct rs_rate lq_rate, tx_resp_rate;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 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]; 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_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta *lq_sta = &mvmsta->lq_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. */ /* Treat uninitialized rate scaling data same as non-existing. */
if (!lq_sta) { if (!lq_sta) {
...@@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *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); rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
/* Here we actually compare this rate to the latest LQ command */ /* 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, IWL_DEBUG_RATE(mvm,
"initial tx resp rate 0x%x does not match 0x%x\n", "tx resp color 0x%x does not match 0x%x\n",
tx_resp_hwrate, lq_hwrate); lq_color, LQ_FLAG_COLOR_GET(table->flags));
/* /*
* Since rates mis-match, the last LQ command may have failed. * 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, ...@@ -3326,6 +3298,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
u8 valid_tx_ant = 0; u8 valid_tx_ant = 0;
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
bool toggle_ant = false; bool toggle_ant = false;
u32 color;
memcpy(&rate, initial_rate, sizeof(rate)); memcpy(&rate, initial_rate, sizeof(rate));
...@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, ...@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
num_rates, num_retries, valid_tx_ant, num_rates, num_retries, valid_tx_ant,
toggle_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 { struct rs_bfer_active_iter_data {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* *
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Mobile Communications GmbH * 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -357,6 +358,20 @@ struct iwl_lq_sta { ...@@ -357,6 +358,20 @@ struct iwl_lq_sta {
} pers; } 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 */ /* Initialize station's rate scaling information after adding station */
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
enum nl80211_band band, bool init); enum nl80211_band band, bool init);
......
...@@ -2120,7 +2120,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -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)) if (!iwl_mvm_is_dqa_supported(mvm))
return 0; 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; return -ENOTSUPP;
/* /*
...@@ -2155,6 +2156,16 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -2155,6 +2156,16 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
mvmvif->cab_queue = queue; mvmvif->cab_queue = queue;
} else if (!fw_has_api(&mvm->fw->ucode_capa, } else if (!fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_STA_TYPE)) { 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, iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0,
&cfg, timeout); &cfg, timeout);
} }
...@@ -3321,18 +3332,15 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, ...@@ -3321,18 +3332,15 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
/* Get the station from the mvm local station table */ /* Get the station from the mvm local station table */
mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta); mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
if (!mvm_sta) { if (mvm_sta)
IWL_ERR(mvm, "Failed to find station\n"); sta_id = mvm_sta->sta_id;
return -EINVAL;
}
sta_id = mvm_sta->sta_id;
IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
keyconf->keyidx, sta_id); keyconf->keyidx, sta_id);
if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || 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_128 ||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
......
...@@ -313,6 +313,7 @@ enum iwl_mvm_agg_state { ...@@ -313,6 +313,7 @@ enum iwl_mvm_agg_state {
* This is basically (last acked packet++). * This is basically (last acked packet++).
* @rate_n_flags: Rate at which Tx was attempted. Holds the data between the * @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). * 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. * @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed.
* @state: state of the BA agreement establishment / tear down. * @state: state of the BA agreement establishment / tear down.
* @txq_id: Tx queue used by the BA session / DQA * @txq_id: Tx queue used by the BA session / DQA
...@@ -331,6 +332,7 @@ struct iwl_mvm_tid_data { ...@@ -331,6 +332,7 @@ struct iwl_mvm_tid_data {
u16 next_reclaimed; u16 next_reclaimed;
/* The rest is Tx AGG related */ /* The rest is Tx AGG related */
u32 rate_n_flags; u32 rate_n_flags;
u8 lq_color;
bool amsdu_in_ampdu_allowed; bool amsdu_in_ampdu_allowed;
enum iwl_mvm_agg_state state; enum iwl_mvm_agg_state state;
u16 txq_id; u16 txq_id;
......
...@@ -790,11 +790,13 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev, ...@@ -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); struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
int ret; int ret;
if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
return -EIO;
mutex_lock(&mvm->mutex); 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)) { if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
......
...@@ -1323,6 +1323,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -1323,6 +1323,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvmsta; struct iwl_mvm_sta *mvmsta;
struct sk_buff_head skbs; struct sk_buff_head skbs;
u8 skb_freed = 0; u8 skb_freed = 0;
u8 lq_color;
u16 next_reclaimed, seq_ctl; u16 next_reclaimed, seq_ctl;
bool is_ndp = false; bool is_ndp = false;
...@@ -1405,8 +1406,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -1405,8 +1406,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
info->status.tx_time = info->status.tx_time =
le16_to_cpu(tx_resp->wireless_media_time); le16_to_cpu(tx_resp->wireless_media_time);
BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); 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] = 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); ieee80211_tx_status(mvm->hw, skb);
} }
...@@ -1638,6 +1640,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, ...@@ -1638,6 +1640,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
le32_to_cpu(tx_resp->initial_rate); le32_to_cpu(tx_resp->initial_rate);
mvmsta->tid_data[tid].tx_time = mvmsta->tid_data[tid].tx_time =
le16_to_cpu(tx_resp->wireless_media_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(); rcu_read_unlock();
...@@ -1707,6 +1712,11 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, ...@@ -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); iwl_mvm_check_ratid_empty(mvm, sta, tid);
freed = 0; 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; ba_info->status.status_driver_data[1] = (void *)(uintptr_t)rate;
skb_queue_walk(&reclaimed_skbs, skb) { skb_queue_walk(&reclaimed_skbs, skb) {
......
...@@ -2803,7 +2803,8 @@ static struct iwl_trans_dump_data ...@@ -2803,7 +2803,8 @@ static struct iwl_trans_dump_data
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int iwl_trans_pcie_suspend(struct iwl_trans *trans) 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 iwl_pci_fw_enter_d0i3(trans);
return 0; return 0;
...@@ -2811,7 +2812,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) ...@@ -2811,7 +2812,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
static void iwl_trans_pcie_resume(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); iwl_pci_fw_exit_d0i3(trans);
} }
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
......
...@@ -906,7 +906,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -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))) { if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) {
ret = -EINVAL; ret = -EINVAL;
goto error; goto error_free_resp;
} }
rsp = (void *)hcmd.resp_pkt->data; rsp = (void *)hcmd.resp_pkt->data;
...@@ -915,13 +915,13 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -915,13 +915,13 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
if (qid > ARRAY_SIZE(trans_pcie->txq)) { if (qid > ARRAY_SIZE(trans_pcie->txq)) {
WARN_ONCE(1, "queue index %d unsupported", qid); WARN_ONCE(1, "queue index %d unsupported", qid);
ret = -EIO; ret = -EIO;
goto error; goto error_free_resp;
} }
if (test_and_set_bit(qid, trans_pcie->queue_used)) { if (test_and_set_bit(qid, trans_pcie->queue_used)) {
WARN_ONCE(1, "queue %d already used", qid); WARN_ONCE(1, "queue %d already used", qid);
ret = -EIO; ret = -EIO;
goto error; goto error_free_resp;
} }
txq->id = qid; txq->id = qid;
...@@ -934,8 +934,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -934,8 +934,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
(txq->write_ptr) | (qid << 16)); (txq->write_ptr) | (qid << 16));
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
iwl_free_resp(&hcmd);
return qid; return qid;
error_free_resp:
iwl_free_resp(&hcmd);
error: error:
iwl_pcie_gen2_txq_free_memory(trans, txq); iwl_pcie_gen2_txq_free_memory(trans, txq);
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册