Skip to content

Commit c76b305

Browse files
committed
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 <[email protected]>
2 parents 2696e11 + d08f301 commit c76b305

File tree

14 files changed

+159
-53
lines changed

14 files changed

+159
-53
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/d3.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,27 +1897,55 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
18971897
ieee80211_resume_disconnect(vif);
18981898
}
18991899

1900-
static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
1901-
struct ieee80211_vif *vif)
1900+
static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
19021901
{
1903-
u32 base = mvm->trans->dbg.lmac_error_event_table[0];
19041902
struct error_table_start {
19051903
/* cf. struct iwl_error_event_table */
19061904
u32 valid;
1907-
u32 error_id;
1905+
__le32 err_id;
19081906
} err_info;
19091907

1910-
iwl_trans_read_mem_bytes(mvm->trans, base,
1908+
if (!base)
1909+
return false;
1910+
1911+
iwl_trans_read_mem_bytes(trans, base,
19111912
&err_info, sizeof(err_info));
1913+
if (err_info.valid && err_id)
1914+
*err_id = le32_to_cpu(err_info.err_id);
19121915

1913-
if (err_info.valid &&
1914-
err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
1915-
struct cfg80211_wowlan_wakeup wakeup = {
1916-
.rfkill_release = true,
1917-
};
1918-
ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL);
1916+
return !!err_info.valid;
1917+
}
1918+
1919+
static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
1920+
struct ieee80211_vif *vif)
1921+
{
1922+
u32 err_id;
1923+
1924+
/* check for lmac1 error */
1925+
if (iwl_mvm_rt_status(mvm->trans,
1926+
mvm->trans->dbg.lmac_error_event_table[0],
1927+
&err_id)) {
1928+
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
1929+
struct cfg80211_wowlan_wakeup wakeup = {
1930+
.rfkill_release = true,
1931+
};
1932+
ieee80211_report_wowlan_wakeup(vif, &wakeup,
1933+
GFP_KERNEL);
1934+
}
1935+
return true;
19191936
}
1920-
return err_info.valid;
1937+
1938+
/* check if we have lmac2 set and check for error */
1939+
if (iwl_mvm_rt_status(mvm->trans,
1940+
mvm->trans->dbg.lmac_error_event_table[1], NULL))
1941+
return true;
1942+
1943+
/* check for umac error */
1944+
if (iwl_mvm_rt_status(mvm->trans,
1945+
mvm->trans->dbg.umac_error_event_table, NULL))
1946+
return true;
1947+
1948+
return false;
19211949
}
19221950

19231951
static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)

drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
99
* Copyright (C) 2018 Intel Corporation
1010
* Copyright (C) 2019 Intel Corporation
11+
* Copyright (C) 2020 Intel Corporation
1112
*
1213
* This program is free software; you can redistribute it and/or modify
1314
* it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
3031
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
3132
* Copyright (C) 2018 Intel Corporation
3233
* Copyright (C) 2019 Intel Corporation
34+
* Copyright (C) 2020 Intel Corporation
3335
* All rights reserved.
3436
*
3537
* 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)
528530
if (req != mvm->ftm_initiator.req)
529531
return;
530532

533+
iwl_mvm_ftm_reset(mvm);
534+
531535
if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD,
532536
LOCATION_GROUP, 0),
533537
0, sizeof(cmd), &cmd))
@@ -641,7 +645,6 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
641645
lockdep_assert_held(&mvm->mutex);
642646

643647
if (!mvm->ftm_initiator.req) {
644-
IWL_ERR(mvm, "Got FTM response but have no request?\n");
645648
return;
646649
}
647650

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
*
66
* GPL LICENSE SUMMARY
77
*
8-
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
98
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
109
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11-
* Copyright(c) 2018 - 2019 Intel Corporation
10+
* Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
1211
*
1312
* This program is free software; you can redistribute it and/or modify
1413
* it under the terms of version 2 of the GNU General Public License as
@@ -28,10 +27,9 @@
2827
*
2928
* BSD LICENSE
3029
*
31-
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3230
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3331
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34-
* Copyright(c) 2018 - 2019 Intel Corporation
32+
* Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
3533
* All rights reserved.
3634
*
3735
* 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,
20372035
rcu_read_lock();
20382036

