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 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 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 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 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 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 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 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 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 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 209 mtkswitch_atu_flush(struct mtkswitch_softc *sc) 210 { 211 return (0); 212 } 213 214 static int 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 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 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 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 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 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 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 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