Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git

ath.git patches for v5.16. Major changes:

ath9k

* add option to reset the wifi chip via debugfs

* convert Device Tree bindings to the json-schema

* support Device Tree ieee80211-freq-limit property to limit channels
This commit is contained in:
Kalle Valo 2021-10-20 11:56:50 +03:00
commit 8347c80600
25 changed files with 315 additions and 108 deletions

View File

@ -1,48 +0,0 @@
* Qualcomm Atheros ath9k wireless devices
This node provides properties for configuring the ath9k wireless device. The
node is expected to be specified as a child node of the PCI controller to
which the wireless chip is connected.
Required properties:
- compatible: For PCI and PCIe devices this should be an identifier following
the format as defined in "PCI Bus Binding to Open Firmware"
Revision 2.1. One of the possible formats is "pciVVVV,DDDD"
where VVVV is the PCI vendor ID and DDDD is PCI device ID.
Typically QCA's PCI vendor ID 168c is used while the PCI device
ID depends on the chipset - see the following (possibly
incomplete) list:
- 0023 for AR5416
- 0024 for AR5418
- 0027 for AR9160
- 0029 for AR9220 and AR9223
- 002a for AR9280 and AR9283
- 002b for AR9285
- 002c for AR2427
- 002d for AR9227
- 002e for AR9287
- 0030 for AR9380, AR9381 and AR9382
- 0032 for AR9485
- 0033 for AR9580 and AR9590
- 0034 for AR9462
- 0036 for AR9565
- 0037 for AR9485
- reg: Address and length of the register set for the device.
Optional properties:
- qca,no-eeprom: Indicates that there is no physical EEPROM connected to the
ath9k wireless chip (in this case the calibration /
EEPROM data will be loaded from userspace using the
kernel firmware loader).
The MAC address will be determined using the optional properties defined in
net/ethernet.txt.
In this example, the node is defined as child node of the PCI controller:
&pci0 {
wifi@168c,002d {
compatible = "pci168c,002d";
reg = <0x7000 0 0 0 0x1000>;
qca,no-eeprom;
};
};

View File

@ -0,0 +1,90 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/wireless/qca,ath9k.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Atheros ath9k wireless devices Generic Binding
maintainers:
- Kalle Valo <kvalo@codeaurora.org>
description: |
This node provides properties for configuring the ath9k wireless device.
The node is expected to be specified as a child node of the PCI controller
to which the wireless chip is connected.
allOf:
- $ref: ieee80211.yaml#
properties:
compatible:
enum:
- pci168c,0023 # AR5416
- pci168c,0024 # AR5418
- pci168c,0027 # AR9160
- pci168c,0029 # AR9220 and AR9223
- pci168c,002a # AR9280 and AR9283
- pci168c,002b # AR9285
- pci168c,002c # AR2427 - 802.11n bonded out
- pci168c,002d # AR9227
- pci168c,002e # AR9287
- pci168c,0030 # AR9380, AR9381 and AR9382
- pci168c,0032 # AR9485
- pci168c,0033 # AR9580 and AR9590
- pci168c,0034 # AR9462
- pci168c,0036 # AR9565
- pci168c,0037 # AR1111 and AR9485
reg:
maxItems: 1
interrupts:
maxItems: 1
ieee80211-freq-limit: true
qca,no-eeprom:
$ref: /schemas/types.yaml#/definitions/flag
description:
Indicates that there is no physical EEPROM connected
nvmem-cells:
items:
- description: Reference to an nvmem node for the MAC address
- description: Reference to an nvmem node for calibration data
nvmem-cell-names:
items:
- const: mac-address
- const: calibration
required:
- compatible
- reg
additionalProperties: false
examples:
- |
pcie0 {
#address-cells = <3>;
#size-cells = <2>;
wifi@0,0 {
compatible = "pci168c,002d";
reg = <0 0 0 0 0>;
interrupts = <3>;
qca,no-eeprom;
};
};
- |
pci0 {
#address-cells = <3>;
#size-cells = <2>;
wifi@0,11 {
compatible = "pci168c,0029";
reg = <0x8800 0 0 0 0>;
nvmem-cells = <&macaddr_art_c>, <&cal_art_1000>;
nvmem-cell-names = "mac-address", "calibration";
};
};

View File

