xref: /linux/drivers/net/dsa/mv88e6xxx/global1_vtu.c (revision 52338415)
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 
19 static 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 
34 static 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 
44 static 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 
59 static 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 
69 static 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 
76 static 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 
90 static 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 
110 static 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  */
128 
129 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
130 				      struct mv88e6xxx_vtu_entry *entry)
131 {
132 	u16 regs[3];
133 	int i;
134 
135 	/* Read all 3 VTU/STU Data registers */
136 	for (i = 0; i < 3; ++i) {
137 		u16 *reg = &regs[i];
138 		int err;
139 
140 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
141 		if (err)
142 			return err;
143 	}
144 
145 	/* Extract MemberTag and PortState data */
146 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
147 		unsigned int member_offset = (i % 4) * 4;
148 		unsigned int state_offset = member_offset + 2;
149 
150 		entry->member[i] = (regs[i / 4] >> member_offset) & 0x3;
151 		entry->state[i] = (regs[i / 4] >> state_offset) & 0x3;
152 	}
153 
154 	return 0;
155 }
156 
157 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
158 				       struct mv88e6xxx_vtu_entry *entry)
159 {
160 	u16 regs[3] = { 0 };
161 	int i;
162 
163 	/* Insert MemberTag and PortState data */
164 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
165 		unsigned int member_offset = (i % 4) * 4;
166 		unsigned int state_offset = member_offset + 2;
167 
168 		regs[i / 4] |= (entry->member[i] & 0x3) << member_offset;
169 		regs[i / 4] |= (entry->state[i] & 0x3) << state_offset;
170 	}
171 
172 	/* Write all 3 VTU/STU Data registers */
173 	for (i = 0; i < 3; ++i) {
174 		u16 reg = regs[i];
175 		int err;
176 
177 		err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
178 		if (err)
179 			return err;
180 	}
181 
182 	return 0;
183 }
184 
185 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
186 {
187 	u16 regs[2];
188 	int i;
189 
190 	/* Read the 2 VTU/STU Data registers */
191 	for (i = 0; i < 2; ++i) {
192 		u16 *reg = &regs[i];
193 		int err;
194 
195 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
196 		if (err)
197 			return err;
198 	}
199 
200 	/* Extract data */
201 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
202 		unsigned int offset = (i % 8) * 2;
203 
204 		data[i] = (regs[i / 8] >> offset) & 0x3;
205 	}
206 
207 	return 0;
208 }
209 
210 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
211 {
212 	u16 regs[2] = { 0 };
213 	int i;
214 
215 	/* Insert data */
216 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
217 		unsigned int offset = (i % 8) * 2;
218 
219 		regs[i / 8] |= (data[i] & 0x3) << offset;
220 	}
221 
222 	/* Write the 2 VTU/STU Data registers */
223 	for (i = 0; i < 2; ++i) {
224 		u16 reg = regs[i];
225 		int err;
226 
227 		err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
228 		if (err)
229 			return err;
230 	}
231 
232 	return 0;
233 }
234 
235 /* VLAN Translation Unit Operations */
236 
237 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip,
238 					struct mv88e6xxx_vtu_entry *entry)
239 {
240 	int err;
241 
242 	err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
243 	if (err)
244 		return err;
245 
246 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
247 	if (err)
248 		return err;
249 
250 	err = mv88e6xxx_g1_vtu_sid_read(chip, entry);
251 	if (err)
252 		return err;
253 
254 	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
255 }
256 
257 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip,
258 				    struct mv88e6xxx_vtu_entry *vtu)
259 {
260 	struct mv88e6xxx_vtu_entry stu;
261 	int err;
262 
263 	err = mv88e6xxx_g1_vtu_sid_read(chip, vtu);
264 	if (err)
265 		return err;
266 
267 	stu.sid = vtu->sid - 1;
268 
269 	err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu);
270 	if (err)
271 		return err;
272 
273 	if (stu.sid != vtu->sid || !stu.valid)
274 		return -EINVAL;
275 
276 	return 0;
277 }
278 
279 static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
280 				    struct mv88e6xxx_vtu_entry *entry)
281 {
282 	int err;
283 
284 	err = mv88e6xxx_g1_vtu_op_wait(chip);
285 	if (err)
286 		return err;
287 
288 	/* To get the next higher active VID, the VTU GetNext operation can be
289 	 * started again without setting the VID registers since it already
290 	 * contains the last VID.
291 	 *
292 	 * To save a few hardware accesses and abstract this to the caller,
293 	 * write the VID only once, when the entry is given as invalid.
294 	 */
295 	if (!entry->valid) {
296 		err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
297 		if (err)
298 			return err;
299 	}
300 
301 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
302 	if (err)
303 		return err;
304 
305 	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
306 }
307 
308 int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
309 			     struct mv88e6xxx_vtu_entry *entry)
310 {
311 	u16 val;
312 	int err;
313 
314 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
315 	if (err)
316 		return err;
317 
318 	if (entry->valid) {
319 		err = mv88e6185_g1_vtu_data_read(chip, entry);
320 		if (err)
321 			return err;
322 
323 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
324 		 * VTU DBNum[5:4] are located in VTU Operation 9:8
325 		 */
326 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
327 		if (err)
328 			return err;
329 
330 		entry->fid = val & 0x000f;
331 		entry->fid |= (val & 0x0300) >> 4;
332 	}
333 
334 	return 0;
335 }
336 
337 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
338 			     struct mv88e6xxx_vtu_entry *entry)
339 {
340 	u16 val;
341 	int err;
342 
343 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
344 	if (err)
345 		return err;
346 
347 	if (entry->valid) {
348 		err = mv88e6185_g1_vtu_data_read(chip, entry);
349 		if (err)
350 			return err;
351 
352 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
353 		 * VTU DBNum[7:4] are located in VTU Operation 11:8
354 		 */
355 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
356 		if (err)
357 			return err;
358 
359 		entry->fid = val & 0x000f;
360 		entry->fid |= (val & 0x0f00) >> 4;
361 	}
362 
363 	return 0;
364 }
365 
366 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
367 			     struct mv88e6xxx_vtu_entry *entry)
368 {
369 	int err;
370 
371 	/* Fetch VLAN MemberTag data from the VTU */
372 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
373 	if (err)
374 		return err;
375 
376 	if (entry->valid) {
377 		/* Fetch (and mask) VLAN PortState data from the STU */
378 		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
379 		if (err)
380 			return err;
381 
382 		err = mv88e6185_g1_vtu_data_read(chip, entry);
383 		if (err)
384 			return err;
385 
386 		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
387 		if (err)
388 			return err;
389 	}
390 
391 	return 0;
392 }
393 
394 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
395 			     struct mv88e6xxx_vtu_entry *entry)
396 {
397 	int err;
398 
399 	/* Fetch VLAN MemberTag data from the VTU */
400 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
401 	if (err)
402 		return err;
403 
404 	if (entry->valid) {
405 		err = mv88e6390_g1_vtu_data_read(chip, entry->member);
406 		if (err)
407 			return err;
408 
409 		/* Fetch VLAN PortState data from the STU */
410 		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
411 		if (err)
412 			return err;
413 
414 		err = mv88e6390_g1_vtu_data_read(chip, entry->state);
415 		if (err)
416 			return err;
417 
418 		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
419 		if (err)
420 			return err;
421 	}
422 
423 	return 0;
424 }
425 
426 int mv88e6250_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
427 			       struct mv88e6xxx_vtu_entry *entry)
428 {
429 	u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
430 	int err;
431 
432 	err = mv88e6xxx_g1_vtu_op_wait(chip);
433 	if (err)
434 		return err;
435 
436 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
437 	if (err)
438 		return err;
439 
440 	if (entry->valid) {
441 		err = mv88e6185_g1_vtu_data_write(chip, entry);
442 		if (err)
443 			return err;
444 
445 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
446 		 * VTU DBNum[5:4] are located in VTU Operation 9:8
447 		 */
448 		op |= entry->fid & 0x000f;
449 		op |= (entry->fid & 0x0030) << 4;
450 	}
451 
452 	return mv88e6xxx_g1_vtu_op(chip, op);
453 }
454 
455 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
456 			       struct mv88e6xxx_vtu_entry *entry)
457 {
458 	u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
459 	int err;
460 
461 	err = mv88e6xxx_g1_vtu_op_wait(chip);
462 	if (err)
463 		return err;
464 
465 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
466 	if (err)
467 		return err;
468 
469 	if (entry->valid) {
470 		err = mv88e6185_g1_vtu_data_write(chip, entry);
471 		if (err)
472 			return err;
473 
474 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
475 		 * VTU DBNum[7:4] are located in VTU Operation 11:8
476 		 */
477 		op |= entry->fid & 0x000f;
478 		op |= (entry->fid & 0x00f0) << 4;
479 	}
480 
481 	return mv88e6xxx_g1_vtu_op(chip, op);
482 }
483 
484 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
485 			       struct mv88e6xxx_vtu_entry *entry)
486 {
487 	int err;
488 
489 	err = mv88e6xxx_g1_vtu_op_wait(chip);
490 	if (err)
491 		return err;
492 
493 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
494 	if (err)
495 		return err;
496 
497 	if (entry->valid) {
498 		/* Write MemberTag and PortState data */
499 		err = mv88e6185_g1_vtu_data_write(chip, entry);
500 		if (err)
501 			return err;
502 
503 		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
504 		if (err)
505 			return err;
506 
507 		/* Load STU entry */
508 		err = mv88e6xxx_g1_vtu_op(chip,
509 					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
510 		if (err)
511 			return err;
512 
513 		err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
514 		if (err)
515 			return err;
516 	}
517 
518 	/* Load/Purge VTU entry */
519 	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
520 }
521 
522 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
523 			       struct mv88e6xxx_vtu_entry *entry)
524 {
525 	int err;
526 
527 	err = mv88e6xxx_g1_vtu_op_wait(chip);
528 	if (err)
529 		return err;
530 
531 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
532 	if (err)
533 		return err;
534 
535 	if (entry->valid) {
536 		/* Write PortState data */
537 		err = mv88e6390_g1_vtu_data_write(chip, entry->state);
538 		if (err)
539 			return err;
540 
541 		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
542 		if (err)
543 			return err;
544 
545 		/* Load STU entry */
546 		err = mv88e6xxx_g1_vtu_op(chip,
547 					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
548 		if (err)
549 			return err;
550 
551 		/* Write MemberTag data */
552 		err = mv88e6390_g1_vtu_data_write(chip, entry->member);
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 
565 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
566 {
567 	int err;
568 
569 	err = mv88e6xxx_g1_vtu_op_wait(chip);
570 	if (err)
571 		return err;
572 
573 	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
574 }
575 
576 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
577 {
578 	struct mv88e6xxx_chip *chip = dev_id;
579 	struct mv88e6xxx_vtu_entry entry;
580 	int spid;
581 	int err;
582 	u16 val;
583 
584 	mv88e6xxx_reg_lock(chip);
585 
586 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
587 	if (err)
588 		goto out;
589 
590 	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
591 	if (err)
592 		goto out;
593 
594 	err = mv88e6xxx_g1_vtu_vid_read(chip, &entry);
595 	if (err)
596 		goto out;
597 
598 	spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
599 
600 	if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
601 		dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
602 				    entry.vid, spid);
603 		chip->ports[spid].vtu_member_violation++;
604 	}
605 
606 	if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
607 		dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
608 				    entry.vid, spid);
609 		chip->ports[spid].vtu_miss_violation++;
610 	}
611 
612 	mv88e6xxx_reg_unlock(chip);
613 
614 	return IRQ_HANDLED;
615 
616 out:
617 	mv88e6xxx_reg_unlock(chip);
618 
619 	dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
620 		err);
621 
622 	return IRQ_HANDLED;
623 }
624 
625 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
626 {
627 	int err;
628 
629 	chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
630 					      MV88E6XXX_G1_STS_IRQ_VTU_PROB);
631 	if (chip->vtu_prob_irq < 0)
632 		return chip->vtu_prob_irq;
633 
634 	err = request_threaded_irq(chip->vtu_prob_irq, NULL,
635 				   mv88e6xxx_g1_vtu_prob_irq_thread_fn,
636 				   IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob",
637 				   chip);
638 	if (err)
639 		irq_dispose_mapping(chip->vtu_prob_irq);
640 
641 	return err;
642 }
643 
644 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
645 {
646 	free_irq(chip->vtu_prob_irq, chip);
647 	irq_dispose_mapping(chip->vtu_prob_irq);
648 }
649