Lines Matching +full:smi +full:- +full:mdio
1 /*-
2 * Copyright (c) 2016-2017 Hiroki Mori
4 * Copyright (c) 2011-2012 Stefan Bethke.
60 #include <dev/mdio/mdio.h>
135 mtx_lock(&(_sc)->sc_mtx)
137 mtx_unlock(&(_sc)->sc_mtx)
139 mtx_assert(&(_sc)->sc_mtx, (_what))
141 mtx_trylock(&(_sc)->sc_mtx)
180 sc->sw_model = devid; in e6060sw_probe()
181 sc->smi_offset = i * 0x10; in e6060sw_probe()
195 device_set_descf(dev, "Marvell %s MDIO switch driver at 0x%02x", in e6060sw_probe()
196 devname, sc->smi_offset); in e6060sw_probe()
210 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->sc_dev)); in e6060sw_attach_phys()
211 for (phy = 0; phy < sc->numports; phy++) { in e6060sw_attach_phys()
212 if (((1 << phy) & sc->phymask) == 0) in e6060sw_attach_phys()
214 sc->ifpport[phy] = port; in e6060sw_attach_phys()
215 sc->portphy[port] = phy; in e6060sw_attach_phys()
216 sc->ifp[port] = if_alloc(IFT_ETHER); in e6060sw_attach_phys()
217 sc->ifp[port]->if_softc = sc; in e6060sw_attach_phys()
218 sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST | in e6060sw_attach_phys()
220 if_initname(sc->ifp[port], name, port); in e6060sw_attach_phys()
221 sc->miibus[port] = malloc(sizeof(device_t), M_E6060SW, in e6060sw_attach_phys()
223 err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], in e6060sw_attach_phys()
225 BMSR_DEFCAPMASK, phy + sc->smi_offset, MII_OFFSET_ANY, 0); in e6060sw_attach_phys()
226 DPRINTF(sc->sc_dev, "%s attached to pseudo interface %s\n", in e6060sw_attach_phys()
227 device_get_nameunit(*sc->miibus[port]), in e6060sw_attach_phys()
228 sc->ifp[port]->if_xname); in e6060sw_attach_phys()
230 device_printf(sc->sc_dev, in e6060sw_attach_phys()
237 sc->info.es_nports = port; in e6060sw_attach_phys()
238 if (sc->cpuport != -1) { in e6060sw_attach_phys()
240 sc->ifpport[sc->cpuport] = port; in e6060sw_attach_phys()
241 sc->portphy[port] = sc->cpuport; in e6060sw_attach_phys()
242 ++sc->info.es_nports; in e6060sw_attach_phys()
256 sc->sc_dev = dev; in e6060sw_attach()
257 mtx_init(&sc->sc_mtx, "e6060sw", NULL, MTX_DEF); in e6060sw_attach()
258 strlcpy(sc->info.es_name, device_get_desc(dev), in e6060sw_attach()
259 sizeof(sc->info.es_name)); in e6060sw_attach()
262 if (sc->sw_model == E6063) { in e6060sw_attach()
263 sc->numports = 3; in e6060sw_attach()
264 sc->phymask = 0x07; in e6060sw_attach()
265 sc->cpuport = 2; in e6060sw_attach()
267 sc->numports = 6; in e6060sw_attach()
268 sc->phymask = 0x1f; in e6060sw_attach()
269 sc->cpuport = 5; in e6060sw_attach()
271 sc->media = 100; in e6060sw_attach()
274 "numports", &sc->numports); in e6060sw_attach()
276 "phymask", &sc->phymask); in e6060sw_attach()
278 "cpuport", &sc->cpuport); in e6060sw_attach()
280 "media", &sc->media); in e6060sw_attach()
282 if (sc->sw_model == E6060) { in e6060sw_attach()
283 sc->info.es_nvlangroups = sc->numports; in e6060sw_attach()
284 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_PORT; in e6060sw_attach()
286 sc->info.es_nvlangroups = 64; in e6060sw_attach()
287 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_PORT | in e6060sw_attach()
293 sc->ifp = malloc(sizeof(if_t) * sc->numports, M_E6060SW, in e6060sw_attach()
295 sc->ifname = malloc(sizeof(char *) * sc->numports, M_E6060SW, in e6060sw_attach()
297 sc->miibus = malloc(sizeof(device_t *) * sc->numports, M_E6060SW, in e6060sw_attach()
299 sc->portphy = malloc(sizeof(int) * sc->numports, M_E6060SW, in e6060sw_attach()
315 callout_init(&sc->callout_tick, 0); in e6060sw_attach()
330 callout_drain(&sc->callout_tick); in e6060sw_detach()
333 if (((1 << i) & sc->phymask) == 0) in e6060sw_detach()
336 if (sc->miibus[port] != NULL) in e6060sw_detach()
337 device_delete_child(dev, (*sc->miibus[port])); in e6060sw_detach()
338 if (sc->ifp[port] != NULL) in e6060sw_detach()
339 if_free(sc->ifp[port]); in e6060sw_detach()
340 free(sc->ifname[port], M_E6060SW); in e6060sw_detach()
341 free(sc->miibus[port], M_E6060SW); in e6060sw_detach()
344 free(sc->portphy, M_E6060SW); in e6060sw_detach()
345 free(sc->miibus, M_E6060SW); in e6060sw_detach()
346 free(sc->ifname, M_E6060SW); in e6060sw_detach()
347 free(sc->ifp, M_E6060SW); in e6060sw_detach()
350 mtx_destroy(&sc->sc_mtx); in e6060sw_detach()
362 return (sc->ifpport[phy]); in e6060sw_portforphy()
369 if (port < 0 || port > sc->numports) in e6060sw_miiforport()
371 if (port == sc->cpuport) in e6060sw_miiforport()
373 return (device_get_softc(*sc->miibus[port])); in e6060sw_miiforport()
380 if (port < 0 || port > sc->numports) in e6060sw_ifpforport()
382 return (sc->ifp[port]); in e6060sw_ifpforport()
398 if (((1 << i) & sc->phymask) == 0) in e6060sw_miipollstat()
401 if ((*sc->miibus[port]) == NULL) in e6060sw_miipollstat()
403 mii = device_get_softc(*sc->miibus[port]); in e6060sw_miipollstat()
404 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { in e6060sw_miipollstat()
405 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != in e6060sw_miipollstat()
406 miisc->mii_inst) in e6060sw_miipollstat()
422 callout_reset(&sc->callout_tick, hz, e6060sw_tick, sc); in e6060sw_tick()
454 return (&sc->info); in e6060sw_getinfo()
466 ifmr = &p->es_ifmr; in e6060sw_getport()
468 if (p->es_port < 0 || p->es_port >= sc->numports) in e6060sw_getport()
471 p->es_pvid = 0; in e6060sw_getport()
472 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in e6060sw_getport()
473 p->es_pvid = MDIO_READREG(device_get_parent(dev), in e6060sw_getport()
474 CORE_REGISTER + sc->smi_offset + p->es_port, in e6060sw_getport()
478 phy = sc->portphy[p->es_port]; in e6060sw_getport()
479 mii = e6060sw_miiforport(sc, p->es_port); in e6060sw_getport()
480 if (sc->cpuport != -1 && phy == sc->cpuport) { in e6060sw_getport()
482 p->es_flags |= ETHERSWITCH_PORT_CPU; in e6060sw_getport()
483 ifmr->ifm_count = 0; in e6060sw_getport()
484 if (sc->media == 100) in e6060sw_getport()
485 ifmr->ifm_current = ifmr->ifm_active = in e6060sw_getport()
488 ifmr->ifm_current = ifmr->ifm_active = in e6060sw_getport()
490 ifmr->ifm_mask = 0; in e6060sw_getport()
491 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; in e6060sw_getport()
493 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, in e6060sw_getport()
494 &mii->mii_media, SIOCGIFMEDIA); in e6060sw_getport()
515 if (p->es_port < 0 || p->es_port >= sc->numports) in e6060sw_setport()
518 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in e6060sw_setport()
520 CORE_REGISTER + sc->smi_offset + p->es_port, in e6060sw_setport()
523 data |= p->es_pvid; in e6060sw_setport()
526 CORE_REGISTER + sc->smi_offset + p->es_port, in e6060sw_setport()
530 if (sc->portphy[p->es_port] == sc->cpuport) in e6060sw_setport()
533 mii = e6060sw_miiforport(sc, p->es_port); in e6060sw_setport()
537 ifp = e6060sw_ifpforport(sc, p->es_port); in e6060sw_setport()
539 ifm = &mii->mii_media; in e6060sw_setport()
540 err = ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA); in e6060sw_setport()
554 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { in e6060sw_getvgroup()
555 vg->es_vid = ETHERSWITCH_VID_VALID; in e6060sw_getvgroup()
556 vg->es_vid |= vg->es_vlangroup; in e6060sw_getvgroup()
558 CORE_REGISTER + sc->smi_offset + vg->es_vlangroup, in e6060sw_getvgroup()
560 vg->es_member_ports = data1 & 0x3f; in e6060sw_getvgroup()
561 vg->es_untagged_ports = vg->es_member_ports; in e6060sw_getvgroup()
562 vg->es_fid = 0; in e6060sw_getvgroup()
563 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in e6060sw_getvgroup()
564 if (vg->es_vlangroup == 0) in e6060sw_getvgroup()
566 vid = e6060sw_read_vtu(dev, vg->es_vlangroup, &data1, &data2); in e6060sw_getvgroup()
568 vg->es_vid = ETHERSWITCH_VID_VALID; in e6060sw_getvgroup()
569 vg->es_vid |= vid; in e6060sw_getvgroup()
570 vg->es_member_ports = 0; in e6060sw_getvgroup()
571 vg->es_untagged_ports = 0; in e6060sw_getvgroup()
575 vg->es_member_ports |= 1 << i; in e6060sw_getvgroup()
576 vg->es_untagged_ports |= 1 << i; in e6060sw_getvgroup()
578 vg->es_member_ports |= 1 << i; in e6060sw_getvgroup()
584 vg->es_member_ports |= 1 << (i + 4); in e6060sw_getvgroup()
585 vg->es_untagged_ports |= 1 << (i + 4); in e6060sw_getvgroup()
587 vg->es_member_ports |= 1 << (i + 4); in e6060sw_getvgroup()
593 vg->es_vid = 0; in e6060sw_getvgroup()
607 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { in e6060sw_setvgroup()
609 CORE_REGISTER + sc->smi_offset + vg->es_vlangroup, in e6060sw_setvgroup()
612 data1 |= vg->es_member_ports; in e6060sw_setvgroup()
614 CORE_REGISTER + sc->smi_offset + vg->es_vlangroup, in e6060sw_setvgroup()
616 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in e6060sw_setvgroup()
617 if (vg->es_vlangroup == 0) in e6060sw_setvgroup()
622 if (vg->es_member_ports & in e6060sw_setvgroup()
623 vg->es_untagged_ports & (1 << i)) { in e6060sw_setvgroup()
627 data2 |= (0xd << (i - 4) * 4); in e6060sw_setvgroup()
629 } else if (vg->es_member_ports & (1 << i)) { in e6060sw_setvgroup()
633 data2 |= (0xe << (i - 4) * 4); in e6060sw_setvgroup()
639 data2 |= (0x3 << (i - 4) * 4); in e6060sw_setvgroup()
643 e6060sw_set_vtu(dev, vg->es_vlangroup, data1, data2); in e6060sw_setvgroup()
658 for (i = 0; i <= sc->numports; i++) { in e6060sw_reset_vlans()
659 ports = (1 << (sc->numports + 1)) - 1; in e6060sw_reset_vlans()
661 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { in e6060sw_reset_vlans()
663 } else if (sc->vlan_mode == 0) { in e6060sw_reset_vlans()
670 CORE_REGISTER + sc->smi_offset + i, PORT_VLAN_MAP, data); in e6060sw_reset_vlans()
683 for (i = 0; i <= sc->numports; i++) { in e6060sw_setup()
684 if (sc->sw_model == E6063 || sc->sw_model == E6065) { in e6060sw_setup()
686 CORE_REGISTER + sc->smi_offset + i, PORT_VLAN_MAP); in e6060sw_setup()
689 CORE_REGISTER + sc->smi_offset + i, in e6060sw_setup()
693 CORE_REGISTER + sc->smi_offset + i, PORT_CONTROL); in e6060sw_setup()
696 CORE_REGISTER + sc->smi_offset + i, in e6060sw_setup()
711 for (i = 0; i <= sc->numports; i++) { in e6060sw_dot1q_mode()
713 CORE_REGISTER + sc->smi_offset + i, PORT_CONTROL2); in e6060sw_dot1q_mode()
717 CORE_REGISTER + sc->smi_offset + i, PORT_CONTROL2, data); in e6060sw_dot1q_mode()
720 CORE_REGISTER + sc->smi_offset + i, in e6060sw_dot1q_mode()
725 CORE_REGISTER + sc->smi_offset + i, in e6060sw_dot1q_mode()
738 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; in e6060sw_getconf()
739 conf->vlan_mode = sc->vlan_mode; in e6060sw_getconf()
752 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_init_vtu()
756 GLOBAL_REGISTER + sc->smi_offset, VTU_OPERATION); in e6060sw_init_vtu()
762 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_init_vtu()
764 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_init_vtu()
766 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_init_vtu()
768 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_init_vtu()
772 GLOBAL_REGISTER + sc->smi_offset, VTU_OPERATION); in e6060sw_init_vtu()
786 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_set_vtu()
788 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_set_vtu()
790 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_set_vtu()
792 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_set_vtu()
796 GLOBAL_REGISTER + sc->smi_offset, VTU_OPERATION); in e6060sw_set_vtu()
811 num = num - 1; in e6060sw_read_vtu()
813 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_read_vtu()
816 MDIO_WRITEREG(device_get_parent(dev), GLOBAL_REGISTER + sc->smi_offset, in e6060sw_read_vtu()
820 GLOBAL_REGISTER + sc->smi_offset, VTU_OPERATION); in e6060sw_read_vtu()
826 GLOBAL_REGISTER + sc->smi_offset, VTU_VID_REG); in e6060sw_read_vtu()
829 GLOBAL_REGISTER + sc->smi_offset, VTU_DATA1_REG); in e6060sw_read_vtu()
831 GLOBAL_REGISTER + sc->smi_offset, VTU_DATA2_REG); in e6060sw_read_vtu()
836 return (-1); in e6060sw_read_vtu()
847 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { in e6060sw_setconf()
848 if (conf->vlan_mode == ETHERSWITCH_VLAN_PORT) { in e6060sw_setconf()
849 sc->vlan_mode = ETHERSWITCH_VLAN_PORT; in e6060sw_setconf()
852 } else if ((sc->sw_model == E6063 || sc->sw_model == E6065) && in e6060sw_setconf()
853 conf->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in e6060sw_setconf()
854 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; in e6060sw_setconf()
858 sc->vlan_mode = 0; in e6060sw_setconf()
884 DPRINTF(sc->sc_dev, "%s\n", __func__); in e6060sw_ifmedia_upd()
900 DPRINTF(sc->sc_dev, "%s\n", __func__); in e6060sw_ifmedia_sts()
905 ifmr->ifm_active = mii->mii_media_active; in e6060sw_ifmedia_sts()
906 ifmr->ifm_status = mii->mii_media_status; in e6060sw_ifmedia_sts()
951 /* addr is 5-8 bit is SMI Device Addres, 0-4 bit is SMI Register Address */
964 /* addr is 5-8 bit is SMI Device Addres, 0-4 bit is SMI Register Address */
991 /* MDIO interface */
1016 DRIVER_MODULE(e6060sw, mdio, e6060sw_driver, 0, 0);
1018 DRIVER_MODULE(mdio, e6060sw, mdio_driver, 0, 0);