@ -15464,6 +15464,7 @@ M: ath9k-devel@qca.qualcomm.com
L: linux-wireless@vger.kernel.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
F: Documentation/devicetree/bindings/net/wireless/qca,ath9k.yaml
F: drivers/net/wireless/ath/ath9k/
QUALCOMM CAMERA SUBSYSTEM DRIVER

View File

@ -1052,7 +1052,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
arg.channel.min_power = 0;
arg.channel.max_power = channel->max_power * 2;
arg.channel.max_reg_power = channel->max_reg_power * 2;
arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
arg.channel.max_antenna_gain = channel->max_antenna_gain;
reinit_completion(&ar->vdev_setup_done);
reinit_completion(&ar->vdev_delete_done);
@ -1498,7 +1498,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
arg.channel.min_power = 0;
arg.channel.max_power = chandef->chan->max_power * 2;
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
@ -3426,7 +3426,7 @@ static int ath10k_update_channel_list(struct ath10k *ar)
ch->min_power = 0;
ch->max_power = channel->max_power * 2;
ch->max_reg_power = channel->max_reg_power * 2;
ch->max_antenna_gain = channel->max_antenna_gain * 2;
ch->max_antenna_gain = channel->max_antenna_gain;
ch->reg_class_id = 0; /* FIXME */
/* FIXME: why use only legacy modes, why not any

View File

@ -864,7 +864,8 @@ static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi)
ath10k_qmi_remove_msa_permission(qmi);
ath10k_core_free_board_files(ar);
if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags))
if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags) &&
!test_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags))
ath10k_snoc_fw_crashed_dump(ar);
ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND);

View File

@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc/qcom_rproc.h>
#include <linux/of_address.h>
#include <linux/iommu.h>
@ -1477,6 +1478,74 @@ void ath10k_snoc_fw_crashed_dump(struct ath10k *ar)
mutex_unlock(&ar->dump_mutex);
}
static int ath10k_snoc_modem_notify(struct notifier_block *nb, unsigned long action,
void *data)
{
struct ath10k_snoc *ar_snoc = container_of(nb, struct ath10k_snoc, nb);
struct ath10k *ar = ar_snoc->ar;
struct qcom_ssr_notify_data *notify_data = data;
switch (action) {
case QCOM_SSR_BEFORE_POWERUP:
ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem starting event\n");
clear_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags);
break;
case QCOM_SSR_AFTER_POWERUP:
ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem running event\n");
break;
case QCOM_SSR_BEFORE_SHUTDOWN:
ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem %s event\n",
notify_data->crashed ? "crashed" : "stopping");
if (!notify_data->crashed)
set_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags);
else
clear_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags);
break;
case QCOM_SSR_AFTER_SHUTDOWN:
ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem offline event\n");
break;
default:
ath10k_err(ar, "received unrecognized event %lu\n", action);
break;
}
return NOTIFY_OK;
}
static int ath10k_modem_init(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
void *notifier;
int ret;
ar_snoc->nb.notifier_call = ath10k_snoc_modem_notify;
notifier = qcom_register_ssr_notifier("mpss", &ar_snoc->nb);
if (IS_ERR(notifier)) {
ret = PTR_ERR(notifier);
ath10k_err(ar, "failed to initialize modem notifier: %d\n", ret);
return ret;
}
ar_snoc->notifier = notifier;
return 0;
}
static void ath10k_modem_deinit(struct ath10k *ar)
{
int ret;
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
ret = qcom_unregister_ssr_notifier(ar_snoc->notifier, &ar_snoc->nb);
if (ret)
ath10k_err(ar, "error %d unregistering notifier\n", ret);
}
static int ath10k_setup_msa_resources(struct ath10k *ar, u32 msa_size)
{
struct device *dev = ar->dev;
@ -1740,10 +1809,17 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
goto err_fw_deinit;
}
ret = ath10k_modem_init(ar);
if (ret)
goto err_qmi_deinit;
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
return 0;
err_qmi_deinit:
ath10k_qmi_deinit(ar);
err_fw_deinit:
ath10k_fw_deinit(ar);
@ -1771,6 +1847,7 @@ static int ath10k_snoc_free_resources(struct ath10k *ar)
ath10k_fw_deinit(ar);
ath10k_snoc_free_irq(ar);
ath10k_snoc_release_resource(ar);
ath10k_modem_deinit(ar);
ath10k_qmi_deinit(ar);
ath10k_core_destroy(ar);

View File

@ -6,6 +6,8 @@
#ifndef _SNOC_H_
#define _SNOC_H_
#include <linux/notifier.h>
#include "hw.h"
#include "ce.h"
#include "qmi.h"
@ -45,6 +47,7 @@ struct ath10k_snoc_ce_irq {
enum ath10k_snoc_flags {
ATH10K_SNOC_FLAG_REGISTERED,
ATH10K_SNOC_FLAG_UNREGISTERING,
ATH10K_SNOC_FLAG_MODEM_STOPPED,
ATH10K_SNOC_FLAG_RECOVERY,
ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK,
};
@ -75,6 +78,8 @@ struct ath10k_snoc {
struct clk_bulk_data *clks;
size_t num_clks;
struct ath10k_qmi *qmi;
struct notifier_block nb;
void *notifier;
unsigned long flags;
bool xo_cal_supported;
u32 xo_cal_data;

View File

@ -2066,7 +2066,9 @@ struct wmi_channel {
union {
__le32 reginfo1;
struct {
/* note: power unit is 1 dBm */
u8 antenna_max;
/* note: power unit is 0.5 dBm */
u8 max_tx_power;
} __packed;
} __packed;
@ -2086,6 +2088,7 @@ struct wmi_channel_arg {
u32 min_power;
u32 max_power;
u32 max_reg_power;
/* note: power unit is 1 dBm */
u32 max_antenna_gain;
u32 reg_class_id;
enum wmi_phy_mode mode;

View File

@ -58,7 +58,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.rx_mac_buf_ring = false,
.vdev_start_delay = false,
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.spectral = {
.fft_sz = 2,
@ -81,6 +80,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
},
{
.hw_rev = ATH11K_HW_IPQ6018_HW10,
@ -109,7 +109,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.rx_mac_buf_ring = false,
.vdev_start_delay = false,
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.spectral = {
.fft_sz = 4,
@ -129,6 +128,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
},
{
.name = "qca6390 hw2.0",
@ -157,7 +157,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.rx_mac_buf_ring = true,
.vdev_start_delay = true,
.htt_peer_map_v2 = false,
.tcl_0_only = true,
.spectral = {
.fft_sz = 0,
@ -176,6 +175,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = true,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
},
{
.name = "qcn9074 hw1.0",
@ -203,7 +203,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.rx_mac_buf_ring = false,
.vdev_start_delay = false,
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.spectral = {
.fft_sz = 2,
@ -223,6 +222,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
},
{
.name = "wcn6855 hw2.0",
@ -251,7 +251,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.rx_mac_buf_ring = true,
.vdev_start_delay = true,
.htt_peer_map_v2 = false,
.tcl_0_only = true,
.spectral = {
.fft_sz = 0,
@ -270,6 +269,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = true,
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
.fix_l1ss = false,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
},
};

View File

@ -806,7 +806,7 @@ static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
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++)
for (i = 0; i < ab->hw_params.max_tx_ring; i++)
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
i, soc_stats->tx_err.desc_na[i]);

View File

@ -311,7 +311,7 @@ void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab)
if (!ab->hw_params.supports_shadow_regs)
return;
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
for (i = 0; i < ab->hw_params.max_tx_ring; i++)
ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]);
ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer);
@ -326,7 +326,7 @@ static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab)
ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring);
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring);
}
@ -366,7 +366,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
goto err;
}
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring,
HAL_TCL_DATA, i, 0,
DP_TCL_DATA_RING_SIZE);
@ -996,7 +996,7 @@ void ath11k_dp_free(struct ath11k_base *ab)
ath11k_dp_reo_cmd_list_cleanup(ab);
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
spin_lock_bh(&dp->tx_ring[i].tx_idr_lock);
idr_for_each(&dp->tx_ring[i].txbuf_idr,
ath11k_dp_tx_pending_cleanup, ab);
@ -1046,7 +1046,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab)
size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
idr_init(&dp->tx_ring[i].txbuf_idr);
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
dp->tx_ring[i].tcl_data_ring_id = i;

