mediatek: add v4.19 support
[openwrt/staging/jow.git] / target / linux / mediatek / files-4.19 / drivers / net / phy / mtk / mt753x / mt753x_swconfig.c
1 /*
2 * OpenWrt swconfig support for MediaTek MT753x Gigabit switch
3 *
4 * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
5 *
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11 #include <linux/if.h>
12 #include <linux/list.h>
13 #include <linux/if_ether.h>
14 #include <linux/skbuff.h>
15 #include <linux/netdevice.h>
16 #include <linux/netlink.h>
17 #include <linux/bitops.h>
18 #include <net/genetlink.h>
19 #include <linux/delay.h>
20 #include <linux/phy.h>
21 #include <linux/netdevice.h>
22 #include <linux/etherdevice.h>
23 #include <linux/lockdep.h>
24 #include <linux/workqueue.h>
25 #include <linux/of_device.h>
26
27 #include "mt753x.h"
28 #include "mt753x_swconfig.h"
29 #include "mt753x_regs.h"
30
31 #define MT753X_PORT_MIB_TXB_ID 18 /* TxByte */
32 #define MT753X_PORT_MIB_RXB_ID 37 /* RxByte */
33
34 #define MIB_DESC(_s, _o, _n) \
35 { \
36 .size = (_s), \
37 .offset = (_o), \
38 .name = (_n), \
39 }
40
41 struct mt753x_mib_desc {
42 unsigned int size;
43 unsigned int offset;
44 const char *name;
45 };
46
47 static const struct mt753x_mib_desc mt753x_mibs[] = {
48 MIB_DESC(1, STATS_TDPC, "TxDrop"),
49 MIB_DESC(1, STATS_TCRC, "TxCRC"),
50 MIB_DESC(1, STATS_TUPC, "TxUni"),
51 MIB_DESC(1, STATS_TMPC, "TxMulti"),
52 MIB_DESC(1, STATS_TBPC, "TxBroad"),
53 MIB_DESC(1, STATS_TCEC, "TxCollision"),
54 MIB_DESC(1, STATS_TSCEC, "TxSingleCol"),
55 MIB_DESC(1, STATS_TMCEC, "TxMultiCol"),
56 MIB_DESC(1, STATS_TDEC, "TxDefer"),
57 MIB_DESC(1, STATS_TLCEC, "TxLateCol"),
58 MIB_DESC(1, STATS_TXCEC, "TxExcCol"),
59 MIB_DESC(1, STATS_TPPC, "TxPause"),
60 MIB_DESC(1, STATS_TL64PC, "Tx64Byte"),
61 MIB_DESC(1, STATS_TL65PC, "Tx65Byte"),
62 MIB_DESC(1, STATS_TL128PC, "Tx128Byte"),
63 MIB_DESC(1, STATS_TL256PC, "Tx256Byte"),
64 MIB_DESC(1, STATS_TL512PC, "Tx512Byte"),
65 MIB_DESC(1, STATS_TL1024PC, "Tx1024Byte"),
66 MIB_DESC(2, STATS_TOC, "TxByte"),
67 MIB_DESC(1, STATS_RDPC, "RxDrop"),
68 MIB_DESC(1, STATS_RFPC, "RxFiltered"),
69 MIB_DESC(1, STATS_RUPC, "RxUni"),
70 MIB_DESC(1, STATS_RMPC, "RxMulti"),
71 MIB_DESC(1, STATS_RBPC, "RxBroad"),
72 MIB_DESC(1, STATS_RAEPC, "RxAlignErr"),
73 MIB_DESC(1, STATS_RCEPC, "RxCRC"),
74 MIB_DESC(1, STATS_RUSPC, "RxUnderSize"),
75 MIB_DESC(1, STATS_RFEPC, "RxFragment"),
76 MIB_DESC(1, STATS_ROSPC, "RxOverSize"),
77 MIB_DESC(1, STATS_RJEPC, "RxJabber"),
78 MIB_DESC(1, STATS_RPPC, "RxPause"),
79 MIB_DESC(1, STATS_RL64PC, "Rx64Byte"),
80 MIB_DESC(1, STATS_RL65PC, "Rx65Byte"),
81 MIB_DESC(1, STATS_RL128PC, "Rx128Byte"),
82 MIB_DESC(1, STATS_RL256PC, "Rx256Byte"),
83 MIB_DESC(1, STATS_RL512PC, "Rx512Byte"),
84 MIB_DESC(1, STATS_RL1024PC, "Rx1024Byte"),
85 MIB_DESC(2, STATS_ROC, "RxByte"),
86 MIB_DESC(1, STATS_RDPC_CTRL, "RxCtrlDrop"),
87 MIB_DESC(1, STATS_RDPC_ING, "RxIngDrop"),
88 MIB_DESC(1, STATS_RDPC_ARL, "RxARLDrop")
89 };
90
91 enum {
92 /* Global attributes. */
93 MT753X_ATTR_ENABLE_VLAN,
94 };
95
96 struct mt753x_mapping {
97 char *name;
98 u16 pvids[MT753X_NUM_PORTS];
99 u8 members[MT753X_NUM_VLANS];
100 u8 etags[MT753X_NUM_VLANS];
101 u16 vids[MT753X_NUM_VLANS];
102 } mt753x_defaults[] = {
103 {
104 .name = "llllw",
105 .pvids = { 1, 1, 1, 1, 2, 2, 1 },
106 .members = { 0, 0x4f, 0x30 },
107 .etags = { 0, 0, 0 },
108 .vids = { 0, 1, 2 },
109 }, {
110 .name = "wllll",
111 .pvids = { 2, 1, 1, 1, 1, 2, 1 },
112 .members = { 0, 0x5e, 0x21 },
113 .etags = { 0, 0, 0 },
114 .vids = { 0, 1, 2 },
115 }, {
116 .name = "lwlll",
117 .pvids = { 1, 2, 1, 1, 1, 2, 1 },
118 .members = { 0, 0x5d, 0x22 },
119 .etags = { 0, 0, 0 },
120 .vids = { 0, 1, 2 },
121 },
122 };
123
124 struct mt753x_mapping *mt753x_find_mapping(struct device_node *np)
125 {
126 const char *map;
127 int i;
128
129 if (of_property_read_string(np, "mediatek,portmap", &map))
130 return NULL;
131
132 for (i = 0; i < ARRAY_SIZE(mt753x_defaults); i++)
133 if (!strcmp(map, mt753x_defaults[i].name))
134 return &mt753x_defaults[i];
135
136 return NULL;
137 }
138
139 static void mt753x_apply_mapping(struct gsw_mt753x *gsw,
140 struct mt753x_mapping *map)
141 {
142 int i = 0;
143
144 for (i = 0; i < MT753X_NUM_PORTS; i++)
145 gsw->port_entries[i].pvid = map->pvids[i];
146
147 for (i = 0; i < MT753X_NUM_VLANS; i++) {
148 gsw->vlan_entries[i].member = map->members[i];
149 gsw->vlan_entries[i].etags = map->etags[i];
150 gsw->vlan_entries[i].vid = map->vids[i];
151 }
152 }
153
154 static int mt753x_get_vlan_enable(struct switch_dev *dev,
155 const struct switch_attr *attr,
156 struct switch_val *val)
157 {
158 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
159
160 val->value.i = gsw->global_vlan_enable;
161
162 return 0;
163 }
164
165 static int mt753x_set_vlan_enable(struct switch_dev *dev,
166 const struct switch_attr *attr,
167 struct switch_val *val)
168 {
169 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
170
171 gsw->global_vlan_enable = val->value.i != 0;
172
173 return 0;
174 }
175
176 static int mt753x_get_port_pvid(struct switch_dev *dev, int port, int *val)
177 {
178 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
179
180 if (port >= MT753X_NUM_PORTS)
181 return -EINVAL;
182
183 *val = mt753x_reg_read(gsw, PPBV1(port));
184 *val &= GRP_PORT_VID_M;
185
186 return 0;
187 }
188
189 static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid)
190 {
191 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
192
193 if (port >= MT753X_NUM_PORTS)
194 return -EINVAL;
195
196 if (pvid < MT753X_MIN_VID || pvid > MT753X_MAX_VID)
197 return -EINVAL;
198
199 gsw->port_entries[port].pvid = pvid;
200
201 return 0;
202 }
203
204 static void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val)
205 {
206 int i;
207
208 mt753x_reg_write(gsw, VTCR,
209 VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) |
210 (val & VTCR_VID_M));
211
212 for (i = 0; i < 300; i++) {
213 u32 val = mt753x_reg_read(gsw, VTCR);
214
215 if ((val & VTCR_BUSY) == 0)
216 break;
217
218 usleep_range(1000, 1100);
219 }
220
221 if (i == 300)
222 dev_info(gsw->dev, "vtcr timeout\n");
223 }
224
225 static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
226 {
227 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
228 u32 member;
229 u32 etags;
230 int i;
231
232 val->len = 0;
233
234 if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS)
235 return -EINVAL;
236
237 mt753x_vlan_ctrl(gsw, VTCR_READ_VLAN_ENTRY, val->port_vlan);
238
239 member = mt753x_reg_read(gsw, VAWD1);
240 member &= PORT_MEM_M;
241 member >>= PORT_MEM_S;
242
243 etags = mt753x_reg_read(gsw, VAWD2);
244
245 for (i = 0; i < MT753X_NUM_PORTS; i++) {
246 struct switch_port *p;
247 int etag;
248
249 if (!(member & BIT(i)))
250 continue;
251
252 p = &val->value.ports[val->len++];
253 p->id = i;
254
255 etag = (etags >> PORT_ETAG_S(i)) & PORT_ETAG_M;
256
257 if (etag == ETAG_CTRL_TAG)
258 p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
259 else if (etag != ETAG_CTRL_UNTAG)
260 dev_info(gsw->dev,
261 "vlan egress tag control neither untag nor tag.\n");
262 }
263
264 return 0;
265 }
266
267 static int mt753x_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
268 {
269 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
270 u8 member = 0;
271 u8 etags = 0;
272 int i;
273
274 if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS ||
275 val->len > MT753X_NUM_PORTS)
276 return -EINVAL;
277
278 for (i = 0; i < val->len; i++) {
279 struct switch_port *p = &val->value.ports[i];
280
281 if (p->id >= MT753X_NUM_PORTS)
282 return -EINVAL;
283
284 member |= BIT(p->id);
285
286 if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
287 etags |= BIT(p->id);
288 }
289
290 gsw->vlan_entries[val->port_vlan].member = member;
291 gsw->vlan_entries[val->port_vlan].etags = etags;
292
293 return 0;
294 }
295
296 static int mt753x_set_vid(struct switch_dev *dev,
297 const struct switch_attr *attr,
298 struct switch_val *val)
299 {
300 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
301 int vlan;
302 u16 vid;
303
304 vlan = val->port_vlan;
305 vid = (u16)val->value.i;
306
307 if (vlan < 0 || vlan >= MT753X_NUM_VLANS)
308 return -EINVAL;
309
310 if (vid < MT753X_MIN_VID || vid > MT753X_MAX_VID)
311 return -EINVAL;
312
313 gsw->vlan_entries[vlan].vid = vid;
314 return 0;
315 }
316
317 static int mt753x_get_vid(struct switch_dev *dev,
318 const struct switch_attr *attr,
319 struct switch_val *val)
320 {
321 val->value.i = val->port_vlan;
322 return 0;
323 }
324
325 static int mt753x_get_port_link(struct switch_dev *dev, int port,
326 struct switch_port_link *link)
327 {
328 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
329 u32 speed, pmsr;
330
331 if (port < 0 || port >= MT753X_NUM_PORTS)
332 return -EINVAL;
333
334 pmsr = mt753x_reg_read(gsw, PMSR(port));
335
336 link->link = pmsr & MAC_LNK_STS;
337 link->duplex = pmsr & MAC_DPX_STS;
338 speed = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
339
340 switch (speed) {
341 case MAC_SPD_10:
342 link->speed = SWITCH_PORT_SPEED_10;
343 break;
344 case MAC_SPD_100:
345 link->speed = SWITCH_PORT_SPEED_100;
346 break;
347 case MAC_SPD_1000:
348 link->speed = SWITCH_PORT_SPEED_1000;
349 break;
350 case MAC_SPD_2500:
351 /* TODO: swconfig has no support for 2500 now */
352 link->speed = SWITCH_PORT_SPEED_UNKNOWN;
353 break;
354 }
355
356 return 0;
357 }
358
359 static int mt753x_set_port_link(struct switch_dev *dev, int port,
360 struct switch_port_link *link)
361 {
362 #ifndef MODULE
363 if (port >= MT753X_NUM_PHYS)
364 return -EINVAL;
365
366 return switch_generic_set_link(dev, port, link);
367 #else
368 return -ENOTSUPP;
369 #endif
370 }
371
372 static u64 get_mib_counter(struct gsw_mt753x *gsw, int i, int port)
373 {
374 unsigned int offset;
375 u64 lo, hi, hi2;
376
377 offset = mt753x_mibs[i].offset;
378
379 if (mt753x_mibs[i].size == 1)
380 return mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
381
382 do {
383 hi = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
384 lo = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
385 hi2 = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
386 } while (hi2 != hi);
387
388 return (hi << 32) | lo;
389 }
390
391 static int mt753x_get_port_mib(struct switch_dev *dev,
392 const struct switch_attr *attr,
393 struct switch_val *val)
394 {
395 static char buf[4096];
396 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
397 int i, len = 0;
398
399 if (val->port_vlan >= MT753X_NUM_PORTS)
400 return -EINVAL;
401
402 len += snprintf(buf + len, sizeof(buf) - len,
403 "Port %d MIB counters\n", val->port_vlan);
404
405 for (i = 0; i < ARRAY_SIZE(mt753x_mibs); ++i) {
406 u64 counter;
407
408 len += snprintf(buf + len, sizeof(buf) - len,
409 "%-11s: ", mt753x_mibs[i].name);
410 counter = get_mib_counter(gsw, i, val->port_vlan);
411 len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
412 counter);
413 }
414
415 val->value.s = buf;
416 val->len = len;
417 return 0;
418 }
419
420 static int mt753x_get_port_stats(struct switch_dev *dev, int port,
421 struct switch_port_stats *stats)
422 {
423 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
424
425 if (port < 0 || port >= MT753X_NUM_PORTS)
426 return -EINVAL;
427
428 stats->tx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_TXB_ID, port);
429 stats->rx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_RXB_ID, port);
430
431 return 0;
432 }
433
434 static void mt753x_port_isolation(struct gsw_mt753x *gsw)
435 {
436 int i;
437
438 for (i = 0; i < MT753X_NUM_PORTS; i++)
439 mt753x_reg_write(gsw, PCR(i),
440 BIT(gsw->cpu_port) << PORT_MATRIX_S);
441
442 mt753x_reg_write(gsw, PCR(gsw->cpu_port), PORT_MATRIX_M);
443
444 for (i = 0; i < MT753X_NUM_PORTS; i++)
445 mt753x_reg_write(gsw, PVC(i),
446 (0x8100 << STAG_VPID_S) |
447 (VA_TRANSPARENT_PORT << VLAN_ATTR_S));
448 }
449
450 static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid,
451 u8 ports, u8 etags)
452 {
453 int port;
454 u32 val;
455
456 /* vlan port membership */
457 if (ports)
458 mt753x_reg_write(gsw, VAWD1,
459 IVL_MAC | VTAG_EN | VENTRY_VALID |
460 ((ports << PORT_MEM_S) & PORT_MEM_M));
461 else
462 mt753x_reg_write(gsw, VAWD1, 0);
463
464 /* egress mode */
465 val = 0;
466 for (port = 0; port < MT753X_NUM_PORTS; port++) {
467 if (etags & BIT(port))
468 val |= ETAG_CTRL_TAG << PORT_ETAG_S(port);
469 else
470 val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port);
471 }
472 mt753x_reg_write(gsw, VAWD2, val);
473
474 /* write to vlan table */
475 mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid);
476 }
477
478 static int mt753x_apply_config(struct switch_dev *dev)
479 {
480 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
481 int i, j;
482 u8 tag_ports;
483 u8 untag_ports;
484
485 if (!gsw->global_vlan_enable) {
486 mt753x_port_isolation(gsw);
487 return 0;
488 }
489
490 /* set all ports as security mode */
491 for (i = 0; i < MT753X_NUM_PORTS; i++)
492 mt753x_reg_write(gsw, PCR(i),
493 PORT_MATRIX_M | SECURITY_MODE);
494
495 /* check if a port is used in tag/untag vlan egress mode */
496 tag_ports = 0;
497 untag_ports = 0;
498
499 for (i = 0; i < MT753X_NUM_VLANS; i++) {
500 u8 member = gsw->vlan_entries[i].member;
501 u8 etags = gsw->vlan_entries[i].etags;
502
503 if (!member)
504 continue;
505
506 for (j = 0; j < MT753X_NUM_PORTS; j++) {
507 if (!(member & BIT(j)))
508 continue;
509
510 if (etags & BIT(j))
511 tag_ports |= 1u << j;
512 else
513 untag_ports |= 1u << j;
514 }
515 }
516
517 /* set all untag-only ports as transparent and the rest as user port */
518 for (i = 0; i < MT753X_NUM_PORTS; i++) {
519 u32 pvc_mode = 0x8100 << STAG_VPID_S;
520
521 if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
522 pvc_mode = (0x8100 << STAG_VPID_S) |
523 (VA_TRANSPARENT_PORT << VLAN_ATTR_S);
524
525 mt753x_reg_write(gsw, PVC(i), pvc_mode);
526 }
527
528 /* first clear the swtich vlan table */
529 for (i = 0; i < MT753X_NUM_VLANS; i++)
530 mt753x_write_vlan_entry(gsw, i, i, 0, 0);
531
532 /* now program only vlans with members to avoid
533 * clobbering remapped entries in later iterations
534 */
535 for (i = 0; i < MT753X_NUM_VLANS; i++) {
536 u16 vid = gsw->vlan_entries[i].vid;
537 u8 member = gsw->vlan_entries[i].member;
538 u8 etags = gsw->vlan_entries[i].etags;
539
540 if (member)
541 mt753x_write_vlan_entry(gsw, i, vid, member, etags);
542 }
543
544 /* Port Default PVID */
545 for (i = 0; i < MT753X_NUM_PORTS; i++) {
546 int vlan = gsw->port_entries[i].pvid;
547 u16 pvid = 0;
548 u32 val;
549
550 if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member)
551 pvid = gsw->vlan_entries[vlan].vid;
552
553 val = mt753x_reg_read(gsw, PPBV1(i));
554 val &= ~GRP_PORT_VID_M;
555 val |= pvid;
556 mt753x_reg_write(gsw, PPBV1(i), val);
557 }
558
559 return 0;
560 }
561
562 static int mt753x_reset_switch(struct switch_dev *dev)
563 {
564 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
565 int i;
566
567 memset(gsw->port_entries, 0, sizeof(gsw->port_entries));
568 memset(gsw->vlan_entries, 0, sizeof(gsw->vlan_entries));
569
570 /* set default vid of each vlan to the same number of vlan, so the vid
571 * won't need be set explicitly.
572 */
573 for (i = 0; i < MT753X_NUM_VLANS; i++)
574 gsw->vlan_entries[i].vid = i;
575
576 return 0;
577 }
578
579 static int mt753x_phy_read16(struct switch_dev *dev, int addr, u8 reg,
580 u16 *value)
581 {
582 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
583
584 *value = gsw->mii_read(gsw, addr, reg);
585
586 return 0;
587 }
588
589 static int mt753x_phy_write16(struct switch_dev *dev, int addr, u8 reg,
590 u16 value)
591 {
592 struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
593
594 gsw->mii_write(gsw, addr, reg, value);
595
596 return 0;
597 }
598
599 static const struct switch_attr mt753x_global[] = {
600 {
601 .type = SWITCH_TYPE_INT,
602 .name = "enable_vlan",
603 .description = "VLAN mode (1:enabled)",
604 .max = 1,
605 .id = MT753X_ATTR_ENABLE_VLAN,
606 .get = mt753x_get_vlan_enable,
607 .set = mt753x_set_vlan_enable,
608 }
609 };
610
611 static const struct switch_attr mt753x_port[] = {
612 {
613 .type = SWITCH_TYPE_STRING,
614 .name = "mib",
615 .description = "Get MIB counters for port",
616 .get = mt753x_get_port_mib,
617 .set = NULL,
618 },
619 };
620
621 static const struct switch_attr mt753x_vlan[] = {
622 {
623 .type = SWITCH_TYPE_INT,
624 .name = "vid",
625 .description = "VLAN ID (0-4094)",
626 .set = mt753x_set_vid,
627 .get = mt753x_get_vid,
628 .max = 4094,
629 },
630 };
631
632 static const struct switch_dev_ops mt753x_swdev_ops = {
633 .attr_global = {
634 .attr = mt753x_global,
635 .n_attr = ARRAY_SIZE(mt753x_global),
636 },
637 .attr_port = {
638 .attr = mt753x_port,
639 .n_attr = ARRAY_SIZE(mt753x_port),
640 },
641 .attr_vlan = {
642 .attr = mt753x_vlan,
643 .n_attr = ARRAY_SIZE(mt753x_vlan),
644 },
645 .get_vlan_ports = mt753x_get_vlan_ports,
646 .set_vlan_ports = mt753x_set_vlan_ports,
647 .get_port_pvid = mt753x_get_port_pvid,
648 .set_port_pvid = mt753x_set_port_pvid,
649 .get_port_link = mt753x_get_port_link,
650 .set_port_link = mt753x_set_port_link,
651 .get_port_stats = mt753x_get_port_stats,
652 .apply_config = mt753x_apply_config,
653 .reset_switch = mt753x_reset_switch,
654 .phy_read16 = mt753x_phy_read16,
655 .phy_write16 = mt753x_phy_write16,
656 };
657
658 int mt753x_swconfig_init(struct gsw_mt753x *gsw)
659 {
660 struct device_node *np = gsw->dev->of_node;
661 struct switch_dev *swdev;
662 struct mt753x_mapping *map;
663 int ret;
664
665 if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port))
666 gsw->cpu_port = MT753X_DFL_CPU_PORT;
667
668 swdev = &gsw->swdev;
669
670 swdev->name = gsw->name;
671 swdev->alias = gsw->name;
672 swdev->cpu_port = gsw->cpu_port;
673 swdev->ports = MT753X_NUM_PORTS;
674 swdev->vlans = MT753X_NUM_VLANS;
675 swdev->ops = &mt753x_swdev_ops;
676
677 ret = register_switch(swdev, NULL);
678 if (ret) {
679 dev_err(gsw->dev, "Failed to register switch %s\n",
680 swdev->name);
681 return ret;
682 }
683
684 map = mt753x_find_mapping(gsw->dev->of_node);
685 if (map)
686 mt753x_apply_mapping(gsw, map);
687 mt753x_apply_config(swdev);
688
689 return 0;
690 }
691
692 void mt753x_swconfig_destroy(struct gsw_mt753x *gsw)
693 {
694 unregister_switch(&gsw->swdev);
695 }