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

ath.git patches for v6.4. Major changes:

wcn36xx

* support for pronto v3 hardware

ath11k

* PCIe DeviceTree bindings

* WCN6750: enable SAR support

ath10k

* convert DeviceTree bindings to YAML
This commit is contained in:
Kalle Valo 2023-04-20 19:43:45 +03:00
Родитель d2a158d113 b100722a77
Коммит 3288ee5844
41 изменённых файлов: 898 добавлений и 444 удалений

Просмотреть файл

@ -1,215 +0,0 @@
* Qualcomm Atheros ath10k wireless devices
Required properties:
- compatible: Should be one of the following:
* "qcom,ath10k"
* "qcom,ipq4019-wifi"
* "qcom,wcn3990-wifi"
PCI based devices uses compatible string "qcom,ath10k" and takes calibration
data along with board specific data via "qcom,ath10k-calibration-data".
Rest of the properties are not applicable for PCI based devices.
AHB based devices (i.e. ipq4019) uses compatible string "qcom,ipq4019-wifi"
and also uses most of the properties defined in this doc (except
"qcom,ath10k-calibration-data"). It uses "qcom,ath10k-pre-calibration-data"
to carry pre calibration data.
In general, entry "qcom,ath10k-pre-calibration-data" and
"qcom,ath10k-calibration-data" conflict with each other and only one
can be provided per device.
SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
- reg: Address and length of the register set for the device.
- reg-names: Must include the list of following reg names,
"membase"
- interrupts: reference to the list of 17 interrupt numbers for "qcom,ipq4019-wifi"
compatible target.
reference to the list of 12 interrupt numbers for "qcom,wcn3990-wifi"
compatible target.
Must contain interrupt-names property per entry for
"qcom,ath10k", "qcom,ipq4019-wifi" compatible targets.
- interrupt-names: Must include the entries for MSI interrupt
names ("msi0" to "msi15") and legacy interrupt
name ("legacy") for "qcom,ath10k", "qcom,ipq4019-wifi"
compatible targets.
Optional properties:
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reseti.txt for details.
- reset-names: Must include the list of following reset names,
"wifi_cpu_init"
"wifi_radio_srif"
"wifi_radio_warm"
"wifi_radio_cold"
"wifi_core_warm"
"wifi_core_cold"
- clocks: List of clock specifiers, must contain an entry for each required
entry in clock-names.
- clock-names: Should contain the clock names "wifi_wcss_cmd", "wifi_wcss_ref",
"wifi_wcss_rtc" for "qcom,ipq4019-wifi" compatible target and
"cxo_ref_clk_pin" and optionally "qdss" for "qcom,wcn3990-wifi"
compatible target.
- qcom,msi_addr: MSI interrupt address.
- qcom,msi_base: Base value to add before writing MSI data into
MSI address register.
- qcom,ath10k-calibration-variant: string to search for in the board-2.bin
variant list with the same bus and device
specific ids
- qcom,ath10k-calibration-data : calibration data + board specific data
as an array, the length can vary between
hw versions.
- qcom,ath10k-pre-calibration-data : pre calibration data as an array,
the length can vary between hw versions.
- <supply-name>-supply: handle to the regulator device tree node
optional "supply-name" are "vdd-0.8-cx-mx",
"vdd-1.8-xo", "vdd-1.3-rfa", "vdd-3.3-ch0",
and "vdd-3.3-ch1".
- memory-region:
Usage: optional
Value type: <phandle>
Definition: reference to the reserved-memory for the msa region
used by the wifi firmware running in Q6.
- iommus:
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of phandle and IOMMU specifier pairs.
- ext-fem-name:
Usage: Optional
Value type: string
Definition: Name of external front end module used. Some valid FEM names
for example: "microsemi-lx5586", "sky85703-11"
and "sky85803" etc.
- qcom,snoc-host-cap-8bit-quirk:
Usage: Optional
Value type: <empty>
Definition: Quirk specifying that the firmware expects the 8bit version
of the host capability QMI request
- qcom,xo-cal-data: xo cal offset to be configured in xo trim register.
- qcom,msa-fixed-perm: Boolean context flag to disable SCM call for statically
mapped msa region.
- qcom,coexist-support : should contain eithr "0" or "1" to indicate coex
support by the hardware.
- qcom,coexist-gpio-pin : gpio pin number information to support coex
which will be used by wifi firmware.
* Subnodes
The ath10k wifi node can contain one optional firmware subnode.
Firmware subnode is needed when the platform does not have TustZone.
The firmware subnode must have:
- iommus:
Usage: required
Value type: <prop-encoded-array>
Definition: A list of phandle and IOMMU specifier pairs.
Example (to supply PCI based wifi block details):
In this example, the node is defined as child node of the PCI controller.
pci {
pcie@0 {
reg = <0 0 0 0 0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
wifi@0,0 {
reg = <0 0 0 0 0>;
qcom,ath10k-calibration-data = [ 01 02 03 ... ];
ext-fem-name = "microsemi-lx5586";
};
};
};
Example (to supply ipq4019 SoC wifi block details):
wifi0: wifi@a000000 {
compatible = "qcom,ipq4019-wifi";
reg = <0xa000000 0x200000>;
resets = <&gcc WIFI0_CPU_INIT_RESET>,
<&gcc WIFI0_RADIO_SRIF_RESET>,
<&gcc WIFI0_RADIO_WARM_RESET>,
<&gcc WIFI0_RADIO_COLD_RESET>,
<&gcc WIFI0_CORE_WARM_RESET>,
<&gcc WIFI0_CORE_COLD_RESET>;
reset-names = "wifi_cpu_init",
"wifi_radio_srif",
"wifi_radio_warm",
"wifi_radio_cold",
"wifi_core_warm",
"wifi_core_cold";
clocks = <&gcc GCC_WCSS2G_CLK>,
<&gcc GCC_WCSS2G_REF_CLK>,
<&gcc GCC_WCSS2G_RTC_CLK>;
clock-names = "wifi_wcss_cmd",
"wifi_wcss_ref",
"wifi_wcss_rtc";
interrupts = <0 0x20 0x1>,
<0 0x21 0x1>,
<0 0x22 0x1>,
<0 0x23 0x1>,
<0 0x24 0x1>,
<0 0x25 0x1>,
<0 0x26 0x1>,
<0 0x27 0x1>,
<0 0x28 0x1>,
<0 0x29 0x1>,
<0 0x2a 0x1>,
<0 0x2b 0x1>,
<0 0x2c 0x1>,
<0 0x2d 0x1>,
<0 0x2e 0x1>,
<0 0x2f 0x1>,
<0 0xa8 0x0>;
interrupt-names = "msi0", "msi1", "msi2", "msi3",
"msi4", "msi5", "msi6", "msi7",
"msi8", "msi9", "msi10", "msi11",
"msi12", "msi13", "msi14", "msi15",
"legacy";
qcom,msi_addr = <0x0b006040>;
qcom,msi_base = <0x40>;
qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ];
qcom,coexist-support = <1>;
qcom,coexist-gpio-pin = <0x33>;
};
Example (to supply wcn3990 SoC wifi block details):
wifi@18000000 {
compatible = "qcom,wcn3990-wifi";
reg = <0x18800000 0x800000>;
reg-names = "membase";
clocks = <&clock_gcc clk_rf_clk2_pin>;
clock-names = "cxo_ref_clk_pin";
interrupts =
<GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
vdd-0.8-cx-mx-supply = <&pm8998_l5>;
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
vdd-3.3-ch1-supply = <&vreg_l26a_3p3>;
memory-region = <&wifi_msa_mem>;
iommus = <&apps_smmu 0x0040 0x1>;
qcom,msa-fixed-perm;
wifi-firmware {
iommus = <&apps_iommu 0xc22 0x1>;
};
};

Просмотреть файл

