]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
MFV r347989:
[FreeBSD/FreeBSD.git] / sys / dev / etherswitch / mtkswitch / mtkswitch_rt3050.c
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_rt3050.h>
57
58 static int
59 mtkswitch_reg_read(device_t dev, int reg)
60 {
61         struct mtkswitch_softc *sc = device_get_softc(dev);
62         uint32_t val;
63
64         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
65         val = MTKSWITCH_READ(sc, MTKSWITCH_REG32(reg));
66         if (MTKSWITCH_IS_HI16(reg))
67                 return (MTKSWITCH_HI16(val));
68         return (MTKSWITCH_LO16(val));
69 }
70
71 static int
72 mtkswitch_reg_write(device_t dev, int reg, int val)
73 {
74         struct mtkswitch_softc *sc = device_get_softc(dev);
75         uint32_t tmp;
76
77         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
78         tmp = MTKSWITCH_READ(sc, MTKSWITCH_REG32(reg));
79         if (MTKSWITCH_IS_HI16(reg)) {
80                 tmp &= MTKSWITCH_LO16_MSK;
81                 tmp |= MTKSWITCH_TO_HI16(val);
82         } else {
83                 tmp &= MTKSWITCH_HI16_MSK;
84                 tmp |= MTKSWITCH_TO_LO16(val);
85         }
86         MTKSWITCH_WRITE(sc, MTKSWITCH_REG32(reg), tmp);
87
88         return (0);
89 }
90
91 static int
92 mtkswitch_phy_read(device_t dev, int phy, int reg)
93 {
94         struct mtkswitch_softc *sc = device_get_softc(dev);
95         int val;
96
97         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
98         MTKSWITCH_LOCK(sc);
99         while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
100         MTKSWITCH_WRITE(sc, MTKSWITCH_PCR0, PCR0_READ | PCR0_REG(reg) |
101             PCR0_PHY(phy));
102         while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
103         val = (MTKSWITCH_READ(sc, MTKSWITCH_PCR1) >> PCR1_DATA_OFF) &
104             PCR1_DATA_MASK;
105         MTKSWITCH_UNLOCK(sc);
106         return (val);
107 }
108
109 static int
110 mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
111 {
112         struct mtkswitch_softc *sc = device_get_softc(dev);
113
114         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
115         MTKSWITCH_LOCK(sc);
116         while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
117         MTKSWITCH_WRITE(sc, MTKSWITCH_PCR0, PCR0_WRITE | PCR0_REG(reg) |
118             PCR0_PHY(phy) | PCR0_DATA(val));
119         while (MTKSWITCH_READ(sc, MTKSWITCH_PCR0) & PCR0_ACTIVE);
120         MTKSWITCH_UNLOCK(sc);
121         return (0);
122 }
123
124 static int
125 mtkswitch_reset(struct mtkswitch_softc *sc)
126 {
127
128         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
129         MTKSWITCH_LOCK(sc);
130         MTKSWITCH_WRITE(sc, MTKSWITCH_STRT, STRT_RESET);
131         while (MTKSWITCH_READ(sc, MTKSWITCH_STRT) != 0);
132         MTKSWITCH_UNLOCK(sc);
133
134         return (0);
135 }
136
137 static int
138 mtkswitch_hw_setup(struct mtkswitch_softc *sc)
139 {
140
141         /*
142          * TODO: parse the device tree and see if we need to configure
143          *       ports, etc. differently. For now we fallback to defaults.
144          */
145
146         /* Called early and hence unlocked */
147         /* Set ports 0-4 to auto negotiation */
148         MTKSWITCH_WRITE(sc, MTKSWITCH_FPA, FPA_ALL_AUTO);
149
150         return (0);
151 }
152
153 static int
154 mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
155 {
156
157         /* Called early and hence unlocked */
158         return (0);
159 }
160
161 static void
162 mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
163 {
164         /* Called early and hence unlocked */
165         /* Do nothing - ports are set to auto negotiation in hw_setup */
166 }
167
168 static uint32_t
169 mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
170 {
171         uint32_t val, res;
172
173         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
174         res = 0;
175         val = MTKSWITCH_READ(sc, MTKSWITCH_POA);
176
177         if (val & POA_PRT_LINK(port))
178                 res |= MTKSWITCH_LINK_UP;
179         if (val & POA_PRT_DPX(port))
180                 res |= MTKSWITCH_DUPLEX;
181
182         if (MTKSWITCH_PORT_IS_100M(port)) {
183                 if (val & POA_FE_SPEED(port))
184                         res |= MTKSWITCH_SPEED_100;
185                 if (val & POA_FE_XFC(port))
186                         res |= (MTKSWITCH_TXFLOW | MTKSWITCH_RXFLOW);
187         } else {
188                 switch (POA_GE_SPEED(val, port)) {
189                 case POA_GE_SPEED_10:
190                         res |= MTKSWITCH_SPEED_10;
191                         break;
192                 case POA_GE_SPEED_100:
193                         res |= MTKSWITCH_SPEED_100;
194                         break;
195                 case POA_GE_SPEED_1000:
196                         res |= MTKSWITCH_SPEED_1000;
197                         break;
198                 }
199
200                 val = POA_GE_XFC(val, port);
201                 if (val & POA_GE_XFC_TX_MSK)
202                         res |= MTKSWITCH_TXFLOW;
203                 if (val & POA_GE_XFC_RX_MSK)
204                         res |= MTKSWITCH_RXFLOW;
205         }
206
207         return (res);
208 }
209
210 static int
211 mtkswitch_atu_flush(struct mtkswitch_softc *sc)
212 {
213         return (0);
214 }
215
216 static int
217 mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
218 {
219         uint32_t val;
220         int err, invert = 0;
221
222         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
223         MTKSWITCH_LOCK(sc);
224         /* Set the PVID. */
225         if (p->es_pvid != 0) {
226                 err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
227                     p->es_pvid);
228                 if (err != 0) {
229                         MTKSWITCH_UNLOCK(sc);
230                         return (err);
231                 }
232         }
233
234         /* Mutually exclusive */
235         if (p->es_flags & ETHERSWITCH_PORT_ADDTAG &&
236             p->es_flags & ETHERSWITCH_PORT_STRIPTAG) {
237                 invert = 1;
238         }
239
240         val = MTKSWITCH_READ(sc, MTKSWITCH_SGC2);
241         if (p->es_flags & ETHERSWITCH_PORT_DOUBLE_TAG)
242                 val |= SGC2_DOUBLE_TAG_PORT(p->es_port);
243         else
244                 val &= ~SGC2_DOUBLE_TAG_PORT(p->es_port);
245         MTKSWITCH_WRITE(sc, MTKSWITCH_SGC2, val);
246
247         val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
248         if (invert) {
249                 if (val & POC2_UNTAG_PORT(p->es_port))
250                         val &= ~POC2_UNTAG_PORT(p->es_port);
251                 else
252                         val |= POC2_UNTAG_PORT(p->es_port);
253         } else if (p->es_flags & ETHERSWITCH_PORT_STRIPTAG)
254                 val |= POC2_UNTAG_PORT(p->es_port);
255         else
256                 val &= ~POC2_UNTAG_PORT(p->es_port);
257         MTKSWITCH_WRITE(sc, MTKSWITCH_POC2, val);
258         MTKSWITCH_UNLOCK(sc);
259
260         return (0);
261 }
262
263 static int
264 mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
265 {
266         uint32_t val;
267
268         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
269         MTKSWITCH_LOCK(sc);
270
271         /* Retrieve the PVID */
272         sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
273
274         /* Port flags */
275         p->es_flags = 0;
276         val = MTKSWITCH_READ(sc, MTKSWITCH_SGC2);
277         if (val & SGC2_DOUBLE_TAG_PORT(p->es_port))
278                 p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG;
279
280         val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
281         if (val & POC2_UNTAG_PORT(p->es_port))
282                 p->es_flags |= ETHERSWITCH_PORT_STRIPTAG;
283         else
284                 p->es_flags |= ETHERSWITCH_PORT_ADDTAG;
285
286         MTKSWITCH_UNLOCK(sc);
287
288         return (0);
289 }
290
291 static void
292 mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
293 {
294         uint32_t val, vid;
295         int i;
296
297         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
298         MTKSWITCH_LOCK(sc);
299
300         /* Reset everything to defaults first */
301         for (i = 0; i < sc->info.es_nvlangroups; i++) {
302                 /* Remove all VLAN members and untag info, if any */
303                 if (i % 4 == 0) {
304                         MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(i), 0);
305                         if (sc->sc_switchtype != MTK_SWITCH_RT3050)
306                                 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(i), 0);
307                 }
308                 /* Reset to default VIDs */
309                 val = MTKSWITCH_READ(sc, MTKSWITCH_VLANI(i));
310                 val &= ~(VLANI_MASK << VLANI_OFF(i));
311                 val |= ((i + 1) << VLANI_OFF(i));
312                 MTKSWITCH_WRITE(sc, MTKSWITCH_VLANI(i), val);
313         }
314
315         /* Now, add all ports as untagged members to VLAN1 */
316         vid = 0;
317         val = MTKSWITCH_READ(sc, MTKSWITCH_VMSC(vid));
318         val &= ~(VMSC_MASK << VMSC_OFF(vid));
319         val |= (((1<<sc->numports)-1) << VMSC_OFF(vid));
320         MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(vid), val);
321         if (sc->sc_switchtype != MTK_SWITCH_RT3050) {
322                 val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(vid));
323                 val &= ~(VUB_MASK << VUB_OFF(vid));
324                 val |= (((1<<sc->numports)-1) << VUB_OFF(vid));
325                 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(vid), val);
326         }
327         val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
328         if (sc->sc_switchtype != MTK_SWITCH_RT3050)
329                 val |= POC2_UNTAG_VLAN;
330         val |= ((1<<sc->numports)-1);
331         MTKSWITCH_WRITE(sc, MTKSWITCH_POC2, val);
332
333         /* only the first vlangroup is valid */
334         sc->valid_vlans = (1<<0);
335
336         /* Set all port PVIDs to 1 */
337         vid = 1;
338         for (i = 0; i < sc->info.es_nports; i++) {
339                 val = MTKSWITCH_READ(sc, MTKSWITCH_PVID(i));
340                 val &= ~(PVID_MASK << PVID_OFF(i));
341                 val |= (vid << PVID_OFF(i));
342                 MTKSWITCH_WRITE(sc, MTKSWITCH_PVID(i), val);
343         }
344
345         MTKSWITCH_UNLOCK(sc);
346 }
347
348 static int
349 mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
350 {
351         uint32_t val;
352
353         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
354
355         if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
356             (v->es_vlangroup > sc->info.es_nvlangroups))
357                 return (EINVAL);
358
359         /* Reset the member ports. */
360         v->es_untagged_ports = 0;
361         v->es_member_ports = 0;
362
363         /* Not supported */
364         v->es_fid = 0;
365
366         /* Vlan ID */
367         v->es_vid = 0;
368         if ((sc->valid_vlans & (1<<v->es_vlangroup)) == 0)
369                 return (0);
370
371         MTKSWITCH_LOCK(sc);
372         v->es_vid = (MTKSWITCH_READ(sc, MTKSWITCH_VLANI(v->es_vlangroup)) >>
373             VLANI_OFF(v->es_vlangroup)) & VLANI_MASK;
374         v->es_vid |= ETHERSWITCH_VID_VALID;
375
376         /* Member ports */
377         v->es_member_ports = v->es_untagged_ports =
378             (MTKSWITCH_READ(sc, MTKSWITCH_VMSC(v->es_vlangroup)) >>
379             VMSC_OFF(v->es_vlangroup)) & VMSC_MASK;
380
381         val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
382
383         if ((val & POC2_UNTAG_VLAN) && sc->sc_switchtype != MTK_SWITCH_RT3050) {
384                 val = (MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup)) >>
385                     VUB_OFF(v->es_vlangroup)) & VUB_MASK;
386         } else {
387                 val &= VUB_MASK;
388         }
389         v->es_untagged_ports &= val;
390
391         MTKSWITCH_UNLOCK(sc);
392         return (0);
393 }
394
395 static int
396 mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
397 {
398         uint32_t val, tmp;
399
400         if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
401             (v->es_vlangroup > sc->info.es_nvlangroups))
402                 return (EINVAL);
403
404         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
405         MTKSWITCH_LOCK(sc);
406         /* First, see if we can accomodate the request at all */
407         val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
408         if (sc->sc_switchtype == MTK_SWITCH_RT3050 ||
409             (val & POC2_UNTAG_VLAN) == 0) {
410                 /*
411                  * There are 2 things we can't support in per-port untagging
412                  * mode:
413                  * 1. Adding a port as an untagged member if the port is not
414                  *    set up to do untagging.
415                  * 2. Adding a port as a tagged member if the port is set up
416                  *    to do untagging.
417                  */
418                 val &= VUB_MASK;
419
420                 /* get all untagged members from the member list */
421                 tmp = v->es_untagged_ports & v->es_member_ports;
422                 /* fail if untagged members are not a subset of all members */
423                 if (tmp != v->es_untagged_ports) {
424                         /* Cannot accomodate request */
425                         MTKSWITCH_UNLOCK(sc);
426                         return (ENOTSUP);
427                 }
428
429                 /* fail if any untagged member is set up to do tagging */
430                 if ((tmp & val) != tmp) {
431                         /* Cannot accomodate request */
432                         MTKSWITCH_UNLOCK(sc);
433                         return (ENOTSUP);
434                 }
435
436                 /* now, get the list of all tagged members */
437                 tmp = v->es_member_ports & ~tmp;
438                 /* fail if any tagged member is set up to do untagging */
439                 if ((tmp & val) != 0) {
440                         /* Cannot accomodate request */
441                         MTKSWITCH_UNLOCK(sc);
442                         return (ENOTSUP);
443                 }
444         } else {
445                 /* Prefer per-Vlan untag and set its members */
446                 val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup));
447                 val &= ~(VUB_MASK << VUB_OFF(v->es_vlangroup));
448                 val |= (((v->es_untagged_ports) & VUB_MASK) <<
449                     VUB_OFF(v->es_vlangroup));
450                 MTKSWITCH_WRITE(sc, MTKSWITCH_VUB(v->es_vlangroup), val);
451         }
452
453         /* Set VID */
454         val = MTKSWITCH_READ(sc, MTKSWITCH_VLANI(v->es_vlangroup));
455         val &= ~(VLANI_MASK << VLANI_OFF(v->es_vlangroup));
456         val |= (v->es_vid & VLANI_MASK) << VLANI_OFF(v->es_vlangroup);
457         MTKSWITCH_WRITE(sc, MTKSWITCH_VLANI(v->es_vlangroup), val);
458
459         /* Set members */
460         val = MTKSWITCH_READ(sc, MTKSWITCH_VMSC(v->es_vlangroup));
461         val &= ~(VMSC_MASK << VMSC_OFF(v->es_vlangroup));
462         val |= (v->es_member_ports << VMSC_OFF(v->es_vlangroup));
463         MTKSWITCH_WRITE(sc, MTKSWITCH_VMSC(v->es_vlangroup), val);
464
465         sc->valid_vlans |= (1<<v->es_vlangroup);
466
467         MTKSWITCH_UNLOCK(sc);
468         return (0);
469 }
470
471 static int
472 mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
473 {
474
475         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
476         *pvid = (MTKSWITCH_READ(sc, MTKSWITCH_PVID(port)) >> PVID_OFF(port)) &
477             PVID_MASK;
478
479         return (0); 
480 }
481
482 static int
483 mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
484 {
485         uint32_t val;
486
487         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
488         val = MTKSWITCH_READ(sc, MTKSWITCH_PVID(port));
489         val &= ~(PVID_MASK << PVID_OFF(port));
490         val |= (pvid & PVID_MASK) << PVID_OFF(port);
491         MTKSWITCH_WRITE(sc, MTKSWITCH_PVID(port), val);
492         
493         return (0);
494 }
495
496 extern void
497 mtk_attach_switch_rt3050(struct mtkswitch_softc *sc)
498 {
499
500         sc->portmap = 0x7f;
501         sc->phymap = 0x1f;
502
503         sc->info.es_nports = 7;
504         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
505         sc->info.es_nvlangroups = 16;
506         sprintf(sc->info.es_name, "Ralink ESW");
507
508         sc->hal.mtkswitch_reset = mtkswitch_reset;
509         sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
510         sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
511         sc->hal.mtkswitch_port_init = mtkswitch_port_init;
512         sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
513         sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
514         sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
515         sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
516         sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
517         sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
518         sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
519         sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
520         sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
521         sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
522         sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
523         sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
524         sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;
525 }