wireless-drivers-next patches for v5.9

First set of patches for v5.9. This comes later than usual as I was
 offline for two weeks. The biggest change here is moving Microchip
 wilc1000 driver from staging. There was an immutable topic branch with
 one commit moving the whole driver and the topic branch was pulled
 both to staging-next and wireless-drivers-next. At the moment the only
 reported conflict is in MAINTAINERS file, so I'm hoping the move
 should go smoothly.
 
 Other notable changes are ath11k getting 6 GHz band support and rtw88
 supporting RTL8821CE. And there's also the usual fixes, API changes
 and cleanups all over.
 
 Major changes:
 
 wilc1000
 
 * move from drivers/staging to drivers/net/wireless/microchip
 
 ath11k
 
 * add 6G band support
 
 * add spectral scan support
 
 iwlwifi
 
 * make FW reconfiguration quieter by not using warn level
 
 rtw88
 
 * add support for RTL8821CE
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJfFWQeAAoJEG4XJFUm622bVAwH/3r2oR+NS1kNDNGi9nrLAIav
 trLgPa2VbgPVgTcwIckfvZFl6BK9zo1KG6u6jYp45C6uNBJNESjarf8aLAXvXdFt
 t0yBkb6OCUq+efoOFbxV2im6ER57aN27POsn74xrCeR3fwZgY9QSHRMjQ5x1tjWH
 JdVatT6jtu2LuxsTjfS0K5kjeuyE0vE1iCUlsQ5qwcSLODGa9u7ydheoNcLOHvss
 ACun8zXvWqJhTar+iJHiTJTWyQPE6es0V1SAw0RnTuLRRmtv/Q9Zx4YOH2d3JkOC
 55mfgO3uNzw8fcJ5hoILHtXxhI2qtSkdydIFbE1U9CgBKE39Uo0VgFf9fl6VJRg=
 =7a5a
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-2020-07-20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for v5.9

First set of patches for v5.9. This comes later than usual as I was
offline for two weeks. The biggest change here is moving Microchip
wilc1000 driver from staging. There was an immutable topic branch with
one commit moving the whole driver and the topic branch was pulled
both to staging-next and wireless-drivers-next. At the moment the only
reported conflict is in MAINTAINERS file, so I'm hoping the move
should go smoothly.

Other notable changes are ath11k getting 6 GHz band support and rtw88
supporting RTL8821CE. And there's also the usual fixes, API changes
and cleanups all over.

Major changes:

wilc1000

* move from drivers/staging to drivers/net/wireless/microchip

ath11k

* add 6G band support

* add spectral scan support

iwlwifi

* make FW reconfiguration quieter by not using warn level

rtw88

* add support for RTL8821CE
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-07-20 17:52:50 -07:00
commit cfd6920175
131 changed files with 11832 additions and 627 deletions

View File

@ -11352,6 +11352,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Supported
F: drivers/usb/gadget/udc/atmel_usba_udc.*
MICROCHIP WILC1000 WIFI DRIVER
M: Ajay Singh <ajay.kathat@microchip.com>
M: Claudiu Beznea <claudiu.beznea@microchip.com>
L: linux-wireless@vger.kernel.org
S: Supported
F: drivers/net/wireless/microchip/wilc1000/
MICROCHIP XDMA DRIVER
M: Ludovic Desroches <ludovic.desroches@microchip.com>
L: linux-arm-kernel@lists.infradead.org
@ -16256,13 +16263,6 @@ M: Forest Bond <forest@alittletooquiet.net>
S: Odd Fixes
F: drivers/staging/vt665?/
STAGING - WILC1000 WIFI DRIVER
M: Adham Abozaeid <adham.abozaeid@microchip.com>
M: Ajay Singh <ajay.kathat@microchip.com>
L: linux-wireless@vger.kernel.org
S: Supported
F: drivers/staging/wilc1000/
STAGING SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: devel@driverdev.osuosl.org

View File

@ -14,7 +14,7 @@ menuconfig WLAN
device drivers. For a complete list of drivers and documentation
on them refer to the wireless wiki:
http://wireless.kernel.org/en/users/Drivers
https://wireless.wiki.kernel.org/en/users/Drivers
if WLAN
@ -40,6 +40,7 @@ source "drivers/net/wireless/intel/Kconfig"
source "drivers/net/wireless/intersil/Kconfig"
source "drivers/net/wireless/marvell/Kconfig"
source "drivers/net/wireless/mediatek/Kconfig"
source "drivers/net/wireless/microchip/Kconfig"
source "drivers/net/wireless/ralink/Kconfig"
source "drivers/net/wireless/realtek/Kconfig"
source "drivers/net/wireless/rsi/Kconfig"

View File

@ -12,6 +12,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTEL) += intel/
obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/
obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/
obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/

View File

@ -1976,35 +1976,20 @@ static void adm8211_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
{
pci_save_state(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
static int adm8211_resume(struct pci_dev *pdev)
{
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
return 0;
}
#endif /* CONFIG_PM */
#define adm8211_suspend NULL
#define adm8211_resume NULL
MODULE_DEVICE_TABLE(pci, adm8211_pci_id_table);
static SIMPLE_DEV_PM_OPS(adm8211_pm_ops, adm8211_suspend, adm8211_resume);
/* TODO: implement enable_wake */
static struct pci_driver adm8211_driver = {
.name = "adm8211",
.id_table = adm8211_pci_id_table,
.probe = adm8211_probe,
.remove = adm8211_remove,
#ifdef CONFIG_PM
.suspend = adm8211_suspend,
.resume = adm8211_resume,
#endif /* CONFIG_PM */
.driver.pm = &adm8211_pm_ops,
};
module_pci_driver(adm8211_driver);

View File

@ -15,11 +15,11 @@ config WLAN_VENDOR_ATH
For more information and documentation on this module you can visit:
http://wireless.kernel.org/en/users/Drivers/ath
https://wireless.wiki.kernel.org/en/users/Drivers/ath
For information on all Atheros wireless drivers visit:
http://wireless.kernel.org/en/users/Drivers/Atheros
https://wireless.wiki.kernel.org/en/users/Drivers/Atheros
if WLAN_VENDOR_ATH

View File

@ -1591,7 +1591,9 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
err_unmap_msdu:
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_msdu_id:
spin_lock_bh(&htt->tx_lock);
ath10k_htt_tx_free_msdu_id(htt, msdu_id);
spin_unlock_bh(&htt->tx_lock);
err:
return res;
}
@ -1798,7 +1800,9 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
err_unmap_msdu:
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_msdu_id:
spin_lock_bh(&htt->tx_lock);
ath10k_htt_tx_free_msdu_id(htt, msdu_id);
spin_unlock_bh(&htt->tx_lock);
err:
return res;
}

View File

@ -824,7 +824,7 @@ static int ath10k_usb_setup_pipe_resources(struct ath10k *ar,
ath10k_dbg(ar, ATH10K_DBG_USB, "usb setting up pipes using interface\n");
/* walk decriptors and setup pipes */
/* walk descriptors and setup pipes */
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;

View File

@ -34,3 +34,12 @@ config ATH11K_TRACING
depends on ATH11K && EVENT_TRACING
help
Select this to use ath11k tracing infrastructure.
config ATH11K_SPECTRAL
bool "QCA ath11k spectral scan support"
depends on ATH11K_DEBUGFS
depends on RELAY
help
Enable ath11k spectral scan support
Say Y to enable access to the FFT/spectral data via debugfs.

View File

@ -15,12 +15,14 @@ ath11k-y += core.o \
dp_rx.o \
debug.o \
ce.o \
peer.o
peer.o \
dbring.o
ath11k-$(CONFIG_ATH11K_DEBUGFS) += debug_htt_stats.o debugfs_sta.o
ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
ath11k-$(CONFIG_ATH11K_TRACING) += trace.o
ath11k-$(CONFIG_THERMAL) += thermal.o
ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)

View File

@ -400,8 +400,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
goto err_dp_pdev_free;
}
ret = ath11k_spectral_init(ab);
if (ret) {
ath11k_err(ab, "failed to init spectral %d\n", ret);
goto err_thermal_unregister;
}
return 0;
err_thermal_unregister:
ath11k_thermal_unregister(ab);
err_dp_pdev_free:
ath11k_dp_pdev_free(ab);
err_mac_unregister:
@ -414,6 +422,7 @@ err_pdev_debug:
static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
{
ath11k_spectral_deinit(ab);
ath11k_thermal_unregister(ab);
ath11k_mac_unregister(ab);
ath11k_hif_irq_disable(ab);
@ -582,6 +591,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
ath11k_thermal_unregister(ab);
ath11k_hif_irq_disable(ab);
ath11k_dp_pdev_free(ab);
ath11k_spectral_deinit(ab);
ath11k_hif_stop(ab);
ath11k_wmi_detach(ab);
ath11k_dp_pdev_reo_cleanup(ab);

View File

@ -21,6 +21,8 @@
#include "hal_rx.h"
#include "reg.h"
#include "thermal.h"
#include "dbring.h"
#include "spectral.h"
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@ -215,12 +217,15 @@ struct ath11k_vif {
bool is_started;
bool is_up;
bool spectral_enabled;
u32 aid;
u8 bssid[ETH_ALEN];
struct cfg80211_bitrate_mask bitrate_mask;
int num_legacy_stations;
int rtscts_prot_mode;
int txpower;
bool rsnie_present;
bool wpaie_present;
};
struct ath11k_vif_iter {
@ -353,7 +358,10 @@ struct ath11k_sta {
#endif
};
#define ATH11K_NUM_CHANS 41
#define ATH11K_MIN_5G_FREQ 4150
#define ATH11K_MIN_6G_FREQ 5945
#define ATH11K_MAX_6G_FREQ 7115
#define ATH11K_NUM_CHANS 100
#define ATH11K_MAX_5G_CHAN 173
enum ath11k_state {
@ -431,6 +439,7 @@ struct ath11k {
u32 vht_cap_info;
struct ath11k_he ar_he;
enum ath11k_state state;
bool supports_6ghz;
struct {
struct completion started;
struct completion completed;
@ -536,6 +545,9 @@ struct ath11k {
u32 cached_ppdu_id;
#ifdef CONFIG_ATH11K_DEBUGFS
struct ath11k_debug debug;
#endif
#ifdef CONFIG_ATH11K_SPECTRAL
struct ath11k_spectral spectral;
#endif
bool dfs_block_radar_events;
struct ath11k_thermal thermal;
@ -548,6 +560,7 @@ struct ath11k_band_cap {
u32 he_mcs;
u32 he_cap_phy_info[PSOC_HOST_MAX_PHY_SIZE];
struct ath11k_ppe_threshold he_ppet;
u16 he_6ghz_capa;
};
struct ath11k_pdev_cap {
@ -579,12 +592,42 @@ struct ath11k_board_data {
/* IPQ8074 HW channel counters frequency value in hertz */
#define IPQ8074_CC_FREQ_HERTZ 320000
struct ath11k_soc_dp_rx_stats {
struct ath11k_bp_stats {
/* Head Pointer reported by the last HTT Backpressure event for the ring */
u16 hp;
/* Tail Pointer reported by the last HTT Backpressure event for the ring */
u16 tp;
/* Number of Backpressure events received for the ring */
u32 count;
/* Last recorded event timestamp */
unsigned long jiffies;
};
struct ath11k_dp_ring_bp_stats {
struct ath11k_bp_stats umac_ring_bp_stats[HTT_SW_UMAC_RING_IDX_MAX];
struct ath11k_bp_stats lmac_ring_bp_stats[HTT_SW_LMAC_RING_IDX_MAX][MAX_RADIOS];
};
struct ath11k_soc_dp_tx_err_stats {
/* TCL Ring Descriptor unavailable */
u32 desc_na[DP_TCL_NUM_RING_MAX];
/* Other failures during dp_tx due to mem allocation failure
* idr unavailable etc.
*/
atomic_t misc_fail;
};
struct ath11k_soc_dp_stats {
u32 err_ring_pkts;
u32 invalid_rbm;
u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
u32 hal_reo_error[DP_REO_DST_RING_MAX];
struct ath11k_soc_dp_tx_err_stats tx_err;
struct ath11k_dp_ring_bp_stats bp_stats;
};
/* Master structure to hold the hw data which may be used in core module */
@ -653,7 +696,7 @@ struct ath11k_base {
struct dentry *debugfs_soc;
struct dentry *debugfs_ath11k;
#endif
struct ath11k_soc_dp_rx_stats soc_stats;
struct ath11k_soc_dp_stats soc_stats;
unsigned long dev_flags;
struct completion driver_recovery;
@ -668,6 +711,9 @@ struct ath11k_base {
/* Round robbin based TCL ring selector */
atomic_t tcl_ring_selector;
struct ath11k_dbring_cap *db_caps;
u32 num_db_cap;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};

View File

@ -0,0 +1,356 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
*/
#include "core.h"
#include "debug.h"
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
struct ath11k_dbring *ring,
struct ath11k_dbring_element *buff,
gfp_t gfp)
{
struct ath11k_base *ab = ar->ab;
struct hal_srng *srng;
dma_addr_t paddr;
void *ptr_aligned, *ptr_unaligned, *desc;
int ret;
int buf_id;
u32 cookie;
srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
lockdep_assert_held(&srng->lock);
ath11k_hal_srng_access_begin(ab, srng);
ptr_unaligned = buff->payload;
ptr_aligned = PTR_ALIGN(ptr_unaligned, ring->buf_align);
paddr = dma_map_single(ab->dev, ptr_aligned, ring->buf_sz,
DMA_FROM_DEVICE);
ret = dma_mapping_error(ab->dev, paddr);
if (ret)
goto err;
spin_lock_bh(&ring->idr_lock);
buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp);
spin_unlock_bh(&ring->idr_lock);
if (buf_id < 0) {
ret = -ENOBUFS;
goto err_dma_unmap;
}
desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
if (!desc) {
ret = -ENOENT;
goto err_idr_remove;
}
buff->paddr = paddr;
cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) |
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0);
ath11k_hal_srng_access_end(ab, srng);
return 0;
err_idr_remove:
spin_lock_bh(&ring->idr_lock);
idr_remove(&ring->bufs_idr, buf_id);
spin_unlock_bh(&ring->idr_lock);
err_dma_unmap:
dma_unmap_single(ab->dev, paddr, ring->buf_sz,
DMA_FROM_DEVICE);
err:
ath11k_hal_srng_access_end(ab, srng);
return ret;
}
static int ath11k_dbring_fill_bufs(struct ath11k *ar,
struct ath11k_dbring *ring,
gfp_t gfp)
{
struct ath11k_dbring_element *buff;
struct hal_srng *srng;
int num_remain, req_entries, num_free;
u32 align;
int size, ret;
srng = &ar->ab->hal.srng_list[ring->refill_srng.ring_id];
spin_lock_bh(&srng->lock);
num_free = ath11k_hal_srng_src_num_free(ar->ab, srng, true);
req_entries = min(num_free, ring->bufs_max);
num_remain = req_entries;
align = ring->buf_align;
size = sizeof(*buff) + ring->buf_sz + align - 1;
while (num_remain > 0) {
buff = kzalloc(size, gfp);
if (!buff)
break;
ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp);
if (ret) {
ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
num_remain, req_entries);
kfree(buff);
break;
}
num_remain--;
}
spin_unlock_bh(&srng->lock);
return num_remain;
}
int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
struct ath11k_dbring *ring,
enum wmi_direct_buffer_module id)
{
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {0};
int ret;
if (id >= WMI_DIRECT_BUF_MAX)
return -EINVAL;
param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
param.module_id = id;
param.base_paddr_lo = lower_32_bits(ring->refill_srng.paddr);
param.base_paddr_hi = upper_32_bits(ring->refill_srng.paddr);
param.head_idx_paddr_lo = lower_32_bits(ring->hp_addr);
param.head_idx_paddr_hi = upper_32_bits(ring->hp_addr);
param.tail_idx_paddr_lo = lower_32_bits(ring->tp_addr);
param.tail_idx_paddr_hi = upper_32_bits(ring->tp_addr);
param.num_elems = ring->bufs_max;
param.buf_size = ring->buf_sz;
param.num_resp_per_event = ring->num_resp_per_event;
param.event_timeout_ms = ring->event_timeout_ms;
ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
if (ret) {
ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
return ret;
}
return 0;
}
int ath11k_dbring_set_cfg(struct ath11k *ar, struct ath11k_dbring *ring,
u32 num_resp_per_event, u32 event_timeout_ms,
int (*handler)(struct ath11k *,
struct ath11k_dbring_data *))
{
if (WARN_ON(!ring))
return -EINVAL;
ring->num_resp_per_event = num_resp_per_event;
ring->event_timeout_ms = event_timeout_ms;
ring->handler = handler;
return 0;
}
int ath11k_dbring_buf_setup(struct ath11k *ar,
struct ath11k_dbring *ring,
struct ath11k_dbring_cap *db_cap)
{
struct ath11k_base *ab = ar->ab;
struct hal_srng *srng;
int ret;
srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
ring->bufs_max = ring->refill_srng.size /
ath11k_hal_srng_get_entrysize(HAL_RXDMA_DIR_BUF);
ring->buf_sz = db_cap->min_buf_sz;
ring->buf_align = db_cap->min_buf_align;
ring->pdev_id = db_cap->pdev_id;
ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng);
ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng);
ret = ath11k_dbring_fill_bufs(ar, ring, GFP_KERNEL);
return ret;
}
int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring,
int ring_num, int num_entries)
{
int ret;
ret = ath11k_dp_srng_setup(ar->ab, &ring->refill_srng, HAL_RXDMA_DIR_BUF,
ring_num, ar->pdev_idx, num_entries);
if (ret < 0) {
ath11k_warn(ar->ab, "failed to setup srng: %d ring_id %d\n",
ret, ring_num);
goto err;
}
return 0;
err:
ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng);
return ret;
}
int ath11k_dbring_get_cap(struct ath11k_base *ab,
u8 pdev_idx,
enum wmi_direct_buffer_module id,
struct ath11k_dbring_cap *db_cap)
{
int i;
if (!ab->num_db_cap || !ab->db_caps)
return -ENOENT;
if (id >= WMI_DIRECT_BUF_MAX)
return -EINVAL;
for (i = 0; i < ab->num_db_cap; i++) {
if (pdev_idx == ab->db_caps[i].pdev_id &&
id == ab->db_caps[i].id) {
*db_cap = ab->db_caps[i];
return 0;
}
}
return -ENOENT;
}
int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
struct ath11k_dbring_buf_release_event *ev)
{
struct ath11k_dbring *ring;
struct hal_srng *srng;
struct ath11k *ar;
struct ath11k_dbring_element *buff;
struct ath11k_dbring_data handler_data;
struct ath11k_buffer_addr desc;
u8 *vaddr_unalign;
u32 num_entry, num_buff_reaped;
u8 pdev_idx, rbm;
u32 cookie;
int buf_id;
int size;
dma_addr_t paddr;
int ret = 0;
pdev_idx = ev->fixed.pdev_id;
if (pdev_idx >= ab->num_radios) {
ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx);
return -EINVAL;
}
if (ev->fixed.num_buf_release_entry !=
ev->fixed.num_meta_data_entry) {
ath11k_warn(ab, "Buffer entry %d mismatch meta entry %d\n",
ev->fixed.num_buf_release_entry,
ev->fixed.num_meta_data_entry);
return -EINVAL;
}
ar = ab->pdevs[pdev_idx].ar;
rcu_read_lock();
if (!rcu_dereference(ab->pdevs_active[pdev_idx])) {
ret = -EINVAL;
goto rcu_unlock;
}
switch (ev->fixed.module_id) {
case WMI_DIRECT_BUF_SPECTRAL:
ring = ath11k_spectral_get_dbring(ar);
break;
default:
ring = NULL;
ath11k_warn(ab, "Recv dma buffer release ev on unsupp module %d\n",
ev->fixed.module_id);
break;
}
if (!ring) {
ret = -EINVAL;
goto rcu_unlock;
}
srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
num_entry = ev->fixed.num_buf_release_entry;
size = sizeof(*buff) + ring->buf_sz + ring->buf_align - 1;
num_buff_reaped = 0;
spin_lock_bh(&srng->lock);
while (num_buff_reaped < num_entry) {
desc.info0 = ev->buf_entry[num_buff_reaped].paddr_lo;
desc.info1 = ev->buf_entry[num_buff_reaped].paddr_hi;
handler_data.meta = ev->meta_data[num_buff_reaped];
num_buff_reaped++;
ath11k_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm);
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie);
spin_lock_bh(&ring->idr_lock);
buff = idr_find(&ring->bufs_idr, buf_id);
if (!buff) {
spin_unlock_bh(&ring->idr_lock);
continue;
}
idr_remove(&ring->bufs_idr, buf_id);
spin_unlock_bh(&ring->idr_lock);
dma_unmap_single(ab->dev, buff->paddr, ring->buf_sz,
DMA_FROM_DEVICE);
if (ring->handler) {
vaddr_unalign = buff->payload;
handler_data.data = PTR_ALIGN(vaddr_unalign,
ring->buf_align);
handler_data.data_sz = ring->buf_sz;
ring->handler(ar, &handler_data);
}
memset(buff, 0, size);
ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC);
}
spin_unlock_bh(&srng->lock);
rcu_unlock:
rcu_read_unlock();
return ret;
}
void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring)
{
ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng);
}
void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring)
{
struct ath11k_dbring_element *buff;
int buf_id;
spin_lock_bh(&ring->idr_lock);
idr_for_each_entry(&ring->bufs_idr, buff, buf_id) {
idr_remove(&ring->bufs_idr, buf_id);
dma_unmap_single(ar->ab->dev, buff->paddr,
ring->buf_sz, DMA_FROM_DEVICE);
kfree(buff);
}
idr_destroy(&ring->bufs_idr);
spin_unlock_bh(&ring->idr_lock);
}

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
*/
#ifndef ATH11K_DBRING_H
#define ATH11K_DBRING_H
#include <linux/types.h>
#include <linux/idr.h>
#include <linux/spinlock.h>
#include "dp.h"
struct ath11k_dbring_element {
dma_addr_t paddr;
u8 payload[0];
};
struct ath11k_dbring_data {
void *data;
u32 data_sz;
struct wmi_dma_buf_release_meta_data meta;
};
struct ath11k_dbring_buf_release_event {
struct ath11k_wmi_dma_buf_release_fixed_param fixed;
struct wmi_dma_buf_release_entry *buf_entry;
struct wmi_dma_buf_release_meta_data *meta_data;
u32 num_buf_entry;
u32 num_meta;
};
struct ath11k_dbring_cap {
u32 pdev_id;
enum wmi_direct_buffer_module id;
u32 min_elem;
u32 min_buf_sz;
u32 min_buf_align;
};
struct ath11k_dbring {
struct dp_srng refill_srng;
struct idr bufs_idr;
/* Protects bufs_idr */
spinlock_t idr_lock;
dma_addr_t tp_addr;
dma_addr_t hp_addr;
int bufs_max;
u32 pdev_id;
u32 buf_sz;
u32 buf_align;
u32 num_resp_per_event;
u32 event_timeout_ms;
int (*handler)(struct ath11k *, struct ath11k_dbring_data *);
};
int ath11k_dbring_set_cfg(struct ath11k *ar,
struct ath11k_dbring *ring,
u32 num_resp_per_event,
u32 event_timeout_ms,
int (*handler)(struct ath11k *,
struct ath11k_dbring_data *));
int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
struct ath11k_dbring *ring,
enum wmi_direct_buffer_module id);
int ath11k_dbring_buf_setup(struct ath11k *ar,
struct ath11k_dbring *ring,
struct ath11k_dbring_cap *db_cap);
int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring,
int ring_num, int num_entries);
int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
struct ath11k_dbring_buf_release_event *ev);
int ath11k_dbring_get_cap(struct ath11k_base *ab,
u8 pdev_idx,
enum wmi_direct_buffer_module id,
struct ath11k_dbring_cap *db_cap);
void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
#endif /* ATH11K_DBRING_H */