@ -0,0 +1,358 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/wireless/qcom,ath10k.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies ath10k wireless devices
maintainers:
- Kalle Valo <kvalo@kernel.org>
description:
Qualcomm Technologies, Inc. IEEE 802.11ac devices.
properties:
compatible:
enum:
- qcom,ath10k # SDIO-based devices
- qcom,ipq4019-wifi
- qcom,wcn3990-wifi # SNoC-based devices
reg:
maxItems: 1
reg-names:
items:
- const: membase
interrupts:
minItems: 12
maxItems: 17
interrupt-names:
minItems: 12
maxItems: 17
memory-region:
maxItems: 1
description:
Reference to the MSA memory region used by the Wi-Fi firmware
running on the Q6 core.
iommus:
minItems: 1
maxItems: 2
clocks:
minItems: 1
maxItems: 3
clock-names:
minItems: 1
maxItems: 3
resets:
maxItems: 6
reset-names:
items:
- const: wifi_cpu_init
- const: wifi_radio_srif
- const: wifi_radio_warm
- const: wifi_radio_cold
- const: wifi_core_warm
- const: wifi_core_cold
ext-fem-name:
$ref: /schemas/types.yaml#/definitions/string
description: Name of external front end module used.
enum:
- microsemi-lx5586
- sky85703-11
- sky85803
wifi-firmware:
type: object
additionalProperties: false
description: |
The ath10k Wi-Fi node can contain one optional firmware subnode.
Firmware subnode is needed when the platform does not have Trustzone.
properties:
iommus:
maxItems: 1
required:
- iommus
qcom,ath10k-calibration-data:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Calibration data + board-specific data as a byte array. The length
can vary between hardware versions.
qcom,ath10k-calibration-variant:
$ref: /schemas/types.yaml#/definitions/string
description:
Unique variant identifier of the calibration data in board-2.bin
for designs with colliding bus and device specific ids
qcom,ath10k-pre-calibration-data:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Pre-calibration data as a byte array. The length can vary between
hardware versions.
qcom,coexist-support:
$ref: /schemas/types.yaml#/definitions/uint8
enum: [0, 1]
description:
Indicate coex support by the hardware.
qcom,coexist-gpio-pin:
$ref: /schemas/types.yaml#/definitions/uint32
description:
COEX GPIO number provided to the Wi-Fi firmware.
qcom,msa-fixed-perm:
type: boolean
description:
Whether to skip executing an SCM call that reassigns the memory
region ownership.
qcom,smem-states:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: State bits used by the AP to signal the WLAN Q6.
items:
- description: Signal bits used to enable/disable low power mode
on WCN in the case of WoW (Wake on Wireless).
qcom,smem-state-names:
description: The names of the state bits used for SMP2P output.
items:
- const: wlan-smp2p-out
qcom,snoc-host-cap-8bit-quirk:
type: boolean
description:
Quirk specifying that the firmware expects the 8bit version
of the host capability QMI request
qcom,xo-cal-data:
$ref: /schemas/types.yaml#/definitions/uint32
description:
XO cal offset to be configured in XO trim register.
vdd-0.8-cx-mx-supply:
description: Main logic power rail
vdd-1.8-xo-supply:
description: Crystal oscillator supply
vdd-1.3-rfa-supply:
description: RFA supply
vdd-3.3-ch0-supply:
description: Primary Wi-Fi antenna supply
vdd-3.3-ch1-supply:
description: Secondary Wi-Fi antenna supply
required:
- compatible
- reg
additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,ipq4019-wifi
then:
properties:
interrupts:
minItems: 17
maxItems: 17
interrupt-names:
items:
- const: msi0
- const: msi1
- const: msi2
- const: msi3
- const: msi4
- const: msi5
- const: msi6
- const: msi7
- const: msi8
- const: msi9
- const: msi10
- const: msi11
- const: msi12
- const: msi13
- const: msi14
- const: msi15
- const: legacy
clocks:
items:
- description: Wi-Fi command clock
- description: Wi-Fi reference clock
- description: Wi-Fi RTC clock
clock-names:
items:
- const: wifi_wcss_cmd
- const: wifi_wcss_ref
- const: wifi_wcss_rtc
required:
- clocks
- clock-names
- interrupts
- interrupt-names
- resets
- reset-names
- if:
properties:
compatible:
contains:
enum:
- qcom,wcn3990-wifi
then:
properties:
clocks:
minItems: 1
items:
- description: XO reference clock
- description: Qualcomm Debug Subsystem clock
clock-names:
minItems: 1
items:
- const: cxo_ref_clk_pin
- const: qdss
interrupts:
items:
- description: CE0
- description: CE1
- description: CE2
- description: CE3
- description: CE4
- description: CE5
- description: CE6
- description: CE7
- description: CE8
- description: CE9
- description: CE10
- description: CE11
interrupt-names: false
required:
- interrupts
examples:
# SNoC
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
wifi@18800000 {
compatible = "qcom,wcn3990-wifi";
reg = <0x18800000 0x800000>;
reg-names = "membase";
memory-region = <&wlan_msa_mem>;
clocks = <&rpmcc RPM_SMD_RF_CLK2_PIN>;
clock-names = "cxo_ref_clk_pin";
interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&anoc2_smmu 0x1900>,
<&anoc2_smmu 0x1901>;
qcom,snoc-host-cap-8bit-quirk;
vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
wifi-firmware {
iommus = <&apps_smmu 0x1c02 0x1>;
};
};
# AHB
- |
#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
wifi@a000000 {
compatible = "qcom,ipq4019-wifi";
reg = <0xa000000 0x200000>;
resets = <&gcc WIFI0_CPU_INIT_RESET>,
<&gcc WIFI0_RADIO_SRIF_RESET>,
<&gcc WIFI0_RADIO_WARM_RESET>,
<&gcc WIFI0_RADIO_COLD_RESET>,
<&gcc WIFI0_CORE_WARM_RESET>,
<&gcc WIFI0_CORE_COLD_RESET>;
reset-names = "wifi_cpu_init",
"wifi_radio_srif",
"wifi_radio_warm",
"wifi_radio_cold",
"wifi_core_warm",
"wifi_core_cold";
clocks = <&gcc GCC_WCSS2G_CLK>,
<&gcc GCC_WCSS2G_REF_CLK>,
<&gcc GCC_WCSS2G_RTC_CLK>;
clock-names = "wifi_wcss_cmd",
"wifi_wcss_ref",
"wifi_wcss_rtc";
interrupts = <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 39 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 40 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 41 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 42 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 43 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 45 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 46 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 47 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
"msi3",
"msi4",
"msi5",
"msi6",
"msi7",
"msi8",
"msi9",
"msi10",
"msi11",
"msi12",
"msi13",
"msi14",
"msi15",
"legacy";
};

Просмотреть файл

@ -0,0 +1,58 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (c) 2023 Linaro Limited
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/wireless/qcom,ath11k-pci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies ath11k wireless devices (PCIe)
maintainers:
- Kalle Valo <kvalo@kernel.org>
description: |
Qualcomm Technologies IEEE 802.11ax PCIe devices
properties:
compatible:
enum:
- pci17cb,1103 # WCN6855
reg:
maxItems: 1
qcom,ath11k-calibration-variant:
$ref: /schemas/types.yaml#/definitions/string
description: |
string to uniquely identify variant of the calibration data for designs
with colliding bus and device ids
required:
- compatible
- reg
additionalProperties: false
examples:
- |
pcie {
#address-cells = <3>;
#size-cells = <2>;
pcie@0 {
device_type = "pci";
reg = <0x0 0x0 0x0 0x0 0x0>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
bus-range = <0x01 0xff>;
wifi@0 {
compatible = "pci17cb,1103";
reg = <0x10000 0x0 0x0 0x0 0x0>;
qcom,ath11k-calibration-variant = "LE_X13S";
};
};
};

Просмотреть файл

@ -17218,7 +17218,7 @@ S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
F: drivers/net/wireless/ath/ath10k/
F: Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
F: Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
M: Kalle Valo <kvalo@kernel.org>

Просмотреть файл

@ -84,13 +84,6 @@ ath10k_set_ring_byte(unsigned int offset,
return ((offset << addr_map->lsb) & addr_map->mask);
}
static inline unsigned int
ath10k_get_ring_byte(unsigned int offset,
struct ath10k_hw_ce_regs_addr_map *addr_map)
{
return ((offset & addr_map->mask) >> (addr_map->lsb));
}
static inline u32 ath10k_ce_read32(struct ath10k *ar, u32 offset)
{
struct ath10k_ce *ce = ath10k_ce_priv(ar);

Просмотреть файл

@ -3406,15 +3406,12 @@ static int ath10k_pci_claim(struct ath10k *ar)
if (!ar_pci->mem) {
ath10k_err(ar, "failed to iomap BAR%d\n", BAR_NUM);
ret = -EIO;
goto err_master;
goto err_region;
}
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%pK\n", ar_pci->mem);
return 0;
err_master:
pci_clear_master(pdev);
err_region:
pci_release_region(pdev, BAR_NUM);
@ -3431,7 +3428,6 @@ static void ath10k_pci_release(struct ath10k *ar)
pci_iounmap(pdev, ar_pci->mem);
pci_release_region(pdev, BAR_NUM);
pci_clear_master(pdev);
pci_disable_device(pdev);
}

Просмотреть файл

@ -1078,6 +1078,12 @@ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
struct iommu_domain *iommu;
size_t unmapped_size;
/* Chipsets not requiring MSA would have not initialized
* MSA resources, return success in such cases.
*/
if (!ab->hw_params.fixed_fw_mem)
return 0;
if (ab_ahb->fw.use_tz)
return 0;

Просмотреть файл

@ -116,7 +116,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tcl_ring_retry = true,
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.ftm_responder = true,
},
{
.hw_rev = ATH11K_HW_IPQ6018_HW10,
@ -199,7 +198,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = false,
.ftm_responder = true,
},
{
.name = "qca6390 hw2.0",
@ -284,7 +282,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = true,
.ftm_responder = false,
},
{
.name = "qcn9074 hw1.0",
@ -366,7 +363,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = false,
.ftm_responder = true,
},
{
.name = "wcn6855 hw2.0",
@ -451,7 +447,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = true,
.ftm_responder = false,
},
{
.name = "wcn6855 hw2.1",
@ -534,7 +529,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = true,
.ftm_responder = false,
},
{
.name = "wcn6750 hw1.0",
@ -599,7 +593,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.current_cc_support = true,
.dbr_debug_support = false,
.global_reset = false,
.bios_sar_capa = NULL,
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
.m3_fw_support = false,
.fixed_bdf_addr = false,
.fixed_mem_region = false,
@ -615,7 +609,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
.smp2p_wow_exit = true,
.support_fw_mac_sequence = true,
.ftm_responder = false,
},
{
.hw_rev = ATH11K_HW_IPQ5018_HW10,
@ -695,7 +688,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
.smp2p_wow_exit = false,
.support_fw_mac_sequence = false,
.ftm_responder = true,
},
};

