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