View File

@ -12,6 +12,43 @@
#include "debug_htt_stats.h"
#include "peer.h"
static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
"REO2SW1_RING",
"REO2SW2_RING",
"REO2SW3_RING",
"REO2SW4_RING",
"WBM2REO_LINK_RING",
"REO2TCL_RING",
"REO2FW_RING",
"RELEASE_RING",
"PPE_RELEASE_RING",
"TCL2TQM_RING",
"TQM_RELEASE_RING",
"REO_RELEASE_RING",
"WBM2SW0_RELEASE_RING",
"WBM2SW1_RELEASE_RING",
"WBM2SW2_RELEASE_RING",
"WBM2SW3_RELEASE_RING",
"REO_CMD_RING",
"REO_STATUS_RING",
};
static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
"FW2RXDMA_BUF_RING",
"FW2RXDMA_STATUS_RING",
"FW2RXDMA_LINK_RING",
"SW2RXDMA_BUF_RING",
"WBM2RXDMA_LINK_RING",
"RXDMA2FW_RING",
"RXDMA2SW_RING",
"RXDMA2RELEASE_RING",
"RXDMA2REO_RING",
"MONITOR_STATUS_RING",
"MONITOR_BUF_RING",
"MONITOR_DESC_RING",
"MONITOR_DEST_RING",
};
void ath11k_info(struct ath11k_base *ab, const char *fmt, ...)
{
struct va_format vaf = {
@ -739,12 +776,78 @@ static const struct file_operations fops_extd_rx_stats = {
.open = simple_open,
};
static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
static int ath11k_fill_bp_stats(struct ath11k_base *ab,
struct ath11k_bp_stats *bp_stats,
char *buf, int len, int size)
{
lockdep_assert_held(&ab->base_lock);
len += scnprintf(buf + len, size - len, "count: %u\n",
bp_stats->count);
len += scnprintf(buf + len, size - len, "hp: %u\n",
bp_stats->hp);
len += scnprintf(buf + len, size - len, "tp: %u\n",
bp_stats->tp);
len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
jiffies_to_msecs(jiffies - bp_stats->jiffies));
return len;
}
static ssize_t ath11k_debug_dump_soc_ring_bp_stats(struct ath11k_base *ab,
char *buf, int size)
{
struct ath11k_bp_stats *bp_stats;
bool stats_rxd = false;
u8 i, pdev_idx;
int len = 0;
len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
len += scnprintf(buf + len, size - len, "==================\n");
spin_lock_bh(&ab->base_lock);
for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
if (!bp_stats->count)
continue;
len += scnprintf(buf + len, size - len, "Ring: %s\n",
htt_bp_umac_ring[i]);
len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
stats_rxd = true;
}
for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
bp_stats =
&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
if (!bp_stats->count)
continue;
len += scnprintf(buf + len, size - len, "Ring: %s\n",
htt_bp_lmac_ring[i]);
len += scnprintf(buf + len, size - len, "pdev: %d\n",
pdev_idx);
len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
stats_rxd = true;
}
}
spin_unlock_bh(&ab->base_lock);
if (!stats_rxd)
len += scnprintf(buf + len, size - len,
"No Ring Backpressure stats received\n\n");
return len;
}
static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath11k_base *ab = file->private_data;
struct ath11k_soc_dp_rx_stats *soc_stats = &ab->soc_stats;
struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
int len = 0, i, retval;
const int size = 4096;
static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
@ -788,6 +891,19 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
soc_stats->hal_reo_error[2],
soc_stats->hal_reo_error[3]);
len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
i, soc_stats->tx_err.desc_na[i]);
len += scnprintf(buf + len, size - len,
"\nMisc Transmit Failures: %d\n",
atomic_read(&soc_stats->tx_err.misc_fail));
len += ath11k_debug_dump_soc_ring_bp_stats(ab, buf + len, size - len);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
@ -796,8 +912,8 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
return retval;
}
static const struct file_operations fops_soc_rx_stats = {
.read = ath11k_debug_dump_soc_rx_stats,
static const struct file_operations fops_soc_dp_stats = {
.read = ath11k_debug_dump_soc_dp_stats,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
@ -819,8 +935,8 @@ int ath11k_debug_pdev_create(struct ath11k_base *ab)
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
&fops_simulate_fw_crash);
debugfs_create_file("soc_rx_stats", 0600, ab->debugfs_soc, ab,
&fops_soc_rx_stats);
debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
&fops_soc_dp_stats);
return 0;
}

View File

@ -172,11 +172,12 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
case HAL_RXDMA_DST:
case HAL_RXDMA_MONITOR_DST:
case HAL_RXDMA_MONITOR_DESC:
case HAL_RXDMA_DIR_BUF:
params.intr_batch_cntr_thres_entries =
HAL_SRNG_INT_BATCH_THRESHOLD_OTHER;
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_OTHER;
break;
case HAL_RXDMA_DIR_BUF:
break;
default:
ath11k_warn(ab, "Not a valid ring type in dp :%d\n", type);
return -EINVAL;

View File

@ -999,6 +999,48 @@ struct htt_resp_msg {
#define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0)
#define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16)
#define HTT_BACKPRESSURE_UMAC_RING_TYPE 0
#define HTT_BACKPRESSURE_LMAC_RING_TYPE 1
enum htt_backpressure_umac_ringid {
HTT_SW_RING_IDX_REO_REO2SW1_RING,
HTT_SW_RING_IDX_REO_REO2SW2_RING,
HTT_SW_RING_IDX_REO_REO2SW3_RING,
HTT_SW_RING_IDX_REO_REO2SW4_RING,
HTT_SW_RING_IDX_REO_WBM2REO_LINK_RING,
HTT_SW_RING_IDX_REO_REO2TCL_RING,
HTT_SW_RING_IDX_REO_REO2FW_RING,
HTT_SW_RING_IDX_REO_REO_RELEASE_RING,
HTT_SW_RING_IDX_WBM_PPE_RELEASE_RING,
HTT_SW_RING_IDX_TCL_TCL2TQM_RING,
HTT_SW_RING_IDX_WBM_TQM_RELEASE_RING,
HTT_SW_RING_IDX_WBM_REO_RELEASE_RING,
HTT_SW_RING_IDX_WBM_WBM2SW0_RELEASE_RING,
HTT_SW_RING_IDX_WBM_WBM2SW1_RELEASE_RING,
HTT_SW_RING_IDX_WBM_WBM2SW2_RELEASE_RING,
HTT_SW_RING_IDX_WBM_WBM2SW3_RELEASE_RING,
HTT_SW_RING_IDX_REO_REO_CMD_RING,
HTT_SW_RING_IDX_REO_REO_STATUS_RING,
HTT_SW_UMAC_RING_IDX_MAX,
};
enum htt_backpressure_lmac_ringid {
HTT_SW_RING_IDX_FW2RXDMA_BUF_RING,
HTT_SW_RING_IDX_FW2RXDMA_STATUS_RING,
HTT_SW_RING_IDX_FW2RXDMA_LINK_RING,
HTT_SW_RING_IDX_SW2RXDMA_BUF_RING,
HTT_SW_RING_IDX_WBM2RXDMA_LINK_RING,
HTT_SW_RING_IDX_RXDMA2FW_RING,
HTT_SW_RING_IDX_RXDMA2SW_RING,
HTT_SW_RING_IDX_RXDMA2RELEASE_RING,
HTT_SW_RING_IDX_RXDMA2REO_RING,
HTT_SW_RING_IDX_MONITOR_STATUS_RING,
HTT_SW_RING_IDX_MONITOR_BUF_RING,
HTT_SW_RING_IDX_MONITOR_DESC_RING,
HTT_SW_RING_IDX_MONITOR_DEST_RING,
HTT_SW_LMAC_RING_IDX_MAX,
};
/* ppdu stats
*
* @details

View File

@ -653,10 +653,8 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,
spin_lock_bh(&dp->reo_cmd_lock);
list_add_tail(&elem->list, &dp->reo_cmd_cache_flush_list);
dp->reo_cmd_cache_flush_count++;
spin_unlock_bh(&dp->reo_cmd_lock);
/* Flush and invalidate aged REO desc from HW cache */
spin_lock_bh(&dp->reo_cmd_lock);
list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_cache_flush_list,
list) {
if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD ||
@ -1503,9 +1501,10 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
struct sk_buff *skb)
{
u32 *data = (u32 *)skb->data;
u8 pdev_id, ring_type, ring_id;
u8 pdev_id, ring_type, ring_id, pdev_idx;
u16 hp, tp;
u32 backpressure_time;
struct ath11k_bp_stats *bp_stats;
pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data);
ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data);
@ -1520,6 +1519,31 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n",
pdev_id, ring_type, ring_id, hp, tp, backpressure_time);
if (ring_type == HTT_BACKPRESSURE_UMAC_RING_TYPE) {
if (ring_id >= HTT_SW_UMAC_RING_IDX_MAX)
return;
bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[ring_id];
} else if (ring_type == HTT_BACKPRESSURE_LMAC_RING_TYPE) {
pdev_idx = DP_HW2SW_MACID(pdev_id);
if (ring_id >= HTT_SW_LMAC_RING_IDX_MAX || pdev_idx >= MAX_RADIOS)
return;
bp_stats = &ab->soc_stats.bp_stats.lmac_ring_bp_stats[ring_id][pdev_idx];
} else {
ath11k_warn(ab, "unknown ring type received in htt bp event %d\n",
ring_type);
return;
}
spin_lock_bh(&ab->base_lock);
bp_stats->hp = hp;
bp_stats->tp = tp;
bp_stats->count++;
bp_stats->jiffies = jiffies;
spin_unlock_bh(&ab->base_lock);
}
void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
@ -2162,6 +2186,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
struct ieee80211_rx_status *rx_status)
{
u8 channel_num;
u32 center_freq;
rx_status->freq = 0;
rx_status->rate_idx = 0;
@ -2172,8 +2197,11 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
channel_num = ath11k_dp_rx_h_msdu_start_freq(rx_desc);
center_freq = ath11k_dp_rx_h_msdu_start_freq(rx_desc) >> 16;
if (channel_num >= 1 && channel_num <= 14) {
if (center_freq >= 5935 && center_freq <= 7105) {
rx_status->band = NL80211_BAND_6GHZ;
} else if (channel_num >= 1 && channel_num <= 14) {
rx_status->band = NL80211_BAND_2GHZ;
} else if (channel_num >= 36 && channel_num <= 173) {
rx_status->band = NL80211_BAND_5GHZ;

View File

@ -121,8 +121,10 @@ tcl_ring_sel:
spin_unlock_bh(&tx_ring->tx_idr_lock);
if (ret < 0) {
if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1))
if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) {
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
return -ENOSPC;
}
/* Check if the next ring is available */
ring_selector++;
@ -180,11 +182,13 @@ tcl_ring_sel:
default:
/* TODO: Take care of other encap modes as well */
ret = -EINVAL;
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
goto fail_remove_idr;
}
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);
ath11k_warn(ab, "failed to DMA map data Tx buffer\n");
ret = -ENOMEM;
goto fail_remove_idr;
@ -208,6 +212,7 @@ tcl_ring_sel:
* desc because the desc is directly enqueued onto hw queue.
*/
ath11k_hal_srng_access_end(ab, tcl_ring);
ab->soc_stats.tx_err.desc_na[ti.ring_id]++;
spin_unlock_bh(&tcl_ring->lock);
ret = -ENOMEM;