View File

@ -170,6 +170,7 @@ struct ath11k_pdev_dp {
#define DP_BA_WIN_SZ_MAX 256
#define DP_TCL_NUM_RING_MAX 3
#define DP_TCL_NUM_RING_MAX_QCA6390 1
#define DP_IDLE_SCATTER_BUFS_MAX 16

View File

@ -4828,7 +4828,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
struct ieee80211_rx_status *rxs)
{
struct ath11k_base *ab = ar->ab;
struct sk_buff *msdu, *mpdu_buf, *prev_buf;
struct sk_buff *msdu, *prev_buf;
u32 wifi_hdr_len;
struct hal_rx_desc *rx_desc;
char *hdr_desc;
@ -4836,8 +4836,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
struct ieee80211_hdr_3addr *wh;
struct rx_attention *rx_attention;
mpdu_buf = NULL;
if (!head_msdu)
goto err_merge_fail;
@ -4920,12 +4918,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
return head_msdu;
err_merge_fail:
if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {
ath11k_dbg(ab, ATH11K_DBG_DATA,
"err_merge_fail mpdu_buf %pK", mpdu_buf);
/* Free the head buffer */
dev_kfree_skb_any(mpdu_buf);
}
return NULL;
}

View File

@ -115,11 +115,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
tcl_ring_sel:
tcl_ring_retry = false;
/* For some chip, it can only use tcl0 to tx */
if (ar->ab->hw_params.tcl_0_only)
ti.ring_id = 0;
else
ti.ring_id = ring_selector % DP_TCL_NUM_RING_MAX;
ti.ring_id = ring_selector % ab->hw_params.max_tx_ring;
ring_map |= BIT(ti.ring_id);
@ -131,7 +128,7 @@ 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(ab->hw_params.max_tx_ring) - 1)) {
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
return -ENOSPC;
}
@ -248,8 +245,8 @@ tcl_ring_sel:
* checking this ring earlier for each pkt tx.
* Restart ring selection if some rings are not checked yet.
*/
if (ring_map != (BIT(DP_TCL_NUM_RING_MAX) - 1) &&
!ar->ab->hw_params.tcl_0_only) {
if (ring_map != (BIT(ab->hw_params.max_tx_ring) - 1) &&
ab->hw_params.max_tx_ring > 1) {
tcl_ring_retry = true;
ring_selector++;
}

View File

@ -152,7 +152,6 @@ struct ath11k_hw_params {
bool rx_mac_buf_ring;
bool vdev_start_delay;
bool htt_peer_map_v2;
bool tcl_0_only;
struct {
u8 fft_sz;
@ -170,6 +169,7 @@ struct ath11k_hw_params {
bool supports_suspend;
u32 hal_desc_sz;
bool fix_l1ss;
u8 max_tx_ring;
};
struct ath11k_hw_ops {

View File

@ -5797,7 +5797,7 @@ err_vdev_del:
idr_for_each(&ar->txmgmt_idr,
ath11k_mac_vif_txmgmt_idr_remove, vif);
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock);
idr_for_each(&ab->dp.tx_ring[i].txbuf_idr,
ath11k_mac_vif_unref, vif);
@ -7081,7 +7081,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask))
ath11k_warn(ar->ab,
"could not update fixed rate settings to all peers due to mcs/nss incompaitiblity\n");
"could not update fixed rate settings to all peers due to mcs/nss incompatibility\n");
nss = min_t(u32, ar->num_tx_chains,
max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
ath11k_mac_max_vht_nss(vht_mcs_mask)),

