[PATCH net-next 03/12] mlxsw: Add struct mlxsw_pci_rx_pkt_info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Amit Cohen <amcohen@xxxxxxxxxx>

When Rx packet is received, given byte_count value from the CQE, we
calculate how many scatter/gather entries are used and the size of each
entry.

Such calculation is used for syncing the buffers for CPU and for building
SKB. When XDP will be supported, these values will be used also to create
XDP buffer.

To avoid recalculating number of scatter/gather entries and size of each
entry, add a dedicated structure to hold such info. Store also pointers
to pages. Initialize the new structure once Rx packet is received. This
patch only initializes the structure, next patches will use it.

Add struct mlxsw_pci_rx_pkt_info in pci.h as next patch in this set will
use it from another file.

Signed-off-by: Amit Cohen <amcohen@xxxxxxxxxx>
Reviewed-by: Ido Schimmel <idosch@xxxxxxxxxx>
Signed-off-by: Petr Machata <petrm@xxxxxxxxxx>
---
 drivers/net/ethernet/mellanox/mlxsw/pci.c    | 57 +++++++++++++++++---
 drivers/net/ethernet/mellanox/mlxsw/pci.h    |  8 +++
 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h |  1 -
 3 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 55ef185c9f5a..aca1857a4e70 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -390,6 +390,49 @@ static void mlxsw_pci_wqe_frag_unmap(struct mlxsw_pci *mlxsw_pci, char *wqe,
 	dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction);
 }
 
+static u8 mlxsw_pci_num_sg_entries_get(u16 byte_count)
+{
+	return DIV_ROUND_UP(byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD,
+			    PAGE_SIZE);
+}
+
+static int
+mlxsw_pci_rx_pkt_info_init(const struct mlxsw_pci *pci,
+			   const struct mlxsw_pci_queue_elem_info *elem_info,
+			   u16 byte_count,
+			   struct mlxsw_pci_rx_pkt_info *rx_pkt_info)
+{
+	unsigned int linear_data_size;
+	u8 num_sg_entries;
+	bool linear_only;
+	int i;
+
+	num_sg_entries = mlxsw_pci_num_sg_entries_get(byte_count);
+	if (WARN_ON_ONCE(num_sg_entries > pci->num_sg_entries))
+		return -EINVAL;
+
+	rx_pkt_info->num_sg_entries = num_sg_entries;
+
+	linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
+	linear_data_size = linear_only ? byte_count :
+					 PAGE_SIZE -
+					 MLXSW_PCI_RX_BUF_SW_OVERHEAD;
+
+	for (i = 0; i < num_sg_entries; i++) {
+		unsigned int sg_entry_size;
+
+		sg_entry_size = i ? min(byte_count, PAGE_SIZE) :
+				    linear_data_size;
+
+		rx_pkt_info->sg_entries_size[i] = sg_entry_size;
+		rx_pkt_info->pages[i] = elem_info->pages[i];
+
+		byte_count -= sg_entry_size;
+	}
+
+	return 0;
+}
+
 static struct sk_buff *mlxsw_pci_rdq_build_skb(struct mlxsw_pci_queue *q,
 					       struct page *pages[],
 					       u16 byte_count)
@@ -470,12 +513,6 @@ static void mlxsw_pci_rdq_page_free(struct mlxsw_pci_queue *q,
 			   false);
 }
 
-static u8 mlxsw_pci_num_sg_entries_get(u16 byte_count)
-{
-	return DIV_ROUND_UP(byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD,
-			    PAGE_SIZE);
-}
-
 static int
 mlxsw_pci_elem_info_pages_ref_store(const struct mlxsw_pci_queue *q,
 				    const struct mlxsw_pci_queue_elem_info *el,
@@ -486,8 +523,6 @@ mlxsw_pci_elem_info_pages_ref_store(const struct mlxsw_pci_queue *q,
 	int i;
 
 	num_sg_entries = mlxsw_pci_num_sg_entries_get(byte_count);
-	if (WARN_ON_ONCE(num_sg_entries > q->pci->num_sg_entries))
-		return -EINVAL;
 
 	for (i = 0; i < num_sg_entries; i++)
 		pages[i] = el->pages[i];
@@ -743,6 +778,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
 				     u16 consumer_counter_limit,
 				     enum mlxsw_pci_cqe_v cqe_v, char *cqe)
 {
+	struct mlxsw_pci_rx_pkt_info rx_pkt_info = {};
 	struct pci_dev *pdev = mlxsw_pci->pdev;
 	struct page *pages[MLXSW_PCI_WQE_SG_ENTRIES];
 	struct mlxsw_pci_queue_elem_info *elem_info;
@@ -773,6 +809,11 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
 		rx_info.local_port = mlxsw_pci_cqe_system_port_get(cqe);
 	}
 
+	err = mlxsw_pci_rx_pkt_info_init(q->pci, elem_info, byte_count,
+					 &rx_pkt_info);
+	if (err)
+		goto out;
+
 	err = mlxsw_pci_elem_info_pages_ref_store(q, elem_info, byte_count,
 						  pages, &num_sg_entries);
 	if (err)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.h b/drivers/net/ethernet/mellanox/mlxsw/pci.h
index cacc2f9fa1d4..74677feacbb5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.h
@@ -11,11 +11,19 @@
 #define PCI_DEVICE_ID_MELLANOX_SPECTRUM3	0xcf70
 #define PCI_DEVICE_ID_MELLANOX_SPECTRUM4	0xcf80
 
+#define MLXSW_PCI_WQE_SG_ENTRIES	3
+
 #if IS_ENABLED(CONFIG_MLXSW_PCI)
 
 int mlxsw_pci_driver_register(struct pci_driver *pci_driver);
 void mlxsw_pci_driver_unregister(struct pci_driver *pci_driver);
 
+struct mlxsw_pci_rx_pkt_info {
+	struct page *pages[MLXSW_PCI_WQE_SG_ENTRIES];
+	unsigned int sg_entries_size[MLXSW_PCI_WQE_SG_ENTRIES];
+	u8 num_sg_entries;
+};
+
 #else
 
 static inline int
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index 6bed495dcf0f..83d25f926287 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -64,7 +64,6 @@
 #define MLXSW_PCI_EQE_COUNT	(MLXSW_PCI_AQ_SIZE / MLXSW_PCI_EQE_SIZE)
 #define MLXSW_PCI_EQE_UPDATE_COUNT	0x80
 
-#define MLXSW_PCI_WQE_SG_ENTRIES	3
 #define MLXSW_PCI_WQE_TYPE_ETHERNET	0xA
 
 /* pci_wqe_c
-- 
2.47.0





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux