wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/753-01-ath12k-sawf-update-the-TCL-Data-command-when-SKB-has.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

321 lines
13 KiB
Diff

From 8ef5660948078fe9a17574412e232a5b199da054 Mon Sep 17 00:00:00 2001
From: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
Date: Tue, 4 Apr 2023 14:54:54 +0530
Subject: [PATCH 1/3] ath12k: sawf: update the TCL Data command when
datapacket's Skb->mark field has valid SAWF TAG.
The SFE module fetch the five tuple information from datapacket while routing and
forward it to ECM.
ECM will check with SPM to find any matching rule available.
Once the rule is matched, ECM will allocate MSDUQ from the host driver and provide
MSDUQ ID, Peer Id and Service class ID(SVC_ID) details to SFE. SFE Then update packet Skb->mark
with follwing details,
MSDUQ_ID BIT_MASK(5, 0)
PEER_ID BIT_MASK(16, 6)
SVC_ID BIT_MASK(17, 23)
SAWF_VALIDITY_TAG BIT_MASK(24, 31)
SAWF_VALID_TAG_VALUE = 0xAA
The TCL Data command will be updated with Flow override details
when the Skb->mark's SAWF_VALIDITY_TAG contains 0xAA
Signed-off-by: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.h | 75 +++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/dp_rx.c | 44 +++++++++++++++
drivers/net/wireless/ath/ath12k/dp_tx.c | 66 +++++++++++++++++++++-
drivers/net/wireless/ath/ath12k/sawf.h | 15 +++++
4 files changed, 199 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index ceb4ff7..8091125 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -421,6 +421,11 @@ struct ath12k_dp {
#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3)
#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128
+/* Service Class meta data */
+#define HTT_TCL_META_DATA_TYPE_SVC_ID_BASED 2
+#define HTT_TCL_META_DATA_SAWF_SVC_ID GENMASK(10, 3)
+#define HTT_TCL_META_DATA_SAWF_TID_OVERRIDE BIT(12)
+
/* HTT tx completion is overlayed in wbm_release_ring v3 version */
#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13)
#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0)
@@ -1313,6 +1318,7 @@ enum htt_t2h_msg_type {
HTT_T2H_MSG_TYPE_MLO_RX_PEER_UNMAP = 0x2a,
HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b,
HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c,
+ HTT_T2H_MSG_TYPE_SAWF_MSDUQ_INFO_IND = 0x2e,
};
#define HTT_TARGET_VERSION_MAJOR 3
@@ -1449,6 +1455,75 @@ enum htt_backpressure_lmac_ringid {
HTT_SW_LMAC_RING_IDX_MAX,
};
+/* MSG_TYPE => HTT_T2H_SAWF_MSDUQ_INFO_IND
+ *
+ * @details
+ * When SAWF is enabled and a flow is mapped to a policy during the traffic
+ * flow if the flow is seen the associated service class is conveyed to the
+ * target via TCL Data Command. Target on the other hand internally creates the
+ * MSDUQ. Once the target creates the MSDUQ the target sends the information
+ * of the newly created MSDUQ and some other identifiers to uniquely identity
+ * the newly created MSDUQ
+ *
+ * |31 27| 24|23 16|15|14 11|10|9 8|7 4|3 0|
+ * |------------------------------+------------------------+--------------|
+ * | peer ID | HTT qtype | msg type |
+ * |---------------------------------+--------------+--+---+-------+------|
+ * | reserved |AST list index|FO|WC | HLOS | remap|
+ * | | | | | TID | TID |
+ * |---------------------+------------------------------------------------|
+ * | reserved1 | tgt_opaque_id |
+ * |---------------------+------------------------------------------------|
+ *
+ * Header fields:
+ *
+ * info0 - b'7:0 - msg_type: This will be set to
+ * 0x2e (HTT_T2H_SAWF_MSDUQ_INFO_IND)
+ * b'15:8 - HTT qtype
+ * b'31:16 - peer ID
+ *
+ * info1 - b'3:0 - remap TID, as assigned in firmware
+ * b'7:4 - HLOS TID, as sent by host in TCL Data Command
+ * hlos_tid : Common to Lithium and Beryllium
+ * b'9:8 - who_classify_info_sel (WC), as sent by host in
+ * TCL Data Command : Beryllium
+ * b10 - flow_override (FO), as sent by host in
+ * TCL Data Command: Beryllium
+ * b11:14 - ast_list_idx
+ * Array index into the list of extension AST entries
+ * (not the actual AST 16-bit index).
+ * The ast_list_idx is one-based, with the following
+ * range of values:
+ * - legacy targets supporting 16 user-defined
+ * MSDU queues: 1-2
+ * - legacy targets supporting 48 user-defined
+ * MSDU queues: 1-6
+ * - new targets: 0 (peer_id is used instead)
+ * Note that since ast_list_idx is one-based,
+ * the host will need to subtract 1 to use it as an
+ * index into a list of extension AST entries.
+ * b15:31 - reserved
+ *
+ * info2 - b'23:0 - tgt_opaque_id Opaque Tx flow number which is a
+ * unique MSDUQ id in firmware
+ * b'24:31 - reserved1
+ */
+
+#define HTT_T2H_SAWF_MSDUQ_INFO_0_IND_HTT_QTYPE_ID GENMASK(15, 8)
+#define HTT_T2H_SAWF_MSDUQ_INFO_0_IND_PEER_ID GENMASK(31, 16)
+#define HTT_T2H_SAWF_MSDUQ_INFO_1_IND_REMAP_TID_ID GENMASK(3, 0)
+#define HTT_T2H_SAWF_MSDUQ_INFO_1_IND_HLOS_TID_ID GENMASK(7, 4)
+#define HTT_T2H_SAWF_MSDUQ_INFO_1_IND_WHO_CLSFY_INFO_SEL_ID GENMASK(9, 8)
+#define HTT_T2H_SAWF_MSDUQ_INFO_1_IND_FLOW_OVERRIDE_ID BIT(10)
+#define HTT_T2H_SAWF_MSDUQ_INFO_1_IND_AST_INDEX_ID GENMASK(14, 11)
+#define HTT_T2H_SAWF_MSDUQ_INFO_2_IND_TGT_OPAQUE_ID GENMASK(23, 0)
+
+struct htt_t2h_sawf_info_ind {
+ __le32 info0;
+ __le32 info1;
+ __le32 info2;
+} __packed;
+
/* ppdu stats
*
* @details
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 97d1475..3e40982 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2091,6 +2091,47 @@ next:
}
}
+static void ath12k_htt_sawf_info_ind_handler(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct htt_t2h_sawf_info_ind *resp = (struct htt_t2h_sawf_info_ind *)skb->data;
+ u32 htt_qtype, remapped_tid, peer_id;
+ u32 hlos_tid, flow_or, ast_idx, who_cl, tgt_opaque_id;
+
+ htt_qtype = u32_get_bits(__le32_to_cpu(resp->info0),
+ HTT_T2H_SAWF_MSDUQ_INFO_0_IND_HTT_QTYPE_ID);
+ peer_id = u32_get_bits(__le32_to_cpu(resp->info0),
+ HTT_T2H_SAWF_MSDUQ_INFO_0_IND_PEER_ID);
+
+ remapped_tid = u32_get_bits(__le32_to_cpu(resp->info1),
+ HTT_T2H_SAWF_MSDUQ_INFO_1_IND_REMAP_TID_ID);
+ hlos_tid = u32_get_bits(__le32_to_cpu(resp->info1),
+ HTT_T2H_SAWF_MSDUQ_INFO_1_IND_HLOS_TID_ID);
+ who_cl = u32_get_bits(__le32_to_cpu(resp->info1),
+ HTT_T2H_SAWF_MSDUQ_INFO_1_IND_WHO_CLSFY_INFO_SEL_ID);
+ flow_or = u32_get_bits(__le32_to_cpu(resp->info1),
+ HTT_T2H_SAWF_MSDUQ_INFO_1_IND_FLOW_OVERRIDE_ID);
+ ast_idx = u32_get_bits(__le32_to_cpu(resp->info1),
+ HTT_T2H_SAWF_MSDUQ_INFO_1_IND_AST_INDEX_ID);
+
+ tgt_opaque_id = u32_get_bits(__le32_to_cpu(resp->info2),
+ HTT_T2H_SAWF_MSDUQ_INFO_2_IND_TGT_OPAQUE_ID);
+
+ ath12k_dbg(ab, ATH12K_DBG_SAWF, "Sawf Info ind:\n");
+ ath12k_dbg(ab, ATH12K_DBG_SAWF,
+ "htt_qtype[0x%x]Peer_Id[0x%x]Remp_Tid[0x%x]Hlos_Tid[0x%x]\n",
+ htt_qtype,
+ peer_id,
+ remapped_tid,
+ hlos_tid);
+ ath12k_dbg(ab, ATH12K_DBG_SAWF,
+ "who_cl[0x%x]flow_or[0x%x]Ast[0x%x]Op[0x%x]\n",
+ who_cl,
+ flow_or,
+ ast_idx,
+ tgt_opaque_id);
+}
+
void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
struct sk_buff *skb)
{
@@ -2188,6 +2229,9 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
case HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND:
ath12k_htt_vdev_txrx_stats_handler(ab, skb);
break;
+ case HTT_T2H_MSG_TYPE_SAWF_MSDUQ_INFO_IND:
+ ath12k_htt_sawf_info_ind_handler(ab, skb);
+ break;
default:
ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n",
type);
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 12e4f7d..7ff41b4 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -13,6 +13,37 @@
#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
+static inline u32 ath12k_sawf_get_tcl_metadata_update(u32 sk_buff_mark)
+{
+ u32 tcl_metadata = 0;
+ u32 svc_id = u32_get_bits(sk_buff_mark, SAWF_SERVICE_CLASS_ID);
+
+ tcl_metadata = u32_encode_bits(HTT_TCL_META_DATA_TYPE_SVC_ID_BASED,
+ HTT_TCL_META_DATA_TYPE_MISSION) |
+ u32_encode_bits(1, HTT_TCL_META_DATA_SAWF_TID_OVERRIDE) |
+ u32_encode_bits(svc_id - 1, HTT_TCL_META_DATA_SAWF_SVC_ID);
+ return tcl_metadata;
+}
+
+static inline u32 ath12k_sawf_get_tcl_cmd_info3_update(u32 msduq_id)
+{
+ u32 tid, flow_override, who_classify_info_sel, update = 0;
+
+ tid = u32_get_bits(msduq_id, TID_FROM_Q_ID);
+ flow_override = u32_get_bits(msduq_id, FLOW_OVERRIDE_FROM_Q_ID);
+ who_classify_info_sel = u32_get_bits(msduq_id, WHO_CLASSIFY_INFO_FROM_Q_ID);
+
+ update = u32_encode_bits(tid, HAL_TCL_DATA_CMD_INFO3_TID) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_FLOW_OVERRIDE_EN) |
+ u32_encode_bits(who_classify_info_sel,
+ HAL_TCL_DATA_CMD_INFO3_CLASSIFY_INFO_SEL) |
+ u32_encode_bits(flow_override,
+ HAL_TCL_DATA_CMD_INFO3_FLOW_OVERRIDE);
+
+ return update;
+}
+
static enum hal_tcl_encap_type
ath12k_dp_tx_get_encap_type(struct ath12k_link_vif *arvif, struct sk_buff *skb)
{
@@ -234,6 +265,19 @@ int ath12k_dp_tx_direct(struct ath12k_link_vif *arvif, struct sk_buff *skb)
tcl_desc.info3 = arvif->desc.info3;
tcl_desc.info4 = arvif->desc.info4;
tcl_desc.info5 = 0;
+ /* SAWF */
+ if (u32_get_bits(skb->mark, SAWF_TAG_ID) == SAWF_VALID_TAG) {
+ u32 msduq_id = u32_get_bits(skb->mark, SAWF_MSDUQ_ID);
+
+ if (msduq_id < (ab->max_msduq_per_tid * ATH12K_SAWF_MAX_TID_SUPPORT)) {
+ u32 meta_data_flags;
+ tcl_desc.info3 |= ath12k_sawf_get_tcl_cmd_info3_update(msduq_id);
+ meta_data_flags =
+ ath12k_sawf_get_tcl_metadata_update(skb->mark);
+ tcl_desc.info1 = u32_encode_bits(meta_data_flags,
+ HAL_TCL_DATA_CMD_INFO1_CMD_NUM);
+ }
+ }
memcpy(hal_tcl_desc, &tcl_desc, sizeof(tcl_desc));
dsb(st);
ath12k_hal_srng_access_umac_src_ring_end_nolock(tcl_ring);
@@ -322,7 +366,17 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
ti.meta_data_flags = arvif->tcl_metadata;
}
- if (gsn_valid) {
+ /* TCL Meta data flags are shared for both SAWF and Global Seq Number updates.
+ * SAWF and Global Seq Number are mutually exclusive.
+ * Global Seq Number - Multicast, SAWF - Unicast
+ */
+ if (u32_get_bits(skb->mark, SAWF_TAG_ID) == SAWF_VALID_TAG) {
+ u32 msduq_id = u32_get_bits(skb->mark, SAWF_MSDUQ_ID);
+ if (msduq_id < (ab->max_msduq_per_tid * ATH12K_SAWF_MAX_TID_SUPPORT)) {
+ ti.meta_data_flags =
+ ath12k_sawf_get_tcl_metadata_update(skb->mark);
+ }
+ } else if (gsn_valid) {
ti.meta_data_flags = u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM,
HTT_TCL_META_DATA_TYPE_MISSION) |
u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
@@ -491,6 +545,16 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
tcl_cmd->info4 = arvif->desc.info4;
tcl_cmd->info5 = 0;
+ /* SAWF */
+ if (u32_get_bits(skb->mark, SAWF_TAG_ID) == SAWF_VALID_TAG) {
+ u32 msduq_id = u32_get_bits(skb->mark, SAWF_MSDUQ_ID);
+
+ if (msduq_id < (ab->max_msduq_per_tid * ATH12K_SAWF_MAX_TID_SUPPORT)) {
+ tcl_cmd->info3 |=
+ ath12k_sawf_get_tcl_cmd_info3_update(msduq_id);
+ }
+ }
+
ath12k_hal_srng_access_umac_src_ring_end_nolock(tcl_ring);
ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ",
diff --git a/drivers/net/wireless/ath/ath12k/sawf.h b/drivers/net/wireless/ath/ath12k/sawf.h
index 162ba5a..35b7f86 100644
--- a/drivers/net/wireless/ath/ath12k/sawf.h
+++ b/drivers/net/wireless/ath/ath12k/sawf.h
@@ -9,6 +9,21 @@
#define ATH12K_SAWF_SVC_CLASS_MIN 1
#define ATH12K_SAWF_SVC_CLASS_MAX 128
#define ATH12K_MAX_APP_NAME 64
+#define ATH12K_SAWF_MAX_TID_SUPPORT 8
+/**
+ ** SAWF_metadata related information.
+ **/
+#define SAWF_VALID_TAG 0xAA
+
+/* Skb mark for SAWF */
+#define SAWF_MSDUQ_ID GENMASK(5, 0)
+#define SAWF_PEER_ID GENMASK(15, 6)
+#define SAWF_SERVICE_CLASS_ID GENMASK(23, 16)
+#define SAWF_TAG_ID GENMASK(31, 24)
+
+#define TID_FROM_Q_ID GENMASK(2, 0)
+#define FLOW_OVERRIDE_FROM_Q_ID BIT(3)
+#define WHO_CLASSIFY_INFO_FROM_Q_ID GENMASK(5, 4)
/*
* Min throughput limit 0 - 10 Gb/s
--
2.17.1