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 accommodate 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 accommodate 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 accommodate 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 accommodate 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 } 526