Commit a44acf90 authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-for-davem-2019-04-15' of...

Merge tag 'wireless-drivers-for-davem-2019-04-15' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

Kalle Valo says:

====================
wireless-drivers fixes for 5.1

Second set of fixes for 5.1.

iwlwifi

* add some new PCI IDs (plus a struct name change they depend on)

* fix crypto with new devices, namely 22560 and above

* fix for a potential deadlock in the TX path

* a fix for offloaded rate-control

* support new PCI HW IDs which use a new FW

mt76

* fix lock initialisation and a possible deadlock

* aggregation fixes

rt2x00

* fix sequence numbering during retransmits
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 73248801 832bc250
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
#define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-" #define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-"
#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-"
#define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0-"
#define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-" #define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-"
#define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-" #define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-"
#define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-" #define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-"
...@@ -105,8 +106,8 @@ ...@@ -105,8 +106,8 @@
IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \ #define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \
IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode" IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode"
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ #define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" IWL_QUZ_A_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \ #define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \
...@@ -235,8 +236,20 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = { ...@@ -235,8 +236,20 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
}; };
const struct iwl_cfg iwl22260_2ax_cfg = { const struct iwl_cfg iwl_ax101_cfg_quz_hr = {
.name = "Intel(R) Wireless-AX 22260", .name = "Intel(R) Wi-Fi 6 AX101",
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
* This device doesn't support receiving BlockAck with a large bitmap
* so we need to restrict the size of transmitted aggregation to the
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
};
const struct iwl_cfg iwl_ax200_cfg_cc = {
.name = "Intel(R) Wi-Fi 6 AX200 160MHz",
.fw_name_pre = IWL_CC_A_FW_PRE, .fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
...@@ -249,7 +262,7 @@ const struct iwl_cfg iwl22260_2ax_cfg = { ...@@ -249,7 +262,7 @@ const struct iwl_cfg iwl22260_2ax_cfg = {
}; };
const struct iwl_cfg killer1650x_2ax_cfg = { const struct iwl_cfg killer1650x_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (200NGW)", .name = "Killer(R) Wi-Fi 6 AX1650x 160MHz Wireless Network Adapter (200NGW)",
.fw_name_pre = IWL_CC_A_FW_PRE, .fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
...@@ -262,7 +275,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = { ...@@ -262,7 +275,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
}; };
const struct iwl_cfg killer1650w_2ax_cfg = { const struct iwl_cfg killer1650w_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (200D2W)", .name = "Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)",
.fw_name_pre = IWL_CC_A_FW_PRE, .fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
...@@ -328,7 +341,7 @@ const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = { ...@@ -328,7 +341,7 @@ const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = {
}; };
const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = {
.name = "Killer(R) Wireless-AX 1650i Wireless Network Adapter (22560NGW)", .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
.fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
...@@ -340,7 +353,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { ...@@ -340,7 +353,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = {
}; };
const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
.name = "Killer(R) Wireless-AX 1650s Wireless Network Adapter (22560D2W)", .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
.fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
...@@ -444,6 +457,7 @@ MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); ...@@ -444,6 +457,7 @@ MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
......
...@@ -1614,6 +1614,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, ...@@ -1614,6 +1614,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
if (!range) { if (!range) {
IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n", IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type); le32_to_cpu(reg->region_id), type);
memset(*data, 0, le32_to_cpu((*data)->len));
return; return;
} }
...@@ -1623,6 +1624,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, ...@@ -1623,6 +1624,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
if (range_size < 0) { if (range_size < 0) {
IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n", IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type); le32_to_cpu(reg->region_id), type);
memset(*data, 0, le32_to_cpu((*data)->len));
return; return;
} }
range = range + range_size; range = range + range_size;
...@@ -1807,12 +1809,12 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, ...@@ -1807,12 +1809,12 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
trigger = fwrt->dump.active_trigs[id].trig; trigger = fwrt->dump.active_trigs[id].trig;
size = sizeof(*dump_file); size = iwl_fw_ini_get_trigger_len(fwrt, trigger);
size += iwl_fw_ini_get_trigger_len(fwrt, trigger);
if (!size) if (!size)
return NULL; return NULL;
size += sizeof(*dump_file);
dump_file = vzalloc(size); dump_file = vzalloc(size);
if (!dump_file) if (!dump_file)
return NULL; return NULL;
...@@ -1942,14 +1944,10 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt, ...@@ -1942,14 +1944,10 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
iwl_dump_error_desc->len = 0; iwl_dump_error_desc->len = 0;
ret = iwl_fw_dbg_collect_desc(fwrt, iwl_dump_error_desc, false, 0); ret = iwl_fw_dbg_collect_desc(fwrt, iwl_dump_error_desc, false, 0);
if (ret) { if (ret)
kfree(iwl_dump_error_desc); kfree(iwl_dump_error_desc);
} else { else
set_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status); iwl_trans_sync_nmi(fwrt->trans);
/* trigger nmi to halt the fw */
iwl_force_nmi(fwrt->trans);
}
return ret; return ret;
} }
...@@ -2489,22 +2487,6 @@ IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); ...@@ -2489,22 +2487,6 @@ IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt) void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt)
{ {
/* if the wait event timeout elapses instead of wake up then
* the driver did not receive NMI interrupt and can not assume the FW
* is halted
*/
int ret = wait_event_timeout(fwrt->trans->fw_halt_waitq,
!test_bit(STATUS_FW_WAIT_DUMP,
&fwrt->trans->status),
msecs_to_jiffies(2000));
if (!ret) {
/* failed to receive NMI interrupt, assuming the FW is stuck */
set_bit(STATUS_FW_ERROR, &fwrt->trans->status);
clear_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status);
}
/* Assuming the op mode mutex is held at this point */
iwl_fw_dbg_collect_sync(fwrt); iwl_fw_dbg_collect_sync(fwrt);
iwl_trans_stop_device(fwrt->trans); iwl_trans_stop_device(fwrt->trans);
......
...@@ -76,7 +76,6 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, ...@@ -76,7 +76,6 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
fwrt->ops_ctx = ops_ctx; fwrt->ops_ctx = ops_ctx;
INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk); INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk);
iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
init_waitqueue_head(&fwrt->trans->fw_halt_waitq);
} }
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
......
...@@ -549,8 +549,9 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr; ...@@ -549,8 +549,9 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
extern const struct iwl_cfg iwl22000_2ac_cfg_jf; extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
extern const struct iwl_cfg iwl22000_2ax_cfg_hr; extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
extern const struct iwl_cfg iwl22260_2ax_cfg; extern const struct iwl_cfg iwl_ax200_cfg_cc;
extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0; extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0; extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0;
extern const struct iwl_cfg killer1650x_2ax_cfg; extern const struct iwl_cfg killer1650x_2ax_cfg;
......
...@@ -327,6 +327,7 @@ enum { ...@@ -327,6 +327,7 @@ enum {
#define CSR_HW_REV_TYPE_NONE (0x00001F0) #define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360) #define CSR_HW_REV_TYPE_QNJ (0x0000360)
#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364) #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
#define CSR_HW_REV_TYPE_QUZ (0x0000354)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340) #define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
#define CSR_HW_REV_TYPE_SO (0x0000370) #define CSR_HW_REV_TYPE_SO (0x0000370)
#define CSR_HW_REV_TYPE_TY (0x0000420) #define CSR_HW_REV_TYPE_TY (0x0000420)
......
...@@ -338,7 +338,6 @@ enum iwl_d3_status { ...@@ -338,7 +338,6 @@ enum iwl_d3_status {
* are sent * are sent
* @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
* @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation * @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
* @STATUS_FW_WAIT_DUMP: if set, wait until cleared before collecting dump
*/ */
enum iwl_trans_status { enum iwl_trans_status {
STATUS_SYNC_HCMD_ACTIVE, STATUS_SYNC_HCMD_ACTIVE,
...@@ -351,7 +350,6 @@ enum iwl_trans_status { ...@@ -351,7 +350,6 @@ enum iwl_trans_status {
STATUS_TRANS_GOING_IDLE, STATUS_TRANS_GOING_IDLE,
STATUS_TRANS_IDLE, STATUS_TRANS_IDLE,
STATUS_TRANS_DEAD, STATUS_TRANS_DEAD,
STATUS_FW_WAIT_DUMP,
}; };
static inline int static inline int
...@@ -618,6 +616,7 @@ struct iwl_trans_ops { ...@@ -618,6 +616,7 @@ struct iwl_trans_ops {
struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans, struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
u32 dump_mask); u32 dump_mask);
void (*debugfs_cleanup)(struct iwl_trans *trans); void (*debugfs_cleanup)(struct iwl_trans *trans);
void (*sync_nmi)(struct iwl_trans *trans);
}; };
/** /**
...@@ -831,7 +830,6 @@ struct iwl_trans { ...@@ -831,7 +830,6 @@ struct iwl_trans {
u32 lmac_error_event_table[2]; u32 lmac_error_event_table[2];
u32 umac_error_event_table; u32 umac_error_event_table;
unsigned int error_event_table_tlv_status; unsigned int error_event_table_tlv_status;
wait_queue_head_t fw_halt_waitq;
/* pointer to trans specific struct */ /* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */ /*Ensure that this pointer will always be aligned to sizeof pointer */
...@@ -1239,10 +1237,12 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans) ...@@ -1239,10 +1237,12 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans)
/* prevent double restarts due to the same erroneous FW */ /* prevent double restarts due to the same erroneous FW */
if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status))
iwl_op_mode_nic_error(trans->op_mode); iwl_op_mode_nic_error(trans->op_mode);
}
if (test_and_clear_bit(STATUS_FW_WAIT_DUMP, &trans->status)) static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
wake_up(&trans->fw_halt_waitq); {
if (trans->ops->sync_nmi)
trans->ops->sync_nmi(trans);
} }
/***************************************************** /*****************************************************
......
...@@ -2714,9 +2714,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, ...@@ -2714,9 +2714,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
iwl_mvm_mac_ctxt_remove(mvm, vif); iwl_mvm_mac_ctxt_remove(mvm, vif);
kfree(mvmvif->ap_wep_key);
mvmvif->ap_wep_key = NULL;
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
} }
...@@ -3183,24 +3180,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, ...@@ -3183,24 +3180,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
ret = iwl_mvm_update_sta(mvm, vif, sta); ret = iwl_mvm_update_sta(mvm, vif, sta);
} else if (old_state == IEEE80211_STA_ASSOC && } else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTHORIZED) { new_state == IEEE80211_STA_AUTHORIZED) {
/* if wep is used, need to set the key for the station now */ ret = 0;
if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) {
mvm_sta->wep_key =
kmemdup(mvmvif->ap_wep_key,
sizeof(*mvmvif->ap_wep_key) +
mvmvif->ap_wep_key->keylen,
GFP_KERNEL);
if (!mvm_sta->wep_key) {
ret = -ENOMEM;
goto out_unlock;
}
ret = iwl_mvm_set_sta_key(mvm, vif, sta,
mvm_sta->wep_key,
STA_KEY_IDX_INVALID);
} else {
ret = 0;
}
/* we don't support TDLS during DCM */ /* we don't support TDLS during DCM */
if (iwl_mvm_phy_ctx_count(mvm) > 1) if (iwl_mvm_phy_ctx_count(mvm) > 1)
...@@ -3242,17 +3222,6 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, ...@@ -3242,17 +3222,6 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
NL80211_TDLS_DISABLE_LINK); NL80211_TDLS_DISABLE_LINK);
} }
/* Remove STA key if this is an AP using WEP */
if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) {
int rm_ret = iwl_mvm_remove_sta_key(mvm, vif, sta,
mvm_sta->wep_key);
if (!ret)
ret = rm_ret;
kfree(mvm_sta->wep_key);
mvm_sta->wep_key = NULL;
}
if (unlikely(ret && if (unlikely(ret &&
test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
&mvm->status))) &mvm->status)))
...@@ -3289,6 +3258,13 @@ static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, ...@@ -3289,6 +3258,13 @@ static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u32 changed) struct ieee80211_sta *sta, u32 changed)
{ {
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (changed & (IEEE80211_RC_BW_CHANGED |
IEEE80211_RC_SUPP_RATES_CHANGED |
IEEE80211_RC_NSS_CHANGED))
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
true);
if (vif->type == NL80211_IFTYPE_STATION && if (vif->type == NL80211_IFTYPE_STATION &&
changed & IEEE80211_RC_NSS_CHANGED) changed & IEEE80211_RC_NSS_CHANGED)
...@@ -3439,20 +3415,12 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, ...@@ -3439,20 +3415,12 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
break; break;
case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_WEP104:
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_STATION)
struct iwl_mvm_vif *mvmvif = break;
iwl_mvm_vif_from_mac80211(vif); if (iwl_mvm_has_new_tx_api(mvm))
return -EOPNOTSUPP;
mvmvif->ap_wep_key = kmemdup(key, /* support HW crypto on TX */
sizeof(*key) + key->keylen, return 0;
GFP_KERNEL);
if (!mvmvif->ap_wep_key)
return -ENOMEM;
}
if (vif->type != NL80211_IFTYPE_STATION)
return 0;
break;
default: default:
/* currently FW supports only one optional cipher scheme */ /* currently FW supports only one optional cipher scheme */
if (hw->n_cipher_schemes && if (hw->n_cipher_schemes &&
...@@ -3540,12 +3508,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, ...@@ -3540,12 +3508,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset); ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset);
if (ret) { if (ret) {
IWL_WARN(mvm, "set key failed\n"); IWL_WARN(mvm, "set key failed\n");
key->hw_key_idx = STA_KEY_IDX_INVALID;
/* /*
* can't add key for RX, but we don't need it * can't add key for RX, but we don't need it
* in the device for TX so still return 0 * in the device for TX so still return 0,
* unless we have new TX API where we cannot
* put key material into the TX_CMD
*/ */
key->hw_key_idx = STA_KEY_IDX_INVALID; if (iwl_mvm_has_new_tx_api(mvm))
ret = 0; ret = -EOPNOTSUPP;
else
ret = 0;
} }
break; break;
......
...@@ -498,7 +498,6 @@ struct iwl_mvm_vif { ...@@ -498,7 +498,6 @@ struct iwl_mvm_vif {
netdev_features_t features; netdev_features_t features;
struct iwl_probe_resp_data __rcu *probe_resp_data; struct iwl_probe_resp_data __rcu *probe_resp_data;
struct ieee80211_key_conf *ap_wep_key;
}; };
static inline struct iwl_mvm_vif * static inline struct iwl_mvm_vif *
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2015 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2015 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation * Copyright(c) 2018 - 2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2015 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2015 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -1399,7 +1399,9 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk) ...@@ -1399,7 +1399,9 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, tid); iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, tid);
list_del_init(&mvmtxq->list); list_del_init(&mvmtxq->list);
local_bh_disable();
iwl_mvm_mac_itxq_xmit(mvm->hw, txq); iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
local_bh_enable();
} }
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
...@@ -2333,21 +2335,6 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -2333,21 +2335,6 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
iwl_mvm_enable_txq(mvm, NULL, mvmvif->cab_queue, 0, &cfg, iwl_mvm_enable_txq(mvm, NULL, mvmvif->cab_queue, 0, &cfg,
timeout); timeout);
if (mvmvif->ap_wep_key) {
u8 key_offset = iwl_mvm_set_fw_key_idx(mvm);
__set_bit(key_offset, mvm->fw_key_table);
if (key_offset == STA_KEY_IDX_INVALID)
return -ENOSPC;
ret = iwl_mvm_send_sta_key(mvm, mvmvif->mcast_sta.sta_id,
mvmvif->ap_wep_key, true, 0, NULL, 0,
key_offset, 0);
if (ret)
return ret;
}
return 0; return 0;
} }
...@@ -2419,28 +2406,6 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -2419,28 +2406,6 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0); iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0);
if (mvmvif->ap_wep_key) {
int i;
if (!__test_and_clear_bit(mvmvif->ap_wep_key->hw_key_idx,
mvm->fw_key_table)) {
IWL_ERR(mvm, "offset %d not used in fw key table.\n",
mvmvif->ap_wep_key->hw_key_idx);
return -ENOENT;
}
/* track which key was deleted last */
for (i = 0; i < STA_KEY_MAX_NUM; i++) {
if (mvm->fw_key_deleted[i] < U8_MAX)
mvm->fw_key_deleted[i]++;
}
mvm->fw_key_deleted[mvmvif->ap_wep_key->hw_key_idx] = 0;
ret = __iwl_mvm_remove_sta_key(mvm, mvmvif->mcast_sta.sta_id,
mvmvif->ap_wep_key, true);
if (ret)
return ret;
}
ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id);
if (ret) if (ret)
IWL_WARN(mvm, "Failed sending remove station\n"); IWL_WARN(mvm, "Failed sending remove station\n");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation * Copyright(c) 2018 - 2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -394,7 +394,6 @@ struct iwl_mvm_rxq_dup_data { ...@@ -394,7 +394,6 @@ struct iwl_mvm_rxq_dup_data {
* the BA window. To be used for UAPSD only. * the BA window. To be used for UAPSD only.
* @ptk_pn: per-queue PTK PN data structures * @ptk_pn: per-queue PTK PN data structures
* @dup_data: per queue duplicate packet detection data * @dup_data: per queue duplicate packet detection data
* @wep_key: used in AP mode. Is a duplicate of the WEP key.
* @deferred_traffic_tid_map: indication bitmap of deferred traffic per-TID * @deferred_traffic_tid_map: indication bitmap of deferred traffic per-TID
* @tx_ant: the index of the antenna to use for data tx to this station. Only * @tx_ant: the index of the antenna to use for data tx to this station. Only
* used during connection establishment (e.g. for the 4 way handshake * used during connection establishment (e.g. for the 4 way handshake
...@@ -426,8 +425,6 @@ struct iwl_mvm_sta { ...@@ -426,8 +425,6 @@ struct iwl_mvm_sta {
struct iwl_mvm_key_pn __rcu *ptk_pn[4]; struct iwl_mvm_key_pn __rcu *ptk_pn[4];
struct iwl_mvm_rxq_dup_data *dup_data; struct iwl_mvm_rxq_dup_data *dup_data;
struct ieee80211_key_conf *wep_key;
u8 reserved_queue; u8 reserved_queue;
/* Temporary, until the new TLC will control the Tx protection */ /* Temporary, until the new TLC will control the Tx protection */
......
...@@ -953,14 +953,15 @@ static const struct pci_device_id iwl_hw_card_ids[] = { ...@@ -953,14 +953,15 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2723, 0x0080, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x0080, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x0084, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x0084, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x0088, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x0088, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x008C, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x008C, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x1653, killer1650w_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x1653, killer1650w_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x1654, killer1650x_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x1654, killer1650x_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x4080, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x2080, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x4088, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x4080, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x2723, 0x4088, iwl_ax200_cfg_cc)},
{IWL_PCI_DEVICE(0x1a56, 0x1653, killer1650w_2ax_cfg)}, {IWL_PCI_DEVICE(0x1a56, 0x1653, killer1650w_2ax_cfg)},
{IWL_PCI_DEVICE(0x1a56, 0x1654, killer1650x_2ax_cfg)}, {IWL_PCI_DEVICE(0x1a56, 0x1654, killer1650x_2ax_cfg)},
......
...@@ -1043,7 +1043,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) ...@@ -1043,7 +1043,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
void iwl_trans_sync_nmi(struct iwl_trans *trans); void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans); int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
......
...@@ -3318,7 +3318,8 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans) ...@@ -3318,7 +3318,8 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
.unref = iwl_trans_pcie_unref, \ .unref = iwl_trans_pcie_unref, \
.dump_data = iwl_trans_pcie_dump_data, \ .dump_data = iwl_trans_pcie_dump_data, \
.d3_suspend = iwl_trans_pcie_d3_suspend, \ .d3_suspend = iwl_trans_pcie_d3_suspend, \
.d3_resume = iwl_trans_pcie_d3_resume .d3_resume = iwl_trans_pcie_d3_resume, \
.sync_nmi = iwl_trans_pcie_sync_nmi
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
#define IWL_TRANS_PM_OPS \ #define IWL_TRANS_PM_OPS \
...@@ -3542,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3542,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
} }
} else if (cfg == &iwl_ax101_cfg_qu_hr) { } else if (cfg == &iwl_ax101_cfg_qu_hr) {
if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
trans->cfg = &iwl_ax101_cfg_qu_hr; trans->cfg = &iwl_ax101_cfg_qu_hr;
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
...@@ -3560,7 +3565,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3560,7 +3565,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
} }
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
(trans->cfg != &iwl22260_2ax_cfg || (trans->cfg != &iwl_ax200_cfg_cc ||
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) { trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
u32 hw_status; u32 hw_status;
...@@ -3637,7 +3642,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3637,7 +3642,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
return ERR_PTR(ret); return ERR_PTR(ret);
} }
void iwl_trans_sync_nmi(struct iwl_trans *trans) void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
{ {
unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT; unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
......
...@@ -965,7 +965,7 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans, ...@@ -965,7 +965,7 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
cmd_str); cmd_str);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
iwl_trans_sync_nmi(trans); iwl_trans_pcie_sync_nmi(trans);
goto cancel; goto cancel;
} }
......
...@@ -1960,7 +1960,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, ...@@ -1960,7 +1960,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
iwl_get_cmd_string(trans, cmd->id)); iwl_get_cmd_string(trans, cmd->id));
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
iwl_trans_sync_nmi(trans); iwl_trans_pcie_sync_nmi(trans);
goto cancel; goto cancel;
} }
......
...@@ -510,6 +510,8 @@ int mt7603_register_device(struct mt7603_dev *dev) ...@@ -510,6 +510,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
bus_ops->rmw = mt7603_rmw; bus_ops->rmw = mt7603_rmw;
dev->mt76.bus = bus_ops; dev->mt76.bus = bus_ops;
spin_lock_init(&dev->ps_lock);
INIT_DELAYED_WORK(&dev->mac_work, mt7603_mac_work); INIT_DELAYED_WORK(&dev->mac_work, mt7603_mac_work);
tasklet_init(&dev->pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet, tasklet_init(&dev->pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet,
(unsigned long)dev); (unsigned long)dev);
......
...@@ -343,7 +343,7 @@ void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid) ...@@ -343,7 +343,7 @@ void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid)
MT_BA_CONTROL_1_RESET)); MT_BA_CONTROL_1_RESET));
} }
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn, void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid,
int ba_size) int ba_size)
{ {
u32 addr = mt7603_wtbl2_addr(wcid); u32 addr = mt7603_wtbl2_addr(wcid);
...@@ -358,43 +358,6 @@ void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn, ...@@ -358,43 +358,6 @@ void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn,
mt76_clear(dev, addr + (15 * 4), tid_mask); mt76_clear(dev, addr + (15 * 4), tid_mask);
return; return;
} }
mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
mt7603_mac_stop(dev);
switch (tid) {
case 0:
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID0_SN, ssn);
break;
case 1:
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID1_SN, ssn);
break;
case 2:
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID2_SN_LO,
ssn);
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID2_SN_HI,
ssn >> 8);
break;
case 3:
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID3_SN, ssn);
break;
case 4:
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID4_SN, ssn);
break;
case 5:
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID5_SN_LO,
ssn);
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID5_SN_HI,
ssn >> 4);
break;
case 6:
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID6_SN, ssn);
break;
case 7:
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID7_SN, ssn);
break;
}
mt7603_wtbl_update(dev, wcid, MT_WTBL_UPDATE_WTBL2);
mt7603_mac_start(dev);
for (i = 7; i > 0; i--) { for (i = 7; i > 0; i--) {
if (ba_size >= MT_AGG_SIZE_LIMIT(i)) if (ba_size >= MT_AGG_SIZE_LIMIT(i))
...@@ -827,6 +790,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi, ...@@ -827,6 +790,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0]; struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
struct ieee80211_vif *vif = info->control.vif; struct ieee80211_vif *vif = info->control.vif;
struct mt7603_vif *mvif; struct mt7603_vif *mvif;
int wlan_idx; int wlan_idx;
...@@ -834,6 +798,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi, ...@@ -834,6 +798,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
int tx_count = 8; int tx_count = 8;
u8 frame_type, frame_subtype; u8 frame_type, frame_subtype;
u16 fc = le16_to_cpu(hdr->frame_control); u16 fc = le16_to_cpu(hdr->frame_control);
u16 seqno = 0;
u8 vif_idx = 0; u8 vif_idx = 0;
u32 val; u32 val;
u8 bw; u8 bw;
...@@ -919,7 +884,17 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi, ...@@ -919,7 +884,17 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
tx_count = 0x1f; tx_count = 0x1f;
val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count) | val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count) |
FIELD_PREP(MT_TXD3_SEQ, le16_to_cpu(hdr->seq_ctrl)); MT_TXD3_SN_VALID;
if (ieee80211_is_data_qos(hdr->frame_control))
seqno = le16_to_cpu(hdr->seq_ctrl);
else if (ieee80211_is_back_req(hdr->frame_control))
seqno = le16_to_cpu(bar->start_seq_num);
else
val &= ~MT_TXD3_SN_VALID;
val |= FIELD_PREP(MT_TXD3_SEQ, seqno >> 4);
txwi[3] = cpu_to_le32(val); txwi[3] = cpu_to_le32(val);
if (key) { if (key) {
......
...@@ -372,7 +372,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) ...@@ -372,7 +372,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv; struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
struct sk_buff_head list; struct sk_buff_head list;
mt76_stop_tx_queues(&dev->mt76, sta, false); mt76_stop_tx_queues(&dev->mt76, sta, true);
mt7603_wtbl_set_ps(dev, msta, ps); mt7603_wtbl_set_ps(dev, msta, ps);
if (ps) if (ps)
return; return;
...@@ -584,13 +584,13 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -584,13 +584,13 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
case IEEE80211_AMPDU_TX_OPERATIONAL: case IEEE80211_AMPDU_TX_OPERATIONAL:
mtxq->aggr = true; mtxq->aggr = true;
mtxq->send_bar = false; mtxq->send_bar = false;
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, ba_size); mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, ba_size);
break; break;
case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
mtxq->aggr = false; mtxq->aggr = false;
ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, -1); mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
break; break;
case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_START:
mtxq->agg_ssn = *ssn << 4; mtxq->agg_ssn = *ssn << 4;
...@@ -598,7 +598,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -598,7 +598,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
break; break;
case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_CONT:
mtxq->aggr = false; mtxq->aggr = false;
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, -1); mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break; break;
} }
......
...@@ -200,7 +200,7 @@ void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval); ...@@ -200,7 +200,7 @@ void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval);
int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb); int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb);
void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data); void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data);
void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid); void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid);
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn, void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid,
int ba_size); int ba_size);
void mt7603_pse_client_reset(struct mt7603_dev *dev); void mt7603_pse_client_reset(struct mt7603_dev *dev);
......
...@@ -466,7 +466,6 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev, ...@@ -466,7 +466,6 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
return; return;
rcu_read_lock(); rcu_read_lock();
mt76_tx_status_lock(mdev, &list);
if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid))
wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
...@@ -479,6 +478,8 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev, ...@@ -479,6 +478,8 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
drv_priv); drv_priv);
} }
mt76_tx_status_lock(mdev, &list);
if (wcid) { if (wcid) {
if (stat->pktid >= MT_PACKET_ID_FIRST) if (stat->pktid >= MT_PACKET_ID_FIRST)
status.skb = mt76_tx_status_skb_get(mdev, wcid, status.skb = mt76_tx_status_skb_get(mdev, wcid,
...@@ -498,7 +499,9 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev, ...@@ -498,7 +499,9 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
if (*update == 0 && stat_val == stat_cache && if (*update == 0 && stat_val == stat_cache &&
stat->wcid == msta->status.wcid && msta->n_frames < 32) { stat->wcid == msta->status.wcid && msta->n_frames < 32) {
msta->n_frames++; msta->n_frames++;
goto out; mt76_tx_status_unlock(mdev, &list);
rcu_read_unlock();
return;
} }
mt76x02_mac_fill_tx_status(dev, status.info, &msta->status, mt76x02_mac_fill_tx_status(dev, status.info, &msta->status,
...@@ -514,11 +517,10 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev, ...@@ -514,11 +517,10 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
if (status.skb) if (status.skb)
mt76_tx_status_skb_done(mdev, status.skb, &list); mt76_tx_status_skb_done(mdev, status.skb, &list);
else
ieee80211_tx_status_ext(mt76_hw(dev), &status);
out:
mt76_tx_status_unlock(mdev, &list); mt76_tx_status_unlock(mdev, &list);
if (!status.skb)
ieee80211_tx_status_ext(mt76_hw(dev), &status);
rcu_read_unlock(); rcu_read_unlock();
} }
......
...@@ -673,7 +673,6 @@ enum rt2x00_state_flags { ...@@ -673,7 +673,6 @@ enum rt2x00_state_flags {
CONFIG_CHANNEL_HT40, CONFIG_CHANNEL_HT40,
CONFIG_POWERSAVING, CONFIG_POWERSAVING,
CONFIG_HT_DISABLED, CONFIG_HT_DISABLED,
CONFIG_QOS_DISABLED,
CONFIG_MONITORING, CONFIG_MONITORING,
/* /*
......
...@@ -642,18 +642,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, ...@@ -642,18 +642,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
rt2x00dev->intf_associated--; rt2x00dev->intf_associated--;
rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
clear_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags);
} }
/*
* Check for access point which do not support 802.11e . We have to
* generate data frames sequence number in S/W for such AP, because
* of H/W bug.
*/
if (changes & BSS_CHANGED_QOS && !bss_conf->qos)
set_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags);
/* /*
* When the erp information has changed, we should perform * When the erp information has changed, we should perform
* additional configuration steps. For all other changes we are done. * additional configuration steps. For all other changes we are done.
......
...@@ -201,15 +201,18 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, ...@@ -201,15 +201,18 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_SW_SEQNO)) { if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_SW_SEQNO)) {
/* /*
* rt2800 has a H/W (or F/W) bug, device incorrectly increase * rt2800 has a H/W (or F/W) bug, device incorrectly increase
* seqno on retransmited data (non-QOS) frames. To workaround * seqno on retransmitted data (non-QOS) and management frames.
* the problem let's generate seqno in software if QOS is * To workaround the problem let's generate seqno in software.
* disabled. * Except for beacons which are transmitted periodically by H/W
* hence hardware has to assign seqno for them.
*/ */
if (test_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags)) if (ieee80211_is_beacon(hdr->frame_control)) {
__clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
else
/* H/W will generate sequence number */ /* H/W will generate sequence number */
return; return;
}
__clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment