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