Line data Source code
1 1 : /*
2 : * Copyright 2025 NXP
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : /** @file
7 : * @brief Distributed Switch Architecture (DSA)
8 : */
9 :
10 : #ifndef ZEPHYR_INCLUDE_NET_DSA_CORE_H_
11 : #define ZEPHYR_INCLUDE_NET_DSA_CORE_H_
12 :
13 : #include <errno.h>
14 : #include <zephyr/device.h>
15 : #include <zephyr/devicetree.h>
16 : #include <zephyr/net/net_if.h>
17 : #include <zephyr/net/phy.h>
18 : #include <zephyr/net/ethernet.h>
19 :
20 : /**
21 : * @brief Distributed Switch Architecture (DSA)
22 : * @defgroup dsa_core Distributed Switch Architecture (DSA)
23 : * @since 4.2
24 : * @version 0.8.0
25 : * @ingroup networking
26 : * @{
27 : */
28 :
29 : /** @cond INTERNAL_HIDDEN */
30 :
31 : #if defined(CONFIG_DSA_PORT_MAX_COUNT)
32 : #define DSA_PORT_MAX_COUNT CONFIG_DSA_PORT_MAX_COUNT
33 : #else
34 : #define DSA_PORT_MAX_COUNT 0
35 : #endif
36 :
37 : /** @endcond */
38 :
39 : #ifdef __cplusplus
40 : extern "C" {
41 : #endif
42 :
43 : /**
44 : * @brief Macro for DSA port instance initialization.
45 : *
46 : * @param port DSA port node identifier.
47 : * @param n DSA instance number.
48 : * @param cfg Pointer to dsa_port_config.
49 : */
50 1 : #define DSA_PORT_INST_INIT(port, n, cfg) \
51 : NET_DEVICE_INIT_INSTANCE(CONCAT(dsa_, n, port), DEVICE_DT_NAME(port), DT_REG_ADDR(port), \
52 : dsa_port_initialize, NULL, &dsa_switch_context_##n, cfg, \
53 : CONFIG_ETH_INIT_PRIORITY, &dsa_eth_api, ETHERNET_L2, \
54 : NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
55 :
56 : /**
57 : * @brief Macro for DSA switch instance initialization.
58 : *
59 : * @param n DSA instance number.
60 : * @param _dapi Pointer to dsa_api.
61 : * @param data Pointer to private data.
62 : * @param fn DSA port instance init function.
63 : */
64 1 : #define DSA_SWITCH_INST_INIT(n, _dapi, data, fn) \
65 : struct dsa_switch_context dsa_switch_context_##n = { \
66 : .dapi = _dapi, \
67 : .prv_data = data, \
68 : .init_ports = 0, \
69 : .num_ports = DT_INST_CHILD_NUM_STATUS_OKAY(n), \
70 : }; \
71 : DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, fn, n);
72 :
73 : /** DSA switch context data */
74 1 : struct dsa_switch_context {
75 : /** Pointers to all DSA user network interfaces */
76 1 : struct net_if *iface_user[DSA_PORT_MAX_COUNT];
77 :
78 : /** Pointer to DSA conduit network interface */
79 1 : struct net_if *iface_conduit;
80 :
81 : /** DSA specific API callbacks */
82 1 : struct dsa_api *dapi;
83 :
84 : /** Instance specific data */
85 1 : void *prv_data;
86 :
87 : /** Number of ports in the DSA switch */
88 1 : uint8_t num_ports;
89 :
90 : /** Number of initialized ports in the DSA switch */
91 1 : uint8_t init_ports;
92 :
93 : /** DSA tagger data provided by instance when connecting to tag protocol */
94 1 : void *tagger_data;
95 : };
96 :
97 : /**
98 : * Structure to provide DSA switch api callbacks - it is an augmented
99 : * struct ethernet_api.
100 : */
101 1 : struct dsa_api {
102 : /** DSA helper callbacks */
103 :
104 : /** Handle receive packet on conduit port for untagging and redirection */
105 : struct net_if *(*recv)(struct net_if *iface, struct net_pkt *pkt);
106 :
107 : /** Transmit packet on the user port with tagging */
108 : struct net_pkt *(*xmit)(struct net_if *iface, struct net_pkt *pkt);
109 :
110 : /** Port init */
111 1 : int (*port_init)(const struct device *dev);
112 :
113 : /** Port link change */
114 1 : void (*port_phylink_change)(const struct device *dev, struct phy_link_state *state,
115 : void *user_data);
116 :
117 : /** Port generates random mac address */
118 1 : void (*port_generate_random_mac)(uint8_t *mac_addr);
119 :
120 : #if defined(CONFIG_NET_L2_PTP) || defined(__DOXYGEN__)
121 : /**
122 : * Port TX timestamp handling
123 : * @kconfig_dep{CONFIG_NET_L2_PTP}
124 : */
125 1 : int (*port_txtstamp)(const struct device *dev, struct net_pkt *pkt);
126 : #endif
127 : /** Switch setup */
128 1 : int (*switch_setup)(const struct dsa_switch_context *dsa_switch_ctx);
129 :
130 : /** Connect the switch to the tag protocol */
131 1 : int (*connect_tag_protocol)(struct dsa_switch_context *dsa_switch_ctx, int tag_proto);
132 :
133 : /** Get the device capabilities */
134 : enum ethernet_hw_caps (*get_capabilities)(const struct device *dev);
135 :
136 : /** Set specific hardware configuration */
137 1 : int (*set_config)(const struct device *dev,
138 : enum ethernet_config_type type,
139 : const struct ethernet_config *config);
140 :
141 : /** Get hardware specific configuration */
142 1 : int (*get_config)(const struct device *dev,
143 : enum ethernet_config_type type,
144 : struct ethernet_config *config);
145 : };
146 :
147 : /**
148 : * Structure of DSA port configuration.
149 : */
150 1 : struct dsa_port_config {
151 : /** Port mac address */
152 1 : uint8_t mac_addr[6];
153 : /** Use random mac address or not */
154 1 : const bool use_random_mac_addr;
155 : /** Port index */
156 1 : const int port_idx;
157 : /** PHY device */
158 1 : const struct device *phy_dev;
159 : /** PHY mode */
160 1 : const char *phy_mode;
161 : /** Tag protocol */
162 1 : const int tag_proto;
163 : /** Ethernet device connected to the port */
164 1 : const struct device *ethernet_connection;
165 : #if defined(CONFIG_NET_L2_PTP) || defined(__DOXYGEN__)
166 : /**
167 : * PTP clock used on the port
168 : * @kconfig_dep{CONFIG_NET_L2_PTP}
169 : */
170 1 : const struct device *ptp_clock;
171 : #endif
172 : /** Instance specific config */
173 1 : void *prv_config;
174 : };
175 :
176 : /** @cond INTERNAL_HIDDEN */
177 :
178 : /*
179 : * DSA port init
180 : *
181 : * Returns:
182 : * - 0 if ok, < 0 if error
183 : */
184 : int dsa_port_initialize(const struct device *dev);
185 :
186 : /*
187 : * DSA transmit function
188 : *
189 : * param dev: Port device to transmit
190 : * param pkt: Network packet
191 : *
192 : * Returns:
193 : * - 0 if ok, < 0 if error
194 : */
195 : int dsa_xmit(const struct device *dev, struct net_pkt *pkt);
196 :
197 : /*
198 : * DSA receive function
199 : *
200 : * param iface: Interface of conduit port
201 : * param pkt: Network packet
202 : *
203 : * Returns:
204 : * - Interface to redirect
205 : */
206 : struct net_if *dsa_recv(struct net_if *iface, struct net_pkt *pkt);
207 :
208 : /*
209 : * DSA ethernet init function to handle flags
210 : *
211 : * param iface: Interface of port
212 : *
213 : * Returns:
214 : * - 0 if ok, < 0 if error
215 : */
216 : int dsa_eth_init(struct net_if *iface);
217 :
218 : /* Ethernet APIs definition for switch ports */
219 : extern const struct ethernet_api dsa_eth_api;
220 :
221 : /** @endcond */
222 :
223 : /**
224 : * @brief Get network interface of a user port
225 : *
226 : * @param iface Conduit port
227 : * @param[in] port_idx Port index
228 : *
229 : * @return network interface of the user if successful
230 : * @return NULL if user port does not exist
231 : */
232 1 : struct net_if *dsa_user_get_iface(struct net_if *iface, int port_idx);
233 :
234 : #ifdef __cplusplus
235 : }
236 : #endif
237 :
238 : /**
239 : * @}
240 : */
241 : #endif /* ZEPHYR_INCLUDE_NET_DSA_CORE_H_ */
|