xref: /linux/drivers/net/dsa/netc/netc_platform.c (revision 8d72997dab65b1e9e3220302e26eaecd9b99c02f)
1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /*
3  * NXP NETC switch driver
4  * Copyright 2025-2026 NXP
5  */
6 
7 #include "netc_switch.h"
8 
9 struct netc_switch_platform {
10 	u16 revision;
11 	const struct netc_switch_info *info;
12 };
13 
14 static void imx94_switch_phylink_get_caps(int port,
15 					  struct phylink_config *config)
16 {
17 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_1000FD;
18 
19 	switch (port) {
20 	case 0 ... 1:
21 		__set_bit(PHY_INTERFACE_MODE_SGMII,
22 			  config->supported_interfaces);
23 		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
24 			  config->supported_interfaces);
25 		config->mac_capabilities |= MAC_2500FD;
26 		fallthrough;
27 	case 2:
28 		config->mac_capabilities |= MAC_10 | MAC_100;
29 		__set_bit(PHY_INTERFACE_MODE_MII,
30 			  config->supported_interfaces);
31 		__set_bit(PHY_INTERFACE_MODE_RMII,
32 			  config->supported_interfaces);
33 		/* Port 0 and 1 do not support REVMII */
34 		if (port == 2)
35 			__set_bit(PHY_INTERFACE_MODE_REVMII,
36 				  config->supported_interfaces);
37 
38 		phy_interface_set_rgmii(config->supported_interfaces);
39 		break;
40 	case 3: /* CPU port */
41 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
42 			  config->supported_interfaces);
43 		config->mac_capabilities |= MAC_10FD | MAC_100FD |
44 					    MAC_2500FD;
45 		break;
46 	default:
47 		break;
48 	}
49 }
50 
51 static const struct netc_switch_info imx94_info = {
52 	.num_ports = 4,
53 	.phylink_get_caps = imx94_switch_phylink_get_caps,
54 };
55 
56 static const struct netc_switch_platform netc_platforms[] = {
57 	{ .revision = NETC_SWITCH_REV_4_3, .info = &imx94_info, },
58 	{ }
59 };
60 
61 static const struct netc_switch_info *
62 netc_switch_get_info(struct netc_switch *priv)
63 {
64 	int i;
65 
66 	/* Matching based on IP revision */
67 	for (i = 0; i < ARRAY_SIZE(netc_platforms); i++) {
68 		if (priv->revision == netc_platforms[i].revision)
69 			return netc_platforms[i].info;
70 	}
71 
72 	return NULL;
73 }
74 
75 int netc_switch_platform_probe(struct netc_switch *priv)
76 {
77 	const struct netc_switch_info *info = netc_switch_get_info(priv);
78 
79 	if (!info) {
80 		dev_err(priv->dev, "Cannot find switch platform info\n");
81 		return -EINVAL;
82 	}
83 
84 	priv->info = info;
85 
86 	return 0;
87 }
88