1187fbae0SWei Fang // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2187fbae0SWei Fang /* 3187fbae0SWei Fang * NXP NETC switch driver 4187fbae0SWei Fang * Copyright 2025-2026 NXP 5187fbae0SWei Fang */ 6187fbae0SWei Fang 7187fbae0SWei Fang #include "netc_switch.h" 8187fbae0SWei Fang 9187fbae0SWei Fang struct netc_switch_platform { 10187fbae0SWei Fang u16 revision; 11187fbae0SWei Fang const struct netc_switch_info *info; 12187fbae0SWei Fang }; 13187fbae0SWei Fang 14bbe97e34SWei Fang static void imx94_switch_phylink_get_caps(int port, 15bbe97e34SWei Fang struct phylink_config *config) 16bbe97e34SWei Fang { 17*a5ccb7f5SWei Fang config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_1000FD; 18bbe97e34SWei Fang 19bbe97e34SWei Fang switch (port) { 20bbe97e34SWei Fang case 0 ... 1: 21bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_SGMII, 22bbe97e34SWei Fang config->supported_interfaces); 23bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_2500BASEX, 24bbe97e34SWei Fang config->supported_interfaces); 25bbe97e34SWei Fang config->mac_capabilities |= MAC_2500FD; 26bbe97e34SWei Fang fallthrough; 27bbe97e34SWei Fang case 2: 28bbe97e34SWei Fang config->mac_capabilities |= MAC_10 | MAC_100; 29bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_MII, 30bbe97e34SWei Fang config->supported_interfaces); 31bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_RMII, 32bbe97e34SWei Fang config->supported_interfaces); 33bbe97e34SWei Fang /* Port 0 and 1 do not support REVMII */ 34bbe97e34SWei Fang if (port == 2) 35bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_REVMII, 36bbe97e34SWei Fang config->supported_interfaces); 37bbe97e34SWei Fang 38bbe97e34SWei Fang phy_interface_set_rgmii(config->supported_interfaces); 39bbe97e34SWei Fang break; 40bbe97e34SWei Fang case 3: /* CPU port */ 41bbe97e34SWei Fang __set_bit(PHY_INTERFACE_MODE_INTERNAL, 42bbe97e34SWei Fang config->supported_interfaces); 43bbe97e34SWei Fang config->mac_capabilities |= MAC_10FD | MAC_100FD | 44bbe97e34SWei Fang MAC_2500FD; 45bbe97e34SWei Fang break; 46bbe97e34SWei Fang default: 47bbe97e34SWei Fang break; 48bbe97e34SWei Fang } 49bbe97e34SWei Fang } 50bbe97e34SWei Fang 51187fbae0SWei Fang static const struct netc_switch_info imx94_info = { 52187fbae0SWei Fang .num_ports = 4, 53bbe97e34SWei Fang .phylink_get_caps = imx94_switch_phylink_get_caps, 54187fbae0SWei Fang }; 55187fbae0SWei Fang 56187fbae0SWei Fang static const struct netc_switch_platform netc_platforms[] = { 57187fbae0SWei Fang { .revision = NETC_SWITCH_REV_4_3, .info = &imx94_info, }, 58187fbae0SWei Fang { } 59187fbae0SWei Fang }; 60187fbae0SWei Fang 61187fbae0SWei Fang static const struct netc_switch_info * 62187fbae0SWei Fang netc_switch_get_info(struct netc_switch *priv) 63187fbae0SWei Fang { 64187fbae0SWei Fang int i; 65187fbae0SWei Fang 66187fbae0SWei Fang /* Matching based on IP revision */ 67187fbae0SWei Fang for (i = 0; i < ARRAY_SIZE(netc_platforms); i++) { 68187fbae0SWei Fang if (priv->revision == netc_platforms[i].revision) 69187fbae0SWei Fang return netc_platforms[i].info; 70187fbae0SWei Fang } 71187fbae0SWei Fang 72187fbae0SWei Fang return NULL; 73187fbae0SWei Fang } 74187fbae0SWei Fang 75187fbae0SWei Fang int netc_switch_platform_probe(struct netc_switch *priv) 76187fbae0SWei Fang { 77187fbae0SWei Fang const struct netc_switch_info *info = netc_switch_get_info(priv); 78187fbae0SWei Fang 79187fbae0SWei Fang if (!info) { 80187fbae0SWei Fang dev_err(priv->dev, "Cannot find switch platform info\n"); 81187fbae0SWei Fang return -EINVAL; 82187fbae0SWei Fang } 83187fbae0SWei Fang 84187fbae0SWei Fang priv->info = info; 85187fbae0SWei Fang 86187fbae0SWei Fang return 0; 87187fbae0SWei Fang } 88