Commit d353e1a3 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'wireless-next-2022-05-19' of...

Merge tag 'wireless-next-2022-05-19' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Kalle Valo says:

====================
wireless-next patches for v5.19

Second set of patches for v5.19 and most likely the last one. rtw89
got support for 8852ce devices and mt76 now supports Wireless Ethernet
Dispatch.

Major changes:

cfg80211/mac80211
 - support disabling EHT mode

rtw89
 - add support for Realtek 8852ce devices

mt76
 - Wireless Ethernet Dispatch support for flow offload
 - non-standard VHT MCS10-11 support
 - mt7921 AP mode support
 - mt7921 ipv6 NS offload support

ath11k
 - enable keepalive during WoWLAN suspend
 - implement remain-on-channel support

* tag 'wireless-next-2022-05-19' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (135 commits)
  iwlwifi: mei: fix potential NULL-ptr deref
  iwlwifi: mei: clear the sap data header before sending
  iwlwifi: mvm: remove vif_count
  iwlwifi: mvm: always tell the firmware to accept MCAST frames in BSS
  iwlwifi: mvm: add OTP info in case of init failure
  iwlwifi: mvm: fix assert 1F04 upon reconfig
  iwlwifi: fw: init SAR GEO table only if data is present
  iwlwifi: mvm: clean up authorized condition
  iwlwifi: mvm: use NULL instead of ERR_PTR when parsing wowlan status
  iwlwifi: pcie: simplify MSI-X cause mapping
  rtw89: pci: only mask out INT indicator register for disable interrupt v1
  rtw89: convert rtw89_band to nl80211_band precisely
  rtw89: 8852c: update txpwr tables to HALRF_027_00_052
  rtw89: cfo: check mac_id to avoid out-of-bounds
  rtw89: 8852c: set TX antenna path
  rtw89: add ieee80211::sta_rc_update ops
  wireless: Fix Makefile to be in alphabetical order
  mac80211: refactor freeing the next_beacon
  cfg80211: fix kernel-doc for cfg80211_beacon_data
  mac80211: minstrel_ht: support ieee80211_rate_status
  ...
====================

Link: https://lore.kernel.org/r/20220519153334.8D051C385AA@smtp.kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d7e6f583 78488a64
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/export.h>
#include <linux/property.h>

#include <linux/bcma/bcma.h>

#include "bcma_private.h"
@@ -182,9 +184,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
	chip->direction_input	= bcma_gpio_direction_input;
	chip->direction_output	= bcma_gpio_direction_output;
	chip->parent		= bus->dev;
#if IS_BUILTIN(CONFIG_OF)
	chip->of_node		= cc->core->dev.of_node;
#endif
	chip->fwnode		= dev_fwnode(&cc->core->dev);

	switch (bus->chipinfo.id) {
	case BCMA_CHIP_ID_BCM4707:
	case BCMA_CHIP_ID_BCM5357:
+1 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_WLAN_VENDOR_PURELIFI) += purelifi/
obj-$(CONFIG_WLAN_VENDOR_QUANTENNA) += quantenna/
obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/
obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/
@@ -21,7 +22,6 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/
obj-$(CONFIG_WLAN_VENDOR_ST) += st/
obj-$(CONFIG_WLAN_VENDOR_TI) += ti/
obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/
obj-$(CONFIG_WLAN_VENDOR_QUANTENNA) += quantenna/

# 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS)	+= ray_cs.o
+12 −1
Original line number Diff line number Diff line
@@ -1233,6 +1233,7 @@ static int ath10k_fetch_cal_file(struct ath10k *ar)
static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
{
	const struct firmware *fw;
	char boardname[100];

	if (bd_ie_type == ATH10K_BD_IE_BOARD) {
		if (!ar->hw_params.fw.board) {
@@ -1240,9 +1241,19 @@ static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
			return -EINVAL;
		}

		scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",
			  ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));

		ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
								ar->hw_params.fw.dir,
								boardname);
		if (IS_ERR(ar->normal_mode_fw.board)) {
			fw = ath10k_fetch_fw_file(ar,
						  ar->hw_params.fw.dir,
						  ar->hw_params.fw.board);
			ar->normal_mode_fw.board = fw;
		}

		if (IS_ERR(ar->normal_mode_fw.board))
			return PTR_ERR(ar->normal_mode_fw.board);

