Lines Matching +full:conf +full:- +full:mdio
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
53 #include <dev/mdio/mdio.h>
79 { "qcom,ess-switch", 1 },
90 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in ar40xx_probe()
103 callout_reset(&sc->sc_phy_callout, hz, ar40xx_tick, sc); in ar40xx_tick()
119 return MDIO_READREG(sc->sc_mdio_dev, phy, reg); in ar40xx_readphy()
127 return MDIO_WRITEREG(sc->sc_mdio_dev, phy, reg, val); in ar40xx_writephy()
141 memset(&sc->sc_vlan, 0, sizeof(sc->sc_vlan)); in ar40xx_reset_switch()
145 sc->sc_vlan.vlan_id[i] = 0; in ar40xx_reset_switch()
151 sc->sc_monitor.mirror_tx = false; in ar40xx_reset_switch()
152 sc->sc_monitor.mirror_rx = false; in ar40xx_reset_switch()
153 sc->sc_monitor.source_port = 0; in ar40xx_reset_switch()
154 sc->sc_monitor.monitor_port = 0; in ar40xx_reset_switch()
173 if (error || !req->newptr) in ar40xx_sysctl_dump_port_state()
182 device_printf(sc->sc_dev, "port %d: PORT_STATUS=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
184 device_printf(sc->sc_dev, "port %d: PORT_HEADER=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
186 device_printf(sc->sc_dev, "port %d: PORT_VLAN0=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
188 device_printf(sc->sc_dev, "port %d: PORT_VLAN1=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
190 device_printf(sc->sc_dev, "port %d: PORT_LOOKUP=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
192 device_printf(sc->sc_dev, "port %d: PORT_HOL_CTRL1=0x%08x\n", val, in ar40xx_sysctl_dump_port_state()
194 device_printf(sc->sc_dev, "port %d: PORT_FLOWCTRL_THRESH=0x%08x\n", in ar40xx_sysctl_dump_port_state()
213 if (error || !req->newptr) in ar40xx_sysctl_dump_port_mibstats()
235 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); in ar40xx_sysctl_attach()
236 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); in ar40xx_sysctl_attach()
239 "debug", CTLFLAG_RW, &sc->sc_debug, 0, in ar40xx_sysctl_attach()
259 device_printf(sc->sc_dev, "%s: called\n", __func__); in ar40xx_detach()
261 callout_drain(&sc->sc_phy_callout); in ar40xx_detach()
265 if (sc->sc_phys.miibus[i] != NULL) in ar40xx_detach()
266 device_delete_child(dev, sc->sc_phys.miibus[i]); in ar40xx_detach()
267 if (sc->sc_phys.ifp[i] != NULL) in ar40xx_detach()
268 if_free(sc->sc_phys.ifp[i]); in ar40xx_detach()
269 free(sc->sc_phys.ifname[i], M_DEVBUF); in ar40xx_detach()
273 mtx_destroy(&sc->sc_mtx); in ar40xx_detach()
285 sc->sc_dev = dev; in ar40xx_attach()
286 mtx_init(&sc->sc_mtx, "ar40xx_switch", NULL, MTX_DEF); in ar40xx_attach()
288 psgmii_p = OF_finddevice("/soc/ess-psgmii"); in ar40xx_attach()
289 if (psgmii_p == -1) { in ar40xx_attach()
291 "%s: couldn't find /soc/ess-psgmii DT node\n", in ar40xx_attach()
297 * Get the ipq4019-mdio node here, to talk to our local PHYs in ar40xx_attach()
301 mdio_p = ofw_bus_find_compatible(root_p, "qcom,ipq4019-mdio"); in ar40xx_attach()
302 if (mdio_p == -1) { in ar40xx_attach()
303 device_printf(dev, "%s: couldn't find ipq4019-mdio DT node\n", in ar40xx_attach()
307 sc->sc_mdio_phandle = mdio_p; in ar40xx_attach()
308 sc->sc_mdio_dev = OF_device_from_xref(OF_xref_from_node(mdio_p)); in ar40xx_attach()
309 if (sc->sc_mdio_dev == NULL) { in ar40xx_attach()
311 "%s: couldn't get mdio device (mdio_p=%u)\n", in ar40xx_attach()
317 ret = OF_decode_addr(psgmii_p, 0, &sc->sc_psgmii_mem_tag, in ar40xx_attach()
318 &sc->sc_psgmii_mem_handle, in ar40xx_attach()
319 &sc->sc_psgmii_mem_size); in ar40xx_attach()
327 sc->sc_ess_mem_rid = 0; in ar40xx_attach()
328 sc->sc_ess_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in ar40xx_attach()
329 &sc->sc_ess_mem_rid, RF_ACTIVE); in ar40xx_attach()
330 if (sc->sc_ess_mem_res == NULL) { in ar40xx_attach()
335 sc->sc_ess_mem_size = (size_t) bus_get_resource_count(dev, in ar40xx_attach()
336 SYS_RES_MEMORY, sc->sc_ess_mem_rid); in ar40xx_attach()
337 if (sc->sc_ess_mem_size == 0) { in ar40xx_attach()
344 &sc->sc_config.switch_mac_mode, in ar40xx_attach()
345 sizeof(sc->sc_config.switch_mac_mode)); in ar40xx_attach()
353 &sc->sc_config.switch_cpu_bmp, in ar40xx_attach()
354 sizeof(sc->sc_config.switch_cpu_bmp)); in ar40xx_attach()
362 &sc->sc_config.switch_lan_bmp, in ar40xx_attach()
363 sizeof(sc->sc_config.switch_lan_bmp)); in ar40xx_attach()
371 &sc->sc_config.switch_wan_bmp, in ar40xx_attach()
372 sizeof(sc->sc_config.switch_wan_bmp)); in ar40xx_attach()
379 ret = clk_get_by_ofw_name(dev, 0, "ess_clk", &sc->sc_ess_clk); in ar40xx_attach()
385 ret = clk_enable(sc->sc_ess_clk); in ar40xx_attach()
392 ret = hwreset_get_by_ofw_name(dev, 0, "ess_rst", &sc->sc_ess_rst); in ar40xx_attach()
409 device_printf(sc->sc_dev, in ar40xx_attach()
415 * ESS reset - this resets both the ethernet switch in ar40xx_attach()
420 device_printf(sc->sc_dev, in ar40xx_attach()
433 device_printf(sc->sc_dev, in ar40xx_attach()
440 * Do PSGMII PHY self-test; work-around issues. in ar40xx_attach()
444 device_printf(sc->sc_dev, in ar40xx_attach()
445 "ERROR: failed to do PSGMII self-test (%d)\n", ret); in ar40xx_attach()
452 device_printf(sc->sc_dev, in ar40xx_attach()
459 sc->sc_config.switch_mac_mode); in ar40xx_attach()
490 callout_init_mtx(&sc->sc_phy_callout, &sc->sc_mtx, 0); in ar40xx_attach()
495 strlcpy(sc->sc_info.es_name, device_get_desc(dev), in ar40xx_attach()
496 sizeof(sc->sc_info.es_name)); in ar40xx_attach()
497 sc->sc_info.es_nports = AR40XX_NUM_PORTS; in ar40xx_attach()
498 sc->sc_info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q; in ar40xx_attach()
499 /* XXX TODO: double-tag / 802.1ad */ in ar40xx_attach()
500 sc->sc_info.es_nvlangroups = AR40XX_NUM_VTU_ENTRIES; in ar40xx_attach()
541 return (&sc->sc_info); in ar40xx_getinfo()
549 if (addr >= sc->sc_ess_mem_size - 1) in ar40xx_readreg()
550 return (-1); in ar40xx_readreg()
562 if (addr >= sc->sc_ess_mem_size - 1) in ar40xx_writereg()
563 return (-1); in ar40xx_writereg()
581 if (p->es_port < 0 || p->es_port > sc->sc_info.es_nports) in ar40xx_getport()
587 ar40xx_hw_get_port_pvid(sc, p->es_port, &p->es_pvid); in ar40xx_getport()
595 mii = ar40xx_phy_miiforport(sc, p->es_port); in ar40xx_getport()
599 if (p->es_port == 0) { in ar40xx_getport()
601 p->es_flags |= ETHERSWITCH_PORT_CPU; in ar40xx_getport()
602 ifmr = &p->es_ifmr; in ar40xx_getport()
603 ifmr->ifm_count = 0; in ar40xx_getport()
604 ifmr->ifm_current = ifmr->ifm_active = in ar40xx_getport()
606 ifmr->ifm_mask = 0; in ar40xx_getport()
607 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; in ar40xx_getport()
609 /* non-CPU port */ in ar40xx_getport()
610 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, in ar40xx_getport()
611 &mii->mii_media, SIOCGIFMEDIA); in ar40xx_getport()
633 if (p->es_port < 0 || p->es_port > sc->sc_info.es_nports) in ar40xx_setport()
638 ret = ar40xx_hw_set_port_pvid(sc, p->es_port, p->es_pvid); in ar40xx_setport()
643 /* XXX TODO: tag strip/unstrip, double-tag, etc */ in ar40xx_setport()
647 if (p->es_port == 0) in ar40xx_setport()
650 mii = ar40xx_phy_miiforport(sc, p->es_port); in ar40xx_setport()
654 ifp = ar40xx_phy_ifpforport(sc, p->es_port); in ar40xx_setport()
656 ifm = &mii->mii_media; in ar40xx_setport()
657 return (ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA)); in ar40xx_setport()
663 * Get the current VLAN group (per-port, ISL, dot1q) configuration.
673 if (vg->es_vlangroup > sc->sc_info.es_nvlangroups) in ar40xx_getvgroup()
676 vg->es_untagged_ports = 0; in ar40xx_getvgroup()
677 vg->es_member_ports = 0; in ar40xx_getvgroup()
678 vg->es_fid = 0; in ar40xx_getvgroup()
683 if (sc->sc_vlan.vlan != 1) { in ar40xx_getvgroup()
684 vg->es_member_ports = 0; in ar40xx_getvgroup()
685 vg->es_untagged_ports = 0; in ar40xx_getvgroup()
687 return (-1); in ar40xx_getvgroup()
691 vid = sc->sc_vlan.vlan_id[vg->es_vlangroup]; in ar40xx_getvgroup()
697 vg->es_vid = vid; in ar40xx_getvgroup()
699 ret = ar40xx_hw_vtu_get_vlan(sc, vid, &vg->es_member_ports, in ar40xx_getvgroup()
700 &vg->es_untagged_ports); in ar40xx_getvgroup()
705 vg->es_vid |= ETHERSWITCH_VID_VALID; in ar40xx_getvgroup()
712 * Set the current VLAN group (per-port, ISL, dot1q) configuration.
723 if (sc->sc_vlan.vlan == 0) in ar40xx_setvgroup()
727 vid = sc->sc_vlan.vlan_id[vg->es_vlangroup]; in ar40xx_setvgroup()
735 (vg->es_vid & ETHERSWITCH_VID_MASK))) { in ar40xx_setvgroup()
746 vid = vg->es_vid & ETHERSWITCH_VID_MASK; in ar40xx_setvgroup()
747 sc->sc_vlan.vlan_id[vg->es_vlangroup] = vid; in ar40xx_setvgroup()
754 sc->sc_vlan.vlan_id[vg->es_vlangroup] = vid | ETHERSWITCH_VID_VALID; in ar40xx_setvgroup()
757 err = ar40xx_hw_vtu_load_vlan(sc, vid, vg->es_member_ports, in ar40xx_setvgroup()
758 vg->es_untagged_ports); in ar40xx_setvgroup()
765 sc->sc_vlan.vlan_ports[vg->es_vlangroup] = vg->es_member_ports; in ar40xx_setvgroup()
766 sc->sc_vlan.vlan_untagged[vg->es_vlangroup] = vg->es_untagged_ports; in ar40xx_setvgroup()
777 ar40xx_getconf(device_t dev, etherswitch_conf_t *conf) in ar40xx_getconf() argument
785 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; in ar40xx_getconf()
786 conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; in ar40xx_getconf()
789 ret = ar40xx_hw_read_switch_mac_address(sc, &conf->switch_macaddr); in ar40xx_getconf()
791 conf->cmd |= ETHERSWITCH_CONF_SWITCH_MACADDR; in ar40xx_getconf()
802 * allow it to be set to non-dot1q.
805 ar40xx_setconf(device_t dev, etherswitch_conf_t *conf) in ar40xx_setconf() argument
810 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { in ar40xx_setconf()
812 if (conf->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) in ar40xx_setconf()
816 if (conf->cmd & ETHERSWITCH_CONF_SWITCH_MACADDR) { in ar40xx_setconf()
819 &conf->switch_macaddr); in ar40xx_setconf()
866 memset(&sc->atu.entries, 0, sizeof(sc->atu.entries)); in ar40xx_atu_fetch_table()
868 table->es_nitems = 0; in ar40xx_atu_fetch_table()
872 sc->atu.count = 0; in ar40xx_atu_fetch_table()
879 &sc->atu.entries[nitems], 1); in ar40xx_atu_fetch_table()
882 sc->atu.entries[nitems].id = nitems; in ar40xx_atu_fetch_table()
886 sc->atu.count = nitems; in ar40xx_atu_fetch_table()
887 table->es_nitems = nitems; in ar40xx_atu_fetch_table()
903 id = e->id; in ar40xx_atu_fetch_table_entry()
905 if (id > sc->atu.count) { in ar40xx_atu_fetch_table_entry()
909 memcpy(e, &sc->atu.entries[id], sizeof(*e)); in ar40xx_atu_fetch_table_entry()
929 /* MDIO interface */
962 DRIVER_MODULE(mdio, ar40xx, mdio_driver, 0, 0);
964 MODULE_DEPEND(ar40xx, mdio, 1, 1, 1);