hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/dsa/mv88e6xxx/global2.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Marvell 88E6xxx Switch Global 2 Registers support
34 *
....@@ -5,11 +6,6 @@
56 *
67 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
78 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version.
139 */
1410
1511 #include <linux/bitfield.h>
....@@ -30,14 +26,11 @@
3026 return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
3127 }
3228
33
-int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
29
+int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
30
+ bit, int val)
3431 {
35
- return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update);
36
-}
37
-
38
-int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
39
-{
40
- return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
32
+ return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
33
+ bit, val);
4134 }
4235
4336 /* Offset 0x00: Interrupt Source Register */
....@@ -127,7 +120,8 @@
127120 * but bit 4 is reserved on older chips, so it is safe to use.
128121 */
129122
130
- return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_DEVICE_MAPPING, val);
123
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
124
+ MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
131125 }
132126
133127 /* Offset 0x07: Trunk Mask Table register */
....@@ -140,7 +134,8 @@
140134 if (hash)
141135 val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
142136
143
- return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MASK, val);
137
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
138
+ MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
144139 }
145140
146141 /* Offset 0x08: Trunk Mapping Table register */
....@@ -151,7 +146,8 @@
151146 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
152147 u16 val = (id << 11) | (map & port_mask);
153148
154
- return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MAPPING, val);
149
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
150
+ MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
155151 }
156152
157153 int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
....@@ -182,8 +178,9 @@
182178
183179 static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
184180 {
185
- return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_IRL_CMD,
186
- MV88E6XXX_G2_IRL_CMD_BUSY);
181
+ int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);
182
+
183
+ return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
187184 }
188185
189186 static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
....@@ -218,8 +215,9 @@
218215
219216 static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
220217 {
221
- return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_PVT_ADDR,
222
- MV88E6XXX_G2_PVT_ADDR_BUSY);
218
+ int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);
219
+
220
+ return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
223221 }
224222
225223 static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
....@@ -265,7 +263,8 @@
265263 {
266264 u16 val = (pointer << 8) | data;
267265
268
- return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SWITCH_MAC, val);
266
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
267
+ MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
269268 }
270269
271270 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
....@@ -281,6 +280,19 @@
281280 return err;
282281 }
283282
283
+/* Offset 0x0E: ATU Statistics */
284
+
285
+int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
286
+{
287
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
288
+ kind | bin);
289
+}
290
+
291
+int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
292
+{
293
+ return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
294
+}
295
+
284296 /* Offset 0x0F: Priority Override Table */
285297
286298 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
....@@ -288,7 +300,8 @@
288300 {
289301 u16 val = (pointer << 8) | (data & 0x7);
290302
291
- return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_PRIO_OVERRIDE, val);
303
+ return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
304
+ MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
292305 }
293306
294307 int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
....@@ -312,9 +325,16 @@
312325
313326 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
314327 {
315
- return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_EEPROM_CMD,
316
- MV88E6XXX_G2_EEPROM_CMD_BUSY |
317
- MV88E6XXX_G2_EEPROM_CMD_RUNNING);
328
+ int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
329
+ int err;
330
+
331
+ err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
332
+ if (err)
333
+ return err;
334
+
335
+ bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
336
+
337
+ return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
318338 }
319339
320340 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
....@@ -576,8 +596,9 @@
576596
577597 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
578598 {
579
- return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD,
580
- MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
599
+ int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
600
+
601
+ return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
581602 }
582603
583604 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
....@@ -816,31 +837,57 @@
816837 .irq_free = mv88e6097_watchdog_free,
817838 };
818839
840
+static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
841
+{
842
+ u16 reg;
843
+
844
+ mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, &reg);
845
+
846
+ reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
847
+ MV88E6250_G2_WDOG_CTL_QC_ENABLE);
848
+
849
+ mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
850
+}
851
+
852
+static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
853
+{
854
+ return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
855
+ MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
856
+ MV88E6250_G2_WDOG_CTL_QC_ENABLE |
857
+ MV88E6250_G2_WDOG_CTL_SWRESET);
858
+}
859
+
860
+const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
861
+ .irq_action = mv88e6097_watchdog_action,
862
+ .irq_setup = mv88e6250_watchdog_setup,
863
+ .irq_free = mv88e6250_watchdog_free,
864
+};
865
+
819866 static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
820867 {
821
- return mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
822
- MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
823
- MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
824
- MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
825
- MV88E6390_G2_WDOG_CTL_EGRESS |
826
- MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
868
+ return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
869
+ MV88E6390_G2_WDOG_CTL_UPDATE |
870
+ MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
871
+ MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
872
+ MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
873
+ MV88E6390_G2_WDOG_CTL_EGRESS |
874
+ MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
827875 }
828876
829877 static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
830878 {
831
- int err;
832879 u16 reg;
833880
834881 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
835882 MV88E6390_G2_WDOG_CTL_PTR_EVENT);
836
- err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
883
+ mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
837884
838885 dev_info(chip->dev, "Watchdog event: 0x%04x",
839886 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
840887
841888 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
842889 MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
843
- err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
890
+ mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
844891
845892 dev_info(chip->dev, "Watchdog history: 0x%04x",
846893 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
....@@ -856,8 +903,9 @@
856903
857904 static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
858905 {
859
- mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
860
- MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
906
+ mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
907
+ MV88E6390_G2_WDOG_CTL_UPDATE |
908
+ MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
861909 }
862910
863911 const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
....@@ -871,20 +919,20 @@
871919 struct mv88e6xxx_chip *chip = dev_id;
872920 irqreturn_t ret = IRQ_NONE;
873921
874
- mutex_lock(&chip->reg_lock);
922
+ mv88e6xxx_reg_lock(chip);
875923 if (chip->info->ops->watchdog_ops->irq_action)
876924 ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
877
- mutex_unlock(&chip->reg_lock);
925
+ mv88e6xxx_reg_unlock(chip);
878926
879927 return ret;
880928 }
881929
882930 static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
883931 {
884
- mutex_lock(&chip->reg_lock);
932
+ mv88e6xxx_reg_lock(chip);
885933 if (chip->info->ops->watchdog_ops->irq_free)
886934 chip->info->ops->watchdog_ops->irq_free(chip);
887
- mutex_unlock(&chip->reg_lock);
935
+ mv88e6xxx_reg_unlock(chip);
888936
889937 free_irq(chip->watchdog_irq, chip);
890938 irq_dispose_mapping(chip->watchdog_irq);
....@@ -899,17 +947,20 @@
899947 if (chip->watchdog_irq < 0)
900948 return chip->watchdog_irq;
901949
950
+ snprintf(chip->watchdog_irq_name, sizeof(chip->watchdog_irq_name),
951
+ "mv88e6xxx-%s-watchdog", dev_name(chip->dev));
952
+
902953 err = request_threaded_irq(chip->watchdog_irq, NULL,
903954 mv88e6xxx_g2_watchdog_thread_fn,
904955 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
905
- "mv88e6xxx-watchdog", chip);
956
+ chip->watchdog_irq_name, chip);
906957 if (err)
907958 return err;
908959
909
- mutex_lock(&chip->reg_lock);
960
+ mv88e6xxx_reg_lock(chip);
910961 if (chip->info->ops->watchdog_ops->irq_setup)
911962 err = chip->info->ops->watchdog_ops->irq_setup(chip);
912
- mutex_unlock(&chip->reg_lock);
963
+ mv88e6xxx_reg_unlock(chip);
913964
914965 return err;
915966 }
....@@ -964,9 +1015,9 @@
9641015 int err;
9651016 u16 reg;
9661017
967
- mutex_lock(&chip->reg_lock);
1018
+ mv88e6xxx_reg_lock(chip);
9681019 err = mv88e6xxx_g2_int_source(chip, &reg);
969
- mutex_unlock(&chip->reg_lock);
1020
+ mv88e6xxx_reg_unlock(chip);
9701021 if (err)
9711022 goto out;
9721023
....@@ -985,7 +1036,7 @@
9851036 {
9861037 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
9871038
988
- mutex_lock(&chip->reg_lock);
1039
+ mv88e6xxx_reg_lock(chip);
9891040 }
9901041
9911042 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
....@@ -997,7 +1048,7 @@
9971048 if (err)
9981049 dev_err(chip->dev, "failed to mask interrupts\n");
9991050
1000
- mutex_unlock(&chip->reg_lock);
1051
+ mv88e6xxx_reg_unlock(chip);
10011052 }
10021053
10031054 static const struct irq_chip mv88e6xxx_g2_irq_chip = {
....@@ -1047,6 +1098,13 @@
10471098 {
10481099 int err, irq, virq;
10491100
1101
+ chip->g2_irq.masked = ~0;
1102
+ mv88e6xxx_reg_lock(chip);
1103
+ err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1104
+ mv88e6xxx_reg_unlock(chip);
1105
+ if (err)
1106
+ return err;
1107
+
10501108 chip->g2_irq.domain = irq_domain_add_simple(
10511109 chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
10521110 if (!chip->g2_irq.domain)
....@@ -1056,7 +1114,6 @@
10561114 irq_create_mapping(chip->g2_irq.domain, irq);
10571115
10581116 chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1059
- chip->g2_irq.masked = ~0;
10601117
10611118 chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
10621119 MV88E6XXX_G1_STS_IRQ_DEVICE);
....@@ -1065,9 +1122,12 @@
10651122 goto out;
10661123 }
10671124
1125
+ snprintf(chip->device_irq_name, sizeof(chip->device_irq_name),
1126
+ "mv88e6xxx-%s-g2", dev_name(chip->dev));
1127
+
10681128 err = request_threaded_irq(chip->device_irq, NULL,
10691129 mv88e6xxx_g2_irq_thread_fn,
1070
- IRQF_ONESHOT, "mv88e6xxx-g2", chip);
1130
+ IRQF_ONESHOT, chip->device_irq_name, chip);
10711131 if (err)
10721132 goto out;
10731133