Просмотреть файл

@ -26,13 +26,13 @@ int ath11k_dbring_validate_buffer(struct ath11k *ar, void *buffer, u32 size)
static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
void *buffer, u32 size)
{
u32 *temp;
int idx;
/* memset32 function fills buffer payload with the ATH11K_DB_MAGIC_VALUE
* and the variable size is expected to be the number of u32 values
* to be stored, not the number of bytes.
*/
size = size / sizeof(u32);
size = size >> 2;
for (idx = 0, temp = buffer; idx < size; idx++, temp++)
*temp++ = ATH11K_DB_MAGIC_VALUE;
memset32(buffer, ATH11K_DB_MAGIC_VALUE, size);
}
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,

Просмотреть файл

@ -143,7 +143,8 @@ enum htt_tx_pdev_underrun_enum {
/* Bytes stored in little endian order */
/* Length should be multiple of DWORD */
struct htt_stats_string_tlv {
u32 data[0]; /* Can be variable length */
/* Can be variable length */
DECLARE_FLEX_ARRAY(u32, data);
} __packed;
#define HTT_STATS_MAC_ID GENMASK(7, 0)
@ -205,27 +206,32 @@ struct htt_tx_pdev_stats_cmn_tlv {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_pdev_stats_urrn_tlv_v {
u32 urrn_stats[0]; /* HTT_TX_PDEV_MAX_URRN_STATS */
/* HTT_TX_PDEV_MAX_URRN_STATS */
DECLARE_FLEX_ARRAY(u32, urrn_stats);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_pdev_stats_flush_tlv_v {
u32 flush_errs[0]; /* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */
/* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */
DECLARE_FLEX_ARRAY(u32, flush_errs);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_pdev_stats_sifs_tlv_v {
u32 sifs_status[0]; /* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */
/* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */
DECLARE_FLEX_ARRAY(u32, sifs_status);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_pdev_stats_phy_err_tlv_v {
u32 phy_errs[0]; /* HTT_TX_PDEV_MAX_PHY_ERR_STATS */
/* HTT_TX_PDEV_MAX_PHY_ERR_STATS */
DECLARE_FLEX_ARRAY(u32, phy_errs);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_pdev_stats_sifs_hist_tlv_v {
u32 sifs_hist_status[0]; /* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */
/* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */
DECLARE_FLEX_ARRAY(u32, sifs_hist_status);
};
struct htt_tx_pdev_stats_tx_ppdu_stats_tlv_v {
@ -590,20 +596,20 @@ struct htt_tx_hwq_difs_latency_stats_tlv_v {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_hwq_cmd_result_stats_tlv_v {
/* Histogram of sched cmd result */
u32 cmd_result[0]; /* HTT_TX_HWQ_MAX_CMD_RESULT_STATS */
/* Histogram of sched cmd result, HTT_TX_HWQ_MAX_CMD_RESULT_STATS */
DECLARE_FLEX_ARRAY(u32, cmd_result);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_hwq_cmd_stall_stats_tlv_v {
/* Histogram of various pause conitions */
u32 cmd_stall_status[0]; /* HTT_TX_HWQ_MAX_CMD_STALL_STATS */
/* Histogram of various pause conitions, HTT_TX_HWQ_MAX_CMD_STALL_STATS */
DECLARE_FLEX_ARRAY(u32, cmd_stall_status);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_hwq_fes_result_stats_tlv_v {
/* Histogram of number of user fes result */
u32 fes_result[0]; /* HTT_TX_HWQ_MAX_FES_RESULT_STATS */
/* Histogram of number of user fes result, HTT_TX_HWQ_MAX_FES_RESULT_STATS */
DECLARE_FLEX_ARRAY(u32, fes_result);
};
/* NOTE: Variable length TLV, use length spec to infer array size
@ -635,8 +641,8 @@ struct htt_tx_hwq_tried_mpdu_cnt_hist_tlv_v {
* #define WAL_TXOP_USED_HISTOGRAM_INTERVAL 1000 ( 1 ms )
*/
struct htt_tx_hwq_txop_used_cnt_hist_tlv_v {
/* Histogram of txop used cnt */
u32 txop_used_cnt_hist[0]; /* HTT_TX_HWQ_TXOP_USED_CNT_HIST */
/* Histogram of txop used cnt, HTT_TX_HWQ_TXOP_USED_CNT_HIST */
DECLARE_FLEX_ARRAY(u32, txop_used_cnt_hist);
};
/* == TX SELFGEN STATS == */
@ -804,17 +810,20 @@ struct htt_tx_pdev_mpdu_stats_tlv {
/* == TX SCHED STATS == */
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_sched_txq_cmd_posted_tlv_v {
u32 sched_cmd_posted[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */
/* HTT_TX_PDEV_SCHED_TX_MODE_MAX */
DECLARE_FLEX_ARRAY(u32, sched_cmd_posted);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_sched_txq_cmd_reaped_tlv_v {
u32 sched_cmd_reaped[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */
/* HTT_TX_PDEV_SCHED_TX_MODE_MAX */
DECLARE_FLEX_ARRAY(u32, sched_cmd_reaped);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_sched_txq_sched_order_su_tlv_v {
u32 sched_order_su[0]; /* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */
/* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */
DECLARE_FLEX_ARRAY(u32, sched_order_su);
};
enum htt_sched_txq_sched_ineligibility_tlv_enum {
@ -842,7 +851,7 @@ enum htt_sched_txq_sched_ineligibility_tlv_enum {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_sched_txq_sched_ineligibility_tlv_v {
/* indexed by htt_sched_txq_sched_ineligibility_tlv_enum */
u32 sched_ineligibility[0];
DECLARE_FLEX_ARRAY(u32, sched_ineligibility);
};
#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0)
@ -888,18 +897,20 @@ struct htt_stats_tx_sched_cmn_tlv {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_tqm_gen_mpdu_stats_tlv_v {
u32 gen_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */
/* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */
DECLARE_FLEX_ARRAY(u32, gen_mpdu_end_reason);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_tqm_list_mpdu_stats_tlv_v {
u32 list_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */
/* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */
DECLARE_FLEX_ARRAY(u32, list_mpdu_end_reason);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_tx_tqm_list_mpdu_cnt_tlv_v {
u32 list_mpdu_cnt_hist[0];
/* HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS */
DECLARE_FLEX_ARRAY(u32, list_mpdu_cnt_hist);
};
struct htt_tx_tqm_pdev_stats_tlv_v {
@ -1098,7 +1109,7 @@ struct htt_tx_de_compl_stats_tlv {
* ENTRIES_PER_BIN_COUNT)
*/
struct htt_tx_de_fw2wbm_ring_full_hist_tlv {
u32 fw2wbm_ring_full_hist[0];
DECLARE_FLEX_ARRAY(u32, fw2wbm_ring_full_hist);
};
struct htt_tx_de_cmn_stats_tlv {
@ -1151,7 +1162,7 @@ struct htt_ring_if_cmn_tlv {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_sfm_client_user_tlv_v {
/* Number of DWORDS used per user and per client */
u32 dwords_used_by_user_n[0];
DECLARE_FLEX_ARRAY(u32, dwords_used_by_user_n);
};
struct htt_sfm_client_tlv {
@ -1436,12 +1447,14 @@ struct htt_rx_soc_fw_stats_tlv {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_soc_fw_refill_ring_empty_tlv_v {
u32 refill_ring_empty_cnt[0]; /* HTT_RX_STATS_REFILL_MAX_RING */
/* HTT_RX_STATS_REFILL_MAX_RING */
DECLARE_FLEX_ARRAY(u32, refill_ring_empty_cnt);
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_soc_fw_refill_ring_num_refill_tlv_v {
u32 refill_ring_num_refill[0]; /* HTT_RX_STATS_REFILL_MAX_RING */
/* HTT_RX_STATS_REFILL_MAX_RING */
DECLARE_FLEX_ARRAY(u32, refill_ring_num_refill);
};
/* RXDMA error code from WBM released packets */
@ -1473,7 +1486,7 @@ enum htt_rx_rxdma_error_code_enum {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v {
u32 rxdma_err[0]; /* HTT_RX_RXDMA_MAX_ERR_CODE */
DECLARE_FLEX_ARRAY(u32, rxdma_err); /* HTT_RX_RXDMA_MAX_ERR_CODE */
};
/* REO error code from WBM released packets */
@ -1505,7 +1518,7 @@ enum htt_rx_reo_error_code_enum {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_soc_fw_refill_ring_num_reo_err_tlv_v {
u32 reo_err[0]; /* HTT_RX_REO_MAX_ERR_CODE */
DECLARE_FLEX_ARRAY(u32, reo_err); /* HTT_RX_REO_MAX_ERR_CODE */
};
/* == RX PDEV STATS == */
@ -1622,13 +1635,13 @@ struct htt_rx_pdev_fw_stats_phy_err_tlv {
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_pdev_fw_ring_mpdu_err_tlv_v {
/* Num error MPDU for each RxDMA error type */
u32 fw_ring_mpdu_err[0]; /* HTT_RX_STATS_RXDMA_MAX_ERR */
DECLARE_FLEX_ARRAY(u32, fw_ring_mpdu_err); /* HTT_RX_STATS_RXDMA_MAX_ERR */
};
/* NOTE: Variable length TLV, use length spec to infer array size */
struct htt_rx_pdev_fw_mpdu_drop_tlv_v {
/* Num MPDU dropped */
u32 fw_mpdu_drop[0]; /* HTT_RX_STATS_FW_DROP_REASON_MAX */
DECLARE_FLEX_ARRAY(u32, fw_mpdu_drop); /* HTT_RX_STATS_FW_DROP_REASON_MAX */
};
#define HTT_PDEV_CCA_STATS_TX_FRAME_INFO_PRESENT (0x1)

Просмотреть файл

@ -36,6 +36,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
}
ath11k_peer_rx_tid_cleanup(ar, peer);
peer->dp_setup_done = false;
crypto_free_shash(peer->tfm_mmic);
spin_unlock_bh(&ab->base_lock);
}
@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
if (ret) {
ath11k_warn(ab, "failed to setup rx defrag context\n");
return ret;
tid--;
goto peer_clean;
}
/* TODO: Setup other peer specific resource used in data path */

Просмотреть файл

@ -214,7 +214,7 @@ struct ath11k_pdev_dp {
#define DP_REO_REINJECT_RING_SIZE 32
#define DP_RX_RELEASE_RING_SIZE 1024
#define DP_REO_EXCEPTION_RING_SIZE 128
#define DP_REO_CMD_RING_SIZE 128
#define DP_REO_CMD_RING_SIZE 256
#define DP_REO_STATUS_RING_SIZE 2048
#define DP_RXDMA_BUF_RING_SIZE 4096
#define DP_RXDMA_REFILL_RING_SIZE 2048
@ -303,12 +303,16 @@ struct ath11k_dp {
#define HTT_TX_WBM_COMP_STATUS_OFFSET 8
#define HTT_INVALID_PEER_ID 0xffff
/* HTT tx completion is overlaid in wbm_release_ring */
#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(12, 9)
#define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13)
#define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13)
#define HTT_TX_WBM_COMP_INFO1_ACK_RSSI GENMASK(31, 24)
#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID GENMASK(15, 0)
#define HTT_TX_WBM_COMP_INFO2_VALID BIT(21)
struct htt_tx_wbm_completion {
u32 info0;

Просмотреть файл

@ -389,10 +389,10 @@ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
goto fail_free_skb;
spin_lock_bh(&rx_ring->idr_lock);
buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
rx_ring->bufs_max * 3, GFP_ATOMIC);
buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,
(rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);
spin_unlock_bh(&rx_ring->idr_lock);
if (buf_id < 0)
if (buf_id <= 0)
goto fail_dma_unmap;
desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
@ -435,7 +435,6 @@ fail_free_skb:
static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar,
struct dp_rxdma_ring *rx_ring)
{
struct ath11k_pdev_dp *dp = &ar->dp;
struct sk_buff *skb;
int buf_id;
@ -453,28 +452,6 @@ static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar,
idr_destroy(&rx_ring->bufs_idr);
spin_unlock_bh(&rx_ring->idr_lock);
/* if rxdma1_enable is false, mon_status_refill_ring
* isn't setup, so don't clean.
*/
if (!ar->ab->hw_params.rxdma1_enable)
return 0;
rx_ring = &dp->rx_mon_status_refill_ring[0];
spin_lock_bh(&rx_ring->idr_lock);
idr_for_each_entry(&rx_ring->bufs_idr, skb, buf_id) {
idr_remove(&rx_ring->bufs_idr, buf_id);
/* XXX: Understand where internal driver does this dma_unmap
* of rxdma_buffer.
*/
dma_unmap_single(ar->ab->dev, ATH11K_SKB_RXCB(skb)->paddr,
skb->len + skb_tailroom(skb), DMA_BIDIRECTIONAL);
dev_kfree_skb_any(skb);
}
idr_destroy(&rx_ring->bufs_idr);
spin_unlock_bh(&rx_ring->idr_lock);
return 0;
}
@ -691,13 +668,18 @@ void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab)
struct ath11k_dp *dp = &ab->dp;
struct dp_reo_cmd *cmd, *tmp;
struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache;
struct dp_rx_tid *rx_tid;
spin_lock_bh(&dp->reo_cmd_lock);
list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {
list_del(&cmd->list);
dma_unmap_single(ab->dev, cmd->data.paddr,
cmd->data.size, DMA_BIDIRECTIONAL);
kfree(cmd->data.vaddr);
rx_tid = &cmd->data;
if (rx_tid->vaddr) {
dma_unmap_single(ab->dev, rx_tid->paddr,
rx_tid->size, DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
kfree(cmd);
}
@ -705,9 +687,13 @@ void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab)
&dp->reo_cmd_cache_flush_list, list) {
list_del(&cmd_cache->list);
dp->reo_cmd_cache_flush_count--;
dma_unmap_single(ab->dev, cmd_cache->data.paddr,
cmd_cache->data.size, DMA_BIDIRECTIONAL);
kfree(cmd_cache->data.vaddr);
rx_tid = &cmd_cache->data;
if (rx_tid->vaddr) {
dma_unmap_single(ab->dev, rx_tid->paddr,
rx_tid->size, DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
kfree(cmd_cache);
}
spin_unlock_bh(&dp->reo_cmd_lock);
@ -721,10 +707,12 @@ static void ath11k_dp_reo_cmd_free(struct ath11k_dp *dp, void *ctx,
if (status != HAL_REO_CMD_SUCCESS)
ath11k_warn(dp->ab, "failed to flush rx tid hw desc, tid %d status %d\n",
rx_tid->tid, status);
if (rx_tid->vaddr) {
dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size,
DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
}
static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab,
@ -763,6 +751,7 @@ static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab,
dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,
DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
}
@ -815,6 +804,7 @@ free_desc:
dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,
DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
void ath11k_peer_rx_tid_delete(struct ath11k *ar,
@ -827,6 +817,8 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar,
if (!rx_tid->active)
return;
rx_tid->active = false;
cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
cmd.addr_lo = lower_32_bits(rx_tid->paddr);
cmd.addr_hi = upper_32_bits(rx_tid->paddr);
@ -841,9 +833,11 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar,
dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size,
DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
}
rx_tid->active = false;
rx_tid->paddr = 0;
rx_tid->size = 0;
}
static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab,
@ -990,6 +984,7 @@ static void ath11k_dp_rx_tid_mem_free(struct ath11k_base *ab,
dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,
DMA_BIDIRECTIONAL);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
rx_tid->active = false;
@ -1014,7 +1009,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
peer = ath11k_peer_find(ab, vdev_id, peer_mac);
if (!peer) {
ath11k_warn(ab, "failed to find the peer to set up rx tid\n");
ath11k_warn(ab, "failed to find the peer %pM to set up rx tid\n",
peer_mac);
spin_unlock_bh(&ab->base_lock);
return -ENOENT;
}
@ -1027,7 +1023,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
ba_win_sz, ssn, true);
spin_unlock_bh(&ab->base_lock);
if (ret) {
ath11k_warn(ab, "failed to update reo for rx tid %d\n", tid);
ath11k_warn(ab, "failed to update reo for peer %pM rx tid %d\n: %d",
peer_mac, tid, ret);
return ret;
}
@ -1035,8 +1032,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
peer_mac, paddr,
tid, 1, ba_win_sz);
if (ret)
ath11k_warn(ab, "failed to send wmi command to update rx reorder queue, tid :%d (%d)\n",
tid, ret);
ath11k_warn(ab, "failed to send wmi rx reorder queue for peer %pM tid %d: %d\n",
peer_mac, tid, ret);
return ret;
}
@ -1069,6 +1066,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
ret = dma_mapping_error(ab->dev, paddr);
if (ret) {
spin_unlock_bh(&ab->base_lock);
ath11k_warn(ab, "failed to setup dma map for peer %pM rx tid %d: %d\n",
peer_mac, tid, ret);
goto err_mem_free;
}
@ -1082,15 +1081,16 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac,
paddr, tid, 1, ba_win_sz);
if (ret) {
ath11k_warn(ar->ab, "failed to setup rx reorder queue, tid :%d (%d)\n",
tid, ret);
ath11k_warn(ar->ab, "failed to setup rx reorder queue for peer %pM tid %d: %d\n",
peer_mac, tid, ret);
ath11k_dp_rx_tid_mem_free(ab, peer_mac, vdev_id, tid);
}
return ret;
err_mem_free:
kfree(vaddr);
kfree(rx_tid->vaddr);
rx_tid->vaddr = NULL;
return ret;
}
@ -2665,6 +2665,9 @@ try_again:
cookie);
mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
if (unlikely(buf_id == 0))
continue;
ar = ab->pdevs[mac_id].ar;
rx_ring = &ar->dp.rx_refill_buf_ring;
spin_lock_bh(&rx_ring->idr_lock);
@ -3029,39 +3032,51 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
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) {
ath11k_warn(ab, "rx monitor status with invalid buf_id %d\n",
buf_id);
spin_unlock_bh(&rx_ring->idr_lock);
pmon->buf_state = DP_MON_STATUS_REPLINISH;
goto move_next;
}
idr_remove(&rx_ring->bufs_idr, buf_id);
spin_unlock_bh(&rx_ring->idr_lock);
rxcb = ATH11K_SKB_RXCB(skb);
dma_unmap_single(ab->dev, rxcb->paddr,
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) {
ath11k_warn(ab, "mon status DONE not set %lx\n",
ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n",
FIELD_GET(HAL_TLV_HDR_TAG,
tlv->tl));
dev_kfree_skb_any(skb);
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
*/
pmon->buf_state = DP_MON_STATUS_NO_DMA;
goto move_next;
break;
}
spin_lock_bh(&rx_ring->idr_lock);
idr_remove(&rx_ring->bufs_idr, buf_id);
spin_unlock_bh(&rx_ring->idr_lock);
if (ab->hw_params.full_monitor_mode) {
ath11k_dp_rx_mon_update_status_buf_state(pmon, tlv);
if (paddr == pmon->mon_status_paddr)
pmon->buf_state = DP_MON_STATUS_MATCH;
}
dma_unmap_single(ab->dev, rxcb->paddr,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
__skb_queue_tail(skb_list, skb);
} else {
pmon->buf_state = DP_MON_STATUS_REPLINISH;
@ -3117,8 +3132,11 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
int i;
tfm = crypto_alloc_shash("michael_mic", 0, 0);
if (IS_ERR(tfm))
if (IS_ERR(tfm)) {
ath11k_warn(ab, "failed to allocate michael_mic shash: %ld\n",
PTR_ERR(tfm));
return PTR_ERR(tfm);
}
spin_lock_bh(&ab->base_lock);
@ -3138,6 +3156,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
}
peer->tfm_mmic = tfm;
peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);
return 0;
@ -3583,6 +3602,13 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
ret = -ENOENT;
goto out_unlock;
}
if (!peer->dp_setup_done) {
ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
peer->addr, peer_id);
ret = -ENOENT;
goto out_unlock;
}
rx_tid = &peer->rx_tid[tid];
if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
@ -3598,7 +3624,7 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
goto out_unlock;
}
if (frag_no > __fls(rx_tid->rx_frag_bitmap))
if (!rx_tid->rx_frag_bitmap || (frag_no > __fls(rx_tid->rx_frag_bitmap)))
__skb_queue_tail(&rx_tid->rx_frags, msdu);
else
ath11k_dp_rx_h_sort_frags(ar, &rx_tid->rx_frags, msdu);

Просмотреть файл

@ -316,10 +316,12 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
struct dp_tx_ring *tx_ring,
struct ath11k_dp_htt_wbm_tx_status *ts)
{
struct ieee80211_tx_status status = { 0 };
struct sk_buff *msdu;
struct ieee80211_tx_info *info;
struct ath11k_skb_cb *skb_cb;
struct ath11k *ar;
struct ath11k_peer *peer;
spin_lock(&tx_ring->tx_idr_lock);
msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id);
@ -341,6 +343,11 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
if (!skb_cb->vif) {
dev_kfree_skb_any(msdu);
return;
}
memset(&info->status, 0, sizeof(info->status));
if (ts->acked) {
@ -355,7 +362,23 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
}
}
ieee80211_tx_status(ar->hw, msdu);
spin_lock_bh(&ab->base_lock);
peer = ath11k_peer_find_by_id(ab, ts->peer_id);
if (!peer || !peer->sta) {
ath11k_dbg(ab, ATH11K_DBG_DATA,
"dp_tx: failed to find the peer with peer_id %d\n",
ts->peer_id);
spin_unlock_bh(&ab->base_lock);
dev_kfree_skb_any(msdu);
return;
}
spin_unlock_bh(&ab->base_lock);
status.sta = peer->sta;
status.info = info;
status.skb = msdu;
ieee80211_tx_status_ext(ar->hw, &status);
}
static void
@ -379,7 +402,15 @@ ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab,
ts.msdu_id = msdu_id;
ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI,
status_desc->info1);
if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2))
ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID,
status_desc->info2);
else
ts.peer_id = HTT_INVALID_PEER_ID;
ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts);
break;
case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:

Просмотреть файл

@ -13,6 +13,7 @@ struct ath11k_dp_htt_wbm_tx_status {
u32 msdu_id;
bool acked;
int ack_rssi;
u16 peer_id;
};
void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts);

Просмотреть файл

@ -865,6 +865,12 @@ ath11k_hal_rx_populate_mu_user_info(void *rx_tlv, struct hal_rx_mon_ppdu_info *p
ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
}
static u16 ath11k_hal_rx_mpduinfo_get_peerid(struct ath11k_base *ab,
struct hal_rx_mpdu_info *mpdu_info)
{
return ab->hw_params.hw_ops->mpdu_info_get_peerid(mpdu_info);
}
static enum hal_rx_mon_status
ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
struct hal_rx_mon_ppdu_info *ppdu_info,
@ -1023,7 +1029,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
info1 = __le32_to_cpu(vht_sig->info1);
ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING,
info0);
info1);
ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS,
info1);
gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING,
@ -1446,7 +1452,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
* PHYRX_OTHER_RECEIVE_INFO TLV.
*/
ppdu_info->rssi_comb =
FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB,
FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB,
__le32_to_cpu(rssi->info0));
if (db2dbm) {
@ -1459,9 +1465,11 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
break;
}
case HAL_RX_MPDU_START: {
struct hal_rx_mpdu_info *mpdu_info =
(struct hal_rx_mpdu_info *)tlv_data;
u16 peer_id;
peer_id = ab->hw_params.hw_ops->mpdu_info_get_peerid(tlv_data);
peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info);
if (peer_id)
ppdu_info->peer_id = peer_id;
break;

Просмотреть файл

@ -385,7 +385,7 @@ struct hal_rx_he_sig_b2_ofdma_info {
__le32 info0;
} __packed;
#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB GENMASK(15, 8)
#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB GENMASK(15, 8)
#define HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 GENMASK(7, 0)
@ -405,7 +405,7 @@ struct hal_rx_phyrx_rssi_legacy_info {
#define HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855 GENMASK(15, 0)
#define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0)
struct hal_rx_mpdu_info {
struct hal_rx_mpdu_info_ipq8074 {
__le32 rsvd0;
__le32 info0;
__le32 rsvd1[11];
@ -413,12 +413,28 @@ struct hal_rx_mpdu_info {
__le32 rsvd2[9];
} __packed;
struct hal_rx_mpdu_info_qcn9074 {
__le32 rsvd0[10];
__le32 info0;
__le32 rsvd1[2];
__le32 info1;
__le32 rsvd2[9];
} __packed;
struct hal_rx_mpdu_info_wcn6855 {
__le32 rsvd0[8];
__le32 info0;
__le32 rsvd1[14];
} __packed;
struct hal_rx_mpdu_info {
union {
struct hal_rx_mpdu_info_ipq8074 ipq8074;
struct hal_rx_mpdu_info_qcn9074 qcn9074;
struct hal_rx_mpdu_info_wcn6855 wcn6855;
} u;
} __packed;
#define HAL_RX_PPDU_END_DURATION GENMASK(23, 0)
struct hal_rx_ppdu_end_duration {
__le32 rsvd0[9];

Просмотреть файл

@ -835,26 +835,35 @@ static void ath11k_hw_ipq5018_reo_setup(struct ath11k_base *ab)
ring_hash_map);
}
static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data)
static u16
ath11k_hw_ipq8074_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info)
{
u16 peer_id = 0;
struct hal_rx_mpdu_info *mpdu_info =
(struct hal_rx_mpdu_info *)tlv_data;
peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID,
__le32_to_cpu(mpdu_info->info0));
__le32_to_cpu(mpdu_info->u.ipq8074.info0));
return peer_id;
}
static u16 ath11k_hw_wcn6855_mpdu_info_get_peerid(u8 *tlv_data)
static u16
ath11k_hw_qcn9074_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info)
{
u16 peer_id = 0;
peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID,
__le32_to_cpu(mpdu_info->u.qcn9074.info0));
return peer_id;
}
static u16
ath11k_hw_wcn6855_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info)
{
u16 peer_id = 0;
struct hal_rx_mpdu_info_wcn6855 *mpdu_info =
(struct hal_rx_mpdu_info_wcn6855 *)tlv_data;
peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855,
__le32_to_cpu(mpdu_info->info0));
__le32_to_cpu(mpdu_info->u.wcn6855.info0));
return peer_id;
}
@ -1042,7 +1051,7 @@ const struct ath11k_hw_ops qcn9074_ops = {
.rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention,
.rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
.reo_setup = ath11k_hw_ipq8074_reo_setup,
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
.mpdu_info_get_peerid = ath11k_hw_qcn9074_mpdu_info_get_peerid,
.rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid,
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2,
.get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
@ -1224,6 +1233,7 @@ const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074 = {
ATH11K_RX_WBM_REL_RING_MASK_0,
},
.reo_status = {
0, 0, 0,
ATH11K_REO_STATUS_RING_MASK_0,
},
.rxdma2host = {

Просмотреть файл

@ -224,7 +224,6 @@ struct ath11k_hw_params {
u32 tx_ring_size;
bool smp2p_wow_exit;
bool support_fw_mac_sequence;
bool ftm_responder;
};
struct ath11k_hw_ops {
@ -264,7 +263,7 @@ struct ath11k_hw_ops {
struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc);
u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc);
void (*reo_setup)(struct ath11k_base *ab);
u16 (*mpdu_info_get_peerid)(u8 *tlv_data);
u16 (*mpdu_info_get_peerid)(struct hal_rx_mpdu_info *mpdu_info);
bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc);
u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc);
u32 (*get_ring_selector)(struct sk_buff *skb);

