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