mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 12:14:10 +08:00
wireless-drivers fixes for v5.6
First set of fixes for v5.6. Buffer overflow fixes to mwifiex, quite a few functionality fixes to iwlwifi and smaller fixes to other drivers. mwifiex * fix an unlock from a previous security fix * fix two buffer overflows libertas * fix two bugs from previous security fixes iwlwifi * fix module removal with multiple NICs * don't treat IGTK removal failure as an error * avoid FW crashes due to DTS measurement races * fix a potential use after free in FTM code * prevent a NULL pointer dereference in iwl_mvm_cfg_he_sta() * fix TDLS discovery * check all CPUs when trying to detect an error during resume rtw88 * fix clang warning mt76 * fix reading of max_nss value from a register -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJePoxJAAoJEG4XJFUm622b7a4H/2t/K/AmDv+j2mGos+2oVlSh RFIXBjYs4GY5NGdLQx56qfiQzlgn8NAWwQqwhtoyVxnJTZjhmQkfMpJIw14tbFB1 OwHd+q7y7jXY9v7YBPlyqCxkzQL3u+GrzFIb04cXrSdzqh+5qWk4Zn7F6ZYJ1vwb xRDOJfOE/a9GGzzY5+iwxyZ6Y1E+OjbgT4Ps5YUaotH1iMGza7NPu6s+UkULkyRo ylbiOR9u6jOiwUkSxUz+GGiXKJ9BQTLKm5kLM7lO5I49AcZb5UOIKJaJxHN0hMwj uprqUsqtbO+bv8SKAjKLR/yQf2gmB+pSSeAmmfJ8ov5igg2g12sNfdy8ScWLks8= =FiiT -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-2020-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers Kalle Valo says: ==================== wireless-drivers fixes for v5.6 First set of fixes for v5.6. Buffer overflow fixes to mwifiex, quite a few functionality fixes to iwlwifi and smaller fixes to other drivers. mwifiex * fix an unlock from a previous security fix * fix two buffer overflows libertas * fix two bugs from previous security fixes iwlwifi * fix module removal with multiple NICs * don't treat IGTK removal failure as an error * avoid FW crashes due to DTS measurement races * fix a potential use after free in FTM code * prevent a NULL pointer dereference in iwl_mvm_cfg_he_sta() * fix TDLS discovery * check all CPUs when trying to detect an error during resume rtw88 * fix clang warning mt76 * fix reading of max_nss value from a register ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c76b305c23
@ -1897,27 +1897,55 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
|
||||
ieee80211_resume_disconnect(vif);
|
||||
}
|
||||
|
||||
static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
|
||||
{
|
||||
u32 base = mvm->trans->dbg.lmac_error_event_table[0];
|
||||
struct error_table_start {
|
||||
/* cf. struct iwl_error_event_table */
|
||||
u32 valid;
|
||||
u32 error_id;
|
||||
__le32 err_id;
|
||||
} err_info;
|
||||
|
||||
iwl_trans_read_mem_bytes(mvm->trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
if (err_info.valid &&
|
||||
err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
.rfkill_release = true,
|
||||
};
|
||||
ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL);
|
||||
iwl_trans_read_mem_bytes(trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
if (err_info.valid && err_id)
|
||||
*err_id = le32_to_cpu(err_info.err_id);
|
||||
|
||||
return !!err_info.valid;
|
||||
}
|
||||
|
||||
static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u32 err_id;
|
||||
|
||||
/* check for lmac1 error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[0],
|
||||
&err_id)) {
|
||||
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
.rfkill_release = true,
|
||||
};
|
||||
ieee80211_report_wowlan_wakeup(vif, &wakeup,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return err_info.valid;
|
||||
|
||||
/* check if we have lmac2 set and check for error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[1], NULL))
|
||||
return true;
|
||||
|
||||
/* check for umac error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.umac_error_event_table, NULL))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
@ -30,6 +31,7 @@
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -528,6 +530,8 @@ void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req)
|
||||
if (req != mvm->ftm_initiator.req)
|
||||
return;
|
||||
|
||||
iwl_mvm_ftm_reset(mvm);
|
||||
|
||||
if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD,
|
||||
LOCATION_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd))
|
||||
@ -641,7 +645,6 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (!mvm->ftm_initiator.req) {
|
||||
IWL_ERR(mvm, "Got FTM response but have no request?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,9 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -28,10 +27,9 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications 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.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -2037,7 +2035,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
|
||||
rcu_read_lock();
|
||||
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
|
||||
if (IS_ERR(sta)) {
|
||||
if (IS_ERR_OR_NULL(sta)) {
|
||||
rcu_read_unlock();
|
||||
WARN(1, "Can't find STA to configure HE\n");
|
||||
return;
|
||||
@ -3293,7 +3291,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
|
||||
iwl_mvm_schedule_session_protection(mvm, vif, 900,
|
||||
min_duration);
|
||||
min_duration, false);
|
||||
else
|
||||
iwl_mvm_protect_session(mvm, vif, duration,
|
||||
min_duration, 500, false);
|
||||
|
@ -3320,6 +3320,10 @@ static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
|
||||
igtk_cmd.sta_id = cpu_to_le32(sta_id);
|
||||
|
||||
if (remove_key) {
|
||||
/* This is a valid situation for IGTK */
|
||||
if (sta_id == IWL_MVM_INVALID_STA)
|
||||
return 0;
|
||||
|
||||
igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
|
||||
} else {
|
||||
struct ieee80211_key_seq seq;
|
||||
@ -3574,9 +3578,9 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
|
||||
IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
|
||||
keyconf->keyidx, sta_id);
|
||||
|
||||
if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
|
||||
if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
|
||||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
|
||||
return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
|
||||
|
||||
if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
|
||||
|
@ -205,9 +205,15 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
/* Protect the session to hear the TDLS setup response on the channel */
|
||||
iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
|
||||
iwl_mvm_schedule_session_protection(mvm, vif, duration,
|
||||
duration, true);
|
||||
else
|
||||
iwl_mvm_protect_session(mvm, vif, duration,
|
||||
duration, 100, true);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
|
@ -1056,13 +1056,42 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
|
||||
return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
|
||||
}
|
||||
|
||||
static bool iwl_mvm_session_prot_notif(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
struct iwl_mvm *mvm =
|
||||
container_of(notif_wait, struct iwl_mvm, notif_wait);
|
||||
struct iwl_mvm_session_prot_notif *resp;
|
||||
int resp_len = iwl_rx_packet_payload_len(pkt);
|
||||
|
||||
if (WARN_ON(pkt->hdr.cmd != SESSION_PROTECTION_NOTIF ||
|
||||
pkt->hdr.group_id != MAC_CONF_GROUP))
|
||||
return true;
|
||||
|
||||
if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
|
||||
IWL_ERR(mvm, "Invalid SESSION_PROTECTION_NOTIF response\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
if (!resp->status)
|
||||
IWL_ERR(mvm,
|
||||
"TIME_EVENT_NOTIFICATION received but not executed\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 duration, u32 min_duration)
|
||||
u32 duration, u32 min_duration,
|
||||
bool wait_for_notif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||
|
||||
const u16 notif[] = { iwl_cmd_id(SESSION_PROTECTION_NOTIF,
|
||||
MAC_CONF_GROUP, 0) };
|
||||
struct iwl_notification_wait wait_notif;
|
||||
struct iwl_mvm_session_prot_cmd cmd = {
|
||||
.id_and_color =
|
||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||
@ -1071,7 +1100,6 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
|
||||
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
|
||||
};
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@ -1092,14 +1120,35 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||
IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
|
||||
le32_to_cpu(cmd.duration_tu));
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
|
||||
MAC_CONF_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd);
|
||||
if (ret) {
|
||||
if (!wait_for_notif) {
|
||||
if (iwl_mvm_send_cmd_pdu(mvm,
|
||||
iwl_cmd_id(SESSION_PROTECTION_CMD,
|
||||
MAC_CONF_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd)) {
|
||||
IWL_ERR(mvm,
|
||||
"Couldn't send the SESSION_PROTECTION_CMD\n");
|
||||
spin_lock_bh(&mvm->time_event_lock);
|
||||
iwl_mvm_te_clear_data(mvm, te_data);
|
||||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_init_notification_wait(&mvm->notif_wait, &wait_notif,
|
||||
notif, ARRAY_SIZE(notif),
|
||||
iwl_mvm_session_prot_notif, NULL);
|
||||
|
||||
if (iwl_mvm_send_cmd_pdu(mvm,
|
||||
iwl_cmd_id(SESSION_PROTECTION_CMD,
|
||||
MAC_CONF_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd)) {
|
||||
IWL_ERR(mvm,
|
||||
"Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret);
|
||||
spin_lock_bh(&mvm->time_event_lock);
|
||||
iwl_mvm_te_clear_data(mvm, te_data);
|
||||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
"Couldn't send the SESSION_PROTECTION_CMD\n");
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_notif);
|
||||
} else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
|
||||
TU_TO_JIFFIES(100))) {
|
||||
IWL_ERR(mvm,
|
||||
"Failed to protect session until session protection\n");
|
||||
}
|
||||
}
|
||||
|
@ -250,10 +250,12 @@ iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
|
||||
* @mvm: the mvm component
|
||||
* @vif: the virtual interface for which the protection issued
|
||||
* @duration: the duration of the protection
|
||||
* @wait_for_notif: if true, will block until the start of the protection
|
||||
*/
|
||||
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 duration, u32 min_duration);
|
||||
u32 duration, u32 min_duration,
|
||||
bool wait_for_notif);
|
||||
|
||||
/**
|
||||
* iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
* Copyright(c) 2019 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
* Copyright(c) 2019 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -234,7 +234,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
|
||||
.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
|
||||
};
|
||||
struct iwl_ext_dts_measurement_cmd extcmd = {
|
||||
.control_mode = cpu_to_le32(DTS_AUTOMATIC),
|
||||
.control_mode = cpu_to_le32(DTS_DIRECT_WITHOUT_MEASURE),
|
||||
};
|
||||
u32 cmdid;
|
||||
|
||||
@ -734,7 +734,8 @@ static struct thermal_zone_device_ops tzone_ops = {
|
||||
static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
||||
{
|
||||
int i;
|
||||
char name[] = "iwlwifi";
|
||||
char name[16];
|
||||
static atomic_t counter = ATOMIC_INIT(0);
|
||||
|
||||
if (!iwl_mvm_is_tt_in_fw(mvm)) {
|
||||
mvm->tz_device.tzone = NULL;
|
||||
@ -744,6 +745,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
|
||||
|
||||
sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
|
||||
mvm->tz_device.tzone = thermal_zone_device_register(name,
|
||||
IWL_MAX_DTS_TRIPS,
|
||||
IWL_WRITABLE_TRIPS_MSK,
|
||||
|
@ -1785,6 +1785,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
|
||||
rates_max = rates_eid[1];
|
||||
if (rates_max > MAX_RATES) {
|
||||
lbs_deb_join("invalid rates");
|
||||
rcu_read_unlock();
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
rates = cmd.bss.rates;
|
||||
|
@ -2884,6 +2884,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
|
||||
vs_param_set->header.len =
|
||||
cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
|
||||
& 0x00FF) + 2);
|
||||
if (le16_to_cpu(vs_param_set->header.len) >
|
||||
MWIFIEX_MAX_VSIE_LEN) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"Invalid param length!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
|
||||
le16_to_cpu(vs_param_set->header.len));
|
||||
*buffer += le16_to_cpu(vs_param_set->header.len) +
|
||||
|
@ -232,6 +232,7 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
|
||||
|
||||
if (country_ie_len >
|
||||
(IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) {
|
||||
rcu_read_unlock();
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"11D: country_ie_len overflow!, deauth AP\n");
|
||||
return -EINVAL;
|
||||
|
@ -970,6 +970,10 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
|
||||
"WMM Parameter Set Count: %d\n",
|
||||
wmm_param_ie->qos_info_bitmap & mask);
|
||||
|
||||
if (wmm_param_ie->vend_hdr.len + 2 >
|
||||
sizeof(struct ieee_types_wmm_parameter))
|
||||
break;
|
||||
|
||||
memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
|
||||
wmm_ie, wmm_param_ie,
|
||||
wmm_param_ie->vend_hdr.len + 2);
|
||||
|
@ -92,8 +92,9 @@ static int mt7615_check_eeprom(struct mt76_dev *dev)
|
||||
|
||||
static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
|
||||
{
|
||||
u8 val, *eeprom = dev->mt76.eeprom.data;
|
||||
u8 *eeprom = dev->mt76.eeprom.data;
|
||||
u8 tx_mask, rx_mask, max_nss;
|
||||
u32 val;
|
||||
|
||||
val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
|
||||
eeprom[MT_EE_WIFI_CONF]);
|
||||
|
@ -281,27 +281,26 @@ static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev)
|
||||
rtw_write32_clr(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE);
|
||||
}
|
||||
|
||||
static bool rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable)
|
||||
static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
/* wait 100ms for wow firmware to finish work */
|
||||
msleep(100);
|
||||
|
||||
if (wow_enable) {
|
||||
if (!rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON))
|
||||
ret = 0;
|
||||
if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON))
|
||||
goto wow_fail;
|
||||
} else {
|
||||
if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) == 0 &&
|
||||
rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE) == 0)
|
||||
ret = 0;
|
||||
if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) ||
|
||||
rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE))
|
||||
goto wow_fail;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
rtw_err(rtwdev, "failed to check wow status %s\n",
|
||||
wow_enable ? "enabled" : "disabled");
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
wow_fail:
|
||||
rtw_err(rtwdev, "failed to check wow status %s\n",
|
||||
wow_enable ? "enabled" : "disabled");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void rtw_wow_fw_security_type_iter(struct ieee80211_hw *hw,
|
||||
|
Loading…
Reference in New Issue
Block a user