Line data Source code
1 1 : /*
2 : * Copyright (c) 2020 DENX Software Engineering GmbH
3 : * Lukasz Majewski <lukma@denx.de>
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /** @file
8 : * @brief DSA definitions and handlers
9 : */
10 :
11 : #ifndef ZEPHYR_INCLUDE_NET_DSA_H_
12 : #define ZEPHYR_INCLUDE_NET_DSA_H_
13 :
14 : #include <zephyr/device.h>
15 : #include <zephyr/net/net_if.h>
16 :
17 : /**
18 : * @brief DSA definitions and helpers
19 : * @defgroup DSA Distributed Switch Architecture definitions and helpers
20 : * @since 2.5
21 : * @version 0.8.0
22 : * @ingroup networking
23 : * @{
24 : */
25 :
26 : /** @cond INTERNAL_HIDDEN */
27 :
28 : #define NET_DSA_PORT_MAX_COUNT 8
29 : #define DSA_STATUS_PERIOD_MS K_MSEC(1000)
30 :
31 : /*
32 : * Size of the DSA TAG:
33 : * - KSZ8794 - 1 byte
34 : */
35 : #if defined(CONFIG_DSA_KSZ8794) && defined(CONFIG_DSA_KSZ_TAIL_TAGGING)
36 : #define DSA_TAG_SIZE 1
37 : #else
38 : #define DSA_TAG_SIZE 0
39 : #endif
40 :
41 : /** @endcond */
42 :
43 : #ifdef __cplusplus
44 : extern "C" {
45 : #endif
46 :
47 : /**
48 : * @brief DSA generic transmit function
49 : *
50 : * This is a generic function for passing packets from slave DSA interface to
51 : * master.
52 : *
53 : * @param dev Device
54 : * @param pkt Network packet
55 : *
56 : * Returns:
57 : * - 0 if ok (packet sent via master iface), < 0 if error
58 : */
59 1 : int dsa_tx(const struct device *dev, struct net_pkt *pkt);
60 :
61 : /**
62 : * @brief DSA (MGMT) Receive packet callback
63 : *
64 : * Callback gets called upon receiving packet. It is responsible for
65 : * freeing packet or indicating to the stack that it needs to free packet
66 : * by returning correct net_verdict.
67 : *
68 : * Returns:
69 : * - NET_DROP, if packet was invalid, rejected or we want the stack to free it.
70 : * In this case the core stack will free the packet.
71 : * - NET_OK, if the packet was accepted, in this case the ownership of the
72 : * net_pkt goes to callback and core network stack will forget it.
73 : */
74 : typedef enum net_verdict (*dsa_net_recv_cb_t)(struct net_if *iface,
75 : struct net_pkt *pkt);
76 :
77 : /**
78 : * @brief Register DSA Rx callback functions
79 : *
80 : * @param iface Network interface
81 : * @param cb Receive callback function
82 : *
83 : * @return 0 if ok, < 0 if error
84 : */
85 1 : int dsa_register_recv_callback(struct net_if *iface, dsa_net_recv_cb_t cb);
86 :
87 : /**
88 : * @brief Set DSA interface to packet
89 : *
90 : * @param iface Network interface (master)
91 : * @param pkt Network packet
92 : *
93 : * @return Return the slave network interface
94 : */
95 1 : struct net_if *dsa_net_recv(struct net_if *iface, struct net_pkt **pkt);
96 :
97 : /**
98 : * @brief Pointer to master interface send function
99 : */
100 1 : typedef int (*dsa_send_t)(const struct device *dev, struct net_pkt *pkt);
101 :
102 : /**
103 : * @brief DSA helper function to register transmit function for master
104 : *
105 : * @param iface Network interface (master)
106 : * @param fn Pointer to master interface send method
107 : *
108 : * Returns:
109 : * - 0 if ok, < 0 if error
110 : */
111 1 : int dsa_register_master_tx(struct net_if *iface, dsa_send_t fn);
112 :
113 : /**
114 : * @brief DSA helper function to check if port is master
115 : *
116 : * @param iface Network interface (master)
117 : *
118 : * Returns:
119 : * - true if ok, false otherwise
120 : */
121 1 : bool dsa_is_port_master(struct net_if *iface);
122 :
123 : /**
124 : * @cond INTERNAL_HIDDEN
125 : *
126 : * These are for internal use only, so skip these in
127 : * public documentation.
128 : */
129 :
130 : /** DSA context data */
131 : struct dsa_context {
132 : /** Pointers to all DSA slave network interfaces */
133 : struct net_if *iface_slave[NET_DSA_PORT_MAX_COUNT];
134 :
135 : /** Pointer to DSA master network interface */
136 : struct net_if *iface_master;
137 :
138 : /** DSA specific API callbacks - filled in the switch IC driver */
139 : struct dsa_api *dapi;
140 :
141 : /** DSA related work (e.g. monitor if network interface is up) */
142 : struct k_work_delayable dsa_work;
143 :
144 : /** Number of slave ports in the DSA switch */
145 : uint8_t num_slave_ports;
146 :
147 : /** Status of each port */
148 : bool link_up[NET_DSA_PORT_MAX_COUNT];
149 :
150 : /** Instance specific data */
151 : void *prv_data;
152 : };
153 :
154 : /**
155 : * @brief Structure to provide DSA switch api callbacks - it is an augmented
156 : * struct ethernet_api.
157 : */
158 : struct dsa_api {
159 : /** Function to get proper LAN{123} interface */
160 : struct net_if *(*dsa_get_iface)(struct net_if *iface,
161 : struct net_pkt *pkt);
162 : /*
163 : * Callbacks required for DSA switch initialization and configuration.
164 : *
165 : * Each switch instance (e.g. two KSZ8794 ICs) would have its own struct
166 : * dsa_context.
167 : */
168 : /** Read value from DSA register */
169 : int (*switch_read)(const struct device *dev, uint16_t reg_addr,
170 : uint8_t *value);
171 : /** Write value to DSA register */
172 : int (*switch_write)(const struct device *dev, uint16_t reg_addr,
173 : uint8_t value);
174 :
175 : /** Program (set) mac table entry in the DSA switch */
176 : int (*switch_set_mac_table_entry)(const struct device *dev,
177 : const uint8_t *mac,
178 : uint8_t fw_port,
179 : uint16_t tbl_entry_idx,
180 : uint16_t flags);
181 :
182 : /** Read mac table entry from the DSA switch */
183 : int (*switch_get_mac_table_entry)(const struct device *dev,
184 : uint8_t *buf,
185 : uint16_t tbl_entry_idx);
186 :
187 : /*
188 : * DSA helper callbacks
189 : */
190 : struct net_pkt *(*dsa_xmit_pkt)(struct net_if *iface,
191 : struct net_pkt *pkt);
192 : };
193 :
194 : /**
195 : * @endcond
196 : */
197 :
198 : /**
199 : * @brief Get network interface of a slave port
200 : *
201 : * @param iface Master port
202 : * @param[in] slave_num Slave port number
203 : *
204 : * @return network interface of the slave if successful
205 : * @return NULL if slave port does not exist
206 : */
207 1 : struct net_if *dsa_get_slave_port(struct net_if *iface, int slave_num);
208 :
209 : /**
210 : * @brief Read from DSA switch register
211 : *
212 : * @param iface The interface
213 : * @param[in] reg_addr The register address
214 : * @param value The value
215 : *
216 : * @return 0 if successful, negative if error
217 : */
218 1 : int dsa_switch_read(struct net_if *iface, uint16_t reg_addr, uint8_t *value);
219 :
220 : /**
221 : * @brief Write to DSA switch
222 : *
223 : * @param iface The interface
224 : * @param[in] reg_addr The register address
225 : * @param[in] value The value
226 : *
227 : * @return { description_of_the_return_value }
228 : */
229 1 : int dsa_switch_write(struct net_if *iface, uint16_t reg_addr, uint8_t value);
230 :
231 : /**
232 : * @brief Write static MAC table entry
233 : *
234 : * @param iface Master DSA interface
235 : * @param[in] mac MAC address
236 : * @param[in] fw_port The firmware port
237 : * @param[in] tbl_entry_idx Table entry index
238 : * @param[in] flags Flags
239 : *
240 : * @return 0 if successful, negative if error
241 : */
242 1 : int dsa_switch_set_mac_table_entry(struct net_if *iface,
243 : const uint8_t *mac,
244 : uint8_t fw_port,
245 : uint16_t tbl_entry_idx,
246 : uint16_t flags);
247 :
248 : /**
249 : * @brief Read static MAC table entry
250 : *
251 : * @param iface Master DSA interface
252 : * @param buf Buffer to receive MAC address
253 : * @param[in] tbl_entry_idx Table entry index
254 : *
255 : * @return 0 if successful, negative if error
256 : */
257 1 : int dsa_switch_get_mac_table_entry(struct net_if *iface,
258 : uint8_t *buf,
259 : uint16_t tbl_entry_idx);
260 :
261 : /**
262 : * @brief Structure to provide mac address for each LAN interface
263 : */
264 :
265 1 : struct dsa_slave_config {
266 : /** MAC address for each LAN{123.,} ports */
267 1 : uint8_t mac_addr[6];
268 : };
269 :
270 : #ifdef __cplusplus
271 : }
272 : #endif
273 :
274 : /**
275 : * @}
276 : */
277 : #endif /* ZEPHYR_INCLUDE_NET_DSA_H_ */
|