Skip to content

Commit 8492e4f

Browse files
WeiFang-NXPPaolo Abeni
authored andcommitted
net: fec: use switch statement to check the type of tx_buf
The tx_buf has three types: FEC_TXBUF_T_SKB, FEC_TXBUF_T_XDP_NDO and FEC_TXBUF_T_XDP_TX. Currently, the driver uses 'if...else...' statements to check the type and perform the corresponding processing. This is very detrimental to future expansion. To support AF_XDP zero-copy mode, two new types will be added in the future, continuing to use 'if...else...' would be a very bad coding style. So the 'if...else...' statements in the current driver are replaced with switch statements. Signed-off-by: Wei Fang <wei.fang@nxp.com> Link: https://patch.msgid.link/20260205085742.2685134-11-wei.fang@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 2dcc934 commit 8492e4f

1 file changed

Lines changed: 73 additions & 61 deletions

File tree

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,28 +1023,35 @@ static void fec_enet_bd_init(struct net_device *dev)
10231023
txq->bd.cur = bdp;
10241024

10251025
for (i = 0; i < txq->bd.ring_size; i++) {
1026+
struct page *page;
1027+
10261028
/* Initialize the BD for every fragment in the page. */
10271029
bdp->cbd_sc = cpu_to_fec16(0);
1028-
if (txq->tx_buf[i].type == FEC_TXBUF_T_SKB) {
1030+
1031+
switch (txq->tx_buf[i].type) {
1032+
case FEC_TXBUF_T_SKB:
10291033
if (bdp->cbd_bufaddr &&
10301034
!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
10311035
dma_unmap_single(&fep->pdev->dev,
10321036
fec32_to_cpu(bdp->cbd_bufaddr),
10331037
fec16_to_cpu(bdp->cbd_datlen),
10341038
DMA_TO_DEVICE);
10351039
dev_kfree_skb_any(txq->tx_buf[i].buf_p);
1036-
} else if (txq->tx_buf[i].type == FEC_TXBUF_T_XDP_NDO) {
1040+
break;
1041+
case FEC_TXBUF_T_XDP_NDO:
10371042
dma_unmap_single(&fep->pdev->dev,
10381043
fec32_to_cpu(bdp->cbd_bufaddr),
10391044
fec16_to_cpu(bdp->cbd_datlen),
10401045
DMA_TO_DEVICE);
1041-
10421046
xdp_return_frame(txq->tx_buf[i].buf_p);
1043-
} else {
1044-
struct page *page = txq->tx_buf[i].buf_p;
1045-
1047+
break;
1048+
case FEC_TXBUF_T_XDP_TX:
1049+
page = txq->tx_buf[i].buf_p;
10461050
page_pool_put_page(pp_page_to_nmdesc(page)->pp,
10471051
page, 0, false);
1052+
break;
1053+
default:
1054+
break;
10481055
}
10491056

10501057
txq->tx_buf[i].buf_p = NULL;
@@ -1510,39 +1517,69 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
15101517
break;
15111518

15121519
index = fec_enet_get_bd_index(bdp, &txq->bd);
1520+
frame_len = fec16_to_cpu(bdp->cbd_datlen);
15131521

1514-
if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB) {
1515-
skb = txq->tx_buf[index].buf_p;
1522+
switch (txq->tx_buf[index].type) {
1523+
case FEC_TXBUF_T_SKB:
15161524
if (bdp->cbd_bufaddr &&
15171525
!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
15181526
dma_unmap_single(&fep->pdev->dev,
15191527
fec32_to_cpu(bdp->cbd_bufaddr),
1520-
fec16_to_cpu(bdp->cbd_datlen),
1521-
DMA_TO_DEVICE);
1528+
frame_len, DMA_TO_DEVICE);
1529+
15221530
bdp->cbd_bufaddr = cpu_to_fec32(0);
1531+
skb = txq->tx_buf[index].buf_p;
15231532
if (!skb)
15241533
goto tx_buf_done;
1525-
} else {
1534+
1535+
frame_len = skb->len;
1536+
1537+
/* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who
1538+
* are to time stamp the packet, so we still need to check time
1539+
* stamping enabled flag.
1540+
*/
1541+
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
1542+
fep->hwts_tx_en) && fep->bufdesc_ex) {
1543+
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
1544+
struct skb_shared_hwtstamps shhwtstamps;
1545+
1546+
fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts), &shhwtstamps);
1547+
skb_tstamp_tx(skb, &shhwtstamps);
1548+
}
1549+
1550+
/* Free the sk buffer associated with this last transmit */
1551+
napi_consume_skb(skb, budget);
1552+
break;
1553+
case FEC_TXBUF_T_XDP_NDO:
15261554
/* Tx processing cannot call any XDP (or page pool) APIs if
15271555
* the "budget" is 0. Because NAPI is called with budget of
15281556
* 0 (such as netpoll) indicates we may be in an IRQ context,
15291557
* however, we can't use the page pool from IRQ context.
15301558
*/
15311559
if (unlikely(!budget))
1532-
break;
1560+
goto out;
15331561

