hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/net/dsa/mv88e6xxx/global1_vtu.c
....@@ -1,16 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
34 *
45 * Copyright (c) 2008 Marvell Semiconductor
56 * Copyright (c) 2015 CMC Electronics, Inc.
67 * 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.
128 */
139
10
+#include <linux/bitfield.h>
1411 #include <linux/interrupt.h>
1512 #include <linux/irqdomain.h>
1613
....@@ -71,8 +68,9 @@
7168
7269 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
7370 {
74
- return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_VTU_OP,
75
- MV88E6XXX_G1_VTU_OP_BUSY);
71
+ int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
72
+
73
+ return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
7674 }
7775
7876 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
....@@ -338,6 +336,39 @@
338336 return mv88e6xxx_g1_vtu_vid_read(chip, entry);
339337 }
340338
339
+int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
340
+ struct mv88e6xxx_vtu_entry *entry)
341
+{
342
+ u16 val;
343
+ int err;
344
+
345
+ err = mv88e6xxx_g1_vtu_getnext(chip, entry);
346
+ if (err)
347
+ return err;
348
+
349
+ if (entry->valid) {
350
+ err = mv88e6185_g1_vtu_data_read(chip, entry);
351
+ if (err)
352
+ return err;
353
+
354
+ err = mv88e6185_g1_stu_data_read(chip, entry);
355
+ if (err)
356
+ return err;
357
+
358
+ /* VTU DBNum[3:0] are located in VTU Operation 3:0
359
+ * VTU DBNum[5:4] are located in VTU Operation 9:8
360
+ */
361
+ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
362
+ if (err)
363
+ return err;
364
+
365
+ entry->fid = val & 0x000f;
366
+ entry->fid |= (val & 0x0300) >> 4;
367
+ }
368
+
369
+ return 0;
370
+}
371
+
341372 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
342373 struct mv88e6xxx_vtu_entry *entry)
343374 {
....@@ -433,6 +464,35 @@
433464 }
434465
435466 return 0;
467
+}
468
+
469
+int mv88e6250_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
470
+ struct mv88e6xxx_vtu_entry *entry)
471
+{
472
+ u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
473
+ int err;
474
+
475
+ err = mv88e6xxx_g1_vtu_op_wait(chip);
476
+ if (err)
477
+ return err;
478
+
479
+ err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
480
+ if (err)
481
+ return err;
482
+
483
+ if (entry->valid) {
484
+ err = mv88e6185_g1_vtu_data_write(chip, entry);
485
+ if (err)
486
+ return err;
487
+
488
+ /* VTU DBNum[3:0] are located in VTU Operation 3:0
489
+ * VTU DBNum[5:4] are located in VTU Operation 9:8
490
+ */
491
+ op |= entry->fid & 0x000f;
492
+ op |= (entry->fid & 0x0030) << 4;
493
+ }
494
+
495
+ return mv88e6xxx_g1_vtu_op(chip, op);
436496 }
437497
438498 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
....@@ -564,7 +624,7 @@
564624 int err;
565625 u16 val;
566626
567
- mutex_lock(&chip->reg_lock);
627
+ mv88e6xxx_reg_lock(chip);
568628
569629 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
570630 if (err)
....@@ -592,12 +652,12 @@
592652 chip->ports[spid].vtu_miss_violation++;
593653 }
594654
595
- mutex_unlock(&chip->reg_lock);
655
+ mv88e6xxx_reg_unlock(chip);
596656
597657 return IRQ_HANDLED;
598658
599659 out:
600
- mutex_unlock(&chip->reg_lock);
660
+ mv88e6xxx_reg_unlock(chip);
601661
602662 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
603663 err);
....@@ -614,9 +674,12 @@
614674 if (chip->vtu_prob_irq < 0)
615675 return chip->vtu_prob_irq;
616676
677
+ snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name),
678
+ "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev));
679
+
617680 err = request_threaded_irq(chip->vtu_prob_irq, NULL,
618681 mv88e6xxx_g1_vtu_prob_irq_thread_fn,
619
- IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob",
682
+ IRQF_ONESHOT, chip->vtu_prob_irq_name,
620683 chip);
621684 if (err)
622685 irq_dispose_mapping(chip->vtu_prob_irq);