1 /*
2  * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
3  *
4  * Copyright (c) 2008 Marvell Semiconductor
5  * Copyright (c) 2015 CMC Electronics, Inc.
6  * Copyright (c) 2017 Savoir-faire Linux, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include <linux/interrupt.h>
15 #include <linux/irqdomain.h>
16 
17 #include "chip.h"
18 #include "global1.h"
19 
20 /* Offset 0x02: VTU FID Register */
21 
22 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
23 				     struct mv88e6xxx_vtu_entry *entry)
24 {
25 	u16 val;
26 	int err;
27 
28 	err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
29 	if (err)
30 		return err;
31 
32 	entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
33 
34 	return 0;
35 }
36 
37 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
38 				      struct mv88e6xxx_vtu_entry *entry)
39 {
40 	u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
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 	return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_VTU_OP,
75 				 MV88E6XXX_G1_VTU_OP_BUSY);
76 }
77 
78 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
79 {
80 	int err;
81 
82 	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
83 				 MV88E6XXX_G1_VTU_OP_BUSY | op);
84 	if (err)
85 		return err;
86 
87 	return mv88e6xxx_g1_vtu_op_wait(chip);
88 }
89 
90 /* Offset 0x06: VTU VID Register */
91 
92 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
93 				     struct mv88e6xxx_vtu_entry *entry)
94 {
95 	u16 val;
96 	int err;
97 
98 	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
99 	if (err)
100 		return err;
101 
102 	entry->vid = val & 0xfff;
103 
104 	if (val & MV88E6390_G1_VTU_VID_PAGE)
105 		entry->vid |= 0x1000;
106 
107 	entry->valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
108 
109 	return 0;
110 }
111 
112 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
113 				      struct mv88e6xxx_vtu_entry *entry)
114 {
115 	u16 val = entry->vid & 0xfff;
116 
117 	if (entry->vid & 0x1000)
118 		val |= MV88E6390_G1_VTU_VID_PAGE;
119 
120 	if (entry->valid)
121 		val |= MV88E6XXX_G1_VTU_VID_VALID;
122 
123 	return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
124 }
125 
126 /* Offset 0x07: VTU/STU Data Register 1
127  * Offset 0x08: VTU/STU Data Register 2
128  * Offset 0x09: VTU/STU Data Register 3
129  */
130 
131 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
132 				      struct mv88e6xxx_vtu_entry *entry)
133 {
134 	u16 regs[3];
135 	int i;
136 
137 	/* Read all 3 VTU/STU Data registers */
138 	for (i = 0; i < 3; ++i) {
139 		u16 *reg = &regs[i];
140 		int err;
141 
142 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
143 		if (err)
144 			return err;
145 	}
146 
147 	/* Extract MemberTag and PortState data */
148 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
149 		unsigned int member_offset = (i % 4) * 4;
150 		unsigned int state_offset = member_offset + 2;
151 
152 		entry->member[i] = (regs[i / 4] >> member_offset) & 0x3;
153 		entry->state[i] = (regs[i / 4] >> state_offset) & 0x3;
154 	}
155 
156 	return 0;
157 }
158 
159 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
160 				       struct mv88e6xxx_vtu_entry *entry)
161 {
162 	u16 regs[3] = { 0 };
163 	int i;
164 
165 	/* Insert MemberTag and PortState data */
166 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
167 		unsigned int member_offset = (i % 4) * 4;
168 		unsigned int state_offset = member_offset + 2;
169 
170 		regs[i / 4] |= (entry->member[i] & 0x3) << member_offset;
171 		regs[i / 4] |= (entry->state[i] & 0x3) << state_offset;
172 	}
173 
174 	/* Write all 3 VTU/STU Data registers */
175 	for (i = 0; i < 3; ++i) {
176 		u16 reg = regs[i];
177 		int err;
178 
179 		err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
180 		if (err)
181 			return err;
182 	}
183 
184 	return 0;
185 }
186 
187 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
188 {
189 	u16 regs[2];
190 	int i;
191 
192 	/* Read the 2 VTU/STU Data registers */
193 	for (i = 0; i < 2; ++i) {
194 		u16 *reg = &regs[i];
195 		int err;
196 
197 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
198 		if (err)
199 			return err;
200 	}
201 
202 	/* Extract data */
203 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
204 		unsigned int offset = (i % 8) * 2;
205 
206 		data[i] = (regs[i / 8] >> offset) & 0x3;
207 	}
208 
209 	return 0;
210 }
211 
212 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
213 {
214 	u16 regs[2] = { 0 };
215 	int i;
216 
217 	/* Insert data */
218 	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
219 		unsigned int offset = (i % 8) * 2;
220 
221 		regs[i / 8] |= (data[i] & 0x3) << offset;
222 	}
223 
224 	/* Write 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_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
230 		if (err)
231 			return err;
232 	}
233 
234 	return 0;
235 }
236 
237 /* VLAN Translation Unit Operations */
238 
239 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip,
240 					struct mv88e6xxx_vtu_entry *entry)
241 {
242 	int err;
243 
244 	err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
245 	if (err)
246 		return err;
247 
248 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
249 	if (err)
250 		return err;
251 
252 	err = mv88e6xxx_g1_vtu_sid_read(chip, entry);
253 	if (err)
254 		return err;
255 
256 	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
257 }
258 
259 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip,
260 				    struct mv88e6xxx_vtu_entry *vtu)
261 {
262 	struct mv88e6xxx_vtu_entry stu;
263 	int err;
264 
265 	err = mv88e6xxx_g1_vtu_sid_read(chip, vtu);
266 	if (err)
267 		return err;
268 
269 	stu.sid = vtu->sid - 1;
270 
271 	err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu);
272 	if (err)
273 		return err;
274 
275 	if (stu.sid != vtu->sid || !stu.valid)
276 		return -EINVAL;
277 
278 	return 0;
279 }
280 
281 static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
282 				    struct mv88e6xxx_vtu_entry *entry)
283 {
284 	int err;
285 
286 	err = mv88e6xxx_g1_vtu_op_wait(chip);
287 	if (err)
288 		return err;
289 
290 	/* To get the next higher active VID, the VTU GetNext operation can be
291 	 * started again without setting the VID registers since it already
292 	 * contains the last VID.
293 	 *
294 	 * To save a few hardware accesses and abstract this to the caller,
295 	 * write the VID only once, when the entry is given as invalid.
296 	 */
297 	if (!entry->valid) {
298 		err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
299 		if (err)
300 			return err;
301 	}
302 
303 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
304 	if (err)
305 		return err;
306 
307 	return mv88e6xxx_g1_vtu_vid_read(chip, entry);
308 }
309 
310 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
311 			     struct mv88e6xxx_vtu_entry *entry)
312 {
313 	u16 val;
314 	int err;
315 
316 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
317 	if (err)
318 		return err;
319 
320 	if (entry->valid) {
321 		err = mv88e6185_g1_vtu_data_read(chip, entry);
322 		if (err)
323 			return err;
324 
325 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
326 		 * VTU DBNum[7:4] are located in VTU Operation 11:8
327 		 */
328 		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
329 		if (err)
330 			return err;
331 
332 		entry->fid = val & 0x000f;
333 		entry->fid |= (val & 0x0f00) >> 4;
334 	}
335 
336 	return 0;
337 }
338 
339 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
340 			     struct mv88e6xxx_vtu_entry *entry)
341 {
342 	int err;
343 
344 	/* Fetch VLAN MemberTag data from the VTU */
345 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
346 	if (err)
347 		return err;
348 
349 	if (entry->valid) {
350 		/* Fetch (and mask) VLAN PortState data from the STU */
351 		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
352 		if (err)
353 			return err;
354 
355 		err = mv88e6185_g1_vtu_data_read(chip, entry);
356 		if (err)
357 			return err;
358 
359 		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
360 		if (err)
361 			return err;
362 	}
363 
364 	return 0;
365 }
366 
367 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
368 			     struct mv88e6xxx_vtu_entry *entry)
369 {
370 	int err;
371 
372 	/* Fetch VLAN MemberTag data from the VTU */
373 	err = mv88e6xxx_g1_vtu_getnext(chip, entry);
374 	if (err)
375 		return err;
376 
377 	if (entry->valid) {
378 		err = mv88e6390_g1_vtu_data_read(chip, entry->member);
379 		if (err)
380 			return err;
381 
382 		/* Fetch VLAN PortState data from the STU */
383 		err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
384 		if (err)
385 			return err;
386 
387 		err = mv88e6390_g1_vtu_data_read(chip, entry->state);
388 		if (err)
389 			return err;
390 
391 		err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
392 		if (err)
393 			return err;
394 	}
395 
396 	return 0;
397 }
398 
399 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
400 			       struct mv88e6xxx_vtu_entry *entry)
401 {
402 	u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
403 	int err;
404 
405 	err = mv88e6xxx_g1_vtu_op_wait(chip);
406 	if (err)
407 		return err;
408 
409 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
410 	if (err)
411 		return err;
412 
413 	if (entry->valid) {
414 		err = mv88e6185_g1_vtu_data_write(chip, entry);
415 		if (err)
416 			return err;
417 
418 		/* VTU DBNum[3:0] are located in VTU Operation 3:0
419 		 * VTU DBNum[7:4] are located in VTU Operation 11:8
420 		 */
421 		op |= entry->fid & 0x000f;
422 		op |= (entry->fid & 0x00f0) << 8;
423 	}
424 
425 	return mv88e6xxx_g1_vtu_op(chip, op);
426 }
427 
428 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
429 			       struct mv88e6xxx_vtu_entry *entry)
430 {
431 	int err;
432 
433 	err = mv88e6xxx_g1_vtu_op_wait(chip);
434 	if (err)
435 		return err;
436 
437 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
438 	if (err)
439 		return err;
440 
441 	if (entry->valid) {
442 		/* Write MemberTag and PortState data */
443 		err = mv88e6185_g1_vtu_data_write(chip, entry);
444 		if (err)
445 			return err;
446 
447 		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
448 		if (err)
449 			return err;
450 
451 		/* Load STU entry */
452 		err = mv88e6xxx_g1_vtu_op(chip,
453 					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
454 		if (err)
455 			return err;
456 
457 		err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
458 		if (err)
459 			return err;
460 	}
461 
462 	/* Load/Purge VTU entry */
463 	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
464 }
465 
466 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
467 			       struct mv88e6xxx_vtu_entry *entry)
468 {
469 	int err;
470 
471 	err = mv88e6xxx_g1_vtu_op_wait(chip);
472 	if (err)
473 		return err;
474 
475 	err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
476 	if (err)
477 		return err;
478 
479 	if (entry->valid) {
480 		/* Write PortState data */
481 		err = mv88e6390_g1_vtu_data_write(chip, entry->state);
482 		if (err)
483 			return err;
484 
485 		err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
486 		if (err)
487 			return err;
488 
489 		/* Load STU entry */
490 		err = mv88e6xxx_g1_vtu_op(chip,
491 					  MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
492 		if (err)
493 			return err;
494 
495 		/* Write MemberTag data */
496 		err = mv88e6390_g1_vtu_data_write(chip, entry->member);
497 		if (err)
498 			return err;
499 
500 		err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
501 		if (err)
502 			return err;
503 	}
504 
505 	/* Load/Purge VTU entry */
506 	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
507 }
508 
509 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
510 {
511 	int err;
512 
513 	err = mv88e6xxx_g1_vtu_op_wait(chip);
514 	if (err)
515 		return err;
516 
517 	return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
518 }
519 
520 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
521 {
522 	struct mv88e6xxx_chip *chip = dev_id;
523 	struct mv88e6xxx_vtu_entry entry;
524 	int spid;
525 	int err;
526 	u16 val;
527 
528 	mutex_lock(&chip->reg_lock);
529 
530 	err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
531 	if (err)
532 		goto out;
533 
534 	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
535 	if (err)
536 		goto out;
537 
538 	err = mv88e6xxx_g1_vtu_vid_read(chip, &entry);
539 	if (err)
540 		goto out;
541 
542 	mutex_unlock(&chip->reg_lock);
543 
544 	spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
545 
546 	if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
547 		dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
548 				    entry.vid, spid);
549 	}
550 
551 	if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION)
552 		dev_err_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
553 				    entry.vid, spid);
554 
555 	return IRQ_HANDLED;
556 
557 out:
558 	mutex_unlock(&chip->reg_lock);
559 
560 	dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
561 		err);
562 
563 	return IRQ_HANDLED;
564 }
565 
566 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
567 {
568 	int err;
569 
570 	chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
571 					      MV88E6XXX_G1_STS_IRQ_VTU_PROB);
572 	if (chip->vtu_prob_irq < 0)
573 		return chip->vtu_prob_irq;
574 
575 	err = request_threaded_irq(chip->vtu_prob_irq, NULL,
576 				   mv88e6xxx_g1_vtu_prob_irq_thread_fn,
577 				   IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob",
578 				   chip);
579 	if (err)
580 		irq_dispose_mapping(chip->vtu_prob_irq);
581 
582 	return err;
583 }
584 
585 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
586 {
587 	free_irq(chip->vtu_prob_irq, chip);
588 	irq_dispose_mapping(chip->vtu_prob_irq);
589 }
590