1 /*-
2 * Copyright (c) 2016 Stanislav Galabov.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/param.h>
28 #include <sys/bus.h>
29 #include <sys/errno.h>
30 #include <sys/kernel.h>
31 #include <sys/lock.h>
32 #include <sys/malloc.h>
33 #include <sys/module.h>
34 #include <sys/mutex.h>
35 #include <sys/rman.h>
36 #include <sys/socket.h>
37 #include <sys/sockio.h>
38 #include <sys/sysctl.h>
39 #include <sys/systm.h>
40
41 #include <net/if.h>
42 #include <net/if_var.h>
43 #include <net/ethernet.h>
44 #include <net/if_media.h>
45 #include <net/if_types.h>
46
47 #include <machine/bus.h>
48 #include <dev/mii/mii.h>
49 #include <dev/mii/miivar.h>
50 #include <dev/mdio/mdio.h>
51
52 #include <dev/etherswitch/etherswitch.h>
53 #include <dev/etherswitch/mtkswitch/mtkswitchvar.h>
54 #include <dev/etherswitch/mtkswitch/mtkswitch_rt3050.h>
55
56 static int
mtkswitch_reg_read(device_t dev,int reg)57 mtkswitch_reg_read(device_t dev, int reg)
58 {
59 struct mtkswitch_softc *sc = device_get_softc(dev);
60 uint32_t val;
61
62 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
63 val = MTKSWITCH_READ(sc, MTKSWITCH_REG32(reg));
64 if (MTKSWITCH_IS_HI16(reg))
65 return (MTKSWITCH_HI16(val));
66 return (MTKSWITCH_LO16(val));
67 }
68
69 static int
mtkswitch_reg_write(device_t dev,int reg,int val)70 mtkswitch_reg_write(device_t dev, int reg, int val)
71 {
72 struct mtkswitch_softc *sc = device_get_softc(dev);
73 uint32_t tmp;
74
75 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
76 tmp = MTKSWITCH_READ(sc, MTKSWITCH_REG32(reg));
77 if (MTKSWITCH_IS_HI16(reg)) {
78 tmp &= MTKSWITCH_LO16_MSK;
79 tmp |= MTKSWITCH_TO_HI16(val);
80 } else {
81 tmp &= MTKSWITCH_HI16_MSK;
82 tmp |= MTKSWITCH_TO_LO16(val);
83 }
84 MTKSWITCH_WRITE(sc, MTKSWITCH_REG32(reg), tmp);
85
86 return (0);
87 }
88
89 static int
mtkswitch_phy_read(device_t dev,int phy,int reg)90 mtkswitch_phy_read(device_t dev, int phy, int reg)
91 {
92 struct mtkswitch_softc *sc = device_get_softc(dev);
93 int val;
94
95 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
96 MTKSWITCH_LOCK(sc);
97 while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
98 MTKSWITCH_WRITE(sc, MTKSWITCH_PCR0, PCR0_READ | PCR0_REG(reg) |
99 PCR0_PHY(phy));
100 while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
101 val = (MTKSWITCH_READ(sc, MTKSWITCH_PCR1) >> PCR1_DATA_OFF) &
102 PCR1_DATA_MASK;
103 MTKSWITCH_UNLOCK(sc);
104 return (val);
105 }
106
107 static int
mtkswitch_phy_write(device_t dev,int phy,int reg,int val)108 mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
109 {
110 struct mtkswitch_softc *sc = device_get_softc(dev);
111
112 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
113 MTKSWITCH_LOCK(sc);
114 while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
115 MTKSWITCH_WRITE(sc, MTKSWITCH_PCR0, PCR0_WRITE | PCR0_REG(reg) |
116 PCR0_PHY(phy) | PCR0_DATA(val));
117 while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
118 MTKSWITCH_UNLOCK(sc);
119 return (0);
120 }
121
122 static int
mtkswitch_reset(struct mtkswitch_softc * sc)123 mtkswitch_reset(struct mtkswitch_softc *sc)
124 {
125
126 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
127 MTKSWITCH_LOCK(sc);
128 MTKSWITCH_WRITE(sc, MTKSWITCH_STRT, STRT_RESET);
129 while (MTKSWITCH_READ(sc, MTKSWITCH_STRT) != 0);
130 MTKSWITCH_UNLOCK(sc);
131
132 return (0);
133 }
134
135 static int
mtkswitch_hw_setup(struct mtkswitch_softc * sc)136 mtkswitch_hw_setup(struct mtkswitch_softc *sc)
137 {
138
139 /*
140 * TODO: parse the device tree and see if we need to configure
141 * ports, etc. differently. For now we fallback to defaults.
142 */
143
144 /* Called early and hence unlocked */
145 /* Set ports 0-4 to auto negotiation */
146 MTKSWITCH_WRITE(sc, MTKSWITCH_FPA, FPA_ALL_AUTO);
147
148 return (0);
149 }
150
151 static int
mtkswitch_hw_global_setup(struct mtkswitch_softc * sc)152 mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
153 {
154
155 /* Called early and hence unlocked */
156 return (0);
157 }
158
159 static void
mtkswitch_port_init(struct mtkswitch_softc * sc,int port)160 mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
161 {
162 /* Called early and hence unlocked */
163 /* Do nothing - ports are set to auto negotiation in hw_setup */
164 }
165
166 static uint32_t
mtkswitch_get_port_status(struct mtkswitch_softc * sc,int port)167 mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
168 {
169 uint32_t val, res;
170
171 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
172 res = 0;
173 val = MTKSWITCH_READ(sc, MTKSWITCH_POA);
174
175 if (val & POA_PRT_LINK(port))
176 res |= MTKSWITCH_LINK_UP;
177 if (val & POA_PRT_DPX(port))
178 res |= MTKSWITCH_DUPLEX;
179
180 if (MTKSWITCH_PORT_IS_100M(port)) {
181 if (val & POA_FE_SPEED(port))
182 res |= MTKSWITCH_SPEED_100;
183 if (val & POA_FE_XFC(port))
184 res |= (MTKSWITCH_TXFLOW | MTKSWITCH_RXFLOW);
185 } else {
186 switch (POA_GE_SPEED(val, port)) {
187 case POA_GE_SPEED_10:
188 res |= MTKSWITCH_SPEED_10;
189 break;
190 case POA_GE_SPEED_100:
191 res |= MTKSWITCH_SPEED_100;
192 break;
193 case POA_GE_SPEED_1000:
194 res |= MTKSWITCH_SPEED_1000;
195 break;
196 }
197
198 val = POA_GE_XFC(val, port);
199 if (val & POA_GE_XFC_TX_MSK)
200 res |= MTKSWITCH_TXFLOW;
201 if (val & POA_GE_XFC_RX_MSK)
202 res |= MTKSWITCH_RXFLOW;
203 }
204
205 return (res);
206 }
207
208 static int
mtkswitch_atu_flush(struct mtkswitch_softc * sc)209 mtkswitch_atu_flush(struct mtkswitch_softc *sc)
210 {
211 return (0);
212 }
213
214 static int
mtkswitch_port_vlan_setup(struct mtkswitch_softc * sc,etherswitch_port_t * p)215 mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
216 {
217 uint32_t val;
218 int err, invert = 0;
219
220 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
221 MTKSWITCH_LOCK(sc);
222 /* Set the PVID. */
223 if (p->es_pvid != 0) {
224 err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
225 p->es_pvid);
226 if (err != 0) {
227 MTKSWITCH_UNLOCK(sc);
228 return (err);
229 }
230 }
231
232 /* Mutually exclusive */
233 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG &&
234 p->es_flags & ETHERSWITCH_PORT_STRIPTAG) {
235 invert = 1;
236 }
237
238 val = MTKSWITCH_READ(sc, MTKSWITCH_SGC2);
239 if (p->es_flags & ETHERSWITCH_PORT_DOUBLE_TAG)
240 val |= SGC2_DOUBLE_TAG_PORT(p->es_port);
241 else
242 val &= ~SGC2_DOUBLE_TAG_PORT(p->es_port);
243 MTKSWITCH_WRITE(sc, MTKSWITCH_SGC2, val);
244
245 val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
246 if (invert) {
247 if (val & POC2_UNTAG_PORT(p->es_port))
248 val &= ~POC2_UNTAG_PORT(p->es_port);
249 else
250 val |= POC2_UNTAG_PORT(p->es_port);
251 } else if (p->es_flags & ETHERSWITCH_PORT_STRIPTAG)
252 val |= POC2_UNTAG_PORT(p->es_port);
253 else
254 val &= ~POC2_UNTAG_PORT(p->es_port);
255 MTKSWITCH_WRITE(sc, MTKSWITCH_POC2, val);
256 MTKSWITCH_UNLOCK(sc);
257
258 return (0);
259 }
260
261 static int
mtkswitch_port_vlan_get(struct mtkswitch_softc * sc,etherswitch_port_t * p)262 mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
263 {
264 uint32_t val;
265
266 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
267 MTKSWITCH_LOCK(sc);
268
269 /* Retrieve the PVID */
270 sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
271
272 /* Port flags */
273 p->es_flags = 0;
274 val = MTKSWITCH_READ(sc, MTKSWITCH_SGC2);
275 if (val & SGC2_DOUBLE_TAG_PORT(p->es_port))
276 p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG;
277
278 val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
279 if (val & POC2_UNTAG_PORT(p->es_port))
280 p->es_flags |= ETHERSWITCH_PORT_STRIPTAG;
281 else
282 p->es_flags |= ETHERSWITCH_PORT_ADDTAG;
283
284 MTKSWITCH_UNLOCK(sc);
285
286 return (0);
287 }
288
289 static void
mtkswitch_vlan_init_hw(struct mtkswitch_softc * sc)290 mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
291 {
292 uint32_t val, vid;
293 int i;
294
295 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
296 MTKSWITCH_LOCK(sc);
297
298 /* Reset everything to defaults first */
299 for (i = 0; i < sc->info.es_nvlangroups; i++) {
300 /* Remove all VLAN members and untag info, if any */
301 if (i % 4 == 0) {
302 MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(i), 0);
303 if (sc->sc_switchtype != MTK_SWITCH_RT3050)
304 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(i), 0);
305 }
306 /* Reset to default VIDs */
307 val = MTKSWITCH_READ(sc, MTKSWITCH_VLANI(i));
308 val &= ~(VLANI_MASK << VLANI_OFF(i));
309 val |= ((i + 1) << VLANI_OFF(i));
310 MTKSWITCH_WRITE(sc, MTKSWITCH_VLANI(i), val);
311 }
312
313 /* Now, add all ports as untagged members to VLAN1 */
314 vid = 0;
315 val = MTKSWITCH_READ(sc, MTKSWITCH_VMSC(vid));
316 val &= ~(VMSC_MASK << VMSC_OFF(vid));
317 val |= (((1<<sc->numports)-1) << VMSC_OFF(vid));
318 MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(vid), val);
319 if (sc->sc_switchtype != MTK_SWITCH_RT3050) {
320 val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(vid));
321 val &= ~(VUB_MASK << VUB_OFF(vid));
322 val |= (((1<<sc->numports)-1) << VUB_OFF(vid));
323 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(vid), val);
324 }
325 val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
326 if (sc->sc_switchtype != MTK_SWITCH_RT3050)
327 val |= POC2_UNTAG_VLAN;
328 val |= ((1<<sc->numports)-1);
329 MTKSWITCH_WRITE(sc, MTKSWITCH_POC2, val);
330
331 /* only the first vlangroup is valid */
332 sc->valid_vlans = (1<<0);
333
334 /* Set all port PVIDs to 1 */
335 vid = 1;
336 for (i = 0; i < sc->info.es_nports; i++) {
337 val = MTKSWITCH_READ(sc, MTKSWITCH_PVID(i));
338 val &= ~(PVID_MASK << PVID_OFF(i));
339 val |= (vid << PVID_OFF(i));
340 MTKSWITCH_WRITE(sc, MTKSWITCH_PVID(i), val);
341 }
342
343 MTKSWITCH_UNLOCK(sc);
344 }
345
346 static int
mtkswitch_vlan_getvgroup(struct mtkswitch_softc * sc,etherswitch_vlangroup_t * v)347 mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
348 {
349 uint32_t val;
350
351 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
352
353 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
354 (v->es_vlangroup > sc->info.es_nvlangroups))
355 return (EINVAL);
356
357 /* Reset the member ports. */
358 v->es_untagged_ports = 0;
359 v->es_member_ports = 0;
360
361 /* Not supported */
362 v->es_fid = 0;
363
364 /* Vlan ID */
365 v->es_vid = 0;
366 if ((sc->valid_vlans & (1<<v->es_vlangroup)) == 0)
367 return (0);
368
369 MTKSWITCH_LOCK(sc);
370 v->es_vid = (MTKSWITCH_READ(sc, MTKSWITCH_VLANI(v->es_vlangroup)) >>
371 VLANI_OFF(v->es_vlangroup)) & VLANI_MASK;
372 v->es_vid |= ETHERSWITCH_VID_VALID;
373
374 /* Member ports */
375 v->es_member_ports = v->es_untagged_ports =
376 (MTKSWITCH_READ(sc, MTKSWITCH_VMSC(v->es_vlangroup)) >>
377 VMSC_OFF(v->es_vlangroup)) & VMSC_MASK;
378
379 val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
380
381 if ((val & POC2_UNTAG_VLAN) && sc->sc_switchtype != MTK_SWITCH_RT3050) {
382 val = (MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup)) >>
383 VUB_OFF(v->es_vlangroup)) & VUB_MASK;
384 } else {
385 val &= VUB_MASK;
386 }
387 v->es_untagged_ports &= val;
388
389 MTKSWITCH_UNLOCK(sc);
390 return (0);
391 }
392
393 static int
mtkswitch_vlan_setvgroup(struct mtkswitch_softc * sc,etherswitch_vlangroup_t * v)394 mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
395 {
396 uint32_t val, tmp;
397
398 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
399 (v->es_vlangroup > sc->info.es_nvlangroups))
400 return (EINVAL);
401
402 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
403 MTKSWITCH_LOCK(sc);
404 /* First, see if we can accommodate the request at all */
405 val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
406 if (sc->sc_switchtype == MTK_SWITCH_RT3050 ||
407 (val & POC2_UNTAG_VLAN) == 0) {
408 /*
409 * There are 2 things we can't support in per-port untagging
410 * mode:
411 * 1. Adding a port as an untagged member if the port is not
412 * set up to do untagging.
413 * 2. Adding a port as a tagged member if the port is set up
414 * to do untagging.
415 */
416 val &= VUB_MASK;
417
418 /* get all untagged members from the member list */
419 tmp = v->es_untagged_ports & v->es_member_ports;
420 /* fail if untagged members are not a subset of all members */
421 if (tmp != v->es_untagged_ports) {
422 /* Cannot accommodate request */
423 MTKSWITCH_UNLOCK(sc);
424 return (ENOTSUP);
425 }
426
427 /* fail if any untagged member is set up to do tagging */
428 if ((tmp & val) != tmp) {
429 /* Cannot accommodate request */
430 MTKSWITCH_UNLOCK(sc);
431 return (ENOTSUP);
432 }
433
434 /* now, get the list of all tagged members */
435 tmp = v->es_member_ports & ~tmp;
436 /* fail if any tagged member is set up to do untagging */
437 if ((tmp & val) != 0) {
438 /* Cannot accommodate request */
439 MTKSWITCH_UNLOCK(sc);
440 return (ENOTSUP);
441 }
442 } else {
443 /* Prefer per-Vlan untag and set its members */
444 val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup));
445 val &= ~(VUB_MASK << VUB_OFF(v->es_vlangroup));
446 val |= (((v->es_untagged_ports) & VUB_MASK) <<
447 VUB_OFF(v->es_vlangroup));
448 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(v->es_vlangroup), val);
449 }
450
451 /* Set VID */
452 val = MTKSWITCH_READ(sc, MTKSWITCH_VLANI(v->es_vlangroup));
453 val &= ~(VLANI_MASK << VLANI_OFF(v->es_vlangroup));
454 val |= (v->es_vid & VLANI_MASK) << VLANI_OFF(v->es_vlangroup);
455 MTKSWITCH_WRITE(sc, MTKSWITCH_VLANI(v->es_vlangroup), val);
456
457 /* Set members */
458 val = MTKSWITCH_READ(sc, MTKSWITCH_VMSC(v->es_vlangroup));
459 val &= ~(VMSC_MASK << VMSC_OFF(v->es_vlangroup));
460 val |= (v->es_member_ports << VMSC_OFF(v->es_vlangroup));
461 MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(v->es_vlangroup), val);
462
463 sc->valid_vlans |= (1<<v->es_vlangroup);
464
465 MTKSWITCH_UNLOCK(sc);
466 return (0);
467 }
468
469 static int
mtkswitch_vlan_get_pvid(struct mtkswitch_softc * sc,int port,int * pvid)470 mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
471 {
472
473 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
474 *pvid = (MTKSWITCH_READ(sc, MTKSWITCH_PVID(port)) >> PVID_OFF(port)) &
475 PVID_MASK;
476
477 return (0);
478 }
479
480 static int
mtkswitch_vlan_set_pvid(struct mtkswitch_softc * sc,int port,int pvid)481 mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
482 {
483 uint32_t val;
484
485 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
486 val = MTKSWITCH_READ(sc, MTKSWITCH_PVID(port));
487 val &= ~(PVID_MASK << PVID_OFF(port));
488 val |= (pvid & PVID_MASK) << PVID_OFF(port);
489 MTKSWITCH_WRITE(sc, MTKSWITCH_PVID(port), val);
490
491 return (0);
492 }
493
494 extern void
mtk_attach_switch_rt3050(struct mtkswitch_softc * sc)495 mtk_attach_switch_rt3050(struct mtkswitch_softc *sc)
496 {
497
498 sc->portmap = 0x7f;
499 sc->phymap = 0x1f;
500
501 sc->info.es_nports = 7;
502 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
503 sc->info.es_nvlangroups = 16;
504 sprintf(sc->info.es_name, "Ralink ESW");
505
506 sc->hal.mtkswitch_reset = mtkswitch_reset;
507 sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
508 sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
509 sc->hal.mtkswitch_port_init = mtkswitch_port_init;
510 sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
511 sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
512 sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
513 sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
514 sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
515 sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
516 sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
517 sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
518 sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
519 sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
520 sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
521 sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
522 sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;
523 }
524