20392037
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
2040-
if (IS_ERR(sta)) {
2038+
if (IS_ERR_OR_NULL(sta)) {
20412039
rcu_read_unlock();
20422040
WARN(1, "Can't find STA to configure HE\n");
20432041
return;
@@ -3293,7 +3291,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
32933291
if (fw_has_capa(&mvm->fw->ucode_capa,
32943292
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
32953293
iwl_mvm_schedule_session_protection(mvm, vif, 900,
3296-
min_duration);
3294+
min_duration, false);
32973295
else
32983296
iwl_mvm_protect_session(mvm, vif, duration,
32993297
min_duration, 500, false);

drivers/net/wireless/intel/iwlwifi/mvm/sta.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3320,6 +3320,10 @@ static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
33203320
igtk_cmd.sta_id = cpu_to_le32(sta_id);
33213321

33223322
if (remove_key) {
3323+
/* This is a valid situation for IGTK */
3324+
if (sta_id == IWL_MVM_INVALID_STA)
3325+
return 0;
3326+
33233327
igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
33243328
} else {
33253329
struct ieee80211_key_seq seq;
@@ -3574,9 +3578,9 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
35743578
IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
35753579
keyconf->keyidx, sta_id);
35763580

3577-
if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
3578-
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
3579-
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
3581+
if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
3582+
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
3583+
keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
35803584
return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
35813585

35823586
if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {

drivers/net/wireless/intel/iwlwifi/mvm/tdls.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,15 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
205205
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
206206
u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
207207

208-
mutex_lock(&mvm->mutex);
209208
/* Protect the session to hear the TDLS setup response on the channel */
210-
iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
209+
mutex_lock(&mvm->mutex);
210+
if (fw_has_capa(&mvm->fw->ucode_capa,
211+
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
212+
iwl_mvm_schedule_session_protection(mvm, vif, duration,
213+
duration, true);
214+
else
215+
iwl_mvm_protect_session(mvm, vif, duration,
216+
duration, 100, true);
211217
mutex_unlock(&mvm->mutex);
212218
}
213219

drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,13 +1056,42 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
10561056
return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
10571057
}
10581058

1059+
static bool iwl_mvm_session_prot_notif(struct iwl_notif_wait_data *notif_wait,
1060+
struct iwl_rx_packet *pkt, void *data)
1061+
{
1062+
struct iwl_mvm *mvm =
1063+
container_of(notif_wait, struct iwl_mvm, notif_wait);
1064+
struct iwl_mvm_session_prot_notif *resp;
1065+
int resp_len = iwl_rx_packet_payload_len(pkt);
1066+
1067+
if (WARN_ON(pkt->hdr.cmd != SESSION_PROTECTION_NOTIF ||
1068+
pkt->hdr.group_id != MAC_CONF_GROUP))
1069+
return true;
1070+
1071+
if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
1072+
IWL_ERR(mvm, "Invalid SESSION_PROTECTION_NOTIF response\n");
1073+
return true;
1074+
}
1075+
1076+
resp = (void *)pkt->data;
1077+
1078+
if (!resp->status)
1079+
IWL_ERR(mvm,
1080+
"TIME_EVENT_NOTIFICATION received but not executed\n");
1081+
1082+
return true;
1083+
}
1084+
10591085
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
10601086
struct ieee80211_vif *vif,
1061-
u32 duration, u32 min_duration)
1087+
u32 duration, u32 min_duration,
1088+
bool wait_for_notif)
10621089
{
10631090
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
10641091
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
1065-
1092+
const u16 notif[] = { iwl_cmd_id(SESSION_PROTECTION_NOTIF,
1093+
MAC_CONF_GROUP, 0) };
1094+
struct iwl_notification_wait wait_notif;
10661095
struct iwl_mvm_session_prot_cmd cmd = {
10671096
.id_and_color =
10681097
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
@@ -1071,7 +1100,6 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
10711100
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
10721101
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
10731102
};
1074-
int ret;
10751103

10761104
lockdep_assert_held(&mvm->mutex);
10771105

@@ -1092,14 +1120,35 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
10921120
IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
10931121
le32_to_cpu(cmd.duration_tu));
10941122

1095-
ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
1096-
MAC_CONF_GROUP, 0),
1097-
0, sizeof(cmd), &cmd);
1098-
if (ret) {
1123+
if (!wait_for_notif) {
1124+
if (iwl_mvm_send_cmd_pdu(mvm,
1125+
iwl_cmd_id(SESSION_PROTECTION_CMD,
1126+
MAC_CONF_GROUP, 0),
1127+
0, sizeof(cmd), &cmd)) {
1128+
IWL_ERR(mvm,
1129+
"Couldn't send the SESSION_PROTECTION_CMD\n");
1130+
spin_lock_bh(&mvm->time_event_lock);
1131+
iwl_mvm_te_clear_data(mvm, te_data);
1132+
spin_unlock_bh(&mvm->time_event_lock);
1133+
}
1134+
1135+
return;
1136+
}
1137+
1138+
iwl_init_notification_wait(&mvm->notif_wait, &wait_notif,
1139+
notif, ARRAY_SIZE(notif),
1140+
iwl_mvm_session_prot_notif, NULL);
1141+
1142+
if (iwl_mvm_send_cmd_pdu(mvm,
1143+
iwl_cmd_id(SESSION_PROTECTION_CMD,
1144+
MAC_CONF_GROUP, 0),
1145+
0, sizeof(cmd), &cmd)) {
10991146
IWL_ERR(mvm,
1100-
"Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret);
1101-
spin_lock_bh(&mvm->time_event_lock);
1102-
iwl_mvm_te_clear_data(mvm, te_data);
1103-
spin_unlock_bh(&mvm->time_event_lock);
1147+
"Couldn't send the SESSION_PROTECTION_CMD\n");
1148+
iwl_remove_notification(&mvm->notif_wait, &wait_notif);
1149+
} else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
1150+
TU_TO_JIFFIES(100))) {
1151+
IWL_ERR(mvm,
1152+
"Failed to protect session until session protection\n");
11041153
}
11051154
}

