mirror of
https://github.com/breeze303/openwrt-ipq.git
synced 2025-12-16 22:51:06 +00:00
ath11k_nss: ath11k support dynamic vlan
also support offload for the following:
mac80211:
* vlan
* mesh (partial)
ath11k:
* vlan
This commit is contained in:
parent
6e41396273
commit
b7fe6cbb4c
@ -0,0 +1,381 @@
|
||||
From 71add81f4a3f1ea505f498d789e7a1721c4d7a6e Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Mon, 4 Sep 2023 12:48:19 +0530
|
||||
Subject: [PATCH] ath11k: Add support for dynamic vlan
|
||||
|
||||
This patch adds support for dynamic vlan. VLAN group traffics
|
||||
are encrypted in software. vlan unicast packets shall be taking
|
||||
8023 xmit path if encap offload is enabled and mcast/bcast will
|
||||
be using 80211 xmit path.
|
||||
|
||||
Metadata info in dp_tx added to notify firmware that the
|
||||
multicast/broadcast packets are encrypted in sw.
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 80 +++++++++-
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.h | 198 ++++++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 +
|
||||
4 files changed, 279 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -116,6 +116,7 @@ struct ath11k_skb_cb {
|
||||
u32 cipher;
|
||||
struct ath11k *ar;
|
||||
struct ieee80211_vif *vif;
|
||||
+ u32 pkt_offset;
|
||||
} __packed;
|
||||
|
||||
struct ath11k_skb_rxcb {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -79,6 +79,43 @@ enum hal_encrypt_type ath11k_dp_tx_get_e
|
||||
}
|
||||
}
|
||||
|
||||
+#define HTT_META_DATA_ALIGNMENT 0x8
|
||||
+
|
||||
+static int ath11k_dp_metadata_align_skb(struct sk_buff *skb, u8 align_len)
|
||||
+{
|
||||
+ if (unlikely(skb_cow_head(skb, align_len)))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ skb_push(skb, align_len);
|
||||
+ memset(skb->data, 0, align_len);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_dp_prepare_htt_metadata(struct sk_buff *skb,
|
||||
+ u8 *htt_metadata_size)
|
||||
+{
|
||||
+ u8 htt_desc_size;
|
||||
+ /* Size rounded of multiple of 8 bytes */
|
||||
+ u8 htt_desc_size_aligned;
|
||||
+ int ret;
|
||||
+ struct htt_tx_msdu_desc_ext *desc_ext;
|
||||
+
|
||||
+ htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext);
|
||||
+ htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT);
|
||||
+
|
||||
+ ret = ath11k_dp_metadata_align_skb(skb, htt_desc_size_aligned);
|
||||
+ if (unlikely(ret))
|
||||
+ return ret;
|
||||
+
|
||||
+ desc_ext = (struct htt_tx_msdu_desc_ext *)skb->data;
|
||||
+ desc_ext->valid_encrypt_type = 1;
|
||||
+ desc_ext->encrypt_type = 0;
|
||||
+ desc_ext->host_tx_desc_pool = 1;
|
||||
+ *htt_metadata_size = htt_desc_size_aligned;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
struct ath11k_sta *arsta, struct sk_buff *skb)
|
||||
{
|
||||
@@ -96,7 +133,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru
|
||||
int ret;
|
||||
u32 ring_selector = 0;
|
||||
u8 ring_map = 0;
|
||||
- bool tcl_ring_retry;
|
||||
+ bool tcl_ring_retry, is_diff_encap = false;
|
||||
+ u8 align_pad, htt_meta_size = 0;
|
||||
|
||||
if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)))
|
||||
return -ESHUTDOWN;
|
||||
@@ -189,7 +227,10 @@ tcl_ring_sel:
|
||||
|
||||
switch (ti.encap_type) {
|
||||
case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
|
||||
- ath11k_dp_tx_encap_nwifi(skb);
|
||||
+ if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
+ is_diff_encap = true;
|
||||
+ else
|
||||
+ ath11k_dp_tx_encap_nwifi(skb);
|
||||
break;
|
||||
case HAL_TCL_ENCAP_TYPE_RAW:
|
||||
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
|
||||
@@ -208,6 +249,33 @@ tcl_ring_sel:
|
||||
goto fail_remove_idr;
|
||||
}
|
||||
|
||||
+ /* Add metadata for sw encrypted vlan group traffic */
|
||||
+ if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
|
||||
+ !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
+ !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) ||
|
||||
+ (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) {
|
||||
+ /* HW requirement is that metadata should always point to a
|
||||
+ * 8-byte aligned address. So we add alignment pad to start of
|
||||
+ * buffer. HTT Metadata should be ensured to be multiple of 8-bytes
|
||||
+ * to get 8-byte aligned start address along with align_pad added
|
||||
+ */
|
||||
+ align_pad = ((unsigned long)skb->data) & (HTT_META_DATA_ALIGNMENT - 1);
|
||||
+ ret = ath11k_dp_metadata_align_skb(skb, align_pad);
|
||||
+ if (unlikely(ret))
|
||||
+ goto fail_remove_idr;
|
||||
+
|
||||
+ ti.pkt_offset += align_pad;
|
||||
+ ret = ath11k_dp_prepare_htt_metadata(skb, &htt_meta_size);
|
||||
+ if (unlikely(ret))
|
||||
+ goto fail_remove_idr;
|
||||
+
|
||||
+ ti.pkt_offset += htt_meta_size;
|
||||
+ ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT;
|
||||
+ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
|
||||
+ ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
|
||||
+ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
+ }
|
||||
+
|
||||
ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(ab->dev, ti.paddr))) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
@@ -216,7 +284,8 @@ tcl_ring_sel:
|
||||
goto fail_remove_idr;
|
||||
}
|
||||
|
||||
- ti.data_len = skb->len;
|
||||
+ ti.data_len = skb->len - ti.pkt_offset;
|
||||
+ skb_cb->pkt_offset = ti.pkt_offset;
|
||||
skb_cb->paddr = ti.paddr;
|
||||
skb_cb->vif = arvif->vif;
|
||||
skb_cb->ar = ar;
|
||||
@@ -272,6 +341,8 @@ fail_unmap_dma:
|
||||
dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
|
||||
|
||||
fail_remove_idr:
|
||||
+ if (ti.pkt_offset)
|
||||
+ skb_pull(skb, ti.pkt_offset);
|
||||
spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
idr_remove(&tx_ring->txbuf_idr,
|
||||
FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id));
|
||||
@@ -358,6 +429,9 @@ ath11k_dp_tx_htt_tx_complete_buf(struct
|
||||
flags = skb_cb->flags;
|
||||
vif = skb_cb->vif;
|
||||
|
||||
+ if (skb_cb->pkt_offset)
|
||||
+ skb_pull(msdu, skb_cb->pkt_offset); /* removing the alignment and htt meta data */
|
||||
+
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
|
||||
if (ts->acked) {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
@@ -16,6 +16,204 @@ struct ath11k_dp_htt_wbm_tx_status {
|
||||
u16 peer_id;
|
||||
};
|
||||
|
||||
+/* htt_tx_msdu_desc_ext
|
||||
+ *
|
||||
+ * valid_pwr
|
||||
+ * if set, tx pwr spec is valid
|
||||
+ *
|
||||
+ * valid_mcs_mask
|
||||
+ * if set, tx MCS mask is valid
|
||||
+ *
|
||||
+ * valid_nss_mask
|
||||
+ * if set, tx Nss mask is valid
|
||||
+ *
|
||||
+ * valid_preamble_type
|
||||
+ * if set, tx preamble spec is valid
|
||||
+ *
|
||||
+ * valid_retries
|
||||
+ * if set, tx retries spec is valid
|
||||
+ *
|
||||
+ * valid_bw_info
|
||||
+ * if set, tx dyn_bw and bw_mask are valid
|
||||
+ *
|
||||
+ * valid_guard_interval
|
||||
+ * if set, tx guard intv spec is valid
|
||||
+ *
|
||||
+ * valid_chainmask
|
||||
+ * if set, tx chainmask is valid
|
||||
+ *
|
||||
+ * valid_encrypt_type
|
||||
+ * if set, encrypt type is valid
|
||||
+ *
|
||||
+ * valid_key_flags
|
||||
+ * if set, key flags is valid
|
||||
+ *
|
||||
+ * valid_expire_tsf
|
||||
+ * if set, tx expire TSF spec is valid
|
||||
+ *
|
||||
+ * valid_chanfreq
|
||||
+ * if set, chanfreq is valid
|
||||
+ *
|
||||
+ * is_dsrc
|
||||
+ * if set, MSDU is a DSRC frame
|
||||
+ *
|
||||
+ * guard_interval
|
||||
+ * 0.4us, 0.8us, 1.6us, 3.2us
|
||||
+ *
|
||||
+ * encrypt_type
|
||||
+ * 0 = NO_ENCRYPT,
|
||||
+ * 1 = ENCRYPT,
|
||||
+ * 2 ~ 3 - Reserved
|
||||
+ *
|
||||
+ * retry_limit
|
||||
+ * Specify the maximum number of transmissions, including the
|
||||
+ * initial transmission, to attempt before giving up if no ack
|
||||
+ * is received.
|
||||
+ * If the tx rate is specified, then all retries shall use the
|
||||
+ * same rate as the initial transmission.
|
||||
+ * If no tx rate is specified, the target can choose whether to
|
||||
+ * retain the original rate during the retransmissions, or to
|
||||
+ * fall back to a more robust rate.
|
||||
+ *
|
||||
+ * use_dcm_11ax
|
||||
+ * If set, Use Dual subcarrier modulation.
|
||||
+ * Valid only for 11ax preamble types HE_SU
|
||||
+ * and HE_EXT_SU
|
||||
+ *
|
||||
+ * ltf_subtype_11ax
|
||||
+ * Takes enum values of htt_11ax_ltf_subtype_t
|
||||
+ * Valid only for 11ax preamble types HE_SU
|
||||
+ * and HE_EXT_SU
|
||||
+ *
|
||||
+ * dyn_bw
|
||||
+ * 0 = static bw, 1 = dynamic bw
|
||||
+ *
|
||||
+ * bw_mask
|
||||
+ * Valid only if dyn_bw == 0 (static bw).
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * power
|
||||
+ * unit of the power field is 0.5 dbm
|
||||
+ * signed value ranging from -64dbm to 63.5 dbm
|
||||
+ *
|
||||
+ * mcs_mask
|
||||
+ * mcs bit mask of 0 ~ 11
|
||||
+ * Setting more than one MCS isn't currently
|
||||
+ * supported by the target (but is supported
|
||||
+ * in the interface in case in the future
|
||||
+ * the target supports specifications of
|
||||
+ * a limited set of MCS values.
|
||||
+ *
|
||||
+ * nss_mask
|
||||
+ * Nss bit mask 0 ~ 7
|
||||
+ * Setting more than one Nss isn't currently
|
||||
+ * supported by the target (but is supported
|
||||
+ * in the interface in case in the future
|
||||
+ * the target supports specifications of
|
||||
+ * a limited set of Nss values.
|
||||
+ *
|
||||
+ * pream_type
|
||||
+ * Preamble types
|
||||
+ *
|
||||
+ * update_peer_cache
|
||||
+ * When set these custom values will be
|
||||
+ * used for all packets, until the next
|
||||
+ * update via this ext header.
|
||||
+ * This is to make sure not all packets
|
||||
+ * need to include this header.
|
||||
+ *
|
||||
+ * chain_mask
|
||||
+ * specify which chains to transmit from
|
||||
+ *
|
||||
+ * key_flags
|
||||
+ * Key Index and related flags - used in mesh mode
|
||||
+ *
|
||||
+ * chanfreq
|
||||
+ * Channel frequency: This identifies the desired channel
|
||||
+ * frequency (in MHz) for tx frames. This is used by FW to help
|
||||
+ * determine when it is safe to transmit or drop frames for
|
||||
+ * off-channel operation.
|
||||
+ * The default value of zero indicates to FW that the corresponding
|
||||
+ * VDEV's home channel (if there is one) is the desired channel
|
||||
+ * frequency.
|
||||
+ *
|
||||
+ * expire_tsf_lo
|
||||
+ * tx expiry time (TSF) LSBs
|
||||
+ *
|
||||
+ * expire_tsf_hi
|
||||
+ * tx expiry time (TSF) MSBs
|
||||
+ *
|
||||
+ * learning_frame
|
||||
+ * When this flag is set, this frame will be dropped by FW
|
||||
+ * rather than being enqueued to the Transmit Queue Manager (TQM) HW.
|
||||
+ *
|
||||
+ * send_as_standalone
|
||||
+ * This will indicate if the msdu needs to be sent as a singleton PPDU,
|
||||
+ * i.e. with no A-MSDU or A-MPDU aggregation.
|
||||
+ * The scope is extended to other use-cases.
|
||||
+ *
|
||||
+ * is_host_opaque_valid
|
||||
+ * set this bit to 1 if the host_opaque_cookie is populated
|
||||
+ * with valid information.
|
||||
+ *
|
||||
+ * host_opaque_cookie
|
||||
+ * Host opaque cookie for special frames
|
||||
+ */
|
||||
+
|
||||
+struct htt_tx_msdu_desc_ext {
|
||||
+ u32
|
||||
+ valid_pwr : 1,
|
||||
+ valid_mcs_mask : 1,
|
||||
+ valid_nss_mask : 1,
|
||||
+ valid_preamble_type : 1,
|
||||
+ valid_retries : 1,
|
||||
+ valid_bw_info : 1,
|
||||
+ valid_guard_interval : 1,
|
||||
+ valid_chainmask : 1,
|
||||
+ valid_encrypt_type : 1,
|
||||
+ valid_key_flags : 1,
|
||||
+ valid_expire_tsf : 1,
|
||||
+ valid_chanfreq : 1,
|
||||
+ is_dsrc : 1,
|
||||
+ guard_interval : 2,
|
||||
+ encrypt_type : 2,
|
||||
+ retry_limit : 4,
|
||||
+ use_dcm_11ax : 1,
|
||||
+ ltf_subtype_11ax : 2,
|
||||
+ dyn_bw : 1,
|
||||
+ bw_mask : 6,
|
||||
+ host_tx_desc_pool : 1;
|
||||
+ u32
|
||||
+ power : 8,
|
||||
+ mcs_mask : 12,
|
||||
+ nss_mask : 8,
|
||||
+ pream_type : 3,
|
||||
+ update_peer_cache : 1;
|
||||
+ u32
|
||||
+ chain_mask : 8,
|
||||
+ key_flags : 8,
|
||||
+ chanfreq : 16;
|
||||
+
|
||||
+ u32 expire_tsf_lo;
|
||||
+ u32 expire_tsf_hi;
|
||||
+
|
||||
+ u32
|
||||
+ learning_frame : 1,
|
||||
+ send_as_standalone : 1,
|
||||
+ is_host_opaque_valid : 1,
|
||||
+ rsvd0 : 29;
|
||||
+ u32
|
||||
+ host_opaque_cookie : 16,
|
||||
+ rsvd1 : 16;
|
||||
+} __packed;
|
||||
+
|
||||
void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts);
|
||||
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -9764,6 +9764,9 @@ static int __ath11k_mac_register(struct
|
||||
*/
|
||||
ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
|
||||
|
||||
+ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
|
||||
+ ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
|
||||
+
|
||||
/* Apply the regd received during initialization */
|
||||
ret = ath11k_regd_update(ar);
|
||||
if (ret) {
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,80 @@
|
||||
From 6a9662d48c4f277380283050370ab3f1f940b6a6 Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Date: Mon, 4 Sep 2023 13:44:47 +0530
|
||||
Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config
|
||||
|
||||
Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL,
|
||||
HW only take care of tid classification if this flag is not set.
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 19 +------------------
|
||||
drivers/net/wireless/ath/ath11k/hal_tx.c | 1 -
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 ++
|
||||
3 files changed, 3 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -44,19 +44,6 @@ static void ath11k_dp_tx_encap_nwifi(str
|
||||
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_tx_get_tid(struct sk_buff *skb)
|
||||
-{
|
||||
- struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
- struct ath11k_skb_cb *cb = ATH11K_SKB_CB(skb);
|
||||
-
|
||||
- if (cb->flags & ATH11K_SKB_HW_80211_ENCAP)
|
||||
- return skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||
- else if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
- return HAL_DESC_REO_NON_QOS_TID;
|
||||
- else
|
||||
- return skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||
-}
|
||||
-
|
||||
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
|
||||
{
|
||||
switch (cipher) {
|
||||
@@ -143,9 +130,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru
|
||||
!ieee80211_is_data(hdr->frame_control)))
|
||||
return -ENOTSUPP;
|
||||
|
||||
- pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1);
|
||||
-
|
||||
ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb);
|
||||
+ pool_id = ring_selector;
|
||||
|
||||
tcl_ring_sel:
|
||||
tcl_ring_retry = false;
|
||||
@@ -221,10 +207,6 @@ tcl_ring_sel:
|
||||
if (ieee80211_vif_is_mesh(arvif->vif))
|
||||
ti.enable_mesh = true;
|
||||
|
||||
- ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE, 1);
|
||||
-
|
||||
- ti.tid = ath11k_dp_tx_get_tid(skb);
|
||||
-
|
||||
switch (ti.encap_type) {
|
||||
case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
|
||||
if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_tx.c
|
||||
@@ -65,7 +65,6 @@ void ath11k_hal_tx_cmd_desc_setup(struct
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_PKT_OFFSET, ti->pkt_offset);
|
||||
|
||||
tcl_cmd->info2 = ti->flags1 |
|
||||
- FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID, ti->tid) |
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ti->lmac_id);
|
||||
|
||||
tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -9682,6 +9682,8 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, USES_RSS);
|
||||
}
|
||||
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_TID_CLASS_OFFLOAD);
|
||||
+
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
|
||||
ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From c7bd857a315fb299e4c984be2f3720428477ae6e Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Date: Thu, 11 Nov 2021 11:14:08 +0530
|
||||
Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config
|
||||
|
||||
Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL,
|
||||
HW only take care of tid classification if this flag is not set.
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Signed-off-by: Gautham Kumar Senthilkumaran <quic_gauthamk@quicinc.com>
|
||||
---
|
||||
include/net/mac80211.h | 3 +++
|
||||
net/mac80211/debugfs.c | 1 +
|
||||
net/mac80211/wme.c | 3 +++
|
||||
3 files changed, 7 insertions(+)
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2727,6 +2727,8 @@ struct ieee80211_txq {
|
||||
*
|
||||
* @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload
|
||||
*
|
||||
+ * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload.
|
||||
+ *
|
||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
@@ -2786,6 +2788,7 @@ enum ieee80211_hw_flags {
|
||||
IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX,
|
||||
IEEE80211_HW_SUPPORTS_NSS_OFFLOAD,
|
||||
IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD,
|
||||
+ IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -498,6 +498,7 @@ static const char *hw_flag_names[] = {
|
||||
FLAG(MLO_MCAST_MULTI_LINK_TX),
|
||||
FLAG(SUPPORTS_NSS_OFFLOAD),
|
||||
FLAG(SUPPORTS_MESH_NSS_OFFLOAD),
|
||||
+ FLAG(SUPPORTS_TID_CLASS_OFFLOAD),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
@ -0,0 +1,208 @@
|
||||
From 0f024902a8a54c70204f5b2f824c5dc74888c536 Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <quic_srirrama@quicinc.com>
|
||||
Date: Wed, 29 Sep 2021 09:30:21 +0530
|
||||
Subject: [PATCH] mac80211: Add support for mesh fast Rx path
|
||||
|
||||
Add support to process rx frames for the mesh destination
|
||||
when driver supports fast Rx by offloading PN, Duplicate,
|
||||
reordering to the HW.
|
||||
|
||||
Fast Rx from a peer is enabled once the PLINK is established.
|
||||
Fast Rx is not supported for the forwarding path currently.
|
||||
|
||||
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
|
||||
---
|
||||
net/mac80211/cfg.c | 5 +
|
||||
net/mac80211/ieee80211_i.h | 1 +
|
||||
net/mac80211/mesh_plink.c | 5 +
|
||||
net/mac80211/rx.c | 262 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
4 files changed, 269 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1747,6 +1747,8 @@ static void sta_apply_mesh_params(struct
|
||||
/* init at low value */
|
||||
ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10);
|
||||
|
||||
+ ieee80211_check_fast_rx(sta);
|
||||
+
|
||||
break;
|
||||
case NL80211_PLINK_LISTEN:
|
||||
case NL80211_PLINK_BLOCKED:
|
||||
@@ -1761,6 +1763,7 @@ static void sta_apply_mesh_params(struct
|
||||
ieee80211_mps_sta_status_update(sta);
|
||||
changed |= ieee80211_mps_set_sta_local_pm(sta,
|
||||
NL80211_MESH_POWER_UNKNOWN);
|
||||
+ ieee80211_check_fast_rx(sta);
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
--- a/net/mac80211/mesh_plink.c
|
||||
+++ b/net/mac80211/mesh_plink.c
|
||||
@@ -381,6 +381,8 @@ static u64 __mesh_plink_deactivate(struc
|
||||
changed |= ieee80211_mps_set_sta_local_pm(sta,
|
||||
NL80211_MESH_POWER_UNKNOWN);
|
||||
|
||||
+ ieee80211_check_fast_rx(sta);
|
||||
+
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -846,6 +848,7 @@ static u64 mesh_plink_establish(struct i
|
||||
mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
|
||||
ieee80211_mps_sta_status_update(sta);
|
||||
changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
|
||||
+ ieee80211_check_fast_rx(sta);
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -864,7 +867,7 @@ static u64 mesh_plink_fsm(struct ieee802
|
||||
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
|
||||
enum ieee80211_self_protected_actioncode action = 0;
|
||||
u64 changed = 0;
|
||||
- bool flush = false;
|
||||
+ bool flush = false, check_fast_rx = false;
|
||||
|
||||
mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
|
||||
mplstates[sta->mesh->plink_state], mplevents[event]);
|
||||
@@ -924,6 +927,7 @@ static u64 mesh_plink_fsm(struct ieee802
|
||||
break;
|
||||
case CNF_ACPT:
|
||||
changed |= mesh_plink_establish(sdata, sta);
|
||||
+ check_fast_rx = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -939,6 +943,7 @@ static u64 mesh_plink_fsm(struct ieee802
|
||||
break;
|
||||
case OPN_ACPT:
|
||||
changed |= mesh_plink_establish(sdata, sta);
|
||||
+ check_fast_rx = true;
|
||||
action = WLAN_SP_MESH_PEERING_CONFIRM;
|
||||
break;
|
||||
default:
|
||||
@@ -985,6 +990,10 @@ static u64 mesh_plink_fsm(struct ieee802
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&sta->mesh->plink_lock);
|
||||
+
|
||||
+ if (check_fast_rx)
|
||||
+ ieee80211_check_fast_rx(sta);
|
||||
+
|
||||
if (flush)
|
||||
mesh_path_flush_by_nexthop(sta);
|
||||
if (action) {
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -4663,10 +4663,15 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
+ /* Not required for NSS mode */
|
||||
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))
|
||||
+ goto clear;
|
||||
+ /* Note: da and sa offs are not static, determine in fast rx path */
|
||||
+
|
||||
fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
||||
IEEE80211_FCTL_TODS);
|
||||
- fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
||||
- fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
||||
+
|
||||
+ fastrx.internal_forward = 0;
|
||||
break;
|
||||
default:
|
||||
goto clear;
|
||||
@@ -4707,7 +4712,7 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
__release(check_fast_rx);
|
||||
|
||||
if (assign)
|
||||
- new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
|
||||
+ new = kmemdup(&fastrx, sizeof(fastrx), GFP_ATOMIC);
|
||||
|
||||
offload_flags = get_bss_sdata(sdata)->vif.offload_flags;
|
||||
offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
@@ -4890,6 +4895,10 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
u8 sa[ETH_ALEN];
|
||||
} addrs __aligned(2);
|
||||
struct ieee80211_sta_rx_stats *stats;
|
||||
+ struct ieee80211s_hdr *mesh_hdr;
|
||||
+ struct mesh_path *mppath;
|
||||
+ u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs;
|
||||
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
|
||||
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
|
||||
* to a common data structure; drivers can implement that per queue
|
||||
@@ -4939,6 +4948,37 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
snap_offs += IEEE80211_CCMP_HDR_LEN;
|
||||
}
|
||||
|
||||
+ /* Find corresponding offsets for mesh hdr */
|
||||
+ if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
+ if (status->rx_flags & IEEE80211_RX_AMSDU)
|
||||
+ return false;
|
||||
+
|
||||
+ /* All mesh data frames needs to be QoS Data */
|
||||
+ if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
|
||||
+ return false;
|
||||
+
|
||||
+ /* TODO forwarding not handled yet in fast rx */
|
||||
+ if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Check if Min Mesh hdr is present */
|
||||
+ if (!pskb_may_pull(skb, hdrlen + 6))
|
||||
+ goto drop;
|
||||
+
|
||||
+ /* Goto mesh hdr, located at snap offs compared to AP/STA */
|
||||
+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs);
|
||||
+
|
||||
+ /* Only Ext Mesh hdr supported in this path now */
|
||||
+ if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6)
|
||||
+ return false;
|
||||
+
|
||||
+ /* Point to eaddr1 and eaddr2 */
|
||||
+ da_offs = snap_offs + ETH_ALEN;
|
||||
+ sa_offs = da_offs + ETH_ALEN;
|
||||
+
|
||||
+ snap_offs += sizeof(struct ieee80211s_hdr);
|
||||
+ }
|
||||
+
|
||||
if (!ieee80211_vif_is_mesh(&rx->sdata->vif) &&
|
||||
!(status->rx_flags & IEEE80211_RX_AMSDU)) {
|
||||
if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
|
||||
@@ -4976,9 +5016,33 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
return true;
|
||||
}
|
||||
|
||||
+ /* Update MPP table for the received packet */
|
||||
+ if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
+ char *proxied_addr, *mpp_addr;
|
||||
+
|
||||
+ mpp_addr = hdr->addr4;
|
||||
+ proxied_addr = mesh_hdr->eaddr2;
|
||||
+
|
||||
+ /* Update mpp for the SA */
|
||||
+ rcu_read_lock();
|
||||
+ mppath = mpp_path_lookup(sdata, proxied_addr);
|
||||
+ if (!mppath) {
|
||||
+ mpp_path_add(sdata, proxied_addr, mpp_addr);
|
||||
+ } else {
|
||||
+ spin_lock_bh(&mppath->state_lock);
|
||||
+
|
||||
+ if (!ether_addr_equal(mppath->mpp, mpp_addr))
|
||||
+ ether_addr_copy(mppath->mpp, mpp_addr);
|
||||
+
|
||||
+ mppath->exp_time = jiffies;
|
||||
+ spin_unlock_bh(&mppath->state_lock);
|
||||
+ }
|
||||
+ rcu_read_unlock();
|
||||
+ }
|
||||
+
|
||||
/* do the header conversion - first grab the addresses */
|
||||
- ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
|
||||
- ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
|
||||
+ ether_addr_copy(addrs.da, skb->data + da_offs);
|
||||
+ ether_addr_copy(addrs.sa, skb->data + sa_offs);
|
||||
if (ieee80211_vif_is_mesh(&rx->sdata->vif)) {
|
||||
skb_pull(skb, snap_offs - 2);
|
||||
put_unaligned_be16(skb->len - 2, skb->data);
|
||||
@ -0,0 +1,33 @@
|
||||
From 0628e831520aa2e57aed02aee4a1772b40ce4f9d Mon Sep 17 00:00:00 2001
|
||||
From: Nagarajan Maran <quic_nmaran@quicinc.com>
|
||||
Date: Thu, 30 Jun 2022 17:20:29 +0530
|
||||
Subject: [PATCH] mac80211: fix dynamic vlan warning with monitor interface restart
|
||||
|
||||
When monitor interface restarts, in nss offload disabled
|
||||
case, the encap and decap offload flags are removed
|
||||
from all the interfaces in that phy#.
|
||||
|
||||
However when dynamic VLAN and monitor interfaces are
|
||||
created in the same phy#, these flags are not updated
|
||||
correctly, due to which warning calltrace is observed.
|
||||
|
||||
Add condition check to update the correct flags in
|
||||
dynamic VLAN case.
|
||||
|
||||
Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
|
||||
---
|
||||
net/mac80211/iface.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -994,7 +994,8 @@ static bool ieee80211_set_sdata_offload_
|
||||
flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
|
||||
if (local->monitors &&
|
||||
- !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))
|
||||
+ (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) ||
|
||||
+ !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP)))
|
||||
flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
} else {
|
||||
flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,113 @@
|
||||
From a76238143218ea348cec4b5d26fe9411338ae09e Mon Sep 17 00:00:00 2001
|
||||
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
|
||||
Date: Fri, 6 Oct 2023 18:19:53 +0530
|
||||
Subject: [PATCH] mac80211: fix mesh ping issue
|
||||
|
||||
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
|
||||
---
|
||||
net/mac80211/rx.c | 68 +++--------------------------------------------
|
||||
1 file changed, 4 insertions(+), 64 deletions(-)
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -4748,16 +4748,14 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
- /* Not required for NSS mode */
|
||||
- if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))
|
||||
- goto clear;
|
||||
/* Note: da and sa offs are not static, determine in fast rx path */
|
||||
|
||||
fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
||||
IEEE80211_FCTL_TODS);
|
||||
-
|
||||
- fastrx.internal_forward = 0;
|
||||
- break;
|
||||
+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
||||
+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
goto clear;
|
||||
}
|
||||
@@ -4980,10 +4978,7 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
u8 sa[ETH_ALEN];
|
||||
} addrs __aligned(2);
|
||||
struct ieee80211_sta_rx_stats *stats;
|
||||
- struct ieee80211s_hdr *mesh_hdr;
|
||||
- struct mesh_path *mppath;
|
||||
u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs;
|
||||
- struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
|
||||
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
|
||||
* to a common data structure; drivers can implement that per queue
|
||||
@@ -5033,37 +5028,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
snap_offs += IEEE80211_CCMP_HDR_LEN;
|
||||
}
|
||||
|
||||
- /* Find corresponding offsets for mesh hdr */
|
||||
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
- if (status->rx_flags & IEEE80211_RX_AMSDU)
|
||||
- return false;
|
||||
-
|
||||
- /* All mesh data frames needs to be QoS Data */
|
||||
- if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
|
||||
- return false;
|
||||
-
|
||||
- /* TODO forwarding not handled yet in fast rx */
|
||||
- if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3))
|
||||
- return false;
|
||||
-
|
||||
- /* Check if Min Mesh hdr is present */
|
||||
- if (!pskb_may_pull(skb, hdrlen + 6))
|
||||
- goto drop;
|
||||
-
|
||||
- /* Goto mesh hdr, located at snap offs compared to AP/STA */
|
||||
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs);
|
||||
-
|
||||
- /* Only Ext Mesh hdr supported in this path now */
|
||||
- if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6)
|
||||
- return false;
|
||||
-
|
||||
- /* Point to eaddr1 and eaddr2 */
|
||||
- da_offs = snap_offs + ETH_ALEN;
|
||||
- sa_offs = da_offs + ETH_ALEN;
|
||||
-
|
||||
- snap_offs += sizeof(struct ieee80211s_hdr);
|
||||
- }
|
||||
-
|
||||
if (!ieee80211_vif_is_mesh(&rx->sdata->vif) &&
|
||||
!(status->rx_flags & IEEE80211_RX_AMSDU)) {
|
||||
if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
|
||||
@@ -5101,30 +5065,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
return true;
|
||||
}
|
||||
|
||||
- /* Update MPP table for the received packet */
|
||||
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
- char *proxied_addr, *mpp_addr;
|
||||
-
|
||||
- mpp_addr = hdr->addr4;
|
||||
- proxied_addr = mesh_hdr->eaddr2;
|
||||
-
|
||||
- /* Update mpp for the SA */
|
||||
- rcu_read_lock();
|
||||
- mppath = mpp_path_lookup(sdata, proxied_addr);
|
||||
- if (!mppath) {
|
||||
- mpp_path_add(sdata, proxied_addr, mpp_addr);
|
||||
- } else {
|
||||
- spin_lock_bh(&mppath->state_lock);
|
||||
-
|
||||
- if (!ether_addr_equal(mppath->mpp, mpp_addr))
|
||||
- ether_addr_copy(mppath->mpp, mpp_addr);
|
||||
-
|
||||
- mppath->exp_time = jiffies;
|
||||
- spin_unlock_bh(&mppath->state_lock);
|
||||
- }
|
||||
- rcu_read_unlock();
|
||||
- }
|
||||
-
|
||||
/* do the header conversion - first grab the addresses */
|
||||
ether_addr_copy(addrs.da, skb->data + da_offs);
|
||||
ether_addr_copy(addrs.sa, skb->data + sa_offs);
|
||||
@ -0,0 +1,324 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "spectral.h"
|
||||
#include "wow.h"
|
||||
#include "nss.h"
|
||||
+#include "vendor.h"
|
||||
|
||||
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
|
||||
|
||||
@@ -637,6 +638,11 @@ struct ath11k_coex_info {
|
||||
u32 pta_priority;
|
||||
};
|
||||
|
||||
+enum ath11k_ap_ps_state {
|
||||
+ ATH11K_AP_PS_STATE_OFF,
|
||||
+ ATH11K_AP_PS_STATE_ON,
|
||||
+};
|
||||
+
|
||||
struct ath11k {
|
||||
struct ath11k_base *ab;
|
||||
struct ath11k_pdev *pdev;
|
||||
@@ -765,6 +771,8 @@ struct ath11k {
|
||||
int monitor_vdev_id;
|
||||
struct completion fw_mode_reset;
|
||||
u8 ftm_msgref;
|
||||
+ int ap_ps_enabled;
|
||||
+ enum ath11k_ap_ps_state ap_ps_state;
|
||||
#ifdef CPTCFG_ATH11K_DEBUGFS
|
||||
struct ath11k_debug debug;
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4963,6 +4963,33 @@ static void ath11k_mac_dec_num_stations(
|
||||
ar->num_stations--;
|
||||
}
|
||||
|
||||
+int ath11k_mac_ap_ps_recalc(struct ath11k *ar)
|
||||
+{
|
||||
+ struct ath11k_vif *arvif;
|
||||
+ bool has_sta_iface = false;
|
||||
+ enum ath11k_ap_ps_state state = ATH11K_AP_PS_STATE_OFF;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
+ if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
+ has_sta_iface = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!has_sta_iface && !ar->num_stations && ar->ap_ps_enabled)
|
||||
+ state = ATH11K_AP_PS_STATE_ON;
|
||||
+
|
||||
+ if (ar->ap_ps_state == state)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = ath11k_wmi_pdev_ap_ps_cmd_send(ar, ar->pdev->pdev_id, state);
|
||||
+ if (!ret)
|
||||
+ ar->ap_ps_state = state;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int ath11k_mac_station_add(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
@@ -5002,6 +5029,12 @@ static int ath11k_mac_station_add(struct
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n",
|
||||
sta->addr, arvif->vdev_id);
|
||||
|
||||
+ ret = ath11k_mac_ap_ps_recalc(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {
|
||||
arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL);
|
||||
if (!arsta->tx_stats) {
|
||||
@@ -5158,6 +5191,9 @@ static int ath11k_mac_op_sta_state(struc
|
||||
|
||||
kfree(arsta->tx_stats);
|
||||
arsta->tx_stats = NULL;
|
||||
+ ret = ath11k_mac_ap_ps_recalc(ar);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret);
|
||||
|
||||
kfree(arsta->rx_stats);
|
||||
arsta->rx_stats = NULL;
|
||||
@@ -6566,6 +6602,7 @@ static void ath11k_mac_op_stop(struct ie
|
||||
|
||||
clear_bit(ATH11K_CAC_RUNNING, &ar->dev_flags);
|
||||
ar->state = ATH11K_STATE_OFF;
|
||||
+ ar->ap_ps_state = ATH11K_AP_PS_STATE_OFF;
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
@@ -6973,7 +7010,6 @@ static int ath11k_mac_op_add_interface(s
|
||||
arvif->vdev_id, ret);
|
||||
goto err;
|
||||
}
|
||||
-
|
||||
ar->num_created_vdevs++;
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM created, vdev_id %d\n",
|
||||
vif->addr, arvif->vdev_id);
|
||||
@@ -7120,6 +7156,10 @@ static int ath11k_mac_op_add_interface(s
|
||||
ret);
|
||||
}
|
||||
|
||||
+ ret = ath11k_mac_ap_ps_recalc(ar);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "failed to set ap ps ret %d\n", ret);
|
||||
+
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
@@ -7227,6 +7267,7 @@ err_vdev_del:
|
||||
|
||||
/* Recalc txpower for remaining vdev */
|
||||
ath11k_mac_txpower_recalc(ar);
|
||||
+ ath11k_mac_ap_ps_recalc(ar);
|
||||
|
||||
ath11k_debugfs_remove_interface(arvif);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.h
|
||||
@@ -135,6 +135,7 @@ void ath11k_mac_11d_scan_start(struct at
|
||||
void ath11k_mac_11d_scan_stop(struct ath11k *ar);
|
||||
void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab);
|
||||
|
||||
+int ath11k_mac_ap_ps_recalc(struct ath11k *ar);
|
||||
void ath11k_mac_destroy(struct ath11k_base *ab);
|
||||
void ath11k_mac_unregister(struct ath11k_base *ab);
|
||||
int ath11k_mac_register(struct ath11k_base *ab);
|
||||
--- a/drivers/net/wireless/ath/ath11k/vendor.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/vendor.c
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <net/netlink.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "core.h"
|
||||
-#include "vendor.h"
|
||||
#include "debug.h"
|
||||
|
||||
static const struct nla_policy
|
||||
@@ -21,6 +20,11 @@ ath11k_vendor_wlan_prio_policy[QCA_WLAN_
|
||||
[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
+static const struct nla_policy
|
||||
+ath11k_vendor_set_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
|
||||
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_FLAG}
|
||||
+};
|
||||
+
|
||||
static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
@@ -101,6 +105,51 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ath11k_vendor_set_wifi_config(struct wiphy *wihpy,
|
||||
+ struct wireless_dev *wdev,
|
||||
+ const void *data,
|
||||
+ int data_len)
|
||||
+{
|
||||
+ struct ieee80211_vif *vif;
|
||||
+ struct ath11k_vif *arvif;
|
||||
+ struct ath11k *ar;
|
||||
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!wdev)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ vif = wdev_to_ieee80211_vif(wdev);
|
||||
+ if (!vif)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ arvif = (struct ath11k_vif*)vif->drv_priv;
|
||||
+ if (!arvif)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ar = arvif->ar;
|
||||
+
|
||||
+ mutex_lock(&ar->conf_mutex);
|
||||
+
|
||||
+ ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data, data_len,
|
||||
+ ath11k_vendor_set_wifi_config_policy, NULL);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "invalid set wifi config policy attribute\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ ar->ap_ps_enabled = nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX]);
|
||||
+ ret = ath11k_mac_ap_ps_recalc(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static struct wiphy_vendor_command ath11k_vendor_commands[] = {
|
||||
{
|
||||
.info.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
@@ -108,8 +157,18 @@ static struct wiphy_vendor_command ath11
|
||||
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
|
||||
WIPHY_VENDOR_CMD_NEED_RUNNING,
|
||||
.doit = ath11k_vendor_btcoex_configure,
|
||||
- .policy = ath11k_vendor_btcoex_config_policy
|
||||
- }
|
||||
+ .policy = ath11k_vendor_btcoex_config_policy,
|
||||
+ .maxattr = QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX
|
||||
+ },
|
||||
+ {
|
||||
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
|
||||
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
|
||||
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
|
||||
+ .doit = ath11k_vendor_set_wifi_config,
|
||||
+ .policy = ath11k_vendor_set_wifi_config_policy,
|
||||
+ .maxattr = QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
|
||||
+ },
|
||||
};
|
||||
|
||||
int ath11k_vendor_register(struct ath11k *ar)
|
||||
--- a/drivers/net/wireless/ath/ath11k/vendor.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/vendor.h
|
||||
@@ -9,6 +9,9 @@
|
||||
#define QCA_NL80211_VENDOR_ID 0x001374
|
||||
|
||||
enum qca_nl80211_vendor_subcmds {
|
||||
+ /* Wi-Fi configuration subcommand */
|
||||
+ QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION = 74,
|
||||
+
|
||||
/* QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG: This command is used to
|
||||
* enable/disable BTCOEX and set priority for different type of WLAN
|
||||
* traffic over BT low priority traffic. This uses attributes in
|
||||
@@ -58,7 +61,17 @@ enum qca_wlan_vendor_attr_wlan_prio {
|
||||
QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1,
|
||||
};
|
||||
|
||||
+/* Attributes for data used by
|
||||
+ * QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION
|
||||
+ */
|
||||
+enum qca_wlan_vendor_attr_config {
|
||||
+ QCA_WLAN_VENDOR_ATTR_CONFIG_GTX = 57,
|
||||
|
||||
+ /* keep last */
|
||||
+ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
|
||||
+ QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
|
||||
+ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1,
|
||||
+};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -1446,6 +1446,38 @@ ath11k_wmi_rx_reord_queue_remove(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int ath11k_wmi_pdev_ap_ps_cmd_send(struct ath11k *ar, u8 pdev_id,
|
||||
+ u32 param_value)
|
||||
+{
|
||||
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
+ struct wmi_pdev_ap_ps_cmd *cmd;
|
||||
+ struct sk_buff *skb;
|
||||
+ int ret;
|
||||
+
|
||||
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
+ if (!skb)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ cmd = (struct wmi_pdev_ap_ps_cmd *)skb->data;
|
||||
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
+ WMI_TAG_PDEV_GREEN_AP_PS_ENABLE_CMD) |
|
||||
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
+ cmd->pdev_id = pdev_id;
|
||||
+ cmd->param_value = param_value;
|
||||
+
|
||||
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to send ap ps enable/disable cmd\n");
|
||||
+ dev_kfree_skb(skb);
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
+ "wmi pdev ap ps set pdev id %d value %d\n",
|
||||
+ pdev_id, param_value);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
|
||||
u32 param_value, u8 pdev_id)
|
||||
{
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -3110,6 +3110,12 @@ struct set_fwtest_params {
|
||||
u32 value;
|
||||
};
|
||||
|
||||
+struct wmi_pdev_ap_ps_cmd {
|
||||
+ u32 tlv_header;
|
||||
+ u32 pdev_id;
|
||||
+ u32 param_value;
|
||||
+} __packed;
|
||||
+
|
||||
struct wmi_fwtest_set_param_cmd_param {
|
||||
u32 tlv_header;
|
||||
u32 param_id;
|
||||
@@ -6628,6 +6634,7 @@ int ath11k_wmi_pdev_non_srg_obss_bssid_e
|
||||
u32 *bitmap);
|
||||
int ath11k_send_coex_config_cmd(struct ath11k *ar,
|
||||
struct coex_config_arg *coex_config);
|
||||
+int ath11k_wmi_pdev_ap_ps_cmd_send(struct ath11k *ar, u8 pdev_id, u32 value);
|
||||
int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
u8 bss_color, u32 period,
|
||||
bool enable);
|
||||
@ -0,0 +1,68 @@
|
||||
From 0ff455d1d446e34ae6c2596d4d8491f66fc61913 Mon Sep 17 00:00:00 2001
|
||||
From: Manish Dharanenthiran <quic_mdharane@quicinc.com>
|
||||
Date: Sat, 2 Dec 2023 03:38:31 +0530
|
||||
Subject: [PATCH] wifi: mac80211: Fix memory corruption during mesh beacon
|
||||
update
|
||||
|
||||
During mesh beacon update, u64 flag is used to check for
|
||||
bit set/unset for validation purpose. But, in
|
||||
'ieee80211_mbss_info_change_notify' API, unsigned long flag
|
||||
is modified using sizeof(u64). This leads to following issue:
|
||||
|
||||
> 'mbss_changed' flag in 'ieee80211_if_mesh' is declared as
|
||||
unsigned_long which creates an architecture dependency
|
||||
(32bit vs 64bit) while modifying it with u64 flag which
|
||||
leads to memory corruption.
|
||||
|
||||
Fix above mentioned issue by replacing unsigned long with u64
|
||||
for changed flag.
|
||||
|
||||
Signed-off-by: Manish Dharanenthiran <quic_mdharane@quicinc.com>
|
||||
---
|
||||
net/mac80211/ieee80211_i.h | 2 +-
|
||||
net/mac80211/mesh.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -683,7 +683,7 @@ struct ieee80211_if_mesh {
|
||||
struct timer_list mesh_path_root_timer;
|
||||
|
||||
unsigned long wrkq_flags;
|
||||
- unsigned long mbss_changed[64 / BITS_PER_LONG];
|
||||
+ unsigned long mbss_changed;
|
||||
|
||||
bool userspace_handles_dfs;
|
||||
|
||||
--- a/net/mac80211/mesh.c
|
||||
+++ b/net/mac80211/mesh.c
|
||||
@@ -1183,7 +1183,7 @@ void ieee80211_mbss_info_change_notify(s
|
||||
|
||||
/* if we race with running work, worst case this work becomes a noop */
|
||||
for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
|
||||
- set_bit(bit, ifmsh->mbss_changed);
|
||||
+ set_bit(bit, &ifmsh->mbss_changed);
|
||||
set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
|
||||
wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
|
||||
}
|
||||
@@ -1265,7 +1265,7 @@ void ieee80211_stop_mesh(struct ieee8021
|
||||
|
||||
/* clear any mesh work (for next join) we may have accrued */
|
||||
ifmsh->wrkq_flags = 0;
|
||||
- memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed));
|
||||
+ ifmsh->mbss_changed = 0;
|
||||
|
||||
local->fif_other_bss--;
|
||||
atomic_dec(&local->iff_allmultis);
|
||||
@@ -1732,9 +1732,9 @@ static void mesh_bss_info_changed(struct
|
||||
u32 bit;
|
||||
u64 changed = 0;
|
||||
|
||||
- for_each_set_bit(bit, ifmsh->mbss_changed,
|
||||
+ for_each_set_bit(bit, &ifmsh->mbss_changed,
|
||||
sizeof(changed) * BITS_PER_BYTE) {
|
||||
- clear_bit(bit, ifmsh->mbss_changed);
|
||||
+ clear_bit(bit, &ifmsh->mbss_changed);
|
||||
changed |= BIT(bit);
|
||||
}
|
||||
|
||||
@ -0,0 +1,113 @@
|
||||
From fbe5a76d8c9ff1cf3f906a3c863928fc1adcbc95 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Date: Tue, 16 Feb 2021 13:44:39 +0530
|
||||
Subject: [PATCH] ath11k: Add mesh nss offload support
|
||||
|
||||
- New capability advertising nss offload support for mesh type
|
||||
- Mesh obj vap and link vap registration/clean up
|
||||
- Command/event handling
|
||||
- New .ch files in ath11k for nss mesh offload related debugs
|
||||
- Tx/Rx data path on mesh link vap uses native wifi format
|
||||
- Mesh obj vap handls packets in ether format. No Tx on Mesh
|
||||
obj vap is expected as packets transmitted in slow path is
|
||||
supposed to be encapsulated in 802.11 format.
|
||||
- New mac80211-driver callbacks for mesh vap, mpath and mpp
|
||||
configurations.
|
||||
|
||||
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
|
||||
Change-Id: Ib6950344286ba18fab43586262c62dcd09557614
|
||||
Co-developed-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/nss.c | 1482 ++++++++++++++++++++++++---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.c
|
||||
@@ -35,6 +35,30 @@ ath11k_nss_get_vdev_opmode(struct ath11k
|
||||
return ATH11K_NSS_OPMODE_UNKNOWN;
|
||||
}
|
||||
|
||||
+static struct ath11k_vif *ath11k_nss_get_arvif_from_dev(struct net_device *dev)
|
||||
+{
|
||||
+ struct wireless_dev *wdev;
|
||||
+ struct ieee80211_vif *vif;
|
||||
+ struct ath11k_vif *arvif;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ return NULL;
|
||||
+
|
||||
+ wdev = dev->ieee80211_ptr;
|
||||
+ if (!wdev)
|
||||
+ return NULL;
|
||||
+
|
||||
+ vif = wdev_to_ieee80211_vif(wdev);
|
||||
+ if (!vif)
|
||||
+ return NULL;
|
||||
+
|
||||
+ arvif = (struct ath11k_vif *)vif->drv_priv;
|
||||
+ if (!arvif)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return arvif;
|
||||
+}
|
||||
+
|
||||
static void ath11k_nss_wifili_stats_sync(struct ath11k_base *ab,
|
||||
struct nss_wifili_stats_sync_msg *wlsoc_stats)
|
||||
{
|
||||
@@ -294,6 +318,9 @@ void ath11k_nss_wifili_event_receive(str
|
||||
|
||||
switch (msg_type) {
|
||||
case NSS_WIFILI_INIT_MSG:
|
||||
+ ab->nss.response = response;
|
||||
+ complete(&ab->nss.complete);
|
||||
+ break;
|
||||
case NSS_WIFILI_PDEV_INIT_MSG:
|
||||
case NSS_WIFILI_START_MSG:
|
||||
case NSS_WIFILI_SOC_RESET_MSG:
|
||||
@@ -302,7 +329,6 @@ void ath11k_nss_wifili_event_receive(str
|
||||
ab->nss.response = response;
|
||||
complete(&ab->nss.complete);
|
||||
break;
|
||||
-
|
||||
case NSS_WIFILI_PEER_CREATE_MSG:
|
||||
if (response != NSS_CMN_RESPONSE_EMSG)
|
||||
break;
|
||||
@@ -463,7 +489,9 @@ ath11k_nss_wifili_ext_callback_fn(struct
|
||||
ath11k_nss_process_mic_error(ab, skb);
|
||||
break;
|
||||
default:
|
||||
- kfree(skb);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_NSS, "unknown packet type received in wifili ext cb %d",
|
||||
+ wepm->pkt_type);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -786,24 +814,7 @@ ath11k_nss_vdev_special_data_receive(str
|
||||
int ret = 0;
|
||||
struct ath11k_peer *ta_peer = NULL;
|
||||
|
||||
- if (!dev) {
|
||||
- dev_kfree_skb_any(skb);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- wdev = dev->ieee80211_ptr;
|
||||
- if (!wdev) {
|
||||
- dev_kfree_skb_any(skb);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- vif = wdev_to_ieee80211_vif(wdev);
|
||||
- if (!vif) {
|
||||
- dev_kfree_skb_any(skb);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- arvif = (struct ath11k_vif *)vif->drv_priv;
|
||||
+ arvif = ath11k_nss_get_arvif_from_dev(dev);
|
||||
if (!arvif) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return;
|
||||
@ -0,0 +1,608 @@
|
||||
From 4635ca1f29bc5838d556b09e3c186b76a5198ddb Mon Sep 17 00:00:00 2001
|
||||
From: Manikanta Pubbisetty <mpubbise@codeaurora.org>
|
||||
Date: Fri, 18 Aug 2023 11:43:33 +0530
|
||||
Subject: [PATCH] ath11k: add rx histogram stats
|
||||
|
||||
Adding rx rate table and byte level peer rx statistics. Also,
|
||||
adding a debugfs knob to reset rx stats specific to the peer.
|
||||
|
||||
Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 19 ++-
|
||||
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 152 ++++++++++++++++--
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 95 +++++++++--
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.h | 19 +++
|
||||
drivers/net/wireless/ath/ath11k/hal_rx.c | 85 +++++++---
|
||||
drivers/net/wireless/ath/ath11k/hal_rx.h | 21 +++
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 18 +++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
8 files changed, 351 insertions(+), 59 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
#define ATH11K_INVALID_HW_MAC_ID 0xFF
|
||||
#define ATH11K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
+#define ATH11K_RX_RATE_TABLE_NUM 320
|
||||
+#define ATH11K_RX_RATE_TABLE_11AX_NUM 576
|
||||
|
||||
/* SMBIOS type containing Board Data File Name Extension */
|
||||
#define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8
|
||||
@@ -420,6 +422,17 @@ struct ath11k_vif_iter {
|
||||
struct ath11k_vif *arvif;
|
||||
};
|
||||
|
||||
+struct ath11k_rx_peer_rate_stats {
|
||||
+ u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
|
||||
+ u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1];
|
||||
+ u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1];
|
||||
+ u64 nss_count[HAL_RX_MAX_NSS];
|
||||
+ u64 bw_count[HAL_RX_BW_MAX];
|
||||
+ u64 gi_count[HAL_RX_GI_MAX];
|
||||
+ u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES];
|
||||
+ u64 rx_rate[ATH11K_RX_RATE_TABLE_11AX_NUM];
|
||||
+};
|
||||
+
|
||||
struct ath11k_rx_peer_stats {
|
||||
u64 num_msdu;
|
||||
u64 num_mpdu_fcs_ok;
|
||||
@@ -431,10 +444,6 @@ struct ath11k_rx_peer_stats {
|
||||
u64 non_ampdu_msdu_count;
|
||||
u64 stbc_count;
|
||||
u64 beamformed_count;
|
||||
- u64 mcs_count[HAL_RX_MAX_MCS + 1];
|
||||
- u64 nss_count[HAL_RX_MAX_NSS];
|
||||
- u64 bw_count[HAL_RX_BW_MAX];
|
||||
- u64 gi_count[HAL_RX_GI_MAX];
|
||||
u64 coding_count[HAL_RX_SU_MU_CODING_MAX];
|
||||
u64 tid_count[IEEE80211_NUM_TIDS + 1];
|
||||
u64 pream_cnt[HAL_RX_PREAMBLE_MAX];
|
||||
@@ -442,6 +451,8 @@ struct ath11k_rx_peer_stats {
|
||||
u64 rx_duration;
|
||||
u64 dcm_count;
|
||||
u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX];
|
||||
+ struct ath11k_rx_peer_rate_stats pkt_stats;
|
||||
+ struct ath11k_rx_peer_rate_stats byte_stats;
|
||||
};
|
||||
|
||||
#define ATH11K_HE_MCS_NUM 12
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "peer.h"
|
||||
#include "debug.h"
|
||||
#include "dp_tx.h"
|
||||
+#include "dp_rx.h"
|
||||
#include "debugfs_htt_stats.h"
|
||||
|
||||
static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones)
|
||||
@@ -390,8 +391,14 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
|
||||
int len = 0, i, retval = 0;
|
||||
- const int size = 4096;
|
||||
+ const int size = 4 * 4096;
|
||||
char *buf;
|
||||
+ int he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0;
|
||||
+ int rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM :
|
||||
+ ATH11K_RX_RATE_TABLE_NUM;
|
||||
+ char *legacy_rate_str[] = {"1Mbps", "2Mbps", "5.5Mbps", "6Mbps",
|
||||
+ "9Mbps", "11Mbps", "12Mbps", "18Mbps",
|
||||
+ "24Mbps", "36 Mbps", "48Mbps", "54Mbps"};
|
||||
|
||||
if (!rx_stats)
|
||||
return -ENOENT;
|
||||
@@ -422,14 +429,6 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
|
||||
rx_stats->num_mpdu_fcs_ok);
|
||||
len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS error: %llu\n",
|
||||
rx_stats->num_mpdu_fcs_err);
|
||||
- len += scnprintf(buf + len, size - len,
|
||||
- "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
|
||||
- rx_stats->gi_count[0], rx_stats->gi_count[1],
|
||||
- rx_stats->gi_count[2], rx_stats->gi_count[3]);
|
||||
- len += scnprintf(buf + len, size - len,
|
||||
- "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
|
||||
- rx_stats->bw_count[0], rx_stats->bw_count[1],
|
||||
- rx_stats->bw_count[2], rx_stats->bw_count[3]);
|
||||
len += scnprintf(buf + len, size - len, "BCC %llu LDPC %llu\n",
|
||||
rx_stats->coding_count[0], rx_stats->coding_count[1]);
|
||||
len += scnprintf(buf + len, size - len,
|
||||
@@ -444,14 +443,96 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
|
||||
len += scnprintf(buf + len, size - len, "TID(0-15) Legacy TID(16):");
|
||||
for (i = 0; i <= IEEE80211_NUM_TIDS; i++)
|
||||
len += scnprintf(buf + len, size - len, "%llu ", rx_stats->tid_count[i]);
|
||||
- len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):");
|
||||
- for (i = 0; i < HAL_RX_MAX_MCS + 1; i++)
|
||||
- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]);
|
||||
- len += scnprintf(buf + len, size - len, "\nNSS(1-8):");
|
||||
- for (i = 0; i < HAL_RX_MAX_NSS; i++)
|
||||
- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]);
|
||||
- len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ",
|
||||
+ len += scnprintf(buf + len, size - len, "\nRX Duration:%llu\n",
|
||||
rx_stats->rx_duration);
|
||||
+
|
||||
+ len += scnprintf(buf + len, size - len, "\nRX success packet stats:\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nHE packet stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->pkt_stats.he_mcs_count[i],
|
||||
+ (i + 1) % 6 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nVHT packet stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->pkt_stats.vht_mcs_count[i],
|
||||
+ (i + 1) % 5 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nHT packet stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->pkt_stats.ht_mcs_count[i],
|
||||
+ (i + 1) % 8 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nLegacy rate packet stats:\n");
|
||||
+ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i],
|
||||
+ rx_stats->pkt_stats.legacy_count[i],
|
||||
+ (i + 1) % 4 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nNSS packet stats:\n");
|
||||
+ for (i = 0; i < HAL_RX_MAX_NSS; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1,
|
||||
+ rx_stats->pkt_stats.nss_count[i]);
|
||||
+ len += scnprintf(buf + len, size - len,
|
||||
+ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
|
||||
+ rx_stats->pkt_stats.gi_count[0],
|
||||
+ rx_stats->pkt_stats.gi_count[1],
|
||||
+ rx_stats->pkt_stats.gi_count[2],
|
||||
+ rx_stats->pkt_stats.gi_count[3]);
|
||||
+ len += scnprintf(buf + len, size - len,
|
||||
+ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
|
||||
+ rx_stats->pkt_stats.bw_count[0],
|
||||
+ rx_stats->pkt_stats.bw_count[1],
|
||||
+ rx_stats->pkt_stats.bw_count[2],
|
||||
+ rx_stats->pkt_stats.bw_count[3]);
|
||||
+ len += scnprintf(buf + len, size - len, "\nRate Table (packets):\n");
|
||||
+ for (i = 0; i < rate_table_len; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%10llu%s",
|
||||
+ rx_stats->pkt_stats.rx_rate[i],
|
||||
+ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n");
|
||||
+
|
||||
+ len += scnprintf(buf + len, size - len, "\nRX success byte stats:\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nHE byte stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->byte_stats.he_mcs_count[i],
|
||||
+ (i + 1) % 6 ? "\t" : "\n");
|
||||
+
|
||||
+ len += scnprintf(buf + len, size - len, "\nVHT byte stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->byte_stats.vht_mcs_count[i],
|
||||
+ (i + 1) % 5 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nHT byte stats:\n");
|
||||
+ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i,
|
||||
+ rx_stats->byte_stats.ht_mcs_count[i],
|
||||
+ (i + 1) % 8 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nLegacy rate byte stats:\n");
|
||||
+ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i],
|
||||
+ rx_stats->byte_stats.legacy_count[i],
|
||||
+ (i + 1) % 4 ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len, "\nNSS byte stats:\n");
|
||||
+ for (i = 0; i < HAL_RX_MAX_NSS; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1,
|
||||
+ rx_stats->byte_stats.nss_count[i]);
|
||||
+ len += scnprintf(buf + len, size - len,
|
||||
+ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
|
||||
+ rx_stats->byte_stats.gi_count[0],
|
||||
+ rx_stats->byte_stats.gi_count[1],
|
||||
+ rx_stats->byte_stats.gi_count[2],
|
||||
+ rx_stats->byte_stats.gi_count[3]);
|
||||
+ len += scnprintf(buf + len, size - len,
|
||||
+ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
|
||||
+ rx_stats->byte_stats.bw_count[0],
|
||||
+ rx_stats->byte_stats.bw_count[1],
|
||||
+ rx_stats->byte_stats.bw_count[2],
|
||||
+ rx_stats->byte_stats.bw_count[3]);
|
||||
+ len += scnprintf(buf + len, size - len, "\nRate Table (bytes):\n");
|
||||
+ for (i = 0; i < rate_table_len; i++)
|
||||
+ len += scnprintf(buf + len, size - len, "%10llu%s",
|
||||
+ rx_stats->byte_stats.rx_rate[i],
|
||||
+ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n");
|
||||
+
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n",
|
||||
rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3400,10 +3400,43 @@ exit:
|
||||
return total_msdu_reaped;
|
||||
}
|
||||
|
||||
+static void
|
||||
+ath11k_dp_rx_update_peer_rate_table_stats(struct ath11k_rx_peer_stats *rx_stats,
|
||||
+ struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
+ u32 num_msdu)
|
||||
+{
|
||||
+ u32 rate_idx = 0;
|
||||
+ u32 mcs_idx = ppdu_info->mcs;
|
||||
+ u32 nss_idx = ppdu_info->nss - 1;
|
||||
+ u32 bw_idx = ppdu_info->bw;
|
||||
+ u32 gi_idx = ppdu_info->gi;
|
||||
+
|
||||
+ if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) ||
|
||||
+ (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N ||
|
||||
+ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) {
|
||||
+ rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx;
|
||||
+ rate_idx += bw_idx * 2 + gi_idx;
|
||||
+ } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) {
|
||||
+ gi_idx = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi);
|
||||
+ rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx;
|
||||
+ rate_idx += bw_idx * 3 + gi_idx;
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;
|
||||
+ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info)
|
||||
{
|
||||
struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
|
||||
+ struct ath11k *ar = arsta->arvif->ar;
|
||||
u32 num_msdu;
|
||||
int i;
|
||||
|
||||
@@ -3413,6 +3446,8 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
arsta->rssi_comb = ppdu_info->rssi_comb;
|
||||
ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb);
|
||||
|
||||
+ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar))
|
||||
+ return;
|
||||
num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count +
|
||||
ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count;
|
||||
|
||||
@@ -3429,18 +3464,6 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
ppdu_info->tid = IEEE80211_NUM_TIDS;
|
||||
}
|
||||
|
||||
- if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS)
|
||||
- rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu;
|
||||
-
|
||||
- if (ppdu_info->mcs <= HAL_RX_MAX_MCS)
|
||||
- rx_stats->mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
-
|
||||
- if (ppdu_info->gi < HAL_RX_GI_MAX)
|
||||
- rx_stats->gi_count[ppdu_info->gi] += num_msdu;
|
||||
-
|
||||
- if (ppdu_info->bw < HAL_RX_BW_MAX)
|
||||
- rx_stats->bw_count[ppdu_info->bw] += num_msdu;
|
||||
-
|
||||
if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)
|
||||
rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;
|
||||
|
||||
@@ -3469,8 +3492,6 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
rx_stats->dcm_count += ppdu_info->dcm;
|
||||
rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu;
|
||||
|
||||
- arsta->rssi_comb = ppdu_info->rssi_comb;
|
||||
-
|
||||
BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
|
||||
ARRAY_SIZE(ppdu_info->rssi_chain_pri20));
|
||||
|
||||
@@ -3479,6 +3500,52 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
|
||||
rx_stats->rx_duration += ppdu_info->rx_duration;
|
||||
arsta->rx_duration = rx_stats->rx_duration;
|
||||
+
|
||||
+ if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) {
|
||||
+ rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu;
|
||||
+ rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&
|
||||
+ ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {
|
||||
+ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
+ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
|
||||
+ /* To fit into rate table for HT packets */
|
||||
+ ppdu_info->mcs = ppdu_info->mcs % 8;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&
|
||||
+ ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) {
|
||||
+ rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
+ rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX &&
|
||||
+ ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) {
|
||||
+ rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
+ rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||
|
||||
+ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) &&
|
||||
+ ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) {
|
||||
+ rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu;
|
||||
+ rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->gi < HAL_RX_GI_MAX) {
|
||||
+ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;
|
||||
+ rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->bw < HAL_RX_BW_MAX) {
|
||||
+ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;
|
||||
+ rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu);
|
||||
+
|
||||
}
|
||||
|
||||
static struct sk_buff *ath11k_dp_rx_alloc_mon_status_buf(struct ath11k_base *ab,
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
@@ -69,6 +69,25 @@ struct ath11k_dp_rfc1042_hdr {
|
||||
__be16 snap_type;
|
||||
} __packed;
|
||||
|
||||
+static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi)
|
||||
+{
|
||||
+ u32 ret = 0;
|
||||
+
|
||||
+ switch (sgi) {
|
||||
+ case RX_MSDU_START_SGI_0_8_US:
|
||||
+ ret = NL80211_RATE_INFO_HE_GI_0_8;
|
||||
+ break;
|
||||
+ case RX_MSDU_START_SGI_1_6_US:
|
||||
+ ret = NL80211_RATE_INFO_HE_GI_1_6;
|
||||
+ break;
|
||||
+ case RX_MSDU_START_SGI_3_2_US:
|
||||
+ ret = NL80211_RATE_INFO_HE_GI_3_2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif,
|
||||
struct ieee80211_ampdu_params *params);
|
||||
int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif,
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
@@ -978,44 +978,78 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
||||
ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC,
|
||||
info1);
|
||||
ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1);
|
||||
- ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI;
|
||||
-
|
||||
- switch (ppdu_info->mcs) {
|
||||
- case 0 ... 7:
|
||||
- ppdu_info->nss = 1;
|
||||
- break;
|
||||
- case 8 ... 15:
|
||||
- ppdu_info->nss = 2;
|
||||
- break;
|
||||
- case 16 ... 23:
|
||||
- ppdu_info->nss = 3;
|
||||
- break;
|
||||
- case 24 ... 31:
|
||||
- ppdu_info->nss = 4;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (ppdu_info->nss > 1)
|
||||
- ppdu_info->mcs = ppdu_info->mcs % 8;
|
||||
-
|
||||
+ ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1);
|
||||
+ ppdu_info->nss = (ppdu_info->mcs >> 3) + 1;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_L_SIG_B: {
|
||||
struct hal_rx_lsig_b_info *lsigb =
|
||||
(struct hal_rx_lsig_b_info *)tlv_data;
|
||||
+ u8 rate;
|
||||
+
|
||||
+ rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE,
|
||||
+ __le32_to_cpu(lsigb->info0));
|
||||
|
||||
- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE,
|
||||
- __le32_to_cpu(lsigb->info0));
|
||||
+ switch (rate) {
|
||||
+ case 1:
|
||||
+ rate = HAL_RX_LEGACY_RATE_1_MBPS;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ case 5:
|
||||
+ rate = HAL_RX_LEGACY_RATE_2_MBPS;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ case 6:
|
||||
+ rate = HAL_RX_LEGACY_RATE_5_5_MBPS;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ case 7:
|
||||
+ rate = HAL_RX_LEGACY_RATE_11_MBPS;
|
||||
+ break;
|
||||
+ default:
|
||||
+ rate = HAL_RX_LEGACY_RATE_INVALID;
|
||||
+ }
|
||||
+ ppdu_info->rate = rate;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_L_SIG_A: {
|
||||
struct hal_rx_lsig_a_info *lsiga =
|
||||
(struct hal_rx_lsig_a_info *)tlv_data;
|
||||
+ u8 rate;
|
||||
|
||||
- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE,
|
||||
- __le32_to_cpu(lsiga->info0));
|
||||
+ rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE,
|
||||
+ __le32_to_cpu(lsiga->info0));
|
||||
+ switch (rate) {
|
||||
+ case 8:
|
||||
+ rate = HAL_RX_LEGACY_RATE_48_MBPS;
|
||||
+ break;
|
||||
+ case 9:
|
||||
+ rate = HAL_RX_LEGACY_RATE_24_MBPS;
|
||||
+ break;
|
||||
+ case 10:
|
||||
+ rate = HAL_RX_LEGACY_RATE_12_MBPS;
|
||||
+ break;
|
||||
+ case 11:
|
||||
+ rate = HAL_RX_LEGACY_RATE_6_MBPS;
|
||||
+ break;
|
||||
+ case 12:
|
||||
+ rate = HAL_RX_LEGACY_RATE_54_MBPS;
|
||||
+ break;
|
||||
+ case 13:
|
||||
+ rate = HAL_RX_LEGACY_RATE_36_MBPS;
|
||||
+ break;
|
||||
+ case 14:
|
||||
+ rate = HAL_RX_LEGACY_RATE_18_MBPS;
|
||||
+ break;
|
||||
+ case 15:
|
||||
+ rate = HAL_RX_LEGACY_RATE_9_MBPS;
|
||||
+ break;
|
||||
+ default:
|
||||
+ rate = HAL_RX_LEGACY_RATE_INVALID;
|
||||
+ }
|
||||
+ ppdu_info->rate = rate;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
|
||||
break;
|
||||
}
|
||||
@@ -1473,6 +1507,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
||||
peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info);
|
||||
if (peer_id)
|
||||
ppdu_info->peer_id = peer_id;
|
||||
+
|
||||
+ ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(mpdu_info);
|
||||
+
|
||||
break;
|
||||
}
|
||||
case HAL_RXPCU_PPDU_END_INFO: {
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
|
||||
@@ -19,7 +19,11 @@ struct hal_rx_wbm_rel_info {
|
||||
#define VHT_SIG_SU_NSS_MASK 0x7
|
||||
|
||||
#define HAL_RX_MAX_MCS 12
|
||||
+#define HAL_RX_MAX_MCS_HT 31
|
||||
+#define HAL_RX_MAX_MCS_VHT 9
|
||||
+#define HAL_RX_MAX_MCS_HE 11
|
||||
#define HAL_RX_MAX_NSS 8
|
||||
+#define HAL_RX_MAX_NUM_LEGACY_RATES 12
|
||||
|
||||
struct hal_rx_mon_status_tlv_hdr {
|
||||
u32 hdr;
|
||||
@@ -104,6 +108,22 @@ struct hal_rx_user_status {
|
||||
u32 mpdu_err_byte_count;
|
||||
};
|
||||
|
||||
+enum hal_rx_legacy_rate {
|
||||
+ HAL_RX_LEGACY_RATE_1_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_2_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_5_5_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_6_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_9_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_11_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_12_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_18_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_24_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_36_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_48_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_54_MBPS,
|
||||
+ HAL_RX_LEGACY_RATE_INVALID,
|
||||
+};
|
||||
+
|
||||
#define HAL_TLV_STATUS_PPDU_NOT_DONE HAL_RX_MON_STATUS_PPDU_NOT_DONE
|
||||
#define HAL_TLV_STATUS_PPDU_DONE HAL_RX_MON_STATUS_PPDU_DONE
|
||||
#define HAL_TLV_STATUS_BUF_DONE HAL_RX_MON_STATUS_BUF_DONE
|
||||
@@ -128,6 +148,7 @@ struct hal_rx_mon_ppdu_info {
|
||||
u32 num_mpdu_fcs_ok;
|
||||
u32 num_mpdu_fcs_err;
|
||||
u32 preamble_type;
|
||||
+ u32 mpdu_len;
|
||||
u16 chan_num;
|
||||
u16 tcp_msdu_count;
|
||||
u16 tcp_ack_msdu_count;
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -1051,6 +1051,17 @@ static u32 ath11k_hw_wcn6750_get_tcl_rin
|
||||
return skb_get_hash(skb);
|
||||
}
|
||||
|
||||
+static u32 ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info)
|
||||
+{
|
||||
+ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN,
|
||||
+ __le32_to_cpu(mpdu_info->u.ipq8074.info1));
|
||||
+}
|
||||
+
|
||||
+static u32 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info)
|
||||
+{
|
||||
+ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN,
|
||||
+ __le32_to_cpu(mpdu_info->u.qcn9074.info1));
|
||||
+}
|
||||
const struct ath11k_hw_ops ipq8074_ops = {
|
||||
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
|
||||
.wmi_init_config = ath11k_init_wmi_config_ipq8074,
|
||||
@@ -1089,6 +1100,7 @@ const struct ath11k_hw_ops ipq8074_ops =
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
.get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
|
||||
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
|
||||
#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
|
||||
.rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset,
|
||||
#endif
|
||||
@@ -1136,6 +1148,7 @@ const struct ath11k_hw_ops ipq6018_ops =
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
.get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
|
||||
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qca6390_ops = {
|
||||
@@ -1177,6 +1190,7 @@ const struct ath11k_hw_ops qca6390_ops =
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
.get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
|
||||
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qcn9074_ops = {
|
||||
@@ -1217,6 +1231,7 @@ const struct ath11k_hw_ops qcn9074_ops =
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_qcn9074_mpdu_info_get_peerid,
|
||||
.get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
|
||||
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops wcn6855_ops = {
|
||||
@@ -1339,6 +1354,7 @@ const struct ath11k_hw_ops ipq5018_ops =
|
||||
.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,
|
||||
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len,
|
||||
};
|
||||
|
||||
#define ATH11K_TX_RING_MASK_0 BIT(0)
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -315,6 +315,7 @@ struct ath11k_hw_ops {
|
||||
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);
|
||||
+ u32 (*rx_desc_get_hal_mpdu_len)(struct hal_rx_mpdu_info *mpdu_info);
|
||||
#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
|
||||
void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter);
|
||||
#endif
|
||||
@ -0,0 +1,452 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
@@ -532,6 +532,12 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
|
||||
len += scnprintf(buf + len, size - len, "%10llu%s",
|
||||
rx_stats->byte_stats.rx_rate[i],
|
||||
(i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n");
|
||||
+ len += scnprintf(buf + len, size - len,
|
||||
+ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %llu\n",
|
||||
+ rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
|
||||
+ rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2],
|
||||
+ rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4],
|
||||
+ rx_stats->ru_alloc_cnt[5]);
|
||||
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n",
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3236,11 +3236,12 @@ exit:
|
||||
static void
|
||||
ath11k_dp_rx_update_peer_rate_table_stats(struct ath11k_rx_peer_stats *rx_stats,
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
+ struct hal_rx_user_status* user_stats,
|
||||
u32 num_msdu)
|
||||
{
|
||||
u32 rate_idx = 0;
|
||||
- u32 mcs_idx = ppdu_info->mcs;
|
||||
- u32 nss_idx = ppdu_info->nss - 1;
|
||||
+ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs;
|
||||
+ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1;
|
||||
u32 bw_idx = ppdu_info->bw;
|
||||
u32 gi_idx = ppdu_info->gi;
|
||||
|
||||
@@ -3262,10 +3263,13 @@ ath11k_dp_rx_update_peer_rate_table_stat
|
||||
}
|
||||
|
||||
rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;
|
||||
- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
|
||||
+ if (user_stats)
|
||||
+ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count;
|
||||
+ else
|
||||
+ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
|
||||
}
|
||||
|
||||
-static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,
|
||||
+static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta,
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info)
|
||||
{
|
||||
struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
|
||||
@@ -3323,7 +3327,6 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;
|
||||
rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;
|
||||
rx_stats->dcm_count += ppdu_info->dcm;
|
||||
- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
|
||||
ARRAY_SIZE(ppdu_info->rssi_chain_pri20));
|
||||
@@ -3341,10 +3344,10 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
|
||||
if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&
|
||||
ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {
|
||||
- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
|
||||
- /* To fit into rate table for HT packets */
|
||||
- ppdu_info->mcs = ppdu_info->mcs % 8;
|
||||
+ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
|
||||
+ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
|
||||
+ /* To fit into rate table for HT packets */
|
||||
+ ppdu_info->mcs = ppdu_info->mcs % 8;
|
||||
}
|
||||
|
||||
if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&
|
||||
@@ -3377,7 +3380,120 @@ static void ath11k_dp_rx_update_peer_sta
|
||||
rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;
|
||||
}
|
||||
|
||||
- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu);
|
||||
+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void ath11k_dp_rx_update_user_stats(struct ath11k *ar,
|
||||
+ struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
+ u32 uid)
|
||||
+{
|
||||
+ struct ath11k_sta *arsta = NULL;
|
||||
+ struct ath11k_rx_peer_stats *rx_stats = NULL;
|
||||
+ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid];
|
||||
+ struct ath11k_peer *peer;
|
||||
+ u32 num_msdu;
|
||||
+
|
||||
+ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF)
|
||||
+ return;
|
||||
+
|
||||
+ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index);
|
||||
+
|
||||
+ if (peer == NULL) {
|
||||
+ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n",
|
||||
+ user_stats->ast_index);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ arsta = (struct ath11k_sta *)peer->sta->drv_priv;
|
||||
+ rx_stats = arsta->rx_stats;
|
||||
+
|
||||
+ if (!rx_stats)
|
||||
+ return;
|
||||
+
|
||||
+ arsta->rssi_comb = ppdu_info->rssi_comb;
|
||||
+
|
||||
+ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count +
|
||||
+ user_stats->udp_msdu_count + user_stats->other_msdu_count;
|
||||
+
|
||||
+ rx_stats->num_msdu += num_msdu;
|
||||
+ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count +
|
||||
+ user_stats->tcp_ack_msdu_count;
|
||||
+ rx_stats->udp_msdu_count += user_stats->udp_msdu_count;
|
||||
+ rx_stats->other_msdu_count += user_stats->other_msdu_count;
|
||||
+
|
||||
+ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)
|
||||
+ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;
|
||||
+
|
||||
+ if (user_stats->tid <= IEEE80211_NUM_TIDS)
|
||||
+ rx_stats->tid_count[user_stats->tid] += num_msdu;
|
||||
+
|
||||
+ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX)
|
||||
+ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu;
|
||||
+
|
||||
+ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)
|
||||
+ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;
|
||||
+
|
||||
+ if (ppdu_info->is_stbc)
|
||||
+ rx_stats->stbc_count += num_msdu;
|
||||
+
|
||||
+ if (ppdu_info->beamformed)
|
||||
+ rx_stats->beamformed_count += num_msdu;
|
||||
+
|
||||
+ if (user_stats->mpdu_cnt_fcs_ok > 1)
|
||||
+ rx_stats->ampdu_msdu_count += num_msdu;
|
||||
+ else
|
||||
+ rx_stats->non_ampdu_msdu_count += num_msdu;
|
||||
+
|
||||
+ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok;
|
||||
+ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err;
|
||||
+ rx_stats->dcm_count += ppdu_info->dcm;
|
||||
+ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
|
||||
+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)
|
||||
+ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;
|
||||
+
|
||||
+ rx_stats->rx_duration += ppdu_info->rx_duration;
|
||||
+ arsta->rx_duration = rx_stats->rx_duration;
|
||||
+
|
||||
+ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {
|
||||
+ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;
|
||||
+ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count;
|
||||
+ }
|
||||
+
|
||||
+ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX &&
|
||||
+ user_stats->mcs <= HAL_RX_MAX_MCS_HE) {
|
||||
+ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu;
|
||||
+ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->gi < HAL_RX_GI_MAX) {
|
||||
+ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;
|
||||
+ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count;
|
||||
+ }
|
||||
+
|
||||
+ if (ppdu_info->bw < HAL_RX_BW_MAX) {
|
||||
+ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;
|
||||
+ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu);
|
||||
+}
|
||||
+
|
||||
+static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar,
|
||||
+ struct hal_rx_mon_ppdu_info *ppdu_info)
|
||||
+{
|
||||
+ u32 num_users, i;
|
||||
+
|
||||
+ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar))
|
||||
+ return;
|
||||
+
|
||||
+ num_users = ppdu_info->num_users;
|
||||
+ if (num_users > HAL_MAX_UL_MU_USERS)
|
||||
+ num_users = HAL_MAX_UL_MU_USERS;
|
||||
+
|
||||
+ for (i = 0; i < num_users; i++) {
|
||||
+ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i);
|
||||
+ }
|
||||
|
||||
}
|
||||
|
||||
@@ -5846,6 +5962,55 @@ static void ath11k_dp_rx_mon_dest_proces
|
||||
}
|
||||
}
|
||||
|
||||
+void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info)
|
||||
+{
|
||||
+ struct hal_rx_user_status *rx_user_status;
|
||||
+ u32 num_users;
|
||||
+ uint32_t i;
|
||||
+ uint32_t mu_ul_user_v0_word0;
|
||||
+ uint32_t mu_ul_user_v0_word1;
|
||||
+ uint32_t ru_size;
|
||||
+
|
||||
+ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
|
||||
+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO))
|
||||
+ return;
|
||||
+
|
||||
+ num_users = ppdu_info->num_users;
|
||||
+ if (num_users > HAL_MAX_UL_MU_USERS)
|
||||
+ num_users = HAL_MAX_UL_MU_USERS;
|
||||
+
|
||||
+ for (i = 0; i < num_users; i++) {
|
||||
+ rx_user_status = &ppdu_info->userstats[i];
|
||||
+ mu_ul_user_v0_word0 =
|
||||
+ rx_user_status->ul_ofdma_user_v0_word0;
|
||||
+ mu_ul_user_v0_word1 =
|
||||
+ rx_user_status->ul_ofdma_user_v0_word1;
|
||||
+
|
||||
+ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID,
|
||||
+ mu_ul_user_v0_word0) &&
|
||||
+ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER,
|
||||
+ mu_ul_user_v0_word0)) {
|
||||
+ rx_user_status->mcs =
|
||||
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS,
|
||||
+ mu_ul_user_v0_word1);
|
||||
+ rx_user_status->nss =
|
||||
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS,
|
||||
+ mu_ul_user_v0_word1) + 1;
|
||||
+
|
||||
+ rx_user_status->ofdma_info_valid = 1;
|
||||
+ rx_user_status->ul_ofdma_ru_start_index =
|
||||
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START,
|
||||
+ mu_ul_user_v0_word1);
|
||||
+
|
||||
+ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE,
|
||||
+ mu_ul_user_v0_word1);
|
||||
+ rx_user_status->ul_ofdma_ru_width = ru_size;
|
||||
+ rx_user_status->ul_ofdma_ru_size = ru_size;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
@@ -5919,8 +6084,13 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
|
||||
if ((ppdu_info->fc_valid) &&
|
||||
(ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
|
||||
- arsta = (struct ath11k_sta *)peer->sta->drv_priv;
|
||||
- ath11k_dp_rx_update_peer_stats(arsta, ppdu_info);
|
||||
+ if (ppdu_info.reception_type == HAL_RX_RECEPTION_TYPE_SU) {
|
||||
+ arsta = (struct ath11k_sta *)peer->sta->drv_priv;
|
||||
+ ath11k_dp_rx_update_peer_su_stats(arsta, &ppdu_info);
|
||||
+ } else {
|
||||
+ ath11k_dp_rx_mon_process_ulofdma(&ppdu_info);
|
||||
+ ath11k_dp_rx_update_peer_mu_stats(ar, &ppdu_info);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
@@ -804,7 +804,6 @@ void ath11k_hal_reo_init_cmd_ring(struct
|
||||
}
|
||||
}
|
||||
|
||||
-#define HAL_MAX_UL_MU_USERS 37
|
||||
static inline void
|
||||
ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
|
||||
struct hal_rx_user_status *rx_user_status)
|
||||
@@ -836,6 +835,8 @@ ath11k_hal_rx_populate_mu_user_info(void
|
||||
{
|
||||
rx_user_status->ast_index = ppdu_info->ast_index;
|
||||
rx_user_status->tid = ppdu_info->tid;
|
||||
+ rx_user_status->tcp_ack_msdu_count =
|
||||
+ ppdu_info->tcp_ack_msdu_count;
|
||||
rx_user_status->tcp_msdu_count =
|
||||
ppdu_info->tcp_msdu_count;
|
||||
rx_user_status->udp_msdu_count =
|
||||
@@ -859,6 +860,9 @@ ath11k_hal_rx_populate_mu_user_info(void
|
||||
ppdu_info->num_mpdu_fcs_ok;
|
||||
rx_user_status->mpdu_cnt_fcs_err =
|
||||
ppdu_info->num_mpdu_fcs_err;
|
||||
+ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0],
|
||||
+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
|
||||
+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
|
||||
|
||||
ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
|
||||
}
|
||||
@@ -888,6 +892,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
||||
__le32_to_cpu(ppdu_start->info0));
|
||||
ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);
|
||||
ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);
|
||||
+
|
||||
+ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {
|
||||
+ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;
|
||||
+ ppdu_info->num_users = 0;
|
||||
+ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,
|
||||
+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
|
||||
+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
case HAL_RX_PPDU_END_USER_STATS: {
|
||||
@@ -942,15 +954,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
||||
|
||||
if (userid < HAL_MAX_UL_MU_USERS) {
|
||||
struct hal_rx_user_status *rxuser_stats =
|
||||
- &ppdu_info->userstats;
|
||||
+ &ppdu_info->userstats[userid];
|
||||
+ ppdu_info->num_users += 1;
|
||||
|
||||
ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats);
|
||||
ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info,
|
||||
rxuser_stats);
|
||||
}
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] =
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[0] =
|
||||
__le32_to_cpu(eu_stats->rsvd1[0]);
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] =
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[1] =
|
||||
__le32_to_cpu(eu_stats->rsvd1[1]);
|
||||
|
||||
break;
|
||||
@@ -958,12 +971,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
||||
case HAL_RX_PPDU_END_USER_STATS_EXT: {
|
||||
struct hal_rx_ppdu_end_user_stats_ext *eu_stats =
|
||||
(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5;
|
||||
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5;
|
||||
+ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6;
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_HT_SIG: {
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
|
||||
@@ -72,6 +72,10 @@ enum hal_rx_reception_type {
|
||||
#define HAL_RX_FCS_LEN 4
|
||||
#define HAL_AST_IDX_INVALID 0xFFFF
|
||||
|
||||
+#define HAL_MAX_UL_MU_USERS 37
|
||||
+#define HAL_RX_MAX_MPDU 256
|
||||
+#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5)
|
||||
+
|
||||
enum hal_rx_mon_status {
|
||||
HAL_RX_MON_STATUS_PPDU_NOT_DONE,
|
||||
HAL_RX_MON_STATUS_PPDU_DONE,
|
||||
@@ -82,14 +86,15 @@ struct hal_rx_user_status {
|
||||
u32 mcs:4,
|
||||
nss:3,
|
||||
ofdma_info_valid:1,
|
||||
- dl_ofdma_ru_start_index:7,
|
||||
- dl_ofdma_ru_width:7,
|
||||
- dl_ofdma_ru_size:8;
|
||||
+ ul_ofdma_ru_start_index:7,
|
||||
+ ul_ofdma_ru_width:7,
|
||||
+ ul_ofdma_ru_size:8;
|
||||
u32 ul_ofdma_user_v0_word0;
|
||||
u32 ul_ofdma_user_v0_word1;
|
||||
u32 ast_index;
|
||||
u32 tid;
|
||||
u16 tcp_msdu_count;
|
||||
+ u16 tcp_ack_msdu_count;
|
||||
u16 udp_msdu_count;
|
||||
u16 other_msdu_count;
|
||||
u16 frame_control;
|
||||
@@ -103,7 +108,7 @@ struct hal_rx_user_status {
|
||||
u8 rs_flags;
|
||||
u32 mpdu_cnt_fcs_ok;
|
||||
u32 mpdu_cnt_fcs_err;
|
||||
- u32 mpdu_fcs_ok_bitmap[8];
|
||||
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
|
||||
u32 mpdu_ok_byte_count;
|
||||
u32 mpdu_err_byte_count;
|
||||
};
|
||||
@@ -144,6 +149,7 @@ struct hal_sw_mon_ring_entries {
|
||||
|
||||
struct hal_rx_mon_ppdu_info {
|
||||
u32 ppdu_id;
|
||||
+ u32 last_ppdu_id;
|
||||
u32 ppdu_ts;
|
||||
u32 num_mpdu_fcs_ok;
|
||||
u32 num_mpdu_fcs_err;
|
||||
@@ -212,9 +218,20 @@ struct hal_rx_mon_ppdu_info {
|
||||
u8 ltf_size;
|
||||
u8 rxpcu_filter_pass;
|
||||
char rssi_chain[8][8];
|
||||
- struct hal_rx_user_status userstats;
|
||||
+ u32 num_users;
|
||||
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
|
||||
+ struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS];
|
||||
};
|
||||
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9)
|
||||
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16)
|
||||
+
|
||||
#define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0)
|
||||
|
||||
struct hal_rx_ppdu_start {
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -94,6 +94,20 @@ struct ath11k_peer *ath11k_peer_find_by_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab,
|
||||
+ int ast_hash)
|
||||
+{
|
||||
+ struct ath11k_peer *peer;
|
||||
+
|
||||
+ lockdep_assert_held(&ab->base_lock);
|
||||
+
|
||||
+ list_for_each_entry(peer, &ab->peers, list)
|
||||
+ if (ast_hash == peer->ast_hash)
|
||||
+ return peer;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab,
|
||||
struct ath11k_peer *peer,
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -112,6 +112,7 @@ struct ath11k_peer *ath11k_peer_find(str
|
||||
struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
|
||||
const u8 *addr);
|
||||
struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id);
|
||||
+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash);
|
||||
void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id);
|
||||
int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr);
|
||||
int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
@ -0,0 +1,146 @@
|
||||
From 41363c3109235a96d90d5946bbc01d1cc8dad47e Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Sun, 6 Sep 2020 11:01:38 +0530
|
||||
Subject: [PATCH] ath11k: update debugfs support for mupltiple radios in PCI
|
||||
bus
|
||||
|
||||
debugfs_ath11k struct is moved to ath11k_core, since its common
|
||||
for both pci and ahb.
|
||||
|
||||
Current ath11k_pci insmod fails if there are multiple PCI rdaios,
|
||||
debugfs directory is created with soc_name and bus_id to allow
|
||||
creating debugfs directory for second PCI radio.
|
||||
|
||||
with this Debugfs entries looks like,
|
||||
# ls -l /sys/kernel/debug/ath11k/
|
||||
ipq8074 hw2.0 qcn9000 hw1.0_0000:01:00.0 qcn9000 hw1.0_0001:01:00.0
|
||||
|
||||
# ls -l /sys/kernel/debug/ath11k/ipq8074 hw2.0/
|
||||
mac0 mac1 simulate_fw_crash soc_dp_stats
|
||||
|
||||
# ls -l /sys/kernel/debug/ath11k/qcn9000 hw1.0_0000:01:00.0
|
||||
mac0 simulate_fw_crash soc_dp_stats
|
||||
|
||||
# /sys/kernel/debug/ath11k/qcn9000 hw1.0_0001:01:00.0:
|
||||
mac0 simulate_fw_crash soc_dp_stats
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 12 +++++++
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 -
|
||||
drivers/net/wireless/ath/ath11k/debugfs.c | 57 ++++++++++++++++++++++++------
|
||||
drivers/net/wireless/ath/ath11k/debugfs.h | 11 ++++++
|
||||
5 files changed, 72 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -2260,5 +2260,17 @@ err_sc_free:
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_core_alloc);
|
||||
|
||||
+int ath11k_init(void)
|
||||
+{
|
||||
+ return ath11k_debugfs_create();
|
||||
+}
|
||||
+module_init(ath11k_init);
|
||||
+
|
||||
+void ath11k_exit(void)
|
||||
+{
|
||||
+ ath11k_debugfs_destroy();
|
||||
+}
|
||||
+module_exit(ath11k_exit);
|
||||
+
|
||||
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "hif.h"
|
||||
#include "qmi.h"
|
||||
|
||||
+struct dentry *debugfs_ath11k;
|
||||
+
|
||||
static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
|
||||
"REO2SW1_RING",
|
||||
"REO2SW2_RING",
|
||||
@@ -1228,8 +1230,6 @@ int ath11k_debugfs_pdev_create(struct at
|
||||
|
||||
void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
|
||||
{
|
||||
- debugfs_remove_recursive(ab->debugfs_soc);
|
||||
- ab->debugfs_soc = NULL;
|
||||
}
|
||||
|
||||
int ath11k_debugfs_soc_create(struct ath11k_base *ab)
|
||||
@@ -1282,6 +1282,24 @@ void ath11k_debugfs_soc_destroy(struct a
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
|
||||
|
||||
+int ath11k_debugfs_create(void)
|
||||
+{
|
||||
+ debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
|
||||
+ if (IS_ERR_OR_NULL(debugfs_ath11k)) {
|
||||
+ if (IS_ERR(debugfs_ath11k))
|
||||
+ return PTR_ERR(debugfs_ath11k);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void ath11k_debugfs_destroy(void)
|
||||
+{
|
||||
+ debugfs_remove_recursive(debugfs_ath11k);
|
||||
+ debugfs_ath11k = NULL;
|
||||
+}
|
||||
+
|
||||
void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
|
||||
{
|
||||
struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
|
||||
@@ -1932,6 +1950,9 @@ void ath11k_debugfs_unregister(struct at
|
||||
kfree(dbr_debug);
|
||||
ar->debug.dbr_debug[i] = NULL;
|
||||
}
|
||||
+
|
||||
+ debugfs_remove_recursive(ar->debug.debugfs_pdev);
|
||||
+ ar->debug.debugfs_pdev = NULL;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_write_twt_add_dialog(struct file *file,
|
||||
@@ -2294,6 +2315,9 @@ int ath11k_debugfs_register(struct ath11
|
||||
char pdev_name[10];
|
||||
char buf[100] = {0};
|
||||
|
||||
+ if (!(IS_ERR_OR_NULL(ar->debug.debugfs_pdev)))
|
||||
+ return 0;
|
||||
+
|
||||
snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx);
|
||||
|
||||
ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
|
||||
@@ -282,6 +282,8 @@ do { \
|
||||
#endif
|
||||
|
||||
#ifdef CPTCFG_ATH11K_DEBUGFS
|
||||
+int ath11k_debugfs_create(void);
|
||||
+void ath11k_debugfs_destroy(void);
|
||||
int ath11k_debugfs_soc_create(struct ath11k_base *ab);
|
||||
void ath11k_debugfs_soc_destroy(struct ath11k_base *ab);
|
||||
int ath11k_debugfs_pdev_create(struct ath11k_base *ab);
|
||||
@@ -338,6 +340,15 @@ static inline int ath11k_debug_is_memory
|
||||
}
|
||||
|
||||
#else
|
||||
+static inline int ath11k_debugfs_create(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void ath11k_debugfs_destroy(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab)
|
||||
{
|
||||
return 0;
|
||||
@ -0,0 +1,253 @@
|
||||
From 91df8aa674d2d4064ab22f47515c3fb126527208 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Date: Thu, 12 Nov 2020 15:02:56 +0530
|
||||
Subject: [PATCH] ath11k: NSS MCBC Exception added for STA
|
||||
|
||||
Since NSS FW is not supporting PN check for MCBC pkts, those pkts are
|
||||
excepted from NSS offload to pass through mac80211 PN check.
|
||||
|
||||
Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/nss.c | 128 +++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/nss.h | 51 ++++----
|
||||
2 files changed, 153 insertions(+), 26 deletions(-)
|
||||
create mode 100644 mac80211/patches/301-ath11k-nss-mcbc-exception.patch
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.c
|
||||
@@ -611,7 +611,7 @@ static int ath11k_nss_undecap_nwifi(stru
|
||||
|
||||
static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev,
|
||||
u8* src_mac, u8 is_sa_valid, u8 addr4_valid,
|
||||
- u16 peer_id, bool *drop)
|
||||
+ u16 peer_id)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_ast_entry *ast_entry = NULL;
|
||||
@@ -647,8 +647,6 @@ static void ath11k_nss_wds_type_rx(struc
|
||||
}
|
||||
}
|
||||
|
||||
- if (!ta_peer->nss.ext_vdev_up)
|
||||
- *drop = true;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
@@ -692,8 +690,7 @@ static void ath11k_nss_mec_handler(struc
|
||||
|
||||
static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif,
|
||||
struct sk_buff *skb,
|
||||
- struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata,
|
||||
- bool *drop)
|
||||
+ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
@@ -715,7 +712,7 @@ static void ath11k_nss_vdev_spl_receive_
|
||||
switch (wds_type) {
|
||||
case NSS_WIFI_VDEV_WDS_TYPE_RX:
|
||||
ath11k_nss_wds_type_rx(ar, skb->dev, src_mac, is_sa_valid,
|
||||
- addr4_valid, peer_id, drop);
|
||||
+ addr4_valid, peer_id);
|
||||
break;
|
||||
case NSS_WIFI_VDEV_WDS_TYPE_MEC:
|
||||
ath11k_nss_mec_handler(ar, (u8 *)(skb->data));
|
||||
@@ -778,14 +775,16 @@ ath11k_nss_vdev_special_data_receive(str
|
||||
{
|
||||
struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL;
|
||||
struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL;
|
||||
+ struct nss_wifi_vdev_addr4_data_metadata *addr4_metadata = NULL;
|
||||
struct wireless_dev *wdev;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ath11k_vif *arvif;
|
||||
struct ath11k_base *ab;
|
||||
- bool drop = false;
|
||||
+ struct ath11k_skb_rxcb *rxcb;
|
||||
bool eth_decap = false;
|
||||
int data_offs = 0;
|
||||
int ret = 0;
|
||||
+ struct ath11k_peer *ta_peer = NULL;
|
||||
|
||||
if (!dev) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -834,15 +833,50 @@ ath11k_nss_vdev_special_data_receive(str
|
||||
return;
|
||||
}
|
||||
|
||||
- if (eth_decap && wifi_metadata->pkt_type ==
|
||||
- NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN) {
|
||||
- wds_metadata = &wifi_metadata->metadata.wds_metadata;
|
||||
- ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb,
|
||||
- wds_metadata, &drop);
|
||||
- }
|
||||
+ switch(wifi_metadata->pkt_type) {
|
||||
+ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN:
|
||||
+ if (eth_decap) {
|
||||
+ wds_metadata = &wifi_metadata->metadata.wds_metadata;
|
||||
+ ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb,
|
||||
+ wds_metadata);
|
||||
+ }
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ break;
|
||||
+ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX:
|
||||
+ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "",
|
||||
+ "mcbc packet exception from nss: ",
|
||||
+ skb->data, skb->len);
|
||||
+ rxcb = ATH11K_SKB_RXCB(skb);
|
||||
+ rxcb->rx_desc = (struct hal_rx_desc *)skb->head;
|
||||
+ rxcb->is_first_msdu = rxcb->is_last_msdu = true;
|
||||
+ rxcb->is_continuation = false;
|
||||
+ rxcb->is_mcbc = true;
|
||||
+ ath11k_dp_rx_from_nss(arvif->ar, skb, napi);
|
||||
+ break;
|
||||
+ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_4ADDR:
|
||||
+ if (eth_decap) {
|
||||
+ addr4_metadata = &wifi_metadata->metadata.addr4_metadata;
|
||||
+
|
||||
+ spin_lock_bh(&ab->base_lock);
|
||||
+ ta_peer = ath11k_peer_find_by_id(ab, addr4_metadata->peer_id);
|
||||
+ if (!ta_peer) {
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (!drop)
|
||||
- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "4addr exception ta_peer %pM\n",
|
||||
+ ta_peer->addr);
|
||||
+ if (!ta_peer->nss.ext_vdev_up && addr4_metadata->addr4_valid)
|
||||
+ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr);
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+ }
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath11k_warn(ab, "unsupported pkt_type %d from nss\n", wifi_metadata->pkt_type);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1049,6 +1083,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11
|
||||
case ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD:
|
||||
cmd = NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD;
|
||||
break;
|
||||
+ case ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD:
|
||||
+ cmd = NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1299,12 +1336,31 @@ int ath11k_nss_vdev_create(struct ath11k
|
||||
goto free_vdev;
|
||||
|
||||
switch (arvif->vif->type) {
|
||||
- case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
ret = ath11k_nss_vdev_configure(arvif);
|
||||
if (ret)
|
||||
goto unregister_vdev;
|
||||
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif,
|
||||
+ ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD,
|
||||
+ ATH11K_NSS_ENABLE_MCBC_EXC);
|
||||
+ if (ret) {
|
||||
+ ath11k_err(ab, "failed to set MCBC in nss %d\n", ret);
|
||||
+ goto unregister_vdev;
|
||||
+ }
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ ret = ath11k_nss_vdev_configure(arvif);
|
||||
+ if (ret)
|
||||
+ goto unregister_vdev;
|
||||
+
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif,
|
||||
+ ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD,
|
||||
+ true);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ab, "failed to cfg wds backhaul in nss %d\n", ret);
|
||||
+ goto unregister_vdev;
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
@@ -1463,7 +1519,7 @@ int ath11k_nss_ext_vdev_cfg_wds_peer(str
|
||||
|
||||
cfg_wds_msg = &ext_vdev_msg->msg.wmsg;
|
||||
cfg_wds_msg->wds_peer_id = wds_peer_id;
|
||||
- ether_addr_copy(cfg_wds_msg->mac_addr, wds_addr);
|
||||
+ ether_addr_copy((u8 *) cfg_wds_msg->mac_addr, wds_addr);
|
||||
|
||||
nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num,
|
||||
NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS,
|
||||
@@ -1587,7 +1643,6 @@ static int ath11k_nss_ext_vdev_register(
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
- nss_tx_status_t status;
|
||||
u32 features = 0;
|
||||
|
||||
if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx)
|
||||
@@ -1601,7 +1656,7 @@ static int ath11k_nss_ext_vdev_register(
|
||||
|
||||
if (!arvif->nss.ctx) {
|
||||
ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n",
|
||||
- arvif->nss.if_num, status);
|
||||
+ arvif->nss.if_num, NSS_TX_FAILURE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.h
|
||||
@@ -110,10 +110,14 @@ enum ath11k_nss_vdev_cmd {
|
||||
ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD,
|
||||
ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD,
|
||||
ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD,
|
||||
+ ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD,
|
||||
};
|
||||
|
||||
#define WIFILI_SCHEME_ID_INVALID -1
|
||||
|
||||
+/* Enables the MCBC exception in NSS fw, 1 = enable */
|
||||
+#define ATH11K_NSS_ENABLE_MCBC_EXC 1
|
||||
+
|
||||
enum ath11k_nss_opmode {
|
||||
ATH11K_NSS_OPMODE_UNKNOWN,
|
||||
ATH11K_NSS_OPMODE_AP,
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3086,6 +3086,23 @@ static void ath11k_dp_rx_process_receive
|
||||
}
|
||||
}
|
||||
|
||||
+void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu,
|
||||
+ struct napi_struct *napi)
|
||||
+{
|
||||
+ struct ieee80211_rx_status rx_status = {0};
|
||||
+ struct ath11k_skb_rxcb *rxcb;
|
||||
+ bool fast_rx = false;
|
||||
+
|
||||
+ rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+
|
||||
+ ath11k_dp_rx_h_ppdu(ar, rxcb->rx_desc, &rx_status);
|
||||
+ ath11k_dp_rx_h_mpdu(ar, msdu, rxcb->rx_desc, &rx_status, &fast_rx);
|
||||
+
|
||||
+ rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
+
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
+}
|
||||
+
|
||||
int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
@@ -157,4 +157,6 @@ bool ath11k_dp_rx_h_attn_is_mcbc(struct
|
||||
struct hal_rx_desc *desc);
|
||||
u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc);
|
||||
+void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu,
|
||||
+ struct napi_struct *napi);
|
||||
#endif /* ATH11K_DP_RX_H */
|
||||
@ -0,0 +1,522 @@
|
||||
From 9e1f28f343347774b01f330d76d2c5323fcd07ae Mon Sep 17 00:00:00 2001
|
||||
From: Rameshkumar Sundaram <ramess@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 18:25:08 +0530
|
||||
Subject: [PATCH] ath11k: sync wds ast entry on peer/entry deletions
|
||||
|
||||
Peer specific ast entries list is shared between
|
||||
peer_unmap_event(softirq) and peer_ast_wds_wmi_wk
|
||||
(worker). The worker sends a WMI command and hence tends to
|
||||
sleep.
|
||||
complete_work_sync() is used in peer_unmap_event bh handler
|
||||
which tries to yield the CPU(calls schedule)
|
||||
until the worker completes. This results kernel reporting
|
||||
schedule in atomic context and system crash.
|
||||
Add new global wmi_ast_list and add all ast add/update
|
||||
work to this list.
|
||||
Add a new global wmi_ast_work and queue this
|
||||
work on each entry to global wmi_ast_list list.
|
||||
Process the wmi_ast_list in worker and send updates
|
||||
to FW.
|
||||
Each ast entry node is shared between global wmi_ast list
|
||||
and peer specific ast_list and deletes will be done
|
||||
in sync between two lists.
|
||||
On peer deletion all the peer specific entries will
|
||||
be deleted from wmi_ast_list and peer delete in progress
|
||||
will be set to avoid new ast entries adding up and therefore
|
||||
peer unmap evnt won't find any ast worker in progress
|
||||
entries to free in irq context.
|
||||
This peer ast cleanup and worker processing same entry
|
||||
will be synchronized with new base_ast_lock mutex.
|
||||
FW indpendently Deleting a single wds ast entry in irq context &
|
||||
worker already processing the same cannot be synchronized.
|
||||
As we can't hold bh scheduling while worker tries to sleep,
|
||||
and entry in scheduled update work will be sent to FW.
|
||||
|
||||
Signed-off-by: Rameshkumar Sundaram <ramess@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ahb.c | 1 +
|
||||
drivers/net/wireless/ath/ath11k/core.c | 3 +
|
||||
drivers/net/wireless/ath/ath11k/core.h | 4 +
|
||||
drivers/net/wireless/ath/ath11k/nss.c | 6 +-
|
||||
drivers/net/wireless/ath/ath11k/nss.h | 8 +-
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 1 +
|
||||
drivers/net/wireless/ath/ath11k/peer.c | 172 ++++++++++++++++++++++++---------
|
||||
drivers/net/wireless/ath/ath11k/peer.h | 3 +-
|
||||
8 files changed, 144 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -1245,6 +1245,7 @@ static void ath11k_ahb_remove_prepare(st
|
||||
set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
|
||||
cancel_work_sync(&ab->restart_work);
|
||||
cancel_work_sync(&ab->qmi.event_work);
|
||||
+ cancel_work_sync(&ab->wmi_ast_work);
|
||||
}
|
||||
|
||||
static void ath11k_ahb_free_resources(struct ath11k_base *ab)
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -2230,6 +2230,7 @@ struct ath11k_base *ath11k_core_alloc(st
|
||||
|
||||
mutex_init(&ab->core_lock);
|
||||
mutex_init(&ab->tbl_mtx_lock);
|
||||
+ mutex_init(&ab->base_ast_lock);
|
||||
spin_lock_init(&ab->base_lock);
|
||||
mutex_init(&ab->vdev_id_11d_lock);
|
||||
init_completion(&ab->reset_complete);
|
||||
@@ -2243,6 +2244,8 @@ struct ath11k_base *ath11k_core_alloc(st
|
||||
INIT_WORK(&ab->restart_work, ath11k_core_restart);
|
||||
INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
|
||||
INIT_WORK(&ab->reset_work, ath11k_core_reset);
|
||||
+ INIT_WORK(&ab->wmi_ast_work, ath11k_peer_ast_wds_wmi_wk);
|
||||
+ INIT_LIST_HEAD(&ab->wmi_ast_list);
|
||||
timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
|
||||
init_completion(&ab->htc_suspend);
|
||||
init_completion(&ab->wow.wakeup_completed);
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "rx_desc.h"
|
||||
#include "nss.h"
|
||||
#include "vendor.h"
|
||||
+#include "peer.h"
|
||||
|
||||
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
|
||||
|
||||
@@ -1131,6 +1132,11 @@ struct ath11k_base {
|
||||
|
||||
u32 max_ast_index;
|
||||
u32 num_ast_entries;
|
||||
+
|
||||
+ struct mutex base_ast_lock;
|
||||
+ struct work_struct wmi_ast_work;
|
||||
+ struct list_head wmi_ast_list;
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.c
|
||||
@@ -691,8 +691,9 @@ static void ath11k_nss_wds_type_rx(struc
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
}
|
||||
|
||||
-static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr)
|
||||
+static void ath11k_nss_mec_handler(struct ath11k_vif *arvif, u8* mec_mac_addr)
|
||||
{
|
||||
+ struct ath11k *ar = arvif->ar;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_peer *peer = ar->bss_peer;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
@@ -719,7 +720,7 @@ static void ath11k_nss_mec_handler(struc
|
||||
memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4);
|
||||
memcpy(mac_addr + 2, mac_addr_l32, 4);
|
||||
|
||||
- if (!ether_addr_equal(ar->mac_addr, mac_addr)) {
|
||||
+ if (!ether_addr_equal(arvif->vif->addr, mac_addr)) {
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
ath11k_peer_add_ast(ar, peer, mac_addr,
|
||||
ATH11K_AST_TYPE_MEC);
|
||||
@@ -754,7 +755,7 @@ static void ath11k_nss_vdev_spl_receive_
|
||||
addr4_valid, peer_id);
|
||||
break;
|
||||
case NSS_WIFI_VDEV_WDS_TYPE_MEC:
|
||||
- ath11k_nss_mec_handler(ar, (u8 *)(skb->data));
|
||||
+ ath11k_nss_mec_handler(arvif, (u8 *)(skb->data));
|
||||
break;
|
||||
default:
|
||||
ath11k_warn(ab, "unsupported wds_type %d\n", wds_type);
|
||||
@@ -3848,11 +3849,7 @@ int ath11k_nss_add_wds_peer(struct ath11
|
||||
wds_peer_msg->ast_type = type;
|
||||
wds_peer_msg->peer_id = peer->peer_id;
|
||||
|
||||
- if (type == ATH11K_AST_TYPE_MEC)
|
||||
- ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr);
|
||||
- else
|
||||
- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
|
||||
-
|
||||
+ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
|
||||
ether_addr_copy(wds_peer_msg->dest_mac, dest_mac);
|
||||
|
||||
msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
|
||||
@@ -3975,7 +3972,7 @@ msg_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
+int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, int peer_id,
|
||||
u8 *dest_mac)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
@@ -3993,8 +3990,8 @@ int ath11k_nss_del_wds_peer(struct ath11
|
||||
|
||||
wds_peer_msg->pdev_id = ar->pdev->pdev_id;
|
||||
wds_peer_msg->ast_type = ATH11K_AST_TYPE_NONE;
|
||||
- wds_peer_msg->peer_id = peer->peer_id;
|
||||
- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
|
||||
+ wds_peer_msg->peer_id = peer_id;
|
||||
+ ether_addr_copy(wds_peer_msg->peer_mac, peer_addr);
|
||||
ether_addr_copy(wds_peer_msg->dest_mac, dest_mac);
|
||||
|
||||
msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.h
|
||||
@@ -291,8 +291,8 @@ int ath11k_nss_update_wds_peer(struct at
|
||||
u8 *dest_mac);
|
||||
int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
u8 *dest_mac, enum ath11k_ast_entry_type type);
|
||||
-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
- u8 *dest_mac);
|
||||
+int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr,
|
||||
+ int peer_id, u8 *dest_mac);
|
||||
int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif,
|
||||
u8 *wds_addr, u32 wds_peer_id);
|
||||
int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif,
|
||||
@@ -404,8 +404,8 @@ static inline int ath11k_nss_map_wds_pee
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer,
|
||||
- u8 *dest_mac)
|
||||
+static inline int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr,
|
||||
+ int peer_id, u8 *dest_mac)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -970,6 +970,7 @@ static void ath11k_pci_remove(struct pci
|
||||
}
|
||||
|
||||
set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
|
||||
+ cancel_work_sync(&ab->wmi_ast_work);
|
||||
|
||||
ath11k_core_deinit(ab);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -160,49 +160,68 @@ struct ath11k_ast_entry *ath11k_peer_ast
|
||||
|
||||
void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk)
|
||||
{
|
||||
- struct ath11k_ast_entry *ast_entry = container_of(wk,
|
||||
- struct ath11k_ast_entry,
|
||||
- wds_wmi_wk);
|
||||
- struct ath11k *ar;
|
||||
+ struct ath11k_ast_entry *ast_entry, *entry;
|
||||
+ struct ath11k_base *ab = container_of(wk, struct ath11k_base, wmi_ast_work);
|
||||
struct ath11k_peer *peer;
|
||||
+ struct ath11k *ar;
|
||||
int ret;
|
||||
+ u8 peer_addr[ETH_ALEN];
|
||||
+ int peer_id;
|
||||
|
||||
- if (!ast_entry)
|
||||
- return;
|
||||
+ ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC);
|
||||
|
||||
- ar = ast_entry->ar;
|
||||
- peer = ast_entry->peer;
|
||||
+ mutex_lock(&ab->base_ast_lock);
|
||||
+ spin_lock_bh(&ab->base_lock);
|
||||
+
|
||||
+ while ((entry = list_first_entry_or_null(&ab->wmi_ast_list,
|
||||
+ struct ath11k_ast_entry, wmi_list))) {
|
||||
+ list_del_init(&entry->wmi_list);
|
||||
|
||||
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM next_node %pM vdev %d\n",
|
||||
- ast_entry->action, ast_entry->addr, ast_entry->next_node_mac,
|
||||
- ast_entry->vdev_id);
|
||||
-
|
||||
- if (ast_entry->action == ATH11K_WDS_WMI_ADD) {
|
||||
- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar,
|
||||
- ast_entry->next_node_mac,
|
||||
- ast_entry->addr,
|
||||
- ast_entry->vdev_id,
|
||||
- true);
|
||||
- if (ret) {
|
||||
- ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM next_node %pM\n",
|
||||
- ret, ast_entry->addr,
|
||||
- ast_entry->next_node_mac);
|
||||
- if (peer)
|
||||
- ath11k_nss_del_wds_peer(ar, peer,
|
||||
- ast_entry->addr);
|
||||
+ if (!entry->ar || (entry->peer && entry->peer->delete_in_progress)) {
|
||||
+ continue;
|
||||
}
|
||||
- } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) {
|
||||
- if (!peer)
|
||||
- return;
|
||||
+ memcpy(ast_entry, entry, sizeof(*ast_entry));
|
||||
+ ar = ast_entry->ar;
|
||||
+ peer = ast_entry->peer;
|
||||
+ memcpy(peer_addr, peer->addr, sizeof(peer_addr));
|
||||
+ peer_id = peer->peer_id;
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM peer %pM vdev %d\n",
|
||||
+ ast_entry->action, ast_entry->addr, peer_addr,
|
||||
+ ast_entry->vdev_id);
|
||||
|
||||
- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer->addr,
|
||||
- ast_entry->addr,
|
||||
- ast_entry->vdev_id,
|
||||
- false);
|
||||
- if (ret)
|
||||
- ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n",
|
||||
- ret, ast_entry->addr, peer->addr);
|
||||
+ if (ast_entry->action == ATH11K_WDS_WMI_ADD) {
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr,
|
||||
+ ast_entry->addr,
|
||||
+ ast_entry->vdev_id,
|
||||
+ true);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM, peer %pM\n",
|
||||
+ ret, ast_entry->addr, peer_addr);
|
||||
+ if (peer)
|
||||
+ ath11k_nss_del_wds_peer(ar, peer_addr, peer_id,
|
||||
+ ast_entry->addr);
|
||||
+ }
|
||||
+ } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) {
|
||||
+ if (!peer) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr,
|
||||
+ ast_entry->addr,
|
||||
+ ast_entry->vdev_id,
|
||||
+ false);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n",
|
||||
+ ret, ast_entry->addr, peer_addr);
|
||||
+ }
|
||||
+ spin_lock_bh(&ab->base_lock);
|
||||
}
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+ mutex_unlock(&ab->base_ast_lock);
|
||||
+ kfree(ast_entry);
|
||||
}
|
||||
|
||||
int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
@@ -211,6 +230,8 @@ int ath11k_peer_add_ast(struct ath11k *a
|
||||
struct ath11k_ast_entry *ast_entry = NULL;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
|
||||
+ lockdep_assert_held(&ab->base_lock);
|
||||
+
|
||||
if (ab->num_ast_entries == ab->max_ast_index) {
|
||||
ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n",
|
||||
mac_addr, ab->max_ast_index);
|
||||
@@ -226,6 +247,9 @@ int ath11k_peer_add_ast(struct ath11k *a
|
||||
}
|
||||
}
|
||||
|
||||
+ if (peer && peer->delete_in_progress)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC);
|
||||
if (!ast_entry) {
|
||||
ath11k_warn(ab, "failed to alloc ast_entry for %pM\n",
|
||||
@@ -257,7 +281,7 @@ int ath11k_peer_add_ast(struct ath11k *a
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&ast_entry->ase_list);
|
||||
- INIT_WORK(&ast_entry->wds_wmi_wk, ath11k_peer_ast_wds_wmi_wk);
|
||||
+ INIT_LIST_HEAD(&ast_entry->wmi_list);
|
||||
ast_entry->vdev_id = peer->vdev_id;
|
||||
ast_entry->pdev_idx = peer->pdev_idx;
|
||||
ast_entry->is_mapped = false;
|
||||
@@ -271,16 +295,12 @@ int ath11k_peer_add_ast(struct ath11k *a
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n",
|
||||
peer->addr, mac_addr, ast_entry->type);
|
||||
|
||||
- if (type == ATH11K_AST_TYPE_MEC)
|
||||
- ether_addr_copy(ast_entry->next_node_mac, ar->mac_addr);
|
||||
- else if (type == ATH11K_AST_TYPE_WDS)
|
||||
- ether_addr_copy(ast_entry->next_node_mac, peer->addr);
|
||||
-
|
||||
if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
|
||||
(ast_entry->type == ATH11K_AST_TYPE_MEC)) {
|
||||
ath11k_nss_add_wds_peer(ar, peer, mac_addr, ast_entry->type);
|
||||
ast_entry->action = ATH11K_WDS_WMI_ADD;
|
||||
- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk);
|
||||
+ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list);
|
||||
+ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work);
|
||||
}
|
||||
|
||||
ab->num_ast_entries++;
|
||||
@@ -293,6 +313,8 @@ int ath11k_peer_update_ast(struct ath11k
|
||||
struct ath11k_peer *old_peer = ast_entry->peer;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
|
||||
+ lockdep_assert_held(&ab->base_lock);
|
||||
+
|
||||
if (!ast_entry->is_mapped) {
|
||||
ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n",
|
||||
ast_entry->addr);
|
||||
@@ -305,6 +327,9 @@ int ath11k_peer_update_ast(struct ath11k
|
||||
(ast_entry->is_active))
|
||||
return 0;
|
||||
|
||||
+ if (peer && peer->delete_in_progress)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
ast_entry->vdev_id = peer->vdev_id;
|
||||
ast_entry->pdev_idx = peer->pdev_idx;
|
||||
ast_entry->type = ATH11K_AST_TYPE_WDS;
|
||||
@@ -317,7 +342,14 @@ int ath11k_peer_update_ast(struct ath11k
|
||||
old_peer->addr, peer->addr, ast_entry->addr);
|
||||
|
||||
ast_entry->action = ATH11K_WDS_WMI_UPDATE;
|
||||
- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk);
|
||||
+
|
||||
+ /* wmi_list entry might've been processed & removed.*/
|
||||
+ if (list_empty(&ast_entry->wmi_list))
|
||||
+ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list);
|
||||
+ else
|
||||
+ list_move_tail(&ast_entry->wmi_list, &ab->wmi_ast_list);
|
||||
+
|
||||
+ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -363,16 +395,23 @@ void ath11k_peer_del_ast(struct ath11k *
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n",
|
||||
ar->pdev->pdev_id, peer->addr, ast_entry->addr);
|
||||
|
||||
- if (ast_entry->is_mapped)
|
||||
- list_del(&ast_entry->ase_list);
|
||||
+ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
|
||||
+ (ast_entry->type == ATH11K_AST_TYPE_MEC)) {
|
||||
+ if (!list_empty(&ast_entry->wmi_list)) {
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_MAC,
|
||||
+ "ath11k_peer_del_ast deleting unprocessed ast entry %pM "
|
||||
+ "of peer %pM from wmi list\n", ast_entry->addr, peer->addr);
|
||||
+ list_del_init(&ast_entry->wmi_list);
|
||||
+ }
|
||||
+ }
|
||||
+ list_del(&ast_entry->ase_list);
|
||||
|
||||
/* WDS, MEC type AST entries need to be deleted on NSS */
|
||||
if (ast_entry->next_hop)
|
||||
- ath11k_nss_del_wds_peer(ar, peer, ast_entry->addr);
|
||||
+ ath11k_nss_del_wds_peer(ar, peer->addr, peer->peer_id,
|
||||
+ ast_entry->addr);
|
||||
|
||||
- cancel_work_sync(&ast_entry->wds_wmi_wk);
|
||||
kfree(ast_entry);
|
||||
-
|
||||
ab->num_ast_entries--;
|
||||
}
|
||||
|
||||
@@ -681,6 +720,10 @@ void ath11k_peer_cleanup(struct ath11k *
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ mutex_lock(&ab->base_ast_lock);
|
||||
+#endif
|
||||
+
|
||||
mutex_lock(&ab->tbl_mtx_lock);
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) {
|
||||
@@ -709,6 +752,9 @@ void ath11k_peer_cleanup(struct ath11k *
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
mutex_unlock(&ab->tbl_mtx_lock);
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ mutex_unlock(&ab->base_ast_lock);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr)
|
||||
@@ -743,12 +789,18 @@ static int __ath11k_peer_delete(struct a
|
||||
int ret;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ struct ath11k_ast_entry *ast_entry, *tmp_ast;
|
||||
+#endif
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
reinit_completion(&ar->peer_delete_done);
|
||||
ath11k_nss_peer_delete(ar->ab, vdev_id, addr);
|
||||
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ mutex_lock(&ab->base_ast_lock);
|
||||
+#endif
|
||||
mutex_lock(&ab->tbl_mtx_lock);
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
|
||||
@@ -771,17 +823,35 @@ static int __ath11k_peer_delete(struct a
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- /* Check if the found peer is what we want to remove.
|
||||
- * While the sta is transitioning to another band we may
|
||||
- * have 2 peer with the same addr assigned to different
|
||||
- * vdev_id. Make sure we are deleting the correct peer.
|
||||
- */
|
||||
- if (peer && peer->vdev_id == vdev_id)
|
||||
+ if (peer) {
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ peer->delete_in_progress = true;
|
||||
+ if (peer->self_ast_entry) {
|
||||
+ ath11k_peer_del_ast(ar, peer->self_ast_entry);
|
||||
+ peer->self_ast_entry = NULL;
|
||||
+ }
|
||||
+
|
||||
+ list_for_each_entry_safe(ast_entry, tmp_ast,
|
||||
+ &peer->ast_entry_list, ase_list)
|
||||
+ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
|
||||
+ (ast_entry->type == ATH11K_AST_TYPE_MEC)) {
|
||||
+ if (!list_empty(&ast_entry->wmi_list)) {
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "%s deleting unprocessed ast entry %pM of peer %pM from wmi list\n",
|
||||
+ __func__, ast_entry->addr, addr);
|
||||
+ list_del_init(&ast_entry->wmi_list);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
ath11k_peer_rhash_delete(ab, peer);
|
||||
+ }
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
mutex_unlock(&ab->tbl_mtx_lock);
|
||||
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ mutex_unlock(&ab->base_ast_lock);
|
||||
+#endif
|
||||
|
||||
ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id);
|
||||
if (ret) {
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -31,9 +31,7 @@ enum ath11k_wds_wmi_action {
|
||||
struct ath11k_ast_entry {
|
||||
u16 ast_idx;
|
||||
u8 addr[ETH_ALEN];
|
||||
- u8 next_node_mac[ETH_ALEN];
|
||||
enum ath11k_wds_wmi_action action;
|
||||
- struct work_struct wds_wmi_wk;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k *ar;
|
||||
bool next_hop;
|
||||
@@ -47,6 +45,7 @@ struct ath11k_ast_entry {
|
||||
bool delete_in_progress;
|
||||
void *cookie;
|
||||
struct list_head ase_list;
|
||||
+ struct list_head wmi_list;
|
||||
};
|
||||
|
||||
struct ppdu_user_delayba {
|
||||
@@ -97,6 +96,7 @@ struct ath11k_peer {
|
||||
bool dp_setup_done;
|
||||
struct ppdu_user_delayba ppdu_stats_delayba;
|
||||
bool delayba_flag;
|
||||
+ bool delete_in_progress;
|
||||
};
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
||||
@ -0,0 +1,96 @@
|
||||
From 396176575be9767a79d451fba4fe2931305f0435 Mon Sep 17 00:00:00 2001
|
||||
From: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
|
||||
Date: Mon, 7 Nov 2022 21:49:20 +0530
|
||||
Subject: [PATCH] ath11k: fix incorrect ast index assignment for wds peer
|
||||
|
||||
Currently, same ast index is assigned for different nss wds peer mac
|
||||
addresses which is incorrect. However, firmware provides the correct
|
||||
and different ast index for different mac addresses.
|
||||
|
||||
Hence, fix this issue by assigning the correct ast index provided by
|
||||
the firmware.
|
||||
|
||||
Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/nss.c | 5 +++--
|
||||
drivers/net/wireless/ath/ath11k/nss.h | 6 ++++--
|
||||
drivers/net/wireless/ath/ath11k/peer.c | 3 +--
|
||||
3 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.c
|
||||
@@ -805,8 +805,6 @@ ath11k_nss_vdev_special_data_receive(str
|
||||
struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL;
|
||||
struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL;
|
||||
struct nss_wifi_vdev_addr4_data_metadata *addr4_metadata = NULL;
|
||||
- struct wireless_dev *wdev;
|
||||
- struct ieee80211_vif *vif;
|
||||
struct ath11k_vif *arvif;
|
||||
struct ath11k_base *ab;
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
@@ -2487,13 +2485,14 @@ msg_free:
|
||||
}
|
||||
|
||||
int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
- u8 *dest_mac, enum ath11k_ast_entry_type type)
|
||||
+ u8 *dest_mac, struct ath11k_ast_entry *ast_entry)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg;
|
||||
struct nss_wifili_msg *wlmsg = NULL;
|
||||
nss_wifili_msg_callback_t msg_cb;
|
||||
nss_tx_status_t status;
|
||||
+ enum ath11k_ast_entry_type type = ast_entry->type;
|
||||
int ret = 0;
|
||||
|
||||
wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC);
|
||||
@@ -2503,7 +2502,7 @@ int ath11k_nss_map_wds_peer(struct ath11
|
||||
wds_peer_map_msg = &wlmsg->msg.wdspeermapmsg;
|
||||
|
||||
wds_peer_map_msg->vdev_id = peer->vdev_id;
|
||||
- wds_peer_map_msg->ast_idx = peer->hw_peer_id;
|
||||
+ wds_peer_map_msg->ast_idx = ast_entry->ast_idx;
|
||||
|
||||
if (type == ATH11K_AST_TYPE_MEC)
|
||||
wds_peer_map_msg->peer_id = NSS_WIFILI_MEC_PEER_ID;
|
||||
--- a/drivers/net/wireless/ath/ath11k/nss.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/nss.h
|
||||
@@ -16,6 +16,7 @@ struct ath11k;
|
||||
struct ath11k_base;
|
||||
struct ath11k_vif;
|
||||
struct ath11k_peer;
|
||||
+struct ath11k_ast_entry;
|
||||
struct ath11k_sta;
|
||||
enum ath11k_ast_entry_type;
|
||||
struct hal_rx_mon_ppdu_info;
|
||||
@@ -241,7 +242,7 @@ int ath11k_nss_add_wds_peer(struct ath11
|
||||
int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
u8 *dest_mac);
|
||||
int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
- u8 *dest_mac, enum ath11k_ast_entry_type type);
|
||||
+ u8 *dest_mac, struct ath11k_ast_entry *ast_entry);
|
||||
int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr,
|
||||
int peer_id, u8 *dest_mac);
|
||||
int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif,
|
||||
@@ -337,7 +338,8 @@ static inline int ath11k_nss_update_wds_
|
||||
}
|
||||
|
||||
static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
|
||||
- u8 *dest_mac, int type)
|
||||
+ u8 *dest_mac,
|
||||
+ struct ath11k_ast_entry *ast_entry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k *
|
||||
|
||||
if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
|
||||
(ast_entry->type == ATH11K_AST_TYPE_MEC))
|
||||
- ath11k_nss_map_wds_peer(ar, peer, mac_addr,
|
||||
- ast_entry->type);
|
||||
+ ath11k_nss_map_wds_peer(ar, peer, mac_addr, ast_entry);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_map_ast peer %pM ast_entry %pM\n",
|
||||
peer->addr, ast_entry->addr);
|
||||
Loading…
Reference in New Issue
Block a user