1 |
From 2ce5aed72b47d4c78a232cddda3c49c0d6d68de4 Mon Sep 17 00:00:00 2001 |
2 |
From: Sasha Levin <sashal@kernel.org> |
3 |
Date: Fri, 17 Jun 2022 14:12:46 +0530 |
4 |
Subject: net: dsa: microchip: move switch chip_id detection to ksz_common |
5 |
|
6 |
From: Arun Ramadoss <arun.ramadoss@microchip.com> |
7 |
|
8 |
[ Upstream commit 91a98917a8839923d404a77c21646ca5fc9e330a ] |
9 |
|
10 |
KSZ87xx and KSZ88xx have chip_id representation at reg location 0. And |
11 |
KSZ9477 compatible switch and LAN937x switch have same chip_id detection |
12 |
at location 0x01 and 0x02. To have the common switch detect |
13 |
functionality for ksz switches, ksz_switch_detect function is |
14 |
introduced. |
15 |
|
16 |
Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> |
17 |
Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
18 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
19 |
--- |
20 |
drivers/net/dsa/microchip/ksz8795.c | 48 +-------------- |
21 |
drivers/net/dsa/microchip/ksz8795_reg.h | 16 ----- |
22 |
drivers/net/dsa/microchip/ksz9477.c | 21 ------- |
23 |
drivers/net/dsa/microchip/ksz9477_reg.h | 1 - |
24 |
drivers/net/dsa/microchip/ksz_common.c | 78 +++++++++++++++++++++++-- |
25 |
drivers/net/dsa/microchip/ksz_common.h | 19 +++++- |
26 |
6 files changed, 93 insertions(+), 90 deletions(-) |
27 |
|
28 |
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c |
29 |
index 12a599d5e61a4..3cc51ee5fb6cc 100644 |
30 |
--- a/drivers/net/dsa/microchip/ksz8795.c |
31 |
+++ b/drivers/net/dsa/microchip/ksz8795.c |
32 |
@@ -1272,7 +1272,7 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds) |
33 |
continue; |
34 |
if (!ksz_is_ksz88x3(dev)) { |
35 |
ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote); |
36 |
- if (remote & PORT_FIBER_MODE) |
37 |
+ if (remote & KSZ8_PORT_FIBER_MODE) |
38 |
p->fiber = 1; |
39 |
} |
40 |
if (p->fiber) |
41 |
@@ -1424,51 +1424,6 @@ static u32 ksz8_get_port_addr(int port, int offset) |
42 |
return PORT_CTRL_ADDR(port, offset); |
43 |
} |
44 |
|
45 |
-static int ksz8_switch_detect(struct ksz_device *dev) |
46 |
-{ |
47 |
- u8 id1, id2; |
48 |
- u16 id16; |
49 |
- int ret; |
50 |
- |
51 |
- /* read chip id */ |
52 |
- ret = ksz_read16(dev, REG_CHIP_ID0, &id16); |
53 |
- if (ret) |
54 |
- return ret; |
55 |
- |
56 |
- id1 = id16 >> 8; |
57 |
- id2 = id16 & SW_CHIP_ID_M; |
58 |
- |
59 |
- switch (id1) { |
60 |
- case KSZ87_FAMILY_ID: |
61 |
- if ((id2 != CHIP_ID_94 && id2 != CHIP_ID_95)) |
62 |
- return -ENODEV; |
63 |
- |
64 |
- if (id2 == CHIP_ID_95) { |
65 |
- u8 val; |
66 |
- |
67 |
- id2 = 0x95; |
68 |
- ksz_read8(dev, REG_PORT_STATUS_0, &val); |
69 |
- if (val & PORT_FIBER_MODE) |
70 |
- id2 = 0x65; |
71 |
- } else if (id2 == CHIP_ID_94) { |
72 |
- id2 = 0x94; |
73 |
- } |
74 |
- break; |
75 |
- case KSZ88_FAMILY_ID: |
76 |
- if (id2 != CHIP_ID_63) |
77 |
- return -ENODEV; |
78 |
- break; |
79 |
- default: |
80 |
- dev_err(dev->dev, "invalid family id: %d\n", id1); |
81 |
- return -ENODEV; |
82 |
- } |
83 |
- id16 &= ~0xff; |
84 |
- id16 |= id2; |
85 |
- dev->chip_id = id16; |
86 |
- |
87 |
- return 0; |
88 |
-} |
89 |
- |
90 |
static int ksz8_switch_init(struct ksz_device *dev) |
91 |
{ |
92 |
struct ksz8 *ksz8 = dev->priv; |
93 |
@@ -1522,7 +1477,6 @@ static const struct ksz_dev_ops ksz8_dev_ops = { |
94 |
.freeze_mib = ksz8_freeze_mib, |
95 |
.port_init_cnt = ksz8_port_init_cnt, |
96 |
.shutdown = ksz8_reset_switch, |
97 |
- .detect = ksz8_switch_detect, |
98 |
.init = ksz8_switch_init, |
99 |
.exit = ksz8_switch_exit, |
100 |
}; |
101 |
diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h |
102 |
index 4109433b6b6c2..b8f6ad7581bcd 100644 |
103 |
--- a/drivers/net/dsa/microchip/ksz8795_reg.h |
104 |
+++ b/drivers/net/dsa/microchip/ksz8795_reg.h |
105 |
@@ -14,23 +14,10 @@ |
106 |
#define KS_PRIO_M 0x3 |
107 |
#define KS_PRIO_S 2 |
108 |
|
109 |
-#define REG_CHIP_ID0 0x00 |
110 |
- |
111 |
-#define KSZ87_FAMILY_ID 0x87 |
112 |
-#define KSZ88_FAMILY_ID 0x88 |
113 |
- |
114 |
-#define REG_CHIP_ID1 0x01 |
115 |
- |
116 |
-#define SW_CHIP_ID_M 0xF0 |
117 |
-#define SW_CHIP_ID_S 4 |
118 |
#define SW_REVISION_M 0x0E |
119 |
#define SW_REVISION_S 1 |
120 |
#define SW_START 0x01 |
121 |
|
122 |
-#define CHIP_ID_94 0x60 |
123 |
-#define CHIP_ID_95 0x90 |
124 |
-#define CHIP_ID_63 0x30 |
125 |
- |
126 |
#define KSZ8863_REG_SW_RESET 0x43 |
127 |
|
128 |
#define KSZ8863_GLOBAL_SOFTWARE_RESET BIT(4) |
129 |
@@ -217,8 +204,6 @@ |
130 |
#define REG_PORT_4_STATUS_0 0x48 |
131 |
|
132 |
/* For KSZ8765. */ |
133 |
-#define PORT_FIBER_MODE BIT(7) |
134 |
- |
135 |
#define PORT_REMOTE_ASYM_PAUSE BIT(5) |
136 |
#define PORT_REMOTE_SYM_PAUSE BIT(4) |
137 |
#define PORT_REMOTE_100BTX_FD BIT(3) |
138 |
@@ -322,7 +307,6 @@ |
139 |
|
140 |
#define REG_PORT_CTRL_5 0x05 |
141 |
|
142 |
-#define REG_PORT_STATUS_0 0x08 |
143 |
#define REG_PORT_STATUS_1 0x09 |
144 |
#define REG_PORT_LINK_MD_CTRL 0x0A |
145 |
#define REG_PORT_LINK_MD_RESULT 0x0B |
146 |
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c |
147 |
index 876a801ac23a4..bcfdd505ca79a 100644 |
148 |
--- a/drivers/net/dsa/microchip/ksz9477.c |
149 |
+++ b/drivers/net/dsa/microchip/ksz9477.c |
150 |
@@ -1363,23 +1363,6 @@ static u32 ksz9477_get_port_addr(int port, int offset) |
151 |
return PORT_CTRL_ADDR(port, offset); |
152 |
} |
153 |
|
154 |
-static int ksz9477_switch_detect(struct ksz_device *dev) |
155 |
-{ |
156 |
- u32 id32; |
157 |
- int ret; |
158 |
- |
159 |
- /* read chip id */ |
160 |
- ret = ksz_read32(dev, REG_CHIP_ID0__1, &id32); |
161 |
- if (ret) |
162 |
- return ret; |
163 |
- |
164 |
- dev_dbg(dev->dev, "Switch detect: ID=%08x\n", id32); |
165 |
- |
166 |
- dev->chip_id = id32 & 0x00FFFF00; |
167 |
- |
168 |
- return 0; |
169 |
-} |
170 |
- |
171 |
static int ksz9477_switch_init(struct ksz_device *dev) |
172 |
{ |
173 |
u8 data8; |
174 |
@@ -1410,8 +1393,6 @@ static int ksz9477_switch_init(struct ksz_device *dev) |
175 |
dev->features = GBIT_SUPPORT; |
176 |
|
177 |
if (dev->chip_id == KSZ9893_CHIP_ID) { |
178 |
- /* Chip is from KSZ9893 design. */ |
179 |
- dev_info(dev->dev, "Found KSZ9893\n"); |
180 |
dev->features |= IS_9893; |
181 |
|
182 |
/* Chip does not support gigabit. */ |
183 |
@@ -1419,7 +1400,6 @@ static int ksz9477_switch_init(struct ksz_device *dev) |
184 |
dev->features &= ~GBIT_SUPPORT; |
185 |
dev->phy_port_cnt = 2; |
186 |
} else { |
187 |
- dev_info(dev->dev, "Found KSZ9477 or compatible\n"); |
188 |
/* Chip uses new XMII register definitions. */ |
189 |
dev->features |= NEW_XMII; |
190 |
|
191 |
@@ -1446,7 +1426,6 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { |
192 |
.freeze_mib = ksz9477_freeze_mib, |
193 |
.port_init_cnt = ksz9477_port_init_cnt, |
194 |
.shutdown = ksz9477_reset_switch, |
195 |
- .detect = ksz9477_switch_detect, |
196 |
.init = ksz9477_switch_init, |
197 |
.exit = ksz9477_switch_exit, |
198 |
}; |
199 |
diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h |
200 |
index 7a2c8d4767aff..077e35ab11b54 100644 |
201 |
--- a/drivers/net/dsa/microchip/ksz9477_reg.h |
202 |
+++ b/drivers/net/dsa/microchip/ksz9477_reg.h |
203 |
@@ -25,7 +25,6 @@ |
204 |
|
205 |
#define REG_CHIP_ID2__1 0x0002 |
206 |
|
207 |
-#define CHIP_ID_63 0x63 |
208 |
#define CHIP_ID_66 0x66 |
209 |
#define CHIP_ID_67 0x67 |
210 |
#define CHIP_ID_77 0x77 |
211 |
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c |
212 |
index 92a500e1ccd21..4511e99823f57 100644 |
213 |
--- a/drivers/net/dsa/microchip/ksz_common.c |
214 |
+++ b/drivers/net/dsa/microchip/ksz_common.c |
215 |
@@ -930,6 +930,72 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, |
216 |
} |
217 |
EXPORT_SYMBOL_GPL(ksz_port_stp_state_set); |
218 |
|
219 |
+static int ksz_switch_detect(struct ksz_device *dev) |
220 |
+{ |
221 |
+ u8 id1, id2; |
222 |
+ u16 id16; |
223 |
+ u32 id32; |
224 |
+ int ret; |
225 |
+ |
226 |
+ /* read chip id */ |
227 |
+ ret = ksz_read16(dev, REG_CHIP_ID0, &id16); |
228 |
+ if (ret) |
229 |
+ return ret; |
230 |
+ |
231 |
+ id1 = FIELD_GET(SW_FAMILY_ID_M, id16); |
232 |
+ id2 = FIELD_GET(SW_CHIP_ID_M, id16); |
233 |
+ |
234 |
+ switch (id1) { |
235 |
+ case KSZ87_FAMILY_ID: |
236 |
+ if (id2 == KSZ87_CHIP_ID_95) { |
237 |
+ u8 val; |
238 |
+ |
239 |
+ dev->chip_id = KSZ8795_CHIP_ID; |
240 |
+ |
241 |
+ ksz_read8(dev, KSZ8_PORT_STATUS_0, &val); |
242 |
+ if (val & KSZ8_PORT_FIBER_MODE) |
243 |
+ dev->chip_id = KSZ8765_CHIP_ID; |
244 |
+ } else if (id2 == KSZ87_CHIP_ID_94) { |
245 |
+ dev->chip_id = KSZ8794_CHIP_ID; |
246 |
+ } else { |
247 |
+ return -ENODEV; |
248 |
+ } |
249 |
+ break; |
250 |
+ case KSZ88_FAMILY_ID: |
251 |
+ if (id2 == KSZ88_CHIP_ID_63) |
252 |
+ dev->chip_id = KSZ8830_CHIP_ID; |
253 |
+ else |
254 |
+ return -ENODEV; |
255 |
+ break; |
256 |
+ default: |
257 |
+ ret = ksz_read32(dev, REG_CHIP_ID0, &id32); |
258 |
+ if (ret) |
259 |
+ return ret; |
260 |
+ |
261 |
+ dev->chip_rev = FIELD_GET(SW_REV_ID_M, id32); |
262 |
+ id32 &= ~0xFF; |
263 |
+ |
264 |
+ switch (id32) { |
265 |
+ case KSZ9477_CHIP_ID: |
266 |
+ case KSZ9897_CHIP_ID: |
267 |
+ case KSZ9893_CHIP_ID: |
268 |
+ case KSZ9567_CHIP_ID: |
269 |
+ case LAN9370_CHIP_ID: |
270 |
+ case LAN9371_CHIP_ID: |
271 |
+ case LAN9372_CHIP_ID: |
272 |
+ case LAN9373_CHIP_ID: |
273 |
+ case LAN9374_CHIP_ID: |
274 |
+ dev->chip_id = id32; |
275 |
+ break; |
276 |
+ default: |
277 |
+ dev_err(dev->dev, |
278 |
+ "unsupported switch detected %x)\n", id32); |
279 |
+ return -ENODEV; |
280 |
+ } |
281 |
+ } |
282 |
+ return 0; |
283 |
+} |
284 |
+ |
285 |
struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) |
286 |
{ |
287 |
struct dsa_switch *ds; |
288 |
@@ -986,10 +1052,9 @@ int ksz_switch_register(struct ksz_device *dev, |
289 |
mutex_init(&dev->alu_mutex); |
290 |
mutex_init(&dev->vlan_mutex); |
291 |
|
292 |
- dev->dev_ops = ops; |
293 |
- |
294 |
- if (dev->dev_ops->detect(dev)) |
295 |
- return -EINVAL; |
296 |
+ ret = ksz_switch_detect(dev); |
297 |
+ if (ret) |
298 |
+ return ret; |
299 |
|
300 |
info = ksz_lookup_info(dev->chip_id); |
301 |
if (!info) |
302 |
@@ -998,10 +1063,15 @@ int ksz_switch_register(struct ksz_device *dev, |
303 |
/* Update the compatible info with the probed one */ |
304 |
dev->info = info; |
305 |
|
306 |
+ dev_info(dev->dev, "found switch: %s, rev %i\n", |
307 |
+ dev->info->dev_name, dev->chip_rev); |
308 |
+ |
309 |
ret = ksz_check_device_id(dev); |
310 |
if (ret) |
311 |
return ret; |
312 |
|
313 |
+ dev->dev_ops = ops; |
314 |
+ |
315 |
ret = dev->dev_ops->init(dev); |
316 |
if (ret) |
317 |
return ret; |
318 |
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h |
319 |
index 8500eaedad67a..e6bc5fb2b1303 100644 |
320 |
--- a/drivers/net/dsa/microchip/ksz_common.h |
321 |
+++ b/drivers/net/dsa/microchip/ksz_common.h |
322 |
@@ -90,6 +90,7 @@ struct ksz_device { |
323 |
|
324 |
/* chip specific data */ |
325 |
u32 chip_id; |
326 |
+ u8 chip_rev; |
327 |
int cpu_port; /* port connected to CPU */ |
328 |
int phy_port_cnt; |
329 |
phy_interface_t compat_interface; |
330 |
@@ -182,7 +183,6 @@ struct ksz_dev_ops { |
331 |
void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); |
332 |
void (*port_init_cnt)(struct ksz_device *dev, int port); |
333 |
int (*shutdown)(struct ksz_device *dev); |
334 |
- int (*detect)(struct ksz_device *dev); |
335 |
int (*init)(struct ksz_device *dev); |
336 |
void (*exit)(struct ksz_device *dev); |
337 |
}; |
338 |
@@ -353,6 +353,23 @@ static inline void ksz_regmap_unlock(void *__mtx) |
339 |
#define PORT_RX_ENABLE BIT(1) |
340 |
#define PORT_LEARN_DISABLE BIT(0) |
341 |
|
342 |
+/* Switch ID Defines */ |
343 |
+#define REG_CHIP_ID0 0x00 |
344 |
+ |
345 |
+#define SW_FAMILY_ID_M GENMASK(15, 8) |
346 |
+#define KSZ87_FAMILY_ID 0x87 |
347 |
+#define KSZ88_FAMILY_ID 0x88 |
348 |
+ |
349 |
+#define KSZ8_PORT_STATUS_0 0x08 |
350 |
+#define KSZ8_PORT_FIBER_MODE BIT(7) |
351 |
+ |
352 |
+#define SW_CHIP_ID_M GENMASK(7, 4) |
353 |
+#define KSZ87_CHIP_ID_94 0x6 |
354 |
+#define KSZ87_CHIP_ID_95 0x9 |
355 |
+#define KSZ88_CHIP_ID_63 0x3 |
356 |
+ |
357 |
+#define SW_REV_ID_M GENMASK(7, 4) |
358 |
+ |
359 |
/* Regmap tables generation */ |
360 |
#define KSZ_SPI_OP_RD 3 |
361 |
#define KSZ_SPI_OP_WR 2 |
362 |
-- |
363 |
2.35.1 |
364 |
|