1/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
2/*
3 * DSA driver for:
4 * Hirschmann Hellcreek TSN switch.
5 *
6 * Copyright (C) 2019-2021 Linutronix GmbH
7 * Author Kurt Kanzenbach <kurt@linutronix.de>
8 */
9
10#ifndef _HELLCREEK_H_
11#define _HELLCREEK_H_
12
13#include <linux/bitmap.h>
14#include <linux/bitops.h>
15#include <linux/device.h>
16#include <linux/kernel.h>
17#include <linux/mutex.h>
18#include <linux/workqueue.h>
19#include <linux/leds.h>
20#include <linux/platform_data/hirschmann-hellcreek.h>
21#include <linux/ptp_clock_kernel.h>
22#include <linux/timecounter.h>
23#include <net/dsa.h>
24#include <net/pkt_sched.h>
25
26/* Ports:
27 * - 0: CPU
28 * - 1: Tunnel
29 * - 2: TSN front port 1
30 * - 3: TSN front port 2
31 * - ...
32 */
33#define CPU_PORT 0
34#define TUNNEL_PORT 1
35
36#define HELLCREEK_VLAN_NO_MEMBER 0x0
37#define HELLCREEK_VLAN_UNTAGGED_MEMBER 0x1
38#define HELLCREEK_VLAN_TAGGED_MEMBER 0x3
39#define HELLCREEK_NUM_EGRESS_QUEUES 8
40#define HELLCREEK_DEFAULT_MAX_SDU 1536
41
42/* Register definitions */
43#define HR_MODID_C (0 * 2)
44#define HR_REL_L_C (1 * 2)
45#define HR_REL_H_C (2 * 2)
46#define HR_BLD_L_C (3 * 2)
47#define HR_BLD_H_C (4 * 2)
48#define HR_CTRL_C (5 * 2)
49#define HR_CTRL_C_READY BIT(14)
50#define HR_CTRL_C_TRANSITION BIT(13)
51#define HR_CTRL_C_ENABLE BIT(0)
52
53#define HR_PSEL (0xa6 * 2)
54#define HR_PSEL_PTWSEL_SHIFT 4
55#define HR_PSEL_PTWSEL_MASK GENMASK(5, 4)
56#define HR_PSEL_PRTCWSEL_SHIFT 0
57#define HR_PSEL_PRTCWSEL_MASK GENMASK(2, 0)
58
59#define HR_PTCFG (0xa7 * 2)
60#define HR_PTCFG_MLIMIT_EN BIT(13)
61#define HR_PTCFG_UMC_FLT BIT(10)
62#define HR_PTCFG_UUC_FLT BIT(9)
63#define HR_PTCFG_UNTRUST BIT(8)
64#define HR_PTCFG_TAG_REQUIRED BIT(7)
65#define HR_PTCFG_PPRIO_SHIFT 4
66#define HR_PTCFG_PPRIO_MASK GENMASK(6, 4)
67#define HR_PTCFG_INGRESSFLT BIT(3)
68#define HR_PTCFG_BLOCKED BIT(2)
69#define HR_PTCFG_LEARNING_EN BIT(1)
70#define HR_PTCFG_ADMIN_EN BIT(0)
71
72#define HR_PRTCCFG (0xa8 * 2)
73#define HR_PRTCCFG_PCP_TC_MAP_SHIFT 0
74#define HR_PRTCCFG_PCP_TC_MAP_MASK GENMASK(2, 0)
75
76#define HR_PTPRTCCFG (0xa9 * 2)
77#define HR_PTPRTCCFG_SET_QTRACK BIT(15)
78#define HR_PTPRTCCFG_REJECT BIT(14)
79#define HR_PTPRTCCFG_MAXSDU_SHIFT 0
80#define HR_PTPRTCCFG_MAXSDU_MASK GENMASK(10, 0)
81
82#define HR_CSEL (0x8d * 2)
83#define HR_CSEL_SHIFT 0
84#define HR_CSEL_MASK GENMASK(7, 0)
85#define HR_CRDL (0x8e * 2)
86#define HR_CRDH (0x8f * 2)
87
88#define HR_SWTRC_CFG (0x90 * 2)
89#define HR_SWTRC0 (0x91 * 2)
90#define HR_SWTRC1 (0x92 * 2)
91#define HR_PFREE (0x93 * 2)
92#define HR_MFREE (0x94 * 2)
93
94#define HR_FDBAGE (0x97 * 2)
95#define HR_FDBMAX (0x98 * 2)
96#define HR_FDBRDL (0x99 * 2)
97#define HR_FDBRDM (0x9a * 2)
98#define HR_FDBRDH (0x9b * 2)
99
100#define HR_FDBMDRD (0x9c * 2)
101#define HR_FDBMDRD_PORTMASK_SHIFT 0
102#define HR_FDBMDRD_PORTMASK_MASK GENMASK(3, 0)
103#define HR_FDBMDRD_AGE_SHIFT 4
104#define HR_FDBMDRD_AGE_MASK GENMASK(7, 4)
105#define HR_FDBMDRD_OBT BIT(8)
106#define HR_FDBMDRD_PASS_BLOCKED BIT(9)
107#define HR_FDBMDRD_STATIC BIT(11)
108#define HR_FDBMDRD_REPRIO_TC_SHIFT 12
109#define HR_FDBMDRD_REPRIO_TC_MASK GENMASK(14, 12)
110#define HR_FDBMDRD_REPRIO_EN BIT(15)
111
112#define HR_FDBWDL (0x9d * 2)
113#define HR_FDBWDM (0x9e * 2)
114#define HR_FDBWDH (0x9f * 2)
115#define HR_FDBWRM0 (0xa0 * 2)
116#define HR_FDBWRM0_PORTMASK_SHIFT 0
117#define HR_FDBWRM0_PORTMASK_MASK GENMASK(3, 0)
118#define HR_FDBWRM0_OBT BIT(8)
119#define HR_FDBWRM0_PASS_BLOCKED BIT(9)
120#define HR_FDBWRM0_REPRIO_TC_SHIFT 12
121#define HR_FDBWRM0_REPRIO_TC_MASK GENMASK(14, 12)
122#define HR_FDBWRM0_REPRIO_EN BIT(15)
123#define HR_FDBWRM1 (0xa1 * 2)
124
125#define HR_FDBWRCMD (0xa2 * 2)
126#define HR_FDBWRCMD_FDBDEL BIT(9)
127
128#define HR_SWCFG (0xa3 * 2)
129#define HR_SWCFG_GM_STATEMD BIT(15)
130#define HR_SWCFG_LAS_MODE_SHIFT 12
131#define HR_SWCFG_LAS_MODE_MASK GENMASK(13, 12)
132#define HR_SWCFG_LAS_OFF (0x00)
133#define HR_SWCFG_LAS_ON (0x01)
134#define HR_SWCFG_LAS_STATIC (0x10)
135#define HR_SWCFG_CT_EN BIT(11)
136#define HR_SWCFG_VLAN_UNAWARE BIT(10)
137#define HR_SWCFG_ALWAYS_OBT BIT(9)
138#define HR_SWCFG_FDBAGE_EN BIT(5)
139#define HR_SWCFG_FDBLRN_EN BIT(4)
140
141#define HR_SWSTAT (0xa4 * 2)
142#define HR_SWSTAT_FAIL BIT(4)
143#define HR_SWSTAT_BUSY BIT(0)
144
145#define HR_SWCMD (0xa5 * 2)
146#define HW_SWCMD_FLUSH BIT(0)
147
148#define HR_VIDCFG (0xaa * 2)
149#define HR_VIDCFG_VID_SHIFT 0
150#define HR_VIDCFG_VID_MASK GENMASK(11, 0)
151#define HR_VIDCFG_PVID BIT(12)
152
153#define HR_VIDMBRCFG (0xab * 2)
154#define HR_VIDMBRCFG_P0MBR_SHIFT 0
155#define HR_VIDMBRCFG_P0MBR_MASK GENMASK(1, 0)
156#define HR_VIDMBRCFG_P1MBR_SHIFT 2
157#define HR_VIDMBRCFG_P1MBR_MASK GENMASK(3, 2)
158#define HR_VIDMBRCFG_P2MBR_SHIFT 4
159#define HR_VIDMBRCFG_P2MBR_MASK GENMASK(5, 4)
160#define HR_VIDMBRCFG_P3MBR_SHIFT 6
161#define HR_VIDMBRCFG_P3MBR_MASK GENMASK(7, 6)
162
163#define HR_FEABITS0 (0xac * 2)
164#define HR_FEABITS0_FDBBINS_SHIFT 4
165#define HR_FEABITS0_FDBBINS_MASK GENMASK(7, 4)
166#define HR_FEABITS0_PCNT_SHIFT 8
167#define HR_FEABITS0_PCNT_MASK GENMASK(11, 8)
168#define HR_FEABITS0_MCNT_SHIFT 12
169#define HR_FEABITS0_MCNT_MASK GENMASK(15, 12)
170
171#define TR_QTRACK (0xb1 * 2)
172#define TR_TGDVER (0xb3 * 2)
173#define TR_TGDVER_REV_MIN_MASK GENMASK(7, 0)
174#define TR_TGDVER_REV_MIN_SHIFT 0
175#define TR_TGDVER_REV_MAJ_MASK GENMASK(15, 8)
176#define TR_TGDVER_REV_MAJ_SHIFT 8
177#define TR_TGDSEL (0xb4 * 2)
178#define TR_TGDSEL_TDGSEL_MASK GENMASK(1, 0)
179#define TR_TGDSEL_TDGSEL_SHIFT 0
180#define TR_TGDCTRL (0xb5 * 2)
181#define TR_TGDCTRL_GATE_EN BIT(0)
182#define TR_TGDCTRL_CYC_SNAP BIT(4)
183#define TR_TGDCTRL_SNAP_EST BIT(5)
184#define TR_TGDCTRL_ADMINGATESTATES_MASK GENMASK(15, 8)
185#define TR_TGDCTRL_ADMINGATESTATES_SHIFT 8
186#define TR_TGDSTAT0 (0xb6 * 2)
187#define TR_TGDSTAT1 (0xb7 * 2)
188#define TR_ESTWRL (0xb8 * 2)
189#define TR_ESTWRH (0xb9 * 2)
190#define TR_ESTCMD (0xba * 2)
191#define TR_ESTCMD_ESTSEC_MASK GENMASK(2, 0)
192#define TR_ESTCMD_ESTSEC_SHIFT 0
193#define TR_ESTCMD_ESTARM BIT(4)
194#define TR_ESTCMD_ESTSWCFG BIT(5)
195#define TR_EETWRL (0xbb * 2)
196#define TR_EETWRH (0xbc * 2)
197#define TR_EETCMD (0xbd * 2)
198#define TR_EETCMD_EETSEC_MASK GEMASK(2, 0)
199#define TR_EETCMD_EETSEC_SHIFT 0
200#define TR_EETCMD_EETARM BIT(4)
201#define TR_CTWRL (0xbe * 2)
202#define TR_CTWRH (0xbf * 2)
203#define TR_LCNSL (0xc1 * 2)
204#define TR_LCNSH (0xc2 * 2)
205#define TR_LCS (0xc3 * 2)
206#define TR_GCLDAT (0xc4 * 2)
207#define TR_GCLDAT_GCLWRGATES_MASK GENMASK(7, 0)
208#define TR_GCLDAT_GCLWRGATES_SHIFT 0
209#define TR_GCLDAT_GCLWRLAST BIT(8)
210#define TR_GCLDAT_GCLOVRI BIT(9)
211#define TR_GCLTIL (0xc5 * 2)
212#define TR_GCLTIH (0xc6 * 2)
213#define TR_GCLCMD (0xc7 * 2)
214#define TR_GCLCMD_GCLWRADR_MASK GENMASK(7, 0)
215#define TR_GCLCMD_GCLWRADR_SHIFT 0
216#define TR_GCLCMD_INIT_GATE_STATES_MASK GENMASK(15, 8)
217#define TR_GCLCMD_INIT_GATE_STATES_SHIFT 8
218
219struct hellcreek_counter {
220 u8 offset;
221 const char *name;
222};
223
224struct hellcreek;
225
226/* State flags for hellcreek_port_hwtstamp::state */
227enum {
228 HELLCREEK_HWTSTAMP_ENABLED,
229 HELLCREEK_HWTSTAMP_TX_IN_PROGRESS,
230};
231
232/* A structure to hold hardware timestamping information per port */
233struct hellcreek_port_hwtstamp {
234 /* Timestamping state */
235 unsigned long state;
236
237 /* Resources for receive timestamping */
238 struct sk_buff_head rx_queue; /* For synchronization messages */
239
240 /* Resources for transmit timestamping */
241 unsigned long tx_tstamp_start;
242 struct sk_buff *tx_skb;
243
244 /* Current timestamp configuration */
245 struct hwtstamp_config tstamp_config;
246};
247
248struct hellcreek_port {
249 struct hellcreek *hellcreek;
250 unsigned long *vlan_dev_bitmap;
251 int port;
252 u16 ptcfg; /* ptcfg shadow */
253 u64 *counter_values;
254
255 /* Per-port timestamping resources */
256 struct hellcreek_port_hwtstamp port_hwtstamp;
257
258 /* Per-port Qbv schedule information */
259 struct tc_taprio_qopt_offload *current_schedule;
260 struct delayed_work schedule_work;
261};
262
263struct hellcreek_fdb_entry {
264 size_t idx;
265 unsigned char mac[ETH_ALEN];
266 u8 portmask;
267 u8 age;
268 u8 is_obt;
269 u8 pass_blocked;
270 u8 is_static;
271 u8 reprio_tc;
272 u8 reprio_en;
273};
274
275struct hellcreek {
276 const struct hellcreek_platform_data *pdata;
277 struct device *dev;
278 struct dsa_switch *ds;
279 struct ptp_clock *ptp_clock;
280 struct ptp_clock_info ptp_clock_info;
281 struct hellcreek_port *ports;
282 struct delayed_work overflow_work;
283 struct led_classdev led_is_gm;
284 struct led_classdev led_sync_good;
285 struct mutex reg_lock; /* Switch IP register lock */
286 struct mutex vlan_lock; /* VLAN bitmaps lock */
287 struct mutex ptp_lock; /* PTP IP register lock */
288 struct devlink_region *vlan_region;
289 struct devlink_region *fdb_region;
290 void __iomem *base;
291 void __iomem *ptp_base;
292 u16 swcfg; /* swcfg shadow */
293 u8 *vidmbrcfg; /* vidmbrcfg shadow */
294 u64 seconds; /* PTP seconds */
295 u64 last_ts; /* Used for overflow detection */
296 u16 status_out; /* ptp.status_out shadow */
297 size_t fdb_entries;
298};
299
300/* A Qbv schedule can only started up to 8 seconds in the future. If the delta
301 * between the base time and the current ptp time is larger than 8 seconds, then
302 * use periodic work to check for the schedule to be started. The delayed work
303 * cannot be armed directly to $base_time - 8 + X, because for large deltas the
304 * PTP frequency matters.
305 */
306#define HELLCREEK_SCHEDULE_PERIOD (2 * HZ)
307#define dw_to_hellcreek_port(dw) \
308 container_of(dw, struct hellcreek_port, schedule_work)
309
310/* Devlink resources */
311enum hellcreek_devlink_resource_id {
312 HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,
313 HELLCREEK_DEVLINK_PARAM_ID_FDB_TABLE,
314};
315
316struct hellcreek_devlink_vlan_entry {
317 u16 vid;
318 u16 member;
319};
320
321#endif /* _HELLCREEK_H_ */
322

source code of linux/drivers/net/dsa/hirschmann/hellcreek.h