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 * $FreeBSD$
27 */
28
29#include <sys/param.h>
30#include <sys/bus.h>
31#include <sys/errno.h>
32#include <sys/kernel.h>
33#include <sys/lock.h>
34#include <sys/malloc.h>
35#include <sys/module.h>
36#include <sys/mutex.h>
37#include <sys/rman.h>
38#include <sys/socket.h>
39#include <sys/sockio.h>
40#include <sys/sysctl.h>
41#include <sys/systm.h>
42
43#include <net/if.h>
44#include <net/if_var.h>
45#include <net/ethernet.h>
46#include <net/if_media.h>
47#include <net/if_types.h>
48
49#include <machine/bus.h>
50#include <dev/mii/mii.h>
51#include <dev/mii/miivar.h>
52#include <dev/mdio/mdio.h>
53
54#include <dev/etherswitch/etherswitch.h>
55#include <dev/etherswitch/mtkswitch/mtkswitchvar.h>
56#include <dev/etherswitch/mtkswitch/mtkswitch_mt7620.h>
57
58static int
59mtkswitch_phy_read_locked(struct mtkswitch_softc *sc, int phy, int reg)
60{
61	uint32_t data;
62
63	MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
64	    (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
65	    PIAC_MDIO_CMD_READ);
66	while ((data = MTKSWITCH_READ(sc, MTKSWITCH_PIAC)) & PIAC_PHY_ACS_ST);
67
68	return ((int)(data & PIAC_MDIO_RW_DATA_MASK));
69}
70
71static int
72mtkswitch_phy_read(device_t dev, int phy, int reg)
73{
74	struct mtkswitch_softc *sc = device_get_softc(dev);
75	int data;
76
77	if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
78		return (ENXIO);
79
80	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
81	MTKSWITCH_LOCK(sc);
82	data = mtkswitch_phy_read_locked(sc, phy, reg);
83	MTKSWITCH_UNLOCK(sc);
84
85	return (data);
86}
87
88static int
89mtkswitch_phy_write_locked(struct mtkswitch_softc *sc, int phy, int reg,
90    int val)
91{
92
93	MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
94	    (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
95	    (val & PIAC_MDIO_RW_DATA_MASK) | PIAC_MDIO_CMD_WRITE);
96	while (MTKSWITCH_READ(sc, MTKSWITCH_PIAC) & PIAC_PHY_ACS_ST);
97
98	return (0);
99}
100
101static int
102mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
103{
104	struct mtkswitch_softc *sc = device_get_softc(dev);
105	int res;
106
107	if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
108		return (ENXIO);
109
110	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
111	MTKSWITCH_LOCK(sc);
112	res = mtkswitch_phy_write_locked(sc, phy, reg, val);
113	MTKSWITCH_UNLOCK(sc);
114
115	return (res);
116}
117
118static uint32_t
119mtkswitch_reg_read32(struct mtkswitch_softc *sc, int reg)
120{
121
122	return (MTKSWITCH_READ(sc, reg));
123}
124
125static uint32_t
126mtkswitch_reg_write32(struct mtkswitch_softc *sc, int reg, uint32_t val)
127{
128
129	MTKSWITCH_WRITE(sc, reg, val);
130	return (0);
131}
132
133static uint32_t
134mtkswitch_reg_read32_mt7621(struct mtkswitch_softc *sc, int reg)
135{
136	uint32_t low, hi;
137
138	mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
139	    MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
140	low = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
141	    MTKSWITCH_REG_LO(reg));
142	hi = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
143	    MTKSWITCH_REG_HI(reg));;
144	return (low | (hi << 16));
145}
146
147static uint32_t
148mtkswitch_reg_write32_mt7621(struct mtkswitch_softc *sc, int reg, uint32_t val)
149{
150
151	mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
152	    MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
153	mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
154	    MTKSWITCH_REG_LO(reg), MTKSWITCH_VAL_LO(val));
155	mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
156	    MTKSWITCH_REG_HI(reg), MTKSWITCH_VAL_HI(val));
157	return (0);
158}
159
160static int
161mtkswitch_reg_read(device_t dev, int reg)
162{
163	struct mtkswitch_softc *sc = device_get_softc(dev);
164	uint32_t val;
165
166	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
167	if (MTKSWITCH_IS_HI16(reg))
168		return (MTKSWITCH_HI16(val));
169	return (MTKSWITCH_LO16(val));
170}
171
172static int
173mtkswitch_reg_write(device_t dev, int reg, int val)
174{
175	struct mtkswitch_softc *sc = device_get_softc(dev);
176	uint32_t tmp;
177
178	tmp = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
179	if (MTKSWITCH_IS_HI16(reg)) {
180		tmp &= MTKSWITCH_LO16_MSK;
181		tmp |= MTKSWITCH_TO_HI16(val);
182	} else {
183		tmp &= MTKSWITCH_HI16_MSK;
184		tmp |= MTKSWITCH_TO_LO16(val);
185	}
186	sc->hal.mtkswitch_write(sc, MTKSWITCH_REG32(reg), tmp);
187
188	return (0);
189}
190
191static int
192mtkswitch_reset(struct mtkswitch_softc *sc)
193{
194
195	/* We don't reset the switch for now */
196	return (0);
197}
198
199static int
200mtkswitch_hw_setup(struct mtkswitch_softc *sc)
201{
202
203	/*
204	 * TODO: parse the device tree and see if we need to configure
205	 *       ports, etc. differently. For now we fallback to defaults.
206	 */
207
208	/* Called early and hence unlocked */
209	return (0);
210}
211
212static int
213mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
214{
215	/* Currently does nothing */
216
217	/* Called early and hence unlocked */
218	return (0);
219}
220
221static void
222mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
223{
224	uint32_t val;
225
226	/* Called early and hence unlocked */
227
228	/* Set the port to secure mode */
229	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PCR(port));
230	val |= PCR_PORT_VLAN_SECURE;
231	sc->hal.mtkswitch_write(sc, MTKSWITCH_PCR(port), val);
232
233	/* Set port's vlan_attr to user port */
234	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PVC(port));
235	val &= ~PVC_VLAN_ATTR_MASK;
236	sc->hal.mtkswitch_write(sc, MTKSWITCH_PVC(port), val);
237
238	val = PMCR_CFG_DEFAULT;
239	if (port == sc->cpuport)
240		val |= PMCR_FORCE_LINK | PMCR_FORCE_DPX | PMCR_FORCE_SPD_1000 |
241		    PMCR_FORCE_MODE;
242	/* Set port's MAC to default settings */
243	sc->hal.mtkswitch_write(sc, MTKSWITCH_PMCR(port), val);
244}
245
246static uint32_t
247mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
248{
249	uint32_t val, res, tmp;
250
251	MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
252	res = 0;
253	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PMSR(port));
254
255	if (val & PMSR_MAC_LINK_STS)
256		res |= MTKSWITCH_LINK_UP;
257	if (val & PMSR_MAC_DPX_STS)
258		res |= MTKSWITCH_DUPLEX;
259	tmp = PMSR_MAC_SPD(val);
260	if (tmp == 0)
261		res |= MTKSWITCH_SPEED_10;
262	else if (tmp == 1)
263		res |= MTKSWITCH_SPEED_100;
264	else if (tmp == 2)
265		res |= MTKSWITCH_SPEED_1000;
266	if (val & PMSR_TX_FC_STS)
267		res |= MTKSWITCH_TXFLOW;
268	if (val & PMSR_RX_FC_STS)
269		res |= MTKSWITCH_RXFLOW;
270
271	return (res);
272}
273
274static int
275mtkswitch_atu_flush(struct mtkswitch_softc *sc)
276{
277
278	MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
279
280	/* Flush all non-static MAC addresses */
281	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
282	sc->hal.mtkswitch_write(sc, MTKSWITCH_ATC, ATC_BUSY |
283	    ATC_AC_MAT_NON_STATIC_MACS | ATC_AC_CMD_CLEAN);
284	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
285
286	return (0);
287}
288
289static int
290mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
291{
292	int err;
293
294	/*
295	 * Port behaviour wrt tag/untag/stack is currently defined per-VLAN.
296	 * So we say we don't support it here.
297	 */
298	if ((p->es_flags & (ETHERSWITCH_PORT_DOUBLE_TAG |
299	    ETHERSWITCH_PORT_ADDTAG | ETHERSWITCH_PORT_STRIPTAG)) != 0)
300		return (ENOTSUP);
301
302	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
303	MTKSWITCH_LOCK(sc);
304
305	/* Set the PVID */
306	if (p->es_pvid != 0) {
307		err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
308		    p->es_pvid);
309		if (err != 0) {
310			MTKSWITCH_UNLOCK(sc);
311			return (err);
312		}
313	}
314
315	MTKSWITCH_UNLOCK(sc);
316
317	return (0);
318}
319
320static int
321mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
322{
323
324	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
325	MTKSWITCH_LOCK(sc);
326
327	/* Retrieve the PVID */
328	sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
329
330	/*
331	 * Port flags are not supported at the moment.
332	 * Port's tag/untag/stack behaviour is defined per-VLAN.
333	 */
334	p->es_flags = 0;
335
336	MTKSWITCH_UNLOCK(sc);
337
338	return (0);
339}
340
341static void
342mtkswitch_invalidate_vlan(struct mtkswitch_softc *sc, uint32_t vid)
343{
344
345	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
346	sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
347	    VTCR_FUNC_VID_INVALID | (vid & VTCR_VID_MASK));
348	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
349}
350
351static void
352mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
353{
354	uint32_t val, vid, i;
355
356	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
357	MTKSWITCH_LOCK(sc);
358	/* Reset all VLANs to defaults first */
359	for (i = 0; i < sc->info.es_nvlangroups; i++) {
360		mtkswitch_invalidate_vlan(sc, i);
361		if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
362			val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTIM(i));
363			val &= ~(VTIM_MASK << VTIM_OFF(i));
364			val |= ((i + 1) << VTIM_OFF(i));
365			sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(i), val);
366		}
367	}
368
369	/* Now, add all ports as untagged members of VLAN 1 */
370	if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
371		/* MT7620 uses vid index instead of actual vid */
372		vid = 0;
373	} else {
374		/* MT7621 uses the vid itself */
375		vid = 1;
376	}
377	val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
378	for (i = 0; i < sc->info.es_nports; i++)
379		val |= VAWD1_PORT_MEMBER(i);
380	sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
381	sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, 0);
382	val = VTCR_BUSY | VTCR_FUNC_VID_WRITE | vid;
383	sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, val);
384
385	/* Set all port PVIDs to 1 */
386	for (i = 0; i < sc->info.es_nports; i++) {
387		sc->hal.mtkswitch_vlan_set_pvid(sc, i, 1);
388	}
389
390	MTKSWITCH_UNLOCK(sc);
391}
392
393static int
394mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
395{
396	uint32_t val, i;
397
398	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
399
400	if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
401	    (v->es_vlangroup > sc->info.es_nvlangroups))
402		return (EINVAL);
403
404	/* Reset the member ports. */
405	v->es_untagged_ports = 0;
406	v->es_member_ports = 0;
407
408	/* Not supported for now */
409	v->es_fid = 0;
410
411	MTKSWITCH_LOCK(sc);
412	if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
413		v->es_vid = (sc->hal.mtkswitch_read(sc,
414		    MTKSWITCH_VTIM(v->es_vlangroup)) >>
415		    VTIM_OFF(v->es_vlangroup)) & VTIM_MASK;
416	} else {
417		v->es_vid = v->es_vlangroup;
418	}
419
420	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
421	sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
422	    VTCR_FUNC_VID_READ | (v->es_vlangroup & VTCR_VID_MASK));
423	while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
424	if (val & VTCR_IDX_INVALID) {
425		MTKSWITCH_UNLOCK(sc);
426		return (0);
427	}
428
429	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD1);
430	if (val & VAWD1_VALID)
431		v->es_vid |= ETHERSWITCH_VID_VALID;
432	else {
433		MTKSWITCH_UNLOCK(sc);
434		return (0);
435	}
436	v->es_member_ports = (val >> VAWD1_MEMBER_OFF) & VAWD1_MEMBER_MASK;
437
438	val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD2);
439	for (i = 0; i < sc->info.es_nports; i++) {
440		if ((val & VAWD2_PORT_MASK(i)) == VAWD2_PORT_UNTAGGED(i))
441			v->es_untagged_ports |= (1<<i);
442	}
443
444	MTKSWITCH_UNLOCK(sc);
445	return (0);
446}
447
448static int
449mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
450{
451	uint32_t val, i, vid;
452
453	MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
454
455	if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
456	    (v->es_vlangroup > sc->info.es_nvlangroups))
457		return (EINVAL);
458
459	/* We currently don't support FID */
460	if (v->es_fid != 0)
461		return (EINVAL);
462
463	MTKSWITCH_LOCK(sc);
464	while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
465	if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
466		val = sc->hal.mtkswitch_read(sc,
467		    MTKSWITCH_VTIM(v->es_vlangroup));
468		val &= ~(VTIM_MASK << VTIM_OFF(v->es_vlangroup));
469		val |= ((v->es_vid & VTIM_MASK) << VTIM_OFF(v->es_vlangroup));
470		sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(v->es_vlangroup),
471		    val);
472		vid = v->es_vlangroup;
473	} else
474		vid = v->es_vid;
475
476	/* We use FID 0 */
477	val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
478	val |= ((v->es_member_ports & VAWD1_MEMBER_MASK) << VAWD1_MEMBER_OFF);
479	sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
480
481	/* Set tagged ports */
482	val = 0;
483	for (i = 0; i < sc->info.es_nports; i++)
484		if (((1<<i) & v->es_untagged_ports) == 0)
485			val |= VAWD2_PORT_TAGGED(i);
486	sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, val);
487
488	/* Write the VLAN entry */
489	sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
490	    VTCR_FUNC_VID_WRITE | (vid & VTCR_VID_MASK));
491	while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
492
493	MTKSWITCH_UNLOCK(sc);
494
495	if (val & VTCR_IDX_INVALID)
496		return (EINVAL);
497
498	return (0);
499}
500
501static int
502mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
503{
504
505	MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
506
507	*pvid = sc->hal.mtkswitch_read(sc, MTKSWITCH_PPBV1(port));
508	*pvid = PPBV_VID_FROM_REG(*pvid);
509
510	return (0);
511}
512
513static int
514mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
515{
516	uint32_t val;
517
518	MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
519	val = PPBV_VID(pvid & PPBV_VID_MASK);
520	sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV1(port), val);
521	sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV2(port), val);
522
523	return (0);
524}
525
526extern void
527mtk_attach_switch_mt7620(struct mtkswitch_softc *sc)
528{
529
530	sc->portmap = 0x7f;
531	sc->phymap = 0x1f;
532
533	sc->info.es_nports = 7;
534	sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
535	sc->info.es_nvlangroups = 16;
536	sprintf(sc->info.es_name, "Mediatek GSW");
537
538	if (sc->sc_switchtype == MTK_SWITCH_MT7621) {
539		sc->hal.mtkswitch_read = mtkswitch_reg_read32_mt7621;
540		sc->hal.mtkswitch_write = mtkswitch_reg_write32_mt7621;
541		sc->info.es_nvlangroups = 4096;
542	} else {
543		sc->hal.mtkswitch_read = mtkswitch_reg_read32;
544		sc->hal.mtkswitch_write = mtkswitch_reg_write32;
545	}
546
547	sc->hal.mtkswitch_reset = mtkswitch_reset;
548	sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
549	sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
550	sc->hal.mtkswitch_port_init = mtkswitch_port_init;
551	sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
552	sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
553	sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
554	sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
555	sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
556	sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
557	sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
558	sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
559	sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
560	sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
561	sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
562	sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
563	sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;
564}
565