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
17struct prestera_fw_rev {
18	u16 maj;
19	u16 min;
20	u16 sub;
21};
22
23struct 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
56struct prestera_port_caps {
57	u64 supp_link_modes;
58	u8 supp_fec;
59	u8 type;
60	u8 transceiver;
61};
62
63struct prestera_port {
64	struct net_device *dev;
65	struct prestera_switch *sw;
66	struct devlink_port dl_port;
67	u32 id;
68	u32 hw_id;
69	u32 dev_id;
70	u16 fp_id;
71	u16 pvid;
72	bool autoneg;
73	u64 adver_link_modes;
74	u8 adver_fec;
75	struct prestera_port_caps caps;
76	struct list_head list;
77	struct list_head vlans_list;
78	struct {
79		struct prestera_port_stats stats;
80		struct delayed_work caching_dw;
81	} cached_hw_stats;
82};
83
84struct prestera_device {
85	struct device *dev;
86	u8 __iomem *ctl_regs;
87	u8 __iomem *pp_regs;
88	struct prestera_fw_rev fw_rev;
89	void *priv;
90
91	/* called by device driver to handle received packets */
92	void (*recv_pkt)(struct prestera_device *dev);
93
94	/* called by device driver to pass event up to the higher layer */
95	int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size);
96
97	/* called by higher layer to send request to the firmware */
98	int (*send_req)(struct prestera_device *dev, void *in_msg,
99			size_t in_size, void *out_msg, size_t out_size,
100			unsigned int wait);
101};
102
103enum prestera_event_type {
104	PRESTERA_EVENT_TYPE_UNSPEC,
105
106	PRESTERA_EVENT_TYPE_PORT,
107	PRESTERA_EVENT_TYPE_FDB,
108	PRESTERA_EVENT_TYPE_RXTX,
109
110	PRESTERA_EVENT_TYPE_MAX
111};
112
113enum prestera_rxtx_event_id {
114	PRESTERA_RXTX_EVENT_UNSPEC,
115	PRESTERA_RXTX_EVENT_RCV_PKT,
116};
117
118enum prestera_port_event_id {
119	PRESTERA_PORT_EVENT_UNSPEC,
120	PRESTERA_PORT_EVENT_STATE_CHANGED,
121};
122
123struct prestera_port_event {
124	u32 port_id;
125	union {
126		u32 oper_state;
127	} data;
128};
129
130enum prestera_fdb_event_id {
131	PRESTERA_FDB_EVENT_UNSPEC,
132	PRESTERA_FDB_EVENT_LEARNED,
133	PRESTERA_FDB_EVENT_AGED,
134};
135
136struct prestera_fdb_event {
137	u32 port_id;
138	u32 vid;
139	union {
140		u8 mac[ETH_ALEN];
141	} data;
142};
143
144struct prestera_event {
145	u16 id;
146	union {
147		struct prestera_port_event port_evt;
148		struct prestera_fdb_event fdb_evt;
149	};
150};
151
152struct prestera_switchdev;
153struct prestera_rxtx;
154
155struct prestera_switch {
156	struct prestera_device *dev;
157	struct prestera_switchdev *swdev;
158	struct prestera_rxtx *rxtx;
159	struct list_head event_handlers;
160	struct notifier_block netdev_nb;
161	char base_mac[ETH_ALEN];
162	struct list_head port_list;
163	rwlock_t port_list_lock;
164	u32 port_count;
165	u32 mtu_min;
166	u32 mtu_max;
167	u8 id;
168};
169
170struct prestera_rxtx_params {
171	bool use_sdma;
172	u32 map_addr;
173};
174
175#define prestera_dev(sw)		((sw)->dev->dev)
176
177static inline void prestera_write(const struct prestera_switch *sw,
178				  unsigned int reg, u32 val)
179{
180	writel(val, sw->dev->pp_regs + reg);
181}
182
183static inline u32 prestera_read(const struct prestera_switch *sw,
184				unsigned int reg)
185{
186	return readl(sw->dev->pp_regs + reg);
187}
188
189int prestera_device_register(struct prestera_device *dev);
190void prestera_device_unregister(struct prestera_device *dev);
191
192struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
193						 u32 dev_id, u32 hw_id);
194
195int prestera_port_autoneg_set(struct prestera_port *port, bool enable,
196			      u64 adver_link_modes, u8 adver_fec);
197
198struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id);
199
200struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev);
201
202int prestera_port_pvid_set(struct prestera_port *port, u16 vid);
203
204bool prestera_netdev_check(const struct net_device *dev);
205
206#endif /* _PRESTERA_H_ */
207