1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name> |
4 | * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. |
6 | * Copyright (c) 2016 John Crispin <john@phrozen.org> |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/phy.h> |
11 | #include <linux/netdevice.h> |
12 | #include <linux/bitfield.h> |
13 | #include <linux/regmap.h> |
14 | #include <net/dsa.h> |
15 | #include <linux/of_net.h> |
16 | #include <linux/of_mdio.h> |
17 | #include <linux/of_platform.h> |
18 | #include <linux/mdio.h> |
19 | #include <linux/phylink.h> |
20 | #include <linux/gpio/consumer.h> |
21 | #include <linux/etherdevice.h> |
22 | #include <linux/dsa/tag_qca.h> |
23 | |
24 | #include "qca8k.h" |
25 | #include "qca8k_leds.h" |
26 | |
27 | static void |
28 | qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) |
29 | { |
30 | regaddr >>= 1; |
31 | *r1 = regaddr & 0x1e; |
32 | |
33 | regaddr >>= 5; |
34 | *r2 = regaddr & 0x7; |
35 | |
36 | regaddr >>= 3; |
37 | *page = regaddr & 0x3ff; |
38 | } |
39 | |
40 | static int |
41 | qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) |
42 | { |
43 | int ret; |
44 | u16 lo; |
45 | |
46 | lo = val & 0xffff; |
47 | ret = bus->write(bus, phy_id, regnum, lo); |
48 | if (ret < 0) |
49 | dev_err_ratelimited(&bus->dev, |
50 | "failed to write qca8k 32bit lo register\n" ); |
51 | |
52 | return ret; |
53 | } |
54 | |
55 | static int |
56 | qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) |
57 | { |
58 | int ret; |
59 | u16 hi; |
60 | |
61 | hi = (u16)(val >> 16); |
62 | ret = bus->write(bus, phy_id, regnum, hi); |
63 | if (ret < 0) |
64 | dev_err_ratelimited(&bus->dev, |
65 | "failed to write qca8k 32bit hi register\n" ); |
66 | |
67 | return ret; |
68 | } |
69 | |
70 | static int |
71 | qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) |
72 | { |
73 | int ret; |
74 | |
75 | ret = bus->read(bus, phy_id, regnum); |
76 | if (ret < 0) |
77 | goto err; |
78 | |
79 | *val = ret & 0xffff; |
80 | return 0; |
81 | |
82 | err: |
83 | dev_err_ratelimited(&bus->dev, |
84 | "failed to read qca8k 32bit lo register\n" ); |
85 | *val = 0; |
86 | |
87 | return ret; |
88 | } |
89 | |
90 | static int |
91 | qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) |
92 | { |
93 | int ret; |
94 | |
95 | ret = bus->read(bus, phy_id, regnum); |
96 | if (ret < 0) |
97 | goto err; |
98 | |
99 | *val = ret << 16; |
100 | return 0; |
101 | |
102 | err: |
103 | dev_err_ratelimited(&bus->dev, |
104 | "failed to read qca8k 32bit hi register\n" ); |
105 | *val = 0; |
106 | |
107 | return ret; |
108 | } |
109 | |
110 | static int |
111 | qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) |
112 | { |
113 | u32 hi, lo; |
114 | int ret; |
115 | |
116 | *val = 0; |
117 | |
118 | ret = qca8k_mii_read_lo(bus, phy_id, regnum, val: &lo); |
119 | if (ret < 0) |
120 | goto err; |
121 | |
122 | ret = qca8k_mii_read_hi(bus, phy_id, regnum: regnum + 1, val: &hi); |
123 | if (ret < 0) |
124 | goto err; |
125 | |
126 | *val = lo | hi; |
127 | |
128 | err: |
129 | return ret; |
130 | } |
131 | |
132 | static void |
133 | qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) |
134 | { |
135 | if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0) |
136 | return; |
137 | |
138 | qca8k_mii_write_hi(bus, phy_id, regnum: regnum + 1, val); |
139 | } |
140 | |
141 | static int |
142 | qca8k_set_page(struct qca8k_priv *priv, u16 page) |
143 | { |
144 | u16 *cached_page = &priv->mdio_cache.page; |
145 | struct mii_bus *bus = priv->bus; |
146 | int ret; |
147 | |
148 | if (page == *cached_page) |
149 | return 0; |
150 | |
151 | ret = bus->write(bus, 0x18, 0, page); |
152 | if (ret < 0) { |
153 | dev_err_ratelimited(&bus->dev, |
154 | "failed to set qca8k page\n" ); |
155 | return ret; |
156 | } |
157 | |
158 | *cached_page = page; |
159 | usleep_range(min: 1000, max: 2000); |
160 | return 0; |
161 | } |
162 | |
163 | static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) |
164 | { |
165 | struct qca8k_mgmt_eth_data *mgmt_eth_data; |
166 | struct qca8k_priv *priv = ds->priv; |
167 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
168 | u32 command; |
169 | u8 len, cmd; |
170 | int i; |
171 | |
172 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); |
173 | mgmt_eth_data = &priv->mgmt_eth_data; |
174 | |
175 | command = get_unaligned_le32(p: &mgmt_ethhdr->command); |
176 | cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); |
177 | |
178 | len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); |
179 | /* Special case for len of 15 as this is the max value for len and needs to |
180 | * be increased before converting it from word to dword. |
181 | */ |
182 | if (len == 15) |
183 | len++; |
184 | |
185 | /* We can ignore odd value, we always round up them in the alloc function. */ |
186 | len *= sizeof(u16); |
187 | |
188 | /* Make sure the seq match the requested packet */ |
189 | if (get_unaligned_le32(p: &mgmt_ethhdr->seq) == mgmt_eth_data->seq) |
190 | mgmt_eth_data->ack = true; |
191 | |
192 | if (cmd == MDIO_READ) { |
193 | u32 *val = mgmt_eth_data->data; |
194 | |
195 | *val = get_unaligned_le32(p: &mgmt_ethhdr->mdio_data); |
196 | |
197 | /* Get the rest of the 12 byte of data. |
198 | * The read/write function will extract the requested data. |
199 | */ |
200 | if (len > QCA_HDR_MGMT_DATA1_LEN) { |
201 | __le32 *data2 = (__le32 *)skb->data; |
202 | int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, |
203 | len - QCA_HDR_MGMT_DATA1_LEN); |
204 | |
205 | val++; |
206 | |
207 | for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { |
208 | *val = get_unaligned_le32(p: data2); |
209 | val++; |
210 | data2++; |
211 | } |
212 | } |
213 | } |
214 | |
215 | complete(&mgmt_eth_data->rw_done); |
216 | } |
217 | |
218 | static struct sk_buff *(enum mdio_cmd cmd, u32 reg, u32 *val, |
219 | int priority, unsigned int len) |
220 | { |
221 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
222 | unsigned int real_len; |
223 | struct sk_buff *skb; |
224 | __le32 *data2; |
225 | u32 command; |
226 | u16 hdr; |
227 | int i; |
228 | |
229 | skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); |
230 | if (!skb) |
231 | return NULL; |
232 | |
233 | /* Hdr mgmt length value is in step of word size. |
234 | * As an example to process 4 byte of data the correct length to set is 2. |
235 | * To process 8 byte 4, 12 byte 6, 16 byte 8... |
236 | * |
237 | * Odd values will always return the next size on the ack packet. |
238 | * (length of 3 (6 byte) will always return 8 bytes of data) |
239 | * |
240 | * This means that a value of 15 (0xf) actually means reading/writing 32 bytes |
241 | * of data. |
242 | * |
243 | * To correctly calculate the length we devide the requested len by word and |
244 | * round up. |
245 | * On the ack function we can skip the odd check as we already handle the |
246 | * case here. |
247 | */ |
248 | real_len = DIV_ROUND_UP(len, sizeof(u16)); |
249 | |
250 | /* We check if the result len is odd and we round up another time to |
251 | * the next size. (length of 3 will be increased to 4 as switch will always |
252 | * return 8 bytes) |
253 | */ |
254 | if (real_len % sizeof(u16) != 0) |
255 | real_len++; |
256 | |
257 | /* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */ |
258 | if (real_len == 16) |
259 | real_len--; |
260 | |
261 | skb_reset_mac_header(skb); |
262 | skb_set_network_header(skb, offset: skb->len); |
263 | |
264 | mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); |
265 | |
266 | hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); |
267 | hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); |
268 | hdr |= QCA_HDR_XMIT_FROM_CPU; |
269 | hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); |
270 | hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); |
271 | |
272 | command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); |
273 | command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); |
274 | command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); |
275 | command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, |
276 | QCA_HDR_MGMT_CHECK_CODE_VAL); |
277 | |
278 | put_unaligned_le32(val: command, p: &mgmt_ethhdr->command); |
279 | |
280 | if (cmd == MDIO_WRITE) |
281 | put_unaligned_le32(val: *val, p: &mgmt_ethhdr->mdio_data); |
282 | |
283 | mgmt_ethhdr->hdr = htons(hdr); |
284 | |
285 | data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); |
286 | if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) { |
287 | int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, |
288 | len - QCA_HDR_MGMT_DATA1_LEN); |
289 | |
290 | val++; |
291 | |
292 | for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { |
293 | put_unaligned_le32(val: *val, p: data2); |
294 | data2++; |
295 | val++; |
296 | } |
297 | } |
298 | |
299 | return skb; |
300 | } |
301 | |
302 | static void (struct sk_buff *skb, u32 seq_num) |
303 | { |
304 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
305 | u32 seq; |
306 | |
307 | seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); |
308 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; |
309 | put_unaligned_le32(val: seq, p: &mgmt_ethhdr->seq); |
310 | } |
311 | |
312 | static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) |
313 | { |
314 | struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; |
315 | struct sk_buff *skb; |
316 | bool ack; |
317 | int ret; |
318 | |
319 | skb = qca8k_alloc_mdio_header(cmd: MDIO_READ, reg, NULL, |
320 | QCA8K_ETHERNET_MDIO_PRIORITY, len); |
321 | if (!skb) |
322 | return -ENOMEM; |
323 | |
324 | mutex_lock(&mgmt_eth_data->mutex); |
325 | |
326 | /* Check if the mgmt_conduit if is operational */ |
327 | if (!priv->mgmt_conduit) { |
328 | kfree_skb(skb); |
329 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
330 | return -EINVAL; |
331 | } |
332 | |
333 | skb->dev = priv->mgmt_conduit; |
334 | |
335 | reinit_completion(x: &mgmt_eth_data->rw_done); |
336 | |
337 | /* Increment seq_num and set it in the mdio pkt */ |
338 | mgmt_eth_data->seq++; |
339 | qca8k_mdio_header_fill_seq_num(skb, seq_num: mgmt_eth_data->seq); |
340 | mgmt_eth_data->ack = false; |
341 | |
342 | dev_queue_xmit(skb); |
343 | |
344 | ret = wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
345 | timeout: msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); |
346 | |
347 | *val = mgmt_eth_data->data[0]; |
348 | if (len > QCA_HDR_MGMT_DATA1_LEN) |
349 | memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); |
350 | |
351 | ack = mgmt_eth_data->ack; |
352 | |
353 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
354 | |
355 | if (ret <= 0) |
356 | return -ETIMEDOUT; |
357 | |
358 | if (!ack) |
359 | return -EINVAL; |
360 | |
361 | return 0; |
362 | } |
363 | |
364 | static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) |
365 | { |
366 | struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; |
367 | struct sk_buff *skb; |
368 | bool ack; |
369 | int ret; |
370 | |
371 | skb = qca8k_alloc_mdio_header(cmd: MDIO_WRITE, reg, val, |
372 | QCA8K_ETHERNET_MDIO_PRIORITY, len); |
373 | if (!skb) |
374 | return -ENOMEM; |
375 | |
376 | mutex_lock(&mgmt_eth_data->mutex); |
377 | |
378 | /* Check if the mgmt_conduit if is operational */ |
379 | if (!priv->mgmt_conduit) { |
380 | kfree_skb(skb); |
381 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
382 | return -EINVAL; |
383 | } |
384 | |
385 | skb->dev = priv->mgmt_conduit; |
386 | |
387 | reinit_completion(x: &mgmt_eth_data->rw_done); |
388 | |
389 | /* Increment seq_num and set it in the mdio pkt */ |
390 | mgmt_eth_data->seq++; |
391 | qca8k_mdio_header_fill_seq_num(skb, seq_num: mgmt_eth_data->seq); |
392 | mgmt_eth_data->ack = false; |
393 | |
394 | dev_queue_xmit(skb); |
395 | |
396 | ret = wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
397 | timeout: msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); |
398 | |
399 | ack = mgmt_eth_data->ack; |
400 | |
401 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
402 | |
403 | if (ret <= 0) |
404 | return -ETIMEDOUT; |
405 | |
406 | if (!ack) |
407 | return -EINVAL; |
408 | |
409 | return 0; |
410 | } |
411 | |
412 | static int |
413 | qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) |
414 | { |
415 | u32 val = 0; |
416 | int ret; |
417 | |
418 | ret = qca8k_read_eth(priv, reg, val: &val, len: sizeof(val)); |
419 | if (ret) |
420 | return ret; |
421 | |
422 | val &= ~mask; |
423 | val |= write_val; |
424 | |
425 | return qca8k_write_eth(priv, reg, val: &val, len: sizeof(val)); |
426 | } |
427 | |
428 | static int |
429 | qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val) |
430 | { |
431 | struct mii_bus *bus = priv->bus; |
432 | u16 r1, r2, page; |
433 | int ret; |
434 | |
435 | qca8k_split_addr(regaddr: reg, r1: &r1, r2: &r2, page: &page); |
436 | |
437 | mutex_lock_nested(lock: &bus->mdio_lock, subclass: MDIO_MUTEX_NESTED); |
438 | |
439 | ret = qca8k_set_page(priv, page); |
440 | if (ret < 0) |
441 | goto exit; |
442 | |
443 | ret = qca8k_mii_read32(bus, phy_id: 0x10 | r2, regnum: r1, val); |
444 | |
445 | exit: |
446 | mutex_unlock(lock: &bus->mdio_lock); |
447 | return ret; |
448 | } |
449 | |
450 | static int |
451 | qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val) |
452 | { |
453 | struct mii_bus *bus = priv->bus; |
454 | u16 r1, r2, page; |
455 | int ret; |
456 | |
457 | qca8k_split_addr(regaddr: reg, r1: &r1, r2: &r2, page: &page); |
458 | |
459 | mutex_lock_nested(lock: &bus->mdio_lock, subclass: MDIO_MUTEX_NESTED); |
460 | |
461 | ret = qca8k_set_page(priv, page); |
462 | if (ret < 0) |
463 | goto exit; |
464 | |
465 | qca8k_mii_write32(bus, phy_id: 0x10 | r2, regnum: r1, val); |
466 | |
467 | exit: |
468 | mutex_unlock(lock: &bus->mdio_lock); |
469 | return ret; |
470 | } |
471 | |
472 | static int |
473 | qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg, |
474 | uint32_t mask, uint32_t write_val) |
475 | { |
476 | struct mii_bus *bus = priv->bus; |
477 | u16 r1, r2, page; |
478 | u32 val; |
479 | int ret; |
480 | |
481 | qca8k_split_addr(regaddr: reg, r1: &r1, r2: &r2, page: &page); |
482 | |
483 | mutex_lock_nested(lock: &bus->mdio_lock, subclass: MDIO_MUTEX_NESTED); |
484 | |
485 | ret = qca8k_set_page(priv, page); |
486 | if (ret < 0) |
487 | goto exit; |
488 | |
489 | ret = qca8k_mii_read32(bus, phy_id: 0x10 | r2, regnum: r1, val: &val); |
490 | if (ret < 0) |
491 | goto exit; |
492 | |
493 | val &= ~mask; |
494 | val |= write_val; |
495 | qca8k_mii_write32(bus, phy_id: 0x10 | r2, regnum: r1, val); |
496 | |
497 | exit: |
498 | mutex_unlock(lock: &bus->mdio_lock); |
499 | |
500 | return ret; |
501 | } |
502 | |
503 | static int |
504 | qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len, |
505 | void *val_buf, size_t val_len) |
506 | { |
507 | int i, count = val_len / sizeof(u32), ret; |
508 | struct qca8k_priv *priv = ctx; |
509 | u32 reg = *(u16 *)reg_buf; |
510 | |
511 | if (priv->mgmt_conduit && |
512 | !qca8k_read_eth(priv, reg, val: val_buf, len: val_len)) |
513 | return 0; |
514 | |
515 | /* loop count times and increment reg of 4 */ |
516 | for (i = 0; i < count; i++, reg += sizeof(u32)) { |
517 | ret = qca8k_read_mii(priv, reg, val: val_buf + i); |
518 | if (ret < 0) |
519 | return ret; |
520 | } |
521 | |
522 | return 0; |
523 | } |
524 | |
525 | static int |
526 | qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len, |
527 | const void *val_buf, size_t val_len) |
528 | { |
529 | int i, count = val_len / sizeof(u32), ret; |
530 | struct qca8k_priv *priv = ctx; |
531 | u32 reg = *(u16 *)reg_buf; |
532 | u32 *val = (u32 *)val_buf; |
533 | |
534 | if (priv->mgmt_conduit && |
535 | !qca8k_write_eth(priv, reg, val, len: val_len)) |
536 | return 0; |
537 | |
538 | /* loop count times, increment reg of 4 and increment val ptr to |
539 | * the next value |
540 | */ |
541 | for (i = 0; i < count; i++, reg += sizeof(u32), val++) { |
542 | ret = qca8k_write_mii(priv, reg, val: *val); |
543 | if (ret < 0) |
544 | return ret; |
545 | } |
546 | |
547 | return 0; |
548 | } |
549 | |
550 | static int |
551 | qca8k_bulk_write(void *ctx, const void *data, size_t bytes) |
552 | { |
553 | return qca8k_bulk_gather_write(ctx, reg_buf: data, reg_len: sizeof(u16), val_buf: data + sizeof(u16), |
554 | val_len: bytes - sizeof(u16)); |
555 | } |
556 | |
557 | static int |
558 | qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) |
559 | { |
560 | struct qca8k_priv *priv = ctx; |
561 | |
562 | if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) |
563 | return 0; |
564 | |
565 | return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val); |
566 | } |
567 | |
568 | static struct regmap_config qca8k_regmap_config = { |
569 | .reg_bits = 16, |
570 | .val_bits = 32, |
571 | .reg_stride = 4, |
572 | .max_register = 0x16ac, /* end MIB - Port6 range */ |
573 | .read = qca8k_bulk_read, |
574 | .write = qca8k_bulk_write, |
575 | .reg_update_bits = qca8k_regmap_update_bits, |
576 | .rd_table = &qca8k_readable_table, |
577 | .disable_locking = true, /* Locking is handled by qca8k read/write */ |
578 | .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ |
579 | .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */ |
580 | /* ATU regs suffer from a bug where some data are not correctly |
581 | * written. Disable bulk write to correctly write ATU entry. |
582 | */ |
583 | .use_single_write = true, |
584 | }; |
585 | |
586 | static int |
587 | qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, |
588 | struct sk_buff *read_skb, u32 *val) |
589 | { |
590 | struct sk_buff *skb = skb_copy(skb: read_skb, GFP_KERNEL); |
591 | bool ack; |
592 | int ret; |
593 | |
594 | if (!skb) |
595 | return -ENOMEM; |
596 | |
597 | reinit_completion(x: &mgmt_eth_data->rw_done); |
598 | |
599 | /* Increment seq_num and set it in the copy pkt */ |
600 | mgmt_eth_data->seq++; |
601 | qca8k_mdio_header_fill_seq_num(skb, seq_num: mgmt_eth_data->seq); |
602 | mgmt_eth_data->ack = false; |
603 | |
604 | dev_queue_xmit(skb); |
605 | |
606 | ret = wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
607 | QCA8K_ETHERNET_TIMEOUT); |
608 | |
609 | ack = mgmt_eth_data->ack; |
610 | |
611 | if (ret <= 0) |
612 | return -ETIMEDOUT; |
613 | |
614 | if (!ack) |
615 | return -EINVAL; |
616 | |
617 | *val = mgmt_eth_data->data[0]; |
618 | |
619 | return 0; |
620 | } |
621 | |
622 | static int |
623 | qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, |
624 | int regnum, u16 data) |
625 | { |
626 | struct sk_buff *write_skb, *clear_skb, *read_skb; |
627 | struct qca8k_mgmt_eth_data *mgmt_eth_data; |
628 | u32 write_val, clear_val = 0, val; |
629 | struct net_device *mgmt_conduit; |
630 | int ret, ret1; |
631 | bool ack; |
632 | |
633 | if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) |
634 | return -EINVAL; |
635 | |
636 | mgmt_eth_data = &priv->mgmt_eth_data; |
637 | |
638 | write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | |
639 | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | |
640 | QCA8K_MDIO_MASTER_REG_ADDR(regnum); |
641 | |
642 | if (read) { |
643 | write_val |= QCA8K_MDIO_MASTER_READ; |
644 | } else { |
645 | write_val |= QCA8K_MDIO_MASTER_WRITE; |
646 | write_val |= QCA8K_MDIO_MASTER_DATA(data); |
647 | } |
648 | |
649 | /* Prealloc all the needed skb before the lock */ |
650 | write_skb = qca8k_alloc_mdio_header(cmd: MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, val: &write_val, |
651 | QCA8K_ETHERNET_PHY_PRIORITY, len: sizeof(write_val)); |
652 | if (!write_skb) |
653 | return -ENOMEM; |
654 | |
655 | clear_skb = qca8k_alloc_mdio_header(cmd: MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, val: &clear_val, |
656 | QCA8K_ETHERNET_PHY_PRIORITY, len: sizeof(clear_val)); |
657 | if (!clear_skb) { |
658 | ret = -ENOMEM; |
659 | goto err_clear_skb; |
660 | } |
661 | |
662 | read_skb = qca8k_alloc_mdio_header(cmd: MDIO_READ, QCA8K_MDIO_MASTER_CTRL, val: &clear_val, |
663 | QCA8K_ETHERNET_PHY_PRIORITY, len: sizeof(clear_val)); |
664 | if (!read_skb) { |
665 | ret = -ENOMEM; |
666 | goto err_read_skb; |
667 | } |
668 | |
669 | /* It seems that accessing the switch's internal PHYs via management |
670 | * packets still uses the MDIO bus within the switch internally, and |
671 | * these accesses can conflict with external MDIO accesses to other |
672 | * devices on the MDIO bus. |
673 | * We therefore need to lock the MDIO bus onto which the switch is |
674 | * connected. |
675 | */ |
676 | mutex_lock(&priv->bus->mdio_lock); |
677 | |
678 | /* Actually start the request: |
679 | * 1. Send mdio master packet |
680 | * 2. Busy Wait for mdio master command |
681 | * 3. Get the data if we are reading |
682 | * 4. Reset the mdio master (even with error) |
683 | */ |
684 | mutex_lock(&mgmt_eth_data->mutex); |
685 | |
686 | /* Check if mgmt_conduit is operational */ |
687 | mgmt_conduit = priv->mgmt_conduit; |
688 | if (!mgmt_conduit) { |
689 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
690 | mutex_unlock(lock: &priv->bus->mdio_lock); |
691 | ret = -EINVAL; |
692 | goto err_mgmt_conduit; |
693 | } |
694 | |
695 | read_skb->dev = mgmt_conduit; |
696 | clear_skb->dev = mgmt_conduit; |
697 | write_skb->dev = mgmt_conduit; |
698 | |
699 | reinit_completion(x: &mgmt_eth_data->rw_done); |
700 | |
701 | /* Increment seq_num and set it in the write pkt */ |
702 | mgmt_eth_data->seq++; |
703 | qca8k_mdio_header_fill_seq_num(skb: write_skb, seq_num: mgmt_eth_data->seq); |
704 | mgmt_eth_data->ack = false; |
705 | |
706 | dev_queue_xmit(skb: write_skb); |
707 | |
708 | ret = wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
709 | QCA8K_ETHERNET_TIMEOUT); |
710 | |
711 | ack = mgmt_eth_data->ack; |
712 | |
713 | if (ret <= 0) { |
714 | ret = -ETIMEDOUT; |
715 | kfree_skb(skb: read_skb); |
716 | goto exit; |
717 | } |
718 | |
719 | if (!ack) { |
720 | ret = -EINVAL; |
721 | kfree_skb(skb: read_skb); |
722 | goto exit; |
723 | } |
724 | |
725 | ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, |
726 | !(val & QCA8K_MDIO_MASTER_BUSY), 0, |
727 | QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, |
728 | mgmt_eth_data, read_skb, &val); |
729 | |
730 | if (ret < 0 && ret1 < 0) { |
731 | ret = ret1; |
732 | goto exit; |
733 | } |
734 | |
735 | if (read) { |
736 | reinit_completion(x: &mgmt_eth_data->rw_done); |
737 | |
738 | /* Increment seq_num and set it in the read pkt */ |
739 | mgmt_eth_data->seq++; |
740 | qca8k_mdio_header_fill_seq_num(skb: read_skb, seq_num: mgmt_eth_data->seq); |
741 | mgmt_eth_data->ack = false; |
742 | |
743 | dev_queue_xmit(skb: read_skb); |
744 | |
745 | ret = wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
746 | QCA8K_ETHERNET_TIMEOUT); |
747 | |
748 | ack = mgmt_eth_data->ack; |
749 | |
750 | if (ret <= 0) { |
751 | ret = -ETIMEDOUT; |
752 | goto exit; |
753 | } |
754 | |
755 | if (!ack) { |
756 | ret = -EINVAL; |
757 | goto exit; |
758 | } |
759 | |
760 | ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; |
761 | } else { |
762 | kfree_skb(skb: read_skb); |
763 | } |
764 | exit: |
765 | reinit_completion(x: &mgmt_eth_data->rw_done); |
766 | |
767 | /* Increment seq_num and set it in the clear pkt */ |
768 | mgmt_eth_data->seq++; |
769 | qca8k_mdio_header_fill_seq_num(skb: clear_skb, seq_num: mgmt_eth_data->seq); |
770 | mgmt_eth_data->ack = false; |
771 | |
772 | dev_queue_xmit(skb: clear_skb); |
773 | |
774 | wait_for_completion_timeout(x: &mgmt_eth_data->rw_done, |
775 | QCA8K_ETHERNET_TIMEOUT); |
776 | |
777 | mutex_unlock(lock: &mgmt_eth_data->mutex); |
778 | mutex_unlock(lock: &priv->bus->mdio_lock); |
779 | |
780 | return ret; |
781 | |
782 | /* Error handling before lock */ |
783 | err_mgmt_conduit: |
784 | kfree_skb(skb: read_skb); |
785 | err_read_skb: |
786 | kfree_skb(skb: clear_skb); |
787 | err_clear_skb: |
788 | kfree_skb(skb: write_skb); |
789 | |
790 | return ret; |
791 | } |
792 | |
793 | static int |
794 | qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) |
795 | { |
796 | u16 r1, r2, page; |
797 | u32 val; |
798 | int ret, ret1; |
799 | |
800 | qca8k_split_addr(regaddr: reg, r1: &r1, r2: &r2, page: &page); |
801 | |
802 | ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0, |
803 | QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, |
804 | bus, 0x10 | r2, r1 + 1, &val); |
805 | |
806 | /* Check if qca8k_read has failed for a different reason |
807 | * before returnting -ETIMEDOUT |
808 | */ |
809 | if (ret < 0 && ret1 < 0) |
810 | return ret1; |
811 | |
812 | return ret; |
813 | } |
814 | |
815 | static int |
816 | qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) |
817 | { |
818 | struct mii_bus *bus = priv->bus; |
819 | u16 r1, r2, page; |
820 | u32 val; |
821 | int ret; |
822 | |
823 | if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) |
824 | return -EINVAL; |
825 | |
826 | val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | |
827 | QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | |
828 | QCA8K_MDIO_MASTER_REG_ADDR(regnum) | |
829 | QCA8K_MDIO_MASTER_DATA(data); |
830 | |
831 | qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, r1: &r1, r2: &r2, page: &page); |
832 | |
833 | mutex_lock_nested(lock: &bus->mdio_lock, subclass: MDIO_MUTEX_NESTED); |
834 | |
835 | ret = qca8k_set_page(priv, page); |
836 | if (ret) |
837 | goto exit; |
838 | |
839 | qca8k_mii_write32(bus, phy_id: 0x10 | r2, regnum: r1, val); |
840 | |
841 | ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, |
842 | QCA8K_MDIO_MASTER_BUSY); |
843 | |
844 | exit: |
845 | /* even if the busy_wait timeouts try to clear the MASTER_EN */ |
846 | qca8k_mii_write_hi(bus, phy_id: 0x10 | r2, regnum: r1 + 1, val: 0); |
847 | |
848 | mutex_unlock(lock: &bus->mdio_lock); |
849 | |
850 | return ret; |
851 | } |
852 | |
853 | static int |
854 | qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) |
855 | { |
856 | struct mii_bus *bus = priv->bus; |
857 | u16 r1, r2, page; |
858 | u32 val; |
859 | int ret; |
860 | |
861 | if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) |
862 | return -EINVAL; |
863 | |
864 | val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | |
865 | QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | |
866 | QCA8K_MDIO_MASTER_REG_ADDR(regnum); |
867 | |
868 | qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, r1: &r1, r2: &r2, page: &page); |
869 | |
870 | mutex_lock_nested(lock: &bus->mdio_lock, subclass: MDIO_MUTEX_NESTED); |
871 | |
872 | ret = qca8k_set_page(priv, page); |
873 | if (ret) |
874 | goto exit; |
875 | |
876 | qca8k_mii_write_hi(bus, phy_id: 0x10 | r2, regnum: r1 + 1, val); |
877 | |
878 | ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, |
879 | QCA8K_MDIO_MASTER_BUSY); |
880 | if (ret) |
881 | goto exit; |
882 | |
883 | ret = qca8k_mii_read_lo(bus, phy_id: 0x10 | r2, regnum: r1, val: &val); |
884 | |
885 | exit: |
886 | /* even if the busy_wait timeouts try to clear the MASTER_EN */ |
887 | qca8k_mii_write_hi(bus, phy_id: 0x10 | r2, regnum: r1 + 1, val: 0); |
888 | |
889 | mutex_unlock(lock: &bus->mdio_lock); |
890 | |
891 | if (ret >= 0) |
892 | ret = val & QCA8K_MDIO_MASTER_DATA_MASK; |
893 | |
894 | return ret; |
895 | } |
896 | |
897 | static int |
898 | qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) |
899 | { |
900 | struct qca8k_priv *priv = slave_bus->priv; |
901 | int ret; |
902 | |
903 | /* Use mdio Ethernet when available, fallback to legacy one on error */ |
904 | ret = qca8k_phy_eth_command(priv, read: false, phy, regnum, data); |
905 | if (!ret) |
906 | return 0; |
907 | |
908 | return qca8k_mdio_write(priv, phy, regnum, data); |
909 | } |
910 | |
911 | static int |
912 | qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) |
913 | { |
914 | struct qca8k_priv *priv = slave_bus->priv; |
915 | int ret; |
916 | |
917 | /* Use mdio Ethernet when available, fallback to legacy one on error */ |
918 | ret = qca8k_phy_eth_command(priv, read: true, phy, regnum, data: 0); |
919 | if (ret >= 0) |
920 | return ret; |
921 | |
922 | ret = qca8k_mdio_read(priv, phy, regnum); |
923 | |
924 | if (ret < 0) |
925 | return 0xffff; |
926 | |
927 | return ret; |
928 | } |
929 | |
930 | static int |
931 | qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) |
932 | { |
933 | port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; |
934 | |
935 | return qca8k_internal_mdio_write(slave_bus, phy: port, regnum, data); |
936 | } |
937 | |
938 | static int |
939 | qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) |
940 | { |
941 | port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; |
942 | |
943 | return qca8k_internal_mdio_read(slave_bus, phy: port, regnum); |
944 | } |
945 | |
946 | static int |
947 | qca8k_mdio_register(struct qca8k_priv *priv) |
948 | { |
949 | struct dsa_switch *ds = priv->ds; |
950 | struct device *dev = ds->dev; |
951 | struct device_node *mdio; |
952 | struct mii_bus *bus; |
953 | int ret = 0; |
954 | |
955 | mdio = of_get_child_by_name(node: dev->of_node, name: "mdio" ); |
956 | if (mdio && !of_device_is_available(device: mdio)) |
957 | goto out_put_node; |
958 | |
959 | bus = devm_mdiobus_alloc(dev); |
960 | if (!bus) { |
961 | ret = -ENOMEM; |
962 | goto out_put_node; |
963 | } |
964 | |
965 | priv->internal_mdio_bus = bus; |
966 | bus->priv = (void *)priv; |
967 | snprintf(buf: bus->id, MII_BUS_ID_SIZE, fmt: "qca8k-%d.%d" , |
968 | ds->dst->index, ds->index); |
969 | bus->parent = dev; |
970 | |
971 | if (mdio) { |
972 | /* Check if the device tree declares the port:phy mapping */ |
973 | bus->name = "qca8k user mii" ; |
974 | bus->read = qca8k_internal_mdio_read; |
975 | bus->write = qca8k_internal_mdio_write; |
976 | } else { |
977 | /* If a mapping can't be found, the legacy mapping is used, |
978 | * using qca8k_port_to_phy() |
979 | */ |
980 | ds->user_mii_bus = bus; |
981 | bus->phy_mask = ~ds->phys_mii_mask; |
982 | bus->name = "qca8k-legacy user mii" ; |
983 | bus->read = qca8k_legacy_mdio_read; |
984 | bus->write = qca8k_legacy_mdio_write; |
985 | } |
986 | |
987 | ret = devm_of_mdiobus_register(dev, mdio: bus, np: mdio); |
988 | |
989 | out_put_node: |
990 | of_node_put(node: mdio); |
991 | return ret; |
992 | } |
993 | |
994 | static int |
995 | qca8k_setup_mdio_bus(struct qca8k_priv *priv) |
996 | { |
997 | u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; |
998 | struct device_node *ports, *port; |
999 | phy_interface_t mode; |
1000 | int ret; |
1001 | |
1002 | ports = of_get_child_by_name(node: priv->dev->of_node, name: "ports" ); |
1003 | if (!ports) |
1004 | ports = of_get_child_by_name(node: priv->dev->of_node, name: "ethernet-ports" ); |
1005 | |
1006 | if (!ports) |
1007 | return -EINVAL; |
1008 | |
1009 | for_each_available_child_of_node(ports, port) { |
1010 | ret = of_property_read_u32(np: port, propname: "reg" , out_value: ®); |
1011 | if (ret) { |
1012 | of_node_put(node: port); |
1013 | of_node_put(node: ports); |
1014 | return ret; |
1015 | } |
1016 | |
1017 | if (!dsa_is_user_port(ds: priv->ds, p: reg)) |
1018 | continue; |
1019 | |
1020 | of_get_phy_mode(np: port, interface: &mode); |
1021 | |
1022 | if (of_property_read_bool(np: port, propname: "phy-handle" ) && |
1023 | mode != PHY_INTERFACE_MODE_INTERNAL) |
1024 | external_mdio_mask |= BIT(reg); |
1025 | else |
1026 | internal_mdio_mask |= BIT(reg); |
1027 | } |
1028 | |
1029 | of_node_put(node: ports); |
1030 | if (!external_mdio_mask && !internal_mdio_mask) { |
1031 | dev_err(priv->dev, "no PHYs are defined.\n" ); |
1032 | return -EINVAL; |
1033 | } |
1034 | |
1035 | /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through |
1036 | * the MDIO_MASTER register also _disconnects_ the external MDC |
1037 | * passthrough to the internal PHYs. It's not possible to use both |
1038 | * configurations at the same time! |
1039 | * |
1040 | * Because this came up during the review process: |
1041 | * If the external mdio-bus driver is capable magically disabling |
1042 | * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's |
1043 | * accessors for the time being, it would be possible to pull this |
1044 | * off. |
1045 | */ |
1046 | if (!!external_mdio_mask && !!internal_mdio_mask) { |
1047 | dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n" ); |
1048 | return -EINVAL; |
1049 | } |
1050 | |
1051 | if (external_mdio_mask) { |
1052 | /* Make sure to disable the internal mdio bus in cases |
1053 | * a dt-overlay and driver reload changed the configuration |
1054 | */ |
1055 | |
1056 | return regmap_clear_bits(map: priv->regmap, QCA8K_MDIO_MASTER_CTRL, |
1057 | QCA8K_MDIO_MASTER_EN); |
1058 | } |
1059 | |
1060 | return qca8k_mdio_register(priv); |
1061 | } |
1062 | |
1063 | static int |
1064 | qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) |
1065 | { |
1066 | u32 mask = 0; |
1067 | int ret = 0; |
1068 | |
1069 | /* SoC specific settings for ipq8064. |
1070 | * If more device require this consider adding |
1071 | * a dedicated binding. |
1072 | */ |
1073 | if (of_machine_is_compatible(compat: "qcom,ipq8064" )) |
1074 | mask |= QCA8K_MAC_PWR_RGMII0_1_8V; |
1075 | |
1076 | /* SoC specific settings for ipq8065 */ |
1077 | if (of_machine_is_compatible(compat: "qcom,ipq8065" )) |
1078 | mask |= QCA8K_MAC_PWR_RGMII1_1_8V; |
1079 | |
1080 | if (mask) { |
1081 | ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, |
1082 | QCA8K_MAC_PWR_RGMII0_1_8V | |
1083 | QCA8K_MAC_PWR_RGMII1_1_8V, |
1084 | write_val: mask); |
1085 | } |
1086 | |
1087 | return ret; |
1088 | } |
1089 | |
1090 | static int qca8k_find_cpu_port(struct dsa_switch *ds) |
1091 | { |
1092 | struct qca8k_priv *priv = ds->priv; |
1093 | |
1094 | /* Find the connected cpu port. Valid port are 0 or 6 */ |
1095 | if (dsa_is_cpu_port(ds, p: 0)) |
1096 | return 0; |
1097 | |
1098 | dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6" ); |
1099 | |
1100 | if (dsa_is_cpu_port(ds, p: 6)) |
1101 | return 6; |
1102 | |
1103 | return -EINVAL; |
1104 | } |
1105 | |
1106 | static int |
1107 | qca8k_setup_of_pws_reg(struct qca8k_priv *priv) |
1108 | { |
1109 | const struct qca8k_match_data *data = priv->info; |
1110 | struct device_node *node = priv->dev->of_node; |
1111 | u32 val = 0; |
1112 | int ret; |
1113 | |
1114 | /* QCA8327 require to set to the correct mode. |
1115 | * His bigger brother QCA8328 have the 172 pin layout. |
1116 | * Should be applied by default but we set this just to make sure. |
1117 | */ |
1118 | if (priv->switch_id == QCA8K_ID_QCA8327) { |
1119 | /* Set the correct package of 148 pin for QCA8327 */ |
1120 | if (data->reduced_package) |
1121 | val |= QCA8327_PWS_PACKAGE148_EN; |
1122 | |
1123 | ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, |
1124 | write_val: val); |
1125 | if (ret) |
1126 | return ret; |
1127 | } |
1128 | |
1129 | if (of_property_read_bool(np: node, propname: "qca,ignore-power-on-sel" )) |
1130 | val |= QCA8K_PWS_POWER_ON_SEL; |
1131 | |
1132 | if (of_property_read_bool(np: node, propname: "qca,led-open-drain" )) { |
1133 | if (!(val & QCA8K_PWS_POWER_ON_SEL)) { |
1134 | dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set." ); |
1135 | return -EINVAL; |
1136 | } |
1137 | |
1138 | val |= QCA8K_PWS_LED_OPEN_EN_CSR; |
1139 | } |
1140 | |
1141 | return qca8k_rmw(priv, QCA8K_REG_PWS, |
1142 | QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, |
1143 | write_val: val); |
1144 | } |
1145 | |
1146 | static int |
1147 | qca8k_parse_port_config(struct qca8k_priv *priv) |
1148 | { |
1149 | int port, cpu_port_index = -1, ret; |
1150 | struct device_node *port_dn; |
1151 | phy_interface_t mode; |
1152 | struct dsa_port *dp; |
1153 | u32 delay; |
1154 | |
1155 | /* We have 2 CPU port. Check them */ |
1156 | for (port = 0; port < QCA8K_NUM_PORTS; port++) { |
1157 | /* Skip every other port */ |
1158 | if (port != 0 && port != 6) |
1159 | continue; |
1160 | |
1161 | dp = dsa_to_port(ds: priv->ds, p: port); |
1162 | port_dn = dp->dn; |
1163 | cpu_port_index++; |
1164 | |
1165 | if (!of_device_is_available(device: port_dn)) |
1166 | continue; |
1167 | |
1168 | ret = of_get_phy_mode(np: port_dn, interface: &mode); |
1169 | if (ret) |
1170 | continue; |
1171 | |
1172 | switch (mode) { |
1173 | case PHY_INTERFACE_MODE_RGMII: |
1174 | case PHY_INTERFACE_MODE_RGMII_ID: |
1175 | case PHY_INTERFACE_MODE_RGMII_TXID: |
1176 | case PHY_INTERFACE_MODE_RGMII_RXID: |
1177 | case PHY_INTERFACE_MODE_SGMII: |
1178 | delay = 0; |
1179 | |
1180 | if (!of_property_read_u32(np: port_dn, propname: "tx-internal-delay-ps" , out_value: &delay)) |
1181 | /* Switch regs accept value in ns, convert ps to ns */ |
1182 | delay = delay / 1000; |
1183 | else if (mode == PHY_INTERFACE_MODE_RGMII_ID || |
1184 | mode == PHY_INTERFACE_MODE_RGMII_TXID) |
1185 | delay = 1; |
1186 | |
1187 | if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { |
1188 | dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value" ); |
1189 | delay = 3; |
1190 | } |
1191 | |
1192 | priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; |
1193 | |
1194 | delay = 0; |
1195 | |
1196 | if (!of_property_read_u32(np: port_dn, propname: "rx-internal-delay-ps" , out_value: &delay)) |
1197 | /* Switch regs accept value in ns, convert ps to ns */ |
1198 | delay = delay / 1000; |
1199 | else if (mode == PHY_INTERFACE_MODE_RGMII_ID || |
1200 | mode == PHY_INTERFACE_MODE_RGMII_RXID) |
1201 | delay = 2; |
1202 | |
1203 | if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { |
1204 | dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value" ); |
1205 | delay = 3; |
1206 | } |
1207 | |
1208 | priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; |
1209 | |
1210 | /* Skip sgmii parsing for rgmii* mode */ |
1211 | if (mode == PHY_INTERFACE_MODE_RGMII || |
1212 | mode == PHY_INTERFACE_MODE_RGMII_ID || |
1213 | mode == PHY_INTERFACE_MODE_RGMII_TXID || |
1214 | mode == PHY_INTERFACE_MODE_RGMII_RXID) |
1215 | break; |
1216 | |
1217 | if (of_property_read_bool(np: port_dn, propname: "qca,sgmii-txclk-falling-edge" )) |
1218 | priv->ports_config.sgmii_tx_clk_falling_edge = true; |
1219 | |
1220 | if (of_property_read_bool(np: port_dn, propname: "qca,sgmii-rxclk-falling-edge" )) |
1221 | priv->ports_config.sgmii_rx_clk_falling_edge = true; |
1222 | |
1223 | if (of_property_read_bool(np: port_dn, propname: "qca,sgmii-enable-pll" )) { |
1224 | priv->ports_config.sgmii_enable_pll = true; |
1225 | |
1226 | if (priv->switch_id == QCA8K_ID_QCA8327) { |
1227 | dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling" ); |
1228 | priv->ports_config.sgmii_enable_pll = false; |
1229 | } |
1230 | |
1231 | if (priv->switch_revision < 2) |
1232 | dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more." ); |
1233 | } |
1234 | |
1235 | break; |
1236 | default: |
1237 | continue; |
1238 | } |
1239 | } |
1240 | |
1241 | return 0; |
1242 | } |
1243 | |
1244 | static void |
1245 | qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, |
1246 | u32 reg) |
1247 | { |
1248 | u32 delay, val = 0; |
1249 | int ret; |
1250 | |
1251 | /* Delay can be declared in 3 different way. |
1252 | * Mode to rgmii and internal-delay standard binding defined |
1253 | * rgmii-id or rgmii-tx/rx phy mode set. |
1254 | * The parse logic set a delay different than 0 only when one |
1255 | * of the 3 different way is used. In all other case delay is |
1256 | * not enabled. With ID or TX/RXID delay is enabled and set |
1257 | * to the default and recommended value. |
1258 | */ |
1259 | if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { |
1260 | delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; |
1261 | |
1262 | val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | |
1263 | QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; |
1264 | } |
1265 | |
1266 | if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { |
1267 | delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; |
1268 | |
1269 | val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | |
1270 | QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; |
1271 | } |
1272 | |
1273 | /* Set RGMII delay based on the selected values */ |
1274 | ret = qca8k_rmw(priv, reg, |
1275 | QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | |
1276 | QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | |
1277 | QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | |
1278 | QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, |
1279 | write_val: val); |
1280 | if (ret) |
1281 | dev_err(priv->dev, "Failed to set internal delay for CPU port%d" , |
1282 | cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); |
1283 | } |
1284 | |
1285 | static struct phylink_pcs * |
1286 | qca8k_phylink_mac_select_pcs(struct dsa_switch *ds, int port, |
1287 | phy_interface_t interface) |
1288 | { |
1289 | struct qca8k_priv *priv = ds->priv; |
1290 | struct phylink_pcs *pcs = NULL; |
1291 | |
1292 | switch (interface) { |
1293 | case PHY_INTERFACE_MODE_SGMII: |
1294 | case PHY_INTERFACE_MODE_1000BASEX: |
1295 | switch (port) { |
1296 | case 0: |
1297 | pcs = &priv->pcs_port_0.pcs; |
1298 | break; |
1299 | |
1300 | case 6: |
1301 | pcs = &priv->pcs_port_6.pcs; |
1302 | break; |
1303 | } |
1304 | break; |
1305 | |
1306 | default: |
1307 | break; |
1308 | } |
1309 | |
1310 | return pcs; |
1311 | } |
1312 | |
1313 | static void |
1314 | qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, |
1315 | const struct phylink_link_state *state) |
1316 | { |
1317 | struct qca8k_priv *priv = ds->priv; |
1318 | int cpu_port_index; |
1319 | u32 reg; |
1320 | |
1321 | switch (port) { |
1322 | case 0: /* 1st CPU port */ |
1323 | if (state->interface != PHY_INTERFACE_MODE_RGMII && |
1324 | state->interface != PHY_INTERFACE_MODE_RGMII_ID && |
1325 | state->interface != PHY_INTERFACE_MODE_RGMII_TXID && |
1326 | state->interface != PHY_INTERFACE_MODE_RGMII_RXID && |
1327 | state->interface != PHY_INTERFACE_MODE_SGMII) |
1328 | return; |
1329 | |
1330 | reg = QCA8K_REG_PORT0_PAD_CTRL; |
1331 | cpu_port_index = QCA8K_CPU_PORT0; |
1332 | break; |
1333 | case 1: |
1334 | case 2: |
1335 | case 3: |
1336 | case 4: |
1337 | case 5: |
1338 | /* Internal PHY, nothing to do */ |
1339 | return; |
1340 | case 6: /* 2nd CPU port / external PHY */ |
1341 | if (state->interface != PHY_INTERFACE_MODE_RGMII && |
1342 | state->interface != PHY_INTERFACE_MODE_RGMII_ID && |
1343 | state->interface != PHY_INTERFACE_MODE_RGMII_TXID && |
1344 | state->interface != PHY_INTERFACE_MODE_RGMII_RXID && |
1345 | state->interface != PHY_INTERFACE_MODE_SGMII && |
1346 | state->interface != PHY_INTERFACE_MODE_1000BASEX) |
1347 | return; |
1348 | |
1349 | reg = QCA8K_REG_PORT6_PAD_CTRL; |
1350 | cpu_port_index = QCA8K_CPU_PORT6; |
1351 | break; |
1352 | default: |
1353 | dev_err(ds->dev, "%s: unsupported port: %i\n" , __func__, port); |
1354 | return; |
1355 | } |
1356 | |
1357 | if (port != 6 && phylink_autoneg_inband(mode)) { |
1358 | dev_err(ds->dev, "%s: in-band negotiation unsupported\n" , |
1359 | __func__); |
1360 | return; |
1361 | } |
1362 | |
1363 | switch (state->interface) { |
1364 | case PHY_INTERFACE_MODE_RGMII: |
1365 | case PHY_INTERFACE_MODE_RGMII_ID: |
1366 | case PHY_INTERFACE_MODE_RGMII_TXID: |
1367 | case PHY_INTERFACE_MODE_RGMII_RXID: |
1368 | qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); |
1369 | |
1370 | /* Configure rgmii delay */ |
1371 | qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); |
1372 | |
1373 | /* QCA8337 requires to set rgmii rx delay for all ports. |
1374 | * This is enabled through PORT5_PAD_CTRL for all ports, |
1375 | * rather than individual port registers. |
1376 | */ |
1377 | if (priv->switch_id == QCA8K_ID_QCA8337) |
1378 | qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, |
1379 | QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); |
1380 | break; |
1381 | case PHY_INTERFACE_MODE_SGMII: |
1382 | case PHY_INTERFACE_MODE_1000BASEX: |
1383 | /* Enable SGMII on the port */ |
1384 | qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); |
1385 | break; |
1386 | default: |
1387 | dev_err(ds->dev, "xMII mode %s not supported for port %d\n" , |
1388 | phy_modes(state->interface), port); |
1389 | return; |
1390 | } |
1391 | } |
1392 | |
1393 | static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port, |
1394 | struct phylink_config *config) |
1395 | { |
1396 | switch (port) { |
1397 | case 0: /* 1st CPU port */ |
1398 | phy_interface_set_rgmii(intf: config->supported_interfaces); |
1399 | __set_bit(PHY_INTERFACE_MODE_SGMII, |
1400 | config->supported_interfaces); |
1401 | break; |
1402 | |
1403 | case 1: |
1404 | case 2: |
1405 | case 3: |
1406 | case 4: |
1407 | case 5: |
1408 | /* Internal PHY */ |
1409 | __set_bit(PHY_INTERFACE_MODE_GMII, |
1410 | config->supported_interfaces); |
1411 | __set_bit(PHY_INTERFACE_MODE_INTERNAL, |
1412 | config->supported_interfaces); |
1413 | break; |
1414 | |
1415 | case 6: /* 2nd CPU port / external PHY */ |
1416 | phy_interface_set_rgmii(intf: config->supported_interfaces); |
1417 | __set_bit(PHY_INTERFACE_MODE_SGMII, |
1418 | config->supported_interfaces); |
1419 | __set_bit(PHY_INTERFACE_MODE_1000BASEX, |
1420 | config->supported_interfaces); |
1421 | break; |
1422 | } |
1423 | |
1424 | config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | |
1425 | MAC_10 | MAC_100 | MAC_1000FD; |
1426 | } |
1427 | |
1428 | static void |
1429 | qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, |
1430 | phy_interface_t interface) |
1431 | { |
1432 | struct qca8k_priv *priv = ds->priv; |
1433 | |
1434 | qca8k_port_set_status(priv, port, enable: 0); |
1435 | } |
1436 | |
1437 | static void |
1438 | qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, |
1439 | phy_interface_t interface, struct phy_device *phydev, |
1440 | int speed, int duplex, bool tx_pause, bool rx_pause) |
1441 | { |
1442 | struct qca8k_priv *priv = ds->priv; |
1443 | u32 reg; |
1444 | |
1445 | if (phylink_autoneg_inband(mode)) { |
1446 | reg = QCA8K_PORT_STATUS_LINK_AUTO; |
1447 | } else { |
1448 | switch (speed) { |
1449 | case SPEED_10: |
1450 | reg = QCA8K_PORT_STATUS_SPEED_10; |
1451 | break; |
1452 | case SPEED_100: |
1453 | reg = QCA8K_PORT_STATUS_SPEED_100; |
1454 | break; |
1455 | case SPEED_1000: |
1456 | reg = QCA8K_PORT_STATUS_SPEED_1000; |
1457 | break; |
1458 | default: |
1459 | reg = QCA8K_PORT_STATUS_LINK_AUTO; |
1460 | break; |
1461 | } |
1462 | |
1463 | if (duplex == DUPLEX_FULL) |
1464 | reg |= QCA8K_PORT_STATUS_DUPLEX; |
1465 | |
1466 | if (rx_pause || dsa_is_cpu_port(ds, p: port)) |
1467 | reg |= QCA8K_PORT_STATUS_RXFLOW; |
1468 | |
1469 | if (tx_pause || dsa_is_cpu_port(ds, p: port)) |
1470 | reg |= QCA8K_PORT_STATUS_TXFLOW; |
1471 | } |
1472 | |
1473 | reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; |
1474 | |
1475 | qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), val: reg); |
1476 | } |
1477 | |
1478 | static struct qca8k_pcs *pcs_to_qca8k_pcs(struct phylink_pcs *pcs) |
1479 | { |
1480 | return container_of(pcs, struct qca8k_pcs, pcs); |
1481 | } |
1482 | |
1483 | static void qca8k_pcs_get_state(struct phylink_pcs *pcs, |
1484 | struct phylink_link_state *state) |
1485 | { |
1486 | struct qca8k_priv *priv = pcs_to_qca8k_pcs(pcs)->priv; |
1487 | int port = pcs_to_qca8k_pcs(pcs)->port; |
1488 | u32 reg; |
1489 | int ret; |
1490 | |
1491 | ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), val: ®); |
1492 | if (ret < 0) { |
1493 | state->link = false; |
1494 | return; |
1495 | } |
1496 | |
1497 | state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); |
1498 | state->an_complete = state->link; |
1499 | state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : |
1500 | DUPLEX_HALF; |
1501 | |
1502 | switch (reg & QCA8K_PORT_STATUS_SPEED) { |
1503 | case QCA8K_PORT_STATUS_SPEED_10: |
1504 | state->speed = SPEED_10; |
1505 | break; |
1506 | case QCA8K_PORT_STATUS_SPEED_100: |
1507 | state->speed = SPEED_100; |
1508 | break; |
1509 | case QCA8K_PORT_STATUS_SPEED_1000: |
1510 | state->speed = SPEED_1000; |
1511 | break; |
1512 | default: |
1513 | state->speed = SPEED_UNKNOWN; |
1514 | break; |
1515 | } |
1516 | |
1517 | if (reg & QCA8K_PORT_STATUS_RXFLOW) |
1518 | state->pause |= MLO_PAUSE_RX; |
1519 | if (reg & QCA8K_PORT_STATUS_TXFLOW) |
1520 | state->pause |= MLO_PAUSE_TX; |
1521 | } |
1522 | |
1523 | static int qca8k_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, |
1524 | phy_interface_t interface, |
1525 | const unsigned long *advertising, |
1526 | bool permit_pause_to_mac) |
1527 | { |
1528 | struct qca8k_priv *priv = pcs_to_qca8k_pcs(pcs)->priv; |
1529 | int cpu_port_index, ret, port; |
1530 | u32 reg, val; |
1531 | |
1532 | port = pcs_to_qca8k_pcs(pcs)->port; |
1533 | switch (port) { |
1534 | case 0: |
1535 | reg = QCA8K_REG_PORT0_PAD_CTRL; |
1536 | cpu_port_index = QCA8K_CPU_PORT0; |
1537 | break; |
1538 | |
1539 | case 6: |
1540 | reg = QCA8K_REG_PORT6_PAD_CTRL; |
1541 | cpu_port_index = QCA8K_CPU_PORT6; |
1542 | break; |
1543 | |
1544 | default: |
1545 | WARN_ON(1); |
1546 | return -EINVAL; |
1547 | } |
1548 | |
1549 | /* Enable/disable SerDes auto-negotiation as necessary */ |
1550 | val = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? |
1551 | 0 : QCA8K_PWS_SERDES_AEN_DIS; |
1552 | |
1553 | ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8K_PWS_SERDES_AEN_DIS, write_val: val); |
1554 | if (ret) |
1555 | return ret; |
1556 | |
1557 | /* Configure the SGMII parameters */ |
1558 | ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, val: &val); |
1559 | if (ret) |
1560 | return ret; |
1561 | |
1562 | val |= QCA8K_SGMII_EN_SD; |
1563 | |
1564 | if (priv->ports_config.sgmii_enable_pll) |
1565 | val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | |
1566 | QCA8K_SGMII_EN_TX; |
1567 | |
1568 | if (dsa_is_cpu_port(ds: priv->ds, p: port)) { |
1569 | /* CPU port, we're talking to the CPU MAC, be a PHY */ |
1570 | val &= ~QCA8K_SGMII_MODE_CTRL_MASK; |
1571 | val |= QCA8K_SGMII_MODE_CTRL_PHY; |
1572 | } else if (interface == PHY_INTERFACE_MODE_SGMII) { |
1573 | val &= ~QCA8K_SGMII_MODE_CTRL_MASK; |
1574 | val |= QCA8K_SGMII_MODE_CTRL_MAC; |
1575 | } else if (interface == PHY_INTERFACE_MODE_1000BASEX) { |
1576 | val &= ~QCA8K_SGMII_MODE_CTRL_MASK; |
1577 | val |= QCA8K_SGMII_MODE_CTRL_BASEX; |
1578 | } |
1579 | |
1580 | qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); |
1581 | |
1582 | /* From original code is reported port instability as SGMII also |
1583 | * require delay set. Apply advised values here or take them from DT. |
1584 | */ |
1585 | if (interface == PHY_INTERFACE_MODE_SGMII) |
1586 | qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); |
1587 | /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and |
1588 | * falling edge is set writing in the PORT0 PAD reg |
1589 | */ |
1590 | if (priv->switch_id == QCA8K_ID_QCA8327 || |
1591 | priv->switch_id == QCA8K_ID_QCA8337) |
1592 | reg = QCA8K_REG_PORT0_PAD_CTRL; |
1593 | |
1594 | val = 0; |
1595 | |
1596 | /* SGMII Clock phase configuration */ |
1597 | if (priv->ports_config.sgmii_rx_clk_falling_edge) |
1598 | val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; |
1599 | |
1600 | if (priv->ports_config.sgmii_tx_clk_falling_edge) |
1601 | val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; |
1602 | |
1603 | if (val) |
1604 | ret = qca8k_rmw(priv, reg, |
1605 | QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | |
1606 | QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, |
1607 | write_val: val); |
1608 | |
1609 | return 0; |
1610 | } |
1611 | |
1612 | static void qca8k_pcs_an_restart(struct phylink_pcs *pcs) |
1613 | { |
1614 | } |
1615 | |
1616 | static const struct phylink_pcs_ops qca8k_pcs_ops = { |
1617 | .pcs_get_state = qca8k_pcs_get_state, |
1618 | .pcs_config = qca8k_pcs_config, |
1619 | .pcs_an_restart = qca8k_pcs_an_restart, |
1620 | }; |
1621 | |
1622 | static void qca8k_setup_pcs(struct qca8k_priv *priv, struct qca8k_pcs *qpcs, |
1623 | int port) |
1624 | { |
1625 | qpcs->pcs.ops = &qca8k_pcs_ops; |
1626 | qpcs->pcs.neg_mode = true; |
1627 | |
1628 | /* We don't have interrupts for link changes, so we need to poll */ |
1629 | qpcs->pcs.poll = true; |
1630 | qpcs->priv = priv; |
1631 | qpcs->port = port; |
1632 | } |
1633 | |
1634 | static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) |
1635 | { |
1636 | struct qca8k_mib_eth_data *mib_eth_data; |
1637 | struct qca8k_priv *priv = ds->priv; |
1638 | const struct qca8k_mib_desc *mib; |
1639 | struct mib_ethhdr *mib_ethhdr; |
1640 | __le32 *data2; |
1641 | u8 port; |
1642 | int i; |
1643 | |
1644 | mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); |
1645 | mib_eth_data = &priv->mib_eth_data; |
1646 | |
1647 | /* The switch autocast every port. Ignore other packet and |
1648 | * parse only the requested one. |
1649 | */ |
1650 | port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); |
1651 | if (port != mib_eth_data->req_port) |
1652 | goto exit; |
1653 | |
1654 | data2 = (__le32 *)skb->data; |
1655 | |
1656 | for (i = 0; i < priv->info->mib_count; i++) { |
1657 | mib = &ar8327_mib[i]; |
1658 | |
1659 | /* First 3 mib are present in the skb head */ |
1660 | if (i < 3) { |
1661 | mib_eth_data->data[i] = get_unaligned_le32(p: mib_ethhdr->data + i); |
1662 | continue; |
1663 | } |
1664 | |
1665 | /* Some mib are 64 bit wide */ |
1666 | if (mib->size == 2) |
1667 | mib_eth_data->data[i] = get_unaligned_le64(p: (__le64 *)data2); |
1668 | else |
1669 | mib_eth_data->data[i] = get_unaligned_le32(p: data2); |
1670 | |
1671 | data2 += mib->size; |
1672 | } |
1673 | |
1674 | exit: |
1675 | /* Complete on receiving all the mib packet */ |
1676 | if (refcount_dec_and_test(r: &mib_eth_data->port_parsed)) |
1677 | complete(&mib_eth_data->rw_done); |
1678 | } |
1679 | |
1680 | static int |
1681 | qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) |
1682 | { |
1683 | struct dsa_port *dp = dsa_to_port(ds, p: port); |
1684 | struct qca8k_mib_eth_data *mib_eth_data; |
1685 | struct qca8k_priv *priv = ds->priv; |
1686 | int ret; |
1687 | |
1688 | mib_eth_data = &priv->mib_eth_data; |
1689 | |
1690 | mutex_lock(&mib_eth_data->mutex); |
1691 | |
1692 | reinit_completion(x: &mib_eth_data->rw_done); |
1693 | |
1694 | mib_eth_data->req_port = dp->index; |
1695 | mib_eth_data->data = data; |
1696 | refcount_set(r: &mib_eth_data->port_parsed, QCA8K_NUM_PORTS); |
1697 | |
1698 | mutex_lock(&priv->reg_mutex); |
1699 | |
1700 | /* Send mib autocast request */ |
1701 | ret = regmap_update_bits(map: priv->regmap, QCA8K_REG_MIB, |
1702 | QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, |
1703 | FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | |
1704 | QCA8K_MIB_BUSY); |
1705 | |
1706 | mutex_unlock(lock: &priv->reg_mutex); |
1707 | |
1708 | if (ret) |
1709 | goto exit; |
1710 | |
1711 | ret = wait_for_completion_timeout(x: &mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); |
1712 | |
1713 | exit: |
1714 | mutex_unlock(lock: &mib_eth_data->mutex); |
1715 | |
1716 | return ret; |
1717 | } |
1718 | |
1719 | static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) |
1720 | { |
1721 | struct qca8k_priv *priv = ds->priv; |
1722 | |
1723 | /* Communicate to the phy internal driver the switch revision. |
1724 | * Based on the switch revision different values needs to be |
1725 | * set to the dbg and mmd reg on the phy. |
1726 | * The first 2 bit are used to communicate the switch revision |
1727 | * to the phy driver. |
1728 | */ |
1729 | if (port > 0 && port < 6) |
1730 | return priv->switch_revision; |
1731 | |
1732 | return 0; |
1733 | } |
1734 | |
1735 | static enum dsa_tag_protocol |
1736 | qca8k_get_tag_protocol(struct dsa_switch *ds, int port, |
1737 | enum dsa_tag_protocol mp) |
1738 | { |
1739 | return DSA_TAG_PROTO_QCA; |
1740 | } |
1741 | |
1742 | static void |
1743 | qca8k_conduit_change(struct dsa_switch *ds, const struct net_device *conduit, |
1744 | bool operational) |
1745 | { |
1746 | struct dsa_port *dp = conduit->dsa_ptr; |
1747 | struct qca8k_priv *priv = ds->priv; |
1748 | |
1749 | /* Ethernet MIB/MDIO is only supported for CPU port 0 */ |
1750 | if (dp->index != 0) |
1751 | return; |
1752 | |
1753 | mutex_lock(&priv->mgmt_eth_data.mutex); |
1754 | mutex_lock(&priv->mib_eth_data.mutex); |
1755 | |
1756 | priv->mgmt_conduit = operational ? (struct net_device *)conduit : NULL; |
1757 | |
1758 | mutex_unlock(lock: &priv->mib_eth_data.mutex); |
1759 | mutex_unlock(lock: &priv->mgmt_eth_data.mutex); |
1760 | } |
1761 | |
1762 | static int qca8k_connect_tag_protocol(struct dsa_switch *ds, |
1763 | enum dsa_tag_protocol proto) |
1764 | { |
1765 | struct qca_tagger_data *tagger_data; |
1766 | |
1767 | switch (proto) { |
1768 | case DSA_TAG_PROTO_QCA: |
1769 | tagger_data = ds->tagger_data; |
1770 | |
1771 | tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; |
1772 | tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; |
1773 | |
1774 | break; |
1775 | default: |
1776 | return -EOPNOTSUPP; |
1777 | } |
1778 | |
1779 | return 0; |
1780 | } |
1781 | |
1782 | static void qca8k_setup_hol_fixup(struct qca8k_priv *priv, int port) |
1783 | { |
1784 | u32 mask; |
1785 | |
1786 | switch (port) { |
1787 | /* The 2 CPU port and port 5 requires some different |
1788 | * priority than any other ports. |
1789 | */ |
1790 | case 0: |
1791 | case 5: |
1792 | case 6: |
1793 | mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | |
1794 | QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | |
1795 | QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | |
1796 | QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | |
1797 | QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | |
1798 | QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | |
1799 | QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); |
1800 | break; |
1801 | default: |
1802 | mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | |
1803 | QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | |
1804 | QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | |
1805 | QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | |
1806 | QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); |
1807 | } |
1808 | regmap_write(map: priv->regmap, QCA8K_REG_PORT_HOL_CTRL0(port), val: mask); |
1809 | |
1810 | mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | |
1811 | QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | |
1812 | QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | |
1813 | QCA8K_PORT_HOL_CTRL1_WRED_EN; |
1814 | regmap_update_bits(map: priv->regmap, QCA8K_REG_PORT_HOL_CTRL1(port), |
1815 | QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | |
1816 | QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | |
1817 | QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | |
1818 | QCA8K_PORT_HOL_CTRL1_WRED_EN, |
1819 | val: mask); |
1820 | } |
1821 | |
1822 | static int |
1823 | qca8k_setup(struct dsa_switch *ds) |
1824 | { |
1825 | struct qca8k_priv *priv = ds->priv; |
1826 | struct dsa_port *dp; |
1827 | int cpu_port, ret; |
1828 | u32 mask; |
1829 | |
1830 | cpu_port = qca8k_find_cpu_port(ds); |
1831 | if (cpu_port < 0) { |
1832 | dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6" ); |
1833 | return cpu_port; |
1834 | } |
1835 | |
1836 | /* Parse CPU port config to be later used in phy_link mac_config */ |
1837 | ret = qca8k_parse_port_config(priv); |
1838 | if (ret) |
1839 | return ret; |
1840 | |
1841 | ret = qca8k_setup_mdio_bus(priv); |
1842 | if (ret) |
1843 | return ret; |
1844 | |
1845 | ret = qca8k_setup_of_pws_reg(priv); |
1846 | if (ret) |
1847 | return ret; |
1848 | |
1849 | ret = qca8k_setup_mac_pwr_sel(priv); |
1850 | if (ret) |
1851 | return ret; |
1852 | |
1853 | ret = qca8k_setup_led_ctrl(priv); |
1854 | if (ret) |
1855 | return ret; |
1856 | |
1857 | qca8k_setup_pcs(priv, qpcs: &priv->pcs_port_0, port: 0); |
1858 | qca8k_setup_pcs(priv, qpcs: &priv->pcs_port_6, port: 6); |
1859 | |
1860 | /* Make sure MAC06 is disabled */ |
1861 | ret = regmap_clear_bits(map: priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, |
1862 | QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); |
1863 | if (ret) { |
1864 | dev_err(priv->dev, "failed disabling MAC06 exchange" ); |
1865 | return ret; |
1866 | } |
1867 | |
1868 | /* Enable CPU Port */ |
1869 | ret = regmap_set_bits(map: priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, |
1870 | QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); |
1871 | if (ret) { |
1872 | dev_err(priv->dev, "failed enabling CPU port" ); |
1873 | return ret; |
1874 | } |
1875 | |
1876 | /* Enable MIB counters */ |
1877 | ret = qca8k_mib_init(priv); |
1878 | if (ret) |
1879 | dev_warn(priv->dev, "mib init failed" ); |
1880 | |
1881 | /* Initial setup of all ports */ |
1882 | dsa_switch_for_each_port(dp, ds) { |
1883 | /* Disable forwarding by default on all ports */ |
1884 | ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp->index), |
1885 | QCA8K_PORT_LOOKUP_MEMBER, write_val: 0); |
1886 | if (ret) |
1887 | return ret; |
1888 | } |
1889 | |
1890 | /* Disable MAC by default on all user ports */ |
1891 | dsa_switch_for_each_user_port(dp, ds) |
1892 | qca8k_port_set_status(priv, port: dp->index, enable: 0); |
1893 | |
1894 | /* Enable QCA header mode on all cpu ports */ |
1895 | dsa_switch_for_each_cpu_port(dp, ds) { |
1896 | ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(dp->index), |
1897 | FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | |
1898 | FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); |
1899 | if (ret) { |
1900 | dev_err(priv->dev, "failed enabling QCA header mode on port %d" , dp->index); |
1901 | return ret; |
1902 | } |
1903 | } |
1904 | |
1905 | /* Forward all unknown frames to CPU port for Linux processing |
1906 | * Notice that in multi-cpu config only one port should be set |
1907 | * for igmp, unknown, multicast and broadcast packet |
1908 | */ |
1909 | ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, |
1910 | FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | |
1911 | FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | |
1912 | FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | |
1913 | FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); |
1914 | if (ret) |
1915 | return ret; |
1916 | |
1917 | /* CPU port gets connected to all user ports of the switch */ |
1918 | ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port), |
1919 | QCA8K_PORT_LOOKUP_MEMBER, write_val: dsa_user_ports(ds)); |
1920 | if (ret) |
1921 | return ret; |
1922 | |
1923 | /* Setup connection between CPU port & user ports |
1924 | * Individual user ports get connected to CPU port only |
1925 | */ |
1926 | dsa_switch_for_each_user_port(dp, ds) { |
1927 | u8 port = dp->index; |
1928 | |
1929 | ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), |
1930 | QCA8K_PORT_LOOKUP_MEMBER, |
1931 | BIT(cpu_port)); |
1932 | if (ret) |
1933 | return ret; |
1934 | |
1935 | ret = regmap_clear_bits(map: priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), |
1936 | QCA8K_PORT_LOOKUP_LEARN); |
1937 | if (ret) |
1938 | return ret; |
1939 | |
1940 | /* For port based vlans to work we need to set the |
1941 | * default egress vid |
1942 | */ |
1943 | ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), |
1944 | QCA8K_EGREES_VLAN_PORT_MASK(port), |
1945 | QCA8K_EGREES_VLAN_PORT(port, QCA8K_PORT_VID_DEF)); |
1946 | if (ret) |
1947 | return ret; |
1948 | |
1949 | ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), |
1950 | QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | |
1951 | QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); |
1952 | if (ret) |
1953 | return ret; |
1954 | } |
1955 | |
1956 | /* The port 5 of the qca8337 have some problem in flood condition. The |
1957 | * original legacy driver had some specific buffer and priority settings |
1958 | * for the different port suggested by the QCA switch team. Add this |
1959 | * missing settings to improve switch stability under load condition. |
1960 | * This problem is limited to qca8337 and other qca8k switch are not affected. |
1961 | */ |
1962 | if (priv->switch_id == QCA8K_ID_QCA8337) |
1963 | dsa_switch_for_each_available_port(dp, ds) |
1964 | qca8k_setup_hol_fixup(priv, port: dp->index); |
1965 | |
1966 | /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ |
1967 | if (priv->switch_id == QCA8K_ID_QCA8327) { |
1968 | mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | |
1969 | QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); |
1970 | qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, |
1971 | QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | |
1972 | QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, |
1973 | write_val: mask); |
1974 | } |
1975 | |
1976 | /* Setup our port MTUs to match power on defaults */ |
1977 | ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); |
1978 | if (ret) |
1979 | dev_warn(priv->dev, "failed setting MTU settings" ); |
1980 | |
1981 | /* Flush the FDB table */ |
1982 | qca8k_fdb_flush(priv); |
1983 | |
1984 | /* Set min a max ageing value supported */ |
1985 | ds->ageing_time_min = 7000; |
1986 | ds->ageing_time_max = 458745000; |
1987 | |
1988 | /* Set max number of LAGs supported */ |
1989 | ds->num_lag_ids = QCA8K_NUM_LAGS; |
1990 | |
1991 | return 0; |
1992 | } |
1993 | |
1994 | static const struct dsa_switch_ops qca8k_switch_ops = { |
1995 | .get_tag_protocol = qca8k_get_tag_protocol, |
1996 | .setup = qca8k_setup, |
1997 | .get_strings = qca8k_get_strings, |
1998 | .get_ethtool_stats = qca8k_get_ethtool_stats, |
1999 | .get_sset_count = qca8k_get_sset_count, |
2000 | .set_ageing_time = qca8k_set_ageing_time, |
2001 | .get_mac_eee = qca8k_get_mac_eee, |
2002 | .set_mac_eee = qca8k_set_mac_eee, |
2003 | .port_enable = qca8k_port_enable, |
2004 | .port_disable = qca8k_port_disable, |
2005 | .port_change_mtu = qca8k_port_change_mtu, |
2006 | .port_max_mtu = qca8k_port_max_mtu, |
2007 | .port_stp_state_set = qca8k_port_stp_state_set, |
2008 | .port_pre_bridge_flags = qca8k_port_pre_bridge_flags, |
2009 | .port_bridge_flags = qca8k_port_bridge_flags, |
2010 | .port_bridge_join = qca8k_port_bridge_join, |
2011 | .port_bridge_leave = qca8k_port_bridge_leave, |
2012 | .port_fast_age = qca8k_port_fast_age, |
2013 | .port_fdb_add = qca8k_port_fdb_add, |
2014 | .port_fdb_del = qca8k_port_fdb_del, |
2015 | .port_fdb_dump = qca8k_port_fdb_dump, |
2016 | .port_mdb_add = qca8k_port_mdb_add, |
2017 | .port_mdb_del = qca8k_port_mdb_del, |
2018 | .port_mirror_add = qca8k_port_mirror_add, |
2019 | .port_mirror_del = qca8k_port_mirror_del, |
2020 | .port_vlan_filtering = qca8k_port_vlan_filtering, |
2021 | .port_vlan_add = qca8k_port_vlan_add, |
2022 | .port_vlan_del = qca8k_port_vlan_del, |
2023 | .phylink_get_caps = qca8k_phylink_get_caps, |
2024 | .phylink_mac_select_pcs = qca8k_phylink_mac_select_pcs, |
2025 | .phylink_mac_config = qca8k_phylink_mac_config, |
2026 | .phylink_mac_link_down = qca8k_phylink_mac_link_down, |
2027 | .phylink_mac_link_up = qca8k_phylink_mac_link_up, |
2028 | .get_phy_flags = qca8k_get_phy_flags, |
2029 | .port_lag_join = qca8k_port_lag_join, |
2030 | .port_lag_leave = qca8k_port_lag_leave, |
2031 | .conduit_state_change = qca8k_conduit_change, |
2032 | .connect_tag_protocol = qca8k_connect_tag_protocol, |
2033 | }; |
2034 | |
2035 | static int |
2036 | qca8k_sw_probe(struct mdio_device *mdiodev) |
2037 | { |
2038 | struct qca8k_priv *priv; |
2039 | int ret; |
2040 | |
2041 | /* allocate the private data struct so that we can probe the switches |
2042 | * ID register |
2043 | */ |
2044 | priv = devm_kzalloc(dev: &mdiodev->dev, size: sizeof(*priv), GFP_KERNEL); |
2045 | if (!priv) |
2046 | return -ENOMEM; |
2047 | |
2048 | priv->bus = mdiodev->bus; |
2049 | priv->dev = &mdiodev->dev; |
2050 | priv->info = of_device_get_match_data(dev: priv->dev); |
2051 | |
2052 | priv->reset_gpio = devm_gpiod_get_optional(dev: priv->dev, con_id: "reset" , |
2053 | flags: GPIOD_OUT_HIGH); |
2054 | if (IS_ERR(ptr: priv->reset_gpio)) |
2055 | return PTR_ERR(ptr: priv->reset_gpio); |
2056 | |
2057 | if (priv->reset_gpio) { |
2058 | /* The active low duration must be greater than 10 ms |
2059 | * and checkpatch.pl wants 20 ms. |
2060 | */ |
2061 | msleep(msecs: 20); |
2062 | gpiod_set_value_cansleep(desc: priv->reset_gpio, value: 0); |
2063 | } |
2064 | |
2065 | /* Start by setting up the register mapping */ |
2066 | priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, |
2067 | &qca8k_regmap_config); |
2068 | if (IS_ERR(ptr: priv->regmap)) { |
2069 | dev_err(priv->dev, "regmap initialization failed" ); |
2070 | return PTR_ERR(ptr: priv->regmap); |
2071 | } |
2072 | |
2073 | priv->mdio_cache.page = 0xffff; |
2074 | |
2075 | /* Check the detected switch id */ |
2076 | ret = qca8k_read_switch_id(priv); |
2077 | if (ret) |
2078 | return ret; |
2079 | |
2080 | priv->ds = devm_kzalloc(dev: &mdiodev->dev, size: sizeof(*priv->ds), GFP_KERNEL); |
2081 | if (!priv->ds) |
2082 | return -ENOMEM; |
2083 | |
2084 | mutex_init(&priv->mgmt_eth_data.mutex); |
2085 | init_completion(x: &priv->mgmt_eth_data.rw_done); |
2086 | |
2087 | mutex_init(&priv->mib_eth_data.mutex); |
2088 | init_completion(x: &priv->mib_eth_data.rw_done); |
2089 | |
2090 | priv->ds->dev = &mdiodev->dev; |
2091 | priv->ds->num_ports = QCA8K_NUM_PORTS; |
2092 | priv->ds->priv = priv; |
2093 | priv->ds->ops = &qca8k_switch_ops; |
2094 | mutex_init(&priv->reg_mutex); |
2095 | dev_set_drvdata(dev: &mdiodev->dev, data: priv); |
2096 | |
2097 | return dsa_register_switch(ds: priv->ds); |
2098 | } |
2099 | |
2100 | static void |
2101 | qca8k_sw_remove(struct mdio_device *mdiodev) |
2102 | { |
2103 | struct qca8k_priv *priv = dev_get_drvdata(dev: &mdiodev->dev); |
2104 | int i; |
2105 | |
2106 | if (!priv) |
2107 | return; |
2108 | |
2109 | for (i = 0; i < QCA8K_NUM_PORTS; i++) |
2110 | qca8k_port_set_status(priv, port: i, enable: 0); |
2111 | |
2112 | dsa_unregister_switch(ds: priv->ds); |
2113 | } |
2114 | |
2115 | static void qca8k_sw_shutdown(struct mdio_device *mdiodev) |
2116 | { |
2117 | struct qca8k_priv *priv = dev_get_drvdata(dev: &mdiodev->dev); |
2118 | |
2119 | if (!priv) |
2120 | return; |
2121 | |
2122 | dsa_switch_shutdown(ds: priv->ds); |
2123 | |
2124 | dev_set_drvdata(dev: &mdiodev->dev, NULL); |
2125 | } |
2126 | |
2127 | #ifdef CONFIG_PM_SLEEP |
2128 | static void |
2129 | qca8k_set_pm(struct qca8k_priv *priv, int enable) |
2130 | { |
2131 | int port; |
2132 | |
2133 | for (port = 0; port < QCA8K_NUM_PORTS; port++) { |
2134 | /* Do not enable on resume if the port was |
2135 | * disabled before. |
2136 | */ |
2137 | if (!(priv->port_enabled_map & BIT(port))) |
2138 | continue; |
2139 | |
2140 | qca8k_port_set_status(priv, port, enable); |
2141 | } |
2142 | } |
2143 | |
2144 | static int qca8k_suspend(struct device *dev) |
2145 | { |
2146 | struct qca8k_priv *priv = dev_get_drvdata(dev); |
2147 | |
2148 | qca8k_set_pm(priv, enable: 0); |
2149 | |
2150 | return dsa_switch_suspend(ds: priv->ds); |
2151 | } |
2152 | |
2153 | static int qca8k_resume(struct device *dev) |
2154 | { |
2155 | struct qca8k_priv *priv = dev_get_drvdata(dev); |
2156 | |
2157 | qca8k_set_pm(priv, enable: 1); |
2158 | |
2159 | return dsa_switch_resume(ds: priv->ds); |
2160 | } |
2161 | #endif /* CONFIG_PM_SLEEP */ |
2162 | |
2163 | static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, |
2164 | qca8k_suspend, qca8k_resume); |
2165 | |
2166 | static const struct qca8k_info_ops qca8xxx_ops = { |
2167 | .autocast_mib = qca8k_get_ethtool_stats_eth, |
2168 | }; |
2169 | |
2170 | static const struct qca8k_match_data qca8327 = { |
2171 | .id = QCA8K_ID_QCA8327, |
2172 | .reduced_package = true, |
2173 | .mib_count = QCA8K_QCA832X_MIB_COUNT, |
2174 | .ops = &qca8xxx_ops, |
2175 | }; |
2176 | |
2177 | static const struct qca8k_match_data qca8328 = { |
2178 | .id = QCA8K_ID_QCA8327, |
2179 | .mib_count = QCA8K_QCA832X_MIB_COUNT, |
2180 | .ops = &qca8xxx_ops, |
2181 | }; |
2182 | |
2183 | static const struct qca8k_match_data qca833x = { |
2184 | .id = QCA8K_ID_QCA8337, |
2185 | .mib_count = QCA8K_QCA833X_MIB_COUNT, |
2186 | .ops = &qca8xxx_ops, |
2187 | }; |
2188 | |
2189 | static const struct of_device_id qca8k_of_match[] = { |
2190 | { .compatible = "qca,qca8327" , .data = &qca8327 }, |
2191 | { .compatible = "qca,qca8328" , .data = &qca8328 }, |
2192 | { .compatible = "qca,qca8334" , .data = &qca833x }, |
2193 | { .compatible = "qca,qca8337" , .data = &qca833x }, |
2194 | { /* sentinel */ }, |
2195 | }; |
2196 | |
2197 | static struct mdio_driver qca8kmdio_driver = { |
2198 | .probe = qca8k_sw_probe, |
2199 | .remove = qca8k_sw_remove, |
2200 | .shutdown = qca8k_sw_shutdown, |
2201 | .mdiodrv.driver = { |
2202 | .name = "qca8k" , |
2203 | .of_match_table = qca8k_of_match, |
2204 | .pm = &qca8k_pm_ops, |
2205 | }, |
2206 | }; |
2207 | |
2208 | mdio_module_driver(qca8kmdio_driver); |
2209 | |
2210 | MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>" ); |
2211 | MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family" ); |
2212 | MODULE_LICENSE("GPL v2" ); |
2213 | MODULE_ALIAS("platform:qca8k" ); |
2214 | |