Commit b2ca1661 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Kalle Valo says:

====================
wireless fixes for v6.11

We have few fixes to drivers. The most important here is a fix for
iwlwifi which caused major slowdowns for several users.

* tag 'wireless-2024-08-14' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: iwlwifi: correctly lookup DMA address in SG table
  wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change
  wifi: brcmfmac: cfg80211: Handle SSID based pmksa deletion
  wifi: rtlwifi: rtl8192du: Initialise value32 in _rtl92du_init_queue_reserved_page
  wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
====================

Link: https://patch.msgid.link/20240814171606.E14A0C116B1@smtp.kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6c569b77 e37a9184
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -162,6 +162,60 @@ static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb)
	return 0;
}

static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
				      unsigned long delta,
				      bool head)
{
	unsigned long len = skb->len;

	if (head) {
		skb_push(skb, delta);
		memmove(skb->data, skb->data + delta, len);
		skb_trim(skb, len);
	} else {
		skb_put(skb, delta);
		memmove(skb->data + delta, skb->data, len);
		skb_pull(skb, delta);
	}
}

static int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
				      struct sk_buff **pskb)
{
	u32 iova_mask = ab->hw_params->iova_mask;
	unsigned long offset, delta1, delta2;
	struct sk_buff *skb2, *skb = *pskb;
	unsigned int headroom = skb_headroom(skb);
	int tailroom = skb_tailroom(skb);
	int ret = 0;

	offset = (unsigned long)skb->data & iova_mask;
	delta1 = offset;
	delta2 = iova_mask - offset + 1;

	if (headroom >= delta1) {
		ath12k_dp_tx_move_payload(skb, delta1, true);
	} else if (tailroom >= delta2) {
		ath12k_dp_tx_move_payload(skb, delta2, false);
	} else {
		skb2 = skb_realloc_headroom(skb, iova_mask);
		if (!skb2) {
			ret = -ENOMEM;
			goto out;
		}

		dev_kfree_skb_any(skb);

		offset = (unsigned long)skb2->data & iova_mask;
		if (offset)
			ath12k_dp_tx_move_payload(skb2, offset, true);
		*pskb = skb2;
	}

out:
	return ret;
}

int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
		 struct sk_buff *skb)
{
@@ -184,6 +238,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
	bool tcl_ring_retry;
	bool msdu_ext_desc = false;
	bool add_htt_metadata = false;
	u32 iova_mask = ab->hw_params->iova_mask;

	if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
		return -ESHUTDOWN;
@@ -279,6 +334,23 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
		goto fail_remove_tx_buf;
	}

	if (iova_mask &&
	    (unsigned long)skb->data & iova_mask) {
		ret = ath12k_dp_tx_align_payload(ab, &skb);
		if (ret) {
			ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
			/* don't bail out, give original buffer
			 * a chance even unaligned.
			 */
			goto map;
		}

		/* hdr is pointing to a wrong place after alignment,
		 * so refresh it for later use.
		 */
		hdr = (void *)skb->data;
	}
map:
	ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
	if (dma_mapping_error(ab->dev, ti.paddr)) {
		atomic_inc(&ab->soc_stats.tx_err.misc_fail);
+6 −0
Original line number Diff line number Diff line
@@ -924,6 +924,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {

		.acpi_guid = NULL,
		.supports_dynamic_smps_6ghz = true,

		.iova_mask = 0,
	},
	{
		.name = "wcn7850 hw2.0",
@@ -1000,6 +1002,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {

		.acpi_guid = &wcn7850_uuid,
		.supports_dynamic_smps_6ghz = false,

		.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
	},
	{
		.name = "qcn9274 hw2.0",
@@ -1072,6 +1076,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {

		.acpi_guid = NULL,
		.supports_dynamic_smps_6ghz = true,

		.iova_mask = 0,
	},
};

+4 −0
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@
#define ATH12K_M3_FILE			"m3.bin"
#define ATH12K_REGDB_FILE_NAME		"regdb.bin"

#define ATH12K_PCIE_MAX_PAYLOAD_SIZE	128

enum ath12k_hw_rate_cck {
	ATH12K_HW_RATE_CCK_LP_11M = 0,
	ATH12K_HW_RATE_CCK_LP_5_5M,
@@ -215,6 +217,8 @@ struct ath12k_hw_params {

	const guid_t *acpi_guid;
	bool supports_dynamic_smps_6ghz;

	u32 iova_mask;
};

struct ath12k_hw_ops {
+1 −0
Original line number Diff line number Diff line
@@ -9193,6 +9193,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)

	hw->vif_data_size = sizeof(struct ath12k_vif);
	hw->sta_data_size = sizeof(struct ath12k_sta);
	hw->extra_tx_headroom = ab->hw_params->iova_mask;

	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
+10 −3
Original line number Diff line number Diff line
@@ -4320,9 +4320,16 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,
		/* Single PMK operation */
		pmk_op->count = cpu_to_le16(1);
		length += sizeof(struct brcmf_pmksa_v3);
		if (pmksa->bssid)
			memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN);
		if (pmksa->pmkid) {
			memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
			pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN;
		}
		if (pmksa->ssid && pmksa->ssid_len) {
			memcpy(pmk_op->pmk[0].ssid.SSID, pmksa->ssid, pmksa->ssid_len);
			pmk_op->pmk[0].ssid.SSID_len = pmksa->ssid_len;
		}
		pmk_op->pmk[0].time_left = cpu_to_le32(alive ? BRCMF_PMKSA_NO_EXPIRY : 0);
	}

Loading