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

net: stmmac: Add support for Enterprise MAC version

Adds the support for Enterprise MAC IP version which is very similar to
XGMAC. It's so similar that we just need to check the device id and add
new speeds definitions and some minor callbacks.

Signed-off-by: Jose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jose Abreu and committed by
David S. Miller
4a4ccde0 8a880936

+173 -1
+7
drivers/net/ethernet/stmicro/stmmac/common.h
··· 34 34 #define DWMAC_CORE_5_00 0x50 35 35 #define DWMAC_CORE_5_10 0x51 36 36 #define DWXGMAC_CORE_2_10 0x21 37 + #define DWXLGMAC_CORE_2_00 0x20 38 + 39 + /* Device ID */ 40 + #define DWXGMAC_ID 0x76 41 + #define DWXLGMAC_ID 0x27 37 42 38 43 #define STMMAC_CHAN0 0 /* Always supported and default for all chips */ 39 44 ··· 470 465 unsigned int pcs; 471 466 unsigned int pmt; 472 467 unsigned int ps; 468 + unsigned int xlgmac; 473 469 }; 474 470 475 471 struct stmmac_rx_routing { ··· 482 476 int dwmac1000_setup(struct stmmac_priv *priv); 483 477 int dwmac4_setup(struct stmmac_priv *priv); 484 478 int dwxgmac2_setup(struct stmmac_priv *priv); 479 + int dwxlgmac2_setup(struct stmmac_priv *priv); 485 480 486 481 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], 487 482 unsigned int high, unsigned int low);
+99
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
··· 9 9 #include <linux/iopoll.h> 10 10 #include "stmmac.h" 11 11 #include "stmmac_ptp.h" 12 + #include "dwxlgmac2.h" 12 13 #include "dwxgmac2.h" 13 14 14 15 static void dwxgmac2_core_init(struct mac_device_info *hw, ··· 1486 1485 .fpe_configure = dwxgmac3_fpe_configure, 1487 1486 }; 1488 1487 1488 + static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode, 1489 + u32 queue) 1490 + { 1491 + void __iomem *ioaddr = hw->pcsr; 1492 + u32 value; 1493 + 1494 + value = readl(ioaddr + XLGMAC_RXQ_ENABLE_CTRL0) & ~XGMAC_RXQEN(queue); 1495 + if (mode == MTL_QUEUE_AVB) 1496 + value |= 0x1 << XGMAC_RXQEN_SHIFT(queue); 1497 + else if (mode == MTL_QUEUE_DCB) 1498 + value |= 0x2 << XGMAC_RXQEN_SHIFT(queue); 1499 + writel(value, ioaddr + XLGMAC_RXQ_ENABLE_CTRL0); 1500 + } 1501 + 1502 + const struct stmmac_ops dwxlgmac2_ops = { 1503 + .core_init = dwxgmac2_core_init, 1504 + .set_mac = dwxgmac2_set_mac, 1505 + .rx_ipc = dwxgmac2_rx_ipc, 1506 + .rx_queue_enable = dwxlgmac2_rx_queue_enable, 1507 + .rx_queue_prio = dwxgmac2_rx_queue_prio, 1508 + .tx_queue_prio = dwxgmac2_tx_queue_prio, 1509 + .rx_queue_routing = NULL, 1510 + .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms, 1511 + .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms, 1512 + .set_mtl_tx_queue_weight = dwxgmac2_set_mtl_tx_queue_weight, 1513 + .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma, 1514 + .config_cbs = dwxgmac2_config_cbs, 1515 + .dump_regs = dwxgmac2_dump_regs, 1516 + .host_irq_status = dwxgmac2_host_irq_status, 1517 + .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status, 1518 + .flow_ctrl = dwxgmac2_flow_ctrl, 1519 + .pmt = dwxgmac2_pmt, 1520 + .set_umac_addr = dwxgmac2_set_umac_addr, 1521 + .get_umac_addr = dwxgmac2_get_umac_addr, 1522 + .set_eee_mode = dwxgmac2_set_eee_mode, 1523 + .reset_eee_mode = dwxgmac2_reset_eee_mode, 1524 + .set_eee_timer = dwxgmac2_set_eee_timer, 1525 + .set_eee_pls = dwxgmac2_set_eee_pls, 1526 + .pcs_ctrl_ane = NULL, 1527 + .pcs_rane = NULL, 1528 + .pcs_get_adv_lp = NULL, 1529 + .debug = NULL, 1530 + .set_filter = dwxgmac2_set_filter, 1531 + .safety_feat_config = dwxgmac3_safety_feat_config, 1532 + .safety_feat_irq_status = dwxgmac3_safety_feat_irq_status, 1533 + .safety_feat_dump = dwxgmac3_safety_feat_dump, 1534 + .set_mac_loopback = dwxgmac2_set_mac_loopback, 1535 + .rss_configure = dwxgmac2_rss_configure, 1536 + .update_vlan_hash = dwxgmac2_update_vlan_hash, 1537 + .rxp_config = dwxgmac3_rxp_config, 1538 + .get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp, 1539 + .flex_pps_config = dwxgmac2_flex_pps_config, 1540 + .sarc_configure = dwxgmac2_sarc_configure, 1541 + .enable_vlan = dwxgmac2_enable_vlan, 1542 + .config_l3_filter = dwxgmac2_config_l3_filter, 1543 + .config_l4_filter = dwxgmac2_config_l4_filter, 1544 + .set_arp_offload = dwxgmac2_set_arp_offload, 1545 + .est_configure = dwxgmac3_est_configure, 1546 + .fpe_configure = dwxgmac3_fpe_configure, 1547 + }; 1548 + 1489 1549 int dwxgmac2_setup(struct stmmac_priv *priv) 1490 1550 { 1491 1551 struct mac_device_info *mac = priv->hw; ··· 1571 1509 mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000; 1572 1510 mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000; 1573 1511 mac->link.speed_mask = XGMAC_CONFIG_SS_MASK; 1512 + 1513 + mac->mii.addr = XGMAC_MDIO_ADDR; 1514 + mac->mii.data = XGMAC_MDIO_DATA; 1515 + mac->mii.addr_shift = 16; 1516 + mac->mii.addr_mask = GENMASK(20, 16); 1517 + mac->mii.reg_shift = 0; 1518 + mac->mii.reg_mask = GENMASK(15, 0); 1519 + mac->mii.clk_csr_shift = 19; 1520 + mac->mii.clk_csr_mask = GENMASK(21, 19); 1521 + 1522 + return 0; 1523 + } 1524 + 1525 + int dwxlgmac2_setup(struct stmmac_priv *priv) 1526 + { 1527 + struct mac_device_info *mac = priv->hw; 1528 + 1529 + dev_info(priv->device, "\tXLGMAC\n"); 1530 + 1531 + priv->dev->priv_flags |= IFF_UNICAST_FLT; 1532 + mac->pcsr = priv->ioaddr; 1533 + mac->multicast_filter_bins = priv->plat->multicast_filter_bins; 1534 + mac->unicast_filter_entries = priv->plat->unicast_filter_entries; 1535 + mac->mcast_bits_log2 = 0; 1536 + 1537 + if (mac->multicast_filter_bins) 1538 + mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); 1539 + 1540 + mac->link.duplex = 0; 1541 + mac->link.speed1000 = XLGMAC_CONFIG_SS_1000; 1542 + mac->link.speed2500 = XLGMAC_CONFIG_SS_2500; 1543 + mac->link.xgmii.speed10000 = XLGMAC_CONFIG_SS_10G; 1544 + mac->link.xlgmii.speed25000 = XLGMAC_CONFIG_SS_25G; 1545 + mac->link.xlgmii.speed40000 = XLGMAC_CONFIG_SS_40G; 1546 + mac->link.xlgmii.speed50000 = XLGMAC_CONFIG_SS_50G; 1547 + mac->link.xlgmii.speed100000 = XLGMAC_CONFIG_SS_100G; 1548 + mac->link.speed_mask = XLGMAC_CONFIG_SS; 1574 1549 1575 1550 mac->mii.addr = XGMAC_MDIO_ADDR; 1576 1551 mac->mii.data = XGMAC_MDIO_DATA;
+22
drivers/net/ethernet/stmicro/stmmac/dwxlgmac2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates. 4 + * Synopsys DesignWare XLGMAC definitions. 5 + */ 6 + 7 + #ifndef __STMMAC_DWXLGMAC2_H__ 8 + #define __STMMAC_DWXLGMAC2_H__ 9 + 10 + /* MAC Registers */ 11 + #define XLGMAC_CONFIG_SS GENMASK(30, 28) 12 + #define XLGMAC_CONFIG_SS_SHIFT 28 13 + #define XLGMAC_CONFIG_SS_40G (0x0 << XLGMAC_CONFIG_SS_SHIFT) 14 + #define XLGMAC_CONFIG_SS_25G (0x1 << XLGMAC_CONFIG_SS_SHIFT) 15 + #define XLGMAC_CONFIG_SS_50G (0x2 << XLGMAC_CONFIG_SS_SHIFT) 16 + #define XLGMAC_CONFIG_SS_100G (0x3 << XLGMAC_CONFIG_SS_SHIFT) 17 + #define XLGMAC_CONFIG_SS_10G (0x4 << XLGMAC_CONFIG_SS_SHIFT) 18 + #define XLGMAC_CONFIG_SS_2500 (0x6 << XLGMAC_CONFIG_SS_SHIFT) 19 + #define XLGMAC_CONFIG_SS_1000 (0x7 << XLGMAC_CONFIG_SS_SHIFT) 20 + #define XLGMAC_RXQ_ENABLE_CTRL0 0x00000140 21 + 22 + #endif /* __STMMAC_DWXLGMAC2_H__ */
+44 -1
drivers/net/ethernet/stmicro/stmmac/hwif.c
··· 23 23 return reg & GENMASK(7, 0); 24 24 } 25 25 26 + static u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 id_reg) 27 + { 28 + u32 reg = readl(priv->ioaddr + id_reg); 29 + 30 + if (!reg) { 31 + dev_info(priv->device, "Version ID not available\n"); 32 + return 0x0; 33 + } 34 + 35 + return (reg & GENMASK(15, 8)) >> 8; 36 + } 37 + 26 38 static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) 27 39 { 28 40 struct mac_device_info *mac = priv->hw; ··· 81 69 return 0; 82 70 } 83 71 72 + static int stmmac_dwxlgmac_quirks(struct stmmac_priv *priv) 73 + { 74 + priv->hw->xlgmac = true; 75 + return 0; 76 + } 77 + 84 78 static const struct stmmac_hwif_entry { 85 79 bool gmac; 86 80 bool gmac4; 87 81 bool xgmac; 88 82 u32 min_id; 83 + u32 dev_id; 89 84 const struct stmmac_regs_off regs; 90 85 const void *desc; 91 86 const void *dma; ··· 218 199 .gmac4 = false, 219 200 .xgmac = true, 220 201 .min_id = DWXGMAC_CORE_2_10, 202 + .dev_id = DWXGMAC_ID, 221 203 .regs = { 222 204 .ptp_off = PTP_XGMAC_OFFSET, 223 205 .mmc_off = MMC_XGMAC_OFFSET, ··· 232 212 .mmc = &dwxgmac_mmc_ops, 233 213 .setup = dwxgmac2_setup, 234 214 .quirks = NULL, 215 + }, { 216 + .gmac = false, 217 + .gmac4 = false, 218 + .xgmac = true, 219 + .min_id = DWXLGMAC_CORE_2_00, 220 + .dev_id = DWXLGMAC_ID, 221 + .regs = { 222 + .ptp_off = PTP_XGMAC_OFFSET, 223 + .mmc_off = MMC_XGMAC_OFFSET, 224 + }, 225 + .desc = &dwxgmac210_desc_ops, 226 + .dma = &dwxgmac210_dma_ops, 227 + .mac = &dwxlgmac2_ops, 228 + .hwtimestamp = &stmmac_ptp, 229 + .mode = NULL, 230 + .tc = &dwmac510_tc_ops, 231 + .mmc = &dwxgmac_mmc_ops, 232 + .setup = dwxlgmac2_setup, 233 + .quirks = stmmac_dwxlgmac_quirks, 235 234 }, 236 235 }; 237 236 ··· 262 223 const struct stmmac_hwif_entry *entry; 263 224 struct mac_device_info *mac; 264 225 bool needs_setup = true; 226 + u32 id, dev_id = 0; 265 227 int i, ret; 266 - u32 id; 267 228 268 229 if (needs_gmac) { 269 230 id = stmmac_get_id(priv, GMAC_VERSION); 270 231 } else if (needs_gmac4 || needs_xgmac) { 271 232 id = stmmac_get_id(priv, GMAC4_VERSION); 233 + if (needs_xgmac) 234 + dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); 272 235 } else { 273 236 id = 0; 274 237 } ··· 307 266 continue; 308 267 /* Use synopsys_id var because some setups can override this */ 309 268 if (priv->synopsys_id < entry->min_id) 269 + continue; 270 + if (needs_xgmac && (dev_id ^ entry->dev_id)) 310 271 continue; 311 272 312 273 /* Only use generic HW helpers if needed */
+1
drivers/net/ethernet/stmicro/stmmac/hwif.h
··· 605 605 extern const struct stmmac_ops dwmac510_ops; 606 606 extern const struct stmmac_tc_ops dwmac510_tc_ops; 607 607 extern const struct stmmac_ops dwxgmac210_ops; 608 + extern const struct stmmac_ops dwxlgmac2_ops; 608 609 extern const struct stmmac_dma_ops dwxgmac210_dma_ops; 609 610 extern const struct stmmac_desc_ops dwxgmac210_desc_ops; 610 611 extern const struct stmmac_mmc_ops dwmac_mmc_ops;