1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2015 CMC Electronics, Inc.
7 * Copyright (c) 2017 Savoir-faire Linux, Inc.
8 */
9
10#include <linux/bitfield.h>
11#include <linux/interrupt.h>
12#include <linux/irqdomain.h>
13
14#include "chip.h"
15#include "global1.h"
16
17/* Offset 0x02: VTU FID Register */
18
19static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
20				     struct mv88e6xxx_vtu_entry *entry)
21{
22	u16 val;
23	int err;
24
25	err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
26	if (err)
27		return err;
28
29	entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
30
31	return 0;
32}
33
34static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
35				      struct mv88e6xxx_vtu_entry *entry)
36{
37	u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
38
39	return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val);
40}
41
42/* Offset 0x03: VTU SID Register */
43
44static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip,
45				     struct mv88e6xxx_vtu_entry *entry)
46{
47	u16 val;
48	int err;
49
50	err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val);
51	if (err)
52		return err;
53
54	entry->sid = val & MV88E6352_G1_VTU_SID_MASK;
55
56	return 0;
57}
58
59static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip,
60				      struct mv88e6xxx_vtu_entry *entry)
61{
62	u16 val = entry->sid & MV88E6352_G1_VTU_SID_MASK;
63
64	return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val);
65}
66
67/* Offset 0x05: VTU Operation Register */
68
69static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
70{
71	int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
72
73	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
74}
75
76static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
77{
78	int err;
79
80	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
81				 MV88E6XXX_G1_VTU_OP_BUSY | op);
82	if (err)
83		return err;
84
85	return mv88e6xxx_g1_vtu_op_wait(chip);
86}
87
88/* Offset 0x06: VTU VID Register */
89
90static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
91				     struct mv88e6xxx_vtu_entry *entry)
92{
93	u16 val;
94	int err;
95
96	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
97	if (err)
98		return err;
99
100	entry->vid = val & 0xfff;
101
102	if (val & MV88E6390_G1_VTU_VID_PAGE)
103		entry->vid |= 0x1000;
104
105	entry->valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
106
107	return 0;
108}
109
110static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
111				      struct mv88e6xxx_vtu_entry *entry)
112{
113	u16 val = entry->vid & 0xfff;
114
115	if (entry->vid & 0x1000)
116		val |= MV88E6390_G1_VTU_VID_PAGE;
117
118	if (entry->valid)
119		val |= MV88E6XXX_G1_VTU_VID_VALID;
120
121	return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
122}
123
124/* Offset 0x07: VTU/STU Data Register 1
125 * Offset 0x08: VTU/STU Data Register 2
126 * Offset 0x09: VTU/STU Data Register 3
127 */
128static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
129					  u16 *regs)
130{
131	int i;
132
133	/* Read all 3 VTU/STU Data registers */
134	for (i = 0; i < 3; ++i) {
135		u16 *reg = &regs[i];
136		int err;
137
138		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
139		if (err)
140			return err;
141	}
142
143	return 0;
144}
145
146static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
147				      struct mv88e6xxx_vtu_entry *entry)
148{
149	u16 regs[3];
150	int err;
151	int i;
152
153	err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
154	if (err)
155		return err;
156
157	/* Extract MemberTag data */
158	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
159		unsigned int member_offset = (i % 4) * 4;
160
161		entry->member[i] = (regs[i / 4] >> member_offset) & 0x3;
162	}
163
164	return 0;
165}
166
167static int mv88e6185_g1_stu_data_read(struct mv88e6xxx_chip *chip,
168				      struct mv88e6xxx_vtu_entry *entry)
169{
170	u16 regs[3];
171	int err;
172	int i;
173
174	err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
175	if (err)
176		return err;
177
178	/* Extract PortState data */
179	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
180		unsigned int state_offset = (i % 4) * 4 + 2;
181
182		entry->state[i] = (regs[i / 4] >> state_offset) & 0x3;
183	}
184
185	return 0;
186}
187
188static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
189				       struct mv88e6xxx_vtu_entry *entry)
190{
191	u16 regs[3] = { 0 };
192	int i;
193
194	/* Insert MemberTag and PortState data */
195	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
196		unsigned int member_offset = (i % 4) * 4;
197		unsigned int state_offset = member_offset + 2;
198
199		regs[i / 4] |= (entry->member[i] & 0x3) << member_offset;
200		regs[i / 4] |= (entry->state[i] & 0x3) << state_offset;
201	}
202
203	/* Write all 3 VTU/STU Data registers */
204	for (i = 0; i < 3; ++i) {
205		u16 reg = regs[i];
206		int err;
207
208		err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
209		if (err)
210			return err;
211	}
212
213	return 0;
214}
215
216static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
217{
218	u16 regs[2];
219	int i;
220
221	/* Read the 2 VTU/STU Data registers */
222	for (i = 0; i < 2; ++i) {
223		u16 *reg = &regs[i];
224		int err;
225
226		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
227		if (err)
228			return err;
229	}
230
231	/* Extract data */
232	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
233		unsigned int offset = (i % 8) * 2;
234
235		data[i] = (regs[i / 8] >> offset) & 0x3;
236	}
237
238	return 0;
239}
240
241static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
242{
243	u16 regs[2] = { 0 };
244	int i;
245
246	/* Insert data */
247	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
248		unsigned int offset = (i % 8) * 2;
249
250		regs[i / 8] |= (data[i] & 0x3) << offset;
251	}
252
253	/* Write the 2 VTU/STU Data registers */
254	for (i = 0; i < 2; ++i) {
255		u16 reg = regs[i];
256		int err;
257
258		err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
259		if (err)
260			return err;
261	}
262
263	return 0;
264}
265
266/* VLAN Translation Unit Operations */
267
268static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip,
269					struct mv88e6xxx_vtu_entry *entry)
270{
271	int err;
272
273	err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
274	if (err)
275		return err;
276
277	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
278	if (err)
279		return err;
280
281	err = mv88e6xxx_g1_vtu_sid_read(chip, entry);
282	if (err)
283		return err;
284
285	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
286}
287
288static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip,
289				    struct mv88e6xxx_vtu_entry *vtu)
290{
291	struct mv88e6xxx_vtu_entry stu;
292	int err;
293
294	err = mv88e6xxx_g1_vtu_sid_read(chip, vtu);
295	if (err)
296		return err;
297
298	stu.sid = vtu->sid - 1;
299
300	err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu);
301	if (err)
302		return err;
303
304	if (stu.sid != vtu->sid || !stu.valid)
305		return -EINVAL;
306
307	return 0;
308}
309
310static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
311				    struct mv88e6xxx_vtu_entry *entry)
312{
313	int err;
314
315	err = mv88e6xxx_g1_vtu_op_wait(chip);
316	if (err)
317		return err;
318
319	/* To get the next higher active VID, the VTU GetNext operation can be
320	 * started again without setting the VID registers since it already
321	 * contains the last VID.
322	 *
323	 * To save a few hardware accesses and abstract this to the caller,
324	 * write the VID only once, when the entry is given as invalid.
325	 */
326	if (!entry->valid) {
327		err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
328		if (err)
329			return err;
330	}
331
332	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
333	if (err)
334		return err;
335
336	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
337}
338
339int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
340			     struct mv88e6xxx_vtu_entry *entry)
341{
342	u16 val;
343	int err;
344
345	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
346	if (err)
347		return err;
348
349	if (entry->valid) {
350		err = mv88e6185_g1_vtu_data_read(chip, entry);
351		if (err)
352			return err;
353
354		err = mv88e6185_g1_stu_data_read(chip, entry);
355		if (err)
356			return err;
357
358		/* VTU DBNum[3:0] are located in VTU Operation 3:0
359		 * VTU DBNum[5:4] are located in VTU Operation 9:8
360		 */
361		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
362		if (err)
363			return err;
364
365		entry->fid = val & 0x000f;
366		entry->fid |= (val & 0x0300) >> 4;
367	}
368
369	return 0;
370}
371
372int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
373			     struct mv88e6xxx_vtu_entry *entry)
374{
375	u16 val;
376	int err;
377
378	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
379	if (err)
380		return err;
381
382	if (entry->valid) {
383		err = mv88e6185_g1_vtu_data_read(chip, entry);
384		if (err)
385			return err;
386
387		err = mv88e6185_g1_stu_data_read(chip, entry);
388		if (err)
389			return err;
390
391		/* VTU DBNum[3:0] are located in VTU Operation 3:0
392		 * VTU DBNum[7:4] are located in VTU Operation 11:8
393		 */
394		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
395		if (err)
396			return err;
397
398		entry->fid = val & 0x000f;
399		entry->fid |= (val & 0x0f00) >> 4;
400	}
401
402	return 0;
403}
404
405int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
406			     struct mv88e6xxx_vtu_entry *entry)
407{
408	int err;
409
410	/* Fetch VLAN MemberTag data from the VTU */
411	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
412	if (err)
413		return err;
414
415	if (entry->valid) {
416		err = mv88e6185_g1_vtu_data_read(chip, entry);
417		if (err)
418			return err;
419
420		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
421		if (err)
422			return err;
423
424		/* Fetch VLAN PortState data from the STU */
425		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
426		if (err)
427			return err;
428
429		err = mv88e6185_g1_stu_data_read(chip, entry);
430		if (err)
431			return err;
432	}
433
434	return 0;
435}
436
437int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
438			     struct mv88e6xxx_vtu_entry *entry)
439{
440	int err;
441
442	/* Fetch VLAN MemberTag data from the VTU */
443	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
444	if (err)
445		return err;
446
447	if (entry->valid) {
448		err = mv88e6390_g1_vtu_data_read(chip, entry->member);
449		if (err)
450			return err;
451
452		/* Fetch VLAN PortState data from the STU */
453		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
454		if (err)
455			return err;
456
457		err = mv88e6390_g1_vtu_data_read(chip, entry->state);
458		if (err)
459			return err;
460
461		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
462		if (err)
463			return err;
464	}
465
466	return 0;
467}
468
469int mv88e6250_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
470			       struct mv88e6xxx_vtu_entry *entry)
471{
472	u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
473	int err;
474
475	err = mv88e6xxx_g1_vtu_op_wait(chip);
476	if (err)
477		return err;
478
479	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
480	if (err)
481		return err;
482
483	if (entry->valid) {
484		err = mv88e6185_g1_vtu_data_write(chip, entry);
485		if (err)
486			return err;
487
488		/* VTU DBNum[3:0] are located in VTU Operation 3:0
489		 * VTU DBNum[5:4] are located in VTU Operation 9:8
490		 */
491		op |= entry->fid & 0x000f;
492		op |= (entry->fid & 0x0030) << 4;
493	}
494
495	return mv88e6xxx_g1_vtu_op(chip, op);
496}
497
498int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
499			       struct mv88e6xxx_vtu_entry *entry)
500{
501	u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
502	int err;
503
504	err = mv88e6xxx_g1_vtu_op_wait(chip);
505	if (err)
506		return err;
507
508	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
509	if (err)
510		return err;
511
512	if (entry->valid) {
513		err = mv88e6185_g1_vtu_data_write(chip, entry);
514		if (err)
515			return err;
516
517		/* VTU DBNum[3:0] are located in VTU Operation 3:0
518		 * VTU DBNum[7:4] are located in VTU Operation 11:8
519		 */
520		op |= entry->fid & 0x000f;
521		op |= (entry->fid & 0x00f0) << 4;
522	}
523
524	return mv88e6xxx_g1_vtu_op(chip, op);
525}
526
527int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
528			       struct mv88e6xxx_vtu_entry *entry)
529{
530	int err;
531
532	err = mv88e6xxx_g1_vtu_op_wait(chip);
533	if (err)
534		return err;
535
536	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
537	if (err)
538		return err;
539
540	if (entry->valid) {
541		/* Write MemberTag and PortState data */
542		err = mv88e6185_g1_vtu_data_write(chip, entry);
543		if (err)
544			return err;
545
546		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
547		if (err)
548			return err;
549
550		/* Load STU entry */
551		err = mv88e6xxx_g1_vtu_op(chip,
552					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
553		if (err)
554			return err;
555
556		err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
557		if (err)
558			return err;
559	}
560
561	/* Load/Purge VTU entry */
562	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
563}
564
565int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
566			       struct mv88e6xxx_vtu_entry *entry)
567{
568	int err;
569
570	err = mv88e6xxx_g1_vtu_op_wait(chip);
571	if (err)
572		return err;
573
574	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
575	if (err)
576		return err;
577
578	if (entry->valid) {
579		/* Write PortState data */
580		err = mv88e6390_g1_vtu_data_write(chip, entry->state);
581		if (err)
582			return err;
583
584		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
585		if (err)
586			return err;
587
588		/* Load STU entry */
589		err = mv88e6xxx_g1_vtu_op(chip,
590					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
591		if (err)
592			return err;
593
594		/* Write MemberTag data */
595		err = mv88e6390_g1_vtu_data_write(chip, entry->member);
596		if (err)
597			return err;
598
599		err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
600		if (err)
601			return err;
602	}
603
604	/* Load/Purge VTU entry */
605	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
606}
607
608int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
609{
610	int err;
611
612	err = mv88e6xxx_g1_vtu_op_wait(chip);
613	if (err)
614		return err;
615
616	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
617}
618
619static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
620{
621	struct mv88e6xxx_chip *chip = dev_id;
622	struct mv88e6xxx_vtu_entry entry;
623	int spid;
624	int err;
625	u16 val;
626
627	mv88e6xxx_reg_lock(chip);
628
629	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
630	if (err)
631		goto out;
632
633	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
634	if (err)
635		goto out;
636
637	err = mv88e6xxx_g1_vtu_vid_read(chip, &entry);
638	if (err)
639		goto out;
640
641	spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
642
643	if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
644		dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
645				    entry.vid, spid);
646		chip->ports[spid].vtu_member_violation++;
647	}
648
649	if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
650		dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
651				    entry.vid, spid);
652		chip->ports[spid].vtu_miss_violation++;
653	}
654
655	mv88e6xxx_reg_unlock(chip);
656
657	return IRQ_HANDLED;
658
659out:
660	mv88e6xxx_reg_unlock(chip);
661
662	dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
663		err);
664
665	return IRQ_HANDLED;
666}
667
668int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
669{
670	int err;
671
672	chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
673					      MV88E6XXX_G1_STS_IRQ_VTU_PROB);
674	if (chip->vtu_prob_irq < 0)
675		return chip->vtu_prob_irq;
676
677	snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name),
678		 "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev));
679
680	err = request_threaded_irq(chip->vtu_prob_irq, NULL,
681				   mv88e6xxx_g1_vtu_prob_irq_thread_fn,
682				   IRQF_ONESHOT, chip->vtu_prob_irq_name,
683				   chip);
684	if (err)
685		irq_dispose_mapping(chip->vtu_prob_irq);
686
687	return err;
688}
689
690void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
691{
692	free_irq(chip->vtu_prob_irq, chip);
693	irq_dispose_mapping(chip->vtu_prob_irq);
694}
695