View File

@ -33,6 +33,15 @@
.max_power = 30, \
}
#define CHAN6G(_channel, _freq, _flags) { \
.band = NL80211_BAND_6GHZ, \
.hw_value = (_channel), \
.center_freq = (_freq), \
.flags = (_flags), \
.max_antenna_gain = 0, \
.max_power = 30, \
}
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
static unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
@ -86,6 +95,68 @@ static const struct ieee80211_channel ath11k_5ghz_channels[] = {
CHAN5G(173, 5865, 0),
};
static const struct ieee80211_channel ath11k_6ghz_channels[] = {
CHAN6G(1, 5955, 0),
CHAN6G(5, 5975, 0),
CHAN6G(9, 5995, 0),
CHAN6G(13, 6015, 0),
CHAN6G(17, 6035, 0),
CHAN6G(21, 6055, 0),
CHAN6G(25, 6075, 0),
CHAN6G(29, 6095, 0),
CHAN6G(33, 6115, 0),
CHAN6G(37, 6135, 0),
CHAN6G(41, 6155, 0),
CHAN6G(45, 6175, 0),
CHAN6G(49, 6195, 0),
CHAN6G(53, 6215, 0),
CHAN6G(57, 6235, 0),
CHAN6G(61, 6255, 0),
CHAN6G(65, 6275, 0),
CHAN6G(69, 6295, 0),
CHAN6G(73, 6315, 0),
CHAN6G(77, 6335, 0),
CHAN6G(81, 6355, 0),
CHAN6G(85, 6375, 0),
CHAN6G(89, 6395, 0),
CHAN6G(93, 6415, 0),
CHAN6G(97, 6435, 0),
CHAN6G(101, 6455, 0),
CHAN6G(105, 6475, 0),
CHAN6G(109, 6495, 0),
CHAN6G(113, 6515, 0),
CHAN6G(117, 6535, 0),
CHAN6G(121, 6555, 0),
CHAN6G(125, 6575, 0),
CHAN6G(129, 6595, 0),
CHAN6G(133, 6615, 0),
CHAN6G(137, 6635, 0),
CHAN6G(141, 6655, 0),
CHAN6G(145, 6675, 0),
CHAN6G(149, 6695, 0),
CHAN6G(153, 6715, 0),
CHAN6G(157, 6735, 0),
CHAN6G(161, 6755, 0),
CHAN6G(165, 6775, 0),
CHAN6G(169, 6795, 0),
CHAN6G(173, 6815, 0),
CHAN6G(177, 6835, 0),
CHAN6G(181, 6855, 0),
CHAN6G(185, 6875, 0),
CHAN6G(189, 6895, 0),
CHAN6G(193, 6915, 0),
CHAN6G(197, 6935, 0),
CHAN6G(201, 6955, 0),
CHAN6G(205, 6975, 0),
CHAN6G(209, 6995, 0),
CHAN6G(213, 7015, 0),
CHAN6G(217, 7035, 0),
CHAN6G(221, 7055, 0),
CHAN6G(225, 7075, 0),
CHAN6G(229, 7095, 0),
CHAN6G(233, 7115, 0),
};
static struct ieee80211_rate ath11k_legacy_rates[] = {
{ .bitrate = 10,
.hw_value = ATH11K_HW_RATE_CCK_LP_1M },
@ -134,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = {
[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
},
[NL80211_BAND_6GHZ] = {
[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,
[NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
[NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
[NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
},
};
const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = {
@ -698,6 +780,8 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
struct ieee80211_vif *vif = arvif->vif;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
struct ieee80211_mgmt *mgmt;
u8 *ies;
int ret;
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
@ -709,6 +793,17 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
return -EPERM;
}
ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
ies += sizeof(mgmt->u.beacon);
if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))
arvif->rsnie_present = true;
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA,
ies, (skb_tail_pointer(bcn) - ies)))
arvif->wpaie_present = true;
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
kfree_skb(bcn);
@ -798,6 +893,7 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar,
struct ieee80211_bss_conf *info = &vif->bss_conf;
struct cfg80211_chan_def def;
struct cfg80211_bss *bss;
struct ath11k_vif *arvif = (struct ath11k_vif *)vif->drv_priv;
const u8 *rsnie = NULL;
const u8 *wpaie = NULL;
@ -808,7 +904,12 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar,
bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
if (bss) {
if (arvif->rsnie_present || arvif->wpaie_present) {
arg->need_ptk_4_way = true;
if (arvif->wpaie_present)
arg->need_gtk_2_way = true;
} else if (bss) {
const struct cfg80211_bss_ies *ies;
rcu_read_lock();
@ -1489,6 +1590,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
}
break;
case NL80211_BAND_5GHZ:
case NL80211_BAND_6GHZ:
/* Check HE first */
if (sta->he_cap.has_he) {
phymode = ath11k_mac_get_phymode_he(ar, sta);
@ -2125,6 +2227,9 @@ static int ath11k_start_scan(struct ath11k *ar,
lockdep_assert_held(&ar->conf_mutex);
if (ath11k_spectral_get_mode(ar) == ATH11K_SPECTRAL_BACKGROUND)
ath11k_spectral_reset_buffer(ar);
ret = ath11k_wmi_send_scan_start_cmd(ar, arg);
if (ret)
return ret;
@ -3411,7 +3516,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar,
rate_cap_rx_chainmask);
}
if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) {
band = &ar->mac.sbands[NL80211_BAND_5GHZ];
ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;
if (ht_cap_info)
@ -3532,6 +3637,35 @@ ath11k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem)
he_cap_elem->phy_cap_info[9] &= ~m;
}
static __le16 ath11k_mac_setup_he_6ghz_cap(struct ath11k_pdev_cap *pcap,
struct ath11k_band_cap *bcap)
{
u8 val;
bcap->he_6ghz_capa = IEEE80211_HT_MPDU_DENSITY_NONE;
if (bcap->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
bcap->he_6ghz_capa |=
FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
WLAN_HT_CAP_SM_PS_DYNAMIC);
else
bcap->he_6ghz_capa |=
FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
WLAN_HT_CAP_SM_PS_DISABLED);
val = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
pcap->vht_cap);
bcap->he_6ghz_capa |=
FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, val);
val = FIELD_GET(IEEE80211_VHT_CAP_MAX_MPDU_MASK, pcap->vht_cap);
bcap->he_6ghz_capa |=
FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, val);
if (pcap->vht_cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN)
bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
if (pcap->vht_cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN)
bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
return cpu_to_le16(bcap->he_6ghz_capa);
}
static int ath11k_mac_copy_he_cap(struct ath11k *ar,
struct ath11k_pdev_cap *cap,
struct ieee80211_sband_iftype_data *data,
@ -3614,6 +3748,11 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
ath11k_gen_ppe_thresh(&band_cap->he_ppet,
he_cap->ppe_thres);
if (band == NL80211_BAND_6GHZ) {
data[idx].he_6ghz_capa.capa =
ath11k_mac_setup_he_6ghz_cap(cap, band_cap);
}
idx++;
}
@ -3643,6 +3782,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar,
band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
band->n_iftype_data = count;
}
if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
ar->supports_6ghz) {
count = ath11k_mac_copy_he_cap(ar, cap,
ar->mac.iftype[NL80211_BAND_6GHZ],
NL80211_BAND_6GHZ);
band = &ar->mac.sbands[NL80211_BAND_6GHZ];
band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
band->n_iftype_data = count;
}
}
static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
@ -4085,6 +4234,11 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
}
if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP &&
ar->supports_6ghz) {
params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
}
}
static u32
@ -5217,7 +5371,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar,
rate_idx = ffs(mask->control[band].legacy) - 1;
if (band == NL80211_BAND_5GHZ)
if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ)
rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;
hw_rate = ath11k_legacy_rates[rate_idx].hw_value;
@ -5683,7 +5837,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
void *channels;
BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_channels) +
ARRAY_SIZE(ath11k_5ghz_channels)) !=
ARRAY_SIZE(ath11k_5ghz_channels) +
ARRAY_SIZE(ath11k_6ghz_channels)) !=
ATH11K_NUM_CHANS);
reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
@ -5696,6 +5851,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
return -ENOMEM;
band = &ar->mac.sbands[NL80211_BAND_2GHZ];
band->band = NL80211_BAND_2GHZ;
band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels);
band->channels = channels;
band->n_bitrates = ath11k_g_rates_size;
@ -5707,23 +5863,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
}
if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
channels = kmemdup(ath11k_5ghz_channels,
sizeof(ath11k_5ghz_channels),
GFP_KERNEL);
if (!channels) {
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
return -ENOMEM;
if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
channels = kmemdup(ath11k_6ghz_channels,
sizeof(ath11k_6ghz_channels), GFP_KERNEL);
if (!channels) {
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
return -ENOMEM;
}
ar->supports_6ghz = true;
band = &ar->mac.sbands[NL80211_BAND_6GHZ];
band->band = NL80211_BAND_6GHZ;
band->n_channels = ARRAY_SIZE(ath11k_6ghz_channels);
band->channels = channels;
band->n_bitrates = ath11k_a_rates_size;
band->bitrates = ath11k_a_rates;
ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
ath11k_mac_update_ch_list(ar, band,
reg_cap->low_5ghz_chan,
reg_cap->high_5ghz_chan);
}
band = &ar->mac.sbands[NL80211_BAND_5GHZ];
band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);
band->channels = channels;
band->n_bitrates = ath11k_a_rates_size;
band->bitrates = ath11k_a_rates;
ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
ath11k_mac_update_ch_list(ar, band,
reg_cap->low_5ghz_chan,
reg_cap->high_5ghz_chan);
if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
channels = kmemdup(ath11k_5ghz_channels,
sizeof(ath11k_5ghz_channels),
GFP_KERNEL);
if (!channels) {
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
return -ENOMEM;
}
band = &ar->mac.sbands[NL80211_BAND_5GHZ];
band->band = NL80211_BAND_5GHZ;
band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);
band->channels = channels;
band->n_bitrates = ath11k_a_rates_size;
band->bitrates = ath11k_a_rates;
ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
ath11k_mac_update_ch_list(ar, band,
reg_cap->low_5ghz_chan,
reg_cap->high_5ghz_chan);
}
}
return 0;
@ -5777,6 +5958,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar)
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
SET_IEEE80211_DEV(ar->hw, NULL);
}

View File

@ -161,6 +161,10 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
else
ch->phy_mode = MODE_11A;
if (channel->band == NL80211_BAND_6GHZ &&
cfg80211_channel_is_psc(channel))
ch->psc_channel = true;
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
i, params->nallchans,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
*/
#ifndef ATH11K_SPECTRAL_H
#define ATH11K_SPECTRAL_H
#include "../spectral_common.h"
#include "dbring.h"
/* enum ath11k_spectral_mode:
*
* @SPECTRAL_DISABLED: spectral mode is disabled
* @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
* something else.
* @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
* is performed manually.
*/
enum ath11k_spectral_mode {
ATH11K_SPECTRAL_DISABLED = 0,
ATH11K_SPECTRAL_BACKGROUND,
ATH11K_SPECTRAL_MANUAL,
};
struct ath11k_spectral {
struct ath11k_dbring rx_ring;
/* Protects enabled */
spinlock_t lock;
struct rchan *rfs_scan; /* relay(fs) channel for spectral scan */
struct dentry *scan_ctl;
struct dentry *scan_count;
struct dentry *scan_bins;
enum ath11k_spectral_mode mode;
u16 count;
u8 fft_size;
bool enabled;
};
#ifdef CONFIG_ATH11K_SPECTRAL
int ath11k_spectral_init(struct ath11k_base *ab);
void ath11k_spectral_deinit(struct ath11k_base *ab);
int ath11k_spectral_vif_stop(struct ath11k_vif *arvif);
void ath11k_spectral_reset_buffer(struct ath11k *ar);
enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar);
struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar);
#else
static inline int ath11k_spectral_init(struct ath11k_base *ab)
{
return 0;
}
static inline void ath11k_spectral_deinit(struct ath11k_base *ab)
{
}
static inline int ath11k_spectral_vif_stop(struct ath11k_vif *arvif)
{
return 0;
}
static inline void ath11k_spectral_reset_buffer(struct ath11k *ar)
{
}
static inline
enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar)
{
return ATH11K_SPECTRAL_DISABLED;
}
static inline
struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar)
{
return NULL;
}
#endif /* CONFIG_ATH11K_SPECTRAL */
#endif /* ATH11K_SPECTRAL_H */

View File

