Lines Matching +full:led +full:- +full:pattern
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2011-2012 Stefan Bethke.
74 /* Map ETHERSWITCH_PORT_LED_* to Atheros pattern codes */
90 static int arswitch_setled(struct arswitch_softc *sc, int phy, int led,
102 sc->page = -1;
106 sc->chip_rev = (id & AR8X16_MASK_CTRL_REV_MASK);
107 sc->chip_ver = (id & AR8X16_MASK_CTRL_VER_MASK) >> AR8X16_MASK_CTRL_VER_SHIFT;
111 sc->sc_switchtype = AR8X16_SWITCH_AR8216;
115 sc->sc_switchtype = AR8X16_SWITCH_AR8226;
117 /* 0x0301 - AR8236 */
121 sc->sc_switchtype = AR8X16_SWITCH_AR8316;
126 sc->sc_switchtype = AR8X16_SWITCH_AR8327;
127 sc->mii_lo_first = 1;
137 chipname, sc->chip_ver, sc->chip_rev);
150 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->sc_dev));
151 for (phy = 0; phy < sc->numphys; phy++) {
152 sc->ifp[phy] = if_alloc(IFT_ETHER);
153 if_setsoftc(sc->ifp[phy], sc);
154 if_setflagbits(sc->ifp[phy], IFF_UP | IFF_BROADCAST |
156 sc->ifname[phy] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
157 bcopy(name, sc->ifname[phy], strlen(name)+1);
158 if_initname(sc->ifp[phy], sc->ifname[phy],
160 err = mii_attach(sc->sc_dev, &sc->miibus[phy], sc->ifp[phy],
164 DPRINTF(sc->sc_dev, "%s attached to pseudo interface %s\n",
165 device_get_nameunit(sc->miibus[phy]),
166 sc->ifp[phy]->if_xname);
169 device_printf(sc->sc_dev,
176 int led;
179 for (led = 0; led < 3; led++) {
181 arswitch_portforphy(phy), led+1);
182 sc->dev_led[phy][led].sc = sc;
183 sc->dev_led[phy][led].phy = phy;
184 sc->dev_led[phy][led].lednum = led;
201 return (-1);
211 if ((mode & sc->info.es_vlan_caps) != mode)
216 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
219 sc->vlan_mode = ETHERSWITCH_VLAN_PORT;
222 sc->vlan_mode = 0;
226 sc->hal.arswitch_vlan_init_hw(sc);
235 /* Port0 - CPU */
237 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_STS(0),
245 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_CTRL(0),
246 arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(0)) &
250 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_STS(port),
252 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_CTRL(port),
253 arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(port)) &
265 ret = arswitch_waitreg(sc->sc_dev,
288 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
291 arswitch_writereg(sc->sc_dev,
321 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
324 arswitch_writereg(sc->sc_dev,
353 arswitch_writereg(sc->sc_dev,
355 arswitch_writereg(sc->sc_dev,
357 arswitch_writereg(sc->sc_dev,
370 val = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU);
372 arswitch_writereg(sc->sc_dev, AR8216_REG_ATU, val);
378 ret0 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU);
379 ret1 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU_DATA);
380 ret2 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU_CTRL2);
384 return (-1);
387 e->es_macaddr[5] = MS(ret0, AR8216_ATU_ADDR5);
388 e->es_macaddr[4] = MS(ret0, AR8216_ATU_ADDR4);
389 e->es_macaddr[3] = MS(ret1, AR8216_ATU_ADDR3);
390 e->es_macaddr[2] = MS(ret1, AR8216_ATU_ADDR2);
391 e->es_macaddr[1] = MS(ret1, AR8216_ATU_ADDR1);
392 e->es_macaddr[0] = MS(ret1, AR8216_ATU_ADDR0);
395 e->es_portmask = MS(ret2, AR8216_ATU_CTRL2_DESPORT);
401 e->es_macaddr, ":", e->es_portmask);
404 return (-1);
406 return (-1);
423 * + ARP_EN - enable "acknowledgement" of ARP frames - they are
425 * + LEARN_CHANGE_EN - hash table violations when learning MAC addresses
428 * + AGE_EN - enable address table aging
429 * + AGE_TIME - set to 5 minutes
437 ret = arswitch_writereg(sc->sc_dev,
442 device_printf(sc->sc_dev, "%s: writereg failed\n", __func__);
464 ret0 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR0);
465 ret1 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR1);
501 /* sc->sc_switchtype is already decided in arswitch_probe() */
502 sc->sc_dev = dev;
503 mtx_init(&sc->sc_mtx, "arswitch", NULL, MTX_DEF);
504 sc->page = -1;
505 strlcpy(sc->info.es_name, device_get_desc(dev),
506 sizeof(sc->info.es_name));
509 ctx = device_get_sysctl_ctx(sc->sc_dev);
510 tree = device_get_sysctl_tree(sc->sc_dev);
512 "debug", CTLFLAG_RW, &sc->sc_debug, 0,
517 sc->atu.entries = malloc(sizeof(etherswitch_atu_entry_t) * 128,
519 if (sc->atu.entries == NULL) {
520 device_printf(sc->sc_dev, "%s: failed to allocate ATU table\n",
524 sc->atu.count = 0;
525 sc->atu.size = 128;
528 sc->hal.arswitch_port_init = ar8xxx_port_init;
529 sc->hal.arswitch_port_vlan_setup = ar8xxx_port_vlan_setup;
530 sc->hal.arswitch_port_vlan_get = ar8xxx_port_vlan_get;
531 sc->hal.arswitch_vlan_init_hw = ar8xxx_reset_vlans;
532 sc->hal.arswitch_hw_get_switch_macaddr = ar8xxx_hw_get_switch_macaddr;
533 sc->hal.arswitch_hw_set_switch_macaddr = ar8xxx_hw_set_switch_macaddr;
535 sc->hal.arswitch_vlan_getvgroup = ar8xxx_getvgroup;
536 sc->hal.arswitch_vlan_setvgroup = ar8xxx_setvgroup;
538 sc->hal.arswitch_vlan_get_pvid = ar8xxx_get_pvid;
539 sc->hal.arswitch_vlan_set_pvid = ar8xxx_set_pvid;
541 sc->hal.arswitch_get_dot1q_vlan = ar8xxx_get_dot1q_vlan;
542 sc->hal.arswitch_set_dot1q_vlan = ar8xxx_set_dot1q_vlan;
543 sc->hal.arswitch_flush_dot1q_vlan = ar8xxx_flush_dot1q_vlan;
544 sc->hal.arswitch_purge_dot1q_vlan = ar8xxx_purge_dot1q_vlan;
545 sc->hal.arswitch_get_port_vlan = ar8xxx_get_port_vlan;
546 sc->hal.arswitch_set_port_vlan = ar8xxx_set_port_vlan;
548 sc->hal.arswitch_atu_flush = ar8xxx_atu_flush;
549 sc->hal.arswitch_atu_flush_port = ar8xxx_atu_flush_port;
550 sc->hal.arswitch_atu_learn_default = ar8xxx_atu_learn_default;
551 sc->hal.arswitch_atu_fetch_table = ar8xxx_atu_fetch_table;
553 sc->hal.arswitch_phy_read = arswitch_readphy_internal;
554 sc->hal.arswitch_phy_write = arswitch_writephy_internal;
569 "%s: unknown switch (%d)?\n", __func__, sc->sc_switchtype);
574 sc->info.es_nports = 5; /* XXX technically 6, but 6th not used */
577 sc->numphys = 4;
578 sc->phy4cpu = 1;
579 sc->is_rgmii = 1;
580 sc->is_gmii = 0;
581 sc->is_mii = 0;
584 "numphys", &sc->numphys);
586 "phy4cpu", &sc->phy4cpu);
588 "is_rgmii", &sc->is_rgmii);
590 "is_gmii", &sc->is_gmii);
592 "is_mii", &sc->is_mii);
594 if (sc->numphys > AR8X16_NUM_PHYS)
595 sc->numphys = AR8X16_NUM_PHYS;
604 err = sc->hal.arswitch_hw_setup(sc);
611 err = sc->hal.arswitch_hw_global_setup(sc);
622 err = sc->hal.arswitch_atu_learn_default(sc);
630 for (port = 0; port <= sc->numphys; port++) {
631 sc->hal.arswitch_port_init(sc, port);
656 callout_init_mtx(&sc->callout_tick, &sc->sc_mtx, 0);
671 callout_drain(&sc->callout_tick);
677 for (i=0; i < sc->numphys; i++) {
678 if (sc->ifp[i] != NULL)
679 if_free(sc->ifp[i]);
680 free(sc->ifname[i], M_DEVBUF);
683 free(sc->atu.entries, M_DEVBUF);
685 mtx_destroy(&sc->sc_mtx);
703 int phy = port-1;
705 if (phy < 0 || phy >= sc->numphys)
707 return (device_get_softc(sc->miibus[phy]));
713 int phy = port-1;
715 if (phy < 0 || phy >= sc->numphys)
717 return (sc->ifp[phy]);
774 for (i = 0; i < sc->numphys; i++) {
775 if (sc->miibus[i] == NULL)
777 mii = device_get_softc(sc->miibus[i]);
778 /* XXX This would be nice to have abstracted out to be per-chip */
781 portstatus = arswitch_readreg(sc->sc_dev,
784 portstatus = arswitch_readreg(sc->sc_dev,
798 if ((mii->mii_media_status & IFM_ACTIVE) == 0 &&
800 device_printf(sc->sc_dev, "%s: port %d: port -> UP\n",
806 * and maybe if a port goes up->down?
808 if ((mii->mii_media_status & IFM_ACTIVE) != 0 &&
810 device_printf(sc->sc_dev, "%s: port %d: port -> DOWN\n",
815 arswitch_update_ifmedia(portstatus, &mii->mii_media_status,
816 &mii->mii_media_active);
817 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
818 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) !=
819 miisc->mii_inst)
825 /* If a port went from down->up, flush the ATU */
827 sc->hal.arswitch_atu_flush(sc);
836 callout_reset(&sc->callout_tick, hz, arswitch_tick, sc);
862 return (&sc->info);
873 sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
876 reg = arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(p->es_port));
878 p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG;
881 p->es_flags |= ETHERSWITCH_PORT_ADDTAG;
883 p->es_flags |= ETHERSWITCH_PORT_STRIPTAG;
908 if (p->es_port < 0 || p->es_port > sc->info.es_nports)
911 err = sc->hal.arswitch_port_vlan_get(sc, p);
915 mii = arswitch_miiforport(sc, p->es_port);
916 if (arswitch_is_cpuport(sc, p->es_port)) {
919 p->es_flags |= ETHERSWITCH_PORT_CPU;
920 ifmr = &p->es_ifmr;
921 ifmr->ifm_count = 0;
922 ifmr->ifm_current = ifmr->ifm_active =
924 ifmr->ifm_mask = 0;
925 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
927 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr,
928 &mii->mii_media, SIOCGIFMEDIA);
935 if (!arswitch_is_cpuport(sc, p->es_port) &&
937 int led;
938 p->es_nleds = 3;
940 for (led = 0; led < p->es_nleds; led++)
945 /* Find the right style enum for our pattern */
947 ar8327_led_mapping[p->es_port-1][led].reg);
948 val = (val>>ar8327_led_mapping[p->es_port-1][led].shift)&0x03;
959 p->es_led[led] = style;
963 p->es_nleds = 0;
978 if (p->es_pvid != 0)
979 sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid);
982 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG &&
983 p->es_flags & ETHERSWITCH_PORT_STRIPTAG) {
989 if (p->es_flags & ETHERSWITCH_PORT_DOUBLE_TAG)
991 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG)
994 if (p->es_flags & ETHERSWITCH_PORT_STRIPTAG)
998 err = arswitch_modifyreg(sc->sc_dev,
999 AR8X16_REG_PORT_CTRL(p->es_port),
1017 if (p->es_port < 0 || p->es_port > sc->info.es_nports)
1021 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
1022 err = sc->hal.arswitch_port_vlan_setup(sc, p);
1027 /* Do not allow media or led changes on CPU port. */
1028 if (arswitch_is_cpuport(sc, p->es_port))
1036 err = arswitch_setled(sc, p->es_port-1, i, p->es_led[i]);
1042 mii = arswitch_miiforport(sc, p->es_port);
1046 ifp = arswitch_ifpforport(sc, p->es_port);
1048 ifm = &mii->mii_media;
1049 return (ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA));
1053 arswitch_setled(struct arswitch_softc *sc, int phy, int led, int style)
1058 if (phy < 0 || phy > sc->numphys)
1066 shift = ar8327_led_mapping[phy][led].shift;
1067 err = (arswitch_modifyreg(sc->sc_dev,
1068 ar8327_led_mapping[phy][led].reg,
1106 ifmr->ifm_active = mii->mii_media_active;
1107 ifmr->ifm_status = mii->mii_media_status;
1119 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
1120 conf->vlan_mode = sc->vlan_mode;
1123 ret = sc->hal.arswitch_hw_get_switch_macaddr(sc,
1124 &conf->switch_macaddr);
1126 conf->cmd |= ETHERSWITCH_CONF_SWITCH_MACADDR;
1141 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) {
1142 err = arswitch_set_vlan_mode(sc, conf->vlan_mode);
1160 err = sc->hal.arswitch_atu_flush(sc);
1162 sc->atu.count = 0;
1175 err = sc->hal.arswitch_atu_flush_port(sc, port);
1177 sc->atu.count = 0;
1193 err = sc->hal.arswitch_atu_fetch_table(sc, NULL, 0);
1195 /* fetch - ideally yes we'd fetch into a separate table then switch */
1196 while (err == 0 && nitems < sc->atu.size) {
1197 err = sc->hal.arswitch_atu_fetch_table(sc,
1198 &sc->atu.entries[nitems], 1);
1200 sc->atu.entries[nitems].id = nitems;
1204 sc->atu.count = nitems;
1207 table->es_nitems = nitems;
1219 id = e->id;
1222 if (id > sc->atu.count) {
1227 memcpy(e, &sc->atu.entries[id], sizeof(*e));
1237 return (sc->hal.arswitch_vlan_getvgroup(sc, e));
1245 return (sc->hal.arswitch_vlan_setvgroup(sc, e));
1253 return (sc->hal.arswitch_phy_read(dev, phy, reg));
1261 return (sc->hal.arswitch_phy_write(dev, phy, reg, val));