Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ffe0acc authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-next-for-davem-2019-05-03' of...

Merge tag 'wireless-drivers-next-for-davem-2019-05-03' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next



Kalle Valo says:

====================
wireless-drivers-next patches for 5.2

Most likely the last patchset of new feature for 5.2, and this time we
have quite a lot of new features. Most obvious being rtw88 from
Realtek which supports RTL8822BE and RTL8822CE 802.11ac devices. We
have also new hardware support for existing drivers and improvements.

There's one conflict in iwlwifi, my example conflict resolution below.

Major changes:

iwlwifi

* bump the 20000-series FW API version

* work on new hardware continues

* RTT confidence indication support for Fine Timing Measurement (FTM)

* an improvement in HE (802.11ax) rate-scaling

* add command version parsing from the fimware TLVs

* add support for a new WoWLAN patterns firmware API

rsi

* add support for rs9116

mwifiex

* add support for SD8987

brcmfmac

* add quirk for ACEPC T8 and T11 mini PCs

rt2x00

* add RT3883 support

qtnfmac

* fix debugfs interface to support multiple cards

rtw88

* new driver

mt76

* share more code across drivers

* add support for MT7615 chipset

* rework DMA API

* tx/rx performance optimizations

* use NAPI for tx cleanup on mt76x02

* AP mode support for USB devices

* USB stability fixes

* tx power handling fixes for 76x2

* endian fixes

Conflicts:

There's a trivial conflict in
drivers/net/wireless/intel/iwlwifi/fw/file.h, just leave
IWL_UCODE_TLV_FW_FSEQ_VERSION to the file. 'git diff' output should be
just empty:

diff --cc drivers/net/wireless/intel/iwlwifi/fw/file.h
index cd622af90077,b0671e16e1ce..000000000000
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cc0d47b8 f9b628d6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -9782,6 +9782,8 @@ F: Documentation/devicetree/bindings/media/mediatek-vpu.txt
MEDIATEK MT76 WIRELESS LAN DRIVER
M:	Felix Fietkau <nbd@nbd.name>
M:	Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
R:	Ryder Lee <ryder.lee@mediatek.com>
R:	Roy Luo <royluo@google.com>
L:	linux-wireless@vger.kernel.org
S:	Maintained
F:	drivers/net/wireless/mediatek/mt76/
@@ -13412,6 +13414,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g
S:	Maintained
F:	drivers/net/wireless/realtek/rtlwifi/

REALTEK WIRELESS DRIVER (rtw88)
M:	Yan-Hsuan Chuang <yhchuang@realtek.com>
L:	linux-wireless@vger.kernel.org
S:	Maintained
F:	drivers/net/wireless/realtek/rtw88/

RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
M:	Jes Sorensen <Jes.Sorensen@gmail.com>
L:	linux-wireless@vger.kernel.org
+8 −3
Original line number Diff line number Diff line
@@ -465,7 +465,7 @@ static int wil_cfg80211_validate_add_iface(struct wil6210_priv *wil,
		.num_different_channels = 1,
	};

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		if (wil->vifs[i]) {
			wdev = vif_to_wdev(wil->vifs[i]);
			params.iftype_num[wdev->iftype]++;
@@ -486,7 +486,7 @@ static int wil_cfg80211_validate_change_iface(struct wil6210_priv *wil,
	};
	bool check_combos = false;

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		struct wil6210_vif *vif_pos = wil->vifs[i];

		if (vif_pos && vif != vif_pos) {
@@ -1274,7 +1274,12 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
			     params->wait);

out:
	/* when the sent packet was not acked by receiver(ACK=0), rc will
	 * be -EAGAIN. In this case this function needs to return success,
	 * the ACK=0 will be reflected in tx_status.
	 */
	tx_status = (rc == 0);
	rc = (rc == -EAGAIN) ? 0 : rc;
	cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
				tx_status, GFP_KERNEL);

@@ -1806,7 +1811,7 @@ void wil_cfg80211_ap_recovery(struct wil6210_priv *wil)
	int rc, i;
	struct wiphy *wiphy = wil_to_wiphy(wil);

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		struct wil6210_vif *vif = wil->vifs[i];
		struct net_device *ndev;
		struct cfg80211_beacon_data bcon = {};
+29 −9
Original line number Diff line number Diff line
@@ -207,6 +207,8 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil,
		seq_puts(s, "???\n");
	}
	seq_printf(s, "  desc_rdy_pol   = %d\n", sring->desc_rdy_pol);
	seq_printf(s, "  invalid_buff_id_cnt   = %d\n",
		   sring->invalid_buff_id_cnt);

	if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
		uint i;