@ -27,6 +27,11 @@ struct wmi_tlv_svc_ready_parse {
bool wmi_svc_bitmap_done;
};
struct wmi_tlv_dma_ring_caps_parse {
struct wmi_dma_ring_capabilities *dma_ring_caps;
u32 n_dma_ring_caps;
};
struct wmi_tlv_svc_rdy_ext_parse {
struct ath11k_service_ext_param param;
struct wmi_soc_mac_phy_hw_mode_caps *hw_caps;
@ -39,15 +44,35 @@ struct wmi_tlv_svc_rdy_ext_parse {
struct wmi_soc_hal_reg_capabilities *soc_hal_reg_caps;
struct wmi_hal_reg_capabilities_ext *ext_hal_reg_caps;
u32 n_ext_hal_reg_caps;
struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
bool hw_mode_done;
bool mac_phy_done;
bool ext_hal_reg_done;
bool mac_phy_chainmask_combo_done;
bool mac_phy_chainmask_cap_done;
bool oem_dma_ring_cap_done;
bool dma_ring_cap_done;
};
struct wmi_tlv_svc_rdy_ext2_parse {
struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
bool dma_ring_cap_done;
};
struct wmi_tlv_rdy_parse {
u32 num_extra_mac_addr;
};
struct wmi_tlv_dma_buf_release_parse {
struct ath11k_wmi_dma_buf_release_fixed_param fixed;
struct wmi_dma_buf_release_entry *buf_entry;
struct wmi_dma_buf_release_meta_data *meta_data;
u32 num_buf_entry;
u32 num_meta;
bool buf_entry_done;
bool meta_data_done;
};
static const struct wmi_tlv_policy wmi_tlv_policies[] = {
[WMI_TAG_ARRAY_BYTE]
= { .min_len = 0 },
@ -368,6 +393,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
sizeof(struct ath11k_ppe_threshold));
cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
sizeof(struct ath11k_ppe_threshold));
return 0;
}
@ -1692,10 +1728,10 @@ ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
*/
if (param->auth_flag)
cmd->peer_flags |= WMI_PEER_AUTH;
if (param->need_ptk_4_way)
if (param->need_ptk_4_way) {
cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
else
cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
cmd->peer_flags &= ~WMI_PEER_AUTH;
}
if (param->need_gtk_2_way)
cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
/* safe mode bypass the 4-way handshake */
@ -1778,6 +1814,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0];
cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1];
cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal;
cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz;
cmd->peer_he_ops = param->peer_he_ops;
memcpy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
sizeof(param->peer_he_cap_phyinfo));
@ -1831,6 +1868,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
/* HE Rates */
cmd->peer_he_mcs = param->peer_he_mcs_count;
cmd->min_data_rate = param->min_data_rate;
ptr += sizeof(*mcs);
@ -1886,6 +1924,8 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar,
arg->dwell_time_active = 50;
arg->dwell_time_active_2g = 0;
arg->dwell_time_passive = 150;
arg->dwell_time_active_6g = 40;
arg->dwell_time_passive_6g = 30;
arg->min_rest_time = 50;
arg->max_rest_time = 500;
arg->repeat_probe_time = 0;
@ -1990,6 +2030,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
int i, ret, len;
u32 *tmp_ptr;
u8 extraie_len_with_pad = 0;
struct hint_short_ssid *s_ssid = NULL;
struct hint_bssid *hint_bssid = NULL;
len = sizeof(*cmd);
@ -2011,6 +2053,14 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
roundup(params->extraie.len, sizeof(u32));
len += extraie_len_with_pad;
if (params->num_hint_bssid)
len += TLV_HDR_SIZE +
params->num_hint_bssid * sizeof(struct hint_bssid);
if (params->num_hint_s_ssid)
len += TLV_HDR_SIZE +
params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
return -ENOMEM;
@ -2032,6 +2082,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
cmd->dwell_time_active = params->dwell_time_active;
cmd->dwell_time_active_2g = params->dwell_time_active_2g;
cmd->dwell_time_passive = params->dwell_time_passive;
cmd->dwell_time_active_6g = params->dwell_time_active_6g;
cmd->dwell_time_passive_6g = params->dwell_time_passive_6g;
cmd->min_rest_time = params->min_rest_time;
cmd->max_rest_time = params->max_rest_time;
cmd->repeat_probe_time = params->repeat_probe_time;
@ -2109,6 +2161,68 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
ptr += extraie_len_with_pad;
if (params->num_hint_s_ssid) {
len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
s_ssid = ptr;
for (i = 0; i < params->num_hint_s_ssid; ++i) {
s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
s_ssid++;
}
ptr += len;
}
if (params->num_hint_bssid) {
len = params->num_hint_bssid * sizeof(struct hint_bssid);
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
hint_bssid = ptr;
for (i = 0; i < params->num_hint_bssid; ++i) {
hint_bssid->freq_flags =
params->hint_bssid[i].freq_flags;
ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
&hint_bssid->bssid.addr[0]);
hint_bssid++;
}
}
len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
if (params->num_hint_s_ssid) {
s_ssid = ptr;
for (i = 0; i < params->num_hint_s_ssid; ++i) {
s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
s_ssid++;
}
}
ptr += len;
len = params->num_hint_bssid * sizeof(struct hint_bssid);
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
if (params->num_hint_bssid) {
hint_bssid = ptr;
for (i = 0; i < params->num_hint_bssid; ++i) {
hint_bssid->freq_flags =
params->hint_bssid[i].freq_flags;
ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
&hint_bssid->bssid.addr[0]);
hint_bssid++;
}
}
ret = ath11k_wmi_cmd_send(wmi, skb,
WMI_START_SCAN_CMDID);
if (ret) {
@ -2178,91 +2292,110 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
struct wmi_tlv *tlv;
void *ptr;
int i, ret, len;
u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
u32 *reg1, *reg2;
len = sizeof(*cmd) + TLV_HDR_SIZE +
sizeof(*chan_info) * chan_list->nallchans;
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
return -ENOMEM;
cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI no.of chan = %d len = %d\n", chan_list->nallchans, len);
cmd->pdev_id = chan_list->pdev_id;
cmd->num_scan_chans = chan_list->nallchans;
ptr = skb->data + sizeof(*cmd);
len = sizeof(*chan_info) * chan_list->nallchans;
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
ptr += TLV_HDR_SIZE;
tchan_info = &chan_list->ch_param[0];
while (chan_list->nallchans) {
len = sizeof(*cmd) + TLV_HDR_SIZE;
max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
sizeof(*chan_info);
for (i = 0; i < chan_list->nallchans; ++i) {
chan_info = ptr;
memset(chan_info, 0, sizeof(*chan_info));
len = sizeof(*chan_info);
chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_CHANNEL) |
FIELD_PREP(WMI_TLV_LEN,
len - TLV_HDR_SIZE);
if (chan_list->nallchans > max_chan_limit)
num_send_chans = max_chan_limit;
else
num_send_chans = chan_list->nallchans;
reg1 = &chan_info->reg_info_1;
reg2 = &chan_info->reg_info_2;
chan_info->mhz = tchan_info->mhz;
chan_info->band_center_freq1 = tchan_info->cfreq1;
chan_info->band_center_freq2 = tchan_info->cfreq2;
chan_list->nallchans -= num_send_chans;
len += sizeof(*chan_info) * num_send_chans;
if (tchan_info->is_chan_passive)
chan_info->info |= WMI_CHAN_INFO_PASSIVE;
if (tchan_info->allow_he)
chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
else if (tchan_info->allow_vht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
else if (tchan_info->allow_ht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
if (tchan_info->half_rate)
chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
if (tchan_info->quarter_rate)
chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
return -ENOMEM;
chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
tchan_info->phy_mode);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
tchan_info->minpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
tchan_info->maxpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
tchan_info->maxregpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
tchan_info->reg_class_id);
*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
tchan_info->antennamax);
cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
cmd->pdev_id = chan_list->pdev_id;
cmd->num_scan_chans = num_send_chans;
if (num_sends)
cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG;
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI chan scan list chan[%d] = %u\n",
i, chan_info->mhz);
"WMI no.of chan = %d len = %d pdev_id = %d num_sends = %d\n",
num_send_chans, len, cmd->pdev_id, num_sends);
ptr += sizeof(*chan_info);
ptr = skb->data + sizeof(*cmd);
tchan_info++;
len = sizeof(*chan_info) * num_send_chans;
tlv = ptr;
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
ptr += TLV_HDR_SIZE;
for (i = 0; i < num_send_chans; ++i) {
chan_info = ptr;
memset(chan_info, 0, sizeof(*chan_info));
len = sizeof(*chan_info);
chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_CHANNEL) |
FIELD_PREP(WMI_TLV_LEN,
len - TLV_HDR_SIZE);
reg1 = &chan_info->reg_info_1;
reg2 = &chan_info->reg_info_2;
chan_info->mhz = tchan_info->mhz;
chan_info->band_center_freq1 = tchan_info->cfreq1;
chan_info->band_center_freq2 = tchan_info->cfreq2;
if (tchan_info->is_chan_passive)
chan_info->info |= WMI_CHAN_INFO_PASSIVE;
if (tchan_info->allow_he)
chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
else if (tchan_info->allow_vht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
else if (tchan_info->allow_ht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
if (tchan_info->half_rate)
chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
if (tchan_info->quarter_rate)
chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
if (tchan_info->psc_channel)
chan_info->info |= WMI_CHAN_INFO_PSC;
chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
tchan_info->phy_mode);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
tchan_info->minpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
tchan_info->maxpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
tchan_info->maxregpower);
*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
tchan_info->reg_class_id);
*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
tchan_info->antennamax);
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI chan scan list chan[%d] = %u, chan_info->info %8x\n",
i, chan_info->mhz, chan_info->info);
ptr += sizeof(*chan_info);
tchan_info++;
}
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
if (ret) {
ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
dev_kfree_skb(skb);
return ret;
}
num_sends++;
}
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
if (ret) {
ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
dev_kfree_skb(skb);
}
return ret;
return 0;
}
int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
@ -3265,6 +3398,236 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
return ath11k_init_cmd_send(&wmi_sc->wmi[0], &init_param);
}
int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar,
struct ath11k_wmi_vdev_spectral_conf_param *param)
{
struct ath11k_wmi_vdev_spectral_conf_cmd *cmd;
struct sk_buff *skb;
int ret;
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
if (!skb)
return -ENOMEM;
cmd = (struct ath11k_wmi_vdev_spectral_conf_cmd *)skb->data;
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD) |
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
memcpy(&cmd->param, param, sizeof(*param));
ret = ath11k_wmi_cmd_send(ar->wmi, skb,
WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
if (ret) {
ath11k_warn(ar->ab,
"failed to send spectral scan config wmi cmd\n");
goto err;
}
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI spectral scan config cmd vdev_id 0x%x\n",
param->vdev_id);
return 0;
err:
dev_kfree_skb(skb);
return ret;
}
int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id,
u32 trigger, u32 enable)
{
struct ath11k_wmi_vdev_spectral_enable_cmd *cmd;
struct sk_buff *skb;
int ret;
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
if (!skb)
return -ENOMEM;
cmd = (struct ath11k_wmi_vdev_spectral_enable_cmd *)skb->data;
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD) |
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
cmd->vdev_id = vdev_id;
cmd->trigger_cmd = trigger;
cmd->enable_cmd = enable;
ret = ath11k_wmi_cmd_send(ar->wmi, skb,
WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
if (ret) {
ath11k_warn(ar->ab,
"failed to send spectral enable wmi cmd\n");
goto err;
}
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI spectral enable cmd vdev id 0x%x\n",
vdev_id);
return 0;
err:
dev_kfree_skb(skb);
return ret;
}
int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar,
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param)
{
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *cmd;
struct sk_buff *skb;
int ret;
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
if (!skb)
return -ENOMEM;
cmd = (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *)skb->data;
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DMA_RING_CFG_REQ) |
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
cmd->pdev_id = param->pdev_id;
cmd->module_id = param->module_id;
cmd->base_paddr_lo = param->base_paddr_lo;
cmd->base_paddr_hi = param->base_paddr_hi;
cmd->head_idx_paddr_lo = param->head_idx_paddr_lo;
cmd->head_idx_paddr_hi = param->head_idx_paddr_hi;
cmd->tail_idx_paddr_lo = param->tail_idx_paddr_lo;
cmd->tail_idx_paddr_hi = param->tail_idx_paddr_hi;
cmd->num_elems = param->num_elems;
cmd->buf_size = param->buf_size;
cmd->num_resp_per_event = param->num_resp_per_event;
cmd->event_timeout_ms = param->event_timeout_ms;
ret = ath11k_wmi_cmd_send(ar->wmi, skb,
WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
if (ret) {
ath11k_warn(ar->ab,
"failed to send dma ring cfg req wmi cmd\n");
goto err;
}
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"WMI DMA ring cfg req cmd pdev_id 0x%x\n",
param->pdev_id);
return 0;
err:
dev_kfree_skb(skb);
return ret;
}
static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base *soc,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_dma_buf_release_parse *parse = data;
if (tag != WMI_TAG_DMA_BUF_RELEASE_ENTRY)
return -EPROTO;
if (parse->num_buf_entry >= parse->fixed.num_buf_release_entry)
return -ENOBUFS;
parse->num_buf_entry++;
return 0;
}
static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base *soc,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_dma_buf_release_parse *parse = data;
if (tag != WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA)
return -EPROTO;
if (parse->num_meta >= parse->fixed.num_meta_data_entry)
return -ENOBUFS;
parse->num_meta++;
return 0;
}
static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_dma_buf_release_parse *parse = data;
int ret;
switch (tag) {
case WMI_TAG_DMA_BUF_RELEASE:
memcpy(&parse->fixed, ptr,
sizeof(struct ath11k_wmi_dma_buf_release_fixed_param));
parse->fixed.pdev_id = DP_HW2SW_MACID(parse->fixed.pdev_id);
break;
case WMI_TAG_ARRAY_STRUCT:
if (!parse->buf_entry_done) {
parse->num_buf_entry = 0;
parse->buf_entry = (struct wmi_dma_buf_release_entry *)ptr;
ret = ath11k_wmi_tlv_iter(ab, ptr, len,
ath11k_wmi_tlv_dma_buf_entry_parse,
parse);
if (ret) {
ath11k_warn(ab, "failed to parse dma buf entry tlv %d\n",
ret);
return ret;
}
parse->buf_entry_done = true;
} else if (!parse->meta_data_done) {
parse->num_meta = 0;
parse->meta_data = (struct wmi_dma_buf_release_meta_data *)ptr;
ret = ath11k_wmi_tlv_iter(ab, ptr, len,
ath11k_wmi_tlv_dma_buf_meta_parse,
parse);
if (ret) {
ath11k_warn(ab, "failed to parse dma buf meta tlv %d\n",
ret);
return ret;
}
parse->meta_data_done = true;
}
break;
default:
break;
}
return 0;
}
static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base *ab,
struct sk_buff *skb)
{
struct wmi_tlv_dma_buf_release_parse parse = { };
struct ath11k_dbring_buf_release_event param;
int ret;
ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
ath11k_wmi_tlv_dma_buf_parse,
&parse);
if (ret) {
ath11k_warn(ab, "failed to parse dma buf release tlv %d\n", ret);
return;
}
param.fixed = parse.fixed;
param.buf_entry = parse.buf_entry;
param.num_buf_entry = parse.num_buf_entry;
param.meta_data = parse.meta_data;
param.num_meta = parse.num_meta;
ret = ath11k_dbring_buffer_release_event(ab, &param);
if (ret) {
ath11k_warn(ab, "failed to handle dma buf release event %d\n", ret);
return;
}
}
static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base *soc,
u16 tag, u16 len,
const void *ptr, void *data)
@ -3445,6 +3808,95 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc,
return 0;
}
static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base *soc,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_dma_ring_caps_parse *parse = data;
if (tag != WMI_TAG_DMA_RING_CAPABILITIES)
return -EPROTO;
parse->n_dma_ring_caps++;
return 0;
}
static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base *ab,
u32 num_cap)
{
size_t sz;
void *ptr;
sz = num_cap * sizeof(struct ath11k_dbring_cap);
ptr = kzalloc(sz, GFP_ATOMIC);
if (!ptr)
return -ENOMEM;
ab->db_caps = ptr;
ab->num_db_cap = num_cap;
return 0;
}
static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab)
{
kfree(ab->db_caps);
ab->db_caps = NULL;
}
static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab,
u16 len, const void *ptr, void *data)
{
struct wmi_tlv_dma_ring_caps_parse *dma_caps_parse = data;
struct wmi_dma_ring_capabilities *dma_caps;
struct ath11k_dbring_cap *dir_buff_caps;
int ret;
u32 i;
dma_caps_parse->n_dma_ring_caps = 0;
dma_caps = (struct wmi_dma_ring_capabilities *)ptr;
ret = ath11k_wmi_tlv_iter(ab, ptr, len,
ath11k_wmi_tlv_dma_ring_caps_parse,
dma_caps_parse);
if (ret) {
ath11k_warn(ab, "failed to parse dma ring caps tlv %d\n", ret);
return ret;
}
if (!dma_caps_parse->n_dma_ring_caps)
return 0;
if (ab->num_db_cap) {
ath11k_warn(ab, "Already processed, so ignoring dma ring caps\n");
return 0;
}
ret = ath11k_wmi_alloc_dbring_caps(ab, dma_caps_parse->n_dma_ring_caps);
if (ret)
return ret;
dir_buff_caps = ab->db_caps;
for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) {
if (dma_caps[i].module_id >= WMI_DIRECT_BUF_MAX) {
ath11k_warn(ab, "Invalid module id %d\n", dma_caps[i].module_id);
ret = -EINVAL;
goto free_dir_buff;
}
dir_buff_caps[i].id = dma_caps[i].module_id;
dir_buff_caps[i].pdev_id = DP_HW2SW_MACID(dma_caps[i].pdev_id);
dir_buff_caps[i].min_elem = dma_caps[i].min_elem;
dir_buff_caps[i].min_buf_sz = dma_caps[i].min_buf_sz;
dir_buff_caps[i].min_buf_align = dma_caps[i].min_buf_align;
}
return 0;
free_dir_buff:
ath11k_wmi_free_dbring_caps(ab);
return ret;
}
static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
@ -3501,7 +3953,19 @@ static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
return ret;
svc_rdy_ext->ext_hal_reg_done = true;
complete(&ab->wmi_ab.service_ready);
} else if (!svc_rdy_ext->mac_phy_chainmask_combo_done) {
svc_rdy_ext->mac_phy_chainmask_combo_done = true;
} else if (!svc_rdy_ext->mac_phy_chainmask_cap_done) {
svc_rdy_ext->mac_phy_chainmask_cap_done = true;
} else if (!svc_rdy_ext->oem_dma_ring_cap_done) {
svc_rdy_ext->oem_dma_ring_cap_done = true;
} else if (!svc_rdy_ext->dma_ring_cap_done) {
ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
&svc_rdy_ext->dma_caps_parse);
if (ret)
return ret;
svc_rdy_ext->dma_ring_cap_done = true;
}
break;
@ -3522,11 +3986,66 @@ static int ath11k_service_ready_ext_event(struct ath11k_base *ab,
&svc_rdy_ext);
if (ret) {
ath11k_warn(ab, "failed to parse tlv %d\n", ret);
return ret;
goto err;
}
if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG, ab->wmi_ab.svc_map))
complete(&ab->wmi_ab.service_ready);
kfree(svc_rdy_ext.mac_phy_caps);
return 0;
err:
ath11k_wmi_free_dbring_caps(ab);
return ret;
}
static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_svc_rdy_ext2_parse *parse = data;
int ret;
switch (tag) {
case WMI_TAG_ARRAY_STRUCT:
if (!parse->dma_ring_cap_done) {
ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
&parse->dma_caps_parse);
if (ret)
return ret;
parse->dma_ring_cap_done = true;
}
break;
default:
break;
}
return 0;
}
static int ath11k_service_ready_ext2_event(struct ath11k_base *ab,
struct sk_buff *skb)
{
struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2 = { };
int ret;
ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
ath11k_wmi_tlv_svc_rdy_ext2_parse,
&svc_rdy_ext2);
if (ret) {
ath11k_warn(ab, "failed to parse ext2 event tlv %d\n", ret);
goto err;
}
complete(&ab->wmi_ab.service_ready);
return 0;
err:
ath11k_wmi_free_dbring_caps(ab);
return ret;
}
static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buff *skb,
@ -3822,6 +4341,7 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
}
hdr->pdev_id = ev->pdev_id;
hdr->chan_freq = ev->chan_freq;
hdr->channel = ev->channel;
hdr->snr = ev->snr;
hdr->rate = ev->rate;
@ -5193,7 +5713,9 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
status->flag |= RX_FLAG_MMIC_ERROR;
if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) {
status->band = NL80211_BAND_6GHZ;
} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
status->band = NL80211_BAND_2GHZ;
} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) {
status->band = NL80211_BAND_5GHZ;
@ -5206,9 +5728,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
goto exit;
}
if (rx_ev.phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
if (rx_ev.phy_mode == MODE_11B &&
(status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ))
ath11k_dbg(ab, ATH11K_DBG_WMI,
"wmi mgmt rx 11b (CCK) on 5GHz\n");
"wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band);
sband = &ar->mac.sbands[status->band];
@ -5933,6 +6456,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
case WMI_SERVICE_READY_EXT_EVENTID:
ath11k_service_ready_ext_event(ab, skb);
break;
case WMI_SERVICE_READY_EXT2_EVENTID:
ath11k_service_ready_ext2_event(ab, skb);
break;
case WMI_REG_CHAN_LIST_CC_EVENTID:
ath11k_reg_chan_list_event(ab, skb);
break;
@ -5994,12 +6520,16 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
case WMI_PDEV_TEMPERATURE_EVENTID:
ath11k_wmi_pdev_temperature_event(ab, skb);
break;
case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID:
ath11k_wmi_pdev_dma_ring_buf_release_event(ab, skb);
break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_VDEV_DELETE_RESP_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
case WMI_TWT_ENABLE_EVENTID:
case WMI_TWT_DISABLE_EVENTID:
case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID:
ath11k_dbg(ab, ATH11K_DBG_WMI,
"ignoring unsupported event 0x%x\n", id);
break;
@ -6213,4 +6743,6 @@ void ath11k_wmi_detach(struct ath11k_base *ab)
for (i = 0; i < ab->htc.wmi_ep_count; i++)
ath11k_wmi_pdev_detach(ab, i);
ath11k_wmi_free_dbring_caps(ab);
}