1534-
if (txq->tx_buf[index].type == FEC_TXBUF_T_XDP_NDO) {
1535-
xdpf = txq->tx_buf[index].buf_p;
1536-
dma_unmap_single(&fep->pdev->dev,
1537-
fec32_to_cpu(bdp->cbd_bufaddr),
1538-
fec16_to_cpu(bdp->cbd_datlen),
1539-
DMA_TO_DEVICE);
1540-
} else {
1541-
page = txq->tx_buf[index].buf_p;
1542-
}
1562+
xdpf = txq->tx_buf[index].buf_p;
1563+
dma_unmap_single(&fep->pdev->dev,
1564+
fec32_to_cpu(bdp->cbd_bufaddr),
1565+
frame_len, DMA_TO_DEVICE);
1566+
bdp->cbd_bufaddr = cpu_to_fec32(0);
1567+
xdp_return_frame_rx_napi(xdpf);
1568+
break;
1569+
case FEC_TXBUF_T_XDP_TX:
1570+
if (unlikely(!budget))
1571+
goto out;
15431572

15441573
bdp->cbd_bufaddr = cpu_to_fec32(0);
1545-
frame_len = fec16_to_cpu(bdp->cbd_datlen);
1574+
page = txq->tx_buf[index].buf_p;
1575+
/* The dma_sync_size = 0 as XDP_TX has already synced
1576+
* DMA for_device
1577+
*/
1578+
page_pool_put_page(pp_page_to_nmdesc(page)->pp, page,
1579+
0, true);
1580+
break;
1581+
default:
1582+
break;
15461583
}
15471584

15481585
/* Check for errors. */
@@ -1562,11 +1599,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
15621599
ndev->stats.tx_carrier_errors++;
15631600
} else {
15641601
ndev->stats.tx_packets++;
1565-
1566-
if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB)
1567-
ndev->stats.tx_bytes += skb->len;
1568-
else
1569-
ndev->stats.tx_bytes += frame_len;
1602+
ndev->stats.tx_bytes += frame_len;
15701603
}
15711604

15721605
/* Deferred means some collisions occurred during transmit,
@@ -1575,30 +1608,6 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
15751608
if (status & BD_ENET_TX_DEF)
15761609
ndev->stats.collisions++;
15771610

1578-
if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB) {
1579-
/* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who
1580-
* are to time stamp the packet, so we still need to check time
1581-
* stamping enabled flag.
1582-
*/
1583-
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
1584-
fep->hwts_tx_en) && fep->bufdesc_ex) {
1585-
struct skb_shared_hwtstamps shhwtstamps;
1586-
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
1587-
1588-
fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts), &shhwtstamps);
1589-
skb_tstamp_tx(skb, &shhwtstamps);
1590-
}
1591-
1592-
/* Free the sk buffer associated with this last transmit */
1593-
napi_consume_skb(skb, budget);
1594-
} else if (txq->tx_buf[index].type == FEC_TXBUF_T_XDP_NDO) {
1595-
xdp_return_frame_rx_napi(xdpf);
1596-
} else { /* recycle pages of XDP_TX frames */
1597-
/* The dma_sync_size = 0 as XDP_TX has already synced DMA for_device */
1598-
page_pool_put_page(pp_page_to_nmdesc(page)->pp, page,
1599-
0, true);
1600-
}
1601-
16021611
txq->tx_buf[index].buf_p = NULL;
16031612
/* restore default tx buffer type: FEC_TXBUF_T_SKB */
16041613
txq->tx_buf[index].type = FEC_TXBUF_T_SKB;
@@ -1622,6 +1631,8 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
16221631
}
16231632
}
16241633

1634+
out:
1635+
16251636
/* ERR006358: Keep the transmitter going */
16261637
if (bdp != txq->bd.cur &&
16271638
readl(txq->bd.reg_desc_active) == 0)
@@ -3415,6 +3426,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
34153426
unsigned int i;
34163427
struct fec_enet_priv_tx_q *txq;
34173428
struct fec_enet_priv_rx_q *rxq;
3429+
struct page *page;
34183430
unsigned int q;
34193431

34203432
for (q = 0; q < fep->num_rx_queues; q++) {
@@ -3438,20 +3450,20 @@ static void fec_enet_free_buffers(struct net_device *ndev)
34383450
kfree(txq->tx_bounce[i]);
34393451
txq->tx_bounce[i] = NULL;
34403452

3441-
if (!txq->tx_buf[i].buf_p) {
3442-
txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
3443-
continue;
3444-
}
3445-
3446-
if (txq->tx_buf[i].type == FEC_TXBUF_T_SKB) {
3453+
switch (txq->tx_buf[i].type) {
3454+
case FEC_TXBUF_T_SKB:
34473455
dev_kfree_skb(txq->tx_buf[i].buf_p);
3448-
} else if (txq->tx_buf[i].type == FEC_TXBUF_T_XDP_NDO) {
3456+
break;
3457+
case FEC_TXBUF_T_XDP_NDO:
34493458
xdp_return_frame(txq->tx_buf[i].buf_p);
3450-
} else {
3451-
struct page *page = txq->tx_buf[i].buf_p;
3452-
3459+
break;
3460+
case FEC_TXBUF_T_XDP_TX:
3461+
page = txq->tx_buf[i].buf_p;
34533462
page_pool_put_page(pp_page_to_nmdesc(page)->pp,
34543463
page, 0, false);
3464+
break;
3465+
default:
3466+
break;
34553467
}
34563468

34573469
txq->tx_buf[i].buf_p = NULL;

0 commit comments

Comments
 (0)