mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
ath.git patches for v6.11
ath12k * remove unsupported tx monitor handling * channel 2 in 6 GHz band support * Spatial Multiplexing Power Save (SMPS) in 6 GHz band support * multiple BSSID (MBSSID) and Enhanced Multi-BSSID Advertisements (EMA) support * dynamic VLAN support * add panic handler for resetting the firmware state ath10k * add qcom,no-msa-ready-indicator Device Tree property * LED support for various chipsets -----BEGIN PGP SIGNATURE----- iQFLBAABCgA1FiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmZgjPUXHHF1aWNfa3Zh bG9AcXVpY2luYy5jb20ACgkQbhckVSbrbZuVggf/SUE9KjLAt4HBg3ag6Kj5E6U+ c9Z2oCaqCpSMP2K48PMekSJuemr92gVvs1g7I1ksOsgIpFVsNozgnb9SQVDJn9Py kO53Vi0W7a3EoQ+zLv+YZGEguj5TUN5ijj4W6zG9AInNwDKbz4vcaART70WUbjtN maxBnxMvSnCcHjfnam2GfDd5nK+Te/DrOZqIMxMWFlKOQLmNLfFWxdN6MHCNiBYf 1v3i4r6RkwFWLsafcMoDJJc5AbEK38Gp1h5/QeGZo3nCokknW8e7s7nDFifoOVSQ k1AiWIIy8zj0HixAFfUwON+APdAWNENJiIoUMIt8j5dAcxoLa3fMFYM16qClew== =8QAR -----END PGP SIGNATURE----- Merge tag 'ath-next-20240605' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath ath.git patches for v6.11 ath12k * remove unsupported tx monitor handling * channel 2 in 6 GHz band support * Spatial Multiplexing Power Save (SMPS) in 6 GHz band support * multiple BSSID (MBSSID) and Enhanced Multi-BSSID Advertisements (EMA) support * dynamic VLAN support * add panic handler for resetting the firmware state ath10k * add qcom,no-msa-ready-indicator Device Tree property * LED support for various chipsets
This commit is contained in:
commit
a46300b1b0
|
|
@ -128,6 +128,11 @@ properties:
|
|||
Whether to skip executing an SCM call that reassigns the memory
|
||||
region ownership.
|
||||
|
||||
qcom,no-msa-ready-indicator:
|
||||
type: boolean
|
||||
description:
|
||||
Don't wait for MSA_READY indicator to complete init.
|
||||
|
||||
qcom,smem-states:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: State bits used by the AP to signal the WLAN Q6.
|
||||
|
|
|
|||
|
|
@ -265,15 +265,6 @@ allOf:
|
|||
|
||||
examples:
|
||||
- |
|
||||
|
||||
q6v5_wcss: remoteproc@cd00000 {
|
||||
compatible = "qcom,ipq8074-wcss-pil";
|
||||
reg = <0xcd00000 0x4040>,
|
||||
<0x4ab000 0x20>;
|
||||
reg-names = "qdsp6",
|
||||
"rmb";
|
||||
};
|
||||
|
||||
wifi0: wifi@c000000 {
|
||||
compatible = "qcom,ipq8074-wifi";
|
||||
reg = <0xc000000 0x2000000>;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ config ATH10K_DEBUGFS
|
|||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
config ATH10K_LEDS
|
||||
bool
|
||||
depends on ATH10K
|
||||
depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
|
||||
default y
|
||||
|
||||
config ATH10K_SPECTRAL
|
||||
bool "Atheros ath10k spectral scan support"
|
||||
depends on ATH10K_DEBUGFS
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += spectral.o
|
|||
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
|
||||
ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
||||
ath10k_core-$(CONFIG_ATH10K_LEDS) += leds.o
|
||||
ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o
|
||||
ath10k_core-$(CONFIG_PM) += wow.o
|
||||
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "testmode.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "coredump.h"
|
||||
#include "leds.h"
|
||||
|
||||
unsigned int ath10k_debug_mask;
|
||||
EXPORT_SYMBOL(ath10k_debug_mask);
|
||||
|
|
@ -68,6 +69,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca988x hw2.0",
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 1,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
|
|
@ -108,6 +110,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca988x hw2.0 ubiquiti",
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 0,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
|
|
@ -149,6 +152,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9887 hw1.0",
|
||||
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 1,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
|
|
@ -190,6 +194,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca6174 hw3.2 sdio",
|
||||
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 19,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -226,6 +231,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca6164 hw2.1",
|
||||
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -266,6 +272,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca6174 hw2.1",
|
||||
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -306,6 +313,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca6174 hw3.0",
|
||||
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -346,6 +354,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca6174 hw3.2",
|
||||
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -390,6 +399,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca99x0 hw2.0",
|
||||
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 17,
|
||||
.otp_exe_param = 0x00000700,
|
||||
.continuous_frag_desc = true,
|
||||
.cck_rate_map_rev2 = true,
|
||||
|
|
@ -436,6 +446,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9984/qca9994 hw1.0",
|
||||
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 17,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
.otp_exe_param = 0x00000700,
|
||||
.continuous_frag_desc = true,
|
||||
|
|
@ -488,6 +499,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9888 hw2.0",
|
||||
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 17,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
.otp_exe_param = 0x00000700,
|
||||
.continuous_frag_desc = true,
|
||||
|
|
@ -538,6 +550,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9377 hw1.0",
|
||||
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -578,6 +591,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9377 hw1.1",
|
||||
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 6,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -620,6 +634,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca9377 hw1.1 sdio",
|
||||
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 19,
|
||||
.led_pin = 0,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
|
@ -653,6 +668,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca4019 hw1.0",
|
||||
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.led_pin = 0,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
.otp_exe_param = 0x0010000,
|
||||
.continuous_frag_desc = true,
|
||||
|
|
@ -698,6 +714,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.dev_id = 0,
|
||||
.bus = ATH10K_BUS_SNOC,
|
||||
.name = "wcn3990 hw1.0",
|
||||
.led_pin = 0,
|
||||
.continuous_frag_desc = true,
|
||||
.tx_chain_mask = 0x7,
|
||||
.rx_chain_mask = 0x7,
|
||||
|
|
@ -3224,6 +3241,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
status = ath10k_leds_start(ar);
|
||||
if (status)
|
||||
goto err_hif_stop;
|
||||
|
||||
return 0;
|
||||
|
||||
err_hif_stop:
|
||||
|
|
@ -3482,9 +3503,18 @@ static void ath10k_core_register_work(struct work_struct *work)
|
|||
goto err_spectral_destroy;
|
||||
}
|
||||
|
||||
status = ath10k_leds_register(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar, "could not register leds: %d\n",
|
||||
status);
|
||||
goto err_thermal_unregister;
|
||||
}
|
||||
|
||||
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
|
||||
return;
|
||||
|
||||
err_thermal_unregister:
|
||||
ath10k_thermal_unregister(ar);
|
||||
err_spectral_destroy:
|
||||
ath10k_spectral_destroy(ar);
|
||||
err_debug_destroy:
|
||||
|
|
@ -3520,6 +3550,8 @@ void ath10k_core_unregister(struct ath10k *ar)
|
|||
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
return;
|
||||
|
||||
ath10k_leds_unregister(ar);
|
||||
|
||||
ath10k_thermal_unregister(ar);
|
||||
/* Stop spectral before unregistering from mac80211 to remove the
|
||||
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/uuid.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include "htt.h"
|
||||
#include "htc.h"
|
||||
|
|
@ -1258,6 +1259,13 @@ struct ath10k {
|
|||
bool utf_monitor;
|
||||
} testmode;
|
||||
|
||||
struct {
|
||||
struct gpio_led wifi_led;
|
||||
struct led_classdev cdev;
|
||||
char label[48];
|
||||
u32 gpio_state_pin;
|
||||
} leds;
|
||||
|
||||
struct {
|
||||
/* protected by data_lock */
|
||||
u32 rx_crc_err_drop;
|
||||
|
|
|
|||
|
|
@ -512,6 +512,7 @@ struct ath10k_hw_params {
|
|||
const char *name;
|
||||
u32 patch_load_addr;
|
||||
int uart_pin;
|
||||
int led_pin;
|
||||
u32 otp_exe_param;
|
||||
|
||||
/* Type of hw cycle counter wraparound logic, for more info
|
||||
|
|
|
|||
90
drivers/net/wireless/ath/ath10k/leds.c
Normal file
90
drivers/net/wireless/ath/ath10k/leds.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "wmi.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
#include "leds.h"
|
||||
|
||||
static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct ath10k *ar = container_of(led_cdev, struct ath10k,
|
||||
leds.cdev);
|
||||
struct gpio_led *led = &ar->leds.wifi_led;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON)
|
||||
goto out;
|
||||
|
||||
ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low;
|
||||
ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin);
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_leds_start(struct ath10k *ar)
|
||||
{
|
||||
if (ar->hw_params.led_pin == 0)
|
||||
/* leds not supported */
|
||||
return 0;
|
||||
|
||||
/* under some circumstances, the gpio pin gets reconfigured
|
||||
* to default state by the firmware, so we need to
|
||||
* reconfigure it this behaviour has only ben seen on
|
||||
* QCA9984 and QCA99XX devices so far
|
||||
*/
|
||||
ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0,
|
||||
WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE);
|
||||
ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_leds_register(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ar->hw_params.led_pin == 0)
|
||||
/* leds not supported */
|
||||
return 0;
|
||||
|
||||
snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
ar->leds.wifi_led.active_low = 1;
|
||||
ar->leds.wifi_led.gpio = ar->hw_params.led_pin;
|
||||
ar->leds.wifi_led.name = ar->leds.label;
|
||||
ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
|
||||
|
||||
ar->leds.cdev.name = ar->leds.label;
|
||||
ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
|
||||
ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
|
||||
|
||||
ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_leds_unregister(struct ath10k *ar)
|
||||
{
|
||||
if (ar->hw_params.led_pin == 0)
|
||||
/* leds not supported */
|
||||
return;
|
||||
|
||||
led_classdev_unregister(&ar->leds.cdev);
|
||||
}
|
||||
|
||||
34
drivers/net/wireless/ath/ath10k/leds.h
Normal file
34
drivers/net/wireless/ath/ath10k/leds.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LEDS_H_
|
||||
#define _LEDS_H_
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#ifdef CONFIG_ATH10K_LEDS
|
||||
void ath10k_leds_unregister(struct ath10k *ar);
|
||||
int ath10k_leds_start(struct ath10k *ar);
|
||||
int ath10k_leds_register(struct ath10k *ar);
|
||||
#else
|
||||
static inline void ath10k_leds_unregister(struct ath10k *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath10k_leds_start(struct ath10k *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ath10k_leds_register(struct ath10k *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* _LEDS_H_ */
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include "wmi-tlv.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "wow.h"
|
||||
#include "leds.h"
|
||||
|
||||
/*********/
|
||||
/* Rates */
|
||||
|
|
|
|||
|
|
@ -1040,6 +1040,10 @@ static void ath10k_qmi_driver_event_work(struct work_struct *work)
|
|||
switch (event->type) {
|
||||
case ATH10K_QMI_EVENT_SERVER_ARRIVE:
|
||||
ath10k_qmi_event_server_arrive(qmi);
|
||||
if (qmi->no_msa_ready_indicator) {
|
||||
ath10k_info(ar, "qmi not waiting for msa_ready indicator");
|
||||
ath10k_qmi_event_msa_ready(qmi);
|
||||
}
|
||||
break;
|
||||
case ATH10K_QMI_EVENT_SERVER_EXIT:
|
||||
ath10k_qmi_event_server_exit(qmi);
|
||||
|
|
@ -1048,6 +1052,10 @@ static void ath10k_qmi_driver_event_work(struct work_struct *work)
|
|||
ath10k_qmi_event_fw_ready_ind(qmi);
|
||||
break;
|
||||
case ATH10K_QMI_EVENT_MSA_READY_IND:
|
||||
if (qmi->no_msa_ready_indicator) {
|
||||
ath10k_warn(ar, "qmi unexpected msa_ready indicator");
|
||||
break;
|
||||
}
|
||||
ath10k_qmi_event_msa_ready(qmi);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1077,6 +1085,9 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
|
|||
if (of_property_read_bool(dev->of_node, "qcom,msa-fixed-perm"))
|
||||
qmi->msa_fixed_perm = true;
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "qcom,no-msa-ready-indicator"))
|
||||
qmi->no_msa_ready_indicator = true;
|
||||
|
||||
ret = qmi_handle_init(&qmi->qmi_hdl,
|
||||
WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
|
||||
&ath10k_qmi_ops, qmi_msg_handler);
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ struct ath10k_qmi {
|
|||
char fw_build_timestamp[MAX_TIMESTAMP_LEN + 1];
|
||||
struct ath10k_qmi_cal_data cal_data[MAX_NUM_CAL_V01];
|
||||
bool msa_fixed_perm;
|
||||
bool no_msa_ready_indicator;
|
||||
enum ath10k_qmi_state state;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,10 @@ struct wmi_ops {
|
|||
const struct wmi_bb_timing_cfg_arg *arg);
|
||||
struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar,
|
||||
const struct wmi_per_peer_per_tid_cfg_arg *arg);
|
||||
struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
|
||||
u32 input, u32 pull_type, u32 intr_mode);
|
||||
|
||||
struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
|
||||
};
|
||||
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
|
|
@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *ar,
|
|||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
|
||||
}
|
||||
|
||||
static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num,
|
||||
u32 input, u32 pull_type, u32 intr_mode)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_gpio_config)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid);
|
||||
}
|
||||
|
||||
static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_gpio_config)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4606,6 +4606,8 @@ static const struct wmi_ops wmi_tlv_ops = {
|
|||
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
||||
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
||||
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
||||
/* .gen_gpio_config not implemented */
|
||||
/* .gen_gpio_output not implemented */
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
|
|
|
|||
|
|
@ -7493,6 +7493,49 @@ ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
|
|||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
|
||||
u32 gpio_num, u32 input,
|
||||
u32 pull_type, u32 intr_mode)
|
||||
{
|
||||
struct wmi_gpio_config_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cmd = (struct wmi_gpio_config_cmd *)skb->data;
|
||||
cmd->pull_type = __cpu_to_le32(pull_type);
|
||||
cmd->gpio_num = __cpu_to_le32(gpio_num);
|
||||
cmd->input = __cpu_to_le32(input);
|
||||
cmd->intr_mode = __cpu_to_le32(intr_mode);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
|
||||
gpio_num, input, pull_type, intr_mode);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
|
||||
u32 gpio_num, u32 set)
|
||||
{
|
||||
struct wmi_gpio_output_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cmd = (struct wmi_gpio_output_cmd *)skb->data;
|
||||
cmd->gpio_num = __cpu_to_le32(gpio_num);
|
||||
cmd->set = __cpu_to_le32(set);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
|
||||
gpio_num, set);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode)
|
||||
|
|
@ -9157,6 +9200,9 @@ static const struct wmi_ops wmi_ops = {
|
|||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
|
|
@ -9227,6 +9273,8 @@ static const struct wmi_ops wmi_10_1_ops = {
|
|||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
|
|
@ -9299,6 +9347,8 @@ static const struct wmi_ops wmi_10_2_ops = {
|
|||
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_pdev_enable_adaptive_cca not implemented */
|
||||
};
|
||||
|
||||
|
|
@ -9370,6 +9420,8 @@ static const struct wmi_ops wmi_10_2_4_ops = {
|
|||
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
||||
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
||||
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
|
||||
.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
|
|
@ -9451,6 +9503,8 @@ static const struct wmi_ops wmi_10_4_ops = {
|
|||
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
|
||||
.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
};
|
||||
|
||||
int ath10k_wmi_attach(struct ath10k *ar)
|
||||
|
|
|
|||
|
|
@ -3034,6 +3034,41 @@ enum wmi_10_4_feature_mask {
|
|||
|
||||
};
|
||||
|
||||
/* WMI_GPIO_CONFIG_CMDID */
|
||||
enum {
|
||||
WMI_GPIO_PULL_NONE,
|
||||
WMI_GPIO_PULL_UP,
|
||||
WMI_GPIO_PULL_DOWN,
|
||||
};
|
||||
|
||||
enum {
|
||||
WMI_GPIO_INTTYPE_DISABLE,
|
||||
WMI_GPIO_INTTYPE_RISING_EDGE,
|
||||
WMI_GPIO_INTTYPE_FALLING_EDGE,
|
||||
WMI_GPIO_INTTYPE_BOTH_EDGE,
|
||||
WMI_GPIO_INTTYPE_LEVEL_LOW,
|
||||
WMI_GPIO_INTTYPE_LEVEL_HIGH
|
||||
};
|
||||
|
||||
/* WMI_GPIO_CONFIG_CMDID */
|
||||
struct wmi_gpio_config_cmd {
|
||||
__le32 gpio_num; /* GPIO number to be setup */
|
||||
__le32 input; /* 0 - Output/ 1 - Input */
|
||||
__le32 pull_type; /* Pull type defined above */
|
||||
__le32 intr_mode; /* Interrupt mode defined above (Input) */
|
||||
} __packed;
|
||||
|
||||
/* WMI_GPIO_OUTPUT_CMDID */
|
||||
struct wmi_gpio_output_cmd {
|
||||
__le32 gpio_num; /* GPIO number to be setup */
|
||||
__le32 set; /* Set the GPIO pin*/
|
||||
} __packed;
|
||||
|
||||
/* WMI_GPIO_INPUT_EVENTID */
|
||||
struct wmi_gpio_input_event {
|
||||
__le32 gpio_num; /* GPIO number which changed state */
|
||||
} __packed;
|
||||
|
||||
struct wmi_ext_resource_config_10_4_cmd {
|
||||
/* contains enum wmi_host_platform_type */
|
||||
__le32 host_platform_config;
|
||||
|
|
|
|||
|
|
@ -954,6 +954,36 @@ static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_ahb_ce_remap(struct ath11k_base *ab)
|
||||
{
|
||||
const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
|
||||
struct platform_device *pdev = ab->pdev;
|
||||
|
||||
if (!ce_remap) {
|
||||
/* no separate CE register space */
|
||||
ab->mem_ce = ab->mem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ce register space is moved out of wcss unlike ipq8074 or ipq6018
|
||||
* and the space is not contiguous, hence remapping the CE registers
|
||||
* to a new space for accessing them.
|
||||
*/
|
||||
ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
|
||||
if (!ab->mem_ce) {
|
||||
dev_err(&pdev->dev, "ce ioremap error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath11k_ahb_ce_unmap(struct ath11k_base *ab)
|
||||
{
|
||||
if (ab->hw_params.ce_remap)
|
||||
iounmap(ab->mem_ce);
|
||||
}
|
||||
|
||||
static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
|
||||
|
|
@ -1146,25 +1176,13 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto err_core_free;
|
||||
|
||||
ab->mem_ce = ab->mem;
|
||||
|
||||
if (ab->hw_params.ce_remap) {
|
||||
const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
|
||||
/* ce register space is moved out of wcss unlike ipq8074 or ipq6018
|
||||
* and the space is not contiguous, hence remapping the CE registers
|
||||
* to a new space for accessing them.
|
||||
*/
|
||||
ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
|
||||
if (!ab->mem_ce) {
|
||||
dev_err(&pdev->dev, "ce ioremap error\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_core_free;
|
||||
}
|
||||
}
|
||||
ret = ath11k_ahb_ce_remap(ab);
|
||||
if (ret)
|
||||
goto err_core_free;
|
||||
|
||||
ret = ath11k_ahb_fw_resources_init(ab);
|
||||
if (ret)
|
||||
goto err_core_free;
|
||||
goto err_ce_unmap;
|
||||
|
||||
ret = ath11k_ahb_setup_smp2p_handle(ab);
|
||||
if (ret)
|
||||
|
|
@ -1216,6 +1234,9 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
|
|||
err_fw_deinit:
|
||||
ath11k_ahb_fw_resource_deinit(ab);
|
||||
|
||||
err_ce_unmap:
|
||||
ath11k_ahb_ce_unmap(ab);
|
||||
|
||||
err_core_free:
|
||||
ath11k_core_free(ab);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
|
@ -1248,9 +1269,7 @@ static void ath11k_ahb_free_resources(struct ath11k_base *ab)
|
|||
ath11k_ahb_release_smp2p_handle(ab);
|
||||
ath11k_ahb_fw_resource_deinit(ab);
|
||||
ath11k_ce_free_pipes(ab);
|
||||
|
||||
if (ab->hw_params.ce_remap)
|
||||
iounmap(ab->mem_ce);
|
||||
ath11k_ahb_ce_unmap(ab);
|
||||
|
||||
ath11k_core_free(ab);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_CE_H
|
||||
|
|
@ -146,7 +146,7 @@ struct ath11k_ce_ring {
|
|||
/* Host address space */
|
||||
void *base_addr_owner_space_unaligned;
|
||||
/* CE address space */
|
||||
u32 base_addr_ce_space_unaligned;
|
||||
dma_addr_t base_addr_ce_space_unaligned;
|
||||
|
||||
/* Actual start of descriptors.
|
||||
* Aligned to descriptor-size boundary.
|
||||
|
|
@ -156,7 +156,7 @@ struct ath11k_ce_ring {
|
|||
void *base_addr_owner_space;
|
||||
|
||||
/* CE address space */
|
||||
u32 base_addr_ce_space;
|
||||
dma_addr_t base_addr_ce_space;
|
||||
|
||||
/* HAL ring id */
|
||||
u32 hal_ring_id;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = false,
|
||||
.rxdma1_enable = true,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
|
|
@ -148,7 +148,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = false,
|
||||
.rxdma1_enable = true,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
|
|
@ -232,7 +232,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = true,
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 2,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
|
|
@ -320,7 +320,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.svc_to_ce_map_len = 18,
|
||||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.rxdma1_enable = true,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
|
|
@ -404,7 +404,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = true,
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 2,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
|
|
@ -492,7 +492,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.svc_to_ce_map_len = 14,
|
||||
.single_pdev_only = true,
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 2,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
|
|
@ -580,7 +580,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = true,
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
|
|
@ -673,7 +673,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
|
||||
.ce_remap = &ath11k_ce_remap_ipq5018,
|
||||
.rxdma1_enable = true,
|
||||
.num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
|
||||
.num_rxdma_per_pdev = RXDMA_PER_PDEV_5018,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
|
|
@ -744,7 +744,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
||||
.single_pdev_only = true,
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 2,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
|
|
@ -1009,6 +1009,16 @@ int ath11k_core_resume(struct ath11k_base *ab)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (ab->hw_params.current_cc_support &&
|
||||
ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
|
||||
ret = ath11k_reg_set_cc(ar);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to set country code during resume: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ath11k_dp_rx_pktlog_start(ab);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
|
||||
|
|
@ -1801,7 +1811,7 @@ static int ath11k_core_start(struct ath11k_base *ab)
|
|||
}
|
||||
|
||||
/* put hardware to DBS mode */
|
||||
if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) {
|
||||
if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1) {
|
||||
ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
|
||||
|
|
@ -1978,23 +1988,20 @@ static void ath11k_update_11d(struct work_struct *work)
|
|||
struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
|
||||
struct ath11k *ar;
|
||||
struct ath11k_pdev *pdev;
|
||||
struct wmi_set_current_country_params set_current_param = {};
|
||||
int ret, i;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
|
||||
set_current_param.alpha2[0],
|
||||
set_current_param.alpha2[1]);
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
|
||||
memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
|
||||
ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
memcpy(&ar->alpha2, &ab->new_alpha2, 2);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c for pdev %d\n",
|
||||
ar->alpha2[0], ar->alpha2[1], i);
|
||||
|
||||
ret = ath11k_reg_set_cc(ar);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab,
|
||||
"pdev id %d failed set current country code: %d\n",
|
||||
|
|
|
|||
|
|
@ -668,7 +668,7 @@ static ssize_t ath11k_write_extd_rx_stats(struct file *file,
|
|||
|
||||
ar->debug.rx_filter = tlv_filter.rx_filter;
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
|
|
@ -1112,7 +1112,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
}
|
||||
|
||||
/* Clear rx filter set for monitor mode and rx status */
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
|
|
@ -1171,7 +1171,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
HTT_RX_FP_DATA_FILTER_FLASG3;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
ar->dp.mac_id + i,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <crypto/hash.h>
|
||||
|
|
@ -830,8 +830,8 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|||
|
||||
if (ab->hw_params.ring_mask->rx_mon_status[grp_id]) {
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
|
||||
int id = i * ab->hw_params.num_rxmda_per_pdev + j;
|
||||
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
|
||||
int id = i * ab->hw_params.num_rxdma_per_pdev + j;
|
||||
|
||||
if (ab->hw_params.ring_mask->rx_mon_status[grp_id] &
|
||||
BIT(id)) {
|
||||
|
|
@ -853,8 +853,8 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|||
ath11k_dp_process_reo_status(ab);
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
|
||||
int id = i * ab->hw_params.num_rxmda_per_pdev + j;
|
||||
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
|
||||
int id = i * ab->hw_params.num_rxdma_per_pdev + j;
|
||||
|
||||
if (ab->hw_params.ring_mask->rxdma2host[grp_id] & BIT(id)) {
|
||||
work_done = ath11k_dp_process_rxdma_err(ab, id, budget);
|
||||
|
|
@ -913,7 +913,7 @@ void ath11k_dp_pdev_pre_alloc(struct ath11k_base *ab)
|
|||
spin_lock_init(&dp->rx_refill_buf_ring.idr_lock);
|
||||
atomic_set(&dp->num_tx_pending, 0);
|
||||
init_waitqueue_head(&dp->tx_empty_waitq);
|
||||
for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
|
||||
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
|
||||
idr_init(&dp->rx_mon_status_refill_ring[j].bufs_idr);
|
||||
spin_lock_init(&dp->rx_mon_status_refill_ring[j].idr_lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
|
|
@ -311,7 +311,7 @@ static void ath11k_dp_service_mon_ring(struct timer_list *t)
|
|||
struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++)
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)
|
||||
ath11k_dp_rx_process_mon_rings(ab, i, NULL, DP_MON_SERVICE_BUDGET);
|
||||
|
||||
mod_timer(&ab->mon_reap_timer, jiffies +
|
||||
|
|
@ -324,7 +324,7 @@ static int ath11k_dp_purge_mon_ring(struct ath11k_base *ab)
|
|||
unsigned long timeout = jiffies + msecs_to_jiffies(DP_MON_PURGE_TIMEOUT_MS);
|
||||
|
||||
do {
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++)
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)
|
||||
reaped += ath11k_dp_rx_process_mon_rings(ab, i,
|
||||
NULL,
|
||||
DP_MON_SERVICE_BUDGET);
|
||||
|
|
@ -468,7 +468,7 @@ static int ath11k_dp_rxdma_pdev_buf_free(struct ath11k *ar)
|
|||
rx_ring = &dp->rxdma_mon_buf_ring;
|
||||
ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
rx_ring = &dp->rx_mon_status_refill_ring[i];
|
||||
ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);
|
||||
}
|
||||
|
|
@ -506,7 +506,7 @@ static int ath11k_dp_rxdma_pdev_buf_setup(struct ath11k *ar)
|
|||
ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_BUF);
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
rx_ring = &dp->rx_mon_status_refill_ring[i];
|
||||
ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_STATUS);
|
||||
}
|
||||
|
|
@ -522,7 +522,7 @@ static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar)
|
|||
|
||||
ath11k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring);
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
if (ab->hw_params.rx_mac_buf_ring)
|
||||
ath11k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]);
|
||||
|
||||
|
|
@ -585,7 +585,7 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)
|
|||
}
|
||||
|
||||
if (ar->ab->hw_params.rx_mac_buf_ring) {
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ret = ath11k_dp_srng_setup(ar->ab,
|
||||
&dp->rx_mac_buf_ring[i],
|
||||
HAL_RXDMA_BUF, 1,
|
||||
|
|
@ -598,7 +598,7 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring[i],
|
||||
HAL_RXDMA_DST, 0, dp->mac_id + i,
|
||||
DP_RXDMA_ERR_DST_RING_SIZE);
|
||||
|
|
@ -608,7 +608,7 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring;
|
||||
ret = ath11k_dp_srng_setup(ar->ab,
|
||||
srng,
|
||||
|
|
@ -2990,11 +2990,52 @@ ath11k_dp_rx_mon_update_status_buf_state(struct ath11k_mon_data *pmon,
|
|||
}
|
||||
}
|
||||
|
||||
static enum dp_mon_status_buf_state
|
||||
ath11k_dp_rx_mon_buf_done(struct ath11k_base *ab, struct hal_srng *srng,
|
||||
struct dp_rxdma_ring *rx_ring)
|
||||
{
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct hal_tlv_hdr *tlv;
|
||||
struct sk_buff *skb;
|
||||
void *status_desc;
|
||||
dma_addr_t paddr;
|
||||
u32 cookie;
|
||||
int buf_id;
|
||||
u8 rbm;
|
||||
|
||||
status_desc = ath11k_hal_srng_src_next_peek(ab, srng);
|
||||
if (!status_desc)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
ath11k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm);
|
||||
|
||||
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie);
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
skb = idr_find(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
if (!skb)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
rxcb = ATH11K_SKB_RXCB(skb);
|
||||
dma_sync_single_for_cpu(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
tlv = (struct hal_tlv_hdr *)skb->data;
|
||||
if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
return DP_MON_STATUS_REPLINISH;
|
||||
}
|
||||
|
||||
static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
|
||||
int *budget, struct sk_buff_head *skb_list)
|
||||
{
|
||||
struct ath11k *ar;
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
enum dp_mon_status_buf_state reap_status;
|
||||
struct ath11k_pdev_dp *dp;
|
||||
struct dp_rxdma_ring *rx_ring;
|
||||
struct ath11k_mon_data *pmon;
|
||||
|
|
@ -3057,15 +3098,38 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
|
|||
ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n",
|
||||
FIELD_GET(HAL_TLV_HDR_TAG,
|
||||
tlv->tl), buf_id);
|
||||
/* If done status is missing, hold onto status
|
||||
* ring until status is done for this status
|
||||
* ring buffer.
|
||||
* Keep HP in mon_status_ring unchanged,
|
||||
* and break from here.
|
||||
* Check status for same buffer for next time
|
||||
/* RxDMA status done bit might not be set even
|
||||
* though tp is moved by HW.
|
||||
*/
|
||||
pmon->buf_state = DP_MON_STATUS_NO_DMA;
|
||||
break;
|
||||
|
||||
/* If done status is missing:
|
||||
* 1. As per MAC team's suggestion,
|
||||
* when HP + 1 entry is peeked and if DMA
|
||||
* is not done and if HP + 2 entry's DMA done
|
||||
* is set. skip HP + 1 entry and
|
||||
* start processing in next interrupt.
|
||||
* 2. If HP + 2 entry's DMA done is not set,
|
||||
* poll onto HP + 1 entry DMA done to be set.
|
||||
* Check status for same buffer for next time
|
||||
* dp_rx_mon_status_srng_process
|
||||
*/
|
||||
|
||||
reap_status = ath11k_dp_rx_mon_buf_done(ab, srng,
|
||||
rx_ring);
|
||||
if (reap_status == DP_MON_STATUS_NO_DMA)
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
idr_remove(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
pmon->buf_state = DP_MON_STATUS_REPLINISH;
|
||||
goto move_next;
|
||||
}
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
|
|
@ -4391,7 +4455,7 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id)
|
|||
}
|
||||
|
||||
if (ab->hw_params.rx_mac_buf_ring) {
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
mac_id + i, HAL_RXDMA_BUF);
|
||||
|
|
@ -4403,7 +4467,7 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rxdma_err_dst_ring[i].ring_id;
|
||||
ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
mac_id + i, HAL_RXDMA_DST);
|
||||
|
|
@ -4443,7 +4507,7 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id)
|
|||
}
|
||||
|
||||
config_refill_ring:
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id + i,
|
||||
HAL_RXDMA_MONITOR_STATUS);
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ int ath11k_dp_tx_htt_h2t_ppdu_stats_req(struct ath11k *ar, u32 mask)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
skb = ath11k_htc_alloc_skb(ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1218,7 +1218,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
|
|||
&tlv_filter);
|
||||
} else if (!reset) {
|
||||
/* set in monitor mode only */
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
|
||||
dp->mac_id + i,
|
||||
|
|
@ -1231,7 +1231,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
if (!reset) {
|
||||
tlv_filter.rx_filter =
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/dma-mapping.h>
|
||||
#include "hal_tx.h"
|
||||
|
|
@ -796,6 +796,20 @@ u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab,
|
|||
return desc;
|
||||
}
|
||||
|
||||
u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, struct hal_srng *srng)
|
||||
{
|
||||
u32 next_hp;
|
||||
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
||||
next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size;
|
||||
|
||||
if (next_hp != srng->u.src_ring.cached_tp)
|
||||
return srng->ring_base_vaddr + next_hp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng)
|
||||
{
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
|
|
|||
|
|
@ -947,6 +947,8 @@ u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng);
|
|||
int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng,
|
||||
bool sync_hw_ptr);
|
||||
u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng);
|
||||
u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
u32 *ath11k_hal_srng_src_reap_next(struct ath11k_base *ab,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_HW_H
|
||||
|
|
@ -167,7 +167,7 @@ struct ath11k_hw_params {
|
|||
bool single_pdev_only;
|
||||
|
||||
bool rxdma1_enable;
|
||||
int num_rxmda_per_pdev;
|
||||
int num_rxdma_per_pdev;
|
||||
bool rx_mac_buf_ring;
|
||||
bool vdev_start_delay;
|
||||
bool htt_peer_map_v2;
|
||||
|
|
|
|||
|
|
@ -6108,7 +6108,7 @@ static int ath11k_mac_config_mon_status_default(struct ath11k *ar, bool enable)
|
|||
tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
|
||||
ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
|
||||
ar->dp.mac_id + i,
|
||||
|
|
@ -8790,12 +8790,8 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
ieee80211_wake_queues(ar->hw);
|
||||
|
||||
if (ar->ab->hw_params.current_cc_support &&
|
||||
ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
|
||||
struct wmi_set_current_country_params set_current_param = {};
|
||||
|
||||
memcpy(&set_current_param.alpha2, ar->alpha2, 2);
|
||||
ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
|
||||
}
|
||||
ar->alpha2[0] != 0 && ar->alpha2[1] != 0)
|
||||
ath11k_reg_set_cc(ar);
|
||||
|
||||
if (ab->is_reset) {
|
||||
recovery_count = atomic_inc_return(&ab->recovery_count);
|
||||
|
|
@ -9030,7 +9026,6 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,
|
|||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct inet6_ifaddr *ifa6;
|
||||
struct ifacaddr6 *ifaca6;
|
||||
struct list_head *p;
|
||||
u32 count, scope;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "op ipv6 changed\n");
|
||||
|
|
@ -9046,11 +9041,10 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,
|
|||
memcpy(offload->mac_addr, vif->addr, ETH_ALEN);
|
||||
|
||||
/* get unicast address */
|
||||
list_for_each(p, &idev->addr_list) {
|
||||
list_for_each_entry(ifa6, &idev->addr_list, if_list) {
|
||||
if (count >= ATH11K_IPV6_MAX_COUNT)
|
||||
goto generate;
|
||||
|
||||
ifa6 = list_entry(p, struct inet6_ifaddr, if_list);
|
||||
if (ifa6->flags & IFA_F_DADFAILED)
|
||||
continue;
|
||||
scope = ipv6_addr_src_scope(&ifa6->addr);
|
||||
|
|
@ -10239,11 +10233,8 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
|||
}
|
||||
|
||||
if (ab->hw_params.current_cc_support && ab->new_alpha2[0]) {
|
||||
struct wmi_set_current_country_params set_current_param = {};
|
||||
|
||||
memcpy(&set_current_param.alpha2, ab->new_alpha2, 2);
|
||||
memcpy(&ar->alpha2, ab->new_alpha2, 2);
|
||||
ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
|
||||
ret = ath11k_reg_set_cc(ar);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab,
|
||||
"failed set cc code for mac register: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -2293,7 +2293,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
|
|||
struct qmi_txn txn;
|
||||
const u8 *temp = data;
|
||||
void __iomem *bdf_addr = NULL;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
u32 remaining = len;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
|
|
@ -49,7 +49,6 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
|||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct wmi_init_country_params init_country_param;
|
||||
struct wmi_set_current_country_params set_current_param = {};
|
||||
struct ath11k *ar = hw->priv;
|
||||
int ret;
|
||||
|
||||
|
|
@ -83,9 +82,8 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
|||
* reg info
|
||||
*/
|
||||
if (ar->ab->hw_params.current_cc_support) {
|
||||
memcpy(&set_current_param.alpha2, request->alpha2, 2);
|
||||
memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
|
||||
ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
|
||||
memcpy(&ar->alpha2, request->alpha2, 2);
|
||||
ret = ath11k_reg_set_cc(ar);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab,
|
||||
"failed set current country code: %d\n", ret);
|
||||
|
|
@ -878,7 +876,7 @@ int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
|
|||
ath11k_reg_reset_info(reg_info);
|
||||
|
||||
if (ab->hw_params.single_pdev_only &&
|
||||
pdev_idx < ab->hw_params.num_rxmda_per_pdev)
|
||||
pdev_idx < ab->hw_params.num_rxdma_per_pdev)
|
||||
return 0;
|
||||
goto fallback;
|
||||
}
|
||||
|
|
@ -1017,3 +1015,11 @@ void ath11k_reg_free(struct ath11k_base *ab)
|
|||
kfree(ab->new_regd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int ath11k_reg_set_cc(struct ath11k *ar)
|
||||
{
|
||||
struct wmi_set_current_country_params set_current_param = {};
|
||||
|
||||
memcpy(&set_current_param.alpha2, ar->alpha2, 2);
|
||||
return ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_REG_H
|
||||
|
|
@ -45,5 +45,5 @@ ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
|
|||
int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
|
||||
int ath11k_reg_set_cc(struct ath11k *ar);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9082,7 +9082,7 @@ int ath11k_wmi_attach(struct ath11k_base *ab)
|
|||
ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX;
|
||||
|
||||
/* It's overwritten when service_ext_ready is handled */
|
||||
if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1)
|
||||
if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1)
|
||||
ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_SINGLE;
|
||||
|
||||
/* TODO: Init remaining wmi soc resources required */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_CE_H
|
||||
|
|
@ -119,7 +119,7 @@ struct ath12k_ce_ring {
|
|||
/* Host address space */
|
||||
void *base_addr_owner_space_unaligned;
|
||||
/* CE address space */
|
||||
u32 base_addr_ce_space_unaligned;
|
||||
dma_addr_t base_addr_ce_space_unaligned;
|
||||
|
||||
/* Actual start of descriptors.
|
||||
* Aligned to descriptor-size boundary.
|
||||
|
|
@ -129,7 +129,7 @@ struct ath12k_ce_ring {
|
|||
void *base_addr_owner_space;
|
||||
|
||||
/* CE address space */
|
||||
u32 base_addr_ce_space;
|
||||
dma_addr_t base_addr_ce_space;
|
||||
|
||||
/* HAL ring id */
|
||||
u32 hal_ring_id;
|
||||
|
|
|
|||
|
|
@ -50,19 +50,16 @@ int ath12k_core_suspend(struct ath12k_base *ab)
|
|||
if (!ab->hw_params->supports_suspend)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
ar = ath12k_mac_get_ar_by_pdev_id(ab, i);
|
||||
ar = ab->pdevs[i].ar;
|
||||
if (!ar)
|
||||
continue;
|
||||
ret = ath12k_mac_wait_tx_complete(ar);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to wait tx complete: %d\n", ret);
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
/* PM framework skips suspend_late/resume_early callbacks
|
||||
* if other devices report errors in their suspend callbacks.
|
||||
|
|
@ -994,9 +991,8 @@ void ath12k_core_halt(struct ath12k *ar)
|
|||
static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k *ar;
|
||||
struct ath12k_pdev *pdev;
|
||||
struct ath12k_hw *ah;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
ab->stats.fw_crash_counter++;
|
||||
|
|
@ -1006,35 +1002,32 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
|||
set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
||||
|
||||
for (i = 0; i < ab->num_hw; i++) {
|
||||
if (!ab->ah[i])
|
||||
continue;
|
||||
|
||||
ah = ab->ah[i];
|
||||
ieee80211_stop_queues(ah->hw);
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
if (!ar || ar->state == ATH12K_STATE_OFF)
|
||||
if (!ah || ah->state == ATH12K_HW_STATE_OFF)
|
||||
continue;
|
||||
|
||||
ath12k_mac_drain_tx(ar);
|
||||
complete(&ar->scan.started);
|
||||
complete(&ar->scan.completed);
|
||||
complete(&ar->scan.on_channel);
|
||||
complete(&ar->peer_assoc_done);
|
||||
complete(&ar->peer_delete_done);
|
||||
complete(&ar->install_key_done);
|
||||
complete(&ar->vdev_setup_done);
|
||||
complete(&ar->vdev_delete_done);
|
||||
complete(&ar->bss_survey_done);
|
||||
ieee80211_stop_queues(ah->hw);
|
||||
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
idr_for_each(&ar->txmgmt_idr,
|
||||
ath12k_mac_tx_mgmt_pending_free, ar);
|
||||
idr_destroy(&ar->txmgmt_idr);
|
||||
wake_up(&ar->txmgmt_empty_waitq);
|
||||
for (j = 0; j < ah->num_radio; j++) {
|
||||
ar = &ah->radio[j];
|
||||
|
||||
ath12k_mac_drain_tx(ar);
|
||||
complete(&ar->scan.started);
|
||||
complete(&ar->scan.completed);
|
||||
complete(&ar->scan.on_channel);
|
||||
complete(&ar->peer_assoc_done);
|
||||
complete(&ar->peer_delete_done);
|
||||
complete(&ar->install_key_done);
|
||||
complete(&ar->vdev_setup_done);
|
||||
complete(&ar->vdev_delete_done);
|
||||
complete(&ar->bss_survey_done);
|
||||
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
idr_for_each(&ar->txmgmt_idr,
|
||||
ath12k_mac_tx_mgmt_pending_free, ar);
|
||||
idr_destroy(&ar->txmgmt_idr);
|
||||
wake_up(&ar->txmgmt_empty_waitq);
|
||||
}
|
||||
}
|
||||
|
||||
wake_up(&ab->wmi_ab.tx_credits_wq);
|
||||
|
|
@ -1043,41 +1036,51 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
|||
|
||||
static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_hw *ah;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_pdev *pdev;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
if (!ar || ar->state == ATH12K_STATE_OFF)
|
||||
for (i = 0; i < ab->num_hw; i++) {
|
||||
ah = ab->ah[i];
|
||||
if (!ah || ah->state == ATH12K_HW_STATE_OFF)
|
||||
continue;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
mutex_lock(&ah->hw_mutex);
|
||||
|
||||
switch (ar->state) {
|
||||
case ATH12K_STATE_ON:
|
||||
ar->state = ATH12K_STATE_RESTARTING;
|
||||
ath12k_core_halt(ar);
|
||||
ieee80211_restart_hw(ath12k_ar_to_hw(ar));
|
||||
switch (ah->state) {
|
||||
case ATH12K_HW_STATE_ON:
|
||||
ah->state = ATH12K_HW_STATE_RESTARTING;
|
||||
|
||||
for (j = 0; j < ah->num_radio; j++) {
|
||||
ar = &ah->radio[j];
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ath12k_core_halt(ar);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
/* Restart after all the link/radio halt */
|
||||
ieee80211_restart_hw(ah->hw);
|
||||
break;
|
||||
case ATH12K_STATE_OFF:
|
||||
case ATH12K_HW_STATE_OFF:
|
||||
ath12k_warn(ab,
|
||||
"cannot restart radio %d that hasn't been started\n",
|
||||
"cannot restart hw %d that hasn't been started\n",
|
||||
i);
|
||||
break;
|
||||
case ATH12K_STATE_RESTARTING:
|
||||
case ATH12K_HW_STATE_RESTARTING:
|
||||
break;
|
||||
case ATH12K_STATE_RESTARTED:
|
||||
ar->state = ATH12K_STATE_WEDGED;
|
||||
case ATH12K_HW_STATE_RESTARTED:
|
||||
ah->state = ATH12K_HW_STATE_WEDGED;
|
||||
fallthrough;
|
||||
case ATH12K_STATE_WEDGED:
|
||||
case ATH12K_HW_STATE_WEDGED:
|
||||
ath12k_warn(ab,
|
||||
"device is wedged, will not restart radio %d\n", i);
|
||||
"device is wedged, will not restart hw %d\n", i);
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
mutex_unlock(&ah->hw_mutex);
|
||||
}
|
||||
|
||||
complete(&ab->driver_recovery);
|
||||
}
|
||||
|
||||
|
|
@ -1185,6 +1188,29 @@ int ath12k_core_pre_init(struct ath12k_base *ab)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_core_panic_handler(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct ath12k_base *ab = container_of(nb, struct ath12k_base,
|
||||
panic_nb);
|
||||
|
||||
return ath12k_hif_panic_handler(ab);
|
||||
}
|
||||
|
||||
static int ath12k_core_panic_notifier_register(struct ath12k_base *ab)
|
||||
{
|
||||
ab->panic_nb.notifier_call = ath12k_core_panic_handler;
|
||||
|
||||
return atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&ab->panic_nb);
|
||||
}
|
||||
|
||||
static void ath12k_core_panic_notifier_unregister(struct ath12k_base *ab)
|
||||
{
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&ab->panic_nb);
|
||||
}
|
||||
|
||||
int ath12k_core_init(struct ath12k_base *ab)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1195,11 +1221,17 @@ int ath12k_core_init(struct ath12k_base *ab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_core_panic_notifier_register(ab);
|
||||
if (ret)
|
||||
ath12k_warn(ab, "failed to register panic handler: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath12k_core_deinit(struct ath12k_base *ab)
|
||||
{
|
||||
ath12k_core_panic_notifier_unregister(ab);
|
||||
|
||||
mutex_lock(&ab->core_lock);
|
||||
|
||||
ath12k_core_pdev_destroy(ab);
|
||||
|
|
@ -1262,6 +1294,16 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
|
|||
ab->qmi.num_radios = U8_MAX;
|
||||
ab->mlo_capable_flags = ATH12K_INTRA_DEVICE_MLO_SUPPORT;
|
||||
|
||||
/* Device index used to identify the devices in a group.
|
||||
*
|
||||
* In Intra-device MLO, only one device present in a group,
|
||||
* so it is always zero.
|
||||
*
|
||||
* In Inter-device MLO, Multiple device present in a group,
|
||||
* expect non-zero value.
|
||||
*/
|
||||
ab->device_id = 0;
|
||||
|
||||
return ab;
|
||||
|
||||
err_free_wq:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/dmi.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/panic_notifier.h>
|
||||
#include "qmi.h"
|
||||
#include "htc.h"
|
||||
#include "wmi.h"
|
||||
|
|
@ -146,7 +147,7 @@ struct ath12k_ext_irq_grp {
|
|||
u32 grp_id;
|
||||
u64 timestamp;
|
||||
struct napi_struct napi;
|
||||
struct net_device napi_ndev;
|
||||
struct net_device *napi_ndev;
|
||||
};
|
||||
|
||||
struct ath12k_smbios_bdf {
|
||||
|
|
@ -180,8 +181,6 @@ struct ath12k_he {
|
|||
u32 heop_param;
|
||||
};
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
|
||||
enum {
|
||||
WMI_HOST_TP_SCALE_MAX = 0,
|
||||
WMI_HOST_TP_SCALE_50 = 1,
|
||||
|
|
@ -212,10 +211,6 @@ enum ath12k_dev_flags {
|
|||
ATH12K_FLAG_EXT_IRQ_ENABLED,
|
||||
};
|
||||
|
||||
enum ath12k_monitor_flags {
|
||||
ATH12K_FLAG_MONITOR_ENABLED,
|
||||
};
|
||||
|
||||
struct ath12k_tx_conf {
|
||||
bool changed;
|
||||
u16 ac;
|
||||
|
|
@ -454,15 +449,15 @@ struct ath12k_sta {
|
|||
#define ATH12K_MIN_5G_FREQ 4150
|
||||
#define ATH12K_MIN_6G_FREQ 5925
|
||||
#define ATH12K_MAX_6G_FREQ 7115
|
||||
#define ATH12K_NUM_CHANS 100
|
||||
#define ATH12K_NUM_CHANS 101
|
||||
#define ATH12K_MAX_5G_CHAN 173
|
||||
|
||||
enum ath12k_state {
|
||||
ATH12K_STATE_OFF,
|
||||
ATH12K_STATE_ON,
|
||||
ATH12K_STATE_RESTARTING,
|
||||
ATH12K_STATE_RESTARTED,
|
||||
ATH12K_STATE_WEDGED,
|
||||
enum ath12k_hw_state {
|
||||
ATH12K_HW_STATE_OFF,
|
||||
ATH12K_HW_STATE_ON,
|
||||
ATH12K_HW_STATE_RESTARTING,
|
||||
ATH12K_HW_STATE_RESTARTED,
|
||||
ATH12K_HW_STATE_WEDGED,
|
||||
/* Add other states as required */
|
||||
};
|
||||
|
||||
|
|
@ -511,7 +506,6 @@ struct ath12k {
|
|||
u32 ht_cap_info;
|
||||
u32 vht_cap_info;
|
||||
struct ath12k_he ar_he;
|
||||
enum ath12k_state state;
|
||||
bool supports_6ghz;
|
||||
struct {
|
||||
struct completion started;
|
||||
|
|
@ -533,7 +527,6 @@ struct ath12k {
|
|||
|
||||
unsigned long dev_flags;
|
||||
unsigned int filter_flags;
|
||||
unsigned long monitor_flags;
|
||||
u32 min_tx_power;
|
||||
u32 max_tx_power;
|
||||
u32 txpower_limit_2g;
|
||||
|
|
@ -636,10 +629,18 @@ struct ath12k {
|
|||
|
||||
struct ath12k_hw {
|
||||
struct ieee80211_hw *hw;
|
||||
struct ath12k_base *ab;
|
||||
|
||||
/* Protect the write operation of the hardware state ath12k_hw::state
|
||||
* between hardware start<=>reconfigure<=>stop transitions.
|
||||
*/
|
||||
struct mutex hw_mutex;
|
||||
enum ath12k_hw_state state;
|
||||
bool regd_updated;
|
||||
bool use_6ghz_regd;
|
||||
|
||||
u8 num_radio;
|
||||
|
||||
/* Keep last */
|
||||
struct ath12k radio[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
|
|
@ -689,6 +690,7 @@ struct mlo_timestamp {
|
|||
struct ath12k_pdev {
|
||||
struct ath12k *ar;
|
||||
u32 pdev_id;
|
||||
u32 hw_link_id;
|
||||
struct ath12k_pdev_cap cap;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
struct mlo_timestamp timestamp;
|
||||
|
|
@ -747,6 +749,7 @@ struct ath12k_base {
|
|||
struct ath12k_qmi qmi;
|
||||
struct ath12k_wmi_base wmi_ab;
|
||||
struct completion fw_ready;
|
||||
u8 device_id;
|
||||
int num_radios;
|
||||
/* HW channel counters frequency value in hertz common to all MACs */
|
||||
u32 cc_freq_hz;
|
||||
|
|
@ -923,6 +926,8 @@ struct ath12k_base {
|
|||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
struct notifier_block panic_nb;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
|
@ -1037,6 +1042,11 @@ static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah, u8 hw_link_id
|
|||
return &ah->radio[hw_link_id];
|
||||
}
|
||||
|
||||
static inline struct ath12k_hw *ath12k_ar_to_ah(struct ath12k *ar)
|
||||
{
|
||||
return ar->ah;
|
||||
}
|
||||
|
||||
static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar)
|
||||
{
|
||||
return ar->ah->hw;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,9 @@ static int ath12k_dp_srng_find_ring_in_mask(int ring_num, const u8 *grp_mask)
|
|||
static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab,
|
||||
enum hal_ring_type type, int ring_num)
|
||||
{
|
||||
const struct ath12k_hal_tcl_to_wbm_rbm_map *map;
|
||||
const u8 *grp_mask;
|
||||
int i;
|
||||
|
||||
switch (type) {
|
||||
case HAL_WBM2SW_RELEASE:
|
||||
|
|
@ -140,6 +142,14 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab,
|
|||
grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0];
|
||||
ring_num = 0;
|
||||
} else {
|
||||
map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map;
|
||||
for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
|
||||
if (ring_num == map[i].wbm_ring_num) {
|
||||
ring_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
grp_mask = &ab->hw_params->ring_mask->tx[0];
|
||||
}
|
||||
break;
|
||||
|
|
@ -457,8 +467,6 @@ static void ath12k_dp_srng_common_cleanup(struct ath12k_base *ab)
|
|||
ath12k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring);
|
||||
ath12k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring);
|
||||
}
|
||||
ath12k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
|
||||
ath12k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
|
||||
ath12k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
|
||||
}
|
||||
|
||||
|
|
@ -479,20 +487,6 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab)
|
|||
goto err;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_srng_setup(ab, &dp->tcl_cmd_ring, HAL_TCL_CMD, 0, 0,
|
||||
DP_TCL_CMD_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to set up tcl_cmd ring :%d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_srng_setup(ab, &dp->tcl_status_ring, HAL_TCL_STATUS,
|
||||
0, 0, DP_TCL_STATUS_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to set up tcl_status ring :%d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
|
||||
map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map;
|
||||
tx_comp_ring_num = map[i].wbm_ring_num;
|
||||
|
|
@ -616,6 +610,7 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab,
|
|||
int i;
|
||||
int ret = 0;
|
||||
u32 end_offset, cookie;
|
||||
enum hal_rx_buf_return_buf_manager rbm = dp->idle_link_rbm;
|
||||
|
||||
n_entries_per_buf = HAL_WBM_IDLE_SCATTER_BUF_SIZE /
|
||||
ath12k_hal_srng_get_entrysize(ab, HAL_WBM_IDLE_LINK);
|
||||
|
|
@ -646,7 +641,8 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab,
|
|||
paddr = link_desc_banks[i].paddr;
|
||||
while (n_entries) {
|
||||
cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i);
|
||||
ath12k_hal_set_link_desc_addr(scatter_buf, cookie, paddr);
|
||||
ath12k_hal_set_link_desc_addr(scatter_buf, cookie,
|
||||
paddr, rbm);
|
||||
n_entries--;
|
||||
paddr += HAL_LINK_DESC_SIZE;
|
||||
if (rem_entries) {
|
||||
|
|
@ -790,6 +786,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab,
|
|||
u32 paddr;
|
||||
int i, ret;
|
||||
u32 cookie;
|
||||
enum hal_rx_buf_return_buf_manager rbm = ab->dp.idle_link_rbm;
|
||||
|
||||
tot_mem_sz = n_link_desc * HAL_LINK_DESC_SIZE;
|
||||
tot_mem_sz += HAL_LINK_DESC_ALIGN;
|
||||
|
|
@ -850,8 +847,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab,
|
|||
while (n_entries &&
|
||||
(desc = ath12k_hal_srng_src_get_next_entry(ab, srng))) {
|
||||
cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i);
|
||||
ath12k_hal_set_link_desc_addr(desc,
|
||||
cookie, paddr);
|
||||
ath12k_hal_set_link_desc_addr(desc, cookie, paddr, rbm);
|
||||
n_entries--;
|
||||
paddr += HAL_LINK_DESC_SIZE;
|
||||
}
|
||||
|
|
@ -881,11 +877,9 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
|
|||
enum dp_monitor_mode monitor_mode;
|
||||
u8 ring_mask;
|
||||
|
||||
while (i < ab->hw_params->max_tx_ring) {
|
||||
if (ab->hw_params->ring_mask->tx[grp_id] &
|
||||
BIT(ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[i].wbm_ring_num))
|
||||
ath12k_dp_tx_completion_handler(ab, i);
|
||||
i++;
|
||||
if (ab->hw_params->ring_mask->tx[grp_id]) {
|
||||
i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1;
|
||||
ath12k_dp_tx_completion_handler(ab, i);
|
||||
}
|
||||
|
||||
if (ab->hw_params->ring_mask->rx_err[grp_id]) {
|
||||
|
|
@ -921,8 +915,8 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
|
|||
monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
|
||||
ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id];
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params->num_rxmda_per_pdev; j++) {
|
||||
int id = i * ab->hw_params->num_rxmda_per_pdev + j;
|
||||
for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
|
||||
int id = i * ab->hw_params->num_rxdma_per_pdev + j;
|
||||
|
||||
if (ring_mask & BIT(id)) {
|
||||
work_done =
|
||||
|
|
@ -942,8 +936,8 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
|
|||
monitor_mode = ATH12K_DP_TX_MONITOR_MODE;
|
||||
ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id];
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params->num_rxmda_per_pdev; j++) {
|
||||
int id = i * ab->hw_params->num_rxmda_per_pdev + j;
|
||||
for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
|
||||
int id = i * ab->hw_params->num_rxdma_per_pdev + j;
|
||||
|
||||
if (ring_mask & BIT(id)) {
|
||||
work_done =
|
||||
|
|
@ -1031,7 +1025,7 @@ static void ath12k_dp_service_mon_ring(struct timer_list *t)
|
|||
struct ath12k_base *ab = from_timer(ab, t, mon_reap_timer);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++)
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++)
|
||||
ath12k_dp_mon_process_ring(ab, i, NULL, DP_MON_SERVICE_BUDGET,
|
||||
ATH12K_DP_RX_MONITOR_MODE);
|
||||
|
||||
|
|
@ -1355,13 +1349,14 @@ static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab,
|
|||
struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab,
|
||||
u32 cookie)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct ath12k_rx_desc_info **desc_addr_ptr;
|
||||
u16 start_ppt_idx, end_ppt_idx, ppt_idx, spt_idx;
|
||||
|
||||
ppt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_PPT);
|
||||
spt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_SPT);
|
||||
|
||||
start_ppt_idx = ATH12K_RX_SPT_PAGE_OFFSET;
|
||||
start_ppt_idx = dp->rx_ppt_base + ATH12K_RX_SPT_PAGE_OFFSET;
|
||||
end_ppt_idx = start_ppt_idx + ATH12K_NUM_RX_SPT_PAGES;
|
||||
|
||||
if (ppt_idx < start_ppt_idx ||
|
||||
|
|
@ -1369,6 +1364,7 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab,
|
|||
spt_idx > ATH12K_MAX_SPT_ENTRIES)
|
||||
return NULL;
|
||||
|
||||
ppt_idx = ppt_idx - dp->rx_ppt_base;
|
||||
desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, spt_idx);
|
||||
|
||||
return *desc_addr_ptr;
|
||||
|
|
@ -1403,7 +1399,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab)
|
|||
struct ath12k_rx_desc_info *rx_descs, **rx_desc_addr;
|
||||
struct ath12k_tx_desc_info *tx_descs, **tx_desc_addr;
|
||||
u32 i, j, pool_id, tx_spt_page;
|
||||
u32 ppt_idx;
|
||||
u32 ppt_idx, cookie_ppt_idx;
|
||||
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
|
||||
|
|
@ -1418,10 +1414,11 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab)
|
|||
}
|
||||
|
||||
ppt_idx = ATH12K_RX_SPT_PAGE_OFFSET + i;
|
||||
cookie_ppt_idx = dp->rx_ppt_base + ppt_idx;
|
||||
dp->spt_info->rxbaddr[i] = &rx_descs[0];
|
||||
|
||||
for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) {
|
||||
rx_descs[j].cookie = ath12k_dp_cc_cookie_gen(ppt_idx, j);
|
||||
rx_descs[j].cookie = ath12k_dp_cc_cookie_gen(cookie_ppt_idx, j);
|
||||
rx_descs[j].magic = ATH12K_DP_RX_DESC_MAGIC;
|
||||
list_add_tail(&rx_descs[j].list, &dp->rx_desc_free_list);
|
||||
|
||||
|
|
@ -1482,6 +1479,7 @@ static int ath12k_dp_cmem_init(struct ath12k_base *ab,
|
|||
end = start + ATH12K_NUM_TX_SPT_PAGES;
|
||||
break;
|
||||
case ATH12K_DP_RX_DESC:
|
||||
cmem_base += ATH12K_PPT_ADDR_OFFSET(dp->rx_ppt_base);
|
||||
start = ATH12K_RX_SPT_PAGE_OFFSET;
|
||||
end = start + ATH12K_NUM_RX_SPT_PAGES;
|
||||
break;
|
||||
|
|
@ -1524,6 +1522,8 @@ static int ath12k_dp_cc_init(struct ath12k_base *ab)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dp->rx_ppt_base = ab->device_id * ATH12K_NUM_RX_SPT_PAGES;
|
||||
|
||||
for (i = 0; i < dp->num_spt_pages; i++) {
|
||||
dp->spt_info[i].vaddr = dma_alloc_coherent(ab->dev,
|
||||
ATH12K_PAGE_SIZE,
|
||||
|
|
@ -1587,6 +1587,24 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static enum hal_rx_buf_return_buf_manager
|
||||
ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab)
|
||||
{
|
||||
switch (ab->device_id) {
|
||||
case 0:
|
||||
return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST;
|
||||
case 1:
|
||||
return HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST;
|
||||
case 2:
|
||||
return HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST;
|
||||
default:
|
||||
ath12k_warn(ab, "invalid %d device id, so choose default rbm\n",
|
||||
ab->device_id);
|
||||
WARN_ON(1);
|
||||
return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
int ath12k_dp_alloc(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
|
|
@ -1603,6 +1621,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab)
|
|||
spin_lock_init(&dp->reo_cmd_lock);
|
||||
|
||||
dp->reo_cmd_cache_flush_count = 0;
|
||||
dp->idle_link_rbm = ath12k_dp_get_idle_link_rbm(ab);
|
||||
|
||||
ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -325,10 +325,9 @@ struct ath12k_dp {
|
|||
u8 htt_tgt_ver_major;
|
||||
u8 htt_tgt_ver_minor;
|
||||
struct dp_link_desc_bank link_desc_banks[DP_LINK_DESC_BANKS_MAX];
|
||||
enum hal_rx_buf_return_buf_manager idle_link_rbm;
|
||||
struct dp_srng wbm_idle_ring;
|
||||
struct dp_srng wbm_desc_rel_ring;
|
||||
struct dp_srng tcl_cmd_ring;
|
||||
struct dp_srng tcl_status_ring;
|
||||
struct dp_srng reo_reinject_ring;
|
||||
struct dp_srng rx_rel_ring;
|
||||
struct dp_srng reo_except_ring;
|
||||
|
|
@ -351,6 +350,7 @@ struct ath12k_dp {
|
|||
struct ath12k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX];
|
||||
struct ath12k_spt_info *spt_info;
|
||||
u32 num_spt_pages;
|
||||
u32 rx_ppt_base;
|
||||
struct list_head rx_desc_free_list;
|
||||
/* protects the free desc list */
|
||||
spinlock_t rx_desc_lock;
|
||||
|
|
|
|||
|
|
@ -1903,43 +1903,6 @@ ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab,
|
|||
break;
|
||||
}
|
||||
|
||||
case HAL_MON_BUF_ADDR: {
|
||||
struct dp_rxdma_mon_ring *buf_ring = &ab->dp.tx_mon_buf_ring;
|
||||
struct dp_mon_packet_info *packet_info =
|
||||
(struct dp_mon_packet_info *)tlv_data;
|
||||
int buf_id = u32_get_bits(packet_info->cookie,
|
||||
DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
struct sk_buff *msdu;
|
||||
struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
|
||||
spin_lock_bh(&buf_ring->idr_lock);
|
||||
msdu = idr_remove(&buf_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&buf_ring->idr_lock);
|
||||
|
||||
if (unlikely(!msdu)) {
|
||||
ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",
|
||||
buf_id);
|
||||
return DP_MON_TX_STATUS_PPDU_NOT_DONE;
|
||||
}
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
msdu->len + skb_tailroom(msdu),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (!mon_mpdu->head)
|
||||
mon_mpdu->head = msdu;
|
||||
else if (mon_mpdu->tail)
|
||||
mon_mpdu->tail->next = msdu;
|
||||
|
||||
mon_mpdu->tail = msdu;
|
||||
|
||||
ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
|
||||
status = DP_MON_TX_BUFFER_ADDR;
|
||||
break;
|
||||
}
|
||||
|
||||
case HAL_TX_MPDU_END:
|
||||
list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
|
||||
&tx_ppdu_info->dp_tx_mon_mpdu_list);
|
||||
|
|
@ -2088,8 +2051,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget,
|
|||
mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];
|
||||
buf_ring = &dp->rxdma_mon_buf_ring;
|
||||
} else {
|
||||
mon_dst_ring = &pdev_dp->tx_mon_dst_ring[srng_id];
|
||||
buf_ring = &dp->tx_mon_buf_ring;
|
||||
return 0;
|
||||
}
|
||||
|
||||
srng = &ab->hal.srng_list[mon_dst_ring->ring_id];
|
||||
|
|
|
|||
|
|
@ -422,8 +422,6 @@ static int ath12k_dp_rxdma_buf_free(struct ath12k_base *ab)
|
|||
|
||||
ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->rxdma_mon_buf_ring);
|
||||
|
||||
ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->tx_mon_buf_ring);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -476,15 +474,6 @@ static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab)
|
|||
"failed to setup HAL_RXDMA_MONITOR_BUF\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_rxdma_mon_ring_buf_setup(ab,
|
||||
&dp->tx_mon_buf_ring,
|
||||
HAL_TX_MONITOR_BUF);
|
||||
if (ret) {
|
||||
ath12k_warn(ab,
|
||||
"failed to setup HAL_TX_MONITOR_BUF\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -496,10 +485,8 @@ static void ath12k_dp_rx_pdev_srng_free(struct ath12k *ar)
|
|||
struct ath12k_base *ab = ar->ab;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++)
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rxdma_mon_dst_ring[i]);
|
||||
ath12k_dp_srng_cleanup(ab, &dp->tx_mon_dst_ring[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab)
|
||||
|
|
@ -543,7 +530,7 @@ static int ath12k_dp_rx_pdev_srng_alloc(struct ath12k *ar)
|
|||
int ret;
|
||||
u32 mac_id = dp->mac_id;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ret = ath12k_dp_srng_setup(ar->ab,
|
||||
&dp->rxdma_mon_dst_ring[i],
|
||||
HAL_RXDMA_MONITOR_DST,
|
||||
|
|
@ -554,17 +541,6 @@ static int ath12k_dp_rx_pdev_srng_alloc(struct ath12k *ar)
|
|||
"failed to setup HAL_RXDMA_MONITOR_DST\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_srng_setup(ar->ab,
|
||||
&dp->tx_mon_dst_ring[i],
|
||||
HAL_TX_MONITOR_DST,
|
||||
0, mac_id + i,
|
||||
DP_TX_MONITOR_DEST_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab,
|
||||
"failed to setup HAL_TX_MONITOR_DST\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2383,8 +2359,10 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
|
|||
channel_num = meta_data;
|
||||
center_freq = meta_data >> 16;
|
||||
|
||||
if (center_freq >= 5935 && center_freq <= 7105) {
|
||||
if (center_freq >= ATH12K_MIN_6G_FREQ &&
|
||||
center_freq <= ATH12K_MAX_6G_FREQ) {
|
||||
rx_status->band = NL80211_BAND_6GHZ;
|
||||
rx_status->freq = center_freq;
|
||||
} else if (channel_num >= 1 && channel_num <= 14) {
|
||||
rx_status->band = NL80211_BAND_2GHZ;
|
||||
} else if (channel_num >= 36 && channel_num <= 173) {
|
||||
|
|
@ -2402,8 +2380,9 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
|
|||
rx_desc, sizeof(*rx_desc));
|
||||
}
|
||||
|
||||
rx_status->freq = ieee80211_channel_to_frequency(channel_num,
|
||||
rx_status->band);
|
||||
if (rx_status->band != NL80211_BAND_6GHZ)
|
||||
rx_status->freq = ieee80211_channel_to_frequency(channel_num,
|
||||
rx_status->band);
|
||||
|
||||
ath12k_dp_rx_h_rate(ar, rx_desc, rx_status);
|
||||
}
|
||||
|
|
@ -2649,7 +2628,8 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
|||
if (!desc_info) {
|
||||
desc_info = ath12k_dp_get_rx_desc(ab, cookie);
|
||||
if (!desc_info) {
|
||||
ath12k_warn(ab, "Invalid cookie in manual desc retrieval");
|
||||
ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n",
|
||||
cookie);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -2762,6 +2742,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
|
|||
peer = ath12k_peer_find(ab, vdev_id, peer_mac);
|
||||
if (!peer) {
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
crypto_free_shash(tfm);
|
||||
ath12k_warn(ab, "failed to find the peer to set up fragment info\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
@ -2991,9 +2972,10 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
|||
struct hal_srng *srng;
|
||||
dma_addr_t link_paddr, buf_paddr;
|
||||
u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info;
|
||||
u32 cookie, hal_rx_desc_sz, dest_ring_info0;
|
||||
u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi;
|
||||
int ret;
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm;
|
||||
u8 dst_ind;
|
||||
|
||||
hal_rx_desc_sz = ab->hal.hal_desc_sz;
|
||||
|
|
@ -3027,7 +3009,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
|||
|
||||
buf_paddr = dma_map_single(ab->dev, defrag_skb->data,
|
||||
defrag_skb->len + skb_tailroom(defrag_skb),
|
||||
DMA_FROM_DEVICE);
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(ab->dev, buf_paddr))
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -3071,7 +3053,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
|||
|
||||
ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr,
|
||||
cookie,
|
||||
HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST);
|
||||
idle_link_rbm);
|
||||
|
||||
mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) |
|
||||
u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) |
|
||||
|
|
@ -3083,13 +3065,11 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
|||
reo_ent_ring->rx_mpdu_info.peer_meta_data =
|
||||
reo_dest_ring->rx_mpdu_info.peer_meta_data;
|
||||
|
||||
/* Firmware expects physical address to be filled in queue_addr_lo in
|
||||
* the MLO scenario and in case of non MLO peer meta data needs to be
|
||||
* filled.
|
||||
* TODO: Need to handle for MLO scenario.
|
||||
*/
|
||||
reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data;
|
||||
reo_ent_ring->info0 = le32_encode_bits(dst_ind,
|
||||
reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr));
|
||||
queue_addr_hi = upper_32_bits(rx_tid->paddr);
|
||||
reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi,
|
||||
HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
|
||||
le32_encode_bits(dst_ind,
|
||||
HAL_REO_ENTR_RING_INFO0_DEST_IND);
|
||||
|
||||
reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn,
|
||||
|
|
@ -3113,7 +3093,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
|||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
err_unmap_dma:
|
||||
dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb),
|
||||
DMA_FROM_DEVICE);
|
||||
DMA_TO_DEVICE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -3346,7 +3326,8 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
|
|||
if (!desc_info) {
|
||||
desc_info = ath12k_dp_get_rx_desc(ab, cookie);
|
||||
if (!desc_info) {
|
||||
ath12k_warn(ab, "Invalid cookie in manual desc retrieval");
|
||||
ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n",
|
||||
cookie);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -3451,7 +3432,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
|||
(paddr - link_desc_banks[desc_bank].paddr);
|
||||
ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
|
||||
&rbm);
|
||||
if (rbm != HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST &&
|
||||
if (rbm != dp->idle_link_rbm &&
|
||||
rbm != HAL_RX_BUF_RBM_SW3_BM &&
|
||||
rbm != ab->hw_params->hal_params->rx_buf_rbm) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
|
|
@ -3765,7 +3746,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
|||
if (!desc_info) {
|
||||
desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie);
|
||||
if (!desc_info) {
|
||||
ath12k_warn(ab, "Invalid cookie in manual desc retrieval");
|
||||
ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n",
|
||||
err_info.cookie);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -3961,7 +3943,7 @@ void ath12k_dp_rx_free(struct ath12k_base *ab)
|
|||
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring);
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
if (ab->hw_params->rx_mac_buf_ring)
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]);
|
||||
}
|
||||
|
|
@ -3970,7 +3952,6 @@ void ath12k_dp_rx_free(struct ath12k_base *ab)
|
|||
ath12k_dp_srng_cleanup(ab, &dp->rxdma_err_dst_ring[i]);
|
||||
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rxdma_mon_buf_ring.refill_buf_ring);
|
||||
ath12k_dp_srng_cleanup(ab, &dp->tx_mon_buf_ring.refill_buf_ring);
|
||||
|
||||
ath12k_dp_rxdma_buf_free(ab);
|
||||
}
|
||||
|
|
@ -4028,7 +4009,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
|
|||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct htt_rx_ring_tlv_filter tlv_filter = {0};
|
||||
u32 ring_id;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
|
||||
int i;
|
||||
|
||||
|
|
@ -4054,7 +4035,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
|
|||
* and modify the rx_desc struct
|
||||
*/
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i,
|
||||
HAL_RXDMA_BUF,
|
||||
|
|
@ -4081,7 +4062,7 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab)
|
|||
}
|
||||
|
||||
if (ab->hw_params->rx_mac_buf_ring) {
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
i, HAL_RXDMA_BUF);
|
||||
|
|
@ -4113,15 +4094,6 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab)
|
|||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ring_id = dp->tx_mon_buf_ring.refill_buf_ring.ring_id;
|
||||
ret = ath12k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
0, HAL_TX_MONITOR_BUF);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to configure rxdma_mon_buf_ring %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ab->hw_params->hw_ops->rxdma_ring_sel_config(ab);
|
||||
|
|
@ -4141,9 +4113,6 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
|||
idr_init(&dp->rxdma_mon_buf_ring.bufs_idr);
|
||||
spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock);
|
||||
|
||||
idr_init(&dp->tx_mon_buf_ring.bufs_idr);
|
||||
spin_lock_init(&dp->tx_mon_buf_ring.idr_lock);
|
||||
|
||||
ret = ath12k_dp_srng_setup(ab,
|
||||
&dp->rx_refill_buf_ring.refill_buf_ring,
|
||||
HAL_RXDMA_BUF, 0, 0,
|
||||
|
|
@ -4154,7 +4123,7 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
|||
}
|
||||
|
||||
if (ab->hw_params->rx_mac_buf_ring) {
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ret = ath12k_dp_srng_setup(ab,
|
||||
&dp->rx_mac_buf_ring[i],
|
||||
HAL_RXDMA_BUF, 1,
|
||||
|
|
@ -4186,15 +4155,6 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
|||
ath12k_warn(ab, "failed to setup HAL_RXDMA_MONITOR_BUF\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_srng_setup(ab,
|
||||
&dp->tx_mon_buf_ring.refill_buf_ring,
|
||||
HAL_TX_MONITOR_BUF, 0, 0,
|
||||
DP_TX_MONITOR_BUF_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to setup DP_TX_MONITOR_BUF_RING_SIZE\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ath12k_dp_rxdma_buf_setup(ab);
|
||||
|
|
@ -4223,7 +4183,7 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int mac_id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rxdma_mon_dst_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
mac_id + i,
|
||||
|
|
@ -4234,17 +4194,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int mac_id)
|
|||
i, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ring_id = dp->tx_mon_dst_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_srng_setup(ab, ring_id,
|
||||
mac_id + i,
|
||||
HAL_TX_MONITOR_DST);
|
||||
if (ret) {
|
||||
ath12k_warn(ab,
|
||||
"failed to configure tx_mon_dst_ring %d %d\n",
|
||||
i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,44 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
|
|||
HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
|
||||
}
|
||||
|
||||
#define HTT_META_DATA_ALIGNMENT 0x8
|
||||
|
||||
static void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len)
|
||||
{
|
||||
struct sk_buff *tail;
|
||||
void *metadata;
|
||||
|
||||
if (unlikely(skb_cow_data(skb, tail_len, &tail) < 0))
|
||||
return NULL;
|
||||
|
||||
metadata = pskb_put(skb, tail, tail_len);
|
||||
memset(metadata, 0, tail_len);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/* Preparing HTT Metadata when utilized with ext MSDU */
|
||||
static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb)
|
||||
{
|
||||
struct hal_tx_msdu_metadata *desc_ext;
|
||||
u8 htt_desc_size;
|
||||
/* Size rounded of multiple of 8 bytes */
|
||||
u8 htt_desc_size_aligned;
|
||||
|
||||
htt_desc_size = sizeof(struct hal_tx_msdu_metadata);
|
||||
htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT);
|
||||
|
||||
desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned);
|
||||
if (!desc_ext)
|
||||
return -ENOMEM;
|
||||
|
||||
desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) |
|
||||
le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) |
|
||||
le32_encode_bits(1,
|
||||
HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
|
@ -145,6 +183,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
|
|||
u8 ring_selector, ring_map = 0;
|
||||
bool tcl_ring_retry;
|
||||
bool msdu_ext_desc = false;
|
||||
bool add_htt_metadata = false;
|
||||
|
||||
if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
|
||||
return -ESHUTDOWN;
|
||||
|
|
@ -248,6 +287,18 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
|
|||
goto fail_remove_tx_buf;
|
||||
}
|
||||
|
||||
if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
|
||||
!(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
|
||||
!(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
/* Add metadata for sw encrypted vlan group traffic */
|
||||
add_htt_metadata = true;
|
||||
msdu_ext_desc = true;
|
||||
ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
|
||||
ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
|
||||
ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
}
|
||||
|
||||
tx_desc->skb = skb;
|
||||
tx_desc->mac_id = ar->pdev_idx;
|
||||
ti.desc_id = tx_desc->desc_id;
|
||||
|
|
@ -269,6 +320,15 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
|
|||
msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data;
|
||||
ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti);
|
||||
|
||||
if (add_htt_metadata) {
|
||||
ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc);
|
||||
if (ret < 0) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_DP_TX,
|
||||
"Failed to add HTT meta data, dropping packet\n");
|
||||
goto fail_unmap_dma;
|
||||
}
|
||||
}
|
||||
|
||||
ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data,
|
||||
skb_ext_desc->len, DMA_TO_DEVICE);
|
||||
ret = dma_mapping_error(ab->dev, ti.paddr);
|
||||
|
|
@ -352,15 +412,15 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
|
|||
u8 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
|
||||
|
||||
skb_cb = ATH12K_SKB_CB(msdu);
|
||||
ar = ab->pdevs[pdev_id].ar;
|
||||
|
||||
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
if (skb_cb->paddr_ext_desc)
|
||||
dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
|
||||
sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);
|
||||
|
||||
dev_kfree_skb_any(msdu);
|
||||
ieee80211_free_txskb(ar->ah->hw, msdu);
|
||||
|
||||
ar = ab->pdevs[pdev_id].ar;
|
||||
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
}
|
||||
|
|
@ -393,8 +453,12 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
|||
if (ts->acked) {
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +
|
||||
ts->ack_rssi;
|
||||
info->status.ack_signal = ts->ack_rssi;
|
||||
|
||||
if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
|
||||
ab->wmi_ab.svc_map))
|
||||
info->status.ack_signal += ATH12K_DEFAULT_NOISE_FLOOR;
|
||||
|
||||
info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
|
||||
} else {
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
|
|
@ -448,6 +512,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
|||
struct hal_tx_status *ts)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct ath12k_skb_cb *skb_cb;
|
||||
|
||||
|
|
@ -466,12 +531,12 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
|||
rcu_read_lock();
|
||||
|
||||
if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ieee80211_free_txskb(ah->hw, msdu);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!skb_cb->vif) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ieee80211_free_txskb(ah->hw, msdu);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
@ -481,17 +546,39 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
|||
/* skip tx rate update from ieee80211_status*/
|
||||
info->status.rates[0].idx = -1;
|
||||
|
||||
if (ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED &&
|
||||
!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +
|
||||
ts->ack_rssi;
|
||||
info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
|
||||
}
|
||||
switch (ts->status) {
|
||||
case HAL_WBM_TQM_REL_REASON_FRAME_ACKED:
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
info->status.ack_signal = ts->ack_rssi;
|
||||
|
||||
if (ts->status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX &&
|
||||
(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
|
||||
ab->wmi_ab.svc_map))
|
||||
info->status.ack_signal += ATH12K_DEFAULT_NOISE_FLOOR;
|
||||
|
||||
info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
|
||||
}
|
||||
break;
|
||||
case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX:
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU:
|
||||
case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD:
|
||||
case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES:
|
||||
/* The failure status is due to internal firmware tx failure
|
||||
* hence drop the frame; do not update the status of frame to
|
||||
* the upper layer
|
||||
*/
|
||||
ieee80211_free_txskb(ah->hw, msdu);
|
||||
goto exit;
|
||||
default:
|
||||
ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n",
|
||||
ts->status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* NOTE: Tx rate status reporting. Tx completion status does not have
|
||||
* necessary information (for example nss) to build the tx rate.
|
||||
|
|
@ -669,14 +756,6 @@ ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,
|
|||
*htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
|
||||
*htt_ring_type = HTT_SW_TO_HW_RING;
|
||||
break;
|
||||
case HAL_TX_MONITOR_BUF:
|
||||
*htt_ring_id = HTT_TX_MON_HOST2MON_BUF_RING;
|
||||
*htt_ring_type = HTT_SW_TO_HW_RING;
|
||||
break;
|
||||
case HAL_TX_MONITOR_DST:
|
||||
*htt_ring_id = HTT_TX_MON_MON2HOST_DEST_RING;
|
||||
*htt_ring_type = HTT_HW_TO_SW_RING;
|
||||
break;
|
||||
default:
|
||||
ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);
|
||||
ret = -EINVAL;
|
||||
|
|
@ -854,7 +933,7 @@ int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
skb = ath12k_htc_alloc_skb(ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1044,13 +1123,7 @@ int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset)
|
|||
struct ath12k_base *ab = ar->ab;
|
||||
int ret;
|
||||
|
||||
ret = ath12k_dp_tx_htt_tx_monitor_mode_ring_config(ar, reset);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to setup tx monitor filter %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_tx_htt_tx_monitor_mode_ring_config(ar, reset);
|
||||
ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret);
|
||||
return ret;
|
||||
|
|
@ -1209,31 +1282,3 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
|
|||
dev_kfree_skb_any(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_dp_tx_htt_tx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct htt_tx_ring_tlv_filter tlv_filter = {0};
|
||||
int ret, ring_id;
|
||||
|
||||
ring_id = dp->tx_mon_buf_ring.refill_buf_ring.ring_id;
|
||||
|
||||
/* TODO: Need to set upstream/downstream tlv filters
|
||||
* here
|
||||
*/
|
||||
|
||||
if (ab->hw_params->rxdma1_enable) {
|
||||
ret = ath12k_dp_tx_htt_tx_filter_setup(ar->ab, ring_id, 0,
|
||||
HAL_TX_MONITOR_BUF,
|
||||
DP_RXDMA_REFILL_RING_SIZE,
|
||||
&tlv_filter);
|
||||
if (ret) {
|
||||
ath12k_err(ab,
|
||||
"failed to setup filter for monitor buf %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_DP_TX_H
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
struct ath12k_dp_htt_wbm_tx_status {
|
||||
bool acked;
|
||||
int ack_rssi;
|
||||
s8 ack_rssi;
|
||||
};
|
||||
|
||||
int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
|
||||
|
|
@ -36,6 +36,5 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
|
|||
int mac_id, enum hal_ring_type ring_type,
|
||||
int tx_buf_size,
|
||||
struct htt_tx_ring_tlv_filter *htt_tlv_filter);
|
||||
int ath12k_dp_tx_htt_tx_monitor_mode_ring_config(struct ath12k *ar, bool reset);
|
||||
int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1969,14 +1969,15 @@ u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc
|
|||
}
|
||||
|
||||
void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie,
|
||||
dma_addr_t paddr)
|
||||
dma_addr_t paddr,
|
||||
enum hal_rx_buf_return_buf_manager rbm)
|
||||
{
|
||||
desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK),
|
||||
BUFFER_ADDR_INFO0_ADDR);
|
||||
desc->buf_addr_info.info1 =
|
||||
le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),
|
||||
BUFFER_ADDR_INFO1_ADDR) |
|
||||
le32_encode_bits(1, BUFFER_ADDR_INFO1_RET_BUF_MGR) |
|
||||
le32_encode_bits(rbm, BUFFER_ADDR_INFO1_RET_BUF_MGR) |
|
||||
le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -770,12 +770,12 @@ struct hal_srng_config {
|
|||
* enum hal_rx_buf_return_buf_manager - manager for returned rx buffers
|
||||
*
|
||||
* @HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST: Buffer returned to WBM idle buffer list
|
||||
* @HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the chip 0 WBM is chosen in case of a multi-chip config
|
||||
* @HAL_RX_BUF_RBM_WBM_CHIP1_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the chip 1 WBM is chosen in case of a multi-chip config
|
||||
* @HAL_RX_BUF_RBM_WBM_CHIP2_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the chip 2 WBM is chosen in case of a multi-chip config
|
||||
* @HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the device 0 WBM is chosen in case of a multi-device config
|
||||
* @HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the device 1 WBM is chosen in case of a multi-device config
|
||||
* @HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST: Descriptor returned to WBM idle
|
||||
* descriptor list, where the device 2 WBM is chosen in case of a multi-device config
|
||||
* @HAL_RX_BUF_RBM_FW_BM: Buffer returned to FW
|
||||
* @HAL_RX_BUF_RBM_SW0_BM: For ring 0 -- returned to host
|
||||
* @HAL_RX_BUF_RBM_SW1_BM: For ring 1 -- returned to host
|
||||
|
|
@ -788,9 +788,9 @@ struct hal_srng_config {
|
|||
|
||||
enum hal_rx_buf_return_buf_manager {
|
||||
HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_CHIP1_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_CHIP2_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST,
|
||||
HAL_RX_BUF_RBM_FW_BM,
|
||||
HAL_RX_BUF_RBM_SW0_BM,
|
||||
HAL_RX_BUF_RBM_SW1_BM,
|
||||
|
|
@ -1113,7 +1113,8 @@ dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,
|
|||
dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie,
|
||||
dma_addr_t paddr);
|
||||
dma_addr_t paddr,
|
||||
enum hal_rx_buf_return_buf_manager rbm);
|
||||
u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type);
|
||||
void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr,
|
||||
u32 len, u32 id, u8 byte_swap_data);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include "core.h"
|
||||
|
||||
|
|
@ -2048,6 +2048,19 @@ struct hal_wbm_release_ring {
|
|||
* fw with fw_reason2.
|
||||
* @HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON3: Remove command initiated by
|
||||
* fw with fw_reason3.
|
||||
* @HAL_WBM_TQM_REL_REASON_CMD_DISABLE_QUEUE: Remove command initiated by
|
||||
* fw with disable queue.
|
||||
* @HAL_WBM_TQM_REL_REASON_CMD_TILL_NONMATCHING: Remove command initiated by
|
||||
* fw to remove all mpdu until 1st non-match.
|
||||
* @HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: Dropped due to drop threshold
|
||||
* criteria
|
||||
* @HAL_WBM_TQM_REL_REASON_DROP_LINK_DESC_UNAVAIL: Dropped due to link desc
|
||||
* not available
|
||||
* @HAL_WBM_TQM_REL_REASON_DROP_OR_INVALID_MSDU: Dropped due drop bit set or
|
||||
* null flow
|
||||
* @HAL_WBM_TQM_REL_REASON_MULTICAST_DROP: Dropped due mcast drop set for VDEV
|
||||
* @HAL_WBM_TQM_REL_REASON_VDEV_MISMATCH_DROP: Dropped due to being set with
|
||||
* 'TCL_drop_reason'
|
||||
*/
|
||||
enum hal_wbm_tqm_rel_reason {
|
||||
HAL_WBM_TQM_REL_REASON_FRAME_ACKED,
|
||||
|
|
@ -2058,6 +2071,13 @@ enum hal_wbm_tqm_rel_reason {
|
|||
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON1,
|
||||
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON2,
|
||||
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON3,
|
||||
HAL_WBM_TQM_REL_REASON_CMD_DISABLE_QUEUE,
|
||||
HAL_WBM_TQM_REL_REASON_CMD_TILL_NONMATCHING,
|
||||
HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD,
|
||||
HAL_WBM_TQM_REL_REASON_DROP_LINK_DESC_UNAVAIL,
|
||||
HAL_WBM_TQM_REL_REASON_DROP_OR_INVALID_MSDU,
|
||||
HAL_WBM_TQM_REL_REASON_MULTICAST_DROP,
|
||||
HAL_WBM_TQM_REL_REASON_VDEV_MISMATCH_DROP,
|
||||
};
|
||||
|
||||
struct hal_wbm_buffer_ring {
|
||||
|
|
@ -2964,4 +2984,29 @@ struct hal_mon_dest_desc {
|
|||
* updated by SRNG.
|
||||
*/
|
||||
|
||||
#define HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG BIT(8)
|
||||
#define HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE GENMASK(16, 15)
|
||||
#define HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL BIT(31)
|
||||
|
||||
struct hal_tx_msdu_metadata {
|
||||
__le32 info0;
|
||||
__le32 rsvd0[6];
|
||||
} __packed;
|
||||
|
||||
/* hal_tx_msdu_metadata
|
||||
* valid_encrypt_type
|
||||
* if set, encrypt type is valid
|
||||
* encrypt_type
|
||||
* 0 = NO_ENCRYPT,
|
||||
* 1 = ENCRYPT,
|
||||
* 2 ~ 3 - Reserved
|
||||
* host_tx_desc_pool
|
||||
* If set, Firmware allocates tx_descriptors
|
||||
* in WAL_BUFFERID_TX_HOST_DATA_EXP,instead
|
||||
* of WAL_BUFFERID_TX_TCL_DATA_EXP.
|
||||
* Use cases:
|
||||
* Any time firmware uses TQM-BYPASS for Data
|
||||
* TID, firmware expect host to set this bit.
|
||||
*/
|
||||
|
||||
#endif /* ATH12K_HAL_DESC_H */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_HAL_TX_H
|
||||
|
|
@ -57,7 +57,7 @@ struct hal_tx_info {
|
|||
struct hal_tx_status {
|
||||
enum hal_wbm_rel_src_module buf_rel_source;
|
||||
enum hal_wbm_tqm_rel_reason status;
|
||||
u8 ack_rssi;
|
||||
s8 ack_rssi;
|
||||
u32 flags; /* %HAL_TX_STATUS_FLAGS_ */
|
||||
u32 ppdu_id;
|
||||
u8 try_cnt;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct ath12k_hif_ops {
|
|||
void (*ce_irq_enable)(struct ath12k_base *ab);
|
||||
void (*ce_irq_disable)(struct ath12k_base *ab);
|
||||
void (*get_ce_msi_idx)(struct ath12k_base *ab, u32 ce_id, u32 *msi_idx);
|
||||
int (*panic_handler)(struct ath12k_base *ab);
|
||||
};
|
||||
|
||||
static inline int ath12k_hif_map_service_to_pipe(struct ath12k_base *ab, u16 service_id,
|
||||
|
|
@ -147,4 +148,12 @@ static inline void ath12k_hif_power_down(struct ath12k_base *ab, bool is_suspend
|
|||
ab->hif.ops->power_down(ab, is_suspend);
|
||||
}
|
||||
|
||||
static inline int ath12k_hif_panic_handler(struct ath12k_base *ab)
|
||||
{
|
||||
if (!ab->hif.ops->panic_handler)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
return ab->hif.ops->panic_handler(ab);
|
||||
}
|
||||
|
||||
#endif /* ATH12K_HIF_H */
|
||||
|
|
|
|||
|
|
@ -544,9 +544,6 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = {
|
|||
},
|
||||
.rx_mon_dest = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_MON_RING_MASK_0,
|
||||
ATH12K_RX_MON_RING_MASK_1,
|
||||
ATH12K_RX_MON_RING_MASK_2,
|
||||
},
|
||||
.rx = {
|
||||
0, 0, 0, 0,
|
||||
|
|
@ -572,16 +569,15 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = {
|
|||
ATH12K_HOST2RXDMA_RING_MASK_0,
|
||||
},
|
||||
.tx_mon_dest = {
|
||||
ATH12K_TX_MON_RING_MASK_0,
|
||||
ATH12K_TX_MON_RING_MASK_1,
|
||||
0, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = {
|
||||
.tx = {
|
||||
ATH12K_TX_RING_MASK_0,
|
||||
ATH12K_TX_RING_MASK_1,
|
||||
ATH12K_TX_RING_MASK_2,
|
||||
ATH12K_TX_RING_MASK_4,
|
||||
},
|
||||
.rx_mon_dest = {
|
||||
},
|
||||
|
|
@ -884,14 +880,15 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.hal_params = &ath12k_hw_hal_params_qcn9274,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.num_rxdma_dst_ring = 0,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
BIT(NL80211_IFTYPE_AP_VLAN),
|
||||
.supports_monitor = false,
|
||||
|
||||
.idle_ps = false,
|
||||
|
|
@ -926,6 +923,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.supports_sta_ps = false,
|
||||
|
||||
.acpi_guid = NULL,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
},
|
||||
{
|
||||
.name = "wcn7850 hw2.0",
|
||||
|
|
@ -956,7 +954,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.hal_params = &ath12k_hw_hal_params_wcn7850,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 2,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.num_rxdma_dst_ring = 1,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
|
|
@ -1001,6 +999,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.supports_sta_ps = true,
|
||||
|
||||
.acpi_guid = &wcn7850_uuid,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
},
|
||||
{
|
||||
.name = "qcn9274 hw2.0",
|
||||
|
|
@ -1029,14 +1028,15 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.hal_params = &ath12k_hw_hal_params_qcn9274,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.num_rxdma_dst_ring = 0,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
BIT(NL80211_IFTYPE_AP_VLAN),
|
||||
.supports_monitor = false,
|
||||
|
||||
.idle_ps = false,
|
||||
|
|
@ -1071,6 +1071,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.supports_sta_ps = false,
|
||||
|
||||
.acpi_guid = NULL,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
#define TARGET_RX_BATCHMODE 1
|
||||
#define TARGET_RX_PEER_METADATA_VER_V1A 2
|
||||
#define TARGET_RX_PEER_METADATA_VER_V1B 3
|
||||
#define TARGET_EMA_MAX_PROFILE_PERIOD 8
|
||||
|
||||
#define ATH12K_HW_DEFAULT_QUEUE 0
|
||||
#define ATH12K_HW_MAX_QUEUES 4
|
||||
|
|
@ -174,7 +175,7 @@ struct ath12k_hw_params {
|
|||
const struct ath12k_hw_hal_params *hal_params;
|
||||
|
||||
bool rxdma1_enable:1;
|
||||
int num_rxmda_per_pdev;
|
||||
int num_rxdma_per_pdev;
|
||||
int num_rxdma_dst_ring;
|
||||
bool rx_mac_buf_ring:1;
|
||||
bool vdev_start_delay:1;
|
||||
|
|
@ -215,6 +216,7 @@ struct ath12k_hw_params {
|
|||
bool supports_sta_ps;
|
||||
|
||||
const guid_t *acpi_guid;
|
||||
bool supports_dynamic_smps_6ghz;
|
||||
};
|
||||
|
||||
struct ath12k_hw_ops {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ static const struct ieee80211_channel ath12k_5ghz_channels[] = {
|
|||
};
|
||||
|
||||
static const struct ieee80211_channel ath12k_6ghz_channels[] = {
|
||||
/* Operating Class 136 */
|
||||
CHAN6G(2, 5935, 0),
|
||||
|
||||
/* Operating Classes 131-135 */
|
||||
CHAN6G(1, 5955, 0),
|
||||
CHAN6G(5, 5975, 0),
|
||||
CHAN6G(9, 5995, 0),
|
||||
|
|
@ -863,9 +867,12 @@ static int ath12k_mac_vdev_setup_sync(struct ath12k *ar)
|
|||
|
||||
static int ath12k_monitor_vdev_up(struct ath12k *ar, int vdev_id)
|
||||
{
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
int ret;
|
||||
|
||||
ret = ath12k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
|
||||
params.vdev_id = vdev_id;
|
||||
params.bssid = ar->mac_addr;
|
||||
ret = ath12k_wmi_vdev_up(ar, ¶ms);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
|
||||
vdev_id, ret);
|
||||
|
|
@ -882,6 +889,7 @@ static int ath12k_mac_monitor_vdev_start(struct ath12k *ar, int vdev_id,
|
|||
{
|
||||
struct ieee80211_channel *channel;
|
||||
struct wmi_vdev_start_req_arg arg = {};
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
|
@ -922,7 +930,9 @@ static int ath12k_mac_monitor_vdev_start(struct ath12k *ar, int vdev_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
|
||||
params.vdev_id = vdev_id;
|
||||
params.bssid = ar->mac_addr;
|
||||
ret = ath12k_wmi_vdev_up(ar, ¶ms);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
|
||||
vdev_id, ret);
|
||||
|
|
@ -1289,37 +1299,188 @@ static int ath12k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ath12k_mac_set_arvif_ies(struct ath12k_vif *arvif, struct sk_buff *bcn,
|
||||
u8 bssid_index, bool *nontx_profile_found)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)bcn->data;
|
||||
const struct element *elem, *nontx, *index, *nie;
|
||||
const u8 *start, *tail;
|
||||
u16 rem_len;
|
||||
u8 i;
|
||||
|
||||
start = bcn->data + ieee80211_get_hdrlen_from_skb(bcn) + sizeof(mgmt->u.beacon);
|
||||
tail = skb_tail_pointer(bcn);
|
||||
rem_len = tail - start;
|
||||
|
||||
arvif->rsnie_present = false;
|
||||
arvif->wpaie_present = false;
|
||||
|
||||
if (cfg80211_find_ie(WLAN_EID_RSN, start, rem_len))
|
||||
arvif->rsnie_present = true;
|
||||
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||
start, rem_len))
|
||||
arvif->wpaie_present = true;
|
||||
|
||||
/* Return from here for the transmitted profile */
|
||||
if (!bssid_index)
|
||||
return;
|
||||
|
||||
/* Initial rsnie_present for the nontransmitted profile is set to be same as that
|
||||
* of the transmitted profile. It will be changed if security configurations are
|
||||
* different.
|
||||
*/
|
||||
*nontx_profile_found = false;
|
||||
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, rem_len) {
|
||||
/* Fixed minimum MBSSID element length with at least one
|
||||
* nontransmitted BSSID profile is 12 bytes as given below;
|
||||
* 1 (max BSSID indicator) +
|
||||
* 2 (Nontransmitted BSSID profile: Subelement ID + length) +
|
||||
* 4 (Nontransmitted BSSID Capabilities: tag + length + info)
|
||||
* 2 (Nontransmitted BSSID SSID: tag + length)
|
||||
* 3 (Nontransmitted BSSID Index: tag + length + BSSID index
|
||||
*/
|
||||
if (elem->datalen < 12 || elem->data[0] < 1)
|
||||
continue; /* Max BSSID indicator must be >=1 */
|
||||
|
||||
for_each_element(nontx, elem->data + 1, elem->datalen - 1) {
|
||||
start = nontx->data;
|
||||
|
||||
if (nontx->id != 0 || nontx->datalen < 4)
|
||||
continue; /* Invalid nontransmitted profile */
|
||||
|
||||
if (nontx->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
|
||||
nontx->data[1] != 2) {
|
||||
continue; /* Missing nontransmitted BSS capabilities */
|
||||
}
|
||||
|
||||
if (nontx->data[4] != WLAN_EID_SSID)
|
||||
continue; /* Missing SSID for nontransmitted BSS */
|
||||
|
||||
index = cfg80211_find_elem(WLAN_EID_MULTI_BSSID_IDX,
|
||||
start, nontx->datalen);
|
||||
if (!index || index->datalen < 1 || index->data[0] == 0)
|
||||
continue; /* Invalid MBSSID Index element */
|
||||
|
||||
if (index->data[0] == bssid_index) {
|
||||
*nontx_profile_found = true;
|
||||
if (cfg80211_find_ie(WLAN_EID_RSN,
|
||||
nontx->data,
|
||||
nontx->datalen)) {
|
||||
arvif->rsnie_present = true;
|
||||
return;
|
||||
} else if (!arvif->rsnie_present) {
|
||||
return; /* Both tx and nontx BSS are open */
|
||||
}
|
||||
|
||||
nie = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
|
||||
nontx->data,
|
||||
nontx->datalen);
|
||||
if (!nie || nie->datalen < 2)
|
||||
return; /* Invalid non-inheritance element */
|
||||
|
||||
for (i = 1; i < nie->datalen - 1; i++) {
|
||||
if (nie->data[i] == WLAN_EID_RSN) {
|
||||
arvif->rsnie_present = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ath12k_mac_setup_bcn_tmpl_ema(struct ath12k_vif *arvif)
|
||||
{
|
||||
struct ieee80211_bss_conf *bss_conf = &arvif->vif->bss_conf;
|
||||
struct ath12k_wmi_bcn_tmpl_ema_arg ema_args;
|
||||
struct ieee80211_ema_beacons *beacons;
|
||||
struct ath12k_vif *tx_arvif;
|
||||
bool nontx_profile_found = false;
|
||||
int ret = 0;
|
||||
u8 i;
|
||||
|
||||
tx_arvif = ath12k_vif_to_arvif(arvif->vif->mbssid_tx_vif);
|
||||
beacons = ieee80211_beacon_get_template_ema_list(ath12k_ar_to_hw(tx_arvif->ar),
|
||||
tx_arvif->vif, 0);
|
||||
if (!beacons || !beacons->cnt) {
|
||||
ath12k_warn(arvif->ar->ab,
|
||||
"failed to get ema beacon templates from mac80211\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (tx_arvif == arvif)
|
||||
ath12k_mac_set_arvif_ies(arvif, beacons->bcn[0].skb, 0, NULL);
|
||||
|
||||
for (i = 0; i < beacons->cnt; i++) {
|
||||
if (tx_arvif != arvif && !nontx_profile_found)
|
||||
ath12k_mac_set_arvif_ies(arvif, beacons->bcn[i].skb,
|
||||
bss_conf->bssid_index,
|
||||
&nontx_profile_found);
|
||||
|
||||
ema_args.bcn_cnt = beacons->cnt;
|
||||
ema_args.bcn_index = i;
|
||||
ret = ath12k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id,
|
||||
&beacons->bcn[i].offs,
|
||||
beacons->bcn[i].skb, &ema_args);
|
||||
if (ret) {
|
||||
ath12k_warn(tx_arvif->ar->ab,
|
||||
"failed to set ema beacon template id %i error %d\n",
|
||||
i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_arvif != arvif && !nontx_profile_found)
|
||||
ath12k_warn(arvif->ar->ab,
|
||||
"nontransmitted bssid index %u not found in beacon template\n",
|
||||
bss_conf->bssid_index);
|
||||
|
||||
ieee80211_beacon_free_ema_list(beacons);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
|
||||
{
|
||||
struct ath12k_vif *tx_arvif = arvif;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ieee80211_vif *vif = arvif->vif;
|
||||
struct ieee80211_mutable_offsets offs = {};
|
||||
bool nontx_profile_found = false;
|
||||
struct sk_buff *bcn;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
u8 *ies;
|
||||
int ret;
|
||||
|
||||
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
|
||||
return 0;
|
||||
|
||||
bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
|
||||
if (vif->mbssid_tx_vif) {
|
||||
tx_arvif = ath12k_vif_to_arvif(vif->mbssid_tx_vif);
|
||||
if (tx_arvif != arvif && arvif->is_up)
|
||||
return 0;
|
||||
|
||||
if (vif->bss_conf.ema_ap)
|
||||
return ath12k_mac_setup_bcn_tmpl_ema(arvif);
|
||||
}
|
||||
|
||||
bcn = ieee80211_beacon_get_template(ath12k_ar_to_hw(tx_arvif->ar), tx_arvif->vif,
|
||||
&offs, 0);
|
||||
if (!bcn) {
|
||||
ath12k_warn(ab, "failed to get beacon template from mac80211\n");
|
||||
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;
|
||||
if (tx_arvif == arvif) {
|
||||
ath12k_mac_set_arvif_ies(arvif, bcn, 0, NULL);
|
||||
} else {
|
||||
ath12k_mac_set_arvif_ies(arvif, bcn,
|
||||
arvif->vif->bss_conf.bssid_index,
|
||||
&nontx_profile_found);
|
||||
if (!nontx_profile_found)
|
||||
ath12k_warn(ab,
|
||||
"nontransmitted profile not found in beacon template\n");
|
||||
}
|
||||
|
||||
if (arvif->vif->type == NL80211_IFTYPE_AP && arvif->vif->p2p) {
|
||||
ret = ath12k_mac_setup_bcn_p2p_ie(arvif, bcn);
|
||||
|
|
@ -1344,7 +1505,7 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
|
|||
}
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
|
||||
ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, NULL);
|
||||
|
||||
if (ret)
|
||||
ath12k_warn(ab, "failed to submit beacon template command: %d\n",
|
||||
|
|
@ -1358,6 +1519,7 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
|
|||
static void ath12k_control_beaconing(struct ath12k_vif *arvif,
|
||||
struct ieee80211_bss_conf *info)
|
||||
{
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
struct ath12k *ar = arvif->ar;
|
||||
int ret;
|
||||
|
||||
|
|
@ -1385,8 +1547,15 @@ static void ath12k_control_beaconing(struct ath12k_vif *arvif,
|
|||
|
||||
ether_addr_copy(arvif->bssid, info->bssid);
|
||||
|
||||
ret = ath12k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
|
||||
arvif->bssid);
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
params.aid = arvif->aid;
|
||||
params.bssid = arvif->bssid;
|
||||
if (arvif->vif->mbssid_tx_vif) {
|
||||
params.tx_bssid = ath12k_vif_to_arvif(arvif->vif->mbssid_tx_vif)->bssid;
|
||||
params.nontx_profile_idx = info->bssid_index;
|
||||
params.nontx_profile_cnt = 1 << info->bssid_indicator;
|
||||
}
|
||||
ret = ath12k_wmi_vdev_up(arvif->ar, ¶ms);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
|
@ -2028,18 +2197,89 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar,
|
|||
}
|
||||
}
|
||||
|
||||
static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ath12k_wmi_peer_assoc_arg *arg)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
struct cfg80211_chan_def def;
|
||||
enum nl80211_band band;
|
||||
u8 ampdu_factor, mpdu_density;
|
||||
|
||||
if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
|
||||
return;
|
||||
|
||||
band = def.chan->band;
|
||||
|
||||
if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->deflink.he_6ghz_capa.capa)
|
||||
return;
|
||||
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)
|
||||
arg->bw_40 = true;
|
||||
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
arg->bw_80 = true;
|
||||
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)
|
||||
arg->bw_160 = true;
|
||||
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_320)
|
||||
arg->bw_320 = true;
|
||||
|
||||
arg->peer_he_caps_6ghz = le16_to_cpu(sta->deflink.he_6ghz_capa.capa);
|
||||
|
||||
mpdu_density = u32_get_bits(arg->peer_he_caps_6ghz,
|
||||
IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
|
||||
arg->peer_mpdu_density = ath12k_parse_mpdudensity(mpdu_density);
|
||||
|
||||
/* From IEEE Std 802.11ax-2021 - Section 10.12.2: An HE STA shall be capable of
|
||||
* receiving A-MPDU where the A-MPDU pre-EOF padding length is up to the value
|
||||
* indicated by the Maximum A-MPDU Length Exponent Extension field in the HE
|
||||
* Capabilities element and the Maximum A-MPDU Length Exponent field in HE 6 GHz
|
||||
* Band Capabilities element in the 6 GHz band.
|
||||
*
|
||||
* Here, we are extracting the Max A-MPDU Exponent Extension from HE caps and
|
||||
* factor is the Maximum A-MPDU Length Exponent from HE 6 GHZ Band capability.
|
||||
*/
|
||||
ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) +
|
||||
u32_get_bits(arg->peer_he_caps_6ghz,
|
||||
IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
|
||||
|
||||
arg->peer_max_mpdu = (1u << (IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR +
|
||||
ampdu_factor)) - 1;
|
||||
}
|
||||
|
||||
static int ath12k_get_smps_from_capa(const struct ieee80211_sta_ht_cap *ht_cap,
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
|
||||
int *smps)
|
||||
{
|
||||
if (!ht_cap->ht_supported && !he_6ghz_capa->capa)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ht_cap->ht_supported)
|
||||
*smps = u16_get_bits(ht_cap->cap, IEEE80211_HT_CAP_SM_PS);
|
||||
else
|
||||
*smps = le16_get_bits(he_6ghz_capa->capa,
|
||||
IEEE80211_HE_6GHZ_CAP_SM_PS);
|
||||
|
||||
if (*smps >= ARRAY_SIZE(ath12k_smps_map))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath12k_peer_assoc_h_smps(struct ieee80211_sta *sta,
|
||||
struct ath12k_wmi_peer_assoc_arg *arg)
|
||||
{
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa = &sta->deflink.he_6ghz_capa;
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
|
||||
int smps;
|
||||
|
||||
if (!ht_cap->ht_supported)
|
||||
if (ath12k_get_smps_from_capa(ht_cap, he_6ghz_capa, &smps))
|
||||
return;
|
||||
|
||||
smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
|
||||
switch (smps) {
|
||||
case WLAN_HT_CAP_SM_PS_STATIC:
|
||||
arg->static_mimops_flag = true;
|
||||
|
|
@ -2500,6 +2740,7 @@ static void ath12k_peer_assoc_prepare(struct ath12k *ar,
|
|||
ath12k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_he(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_he_6ghz(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_eht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_qos(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
|
|
@ -2510,18 +2751,14 @@ static void ath12k_peer_assoc_prepare(struct ath12k *ar,
|
|||
|
||||
static int ath12k_setup_peer_smps(struct ath12k *ar, struct ath12k_vif *arvif,
|
||||
const u8 *addr,
|
||||
const struct ieee80211_sta_ht_cap *ht_cap)
|
||||
const struct ieee80211_sta_ht_cap *ht_cap,
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa)
|
||||
{
|
||||
int smps;
|
||||
int smps, ret = 0;
|
||||
|
||||
if (!ht_cap->ht_supported)
|
||||
return 0;
|
||||
|
||||
smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
|
||||
if (smps >= ARRAY_SIZE(ath12k_smps_map))
|
||||
return -EINVAL;
|
||||
ret = ath12k_get_smps_from_capa(ht_cap, he_6ghz_capa, &smps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ath12k_wmi_set_peer_param(ar, addr, arvif->vdev_id,
|
||||
WMI_PEER_MIMO_PS_STATE,
|
||||
|
|
@ -2533,6 +2770,7 @@ static void ath12k_bss_assoc(struct ath12k *ar,
|
|||
struct ieee80211_bss_conf *bss_conf)
|
||||
{
|
||||
struct ieee80211_vif *vif = arvif->vif;
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
struct ath12k_wmi_peer_assoc_arg peer_arg;
|
||||
struct ieee80211_sta *ap_sta;
|
||||
struct ath12k_peer *peer;
|
||||
|
|
@ -2572,7 +2810,8 @@ static void ath12k_bss_assoc(struct ath12k *ar,
|
|||
}
|
||||
|
||||
ret = ath12k_setup_peer_smps(ar, arvif, bss_conf->bssid,
|
||||
&ap_sta->deflink.ht_cap);
|
||||
&ap_sta->deflink.ht_cap,
|
||||
&ap_sta->deflink.he_6ghz_capa);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
|
@ -2584,7 +2823,10 @@ static void ath12k_bss_assoc(struct ath12k *ar,
|
|||
arvif->aid = vif->cfg.aid;
|
||||
ether_addr_copy(arvif->bssid, bss_conf->bssid);
|
||||
|
||||
ret = ath12k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
params.aid = arvif->aid;
|
||||
params.bssid = arvif->bssid;
|
||||
ret = ath12k_wmi_vdev_up(ar, ¶ms);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to set vdev %d up: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
|
@ -3879,7 +4121,8 @@ static int ath12k_station_assoc(struct ath12k *ar,
|
|||
return 0;
|
||||
|
||||
ret = ath12k_setup_peer_smps(ar, arvif, sta->addr,
|
||||
&sta->deflink.ht_cap);
|
||||
&sta->deflink.ht_cap,
|
||||
&sta->deflink.he_6ghz_capa);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
|
@ -5269,6 +5512,7 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
|
|||
|
||||
static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
|
@ -5289,8 +5533,8 @@ static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
|
|||
ar->cfg_tx_chainmask = tx_ant;
|
||||
ar->cfg_rx_chainmask = rx_ant;
|
||||
|
||||
if (ar->state != ATH12K_STATE_ON &&
|
||||
ar->state != ATH12K_STATE_RESTARTED)
|
||||
if (ah->state != ATH12K_HW_STATE_ON &&
|
||||
ah->state != ATH12K_HW_STATE_RESTARTED)
|
||||
return 0;
|
||||
|
||||
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_TX_CHAIN_MASK,
|
||||
|
|
@ -5614,27 +5858,14 @@ static void ath12k_mac_wait_reconfigure(struct ath12k_base *ab)
|
|||
|
||||
static int ath12k_mac_start(struct ath12k *ar)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_pdev *pdev = ar->pdev;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
lockdep_assert_held(&ah->hw_mutex);
|
||||
|
||||
switch (ar->state) {
|
||||
case ATH12K_STATE_OFF:
|
||||
ar->state = ATH12K_STATE_ON;
|
||||
break;
|
||||
case ATH12K_STATE_RESTARTING:
|
||||
ar->state = ATH12K_STATE_RESTARTED;
|
||||
ath12k_mac_wait_reconfigure(ab);
|
||||
break;
|
||||
case ATH12K_STATE_RESTARTED:
|
||||
case ATH12K_STATE_WEDGED:
|
||||
case ATH12K_STATE_ON:
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS,
|
||||
1, pdev->pdev_id);
|
||||
|
|
@ -5726,7 +5957,6 @@ static int ath12k_mac_start(struct ath12k *ar)
|
|||
|
||||
return 0;
|
||||
err:
|
||||
ar->state = ATH12K_STATE_OFF;
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
|
|
@ -5749,9 +5979,30 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
|
|||
|
||||
ath12k_drain_tx(ah);
|
||||
|
||||
guard(mutex)(&ah->hw_mutex);
|
||||
|
||||
switch (ah->state) {
|
||||
case ATH12K_HW_STATE_OFF:
|
||||
ah->state = ATH12K_HW_STATE_ON;
|
||||
break;
|
||||
case ATH12K_HW_STATE_RESTARTING:
|
||||
ah->state = ATH12K_HW_STATE_RESTARTED;
|
||||
ath12k_mac_wait_reconfigure(ah->ab);
|
||||
break;
|
||||
case ATH12K_HW_STATE_RESTARTED:
|
||||
case ATH12K_HW_STATE_WEDGED:
|
||||
case ATH12K_HW_STATE_ON:
|
||||
ah->state = ATH12K_HW_STATE_OFF;
|
||||
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_ar(ah, ar, i) {
|
||||
ret = ath12k_mac_start(ar);
|
||||
if (ret) {
|
||||
ah->state = ATH12K_HW_STATE_OFF;
|
||||
|
||||
ath12k_err(ar->ab, "fail to start mac operations in pdev idx %d ret %d\n",
|
||||
ar->pdev_idx, ret);
|
||||
goto fail_start;
|
||||
|
|
@ -5759,11 +6010,13 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_start:
|
||||
for (; i > 0; i--) {
|
||||
ar = ath12k_ah_to_ar(ah, i - 1);
|
||||
ath12k_mac_stop(ar);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -5826,9 +6079,12 @@ int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable)
|
|||
|
||||
static void ath12k_mac_stop(struct ath12k *ar)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct htt_ppdu_stats_info *ppdu_stats, *tmp;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ah->hw_mutex);
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ret = ath12k_mac_config_mon_status_default(ar, false);
|
||||
if (ret && (ret != -EOPNOTSUPP))
|
||||
|
|
@ -5836,7 +6092,6 @@ static void ath12k_mac_stop(struct ath12k *ar)
|
|||
ret);
|
||||
|
||||
clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags);
|
||||
ar->state = ATH12K_STATE_OFF;
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
|
|
@ -5865,8 +6120,14 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
|
|||
|
||||
ath12k_drain_tx(ah);
|
||||
|
||||
mutex_lock(&ah->hw_mutex);
|
||||
|
||||
ah->state = ATH12K_HW_STATE_OFF;
|
||||
|
||||
for_each_ar(ah, ar, i)
|
||||
ath12k_mac_stop(ar);
|
||||
|
||||
mutex_unlock(&ah->hw_mutex);
|
||||
}
|
||||
|
||||
static u8
|
||||
|
|
@ -5892,17 +6153,59 @@ ath12k_mac_get_vdev_stats_id(struct ath12k_vif *arvif)
|
|||
return vdev_stats_id;
|
||||
}
|
||||
|
||||
static void ath12k_mac_setup_vdev_create_arg(struct ath12k_vif *arvif,
|
||||
struct ath12k_wmi_vdev_create_arg *arg)
|
||||
static int ath12k_mac_setup_vdev_params_mbssid(struct ath12k_vif *arvif,
|
||||
u32 *flags, u32 *tx_vdev_id)
|
||||
{
|
||||
struct ieee80211_vif *tx_vif = arvif->vif->mbssid_tx_vif;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ath12k_vif *tx_arvif;
|
||||
|
||||
if (!tx_vif)
|
||||
return 0;
|
||||
|
||||
tx_arvif = ath12k_vif_to_arvif(tx_vif);
|
||||
|
||||
if (arvif->vif->bss_conf.nontransmitted) {
|
||||
if (ar->ah->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy)
|
||||
return -EINVAL;
|
||||
|
||||
*flags = WMI_VDEV_MBSSID_FLAGS_NON_TRANSMIT_AP;
|
||||
*tx_vdev_id = tx_arvif->vdev_id;
|
||||
} else if (tx_arvif == arvif) {
|
||||
*flags = WMI_VDEV_MBSSID_FLAGS_TRANSMIT_AP;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arvif->vif->bss_conf.ema_ap)
|
||||
*flags |= WMI_VDEV_MBSSID_FLAGS_EMA_MODE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_mac_setup_vdev_create_arg(struct ath12k_vif *arvif,
|
||||
struct ath12k_wmi_vdev_create_arg *arg)
|
||||
{
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ath12k_pdev *pdev = ar->pdev;
|
||||
int ret;
|
||||
|
||||
arg->if_id = arvif->vdev_id;
|
||||
arg->type = arvif->vdev_type;
|
||||
arg->subtype = arvif->vdev_subtype;
|
||||
arg->pdev_id = pdev->pdev_id;
|
||||
|
||||
arg->mbssid_flags = WMI_VDEV_MBSSID_FLAGS_NON_MBSSID_AP;
|
||||
arg->mbssid_tx_vdev_id = 0;
|
||||
if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map)) {
|
||||
ret = ath12k_mac_setup_vdev_params_mbssid(arvif,
|
||||
&arg->mbssid_flags,
|
||||
&arg->mbssid_tx_vdev_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
|
||||
arg->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
|
||||
arg->chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;
|
||||
|
|
@ -5918,6 +6221,7 @@ static void ath12k_mac_setup_vdev_create_arg(struct ath12k_vif *arvif,
|
|||
}
|
||||
|
||||
arg->if_stats_id = ath12k_mac_get_vdev_stats_id(arvif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32
|
||||
|
|
@ -6099,7 +6403,12 @@ static int ath12k_mac_vdev_create(struct ath12k *ar, struct ieee80211_vif *vif)
|
|||
for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
|
||||
vif->hw_queue[i] = i % (ATH12K_HW_MAX_QUEUES - 1);
|
||||
|
||||
ath12k_mac_setup_vdev_create_arg(arvif, &vdev_arg);
|
||||
ret = ath12k_mac_setup_vdev_create_arg(arvif, &vdev_arg);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to create vdev parameters %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_vdev_create(ar, vif->addr, &vdev_arg);
|
||||
if (ret) {
|
||||
|
|
@ -6492,7 +6801,6 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ieee80211_vif *vif)
|
|||
|
||||
/* Recalc txpower for remaining vdev */
|
||||
ath12k_mac_txpower_recalc(ar);
|
||||
clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
|
||||
/* TODO: recal traffic pause state based on the available vdevs */
|
||||
arvif->is_created = false;
|
||||
|
|
@ -6563,15 +6871,9 @@ static void ath12k_mac_configure_filter(struct ath12k *ar,
|
|||
reset_flag = !(ar->filter_flags & FIF_BCN_PRBRESP_PROMISC);
|
||||
|
||||
ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, reset_flag);
|
||||
if (!ret) {
|
||||
if (!reset_flag)
|
||||
set_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
else
|
||||
clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
} else {
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab,
|
||||
"fail to set monitor filter: %d\n", ret);
|
||||
}
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"total_flags:0x%x, reset_flag:%d\n",
|
||||
|
|
@ -6848,10 +7150,16 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
|
|||
arg.pref_tx_streams = ar->num_tx_chains;
|
||||
arg.pref_rx_streams = ar->num_rx_chains;
|
||||
|
||||
/* Fill the MBSSID flags to indicate AP is non MBSSID by default
|
||||
* Corresponding flags would be updated with MBSSID support.
|
||||
*/
|
||||
arg.mbssid_flags = WMI_VDEV_MBSSID_FLAGS_NON_MBSSID_AP;
|
||||
arg.mbssid_tx_vdev_id = 0;
|
||||
if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map)) {
|
||||
ret = ath12k_mac_setup_vdev_params_mbssid(arvif,
|
||||
&arg.mbssid_flags,
|
||||
&arg.mbssid_tx_vdev_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
arg.ssid = arvif->u.ap.ssid;
|
||||
|
|
@ -7045,7 +7353,9 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
|
|||
struct ieee80211_vif_chanctx_switch *vifs,
|
||||
int n_vifs)
|
||||
{
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ath12k_vif *arvif;
|
||||
int ret;
|
||||
int i;
|
||||
|
|
@ -7054,9 +7364,10 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
|
|||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
for (i = 0; i < n_vifs; i++) {
|
||||
arvif = ath12k_vif_to_arvif(vifs[i].vif);
|
||||
vif = vifs[i].vif;
|
||||
arvif = ath12k_vif_to_arvif(vif);
|
||||
|
||||
if (vifs[i].vif->type == NL80211_IFTYPE_MONITOR)
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
monitor_vif = true;
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC,
|
||||
|
|
@ -7067,29 +7378,6 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
|
|||
vifs[i].old_ctx->def.width,
|
||||
vifs[i].new_ctx->def.width);
|
||||
|
||||
if (WARN_ON(!arvif->is_started))
|
||||
continue;
|
||||
|
||||
if (WARN_ON(!arvif->is_up))
|
||||
continue;
|
||||
|
||||
ret = ath12k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to down vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* All relevant vdevs are downed and associated channel resources
|
||||
* should be available for the channel switch now.
|
||||
*/
|
||||
|
||||
/* TODO: Update ar->rx_channel */
|
||||
|
||||
for (i = 0; i < n_vifs; i++) {
|
||||
arvif = ath12k_vif_to_arvif(vifs[i].vif);
|
||||
|
||||
if (WARN_ON(!arvif->is_started))
|
||||
continue;
|
||||
|
||||
|
|
@ -7125,8 +7413,16 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
|
|||
ath12k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath12k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
|
||||
arvif->bssid);
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
params.aid = arvif->aid;
|
||||
params.bssid = arvif->bssid;
|
||||
if (vif->mbssid_tx_vif) {
|
||||
params.tx_bssid = ath12k_vif_to_arvif(vif->mbssid_tx_vif)->bssid;
|
||||
params.nontx_profile_idx = vif->bss_conf.bssid_index;
|
||||
params.nontx_profile_cnt = 1 << vif->bss_conf.bssid_indicator;
|
||||
}
|
||||
ret = ath12k_wmi_vdev_up(arvif->ar, ¶ms);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to bring vdev up %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
|
@ -7259,7 +7555,6 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
struct ath12k_base *ab;
|
||||
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
|
||||
int ret;
|
||||
struct ath12k_wmi_peer_create_arg param;
|
||||
|
||||
/* For multi radio wiphy, the vdev was not created during add_interface
|
||||
* create now since we have a channel ctx now to assign to a specific ar/fw
|
||||
|
|
@ -7295,21 +7590,6 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (ab->hw_params->vdev_start_delay &&
|
||||
arvif->vdev_type != WMI_VDEV_TYPE_AP &&
|
||||
arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) {
|
||||
param.vdev_id = arvif->vdev_id;
|
||||
param.peer_type = WMI_PEER_TYPE_DEFAULT;
|
||||
param.peer_addr = ar->mac_addr;
|
||||
|
||||
ret = ath12k_peer_create(ar, arvif, NULL, ¶m);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to create peer after vdev start delay: %d",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
ret = ath12k_mac_monitor_start(ar);
|
||||
if (ret)
|
||||
|
|
@ -7371,11 +7651,6 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
|
||||
WARN_ON(!arvif->is_started);
|
||||
|
||||
if (ab->hw_params->vdev_start_delay &&
|
||||
arvif->vdev_type == WMI_VDEV_TYPE_MONITOR &&
|
||||
ath12k_peer_find_by_addr(ab, ar->mac_addr))
|
||||
ath12k_peer_delete(ar, arvif->vdev_id, ar->mac_addr);
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
ret = ath12k_mac_monitor_stop(ar);
|
||||
if (ret) {
|
||||
|
|
@ -7386,7 +7661,8 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
arvif->is_started = false;
|
||||
}
|
||||
|
||||
if (arvif->vdev_type != WMI_VDEV_TYPE_STA) {
|
||||
if (arvif->vdev_type != WMI_VDEV_TYPE_STA &&
|
||||
arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) {
|
||||
ath12k_bss_disassoc(ar, arvif);
|
||||
ret = ath12k_mac_vdev_stop(arvif);
|
||||
if (ret)
|
||||
|
|
@ -7395,10 +7671,6 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
}
|
||||
arvif->is_started = false;
|
||||
|
||||
if (ab->hw_params->vdev_start_delay &&
|
||||
arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
|
||||
ath12k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
|
||||
if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
|
||||
ar->num_started_vdevs == 1 && ar->monitor_vdev_created)
|
||||
ath12k_mac_monitor_stop(ar);
|
||||
|
|
@ -7920,26 +8192,33 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
struct ath12k *ar;
|
||||
struct ath12k_base *ab;
|
||||
struct ath12k_vif *arvif;
|
||||
int recovery_count;
|
||||
int recovery_count, i;
|
||||
|
||||
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
|
||||
return;
|
||||
|
||||
ar = ath12k_ah_to_ar(ah, 0);
|
||||
ab = ar->ab;
|
||||
guard(mutex)(&ah->hw_mutex);
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ah->state != ATH12K_HW_STATE_RESTARTED)
|
||||
return;
|
||||
|
||||
ah->state = ATH12K_HW_STATE_ON;
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
for_each_ar(ah, ar, i) {
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ab = ar->ab;
|
||||
|
||||
if (ar->state == ATH12K_STATE_RESTARTED) {
|
||||
ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
|
||||
ar->pdev->pdev_id);
|
||||
ar->state = ATH12K_STATE_ON;
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
if (ab->is_reset) {
|
||||
recovery_count = atomic_inc_return(&ab->recovery_count);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "recovery count %d\n",
|
||||
recovery_count);
|
||||
|
||||
/* When there are multiple radios in an SOC,
|
||||
* the recovery has to be done for each radio
|
||||
*/
|
||||
|
|
@ -7958,6 +8237,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
arvif->key_cipher,
|
||||
arvif->is_up,
|
||||
arvif->vdev_type);
|
||||
|
||||
/* After trigger disconnect, then upper layer will
|
||||
* trigger connect again, then the PN number of
|
||||
* upper layer will be reset to keep up with AP
|
||||
|
|
@ -7967,13 +8247,14 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
arvif->vdev_type == WMI_VDEV_TYPE_STA &&
|
||||
arvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE) {
|
||||
ieee80211_hw_restart_disconnect(arvif->vif);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"restart disconnect\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8026,6 +8307,17 @@ static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,
|
|||
|
||||
if (!sband)
|
||||
sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
|
||||
if (sband && idx >= sband->n_channels) {
|
||||
idx -= sband->n_channels;
|
||||
sband = NULL;
|
||||
}
|
||||
|
||||
if (!sband)
|
||||
sband = hw->wiphy->bands[NL80211_BAND_6GHZ];
|
||||
if (!sband || idx >= sband->n_channels) {
|
||||
idx -= sband->n_channels;
|
||||
sband = NULL;
|
||||
}
|
||||
|
||||
if (!sband || idx >= sband->n_channels)
|
||||
return -ENOENT;
|
||||
|
|
@ -8488,19 +8780,23 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah)
|
|||
|
||||
static const u8 ath12k_if_types_ext_capa[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
|
||||
};
|
||||
|
||||
static const u8 ath12k_if_types_ext_capa_sta[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
|
||||
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
|
||||
};
|
||||
|
||||
static const u8 ath12k_if_types_ext_capa_ap[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
|
||||
[9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT,
|
||||
[10] = WLAN_EXT_CAPA11_EMA_SUPPORT,
|
||||
};
|
||||
|
||||
static const struct wiphy_iftype_ext_capab ath12k_iftypes_ext_capa[] = {
|
||||
|
|
@ -8685,7 +8981,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
|
||||
ieee80211_hw_set(hw, REPORTS_LOW_ACK);
|
||||
|
||||
if (ht_cap & WMI_HT_CAP_ENABLED) {
|
||||
if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) {
|
||||
ieee80211_hw_set(hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
|
||||
ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
|
||||
|
|
@ -8700,7 +8996,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
* for each band for a dual band capable radio. It will be tricky to
|
||||
* handle it when the ht capability different for each band.
|
||||
*/
|
||||
if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS)
|
||||
if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS ||
|
||||
(ar->supports_6ghz && ab->hw_params->supports_dynamic_smps_6ghz))
|
||||
wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
|
||||
|
||||
wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
|
||||
|
|
@ -8739,6 +9036,9 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
|
||||
wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa);
|
||||
|
||||
wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS;
|
||||
wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;
|
||||
|
||||
if (is_6ghz) {
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_FILS_DISCOVERY);
|
||||
|
|
@ -8842,7 +9142,6 @@ static void ath12k_mac_setup(struct ath12k *ar)
|
|||
|
||||
INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
|
||||
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
|
||||
clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
}
|
||||
|
||||
int ath12k_mac_register(struct ath12k_base *ab)
|
||||
|
|
@ -8917,8 +9216,11 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
|
|||
|
||||
ah = ath12k_hw_to_ah(hw);
|
||||
ah->hw = hw;
|
||||
ah->ab = ab;
|
||||
ah->num_radio = num_pdev_map;
|
||||
|
||||
mutex_init(&ah->hw_mutex);
|
||||
|
||||
for (i = 0; i < num_pdev_map; i++) {
|
||||
ab = pdev_map[i].ab;
|
||||
pdev_idx = pdev_map[i].pdev_idx;
|
||||
|
|
@ -8927,7 +9229,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
|
|||
ar = ath12k_ah_to_ar(ah, i);
|
||||
ar->ah = ah;
|
||||
ar->ab = ab;
|
||||
ar->hw_link_id = i;
|
||||
ar->hw_link_id = pdev->hw_link_id;
|
||||
ar->pdev = pdev;
|
||||
ar->pdev_idx = pdev_idx;
|
||||
pdev->ar = ar;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#define MHI_TIMEOUT_DEFAULT_MS 90000
|
||||
#define OTP_INVALID_BOARD_ID 0xFFFF
|
||||
#define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000
|
||||
#define MHI_CB_INVALID 0xff
|
||||
|
||||
static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = {
|
||||
{
|
||||
|
|
@ -268,6 +269,7 @@ static void ath12k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
|
|||
enum mhi_callback cb)
|
||||
{
|
||||
struct ath12k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
|
||||
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "mhi notify status reason %s\n",
|
||||
ath12k_mhi_op_callback_to_str(cb));
|
||||
|
|
@ -277,12 +279,20 @@ static void ath12k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
|
|||
ath12k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
|
||||
break;
|
||||
case MHI_CB_EE_RDDM:
|
||||
if (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"do not queue again for consecutive RDDM event\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags)))
|
||||
queue_work(ab->workqueue_aux, &ab->reset_work);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ab_pci->mhi_pre_cb = cb;
|
||||
}
|
||||
|
||||
static int ath12k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
|
||||
|
|
@ -313,6 +323,7 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci)
|
|||
if (!mhi_ctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
ab_pci->mhi_pre_cb = MHI_CB_INVALID;
|
||||
ab_pci->mhi_ctrl = mhi_ctrl;
|
||||
mhi_ctrl->cntrl_dev = ab->dev;
|
||||
mhi_ctrl->regs = ab->mem;
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ static void ath12k_pci_free_ext_irq(struct ath12k_base *ab)
|
|||
free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
|
||||
|
||||
netif_napi_del(&irq_grp->napi);
|
||||
free_netdev(irq_grp->napi_ndev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -560,8 +561,9 @@ static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg)
|
|||
static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
|
||||
int i, j, ret, num_vectors = 0;
|
||||
int i, j, n, ret, num_vectors = 0;
|
||||
u32 user_base_data = 0, base_vector = 0, base_idx;
|
||||
struct ath12k_ext_irq_grp *irq_grp;
|
||||
|
||||
base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
|
||||
ret = ath12k_pci_get_user_msi_assignment(ab, "DP",
|
||||
|
|
@ -572,13 +574,18 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
|
|||
return ret;
|
||||
|
||||
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
irq_grp = &ab->ext_irq_grp[i];
|
||||
u32 num_irq = 0;
|
||||
|
||||
irq_grp->ab = ab;
|
||||
irq_grp->grp_id = i;
|
||||
init_dummy_netdev(&irq_grp->napi_ndev);
|
||||
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
|
||||
irq_grp->napi_ndev = alloc_netdev_dummy(0);
|
||||
if (!irq_grp->napi_ndev) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_allocate;
|
||||
}
|
||||
|
||||
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
|
||||
ath12k_pci_ext_grp_napi_poll);
|
||||
|
||||
if (ab->hw_params->ring_mask->tx[i] ||
|
||||
|
|
@ -611,13 +618,23 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
|
|||
if (ret) {
|
||||
ath12k_err(ab, "failed request irq %d: %d\n",
|
||||
vector, ret);
|
||||
return ret;
|
||||
goto fail_request;
|
||||
}
|
||||
}
|
||||
ath12k_pci_ext_grp_disable(irq_grp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_request:
|
||||
/* i ->napi_ndev was properly allocated. Free it also */
|
||||
i += 1;
|
||||
fail_allocate:
|
||||
for (n = 0; n < i; n++) {
|
||||
irq_grp = &ab->ext_irq_grp[n];
|
||||
free_netdev(irq_grp->napi_ndev);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_pci_set_irq_affinity_hint(struct ath12k_pci *ab_pci,
|
||||
|
|
@ -1090,14 +1107,14 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab)
|
|||
{
|
||||
int i;
|
||||
|
||||
set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
|
||||
|
||||
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
|
||||
napi_enable(&irq_grp->napi);
|
||||
ath12k_pci_ext_grp_enable(irq_grp);
|
||||
}
|
||||
|
||||
set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
|
||||
}
|
||||
|
||||
void ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
|
||||
|
|
@ -1285,6 +1302,13 @@ void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend)
|
|||
ath12k_pci_sw_reset(ab_pci->ab, false);
|
||||
}
|
||||
|
||||
static int ath12k_pci_panic_handler(struct ath12k_base *ab)
|
||||
{
|
||||
ath12k_pci_sw_reset(ab, false);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
|
||||
.start = ath12k_pci_start,
|
||||
.stop = ath12k_pci_stop,
|
||||
|
|
@ -1302,6 +1326,7 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
|
|||
.ce_irq_enable = ath12k_pci_hif_ce_irq_enable,
|
||||
.ce_irq_disable = ath12k_pci_hif_ce_irq_disable,
|
||||
.get_ce_msi_idx = ath12k_pci_get_ce_msi_idx,
|
||||
.panic_handler = ath12k_pci_panic_handler,
|
||||
};
|
||||
|
||||
static
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ struct ath12k_pci {
|
|||
struct mhi_controller *mhi_ctrl;
|
||||
const struct ath12k_msi_config *msi_config;
|
||||
unsigned long mhi_state;
|
||||
enum mhi_callback mhi_pre_cb;
|
||||
u32 register_window;
|
||||
|
||||
/* protects register_window above */
|
||||
|
|
|
|||
|
|
@ -2041,7 +2041,7 @@ static void ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
|
|||
req->mlo_capable_valid = 1;
|
||||
req->mlo_capable = 1;
|
||||
req->mlo_chip_id_valid = 1;
|
||||
req->mlo_chip_id = 0;
|
||||
req->mlo_chip_id = ab->device_id;
|
||||
req->mlo_group_id_valid = 1;
|
||||
req->mlo_group_id = 0;
|
||||
req->max_mlo_peer_valid = 1;
|
||||
|
|
@ -2053,7 +2053,7 @@ static void ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
|
|||
req->mlo_num_chips = 1;
|
||||
|
||||
info = &req->mlo_chip_info[0];
|
||||
info->chip_id = 0;
|
||||
info->chip_id = ab->device_id;
|
||||
info->num_local_links = ab->qmi.num_radios;
|
||||
|
||||
for (i = 0; i < info->num_local_links; i++) {
|
||||
|
|
@ -2503,7 +2503,7 @@ static int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
|
|||
ab->qmi.dev_mem[i].size =
|
||||
resp.dev_mem[i].size;
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"devmem [%d] start ox%llx size %llu\n", i,
|
||||
"devmem [%d] start 0x%llx size %llu\n", i,
|
||||
ab->qmi.dev_mem[i].start,
|
||||
ab->qmi.dev_mem[i].size);
|
||||
}
|
||||
|
|
@ -2538,7 +2538,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
|
|||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
const u8 *temp = data;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
u32 remaining = len;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -206,9 +206,9 @@ static void ath12k_copy_regd(struct ieee80211_regdomain *regd_orig,
|
|||
|
||||
int ath12k_regd_update(struct ath12k *ar, bool init)
|
||||
{
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
|
||||
struct ieee80211_hw *hw = ah->hw;
|
||||
struct ieee80211_regdomain *regd, *regd_copy = NULL;
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
int ret, regd_len, pdev_id;
|
||||
struct ath12k_base *ab;
|
||||
int i;
|
||||
|
|
@ -286,19 +286,20 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (ah->state != ATH12K_HW_STATE_ON)
|
||||
goto skip;
|
||||
|
||||
ah->regd_updated = true;
|
||||
/* Apply the new regd to all the radios, this is expected to be received only once
|
||||
* since we check for ah->regd_updated and allow here only once.
|
||||
*/
|
||||
for_each_ar(ah, ar, i) {
|
||||
if (ar->state == ATH12K_STATE_ON) {
|
||||
ab = ar->ab;
|
||||
ret = ath12k_reg_update_chan_list(ar);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
ab = ar->ab;
|
||||
ret = ath12k_reg_update_chan_list(ar);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
skip:
|
||||
return 0;
|
||||
err:
|
||||
ath12k_warn(ab, "failed to perform regd update : %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -228,6 +228,9 @@ void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
|
|||
config->peer_map_unmap_version = 0x32;
|
||||
config->twt_ap_pdev_count = ab->num_radios;
|
||||
config->twt_ap_sta_count = 1000;
|
||||
config->ema_max_vap_cnt = ab->num_radios;
|
||||
config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD;
|
||||
config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt;
|
||||
|
||||
if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map))
|
||||
config->dp_peer_meta_data_ver = TARGET_RX_PEER_METADATA_VER_V1B;
|
||||
|
|
@ -497,6 +500,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
mac_caps = wmi_mac_phy_caps + phy_idx;
|
||||
|
||||
pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps);
|
||||
pdev->hw_link_id = ath12k_wmi_mac_phy_get_hw_link_id(mac_caps);
|
||||
pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands);
|
||||
pdev_cap->ampdu_density = le32_to_cpu(mac_caps->ampdu_density);
|
||||
|
||||
|
|
@ -841,6 +845,8 @@ int ath12k_wmi_vdev_create(struct ath12k *ar, u8 *macaddr,
|
|||
cmd->vdev_subtype = cpu_to_le32(args->subtype);
|
||||
cmd->num_cfg_txrx_streams = cpu_to_le32(WMI_NUM_SUPPORTED_BAND_MAX);
|
||||
cmd->pdev_id = cpu_to_le32(args->pdev_id);
|
||||
cmd->mbssid_flags = cpu_to_le32(args->mbssid_flags);
|
||||
cmd->mbssid_tx_vdev_id = cpu_to_le32(args->mbssid_tx_vdev_id);
|
||||
cmd->vdev_stats_id = cpu_to_le32(args->if_stats_id);
|
||||
ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
|
||||
|
||||
|
|
@ -1046,6 +1052,7 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
|
|||
cmd->he_ops = cpu_to_le32(arg->he_ops);
|
||||
cmd->punct_bitmap = cpu_to_le32(arg->punct_bitmap);
|
||||
cmd->mbssid_flags = cpu_to_le32(arg->mbssid_flags);
|
||||
cmd->mbssid_tx_vdev_id = cpu_to_le32(arg->mbssid_tx_vdev_id);
|
||||
|
||||
if (!restart) {
|
||||
if (arg->ssid) {
|
||||
|
|
@ -1097,7 +1104,7 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_vdev_up(struct ath12k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
|
||||
int ath12k_wmi_vdev_up(struct ath12k *ar, struct ath12k_wmi_vdev_up_params *params)
|
||||
{
|
||||
struct ath12k_wmi_pdev *wmi = ar->wmi;
|
||||
struct wmi_vdev_up_cmd *cmd;
|
||||
|
|
@ -1112,14 +1119,20 @@ int ath12k_wmi_vdev_up(struct ath12k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
|
|||
|
||||
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_VDEV_UP_CMD,
|
||||
sizeof(*cmd));
|
||||
cmd->vdev_id = cpu_to_le32(vdev_id);
|
||||
cmd->vdev_assoc_id = cpu_to_le32(aid);
|
||||
cmd->vdev_id = cpu_to_le32(params->vdev_id);
|
||||
cmd->vdev_assoc_id = cpu_to_le32(params->aid);
|
||||
|
||||
ether_addr_copy(cmd->vdev_bssid.addr, bssid);
|
||||
ether_addr_copy(cmd->vdev_bssid.addr, params->bssid);
|
||||
|
||||
if (params->tx_bssid) {
|
||||
ether_addr_copy(cmd->tx_vdev_bssid.addr, params->tx_bssid);
|
||||
cmd->nontx_profile_idx = cpu_to_le32(params->nontx_profile_idx);
|
||||
cmd->nontx_profile_cnt = cpu_to_le32(params->nontx_profile_cnt);
|
||||
}
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
|
||||
"WMI mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
|
||||
vdev_id, aid, bssid);
|
||||
params->vdev_id, params->aid, params->bssid);
|
||||
|
||||
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID);
|
||||
if (ret) {
|
||||
|
|
@ -1776,13 +1789,15 @@ int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
|
|||
|
||||
int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
|
||||
struct ieee80211_mutable_offsets *offs,
|
||||
struct sk_buff *bcn)
|
||||
struct sk_buff *bcn,
|
||||
struct ath12k_wmi_bcn_tmpl_ema_arg *ema_args)
|
||||
{
|
||||
struct ath12k_wmi_pdev *wmi = ar->wmi;
|
||||
struct wmi_bcn_tmpl_cmd *cmd;
|
||||
struct ath12k_wmi_bcn_prb_info_params *bcn_prb_info;
|
||||
struct wmi_tlv *tlv;
|
||||
struct sk_buff *skb;
|
||||
u32 ema_params = 0;
|
||||
void *ptr;
|
||||
int ret, len;
|
||||
size_t aligned_len = roundup(bcn->len, 4);
|
||||
|
|
@ -1801,6 +1816,16 @@ int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
|
|||
cmd->csa_switch_count_offset = cpu_to_le32(offs->cntdwn_counter_offs[0]);
|
||||
cmd->ext_csa_switch_count_offset = cpu_to_le32(offs->cntdwn_counter_offs[1]);
|
||||
cmd->buf_len = cpu_to_le32(bcn->len);
|
||||
cmd->mbssid_ie_offset = cpu_to_le32(offs->mbssid_off);
|
||||
if (ema_args) {
|
||||
u32p_replace_bits(&ema_params, ema_args->bcn_cnt, WMI_EMA_BEACON_CNT);
|
||||
u32p_replace_bits(&ema_params, ema_args->bcn_index, WMI_EMA_BEACON_IDX);
|
||||
if (ema_args->bcn_index == 0)
|
||||
u32p_replace_bits(&ema_params, 1, WMI_EMA_BEACON_FIRST);
|
||||
if (ema_args->bcn_index + 1 == ema_args->bcn_cnt)
|
||||
u32p_replace_bits(&ema_params, 1, WMI_EMA_BEACON_LAST);
|
||||
cmd->ema_params = cpu_to_le32(ema_params);
|
||||
}
|
||||
|
||||
ptr = skb->data + sizeof(*cmd);
|
||||
|
||||
|
|
@ -3475,9 +3500,11 @@ ath12k_wmi_copy_resource_config(struct ath12k_wmi_resource_config_params *wmi_cf
|
|||
wmi_cfg->twt_ap_sta_count = cpu_to_le32(tg_cfg->twt_ap_sta_count);
|
||||
wmi_cfg->flags2 = le32_encode_bits(tg_cfg->dp_peer_meta_data_ver,
|
||||
WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION);
|
||||
|
||||
wmi_cfg->host_service_flags = cpu_to_le32(tg_cfg->is_reg_cc_ext_event_supported <<
|
||||
WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT);
|
||||
wmi_cfg->ema_max_vap_cnt = cpu_to_le32(tg_cfg->ema_max_vap_cnt);
|
||||
wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
|
||||
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET);
|
||||
}
|
||||
|
||||
static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,
|
||||
|
|
@ -3808,7 +3835,7 @@ int ath12k_wmi_pdev_dma_ring_cfg(struct ath12k *ar,
|
|||
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_DMA_RING_CFG_REQ,
|
||||
sizeof(*cmd));
|
||||
|
||||
cmd->pdev_id = cpu_to_le32(DP_SW2HW_MACID(arg->pdev_id));
|
||||
cmd->pdev_id = cpu_to_le32(arg->pdev_id);
|
||||
cmd->module_id = cpu_to_le32(arg->module_id);
|
||||
cmd->base_paddr_lo = cpu_to_le32(arg->base_paddr_lo);
|
||||
cmd->base_paddr_hi = cpu_to_le32(arg->base_paddr_hi);
|
||||
|
|
@ -5693,7 +5720,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
|
|||
* event. Otherwise, it goes to fallback.
|
||||
*/
|
||||
if (ab->hw_params->single_pdev_only &&
|
||||
pdev_idx < ab->hw_params->num_rxmda_per_pdev)
|
||||
pdev_idx < ab->hw_params->num_rxdma_per_pdev)
|
||||
goto mem_free;
|
||||
else
|
||||
goto fallback;
|
||||
|
|
@ -6022,8 +6049,10 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
|
||||
status->flag |= RX_FLAG_MMIC_ERROR;
|
||||
|
||||
if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ) {
|
||||
if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ &&
|
||||
rx_ev.chan_freq <= ATH12K_MAX_6G_FREQ) {
|
||||
status->band = NL80211_BAND_6GHZ;
|
||||
status->freq = rx_ev.chan_freq;
|
||||
} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
|
||||
status->band = NL80211_BAND_2GHZ;
|
||||
} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH12K_MAX_5G_CHAN) {
|
||||
|
|
@ -6044,8 +6073,10 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
|
||||
sband = &ar->mac.sbands[status->band];
|
||||
|
||||
status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
|
||||
status->band);
|
||||
if (status->band != NL80211_BAND_6GHZ)
|
||||
status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
|
||||
status->band);
|
||||
|
||||
status->signal = rx_ev.snr + ATH12K_DEFAULT_NOISE_FLOOR;
|
||||
status->rate_idx = ath12k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
|
||||
|
||||
|
|
|
|||
|
|
@ -2154,6 +2154,7 @@ enum wmi_tlv_service {
|
|||
WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213,
|
||||
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
|
||||
WMI_TLV_SERVICE_EXT2_MSG = 220,
|
||||
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
|
||||
|
||||
WMI_MAX_EXT_SERVICE = 256,
|
||||
|
||||
|
|
@ -2356,6 +2357,8 @@ struct ath12k_wmi_resource_config_arg {
|
|||
u32 twt_ap_sta_count;
|
||||
bool is_reg_cc_ext_event_supported;
|
||||
u8 dp_peer_meta_data_ver;
|
||||
u32 ema_max_vap_cnt;
|
||||
u32 ema_max_profile_period;
|
||||
};
|
||||
|
||||
struct ath12k_wmi_init_cmd_arg {
|
||||
|
|
@ -2410,6 +2413,7 @@ struct wmi_init_cmd {
|
|||
#define WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT 4
|
||||
#define WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION GENMASK(5, 4)
|
||||
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||||
#define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
|
||||
|
||||
struct ath12k_wmi_resource_config_params {
|
||||
__le32 tlv_header;
|
||||
|
|
@ -2726,6 +2730,8 @@ struct ath12k_wmi_vdev_create_arg {
|
|||
} chains[NUM_NL80211_BANDS];
|
||||
u32 pdev_id;
|
||||
u8 if_stats_id;
|
||||
u32 mbssid_flags;
|
||||
u32 mbssid_tx_vdev_id;
|
||||
};
|
||||
|
||||
#define ATH12K_MAX_VDEV_STATS_ID 0x30
|
||||
|
|
@ -2757,14 +2763,23 @@ struct wmi_vdev_delete_cmd {
|
|||
__le32 vdev_id;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_wmi_vdev_up_params {
|
||||
u32 vdev_id;
|
||||
u32 aid;
|
||||
const u8 *bssid;
|
||||
const u8 *tx_bssid;
|
||||
u32 nontx_profile_idx;
|
||||
u32 nontx_profile_cnt;
|
||||
};
|
||||
|
||||
struct wmi_vdev_up_cmd {
|
||||
__le32 tlv_header;
|
||||
__le32 vdev_id;
|
||||
__le32 vdev_assoc_id;
|
||||
struct ath12k_wmi_mac_addr_params vdev_bssid;
|
||||
struct ath12k_wmi_mac_addr_params trans_bssid;
|
||||
__le32 profile_idx;
|
||||
__le32 profile_num;
|
||||
struct ath12k_wmi_mac_addr_params tx_vdev_bssid;
|
||||
__le32 nontx_profile_idx;
|
||||
__le32 nontx_profile_cnt;
|
||||
} __packed;
|
||||
|
||||
struct wmi_vdev_stop_cmd {
|
||||
|
|
@ -2792,6 +2807,10 @@ struct ath12k_wmi_ssid_params {
|
|||
|
||||
enum wmi_vdev_mbssid_flags {
|
||||
WMI_VDEV_MBSSID_FLAGS_NON_MBSSID_AP = BIT(0),
|
||||
WMI_VDEV_MBSSID_FLAGS_TRANSMIT_AP = BIT(1),
|
||||
WMI_VDEV_MBSSID_FLAGS_NON_TRANSMIT_AP = BIT(2),
|
||||
WMI_VDEV_MBSSID_FLAGS_EMA_MODE = BIT(3),
|
||||
WMI_VDEV_MBSSID_FLAGS_SCAN_MODE_VAP = BIT(4),
|
||||
};
|
||||
|
||||
struct wmi_vdev_start_request_cmd {
|
||||
|
|
@ -3514,6 +3533,16 @@ struct ath12k_wmi_p2p_noa_info {
|
|||
|
||||
#define WMI_BEACON_TX_BUFFER_SIZE 512
|
||||
|
||||
#define WMI_EMA_BEACON_CNT GENMASK(7, 0)
|
||||
#define WMI_EMA_BEACON_IDX GENMASK(15, 8)
|
||||
#define WMI_EMA_BEACON_FIRST GENMASK(23, 16)
|
||||
#define WMI_EMA_BEACON_LAST GENMASK(31, 24)
|
||||
|
||||
struct ath12k_wmi_bcn_tmpl_ema_arg {
|
||||
u8 bcn_cnt;
|
||||
u8 bcn_index;
|
||||
};
|
||||
|
||||
struct wmi_bcn_tmpl_cmd {
|
||||
__le32 tlv_header;
|
||||
__le32 vdev_id;
|
||||
|
|
@ -3524,6 +3553,11 @@ struct wmi_bcn_tmpl_cmd {
|
|||
__le32 csa_event_bitmap;
|
||||
__le32 mbssid_ie_offset;
|
||||
__le32 esp_ie_offset;
|
||||
__le32 csc_switch_count_offset;
|
||||
__le32 csc_event_bitmap;
|
||||
__le32 mu_edca_ie_offset;
|
||||
__le32 feature_enable_bitmap;
|
||||
__le32 ema_params;
|
||||
} __packed;
|
||||
|
||||
struct wmi_p2p_go_set_beacon_ie_cmd {
|
||||
|
|
@ -4770,7 +4804,7 @@ struct wmi_probe_tmpl_cmd {
|
|||
__le32 buf_len;
|
||||
} __packed;
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
#define MAX_RADIOS 2
|
||||
|
||||
#define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ)
|
||||
#define WMI_SEND_TIMEOUT_HZ (3 * HZ)
|
||||
|
|
@ -4881,10 +4915,10 @@ int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
|
|||
const u8 *p2p_ie);
|
||||
int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
|
||||
struct ieee80211_mutable_offsets *offs,
|
||||
struct sk_buff *bcn);
|
||||
struct sk_buff *bcn,
|
||||
struct ath12k_wmi_bcn_tmpl_ema_arg *ema_args);
|
||||
int ath12k_wmi_vdev_down(struct ath12k *ar, u8 vdev_id);
|
||||
int ath12k_wmi_vdev_up(struct ath12k *ar, u32 vdev_id, u32 aid,
|
||||
const u8 *bssid);
|
||||
int ath12k_wmi_vdev_up(struct ath12k *ar, struct ath12k_wmi_vdev_up_params *params);
|
||||
int ath12k_wmi_vdev_stop(struct ath12k *ar, u8 vdev_id);
|
||||
int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
|
||||
bool restart);
|
||||
|
|
|
|||
|
|
@ -453,16 +453,21 @@ int wil_if_add(struct wil6210_priv *wil)
|
|||
return rc;
|
||||
}
|
||||
|
||||
init_dummy_netdev(&wil->napi_ndev);
|
||||
wil->napi_ndev = alloc_netdev_dummy(0);
|
||||
if (!wil->napi_ndev) {
|
||||
wil_err(wil, "failed to allocate dummy netdev");
|
||||
rc = -ENOMEM;
|
||||
goto out_wiphy;
|
||||
}
|
||||
if (wil->use_enhanced_dma_hw) {
|
||||
netif_napi_add(&wil->napi_ndev, &wil->napi_rx,
|
||||
netif_napi_add(wil->napi_ndev, &wil->napi_rx,
|
||||
wil6210_netdev_poll_rx_edma);
|
||||
netif_napi_add_tx(&wil->napi_ndev,
|
||||
netif_napi_add_tx(wil->napi_ndev,
|
||||
&wil->napi_tx, wil6210_netdev_poll_tx_edma);
|
||||
} else {
|
||||
netif_napi_add(&wil->napi_ndev, &wil->napi_rx,
|
||||
netif_napi_add(wil->napi_ndev, &wil->napi_rx,
|
||||
wil6210_netdev_poll_rx);
|
||||
netif_napi_add_tx(&wil->napi_ndev,
|
||||
netif_napi_add_tx(wil->napi_ndev,
|
||||
&wil->napi_tx, wil6210_netdev_poll_tx);
|
||||
}
|
||||
|
||||
|
|
@ -474,10 +479,12 @@ int wil_if_add(struct wil6210_priv *wil)
|
|||
wiphy_unlock(wiphy);
|
||||
rtnl_unlock();
|
||||
if (rc < 0)
|
||||
goto out_wiphy;
|
||||
goto free_dummy;
|
||||
|
||||
return 0;
|
||||
|
||||
free_dummy:
|
||||
free_netdev(wil->napi_ndev);
|
||||
out_wiphy:
|
||||
wiphy_unregister(wiphy);
|
||||
return rc;
|
||||
|
|
@ -554,5 +561,7 @@ void wil_if_remove(struct wil6210_priv *wil)
|
|||
netif_napi_del(&wil->napi_tx);
|
||||
netif_napi_del(&wil->napi_rx);
|
||||
|
||||
free_netdev(wil->napi_ndev);
|
||||
|
||||
wiphy_unregister(wiphy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -983,7 +983,7 @@ struct wil6210_priv {
|
|||
spinlock_t eap_lock; /* guarding access to eap rekey fields */
|
||||
struct napi_struct napi_rx;
|
||||
struct napi_struct napi_tx;
|
||||
struct net_device napi_ndev; /* dummy net_device serving all VIFs */
|
||||
struct net_device *napi_ndev; /* dummy net_device serving all VIFs */
|
||||
|
||||
/* DMA related */
|
||||
struct wil_ring ring_rx;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user