Просмотреть файл

@ -3538,7 +3538,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_FTM_RESPONDER &&
arvif->ftm_responder != info->ftm_responder &&
ar->ab->hw_params.ftm_responder &&
test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map) &&
(vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_MESH_POINT)) {
arvif->ftm_responder = info->ftm_responder;
@ -3755,6 +3755,18 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
int i;
u32 scan_timeout;
/* Firmwares advertising the support of triggering 11D algorithm
* on the scan results of a regular scan expects driver to send
* WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID.
* With this feature, separate 11D scan can be avoided since
* regdomain can be determined with the scan results of the
* regular scan.
*/
if (ar->state_11d == ATH11K_11D_PREPARING &&
test_bit(WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN,
ar->ab->wmi_ab.svc_map))
ath11k_mac_11d_scan_start(ar, arvif->vdev_id);
mutex_lock(&ar->conf_mutex);
spin_lock_bh(&ar->data_lock);
@ -3819,9 +3831,30 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
goto exit;
}
for (i = 0; i < arg->num_chan; i++)
for (i = 0; i < arg->num_chan; i++) {
if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL,
ar->ab->wmi_ab.svc_map)) {
arg->chan_list[i] =
u32_encode_bits(req->channels[i]->center_freq,
WMI_SCAN_CONFIG_PER_CHANNEL_MASK);
/* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan
* flags, then scan all PSC channels in 6 GHz band and
* those non-PSC channels where RNR IE is found during
* the legacy 2.4/5 GHz scan.
* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set,
* then all channels in 6 GHz will be scanned.
*/
if (req->channels[i]->band == NL80211_BAND_6GHZ &&
req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ &&
!cfg80211_channel_is_psc(req->channels[i]))
arg->chan_list[i] |=
WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND;
} else {
arg->chan_list[i] = req->channels[i]->center_freq;
}
}
}
if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
arg->scan_f_add_spoofed_mac_in_probe = 1;
@ -5552,10 +5585,6 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
he_cap_elem->mac_cap_info[1] &=
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
he_cap_elem->phy_cap_info[0] &=
~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
he_cap_elem->phy_cap_info[0] &=
~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
he_cap_elem->phy_cap_info[5] &=
~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
@ -6652,6 +6681,11 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
ath11k_dbg(ab, ATH11K_DBG_MAC, "mac remove interface (vdev %d)\n",
arvif->vdev_id);
ret = ath11k_spectral_vif_stop(arvif);
if (ret)
ath11k_warn(ab, "failed to stop spectral for vdev %i: %d\n",
arvif->vdev_id, ret);
if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
ath11k_mac_11d_scan_stop(ar);
@ -9213,7 +9247,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
if (ab->hw_params.ftm_responder)
if (test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map))
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);

