mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 19:03:39 +00:00
321 lines
13 KiB
Diff
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
|
|
|