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 <net/devlink.h>
11 #include <uapi/linux/if_ether.h>
12
13 #define PRESTERA_DRV_NAME "prestera"
14
15 #define PRESTERA_DEFAULT_VID 1
16
17 struct prestera_fw_rev {
18 u16 maj;
19 u16 min;
20 u16 sub;
21 };
22
23 struct prestera_port_stats {
24 u64 good_octets_received;
25 u64 bad_octets_received;
26 u64 mac_trans_error;
27 u64 broadcast_frames_received;
28 u64 multicast_frames_received;
29 u64 frames_64_octets;
30 u64 frames_65_to_127_octets;
31 u64 frames_128_to_255_octets;
32 u64 frames_256_to_511_octets;
33 u64 frames_512_to_1023_octets;
34 u64 frames_1024_to_max_octets;
35 u64 excessive_collision;
36 u64 multicast_frames_sent;
37 u64 broadcast_frames_sent;
38 u64 fc_sent;
39 u64 fc_received;
40 u64 buffer_overrun;
41 u64 undersize;
42 u64 fragments;
43 u64 oversize;
44 u64 jabber;
45 u64 rx_error_frame_received;
46 u64 bad_crc;
47 u64 collisions;
48 u64 late_collision;
49 u64 unicast_frames_received;
50 u64 unicast_frames_sent;
51 u64 sent_multiple;
52 u64 sent_deferred;
53 u64 good_octets_sent;
54 };
55
56 #define PRESTERA_AP_PORT_MAX (10)
57
58 struct prestera_port_caps {
59 u64 supp_link_modes;
60 u8 supp_fec;
61 u8 type;
62 u8 transceiver;
63 };
64
65 struct prestera_lag {
66 struct net_device *dev;
67 struct list_head members;
68 u16 member_count;
69 u16 lag_id;
70 };
71
72 struct prestera_flow_block;
73
74 struct prestera_port_mac_state {
75 u32 mode;
76 u32 speed;
77 bool oper;
78 u8 duplex;
79 u8 fc;
80 u8 fec;
81 };
82
83 struct prestera_port_phy_state {
84 u64 lmode_bmap;
85 struct {
86 bool pause;
87 bool asym_pause;
88 } remote_fc;
89 u8 mdix;
90 };
91
92 struct prestera_port_mac_config {
93 u32 mode;
94 u32 speed;
95 bool admin;
96 u8 inband;
97 u8 duplex;
98 u8 fec;
99 };
100
101 struct prestera_port_phy_config {
102 u32 mode;
103 bool admin;
104 u8 mdix;
105 };
106
107 struct prestera_port {
108 struct net_device *dev;
109 struct prestera_switch *sw;
110 struct prestera_flow_block *flow_block;
111 struct devlink_port dl_port;
112 struct list_head lag_member;
113 struct prestera_lag *lag;
114 u32 id;
115 u32 hw_id;
116 u32 dev_id;
117 u16 fp_id;
118 u16 pvid;
119 bool autoneg;
120 u64 adver_link_modes;
121 u8 adver_fec;
122 struct prestera_port_caps caps;
123 struct list_head list;
124 struct list_head vlans_list;
125 struct {
126 struct prestera_port_stats stats;
127 struct delayed_work caching_dw;
128 } cached_hw_stats;
129 struct prestera_port_mac_config cfg_mac;
130 struct prestera_port_phy_config cfg_phy;
131 struct prestera_port_mac_state state_mac;
132 struct prestera_port_phy_state state_phy;
133 };
134
135 struct prestera_device {
136 struct device *dev;
137 u8 __iomem *ctl_regs;
138 u8 __iomem *pp_regs;
139 struct prestera_fw_rev fw_rev;
140 void *priv;
141
142 /* called by device driver to handle received packets */
143 void (*recv_pkt)(struct prestera_device *dev);
144
145 /* called by device driver to pass event up to the higher layer */
146 int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size);
147
148 /* called by higher layer to send request to the firmware */
149 int (*send_req)(struct prestera_device *dev, int qid, void *in_msg,
150 size_t in_size, void *out_msg, size_t out_size,
151 unsigned int wait);
152 };
153
154 enum prestera_event_type {
155 PRESTERA_EVENT_TYPE_UNSPEC,
156
157 PRESTERA_EVENT_TYPE_PORT,
158 PRESTERA_EVENT_TYPE_FDB,
159 PRESTERA_EVENT_TYPE_RXTX,
160
161 PRESTERA_EVENT_TYPE_MAX
162 };
163
164 enum prestera_rxtx_event_id {
165 PRESTERA_RXTX_EVENT_UNSPEC,
166 PRESTERA_RXTX_EVENT_RCV_PKT,
167 };
168
169 enum prestera_port_event_id {
170 PRESTERA_PORT_EVENT_UNSPEC,
171 PRESTERA_PORT_EVENT_MAC_STATE_CHANGED,
172 };
173
174 struct prestera_port_event {
175 u32 port_id;
176 union {
177 struct {
178 u32 mode;
179 u32 speed;
180 u8 oper;
181 u8 duplex;
182 u8 fc;
183 u8 fec;
184 } mac;
185 struct {
186 u64 lmode_bmap;
187 struct {
188 bool pause;
189 bool asym_pause;
190 } remote_fc;
191 u8 mdix;
192 } phy;
193 } data;
194 };
195
196 enum prestera_fdb_entry_type {
197 PRESTERA_FDB_ENTRY_TYPE_REG_PORT,
198 PRESTERA_FDB_ENTRY_TYPE_LAG,
199 PRESTERA_FDB_ENTRY_TYPE_MAX
200 };
201
202 enum prestera_fdb_event_id {
203 PRESTERA_FDB_EVENT_UNSPEC,
204 PRESTERA_FDB_EVENT_LEARNED,
205 PRESTERA_FDB_EVENT_AGED,
206 };
207
208 struct prestera_fdb_event {
209 enum prestera_fdb_entry_type type;
210 union {
211 u32 port_id;
212 u16 lag_id;
213 } dest;
214 u32 vid;
215 union {
216 u8 mac[ETH_ALEN];
217 } data;
218 };
219
220 struct prestera_event {
221 u16 id;
222 union {
223 struct prestera_port_event port_evt;
224 struct prestera_fdb_event fdb_evt;
225 };
226 };
227
228 struct prestera_switchdev;
229 struct prestera_span;
230 struct prestera_rxtx;
231 struct prestera_trap_data;
232 struct prestera_acl;
233
234 struct prestera_switch {
235 struct prestera_device *dev;
236 struct prestera_switchdev *swdev;
237 struct prestera_rxtx *rxtx;
238 struct prestera_acl *acl;
239 struct prestera_span *span;
240 struct list_head event_handlers;
241 struct notifier_block netdev_nb;
242 struct prestera_trap_data *trap_data;
243 char base_mac[ETH_ALEN];
244 struct list_head port_list;
245 rwlock_t port_list_lock;
246 u32 port_count;
247 u32 mtu_min;
248 u32 mtu_max;
249 u8 id;
250 struct prestera_lag *lags;
251 u8 lag_member_max;
252 u8 lag_max;
253 };
254
255 struct prestera_rxtx_params {
256 bool use_sdma;
257 u32 map_addr;
258 };
259
260 #define prestera_dev(sw) ((sw)->dev->dev)
261
prestera_write(const struct prestera_switch * sw,unsigned int reg,u32 val)262 static inline void prestera_write(const struct prestera_switch *sw,
263 unsigned int reg, u32 val)
264 {
265 writel(val, sw->dev->pp_regs + reg);
266 }
267
prestera_read(const struct prestera_switch * sw,unsigned int reg)268 static inline u32 prestera_read(const struct prestera_switch *sw,
269 unsigned int reg)
270 {
271 return readl(sw->dev->pp_regs + reg);
272 }
273
274 int prestera_device_register(struct prestera_device *dev);
275 void prestera_device_unregister(struct prestera_device *dev);
276
277 struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
278 u32 dev_id, u32 hw_id);
279
280 int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes);
281
282 struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id);
283
284 int prestera_port_cfg_mac_read(struct prestera_port *port,
285 struct prestera_port_mac_config *cfg);
286
287 int prestera_port_cfg_mac_write(struct prestera_port *port,
288 struct prestera_port_mac_config *cfg);
289
290 struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev);
291
292 int prestera_port_pvid_set(struct prestera_port *port, u16 vid);
293
294 bool prestera_netdev_check(const struct net_device *dev);
295
296 bool prestera_port_is_lag_member(const struct prestera_port *port);
297
298 struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id);
299
300 u16 prestera_port_lag_id(const struct prestera_port *port);
301
302 #endif /* _PRESTERA_H_ */
303