realtek: eth: add helper for SKB creation

Simplify rteth_hw_receive() by using a separate helper for SKB creation.

Link: https://github.com/openwrt/openwrt/pull/24245
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
Markus Stockhausen
2026-07-21 09:30:09 +02:00
parent 39d466aba3
commit 7226c6edbf
@@ -1117,14 +1117,54 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
static struct sk_buff *rteth_create_skb(struct rteth_ctrl *ctrl, int ring,
struct rteth_packet *packet)
{
struct page_pool *pool = ctrl->rx_qs[ring].page_pool;
unsigned int offset = packet->page_offset;
struct net_device *dev = ctrl->dev;
struct page *page = packet->page;
unsigned int len = packet->len;
struct sk_buff *skb;
struct dsa_tag tag;
page_pool_dma_sync_for_cpu(pool, page, offset + ctrl->r->skb_headroom, len);
skb = napi_build_skb(page_address(page) + offset, PPOOL_FRAG_SIZE);
if (unlikely(!skb)) {
page_pool_put_full_page(pool, page, true);
return NULL;
}
skb_reserve(skb, ctrl->r->skb_headroom);
skb_mark_for_recycle(skb);
skb_put(skb, len);
ctrl->r->decode_tag(packet, &tag);
if (netdev_uses_dsa(dev)) {
if (tag.port < ctrl->r->cpu_port)
skb_dst_set_noref(skb, &ctrl->dsa_meta[tag.port]->dst);
if (tag.l2_offloaded)
skb->offload_fwd_mark = 1;
}
if (dev->features & NETIF_F_RXCSUM) {
if (tag.crc_error)
skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
return skb;
}
static int rteth_hw_receive(struct net_device *dev, int ring, int budget)
{
int slot, work_done = 0, rx_packets = 0, rx_bytes = 0;
struct rteth_ctrl *ctrl = netdev_priv(dev);
unsigned int len, new_offset, old_offset;
struct page *old_page, *new_page;
unsigned int len, new_offset;
struct rteth_packet *packet;
struct page_pool *pool;
struct page *new_page;
dma_addr_t packet_dma;
struct sk_buff *skb;
struct dsa_tag tag;
@@ -1162,41 +1202,10 @@ static int rteth_hw_receive(struct net_device *dev, int ring, int budget)
goto recycle;
}
old_page = packet->page;
old_offset = packet->page_offset;
packet->page = new_page;
packet->page_offset = new_offset;
packet->dma = page_pool_get_dma_addr(new_page)
+ new_offset + ctrl->r->skb_headroom;
page_pool_dma_sync_for_cpu(pool, old_page,
old_offset + ctrl->r->skb_headroom, len);
skb = napi_build_skb(page_address(old_page) + old_offset, PPOOL_FRAG_SIZE);
skb = rteth_create_skb(ctrl, ring, packet);
if (unlikely(!skb)) {
page_pool_put_full_page(pool, old_page, true);
netdev_err(dev, "skb creation failed\n");
dev->stats.rx_dropped++;
goto recycle;
}
skb_reserve(skb, ctrl->r->skb_headroom);
skb_mark_for_recycle(skb);
skb_put(skb, len);
ctrl->r->decode_tag(packet, &tag);
if (netdev_uses_dsa(dev)) {
if (tag.port < ctrl->r->cpu_port)
skb_dst_set_noref(skb, &ctrl->dsa_meta[tag.port]->dst);
if (tag.l2_offloaded)
skb->offload_fwd_mark = 1;
}
if (dev->features & NETIF_F_RXCSUM) {
if (tag.crc_error)
skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
if (is_tail && skb) {
@@ -1211,6 +1220,11 @@ static int rteth_hw_receive(struct net_device *dev, int ring, int budget)
skb = NULL;
}
}
packet->page = new_page;
packet->page_offset = new_offset;
packet->dma = page_pool_get_dma_addr(new_page)
+ new_offset + ctrl->r->skb_headroom;
recycle:
dma_wmb();
ctrl->rx_data[ring].ring[slot] = packet_dma | RING_OWN_HW;