drivers/net/wireless/intel/iwlwifi/mvm/time-event.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,12 @@ iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
250250
* @mvm: the mvm component
251251
* @vif: the virtual interface for which the protection issued
252252
* @duration: the duration of the protection
253+
* @wait_for_notif: if true, will block until the start of the protection
253254
*/
254255
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
255256
struct ieee80211_vif *vif,
256-
u32 duration, u32 min_duration);
257+
u32 duration, u32 min_duration,
258+
bool wait_for_notif);
257259

258260
/**
259261
* iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF

drivers/net/wireless/intel/iwlwifi/mvm/tt.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved.
99
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
1010
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
11-
* Copyright(c) 2019 Intel Corporation
11+
* Copyright(c) 2019 - 2020 Intel Corporation
1212
*
1313
* This program is free software; you can redistribute it and/or modify
1414
* it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
3131
* Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved.
3232
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
3333
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
34-
* Copyright(c) 2019 Intel Corporation
34+
* Copyright(c) 2019 - 2020 Intel Corporation
3535
* All rights reserved.
3636
*
3737
* 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)
234234
.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
235235
};
236236
struct iwl_ext_dts_measurement_cmd extcmd = {
237-
.control_mode = cpu_to_le32(DTS_AUTOMATIC),
237+
.control_mode = cpu_to_le32(DTS_DIRECT_WITHOUT_MEASURE),
238238
};
239239
u32 cmdid;
240240

@@ -734,7 +734,8 @@ static struct thermal_zone_device_ops tzone_ops = {
734734
static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
735735
{
736736
int i;
737-
char name[] = "iwlwifi";
737+
char name[16];
738+
static atomic_t counter = ATOMIC_INIT(0);
738739

739740
if (!iwl_mvm_is_tt_in_fw(mvm)) {
740741
mvm->tz_device.tzone = NULL;
@@ -744,6 +745,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
744745

745746
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
746747

748+
sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
747749
mvm->tz_device.tzone = thermal_zone_device_register(name,
748750
IWL_MAX_DTS_TRIPS,
749751
IWL_WRITABLE_TRIPS_MSK,

drivers/net/wireless/marvell/libertas/cfg.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
17851785
rates_max = rates_eid[1];
17861786
if (rates_max > MAX_RATES) {
17871787
lbs_deb_join("invalid rates");
1788+
rcu_read_unlock();
1789+
ret = -EINVAL;
17881790
goto out;
17891791
}
17901792
rates = cmd.bss.rates;

drivers/net/wireless/marvell/mwifiex/scan.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2884,6 +2884,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
28842884
vs_param_set->header.len =
28852885
cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
28862886
& 0x00FF) + 2);
2887+
if (le16_to_cpu(vs_param_set->header.len) >
2888+
MWIFIEX_MAX_VSIE_LEN) {
2889+
mwifiex_dbg(priv->adapter, ERROR,
2890+
"Invalid param length!\n");
2891+
break;
2892+
}
2893+
28872894
memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
28882895
le16_to_cpu(vs_param_set->header.len));
28892896
*buffer += le16_to_cpu(vs_param_set->header.len) +

0 commit comments

Comments
 (0)