Lines Matching +full:ether +full:- +full:link +full:- +full:active +full:- +full:low
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
39 * a 3-port store-and-forward switch connected to two independent
238 MODULE_DEPEND(cpsw, ether, 1, 1, 1);
252 { -1, 0 }
331 if ((_sc)->debug) { \
341 mtx_assert(&(sc)->rx.lock, MA_NOTOWNED); \
342 mtx_lock(&(sc)->tx.lock); \
345 #define CPSW_TX_UNLOCK(sc) mtx_unlock(&(sc)->tx.lock)
346 #define CPSW_TX_LOCK_ASSERT(sc) mtx_assert(&(sc)->tx.lock, MA_OWNED)
349 mtx_assert(&(sc)->tx.lock, MA_NOTOWNED); \
350 mtx_lock(&(sc)->rx.lock); \
353 #define CPSW_RX_UNLOCK(sc) mtx_unlock(&(sc)->rx.lock)
354 #define CPSW_RX_LOCK_ASSERT(sc) mtx_assert(&(sc)->rx.lock, MA_OWNED)
357 mtx_assert(&(_sc)->lock, MA_NOTOWNED); \
358 mtx_lock(&(_sc)->lock); \
361 #define CPSW_PORT_UNLOCK(_sc) mtx_unlock(&(_sc)->lock)
362 #define CPSW_PORT_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->lock, MA_OWNED)
367 #define cpsw_read_4(_sc, _reg) bus_read_4((_sc)->mem_res, (_reg))
369 bus_write_4((_sc)->mem_res, (_reg), (_val))
374 BUS_SPACE_PHYSADDR(sc->mem_res, slot->bd_offset)
376 bus_read_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
378 bus_write_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
380 cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot))
382 bus_write_2(sc->mem_res, slot->bd_offset + 14, val)
384 bus_read_2(sc->mem_res, slot->bd_offset + 14)
386 cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot))
387 #define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0))
389 cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET)
391 cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val))
400 uint32_t reg = queue->hdp_offset;
437 if (bd.flags & (1 << (15 - i))) {
443 if (slot->mbuf) {
444 printf(" Ether: %14D\n",
445 (char *)(slot->mbuf->m_data), " ");
447 (char *)(slot->mbuf->m_data) + 14, " ");
488 STAILQ_INIT(&sc->avail);
491 for (i = 0; i < nitems(sc->_slots); i++) {
492 slot = &sc->_slots[i];
493 slot->bd_offset = cpsw_cpdma_bd_offset(i);
494 STAILQ_INSERT_TAIL(&sc->avail, slot, next);
501 const int max_slots = nitems(sc->_slots);
509 slot = STAILQ_FIRST(&sc->avail);
512 if (bus_dmamap_create(sc->mbuf_dtag, 0, &slot->dmamap)) {
513 device_printf(sc->dev, "failed to create dmamap\n");
516 STAILQ_REMOVE_HEAD(&sc->avail, next);
517 STAILQ_INSERT_TAIL(&queue->avail, slot, next);
518 ++queue->avail_queue_len;
519 ++queue->queue_slots;
529 if (slot->dmamap) {
530 if (slot->mbuf)
531 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
532 error = bus_dmamap_destroy(sc->mbuf_dtag, slot->dmamap);
533 KASSERT(error == 0, ("Mapping still active"));
534 slot->dmamap = NULL;
536 if (slot->mbuf) {
537 m_freem(slot->mbuf);
538 slot->mbuf = NULL;
547 callout_stop(&sc->watchdog.callout);
613 if (sc->dualemac)
658 /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
665 /* Initialize active queues. */
666 slot = STAILQ_FIRST(&sc->tx.active);
668 cpsw_write_hdp_slot(sc, &sc->tx, slot);
669 slot = STAILQ_FIRST(&sc->rx.active);
671 cpsw_write_hdp_slot(sc, &sc->rx, slot);
673 cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), sc->rx.active_queue_len);
677 sc->rx.running = 1;
678 sc->tx.running = 1;
679 sc->watchdog.timer = 0;
680 callout_init(&sc->watchdog.callout, 0);
681 callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc);
700 device_set_desc(dev, "3-port Switch Ethernet Subsystem");
710 if (bus_setup_intr(sc->dev, sc->irq_res[i],
712 cpsw_intr_cb[i].cb, sc, &sc->ih_cookie[i]) != 0) {
713 return (-1);
726 if (sc->ih_cookie[i]) {
727 bus_teardown_intr(sc->dev, sc->irq_res[i],
728 sc->ih_cookie[i]);
742 /* Find any slave with phy-handle/phy_id */
743 phy = -1;
744 vlan = -1;
745 for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) {
760 phy = -1;
780 if (phy == -1)
782 sc->port[port].phy = phy;
783 sc->port[port].vlan = vlan;
796 sc->dev = dev;
797 sc->node = ofw_bus_get_node(dev);
798 getbinuptime(&sc->attach_uptime);
800 if (OF_getencprop(sc->node, "active_slave", &sc->active_slave,
801 sizeof(sc->active_slave)) <= 0) {
802 sc->active_slave = 0;
804 if (sc->active_slave > 1)
805 sc->active_slave = 1;
807 if (OF_hasprop(sc->node, "dual_emac"))
808 sc->dualemac = 1;
811 if (!sc->dualemac && i != sc->active_slave)
821 mtx_init(&sc->tx.lock, device_get_nameunit(dev),
823 mtx_init(&sc->rx.lock, device_get_nameunit(dev),
827 error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res);
834 sc->mem_rid = 0;
835 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
836 &sc->mem_rid, RF_ACTIVE);
837 if (sc->mem_res == NULL) {
838 device_printf(sc->dev, "failed to allocate memory resource\n");
851 bus_get_dma_tag(sc->dev), /* parent */
859 &sc->mbuf_dtag); /* dmatag */
867 sc->nullpad = malloc(ETHER_MIN_LEN, M_DEVBUF, M_WAITOK | M_ZERO);
872 STAILQ_INIT(&sc->rx.avail);
873 STAILQ_INIT(&sc->rx.active);
874 STAILQ_INIT(&sc->tx.avail);
875 STAILQ_INIT(&sc->tx.active);
878 if (cpsw_add_slots(sc, &sc->tx, 128) ||
879 cpsw_add_slots(sc, &sc->rx, -1)) {
885 sc->tx.queue_slots, sc->rx.queue_slots);
887 sc->tx.hdp_offset = CPSW_CPDMA_TX_HDP(0);
888 sc->rx.hdp_offset = CPSW_CPDMA_RX_HDP(0);
890 if (cpsw_intr_attach(sc) == -1) {
898 cpsw_vgroups[i].vid = -1;
906 if (!sc->dualemac && i != sc->active_slave)
908 sc->port[i].dev = device_add_child(dev, "cpsw", i);
909 if (sc->port[i].dev == NULL) {
933 callout_stop(&sc->watchdog.callout);
934 callout_drain(&sc->watchdog.callout);
941 for (i = 0; i < nitems(sc->_slots); ++i)
942 cpsw_free_slot(sc, &sc->_slots[i]);
945 if (sc->nullpad)
946 free(sc->nullpad, M_DEVBUF);
949 if (sc->mbuf_dtag) {
950 error = bus_dma_tag_destroy(sc->mbuf_dtag);
955 if (sc->mem_res != NULL)
956 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res);
957 bus_release_resources(dev, irq_res_spec, sc->irq_res);
960 mtx_destroy(&sc->rx.lock);
961 mtx_destroy(&sc->tx.lock);
999 sc->dev = dev;
1000 sc->pdev = device_get_parent(dev);
1001 sc->swsc = device_get_softc(sc->pdev);
1002 sc->unit = device_get_unit(dev);
1003 sc->phy = sc->swsc->port[sc->unit].phy;
1004 sc->vlan = sc->swsc->port[sc->unit].vlan;
1005 if (sc->swsc->dualemac && sc->vlan == -1)
1006 sc->vlan = sc->unit + 1;
1008 if (sc->unit == 0) {
1009 sc->physel = MDIOUSERPHYSEL0;
1010 sc->phyaccess = MDIOUSERACCESS0;
1012 sc->physel = MDIOUSERPHYSEL1;
1013 sc->phyaccess = MDIOUSERACCESS1;
1016 mtx_init(&sc->lock, device_get_nameunit(dev), "cpsw port lock",
1020 ifp = sc->ifp = if_alloc(IFT_ETHER);
1021 if_initname(ifp, device_get_name(sc->dev), sc->unit);
1031 if_setsendqlen(ifp, sc->swsc->tx.queue_slots);
1034 /* FIXME: For now; Go and kidnap syscon from opp-table */
1036 opp_table = OF_finddevice("/opp-table");
1037 if (opp_table == -1) {
1038 device_printf(dev, "Cant find /opp-table\n");
1043 device_printf(dev, "/opp-table doesnt have required syscon property\n");
1054 reg = SYSCON_READ_4(syscon, SCM_MAC_ID0_HI + sc->unit * 8);
1060 /* Get low part of MAC address from control module (mac_id[0|1]_lo) */
1061 reg = SYSCON_READ_4(syscon, SCM_MAC_ID0_LO + sc->unit * 8);
1065 error = mii_attach(dev, &sc->miibus, ifp, cpswp_ifmedia_upd,
1066 cpswp_ifmedia_sts, BMSR_DEFCAPMASK, sc->phy, MII_OFFSET_ANY, 0);
1072 sc->mii = device_get_softc(sc->miibus);
1075 cpsw_write_4(sc->swsc, sc->physel,
1076 MDIO_PHYSEL_LINKINTENB | (sc->phy & 0x1F));
1078 ether_ifattach(sc->ifp, mac_addr);
1079 callout_init(&sc->mii_callout, 0);
1095 CPSW_DEBUGF(sc->swsc, (""));
1097 ether_ifdetach(sc->ifp);
1101 callout_drain(&sc->mii_callout);
1104 if_free(sc->ifp);
1105 mtx_destroy(&sc->lock);
1122 if (!sc->dualemac)
1124 psc = device_get_softc(sc->port[0].dev);
1125 ifp1 = psc->ifp;
1126 psc = device_get_softc(sc->port[1].dev);
1127 ifp2 = psc->ifp;
1139 CPSW_DEBUGF(sc->swsc, (""));
1155 CPSW_DEBUGF(sc->swsc, (""));
1157 ifp = sc->ifp;
1161 getbinuptime(&sc->init_uptime);
1163 if (!sc->swsc->rx.running && !sc->swsc->tx.running) {
1165 cpsw_reset(sc->swsc);
1166 cpsw_init(sc->swsc);
1170 cpsw_write_4(sc->swsc, CPSW_SL_RX_PRI_MAP(sc->unit), 0x76543210);
1171 cpsw_write_4(sc->swsc, CPSW_PORT_P_TX_PRI_MAP(sc->unit + 1),
1173 cpsw_write_4(sc->swsc, CPSW_SL_RX_MAXLEN(sc->unit), 0x5f2);
1177 reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit));
1179 cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg);
1182 cpsw_write_4(sc->swsc, CPSW_ALE_PORTCTL(sc->unit + 1),
1186 if (sc->swsc->dualemac) {
1188 cpsw_write_4(sc->swsc, CPSW_PORT_P_VLAN(sc->unit + 1),
1189 sc->vlan & 0xfff);
1190 cpsw_ale_update_vlan_table(sc->swsc, sc->vlan,
1191 (1 << (sc->unit + 1)) | (1 << 0), /* Member list */
1192 (1 << (sc->unit + 1)) | (1 << 0), /* Untagged egress */
1193 (1 << (sc->unit + 1)) | (1 << 0), 0); /* mcast reg flood */
1196 if (cpsw_vgroups[i].vid != -1)
1198 cpsw_vgroups[i].vid = sc->vlan;
1204 mii_mediachg(sc->mii);
1205 callout_reset(&sc->mii_callout, hz, cpswp_tick, sc);
1220 if (!sc->dualemac && i != sc->active_slave)
1222 psc = device_get_softc(sc->port[i].dev);
1238 sc->rx.teardown = 1;
1241 while (sc->rx.running) {
1243 device_printf(sc->dev,
1249 if (!sc->rx.running)
1261 if (STAILQ_FIRST(&sc->tx.active) != NULL)
1264 sc->tx.teardown = 1;
1266 while (sc->tx.running && ++i < 10) {
1270 if (sc->tx.running) {
1271 device_printf(sc->dev,
1276 sc->tx.active_queue_len));
1286 ifp = sc->ifp;
1287 CPSW_DEBUGF(sc->swsc, (""));
1298 callout_stop(&sc->mii_callout);
1301 if (cpsw_ports_down(sc->swsc)) {
1302 cpsw_rx_teardown(sc->swsc);
1303 cpsw_tx_teardown(sc->swsc);
1307 reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit));
1309 cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg);
1311 if (cpsw_ports_down(sc->swsc)) {
1313 cpsw_stats_collect(sc->swsc);
1315 cpsw_reset(sc->swsc);
1316 cpsw_init(sc->swsc);
1334 if (!sc->dualemac && i != sc->active_slave)
1336 psc = device_get_softc(sc->port[i].dev);
1374 reg = cpsw_read_4(sc->swsc, CPSW_ALE_CONTROL);
1378 cpsw_write_4(sc->swsc, CPSW_ALE_CONTROL, reg);
1385 printf("All-multicast mode unimplemented\n");
1403 changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap;
1405 if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM)
1416 changed = if_getflags(ifp) ^ sc->if_flags;
1417 CPSW_DEBUGF(sc->swsc,
1427 CPSW_DEBUGF(sc->swsc,
1432 CPSW_DEBUGF(sc->swsc, ("SIOCSIFFLAGS: shutting down"));
1436 sc->if_flags = if_getflags(ifp);
1450 error = ifmedia_ioctl(ifp, ifr, &sc->mii->mii_media, command);
1468 while (--retries) {
1485 if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1492 cpsw_write_4(sc->swsc, sc->phyaccess, cmd);
1494 if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1499 r = cpsw_read_4(sc->swsc, sc->phyaccess);
1514 if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1522 cpsw_write_4(sc->swsc, sc->phyaccess, cmd);
1524 if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1539 CPSW_DEBUGF(sc->swsc, (""));
1541 reg = CPSW_SL_MACCONTROL(sc->unit);
1542 mac_control = cpsw_read_4(sc->swsc, reg);
1546 switch(IFM_SUBTYPE(sc->mii->mii_media_active)) {
1558 if (sc->mii->mii_media_active & IFM_FDX)
1561 cpsw_write_4(sc->swsc, reg, mac_control);
1578 if (sc->rx.teardown) {
1579 sc->rx.running = 0;
1580 sc->rx.teardown = 0;
1581 cpsw_write_cp(sc, &sc->rx, 0xfffffffc);
1589 next = received->m_nextpkt;
1590 received->m_nextpkt = NULL;
1591 ifp = received->m_pkthdr.rcvif;
1616 while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) {
1630 STAILQ_REMOVE_HEAD(&sc->rx.active, next);
1631 STAILQ_INSERT_TAIL(&sc->rx.avail, slot, next);
1633 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD);
1634 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
1636 m = slot->mbuf;
1637 slot->mbuf = NULL;
1642 sc->rx.running = 0;
1643 sc->rx.teardown = 0;
1647 port = (bd.flags & CPDMA_BD_PORT_MASK) - 1;
1650 psc = device_get_softc(sc->port[port].dev);
1653 m->m_data += bd.bufoff;
1654 m->m_len = bd.buflen;
1656 m->m_pkthdr.len = bd.pktlen;
1657 m->m_pkthdr.rcvif = psc->ifp;
1658 m->m_flags |= M_PKTHDR;
1663 m->m_next = NULL;
1664 m->m_nextpkt = NULL;
1667 m_adj(m0, -ETHER_CRC_LEN);
1670 if (nsegs > sc->rx.longest_chain)
1671 sc->rx.longest_chain = nsegs;
1675 if ((if_getcapenable(psc->ifp) & IFCAP_RXCSUM) != 0) {
1680 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
1681 m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
1682 m->m_pkthdr.csum_data = 0xffff;
1686 if (STAILQ_FIRST(&sc->rx.active) != NULL &&
1689 cpsw_write_hdp_slot(sc, &sc->rx,
1690 STAILQ_FIRST(&sc->rx.active));
1691 sc->rx.queue_restart++;
1696 mb_tail->m_nextpkt = m;
1698 mb_tail->m_next = m;
1703 __func__, if_name(psc->ifp));
1713 cpsw_write_cp_slot(sc, &sc->rx, last);
1714 sc->rx.queue_removes += removed;
1715 sc->rx.avail_queue_len += removed;
1716 sc->rx.active_queue_len -= removed;
1717 if (sc->rx.avail_queue_len > sc->rx.max_avail_queue_len)
1718 sc->rx.max_avail_queue_len = sc->rx.avail_queue_len;
1735 last_old_slot = STAILQ_LAST(&sc->rx.active, cpsw_slot, next);
1736 while ((slot = STAILQ_FIRST(&sc->rx.avail)) != NULL) {
1739 if (slot->mbuf == NULL) {
1740 slot->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1741 if (slot->mbuf == NULL) {
1742 device_printf(sc->dev,
1746 slot->mbuf->m_len =
1747 slot->mbuf->m_pkthdr.len =
1748 slot->mbuf->m_ext.ext_size;
1751 error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap,
1752 slot->mbuf, seg, &nsegs, BUS_DMA_NOWAIT);
1757 device_printf(sc->dev,
1760 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
1761 m_freem(slot->mbuf);
1762 slot->mbuf = NULL;
1766 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREREAD);
1773 bd.bufptr = seg->ds_addr;
1775 bd.buflen = MCLBYTES - 1;
1781 STAILQ_REMOVE_HEAD(&sc->rx.avail, next);
1782 STAILQ_INSERT_TAIL(&sc->rx.active, slot, next);
1790 /* Link new entries to hardware RX queue. */
1793 cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot);
1798 sc->rx.queue_adds += added;
1799 sc->rx.avail_queue_len -= added;
1800 sc->rx.active_queue_len += added;
1802 if (sc->rx.active_queue_len > sc->rx.max_active_queue_len)
1803 sc->rx.max_active_queue_len = sc->rx.active_queue_len;
1813 sc->swsc->tx.running == 0) {
1816 CPSW_TX_LOCK(sc->swsc);
1818 cpsw_tx_dequeue(sc->swsc);
1819 CPSW_TX_UNLOCK(sc->swsc);
1830 cpsw_write_cp(sc, &sc->tx, 0xfffffffc);
1848 last_old_slot = STAILQ_LAST(&sc->swsc->tx.active, cpsw_slot, next);
1849 while ((slot = STAILQ_FIRST(&sc->swsc->tx.avail)) != NULL) {
1850 m0 = if_dequeue(sc->ifp);
1854 slot->mbuf = m0;
1855 padlen = ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len;
1859 m_append(slot->mbuf, padlen, sc->swsc->nullpad);
1862 error = bus_dmamap_load_mbuf_sg(sc->swsc->mbuf_dtag,
1863 slot->dmamap, slot->mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
1866 (error == 0 && nsegs > sc->swsc->tx.avail_queue_len)) {
1867 bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap);
1868 m0 = m_defrag(slot->mbuf, M_NOWAIT);
1870 device_printf(sc->dev,
1872 m_freem(slot->mbuf);
1874 CPSW_DEBUGF(sc->swsc,
1876 if_sendq_prepend(sc->ifp, m0);
1878 slot->mbuf = NULL;
1882 device_printf(sc->dev,
1885 bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap);
1886 m_freem(slot->mbuf);
1887 slot->mbuf = NULL;
1891 bus_dmamap_sync(sc->swsc->mbuf_dtag, slot->dmamap,
1894 CPSW_DEBUGF(sc->swsc,
1901 /* Link from the previous descriptor. */
1903 cpsw_cpdma_write_bd_next(sc->swsc, last, slot);
1905 slot->ifp = sc->ifp;
1912 bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next);
1919 bd.pktlen = m_length(slot->mbuf, NULL);
1921 if (sc->swsc->dualemac) {
1923 bd.flags |= ((sc->unit + 1) & CPDMA_BD_PORT_MASK);
1927 cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
1928 STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
1929 STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
1930 slot = STAILQ_FIRST(&sc->swsc->tx.avail);
1935 bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next);
1947 cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
1948 STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
1949 STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
1953 if (nsegs > sc->swsc->tx.longest_chain)
1954 sc->swsc->tx.longest_chain = nsegs;
1956 BPF_MTAP(sc->ifp, m0);
1964 (cpsw_cpdma_read_bd_flags(sc->swsc, last_old_slot) &
1967 cpsw_cpdma_write_bd_next(sc->swsc, last_old_slot,
1971 cpsw_write_hdp_slot(sc->swsc, &sc->swsc->tx, first_new_slot);
1973 sc->swsc->tx.queue_adds += added;
1974 sc->swsc->tx.avail_queue_len -= added;
1975 sc->swsc->tx.active_queue_len += added;
1976 if (sc->swsc->tx.active_queue_len > sc->swsc->tx.max_active_queue_len) {
1977 sc->swsc->tx.max_active_queue_len = sc->swsc->tx.active_queue_len;
1979 CPSW_DEBUGF(sc->swsc, ("Queued %d TX packet(s)", added));
1990 slot = STAILQ_FIRST(&sc->tx.active);
1997 sc->tx.teardown = 1;
2001 (CPDMA_BD_SOP | CPDMA_BD_OWNER) && sc->tx.teardown == 0)
2004 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTWRITE);
2005 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
2006 m_freem(slot->mbuf);
2007 slot->mbuf = NULL;
2009 if (slot->ifp) {
2010 if (sc->tx.teardown == 0)
2011 if_inc_counter(slot->ifp, IFCOUNTER_OPACKETS, 1);
2013 if_inc_counter(slot->ifp, IFCOUNTER_OQDROPS, 1);
2017 while (slot != NULL && slot->mbuf == NULL) {
2018 STAILQ_REMOVE_HEAD(&sc->tx.active, next);
2019 STAILQ_INSERT_TAIL(&sc->tx.avail, slot, next);
2022 slot = STAILQ_FIRST(&sc->tx.active);
2025 cpsw_write_cp_slot(sc, &sc->tx, last_removed_slot);
2032 cpsw_write_hdp_slot(sc, &sc->tx, slot);
2033 sc->tx.queue_restart++;
2039 sc->tx.queue_removes += removed;
2040 sc->tx.active_queue_len -= removed;
2041 sc->tx.avail_queue_len += removed;
2042 if (sc->tx.avail_queue_len > sc->tx.max_avail_queue_len)
2043 sc->tx.max_avail_queue_len = sc->tx.avail_queue_len;
2047 if (sc->tx.teardown && STAILQ_EMPTY(&sc->tx.active)) {
2049 sc->tx.teardown = 0;
2050 sc->tx.running = 0;
2077 next = received->m_nextpkt;
2078 received->m_nextpkt = NULL;
2079 ifp = received->m_pkthdr.rcvif;
2094 device_printf(sc->dev,
2098 device_printf(sc->dev, "CPSW_CPDMA_DMA_INTSTAT_MASKED=0x%x\n", intstat);
2100 device_printf(sc->dev, "CPSW_CPDMA_DMASTATUS=0x%x\n", dmastat);
2130 cpsw_dump_queue(sc, &sc->tx.active);
2152 cpsw_dump_queue(sc, &sc->rx.active);
2203 mii_tick(sc->mii);
2204 if (sc->media_status != sc->mii->mii_media.ifm_media) {
2206 sc->mii->mii_media.ifm_media);
2207 cpswp_ifmedia_upd(sc->ifp);
2211 callout_reset(&sc->mii_callout, hz, cpswp_tick, sc);
2221 CPSW_DEBUGF(sc->swsc, (""));
2224 mii = sc->mii;
2227 ifmr->ifm_active = mii->mii_media_active;
2228 ifmr->ifm_status = mii->mii_media_status;
2238 CPSW_DEBUGF(sc->swsc, (""));
2240 mii_mediachg(sc->mii);
2241 sc->media_status = sc->mii->mii_media.ifm_media;
2254 device_printf(sc->dev, "watchdog timeout\n");
2259 cpsw_dump_queue(sc, &sc->tx.active);
2261 if (!sc->dualemac && i != sc->active_slave)
2263 psc = device_get_softc(sc->port[i].dev);
2277 if (sc->tx.active_queue_len == 0 || !sc->tx.running) {
2278 sc->watchdog.timer = 0; /* Nothing to do. */
2279 } else if (sc->tx.queue_removes > sc->tx.queue_removes_at_last_tick) {
2280 sc->watchdog.timer = 0; /* Stuff done while we weren't looking. */
2282 sc->watchdog.timer = 0; /* We just did something. */
2285 ++sc->watchdog.timer;
2286 if (sc->watchdog.timer > 5) {
2287 sc->watchdog.timer = 0;
2288 ++sc->watchdog.resets;
2292 sc->tx.queue_removes_at_last_tick = sc->tx.queue_removes;
2296 callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc);
2329 /* First four entries are link address and broadcast. */
2334 ALE_MCAST(ale_entry) == 1) { /* MCast link addr */
2345 int free_index = -1, matching_index = -1, i;
2373 if (vlan != -1)
2440 if (sc->swsc->dualemac)
2441 portmask = 1 << (sc->unit + 1) | 1 << 0;
2445 cpsw_ale_mc_entry_set(sc->swsc, portmask, sc->vlan, LLADDR(sdl));
2456 if (sc->swsc->dualemac) {
2457 ale_type = ALE_TYPE_VLAN_ADDR << 28 | sc->vlan << 16;
2458 portmask = 1 << (sc->unit + 1) | 1 << 0;
2469 mac = LLADDR((struct sockaddr_dl *)if_getifaddr(sc->ifp)->ifa_addr);
2473 cpsw_ale_write_entry(sc->swsc, 0 + 2 * sc->unit, ale_entry);
2476 cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_HI(sc->unit + 1),
2478 cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_LO(sc->unit + 1),
2486 cpsw_ale_write_entry(sc->swsc, 1 + 2 * sc->unit, ale_entry);
2491 cpsw_ale_remove_all_mc_entries(sc->swsc);
2494 if_foreach_llmaddr(sc->ifp, cpswp_set_maddr, sc);
2506 free_index = matching_index = -1;
2523 return (-1);
2553 (intmax_t)sc->shadow_stats[i], r,
2554 (intmax_t)sc->shadow_stats[i] + r));
2570 sc->shadow_stats[i] += r;
2584 stat = &cpsw_stat_sysctls[oidp->oid_number];
2585 result = sc->shadow_stats[oidp->oid_number];
2586 result += cpsw_read_4(sc, CPSW_STATS_OFFSET + stat->reg);
2599 bintime_sub(&t, &sc->attach_uptime);
2612 error = sysctl_handle_int(oidp, &sc->coal_us, 0, req);
2613 if (error != 0 || req->newptr == NULL)
2618 if (sc->coal_us == 0) {
2626 if (sc->coal_us > CPSW_WR_C_IMAX_US_MAX)
2627 sc->coal_us = CPSW_WR_C_IMAX_US_MAX;
2628 if (sc->coal_us < CPSW_WR_C_IMAX_US_MIN)
2629 sc->coal_us = CPSW_WR_C_IMAX_US_MIN;
2630 intr_per_ms = 1000 / sc->coal_us;
2658 sc = device_get_softc(swsc->port[arg2].dev);
2659 if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) {
2661 bintime_sub(&t, &sc->init_uptime);
2676 CTLFLAG_RD, &queue->queue_slots, 0,
2679 CTLFLAG_RD, &queue->active_queue_len, 0,
2682 CTLFLAG_RD, &queue->max_active_queue_len, 0,
2685 CTLFLAG_RD, &queue->avail_queue_len, 0,
2689 CTLFLAG_RD, &queue->max_avail_queue_len, 0,
2692 CTLFLAG_RD, &queue->queue_adds, 0,
2695 CTLFLAG_RD, &queue->queue_removes, 0,
2698 CTLFLAG_RD, &queue->queue_restart, 0,
2701 CTLFLAG_RD, &queue->longest_chain, 0,
2713 CTLFLAG_RD, &sc->watchdog.resets, 0,
2727 ctx = device_get_sysctl_ctx(sc->dev);
2728 parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
2731 CTLFLAG_RW, &sc->debug, 0, "Enable switch debug messages");
2747 if (!sc->dualemac && i != sc->active_slave)
2777 cpsw_add_queue_sysctls(ctx, node, &sc->tx);
2781 cpsw_add_queue_sysctls(ctx, node, &sc->rx);
2811 if (p->es_port < 0 || p->es_port > CPSW_PORTS)
2816 if (p->es_port == CPSW_CPU_PORT) {
2817 p->es_flags |= ETHERSWITCH_PORT_CPU;
2818 ifmr = &p->es_ifmr;
2819 ifmr->ifm_current = ifmr->ifm_active =
2821 ifmr->ifm_mask = 0;
2822 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
2823 ifmr->ifm_count = 0;
2825 psc = device_get_softc(sc->port[p->es_port - 1].dev);
2826 err = ifmedia_ioctl(psc->ifp, &p->es_ifr,
2827 &psc->mii->mii_media, SIOCGIFMEDIA);
2829 reg = cpsw_read_4(sc, CPSW_PORT_P_VLAN(p->es_port));
2830 p->es_pvid = reg & ETHERSWITCH_VID_MASK;
2832 reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port));
2834 p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED;
2836 p->es_flags |= ETHERSWITCH_PORT_INGRESS;
2849 if (p->es_port < 0 || p->es_port > CPSW_PORTS)
2853 if (p->es_pvid != 0) {
2854 cpsw_write_4(sc, CPSW_PORT_P_VLAN(p->es_port),
2855 p->es_pvid & ETHERSWITCH_VID_MASK);
2858 reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port));
2859 if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED)
2863 if (p->es_flags & ETHERSWITCH_PORT_INGRESS)
2867 cpsw_write_4(sc, CPSW_ALE_PORTCTL(p->es_port), reg);
2870 if (p->es_port == CPSW_CPU_PORT)
2873 psc = device_get_softc(sc->port[p->es_port - 1].dev);
2874 ifm = &psc->mii->mii_media;
2876 return (ifmedia_ioctl(psc->ifp, &p->es_ifr, ifm, SIOCSIFMEDIA));
2884 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
2885 conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
2899 if (vg->es_vlangroup >= CPSW_VLANS)
2902 vg->es_vid = 0;
2903 vid = cpsw_vgroups[vg->es_vlangroup].vid;
2904 if (vid == -1)
2914 vg->es_fid = 0;
2915 vg->es_vid = ALE_VLAN(ale_entry) | ETHERSWITCH_VID_VALID;
2916 vg->es_member_ports = ALE_VLAN_MEMBERS(ale_entry);
2917 vg->es_untagged_ports = ALE_VLAN_UNTAG(ale_entry);
2951 if (vg->es_vlangroup != i && cpsw_vgroups[i].vid == vg->es_vid)
2955 if (vg->es_vid == 0) {
2956 if (cpsw_vgroups[vg->es_vlangroup].vid == -1)
2958 cpsw_remove_vlan(sc, cpsw_vgroups[vg->es_vlangroup].vid);
2959 cpsw_vgroups[vg->es_vlangroup].vid = -1;
2960 vg->es_untagged_ports = 0;
2961 vg->es_member_ports = 0;
2962 vg->es_vid = 0;
2966 vg->es_vid &= ETHERSWITCH_VID_MASK;
2967 vg->es_member_ports &= CPSW_PORTS_MASK;
2968 vg->es_untagged_ports &= CPSW_PORTS_MASK;
2970 if (cpsw_vgroups[vg->es_vlangroup].vid != -1 &&
2971 cpsw_vgroups[vg->es_vlangroup].vid != vg->es_vid)
2974 cpsw_vgroups[vg->es_vlangroup].vid = vg->es_vid;
2975 cpsw_ale_update_vlan_table(sc, vg->es_vid, vg->es_member_ports,
2976 vg->es_untagged_ports, vg->es_member_ports, 0);