c8254e5e4270c897af8a9d95c81026736314990e
[openwrt/staging/blogic.git] /
1 From f318a015330a11befd8c69336efc6284e240f535 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= <alexis.lothore@bootlin.com>
3 Date: Mon, 29 May 2023 10:02:46 +0200
4 Subject: [PATCH 898/898] net: dsa: mv88e6xxx: enable support for 88E6361
5 switch
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 Marvell 88E6361 is an 8-port switch derived from the
11 88E6393X/88E9193X/88E6191X switches family. It can benefit from the
12 existing mv88e6xxx driver by simply adding the proper switch description in
13 the driver. Main differences with other switches from this
14 family are:
15 - 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
16 - No 5GBase-x nor SFI/USXGMII support
17
18 Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
19 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
20 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
21 Adapt to 5.15 since we dont have phylink_get_caps yet.
22 So, update the old mv88e6393x_phylink_validate instead.
23 Remove max_sid since 5.15 driver does not support it yet.
24 [Robert Marko]
25 Signed-off-by: Robert Marko <robimarko@gmail.com>
26 ---
27 drivers/net/dsa/mv88e6xxx/chip.c | 49 +++++++++++++++++++++++++++++++-
28 drivers/net/dsa/mv88e6xxx/chip.h | 3 +-
29 drivers/net/dsa/mv88e6xxx/port.c | 14 +++++++--
30 drivers/net/dsa/mv88e6xxx/port.h | 1 +
31 4 files changed, 62 insertions(+), 5 deletions(-)
32
33 --- a/drivers/net/dsa/mv88e6xxx/chip.c
34 +++ b/drivers/net/dsa/mv88e6xxx/chip.c
35 @@ -648,6 +648,8 @@ static void mv88e6393x_phylink_validate(
36 {
37 bool is_6191x =
38 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
39 + bool is_6361 =
40 + chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361;
41
42 if (((port == 0 || port == 9) && !is_6191x) || port == 10) {
43 phylink_set(mask, 10000baseT_Full);
44 @@ -662,8 +664,28 @@ static void mv88e6393x_phylink_validate(
45 phylink_set(mask, 2500baseT_Full);
46 }
47
48 + if (port == 0 || port == 9 || port == 10) {
49 + phylink_set(mask, 1000baseX_Full);
50 +
51 + /* 6191X supports >1G modes only on port 10 */
52 + if (!is_6191x || port == 10) {
53 + phylink_set(mask, 2500baseX_Full);
54 + phylink_set(mask, 2500baseT_Full);
55 +
56 + if (!is_6361) {
57 + phylink_set(mask, 10000baseT_Full);
58 + phylink_set(mask, 10000baseKR_Full);
59 + phylink_set(mask, 10000baseCR_Full);
60 + phylink_set(mask, 10000baseSR_Full);
61 + phylink_set(mask, 10000baseLR_Full);
62 + phylink_set(mask, 10000baseLRM_Full);
63 + phylink_set(mask, 10000baseER_Full);
64 + phylink_set(mask, 5000baseT_Full);
65 + }
66 + }
67 + }
68 +
69 phylink_set(mask, 1000baseT_Full);
70 - phylink_set(mask, 1000baseX_Full);
71
72 mv88e6065_phylink_validate(chip, port, mask, state);
73 }
74 @@ -5649,6 +5671,31 @@ static const struct mv88e6xxx_info mv88e
75 .ptp_support = true,
76 .ops = &mv88e6352_ops,
77 },
78 + [MV88E6361] = {
79 + .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
80 + .family = MV88E6XXX_FAMILY_6393,
81 + .name = "Marvell 88E6361",
82 + .num_databases = 4096,
83 + .num_macs = 16384,
84 + .num_ports = 11,
85 + /* Ports 1, 2 and 8 are not routed */
86 + .invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
87 + .num_internal_phys = 5,
88 + .internal_phys_offset = 3,
89 + .max_vid = 4095,
90 + .port_base_addr = 0x0,
91 + .phy_base_addr = 0x0,
92 + .global1_addr = 0x1b,
93 + .global2_addr = 0x1c,
94 + .age_time_coeff = 3750,
95 + .g1_irqs = 10,
96 + .g2_irqs = 14,
97 + .atu_move_port_mask = 0x1f,
98 + .pvt = true,
99 + .multi_chip = true,
100 + .ptp_support = true,
101 + .ops = &mv88e6393x_ops,
102 + },
103 [MV88E6390] = {
104 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
105 .family = MV88E6XXX_FAMILY_6390,
106 --- a/drivers/net/dsa/mv88e6xxx/chip.h
107 +++ b/drivers/net/dsa/mv88e6xxx/chip.h
108 @@ -81,6 +81,7 @@ enum mv88e6xxx_model {
109 MV88E6350,
110 MV88E6351,
111 MV88E6352,
112 + MV88E6361,
113 MV88E6390,
114 MV88E6390X,
115 MV88E6393X,
116 @@ -99,7 +100,7 @@ enum mv88e6xxx_family {
117 MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
118 MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
119 MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
120 - MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */
121 + MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6361 6393X */
122 };
123
124 /**
125 --- a/drivers/net/dsa/mv88e6xxx/port.c
126 +++ b/drivers/net/dsa/mv88e6xxx/port.c
127 @@ -451,6 +451,10 @@ int mv88e6393x_port_set_speed_duplex(str
128 if (speed == SPEED_MAX)
129 speed = (port > 0 && port < 9) ? 1000 : 10000;
130
131 + if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 &&
132 + speed > 2500)
133 + return -EOPNOTSUPP;
134 +
135 if (speed == 200 && port != 0)
136 return -EOPNOTSUPP;
137
138 @@ -533,10 +537,14 @@ int mv88e6393x_port_set_speed_duplex(str
139 phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
140 int port)
141 {
142 - if (port == 0 || port == 9 || port == 10)
143 - return PHY_INTERFACE_MODE_10GBASER;
144
145 - return PHY_INTERFACE_MODE_NA;
146 + if (port != 0 && port != 9 && port != 10)
147 + return PHY_INTERFACE_MODE_NA;
148 +
149 + if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361)
150 + return PHY_INTERFACE_MODE_2500BASEX;
151 +
152 + return PHY_INTERFACE_MODE_10GBASER;
153 }
154
155 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
156 --- a/drivers/net/dsa/mv88e6xxx/port.h
157 +++ b/drivers/net/dsa/mv88e6xxx/port.h
158 @@ -128,6 +128,7 @@
159 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200
160 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
161 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
162 +#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361 0x2610
163 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
164 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100
165 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400