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 :
134 : /**
135 : * Structure of DSA port configuration.
136 : */
137 1 : struct dsa_port_config {
138 : /** Port mac address */
139 1 : uint8_t mac_addr[6];
140 : /** Use random mac address or not */
141 1 : const bool use_random_mac_addr;
142 : /** Port index */
143 1 : const int port_idx;
144 : /** PHY device */
145 1 : const struct device *phy_dev;
146 : /** PHY mode */
147 1 : const char *phy_mode;
148 : /** Tag protocol */
149 1 : const int tag_proto;
150 : /** Ethernet device connected to the port */
151 1 : const struct device *ethernet_connection;
152 : #if defined(CONFIG_NET_L2_PTP) || defined(__DOXYGEN__)
153 : /**
154 : * PTP clock used on the port
155 : * @kconfig_dep{CONFIG_NET_L2_PTP}
156 : */
157 1 : const struct device *ptp_clock;
158 : #endif
159 : /** Instance specific config */
160 1 : void *prv_config;
161 : };
162 :
163 : /** @cond INTERNAL_HIDDEN */
164 :
165 : /*
166 : * DSA port init
167 : *
168 : * Returns:
169 : * - 0 if ok, < 0 if error
170 : */
171 : int dsa_port_initialize(const struct device *dev);
172 :
173 : /*
174 : * DSA transmit function
175 : *
176 : * param dev: Port device to transmit
177 : * param pkt: Network packet
178 : *
179 : * Returns:
180 : * - 0 if ok, < 0 if error
181 : */
182 : int dsa_xmit(const struct device *dev, struct net_pkt *pkt);
183 :
184 : /*
185 : * DSA receive function
186 : *
187 : * param iface: Interface of conduit port
188 : * param pkt: Network packet
189 : *
190 : * Returns:
191 : * - Interface to redirect
192 : */
193 : struct net_if *dsa_recv(struct net_if *iface, struct net_pkt *pkt);
194 :
195 : /*
196 : * DSA ethernet init function to handle flags
197 : *
198 : * param iface: Interface of port
199 : *
200 : * Returns:
201 : * - 0 if ok, < 0 if error
202 : */
203 : int dsa_eth_init(struct net_if *iface);
204 :
205 : /* Ethernet APIs definition for switch ports */
206 : extern const struct ethernet_api dsa_eth_api;
207 :
208 : /** @endcond */
209 :
210 : /**
211 : * @brief Get network interface of a user port
212 : *
213 : * @param iface Conduit port
214 : * @param[in] port_idx Port index
215 : *
216 : * @return network interface of the user if successful
217 : * @return NULL if user port does not exist
218 : */
219 1 : struct net_if *dsa_user_get_iface(struct net_if *iface, int port_idx);
220 :
221 : #ifdef __cplusplus
222 : }
223 : #endif
224 :
225 : /**
226 : * @}
227 : */
228 : #endif /* ZEPHYR_INCLUDE_NET_DSA_CORE_H_ */
|