Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-stmmac-refactor-fpe-as-a-separate-module'

Furong Xu says:

====================
net: stmmac: Refactor FPE as a separate module

Refactor FPE implementation by moving common code for DWMAC4 and
DWXGMAC into a separate FPE module.

FPE implementation for DWMAC4 and DWXGMAC differs only for:
1) Offset address of MAC_FPE_CTRL_STS and MTL_FPE_CTRL_STS
2) FPRQ(Frame Preemption Residue Queue) field in MAC_RxQ_Ctrl1
3) Bit offset of Frame Preemption Interrupt Enable

Tested on DWMAC CORE 5.20a and DWXGMAC CORE 3.20a
====================

Link: https://patch.msgid.link/cover.1730449003.git.0x1207@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+476 -412
+1 -1
drivers/net/ethernet/stmicro/stmmac/Makefile
··· 6 6 mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ 7 7 dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \ 8 8 stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \ 9 - stmmac_xdp.o stmmac_est.o \ 9 + stmmac_xdp.o stmmac_est.o stmmac_fpe.o \ 10 10 $(stmmac-y) 11 11 12 12 stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
-1
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
··· 69 69 #define GMAC_RXQCTRL_TACPQE BIT(21) 70 70 #define GMAC_RXQCTRL_TACPQE_SHIFT 21 71 71 #define GMAC_RXQCTRL_FPRQ GENMASK(26, 24) 72 - #define GMAC_RXQCTRL_FPRQ_SHIFT 24 73 72 74 73 /* MAC Packet Filtering */ 75 74 #define GMAC_PACKET_FILTER_PR BIT(0)
+1 -10
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
··· 16 16 #include <linux/io.h> 17 17 #include <linux/iopoll.h> 18 18 #include "stmmac.h" 19 + #include "stmmac_fpe.h" 19 20 #include "stmmac_pcs.h" 20 21 #include "dwmac4.h" 21 22 #include "dwmac5.h" ··· 1262 1261 .set_arp_offload = dwmac4_set_arp_offload, 1263 1262 .config_l3_filter = dwmac4_config_l3_filter, 1264 1263 .config_l4_filter = dwmac4_config_l4_filter, 1265 - .fpe_configure = dwmac5_fpe_configure, 1266 - .fpe_send_mpacket = dwmac5_fpe_send_mpacket, 1267 - .fpe_irq_status = dwmac5_fpe_irq_status, 1268 - .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, 1269 - .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, 1270 1264 .fpe_map_preemption_class = dwmac5_fpe_map_preemption_class, 1271 1265 .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, 1272 1266 .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, ··· 1312 1316 .set_arp_offload = dwmac4_set_arp_offload, 1313 1317 .config_l3_filter = dwmac4_config_l3_filter, 1314 1318 .config_l4_filter = dwmac4_config_l4_filter, 1315 - .fpe_configure = dwmac5_fpe_configure, 1316 - .fpe_send_mpacket = dwmac5_fpe_send_mpacket, 1317 - .fpe_irq_status = dwmac5_fpe_irq_status, 1318 - .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, 1319 - .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, 1320 1319 .fpe_map_preemption_class = dwmac5_fpe_map_preemption_class, 1321 1320 .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, 1322 1321 .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr,
-150
drivers/net/ethernet/stmicro/stmmac/dwmac5.c
··· 572 572 writel(val, ioaddr + MAC_PPS_CONTROL); 573 573 return 0; 574 574 } 575 - 576 - void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, 577 - u32 num_txq, u32 num_rxq, 578 - bool tx_enable, bool pmac_enable) 579 - { 580 - u32 value; 581 - 582 - if (tx_enable) { 583 - cfg->fpe_csr = EFPE; 584 - value = readl(ioaddr + GMAC_RXQ_CTRL1); 585 - value &= ~GMAC_RXQCTRL_FPRQ; 586 - value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; 587 - writel(value, ioaddr + GMAC_RXQ_CTRL1); 588 - } else { 589 - cfg->fpe_csr = 0; 590 - } 591 - writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS); 592 - 593 - value = readl(ioaddr + GMAC_INT_EN); 594 - 595 - if (pmac_enable) { 596 - if (!(value & GMAC_INT_FPE_EN)) { 597 - /* Dummy read to clear any pending masked interrupts */ 598 - readl(ioaddr + MAC_FPE_CTRL_STS); 599 - 600 - value |= GMAC_INT_FPE_EN; 601 - } 602 - } else { 603 - value &= ~GMAC_INT_FPE_EN; 604 - } 605 - 606 - writel(value, ioaddr + GMAC_INT_EN); 607 - } 608 - 609 - int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) 610 - { 611 - u32 value; 612 - int status; 613 - 614 - status = FPE_EVENT_UNKNOWN; 615 - 616 - /* Reads from the MAC_FPE_CTRL_STS register should only be performed 617 - * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read" 618 - */ 619 - value = readl(ioaddr + MAC_FPE_CTRL_STS); 620 - 621 - if (value & TRSP) { 622 - status |= FPE_EVENT_TRSP; 623 - netdev_dbg(dev, "FPE: Respond mPacket is transmitted\n"); 624 - } 625 - 626 - if (value & TVER) { 627 - status |= FPE_EVENT_TVER; 628 - netdev_dbg(dev, "FPE: Verify mPacket is transmitted\n"); 629 - } 630 - 631 - if (value & RRSP) { 632 - status |= FPE_EVENT_RRSP; 633 - netdev_dbg(dev, "FPE: Respond mPacket is received\n"); 634 - } 635 - 636 - if (value & RVER) { 637 - status |= FPE_EVENT_RVER; 638 - netdev_dbg(dev, "FPE: Verify mPacket is received\n"); 639 - } 640 - 641 - return status; 642 - } 643 - 644 - void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, 645 - enum stmmac_mpacket_type type) 646 - { 647 - u32 value = cfg->fpe_csr; 648 - 649 - if (type == MPACKET_VERIFY) 650 - value |= SVER; 651 - else if (type == MPACKET_RESPONSE) 652 - value |= SRSP; 653 - 654 - writel(value, ioaddr + MAC_FPE_CTRL_STS); 655 - } 656 - 657 - int dwmac5_fpe_get_add_frag_size(const void __iomem *ioaddr) 658 - { 659 - return FIELD_GET(DWMAC5_ADD_FRAG_SZ, readl(ioaddr + MTL_FPE_CTRL_STS)); 660 - } 661 - 662 - void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) 663 - { 664 - u32 value; 665 - 666 - value = readl(ioaddr + MTL_FPE_CTRL_STS); 667 - writel(u32_replace_bits(value, add_frag_size, DWMAC5_ADD_FRAG_SZ), 668 - ioaddr + MTL_FPE_CTRL_STS); 669 - } 670 - 671 - #define ALG_ERR_MSG "TX algorithm SP is not suitable for one-to-many mapping" 672 - #define WEIGHT_ERR_MSG "TXQ weight %u differs across other TXQs in TC: [%u]" 673 - 674 - int dwmac5_fpe_map_preemption_class(struct net_device *ndev, 675 - struct netlink_ext_ack *extack, u32 pclass) 676 - { 677 - u32 val, offset, count, queue_weight, preemptible_txqs = 0; 678 - struct stmmac_priv *priv = netdev_priv(ndev); 679 - u32 num_tc = ndev->num_tc; 680 - 681 - if (!pclass) 682 - goto update_mapping; 683 - 684 - /* DWMAC CORE4+ can not program TC:TXQ mapping to hardware. 685 - * 686 - * Synopsys Databook: 687 - * "The number of Tx DMA channels is equal to the number of Tx queues, 688 - * and is direct one-to-one mapping." 689 - */ 690 - for (u32 tc = 0; tc < num_tc; tc++) { 691 - count = ndev->tc_to_txq[tc].count; 692 - offset = ndev->tc_to_txq[tc].offset; 693 - 694 - if (pclass & BIT(tc)) 695 - preemptible_txqs |= GENMASK(offset + count - 1, offset); 696 - 697 - /* This is 1:1 mapping, go to next TC */ 698 - if (count == 1) 699 - continue; 700 - 701 - if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) { 702 - NL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG); 703 - return -EINVAL; 704 - } 705 - 706 - queue_weight = priv->plat->tx_queues_cfg[offset].weight; 707 - 708 - for (u32 i = 1; i < count; i++) { 709 - if (priv->plat->tx_queues_cfg[offset + i].weight != 710 - queue_weight) { 711 - NL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG, 712 - queue_weight, tc); 713 - return -EINVAL; 714 - } 715 - } 716 - } 717 - 718 - update_mapping: 719 - val = readl(priv->ioaddr + MTL_FPE_CTRL_STS); 720 - writel(u32_replace_bits(val, preemptible_txqs, DWMAC5_PREEMPTION_CLASS), 721 - priv->ioaddr + MTL_FPE_CTRL_STS); 722 - 723 - return 0; 724 - }
-26
drivers/net/ethernet/stmicro/stmmac/dwmac5.h
··· 11 11 #define PRTYEN BIT(1) 12 12 #define TMOUTEN BIT(0) 13 13 14 - #define MAC_FPE_CTRL_STS 0x00000234 15 - #define TRSP BIT(19) 16 - #define TVER BIT(18) 17 - #define RRSP BIT(17) 18 - #define RVER BIT(16) 19 - #define SRSP BIT(2) 20 - #define SVER BIT(1) 21 - #define EFPE BIT(0) 22 - 23 14 #define MAC_PPS_CONTROL 0x00000b70 24 15 #define PPS_MAXIDX(x) ((((x) + 1) * 8) - 1) 25 16 #define PPS_MINIDX(x) ((x) * 8) ··· 29 38 #define TTSL0 GENMASK(30, 0) 30 39 #define MAC_PPSx_INTERVAL(x) (0x00000b88 + ((x) * 0x10)) 31 40 #define MAC_PPSx_WIDTH(x) (0x00000b8c + ((x) * 0x10)) 32 - 33 - #define MTL_FPE_CTRL_STS 0x00000c90 34 - /* Preemption Classification */ 35 - #define DWMAC5_PREEMPTION_CLASS GENMASK(15, 8) 36 - /* Additional Fragment Size of preempted frames */ 37 - #define DWMAC5_ADD_FRAG_SZ GENMASK(1, 0) 38 41 39 42 #define MTL_RXP_CONTROL_STATUS 0x00000ca0 40 43 #define RXPI BIT(31) ··· 93 108 int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, 94 109 struct stmmac_pps_cfg *cfg, bool enable, 95 110 u32 sub_second_inc, u32 systime_flags); 96 - void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, 97 - u32 num_txq, u32 num_rxq, 98 - bool tx_enable, bool pmac_enable); 99 - void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, 100 - struct stmmac_fpe_cfg *cfg, 101 - enum stmmac_mpacket_type type); 102 - int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev); 103 - int dwmac5_fpe_get_add_frag_size(const void __iomem *ioaddr); 104 - void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size); 105 - int dwmac5_fpe_map_preemption_class(struct net_device *ndev, 106 - struct netlink_ext_ack *extack, u32 pclass); 107 111 108 112 #endif /* __DWMAC5_H__ */
+2 -4
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
··· 84 84 #define XGMAC_MCBCQEN BIT(15) 85 85 #define XGMAC_MCBCQ GENMASK(11, 8) 86 86 #define XGMAC_MCBCQ_SHIFT 8 87 - #define XGMAC_RQ GENMASK(7, 4) 88 - #define XGMAC_RQ_SHIFT 4 87 + #define XGMAC_FPRQ GENMASK(7, 4) 89 88 #define XGMAC_UPQ GENMASK(3, 0) 90 89 #define XGMAC_UPQ_SHIFT 0 91 90 #define XGMAC_RXQ_CTRL2 0x000000a8 ··· 95 96 #define XGMAC_LPIIS BIT(5) 96 97 #define XGMAC_PMTIS BIT(4) 97 98 #define XGMAC_INT_EN 0x000000b4 99 + #define XGMAC_FPEIE BIT(15) 98 100 #define XGMAC_TSIE BIT(12) 99 101 #define XGMAC_LPIIE BIT(5) 100 102 #define XGMAC_PMTIE BIT(4) ··· 193 193 #define XGMAC_MDIO_ADDR 0x00000200 194 194 #define XGMAC_MDIO_DATA 0x00000204 195 195 #define XGMAC_MDIO_C22P 0x00000220 196 - #define XGMAC_FPE_CTRL_STS 0x00000280 197 - #define XGMAC_EFPE BIT(0) 198 196 #define XGMAC_ADDRx_HIGH(x) (0x00000300 + (x) * 0x8) 199 197 #define XGMAC_ADDR_MAX 32 200 198 #define XGMAC_AE BIT(31)
+3 -28
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
··· 8 8 #include <linux/crc32.h> 9 9 #include <linux/iopoll.h> 10 10 #include "stmmac.h" 11 + #include "stmmac_fpe.h" 11 12 #include "stmmac_ptp.h" 12 13 #include "dwxlgmac2.h" 13 14 #include "dwxgmac2.h" ··· 1505 1504 writel(value, ioaddr + XGMAC_RX_CONFIG); 1506 1505 } 1507 1506 1508 - static void dwxgmac3_fpe_configure(void __iomem *ioaddr, 1509 - struct stmmac_fpe_cfg *cfg, 1510 - u32 num_txq, u32 num_rxq, 1511 - bool tx_enable, bool pmac_enable) 1512 - { 1513 - u32 value; 1514 - 1515 - if (!tx_enable) { 1516 - value = readl(ioaddr + XGMAC_FPE_CTRL_STS); 1517 - 1518 - value &= ~XGMAC_EFPE; 1519 - 1520 - writel(value, ioaddr + XGMAC_FPE_CTRL_STS); 1521 - return; 1522 - } 1523 - 1524 - value = readl(ioaddr + XGMAC_RXQ_CTRL1); 1525 - value &= ~XGMAC_RQ; 1526 - value |= (num_rxq - 1) << XGMAC_RQ_SHIFT; 1527 - writel(value, ioaddr + XGMAC_RXQ_CTRL1); 1528 - 1529 - value = readl(ioaddr + XGMAC_FPE_CTRL_STS); 1530 - value |= XGMAC_EFPE; 1531 - writel(value, ioaddr + XGMAC_FPE_CTRL_STS); 1532 - } 1533 - 1534 1507 const struct stmmac_ops dwxgmac210_ops = { 1535 1508 .core_init = dwxgmac2_core_init, 1536 1509 .set_mac = dwxgmac2_set_mac, ··· 1545 1570 .config_l3_filter = dwxgmac2_config_l3_filter, 1546 1571 .config_l4_filter = dwxgmac2_config_l4_filter, 1547 1572 .set_arp_offload = dwxgmac2_set_arp_offload, 1548 - .fpe_configure = dwxgmac3_fpe_configure, 1573 + .fpe_map_preemption_class = dwxgmac3_fpe_map_preemption_class, 1549 1574 }; 1550 1575 1551 1576 static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode, ··· 1602 1627 .config_l3_filter = dwxgmac2_config_l3_filter, 1603 1628 .config_l4_filter = dwxgmac2_config_l4_filter, 1604 1629 .set_arp_offload = dwxgmac2_set_arp_offload, 1605 - .fpe_configure = dwxgmac3_fpe_configure, 1630 + .fpe_map_preemption_class = dwxgmac3_fpe_map_preemption_class, 1606 1631 }; 1607 1632 1608 1633 int dwxgmac2_setup(struct stmmac_priv *priv)
+7
drivers/net/ethernet/stmicro/stmmac/hwif.c
··· 6 6 7 7 #include "common.h" 8 8 #include "stmmac.h" 9 + #include "stmmac_fpe.h" 9 10 #include "stmmac_ptp.h" 10 11 #include "stmmac_est.h" 11 12 ··· 186 185 .ptp_off = PTP_GMAC4_OFFSET, 187 186 .mmc_off = MMC_GMAC4_OFFSET, 188 187 .est_off = EST_GMAC4_OFFSET, 188 + .fpe_reg = &dwmac5_fpe_reg, 189 189 }, 190 190 .desc = &dwmac4_desc_ops, 191 191 .dma = &dwmac4_dma_ops, ··· 207 205 .ptp_off = PTP_GMAC4_OFFSET, 208 206 .mmc_off = MMC_GMAC4_OFFSET, 209 207 .est_off = EST_GMAC4_OFFSET, 208 + .fpe_reg = &dwmac5_fpe_reg, 210 209 }, 211 210 .desc = &dwmac4_desc_ops, 212 211 .dma = &dwmac410_dma_ops, ··· 228 225 .ptp_off = PTP_GMAC4_OFFSET, 229 226 .mmc_off = MMC_GMAC4_OFFSET, 230 227 .est_off = EST_GMAC4_OFFSET, 228 + .fpe_reg = &dwmac5_fpe_reg, 231 229 }, 232 230 .desc = &dwmac4_desc_ops, 233 231 .dma = &dwmac410_dma_ops, ··· 250 246 .ptp_off = PTP_XGMAC_OFFSET, 251 247 .mmc_off = MMC_XGMAC_OFFSET, 252 248 .est_off = EST_XGMAC_OFFSET, 249 + .fpe_reg = &dwxgmac3_fpe_reg, 253 250 }, 254 251 .desc = &dwxgmac210_desc_ops, 255 252 .dma = &dwxgmac210_dma_ops, ··· 272 267 .ptp_off = PTP_XGMAC_OFFSET, 273 268 .mmc_off = MMC_XGMAC_OFFSET, 274 269 .est_off = EST_XGMAC_OFFSET, 270 + .fpe_reg = &dwxgmac3_fpe_reg, 275 271 }, 276 272 .desc = &dwxgmac210_desc_ops, 277 273 .dma = &dwxgmac210_dma_ops, ··· 359 353 mac->est = mac->est ? : entry->est; 360 354 361 355 priv->hw = mac; 356 + priv->fpe_cfg.reg = entry->regs.fpe_reg; 362 357 priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off; 363 358 priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off; 364 359 if (entry->est)
+1 -19
drivers/net/ethernet/stmicro/stmmac/hwif.h
··· 420 420 bool en, bool udp, bool sa, bool inv, 421 421 u32 match); 422 422 void (*set_arp_offload)(struct mac_device_info *hw, bool en, u32 addr); 423 - void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, 424 - u32 num_txq, u32 num_rxq, 425 - bool tx_enable, bool pmac_enable); 426 - void (*fpe_send_mpacket)(void __iomem *ioaddr, 427 - struct stmmac_fpe_cfg *cfg, 428 - enum stmmac_mpacket_type type); 429 - int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev); 430 - int (*fpe_get_add_frag_size)(const void __iomem *ioaddr); 431 - void (*fpe_set_add_frag_size)(void __iomem *ioaddr, u32 add_frag_size); 432 423 int (*fpe_map_preemption_class)(struct net_device *ndev, 433 424 struct netlink_ext_ack *extack, 434 425 u32 pclass); ··· 521 530 stmmac_do_callback(__priv, mac, config_l4_filter, __args) 522 531 #define stmmac_set_arp_offload(__priv, __args...) \ 523 532 stmmac_do_void_callback(__priv, mac, set_arp_offload, __args) 524 - #define stmmac_fpe_configure(__priv, __args...) \ 525 - stmmac_do_void_callback(__priv, mac, fpe_configure, __args) 526 - #define stmmac_fpe_send_mpacket(__priv, __args...) \ 527 - stmmac_do_void_callback(__priv, mac, fpe_send_mpacket, __args) 528 - #define stmmac_fpe_irq_status(__priv, __args...) \ 529 - stmmac_do_callback(__priv, mac, fpe_irq_status, __args) 530 - #define stmmac_fpe_get_add_frag_size(__priv, __args...) \ 531 - stmmac_do_callback(__priv, mac, fpe_get_add_frag_size, __args) 532 - #define stmmac_fpe_set_add_frag_size(__priv, __args...) \ 533 - stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args) 534 533 #define stmmac_fpe_map_preemption_class(__priv, __args...) \ 535 534 stmmac_do_void_callback(__priv, mac, fpe_map_preemption_class, __args) 536 535 ··· 659 678 stmmac_do_void_callback(__priv, est, irq_status, __args) 660 679 661 680 struct stmmac_regs_off { 681 + const struct stmmac_fpe_reg *fpe_reg; 662 682 u32 ptp_off; 663 683 u32 mmc_off; 664 684 u32 est_off;
+1 -10
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 146 146 u32 index; 147 147 }; 148 148 149 - /* FPE link-partner hand-shaking mPacket type */ 150 - enum stmmac_mpacket_type { 151 - MPACKET_VERIFY = 0, 152 - MPACKET_RESPONSE = 1, 153 - }; 154 - 155 - #define STMMAC_FPE_MM_MAX_VERIFY_RETRIES 3 156 - #define STMMAC_FPE_MM_MAX_VERIFY_TIME_MS 128 157 - 158 149 struct stmmac_fpe_cfg { 159 150 /* Serialize access to MAC Merge state between ethtool requests 160 151 * and link state updates. 161 152 */ 162 153 spinlock_t lock; 163 154 155 + const struct stmmac_fpe_reg *reg; 164 156 u32 fpe_csr; /* MAC_FPE_CTRL_STS reg cache */ 165 157 166 158 enum ethtool_mm_verify_status status; ··· 412 420 int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt); 413 421 int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size); 414 422 int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled); 415 - void stmmac_fpe_apply(struct stmmac_priv *priv); 416 423 417 424 static inline bool stmmac_xdp_is_enabled(struct stmmac_priv *priv) 418 425 {
+4 -4
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
··· 17 17 #include <linux/net_tstamp.h> 18 18 19 19 #include "stmmac.h" 20 + #include "stmmac_fpe.h" 20 21 #include "dwmac_dma.h" 21 22 #include "dwxgmac2.h" 22 - #include "dwmac5.h" 23 23 24 24 #define REG_SPACE_SIZE 0x1060 25 25 #define GMAC4_REG_SPACE_SIZE 0x116C ··· 1271 1271 unsigned long flags; 1272 1272 u32 frag_size; 1273 1273 1274 - if (!priv->dma_cap.fpesel) 1274 + if (!stmmac_fpe_supported(priv)) 1275 1275 return -EOPNOTSUPP; 1276 1276 1277 1277 spin_lock_irqsave(&priv->fpe_cfg.lock, flags); ··· 1294 1294 else 1295 1295 state->tx_active = false; 1296 1296 1297 - frag_size = stmmac_fpe_get_add_frag_size(priv, priv->ioaddr); 1297 + frag_size = stmmac_fpe_get_add_frag_size(priv); 1298 1298 state->tx_min_frag_size = ethtool_mm_frag_size_add_to_min(frag_size); 1299 1299 1300 1300 spin_unlock_irqrestore(&priv->fpe_cfg.lock, flags); ··· 1329 1329 if (!cfg->verify_enabled) 1330 1330 fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_DISABLED; 1331 1331 1332 - stmmac_fpe_set_add_frag_size(priv, priv->ioaddr, frag_size); 1332 + stmmac_fpe_set_add_frag_size(priv, frag_size); 1333 1333 stmmac_fpe_apply(priv); 1334 1334 1335 1335 spin_unlock_irqrestore(&fpe_cfg->lock, flags);
+413
drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2024 Furong Xu <0x1207@gmail.com> 4 + * stmmac FPE(802.3 Qbu) handling 5 + */ 6 + #include "stmmac.h" 7 + #include "stmmac_fpe.h" 8 + #include "dwmac4.h" 9 + #include "dwmac5.h" 10 + #include "dwxgmac2.h" 11 + 12 + #define GMAC5_MAC_FPE_CTRL_STS 0x00000234 13 + #define XGMAC_MAC_FPE_CTRL_STS 0x00000280 14 + 15 + #define GMAC5_MTL_FPE_CTRL_STS 0x00000c90 16 + #define XGMAC_MTL_FPE_CTRL_STS 0x00001090 17 + /* Preemption Classification */ 18 + #define FPE_MTL_PREEMPTION_CLASS GENMASK(15, 8) 19 + /* Additional Fragment Size of preempted frames */ 20 + #define FPE_MTL_ADD_FRAG_SZ GENMASK(1, 0) 21 + 22 + #define STMMAC_MAC_FPE_CTRL_STS_TRSP BIT(19) 23 + #define STMMAC_MAC_FPE_CTRL_STS_TVER BIT(18) 24 + #define STMMAC_MAC_FPE_CTRL_STS_RRSP BIT(17) 25 + #define STMMAC_MAC_FPE_CTRL_STS_RVER BIT(16) 26 + #define STMMAC_MAC_FPE_CTRL_STS_SRSP BIT(2) 27 + #define STMMAC_MAC_FPE_CTRL_STS_SVER BIT(1) 28 + #define STMMAC_MAC_FPE_CTRL_STS_EFPE BIT(0) 29 + 30 + /* FPE link-partner hand-shaking mPacket type */ 31 + enum stmmac_mpacket_type { 32 + MPACKET_VERIFY = 0, 33 + MPACKET_RESPONSE = 1, 34 + }; 35 + 36 + struct stmmac_fpe_reg { 37 + const u32 mac_fpe_reg; /* offset of MAC_FPE_CTRL_STS */ 38 + const u32 mtl_fpe_reg; /* offset of MTL_FPE_CTRL_STS */ 39 + const u32 rxq_ctrl1_reg; /* offset of MAC_RxQ_Ctrl1 */ 40 + const u32 fprq_mask; /* Frame Preemption Residue Queue */ 41 + const u32 int_en_reg; /* offset of MAC_Interrupt_Enable */ 42 + const u32 int_en_bit; /* Frame Preemption Interrupt Enable */ 43 + }; 44 + 45 + bool stmmac_fpe_supported(struct stmmac_priv *priv) 46 + { 47 + return priv->dma_cap.fpesel && priv->fpe_cfg.reg && 48 + priv->hw->mac->fpe_map_preemption_class; 49 + } 50 + 51 + static void stmmac_fpe_configure(struct stmmac_priv *priv, bool tx_enable, 52 + bool pmac_enable) 53 + { 54 + struct stmmac_fpe_cfg *cfg = &priv->fpe_cfg; 55 + const struct stmmac_fpe_reg *reg = cfg->reg; 56 + u32 num_rxq = priv->plat->rx_queues_to_use; 57 + void __iomem *ioaddr = priv->ioaddr; 58 + u32 value; 59 + 60 + if (tx_enable) { 61 + cfg->fpe_csr = STMMAC_MAC_FPE_CTRL_STS_EFPE; 62 + value = readl(ioaddr + reg->rxq_ctrl1_reg); 63 + value &= ~reg->fprq_mask; 64 + /* Keep this SHIFT, FIELD_PREP() expects a constant mask :-/ */ 65 + value |= (num_rxq - 1) << __ffs(reg->fprq_mask); 66 + writel(value, ioaddr + reg->rxq_ctrl1_reg); 67 + } else { 68 + cfg->fpe_csr = 0; 69 + } 70 + writel(cfg->fpe_csr, ioaddr + reg->mac_fpe_reg); 71 + 72 + value = readl(ioaddr + reg->int_en_reg); 73 + 74 + if (pmac_enable) { 75 + if (!(value & reg->int_en_bit)) { 76 + /* Dummy read to clear any pending masked interrupts */ 77 + readl(ioaddr + reg->mac_fpe_reg); 78 + 79 + value |= reg->int_en_bit; 80 + } 81 + } else { 82 + value &= ~reg->int_en_bit; 83 + } 84 + 85 + writel(value, ioaddr + reg->int_en_reg); 86 + } 87 + 88 + static void stmmac_fpe_send_mpacket(struct stmmac_priv *priv, 89 + enum stmmac_mpacket_type type) 90 + { 91 + const struct stmmac_fpe_reg *reg = priv->fpe_cfg.reg; 92 + void __iomem *ioaddr = priv->ioaddr; 93 + u32 value = priv->fpe_cfg.fpe_csr; 94 + 95 + if (type == MPACKET_VERIFY) 96 + value |= STMMAC_MAC_FPE_CTRL_STS_SVER; 97 + else if (type == MPACKET_RESPONSE) 98 + value |= STMMAC_MAC_FPE_CTRL_STS_SRSP; 99 + 100 + writel(value, ioaddr + reg->mac_fpe_reg); 101 + } 102 + 103 + static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status) 104 + { 105 + struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 106 + 107 + /* This is interrupt context, just spin_lock() */ 108 + spin_lock(&fpe_cfg->lock); 109 + 110 + if (!fpe_cfg->pmac_enabled || status == FPE_EVENT_UNKNOWN) 111 + goto unlock_out; 112 + 113 + /* LP has sent verify mPacket */ 114 + if ((status & FPE_EVENT_RVER) == FPE_EVENT_RVER) 115 + stmmac_fpe_send_mpacket(priv, MPACKET_RESPONSE); 116 + 117 + /* Local has sent verify mPacket */ 118 + if ((status & FPE_EVENT_TVER) == FPE_EVENT_TVER && 119 + fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED) 120 + fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING; 121 + 122 + /* LP has sent response mPacket */ 123 + if ((status & FPE_EVENT_RRSP) == FPE_EVENT_RRSP && 124 + fpe_cfg->status == ETHTOOL_MM_VERIFY_STATUS_VERIFYING) 125 + fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED; 126 + 127 + unlock_out: 128 + spin_unlock(&fpe_cfg->lock); 129 + } 130 + 131 + void stmmac_fpe_irq_status(struct stmmac_priv *priv) 132 + { 133 + const struct stmmac_fpe_reg *reg = priv->fpe_cfg.reg; 134 + void __iomem *ioaddr = priv->ioaddr; 135 + struct net_device *dev = priv->dev; 136 + int status = FPE_EVENT_UNKNOWN; 137 + u32 value; 138 + 139 + /* Reads from the MAC_FPE_CTRL_STS register should only be performed 140 + * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read" 141 + */ 142 + value = readl(ioaddr + reg->mac_fpe_reg); 143 + 144 + if (value & STMMAC_MAC_FPE_CTRL_STS_TRSP) { 145 + status |= FPE_EVENT_TRSP; 146 + netdev_dbg(dev, "FPE: Respond mPacket is transmitted\n"); 147 + } 148 + 149 + if (value & STMMAC_MAC_FPE_CTRL_STS_TVER) { 150 + status |= FPE_EVENT_TVER; 151 + netdev_dbg(dev, "FPE: Verify mPacket is transmitted\n"); 152 + } 153 + 154 + if (value & STMMAC_MAC_FPE_CTRL_STS_RRSP) { 155 + status |= FPE_EVENT_RRSP; 156 + netdev_dbg(dev, "FPE: Respond mPacket is received\n"); 157 + } 158 + 159 + if (value & STMMAC_MAC_FPE_CTRL_STS_RVER) { 160 + status |= FPE_EVENT_RVER; 161 + netdev_dbg(dev, "FPE: Verify mPacket is received\n"); 162 + } 163 + 164 + stmmac_fpe_event_status(priv, status); 165 + } 166 + 167 + /** 168 + * stmmac_fpe_verify_timer - Timer for MAC Merge verification 169 + * @t: timer_list struct containing private info 170 + * 171 + * Verify the MAC Merge capability in the local TX direction, by 172 + * transmitting Verify mPackets up to 3 times. Wait until link 173 + * partner responds with a Response mPacket, otherwise fail. 174 + */ 175 + static void stmmac_fpe_verify_timer(struct timer_list *t) 176 + { 177 + struct stmmac_fpe_cfg *fpe_cfg = from_timer(fpe_cfg, t, verify_timer); 178 + struct stmmac_priv *priv = container_of(fpe_cfg, struct stmmac_priv, 179 + fpe_cfg); 180 + unsigned long flags; 181 + bool rearm = false; 182 + 183 + spin_lock_irqsave(&fpe_cfg->lock, flags); 184 + 185 + switch (fpe_cfg->status) { 186 + case ETHTOOL_MM_VERIFY_STATUS_INITIAL: 187 + case ETHTOOL_MM_VERIFY_STATUS_VERIFYING: 188 + if (fpe_cfg->verify_retries != 0) { 189 + stmmac_fpe_send_mpacket(priv, MPACKET_VERIFY); 190 + rearm = true; 191 + } else { 192 + fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_FAILED; 193 + } 194 + 195 + fpe_cfg->verify_retries--; 196 + break; 197 + 198 + case ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED: 199 + stmmac_fpe_configure(priv, true, true); 200 + break; 201 + 202 + default: 203 + break; 204 + } 205 + 206 + if (rearm) { 207 + mod_timer(&fpe_cfg->verify_timer, 208 + jiffies + msecs_to_jiffies(fpe_cfg->verify_time)); 209 + } 210 + 211 + spin_unlock_irqrestore(&fpe_cfg->lock, flags); 212 + } 213 + 214 + static void stmmac_fpe_verify_timer_arm(struct stmmac_fpe_cfg *fpe_cfg) 215 + { 216 + if (fpe_cfg->pmac_enabled && fpe_cfg->tx_enabled && 217 + fpe_cfg->verify_enabled && 218 + fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_FAILED && 219 + fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED) { 220 + timer_setup(&fpe_cfg->verify_timer, stmmac_fpe_verify_timer, 0); 221 + mod_timer(&fpe_cfg->verify_timer, jiffies); 222 + } 223 + } 224 + 225 + void stmmac_fpe_init(struct stmmac_priv *priv) 226 + { 227 + priv->fpe_cfg.verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES; 228 + priv->fpe_cfg.verify_time = STMMAC_FPE_MM_MAX_VERIFY_TIME_MS; 229 + priv->fpe_cfg.status = ETHTOOL_MM_VERIFY_STATUS_DISABLED; 230 + timer_setup(&priv->fpe_cfg.verify_timer, stmmac_fpe_verify_timer, 0); 231 + spin_lock_init(&priv->fpe_cfg.lock); 232 + 233 + if ((!priv->fpe_cfg.reg || !priv->hw->mac->fpe_map_preemption_class) && 234 + priv->dma_cap.fpesel) 235 + dev_info(priv->device, "FPE is not supported by driver.\n"); 236 + } 237 + 238 + void stmmac_fpe_apply(struct stmmac_priv *priv) 239 + { 240 + struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 241 + 242 + /* If verification is disabled, configure FPE right away. 243 + * Otherwise let the timer code do it. 244 + */ 245 + if (!fpe_cfg->verify_enabled) { 246 + stmmac_fpe_configure(priv, fpe_cfg->tx_enabled, 247 + fpe_cfg->pmac_enabled); 248 + } else { 249 + fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_INITIAL; 250 + fpe_cfg->verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES; 251 + 252 + if (netif_running(priv->dev)) 253 + stmmac_fpe_verify_timer_arm(fpe_cfg); 254 + } 255 + } 256 + 257 + void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up) 258 + { 259 + struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 260 + unsigned long flags; 261 + 262 + timer_shutdown_sync(&fpe_cfg->verify_timer); 263 + 264 + spin_lock_irqsave(&fpe_cfg->lock, flags); 265 + 266 + if (is_up && fpe_cfg->pmac_enabled) { 267 + /* VERIFY process requires pmac enabled when NIC comes up */ 268 + stmmac_fpe_configure(priv, false, true); 269 + 270 + /* New link => maybe new partner => new verification process */ 271 + stmmac_fpe_apply(priv); 272 + } else { 273 + /* No link => turn off EFPE */ 274 + stmmac_fpe_configure(priv, false, false); 275 + } 276 + 277 + spin_unlock_irqrestore(&fpe_cfg->lock, flags); 278 + } 279 + 280 + int stmmac_fpe_get_add_frag_size(struct stmmac_priv *priv) 281 + { 282 + const struct stmmac_fpe_reg *reg = priv->fpe_cfg.reg; 283 + void __iomem *ioaddr = priv->ioaddr; 284 + 285 + return FIELD_GET(FPE_MTL_ADD_FRAG_SZ, readl(ioaddr + reg->mtl_fpe_reg)); 286 + } 287 + 288 + void stmmac_fpe_set_add_frag_size(struct stmmac_priv *priv, u32 add_frag_size) 289 + { 290 + const struct stmmac_fpe_reg *reg = priv->fpe_cfg.reg; 291 + void __iomem *ioaddr = priv->ioaddr; 292 + u32 value; 293 + 294 + value = readl(ioaddr + reg->mtl_fpe_reg); 295 + writel(u32_replace_bits(value, add_frag_size, FPE_MTL_ADD_FRAG_SZ), 296 + ioaddr + reg->mtl_fpe_reg); 297 + } 298 + 299 + #define ALG_ERR_MSG "TX algorithm SP is not suitable for one-to-many mapping" 300 + #define WEIGHT_ERR_MSG "TXQ weight %u differs across other TXQs in TC: [%u]" 301 + 302 + int dwmac5_fpe_map_preemption_class(struct net_device *ndev, 303 + struct netlink_ext_ack *extack, u32 pclass) 304 + { 305 + u32 val, offset, count, queue_weight, preemptible_txqs = 0; 306 + struct stmmac_priv *priv = netdev_priv(ndev); 307 + int num_tc = netdev_get_num_tc(ndev); 308 + 309 + if (!pclass) 310 + goto update_mapping; 311 + 312 + /* DWMAC CORE4+ can not program TC:TXQ mapping to hardware. 313 + * 314 + * Synopsys Databook: 315 + * "The number of Tx DMA channels is equal to the number of Tx queues, 316 + * and is direct one-to-one mapping." 317 + */ 318 + for (u32 tc = 0; tc < num_tc; tc++) { 319 + count = ndev->tc_to_txq[tc].count; 320 + offset = ndev->tc_to_txq[tc].offset; 321 + 322 + if (pclass & BIT(tc)) 323 + preemptible_txqs |= GENMASK(offset + count - 1, offset); 324 + 325 + /* This is 1:1 mapping, go to next TC */ 326 + if (count == 1) 327 + continue; 328 + 329 + if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) { 330 + NL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG); 331 + return -EINVAL; 332 + } 333 + 334 + queue_weight = priv->plat->tx_queues_cfg[offset].weight; 335 + 336 + for (u32 i = 1; i < count; i++) { 337 + if (priv->plat->tx_queues_cfg[offset + i].weight != 338 + queue_weight) { 339 + NL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG, 340 + queue_weight, tc); 341 + return -EINVAL; 342 + } 343 + } 344 + } 345 + 346 + update_mapping: 347 + val = readl(priv->ioaddr + GMAC5_MTL_FPE_CTRL_STS); 348 + writel(u32_replace_bits(val, preemptible_txqs, FPE_MTL_PREEMPTION_CLASS), 349 + priv->ioaddr + GMAC5_MTL_FPE_CTRL_STS); 350 + 351 + return 0; 352 + } 353 + 354 + int dwxgmac3_fpe_map_preemption_class(struct net_device *ndev, 355 + struct netlink_ext_ack *extack, u32 pclass) 356 + { 357 + u32 val, offset, count, preemptible_txqs = 0; 358 + struct stmmac_priv *priv = netdev_priv(ndev); 359 + int num_tc = netdev_get_num_tc(ndev); 360 + 361 + if (!num_tc) { 362 + /* Restore default TC:Queue mapping */ 363 + for (u32 i = 0; i < priv->plat->tx_queues_to_use; i++) { 364 + val = readl(priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(i)); 365 + writel(u32_replace_bits(val, i, XGMAC_Q2TCMAP), 366 + priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(i)); 367 + } 368 + } 369 + 370 + /* Synopsys Databook: 371 + * "All Queues within a traffic class are selected in a round robin 372 + * fashion (when packets are available) when the traffic class is 373 + * selected by the scheduler for packet transmission. This is true for 374 + * any of the scheduling algorithms." 375 + */ 376 + for (u32 tc = 0; tc < num_tc; tc++) { 377 + count = ndev->tc_to_txq[tc].count; 378 + offset = ndev->tc_to_txq[tc].offset; 379 + 380 + if (pclass & BIT(tc)) 381 + preemptible_txqs |= GENMASK(offset + count - 1, offset); 382 + 383 + for (u32 i = 0; i < count; i++) { 384 + val = readl(priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(offset + i)); 385 + writel(u32_replace_bits(val, tc, XGMAC_Q2TCMAP), 386 + priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(offset + i)); 387 + } 388 + } 389 + 390 + val = readl(priv->ioaddr + XGMAC_MTL_FPE_CTRL_STS); 391 + writel(u32_replace_bits(val, preemptible_txqs, FPE_MTL_PREEMPTION_CLASS), 392 + priv->ioaddr + XGMAC_MTL_FPE_CTRL_STS); 393 + 394 + return 0; 395 + } 396 + 397 + const struct stmmac_fpe_reg dwmac5_fpe_reg = { 398 + .mac_fpe_reg = GMAC5_MAC_FPE_CTRL_STS, 399 + .mtl_fpe_reg = GMAC5_MTL_FPE_CTRL_STS, 400 + .rxq_ctrl1_reg = GMAC_RXQ_CTRL1, 401 + .fprq_mask = GMAC_RXQCTRL_FPRQ, 402 + .int_en_reg = GMAC_INT_EN, 403 + .int_en_bit = GMAC_INT_FPE_EN, 404 + }; 405 + 406 + const struct stmmac_fpe_reg dwxgmac3_fpe_reg = { 407 + .mac_fpe_reg = XGMAC_MAC_FPE_CTRL_STS, 408 + .mtl_fpe_reg = XGMAC_MTL_FPE_CTRL_STS, 409 + .rxq_ctrl1_reg = XGMAC_RXQ_CTRL1, 410 + .fprq_mask = XGMAC_FPRQ, 411 + .int_en_reg = XGMAC_INT_EN, 412 + .int_en_bit = XGMAC_FPEIE, 413 + };
+33
drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2024 Furong Xu <0x1207@gmail.com> 4 + * stmmac FPE(802.3 Qbu) handling 5 + */ 6 + #ifndef _STMMAC_FPE_H_ 7 + #define _STMMAC_FPE_H_ 8 + 9 + #include <linux/types.h> 10 + #include <linux/netdevice.h> 11 + 12 + #define STMMAC_FPE_MM_MAX_VERIFY_RETRIES 3 13 + #define STMMAC_FPE_MM_MAX_VERIFY_TIME_MS 128 14 + 15 + struct stmmac_priv; 16 + 17 + void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up); 18 + bool stmmac_fpe_supported(struct stmmac_priv *priv); 19 + void stmmac_fpe_init(struct stmmac_priv *priv); 20 + void stmmac_fpe_apply(struct stmmac_priv *priv); 21 + void stmmac_fpe_irq_status(struct stmmac_priv *priv); 22 + int stmmac_fpe_get_add_frag_size(struct stmmac_priv *priv); 23 + void stmmac_fpe_set_add_frag_size(struct stmmac_priv *priv, u32 add_frag_size); 24 + 25 + int dwmac5_fpe_map_preemption_class(struct net_device *ndev, 26 + struct netlink_ext_ack *extack, u32 pclass); 27 + int dwxgmac3_fpe_map_preemption_class(struct net_device *ndev, 28 + struct netlink_ext_ack *extack, u32 pclass); 29 + 30 + extern const struct stmmac_fpe_reg dwmac5_fpe_reg; 31 + extern const struct stmmac_fpe_reg dwxgmac3_fpe_reg; 32 + 33 + #endif
+8 -157
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 43 43 #include <net/pkt_cls.h> 44 44 #include <net/xdp_sock_drv.h> 45 45 #include "stmmac_ptp.h" 46 + #include "stmmac_fpe.h" 46 47 #include "stmmac.h" 47 48 #include "stmmac_xdp.h" 48 49 #include <linux/reset.h> ··· 967 966 /* Nothing to do, xpcs_config() handles everything */ 968 967 } 969 968 970 - static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up) 971 - { 972 - struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 973 - unsigned long flags; 974 - 975 - timer_shutdown_sync(&fpe_cfg->verify_timer); 976 - 977 - spin_lock_irqsave(&fpe_cfg->lock, flags); 978 - 979 - if (is_up && fpe_cfg->pmac_enabled) { 980 - /* VERIFY process requires pmac enabled when NIC comes up */ 981 - stmmac_fpe_configure(priv, priv->ioaddr, fpe_cfg, 982 - priv->plat->tx_queues_to_use, 983 - priv->plat->rx_queues_to_use, 984 - false, true); 985 - 986 - /* New link => maybe new partner => new verification process */ 987 - stmmac_fpe_apply(priv); 988 - } else { 989 - /* No link => turn off EFPE */ 990 - stmmac_fpe_configure(priv, priv->ioaddr, fpe_cfg, 991 - priv->plat->tx_queues_to_use, 992 - priv->plat->rx_queues_to_use, 993 - false, false); 994 - } 995 - 996 - spin_unlock_irqrestore(&fpe_cfg->lock, flags); 997 - } 998 - 999 969 static void stmmac_mac_link_down(struct phylink_config *config, 1000 970 unsigned int mode, phy_interface_t interface) 1001 971 { ··· 978 1006 priv->eee_enabled = stmmac_eee_init(priv); 979 1007 stmmac_set_eee_pls(priv, priv->hw, false); 980 1008 981 - if (priv->dma_cap.fpesel) 1009 + if (stmmac_fpe_supported(priv)) 982 1010 stmmac_fpe_link_state_handle(priv, false); 983 1011 } 984 1012 ··· 1092 1120 stmmac_set_eee_pls(priv, priv->hw, true); 1093 1121 } 1094 1122 1095 - if (priv->dma_cap.fpesel) 1123 + if (stmmac_fpe_supported(priv)) 1096 1124 stmmac_fpe_link_state_handle(priv, true); 1097 1125 1098 1126 if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) ··· 4040 4068 4041 4069 stmmac_release_ptp(priv); 4042 4070 4043 - if (priv->dma_cap.fpesel) 4071 + if (stmmac_fpe_supported(priv)) 4044 4072 timer_shutdown_sync(&priv->fpe_cfg.verify_timer); 4045 4073 4046 4074 pm_runtime_put(priv->device); ··· 5937 5965 return 0; 5938 5966 } 5939 5967 5940 - static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status) 5941 - { 5942 - struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 5943 - 5944 - /* This is interrupt context, just spin_lock() */ 5945 - spin_lock(&fpe_cfg->lock); 5946 - 5947 - if (!fpe_cfg->pmac_enabled || status == FPE_EVENT_UNKNOWN) 5948 - goto unlock_out; 5949 - 5950 - /* LP has sent verify mPacket */ 5951 - if ((status & FPE_EVENT_RVER) == FPE_EVENT_RVER) 5952 - stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg, 5953 - MPACKET_RESPONSE); 5954 - 5955 - /* Local has sent verify mPacket */ 5956 - if ((status & FPE_EVENT_TVER) == FPE_EVENT_TVER && 5957 - fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED) 5958 - fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING; 5959 - 5960 - /* LP has sent response mPacket */ 5961 - if ((status & FPE_EVENT_RRSP) == FPE_EVENT_RRSP && 5962 - fpe_cfg->status == ETHTOOL_MM_VERIFY_STATUS_VERIFYING) 5963 - fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED; 5964 - 5965 - unlock_out: 5966 - spin_unlock(&fpe_cfg->lock); 5967 - } 5968 - 5969 5968 static void stmmac_common_interrupt(struct stmmac_priv *priv) 5970 5969 { 5971 5970 u32 rx_cnt = priv->plat->rx_queues_to_use; ··· 5955 6012 stmmac_est_irq_status(priv, priv, priv->dev, 5956 6013 &priv->xstats, tx_cnt); 5957 6014 5958 - if (priv->dma_cap.fpesel) { 5959 - int status = stmmac_fpe_irq_status(priv, priv->ioaddr, 5960 - priv->dev); 5961 - 5962 - stmmac_fpe_event_status(priv, status); 5963 - } 6015 + if (stmmac_fpe_supported(priv)) 6016 + stmmac_fpe_irq_status(priv); 5964 6017 5965 6018 /* To handle GMAC own interrupts */ 5966 6019 if ((priv->plat->has_gmac) || xmac) { ··· 7288 7349 return ret; 7289 7350 } 7290 7351 7291 - /** 7292 - * stmmac_fpe_verify_timer - Timer for MAC Merge verification 7293 - * @t: timer_list struct containing private info 7294 - * 7295 - * Verify the MAC Merge capability in the local TX direction, by 7296 - * transmitting Verify mPackets up to 3 times. Wait until link 7297 - * partner responds with a Response mPacket, otherwise fail. 7298 - */ 7299 - static void stmmac_fpe_verify_timer(struct timer_list *t) 7300 - { 7301 - struct stmmac_fpe_cfg *fpe_cfg = from_timer(fpe_cfg, t, verify_timer); 7302 - struct stmmac_priv *priv = container_of(fpe_cfg, struct stmmac_priv, 7303 - fpe_cfg); 7304 - unsigned long flags; 7305 - bool rearm = false; 7306 - 7307 - spin_lock_irqsave(&fpe_cfg->lock, flags); 7308 - 7309 - switch (fpe_cfg->status) { 7310 - case ETHTOOL_MM_VERIFY_STATUS_INITIAL: 7311 - case ETHTOOL_MM_VERIFY_STATUS_VERIFYING: 7312 - if (fpe_cfg->verify_retries != 0) { 7313 - stmmac_fpe_send_mpacket(priv, priv->ioaddr, 7314 - fpe_cfg, MPACKET_VERIFY); 7315 - rearm = true; 7316 - } else { 7317 - fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_FAILED; 7318 - } 7319 - 7320 - fpe_cfg->verify_retries--; 7321 - break; 7322 - 7323 - case ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED: 7324 - stmmac_fpe_configure(priv, priv->ioaddr, fpe_cfg, 7325 - priv->plat->tx_queues_to_use, 7326 - priv->plat->rx_queues_to_use, 7327 - true, true); 7328 - break; 7329 - 7330 - default: 7331 - break; 7332 - } 7333 - 7334 - if (rearm) { 7335 - mod_timer(&fpe_cfg->verify_timer, 7336 - jiffies + msecs_to_jiffies(fpe_cfg->verify_time)); 7337 - } 7338 - 7339 - spin_unlock_irqrestore(&fpe_cfg->lock, flags); 7340 - } 7341 - 7342 - static void stmmac_fpe_verify_timer_arm(struct stmmac_fpe_cfg *fpe_cfg) 7343 - { 7344 - if (fpe_cfg->pmac_enabled && fpe_cfg->tx_enabled && 7345 - fpe_cfg->verify_enabled && 7346 - fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_FAILED && 7347 - fpe_cfg->status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED) { 7348 - timer_setup(&fpe_cfg->verify_timer, stmmac_fpe_verify_timer, 0); 7349 - mod_timer(&fpe_cfg->verify_timer, jiffies); 7350 - } 7351 - } 7352 - 7353 - void stmmac_fpe_apply(struct stmmac_priv *priv) 7354 - { 7355 - struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; 7356 - 7357 - /* If verification is disabled, configure FPE right away. 7358 - * Otherwise let the timer code do it. 7359 - */ 7360 - if (!fpe_cfg->verify_enabled) { 7361 - stmmac_fpe_configure(priv, priv->ioaddr, fpe_cfg, 7362 - priv->plat->tx_queues_to_use, 7363 - priv->plat->rx_queues_to_use, 7364 - fpe_cfg->tx_enabled, 7365 - fpe_cfg->pmac_enabled); 7366 - } else { 7367 - fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_INITIAL; 7368 - fpe_cfg->verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES; 7369 - 7370 - if (netif_running(priv->dev)) 7371 - stmmac_fpe_verify_timer_arm(fpe_cfg); 7372 - } 7373 - } 7374 - 7375 7352 static int stmmac_xdp_rx_timestamp(const struct xdp_md *_ctx, u64 *timestamp) 7376 7353 { 7377 7354 const struct stmmac_xdp_buff *ctx = (void *)_ctx; ··· 7566 7711 7567 7712 mutex_init(&priv->lock); 7568 7713 7569 - priv->fpe_cfg.verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES; 7570 - priv->fpe_cfg.verify_time = STMMAC_FPE_MM_MAX_VERIFY_TIME_MS; 7571 - priv->fpe_cfg.status = ETHTOOL_MM_VERIFY_STATUS_DISABLED; 7572 - timer_setup(&priv->fpe_cfg.verify_timer, stmmac_fpe_verify_timer, 0); 7573 - spin_lock_init(&priv->fpe_cfg.lock); 7714 + stmmac_fpe_init(priv); 7574 7715 7575 7716 /* If a specific clk_csr value is passed from the platform 7576 7717 * this means that the CSR Clock Range selection cannot be ··· 7741 7890 } 7742 7891 rtnl_unlock(); 7743 7892 7744 - if (priv->dma_cap.fpesel) 7893 + if (stmmac_fpe_supported(priv)) 7745 7894 timer_shutdown_sync(&priv->fpe_cfg.verify_timer); 7746 7895 7747 7896 priv->speed = SPEED_UNKNOWN;
+2 -2
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
··· 1290 1290 .setup_cls_u32 = tc_setup_cls_u32, 1291 1291 .setup_cbs = tc_setup_cbs, 1292 1292 .setup_cls = tc_setup_cls, 1293 - .setup_taprio = tc_setup_taprio_without_fpe, 1293 + .setup_taprio = tc_setup_taprio, 1294 1294 .setup_etf = tc_setup_etf, 1295 1295 .query_caps = tc_query_caps, 1296 - .setup_mqprio = tc_setup_mqprio_unimplemented, 1296 + .setup_mqprio = tc_setup_dwmac510_mqprio, 1297 1297 };