netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] eth: fbnic: support devmem Tx
@ 2025-09-11 14:43 Jakub Kicinski
  2025-09-11 18:21 ` Mina Almasry
  2025-09-16  7:26 ` Paolo Abeni
  0 siblings, 2 replies; 4+ messages in thread
From: Jakub Kicinski @ 2025-09-11 14:43 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, sdf, almasrymina,
	alexanderduyck, Jakub Kicinski

Support devmem Tx. We already use skb_frag_dma_map(), we just need
to make sure we don't try to unmap the frags. Check if frag is
unreadable and mark the ring entry.

  # ./tools/testing/selftests/drivers/net/hw/devmem.py
  TAP version 13
  1..3
  ok 1 devmem.check_rx
  ok 2 devmem.check_tx
  ok 3 devmem.check_tx_chunks
  # Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 drivers/net/ethernet/meta/fbnic/fbnic_netdev.c |  1 +
 drivers/net/ethernet/meta/fbnic/fbnic_txrx.c   | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index dd35de301870..d12b4cad84a5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -712,6 +712,7 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
 	netdev->netdev_ops = &fbnic_netdev_ops;
 	netdev->stat_ops = &fbnic_stat_ops;
 	netdev->queue_mgmt_ops = &fbnic_queue_mgmt_ops;
+	netdev->netmem_tx = true;
 
 	fbnic_set_ethtool_ops(netdev);
 
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index ac555e045e34..286ad628a557 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -37,6 +37,8 @@ struct fbnic_xmit_cb {
 
 #define FBNIC_XMIT_CB(__skb) ((struct fbnic_xmit_cb *)((__skb)->cb))
 
+#define FBNIC_XMIT_NOUNMAP	(void *)1
+
 static u32 __iomem *fbnic_ring_csr_base(const struct fbnic_ring *ring)
 {
 	unsigned long csr_base = (unsigned long)ring->doorbell;
@@ -315,6 +317,7 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)
 	unsigned int tail = ring->tail, first;
 	unsigned int size, data_len;
 	skb_frag_t *frag;
+	bool is_net_iov;
 	dma_addr_t dma;
 	__le64 *twd;
 
@@ -330,6 +333,7 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)
 	if (size > FIELD_MAX(FBNIC_TWD_LEN_MASK))
 		goto dma_error;
 
+	is_net_iov = false;
 	dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
 
 	for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
@@ -342,6 +346,8 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)
 				   FIELD_PREP(FBNIC_TWD_LEN_MASK, size) |
 				   FIELD_PREP(FBNIC_TWD_TYPE_MASK,
 					      FBNIC_TWD_TYPE_AL));
+		if (is_net_iov)
+			ring->tx_buf[tail] = FBNIC_XMIT_NOUNMAP;
 
 		tail++;
 		tail &= ring->size_mask;
@@ -355,6 +361,7 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)
 		if (size > FIELD_MAX(FBNIC_TWD_LEN_MASK))
 			goto dma_error;
 
+		is_net_iov = skb_frag_is_net_iov(frag);
 		dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE);
 	}
 
