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