15f0456b4SJose Abreu // SPDX-License-Identifier: (GPL-2.0 OR MIT) 25f0456b4SJose Abreu /* 35f0456b4SJose Abreu * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates. 45f0456b4SJose Abreu * stmmac HW Interface Handling 55f0456b4SJose Abreu */ 65f0456b4SJose Abreu 75f0456b4SJose Abreu #include "common.h" 85f0456b4SJose Abreu #include "stmmac.h" 9758d5c73SJose Abreu #include "stmmac_ptp.h" 10c3f3b972SRohan G Thomas #include "stmmac_est.h" 115f0456b4SJose Abreu 125f0456b4SJose Abreu static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg) 135f0456b4SJose Abreu { 145f0456b4SJose Abreu u32 reg = readl(priv->ioaddr + id_reg); 155f0456b4SJose Abreu 165f0456b4SJose Abreu if (!reg) { 175f0456b4SJose Abreu dev_info(priv->device, "Version ID not available\n"); 185f0456b4SJose Abreu return 0x0; 195f0456b4SJose Abreu } 205f0456b4SJose Abreu 215f0456b4SJose Abreu dev_info(priv->device, "User ID: 0x%x, Synopsys ID: 0x%x\n", 225f0456b4SJose Abreu (unsigned int)(reg & GENMASK(15, 8)) >> 8, 235f0456b4SJose Abreu (unsigned int)(reg & GENMASK(7, 0))); 245f0456b4SJose Abreu return reg & GENMASK(7, 0); 255f0456b4SJose Abreu } 265f0456b4SJose Abreu 274a4ccde0SJose Abreu static u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 id_reg) 284a4ccde0SJose Abreu { 294a4ccde0SJose Abreu u32 reg = readl(priv->ioaddr + id_reg); 304a4ccde0SJose Abreu 314a4ccde0SJose Abreu if (!reg) { 324a4ccde0SJose Abreu dev_info(priv->device, "Version ID not available\n"); 334a4ccde0SJose Abreu return 0x0; 344a4ccde0SJose Abreu } 354a4ccde0SJose Abreu 364a4ccde0SJose Abreu return (reg & GENMASK(15, 8)) >> 8; 374a4ccde0SJose Abreu } 384a4ccde0SJose Abreu 395f0456b4SJose Abreu static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) 405f0456b4SJose Abreu { 415f0456b4SJose Abreu struct mac_device_info *mac = priv->hw; 425f0456b4SJose Abreu 435f0456b4SJose Abreu if (priv->chain_mode) { 445f0456b4SJose Abreu dev_info(priv->device, "Chain mode enabled\n"); 455f0456b4SJose Abreu priv->mode = STMMAC_CHAIN_MODE; 465f0456b4SJose Abreu mac->mode = &chain_mode_ops; 475f0456b4SJose Abreu } else { 485f0456b4SJose Abreu dev_info(priv->device, "Ring mode enabled\n"); 495f0456b4SJose Abreu priv->mode = STMMAC_RING_MODE; 505f0456b4SJose Abreu mac->mode = &ring_mode_ops; 515f0456b4SJose Abreu } 525f0456b4SJose Abreu } 535f0456b4SJose Abreu 545f0456b4SJose Abreu static int stmmac_dwmac1_quirks(struct stmmac_priv *priv) 555f0456b4SJose Abreu { 565f0456b4SJose Abreu struct mac_device_info *mac = priv->hw; 575f0456b4SJose Abreu 585f0456b4SJose Abreu if (priv->plat->enh_desc) { 595f0456b4SJose Abreu dev_info(priv->device, "Enhanced/Alternate descriptors\n"); 605f0456b4SJose Abreu 615f0456b4SJose Abreu /* GMAC older than 3.50 has no extended descriptors */ 625f0456b4SJose Abreu if (priv->synopsys_id >= DWMAC_CORE_3_50) { 635f0456b4SJose Abreu dev_info(priv->device, "Enabled extended descriptors\n"); 645f0456b4SJose Abreu priv->extend_desc = 1; 655f0456b4SJose Abreu } else { 665f0456b4SJose Abreu dev_warn(priv->device, "Extended descriptors not supported\n"); 675f0456b4SJose Abreu } 685f0456b4SJose Abreu 695f0456b4SJose Abreu mac->desc = &enh_desc_ops; 705f0456b4SJose Abreu } else { 715f0456b4SJose Abreu dev_info(priv->device, "Normal descriptors\n"); 725f0456b4SJose Abreu mac->desc = &ndesc_ops; 735f0456b4SJose Abreu } 745f0456b4SJose Abreu 755f0456b4SJose Abreu stmmac_dwmac_mode_quirk(priv); 765f0456b4SJose Abreu return 0; 775f0456b4SJose Abreu } 785f0456b4SJose Abreu 795f0456b4SJose Abreu static int stmmac_dwmac4_quirks(struct stmmac_priv *priv) 805f0456b4SJose Abreu { 815f0456b4SJose Abreu stmmac_dwmac_mode_quirk(priv); 825f0456b4SJose Abreu return 0; 835f0456b4SJose Abreu } 845f0456b4SJose Abreu 854a4ccde0SJose Abreu static int stmmac_dwxlgmac_quirks(struct stmmac_priv *priv) 864a4ccde0SJose Abreu { 874a4ccde0SJose Abreu priv->hw->xlgmac = true; 884a4ccde0SJose Abreu return 0; 894a4ccde0SJose Abreu } 904a4ccde0SJose Abreu 9110739ea3SShenwei Wang int stmmac_reset(struct stmmac_priv *priv, void __iomem *ioaddr) 9210739ea3SShenwei Wang { 9310739ea3SShenwei Wang struct plat_stmmacenet_data *plat = priv ? priv->plat : NULL; 9410739ea3SShenwei Wang 9510739ea3SShenwei Wang if (!priv) 9610739ea3SShenwei Wang return -EINVAL; 9710739ea3SShenwei Wang 9810739ea3SShenwei Wang if (plat && plat->fix_soc_reset) 9910739ea3SShenwei Wang return plat->fix_soc_reset(plat, ioaddr); 10010739ea3SShenwei Wang 10110739ea3SShenwei Wang return stmmac_do_callback(priv, dma, reset, ioaddr); 10210739ea3SShenwei Wang } 10310739ea3SShenwei Wang 1045f0456b4SJose Abreu static const struct stmmac_hwif_entry { 1055f0456b4SJose Abreu bool gmac; 1065f0456b4SJose Abreu bool gmac4; 10748ae5554SJose Abreu bool xgmac; 1085f0456b4SJose Abreu u32 min_id; 1094a4ccde0SJose Abreu u32 dev_id; 110758d5c73SJose Abreu const struct stmmac_regs_off regs; 1115f0456b4SJose Abreu const void *desc; 1125f0456b4SJose Abreu const void *dma; 1135f0456b4SJose Abreu const void *mac; 1145f0456b4SJose Abreu const void *hwtimestamp; 1155f0456b4SJose Abreu const void *mode; 1164dbbe8ddSJose Abreu const void *tc; 1173b1dd2c5SJose Abreu const void *mmc; 118c3f3b972SRohan G Thomas const void *est; 1195f0456b4SJose Abreu int (*setup)(struct stmmac_priv *priv); 1205f0456b4SJose Abreu int (*quirks)(struct stmmac_priv *priv); 1215f0456b4SJose Abreu } stmmac_hw[] = { 1225f0456b4SJose Abreu /* NOTE: New HW versions shall go to the end of this table */ 1235f0456b4SJose Abreu { 1245f0456b4SJose Abreu .gmac = false, 1255f0456b4SJose Abreu .gmac4 = false, 12648ae5554SJose Abreu .xgmac = false, 1275f0456b4SJose Abreu .min_id = 0, 128758d5c73SJose Abreu .regs = { 129758d5c73SJose Abreu .ptp_off = PTP_GMAC3_X_OFFSET, 130758d5c73SJose Abreu .mmc_off = MMC_GMAC3_X_OFFSET, 131758d5c73SJose Abreu }, 1325f0456b4SJose Abreu .desc = NULL, 1335f0456b4SJose Abreu .dma = &dwmac100_dma_ops, 1345f0456b4SJose Abreu .mac = &dwmac100_ops, 1355f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 1365f0456b4SJose Abreu .mode = NULL, 1374dbbe8ddSJose Abreu .tc = NULL, 1383b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 1395f0456b4SJose Abreu .setup = dwmac100_setup, 1405f0456b4SJose Abreu .quirks = stmmac_dwmac1_quirks, 1415f0456b4SJose Abreu }, { 1425f0456b4SJose Abreu .gmac = true, 1435f0456b4SJose Abreu .gmac4 = false, 14448ae5554SJose Abreu .xgmac = false, 1455f0456b4SJose Abreu .min_id = 0, 146758d5c73SJose Abreu .regs = { 147758d5c73SJose Abreu .ptp_off = PTP_GMAC3_X_OFFSET, 148758d5c73SJose Abreu .mmc_off = MMC_GMAC3_X_OFFSET, 149758d5c73SJose Abreu }, 1505f0456b4SJose Abreu .desc = NULL, 1515f0456b4SJose Abreu .dma = &dwmac1000_dma_ops, 1525f0456b4SJose Abreu .mac = &dwmac1000_ops, 1535f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 1545f0456b4SJose Abreu .mode = NULL, 1554dbbe8ddSJose Abreu .tc = NULL, 1563b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 1575f0456b4SJose Abreu .setup = dwmac1000_setup, 1585f0456b4SJose Abreu .quirks = stmmac_dwmac1_quirks, 1595f0456b4SJose Abreu }, { 1605f0456b4SJose Abreu .gmac = false, 1615f0456b4SJose Abreu .gmac4 = true, 16248ae5554SJose Abreu .xgmac = false, 1635f0456b4SJose Abreu .min_id = 0, 164758d5c73SJose Abreu .regs = { 165758d5c73SJose Abreu .ptp_off = PTP_GMAC4_OFFSET, 166758d5c73SJose Abreu .mmc_off = MMC_GMAC4_OFFSET, 167c3f3b972SRohan G Thomas .est_off = EST_GMAC4_OFFSET, 168758d5c73SJose Abreu }, 1695f0456b4SJose Abreu .desc = &dwmac4_desc_ops, 1705f0456b4SJose Abreu .dma = &dwmac4_dma_ops, 1715f0456b4SJose Abreu .mac = &dwmac4_ops, 1725f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 1735f0456b4SJose Abreu .mode = NULL, 174*195e4f40SFurong Xu .tc = &dwmac4_tc_ops, 1753b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 176c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 1775f0456b4SJose Abreu .setup = dwmac4_setup, 1785f0456b4SJose Abreu .quirks = stmmac_dwmac4_quirks, 1795f0456b4SJose Abreu }, { 1805f0456b4SJose Abreu .gmac = false, 1815f0456b4SJose Abreu .gmac4 = true, 18248ae5554SJose Abreu .xgmac = false, 1835f0456b4SJose Abreu .min_id = DWMAC_CORE_4_00, 184758d5c73SJose Abreu .regs = { 185758d5c73SJose Abreu .ptp_off = PTP_GMAC4_OFFSET, 186758d5c73SJose Abreu .mmc_off = MMC_GMAC4_OFFSET, 187c3f3b972SRohan G Thomas .est_off = EST_GMAC4_OFFSET, 188758d5c73SJose Abreu }, 1895f0456b4SJose Abreu .desc = &dwmac4_desc_ops, 1905f0456b4SJose Abreu .dma = &dwmac4_dma_ops, 1915f0456b4SJose Abreu .mac = &dwmac410_ops, 1925f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 1935f0456b4SJose Abreu .mode = &dwmac4_ring_mode_ops, 194cc577b01SJose Abreu .tc = &dwmac510_tc_ops, 1953b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 196c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 1975f0456b4SJose Abreu .setup = dwmac4_setup, 1985f0456b4SJose Abreu .quirks = NULL, 1995f0456b4SJose Abreu }, { 2005f0456b4SJose Abreu .gmac = false, 2015f0456b4SJose Abreu .gmac4 = true, 20248ae5554SJose Abreu .xgmac = false, 2035f0456b4SJose Abreu .min_id = DWMAC_CORE_4_10, 204758d5c73SJose Abreu .regs = { 205758d5c73SJose Abreu .ptp_off = PTP_GMAC4_OFFSET, 206758d5c73SJose Abreu .mmc_off = MMC_GMAC4_OFFSET, 207c3f3b972SRohan G Thomas .est_off = EST_GMAC4_OFFSET, 208758d5c73SJose Abreu }, 2095f0456b4SJose Abreu .desc = &dwmac4_desc_ops, 2105f0456b4SJose Abreu .dma = &dwmac410_dma_ops, 2115f0456b4SJose Abreu .mac = &dwmac410_ops, 2125f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 2135f0456b4SJose Abreu .mode = &dwmac4_ring_mode_ops, 214cc577b01SJose Abreu .tc = &dwmac510_tc_ops, 2153b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 216c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 2175f0456b4SJose Abreu .setup = dwmac4_setup, 2185f0456b4SJose Abreu .quirks = NULL, 2195f0456b4SJose Abreu }, { 2205f0456b4SJose Abreu .gmac = false, 2215f0456b4SJose Abreu .gmac4 = true, 22248ae5554SJose Abreu .xgmac = false, 2235f0456b4SJose Abreu .min_id = DWMAC_CORE_5_10, 224758d5c73SJose Abreu .regs = { 225758d5c73SJose Abreu .ptp_off = PTP_GMAC4_OFFSET, 226758d5c73SJose Abreu .mmc_off = MMC_GMAC4_OFFSET, 22790d07e36SKurt Kanzenbach .est_off = EST_GMAC4_OFFSET, 228758d5c73SJose Abreu }, 2295f0456b4SJose Abreu .desc = &dwmac4_desc_ops, 2305f0456b4SJose Abreu .dma = &dwmac410_dma_ops, 2315f0456b4SJose Abreu .mac = &dwmac510_ops, 2325f0456b4SJose Abreu .hwtimestamp = &stmmac_ptp, 2335f0456b4SJose Abreu .mode = &dwmac4_ring_mode_ops, 2344dbbe8ddSJose Abreu .tc = &dwmac510_tc_ops, 2353b1dd2c5SJose Abreu .mmc = &dwmac_mmc_ops, 236c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 2375f0456b4SJose Abreu .setup = dwmac4_setup, 2385f0456b4SJose Abreu .quirks = NULL, 23948ae5554SJose Abreu }, { 24048ae5554SJose Abreu .gmac = false, 24148ae5554SJose Abreu .gmac4 = false, 24248ae5554SJose Abreu .xgmac = true, 24348ae5554SJose Abreu .min_id = DWXGMAC_CORE_2_10, 2444a4ccde0SJose Abreu .dev_id = DWXGMAC_ID, 24548ae5554SJose Abreu .regs = { 2464bb7aff9SJose Abreu .ptp_off = PTP_XGMAC_OFFSET, 247b6cdf09fSJose Abreu .mmc_off = MMC_XGMAC_OFFSET, 248c3f3b972SRohan G Thomas .est_off = EST_XGMAC_OFFSET, 24948ae5554SJose Abreu }, 250874dfb65SJose Abreu .desc = &dwxgmac210_desc_ops, 251d6ddfacdSJose Abreu .dma = &dwxgmac210_dma_ops, 2522142754fSJose Abreu .mac = &dwxgmac210_ops, 2534bb7aff9SJose Abreu .hwtimestamp = &stmmac_ptp, 25448ae5554SJose Abreu .mode = NULL, 255*195e4f40SFurong Xu .tc = &dwxgmac_tc_ops, 256b6cdf09fSJose Abreu .mmc = &dwxgmac_mmc_ops, 257c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 2582142754fSJose Abreu .setup = dwxgmac2_setup, 25948ae5554SJose Abreu .quirks = NULL, 2604a4ccde0SJose Abreu }, { 2614a4ccde0SJose Abreu .gmac = false, 2624a4ccde0SJose Abreu .gmac4 = false, 2634a4ccde0SJose Abreu .xgmac = true, 2644a4ccde0SJose Abreu .min_id = DWXLGMAC_CORE_2_00, 2654a4ccde0SJose Abreu .dev_id = DWXLGMAC_ID, 2664a4ccde0SJose Abreu .regs = { 2674a4ccde0SJose Abreu .ptp_off = PTP_XGMAC_OFFSET, 2684a4ccde0SJose Abreu .mmc_off = MMC_XGMAC_OFFSET, 269c3f3b972SRohan G Thomas .est_off = EST_XGMAC_OFFSET, 2704a4ccde0SJose Abreu }, 2714a4ccde0SJose Abreu .desc = &dwxgmac210_desc_ops, 2724a4ccde0SJose Abreu .dma = &dwxgmac210_dma_ops, 2734a4ccde0SJose Abreu .mac = &dwxlgmac2_ops, 2744a4ccde0SJose Abreu .hwtimestamp = &stmmac_ptp, 2754a4ccde0SJose Abreu .mode = NULL, 276*195e4f40SFurong Xu .tc = &dwxgmac_tc_ops, 2774a4ccde0SJose Abreu .mmc = &dwxgmac_mmc_ops, 278c3f3b972SRohan G Thomas .est = &dwmac510_est_ops, 2794a4ccde0SJose Abreu .setup = dwxlgmac2_setup, 2804a4ccde0SJose Abreu .quirks = stmmac_dwxlgmac_quirks, 28148ae5554SJose Abreu }, 2825f0456b4SJose Abreu }; 2835f0456b4SJose Abreu 2845f0456b4SJose Abreu int stmmac_hwif_init(struct stmmac_priv *priv) 2855f0456b4SJose Abreu { 28648ae5554SJose Abreu bool needs_xgmac = priv->plat->has_xgmac; 2875f0456b4SJose Abreu bool needs_gmac4 = priv->plat->has_gmac4; 2885f0456b4SJose Abreu bool needs_gmac = priv->plat->has_gmac; 2895f0456b4SJose Abreu const struct stmmac_hwif_entry *entry; 2905f0456b4SJose Abreu struct mac_device_info *mac; 291eb38401cSJose Abreu bool needs_setup = true; 2924a4ccde0SJose Abreu u32 id, dev_id = 0; 2935f0456b4SJose Abreu int i, ret; 2945f0456b4SJose Abreu 2955f0456b4SJose Abreu if (needs_gmac) { 2965f0456b4SJose Abreu id = stmmac_get_id(priv, GMAC_VERSION); 29748ae5554SJose Abreu } else if (needs_gmac4 || needs_xgmac) { 2985f0456b4SJose Abreu id = stmmac_get_id(priv, GMAC4_VERSION); 2994a4ccde0SJose Abreu if (needs_xgmac) 3004a4ccde0SJose Abreu dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); 301eb38401cSJose Abreu } else { 302eb38401cSJose Abreu id = 0; 3035f0456b4SJose Abreu } 3045f0456b4SJose Abreu 3055f0456b4SJose Abreu /* Save ID for later use */ 3065f0456b4SJose Abreu priv->synopsys_id = id; 3075f0456b4SJose Abreu 308758d5c73SJose Abreu /* Lets assume some safe values first */ 309758d5c73SJose Abreu priv->ptpaddr = priv->ioaddr + 310758d5c73SJose Abreu (needs_gmac4 ? PTP_GMAC4_OFFSET : PTP_GMAC3_X_OFFSET); 311758d5c73SJose Abreu priv->mmcaddr = priv->ioaddr + 312758d5c73SJose Abreu (needs_gmac4 ? MMC_GMAC4_OFFSET : MMC_GMAC3_X_OFFSET); 313c3f3b972SRohan G Thomas if (needs_gmac4) 314c3f3b972SRohan G Thomas priv->estaddr = priv->ioaddr + EST_GMAC4_OFFSET; 315c3f3b972SRohan G Thomas else if (needs_xgmac) 316c3f3b972SRohan G Thomas priv->estaddr = priv->ioaddr + EST_XGMAC_OFFSET; 317758d5c73SJose Abreu 3185f0456b4SJose Abreu /* Check for HW specific setup first */ 3195f0456b4SJose Abreu if (priv->plat->setup) { 320eb38401cSJose Abreu mac = priv->plat->setup(priv); 321eb38401cSJose Abreu needs_setup = false; 322eb38401cSJose Abreu } else { 323eb38401cSJose Abreu mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); 3245f0456b4SJose Abreu } 3255f0456b4SJose Abreu 3265f0456b4SJose Abreu if (!mac) 3275f0456b4SJose Abreu return -ENOMEM; 3285f0456b4SJose Abreu 3295f0456b4SJose Abreu /* Fallback to generic HW */ 3305f0456b4SJose Abreu for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) { 3315f0456b4SJose Abreu entry = &stmmac_hw[i]; 3325f0456b4SJose Abreu 3335f0456b4SJose Abreu if (needs_gmac ^ entry->gmac) 3345f0456b4SJose Abreu continue; 3355f0456b4SJose Abreu if (needs_gmac4 ^ entry->gmac4) 3365f0456b4SJose Abreu continue; 33748ae5554SJose Abreu if (needs_xgmac ^ entry->xgmac) 33848ae5554SJose Abreu continue; 339eb38401cSJose Abreu /* Use synopsys_id var because some setups can override this */ 340eb38401cSJose Abreu if (priv->synopsys_id < entry->min_id) 3415f0456b4SJose Abreu continue; 3424a4ccde0SJose Abreu if (needs_xgmac && (dev_id ^ entry->dev_id)) 3434a4ccde0SJose Abreu continue; 3445f0456b4SJose Abreu 345eb38401cSJose Abreu /* Only use generic HW helpers if needed */ 346eb38401cSJose Abreu mac->desc = mac->desc ? : entry->desc; 347eb38401cSJose Abreu mac->dma = mac->dma ? : entry->dma; 348eb38401cSJose Abreu mac->mac = mac->mac ? : entry->mac; 349eb38401cSJose Abreu mac->ptp = mac->ptp ? : entry->hwtimestamp; 350eb38401cSJose Abreu mac->mode = mac->mode ? : entry->mode; 351eb38401cSJose Abreu mac->tc = mac->tc ? : entry->tc; 3523b1dd2c5SJose Abreu mac->mmc = mac->mmc ? : entry->mmc; 353c3f3b972SRohan G Thomas mac->est = mac->est ? : entry->est; 3545f0456b4SJose Abreu 3555f0456b4SJose Abreu priv->hw = mac; 356758d5c73SJose Abreu priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off; 357758d5c73SJose Abreu priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off; 358c3f3b972SRohan G Thomas if (entry->est) 359c3f3b972SRohan G Thomas priv->estaddr = priv->ioaddr + entry->regs.est_off; 3605f0456b4SJose Abreu 3615f0456b4SJose Abreu /* Entry found */ 362eb38401cSJose Abreu if (needs_setup) { 3635f0456b4SJose Abreu ret = entry->setup(priv); 3645f0456b4SJose Abreu if (ret) 3655f0456b4SJose Abreu return ret; 366eb38401cSJose Abreu } 3675f0456b4SJose Abreu 3687cfde0afSJose Abreu /* Save quirks, if needed for posterior use */ 3697cfde0afSJose Abreu priv->hwif_quirks = entry->quirks; 3705f0456b4SJose Abreu return 0; 3715f0456b4SJose Abreu } 3725f0456b4SJose Abreu 3735f0456b4SJose Abreu dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", 3745f0456b4SJose Abreu id, needs_gmac, needs_gmac4); 3755f0456b4SJose Abreu return -EINVAL; 3765f0456b4SJose Abreu } 377