+9 −4
Original line number Diff line number Diff line
@@ -2692,8 +2692,10 @@ static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
						    struct ieee80211_sta *sta)
{
	struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;

	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {
		switch (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
		switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
		case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
			return MODE_11AC_VHT160;
		case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
@@ -6926,6 +6928,9 @@ static int ath10k_mac_validate_rate_mask(struct ath10k *ar,
					 struct ieee80211_sta *sta,
					 u32 rate_ctrl_flag, u8 nss)
{
	struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
	struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;

	if (nss > sta->deflink.rx_nss) {
		ath10k_warn(ar, "Invalid nss field, configured %u limit %u\n",
			    nss, sta->deflink.rx_nss);
@@ -6933,19 +6938,19 @@ static int ath10k_mac_validate_rate_mask(struct ath10k *ar,
	}

	if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_VHT) {
		if (!sta->deflink.vht_cap.vht_supported) {
		if (!vht_cap->vht_supported) {
			ath10k_warn(ar, "Invalid VHT rate for sta %pM\n",
				    sta->addr);
			return -EINVAL;
		}
	} else if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_HT) {
		if (!sta->deflink.ht_cap.ht_supported || sta->deflink.vht_cap.vht_supported) {
		if (!ht_cap->ht_supported || vht_cap->vht_supported) {
			ath10k_warn(ar, "Invalid HT rate for sta %pM\n",
				    sta->addr);
			return -EINVAL;
		}
	} else {
		if (sta->deflink.ht_cap.ht_supported || sta->deflink.vht_cap.vht_supported)
		if (ht_cap->ht_supported || vht_cap->vht_supported)
			return -EINVAL;
	}

+177 −1
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/dma-mapping.h>
#include <linux/of_address.h>
#include <linux/iommu.h>
#include "ahb.h"
#include "debug.h"
#include "hif.h"
@@ -757,6 +759,172 @@ static int ath11k_ahb_setup_resources(struct ath11k_base *ab)
	return 0;
}

static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab)
{
	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
	struct device *dev = ab->dev;
	struct device_node *node;
	struct resource r;
	int ret;

	node = of_parse_phandle(dev->of_node, "memory-region", 0);
	if (!node)
		return -ENOENT;

	ret = of_address_to_resource(node, 0, &r);
	of_node_put(node);
	if (ret) {
		dev_err(dev, "failed to resolve msa fixed region\n");
		return ret;
	}

	ab_ahb->fw.msa_paddr = r.start;
	ab_ahb->fw.msa_size = resource_size(&r);

	node = of_parse_phandle(dev->of_node, "memory-region", 1);
	if (!node)
		return -ENOENT;

	ret = of_address_to_resource(node, 0, &r);
	of_node_put(node);
	if (ret) {
		dev_err(dev, "failed to resolve ce fixed region\n");
		return ret;
	}

	ab_ahb->fw.ce_paddr = r.start;
	ab_ahb->fw.ce_size = resource_size(&r);

	return 0;
}

static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab)
{
	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
	struct device *host_dev = ab->dev;
	struct platform_device_info info = {0};
	struct iommu_domain *iommu_dom;
	struct platform_device *pdev;
	struct device_node *node;
	int ret;

	/* Chipsets not requiring MSA need not initialize
	 * MSA resources, return success in such cases.
	 */
	if (!ab->hw_params.fixed_fw_mem)
		return 0;

	ret = ath11k_ahb_setup_msa_resources(ab);
	if (ret) {
		ath11k_err(ab, "failed to setup msa resources\n");
		return ret;
	}

	node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
	if (!node) {
		ab_ahb->fw.use_tz = true;
		return 0;
	}

	info.fwnode = &node->fwnode;
	info.parent = host_dev;
	info.name = node->name;
	info.dma_mask = DMA_BIT_MASK(32);

	pdev = platform_device_register_full(&info);
	if (IS_ERR(pdev)) {
		of_node_put(node);
		return PTR_ERR(pdev);
	}

	ret = of_dma_configure(&pdev->dev, node, true);
	if (ret) {
		ath11k_err(ab, "dma configure fail: %d\n", ret);
		goto err_unregister;
	}

	ab_ahb->fw.dev = &pdev->dev;

	iommu_dom = iommu_domain_alloc(&platform_bus_type);
	if (!iommu_dom) {
		ath11k_err(ab, "failed to allocate iommu domain\n");
		ret = -ENOMEM;
		goto err_unregister;
	}

	ret = iommu_attach_device(iommu_dom, ab_ahb->fw.dev);
	if (ret) {
		ath11k_err(ab, "could not attach device: %d\n", ret);
		goto err_iommu_free;
	}

	ret = iommu_map(iommu_dom, ab_ahb->fw.msa_paddr,
			ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size,
			IOMMU_READ | IOMMU_WRITE);
	if (ret) {
		ath11k_err(ab, "failed to map firmware region: %d\n", ret);
		goto err_iommu_detach;
	}

	ret = iommu_map(iommu_dom, ab_ahb->fw.ce_paddr,
			ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size,
			IOMMU_READ | IOMMU_WRITE);
	if (ret) {
		ath11k_err(ab, "failed to map firmware CE region: %d\n", ret);
		goto err_iommu_unmap;
	}

	ab_ahb->fw.use_tz = false;
	ab_ahb->fw.iommu_domain = iommu_dom;
	of_node_put(node);

	return 0;

err_iommu_unmap:
	iommu_unmap(iommu_dom, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);

err_iommu_detach:
	iommu_detach_device(iommu_dom, ab_ahb->fw.dev);

err_iommu_free:
	iommu_domain_free(iommu_dom);

err_unregister:
	platform_device_unregister(pdev);
	of_node_put(node);

	return ret;
}

static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
{
	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
	struct iommu_domain *iommu;
	size_t unmapped_size;

	if (ab_ahb->fw.use_tz)
		return 0;

	iommu = ab_ahb->fw.iommu_domain;

	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
	if (unmapped_size != ab_ahb->fw.msa_size)
		ath11k_err(ab, "failed to unmap firmware: %zu\n",
			   unmapped_size);

	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size);
	if (unmapped_size != ab_ahb->fw.ce_size)
		ath11k_err(ab, "failed to unmap firmware CE memory: %zu\n",
			   unmapped_size);

	iommu_detach_device(iommu, ab_ahb->fw.dev);
	iommu_domain_free(iommu);

	platform_device_unregister(to_platform_device(ab_ahb->fw.dev));

	return 0;
}

static int ath11k_ahb_probe(struct platform_device *pdev)
{
	struct ath11k_base *ab;
@@ -816,10 +984,14 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
	if (ret)
		goto err_core_free;

	ret = ath11k_hal_srng_init(ab);
	ret = ath11k_ahb_fw_resources_init(ab);
	if (ret)
		goto err_core_free;

	ret = ath11k_hal_srng_init(ab);
	if (ret)
		goto err_fw_deinit;

	ret = ath11k_ce_alloc_pipes(ab);
	if (ret) {
		ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
@@ -856,6 +1028,9 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
err_hal_srng_deinit:
	ath11k_hal_srng_deinit(ab);

err_fw_deinit:
	ath11k_ahb_fw_resource_deinit(ab);

err_core_free:
	ath11k_core_free(ab);
	platform_set_drvdata(pdev, NULL);
@@ -891,6 +1066,7 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
qmi_fail:
	ath11k_ahb_free_irq(ab);
	ath11k_hal_srng_deinit(ab);
	ath11k_ahb_fw_resource_deinit(ab);
	ath11k_ce_free_pipes(ab);
	ath11k_core_free(ab);
	platform_set_drvdata(pdev, NULL);
Loading