diff options
author | David S. Miller <davem@davemloft.net> | 2017-06-06 12:53:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-06 12:53:20 -0400 |
commit | 7b868fed00f6c72d3e0270bcb057b4f26c09e809 (patch) | |
tree | 702afee62998d6a17e0192480a5bb06683d8a091 | |
parent | 80971dfbf047c25b4160f708711fed7e3b28c372 (diff) | |
parent | dc89481bb4c9af0700423e21c8371379d3d943b1 (diff) |
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: David S. Miller <davem@davemloft.net>
19 files changed, 118 insertions, 79 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index d5e993dc9b23..517a315e259b 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -1271,6 +1271,8 @@ static int wcn36xx_remove(struct platform_device *pdev) | |||
1271 | qcom_smem_state_put(wcn->tx_enable_state); | 1271 | qcom_smem_state_put(wcn->tx_enable_state); |
1272 | qcom_smem_state_put(wcn->tx_rings_empty_state); | 1272 | qcom_smem_state_put(wcn->tx_rings_empty_state); |
1273 | 1273 | ||
1274 | rpmsg_destroy_ept(wcn->smd_channel); | ||
1275 | |||
1274 | iounmap(wcn->dxe_base); | 1276 | iounmap(wcn->dxe_base); |
1275 | iounmap(wcn->ccu_base); | 1277 | iounmap(wcn->ccu_base); |
1276 | 1278 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index fc64b8913aa6..e03450059b06 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | |||
@@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
3422 | /* otherwise, set txglomalign */ | 3422 | /* otherwise, set txglomalign */ |
3423 | value = sdiodev->settings->bus.sdio.sd_sgentry_align; | 3423 | value = sdiodev->settings->bus.sdio.sd_sgentry_align; |
3424 | /* SDIO ADMA requires at least 32 bit alignment */ | 3424 | /* SDIO ADMA requires at least 32 bit alignment */ |
3425 | value = max_t(u32, value, 4); | 3425 | value = max_t(u32, value, ALIGNMENT); |
3426 | err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, | 3426 | err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, |
3427 | sizeof(u32)); | 3427 | sizeof(u32)); |
3428 | } | 3428 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c index 3b3e076571d6..45e2efc70d19 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c | |||
@@ -79,8 +79,8 @@ | |||
79 | /* Lowest firmware API version supported */ | 79 | /* Lowest firmware API version supported */ |
80 | #define IWL7260_UCODE_API_MIN 17 | 80 | #define IWL7260_UCODE_API_MIN 17 |
81 | #define IWL7265_UCODE_API_MIN 17 | 81 | #define IWL7265_UCODE_API_MIN 17 |
82 | #define IWL7265D_UCODE_API_MIN 17 | 82 | #define IWL7265D_UCODE_API_MIN 22 |
83 | #define IWL3168_UCODE_API_MIN 20 | 83 | #define IWL3168_UCODE_API_MIN 22 |
84 | 84 | ||
85 | /* NVM versions */ | 85 | /* NVM versions */ |
86 | #define IWL7260_NVM_VERSION 0x0a1d | 86 | #define IWL7260_NVM_VERSION 0x0a1d |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index b9718c0cf174..89137717c1fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c | |||
@@ -74,8 +74,8 @@ | |||
74 | #define IWL8265_UCODE_API_MAX 30 | 74 | #define IWL8265_UCODE_API_MAX 30 |
75 | 75 | ||
76 | /* Lowest firmware API version supported */ | 76 | /* Lowest firmware API version supported */ |
77 | #define IWL8000_UCODE_API_MIN 17 | 77 | #define IWL8000_UCODE_API_MIN 22 |
78 | #define IWL8265_UCODE_API_MIN 20 | 78 | #define IWL8265_UCODE_API_MIN 22 |
79 | 79 | ||
80 | /* NVM versions */ | 80 | /* NVM versions */ |
81 | #define IWL8000_NVM_VERSION 0x0a1d | 81 | #define IWL8000_NVM_VERSION 0x0a1d |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 306bc967742e..77efbb78e867 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h | |||
@@ -370,6 +370,7 @@ | |||
370 | #define MON_DMARB_RD_DATA_ADDR (0xa03c5c) | 370 | #define MON_DMARB_RD_DATA_ADDR (0xa03c5c) |
371 | 371 | ||
372 | #define DBGC_IN_SAMPLE (0xa03c00) | 372 | #define DBGC_IN_SAMPLE (0xa03c00) |
373 | #define DBGC_OUT_CTRL (0xa03c0c) | ||
373 | 374 | ||
374 | /* enable the ID buf for read */ | 375 | /* enable the ID buf for read */ |
375 | #define WFPM_PS_CTL_CLR 0xA0300C | 376 | #define WFPM_PS_CTL_CLR 0xA0300C |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h index 1b7d265ffb0a..a10c6aae9ab9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h | |||
@@ -307,6 +307,11 @@ enum { | |||
307 | /* Bit 1-3: LQ command color. Used to match responses to LQ commands */ | 307 | /* Bit 1-3: LQ command color. Used to match responses to LQ commands */ |
308 | #define LQ_FLAG_COLOR_POS 1 | 308 | #define LQ_FLAG_COLOR_POS 1 |
309 | #define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) | 309 | #define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) |
310 | #define LQ_FLAG_COLOR_GET(_f) (((_f) & LQ_FLAG_COLOR_MSK) >>\ | ||
311 | LQ_FLAG_COLOR_POS) | ||
312 | #define LQ_FLAGS_COLOR_INC(_c) ((((_c) + 1) << LQ_FLAG_COLOR_POS) &\ | ||
313 | LQ_FLAG_COLOR_MSK) | ||
314 | #define LQ_FLAG_COLOR_SET(_f, _c) ((_c) | ((_f) & ~LQ_FLAG_COLOR_MSK)) | ||
310 | 315 | ||
311 | /* Bit 4-5: Tx RTS BW Signalling | 316 | /* Bit 4-5: Tx RTS BW Signalling |
312 | * (0) No RTS BW signalling | 317 | * (0) No RTS BW signalling |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h index 81b98915b1a4..1360ebfdc51b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | |||
@@ -519,8 +519,11 @@ struct agg_tx_status { | |||
519 | * bit-7 invalid rate indication | 519 | * bit-7 invalid rate indication |
520 | */ | 520 | */ |
521 | #define TX_RES_INIT_RATE_INDEX_MSK 0x0f | 521 | #define TX_RES_INIT_RATE_INDEX_MSK 0x0f |
522 | #define TX_RES_RATE_TABLE_COLOR_POS 4 | ||
522 | #define TX_RES_RATE_TABLE_COLOR_MSK 0x70 | 523 | #define TX_RES_RATE_TABLE_COLOR_MSK 0x70 |
523 | #define TX_RES_INV_RATE_INDEX_MSK 0x80 | 524 | #define TX_RES_INV_RATE_INDEX_MSK 0x80 |
525 | #define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\ | ||
526 | TX_RES_RATE_TABLE_COLOR_POS) | ||
524 | 527 | ||
525 | #define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) | 528 | #define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) |
526 | #define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4) | 529 | #define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4) |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 7b86a4f1b574..c8712e6eea74 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | |||
@@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, | |||
1002 | return 0; | 1002 | return 0; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm) | ||
1006 | { | ||
1007 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) | ||
1008 | iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); | ||
1009 | else | ||
1010 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1); | ||
1011 | } | ||
1012 | |||
1013 | int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) | 1005 | int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) |
1014 | { | 1006 | { |
1015 | u8 *ptr; | 1007 | u8 *ptr; |
@@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) | |||
1023 | /* EARLY START - firmware's configuration is hard coded */ | 1015 | /* EARLY START - firmware's configuration is hard coded */ |
1024 | if ((!mvm->fw->dbg_conf_tlv[conf_id] || | 1016 | if ((!mvm->fw->dbg_conf_tlv[conf_id] || |
1025 | !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) && | 1017 | !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) && |
1026 | conf_id == FW_DBG_START_FROM_ALIVE) { | 1018 | conf_id == FW_DBG_START_FROM_ALIVE) |
1027 | iwl_mvm_restart_early_start(mvm); | ||
1028 | return 0; | 1019 | return 0; |
1029 | } | ||
1030 | 1020 | ||
1031 | if (!mvm->fw->dbg_conf_tlv[conf_id]) | 1021 | if (!mvm->fw->dbg_conf_tlv[conf_id]) |
1032 | return -EINVAL; | 1022 | return -EINVAL; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 0f1831b41915..fd2fc46e2fe5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | |||
@@ -1040,7 +1040,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, | |||
1040 | struct iwl_mac_beacon_cmd_v6 beacon_cmd_v6; | 1040 | struct iwl_mac_beacon_cmd_v6 beacon_cmd_v6; |
1041 | struct iwl_mac_beacon_cmd_v7 beacon_cmd; | 1041 | struct iwl_mac_beacon_cmd_v7 beacon_cmd; |
1042 | } u = {}; | 1042 | } u = {}; |
1043 | struct iwl_mac_beacon_cmd beacon_cmd; | 1043 | struct iwl_mac_beacon_cmd beacon_cmd = {}; |
1044 | struct ieee80211_tx_info *info; | 1044 | struct ieee80211_tx_info *info; |
1045 | u32 beacon_skb_len; | 1045 | u32 beacon_skb_len; |
1046 | u32 rate, tx_flags; | 1046 | u32 rate, tx_flags; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 4e74a6b90e70..52f8d7a6a7dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
@@ -1730,8 +1730,11 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq); | |||
1730 | */ | 1730 | */ |
1731 | static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) | 1731 | static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) |
1732 | { | 1732 | { |
1733 | u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE : | ||
1734 | IWL_MVM_CMD_QUEUE; | ||
1735 | |||
1733 | return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) & | 1736 | return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) & |
1734 | ~BIT(IWL_MVM_CMD_QUEUE)); | 1737 | ~BIT(cmd_queue)); |
1735 | } | 1738 | } |
1736 | 1739 | ||
1737 | static inline | 1740 | static inline |
@@ -1753,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) | |||
1753 | if (!iwl_mvm_has_new_tx_api(mvm)) | 1756 | if (!iwl_mvm_has_new_tx_api(mvm)) |
1754 | iwl_free_fw_paging(mvm); | 1757 | iwl_free_fw_paging(mvm); |
1755 | mvm->ucode_loaded = false; | 1758 | mvm->ucode_loaded = false; |
1759 | mvm->fw_dbg_conf = FW_DBG_INVALID; | ||
1756 | iwl_trans_stop_device(mvm->trans); | 1760 | iwl_trans_stop_device(mvm->trans); |
1757 | } | 1761 | } |
1758 | 1762 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 9ffff6ed8133..3da5ec40aaea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) | |||
1149 | 1149 | ||
1150 | mutex_lock(&mvm->mutex); | 1150 | mutex_lock(&mvm->mutex); |
1151 | 1151 | ||
1152 | /* stop recording */ | ||
1153 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { | 1152 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { |
1153 | /* stop recording */ | ||
1154 | iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); | 1154 | iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); |
1155 | |||
1156 | iwl_mvm_fw_error_dump(mvm); | ||
1157 | |||
1158 | /* start recording again if the firmware is not crashed */ | ||
1159 | if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) && | ||
1160 | mvm->fw->dbg_dest_tlv) | ||
1161 | iwl_clear_bits_prph(mvm->trans, | ||
1162 | MON_BUFF_SAMPLE_CTL, 0x100); | ||
1155 | } else { | 1163 | } else { |
1164 | u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE); | ||
1165 | u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL); | ||
1166 | |||
1167 | /* stop recording */ | ||
1156 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); | 1168 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); |
1157 | /* wait before we collect the data till the DBGC stop */ | ||
1158 | udelay(100); | 1169 | udelay(100); |
1159 | } | 1170 | iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0); |
1171 | /* wait before we collect the data till the DBGC stop */ | ||
1172 | udelay(500); | ||
1160 | 1173 | ||
1161 | iwl_mvm_fw_error_dump(mvm); | 1174 | iwl_mvm_fw_error_dump(mvm); |
1162 | 1175 | ||
1163 | /* start recording again if the firmware is not crashed */ | 1176 | /* start recording again if the firmware is not crashed */ |
1164 | WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && | 1177 | if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) && |
1165 | mvm->fw->dbg_dest_tlv && | 1178 | mvm->fw->dbg_dest_tlv) { |
1166 | iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); | 1179 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample); |
1180 | iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl); | ||
1181 | } | ||
1182 | } | ||
1167 | 1183 | ||
1168 | mutex_unlock(&mvm->mutex); | 1184 | mutex_unlock(&mvm->mutex); |
1169 | 1185 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 7788eefcd2bd..aa785cf3cf68 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
5 | * Copyright(c) 2016 Intel Deutschland GmbH | 5 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of version 2 of the GNU General Public License as | 8 | * 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 | rs_get_lower_rate_in_column(lq_sta, rate); | 1083 | rs_get_lower_rate_in_column(lq_sta, rate); |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /* Check if both rates are identical | ||
1087 | * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B | ||
1088 | * with a rate indicating STBC/BFER and ANT_AB. | ||
1089 | */ | ||
1090 | static inline bool rs_rate_equal(struct rs_rate *a, | ||
1091 | struct rs_rate *b, | ||
1092 | bool allow_ant_mismatch) | ||
1093 | |||
1094 | { | ||
1095 | bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) && | ||
1096 | (a->bfer == b->bfer); | ||
1097 | |||
1098 | if (allow_ant_mismatch) { | ||
1099 | if (a->stbc || a->bfer) { | ||
1100 | WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d", | ||
1101 | a->stbc, a->bfer, a->ant); | ||
1102 | ant_match |= (b->ant == ANT_A || b->ant == ANT_B); | ||
1103 | } else if (b->stbc || b->bfer) { | ||
1104 | WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d", | ||
1105 | b->stbc, b->bfer, b->ant); | ||
1106 | ant_match |= (a->ant == ANT_A || a->ant == ANT_B); | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) && | ||
1111 | (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match; | ||
1112 | } | ||
1113 | |||
1114 | /* Check if both rates share the same column */ | 1086 | /* Check if both rates share the same column */ |
1115 | static inline bool rs_rate_column_match(struct rs_rate *a, | 1087 | static inline bool rs_rate_column_match(struct rs_rate *a, |
1116 | struct rs_rate *b) | 1088 | struct rs_rate *b) |
@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
1182 | u32 lq_hwrate; | 1154 | u32 lq_hwrate; |
1183 | struct rs_rate lq_rate, tx_resp_rate; | 1155 | struct rs_rate lq_rate, tx_resp_rate; |
1184 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; | 1156 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; |
1185 | u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0]; | 1157 | u32 tlc_info = (uintptr_t)info->status.status_driver_data[0]; |
1158 | u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK; | ||
1159 | u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info); | ||
1186 | u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; | 1160 | u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; |
1187 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 1161 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
1188 | struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; | 1162 | struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; |
1189 | bool allow_ant_mismatch = fw_has_api(&mvm->fw->ucode_capa, | ||
1190 | IWL_UCODE_TLV_API_LQ_SS_PARAMS); | ||
1191 | 1163 | ||
1192 | /* Treat uninitialized rate scaling data same as non-existing. */ | 1164 | /* Treat uninitialized rate scaling data same as non-existing. */ |
1193 | if (!lq_sta) { | 1165 | if (!lq_sta) { |
@@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
1262 | rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); | 1234 | rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); |
1263 | 1235 | ||
1264 | /* Here we actually compare this rate to the latest LQ command */ | 1236 | /* Here we actually compare this rate to the latest LQ command */ |
1265 | if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) { | 1237 | if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { |
1266 | IWL_DEBUG_RATE(mvm, | 1238 | IWL_DEBUG_RATE(mvm, |
1267 | "initial tx resp rate 0x%x does not match 0x%x\n", | 1239 | "tx resp color 0x%x does not match 0x%x\n", |
1268 | tx_resp_hwrate, lq_hwrate); | 1240 | lq_color, LQ_FLAG_COLOR_GET(table->flags)); |
1269 | 1241 | ||
1270 | /* | 1242 | /* |
1271 | * Since rates mis-match, the last LQ command may have failed. | 1243 | * 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 | u8 valid_tx_ant = 0; | 3298 | u8 valid_tx_ant = 0; |
3327 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; | 3299 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; |
3328 | bool toggle_ant = false; | 3300 | bool toggle_ant = false; |
3301 | u32 color; | ||
3329 | 3302 | ||
3330 | memcpy(&rate, initial_rate, sizeof(rate)); | 3303 | memcpy(&rate, initial_rate, sizeof(rate)); |
3331 | 3304 | ||
@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, | |||
3380 | num_rates, num_retries, valid_tx_ant, | 3353 | num_rates, num_retries, valid_tx_ant, |
3381 | toggle_ant); | 3354 | toggle_ant); |
3382 | 3355 | ||
3356 | /* update the color of the LQ command (as a counter at bits 1-3) */ | ||
3357 | color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); | ||
3358 | lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); | ||
3383 | } | 3359 | } |
3384 | 3360 | ||
3385 | struct rs_bfer_active_iter_data { | 3361 | struct rs_bfer_active_iter_data { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index ee207f2c0a90..3abde1cb0303 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2015 Intel Mobile Communications GmbH | 4 | * Copyright(c) 2015 Intel Mobile Communications GmbH |
5 | * Copyright(c) 2017 Intel Deutschland GmbH | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2 of the GNU General Public License as | 8 | * under the terms of version 2 of the GNU General Public License as |
@@ -357,6 +358,20 @@ struct iwl_lq_sta { | |||
357 | } pers; | 358 | } pers; |
358 | }; | 359 | }; |
359 | 360 | ||
361 | /* ieee80211_tx_info's status_driver_data[0] is packed with lq color and txp | ||
362 | * Note, it's iwlmvm <-> mac80211 interface. | ||
363 | * bits 0-7: reduced tx power | ||
364 | * bits 8-10: LQ command's color | ||
365 | */ | ||
366 | #define RS_DRV_DATA_TXP_MSK 0xff | ||
367 | #define RS_DRV_DATA_LQ_COLOR_POS 8 | ||
368 | #define RS_DRV_DATA_LQ_COLOR_MSK (7 << RS_DRV_DATA_LQ_COLOR_POS) | ||
369 | #define RS_DRV_DATA_LQ_COLOR_GET(_f) (((_f) & RS_DRV_DATA_LQ_COLOR_MSK) >>\ | ||
370 | RS_DRV_DATA_LQ_COLOR_POS) | ||
371 | #define RS_DRV_DATA_PACK(_c, _p) ((void *)(uintptr_t)\ | ||
372 | (((uintptr_t)_p) |\ | ||
373 | ((_c) << RS_DRV_DATA_LQ_COLOR_POS))) | ||
374 | |||
360 | /* Initialize station's rate scaling information after adding station */ | 375 | /* Initialize station's rate scaling information after adding station */ |
361 | void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 376 | void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
362 | enum nl80211_band band, bool init); | 377 | enum nl80211_band band, bool init); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index f5c786ddc526..614d67810d05 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c | |||
@@ -2120,7 +2120,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
2120 | if (!iwl_mvm_is_dqa_supported(mvm)) | 2120 | if (!iwl_mvm_is_dqa_supported(mvm)) |
2121 | return 0; | 2121 | return 0; |
2122 | 2122 | ||
2123 | if (WARN_ON(vif->type != NL80211_IFTYPE_AP)) | 2123 | if (WARN_ON(vif->type != NL80211_IFTYPE_AP && |
2124 | vif->type != NL80211_IFTYPE_ADHOC)) | ||
2124 | return -ENOTSUPP; | 2125 | return -ENOTSUPP; |
2125 | 2126 | ||
2126 | /* | 2127 | /* |
@@ -2155,6 +2156,16 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
2155 | mvmvif->cab_queue = queue; | 2156 | mvmvif->cab_queue = queue; |
2156 | } else if (!fw_has_api(&mvm->fw->ucode_capa, | 2157 | } else if (!fw_has_api(&mvm->fw->ucode_capa, |
2157 | IWL_UCODE_TLV_API_STA_TYPE)) { | 2158 | IWL_UCODE_TLV_API_STA_TYPE)) { |
2159 | /* | ||
2160 | * In IBSS, ieee80211_check_queues() sets the cab_queue to be | ||
2161 | * invalid, so make sure we use the queue we want. | ||
2162 | * Note that this is done here as we want to avoid making DQA | ||
2163 | * changes in mac80211 layer. | ||
2164 | */ | ||
2165 | if (vif->type == NL80211_IFTYPE_ADHOC) { | ||
2166 | vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE; | ||
2167 | mvmvif->cab_queue = vif->cab_queue; | ||
2168 | } | ||
2158 | iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0, | 2169 | iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0, |
2159 | &cfg, timeout); | 2170 | &cfg, timeout); |
2160 | } | 2171 | } |
@@ -3321,18 +3332,15 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | |||
3321 | 3332 | ||
3322 | /* Get the station from the mvm local station table */ | 3333 | /* Get the station from the mvm local station table */ |
3323 | mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta); | 3334 | mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta); |
3324 | if (!mvm_sta) { | 3335 | if (mvm_sta) |
3325 | IWL_ERR(mvm, "Failed to find station\n"); | 3336 | sta_id = mvm_sta->sta_id; |
3326 | return -EINVAL; | ||
3327 | } | ||
3328 | sta_id = mvm_sta->sta_id; | ||
3329 | 3337 | ||
3330 | IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", | 3338 | IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", |
3331 | keyconf->keyidx, sta_id); | 3339 | keyconf->keyidx, sta_id); |
3332 | 3340 | ||
3333 | if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || | 3341 | if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || |
3334 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || | 3342 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || |
3335 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) | 3343 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)) |
3336 | return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); | 3344 | return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); |
3337 | 3345 | ||
3338 | if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { | 3346 | if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index 2716cb5483bf..ad62b67dceb2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h | |||
@@ -313,6 +313,7 @@ enum iwl_mvm_agg_state { | |||
313 | * This is basically (last acked packet++). | 313 | * This is basically (last acked packet++). |
314 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the | 314 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the |
315 | * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA). | 315 | * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA). |
316 | * @lq_color: the color of the LQ command as it appears in tx response. | ||
316 | * @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed. | 317 | * @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed. |
317 | * @state: state of the BA agreement establishment / tear down. | 318 | * @state: state of the BA agreement establishment / tear down. |
318 | * @txq_id: Tx queue used by the BA session / DQA | 319 | * @txq_id: Tx queue used by the BA session / DQA |
@@ -331,6 +332,7 @@ struct iwl_mvm_tid_data { | |||
331 | u16 next_reclaimed; | 332 | u16 next_reclaimed; |
332 | /* The rest is Tx AGG related */ | 333 | /* The rest is Tx AGG related */ |
333 | u32 rate_n_flags; | 334 | u32 rate_n_flags; |
335 | u8 lq_color; | ||
334 | bool amsdu_in_ampdu_allowed; | 336 | bool amsdu_in_ampdu_allowed; |
335 | enum iwl_mvm_agg_state state; | 337 | enum iwl_mvm_agg_state state; |
336 | u16 txq_id; | 338 | u16 txq_id; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index f9cbd197246f..506d58104e1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c | |||
@@ -790,11 +790,13 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev, | |||
790 | struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata); | 790 | struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata); |
791 | int ret; | 791 | int ret; |
792 | 792 | ||
793 | if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) | ||
794 | return -EIO; | ||
795 | |||
796 | mutex_lock(&mvm->mutex); | 793 | mutex_lock(&mvm->mutex); |
797 | 794 | ||
795 | if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) { | ||
796 | ret = -EIO; | ||
797 | goto unlock; | ||
798 | } | ||
799 | |||
798 | if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) { | 800 | if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) { |
799 | ret = -EINVAL; | 801 | ret = -EINVAL; |
800 | goto unlock; | 802 | goto unlock; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index bcaceb64a6e8..f21901cd4a4f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
@@ -1323,6 +1323,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
1323 | struct iwl_mvm_sta *mvmsta; | 1323 | struct iwl_mvm_sta *mvmsta; |
1324 | struct sk_buff_head skbs; | 1324 | struct sk_buff_head skbs; |
1325 | u8 skb_freed = 0; | 1325 | u8 skb_freed = 0; |
1326 | u8 lq_color; | ||
1326 | u16 next_reclaimed, seq_ctl; | 1327 | u16 next_reclaimed, seq_ctl; |
1327 | bool is_ndp = false; | 1328 | bool is_ndp = false; |
1328 | 1329 | ||
@@ -1405,8 +1406,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
1405 | info->status.tx_time = | 1406 | info->status.tx_time = |
1406 | le16_to_cpu(tx_resp->wireless_media_time); | 1407 | le16_to_cpu(tx_resp->wireless_media_time); |
1407 | BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); | 1408 | BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); |
1409 | lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); | ||
1408 | info->status.status_driver_data[0] = | 1410 | info->status.status_driver_data[0] = |
1409 | (void *)(uintptr_t)tx_resp->reduced_tpc; | 1411 | RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc); |
1410 | 1412 | ||
1411 | ieee80211_tx_status(mvm->hw, skb); | 1413 | ieee80211_tx_status(mvm->hw, skb); |
1412 | } | 1414 | } |
@@ -1638,6 +1640,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, | |||
1638 | le32_to_cpu(tx_resp->initial_rate); | 1640 | le32_to_cpu(tx_resp->initial_rate); |
1639 | mvmsta->tid_data[tid].tx_time = | 1641 | mvmsta->tid_data[tid].tx_time = |
1640 | le16_to_cpu(tx_resp->wireless_media_time); | 1642 | le16_to_cpu(tx_resp->wireless_media_time); |
1643 | mvmsta->tid_data[tid].lq_color = | ||
1644 | (tx_resp->tlc_info & TX_RES_RATE_TABLE_COLOR_MSK) >> | ||
1645 | TX_RES_RATE_TABLE_COLOR_POS; | ||
1641 | } | 1646 | } |
1642 | 1647 | ||
1643 | rcu_read_unlock(); | 1648 | rcu_read_unlock(); |
@@ -1707,6 +1712,11 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, | |||
1707 | iwl_mvm_check_ratid_empty(mvm, sta, tid); | 1712 | iwl_mvm_check_ratid_empty(mvm, sta, tid); |
1708 | 1713 | ||
1709 | freed = 0; | 1714 | freed = 0; |
1715 | |||
1716 | /* pack lq color from tid_data along the reduced txp */ | ||
1717 | ba_info->status.status_driver_data[0] = | ||
1718 | RS_DRV_DATA_PACK(tid_data->lq_color, | ||
1719 | ba_info->status.status_driver_data[0]); | ||
1710 | ba_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; | 1720 | ba_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; |
1711 | 1721 | ||
1712 | skb_queue_walk(&reclaimed_skbs, skb) { | 1722 | skb_queue_walk(&reclaimed_skbs, skb) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 70acf850a9f1..93cbc7a69bcd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c | |||
@@ -2803,7 +2803,8 @@ static struct iwl_trans_dump_data | |||
2803 | #ifdef CONFIG_PM_SLEEP | 2803 | #ifdef CONFIG_PM_SLEEP |
2804 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | 2804 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) |
2805 | { | 2805 | { |
2806 | if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3) | 2806 | if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && |
2807 | (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) | ||
2807 | return iwl_pci_fw_enter_d0i3(trans); | 2808 | return iwl_pci_fw_enter_d0i3(trans); |
2808 | 2809 | ||
2809 | return 0; | 2810 | return 0; |
@@ -2811,7 +2812,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | |||
2811 | 2812 | ||
2812 | static void iwl_trans_pcie_resume(struct iwl_trans *trans) | 2813 | static void iwl_trans_pcie_resume(struct iwl_trans *trans) |
2813 | { | 2814 | { |
2814 | if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3) | 2815 | if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && |
2816 | (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) | ||
2815 | iwl_pci_fw_exit_d0i3(trans); | 2817 | iwl_pci_fw_exit_d0i3(trans); |
2816 | } | 2818 | } |
2817 | #endif /* CONFIG_PM_SLEEP */ | 2819 | #endif /* CONFIG_PM_SLEEP */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 9fb46a6f47cf..9c9bfbbabdf1 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | |||
@@ -906,7 +906,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | |||
906 | 906 | ||
907 | if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) { | 907 | if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) { |
908 | ret = -EINVAL; | 908 | ret = -EINVAL; |
909 | goto error; | 909 | goto error_free_resp; |
910 | } | 910 | } |
911 | 911 | ||
912 | rsp = (void *)hcmd.resp_pkt->data; | 912 | rsp = (void *)hcmd.resp_pkt->data; |
@@ -915,13 +915,13 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | |||
915 | if (qid > ARRAY_SIZE(trans_pcie->txq)) { | 915 | if (qid > ARRAY_SIZE(trans_pcie->txq)) { |
916 | WARN_ONCE(1, "queue index %d unsupported", qid); | 916 | WARN_ONCE(1, "queue index %d unsupported", qid); |
917 | ret = -EIO; | 917 | ret = -EIO; |
918 | goto error; | 918 | goto error_free_resp; |
919 | } | 919 | } |
920 | 920 | ||
921 | if (test_and_set_bit(qid, trans_pcie->queue_used)) { | 921 | if (test_and_set_bit(qid, trans_pcie->queue_used)) { |
922 | WARN_ONCE(1, "queue %d already used", qid); | 922 | WARN_ONCE(1, "queue %d already used", qid); |
923 | ret = -EIO; | 923 | ret = -EIO; |
924 | goto error; | 924 | goto error_free_resp; |
925 | } | 925 | } |
926 | 926 | ||
927 | txq->id = qid; | 927 | txq->id = qid; |
@@ -934,8 +934,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | |||
934 | (txq->write_ptr) | (qid << 16)); | 934 | (txq->write_ptr) | (qid << 16)); |
935 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); | 935 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); |
936 | 936 | ||
937 | iwl_free_resp(&hcmd); | ||
937 | return qid; | 938 | return qid; |
938 | 939 | ||
940 | error_free_resp: | ||
941 | iwl_free_resp(&hcmd); | ||
939 | error: | 942 | error: |
940 | iwl_pcie_gen2_txq_free_memory(trans, txq); | 943 | iwl_pcie_gen2_txq_free_memory(trans, txq); |
941 | return ret; | 944 | return ret; |