View File

@ -24,6 +24,8 @@ struct ath11k_fw_stats;
#define HE_PET_8_USEC 1
#define HE_PET_16_USEC 2
#define WMI_MAX_CHAINS 8
#define WMI_MAX_NUM_SS MAX_HE_NSS
#define WMI_MAX_NUM_RU MAX_HE_RU
@ -50,10 +52,20 @@ struct wmi_tlv {
#define WMI_MAX_MEM_REQS 32
#define ATH11K_MAX_HW_LISTEN_INTERVAL 5
#define WLAN_SCAN_MAX_HINT_S_SSID 10
#define WLAN_SCAN_MAX_HINT_BSSID 10
#define MAX_RNR_BSS 5
#define WLAN_SCAN_MAX_HINT_S_SSID 10
#define WLAN_SCAN_MAX_HINT_BSSID 10
#define MAX_RNR_BSS 5
#define WLAN_SCAN_PARAMS_MAX_SSID 16
#define WLAN_SCAN_PARAMS_MAX_BSSID 4
#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1
#define WMI_BA_MODE_BUFFER_SIZE_256 3
/*
* HW mode config type replicated from FW header
@ -586,6 +598,11 @@ enum wmi_tlv_event_id {
WMI_PDEV_DMA_RING_CFG_RSP_EVENTID,
WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID,
WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID,
WMI_PDEV_CSC_SWITCH_COUNT_STATUS_EVENTID,
WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID,
WMI_PDEV_RAP_INFO_EVENTID,
WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID,
WMI_SERVICE_READY_EXT2_EVENTID,
WMI_VDEV_START_RESP_EVENTID = WMI_TLV_CMD(WMI_GRP_VDEV),
WMI_VDEV_STOPPED_EVENTID,
WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
@ -1011,6 +1028,7 @@ enum wmi_tlv_vdev_param {
WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
WMI_VDEV_PARAM_BA_MODE = 0x7e,
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
WMI_VDEV_PARAM_BSS_COLOR,
WMI_VDEV_PARAM_SET_HEMU_MODE,
@ -2013,9 +2031,10 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_DSM_ROAM_FILTER = 211,
WMI_TLV_SERVICE_PACKET_CAPTURE_SUPPORT = 212,
WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213,
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
WMI_TLV_SERVICE_EXT2_MSG = 220,
WMI_MAX_EXT_SERVICE
};
enum {
@ -2076,6 +2095,14 @@ enum wmi_beacon_gen_mode {
WMI_BEACON_BURST_MODE = 1
};
enum wmi_direct_buffer_module {
WMI_DIRECT_BUF_SPECTRAL = 0,
WMI_DIRECT_BUF_CFR = 1,
/* keep it last */
WMI_DIRECT_BUF_MAX
};
struct wmi_host_pdev_band_to_mac {
u32 pdev_id;
u32 start_freq;
@ -2382,6 +2409,15 @@ struct wmi_mac_addr {
} __packed;
} __packed;
struct wmi_dma_ring_capabilities {
u32 tlv_header;
u32 pdev_id;
u32 module_id;
u32 min_elem;
u32 min_buf_sz;
u32 min_buf_align;
} __packed;
struct wmi_ready_event_min {
struct wmi_abi_version fw_abi_vers;
struct wmi_mac_addr mac_addr;
@ -2519,7 +2555,8 @@ struct channel_param {
allow_ht:1,
allow_vht:1,
allow_he:1,
set_agile:1;
set_agile:1,
psc_channel:1;
u32 phy_mode;
u32 cfreq1;
u32 cfreq2;
@ -3059,6 +3096,9 @@ struct wmi_start_scan_cmd {
u32 num_vendor_oui;
u32 scan_ctrl_flags_ext;
u32 dwell_time_active_2g;
u32 dwell_time_active_6g;
u32 dwell_time_passive_6g;
u32 scan_start_offset;
} __packed;
#define WMI_SCAN_FLAG_PASSIVE 0x1
@ -3098,6 +3138,16 @@ enum {
((flag) |= (((mode) << WMI_SCAN_DWELL_MODE_SHIFT) & \
WMI_SCAN_DWELL_MODE_MASK))
struct hint_short_ssid {
u32 freq_flags;
u32 short_ssid;
};
struct hint_bssid {
u32 freq_flags;
struct wmi_mac_addr bssid;
};
struct scan_req_params {
u32 scan_id;
u32 scan_req_id;
@ -3125,6 +3175,8 @@ struct scan_req_params {
u32 dwell_time_active;
u32 dwell_time_active_2g;
u32 dwell_time_passive;
u32 dwell_time_active_6g;
u32 dwell_time_passive_6g;
u32 min_rest_time;
u32 max_rest_time;
u32 repeat_probe_time;
@ -3175,6 +3227,10 @@ struct scan_req_params {
struct element_info extraie;
struct element_info htcap;
struct element_info vhtcap;
u32 num_hint_s_ssid;
u32 num_hint_bssid;
struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID];
struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID];
};
struct wmi_ssid_arg {
@ -3264,6 +3320,7 @@ struct wmi_bcn_send_from_host_cmd {
#define WMI_CHAN_INFO_QUARTER_RATE BIT(15)
#define WMI_CHAN_INFO_DFS_FREQ2 BIT(16)
#define WMI_CHAN_INFO_ALLOW_HE BIT(17)
#define WMI_CHAN_INFO_PSC BIT(18)
#define WMI_CHAN_REG_INFO1_MIN_PWR GENMASK(7, 0)
#define WMI_CHAN_REG_INFO1_MAX_PWR GENMASK(15, 8)
@ -3444,6 +3501,7 @@ struct peer_assoc_params {
u32 tx_max_rate;
u32 tx_mcs_set;
u8 vht_capable;
u8 min_data_rate;
u32 tx_max_mcs_nss;
u32 peer_bw_rxnss_override;
bool is_pmf_enabled;
@ -3472,6 +3530,7 @@ struct peer_assoc_params {
bool he_flag;
u32 peer_he_cap_macinfo[2];
u32 peer_he_cap_macinfo_internal;
u32 peer_he_caps_6ghz;
u32 peer_he_ops;
u32 peer_he_cap_phyinfo[WMI_HOST_MAX_HECAP_PHY_SIZE];
u32 peer_he_mcs_count;
@ -3509,6 +3568,8 @@ struct wmi_peer_assoc_complete_cmd {
u32 peer_he_mcs;
u32 peer_he_cap_info_ext;
u32 peer_he_cap_info_internal;
u32 min_data_rate;
u32 peer_he_caps_6ghz;
} __packed;
struct wmi_stop_scan_cmd {
@ -4228,6 +4289,7 @@ struct wmi_pdev_temperature_event {
#define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4
struct mgmt_rx_event_params {
u32 chan_freq;
u32 channel;
u32 snr;
u8 rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
@ -4257,6 +4319,7 @@ struct wmi_mgmt_rx_hdr {
u32 rx_tsf_l32;
u32 rx_tsf_u32;
u32 pdev_id;
u32 chan_freq;
} __packed;
#define MAX_ANTENNA_EIGHT 8
@ -4734,6 +4797,117 @@ struct ath11k_wmi_pdev_lro_config_cmd {
u32 pdev_id;
} __packed;
#define ATH11K_WMI_SPECTRAL_COUNT_DEFAULT 0
#define ATH11K_WMI_SPECTRAL_PERIOD_DEFAULT 224
#define ATH11K_WMI_SPECTRAL_PRIORITY_DEFAULT 1
#define ATH11K_WMI_SPECTRAL_FFT_SIZE_DEFAULT 7
#define ATH11K_WMI_SPECTRAL_GC_ENA_DEFAULT 1
#define ATH11K_WMI_SPECTRAL_RESTART_ENA_DEFAULT 0
#define ATH11K_WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96
#define ATH11K_WMI_SPECTRAL_INIT_DELAY_DEFAULT 80
#define ATH11K_WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12
#define ATH11K_WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8
#define ATH11K_WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0
#define ATH11K_WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0
#define ATH11K_WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0
#define ATH11K_WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0
#define ATH11K_WMI_SPECTRAL_RPT_MODE_DEFAULT 2
#define ATH11K_WMI_SPECTRAL_BIN_SCALE_DEFAULT 1
#define ATH11K_WMI_SPECTRAL_DBM_ADJ_DEFAULT 1
#define ATH11K_WMI_SPECTRAL_CHN_MASK_DEFAULT 1
struct ath11k_wmi_vdev_spectral_conf_param {
u32 vdev_id;
u32 scan_count;
u32 scan_period;
u32 scan_priority;
u32 scan_fft_size;
u32 scan_gc_ena;
u32 scan_restart_ena;
u32 scan_noise_floor_ref;
u32 scan_init_delay;
u32 scan_nb_tone_thr;
u32 scan_str_bin_thr;
u32 scan_wb_rpt_mode;
u32 scan_rssi_rpt_mode;
u32 scan_rssi_thr;
u32 scan_pwr_format;
u32 scan_rpt_mode;
u32 scan_bin_scale;
u32 scan_dbm_adj;
u32 scan_chn_mask;
} __packed;
struct ath11k_wmi_vdev_spectral_conf_cmd {
u32 tlv_header;
struct ath11k_wmi_vdev_spectral_conf_param param;
} __packed;
#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1
#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2
#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE 1
#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_DISABLE 2
struct ath11k_wmi_vdev_spectral_enable_cmd {
u32 tlv_header;
u32 vdev_id;
u32 trigger_cmd;
u32 enable_cmd;
} __packed;
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd {
u32 tlv_header;
u32 pdev_id;
u32 module_id; /* see enum wmi_direct_buffer_module */
u32 base_paddr_lo;
u32 base_paddr_hi;
u32 head_idx_paddr_lo;
u32 head_idx_paddr_hi;
u32 tail_idx_paddr_lo;
u32 tail_idx_paddr_hi;
u32 num_elems; /* Number of elems in the ring */
u32 buf_size; /* size of allocated buffer in bytes */
/* Number of wmi_dma_buf_release_entry packed together */
u32 num_resp_per_event;
/* Target should timeout and send whatever resp
* it has if this time expires, units in milliseconds
*/
u32 event_timeout_ms;
} __packed;
struct ath11k_wmi_dma_buf_release_fixed_param {
u32 pdev_id;
u32 module_id;
u32 num_buf_release_entry;
u32 num_meta_data_entry;
} __packed;
struct wmi_dma_buf_release_entry {
u32 tlv_header;
u32 paddr_lo;
/* Bits 11:0: address of data
* Bits 31:12: host context data
*/
u32 paddr_hi;
} __packed;
#define WMI_SPECTRAL_META_INFO1_FREQ1 GENMASK(15, 0)
#define WMI_SPECTRAL_META_INFO1_FREQ2 GENMASK(31, 16)
#define WMI_SPECTRAL_META_INFO2_CHN_WIDTH GENMASK(7, 0)
struct wmi_dma_buf_release_meta_data {
u32 tlv_header;
s32 noise_floor[WMI_MAX_CHAINS];
u32 reset_delay;
u32 freq1;
u32 freq2;
u32 ch_width;
} __packed;
struct target_resource_config {
u32 num_vdevs;
u32 num_peers;
@ -4941,4 +5115,10 @@ int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
bool enable);
int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id);
int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar,
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param);
int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id,
u32 trigger, u32 enable);
int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar,
struct ath11k_wmi_vdev_spectral_conf_param *param);
#endif

View File

@ -311,7 +311,7 @@ static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb)
ath6kl_dbg(ATH6KL_DBG_USB, "setting up USB Pipes using interface\n");
/* walk decriptors and setup pipes */
/* walk descriptors and setup pipes */
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;

View File

@ -34,7 +34,7 @@ config ATH9K
APs that come with these cards refer to ath9k wiki
products page:
http://wireless.kernel.org/en/users/Drivers/ath9k/products
https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/products
If you choose to build a module, it'll be called ath9k.
@ -185,7 +185,8 @@ config ATH9K_HTC
Support for Atheros HTC based cards.
Chipsets supported: AR9271
For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
For more information:
https://wireless.wiki.kernel.org/en/users/Drivers/ath9k_htc
The built module will be ath9k_htc.

View File

@ -2410,7 +2410,7 @@ static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask)
* of tests. The testing requirements are going to be documented. Desired
* test requirements are documented at:
*
* http://wireless.kernel.org/en/users/Drivers/ath9k/dfs
* https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/dfs
*
* Once a new chipset gets properly tested an individual commit can be used
* to document the testing for DFS for that chipset.

View File

@ -10,7 +10,7 @@ config CARL9170
It needs a special firmware (carl9170-1.fw), which can be downloaded
from our wiki here:
<http://wireless.kernel.org/en/users/Drivers/carl9170>
<https://wireless.wiki.kernel.org/en/users/Drivers/carl9170>
If you choose to build a module, it'll be called carl9170.

View File

@ -61,7 +61,7 @@ MODULE_ALIAS("arusb_lnx");
* Note:
*
* Always update our wiki's device list (located at:
* http://wireless.kernel.org/en/users/Drivers/ar9170/devices ),
* https://wireless.wiki.kernel.org/en/users/Drivers/ar9170/devices ),
* whenever you add a new device.
*/
static const struct usb_device_id carl9170_usb_ids[] = {

View File

@ -24,6 +24,7 @@
* could be acquired so far.
*/
#define SPECTRAL_ATH10K_MAX_NUM_BINS 256
#define SPECTRAL_ATH11K_MAX_NUM_BINS 512
/* FFT sample format given to userspace via debugfs.
*
@ -37,6 +38,7 @@ enum ath_fft_sample_type {
ATH_FFT_SAMPLE_HT20 = 1,
ATH_FFT_SAMPLE_HT20_40,
ATH_FFT_SAMPLE_ATH10K,
ATH_FFT_SAMPLE_ATH11K
};
struct fft_sample_tlv {
@ -110,4 +112,19 @@ struct fft_sample_ath10k {
u8 data[0];
} __packed;
struct fft_sample_ath11k {
struct fft_sample_tlv tlv;
u8 chan_width_mhz;
s8 max_index;
u8 max_exp;
__be16 freq1;
__be16 freq2;
__be16 max_magnitude;
__be16 rssi;
__be32 tsf;
__be32 noise;
u8 data[0];
} __packed;
#endif /* SPECTRAL_COMMON_H */

View File

@ -10,7 +10,7 @@ config WIL6210
wil6210 chip by Wilocity. It supports operation on the
60 GHz band, covered by the IEEE802.11ad standard.
http://wireless.kernel.org/en/users/Drivers/wil6210
https://wireless.wiki.kernel.org/en/users/Drivers/wil6210
If you choose to build it as a module, it will be called
wil6210

View File

@ -17,7 +17,7 @@
*
* TODO list is at the wiki:
*
* http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
* https://wireless.wiki.kernel.org/en/users/Drivers/at76c50x-usb#TODO
*/
#include <linux/init.h>

View File

@ -2164,7 +2164,7 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
const char text[] =
"You must go to " \
"http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
"https://wireless.wiki.kernel.org/en/users/Drivers/b43#devicefirmware " \
"and download the correct firmware for this driver version. " \
"Please carefully read all instructions on this website.\n";

View File

@ -4222,7 +4222,7 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
u32 rfpwr_offset;
u8 pga_gain, pad_gain;
int i;
const s16 *uninitialized_var(rf_pwr_offset_table);
const s16 *rf_pwr_offset_table = NULL;
table = b43_nphy_get_tx_gain_table(dev);
if (!table)

View File

@ -1477,8 +1477,8 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev)
static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl)
{
b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/"
"Drivers/b43#devicefirmware "
b43legacyerr(wl, "You must go to https://wireless.wiki.kernel.org/en/"
"users/Drivers/b43#devicefirmware "
"and download the correct firmware (version 3).\n");
}

View File

@ -863,7 +863,7 @@ static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
}
#endif /* CONFIG_PM_SLEEP */
static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
{
sdiodev->state = BRCMF_SDIOD_DOWN;
if (sdiodev->bus) {
@ -898,7 +898,7 @@ static void brcmf_sdiod_host_fixup(struct mmc_host *host)
host->caps |= MMC_CAP_NONREMOVABLE;
}
static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
{
int ret = 0;
unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE;

View File

@ -1387,7 +1387,8 @@ static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data,
return err;
}
static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
bool locally_generated)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
struct brcmf_pub *drvr = cfg->pub;
@ -1409,7 +1410,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
(vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
true, GFP_KERNEL);
locally_generated, GFP_KERNEL);
}
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
@ -1588,7 +1589,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
return 0;
}
brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
brcmf_net_setcarrier(ifp, false);
brcmf_dbg(TRACE, "Exit\n");
@ -3907,7 +3908,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
* disassociate from AP to save power while system is
* in suspended state
*/
brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true);
/* Make sure WPA_Supplicant receives all the event
* generated due to DISASSOC call to the fw to keep
* the state fw and WPA_Supplicant state consistent
@ -4835,12 +4836,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
if (settings->hidden_ssid) {
err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
if (err) {
bphy_err(drvr, "closednet error (%d)\n", err);
goto exit;
}
err = brcmf_fil_iovar_int_set(ifp, "closednet",
settings->hidden_ssid);
if (err) {
bphy_err(drvr, "%s closednet error (%d)\n",
settings->hidden_ssid ?
"enabled" : "disabled",
err);
goto exit;
}
brcmf_dbg(TRACE, "AP mode configuration complete\n");
@ -5129,7 +5132,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
&freq);
chan_nr = ieee80211_frequency_to_channel(freq);
af_params->channel = cpu_to_le32(chan_nr);
af_params->dwell_time = cpu_to_le32(params->wait);
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
le16_to_cpu(action_frame->len));
@ -6024,10 +6027,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
brcmf_net_setcarrier(ifp, true);
} else if (brcmf_is_linkdown(e)) {
brcmf_dbg(CONN, "Linkdown\n");
if (!brcmf_is_ibssmode(ifp->vif)) {
if (!brcmf_is_ibssmode(ifp->vif) &&
test_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state)) {
if (memcmp(profile->bssid, e->addr, ETH_ALEN))
return err;
brcmf_bss_connect_done(cfg, ndev, e, false);
brcmf_link_down(ifp->vif,
brcmf_map_fw_linkdown_reason(e));
brcmf_map_fw_linkdown_reason(e),
e->event_code &
(BRCMF_E_DEAUTH_IND |
BRCMF_E_DISASSOC_IND)
? false : true);
brcmf_init_prof(ndev_to_prof(ndev));
if (ndev != cfg_to_ndev(cfg))
complete(&cfg->vif_disabled);
@ -6801,7 +6813,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
* #AP <= 4, matching BI, channels = 1, 4 total
*
* no p2p and rsdb:
* #STA <= 2, #AP <= 2, channels = 2, 4 total
* #STA <= 1, #AP <= 2, channels = 2, 4 total
*
* p2p, no mchan, and mbss:
*
@ -6816,7 +6828,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
* #AP <= 4, matching BI, channels = 1, 4 total
*
* p2p, rsdb, and no mbss:
* #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
* #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
* channels = 2, 4 total
*/
static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
@ -6857,7 +6869,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
goto err;
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
c0_limits[i].max = 1 + rsdb;
c0_limits[i].max = 1;
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
if (mon_flag) {
c0_limits[i].max = 1;
@ -6873,7 +6885,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
if (p2p && rsdb) {
c0_limits[i].max = 2;
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
combo[c].max_interfaces = 5;
combo[c].max_interfaces = 4;
} else if (p2p) {
combo[c].max_interfaces = i;
} else if (rsdb) {
@ -7180,7 +7192,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
* from AP to save power
*/
if (check_vif_up(ifp->vif)) {
brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
/* Make sure WPA_Supplicant receives all the event
generated due to DISASSOC call to the fw to keep

View File

@ -209,8 +209,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err);
goto done;
}
memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
bus = ifp->drvr->bus_if;
ri = &ifp->drvr->revinfo;

View File

@ -352,6 +352,9 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
if ((skb->priority == 0) || (skb->priority > 7))
skb->priority = cfg80211_classify8021d(skb, NULL);
/* set pacing shift for packet aggregation */
sk_pacing_shift_update(skb->sk, 8);
ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
if (ret < 0)
brcmf_txfinalize(ifp, skb, false);

View File

@ -19,7 +19,7 @@
#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0004
#define BRCMF_STA_BRCM 0x00000001 /* Running a Broadcom driver */
#define BRCMF_STA_WME 0x00000002 /* WMM association */

View File

@ -323,6 +323,10 @@ struct brcmf_skbuff_cb {
* firmware suppress the packet as device is already in PS mode.
* @BRCMF_FWS_TXSTATUS_FW_TOSSED:
* firmware tossed the packet.
* @BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK:
* firmware tossed the packet after retries.
* @BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED:
* firmware wrongly reported suppressed previously, now fixing to acked.
* @BRCMF_FWS_TXSTATUS_HOST_TOSSED:
* host tossed the packet.
*/
@ -331,6 +335,8 @@ enum brcmf_fws_txstatus {
BRCMF_FWS_TXSTATUS_CORE_SUPPRESS,
BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS,
BRCMF_FWS_TXSTATUS_FW_TOSSED,
BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK,
BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED,
BRCMF_FWS_TXSTATUS_HOST_TOSSED
};
@ -383,6 +389,7 @@ struct brcmf_fws_mac_descriptor {
};
#define BRCMF_FWS_HANGER_MAXITEMS 3072
#define BRCMF_BORROW_RATIO 3
/**
* enum brcmf_fws_hanger_item_state - state of hanger item.
@ -479,7 +486,8 @@ struct brcmf_fws_info {
u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
int fifo_credit[BRCMF_FWS_FIFO_COUNT];
int init_fifo_credit[BRCMF_FWS_FIFO_COUNT];
int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1];
int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1]
[BRCMF_FWS_FIFO_AC_VO + 1];
int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
u32 fifo_credit_map;
u32 fifo_delay_map;
@ -621,6 +629,7 @@ static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
int ifidx)
{
struct brcmf_fws_hanger_item *hi;
bool (*matchfn)(struct sk_buff *, void *) = NULL;
struct sk_buff *skb;
int prec;
@ -632,6 +641,9 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx);
while (skb) {
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
hi = &fws->hanger.items[hslot];
WARN_ON(skb != hi->pkt);
hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
true);
brcmu_pkt_buf_free_skb(skb);
@ -1187,11 +1199,11 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
fws->fifo_credit_map |= 1 << fifo;
if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
(fws->credits_borrowed[0])) {
if (fifo > BRCMF_FWS_FIFO_AC_BK &&
fifo <= BRCMF_FWS_FIFO_AC_VO) {
for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0;
lender_ac--) {
borrowed = &fws->credits_borrowed[lender_ac];
borrowed = &fws->credits_borrowed[fifo][lender_ac];
if (*borrowed) {
fws->fifo_credit_map |= (1 << lender_ac);
fifo_credit = &fws->fifo_credit[lender_ac];
@ -1208,7 +1220,10 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
}
}
fws->fifo_credit[fifo] += credits;
if (credits) {
fws->fifo_credit[fifo] += credits;
}
if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo])
fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo];
@ -1451,6 +1466,10 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
fws->stats.txs_tossed += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK)
fws->stats.txs_discard += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED)
fws->stats.txs_discard += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
fws->stats.txs_host_tossed += compcnt;
else
@ -1843,6 +1862,9 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
WARN_ON(siglen > skb->len);
if (siglen > skb->len)
siglen = skb->len;
if (!siglen)
return;
/* if flow control disabled, skip to packet data and leave */
@ -2005,27 +2027,31 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
}
}
static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws,
int highest_lender_ac, int borrower_ac,
bool borrow_all)
{
int lender_ac;
int lender_ac, borrow_limit = 0;
if (time_after(fws->borrow_defer_timestamp, jiffies)) {
fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
return -ENAVAIL;
}
for (lender_ac = 0; lender_ac <= highest_lender_ac; lender_ac++) {
for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
if (fws->fifo_credit[lender_ac] > 0) {
fws->credits_borrowed[lender_ac]++;
if (!borrow_all)
borrow_limit =
fws->init_fifo_credit[lender_ac] / BRCMF_BORROW_RATIO;
else
borrow_limit = 0;
if (fws->fifo_credit[lender_ac] > borrow_limit) {
fws->credits_borrowed[borrower_ac][lender_ac]++;
fws->fifo_credit[lender_ac]--;
if (fws->fifo_credit[lender_ac] == 0)
fws->fifo_credit_map &= ~(1 << lender_ac);
fws->fifo_credit_map |= (1 << BRCMF_FWS_FIFO_AC_BE);
fws->fifo_credit_map |= (1 << borrower_ac);
brcmf_dbg(DATA, "borrow credit from: %d\n", lender_ac);
return 0;
}
}
fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
fws->fifo_credit_map &= ~(1 << borrower_ac);
return -ENAVAIL;
}
@ -2216,9 +2242,10 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
}
continue;
}
while ((fws->fifo_credit[fifo] > 0) ||
while ((fws->fifo_credit[fifo]) ||
((!fws->bcmc_credit_check) &&
(fifo == BRCMF_FWS_FIFO_BCMC))) {
(fifo == BRCMF_FWS_FIFO_BCMC))) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb)
break;
@ -2228,10 +2255,14 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
if (fws->bus_flow_blocked)
break;
}
if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
(fws->fifo_credit[fifo] <= 0) &&
(!fws->bus_flow_blocked)) {
while (brcmf_fws_borrow_credit(fws) == 0) {
if (fifo >= BRCMF_FWS_FIFO_AC_BE &&
fifo <= BRCMF_FWS_FIFO_AC_VO &&
fws->fifo_credit[fifo] == 0 &&
!fws->bus_flow_blocked) {
while (brcmf_fws_borrow_credit(fws,
fifo - 1, fifo,
true) == 0) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb) {
brcmf_fws_return_credits(fws, fifo, 1);

View File

@ -54,6 +54,7 @@
#define BRCMF_IOCTL_REQ_PKTID 0xFFFE
#define BRCMF_MSGBUF_MAX_PKT_SIZE 2048
#define BRCMF_MSGBUF_MAX_CTL_PKT_SIZE 8192
#define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32
#define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8
#define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8
@ -1028,7 +1029,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
memset(rx_bufpost, 0, sizeof(*rx_bufpost));
skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE);
if (skb == NULL) {
bphy_err(drvr, "Failed to alloc SKB\n");

View File

@ -17,7 +17,6 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
{
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
struct device_node *root, *np = dev->of_node;
struct property *prop;
int irq;
u32 irqf;
u32 val;
@ -25,8 +24,22 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
/* Set board-type to the first string of the machine compatible prop */
root = of_find_node_by_path("/");
if (root) {
prop = of_find_property(root, "compatible", NULL);
settings->board_type = of_prop_next_string(prop, NULL);
int i, len;
char *board_type;
const char *tmp;
of_property_read_string_index(root, "compatible", 0, &tmp);
/* get rid of '/' in the compatible string to be able to find the FW */
len = strlen(tmp) + 1;
board_type = devm_kzalloc(dev, len, GFP_KERNEL);
strscpy(board_type, tmp, len);
for (i = 0; i < board_type[i]; i++) {
if (board_type[i] == '/')
board_type[i] = '-';
}
settings->board_type = board_type;
of_node_put(root);
}

View File

@ -1700,7 +1700,7 @@ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
return err;
}
static bool brcmf_p2p_check_dwell_overflow(s32 requested_dwell,
static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,
unsigned long dwell_jiffies)
{
if ((requested_dwell & CUSTOM_RETRY_MASK) &&
@ -1738,8 +1738,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
unsigned long dwell_jiffies = 0;
bool dwell_overflow = false;
s32 requested_dwell = af_params->dwell_time;
u32 requested_dwell = le32_to_cpu(af_params->dwell_time);
action_frame = &af_params->action_frame;
action_frame_len = le16_to_cpu(action_frame->len);

View File

@ -16,6 +16,7 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h>
#include <linux/mmc/core.h>
#include <linux/semaphore.h>
#include <linux/firmware.h>
#include <linux/module.h>
@ -648,6 +649,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};
#define TXCTL_CREDITS 2
static void pkt_align(struct sk_buff *p, int len, int align)
{
uint datalign;
@ -661,8 +664,16 @@ static void pkt_align(struct sk_buff *p, int len, int align)
/* To check if there's window offered */
static bool data_ok(struct brcmf_sdio *bus)
{
return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
/* Reserve TXCTL_CREDITS credits for txctl */
return (bus->tx_max - bus->tx_seq) > TXCTL_CREDITS &&
((bus->tx_max - bus->tx_seq) & 0x80) == 0;
}
/* To check if there's window offered */
static bool txctl_ok(struct brcmf_sdio *bus)
{
return (bus->tx_max - bus->tx_seq) != 0 &&
((bus->tx_max - bus->tx_seq) & 0x80) == 0;
}
static int
@ -2668,7 +2679,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_clrintr(bus);
if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
data_ok(bus)) {
txctl_ok(bus)) {
sdio_claim_host(bus->sdiodev->func1);
if (bus->ctrl_frame_stat) {
err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
@ -2676,6 +2687,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
bus->ctrl_frame_err = err;
wmb();
bus->ctrl_frame_stat = false;
if (err)
brcmf_err("sdio ctrlframe tx failed err=%d\n",
err);
}
sdio_release_host(bus->sdiodev->func1);
brcmf_sdio_wait_event_wakeup(bus);
@ -3699,7 +3713,11 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
if (bus->idlecount > bus->idletime) {
brcmf_dbg(SDIO, "idle\n");
sdio_claim_host(bus->sdiodev->func1);
brcmf_sdio_wd_timer(bus, false);
#ifdef DEBUG
if (!BRCMF_FWCON_ON() ||
bus->console_interval == 0)
#endif
brcmf_sdio_wd_timer(bus, false);
bus->idlecount = 0;
brcmf_sdio_bus_sleep(bus, true, false);
sdio_release_host(bus->sdiodev->func1);
@ -4109,6 +4127,36 @@ int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
return 0;
}
static int brcmf_sdio_bus_reset(struct device *dev)
{
int ret = 0;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(SDIO, "Enter\n");
/* start by unregistering irqs */
brcmf_sdiod_intr_unregister(sdiodev);
brcmf_sdiod_remove(sdiodev);
/* reset the adapter */
sdio_claim_host(sdiodev->func1);
mmc_hw_reset(sdiodev->func1->card->host);
sdio_release_host(sdiodev->func1);
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
ret = brcmf_sdiod_probe(sdiodev);
if (ret) {
brcmf_err("Failed to probe after sdio device reset: ret %d\n",
ret);
brcmf_sdiod_remove(sdiodev);
}
return ret;
}
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.stop = brcmf_sdio_bus_stop,
.preinit = brcmf_sdio_bus_preinit,
@ -4120,7 +4168,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump,
.get_fwname = brcmf_sdio_get_fwname,
.debugfs_create = brcmf_sdio_debugfs_create
.debugfs_create = brcmf_sdio_debugfs_create,
.reset = brcmf_sdio_bus_reset
};
#define BRCMF_SDIO_FW_CODE 0

View File

@ -367,6 +367,9 @@ static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
}
#endif /* CONFIG_PM_SLEEP */
int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev);
int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev);
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
void brcmf_sdio_remove(struct brcmf_sdio *bus);
void brcmf_sdio_isr(struct brcmf_sdio *bus);

View File

@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
#include <net/mac80211.h>
#include <linux/bcma/bcma_driver_chipcommon.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/consumer.h>
#include "mac80211_if.h"
#include "pub.h"
@ -19,16 +21,13 @@
static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
{
if (wl->radio_led.gpio == -1)
if (!wl->radio_led.gpiod)
return;
if (wl->radio_led.active_low)
state = !state;
if (state)
gpio_set_value(wl->radio_led.gpio, 1);
gpiod_set_value(wl->radio_led.gpiod, 1);
else
gpio_set_value(wl->radio_led.gpio, 0);
gpiod_set_value(wl->radio_led.gpiod, 0);
}
@ -45,8 +44,8 @@ void brcms_led_unregister(struct brcms_info *wl)
{
if (wl->led_dev.dev)
led_classdev_unregister(&wl->led_dev);
if (wl->radio_led.gpio != -1)
gpio_free(wl->radio_led.gpio);
if (wl->radio_led.gpiod)
gpiochip_free_own_desc(wl->radio_led.gpiod);
}
int brcms_led_register(struct brcms_info *wl)
@ -61,12 +60,8 @@ int brcms_led_register(struct brcms_info *wl)
&sprom->gpio1,
&sprom->gpio2,
&sprom->gpio3 };
unsigned gpio = -1;
bool active_low = false;
/* none by default */
radio_led->gpio = -1;
radio_led->active_low = false;
int hwnum = -1;
enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;
if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
return -ENODEV;
@ -75,30 +70,26 @@ int brcms_led_register(struct brcms_info *wl)
for (i = 0; i < BRCMS_LED_NO; i++) {
u8 led = *leds[i];
if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
gpio = bcma_gpio->base + i;
hwnum = i;
if (led & BRCMS_LED_AL_MASK)
active_low = true;
lflags = GPIO_ACTIVE_LOW;
break;
}
}
if (gpio == -1 || !gpio_is_valid(gpio))
/* No LED, bail out */
if (hwnum == -1)
return -ENODEV;
/* request and configure LED gpio */
err = gpio_request_one(gpio,
active_low ? GPIOF_OUT_INIT_HIGH
: GPIOF_OUT_INIT_LOW,
"radio on");
if (err) {
wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
gpio, err);
return err;
}
err = gpio_direction_output(gpio, 1);
if (err) {
wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
gpio, err);
/* Try to obtain this LED GPIO line */
radio_led->gpiod = gpiochip_request_own_desc(bcma_gpio, hwnum,
"radio on", lflags,
GPIOD_OUT_LOW);
if (IS_ERR(radio_led->gpiod)) {
err = PTR_ERR(radio_led->gpiod);
wiphy_err(wl->wiphy, "requesting led GPIO failed (err: %d)\n",
err);
return err;
}
@ -117,11 +108,8 @@ int brcms_led_register(struct brcms_info *wl)
return err;
}
wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
wl->radio_led.name,
gpio);
radio_led->gpio = gpio;
radio_led->active_low = active_low;
wiphy_info(wl->wiphy, "registered radio enabled led device: %s\n",
wl->radio_led.name);
return 0;
}

