[PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support

[email protected]
Newsgroups org.dpdk.dev
Message-ID <[email protected]>
From: Jie Liu <[email protected]>

Implement sxe2_rxq_buf_split_fill function to configure Rx queue
buffer split offload. The function validates and sets split
parameters based on protocol header type.

Supports following split types:
- L2: Ether
- L3: IPv4, IPv6
- L4: TCP, UDP, SCTP
- Tunnel: GRE/NAT
- Inner L2/L3/L4 for tunneled packets

Sets split_type_mask and header_len (256 bytes) for hardware
buffer split configuration. Returns error if protocol header
is not configured or unsupported.

Signed-off-by: Jie Liu <[email protected]>
---
 drivers/net/sxe2/sxe2_cmd_chnl.c | 142 ++++++++++++++++++++++++++++---
 1 file changed, 128 insertions(+), 14 deletions(-)

diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..9ed5559eff 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
 }
 
 static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
-		struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+		struct sxe2_drv_cmd_params *cmd, uint32_t opc,
 		void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
 {
-	PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
 	cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
 	cmd->opcode  = opc;
 	cmd->vsi_id  = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,7 +43,7 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
 }
 
 #define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
-	__sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
+	__sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len)
 
 
 int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
@@ -193,6 +192,102 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
 #define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN  (1 << 7)
 #define SXE2_RX_HDR_SIZE 256
 
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+				   struct sxe2_drv_rxq_ctxt *ctxt)
+{
+	int32_t ret = 0;
+	uint32_t proto_hdr;
+
+	if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+		proto_hdr = rxq->rx_seg[0].proto_hdr;
+		if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+			PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+			ret = -1;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+		case RTE_PTYPE_L4_TCP:
+			ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_L4_UDP:
+			ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_L4_SCTP:
+			ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+		case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+			ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+			ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+		case RTE_PTYPE_L2_ETHER:
+			ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+		case RTE_PTYPE_INNER_L4_TCP:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_INNER_L4_UDP:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_INNER_L4_SCTP:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+		case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+		case RTE_PTYPE_INNER_L2_ETHER:
+			ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+
+		switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+		case RTE_PTYPE_TUNNEL_GRENAT:
+			ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+			ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+			goto l_end;
+		}
+		PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+		ret = -1;
+	} else {
+		ctxt->hdr_len = 0;
+		ctxt->split_type_mask = 0;
+	}
+l_end:
+	return ret;
+}
+
 static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
 		struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
 {
@@ -226,7 +321,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
 	else
 		ctxt->keep_crc_en = 0;
 
+	if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+		ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+		if (ret)
+			goto l_end;
+		ctxt->split_en = 1;
+	} else {
+		ctxt->split_en = 0;
+	}
+
 	ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
 	return ret;
 }
 
@@ -391,7 +496,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
 			&vsi_info_get_resp, sizeof(vsi_info_get_resp));
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret) {
-		PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+		PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
 		goto l_end;
 	}
 
@@ -412,6 +517,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
 {
 	int32_t ret = 0;
 	struct sxe2_common_device *cdev = adapter->cdev;
+	struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
 	struct sxe2_drv_cmd_params param = {0};
 	struct sxe2_drv_link_info_resp resp = {0};
 
@@ -425,6 +531,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
 	}
 	adapter->link_ctxt.speed = resp.speed;
 	adapter->link_ctxt.link_up = resp.status;
+	(void)sxe2_link_update(dev, 0);
 
 l_end:
 	return ret;
@@ -447,7 +554,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
 				 NULL, 0);
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
-		PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+		PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
 
 	return ret;
 }
@@ -467,7 +574,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
 				 NULL, 0);
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
-		PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+		PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
 
 	return ret;
 }
@@ -668,7 +775,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
-		PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+		PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
 
 	return ret;
 }
@@ -1532,7 +1639,7 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
 		[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U] = SXE2_UDP_TUNNEL_PROTOCOL_GTP_U,
 		[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE] = SXE2_UDP_TUNNEL_PROTOCOL_NVGRE,
 	};
-	struct sxe2_udp_tunnel_cfg tunnel_config = {};
+	struct sxe2_udp_tunnel_cfg tunnel_config = {0};
 
 	tunnel_config.protocol = flow_proto_to_udp_tunnel_proto[proto];
 	ret = sxe2_drv_udp_tunnel_get(adapter, &tunnel_config);
@@ -1560,8 +1667,10 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
 				 &req, sizeof(req),
 				 &resp, sizeof(resp));
 	ret = sxe2_drv_cmd_exec(cdev, &cmd);
-	if (ret)
+	if (ret) {
 		PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+		goto l_end;
+	}
 
 	tunnel_config->fw_port   = resp.port;
 	tunnel_config->fw_status = resp.enable;
@@ -1569,6 +1678,7 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
 	tunnel_config->fw_src_en = resp.src;
 	tunnel_config->fw_used   = resp.fw_used;
 
+l_end:
 	return ret;
 }
 
@@ -1591,7 +1701,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
 				 &resp, sizeof(resp));
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret) {
-		PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+		PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
 		goto l_end;
 	}
 
@@ -1635,7 +1745,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
-		PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+		PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
 
 l_end:
 	return ret;
@@ -1652,7 +1762,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
 
 	txq = eth_dev->data->tx_queues[queue_id];
 	if (txq == NULL) {
-		PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+		PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
 		ret = -EINVAL;
 		goto l_end;
 	}
@@ -1666,7 +1776,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
-		PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+		PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
 
 l_end:
 	return ret;
@@ -1726,10 +1836,14 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
 	sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
 			   sizeof(req), &resp, sizeof(resp));
 	ret = sxe2_drv_cmd_exec(cdev, &cmd);
-	if (ret)
+	if (ret) {
 		PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+		flow->create_err = ret;
+		goto l_end;
+	}
 	flow->flow_id = resp.flow_id;
 	flow->create_err = ret;
+l_end:
 	return ret;
 }
 
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.