Lines Matching +full:conf +full:- +full:mdio
1 /*-
4 * Copyright (c) 2011-2012 Stefan Bethke.
34 * MDC/MDIO.
61 #include <dev/mdio/mdio.h>
107 mtx_lock(&(_sc)->sc_mtx)
109 mtx_unlock(&(_sc)->sc_mtx)
111 mtx_assert(&(_sc)->sc_mtx, (_what))
113 mtx_trylock(&(_sc)->sc_mtx)
156 device_set_desc(dev, "Infineon ADM6996FC/M/MX MDIO switch driver"); in adm6996fc_probe()
169 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->sc_dev)); in adm6996fc_attach_phys()
170 for (phy = 0; phy < sc->numports; phy++) { in adm6996fc_attach_phys()
171 if (((1 << phy) & sc->phymask) == 0) in adm6996fc_attach_phys()
173 sc->ifpport[phy] = port; in adm6996fc_attach_phys()
174 sc->portphy[port] = phy; in adm6996fc_attach_phys()
175 sc->ifp[port] = if_alloc(IFT_ETHER); in adm6996fc_attach_phys()
176 sc->ifp[port]->if_softc = sc; in adm6996fc_attach_phys()
177 sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST | in adm6996fc_attach_phys()
179 if_initname(sc->ifp[port], name, port); in adm6996fc_attach_phys()
180 sc->miibus[port] = malloc(sizeof(device_t), M_ADM6996FC, in adm6996fc_attach_phys()
182 err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], in adm6996fc_attach_phys()
185 DPRINTF(sc->sc_dev, "%s attached to pseudo interface %s\n", in adm6996fc_attach_phys()
186 device_get_nameunit(*sc->miibus[port]), in adm6996fc_attach_phys()
187 sc->ifp[port]->if_xname); in adm6996fc_attach_phys()
189 device_printf(sc->sc_dev, in adm6996fc_attach_phys()
196 sc->info.es_nports = port; in adm6996fc_attach_phys()
197 if (sc->cpuport != -1) { in adm6996fc_attach_phys()
199 sc->ifpport[sc->cpuport] = port; in adm6996fc_attach_phys()
200 sc->portphy[port] = sc->cpuport; in adm6996fc_attach_phys()
201 ++sc->info.es_nports; in adm6996fc_attach_phys()
206 for (phy = 0; phy < sc->numports; phy++) { in adm6996fc_attach_phys()
207 if (((1 << phy) & sc->phymask) == 0) in adm6996fc_attach_phys()
210 if (sc->miibus[port] != NULL) in adm6996fc_attach_phys()
211 device_delete_child(sc->sc_dev, (*sc->miibus[port])); in adm6996fc_attach_phys()
212 if (sc->ifp[port] != NULL) in adm6996fc_attach_phys()
213 if_free(sc->ifp[port]); in adm6996fc_attach_phys()
214 if (sc->ifname[port] != NULL) in adm6996fc_attach_phys()
215 free(sc->ifname[port], M_ADM6996FC); in adm6996fc_attach_phys()
216 if (sc->miibus[port] != NULL) in adm6996fc_attach_phys()
217 free(sc->miibus[port], M_ADM6996FC); in adm6996fc_attach_phys()
231 sc->sc_dev = dev; in adm6996fc_attach()
232 mtx_init(&sc->sc_mtx, "adm6996fc", NULL, MTX_DEF); in adm6996fc_attach()
233 strlcpy(sc->info.es_name, device_get_desc(dev), in adm6996fc_attach()
234 sizeof(sc->info.es_name)); in adm6996fc_attach()
237 sc->numports = 6; in adm6996fc_attach()
238 sc->phymask = 0x1f; in adm6996fc_attach()
239 sc->cpuport = 5; in adm6996fc_attach()
240 sc->media = 100; in adm6996fc_attach()
242 sc->info.es_nvlangroups = 16; in adm6996fc_attach()
243 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOT1Q; in adm6996fc_attach()
245 sc->ifp = malloc(sizeof(if_t) * sc->numports, M_ADM6996FC, in adm6996fc_attach()
247 sc->ifname = malloc(sizeof(char *) * sc->numports, M_ADM6996FC, in adm6996fc_attach()
249 sc->miibus = malloc(sizeof(device_t *) * sc->numports, M_ADM6996FC, in adm6996fc_attach()
251 sc->portphy = malloc(sizeof(int) * sc->numports, M_ADM6996FC, in adm6996fc_attach()
265 callout_init(&sc->callout_tick, 0); in adm6996fc_attach()
272 free(sc->portphy, M_ADM6996FC); in adm6996fc_attach()
273 free(sc->miibus, M_ADM6996FC); in adm6996fc_attach()
274 free(sc->ifname, M_ADM6996FC); in adm6996fc_attach()
275 free(sc->ifp, M_ADM6996FC); in adm6996fc_attach()
288 callout_drain(&sc->callout_tick); in adm6996fc_detach()
291 if (((1 << i) & sc->phymask) == 0) in adm6996fc_detach()
294 if (sc->miibus[port] != NULL) in adm6996fc_detach()
295 device_delete_child(dev, (*sc->miibus[port])); in adm6996fc_detach()
296 if (sc->ifp[port] != NULL) in adm6996fc_detach()
297 if_free(sc->ifp[port]); in adm6996fc_detach()
298 free(sc->ifname[port], M_ADM6996FC); in adm6996fc_detach()
299 free(sc->miibus[port], M_ADM6996FC); in adm6996fc_detach()
302 free(sc->portphy, M_ADM6996FC); in adm6996fc_detach()
303 free(sc->miibus, M_ADM6996FC); in adm6996fc_detach()
304 free(sc->ifname, M_ADM6996FC); in adm6996fc_detach()
305 free(sc->ifp, M_ADM6996FC); in adm6996fc_detach()
308 mtx_destroy(&sc->sc_mtx); in adm6996fc_detach()
320 return (sc->ifpport[phy]); in adm6996fc_portforphy()
327 if (port < 0 || port > sc->numports) in adm6996fc_miiforport()
329 if (port == sc->cpuport) in adm6996fc_miiforport()
331 return (device_get_softc(*sc->miibus[port])); in adm6996fc_miiforport()
338 if (port < 0 || port > sc->numports) in adm6996fc_ifpforport()
340 return (sc->ifp[port]); in adm6996fc_ifpforport()
356 if (((1 << i) & sc->phymask) == 0) in adm6996fc_miipollstat()
359 if ((*sc->miibus[port]) == NULL) in adm6996fc_miipollstat()
361 mii = device_get_softc(*sc->miibus[port]); in adm6996fc_miipollstat()
362 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { in adm6996fc_miipollstat()
363 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != in adm6996fc_miipollstat()
364 miisc->mii_inst) in adm6996fc_miipollstat()
380 callout_reset(&sc->callout_tick, hz, adm6996fc_tick, sc); in adm6996fc_tick()
412 return (&sc->info); in adm6996fc_getinfo()
429 ifmr = &p->es_ifmr; in adm6996fc_getport()
431 if (p->es_port < 0 || p->es_port >= sc->numports) in adm6996fc_getport()
436 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in adm6996fc_getport()
437 data1 = ADM6996FC_READREG(parent, bcaddr[p->es_port]); in adm6996fc_getport()
438 data2 = ADM6996FC_READREG(parent, vidaddr[p->es_port]); in adm6996fc_getport()
440 if (p->es_port == 4) in adm6996fc_getport()
445 p->es_pvid = ADM6996FC_PVIDBYDATA(data1, data2); in adm6996fc_getport()
447 p->es_flags |= ETHERSWITCH_PORT_ADDTAG; in adm6996fc_getport()
449 p->es_pvid = 0; in adm6996fc_getport()
452 phy = sc->portphy[p->es_port]; in adm6996fc_getport()
453 mii = adm6996fc_miiforport(sc, p->es_port); in adm6996fc_getport()
454 if (sc->cpuport != -1 && phy == sc->cpuport) { in adm6996fc_getport()
456 p->es_flags |= ETHERSWITCH_PORT_CPU; in adm6996fc_getport()
457 ifmr->ifm_count = 0; in adm6996fc_getport()
458 if (sc->media == 100) in adm6996fc_getport()
459 ifmr->ifm_current = ifmr->ifm_active = in adm6996fc_getport()
462 ifmr->ifm_current = ifmr->ifm_active = in adm6996fc_getport()
464 ifmr->ifm_mask = 0; in adm6996fc_getport()
465 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; in adm6996fc_getport()
467 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, in adm6996fc_getport()
468 &mii->mii_media, SIOCGIFMEDIA); in adm6996fc_getport()
494 if (p->es_port < 0 || p->es_port >= sc->numports) in adm6996fc_setport()
497 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in adm6996fc_setport()
498 data = ADM6996FC_READREG(parent, bcaddr[p->es_port]); in adm6996fc_setport()
500 data |= (p->es_pvid & 0xf) << ADM6996FC_PVID_SHIFT; in adm6996fc_setport()
501 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG) in adm6996fc_setport()
505 ADM6996FC_WRITEREG(parent, bcaddr[p->es_port], data); in adm6996fc_setport()
506 data = ADM6996FC_READREG(parent, vidaddr[p->es_port]); in adm6996fc_setport()
508 if (p->es_port == 4) { in adm6996fc_setport()
510 data = data | (((p->es_pvid >> 4) & 0xff) << 8); in adm6996fc_setport()
513 data = data | ((p->es_pvid >> 4) & 0xff); in adm6996fc_setport()
515 ADM6996FC_WRITEREG(parent, vidaddr[p->es_port], data); in adm6996fc_setport()
518 if (sc->portphy[p->es_port] == sc->cpuport) in adm6996fc_setport()
522 if (sc->portphy[p->es_port] != sc->cpuport) { in adm6996fc_setport()
523 mii = adm6996fc_miiforport(sc, p->es_port); in adm6996fc_setport()
527 ifp = adm6996fc_ifpforport(sc, p->es_port); in adm6996fc_setport()
529 ifm = &mii->mii_media; in adm6996fc_setport()
530 err = ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA); in adm6996fc_setport()
545 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { in adm6996fc_getvgroup()
546 if (vg->es_vlangroup <= 5) { in adm6996fc_getvgroup()
547 vg->es_vid = ETHERSWITCH_VID_VALID; in adm6996fc_getvgroup()
548 vg->es_vid |= vg->es_vlangroup; in adm6996fc_getvgroup()
550 ADM6996FC_VF0L + 2 * vg->es_vlangroup); in adm6996fc_getvgroup()
552 ADM6996FC_VF0H + 2 * vg->es_vlangroup); in adm6996fc_getvgroup()
554 vg->es_member_ports = datalo & 0x3f; in adm6996fc_getvgroup()
555 vg->es_untagged_ports = vg->es_member_ports; in adm6996fc_getvgroup()
556 vg->es_fid = 0; in adm6996fc_getvgroup()
558 vg->es_vid = 0; in adm6996fc_getvgroup()
560 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in adm6996fc_getvgroup()
562 ADM6996FC_VF0L + 2 * vg->es_vlangroup); in adm6996fc_getvgroup()
564 ADM6996FC_VF0H + 2 * vg->es_vlangroup); in adm6996fc_getvgroup()
567 vg->es_vid = ETHERSWITCH_VID_VALID; in adm6996fc_getvgroup()
568 vg->es_vid |= datahi & 0xfff; in adm6996fc_getvgroup()
569 vg->es_member_ports = datalo & 0x3f; in adm6996fc_getvgroup()
570 vg->es_untagged_ports = (~datalo >> 6) & 0x3f; in adm6996fc_getvgroup()
571 vg->es_fid = 0; in adm6996fc_getvgroup()
573 vg->es_fid = 0; in adm6996fc_getvgroup()
576 vg->es_fid = 0; in adm6996fc_getvgroup()
591 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { in adm6996fc_setvgroup()
592 ADM6996FC_WRITEREG(parent, ADM6996FC_VF0L + 2 * vg->es_vlangroup, in adm6996fc_setvgroup()
593 vg->es_member_ports); in adm6996fc_setvgroup()
594 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in adm6996fc_setvgroup()
595 ADM6996FC_WRITEREG(parent, ADM6996FC_VF0L + 2 * vg->es_vlangroup, in adm6996fc_setvgroup()
596 vg->es_member_ports | ((~vg->es_untagged_ports & 0x3f)<< 6)); in adm6996fc_setvgroup()
597 ADM6996FC_WRITEREG(parent, ADM6996FC_VF0H + 2 * vg->es_vlangroup, in adm6996fc_setvgroup()
598 (1 << ADM6996FC_VV_SHIFT) | vg->es_vid); in adm6996fc_setvgroup()
605 adm6996fc_getconf(device_t dev, etherswitch_conf_t *conf) in adm6996fc_getconf() argument
612 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; in adm6996fc_getconf()
613 conf->vlan_mode = sc->vlan_mode; in adm6996fc_getconf()
619 adm6996fc_setconf(device_t dev, etherswitch_conf_t *conf) in adm6996fc_setconf() argument
630 if ((conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) == 0) in adm6996fc_setconf()
633 if (conf->vlan_mode == ETHERSWITCH_VLAN_PORT) { in adm6996fc_setconf()
634 sc->vlan_mode = ETHERSWITCH_VLAN_PORT; in adm6996fc_setconf()
648 } else if (conf->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { in adm6996fc_setconf()
649 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; in adm6996fc_setconf()
670 sc->vlan_mode = 0; in adm6996fc_setconf()
708 DPRINTF(sc->sc_dev, "%s\n", __func__); in adm6996fc_ifmedia_upd()
724 DPRINTF(sc->sc_dev, "%s\n", __func__); in adm6996fc_ifmedia_sts()
729 ifmr->ifm_active = mii->mii_media_active; in adm6996fc_ifmedia_sts()
730 ifmr->ifm_status = mii->mii_media_status; in adm6996fc_ifmedia_sts()
807 /* MDIO interface */
832 DRIVER_MODULE(adm6996fc, mdio, adm6996fc_driver, 0, 0);
834 DRIVER_MODULE(mdio, adm6996fc, mdio_driver, 0, 0);