View File

@ -16,10 +16,12 @@
#ifndef _BRCM_LED_H_
#define _BRCM_LED_H_
struct gpio_desc;
struct brcms_led {
char name[32];
unsigned gpio;
bool active_low;
struct gpio_desc *gpiod;
};
#ifdef CONFIG_BCMA_DRIVER_GPIO

View File

@ -2450,7 +2450,7 @@ static void mpi_unmap_card(struct pci_dev *pci)
/*************************************************************
* This routine assumes that descriptors have been setup .
* Run at insmod time or after reset when the decriptors
* Run at insmod time or after reset when the descriptors
* have been initialized . Returns 0 if all is well nz
* otherwise . Does not allocate memory but sets up card
* using previously allocated descriptors.
@ -3113,7 +3113,7 @@ static int airo_thread(void *data) {
}
break;
}
current->state = TASK_RUNNING;
__set_current_state(TASK_RUNNING);
remove_wait_queue(&ai->thr_wait, &wait);
locked = 1;
}

View File

@ -6397,10 +6397,9 @@ static void ipw2100_pci_remove_one(struct pci_dev *pci_dev)
IPW_DEBUG_INFO("exit\n");
}
#ifdef CONFIG_PM
static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
static int __maybe_unused ipw2100_suspend(struct device *dev_d)
{
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct ipw2100_priv *priv = dev_get_drvdata(dev_d);
struct net_device *dev = priv->net_dev;
IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
@ -6414,10 +6413,6 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
/* Remove the PRESENT state of the device */
netif_device_detach(dev);
pci_save_state(pci_dev);
pci_disable_device(pci_dev);
pci_set_power_state(pci_dev, PCI_D3hot);
priv->suspend_at = ktime_get_boottime_seconds();
mutex_unlock(&priv->action_mutex);
@ -6425,11 +6420,11 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
return 0;
}
static int ipw2100_resume(struct pci_dev *pci_dev)
static int __maybe_unused ipw2100_resume(struct device *dev_d)
{
struct pci_dev *pci_dev = to_pci_dev(dev_d);
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev;
int err;
u32 val;
if (IPW2100_PM_DISABLED)
@ -6439,16 +6434,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
pci_set_power_state(pci_dev, PCI_D0);
err = pci_enable_device(pci_dev);
if (err) {
printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
dev->name);
mutex_unlock(&priv->action_mutex);
return err;
}
pci_restore_state(pci_dev);
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@ -6473,7 +6458,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
return 0;
}
#endif
static void ipw2100_shutdown(struct pci_dev *pci_dev)
{
@ -6539,15 +6523,14 @@ static const struct pci_device_id ipw2100_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
static SIMPLE_DEV_PM_OPS(ipw2100_pm_ops, ipw2100_suspend, ipw2100_resume);
static struct pci_driver ipw2100_pci_driver = {
.name = DRV_NAME,
.id_table = ipw2100_pci_id_table,
.probe = ipw2100_pci_init_one,
.remove = ipw2100_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ipw2100_suspend,
.resume = ipw2100_resume,
#endif
.driver.pm = &ipw2100_pm_ops,
.shutdown = ipw2100_shutdown,
};

View File

@ -11838,10 +11838,9 @@ static void ipw_pci_remove(struct pci_dev *pdev)
free_firmware();
}
#ifdef CONFIG_PM
static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int __maybe_unused ipw_pci_suspend(struct device *dev_d)
{
struct ipw_priv *priv = pci_get_drvdata(pdev);
struct ipw_priv *priv = dev_get_drvdata(dev_d);
struct net_device *dev = priv->net_dev;
printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
@ -11852,33 +11851,20 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
/* Remove the PRESENT state of the device */
netif_device_detach(dev);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
priv->suspend_at = ktime_get_boottime_seconds();
return 0;
}
static int ipw_pci_resume(struct pci_dev *pdev)
static int __maybe_unused ipw_pci_resume(struct device *dev_d)
{
struct pci_dev *pdev = to_pci_dev(dev_d);
struct ipw_priv *priv = pci_get_drvdata(pdev);
struct net_device *dev = priv->net_dev;
int err;
u32 val;
printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
dev->name);
return err;
}
pci_restore_state(pdev);
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@ -11900,7 +11886,6 @@ static int ipw_pci_resume(struct pci_dev *pdev)
return 0;
}
#endif
static void ipw_pci_shutdown(struct pci_dev *pdev)
{
@ -11912,16 +11897,15 @@ static void ipw_pci_shutdown(struct pci_dev *pdev)
pci_disable_device(pdev);
}
static SIMPLE_DEV_PM_OPS(ipw_pci_pm_ops, ipw_pci_suspend, ipw_pci_resume);
/* driver initialization stuff */
static struct pci_driver ipw_driver = {
.name = DRV_NAME,
.id_table = card_ids,
.probe = ipw_pci_probe,
.remove = ipw_pci_remove,
#ifdef CONFIG_PM
.suspend = ipw_pci_suspend,
.resume = ipw_pci_resume,
#endif
.driver.pm = &ipw_pci_pm_ops,
.shutdown = ipw_pci_shutdown,
};

