Revert "unicode: Don't special case ignorable code points"
[linux.git] / drivers / net / dsa / mv88e6xxx / global1_vtu.c
blobb524f27a2f0df0fba225a5621abb630f9b8f62ff
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
5 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2015 CMC Electronics, Inc.
7 * Copyright (c) 2017 Savoir-faire Linux, Inc.
8 */
10 #include <linux/bitfield.h>
11 #include <linux/interrupt.h>
12 #include <linux/irqdomain.h>
14 #include "chip.h"
15 #include "global1.h"
16 #include "trace.h"
18 /* Offset 0x02: VTU FID Register */
20 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
21 struct mv88e6xxx_vtu_entry *entry)
23 u16 val;
24 int err;
26 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
27 if (err)
28 return err;
30 entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
31 entry->policy = !!(val & MV88E6352_G1_VTU_FID_VID_POLICY);
32 return 0;
35 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
36 struct mv88e6xxx_vtu_entry *entry)
38 u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
40 if (entry->policy)
41 val |= MV88E6352_G1_VTU_FID_VID_POLICY;
43 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val);
46 /* Offset 0x03: VTU SID Register */
48 static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip, u8 *sid)
50 u16 val;
51 int err;
53 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val);
54 if (err)
55 return err;
57 *sid = val & MV88E6352_G1_VTU_SID_MASK;
59 return 0;
62 static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip, u8 sid)
64 u16 val = sid & MV88E6352_G1_VTU_SID_MASK;
66 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val);
69 /* Offset 0x05: VTU Operation Register */
71 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
73 int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
75 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
78 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
80 int err;
82 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
83 MV88E6XXX_G1_VTU_OP_BUSY | op);
84 if (err)
85 return err;
87 return mv88e6xxx_g1_vtu_op_wait(chip);
90 /* Offset 0x06: VTU VID Register */
92 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
93 bool *valid, u16 *vid)
95 u16 val;
96 int err;
98 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
99 if (err)
100 return err;
102 if (vid) {
103 *vid = val & 0xfff;
105 if (val & MV88E6390_G1_VTU_VID_PAGE)
106 *vid |= 0x1000;
109 if (valid)
110 *valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
112 return 0;
115 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
116 bool valid, u16 vid)
118 u16 val = vid & 0xfff;
120 if (vid & 0x1000)
121 val |= MV88E6390_G1_VTU_VID_PAGE;
123 if (valid)
124 val |= MV88E6XXX_G1_VTU_VID_VALID;
126 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
129 /* Offset 0x07: VTU/STU Data Register 1
130 * Offset 0x08: VTU/STU Data Register 2
131 * Offset 0x09: VTU/STU Data Register 3
133 static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
134 u16 *regs)
136 int i;
138 /* Read all 3 VTU/STU Data registers */
139 for (i = 0; i < 3; ++i) {
140 u16 *reg = &regs[i];
141 int err;
143 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
144 if (err)
145 return err;
148 return 0;
151 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
152 u8 *member, u8 *state)
154 u16 regs[3];
155 int err;
156 int i;
158 err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
159 if (err)
160 return err;
162 /* Extract MemberTag data */
163 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
164 unsigned int member_offset = (i % 4) * 4;
165 unsigned int state_offset = member_offset + 2;
167 if (member)
168 member[i] = (regs[i / 4] >> member_offset) & 0x3;
170 if (state)
171 state[i] = (regs[i / 4] >> state_offset) & 0x3;
174 return 0;
177 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
178 u8 *member, u8 *state)
180 u16 regs[3] = { 0 };
181 int i;
183 /* Insert MemberTag and PortState data */
184 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
185 unsigned int member_offset = (i % 4) * 4;
186 unsigned int state_offset = member_offset + 2;
188 if (member)
189 regs[i / 4] |= (member[i] & 0x3) << member_offset;
191 if (state)
192 regs[i / 4] |= (state[i] & 0x3) << state_offset;
195 /* Write all 3 VTU/STU Data registers */
196 for (i = 0; i < 3; ++i) {
197 u16 reg = regs[i];
198 int err;
200 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
201 if (err)
202 return err;
205 return 0;
208 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
210 u16 regs[2];
211 int i;
213 /* Read the 2 VTU/STU Data registers */
214 for (i = 0; i < 2; ++i) {
215 u16 *reg = &regs[i];
216 int err;
218 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
219 if (err)
220 return err;
223 /* Extract data */
224 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
225 unsigned int offset = (i % 8) * 2;
227 data[i] = (regs[i / 8] >> offset) & 0x3;
230 return 0;
233 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
235 u16 regs[2] = { 0 };
236 int i;
238 /* Insert data */
239 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
240 unsigned int offset = (i % 8) * 2;
242 regs[i / 8] |= (data[i] & 0x3) << offset;
245 /* Write the 2 VTU/STU Data registers */
246 for (i = 0; i < 2; ++i) {
247 u16 reg = regs[i];
248 int err;
250 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
251 if (err)
252 return err;
255 return 0;
258 /* VLAN Translation Unit Operations */
260 int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
261 struct mv88e6xxx_vtu_entry *entry)
263 int err;
265 err = mv88e6xxx_g1_vtu_op_wait(chip);
266 if (err)
267 return err;
269 /* To get the next higher active VID, the VTU GetNext operation can be
270 * started again without setting the VID registers since it already
271 * contains the last VID.
273 * To save a few hardware accesses and abstract this to the caller,
274 * write the VID only once, when the entry is given as invalid.
276 if (!entry->valid) {
277 err = mv88e6xxx_g1_vtu_vid_write(chip, false, entry->vid);
278 if (err)
279 return err;
282 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
283 if (err)
284 return err;
286 return mv88e6xxx_g1_vtu_vid_read(chip, &entry->valid, &entry->vid);
289 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
290 struct mv88e6xxx_vtu_entry *entry)
292 u16 val;
293 int err;
295 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
296 if (err)
297 return err;
299 if (entry->valid) {
300 err = mv88e6185_g1_vtu_data_read(chip, entry->member, entry->state);
301 if (err)
302 return err;
304 /* VTU DBNum[3:0] are located in VTU Operation 3:0
305 * VTU DBNum[7:4] ([5:4] for 6250) are located in VTU Operation 11:8 (9:8)
307 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
308 if (err)
309 return err;
311 entry->fid = val & 0x000f;
312 entry->fid |= (val & 0x0f00) >> 4;
313 entry->fid &= mv88e6xxx_num_databases(chip) - 1;
316 return 0;
319 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
320 struct mv88e6xxx_vtu_entry *entry)
322 int err;
324 /* Fetch VLAN MemberTag data from the VTU */
325 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
326 if (err)
327 return err;
329 if (entry->valid) {
330 err = mv88e6185_g1_vtu_data_read(chip, entry->member, NULL);
331 if (err)
332 return err;
334 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
335 if (err)
336 return err;
338 err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
339 if (err)
340 return err;
343 return 0;
346 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
347 struct mv88e6xxx_vtu_entry *entry)
349 int err;
351 /* Fetch VLAN MemberTag data from the VTU */
352 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
353 if (err)
354 return err;
356 if (entry->valid) {
357 err = mv88e6390_g1_vtu_data_read(chip, entry->member);
358 if (err)
359 return err;
361 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
362 if (err)
363 return err;
365 err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
366 if (err)
367 return err;
370 return 0;
373 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
374 struct mv88e6xxx_vtu_entry *entry)
376 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
377 int err;
379 err = mv88e6xxx_g1_vtu_op_wait(chip);
380 if (err)
381 return err;
383 err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
384 if (err)
385 return err;
387 if (entry->valid) {
388 err = mv88e6185_g1_vtu_data_write(chip, entry->member, entry->state);
389 if (err)
390 return err;
392 /* VTU DBNum[3:0] are located in VTU Operation 3:0
393 * VTU DBNum[7:4] are located in VTU Operation 11:8
395 * For the 6250/6220, the latter are really [5:4] and
396 * 9:8, but in those cases bits 7:6 of entry->fid are
397 * 0 since they have num_databases = 64.
399 op |= entry->fid & 0x000f;
400 op |= (entry->fid & 0x00f0) << 4;
403 return mv88e6xxx_g1_vtu_op(chip, op);
406 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
407 struct mv88e6xxx_vtu_entry *entry)
409 int err;
411 err = mv88e6xxx_g1_vtu_op_wait(chip);
412 if (err)
413 return err;
415 err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
416 if (err)
417 return err;
419 if (entry->valid) {
420 /* Write MemberTag data */
421 err = mv88e6185_g1_vtu_data_write(chip, entry->member, NULL);
422 if (err)
423 return err;
425 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
426 if (err)
427 return err;
429 err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
430 if (err)
431 return err;
434 /* Load/Purge VTU entry */
435 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
438 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
439 struct mv88e6xxx_vtu_entry *entry)
441 int err;
443 err = mv88e6xxx_g1_vtu_op_wait(chip);
444 if (err)
445 return err;
447 err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
448 if (err)
449 return err;
451 if (entry->valid) {
452 /* Write MemberTag data */
453 err = mv88e6390_g1_vtu_data_write(chip, entry->member);
454 if (err)
455 return err;
457 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
458 if (err)
459 return err;
461 err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
462 if (err)
463 return err;
466 /* Load/Purge VTU entry */
467 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
470 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
472 int err;
474 /* As part of the VTU flush, refresh FID map */
475 bitmap_zero(chip->fid_bitmap, MV88E6XXX_N_FID);
477 err = mv88e6xxx_g1_vtu_op_wait(chip);
478 if (err)
479 return err;
481 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
484 /* Spanning Tree Unit Operations */
486 int mv88e6xxx_g1_stu_getnext(struct mv88e6xxx_chip *chip,
487 struct mv88e6xxx_stu_entry *entry)
489 int err;
491 err = mv88e6xxx_g1_vtu_op_wait(chip);
492 if (err)
493 return err;
495 /* To get the next higher active SID, the STU GetNext operation can be
496 * started again without setting the SID registers since it already
497 * contains the last SID.
499 * To save a few hardware accesses and abstract this to the caller,
500 * write the SID only once, when the entry is given as invalid.
502 if (!entry->valid) {
503 err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
504 if (err)
505 return err;
508 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
509 if (err)
510 return err;
512 err = mv88e6xxx_g1_vtu_vid_read(chip, &entry->valid, NULL);
513 if (err)
514 return err;
516 if (entry->valid) {
517 err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
518 if (err)
519 return err;
522 return 0;
525 int mv88e6352_g1_stu_getnext(struct mv88e6xxx_chip *chip,
526 struct mv88e6xxx_stu_entry *entry)
528 int err;
530 err = mv88e6xxx_g1_stu_getnext(chip, entry);
531 if (err)
532 return err;
534 if (!entry->valid)
535 return 0;
537 return mv88e6185_g1_vtu_data_read(chip, NULL, entry->state);
540 int mv88e6390_g1_stu_getnext(struct mv88e6xxx_chip *chip,
541 struct mv88e6xxx_stu_entry *entry)
543 int err;
545 err = mv88e6xxx_g1_stu_getnext(chip, entry);
546 if (err)
547 return err;
549 if (!entry->valid)
550 return 0;
552 return mv88e6390_g1_vtu_data_read(chip, entry->state);
555 int mv88e6352_g1_stu_loadpurge(struct mv88e6xxx_chip *chip,
556 struct mv88e6xxx_stu_entry *entry)
558 int err;
560 err = mv88e6xxx_g1_vtu_op_wait(chip);
561 if (err)
562 return err;
564 err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, 0);
565 if (err)
566 return err;
568 err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
569 if (err)
570 return err;
572 if (entry->valid) {
573 err = mv88e6185_g1_vtu_data_write(chip, NULL, entry->state);
574 if (err)
575 return err;
578 /* Load/Purge STU entry */
579 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
582 int mv88e6390_g1_stu_loadpurge(struct mv88e6xxx_chip *chip,
583 struct mv88e6xxx_stu_entry *entry)
585 int err;
587 err = mv88e6xxx_g1_vtu_op_wait(chip);
588 if (err)
589 return err;
591 err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, 0);
592 if (err)
593 return err;
595 err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
596 if (err)
597 return err;
599 if (entry->valid) {
600 err = mv88e6390_g1_vtu_data_write(chip, entry->state);
601 if (err)
602 return err;
605 /* Load/Purge STU entry */
606 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
609 /* VTU Violation Management */
611 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
613 struct mv88e6xxx_chip *chip = dev_id;
614 u16 val, vid;
615 int spid;
616 int err;
618 mv88e6xxx_reg_lock(chip);
620 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
621 if (err)
622 goto out;
624 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
625 if (err)
626 goto out;
628 err = mv88e6xxx_g1_vtu_vid_read(chip, NULL, &vid);
629 if (err)
630 goto out;
632 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
634 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
635 trace_mv88e6xxx_vtu_member_violation(chip->dev, spid, vid);
636 chip->ports[spid].vtu_member_violation++;
639 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
640 trace_mv88e6xxx_vtu_miss_violation(chip->dev, spid, vid);
641 chip->ports[spid].vtu_miss_violation++;
644 mv88e6xxx_reg_unlock(chip);
646 return IRQ_HANDLED;
648 out:
649 mv88e6xxx_reg_unlock(chip);
651 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
652 err);
654 return IRQ_HANDLED;
657 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
659 int err;
661 chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
662 MV88E6XXX_G1_STS_IRQ_VTU_PROB);
663 if (chip->vtu_prob_irq < 0)
664 return chip->vtu_prob_irq;
666 snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name),
667 "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev));
669 err = request_threaded_irq(chip->vtu_prob_irq, NULL,
670 mv88e6xxx_g1_vtu_prob_irq_thread_fn,
671 IRQF_ONESHOT, chip->vtu_prob_irq_name,
672 chip);
673 if (err)
674 irq_dispose_mapping(chip->vtu_prob_irq);
676 return err;
679 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
681 free_irq(chip->vtu_prob_irq, chip);
682 irq_dispose_mapping(chip->vtu_prob_irq);