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-enetc-add-i-mx94-enetc-support'

Wei Fang says:

====================
net: enetc: Add i.MX94 ENETC support

i.MX94 NETC has two kinds of ENETCs, one is the same as i.MX95, which
can be used as a standalone network port. The other one is an internal
ENETC, it connects to the CPU port of NETC switch through the pseudo
MAC. Also, i.MX94 have multiple PTP Timers, which is different from
i.MX95. Any PTP Timer can be bound to a specified standalone ENETC by
the IERB ETBCR registers. Currently, this patch only add ENETC support
and Timer support for i.MX94. The switch will be added by a separate
patch set.

In addition, note that i.MX94 SoC is launched after i.MX95, its NETC
has a higher version, so the driver support is added after i.MX95.
====================

Link: https://patch.msgid.link/20251029013900.407583-1-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+355 -2
+1
Documentation/devicetree/bindings/net/fsl,enetc.yaml
··· 27 27 - const: fsl,enetc 28 28 - enum: 29 29 - pci1131,e101 30 + - pci1131,e110 30 31 31 32 reg: 32 33 maxItems: 1
+1
Documentation/devicetree/bindings/net/nxp,netc-blk-ctrl.yaml
··· 21 21 properties: 22 22 compatible: 23 23 enum: 24 + - nxp,imx94-netc-blk-ctrl 24 25 - nxp,imx95-netc-blk-ctrl 25 26 26 27 reg:
+27 -1
drivers/net/ethernet/freescale/enetc/enetc.c
··· 14 14 15 15 u32 enetc_port_mac_rd(struct enetc_si *si, u32 reg) 16 16 { 17 + /* ENETC with pseudo MAC does not have Ethernet MAC 18 + * port registers. 19 + */ 20 + if (enetc_is_pseudo_mac(si)) 21 + return 0; 22 + 17 23 return enetc_port_rd(&si->hw, reg); 18 24 } 19 25 EXPORT_SYMBOL_GPL(enetc_port_mac_rd); 20 26 21 27 void enetc_port_mac_wr(struct enetc_si *si, u32 reg, u32 val) 22 28 { 29 + if (enetc_is_pseudo_mac(si)) 30 + return; 31 + 23 32 enetc_port_wr(&si->hw, reg, val); 24 33 if (si->hw_features & ENETC_SI_F_QBU) 25 34 enetc_port_wr(&si->hw, reg + si->drvdata->pmac_offset, val); ··· 3376 3367 new_offloads |= ENETC_F_TX_TSTAMP; 3377 3368 break; 3378 3369 case HWTSTAMP_TX_ONESTEP_SYNC: 3379 - if (!enetc_si_is_pf(priv->si)) 3370 + if (!enetc_si_is_pf(priv->si) || 3371 + enetc_is_pseudo_mac(priv->si)) 3380 3372 return -EOPNOTSUPP; 3381 3373 3382 3374 new_offloads &= ~ENETC_F_TX_TSTAMP_MASK; ··· 3718 3708 .eth_ops = &enetc4_pf_ethtool_ops, 3719 3709 }; 3720 3710 3711 + static const struct enetc_drvdata enetc4_ppm_data = { 3712 + .sysclk_freq = ENETC_CLK_333M, 3713 + .tx_csum = true, 3714 + .max_frags = ENETC4_MAX_SKB_FRAGS, 3715 + .eth_ops = &enetc4_ppm_ethtool_ops, 3716 + }; 3717 + 3721 3718 static const struct enetc_drvdata enetc_vf_data = { 3722 3719 .sysclk_freq = ENETC_CLK_400M, 3723 3720 .max_frags = ENETC_MAX_SKB_FRAGS, ··· 3743 3726 { .revision = ENETC_REV_1_0, 3744 3727 .dev_id = ENETC_DEV_ID_VF, 3745 3728 .data = &enetc_vf_data, 3729 + }, 3730 + { 3731 + .revision = ENETC_REV_4_3, 3732 + .dev_id = NXP_ENETC_PPM_DEV_ID, 3733 + .data = &enetc4_ppm_data, 3734 + }, 3735 + { .revision = ENETC_REV_4_3, 3736 + .dev_id = NXP_ENETC_PF_DEV_ID, 3737 + .data = &enetc4_pf_data, 3746 3738 }, 3747 3739 }; 3748 3740
+8
drivers/net/ethernet/freescale/enetc/enetc.h
··· 273 273 #define ENETC_SI_F_QBV BIT(1) 274 274 #define ENETC_SI_F_QBU BIT(2) 275 275 #define ENETC_SI_F_LSO BIT(3) 276 + #define ENETC_SI_F_PPM BIT(4) /* pseudo MAC */ 276 277 277 278 struct enetc_drvdata { 278 279 u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */ ··· 361 360 default: 362 361 return -1; 363 362 } 363 + } 364 + 365 + static inline bool enetc_is_pseudo_mac(struct enetc_si *si) 366 + { 367 + return si->hw_features & ENETC_SI_F_PPM; 364 368 } 365 369 366 370 #define ENETC_MAX_NUM_TXQS 8 ··· 540 534 extern const struct ethtool_ops enetc_pf_ethtool_ops; 541 535 extern const struct ethtool_ops enetc4_pf_ethtool_ops; 542 536 extern const struct ethtool_ops enetc_vf_ethtool_ops; 537 + extern const struct ethtool_ops enetc4_ppm_ethtool_ops; 538 + 543 539 void enetc_set_ethtool_ops(struct net_device *ndev); 544 540 void enetc_mm_link_state_update(struct enetc_ndev_priv *priv, bool link); 545 541 void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);
+30
drivers/net/ethernet/freescale/enetc/enetc4_hw.h
··· 11 11 12 12 #define NXP_ENETC_VENDOR_ID 0x1131 13 13 #define NXP_ENETC_PF_DEV_ID 0xe101 14 + #define NXP_ENETC_PPM_DEV_ID 0xe110 14 15 15 16 /**********************Station interface registers************************/ 16 17 /* Station interface LSO segmentation flag mask register 0/1 */ ··· 116 115 #define PMCAPR_HD BIT(8) 117 116 #define PMCAPR_FP GENMASK(10, 9) 118 117 118 + /* Port capability register */ 119 + #define ENETC4_PCAPR 0x4000 120 + #define PCAPR_LINK_TYPE BIT(4) 121 + 119 122 /* Port configuration register */ 120 123 #define ENETC4_PCR 0x4010 121 124 #define PCR_HDR_FMT BIT(0) ··· 197 192 #define SSP_10M 1 198 193 #define SSP_1G 2 199 194 #define PM_IF_MODE_ENA BIT(15) 195 + 196 + /**********************ENETC Pseudo MAC port registers************************/ 197 + /* Port pseudo MAC receive octets counter (64-bit) */ 198 + #define ENETC4_PPMROCR 0x5080 199 + 200 + /* Port pseudo MAC receive unicast frame counter register (64-bit) */ 201 + #define ENETC4_PPMRUFCR 0x5088 202 + 203 + /* Port pseudo MAC receive multicast frame counter register (64-bit) */ 204 + #define ENETC4_PPMRMFCR 0x5090 205 + 206 + /* Port pseudo MAC receive broadcast frame counter register (64-bit) */ 207 + #define ENETC4_PPMRBFCR 0x5098 208 + 209 + /* Port pseudo MAC transmit octets counter (64-bit) */ 210 + #define ENETC4_PPMTOCR 0x50c0 211 + 212 + /* Port pseudo MAC transmit unicast frame counter register (64-bit) */ 213 + #define ENETC4_PPMTUFCR 0x50c8 214 + 215 + /* Port pseudo MAC transmit multicast frame counter register (64-bit) */ 216 + #define ENETC4_PPMTMFCR 0x50d0 217 + 218 + /* Port pseudo MAC transmit broadcast frame counter register (64-bit) */ 219 + #define ENETC4_PPMTBFCR 0x50d8 200 220 201 221 #endif
+15
drivers/net/ethernet/freescale/enetc/enetc4_pf.c
··· 41 41 pf->caps.mac_filter_num = val & PSIMAFCAPR_NUM_MAC_AFTE; 42 42 } 43 43 44 + static void enetc4_get_psi_hw_features(struct enetc_si *si) 45 + { 46 + struct enetc_hw *hw = &si->hw; 47 + u32 val; 48 + 49 + val = enetc_port_rd(hw, ENETC4_PCAPR); 50 + if (val & PCAPR_LINK_TYPE) 51 + si->hw_features |= ENETC_SI_F_PPM; 52 + } 53 + 44 54 static void enetc4_pf_set_si_primary_mac(struct enetc_hw *hw, int si, 45 55 const u8 *addr) 46 56 { ··· 287 277 pf->ops = &enetc4_pf_ops; 288 278 289 279 enetc4_get_port_caps(pf); 280 + enetc4_get_psi_hw_features(si); 290 281 291 282 return 0; 292 283 } ··· 599 588 struct enetc_ndev_priv *priv = netdev_priv(pf->si->ndev); 600 589 struct enetc_si *si = pf->si; 601 590 u32 val; 591 + 592 + if (enetc_is_pseudo_mac(si)) 593 + return; 602 594 603 595 val = enetc_port_mac_rd(si, ENETC4_PM_IF_MODE(0)); 604 596 val &= ~(PM_IF_MODE_IFMODE | PM_IF_MODE_ENA); ··· 1085 1071 1086 1072 static const struct pci_device_id enetc4_pf_id_table[] = { 1087 1073 { PCI_DEVICE(NXP_ENETC_VENDOR_ID, NXP_ENETC_PF_DEV_ID) }, 1074 + { PCI_DEVICE(NXP_ENETC_VENDOR_ID, NXP_ENETC_PPM_DEV_ID) }, 1088 1075 { 0, } /* End of table. */ 1089 1076 }; 1090 1077 MODULE_DEVICE_TABLE(pci, enetc4_pf_id_table);
+64
drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
··· 435 435 } 436 436 } 437 437 438 + static void enetc_ppm_mac_stats(struct enetc_si *si, 439 + struct ethtool_eth_mac_stats *s) 440 + { 441 + struct enetc_hw *hw = &si->hw; 442 + u64 rufcr, rmfcr, rbfcr; 443 + u64 tufcr, tmfcr, tbfcr; 444 + 445 + rufcr = enetc_port_rd64(hw, ENETC4_PPMRUFCR); 446 + rmfcr = enetc_port_rd64(hw, ENETC4_PPMRMFCR); 447 + rbfcr = enetc_port_rd64(hw, ENETC4_PPMRBFCR); 448 + 449 + tufcr = enetc_port_rd64(hw, ENETC4_PPMTUFCR); 450 + tmfcr = enetc_port_rd64(hw, ENETC4_PPMTMFCR); 451 + tbfcr = enetc_port_rd64(hw, ENETC4_PPMTBFCR); 452 + 453 + s->FramesTransmittedOK = tufcr + tmfcr + tbfcr; 454 + s->FramesReceivedOK = rufcr + rmfcr + rbfcr; 455 + s->OctetsTransmittedOK = enetc_port_rd64(hw, ENETC4_PPMTOCR); 456 + s->OctetsReceivedOK = enetc_port_rd64(hw, ENETC4_PPMROCR); 457 + s->MulticastFramesXmittedOK = tmfcr; 458 + s->BroadcastFramesXmittedOK = tbfcr; 459 + s->MulticastFramesReceivedOK = rmfcr; 460 + s->BroadcastFramesReceivedOK = rbfcr; 461 + } 462 + 463 + static void enetc_ppm_get_eth_mac_stats(struct net_device *ndev, 464 + struct ethtool_eth_mac_stats *mac_stats) 465 + { 466 + struct enetc_ndev_priv *priv = netdev_priv(ndev); 467 + 468 + switch (mac_stats->src) { 469 + case ETHTOOL_MAC_STATS_SRC_EMAC: 470 + enetc_ppm_mac_stats(priv->si, mac_stats); 471 + break; 472 + case ETHTOOL_MAC_STATS_SRC_PMAC: 473 + break; 474 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 475 + ethtool_aggregate_mac_stats(ndev, mac_stats); 476 + break; 477 + } 478 + } 479 + 438 480 static void enetc_get_eth_ctrl_stats(struct net_device *ndev, 439 481 struct ethtool_eth_ctrl_stats *ctrl_stats) 440 482 { ··· 936 894 case ENETC_REV_4_1: 937 895 devfn = PCI_DEVFN(24, 0); 938 896 break; 897 + case ENETC_REV_4_3: 898 + devfn = PCI_DEVFN(0, 1); 899 + break; 939 900 default: 940 901 return -1; 941 902 } ··· 1356 1311 .get_mm = enetc_get_mm, 1357 1312 .set_mm = enetc_set_mm, 1358 1313 .get_mm_stats = enetc_get_mm_stats, 1314 + }; 1315 + 1316 + const struct ethtool_ops enetc4_ppm_ethtool_ops = { 1317 + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1318 + ETHTOOL_COALESCE_MAX_FRAMES | 1319 + ETHTOOL_COALESCE_USE_ADAPTIVE_RX, 1320 + .get_eth_mac_stats = enetc_ppm_get_eth_mac_stats, 1321 + .get_rxnfc = enetc4_get_rxnfc, 1322 + .get_rxfh_key_size = enetc_get_rxfh_key_size, 1323 + .get_rxfh_indir_size = enetc_get_rxfh_indir_size, 1324 + .get_rxfh = enetc_get_rxfh, 1325 + .set_rxfh = enetc_set_rxfh, 1326 + .get_rxfh_fields = enetc_get_rxfh_fields, 1327 + .get_ringparam = enetc_get_ringparam, 1328 + .get_coalesce = enetc_get_coalesce, 1329 + .set_coalesce = enetc_set_coalesce, 1330 + .get_link_ksettings = enetc_get_link_ksettings, 1331 + .set_link_ksettings = enetc_set_link_ksettings, 1332 + .get_link = ethtool_op_get_link, 1359 1333 }; 1360 1334 1361 1335 const struct ethtool_ops enetc_vf_ethtool_ops = {
+1
drivers/net/ethernet/freescale/enetc/enetc_hw.h
··· 378 378 #define EIPBRR0_REVISION GENMASK(15, 0) 379 379 #define ENETC_REV_1_0 0x0100 380 380 #define ENETC_REV_4_1 0X0401 381 + #define ENETC_REV_4_3 0x0403 381 382 382 383 #define ENETC_G_EIPBRR1 0x0bfc 383 384 #define ENETC_G_EPFBLPR(n) (0xd00 + 4 * (n))
+4 -1
drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
··· 109 109 110 110 ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | 111 111 NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | 112 - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK | 112 + NETIF_F_HW_VLAN_CTAG_FILTER | 113 113 NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6 | 114 114 NETIF_F_GSO_UDP_L4; 115 115 ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM | ··· 132 132 ndev->hw_features |= NETIF_F_RXHASH; 133 133 ndev->features |= NETIF_F_RXHASH; 134 134 } 135 + 136 + if (!enetc_is_pseudo_mac(si)) 137 + ndev->hw_features |= NETIF_F_LOOPBACK; 135 138 136 139 /* TODO: currently, i.MX95 ENETC driver does not support advanced features */ 137 140 if (!is_enetc_rev1(si))
+204
drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
··· 47 47 #define PCS_PROT_SFI BIT(4) 48 48 #define PCS_PROT_10G_SXGMII BIT(6) 49 49 50 + #define IMX94_EXT_PIN_CONTROL 0x10 51 + #define MAC2_MAC3_SEL BIT(1) 52 + 53 + #define IMX94_NETC_LINK_CFG(a) (0x4c + (a) * 4) 54 + #define NETC_LINK_CFG_MII_PROT GENMASK(3, 0) 55 + #define NETC_LINK_CFG_IO_VAR GENMASK(19, 16) 56 + 50 57 /* NETC privileged register block register */ 51 58 #define PRB_NETCRR 0x100 52 59 #define NETCRR_SR BIT(0) ··· 66 59 /* NETC integrated endpoint register block register */ 67 60 #define IERB_EMDIOFAUXR 0x344 68 61 #define IERB_T0FAUXR 0x444 62 + #define IERB_ETBCR(a) (0x300c + 0x100 * (a)) 69 63 #define IERB_EFAUXR(a) (0x3044 + 0x100 * (a)) 70 64 #define IERB_VFAUXR(a) (0x4004 + 0x40 * (a)) 71 65 #define FAUXR_LDID GENMASK(3, 0) ··· 75 67 #define IMX95_ENETC0_BUS_DEVFN 0x0 76 68 #define IMX95_ENETC1_BUS_DEVFN 0x40 77 69 #define IMX95_ENETC2_BUS_DEVFN 0x80 70 + 71 + #define IMX94_ENETC0_BUS_DEVFN 0x100 72 + #define IMX94_ENETC1_BUS_DEVFN 0x140 73 + #define IMX94_ENETC2_BUS_DEVFN 0x180 74 + #define IMX94_TIMER0_BUS_DEVFN 0x1 75 + #define IMX94_TIMER1_BUS_DEVFN 0x101 76 + #define IMX94_TIMER2_BUS_DEVFN 0x181 77 + #define IMX94_ENETC0_LINK 3 78 + #define IMX94_ENETC1_LINK 4 79 + #define IMX94_ENETC2_LINK 5 80 + 81 + #define NETC_ENETC_ID(a) (a) 82 + #define NETC_TIMER_ID(a) (a) 78 83 79 84 /* Flags for different platforms */ 80 85 #define NETC_HAS_NETCMIX BIT(0) ··· 213 192 return 0; 214 193 } 215 194 195 + static int imx94_enetc_get_link_id(struct device_node *np) 196 + { 197 + int bus_devfn = netc_of_pci_get_bus_devfn(np); 198 + 199 + /* Parse ENETC link number */ 200 + switch (bus_devfn) { 201 + case IMX94_ENETC0_BUS_DEVFN: 202 + return IMX94_ENETC0_LINK; 203 + case IMX94_ENETC1_BUS_DEVFN: 204 + return IMX94_ENETC1_LINK; 205 + case IMX94_ENETC2_BUS_DEVFN: 206 + return IMX94_ENETC2_LINK; 207 + default: 208 + return -EINVAL; 209 + } 210 + } 211 + 212 + static int imx94_link_config(struct netc_blk_ctrl *priv, 213 + struct device_node *np, int link_id) 214 + { 215 + phy_interface_t interface; 216 + int mii_proto; 217 + u32 val; 218 + 219 + /* The node may be disabled and does not have a 'phy-mode' 220 + * or 'phy-connection-type' property. 221 + */ 222 + if (of_get_phy_mode(np, &interface)) 223 + return 0; 224 + 225 + mii_proto = netc_get_link_mii_protocol(interface); 226 + if (mii_proto < 0) 227 + return mii_proto; 228 + 229 + val = mii_proto & NETC_LINK_CFG_MII_PROT; 230 + if (val == MII_PROT_SERIAL) 231 + val = u32_replace_bits(val, IO_VAR_16FF_16G_SERDES, 232 + NETC_LINK_CFG_IO_VAR); 233 + 234 + netc_reg_write(priv->netcmix, IMX94_NETC_LINK_CFG(link_id), val); 235 + 236 + return 0; 237 + } 238 + 239 + static int imx94_enetc_link_config(struct netc_blk_ctrl *priv, 240 + struct device_node *np) 241 + { 242 + int link_id = imx94_enetc_get_link_id(np); 243 + 244 + if (link_id < 0) 245 + return link_id; 246 + 247 + return imx94_link_config(priv, np, link_id); 248 + } 249 + 250 + static int imx94_netcmix_init(struct platform_device *pdev) 251 + { 252 + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev); 253 + struct device_node *np = pdev->dev.of_node; 254 + u32 val; 255 + int err; 256 + 257 + for_each_child_of_node_scoped(np, child) { 258 + for_each_child_of_node_scoped(child, gchild) { 259 + if (!of_device_is_compatible(gchild, "pci1131,e101")) 260 + continue; 261 + 262 + err = imx94_enetc_link_config(priv, gchild); 263 + if (err) 264 + return err; 265 + } 266 + } 267 + 268 + /* ENETC 0 and switch port 2 share the same parallel interface. 269 + * Currently, the switch is not supported, so this interface is 270 + * used by ENETC 0 by default. 271 + */ 272 + val = netc_reg_read(priv->netcmix, IMX94_EXT_PIN_CONTROL); 273 + val |= MAC2_MAC3_SEL; 274 + netc_reg_write(priv->netcmix, IMX94_EXT_PIN_CONTROL, val); 275 + 276 + return 0; 277 + } 278 + 216 279 static bool netc_ierb_is_locked(struct netc_blk_ctrl *priv) 217 280 { 218 281 return !!(netc_reg_read(priv->prb, PRB_NETCRR) & NETCRR_LOCK); ··· 348 243 netc_reg_write(priv->ierb, IERB_VFAUXR(5), 6); 349 244 /* NETC TIMER */ 350 245 netc_reg_write(priv->ierb, IERB_T0FAUXR, 7); 246 + 247 + return 0; 248 + } 249 + 250 + static int imx94_get_enetc_id(struct device_node *np) 251 + { 252 + int bus_devfn = netc_of_pci_get_bus_devfn(np); 253 + 254 + /* Parse ENETC offset */ 255 + switch (bus_devfn) { 256 + case IMX94_ENETC0_BUS_DEVFN: 257 + return NETC_ENETC_ID(0); 258 + case IMX94_ENETC1_BUS_DEVFN: 259 + return NETC_ENETC_ID(1); 260 + case IMX94_ENETC2_BUS_DEVFN: 261 + return NETC_ENETC_ID(2); 262 + default: 263 + return -EINVAL; 264 + } 265 + } 266 + 267 + static int imx94_get_timer_id(struct device_node *np) 268 + { 269 + int bus_devfn = netc_of_pci_get_bus_devfn(np); 270 + 271 + /* Parse NETC PTP timer ID, the timer0 is on bus 0, 272 + * the timer 1 and timer2 is on bus 1. 273 + */ 274 + switch (bus_devfn) { 275 + case IMX94_TIMER0_BUS_DEVFN: 276 + return NETC_TIMER_ID(0); 277 + case IMX94_TIMER1_BUS_DEVFN: 278 + return NETC_TIMER_ID(1); 279 + case IMX94_TIMER2_BUS_DEVFN: 280 + return NETC_TIMER_ID(2); 281 + default: 282 + return -EINVAL; 283 + } 284 + } 285 + 286 + static int imx94_enetc_update_tid(struct netc_blk_ctrl *priv, 287 + struct device_node *np) 288 + { 289 + struct device *dev = &priv->pdev->dev; 290 + struct device_node *timer_np; 291 + int eid, tid; 292 + 293 + eid = imx94_get_enetc_id(np); 294 + if (eid < 0) { 295 + dev_err(dev, "Failed to get ENETC ID\n"); 296 + return eid; 297 + } 298 + 299 + timer_np = of_parse_phandle(np, "ptp-timer", 0); 300 + if (!timer_np) { 301 + /* If 'ptp-timer' is not present, the timer1 is the default 302 + * timer of all standalone ENETCs, which is on the same PCIe 303 + * bus as these ENETCs. 304 + */ 305 + tid = NETC_TIMER_ID(1); 306 + goto end; 307 + } 308 + 309 + tid = imx94_get_timer_id(timer_np); 310 + of_node_put(timer_np); 311 + if (tid < 0) { 312 + dev_err(dev, "Failed to get NETC Timer ID\n"); 313 + return tid; 314 + } 315 + 316 + end: 317 + netc_reg_write(priv->ierb, IERB_ETBCR(eid), tid); 318 + 319 + return 0; 320 + } 321 + 322 + static int imx94_ierb_init(struct platform_device *pdev) 323 + { 324 + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev); 325 + struct device_node *np = pdev->dev.of_node; 326 + int err; 327 + 328 + for_each_child_of_node_scoped(np, child) { 329 + for_each_child_of_node_scoped(child, gchild) { 330 + if (!of_device_is_compatible(gchild, "pci1131,e101")) 331 + continue; 332 + 333 + err = imx94_enetc_update_tid(priv, gchild); 334 + if (err) 335 + return err; 336 + } 337 + } 351 338 352 339 return 0; 353 340 } ··· 537 340 .ierb_init = imx95_ierb_init, 538 341 }; 539 342 343 + static const struct netc_devinfo imx94_devinfo = { 344 + .flags = NETC_HAS_NETCMIX, 345 + .netcmix_init = imx94_netcmix_init, 346 + .ierb_init = imx94_ierb_init, 347 + }; 348 + 540 349 static const struct of_device_id netc_blk_ctrl_match[] = { 541 350 { .compatible = "nxp,imx95-netc-blk-ctrl", .data = &imx95_devinfo }, 351 + { .compatible = "nxp,imx94-netc-blk-ctrl", .data = &imx94_devinfo }, 542 352 {}, 543 353 }; 544 354 MODULE_DEVICE_TABLE(of, netc_blk_ctrl_match);