View File

@ -855,7 +855,32 @@ static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab)
}
}
static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
static void ath11k_pci_msi_config(struct ath11k_pci *ab_pci, bool enable)
{
struct pci_dev *dev = ab_pci->pdev;
u16 control;
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
if (enable)
control |= PCI_MSI_FLAGS_ENABLE;
else
control &= ~PCI_MSI_FLAGS_ENABLE;
pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
}
static void ath11k_pci_msi_enable(struct ath11k_pci *ab_pci)
{
ath11k_pci_msi_config(ab_pci, true);
}
static void ath11k_pci_msi_disable(struct ath11k_pci *ab_pci)
{
ath11k_pci_msi_config(ab_pci, false);
}
static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)
{
struct ath11k_base *ab = ab_pci->ab;
const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
@ -876,6 +901,7 @@ static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
else
return num_vectors;
}
ath11k_pci_msi_disable(ab_pci);
msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
if (!msi_desc) {
@ -898,7 +924,7 @@ free_msi_vector:
return ret;
}
static void ath11k_pci_disable_msi(struct ath11k_pci *ab_pci)
static void ath11k_pci_free_msi(struct ath11k_pci *ab_pci)
{
pci_free_irq_vectors(ab_pci->pdev);
}
@ -1019,6 +1045,8 @@ static int ath11k_pci_power_up(struct ath11k_base *ab)
*/
ath11k_pci_aspm_disable(ab_pci);
ath11k_pci_msi_enable(ab_pci);
ret = ath11k_mhi_start(ab_pci);
if (ret) {
ath11k_err(ab, "failed to start mhi: %d\n", ret);
@ -1039,6 +1067,9 @@ static void ath11k_pci_power_down(struct ath11k_base *ab)
ath11k_pci_aspm_restore(ab_pci);
ath11k_pci_force_wake(ab_pci->ab);
ath11k_pci_msi_disable(ab_pci);
ath11k_mhi_stop(ab_pci);
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
ath11k_pci_sw_reset(ab_pci->ab, false);
@ -1263,7 +1294,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
goto err_pci_free_region;
}
ret = ath11k_pci_enable_msi(ab_pci);
ret = ath11k_pci_alloc_msi(ab_pci);
if (ret) {
ath11k_err(ab, "failed to enable msi: %d\n", ret);
goto err_pci_free_region;
@ -1317,7 +1348,7 @@ err_mhi_unregister:
ath11k_mhi_unregister(ab_pci);
err_pci_disable_msi:
ath11k_pci_disable_msi(ab_pci);
ath11k_pci_free_msi(ab_pci);
err_pci_free_region:
ath11k_pci_free_region(ab_pci);
@ -1348,7 +1379,7 @@ qmi_fail:
ath11k_mhi_unregister(ab_pci);
ath11k_pci_free_irq(ab);
ath11k_pci_disable_msi(ab_pci);
ath11k_pci_free_msi(ab_pci);
ath11k_pci_free_region(ab_pci);
ath11k_hal_srng_deinit(ab);

View File

@ -2135,7 +2135,6 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
fw_size = bd.len;
fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);

