Lines Matching +full:smi +full:- +full:mdio

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2015-2016 Hiroki Mori.
5 * Copyright (c) 2011-2012 Stefan Bethke.
57 #include <dev/mdio/mdio.h>
70 int smi_acquired; /* serialize access to SMI/I2C bus */
84 #define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
85 #define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
86 #define RTL_LOCK_ASSERT(_sc, _what) mtx_assert(&(_s)c->sc_mtx, (_what))
87 #define RTL_TRYLOCK(_sc) mtx_trylock(&(_sc)->sc_mtx)
94 KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__))
136 if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
139 devi->addr = RTL8366_IIC_ADDR;
153 if (sc->chip_type == RTL8366RB)
168 /* Initialisation for TL-WR1043ND */
186 sc->vid[i] = (i + 1) | ETHERSWITCH_VID_VALID;
214 sc->dev = dev;
215 mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
216 sc->smi_acquired = 0;
217 mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
223 sc->phy4cpu = 0;
225 "phy4cpu", &sc->phy4cpu);
227 sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
229 sc->info.es_nports = sc->numphys + 1;
230 sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
231 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
232 if (sc->chip_type == RTL8366RB)
233 sprintf(sc->info.es_name, "Realtek RTL8366RB");
235 sprintf(sc->info.es_name, "Realtek RTL8366SR");
239 for (i = 0; i < sc->numphys; i++) {
240 sc->ifp[i] = if_alloc(IFT_ETHER);
241 if_setsoftc(sc->ifp[i], sc);
242 if_setflagbits(sc->ifp[i], IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
245 sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
246 bcopy(name, sc->ifname[i], strlen(name)+1);
247 if_initname(sc->ifp[i], sc->ifname[i], i);
248 err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \
263 callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
277 for (i=0; i < sc->numphys; i++) {
278 if (sc->miibus[i])
279 device_delete_child(dev, sc->miibus[i]);
280 if (sc->ifp[i] != NULL)
281 if_free(sc->ifp[i]);
282 free(sc->ifname[i], M_DEVBUF);
285 callout_drain(&sc->callout_tick);
286 mtx_destroy(&sc->callout_mtx);
287 mtx_destroy(&sc->sc_mtx);
333 for (i = 0; i < sc->numphys; i++) {
334 mii = device_get_softc(sc->miibus[i]);
336 if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
344 rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active);
345 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
346 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst)
361 callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
381 for (j=3; j--; ) {
410 sc->chip_type = RTL8366RB;
416 sc->chip_type = RTL8366SR;
442 if (sc->smi_acquired == RTL_SMI_ACQUIRED)
445 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
448 sc->smi_acquired = RTL_SMI_ACQUIRED;
463 iicbus_release_bus(device_get_parent(sc->dev), sc->dev);
464 sc->smi_acquired = 0;
482 slave = devi->addr;
486 if (sc->chip_type == RTL8366SR) { // RTL8366SR work around
488 for (int i=3; i--; )
495 for (i = RTL_IICBUS_RETRIES; i--; ) {
516 iicbus = device_get_parent(sc->dev);
521 err = smi_select(sc->dev, RTL_IICBUS_READ, sleep);
545 iicbus = device_get_parent(sc->dev);
553 err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
628 return (&sc->info);
660 ifmr = &p->es_ifmr;
662 if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
664 if (sc->phy4cpu && p->es_port == sc->numphys) {
665 vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
666 rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
668 vlangroup = RTL8366_PVCR_GET(p->es_port,
669 rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
671 p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
673 if (p->es_port < sc->numphys) {
674 mii = device_get_softc(sc->miibus[p->es_port]);
675 ifm = &mii->mii_media;
676 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
681 p->es_flags |= ETHERSWITCH_PORT_CPU;
684 rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
685 ifmr->ifm_current = ifmr->ifm_active;
686 ifmr->ifm_mask = 0;
687 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
689 if (ifmr->ifm_count > 0) {
690 ifmr->ifm_count = 1;
691 ifmr->ifm_ulist[0] = IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
694 ifmr->ifm_count = 0;
710 if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
712 vlangroup = -1;
714 if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) {
719 if (vlangroup == -1)
721 if (sc->phy4cpu && p->es_port == sc->numphys) {
722 port = p->es_port + 1;
724 port = p->es_port;
732 if (p->es_port == sc->numphys)
734 mii = device_get_softc(sc->miibus[p->es_port]);
735 ifm = &mii->mii_media;
736 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
751 vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
753 vg->es_vid = sc->vid[vg->es_vlangroup];
756 if (sc->phy4cpu) {
757 vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
758 vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
760 vg->es_member_ports = member;
761 vg->es_untagged_ports = untagged;
763 vg->es_fid = RTL8366_VMCR_FID(vmcr);
776 g = vg->es_vlangroup;
778 sc->vid[g] = vg->es_vid;
780 if (vg->es_member_ports == 0 && vg->es_untagged_ports == 0 && vg->es_vid == 0)
782 sc->vid[g] |= ETHERSWITCH_VID_VALID;
784 (vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
785 if (sc->phy4cpu) {
787 member = (vg->es_member_ports & 0x0f) |
788 ((vg->es_member_ports & 0x10) << 1);
789 untagged = (vg->es_untagged_ports & 0x0f) |
790 ((vg->es_untagged_ports & 0x10) << 1);
792 member = vg->es_member_ports;
793 untagged = vg->es_untagged_ports;
795 if (sc->chip_type == RTL8366RB) {
800 vg->es_fid);
805 ((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
815 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
816 conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
840 for (i = RTL_IICBUS_RETRIES; i--; ) {
873 for (i = RTL_IICBUS_RETRIES; i--; ) {
896 mii = device_get_softc(sc->miibus[if_getdunit(ifp)]);
909 mii = device_get_softc(sc->miibus[if_getdunit(ifp)]);
912 ifmr->ifm_active = mii->mii_media_active;
913 ifmr->ifm_status = mii->mii_media_status;
931 /* MDIO interface */
955 DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, 0, 0);