mirror of https://gitee.com/openkylin/linux.git
wireless-drivers fixes for v5.10
First set of fixes for v5.10. One fix for iwlwifi kernel panic, others less notable. rtw88 * fix a bogus test found by clang iwlwifi * fix long memory reads causing soft lockup warnings * fix kernel panic during Channel Switch Announcement (CSA) * other smaller fixes MAINTAINERS * email address updates -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJfu93zAAoJEG4XJFUm622bc3wH+wVAoqqf/lM2e99uq+Z7KgRc HNX1ApQcjidObFBUIiXcuVPj1V8w0HXqE7r4EXznWhKu/01ch2CNaNmN5Ttwp9dA aIhjAx5kiCp7z/kJkTRSDh1vg6WwLDQ29il8nBiveXzD+VVLfcsPlKIF+dsXFOpz FbISvCp4j/4TNME4u6iOafdurCchdOeuHjoZGEWAWkl1wLiryow6WlTdaYou5vTt EDNZa2px4QXb7DS1qAr0SWHBkBH6YfdIW7zDQ/zGgrCmCE3IQNdIKQGw4/K1pn1a 9KbURnI7JgO28f/8wQjzfh6vJw4XA4P/v6mHMDIcFnS0t4YHCTfkfT0YFlBtUiI= =870O -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-2020-11-23' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers Kalle Valo says: ==================== wireless-drivers fixes for v5.10 First set of fixes for v5.10. One fix for iwlwifi kernel panic, others less notable. rtw88 * fix a bogus test found by clang iwlwifi * fix long memory reads causing soft lockup warnings * fix kernel panic during Channel Switch Announcement (CSA) * other smaller fixes MAINTAINERS * email address updates * tag 'wireless-drivers-2020-11-23' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers: iwlwifi: mvm: fix kernel panic in case of assert during CSA iwlwifi: pcie: set LTR to avoid completion timeout iwlwifi: mvm: write queue_sync_state only for sync iwlwifi: mvm: properly cancel a session protection for P2P iwlwifi: mvm: use the HOT_SPOT_CMD to cancel an AUX ROC iwlwifi: sta: set max HE max A-MPDU according to HE capa MAINTAINERS: update maintainers list for Cypress MAINTAINERS: update Yan-Hsuan's email address iwlwifi: pcie: limit memory read spin time rtw88: fix fw_fifo_addr check ==================== Link: https://lore.kernel.org/r/20201123161037.C11D1C43460@smtp.codeaurora.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
1eae77bfad
|
@ -3528,11 +3528,12 @@ BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
||||||
M: Arend van Spriel <arend.vanspriel@broadcom.com>
|
M: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||||
M: Franky Lin <franky.lin@broadcom.com>
|
M: Franky Lin <franky.lin@broadcom.com>
|
||||||
M: Hante Meuleman <hante.meuleman@broadcom.com>
|
M: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||||
M: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
M: Chi-hsien Lin <chi-hsien.lin@infineon.com>
|
||||||
M: Wright Feng <wright.feng@cypress.com>
|
M: Wright Feng <wright.feng@infineon.com>
|
||||||
|
M: Chung-hsien Hsu <chung-hsien.hsu@infineon.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
L: brcm80211-dev-list.pdl@broadcom.com
|
L: brcm80211-dev-list.pdl@broadcom.com
|
||||||
L: brcm80211-dev-list@cypress.com
|
L: SHA-cyfmac-dev-list@infineon.com
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/wireless/broadcom/brcm80211/
|
F: drivers/net/wireless/broadcom/brcm80211/
|
||||||
|
|
||||||
|
@ -14802,7 +14803,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g
|
||||||
F: drivers/net/wireless/realtek/rtlwifi/
|
F: drivers/net/wireless/realtek/rtlwifi/
|
||||||
|
|
||||||
REALTEK WIRELESS DRIVER (rtw88)
|
REALTEK WIRELESS DRIVER (rtw88)
|
||||||
M: Yan-Hsuan Chuang <yhchuang@realtek.com>
|
M: Yan-Hsuan Chuang <tony0620emma@gmail.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/wireless/realtek/rtw88/
|
F: drivers/net/wireless/realtek/rtw88/
|
||||||
|
|
|
@ -5,10 +5,9 @@
|
||||||
*
|
*
|
||||||
* GPL LICENSE SUMMARY
|
* GPL LICENSE SUMMARY
|
||||||
*
|
*
|
||||||
* 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) 2016 - 2017 Intel Deutschland GmbH
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
* Copyright(c) 2012-2014, 2018 - 2020 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
|
||||||
|
@ -28,10 +27,9 @@
|
||||||
*
|
*
|
||||||
* BSD LICENSE
|
* BSD LICENSE
|
||||||
*
|
*
|
||||||
* 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) 2016 - 2017 Intel Deutschland GmbH
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
* Copyright(c) 2012-2014, 2018 - 2020 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
|
||||||
|
@ -128,7 +126,9 @@ enum iwl_sta_flags {
|
||||||
STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
STA_FLG_MAX_AGG_SIZE_MSK = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
STA_FLG_MAX_AGG_SIZE_2M = (8 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
|
STA_FLG_MAX_AGG_SIZE_4M = (9 << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
|
STA_FLG_MAX_AGG_SIZE_MSK = (0xf << STA_FLG_MAX_AGG_SIZE_SHIFT),
|
||||||
|
|
||||||
STA_FLG_AGG_MPDU_DENS_SHIFT = 23,
|
STA_FLG_AGG_MPDU_DENS_SHIFT = 23,
|
||||||
STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT),
|
STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT),
|
||||||
|
|
|
@ -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 - 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 - 2019 Intel Corporation
|
* Copyright(c) 2018 - 2020 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 @@
|
||||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
* Copyright(c) 2012 - 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 - 2017 Intel Deutschland GmbH
|
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
* Copyright(c) 2018 - 2020 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
|
||||||
|
@ -421,12 +421,14 @@ struct iwl_hs20_roc_res {
|
||||||
* able to run the GO Negotiation. Will not be fragmented and not
|
* able to run the GO Negotiation. Will not be fragmented and not
|
||||||
* repetitive. Valid only on the P2P Device MAC. Only the duration will
|
* repetitive. Valid only on the P2P Device MAC. Only the duration will
|
||||||
* be taken into account.
|
* be taken into account.
|
||||||
|
* @SESSION_PROTECT_CONF_MAX_ID: not used
|
||||||
*/
|
*/
|
||||||
enum iwl_mvm_session_prot_conf_id {
|
enum iwl_mvm_session_prot_conf_id {
|
||||||
SESSION_PROTECT_CONF_ASSOC,
|
SESSION_PROTECT_CONF_ASSOC,
|
||||||
SESSION_PROTECT_CONF_GO_CLIENT_ASSOC,
|
SESSION_PROTECT_CONF_GO_CLIENT_ASSOC,
|
||||||
SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV,
|
SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV,
|
||||||
SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION,
|
SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION,
|
||||||
|
SESSION_PROTECT_CONF_MAX_ID,
|
||||||
}; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */
|
}; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -459,7 +461,7 @@ struct iwl_mvm_session_prot_cmd {
|
||||||
* @mac_id: the mac id for which the session protection started / ended
|
* @mac_id: the mac id for which the session protection started / ended
|
||||||
* @status: 1 means success, 0 means failure
|
* @status: 1 means success, 0 means failure
|
||||||
* @start: 1 means the session protection started, 0 means it ended
|
* @start: 1 means the session protection started, 0 means it ended
|
||||||
* @conf_id: the configuration id of the session that started / eneded
|
* @conf_id: see &enum iwl_mvm_session_prot_conf_id
|
||||||
*
|
*
|
||||||
* Note that any session protection will always get two notifications: start
|
* Note that any session protection will always get two notifications: start
|
||||||
* and end even the firmware could not schedule it.
|
* and end even the firmware could not schedule it.
|
||||||
|
|
|
@ -147,6 +147,16 @@
|
||||||
#define CSR_MAC_SHADOW_REG_CTL2 (CSR_BASE + 0x0AC)
|
#define CSR_MAC_SHADOW_REG_CTL2 (CSR_BASE + 0x0AC)
|
||||||
#define CSR_MAC_SHADOW_REG_CTL2_RX_WAKE 0xFFFF
|
#define CSR_MAC_SHADOW_REG_CTL2_RX_WAKE 0xFFFF
|
||||||
|
|
||||||
|
/* LTR control (since IWL_DEVICE_FAMILY_22000) */
|
||||||
|
#define CSR_LTR_LONG_VAL_AD (CSR_BASE + 0x0D4)
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ 0x80000000
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE 0x1c000000
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL 0x03ff0000
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_SNOOP_REQ 0x00008000
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_SNOOP_SCALE 0x00001c00
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_SNOOP_VAL 0x000003ff
|
||||||
|
#define CSR_LTR_LONG_VAL_AD_SCALE_USEC 2
|
||||||
|
|
||||||
/* GIO Chicken Bits (PCI Express bus link power management) */
|
/* GIO Chicken Bits (PCI Express bus link power management) */
|
||||||
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
|
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
|
||||||
|
|
||||||
|
|
|
@ -3080,7 +3080,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
/* this would be a mac80211 bug ... but don't crash */
|
/* this would be a mac80211 bug ... but don't crash */
|
||||||
if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
|
if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
|
||||||
return -EINVAL;
|
return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ? 0 : -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are in a STA removal flow and in DQA mode:
|
* If we are in a STA removal flow and in DQA mode:
|
||||||
|
@ -3127,6 +3127,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vif->type == NL80211_IFTYPE_STATION)
|
||||||
|
vif->bss_conf.he_support = sta->he_cap.has_he;
|
||||||
|
|
||||||
if (sta->tdls &&
|
if (sta->tdls &&
|
||||||
(vif->p2p ||
|
(vif->p2p ||
|
||||||
iwl_mvm_tdls_sta_count(mvm, NULL) ==
|
iwl_mvm_tdls_sta_count(mvm, NULL) ==
|
||||||
|
|
|
@ -196,6 +196,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
mpdu_dens = sta->ht_cap.ampdu_density;
|
mpdu_dens = sta->ht_cap.ampdu_density;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sta->vht_cap.vht_supported) {
|
if (sta->vht_cap.vht_supported) {
|
||||||
agg_size = sta->vht_cap.cap &
|
agg_size = sta->vht_cap.cap &
|
||||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
|
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
|
||||||
|
@ -205,6 +206,23 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
agg_size = sta->ht_cap.ampdu_factor;
|
agg_size = sta->ht_cap.ampdu_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* D6.0 10.12.2 A-MPDU length limit rules
|
||||||
|
* A STA indicates the maximum length of the A-MPDU preEOF padding
|
||||||
|
* that it can receive in an HE PPDU in the Maximum A-MPDU Length
|
||||||
|
* Exponent field in its HT Capabilities, VHT Capabilities,
|
||||||
|
* and HE 6 GHz Band Capabilities elements (if present) and the
|
||||||
|
* Maximum AMPDU Length Exponent Extension field in its HE
|
||||||
|
* Capabilities element
|
||||||
|
*/
|
||||||
|
if (sta->he_cap.has_he)
|
||||||
|
agg_size += u8_get_bits(sta->he_cap.he_cap_elem.mac_cap_info[3],
|
||||||
|
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
|
||||||
|
|
||||||
|
/* Limit to max A-MPDU supported by FW */
|
||||||
|
if (agg_size > (STA_FLG_MAX_AGG_SIZE_4M >> STA_FLG_MAX_AGG_SIZE_SHIFT))
|
||||||
|
agg_size = (STA_FLG_MAX_AGG_SIZE_4M >>
|
||||||
|
STA_FLG_MAX_AGG_SIZE_SHIFT);
|
||||||
|
|
||||||
add_sta_cmd.station_flags |=
|
add_sta_cmd.station_flags |=
|
||||||
cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
|
cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
|
||||||
add_sta_cmd.station_flags |=
|
add_sta_cmd.station_flags |=
|
||||||
|
|
|
@ -641,11 +641,32 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_mvm_vif *mvmvif)
|
||||||
|
{
|
||||||
|
struct iwl_mvm_session_prot_cmd cmd = {
|
||||||
|
.id_and_color =
|
||||||
|
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||||
|
mvmvif->color)),
|
||||||
|
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
||||||
|
.conf_id = cpu_to_le32(mvmvif->time_event_data.id),
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
|
||||||
|
MAC_CONF_GROUP, 0),
|
||||||
|
0, sizeof(cmd), &cmd);
|
||||||
|
if (ret)
|
||||||
|
IWL_ERR(mvm,
|
||||||
|
"Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
||||||
struct iwl_mvm_time_event_data *te_data,
|
struct iwl_mvm_time_event_data *te_data,
|
||||||
u32 *uid)
|
u32 *uid)
|
||||||
{
|
{
|
||||||
u32 id;
|
u32 id;
|
||||||
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is possible that by the time we got to this point the time
|
* It is possible that by the time we got to this point the time
|
||||||
|
@ -663,15 +684,30 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
||||||
iwl_mvm_te_clear_data(mvm, te_data);
|
iwl_mvm_te_clear_data(mvm, te_data);
|
||||||
spin_unlock_bh(&mvm->time_event_lock);
|
spin_unlock_bh(&mvm->time_event_lock);
|
||||||
|
|
||||||
/*
|
/* When session protection is supported, the te_data->id field
|
||||||
* It is possible that by the time we try to remove it, the time event
|
* is reused to save session protection's configuration.
|
||||||
* has already ended and removed. In such a case there is no need to
|
*/
|
||||||
* send a removal command.
|
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
||||||
|
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
|
||||||
|
/* Session protection is still ongoing. Cancel it */
|
||||||
|
iwl_mvm_cancel_session_protection(mvm, mvmvif);
|
||||||
|
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
|
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
||||||
|
iwl_mvm_roc_finished(mvm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
/* It is possible that by the time we try to remove it, the
|
||||||
|
* time event has already ended and removed. In such a case
|
||||||
|
* there is no need to send a removal command.
|
||||||
*/
|
*/
|
||||||
if (id == TE_MAX) {
|
if (id == TE_MAX) {
|
||||||
IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid);
|
IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -771,6 +807,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
||||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
struct iwl_mvm_session_prot_notif *notif = (void *)pkt->data;
|
struct iwl_mvm_session_prot_notif *notif = (void *)pkt->data;
|
||||||
struct ieee80211_vif *vif;
|
struct ieee80211_vif *vif;
|
||||||
|
struct iwl_mvm_vif *mvmvif;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, le32_to_cpu(notif->mac_id),
|
vif = iwl_mvm_rcu_dereference_vif_id(mvm, le32_to_cpu(notif->mac_id),
|
||||||
|
@ -779,9 +816,10 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
||||||
if (!vif)
|
if (!vif)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
|
||||||
/* The vif is not a P2P_DEVICE, maintain its time_event_data */
|
/* The vif is not a P2P_DEVICE, maintain its time_event_data */
|
||||||
if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
|
if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
|
||||||
struct iwl_mvm_time_event_data *te_data =
|
struct iwl_mvm_time_event_data *te_data =
|
||||||
&mvmvif->time_event_data;
|
&mvmvif->time_event_data;
|
||||||
|
|
||||||
|
@ -816,10 +854,14 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) {
|
if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) {
|
||||||
/* End TE, notify mac80211 */
|
/* End TE, notify mac80211 */
|
||||||
|
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
|
||||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||||
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
||||||
iwl_mvm_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
} else if (le32_to_cpu(notif->start)) {
|
} else if (le32_to_cpu(notif->start)) {
|
||||||
|
if (WARN_ON(mvmvif->time_event_data.id !=
|
||||||
|
le32_to_cpu(notif->conf_id)))
|
||||||
|
goto out_unlock;
|
||||||
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
|
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
|
||||||
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
|
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
|
||||||
}
|
}
|
||||||
|
@ -845,20 +887,24 @@ iwl_mvm_start_p2p_roc_session_protection(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
|
/* The time_event_data.id field is reused to save session
|
||||||
|
* protection's configuration.
|
||||||
|
*/
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IEEE80211_ROC_TYPE_NORMAL:
|
case IEEE80211_ROC_TYPE_NORMAL:
|
||||||
cmd.conf_id =
|
mvmvif->time_event_data.id =
|
||||||
cpu_to_le32(SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV);
|
SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV;
|
||||||
break;
|
break;
|
||||||
case IEEE80211_ROC_TYPE_MGMT_TX:
|
case IEEE80211_ROC_TYPE_MGMT_TX:
|
||||||
cmd.conf_id =
|
mvmvif->time_event_data.id =
|
||||||
cpu_to_le32(SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION);
|
SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN_ONCE(1, "Got an invalid ROC type\n");
|
WARN_ONCE(1, "Got an invalid ROC type\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id);
|
||||||
return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
|
return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
|
||||||
MAC_CONF_GROUP, 0),
|
MAC_CONF_GROUP, 0),
|
||||||
0, sizeof(cmd), &cmd);
|
0, sizeof(cmd), &cmd);
|
||||||
|
@ -960,25 +1006,6 @@ void iwl_mvm_cleanup_roc_te(struct iwl_mvm *mvm)
|
||||||
__iwl_mvm_remove_time_event(mvm, te_data, &uid);
|
__iwl_mvm_remove_time_event(mvm, te_data, &uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
|
|
||||||
struct iwl_mvm_vif *mvmvif)
|
|
||||||
{
|
|
||||||
struct iwl_mvm_session_prot_cmd cmd = {
|
|
||||||
.id_and_color =
|
|
||||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
|
||||||
mvmvif->color)),
|
|
||||||
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
|
||||||
};
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
|
|
||||||
MAC_CONF_GROUP, 0),
|
|
||||||
0, sizeof(cmd), &cmd);
|
|
||||||
if (ret)
|
|
||||||
IWL_ERR(mvm,
|
|
||||||
"Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
struct iwl_mvm_vif *mvmvif;
|
struct iwl_mvm_vif *mvmvif;
|
||||||
|
@ -988,10 +1015,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||||
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
||||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
|
||||||
|
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
iwl_mvm_cancel_session_protection(mvm, mvmvif);
|
iwl_mvm_cancel_session_protection(mvm, mvmvif);
|
||||||
|
|
||||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
|
||||||
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
||||||
|
} else {
|
||||||
|
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
|
||||||
|
&mvmvif->time_event_data);
|
||||||
|
}
|
||||||
|
|
||||||
iwl_mvm_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
|
|
||||||
|
@ -1126,10 +1156,15 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||||
mvmvif->color)),
|
mvmvif->color)),
|
||||||
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
|
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
|
||||||
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
|
|
||||||
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
|
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* The time_event_data.id field is reused to save session
|
||||||
|
* protection's configuration.
|
||||||
|
*/
|
||||||
|
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_ASSOC;
|
||||||
|
cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id);
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
spin_lock_bh(&mvm->time_event_lock);
|
spin_lock_bh(&mvm->time_event_lock);
|
||||||
|
|
|
@ -252,6 +252,26 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
||||||
|
|
||||||
iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
|
iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
|
||||||
CSR_AUTO_FUNC_BOOT_ENA);
|
CSR_AUTO_FUNC_BOOT_ENA);
|
||||||
|
|
||||||
|
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
|
||||||
|
/*
|
||||||
|
* The firmware initializes this again later (to a smaller
|
||||||
|
* value), but for the boot process initialize the LTR to
|
||||||
|
* ~250 usec.
|
||||||
|
*/
|
||||||
|
u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
|
||||||
|
u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
|
||||||
|
CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
|
||||||
|
u32_encode_bits(250,
|
||||||
|
CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
|
||||||
|
CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
|
||||||
|
u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
|
||||||
|
CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
|
||||||
|
u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
|
||||||
|
|
||||||
|
iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val);
|
||||||
|
}
|
||||||
|
|
||||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
|
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
|
||||||
iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
|
iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
|
||||||
else
|
else
|
||||||
|
|
|
@ -2156,18 +2156,36 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
|
||||||
void *buf, int dwords)
|
void *buf, int dwords)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int offs, ret = 0;
|
int offs = 0;
|
||||||
u32 *vals = buf;
|
u32 *vals = buf;
|
||||||
|
|
||||||
|
while (offs < dwords) {
|
||||||
|
/* limit the time we spin here under lock to 1/2s */
|
||||||
|
ktime_t timeout = ktime_add_us(ktime_get(), 500 * USEC_PER_MSEC);
|
||||||
|
|
||||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||||
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
|
iwl_write32(trans, HBUS_TARG_MEM_RADDR,
|
||||||
for (offs = 0; offs < dwords; offs++)
|
addr + 4 * offs);
|
||||||
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
|
|
||||||
|
while (offs < dwords) {
|
||||||
|
vals[offs] = iwl_read32(trans,
|
||||||
|
HBUS_TARG_MEM_RDAT);
|
||||||
|
offs++;
|
||||||
|
|
||||||
|
/* calling ktime_get is expensive so
|
||||||
|
* do it once in 128 reads
|
||||||
|
*/
|
||||||
|
if (offs % 128 == 0 && ktime_after(ktime_get(),
|
||||||
|
timeout))
|
||||||
|
break;
|
||||||
|
}
|
||||||
iwl_trans_release_nic_access(trans, &flags);
|
iwl_trans_release_nic_access(trans, &flags);
|
||||||
} else {
|
} else {
|
||||||
ret = -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
return ret;
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
|
static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
|
||||||
|
|
|
@ -1482,7 +1482,7 @@ static bool rtw_fw_dump_check_size(struct rtw_dev *rtwdev,
|
||||||
int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size,
|
int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size,
|
||||||
u32 *buffer)
|
u32 *buffer)
|
||||||
{
|
{
|
||||||
if (!rtwdev->chip->fw_fifo_addr) {
|
if (!rtwdev->chip->fw_fifo_addr[0]) {
|
||||||
rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n");
|
rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n");
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue