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

Merge tag 'wireless-drivers-2020-02-08' of...

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 2696e114 d08f3010
...@@ -1897,27 +1897,55 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac, ...@@ -1897,27 +1897,55 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
ieee80211_resume_disconnect(vif); ieee80211_resume_disconnect(vif);
} }
static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm, static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
struct ieee80211_vif *vif)
{ {
u32 base = mvm->trans->dbg.lmac_error_event_table[0];
struct error_table_start { struct error_table_start {
/* cf. struct iwl_error_event_table */ /* cf. struct iwl_error_event_table */
u32 valid; u32 valid;
u32 error_id; __le32 err_id;
} err_info; } err_info;
iwl_trans_read_mem_bytes(mvm->trans, base, if (!base)
return false;
iwl_trans_read_mem_bytes(trans, base,
&err_info, sizeof(err_info)); &err_info, sizeof(err_info));
if (err_info.valid && err_id)
*err_id = le32_to_cpu(err_info.err_id);
if (err_info.valid && return !!err_info.valid;
err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { }
struct cfg80211_wowlan_wakeup wakeup = {
.rfkill_release = true, static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
}; struct ieee80211_vif *vif)
ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL); {
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) static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018 Intel Corporation
* Copyright (C) 2019 Intel Corporation * Copyright (C) 2019 Intel Corporation
* Copyright (C) 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
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018 Intel Corporation
* Copyright (C) 2019 Intel Corporation * Copyright (C) 2019 Intel Corporation
* Copyright (C) 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
...@@ -528,6 +530,8 @@ void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req) ...@@ -528,6 +530,8 @@ void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req)
if (req != mvm->ftm_initiator.req) if (req != mvm->ftm_initiator.req)
return; return;
iwl_mvm_ftm_reset(mvm);
if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD, if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD,
LOCATION_GROUP, 0), LOCATION_GROUP, 0),
0, sizeof(cmd), &cmd)) 0, sizeof(cmd), &cmd))
...@@ -641,7 +645,6 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) ...@@ -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); lockdep_assert_held(&mvm->mutex);
if (!mvm->ftm_initiator.req) { if (!mvm->ftm_initiator.req) {
IWL_ERR(mvm, "Got FTM response but have no request?\n");
return; return;
} }
......
...@@ -5,10 +5,9 @@ ...@@ -5,10 +5,9 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* 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) 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 @@ ...@@ -28,10 +27,9 @@
* *
* BSD LICENSE * BSD LICENSE
* *
* 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) 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
...@@ -2037,7 +2035,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, ...@@ -2037,7 +2035,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
rcu_read_lock(); rcu_read_lock();
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]); 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(); rcu_read_unlock();
WARN(1, "Can't find STA to configure HE\n"); WARN(1, "Can't find STA to configure HE\n");
return; return;
...@@ -3293,7 +3291,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, ...@@ -3293,7 +3291,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
if (fw_has_capa(&mvm->fw->ucode_capa, if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
iwl_mvm_schedule_session_protection(mvm, vif, 900, iwl_mvm_schedule_session_protection(mvm, vif, 900,
min_duration); min_duration, false);
else else
iwl_mvm_protect_session(mvm, vif, duration, iwl_mvm_protect_session(mvm, vif, duration,
min_duration, 500, false); min_duration, 500, false);
......
...@@ -3320,6 +3320,10 @@ static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm, ...@@ -3320,6 +3320,10 @@ static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
igtk_cmd.sta_id = cpu_to_le32(sta_id); igtk_cmd.sta_id = cpu_to_le32(sta_id);
if (remove_key) { 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); igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
} else { } else {
struct ieee80211_key_seq seq; struct ieee80211_key_seq seq;
...@@ -3574,9 +3578,9 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, ...@@ -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", IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
keyconf->keyidx, sta_id); keyconf->keyidx, sta_id);
if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)) keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
......
...@@ -205,9 +205,15 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, ...@@ -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); struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int; 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 */ /* 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); mutex_unlock(&mvm->mutex);
} }
......
...@@ -1056,13 +1056,42 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, ...@@ -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); 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, void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, 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_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 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 = { struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color = .id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
...@@ -1071,7 +1100,6 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, ...@@ -1071,7 +1100,6 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC), .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)),
}; };
int ret;
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
...@@ -1092,14 +1120,35 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, ...@@ -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", IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
le32_to_cpu(cmd.duration_tu)); le32_to_cpu(cmd.duration_tu));
ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD, if (!wait_for_notif) {
MAC_CONF_GROUP, 0), if (iwl_mvm_send_cmd_pdu(mvm,
0, sizeof(cmd), &cmd); iwl_cmd_id(SESSION_PROTECTION_CMD,
if (ret) { 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, IWL_ERR(mvm,
"Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret); "Couldn't send the SESSION_PROTECTION_CMD\n");
spin_lock_bh(&mvm->time_event_lock); iwl_remove_notification(&mvm->notif_wait, &wait_notif);
iwl_mvm_te_clear_data(mvm, te_data); } else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
spin_unlock_bh(&mvm->time_event_lock); 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) ...@@ -250,10 +250,12 @@ iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
* @mvm: the mvm component * @mvm: the mvm component
* @vif: the virtual interface for which the protection issued * @vif: the virtual interface for which the protection issued
* @duration: the duration of the protection * @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, void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, 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 * iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014, 2019 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) 2019 Intel Corporation * Copyright(c) 2019 - 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 @@ ...@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014, 2019 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) 2019 Intel Corporation * Copyright(c) 2019 - 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
...@@ -234,7 +234,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) ...@@ -234,7 +234,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP), .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
}; };
struct iwl_ext_dts_measurement_cmd extcmd = { 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; u32 cmdid;
...@@ -734,7 +734,8 @@ static struct thermal_zone_device_ops tzone_ops = { ...@@ -734,7 +734,8 @@ static struct thermal_zone_device_ops tzone_ops = {
static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
{ {
int i; int i;
char name[] = "iwlwifi"; char name[16];
static atomic_t counter = ATOMIC_INIT(0);
if (!iwl_mvm_is_tt_in_fw(mvm)) { if (!iwl_mvm_is_tt_in_fw(mvm)) {
mvm->tz_device.tzone = NULL; mvm->tz_device.tzone = NULL;
...@@ -744,6 +745,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) ...@@ -744,6 +745,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH); 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, mvm->tz_device.tzone = thermal_zone_device_register(name,
IWL_MAX_DTS_TRIPS, IWL_MAX_DTS_TRIPS,
IWL_WRITABLE_TRIPS_MSK, IWL_WRITABLE_TRIPS_MSK,
......
...@@ -1785,6 +1785,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv, ...@@ -1785,6 +1785,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
rates_max = rates_eid[1]; rates_max = rates_eid[1];
if (rates_max > MAX_RATES) { if (rates_max > MAX_RATES) {
lbs_deb_join("invalid rates"); lbs_deb_join("invalid rates");
rcu_read_unlock();
ret = -EINVAL;
goto out; goto out;
} }
rates = cmd.bss.rates; rates = cmd.bss.rates;
......
...@@ -2884,6 +2884,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, ...@@ -2884,6 +2884,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
vs_param_set->header.len = vs_param_set->header.len =
cpu_to_le16((((u16) priv->vs_ie[id].ie[1]) cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
& 0x00FF) + 2); & 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, memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
le16_to_cpu(vs_param_set->header.len)); le16_to_cpu(vs_param_set->header.len));
*buffer += 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, ...@@ -232,6 +232,7 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
if (country_ie_len > if (country_ie_len >
(IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) { (IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) {
rcu_read_unlock();
mwifiex_dbg(priv->adapter, ERROR, mwifiex_dbg(priv->adapter, ERROR,
"11D: country_ie_len overflow!, deauth AP\n"); "11D: country_ie_len overflow!, deauth AP\n");
return -EINVAL; return -EINVAL;
......
...@@ -970,6 +970,10 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, ...@@ -970,6 +970,10 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
"WMM Parameter Set Count: %d\n", "WMM Parameter Set Count: %d\n",
wmm_param_ie->qos_info_bitmap & mask); 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. memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
wmm_ie, wmm_param_ie, wmm_ie, wmm_param_ie,
wmm_param_ie->vend_hdr.len + 2); wmm_param_ie->vend_hdr.len + 2);
......
...@@ -92,8 +92,9 @@ static int mt7615_check_eeprom(struct mt76_dev *dev) ...@@ -92,8 +92,9 @@ static int mt7615_check_eeprom(struct mt76_dev *dev)
static void mt7615_eeprom_parse_hw_cap(struct mt7615_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; u8 tx_mask, rx_mask, max_nss;
u32 val;
val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL, val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
eeprom[MT_EE_WIFI_CONF]); eeprom[MT_EE_WIFI_CONF]);
......
...@@ -281,27 +281,26 @@ static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev) ...@@ -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); 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 */ /* wait 100ms for wow firmware to finish work */
msleep(100); msleep(100);
if (wow_enable) { if (wow_enable) {
if (!rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON)) if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON))
ret = 0; goto wow_fail;
} else { } else {
if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) == 0 && if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) ||
rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE) == 0) rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE))
ret = 0; goto wow_fail;
} }
if (ret) return 0;
rtw_err(rtwdev, "failed to check wow status %s\n",
wow_enable ? "enabled" : "disabled");
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, static void rtw_wow_fw_security_type_iter(struct ieee80211_hw *hw,
......
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