Просмотреть файл

@ -540,7 +540,7 @@ static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)
if (!ab->mem) {
ath11k_err(ab, "failed to map pci bar %d\n", ATH11K_PCI_BAR_NUM);
ret = -EIO;
goto clear_master;
goto release_region;
}
ab->mem_ce = ab->mem;
@ -548,8 +548,6 @@ static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
return 0;
clear_master:
pci_clear_master(pdev);
release_region:
pci_release_region(pdev, ATH11K_PCI_BAR_NUM);
disable_device:
@ -565,7 +563,6 @@ static void ath11k_pci_free_region(struct ath11k_pci *ab_pci)
pci_iounmap(pci_dev, ab->mem);
ab->mem = NULL;
pci_clear_master(pci_dev);
pci_release_region(pci_dev, ATH11K_PCI_BAR_NUM);
if (pci_is_enabled(pci_dev))
pci_disable_device(pci_dev);
@ -1039,7 +1036,8 @@ module_exit(ath11k_pci_exit);
MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN PCIe devices");
MODULE_LICENSE("Dual BSD/GPL");
/* QCA639x 2.0 firmware files */
MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_BOARD_API2_FILE);
MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_AMSS_FILE);
MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_M3_FILE);
/* firmware files */
MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/*");
MODULE_FIRMWARE(ATH11K_FW_DIR "/QCN9074/hw1.0/*");
MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.0/*");
MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.1/*");

Просмотреть файл

@ -35,6 +35,7 @@ struct ath11k_peer {
u16 sec_type;
u16 sec_type_grp;
bool is_authorized;
bool dp_setup_done;
};
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);

Просмотреть файл

@ -82,6 +82,12 @@ struct wmi_tlv_fw_stats_parse {
bool chain_rssi_done;
};
struct wmi_tlv_mgmt_rx_parse {
const struct wmi_mgmt_rx_hdr *fixed;
const u8 *frame_buf;
bool frame_buf_done;
};
static const struct wmi_tlv_policy wmi_tlv_policies[] = {
[WMI_TAG_ARRAY_BYTE]
= { .min_len = 0 },
@ -865,7 +871,8 @@ static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan,
chan->band_center_freq2 = arg->channel.band_center_freq1;
} else if (arg->channel.mode == MODE_11AC_VHT80_80) {
} else if ((arg->channel.mode == MODE_11AC_VHT80_80) ||
(arg->channel.mode == MODE_11AX_HE80_80)) {
chan->band_center_freq2 = arg->channel.band_center_freq2;
} else {
chan->band_center_freq2 = 0;
@ -5633,28 +5640,49 @@ static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base *ab, struct sk_
return 0;
}
static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_mgmt_rx_parse *parse = data;
switch (tag) {
case WMI_TAG_MGMT_RX_HDR:
parse->fixed = ptr;
break;
case WMI_TAG_ARRAY_BYTE:
if (!parse->frame_buf_done) {
parse->frame_buf = ptr;
parse->frame_buf_done = true;
}
break;
}
return 0;
}
static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
struct sk_buff *skb,
struct mgmt_rx_event_params *hdr)
{
const void **tb;
struct wmi_tlv_mgmt_rx_parse parse = { };
const struct wmi_mgmt_rx_hdr *ev;
const u8 *frame;
int ret;
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
ath11k_wmi_tlv_mgmt_rx_parse,
&parse);
if (ret) {
ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n",
ret);
return ret;
}
ev = tb[WMI_TAG_MGMT_RX_HDR];
frame = tb[WMI_TAG_ARRAY_BYTE];
ev = parse.fixed;
frame = parse.frame_buf;
if (!ev || !frame) {
ath11k_warn(ab, "failed to fetch mgmt rx hdr");
kfree(tb);
return -EPROTO;
}
@ -5673,7 +5701,6 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
if (skb->len < (frame - skb->data) + hdr->buf_len) {
ath11k_warn(ab, "invalid length in mgmt rx hdr ev");
kfree(tb);
return -EPROTO;
}
@ -5685,7 +5712,6 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
ath11k_ce_byte_swap(skb->data, hdr->buf_len);
kfree(tb);
return 0;
}

Просмотреть файл

@ -2100,8 +2100,10 @@ enum wmi_tlv_service {
/* The second 128 bits */
WMI_MAX_EXT_SERVICE = 256,
WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265,
WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326,
WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN = 357,
/* The third 128 bits */
WMI_MAX_EXT2_SERVICE = 384
@ -3249,6 +3251,9 @@ struct wmi_start_scan_cmd {
#define WMI_SCAN_DWELL_MODE_SHIFT 21
#define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800
#define WMI_SCAN_CONFIG_PER_CHANNEL_MASK GENMASK(19, 0)
#define WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND BIT(20)
enum {
WMI_SCAN_DWELL_MODE_DEFAULT = 0,
WMI_SCAN_DWELL_MODE_CONSERVATIVE = 1,

Просмотреть файл

@ -395,6 +395,7 @@ struct ath12k_sta {
u8 rssi_comb;
struct ath12k_rx_peer_stats *rx_stats;
struct ath12k_wbm_tx_stats *wbm_tx_stats;
u32 bw_prev;
};
#define ATH12K_MIN_5G_FREQ 4150

Просмотреть файл

@ -196,7 +196,8 @@ static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab,
static bool ath12k_dp_rx_h_is_mcbc(struct ath12k_base *ab,
struct hal_rx_desc *desc)
{
return ab->hw_params->hal_ops->rx_desc_is_mcbc(desc);
return (ath12k_dp_rx_h_first_msdu(ab, desc) &&
ab->hw_params->hal_ops->rx_desc_is_mcbc(desc));
}
static bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab,
@ -3047,10 +3048,14 @@ 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;
reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr));
reo_ent_ring->info0 = le32_encode_bits(upper_32_bits(rx_tid->paddr),
HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
le32_encode_bits(dst_ind, HAL_REO_ENTR_RING_INFO0_DEST_IND);
/* 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,
HAL_REO_ENTR_RING_INFO0_DEST_IND);
reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn,
HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM);

Просмотреть файл

@ -13,6 +13,10 @@ static enum hal_tcl_encap_type
ath12k_dp_tx_get_encap_type(struct ath12k_vif *arvif, struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath12k_base *ab = arvif->ar->ab;
if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags))
return HAL_TCL_ENCAP_TYPE_RAW;
if (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
return HAL_TCL_ENCAP_TYPE_ETHERNET;

Просмотреть файл

@ -944,7 +944,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.interface_modes = BIT(NL80211_IFTYPE_STATION),
.supports_monitor = false,
.idle_ps = false,
.idle_ps = true,
.download_calib = false,
.supports_suspend = false,
.tcl_ring_retry = false,

Просмотреть файл

@ -3220,10 +3220,11 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk)
enum nl80211_band band;
const u8 *ht_mcs_mask;
const u16 *vht_mcs_mask;
u32 changed, bw, nss, smps;
u32 changed, bw, nss, smps, bw_prev;
int err, num_vht_rates;
const struct cfg80211_bitrate_mask *mask;
struct ath12k_wmi_peer_assoc_arg peer_arg;
enum wmi_phy_mode peer_phymode;
arsta = container_of(wk, struct ath12k_sta, update_wk);
sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
@ -3243,6 +3244,7 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk)
arsta->changed = 0;
bw = arsta->bw;
bw_prev = arsta->bw_prev;
nss = arsta->nss;
smps = arsta->smps;
@ -3255,11 +3257,53 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk)
ath12k_mac_max_vht_nss(vht_mcs_mask)));
if (changed & IEEE80211_RC_BW_CHANGED) {
err = ath12k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
WMI_PEER_CHWIDTH, bw);
ath12k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);
peer_phymode = peer_arg.peer_phymode;
if (bw > bw_prev) {
/* Phymode shows maximum supported channel width, if we
* upgrade bandwidth then due to sanity check of firmware,
* we have to send WMI_PEER_PHYMODE followed by
* WMI_PEER_CHWIDTH
*/
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac bandwidth upgrade for sta %pM new %d old %d\n",
sta->addr, bw, bw_prev);
err = ath12k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id, WMI_PEER_PHYMODE,
peer_phymode);
if (err) {
ath12k_warn(ar->ab, "failed to update STA %pM to peer phymode %d: %d\n",
sta->addr, peer_phymode, err);
goto err_rc_bw_changed;
}
err = ath12k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id, WMI_PEER_CHWIDTH,
bw);
if (err)
ath12k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
ath12k_warn(ar->ab, "failed to update STA %pM to peer bandwidth %d: %d\n",
sta->addr, bw, err);
} else {
/* When we downgrade bandwidth this will conflict with phymode
* and cause to trigger firmware crash. In this case we send
* WMI_PEER_CHWIDTH followed by WMI_PEER_PHYMODE
*/
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac bandwidth downgrade for sta %pM new %d old %d\n",
sta->addr, bw, bw_prev);
err = ath12k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id, WMI_PEER_CHWIDTH,
bw);
if (err) {
ath12k_warn(ar->ab, "failed to update STA %pM peer to bandwidth %d: %d\n",
sta->addr, bw, err);
goto err_rc_bw_changed;
}
err = ath12k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id, WMI_PEER_PHYMODE,
peer_phymode);
if (err)
ath12k_warn(ar->ab, "failed to update STA %pM to peer phymode %d: %d\n",
sta->addr, peer_phymode, err);
}
}
if (changed & IEEE80211_RC_NSS_CHANGED) {
@ -3321,7 +3365,7 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk)
sta->addr, arvif->vdev_id);
}
}
err_rc_bw_changed:
mutex_unlock(&ar->conf_mutex);
}
@ -3433,6 +3477,34 @@ exit:
return ret;
}
static u32 ath12k_mac_ieee80211_sta_bw_to_wmi(struct ath12k *ar,
struct ieee80211_sta *sta)
{
u32 bw = WMI_PEER_CHWIDTH_20MHZ;
switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_20:
bw = WMI_PEER_CHWIDTH_20MHZ;
break;
case IEEE80211_STA_RX_BW_40:
bw = WMI_PEER_CHWIDTH_40MHZ;
break;
case IEEE80211_STA_RX_BW_80:
bw = WMI_PEER_CHWIDTH_80MHZ;
break;
case IEEE80211_STA_RX_BW_160:
bw = WMI_PEER_CHWIDTH_160MHZ;
break;
default:
ath12k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n",
sta->deflink.bandwidth, sta->addr);
bw = WMI_PEER_CHWIDTH_20MHZ;
break;
}
return bw;
}
static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@ -3498,6 +3570,13 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw,
if (ret)
ath12k_warn(ar->ab, "Failed to associate station: %pM\n",
sta->addr);
spin_lock_bh(&ar->data_lock);
arsta->bw = ath12k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
arsta->bw_prev = sta->deflink.bandwidth;
spin_unlock_bh(&ar->data_lock);
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTHORIZED) {
spin_lock_bh(&ar->ab->base_lock);
@ -3607,28 +3686,8 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
spin_lock_bh(&ar->data_lock);
if (changed & IEEE80211_RC_BW_CHANGED) {
bw = WMI_PEER_CHWIDTH_20MHZ;
switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_20:
bw = WMI_PEER_CHWIDTH_20MHZ;
break;
case IEEE80211_STA_RX_BW_40:
bw = WMI_PEER_CHWIDTH_40MHZ;
break;
case IEEE80211_STA_RX_BW_80:
bw = WMI_PEER_CHWIDTH_80MHZ;
break;
case IEEE80211_STA_RX_BW_160:
bw = WMI_PEER_CHWIDTH_160MHZ;
break;
default:
ath12k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n",
sta->deflink.bandwidth, sta->addr);
bw = WMI_PEER_CHWIDTH_20MHZ;
break;
}
bw = ath12k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
arsta->bw_prev = arsta->bw;
arsta->bw = bw;
}

