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