@@ -258,6 +260,11 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,

	wil_halp_vote(wil);

	if (wil_mem_access_lock(wil)) {
		wil_halp_unvote(wil);
		return;
	}

	wil_memcpy_fromio_32(&r, off, sizeof(r));
	wil_mbox_ring_le2cpus(&r);
	/*
@@ -323,6 +330,7 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,
	}
 out:
	seq_puts(s, "}\n");
	wil_mem_access_unlock(wil);
	wil_halp_unvote(wil);
}

@@ -601,6 +609,12 @@ static int memread_show(struct seq_file *s, void *data)
	if (ret < 0)
		return ret;

	ret = wil_mem_access_lock(wil);
	if (ret) {
		wil_pm_runtime_put(wil);
		return ret;
	}

	a = wmi_buffer(wil, cpu_to_le32(mem_addr));

	if (a)
@@ -608,6 +622,7 @@ static int memread_show(struct seq_file *s, void *data)
	else
		seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);

	wil_mem_access_unlock(wil);
	wil_pm_runtime_put(wil);

	return 0;
@@ -626,10 +641,6 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
	size_t unaligned_bytes, aligned_count, ret;
	int rc;

	if (test_bit(wil_status_suspending, wil_blob->wil->status) ||
	    test_bit(wil_status_suspended, wil_blob->wil->status))
		return 0;

	if (pos < 0)
		return -EINVAL;

@@ -656,11 +667,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
		return rc;
	}

	rc = wil_mem_access_lock(wil);
	if (rc) {
		kfree(buf);
		wil_pm_runtime_put(wil);
		return rc;
	}

	wil_memcpy_fromio_32(buf, (const void __iomem *)
			     wil_blob->blob.data + aligned_pos, aligned_count);

	ret = copy_to_user(user_buf, buf + unaligned_bytes, count);

	wil_mem_access_unlock(wil);
	wil_pm_runtime_put(wil);

	kfree(buf);
@@ -1364,7 +1383,7 @@ static int link_show(struct seq_file *s, void *data)
		if (p->status != wil_sta_connected)
			continue;

		vif = (mid < wil->max_vifs) ? wil->vifs[mid] : NULL;
		vif = (mid < GET_MAX_VIFS(wil)) ? wil->vifs[mid] : NULL;
		if (vif) {
			rc = wil_cid_fill_sinfo(vif, i, sinfo);
			if (rc)
@@ -1562,7 +1581,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
			break;
		}
		mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX;
		if (mid < wil->max_vifs) {
		if (mid < GET_MAX_VIFS(wil)) {
			struct wil6210_vif *vif = wil->vifs[mid];

			if (vif->wdev.iftype == NL80211_IFTYPE_STATION &&
@@ -1628,7 +1647,7 @@ static int mids_show(struct seq_file *s, void *data)
	int i;

	mutex_lock(&wil->vif_mutex);
	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];

		if (vif) {
@@ -1849,7 +1868,7 @@ static int wil_link_stats_debugfs_show(struct seq_file *s, void *data)
	/* iterate over all MIDs and show per-cid statistics. Then show the
	 * global statistics
	 */
	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];

		seq_printf(s, "MID %d ", i);
@@ -1905,7 +1924,7 @@ static ssize_t wil_link_stats_write(struct file *file, const char __user *buf,
	if (rc)
		return rc;

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];
		if (!vif)
			continue;
@@ -2375,6 +2394,7 @@ static const struct dbg_off dbg_wil_regs[] = {
	{"RGF_MAC_MTRL_COUNTER_0", 0444, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
		doff_io32},
	{"RGF_USER_USAGE_1", 0444, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
	{"RGF_USER_USAGE_2", 0444, HOSTADDR(RGF_USER_USAGE_2), doff_io32},
	{},
};

+5 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -647,6 +647,8 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name,

out:
	release_firmware(fw);
	if (rc)
		wil_err_fw(wil, "Loading <%s> failed, rc %d\n", name, rc);
	return rc;
}

@@ -741,6 +743,8 @@ int wil_request_board(struct wil6210_priv *wil, const char *name)

out:
	release_firmware(brd);
	if (rc)
		wil_err_fw(wil, "Loading <%s> failed, rc %d\n", name, rc);
	return rc;
}

+52 −26
Original line number Diff line number Diff line
@@ -184,6 +184,28 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
	}
}

/* Device memory access is prohibited while reset or suspend.
 * wil_mem_access_lock protects accessing device memory in these cases
 */
int wil_mem_access_lock(struct wil6210_priv *wil)
{
	if (!down_read_trylock(&wil->mem_lock))
		return -EBUSY;

	if (test_bit(wil_status_suspending, wil->status) ||
	    test_bit(wil_status_suspended, wil->status)) {
		up_read(&wil->mem_lock);
		return -EBUSY;
	}

	return 0;
}

void wil_mem_access_unlock(struct wil6210_priv *wil)
{
	up_read(&wil->mem_lock);
}