Просмотреть файл

@ -755,14 +755,12 @@ static int ath12k_pci_claim(struct ath12k_pci *ab_pci, struct pci_dev *pdev)
if (!ab->mem) {
ath12k_err(ab, "failed to map pci bar %d\n", ATH12K_PCI_BAR_NUM);
ret = -EIO;
goto clear_master;
goto release_region;
}
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
return 0;
clear_master:
pci_clear_master(pdev);
release_region:
pci_release_region(pdev, ATH12K_PCI_BAR_NUM);
disable_device:
@ -778,7 +776,6 @@ static void ath12k_pci_free_region(struct ath12k_pci *ab_pci)
pci_iounmap(pci_dev, ab->mem);
ab->mem = NULL;
pci_clear_master(pci_dev);
pci_release_region(pci_dev, ATH12K_PCI_BAR_NUM);
if (pci_is_enabled(pci_dev))
pci_disable_device(pci_dev);
@ -1223,7 +1220,8 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
dev_err(&pdev->dev,
"Unknown hardware version found for QCN9274: 0x%x\n",
soc_hw_version_major);
return -EOPNOTSUPP;
ret = -EOPNOTSUPP;
goto err_pci_free_region;
}
break;
case WCN7850_DEVICE_ID:

Просмотреть файл

@ -2991,7 +2991,7 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
spin_unlock(&qmi->event_lock);
if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
return;
goto skip;
switch (event->type) {
case ATH12K_QMI_EVENT_SERVER_ARRIVE:
@ -3032,6 +3032,8 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
ath12k_warn(ab, "invalid event type: %d", event->type);
break;
}
skip:
kfree(event);
spin_lock(&qmi->event_lock);
}