@@ -387,6 +394,7 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)
 	while (tail != first) {
 		tail--;
 		tail &= ring->size_mask;
+		ring->tx_buf[tail] = NULL;
 		twd = &ring->desc[tail];
 		if (tail == first)
 			fbnic_unmap_single_twd(dev, twd);
@@ -574,7 +582,11 @@ static void fbnic_clean_twq0(struct fbnic_napi_vector *nv, int napi_budget,
 		desc_cnt--;
 
 		while (desc_cnt--) {
-			fbnic_unmap_page_twd(nv->dev, &ring->desc[head]);
+			if (ring->tx_buf[head] != FBNIC_XMIT_NOUNMAP)
+				fbnic_unmap_page_twd(nv->dev,
+						     &ring->desc[head]);
+			else
+				ring->tx_buf[head] = NULL;
 			head++;
 			head &= ring->size_mask;
 		}
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] eth: fbnic: support devmem Tx
  2025-09-11 14:43 [PATCH net-next] eth: fbnic: support devmem Tx Jakub Kicinski
@ 2025-09-11 18:21 ` Mina Almasry
  2025-09-11 19:02   ` Andrew Lunn
  2025-09-16  7:26 ` Paolo Abeni
  1 sibling, 1 reply; 4+ messages in thread
From: Mina Almasry @ 2025-09-11 18:21 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, sdf,
	alexanderduyck

On Thu, Sep 11, 2025 at 7:43 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> Support devmem Tx. We already use skb_frag_dma_map(), we just need
> to make sure we don't try to unmap the frags. Check if frag is
> unreadable and mark the ring entry.
>
>   # ./tools/testing/selftests/drivers/net/hw/devmem.py
>   TAP version 13
>   1..3
>   ok 1 devmem.check_rx
>   ok 2 devmem.check_tx
>   ok 3 devmem.check_tx_chunks
>   # Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

For most of the netmem stuff we've tried as much as possible to keep
the complexity and type casts out of the driver and in core. I was
hoping the driver can avoid mem-type checking and special handling. In
the case of the tx path, the helpers provided are
netmem_dma_unmap_addr_set & netmem_dma_unmap_page_attrs. If you can
use them, great, or if you can improve them so that we don't have to
have per-driver special handling I think that would be good too.

It seems in your driver you have a special  way to grab fields via
FIELD_GET and that's why you can't use the common helpers.

But this approach is fine too assuming you're ok with a bit extra
complexity and mem-type checks in the driver, so

Acked-by: Mina Almasry <almasrymina@google.com>

-- 
Thanks,
Mina

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] eth: fbnic: support devmem Tx
  2025-09-11 18:21 ` Mina Almasry
@ 2025-09-11 19:02   ` Andrew Lunn
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2025-09-11 19:02 UTC (permalink / raw)
  To: Mina Almasry
  Cc: Jakub Kicinski, davem, netdev, edumazet, pabeni, andrew+netdev,
	horms, sdf, alexanderduyck

> It seems in your driver you have a special  way to grab fields via
> FIELD_GET

There is nothing special about FIELD_GET().

~/linux/drivers/net$ grep -r FIELD_GET | wc
   3724   15584  331380

They are the recommended way to access fields within words.

     Andrew

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] eth: fbnic: support devmem Tx
  2025-09-11 14:43 [PATCH net-next] eth: fbnic: support devmem Tx Jakub Kicinski
  2025-09-11 18:21 ` Mina Almasry
@ 2025-09-16  7:26 ` Paolo Abeni
  1 sibling, 0 replies; 4+ messages in thread
From: Paolo Abeni @ 2025-09-16  7:26 UTC (permalink / raw)
  To: Jakub Kicinski, davem
  Cc: netdev, edumazet, andrew+netdev, horms, sdf, almasrymina,
	alexanderduyck

On 9/11/25 4:43 PM, Jakub Kicinski wrote:
> @@ -574,7 +582,11 @@ static void fbnic_clean_twq0(struct fbnic_napi_vector *nv, int napi_budget,
>  		desc_cnt--;
>  
>  		while (desc_cnt--) {
> -			fbnic_unmap_page_twd(nv->dev, &ring->desc[head]);
> +			if (ring->tx_buf[head] != FBNIC_XMIT_NOUNMAP)
> +				fbnic_unmap_page_twd(nv->dev,
> +						     &ring->desc[head]);
> +			else
> +				ring->tx_buf[head] = NULL;
>  			head++;
>  			head &= ring->size_mask;
>  		}

Why you don't need to avoid the unmap in the DMA-error path in fbnic_tx_map?

Thanks!

Paolo


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-16  7:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-11 14:43 [PATCH net-next] eth: fbnic: support devmem Tx Jakub Kicinski
2025-09-11 18:21 ` Mina Almasry
2025-09-11 19:02   ` Andrew Lunn
2025-09-16  7:26 ` Paolo Abeni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).