* [PATCH net-next 1/5] net: lan966x: Add define IFH_LEN_BYTES
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
@ 2022-10-19 13:50 ` Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 2/5] net: lan966x: Rename lan966x_fdma_get_max_mtu Horatiu Vultur
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-19 13:50 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver, Horatiu Vultur
The total length of IFH(inter frame header) in bytes is calculated as
IFH_LEN * sizeof(u32). Because IFH_LEN describes the length in words
and not in bytes. As the length of IFH in bytes is used quite often
add a define for this, just to simplify the things.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c | 10 +++++-----
drivers/net/ethernet/microchip/lan966x/lan966x_ifh.h | 1 +
drivers/net/ethernet/microchip/lan966x/lan966x_main.c | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 7e4061c854f0e..1dc4e6ace8b56 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -429,7 +429,7 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
goto free_skb;
skb->dev = lan966x->ports[src_port]->dev;
- skb_pull(skb, IFH_LEN * sizeof(u32));
+ skb_pull(skb, IFH_LEN_BYTES);
if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
skb_trim(skb, skb->len - ETH_FCS_LEN);
@@ -585,7 +585,7 @@ int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev)
}
/* skb processing */
- needed_headroom = max_t(int, IFH_LEN * sizeof(u32) - skb_headroom(skb), 0);
+ needed_headroom = max_t(int, IFH_LEN_BYTES - skb_headroom(skb), 0);
needed_tailroom = max_t(int, ETH_FCS_LEN - skb_tailroom(skb), 0);
if (needed_headroom || needed_tailroom || skb_header_cloned(skb)) {
err = pskb_expand_head(skb, needed_headroom, needed_tailroom,
@@ -598,8 +598,8 @@ int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev)
}
skb_tx_timestamp(skb);
- skb_push(skb, IFH_LEN * sizeof(u32));
- memcpy(skb->data, ifh, IFH_LEN * sizeof(u32));
+ skb_push(skb, IFH_LEN_BYTES);
+ memcpy(skb->data, ifh, IFH_LEN_BYTES);
skb_put(skb, 4);
dma_addr = dma_map_single(lan966x->dev, skb->data, skb->len,
@@ -750,7 +750,7 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
u32 val;
max_mtu = lan966x_fdma_get_max_mtu(lan966x);
- max_mtu += IFH_LEN * sizeof(u32);
+ max_mtu += IFH_LEN_BYTES;
if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
lan966x->rx.page_order)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ifh.h b/drivers/net/ethernet/microchip/lan966x/lan966x_ifh.h
index ca3314789d18d..f3b1e0d318261 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ifh.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ifh.h
@@ -8,6 +8,7 @@
*/
#define IFH_LEN 7
+#define IFH_LEN_BYTES (IFH_LEN * sizeof(u32))
/* Timestamp for frame */
#define IFH_POS_TIMESTAMP 192
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index be2fd030cccbe..6fd857880d3fe 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -760,7 +760,7 @@ static int lan966x_probe_port(struct lan966x *lan966x, u32 p,
NETIF_F_HW_VLAN_STAG_TX |
NETIF_F_HW_TC;
dev->hw_features |= NETIF_F_HW_TC;
- dev->needed_headroom = IFH_LEN * sizeof(u32);
+ dev->needed_headroom = IFH_LEN_BYTES;
eth_hw_addr_gen(dev, lan966x->base_mac, p + 1);
--
2.38.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 2/5] net: lan966x: Rename lan966x_fdma_get_max_mtu
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 1/5] net: lan966x: Add define IFH_LEN_BYTES Horatiu Vultur
@ 2022-10-19 13:50 ` Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 3/5] net: lan966x: Split function lan966x_fdma_rx_get_frame Horatiu Vultur
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-19 13:50 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver, Horatiu Vultur
Rename the function lan966x_fdma_get_max_mtu to lan966x_get_max_mtu
because it doesn't have anything to do with fdma. Because of this
rename, the function is moved also in a different file.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_fdma.c | 22 +------------------
.../ethernet/microchip/lan966x/lan966x_main.c | 19 ++++++++++++++++
.../ethernet/microchip/lan966x/lan966x_main.h | 2 ++
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 1dc4e6ace8b56..e0b9cd289994f 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -661,25 +661,6 @@ int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev)
return err;
}
-static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x)
-{
- int max_mtu = 0;
- int i;
-
- for (i = 0; i < lan966x->num_phys_ports; ++i) {
- int mtu;
-
- if (!lan966x->ports[i])
- continue;
-
- mtu = lan966x->ports[i]->dev->mtu;
- if (mtu > max_mtu)
- max_mtu = mtu;
- }
-
- return max_mtu;
-}
-
static int lan966x_qsys_sw_status(struct lan966x *lan966x)
{
return lan_rd(lan966x, QSYS_SW_STATUS(CPU_PORT));
@@ -749,8 +730,7 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
int err;
u32 val;
- max_mtu = lan966x_fdma_get_max_mtu(lan966x);
- max_mtu += IFH_LEN_BYTES;
+ max_mtu = lan966x_get_max_mtu(lan966x);
if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
lan966x->rx.page_order)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 6fd857880d3fe..4fa8c07039d9f 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -379,6 +379,25 @@ static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
return err;
}
+int lan966x_get_max_mtu(struct lan966x *lan966x)
+{
+ int max_mtu = 0;
+ int i;
+
+ for (i = 0; i < lan966x->num_phys_ports; ++i) {
+ int mtu;
+
+ if (!lan966x->ports[i])
+ continue;
+
+ mtu = lan966x->ports[i]->dev->mtu;
+ if (mtu > max_mtu)
+ max_mtu = mtu;
+ }
+
+ return max_mtu + IFH_LEN_BYTES;
+}
+
static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
{
struct lan966x_port *port = netdev_priv(dev);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 9656071b8289e..e05036841f825 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -333,6 +333,8 @@ void lan966x_unregister_notifier_blocks(void);
bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, struct sk_buff *skb);
+int lan966x_get_max_mtu(struct lan966x *lan966x);
+
void lan966x_ifh_get_src_port(void *ifh, u64 *src_port);
void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp);
--
2.38.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 3/5] net: lan966x: Split function lan966x_fdma_rx_get_frame
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 1/5] net: lan966x: Add define IFH_LEN_BYTES Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 2/5] net: lan966x: Rename lan966x_fdma_get_max_mtu Horatiu Vultur
@ 2022-10-19 13:50 ` Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 4/5] net: lan966x: Add basic XDP support Horatiu Vultur
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-19 13:50 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver, Horatiu Vultur
The function lan966x_fdma_rx_get_frame was unmapping the frame from
device and check also if the frame was received on a valid port. And
only after that it tried to generate the skb.
Move this check in a different function, in preparation for xdp
support. Such that xdp to be added here and the
lan966x_fdma_rx_get_frame to be used only when giving the skb to upper
layers.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_fdma.c | 86 ++++++++++++++-----
.../ethernet/microchip/lan966x/lan966x_main.h | 9 ++
2 files changed, 72 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index e0b9cd289994f..6b6baf6a3d1ee 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -54,6 +54,17 @@ static void lan966x_fdma_rx_free_pages(struct lan966x_rx *rx)
}
}
+static void lan966x_fdma_rx_free_page(struct lan966x_rx *rx)
+{
+ struct page *page;
+
+ page = rx->page[rx->dcb_index][rx->db_index];
+ if (unlikely(!page))
+ return;
+
+ __free_pages(page, rx->page_order);
+}
+
static void lan966x_fdma_rx_add_dcb(struct lan966x_rx *rx,
struct lan966x_rx_dcb *dcb,
u64 nextptr)
@@ -116,6 +127,12 @@ static int lan966x_fdma_rx_alloc(struct lan966x_rx *rx)
return 0;
}
+static void lan966x_fdma_rx_advance_dcb(struct lan966x_rx *rx)
+{
+ rx->dcb_index++;
+ rx->dcb_index &= FDMA_DCB_MAX - 1;
+}
+
static void lan966x_fdma_rx_free(struct lan966x_rx *rx)
{
struct lan966x *lan966x = rx->lan966x;
@@ -402,32 +419,50 @@ static bool lan966x_fdma_rx_more_frames(struct lan966x_rx *rx)
return true;
}
-static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
{
struct lan966x *lan966x = rx->lan966x;
- u64 src_port, timestamp;
struct lan966x_db *db;
- struct sk_buff *skb;
struct page *page;
- /* Get the received frame and unmap it */
db = &rx->dcbs[rx->dcb_index].db[rx->db_index];
page = rx->page[rx->dcb_index][rx->db_index];
- skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order);
- if (unlikely(!skb))
- goto unmap_page;
+ if (unlikely(!page))
+ return FDMA_RX_ERROR;
dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr,
FDMA_DCB_STATUS_BLOCKL(db->status),
DMA_FROM_DEVICE);
+
+ lan966x_ifh_get_src_port(page_address(page), src_port);
+
+ if (WARN_ON(*src_port >= lan966x->num_phys_ports))
+ return FDMA_RX_ERROR;
+
+ return FDMA_RX_OK;
+}
+
+static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
+ u64 src_port)
+{
+ struct lan966x *lan966x = rx->lan966x;
+ struct lan966x_db *db;
+ struct sk_buff *skb;
+ struct page *page;
+ u64 timestamp;
+
+ /* Get the received frame */
+ db = &rx->dcbs[rx->dcb_index].db[rx->db_index];
+ page = rx->page[rx->dcb_index][rx->db_index];
+
+ skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order);
+ if (unlikely(!skb))
+ goto free_page;
+
skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
- lan966x_ifh_get_src_port(skb->data, &src_port);
lan966x_ifh_get_timestamp(skb->data, ×tamp);
- if (WARN_ON(src_port >= lan966x->num_phys_ports))
- goto free_skb;
-
skb->dev = lan966x->ports[src_port]->dev;
skb_pull(skb, IFH_LEN_BYTES);
@@ -450,12 +485,7 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
return skb;
-free_skb:
- kfree_skb(skb);
-unmap_page:
- dma_unmap_page(lan966x->dev, (dma_addr_t)db->dataptr,
- FDMA_DCB_STATUS_BLOCKL(db->status),
- DMA_FROM_DEVICE);
+free_page:
__free_pages(page, rx->page_order);
return NULL;
@@ -467,10 +497,12 @@ static int lan966x_fdma_napi_poll(struct napi_struct *napi, int weight)
struct lan966x_rx *rx = &lan966x->rx;
int dcb_reload = rx->dcb_index;
struct lan966x_rx_dcb *old_dcb;
+ enum lan966x_fdma_rx_error err;
struct lan966x_db *db;
struct sk_buff *skb;
struct page *page;
int counter = 0;
+ u64 src_port;
u64 nextptr;
lan966x_fdma_tx_clear_buf(lan966x, weight);
@@ -480,19 +512,27 @@ static int lan966x_fdma_napi_poll(struct napi_struct *napi, int weight)
if (!lan966x_fdma_rx_more_frames(rx))
break;
- skb = lan966x_fdma_rx_get_frame(rx);
+ counter++;
- rx->page[rx->dcb_index][rx->db_index] = NULL;
- rx->dcb_index++;
- rx->dcb_index &= FDMA_DCB_MAX - 1;
+ err = lan966x_fdma_rx_check_frame(rx, &src_port);
+ switch (err) {
+ case FDMA_RX_OK:
+ break;
+ case FDMA_RX_ERROR:
+ lan966x_fdma_rx_free_page(rx);
+ lan966x_fdma_rx_advance_dcb(rx);
+ goto allocate_new;
+ }
+ skb = lan966x_fdma_rx_get_frame(rx, src_port);
+ lan966x_fdma_rx_advance_dcb(rx);
if (!skb)
- break;
+ goto allocate_new;
napi_gro_receive(&lan966x->napi, skb);
- counter++;
}
+allocate_new:
/* Allocate new pages and map them */
while (dcb_reload != rx->dcb_index) {
db = &rx->dcbs[dcb_reload].db[rx->db_index];
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index e05036841f825..608e2cb81b095 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -98,6 +98,15 @@ enum macaccess_entry_type {
ENTRYTYPE_MACV6,
};
+/* FDMA rx error codes for checking if the frame is valid
+ * FDMA_RX_OK, frame is valid and can be used
+ * FDMA_RX_ERROR, something went wrong, stop getting more frames
+ */
+enum lan966x_fdma_rx_error {
+ FDMA_RX_OK = 0,
+ FDMA_RX_ERROR,
+};
+
struct lan966x_port;
struct lan966x_db {
--
2.38.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 4/5] net: lan966x: Add basic XDP support
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
` (2 preceding siblings ...)
2022-10-19 13:50 ` [PATCH net-next 3/5] net: lan966x: Split function lan966x_fdma_rx_get_frame Horatiu Vultur
@ 2022-10-19 13:50 ` Horatiu Vultur
2022-10-19 13:50 ` [PATCH net-next 5/5] net: lan96x: Use page_pool API Horatiu Vultur
2022-10-20 20:51 ` [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-19 13:50 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver, Horatiu Vultur
Introduce basic XDP support to lan966x driver. Currently the driver
supports only the actions XDP_PASS, XDP_DROP and XDP_ABORTED.
Currently the driver doesn't support xdp programs if any of the ports
have the MTU bigger than a page size.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../net/ethernet/microchip/lan966x/Makefile | 3 +-
.../ethernet/microchip/lan966x/lan966x_fdma.c | 14 ++-
.../ethernet/microchip/lan966x/lan966x_main.c | 5 +
.../ethernet/microchip/lan966x/lan966x_main.h | 14 +++
.../ethernet/microchip/lan966x/lan966x_xdp.c | 100 ++++++++++++++++++
5 files changed, 134 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
diff --git a/drivers/net/ethernet/microchip/lan966x/Makefile b/drivers/net/ethernet/microchip/lan966x/Makefile
index 962f7c5f9e7dd..251a7d561d633 100644
--- a/drivers/net/ethernet/microchip/lan966x/Makefile
+++ b/drivers/net/ethernet/microchip/lan966x/Makefile
@@ -11,4 +11,5 @@ lan966x-switch-objs := lan966x_main.o lan966x_phylink.o lan966x_port.o \
lan966x_ptp.o lan966x_fdma.o lan966x_lag.o \
lan966x_tc.o lan966x_mqprio.o lan966x_taprio.o \
lan966x_tbf.o lan966x_cbs.o lan966x_ets.o \
- lan966x_tc_matchall.o lan966x_police.o lan966x_mirror.o
+ lan966x_tc_matchall.o lan966x_police.o lan966x_mirror.o \
+ lan966x_xdp.o
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 6b6baf6a3d1ee..4e8f7e47c5536 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -422,6 +422,7 @@ static bool lan966x_fdma_rx_more_frames(struct lan966x_rx *rx)
static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
{
struct lan966x *lan966x = rx->lan966x;
+ struct lan966x_port *port;
struct lan966x_db *db;
struct page *page;
@@ -439,7 +440,11 @@ static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
if (WARN_ON(*src_port >= lan966x->num_phys_ports))
return FDMA_RX_ERROR;
- return FDMA_RX_OK;
+ port = lan966x->ports[*src_port];
+ if (!lan966x_xdp_port_present(port))
+ return FDMA_RX_OK;
+
+ return lan966x_xdp_run(port, page, FDMA_DCB_STATUS_BLOCKL(db->status));
}
static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
@@ -518,6 +523,10 @@ static int lan966x_fdma_napi_poll(struct napi_struct *napi, int weight)
switch (err) {
case FDMA_RX_OK:
break;
+ case FDMA_RX_DROP:
+ lan966x_fdma_rx_free_page(rx);
+ lan966x_fdma_rx_advance_dcb(rx);
+ continue;
case FDMA_RX_ERROR:
lan966x_fdma_rx_free_page(rx);
lan966x_fdma_rx_advance_dcb(rx);
@@ -776,6 +785,9 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
lan966x->rx.page_order)
return 0;
+ if (lan966x_xdp_present(lan966x) && max_mtu >= PAGE_SIZE)
+ return -EINVAL;
+
/* Disable the CPU port */
lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0),
QSYS_SW_PORT_MODE_PORT_ENA,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 4fa8c07039d9f..2e48caaadd59c 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -487,6 +487,7 @@ static const struct net_device_ops lan966x_port_netdev_ops = {
.ndo_get_port_parent_id = lan966x_port_get_parent_id,
.ndo_eth_ioctl = lan966x_port_ioctl,
.ndo_setup_tc = lan966x_tc_setup,
+ .ndo_bpf = lan966x_xdp,
};
bool lan966x_netdevice_check(const struct net_device *dev)
@@ -713,6 +714,7 @@ static void lan966x_cleanup_ports(struct lan966x *lan966x)
if (port->dev)
unregister_netdev(port->dev);
+ lan966x_xdp_port_deinit(port);
if (lan966x->fdma && lan966x->fdma_ndev == port->dev)
lan966x_fdma_netdev_deinit(lan966x, port->dev);
@@ -1155,6 +1157,9 @@ static int lan966x_probe(struct platform_device *pdev)
lan966x->ports[p]->serdes = serdes;
lan966x_port_init(lan966x->ports[p]);
+ err = lan966x_xdp_port_init(lan966x->ports[p]);
+ if (err)
+ goto cleanup_ports;
}
lan966x_mdb_init(lan966x);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 608e2cb81b095..e635e529df0d4 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -100,10 +100,12 @@ enum macaccess_entry_type {
/* FDMA rx error codes for checking if the frame is valid
* FDMA_RX_OK, frame is valid and can be used
+ * FDMA_RX_DROP, frame is dropped, but continue to get more frames
* FDMA_RX_ERROR, something went wrong, stop getting more frames
*/
enum lan966x_fdma_rx_error {
FDMA_RX_OK = 0,
+ FDMA_RX_DROP,
FDMA_RX_ERROR,
};
@@ -327,6 +329,9 @@ struct lan966x_port {
enum netdev_lag_hash hash_type;
struct lan966x_port_tc tc;
+
+ struct bpf_prog *xdp_prog;
+ struct xdp_rxq_info xdp_rxq;
};
extern const struct phylink_mac_ops lan966x_phylink_mac_ops;
@@ -536,6 +541,15 @@ void lan966x_mirror_port_stats(struct lan966x_port *port,
struct flow_stats *stats,
bool ingress);
+int lan966x_xdp_port_init(struct lan966x_port *port);
+void lan966x_xdp_port_deinit(struct lan966x_port *port);
+int lan966x_xdp(struct net_device *dev, struct netdev_bpf *xdp);
+int lan966x_xdp_run(struct lan966x_port *port,
+ struct page *page,
+ u32 data_len);
+bool lan966x_xdp_present(struct lan966x *lan966x);
+bool lan966x_xdp_port_present(struct lan966x_port *port);
+
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
int gbase, int ginst,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
new file mode 100644
index 0000000000000..b65bf648c543b
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/bpf.h>
+#include <linux/bpf_trace.h>
+#include <linux/filter.h>
+
+#include "lan966x_main.h"
+
+static int lan966x_xdp_setup(struct net_device *dev, struct netdev_bpf *xdp)
+{
+ struct lan966x_port *port = netdev_priv(dev);
+ struct lan966x *lan966x = port->lan966x;
+ struct bpf_prog *old_prog;
+
+ if (!lan966x->fdma) {
+ NL_SET_ERR_MSG_MOD(xdp->extack,
+ "Allow to set xdp only when using fdma");
+ return -EOPNOTSUPP;
+ }
+
+ if (lan966x_get_max_mtu(lan966x) >= PAGE_SIZE) {
+ NL_SET_ERR_MSG_MOD(xdp->extack,
+ "Jumbo frames not supported on XDP");
+ return -EOPNOTSUPP;
+ }
+
+ old_prog = xchg(&port->xdp_prog, xdp->prog);
+ if (old_prog)
+ bpf_prog_put(old_prog);
+
+ return 0;
+}
+
+int lan966x_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+{
+ switch (xdp->command) {
+ case XDP_SETUP_PROG:
+ return lan966x_xdp_setup(dev, xdp);
+ default:
+ return -EINVAL;
+ }
+}
+
+int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
+{
+ struct bpf_prog *xdp_prog = port->xdp_prog;
+ struct xdp_buff xdp;
+ u32 act;
+
+ xdp_init_buff(&xdp, PAGE_SIZE, &port->xdp_rxq);
+ xdp_prepare_buff(&xdp, page_address(page), IFH_LEN_BYTES,
+ data_len - IFH_LEN_BYTES, false);
+ act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ switch (act) {
+ case XDP_PASS:
+ return FDMA_RX_OK;
+ default:
+ bpf_warn_invalid_xdp_action(port->dev, xdp_prog, act);
+ fallthrough;
+ case XDP_ABORTED:
+ trace_xdp_exception(port->dev, xdp_prog, act);
+ fallthrough;
+ case XDP_DROP:
+ return FDMA_RX_DROP;
+ }
+}
+
+bool lan966x_xdp_port_present(struct lan966x_port *port)
+{
+ return !!port->xdp_prog;
+}
+
+bool lan966x_xdp_present(struct lan966x *lan966x)
+{
+ int p;
+
+ for (p = 0; p < lan966x->num_phys_ports; ++p) {
+ if (!lan966x->ports[p])
+ continue;
+
+ if (lan966x_xdp_port_present(lan966x->ports[p]))
+ return true;
+ }
+
+ return false;
+}
+
+int lan966x_xdp_port_init(struct lan966x_port *port)
+{
+ struct lan966x *lan966x = port->lan966x;
+
+ return xdp_rxq_info_reg(&port->xdp_rxq, port->dev, 0,
+ lan966x->napi.napi_id);
+}
+
+void lan966x_xdp_port_deinit(struct lan966x_port *port)
+{
+ if (xdp_rxq_info_is_reg(&port->xdp_rxq))
+ xdp_rxq_info_unreg(&port->xdp_rxq);
+}
--
2.38.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 5/5] net: lan96x: Use page_pool API
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
` (3 preceding siblings ...)
2022-10-19 13:50 ` [PATCH net-next 4/5] net: lan966x: Add basic XDP support Horatiu Vultur
@ 2022-10-19 13:50 ` Horatiu Vultur
2022-10-20 20:51 ` [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-19 13:50 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver, Horatiu Vultur
Use the page_pool API for allocation, freeing and DMA handling instead
of dev_alloc_pages, __free_pages and dma_map_page.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../net/ethernet/microchip/lan966x/Kconfig | 1 +
.../ethernet/microchip/lan966x/lan966x_fdma.c | 74 +++++++++++--------
.../ethernet/microchip/lan966x/lan966x_main.h | 3 +
3 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/Kconfig b/drivers/net/ethernet/microchip/lan966x/Kconfig
index 49e1464a43139..b7ae5ce7d3f7a 100644
--- a/drivers/net/ethernet/microchip/lan966x/Kconfig
+++ b/drivers/net/ethernet/microchip/lan966x/Kconfig
@@ -7,5 +7,6 @@ config LAN966X_SWITCH
depends on BRIDGE || BRIDGE=n
select PHYLINK
select PACKING
+ select PAGE_POOL
help
This driver supports the Lan966x network switch device.
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 4e8f7e47c5536..ba34a7b7ccd13 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -10,47 +10,25 @@ static int lan966x_fdma_channel_active(struct lan966x *lan966x)
static struct page *lan966x_fdma_rx_alloc_page(struct lan966x_rx *rx,
struct lan966x_db *db)
{
- struct lan966x *lan966x = rx->lan966x;
- dma_addr_t dma_addr;
struct page *page;
- page = dev_alloc_pages(rx->page_order);
+ page = page_pool_dev_alloc_pages(rx->page_pool);
if (unlikely(!page))
return NULL;
- dma_addr = dma_map_page(lan966x->dev, page, 0,
- PAGE_SIZE << rx->page_order,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(lan966x->dev, dma_addr)))
- goto free_page;
-
- db->dataptr = dma_addr;
+ db->dataptr = page_pool_get_dma_addr(page);
return page;
-
-free_page:
- __free_pages(page, rx->page_order);
- return NULL;
}
static void lan966x_fdma_rx_free_pages(struct lan966x_rx *rx)
{
- struct lan966x *lan966x = rx->lan966x;
- struct lan966x_rx_dcb *dcb;
- struct lan966x_db *db;
int i, j;
for (i = 0; i < FDMA_DCB_MAX; ++i) {
- dcb = &rx->dcbs[i];
-
- for (j = 0; j < FDMA_RX_DCB_MAX_DBS; ++j) {
- db = &dcb->db[j];
- dma_unmap_single(lan966x->dev,
- (dma_addr_t)db->dataptr,
- PAGE_SIZE << rx->page_order,
- DMA_FROM_DEVICE);
- __free_pages(rx->page[i][j], rx->page_order);
- }
+ for (j = 0; j < FDMA_RX_DCB_MAX_DBS; ++j)
+ page_pool_put_full_page(rx->page_pool,
+ rx->page[i][j], false);
}
}
@@ -62,7 +40,7 @@ static void lan966x_fdma_rx_free_page(struct lan966x_rx *rx)
if (unlikely(!page))
return;
- __free_pages(page, rx->page_order);
+ page_pool_recycle_direct(rx->page_pool, page);
}
static void lan966x_fdma_rx_add_dcb(struct lan966x_rx *rx,
@@ -84,6 +62,27 @@ static void lan966x_fdma_rx_add_dcb(struct lan966x_rx *rx,
rx->last_entry = dcb;
}
+static int lan966x_fdma_rx_alloc_page_pool(struct lan966x_rx *rx)
+{
+ struct lan966x *lan966x = rx->lan966x;
+ struct page_pool_params pp_params = {
+ .order = rx->page_order,
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
+ .pool_size = FDMA_DCB_MAX,
+ .nid = NUMA_NO_NODE,
+ .dev = lan966x->dev,
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << rx->page_order,
+ };
+
+ rx->page_pool = page_pool_create(&pp_params);
+ if (IS_ERR(rx->page_pool))
+ return PTR_ERR(rx->page_pool);
+
+ return 0;
+}
+
static int lan966x_fdma_rx_alloc(struct lan966x_rx *rx)
{
struct lan966x *lan966x = rx->lan966x;
@@ -93,6 +92,9 @@ static int lan966x_fdma_rx_alloc(struct lan966x_rx *rx)
int i, j;
int size;
+ if (lan966x_fdma_rx_alloc_page_pool(rx))
+ return PTR_ERR(rx->page_pool);
+
/* calculate how many pages are needed to allocate the dcbs */
size = sizeof(struct lan966x_rx_dcb) * FDMA_DCB_MAX;
size = ALIGN(size, PAGE_SIZE);
@@ -431,9 +433,9 @@ static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
if (unlikely(!page))
return FDMA_RX_ERROR;
- dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr,
- FDMA_DCB_STATUS_BLOCKL(db->status),
- DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(lan966x->dev, (dma_addr_t)db->dataptr,
+ FDMA_DCB_STATUS_BLOCKL(db->status),
+ DMA_FROM_DEVICE);
lan966x_ifh_get_src_port(page_address(page), src_port);
@@ -464,6 +466,8 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
if (unlikely(!skb))
goto free_page;
+ skb_mark_for_recycle(skb);
+
skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
lan966x_ifh_get_timestamp(skb->data, ×tamp);
@@ -491,7 +495,7 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
return skb;
free_page:
- __free_pages(page, rx->page_order);
+ page_pool_recycle_direct(rx->page_pool, page);
return NULL;
}
@@ -718,6 +722,7 @@ static int lan966x_qsys_sw_status(struct lan966x *lan966x)
static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
{
void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf;
+ struct page_pool *page_pool;
dma_addr_t rx_dma, tx_dma;
u32 size;
int err;
@@ -728,6 +733,7 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
rx_dcbs = lan966x->rx.dcbs;
tx_dcbs = lan966x->tx.dcbs;
tx_dcbs_buf = lan966x->tx.dcbs_buf;
+ page_pool = lan966x->rx.page_pool;
napi_synchronize(&lan966x->napi);
napi_disable(&lan966x->napi);
@@ -745,6 +751,8 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
size = ALIGN(size, PAGE_SIZE);
dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma);
+ page_pool_destroy(page_pool);
+
lan966x_fdma_tx_disable(&lan966x->tx);
err = lan966x_fdma_tx_alloc(&lan966x->tx);
if (err)
@@ -761,6 +769,7 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
return err;
restore:
+ lan966x->rx.page_pool = page_pool;
lan966x->rx.dma = rx_dma;
lan966x->rx.dcbs = rx_dcbs;
lan966x_fdma_rx_start(&lan966x->rx);
@@ -872,5 +881,6 @@ void lan966x_fdma_deinit(struct lan966x *lan966x)
lan966x_fdma_rx_free_pages(&lan966x->rx);
lan966x_fdma_rx_free(&lan966x->rx);
+ page_pool_destroy(lan966x->rx.page_pool);
lan966x_fdma_tx_free(&lan966x->tx);
}
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index e635e529df0d4..9abdc3fb3f7e5 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -9,6 +9,7 @@
#include <linux/phy.h>
#include <linux/phylink.h>
#include <linux/ptp_clock_kernel.h>
+#include <net/page_pool.h>
#include <net/pkt_cls.h>
#include <net/pkt_sched.h>
#include <net/switchdev.h>
@@ -160,6 +161,8 @@ struct lan966x_rx {
u8 page_order;
u8 channel_id;
+
+ struct page_pool *page_pool;
};
struct lan966x_tx_dcb_buf {
--
2.38.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH net-next 0/5] net: lan966x: Add xdp support
2022-10-19 13:50 [PATCH net-next 0/5] net: lan966x: Add xdp support Horatiu Vultur
` (4 preceding siblings ...)
2022-10-19 13:50 ` [PATCH net-next 5/5] net: lan96x: Use page_pool API Horatiu Vultur
@ 2022-10-20 20:51 ` Horatiu Vultur
5 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2022-10-20 20:51 UTC (permalink / raw)
To: linux-kernel, netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
linux, UNGLinuxDriver
The 10/19/2022 15:50, Horatiu Vultur wrote:
> Add support for xdp in lan966x driver. Currently on XDP_PASS and
> XDP_DROP are supported.
>
> The first 3 patches are just moving things around just to simplify
> the code for when the xdp is added.
> Patch 4 actually adds the xdp. Currently the only supported actions
> are XDP_PASS and XDP_DROP. In the future this will be extended with
> XDP_TX and XDP_REDIRECT.
> Patch 5 changes to use page pool API, because the handling of the
> pages is similar with what already lan966x driver is doing. In this
> way is possible to remove some of the code.
>
> All these changes give a small improvement on the RX side:
> Before:
> iperf3 -c 10.96.10.1 -R
> [ 5] 0.00-10.01 sec 514 MBytes 430 Mbits/sec 0 sender
> [ 5] 0.00-10.00 sec 509 MBytes 427 Mbits/sec receiver
>
> After:
> iperf3 -c 10.96.10.1 -R
> [ 5] 0.00-10.02 sec 540 MBytes 452 Mbits/sec 0 sender
> [ 5] 0.00-10.01 sec 537 MBytes 450 Mbits/sec receiver
If it is possible I would like to withdraw the submission for this patch
series.
The reason is that patch 2 touches some code that has some issues. The
issues were not introduced in this patch series. So I prefer to send first
the patches to fix those issues which need to go in net and only when those
fixes reaches net-next to resend this patch series. Otherwise will be some
pretty ugly merge conflicts.
So just to make the life easier for everyone, please ignore for now
this patch series.
>
>
> Horatiu Vultur (5):
> net: lan966x: Add define IFH_LEN_BYTES
> net: lan966x: Rename lan966x_fdma_get_max_mtu
> net: lan966x: Split function lan966x_fdma_rx_get_frame
> net: lan966x: Add basic XDP support
> net: lan96x: Use page_pool API
>
> .../net/ethernet/microchip/lan966x/Kconfig | 1 +
> .../net/ethernet/microchip/lan966x/Makefile | 3 +-
> .../ethernet/microchip/lan966x/lan966x_fdma.c | 194 +++++++++++-------
> .../ethernet/microchip/lan966x/lan966x_ifh.h | 1 +
> .../ethernet/microchip/lan966x/lan966x_main.c | 26 ++-
> .../ethernet/microchip/lan966x/lan966x_main.h | 28 +++
> .../ethernet/microchip/lan966x/lan966x_xdp.c | 100 +++++++++
> 7 files changed, 275 insertions(+), 78 deletions(-)
> create mode 100644 drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
>
> --
> 2.38.0
>
--
/Horatiu
^ permalink raw reply [flat|nested] 7+ messages in thread