1 // SPDX-License-Identifier: GPL-2.0-or-later
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.
10 #include <linux/bitfield.h>
11 #include <linux/interrupt.h>
12 #include <linux/irqdomain.h>
17 /* Offset 0x02: VTU FID Register */
19 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
20 struct mv88e6xxx_vtu_entry *entry)
25 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
29 entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
34 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
35 struct mv88e6xxx_vtu_entry *entry)
37 u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
39 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val);
42 /* Offset 0x03: VTU SID Register */
44 static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip,
45 struct mv88e6xxx_vtu_entry *entry)
50 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val);
54 entry->sid = val & MV88E6352_G1_VTU_SID_MASK;
59 static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip,
60 struct mv88e6xxx_vtu_entry *entry)
62 u16 val = entry->sid & MV88E6352_G1_VTU_SID_MASK;
64 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val);
67 /* Offset 0x05: VTU Operation Register */
69 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
71 int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
73 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
76 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
80 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
81 MV88E6XXX_G1_VTU_OP_BUSY | op);
85 return mv88e6xxx_g1_vtu_op_wait(chip);
88 /* Offset 0x06: VTU VID Register */
90 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
91 struct mv88e6xxx_vtu_entry *entry)
96 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
100 entry->vid = val & 0xfff;
102 if (val & MV88E6390_G1_VTU_VID_PAGE)
103 entry->vid |= 0x1000;
105 entry->valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
110 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
111 struct mv88e6xxx_vtu_entry *entry)
113 u16 val = entry->vid & 0xfff;
115 if (entry->vid & 0x1000)
116 val |= MV88E6390_G1_VTU_VID_PAGE;
119 val |= MV88E6XXX_G1_VTU_VID_VALID;
121 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
124 /* Offset 0x07: VTU/STU Data Register 1
125 * Offset 0x08: VTU/STU Data Register 2
126 * Offset 0x09: VTU/STU Data Register 3
128 static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
133 /* Read all 3 VTU/STU Data registers */
134 for (i = 0; i < 3; ++i) {
138 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
146 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
147 struct mv88e6xxx_vtu_entry *entry)
153 err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
157 /* Extract MemberTag data */
158 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
159 unsigned int member_offset = (i % 4) * 4;
161 entry->member[i] = (regs[i / 4] >> member_offset) & 0x3;
167 static int mv88e6185_g1_stu_data_read(struct mv88e6xxx_chip *chip,
168 struct mv88e6xxx_vtu_entry *entry)
174 err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
178 /* Extract PortState data */
179 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
180 unsigned int state_offset = (i % 4) * 4 + 2;
182 entry->state[i] = (regs[i / 4] >> state_offset) & 0x3;
188 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
189 struct mv88e6xxx_vtu_entry *entry)
194 /* Insert MemberTag and PortState data */
195 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
196 unsigned int member_offset = (i % 4) * 4;
197 unsigned int state_offset = member_offset + 2;
199 regs[i / 4] |= (entry->member[i] & 0x3) << member_offset;
200 regs[i / 4] |= (entry->state[i] & 0x3) << state_offset;
203 /* Write all 3 VTU/STU Data registers */
204 for (i = 0; i < 3; ++i) {
208 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
216 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
221 /* Read the 2 VTU/STU Data registers */
222 for (i = 0; i < 2; ++i) {
226 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
232 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
233 unsigned int offset = (i % 8) * 2;
235 data[i] = (regs[i / 8] >> offset) & 0x3;
241 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
247 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
248 unsigned int offset = (i % 8) * 2;
250 regs[i / 8] |= (data[i] & 0x3) << offset;
253 /* Write the 2 VTU/STU Data registers */
254 for (i = 0; i < 2; ++i) {
258 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
266 /* VLAN Translation Unit Operations */
268 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip,
269 struct mv88e6xxx_vtu_entry *entry)
273 err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
277 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
281 err = mv88e6xxx_g1_vtu_sid_read(chip, entry);
285 return mv88e6xxx_g1_vtu_vid_read(chip, entry);
288 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip,
289 struct mv88e6xxx_vtu_entry *vtu)
291 struct mv88e6xxx_vtu_entry stu;
294 err = mv88e6xxx_g1_vtu_sid_read(chip, vtu);
298 stu.sid = vtu->sid - 1;
300 err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu);
304 if (stu.sid != vtu->sid || !stu.valid)
310 static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
311 struct mv88e6xxx_vtu_entry *entry)
315 err = mv88e6xxx_g1_vtu_op_wait(chip);
319 /* To get the next higher active VID, the VTU GetNext operation can be
320 * started again without setting the VID registers since it already
321 * contains the last VID.
323 * To save a few hardware accesses and abstract this to the caller,
324 * write the VID only once, when the entry is given as invalid.
327 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
332 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
336 return mv88e6xxx_g1_vtu_vid_read(chip, entry);
339 int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
340 struct mv88e6xxx_vtu_entry *entry)
345 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
350 err = mv88e6185_g1_vtu_data_read(chip, entry);
354 err = mv88e6185_g1_stu_data_read(chip, entry);
358 /* VTU DBNum[3:0] are located in VTU Operation 3:0
359 * VTU DBNum[5:4] are located in VTU Operation 9:8
361 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
365 entry->fid = val & 0x000f;
366 entry->fid |= (val & 0x0300) >> 4;
372 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
373 struct mv88e6xxx_vtu_entry *entry)
378 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
383 err = mv88e6185_g1_vtu_data_read(chip, entry);
387 err = mv88e6185_g1_stu_data_read(chip, entry);
391 /* VTU DBNum[3:0] are located in VTU Operation 3:0
392 * VTU DBNum[7:4] are located in VTU Operation 11:8
394 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
398 entry->fid = val & 0x000f;
399 entry->fid |= (val & 0x0f00) >> 4;
405 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
406 struct mv88e6xxx_vtu_entry *entry)
410 /* Fetch VLAN MemberTag data from the VTU */
411 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
416 err = mv88e6185_g1_vtu_data_read(chip, entry);
420 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
424 /* Fetch VLAN PortState data from the STU */
425 err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
429 err = mv88e6185_g1_stu_data_read(chip, entry);
437 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
438 struct mv88e6xxx_vtu_entry *entry)
442 /* Fetch VLAN MemberTag data from the VTU */
443 err = mv88e6xxx_g1_vtu_getnext(chip, entry);
448 err = mv88e6390_g1_vtu_data_read(chip, entry->member);
452 /* Fetch VLAN PortState data from the STU */
453 err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
457 err = mv88e6390_g1_vtu_data_read(chip, entry->state);
461 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
469 int mv88e6250_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
470 struct mv88e6xxx_vtu_entry *entry)
472 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
475 err = mv88e6xxx_g1_vtu_op_wait(chip);
479 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
484 err = mv88e6185_g1_vtu_data_write(chip, entry);
488 /* VTU DBNum[3:0] are located in VTU Operation 3:0
489 * VTU DBNum[5:4] are located in VTU Operation 9:8
491 op |= entry->fid & 0x000f;
492 op |= (entry->fid & 0x0030) << 4;
495 return mv88e6xxx_g1_vtu_op(chip, op);
498 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
499 struct mv88e6xxx_vtu_entry *entry)
501 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
504 err = mv88e6xxx_g1_vtu_op_wait(chip);
508 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
513 err = mv88e6185_g1_vtu_data_write(chip, entry);
517 /* VTU DBNum[3:0] are located in VTU Operation 3:0
518 * VTU DBNum[7:4] are located in VTU Operation 11:8
520 op |= entry->fid & 0x000f;
521 op |= (entry->fid & 0x00f0) << 4;
524 return mv88e6xxx_g1_vtu_op(chip, op);
527 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
528 struct mv88e6xxx_vtu_entry *entry)
532 err = mv88e6xxx_g1_vtu_op_wait(chip);
536 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
541 /* Write MemberTag and PortState data */
542 err = mv88e6185_g1_vtu_data_write(chip, entry);
546 err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
551 err = mv88e6xxx_g1_vtu_op(chip,
552 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
556 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
561 /* Load/Purge VTU entry */
562 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
565 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
566 struct mv88e6xxx_vtu_entry *entry)
570 err = mv88e6xxx_g1_vtu_op_wait(chip);
574 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
579 /* Write PortState data */
580 err = mv88e6390_g1_vtu_data_write(chip, entry->state);
584 err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
589 err = mv88e6xxx_g1_vtu_op(chip,
590 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
594 /* Write MemberTag data */
595 err = mv88e6390_g1_vtu_data_write(chip, entry->member);
599 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
604 /* Load/Purge VTU entry */
605 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
608 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
612 err = mv88e6xxx_g1_vtu_op_wait(chip);
616 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
619 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
621 struct mv88e6xxx_chip *chip = dev_id;
622 struct mv88e6xxx_vtu_entry entry;
627 mv88e6xxx_reg_lock(chip);
629 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
633 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
637 err = mv88e6xxx_g1_vtu_vid_read(chip, &entry);
641 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
643 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
644 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
646 chip->ports[spid].vtu_member_violation++;
649 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
650 dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
652 chip->ports[spid].vtu_miss_violation++;
655 mv88e6xxx_reg_unlock(chip);
660 mv88e6xxx_reg_unlock(chip);
662 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
668 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
672 chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
673 MV88E6XXX_G1_STS_IRQ_VTU_PROB);
674 if (chip->vtu_prob_irq < 0)
675 return chip->vtu_prob_irq;
677 snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name),
678 "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev));
680 err = request_threaded_irq(chip->vtu_prob_irq, NULL,
681 mv88e6xxx_g1_vtu_prob_irq_thread_fn,
682 IRQF_ONESHOT, chip->vtu_prob_irq_name,
685 irq_dispose_mapping(chip->vtu_prob_irq);
690 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
692 free_irq(chip->vtu_prob_irq, chip);
693 irq_dispose_mapping(chip->vtu_prob_irq);