Skip to content

Commit

Permalink
Merge tag 'wireless-2024-02-14' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/wireless/wireless

Johannes Berg says:

====================
Valentine's day edition, with just few fixes because
that's how we love it ;-)

iwlwifi:
 - correct A3 in A-MSDUs
 - fix crash when operating as AP and running out of station
   slots to use
 - clear link ID to correct some later checks against it
 - fix error codes in SAR table loading
 - fix error path in PPAG table read

mac80211:
 - reload a pointer after SKB may have changed
   (only in certain monitor inject mode scenarios)

* tag 'wireless-2024-02-14' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: iwlwifi: mvm: fix a crash when we run out of stations
  wifi: iwlwifi: uninitialized variable in iwl_acpi_get_ppag_table()
  wifi: iwlwifi: Fix some error codes
  wifi: iwlwifi: clear link_id in time_event
  wifi: iwlwifi: mvm: use correct address 3 in A-MSDU
  wifi: mac80211: reload info pointer in ieee80211_tx_dequeue()
====================

Link: https://lore.kernel.org/r/20240214184326.132813-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
kuba-moo committed Feb 15, 2024
2 parents 9b23fce + b719838 commit 63a3dd6
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 19 deletions.
15 changes: 9 additions & 6 deletions drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 2) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand All @@ -634,7 +634,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 1) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand All @@ -650,7 +650,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 0) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand Down Expand Up @@ -707,7 +707,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 2) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand All @@ -723,7 +723,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 1) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand All @@ -739,7 +739,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 0) {
ret = PTR_ERR(wifi_pkg);
ret = -EINVAL;
goto out_free;
}

Expand Down Expand Up @@ -1116,6 +1116,9 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
goto read_table;
}

ret = PTR_ERR(wifi_pkg);
goto out_free;

read_table:
fwrt->ppag_ver = tbl_rev;
flags = &wifi_pkg->package.elements[1];
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -3687,6 +3687,9 @@ iwl_mvm_sta_state_notexist_to_none(struct iwl_mvm *mvm,
NL80211_TDLS_SETUP);
}

if (ret)
return ret;

for_each_sta_active_link(vif, sta, link_sta, i)
link_sta->agg.max_rc_amsdu_len = 1;

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue,
return false;

mvm_sta = iwl_mvm_sta_from_mac80211(sta);

if (WARN_ON_ONCE(!mvm_sta->dup_data))
return false;

dup_data = &mvm_sta->dup_data[queue];

/*
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2012-2014, 2018-2023 Intel Corporation
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2017 Intel Deutschland GmbH
*/
Expand Down Expand Up @@ -972,6 +972,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) {
/* End TE, notify mac80211 */
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
mvmvif->time_event_data.link_id = -1;
iwl_mvm_p2p_roc_finished(mvm);
ieee80211_remain_on_channel_expired(mvm->hw);
} else if (le32_to_cpu(notif->start)) {
Expand Down
69 changes: 59 additions & 10 deletions drivers/net/wireless/intel/iwlwifi/mvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,13 +520,24 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
}
}

static void iwl_mvm_copy_hdr(void *cmd, const void *hdr, int hdrlen,
const u8 *addr3_override)
{
struct ieee80211_hdr *out_hdr = cmd;

memcpy(cmd, hdr, hdrlen);
if (addr3_override)
memcpy(out_hdr->addr3, addr3_override, ETH_ALEN);
}

/*
* Allocates and sets the Tx cmd the driver data pointers in the skb
*/
static struct iwl_device_tx_cmd *
iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
struct ieee80211_tx_info *info, int hdrlen,
struct ieee80211_sta *sta, u8 sta_id)
struct ieee80211_sta *sta, u8 sta_id,
const u8 *addr3_override)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl_device_tx_cmd *dev_cmd;
Expand Down Expand Up @@ -584,7 +595,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
cmd->len = cpu_to_le16((u16)skb->len);

/* Copy MAC header from skb into command buffer */
memcpy(cmd->hdr, hdr, hdrlen);
iwl_mvm_copy_hdr(cmd->hdr, hdr, hdrlen, addr3_override);

cmd->flags = cpu_to_le16(flags);
cmd->rate_n_flags = cpu_to_le32(rate_n_flags);
Expand All @@ -599,7 +610,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
cmd->len = cpu_to_le16((u16)skb->len);

/* Copy MAC header from skb into command buffer */
memcpy(cmd->hdr, hdr, hdrlen);
iwl_mvm_copy_hdr(cmd->hdr, hdr, hdrlen, addr3_override);