View File

@ -2371,6 +2371,8 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
if (tchan_info->psc_channel)
chan_info->info |= WMI_CHAN_INFO_PSC;
if (tchan_info->dfs_set)
chan_info->info |= WMI_CHAN_INFO_DFS;
chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
tchan_info->phy_mode);
@ -4065,8 +4067,8 @@ static int ath11k_wmi_tlv_mac_phy_caps_parse(struct ath11k_base *soc,
len = min_t(u16, len, sizeof(struct wmi_mac_phy_capabilities));
if (!svc_rdy_ext->n_mac_phy_caps) {
svc_rdy_ext->mac_phy_caps = kzalloc((svc_rdy_ext->tot_phy_id) * len,
GFP_ATOMIC);
svc_rdy_ext->mac_phy_caps = kcalloc(svc_rdy_ext->tot_phy_id,
len, GFP_ATOMIC);
if (!svc_rdy_ext->mac_phy_caps)
return -ENOMEM;
}
@ -4466,8 +4468,8 @@ static struct cur_reg_rule
struct cur_reg_rule *reg_rule_ptr;
u32 count;
reg_rule_ptr = kzalloc((num_reg_rules * sizeof(*reg_rule_ptr)),
GFP_ATOMIC);
reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr),
GFP_ATOMIC);
if (!reg_rule_ptr)
return NULL;

View File

@ -14,7 +14,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
{ \
struct ieee80211_hw *hw = dev_get_drvdata(dev); \
struct ath5k_hw *ah = hw->priv; \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
return sysfs_emit(buf, "%d\n", get); \
} \
\
static ssize_t ath5k_attr_store_##name(struct device *dev, \
@ -41,7 +41,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
{ \
struct ieee80211_hw *hw = dev_get_drvdata(dev); \
struct ath5k_hw *ah = hw->priv; \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
return sysfs_emit(buf, "%d\n", get); \
} \
static DEVICE_ATTR(name, 0444, ath5k_attr_show_##name, NULL)
@ -64,7 +64,7 @@ static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL);
return sysfs_emit(buf, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL);
}
static DEVICE_ATTR(noise_immunity_level_max, 0444,
ath5k_attr_show_noise_immunity_level_max, NULL);
@ -73,7 +73,7 @@ static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL);
return sysfs_emit(buf, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL);
}
static DEVICE_ATTR(firstep_level_max, 0444,
ath5k_attr_show_firstep_level_max, NULL);