Просмотреть файл

@ -2438,6 +2438,9 @@ int ath12k_wmi_send_scan_chan_list_cmd(struct ath12k *ar,
if (channel_arg->psc_channel)
chan_info->info |= cpu_to_le32(WMI_CHAN_INFO_PSC);
if (channel_arg->dfs_set)
chan_info->info |= cpu_to_le32(WMI_CHAN_INFO_DFS);
chan_info->info |= le32_encode_bits(channel_arg->phy_mode,
WMI_CHAN_INFO_MODE);
*reg1 |= le32_encode_bits(channel_arg->minpower,
@ -4934,6 +4937,9 @@ static int freq_to_idx(struct ath12k *ar, int freq)
int band, ch, idx = 0;
for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
if (!ar->mac.sbands[band].channels)
continue;
sband = ar->hw->wiphy->bands[band];
if (!sband)
continue;

Просмотреть файл

@ -42,8 +42,6 @@ static const struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x7015),
.driver_info = AR9287_USB }, /* Atheros */
{ USB_DEVICE(0x1668, 0x1200),
.driver_info = AR9287_USB }, /* Verizon */
{ USB_DEVICE(0x0cf3, 0x7010),
.driver_info = AR9280_USB }, /* Atheros */

Просмотреть файл

@ -646,9 +646,7 @@ void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all)
struct ath_hw *ah = sc->sc_ah;
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
struct ath9k_channel *chan = ah->curchan;
static const u32 channelmap[] = {
0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff
};
u32 channelmap[] = {0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff};
int i;
s16 chan_start, chan_end;
u16 wlan_chan;

