1*4882a593Smuzhiyun /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2*4882a593Smuzhiyun /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #ifndef _PRESTERA_H_
5*4882a593Smuzhiyun #define _PRESTERA_H_
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/notifier.h>
8*4882a593Smuzhiyun #include <linux/skbuff.h>
9*4882a593Smuzhiyun #include <linux/workqueue.h>
10*4882a593Smuzhiyun #include <net/devlink.h>
11*4882a593Smuzhiyun #include <uapi/linux/if_ether.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define PRESTERA_DRV_NAME "prestera"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define PRESTERA_DEFAULT_VID 1
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun struct prestera_fw_rev {
18*4882a593Smuzhiyun u16 maj;
19*4882a593Smuzhiyun u16 min;
20*4882a593Smuzhiyun u16 sub;
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun struct prestera_port_stats {
24*4882a593Smuzhiyun u64 good_octets_received;
25*4882a593Smuzhiyun u64 bad_octets_received;
26*4882a593Smuzhiyun u64 mac_trans_error;
27*4882a593Smuzhiyun u64 broadcast_frames_received;
28*4882a593Smuzhiyun u64 multicast_frames_received;
29*4882a593Smuzhiyun u64 frames_64_octets;
30*4882a593Smuzhiyun u64 frames_65_to_127_octets;
31*4882a593Smuzhiyun u64 frames_128_to_255_octets;
32*4882a593Smuzhiyun u64 frames_256_to_511_octets;
33*4882a593Smuzhiyun u64 frames_512_to_1023_octets;
34*4882a593Smuzhiyun u64 frames_1024_to_max_octets;
35*4882a593Smuzhiyun u64 excessive_collision;
36*4882a593Smuzhiyun u64 multicast_frames_sent;
37*4882a593Smuzhiyun u64 broadcast_frames_sent;
38*4882a593Smuzhiyun u64 fc_sent;
39*4882a593Smuzhiyun u64 fc_received;
40*4882a593Smuzhiyun u64 buffer_overrun;
41*4882a593Smuzhiyun u64 undersize;
42*4882a593Smuzhiyun u64 fragments;
43*4882a593Smuzhiyun u64 oversize;
44*4882a593Smuzhiyun u64 jabber;
45*4882a593Smuzhiyun u64 rx_error_frame_received;
46*4882a593Smuzhiyun u64 bad_crc;
47*4882a593Smuzhiyun u64 collisions;
48*4882a593Smuzhiyun u64 late_collision;
49*4882a593Smuzhiyun u64 unicast_frames_received;
50*4882a593Smuzhiyun u64 unicast_frames_sent;
51*4882a593Smuzhiyun u64 sent_multiple;
52*4882a593Smuzhiyun u64 sent_deferred;
53*4882a593Smuzhiyun u64 good_octets_sent;
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun struct prestera_port_caps {
57*4882a593Smuzhiyun u64 supp_link_modes;
58*4882a593Smuzhiyun u8 supp_fec;
59*4882a593Smuzhiyun u8 type;
60*4882a593Smuzhiyun u8 transceiver;
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun struct prestera_port {
64*4882a593Smuzhiyun struct net_device *dev;
65*4882a593Smuzhiyun struct prestera_switch *sw;
66*4882a593Smuzhiyun struct devlink_port dl_port;
67*4882a593Smuzhiyun u32 id;
68*4882a593Smuzhiyun u32 hw_id;
69*4882a593Smuzhiyun u32 dev_id;
70*4882a593Smuzhiyun u16 fp_id;
71*4882a593Smuzhiyun u16 pvid;
72*4882a593Smuzhiyun bool autoneg;
73*4882a593Smuzhiyun u64 adver_link_modes;
74*4882a593Smuzhiyun u8 adver_fec;
75*4882a593Smuzhiyun struct prestera_port_caps caps;
76*4882a593Smuzhiyun struct list_head list;
77*4882a593Smuzhiyun struct list_head vlans_list;
78*4882a593Smuzhiyun struct {
79*4882a593Smuzhiyun struct prestera_port_stats stats;
80*4882a593Smuzhiyun struct delayed_work caching_dw;
81*4882a593Smuzhiyun } cached_hw_stats;
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun struct prestera_device {
85*4882a593Smuzhiyun struct device *dev;
86*4882a593Smuzhiyun u8 __iomem *ctl_regs;
87*4882a593Smuzhiyun u8 __iomem *pp_regs;
88*4882a593Smuzhiyun struct prestera_fw_rev fw_rev;
89*4882a593Smuzhiyun void *priv;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* called by device driver to handle received packets */
92*4882a593Smuzhiyun void (*recv_pkt)(struct prestera_device *dev);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /* called by device driver to pass event up to the higher layer */
95*4882a593Smuzhiyun int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size);
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun /* called by higher layer to send request to the firmware */
98*4882a593Smuzhiyun int (*send_req)(struct prestera_device *dev, void *in_msg,
99*4882a593Smuzhiyun size_t in_size, void *out_msg, size_t out_size,
100*4882a593Smuzhiyun unsigned int wait);
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun enum prestera_event_type {
104*4882a593Smuzhiyun PRESTERA_EVENT_TYPE_UNSPEC,
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun PRESTERA_EVENT_TYPE_PORT,
107*4882a593Smuzhiyun PRESTERA_EVENT_TYPE_FDB,
108*4882a593Smuzhiyun PRESTERA_EVENT_TYPE_RXTX,
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun PRESTERA_EVENT_TYPE_MAX
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun enum prestera_rxtx_event_id {
114*4882a593Smuzhiyun PRESTERA_RXTX_EVENT_UNSPEC,
115*4882a593Smuzhiyun PRESTERA_RXTX_EVENT_RCV_PKT,
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun enum prestera_port_event_id {
119*4882a593Smuzhiyun PRESTERA_PORT_EVENT_UNSPEC,
120*4882a593Smuzhiyun PRESTERA_PORT_EVENT_STATE_CHANGED,
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun struct prestera_port_event {
124*4882a593Smuzhiyun u32 port_id;
125*4882a593Smuzhiyun union {
126*4882a593Smuzhiyun u32 oper_state;
127*4882a593Smuzhiyun } data;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun enum prestera_fdb_event_id {
131*4882a593Smuzhiyun PRESTERA_FDB_EVENT_UNSPEC,
132*4882a593Smuzhiyun PRESTERA_FDB_EVENT_LEARNED,
133*4882a593Smuzhiyun PRESTERA_FDB_EVENT_AGED,
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun struct prestera_fdb_event {
137*4882a593Smuzhiyun u32 port_id;
138*4882a593Smuzhiyun u32 vid;
139*4882a593Smuzhiyun union {
140*4882a593Smuzhiyun u8 mac[ETH_ALEN];
141*4882a593Smuzhiyun } data;
142*4882a593Smuzhiyun };
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun struct prestera_event {
145*4882a593Smuzhiyun u16 id;
146*4882a593Smuzhiyun union {
147*4882a593Smuzhiyun struct prestera_port_event port_evt;
148*4882a593Smuzhiyun struct prestera_fdb_event fdb_evt;
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun struct prestera_switchdev;
153*4882a593Smuzhiyun struct prestera_rxtx;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun struct prestera_switch {
156*4882a593Smuzhiyun struct prestera_device *dev;
157*4882a593Smuzhiyun struct prestera_switchdev *swdev;
158*4882a593Smuzhiyun struct prestera_rxtx *rxtx;
159*4882a593Smuzhiyun struct list_head event_handlers;
160*4882a593Smuzhiyun struct notifier_block netdev_nb;
161*4882a593Smuzhiyun char base_mac[ETH_ALEN];
162*4882a593Smuzhiyun struct list_head port_list;
163*4882a593Smuzhiyun rwlock_t port_list_lock;
164*4882a593Smuzhiyun u32 port_count;
165*4882a593Smuzhiyun u32 mtu_min;
166*4882a593Smuzhiyun u32 mtu_max;
167*4882a593Smuzhiyun u8 id;
168*4882a593Smuzhiyun };
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun struct prestera_rxtx_params {
171*4882a593Smuzhiyun bool use_sdma;
172*4882a593Smuzhiyun u32 map_addr;
173*4882a593Smuzhiyun };
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun #define prestera_dev(sw) ((sw)->dev->dev)
176*4882a593Smuzhiyun
prestera_write(const struct prestera_switch * sw,unsigned int reg,u32 val)177*4882a593Smuzhiyun static inline void prestera_write(const struct prestera_switch *sw,
178*4882a593Smuzhiyun unsigned int reg, u32 val)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun writel(val, sw->dev->pp_regs + reg);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
prestera_read(const struct prestera_switch * sw,unsigned int reg)183*4882a593Smuzhiyun static inline u32 prestera_read(const struct prestera_switch *sw,
184*4882a593Smuzhiyun unsigned int reg)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun return readl(sw->dev->pp_regs + reg);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun int prestera_device_register(struct prestera_device *dev);
190*4882a593Smuzhiyun void prestera_device_unregister(struct prestera_device *dev);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
193*4882a593Smuzhiyun u32 dev_id, u32 hw_id);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun int prestera_port_autoneg_set(struct prestera_port *port, bool enable,
196*4882a593Smuzhiyun u64 adver_link_modes, u8 adver_fec);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun int prestera_port_pvid_set(struct prestera_port *port, u16 vid);
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun bool prestera_netdev_check(const struct net_device *dev);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun #endif /* _PRESTERA_H_ */
207