cmd->flags = cpu_to_le32(flags);
cmd->rate_n_flags = cpu_to_le32(rate_n_flags);
Expand All @@ -617,7 +628,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);

/* Copy MAC header from skb into command buffer */
memcpy(tx_cmd->hdr, hdr, hdrlen);
iwl_mvm_copy_hdr(tx_cmd->hdr, hdr, hdrlen, addr3_override);

out:
return dev_cmd;
Expand Down Expand Up @@ -820,7 +831,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)

IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, queue);

dev_cmd = iwl_mvm_set_tx_params(mvm, skb, &info, hdrlen, NULL, sta_id);
dev_cmd = iwl_mvm_set_tx_params(mvm, skb, &info, hdrlen, NULL, sta_id,
NULL);
if (!dev_cmd)
return -1;

Expand Down Expand Up @@ -1140,7 +1152,8 @@ static int iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm,
*/
static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta)
struct ieee80211_sta *sta,
const u8 *addr3_override)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl_mvm_sta *mvmsta;
Expand Down Expand Up @@ -1172,7 +1185,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
iwl_mvm_probe_resp_set_noa(mvm, skb);

dev_cmd = iwl_mvm_set_tx_params(mvm, skb, info, hdrlen,
sta, mvmsta->deflink.sta_id);
sta, mvmsta->deflink.sta_id,
addr3_override);
if (!dev_cmd)
goto drop;

Expand Down Expand Up @@ -1294,9 +1308,11 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct ieee80211_tx_info info;
struct sk_buff_head mpdus_skbs;
struct ieee80211_vif *vif;
unsigned int payload_len;
int ret;
struct sk_buff *orig_skb = skb;
const u8 *addr3;

if (WARN_ON_ONCE(!mvmsta))
return -1;
Expand All @@ -1307,26 +1323,59 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
memcpy(&info, skb->cb, sizeof(info));

if (!skb_is_gso(skb))
return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
return iwl_mvm_tx_mpdu(mvm, skb, &info, sta, NULL);

payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
tcp_hdrlen(skb) + skb->data_len;

if (payload_len <= skb_shinfo(skb)->gso_size)
return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
return iwl_mvm_tx_mpdu(mvm, skb, &info, sta, NULL);

__skb_queue_head_init(&mpdus_skbs);

vif = info.control.vif;
if (!vif)
return -1;

ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
if (ret)
return ret;

WARN_ON(skb_queue_empty(&mpdus_skbs));

/*
* As described in IEEE sta 802.11-2020, table 9-30 (Address
* field contents), A-MSDU address 3 should contain the BSSID
* address.
* Pass address 3 down to iwl_mvm_tx_mpdu() and further to set it
* in the command header. We need to preserve the original
* address 3 in the skb header to correctly create all the
* A-MSDU subframe headers from it.
*/
switch (vif->type) {
case NL80211_IFTYPE_STATION:
addr3 = vif->cfg.ap_addr;
break;
case NL80211_IFTYPE_AP:
addr3 = vif->addr;
break;
default:
addr3 = NULL;
break;
}

while (!skb_queue_empty(&mpdus_skbs)) {
struct ieee80211_hdr *hdr;
bool amsdu;

skb = __skb_dequeue(&mpdus_skbs);
hdr = (void *)skb->data;
amsdu = ieee80211_is_data_qos(hdr->frame_control) &&
(*ieee80211_get_qos_ctl(hdr) &
IEEE80211_QOS_CTL_A_MSDU_PRESENT);

ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta,
amsdu ? addr3 : NULL);
if (ret) {
/* Free skbs created as part of TSO logic that have not yet been dequeued */
__skb_queue_purge(&mpdus_skbs);
Expand Down
5 changes: 3 additions & 2 deletions net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2018-2022 Intel Corporation
* Copyright (C) 2018-2024 Intel Corporation
*
* Transmit and frame generation functions.
*/
Expand Down Expand Up @@ -3927,6 +3927,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
goto begin;

skb = __skb_dequeue(&tx.skbs);
info = IEEE80211_SKB_CB(skb);

if (!skb_queue_empty(&tx.skbs)) {
spin_lock_bh(&fq->lock);
Expand Down Expand Up @@ -3971,7 +3972,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
}

encap_out:
IEEE80211_SKB_CB(skb)->control.vif = vif;
info->control.vif = vif;

if (tx.sta &&
wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
Expand Down

0 comments on commit 63a3dd6

Please sign in to comment.