View File

@ -1415,7 +1415,7 @@ il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)
/*
* mac80211 queues, ACs, hardware queues, FIFOs.
*
* Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
* Cf. https://wireless.wiki.kernel.org/en/developers/Documentation/mac80211/queues
*
* Mac80211 uses the following numbers, which we get as from it
* by way of skb_get_queue_mapping(skb):

View File

@ -1749,7 +1749,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
u8 done_search = 0;
u16 high_low;
s32 sr;
u8 tid = MAX_TID_COUNT;
u8 tid;
struct il_tid_data *tid_data;
D_RATE("rate scale calculate new rate for skb\n");

View File

@ -4286,8 +4286,8 @@ il_apm_init(struct il_priv *il)
* power savings, even without L1.
*/
if (il->cfg->set_l0s) {
pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
ret = pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
if (!ret && (lctl & PCI_EXP_LNKCTL_ASPM_L1)) {
/* L1-ASPM enabled; disable(!) L0S */
il_set_bit(il, CSR_GIO_REG,
CSR_GIO_REG_VAL_L0S_ENABLED);

View File

@ -31,7 +31,7 @@ config IWLWIFI
In order to use this driver, you will need a firmware
image for it. You can obtain the microcode from:
<http://wireless.kernel.org/en/users/Drivers/iwlwifi>.
<https://wireless.wiki.kernel.org/en/users/Drivers/iwlwifi>.
The firmware is typically installed in /lib/firmware. You can
look in the hotplug script /etc/hotplug/firmware.agent to

View File

@ -1023,7 +1023,7 @@ struct iwl_wep_cmd {
u8 global_key_type;
u8 flags;
u8 reserved;
struct iwl_wep_key key[0];
struct iwl_wep_key key[];
} __packed;
#define WEP_KEY_WEP_TYPE 1
@ -1305,7 +1305,7 @@ struct iwl_tx_cmd {
* length is 26 or 30 bytes, followed by payload data
*/
u8 payload[0];
struct ieee80211_hdr hdr[0];
struct ieee80211_hdr hdr[];
} __packed;
/*
@ -2380,7 +2380,7 @@ struct iwl_scan_cmd {
* for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
* before requesting another scan.
*/
u8 data[0];
u8 data[];
} __packed;
/* Can abort will notify by complete notification with abort status. */
@ -2475,7 +2475,7 @@ struct iwl_tx_beacon_cmd {
__le16 tim_idx;
u8 tim_size;
u8 reserved1;
struct ieee80211_hdr frame[0]; /* beacon frame */
struct ieee80211_hdr frame[]; /* beacon frame */
} __packed;
/******************************************************************************
@ -3188,7 +3188,7 @@ struct iwl_calib_hdr {
struct iwl_calib_cmd {
struct iwl_calib_hdr hdr;
u8 data[0];
u8 data[];
} __packed;
struct iwl_calib_xtal_freq_cmd {
@ -3216,7 +3216,7 @@ struct iwl_calib_temperature_offset_v2_cmd {
/* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
struct iwl_calib_chain_noise_reset_cmd {
struct iwl_calib_hdr hdr;
u8 data[0];
u8 data[];
};
/* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */

View File

@ -200,6 +200,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
iwl_leds_init(priv);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID);
ret = ieee80211_register_hw(priv->hw);
if (ret) {

View File

@ -361,7 +361,7 @@ struct iwl_mcc_update_resp_v3 {
__le16 time;
__le16 geo_info;
__le32 n_channels;
__le32 channels[0];
__le32 channels[];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */
/**
@ -390,7 +390,7 @@ struct iwl_mcc_update_resp {
u8 source_id;
u8 reserved[3];
__le32 n_channels;
__le32 channels[0];
__le32 channels[];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_4 */
/**

View File

@ -293,7 +293,7 @@ struct iwl_tx_cmd {
__le16 pm_frame_timeout;
__le16 reserved4;
u8 payload[0];
struct ieee80211_hdr hdr[0];
struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_6 */
struct iwl_dram_sec_info {
@ -319,7 +319,7 @@ struct iwl_tx_cmd_gen2 {
__le32 flags;
struct iwl_dram_sec_info dram_info;
__le32 rate_n_flags;
struct ieee80211_hdr hdr[0];
struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_7 */
/**
@ -342,7 +342,7 @@ struct iwl_tx_cmd_gen3 {
struct iwl_dram_sec_info dram_info;
__le32 rate_n_flags;
__le64 ttl;
struct ieee80211_hdr hdr[0];
struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_8 */
/*
@ -766,8 +766,8 @@ struct iwl_mvm_compressed_ba_notif {
__le32 tx_rate;
__le16 tfd_cnt;
__le16 ra_tid_cnt;
struct iwl_mvm_compressed_ba_tfd tfd[0];
struct iwl_mvm_compressed_ba_ratid ra_tid[0];
struct iwl_mvm_compressed_ba_tfd tfd[];
} __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */
/**
@ -784,7 +784,7 @@ struct iwl_mac_beacon_cmd_v6 {
__le32 template_id;
__le32 tim_idx;
__le32 tim_size;
struct ieee80211_hdr frame[0];
struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_6 */
/**
@ -805,7 +805,7 @@ struct iwl_mac_beacon_cmd_v7 {
__le32 tim_size;
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[0];
struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
enum iwl_mac_beacon_flags {
@ -840,7 +840,7 @@ struct iwl_mac_beacon_cmd {
__le32 tim_size;
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[0];
struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */
struct iwl_beacon_notif {

View File

@ -2554,7 +2554,7 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id)
return -EINVAL;
if (fwrt->dump.conf != FW_DBG_INVALID)
IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n",
IWL_INFO(fwrt, "FW already configured (%d) - re-configuring\n",
fwrt->dump.conf);
/* Send all HCMDs for configuring the FW debug */

View File

@ -260,7 +260,7 @@ struct hcmd_write_data {
__be32 cmd_id;
__be32 flags;
__be16 length;
u8 data[0];
u8 data[];
} __packed;
static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf,

View File

@ -641,6 +641,6 @@ extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0;
extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long;
extern const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0;
extern const struct iwl_cfg iwlax211_cfg_snj_gf_a0;
#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */

View File

@ -175,7 +175,7 @@ void iwl_opmode_deregister(const char *name);
struct iwl_op_mode {
const struct iwl_op_mode_ops *ops;
char op_mode_specific[0] __aligned(sizeof(void *));
char op_mode_specific[] __aligned(sizeof(void *));
};
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)

View File

@ -1006,7 +1006,7 @@ struct iwl_trans {
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char trans_specific[0] __aligned(sizeof(void *));
char trans_specific[] __aligned(sizeof(void *));
};
const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id);

View File

@ -543,6 +543,14 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
/* The new Tx API does not allow to pass the key or keyid of a MPDU to
* the hw, preventing us to control which key(id) to use per MPDU.
* Till that's fixed we can't use Extended Key ID for the newer cards.
*/
if (!iwl_mvm_has_new_tx_api(mvm))
wiphy_ext_feature_set(hw->wiphy,
NL80211_EXT_FEATURE_EXT_KEY_ID);
hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
@ -4903,7 +4911,7 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
if (mvmsta->avg_energy) {
sinfo->signal_avg = mvmsta->avg_energy;
sinfo->signal_avg = -(s8)mvmsta->avg_energy;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
}

View File

@ -603,7 +603,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_data, u8 tid,
struct ieee80211_sta *sta)
{
int ret = -EAGAIN;
int ret;
IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);

View File

@ -1369,14 +1369,6 @@ out_err:
return ret;
}
static inline u8 iwl_mvm_tid_to_ac_queue(int tid)
{
if (tid == IWL_MAX_TID_COUNT)
return IEEE80211_AC_VO; /* MGMT */
return tid_to_mac80211_ac[tid];
}
void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
{
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm,

View File

@ -290,8 +290,7 @@ static struct pci_driver orinoco_nortel_driver = {
.id_table = orinoco_nortel_id_table,
.probe = orinoco_nortel_init_one,
.remove = orinoco_nortel_remove_one,
.suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume,
.driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION

View File

@ -230,8 +230,7 @@ static struct pci_driver orinoco_pci_driver = {
.id_table = orinoco_pci_id_table,
.probe = orinoco_pci_init_one,
.remove = orinoco_pci_remove_one,
.suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume,
.driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION

View File

@ -18,51 +18,37 @@ struct orinoco_pci_card {
void __iomem *attr_io;
};
#ifdef CONFIG_PM
static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int __maybe_unused orinoco_pci_suspend(struct device *dev_d)
{
struct pci_dev *pdev = to_pci_dev(dev_d);
struct orinoco_private *priv = pci_get_drvdata(pdev);
orinoco_down(priv);
free_irq(pdev->irq, priv);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
static int orinoco_pci_resume(struct pci_dev *pdev)
static int __maybe_unused orinoco_pci_resume(struct device *dev_d)
{
struct pci_dev *pdev = to_pci_dev(dev_d);
struct orinoco_private *priv = pci_get_drvdata(pdev);
struct net_device *dev = priv->ndev;
int err;
pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
dev->name);
return err;
}
pci_restore_state(pdev);
err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
dev->name, priv);
if (err) {
printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
dev->name);
pci_disable_device(pdev);
return -EBUSY;
}
err = orinoco_up(priv);
return err;
return orinoco_up(priv);
}
#else
#define orinoco_pci_suspend NULL
#define orinoco_pci_resume NULL
#endif
static SIMPLE_DEV_PM_OPS(orinoco_pci_pm_ops,
orinoco_pci_suspend,
orinoco_pci_resume);
#endif /* _ORINOCO_PCI_H */

