1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ |
2 | /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. */ |
3 | |
4 | #ifndef _PRESTERA_H_ |
5 | #define _PRESTERA_H_ |
6 | |
7 | #include <linux/notifier.h> |
8 | #include <linux/skbuff.h> |
9 | #include <linux/workqueue.h> |
10 | #include <linux/phylink.h> |
11 | #include <net/devlink.h> |
12 | #include <uapi/linux/if_ether.h> |
13 | |
14 | #define PRESTERA_DRV_NAME "prestera" |
15 | |
16 | #define PRESTERA_DEFAULT_VID 1 |
17 | |
18 | struct prestera_fw_rev { |
19 | u16 maj; |
20 | u16 min; |
21 | u16 sub; |
22 | }; |
23 | |
24 | struct prestera_flood_domain { |
25 | struct prestera_switch *sw; |
26 | struct list_head flood_domain_port_list; |
27 | u32 idx; |
28 | }; |
29 | |
30 | struct prestera_mdb_entry { |
31 | struct prestera_switch *sw; |
32 | struct prestera_flood_domain *flood_domain; |
33 | unsigned char addr[ETH_ALEN]; |
34 | u16 vid; |
35 | }; |
36 | |
37 | struct prestera_flood_domain_port { |
38 | struct prestera_flood_domain *flood_domain; |
39 | struct net_device *dev; |
40 | struct list_head flood_domain_port_node; |
41 | u16 vid; |
42 | }; |
43 | |
44 | struct prestera_port_stats { |
45 | u64 good_octets_received; |
46 | u64 bad_octets_received; |
47 | u64 mac_trans_error; |
48 | u64 broadcast_frames_received; |
49 | u64 multicast_frames_received; |
50 | u64 frames_64_octets; |
51 | u64 frames_65_to_127_octets; |
52 | u64 frames_128_to_255_octets; |
53 | u64 frames_256_to_511_octets; |
54 | u64 frames_512_to_1023_octets; |
55 | u64 frames_1024_to_max_octets; |
56 | u64 excessive_collision; |
57 | u64 multicast_frames_sent; |
58 | u64 broadcast_frames_sent; |
59 | u64 fc_sent; |
60 | u64 fc_received; |
61 | u64 buffer_overrun; |
62 | u64 undersize; |
63 | u64 fragments; |
64 | u64 oversize; |
65 | u64 jabber; |
66 | u64 rx_error_frame_received; |
67 | u64 bad_crc; |
68 | u64 collisions; |
69 | u64 late_collision; |
70 | u64 unicast_frames_received; |
71 | u64 unicast_frames_sent; |
72 | u64 sent_multiple; |
73 | u64 sent_deferred; |
74 | u64 good_octets_sent; |
75 | }; |
76 | |
77 | #define PRESTERA_AP_PORT_MAX (10) |
78 | |
79 | struct prestera_port_caps { |
80 | u64 supp_link_modes; |
81 | u8 supp_fec; |
82 | u8 type; |
83 | u8 transceiver; |
84 | }; |
85 | |
86 | struct prestera_lag { |
87 | struct net_device *dev; |
88 | struct list_head members; |
89 | u16 member_count; |
90 | u16 lag_id; |
91 | }; |
92 | |
93 | struct prestera_flow_block; |
94 | |
95 | struct prestera_port_mac_state { |
96 | bool valid; |
97 | u32 mode; |
98 | u32 speed; |
99 | bool oper; |
100 | u8 duplex; |
101 | u8 fc; |
102 | u8 fec; |
103 | }; |
104 | |
105 | struct prestera_port_phy_state { |
106 | u64 lmode_bmap; |
107 | struct { |
108 | bool pause; |
109 | bool asym_pause; |
110 | } remote_fc; |
111 | u8 mdix; |
112 | }; |
113 | |
114 | struct prestera_port_mac_config { |
115 | u32 mode; |
116 | u32 speed; |
117 | bool admin; |
118 | u8 inband; |
119 | u8 duplex; |
120 | u8 fec; |
121 | }; |
122 | |
123 | struct prestera_port_phy_config { |
124 | u32 mode; |
125 | bool admin; |
126 | u8 mdix; |
127 | }; |
128 | |
129 | struct prestera_port { |
130 | struct net_device *dev; |
131 | struct prestera_switch *sw; |
132 | struct prestera_flow_block *ingress_flow_block; |
133 | struct prestera_flow_block *egress_flow_block; |
134 | struct devlink_port dl_port; |
135 | struct list_head lag_member; |
136 | struct prestera_lag *lag; |
137 | u32 id; |
138 | u32 hw_id; |
139 | u32 dev_id; |
140 | u16 fp_id; |
141 | u16 pvid; |
142 | bool autoneg; |
143 | u64 adver_link_modes; |
144 | u8 adver_fec; |
145 | struct prestera_port_caps caps; |
146 | struct list_head list; |
147 | struct list_head vlans_list; |
148 | struct { |
149 | struct prestera_port_stats stats; |
150 | struct delayed_work caching_dw; |
151 | } cached_hw_stats; |
152 | struct prestera_port_mac_config cfg_mac; |
153 | struct prestera_port_phy_config cfg_phy; |
154 | struct prestera_port_mac_state state_mac; |
155 | struct prestera_port_phy_state state_phy; |
156 | |
157 | struct phylink_config phy_config; |
158 | struct phylink *phy_link; |
159 | struct phylink_pcs phylink_pcs; |
160 | |
161 | /* protects state_mac */ |
162 | spinlock_t state_mac_lock; |
163 | }; |
164 | |
165 | struct prestera_device { |
166 | struct device *dev; |
167 | u8 __iomem *ctl_regs; |
168 | u8 __iomem *pp_regs; |
169 | struct prestera_fw_rev fw_rev; |
170 | void *priv; |
171 | |
172 | /* called by device driver to handle received packets */ |
173 | void (*recv_pkt)(struct prestera_device *dev); |
174 | |
175 | /* called by device driver to pass event up to the higher layer */ |
176 | int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size); |
177 | |
178 | /* called by higher layer to send request to the firmware */ |
179 | int (*send_req)(struct prestera_device *dev, int qid, void *in_msg, |
180 | size_t in_size, void *out_msg, size_t out_size, |
181 | unsigned int wait); |
182 | }; |
183 | |
184 | enum prestera_event_type { |
185 | PRESTERA_EVENT_TYPE_UNSPEC, |
186 | |
187 | PRESTERA_EVENT_TYPE_PORT, |
188 | PRESTERA_EVENT_TYPE_FDB, |
189 | PRESTERA_EVENT_TYPE_RXTX, |
190 | |
191 | PRESTERA_EVENT_TYPE_MAX |
192 | }; |
193 | |
194 | enum prestera_rxtx_event_id { |
195 | PRESTERA_RXTX_EVENT_UNSPEC, |
196 | PRESTERA_RXTX_EVENT_RCV_PKT, |
197 | }; |
198 | |
199 | enum prestera_port_event_id { |
200 | PRESTERA_PORT_EVENT_UNSPEC, |
201 | PRESTERA_PORT_EVENT_MAC_STATE_CHANGED, |
202 | }; |
203 | |
204 | struct prestera_port_event { |
205 | u32 port_id; |
206 | union { |
207 | struct { |
208 | u32 mode; |
209 | u32 speed; |
210 | u8 oper; |
211 | u8 duplex; |
212 | u8 fc; |
213 | u8 fec; |
214 | } mac; |
215 | struct { |
216 | u64 lmode_bmap; |
217 | struct { |
218 | bool pause; |
219 | bool asym_pause; |
220 | } remote_fc; |
221 | u8 mdix; |
222 | } phy; |
223 | } data; |
224 | }; |
225 | |
226 | enum prestera_fdb_entry_type { |
227 | PRESTERA_FDB_ENTRY_TYPE_REG_PORT, |
228 | PRESTERA_FDB_ENTRY_TYPE_LAG, |
229 | PRESTERA_FDB_ENTRY_TYPE_MAX |
230 | }; |
231 | |
232 | enum prestera_fdb_event_id { |
233 | PRESTERA_FDB_EVENT_UNSPEC, |
234 | PRESTERA_FDB_EVENT_LEARNED, |
235 | PRESTERA_FDB_EVENT_AGED, |
236 | }; |
237 | |
238 | struct prestera_fdb_event { |
239 | enum prestera_fdb_entry_type type; |
240 | union { |
241 | u32 port_id; |
242 | u16 lag_id; |
243 | } dest; |
244 | u32 vid; |
245 | union { |
246 | u8 mac[ETH_ALEN]; |
247 | } data; |
248 | }; |
249 | |
250 | struct prestera_event { |
251 | u16 id; |
252 | union { |
253 | struct prestera_port_event port_evt; |
254 | struct prestera_fdb_event fdb_evt; |
255 | }; |
256 | }; |
257 | |
258 | enum prestera_if_type { |
259 | /* the interface is of port type (dev,port) */ |
260 | PRESTERA_IF_PORT_E = 0, |
261 | |
262 | /* the interface is of lag type (lag-id) */ |
263 | PRESTERA_IF_LAG_E = 1, |
264 | |
265 | /* the interface is of Vid type (vlan-id) */ |
266 | PRESTERA_IF_VID_E = 3, |
267 | }; |
268 | |
269 | struct prestera_iface { |
270 | enum prestera_if_type type; |
271 | struct { |
272 | u32 hw_dev_num; |
273 | u32 port_num; |
274 | } dev_port; |
275 | u32 hw_dev_num; |
276 | u16 vr_id; |
277 | u16 lag_id; |
278 | u16 vlan_id; |
279 | }; |
280 | |
281 | struct prestera_switchdev; |
282 | struct prestera_span; |
283 | struct prestera_rxtx; |
284 | struct prestera_trap_data; |
285 | struct prestera_acl; |
286 | |
287 | struct prestera_switch { |
288 | struct prestera_device *dev; |
289 | struct prestera_switchdev *swdev; |
290 | struct prestera_rxtx *rxtx; |
291 | struct prestera_acl *acl; |
292 | struct prestera_span *span; |
293 | struct list_head event_handlers; |
294 | struct notifier_block netdev_nb; |
295 | struct prestera_trap_data *trap_data; |
296 | char base_mac[ETH_ALEN]; |
297 | struct list_head port_list; |
298 | rwlock_t port_list_lock; |
299 | u32 port_count; |
300 | u32 mtu_min; |
301 | u32 mtu_max; |
302 | u8 id; |
303 | struct device_node *np; |
304 | struct prestera_router *router; |
305 | struct prestera_lag *lags; |
306 | struct prestera_counter *counter; |
307 | u8 lag_member_max; |
308 | u8 lag_max; |
309 | u32 size_tbl_router_nexthop; |
310 | }; |
311 | |
312 | struct prestera_router { |
313 | struct prestera_switch *sw; |
314 | struct list_head vr_list; |
315 | struct list_head rif_entry_list; |
316 | struct rhashtable nh_neigh_ht; |
317 | struct rhashtable nexthop_group_ht; |
318 | struct rhashtable fib_ht; |
319 | struct rhashtable kern_neigh_cache_ht; |
320 | struct rhashtable kern_fib_cache_ht; |
321 | struct notifier_block inetaddr_nb; |
322 | struct notifier_block inetaddr_valid_nb; |
323 | struct notifier_block fib_nb; |
324 | struct notifier_block netevent_nb; |
325 | u8 *nhgrp_hw_state_cache; /* Bitmap cached hw state of nhs */ |
326 | unsigned long nhgrp_hw_cache_kick; /* jiffies */ |
327 | struct { |
328 | struct delayed_work dw; |
329 | } neighs_update; |
330 | }; |
331 | |
332 | struct prestera_rxtx_params { |
333 | bool use_sdma; |
334 | u32 map_addr; |
335 | }; |
336 | |
337 | #define prestera_dev(sw) ((sw)->dev->dev) |
338 | |
339 | static inline void prestera_write(const struct prestera_switch *sw, |
340 | unsigned int reg, u32 val) |
341 | { |
342 | writel(val, addr: sw->dev->pp_regs + reg); |
343 | } |
344 | |
345 | static inline u32 prestera_read(const struct prestera_switch *sw, |
346 | unsigned int reg) |
347 | { |
348 | return readl(addr: sw->dev->pp_regs + reg); |
349 | } |
350 | |
351 | int prestera_device_register(struct prestera_device *dev); |
352 | void prestera_device_unregister(struct prestera_device *dev); |
353 | |
354 | struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw, |
355 | u32 dev_id, u32 hw_id); |
356 | |
357 | int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes); |
358 | |
359 | int prestera_router_init(struct prestera_switch *sw); |
360 | void prestera_router_fini(struct prestera_switch *sw); |
361 | |
362 | struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id); |
363 | |
364 | struct prestera_switch *prestera_switch_get(struct net_device *dev); |
365 | |
366 | int prestera_port_cfg_mac_read(struct prestera_port *port, |
367 | struct prestera_port_mac_config *cfg); |
368 | |
369 | int prestera_port_cfg_mac_write(struct prestera_port *port, |
370 | struct prestera_port_mac_config *cfg); |
371 | |
372 | struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev); |
373 | |
374 | void prestera_queue_work(struct work_struct *work); |
375 | void prestera_queue_delayed_work(struct delayed_work *work, unsigned long delay); |
376 | void prestera_queue_drain(void); |
377 | |
378 | int prestera_port_learning_set(struct prestera_port *port, bool learn_enable); |
379 | int prestera_port_uc_flood_set(struct prestera_port *port, bool flood); |
380 | int prestera_port_mc_flood_set(struct prestera_port *port, bool flood); |
381 | |
382 | int prestera_port_br_locked_set(struct prestera_port *port, bool br_locked); |
383 | |
384 | int prestera_port_pvid_set(struct prestera_port *port, u16 vid); |
385 | |
386 | bool prestera_netdev_check(const struct net_device *dev); |
387 | |
388 | int prestera_is_valid_mac_addr(struct prestera_port *port, const u8 *addr); |
389 | |
390 | bool prestera_port_is_lag_member(const struct prestera_port *port); |
391 | int prestera_lag_id(struct prestera_switch *sw, |
392 | struct net_device *lag_dev, u16 *lag_id); |
393 | |
394 | struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id); |
395 | |
396 | u16 prestera_port_lag_id(const struct prestera_port *port); |
397 | |
398 | struct prestera_mdb_entry * |
399 | prestera_mdb_entry_create(struct prestera_switch *sw, |
400 | const unsigned char *addr, u16 vid); |
401 | void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry); |
402 | |
403 | struct prestera_flood_domain * |
404 | prestera_flood_domain_create(struct prestera_switch *sw); |
405 | void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain); |
406 | |
407 | int |
408 | prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain, |
409 | struct net_device *dev, |
410 | u16 vid); |
411 | void |
412 | prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port); |
413 | struct prestera_flood_domain_port * |
414 | prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain, |
415 | struct net_device *dev, u16 vid); |
416 | |
417 | #endif /* _PRESTERA_H_ */ |
418 | |