View File

@ -749,9 +749,9 @@ static int read_file_misc(struct seq_file *file, void *data)
static int read_file_reset(struct seq_file *file, void *data)
{
struct ieee80211_hw *hw = dev_get_drvdata(file->private);
struct ath_softc *sc = hw->priv;
struct ath_softc *sc = file->private;
static const char * const reset_cause[__RESET_TYPE_MAX] = {
[RESET_TYPE_USER] = "User reset",
[RESET_TYPE_BB_HANG] = "Baseband Hang",
[RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog",
[RESET_TYPE_FATAL_INT] = "Fatal HW Error",
@ -779,6 +779,55 @@ static int read_file_reset(struct seq_file *file, void *data)
return 0;
}
static int open_file_reset(struct inode *inode, struct file *f)
{
return single_open(f, read_file_reset, inode->i_private);
}
static ssize_t write_file_reset(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file_inode(file)->i_private;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
unsigned long val;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
buf[len] = '\0';
if (kstrtoul(buf, 0, &val))
return -EINVAL;
if (val != 1)
return -EINVAL;
/* avoid rearming hw_reset_work on shutdown */
mutex_lock(&sc->mutex);
if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
mutex_unlock(&sc->mutex);
return -EBUSY;
}
ath9k_queue_reset(sc, RESET_TYPE_USER);
mutex_unlock(&sc->mutex);
return count;
}
static const struct file_operations fops_reset = {
.read = seq_read,
.write = write_file_reset,
.open = open_file_reset,
.owner = THIS_MODULE,
.llseek = seq_lseek,
.release = single_release,
};
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_status *ts, struct ath_txq *txq,
unsigned int flags)
@ -1393,8 +1442,8 @@ int ath9k_init_debug(struct ath_hw *ah)
read_file_queues);
debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
read_file_misc);
debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
read_file_reset);
debugfs_create_file("reset", 0600, sc->debug.debugfs_phy,
sc, &fops_reset);
ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);

View File

@ -39,6 +39,7 @@ struct fft_sample_tlv;
#endif
enum ath_reset_type {
RESET_TYPE_USER,
RESET_TYPE_BB_HANG,
RESET_TYPE_BB_WATCHDOG,
RESET_TYPE_FATAL_INT,

View File

@ -610,8 +610,8 @@ static int ath9k_nvmem_request_eeprom(struct ath_softc *sc)
/* devres manages the calibration values release on shutdown */
ah->nvmem_blob = (u16 *)devm_kmemdup(sc->dev, buf, len, GFP_KERNEL);
kfree(buf);
if (IS_ERR(ah->nvmem_blob))
return PTR_ERR(ah->nvmem_blob);
if (!ah->nvmem_blob)
return -ENOMEM;
ah->nvmem_blob_len = len;
ah->ah_flags &= ~AH_USE_EEPROM;
@ -1094,6 +1094,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
ARRAY_SIZE(ath9k_tpt_blink));
#endif
wiphy_read_of_freq_limits(hw->wiphy);
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)

View File

@ -533,8 +533,10 @@ irqreturn_t ath_isr(int irq, void *dev)
ath9k_debug_sync_cause(sc, sync_cause);
status &= ah->imask; /* discard unasked-for bits */
if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
ath9k_hw_kill_interrupts(sc->sc_ah);
return IRQ_HANDLED;
}
/*
* If there are no status bits set, then this interrupt was not

View File

@ -183,10 +183,12 @@ static void channel_detector_exit(struct dfs_pattern_detector *dpd,
if (cd == NULL)
return;
list_del(&cd->head);
for (i = 0; i < dpd->num_radar_types; i++) {
struct pri_detector *de = cd->detectors[i];
if (de != NULL)
de->exit(de);
if (cd->detectors) {
for (i = 0; i < dpd->num_radar_types; i++) {
struct pri_detector *de = cd->detectors[i];
if (de != NULL)
de->exit(de);
}
}
kfree(cd->detectors);
kfree(cd);