static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
{
	struct wil_ring *ring = &wil->ring_tx[id];
@@ -663,7 +685,7 @@ void wil_bcast_fini_all(struct wil6210_priv *wil)
	int i;
	struct wil6210_vif *vif;

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];
		if (vif)
			wil_bcast_fini(vif);
@@ -703,6 +725,7 @@ int wil_priv_init(struct wil6210_priv *wil)
	spin_lock_init(&wil->wmi_ev_lock);
	spin_lock_init(&wil->net_queue_lock);
	init_waitqueue_head(&wil->wq);
	init_rwsem(&wil->mem_lock);

	wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
	if (!wil->wmi_wq)
@@ -1390,6 +1413,13 @@ static int wil_get_otp_info(struct wil6210_priv *wil)
	u8 mac[8];
	int mac_addr;

	/* OEM MAC has precedence */
	mac_addr = RGF_OTP_OEM_MAC;
	wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(mac_addr), sizeof(mac));

	if (is_valid_ether_addr(mac)) {
		wil_info(wil, "using OEM MAC %pM\n", mac);
	} else {
		if (wil->hw_version >= HW_VER_TALYN_MB)
			mac_addr = RGF_OTP_MAC_TALYN_MB;
		else
@@ -1397,6 +1427,8 @@ static int wil_get_otp_info(struct wil6210_priv *wil)

		wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(mac_addr),
				     sizeof(mac));
	}

	if (!is_valid_ether_addr(mac)) {
		wil_err(wil, "Invalid MAC %pM\n", mac);
		return -EINVAL;
@@ -1460,7 +1492,7 @@ void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync)

	lockdep_assert_held(&wil->vif_mutex);

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		struct wil6210_vif *vif = wil->vifs[i];

		if (vif)
@@ -1500,11 +1532,6 @@ static void wil_pre_fw_config(struct wil6210_priv *wil)
	if (wil->hw_version < HW_VER_TALYN_MB) {
		wil_s(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0);
		wil_w(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0);
	} else {
		wil_s(wil,
		      RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, ICR), 0);
		wil_w(wil, RGF_CAF_ICR_TALYN_MB +
		      offsetof(struct RGF_ICR, IMV), ~0);
	}
	/* clear PAL_UNIT_ICR (potential D0->D3 leftover)
	 * In Talyn-MB host cannot access this register due to
@@ -1528,7 +1555,7 @@ static int wil_restore_vifs(struct wil6210_priv *wil)
	struct wireless_dev *wdev;
	int i, rc;

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];
		if (!vif)
			continue;
@@ -1580,7 +1607,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	if (wil->hw_version == HW_VER_UNKNOWN)
		return -ENODEV;

	if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa)) {
	if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa) &&
	    wil->hw_version < HW_VER_TALYN_MB) {
		wil_dbg_misc(wil, "Notify FW to set T_POWER_ON=0\n");
		wil_s(wil, RGF_USER_USAGE_8, BIT_USER_SUPPORT_T_POWER_ON_0);
	}
@@ -1599,20 +1627,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	}

	set_bit(wil_status_resetting, wil->status);
	if (test_bit(wil_status_collecting_dumps, wil->status)) {
		/* Device collects crash dump, cancel the reset.
		 * following crash dump collection, reset would take place.
		 */
		wil_dbg_misc(wil, "reject reset while collecting crash dump\n");
		rc = -EBUSY;
		goto out;
	}

	mutex_lock(&wil->vif_mutex);
	wil_abort_scan_all_vifs(wil, false);
	mutex_unlock(&wil->vif_mutex);

	for (i = 0; i < wil->max_vifs; i++) {
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		vif = wil->vifs[i];
		if (vif) {
			cancel_work_sync(&vif->disconnect_worker);
@@ -1782,7 +1801,9 @@ int __wil_up(struct wil6210_priv *wil)

	WARN_ON(!mutex_is_locked(&wil->mutex));

	down_write(&wil->mem_lock);
	rc = wil_reset(wil, true);
	up_write(&wil->mem_lock);
	if (rc)
		return rc;

@@ -1854,6 +1875,7 @@ int wil_up(struct wil6210_priv *wil)

int __wil_down(struct wil6210_priv *wil)
{
	int rc;
	WARN_ON(!mutex_is_locked(&wil->mutex));

	set_bit(wil_status_resetting, wil->status);
@@ -1873,7 +1895,11 @@ int __wil_down(struct wil6210_priv *wil)
	wil_abort_scan_all_vifs(wil, false);
	mutex_unlock(&wil->vif_mutex);

	return wil_reset(wil, false);
	down_write(&wil->mem_lock);
	rc = wil_reset(wil, false);
	up_write(&wil->mem_lock);

	return rc;
}

int wil_down(struct wil6210_priv *wil)
Loading