View File

@ -336,8 +336,7 @@ static struct pci_driver orinoco_plx_driver = {
.id_table = orinoco_plx_id_table,
.probe = orinoco_plx_init_one,
.remove = orinoco_plx_remove_one,
.suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume,
.driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION

View File

@ -213,8 +213,7 @@ static struct pci_driver orinoco_tmd_driver = {
.id_table = orinoco_tmd_id_table,
.probe = orinoco_tmd_init_one,
.remove = orinoco_tmd_remove_one,
.suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume,
.driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION

View File

@ -158,7 +158,7 @@ MODULE_FIRMWARE("orinoco_ezusb_fw");
#define EZUSB_REQUEST_FW_TRANS 0xA0
#define EZUSB_REQUEST_TRIGER 0xAA
#define EZUSB_REQUEST_TRIGGER 0xAA
#define EZUSB_REQUEST_TRIG_AC 0xAC
#define EZUSB_CPUCS_REG 0x7F92
@ -1318,12 +1318,12 @@ static int ezusb_hard_reset(struct orinoco_private *priv)
netdev_dbg(upriv->dev, "sending control message\n");
retval = usb_control_msg(upriv->udev,
usb_sndctrlpipe(upriv->udev, 0),
EZUSB_REQUEST_TRIGER,
EZUSB_REQUEST_TRIGGER,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_DIR_OUT, 0x0, 0x0, NULL, 0,
DEF_TIMEOUT);
if (retval < 0) {
err("EZUSB_REQUEST_TRIGER failed retval %d", retval);
err("EZUSB_REQUEST_TRIGGER failed retval %d", retval);
return retval;
}
#if 0

View File

@ -27,7 +27,8 @@ module_param(reg_alpha2, charp, 0);
static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
{
.max = 3, .types = BIT(NL80211_IFTYPE_STATION) |
.max = MWIFIEX_MAX_BSS_NUM,
.types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_AP),
@ -3726,11 +3727,11 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
int ret;
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
return -ENOTSUPP;
return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
return -ENOTSUPP;
return -EOPNOTSUPP;
switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST:
@ -3798,11 +3799,11 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
!(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
return -ENOTSUPP;
return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
return -ENOTSUPP;
return -EOPNOTSUPP;
mwifiex_dbg(priv->adapter, MSG,
"TDLS peer=%pM, oper=%d\n", peer, action);
@ -3832,7 +3833,7 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
default:
mwifiex_dbg(priv->adapter, ERROR,
"tdls_oper: operation not supported\n");
return -ENOTSUPP;
return -EOPNOTSUPP;
}
return mwifiex_tdls_oper(priv, peer, action);
@ -3913,11 +3914,11 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
return -ENOTSUPP;
return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
return -ENOTSUPP;
return -EOPNOTSUPP;
return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
}
@ -4150,11 +4151,11 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
/* we support change_station handler only for TDLS peers*/
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
return -ENOTSUPP;
return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
return -ENOTSUPP;
return -EOPNOTSUPP;
priv->sta_params = params;

View File

@ -953,7 +953,7 @@ int mwifiex_set_mac_address(struct mwifiex_private *priv,
} else {
/* Internal mac address change */
if (priv->bss_type == MWIFIEX_BSS_TYPE_ANY)
return -ENOTSUPP;
return -EOPNOTSUPP;
mac_addr = old_mac_addr;

View File

@ -1723,7 +1723,7 @@ mwifiex_cmd_tdls_config(struct mwifiex_private *priv,
default:
mwifiex_dbg(priv->adapter, ERROR,
"Unknown TDLS configuration\n");
return -ENOTSUPP;
return -EOPNOTSUPP;
}
le16_unaligned_add_cpu(&cmd->size, len);
@ -1849,7 +1849,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
break;
default:
mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS operation\n");
return -ENOTSUPP;
return -EOPNOTSUPP;
}
le16_unaligned_add_cpu(&cmd->size, config_len);

View File

@ -580,6 +580,11 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
{
struct host_cmd_ds_802_11_key_material *key =
&resp->params.key_material;
int len;
len = le16_to_cpu(key->key_param_set.key_len);
if (len > sizeof(key->key_param_set.key))
return -EINVAL;
if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
@ -593,9 +598,8 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
memset(priv->aes_key.key_param_set.key, 0,
sizeof(key->key_param_set.key));
priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
le16_to_cpu(priv->aes_key.key_param_set.key_len));
priv->aes_key.key_param_set.key_len = cpu_to_le16(len);
memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len);
return 0;
}
@ -610,9 +614,14 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
struct host_cmd_ds_802_11_key_material_v2 *key_v2;
__le16 len;
int len;
key_v2 = &resp->params.key_material_v2;
len = le16_to_cpu(key_v2->key_param_set.key_params.aes.key_len);
if (len > WLAN_KEY_LEN_CCMP)
return -EINVAL;
if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n");
@ -628,10 +637,9 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
WLAN_KEY_LEN_CCMP);
priv->aes_key_v2.key_param_set.key_params.aes.key_len =
key_v2->key_param_set.key_params.aes.key_len;
len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
cpu_to_le16(len);
memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));
key_v2->key_param_set.key_params.aes.key, len);
return 0;
}

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0
config WLAN_VENDOR_MICROCHIP
bool "Microchip devices"
default y
help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all the
questions about these cards. If you say Y, you will be asked for
your specific card in the following questions.
if WLAN_VENDOR_MICROCHIP
source "drivers/net/wireless/microchip/wilc1000/Kconfig"
endif # WLAN_VENDOR_MICROCHIP

View File

@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_WILC1000) += wilc1000/

View File

@ -1,9 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_WILC1000) += wilc1000.o
ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
-DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
wilc1000-objs := cfg80211.o netdev.o mon.o \
hif.o wlan_cfg.o wlan.o

View File

@ -46,9 +46,11 @@ static const struct ieee80211_txrx_stypes
}
};
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support wowlan_support = {
.flags = WIPHY_WOWLAN_ANY
};
#endif
struct wilc_p2p_mgmt_data {
int size;

View File

@ -229,8 +229,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
return NULL;
wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP;
strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
strlcpy(wl->monitor_dev->name, name, IFNAMSIZ);
wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
wl->monitor_dev->needs_free_netdev = true;

View File

@ -15,6 +15,13 @@
#define WILC_MULTICAST_TABLE_SIZE 8
/* latest API version supported */
#define WILC1000_API_VER 1
#define WILC1000_FW_PREFIX "atmel/wilc1000_wifi_firmware-"
#define __WILC1000_FW(api) WILC1000_FW_PREFIX #api ".bin"
#define WILC1000_FW(api) __WILC1000_FW(api)
static irqreturn_t isr_uh_routine(int irq, void *user_data)
{
struct net_device *dev = user_data;
@ -176,23 +183,22 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
int chip_id;
const struct firmware *wilc_firmware;
char *firmware;
const struct firmware *wilc_fw;
int ret;
chip_id = wilc_get_chipid(wilc, false);
if (chip_id < 0x1003a0)
firmware = FIRMWARE_1002;
else
firmware = FIRMWARE_1003;
netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id,
WILC1000_FW(WILC1000_API_VER));
netdev_info(dev, "loading firmware %s\n", firmware);
if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
netdev_err(dev, "%s - firmware not available\n", firmware);
ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER),
wilc->dev);
if (ret != 0) {
netdev_err(dev, "%s - firmware not available\n",
WILC1000_FW(WILC1000_API_VER));
return -EINVAL;
}
wilc->firmware = wilc_firmware;
wilc->firmware = wilc_fw;
return 0;
}
@ -678,14 +684,14 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
if (skb->dev != ndev) {
netdev_err(ndev, "Packet not destined to this device\n");
return 0;
return NETDEV_TX_OK;
}
tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
if (!tx_data) {
dev_kfree_skb(skb);
netif_wake_queue(ndev);
return 0;
return NETDEV_TX_OK;
}
tx_data->buff = skb->data;
@ -710,7 +716,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
srcu_read_unlock(&wilc->srcu, srcu_idx);
}
return 0;
return NETDEV_TX_OK;
}
static int wilc_mac_close(struct net_device *ndev)
@ -929,3 +935,4 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
}
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER));

View File

@ -1966,32 +1966,17 @@ static void rtl8180_remove(struct pci_dev *pdev)
ieee80211_free_hw(dev);
}
#ifdef CONFIG_PM
static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
{
pci_save_state(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
#define rtl8180_suspend NULL
#define rtl8180_resume NULL
static int rtl8180_resume(struct pci_dev *pdev)
{
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
return 0;
}
#endif /* CONFIG_PM */
static SIMPLE_DEV_PM_OPS(rtl8180_pm_ops, rtl8180_suspend, rtl8180_resume);
static struct pci_driver rtl8180_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl8180_table,
.probe = rtl8180_probe,
.remove = rtl8180_remove,
#ifdef CONFIG_PM
.suspend = rtl8180_suspend,
.resume = rtl8180_resume,
#endif /* CONFIG_PM */
.driver.pm = &rtl8180_pm_ops,
};
module_pci_driver(rtl8180_driver);

View File

@ -769,13 +769,13 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
*(u8 *)(ie + index);
index += 1;
p2pinfo->noa_duration[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_interval[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_start_time[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
}
@ -864,13 +864,13 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
*(u8 *)(ie + index);
index += 1;
p2pinfo->noa_duration[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_interval[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_start_time[i] =
le32_to_cpu(*(__le32 *)ie + index);
le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
}

View File

@ -870,11 +870,11 @@ static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
/*0.1 the following TWO tables decide the
*final index of OFDM/CCK swing table
*/
s8 delta_swing_table_idx[2][15] = {
static const s8 delta_swing_table_idx[2][15] = {
{0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
{0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
};
u8 thermal_threshold[2][15] = {
static const u8 thermal_threshold[2][15] = {
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
};

Some files were not shown because too many files have changed in this diff Show More