Просмотреть файл

@ -34,6 +34,12 @@
#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
/* Shifts in ar5008_phy.c and ar9003_phy.c are equal for all revisions */
#define ATH9K_PWRTBL_11NA_OFDM_SHIFT 0
#define ATH9K_PWRTBL_11NG_OFDM_SHIFT 4
#define ATH9K_PWRTBL_11NA_HT_SHIFT 8
#define ATH9K_PWRTBL_11NG_HT_SHIFT 12
static u16 bits_per_symbol[][2] = {
/* 20MHz 40MHz */
@ -1169,13 +1175,14 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
}
static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
u8 rateidx, bool is_40, bool is_cck)
u8 rateidx, bool is_40, bool is_cck, bool is_mcs)
{
u8 max_power;
struct sk_buff *skb;
struct ath_frame_info *fi;
struct ieee80211_tx_info *info;
struct ath_hw *ah = sc->sc_ah;
bool is_2ghz, is_5ghz, use_stbc;
if (sc->tx99_state || !ah->tpc_enabled)
return MAX_RATE_POWER;
@ -1184,6 +1191,19 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
fi = get_frame_info(skb);
info = IEEE80211_SKB_CB(skb);
is_2ghz = info->band == NL80211_BAND_2GHZ;
is_5ghz = info->band == NL80211_BAND_5GHZ;
use_stbc = is_mcs && rateidx < 8 && (info->flags &
IEEE80211_TX_CTL_STBC);
if (is_mcs)
rateidx += is_5ghz ? ATH9K_PWRTBL_11NA_HT_SHIFT
: ATH9K_PWRTBL_11NG_HT_SHIFT;
else if (is_2ghz && !is_cck)
rateidx += ATH9K_PWRTBL_11NG_OFDM_SHIFT;
else
rateidx += ATH9K_PWRTBL_11NA_OFDM_SHIFT;
if (!AR_SREV_9300_20_OR_LATER(ah)) {
int txpower = fi->tx_power;
@ -1193,10 +1213,8 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
u16 eeprom_rev = ah->eep_ops->get_eeprom_rev(ah);
if (eeprom_rev >= AR5416_EEP_MINOR_VER_2) {
bool is_2ghz;
struct modal_eep_header *pmodal;
is_2ghz = info->band == NL80211_BAND_2GHZ;
pmodal = &eep->modalHeader[is_2ghz];
power_ht40delta = pmodal->ht40PowerIncForPdadc;
} else {
@ -1229,7 +1247,7 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
max_power = 1;
} else if (!bf->bf_state.bfs_paprd) {
if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
if (use_stbc)
max_power = min_t(u8, ah->tx_power_stbc[rateidx],
fi->tx_power);
else
@ -1319,7 +1337,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
}
info->txpower[i] = ath_get_rate_txpower(sc, bf, rix,
is_40, false);
is_40, false, true);
continue;
}
@ -1350,7 +1368,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
is_cck = IS_CCK_RATE(info->rates[i].Rate);
info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, false,
is_cck);
is_cck, false);
}
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */

Просмотреть файл

@ -120,7 +120,7 @@ struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
{
struct carl9170_cmd *tmp;
tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
if (tmp) {
tmp->hdr.cmd = cmd;
tmp->hdr.len = len;

Просмотреть файл

@ -320,9 +320,9 @@ struct carl9170_rsp {
struct carl9170_u32_list rreg_res;
struct carl9170_u32_list echo;
#ifdef __CARL9170FW__
struct carl9170_tx_status tx_status[0];
DECLARE_FLEX_ARRAY(struct carl9170_tx_status, tx_status);
#endif /* __CARL9170FW__ */
struct _carl9170_tx_status _tx_status[0];
DECLARE_FLEX_ARRAY(struct _carl9170_tx_status, _tx_status);
struct carl9170_gpio gpio;
struct carl9170_tsf_rsp tsf;
struct carl9170_psm psm;

Просмотреть файл

@ -112,8 +112,8 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
wcn->dxe_rx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_L;
wcn->dxe_rx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_H;
wcn->dxe_tx_l_ch.dxe_wq = WCN36XX_DXE_WQ_TX_L;
wcn->dxe_tx_h_ch.dxe_wq = WCN36XX_DXE_WQ_TX_H;
wcn->dxe_tx_l_ch.dxe_wq = WCN36XX_DXE_WQ_TX_L(wcn);
wcn->dxe_tx_h_ch.dxe_wq = WCN36XX_DXE_WQ_TX_H(wcn);
wcn->dxe_tx_l_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_L_BD;
wcn->dxe_tx_h_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_H_BD;
@ -165,8 +165,9 @@ void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn)
wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_h_ch);
}
static int wcn36xx_dxe_init_descs(struct device *dev, struct wcn36xx_dxe_ch *wcn_ch)
static int wcn36xx_dxe_init_descs(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *wcn_ch)
{
struct device *dev = wcn->dev;
struct wcn36xx_dxe_desc *cur_dxe = NULL;
struct wcn36xx_dxe_desc *prev_dxe = NULL;
struct wcn36xx_dxe_ctl *cur_ctl = NULL;
@ -190,11 +191,11 @@ static int wcn36xx_dxe_init_descs(struct device *dev, struct wcn36xx_dxe_ch *wcn
switch (wcn_ch->ch_type) {
case WCN36XX_DXE_CH_TX_L:
cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_L;
cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_L;
cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_L(wcn);
break;
case WCN36XX_DXE_CH_TX_H:
cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_H;
cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_H;
cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_H(wcn);
break;
case WCN36XX_DXE_CH_RX_L:
cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_L;
@ -914,7 +915,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***************************************/
/* Init descriptors for TX LOW channel */
/***************************************/
ret = wcn36xx_dxe_init_descs(wcn->dev, &wcn->dxe_tx_l_ch);
ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_tx_l_ch);
if (ret) {
dev_err(wcn->dev, "Error allocating descriptor\n");
return ret;
@ -928,14 +929,14 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/* Program DMA destination addr for TX LOW */
wcn36xx_dxe_write_register(wcn,
WCN36XX_DXE_CH_DEST_ADDR_TX_L,
WCN36XX_DXE_WQ_TX_L);
WCN36XX_DXE_WQ_TX_L(wcn));
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
/***************************************/
/* Init descriptors for TX HIGH channel */
/***************************************/
ret = wcn36xx_dxe_init_descs(wcn->dev, &wcn->dxe_tx_h_ch);
ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_tx_h_ch);
if (ret) {
dev_err(wcn->dev, "Error allocating descriptor\n");
goto out_err_txh_ch;
@ -950,14 +951,14 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/* Program DMA destination addr for TX HIGH */
wcn36xx_dxe_write_register(wcn,
WCN36XX_DXE_CH_DEST_ADDR_TX_H,
WCN36XX_DXE_WQ_TX_H);
WCN36XX_DXE_WQ_TX_H(wcn));
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
/***************************************/
/* Init descriptors for RX LOW channel */
/***************************************/
ret = wcn36xx_dxe_init_descs(wcn->dev, &wcn->dxe_rx_l_ch);
ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_rx_l_ch);
if (ret) {
dev_err(wcn->dev, "Error allocating descriptor\n");
goto out_err_rxl_ch;
@ -988,7 +989,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***************************************/
/* Init descriptors for RX HIGH channel */
/***************************************/
ret = wcn36xx_dxe_init_descs(wcn->dev, &wcn->dxe_rx_h_ch);
ret = wcn36xx_dxe_init_descs(wcn, &wcn->dxe_rx_h_ch);
if (ret) {
dev_err(wcn->dev, "Error allocating descriptor\n");
goto out_err_rxh_ch;

Просмотреть файл

@ -135,8 +135,8 @@ H2H_TEST_RX_TX = DMA2
WCN36xx_DXE_CTRL_ENDIANNESS)
/* TODO This must calculated properly but not hardcoded */
#define WCN36XX_DXE_WQ_TX_L 0x17
#define WCN36XX_DXE_WQ_TX_H 0x17
#define WCN36XX_DXE_WQ_TX_L(wcn) ((wcn)->is_pronto_v3 ? 0x6 : 0x17)
#define WCN36XX_DXE_WQ_TX_H(wcn) ((wcn)->is_pronto_v3 ? 0x6 : 0x17)
#define WCN36XX_DXE_WQ_RX_L 0xB
#define WCN36XX_DXE_WQ_RX_H 0x4

Просмотреть файл

@ -1508,6 +1508,7 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
}
wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto");
wcn->is_pronto_v3 = !!of_device_is_compatible(mmio_node, "qcom,pronto-v3-pil");
/* Map the CCU memory */
index = of_property_match_string(mmio_node, "reg-names", "ccu");

Просмотреть файл

@ -217,6 +217,7 @@ struct wcn36xx {
u8 fw_major;
u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE];
bool is_pronto;
bool is_pronto_v3;
/* extra byte for the NULL termination */
u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];