Lines Matching +full:v +full:- +full:blanking

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Copyright (c) 2001-2003 Thomas Moestl
6 * Copyright (c) 2007-2009 Marius Strobl <marius@FreeBSD.org>
30 * from: NetBSD: gem.c,v 1.21 2002/06/01 23:50:58 lukem Exp
31 * from: FreeBSD: if_gem.c 182060 2008-08-23 15:03:26Z marius
108 CTASSERT((offsetof(struct cas_control_data, m) & ((a) - 1)) == 0)
140 static int cas_intr(void *v);
187 uint32_t v; in cas_attach() local
190 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); in cas_attach()
192 if_initname(ifp, device_get_name(sc->sc_dev), in cas_attach()
193 device_get_unit(sc->sc_dev)); in cas_attach()
201 callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0); in cas_attach()
202 callout_init_mtx(&sc->sc_rx_ch, &sc->sc_mtx, 0); in cas_attach()
204 NET_TASK_INIT(&sc->sc_intr_task, 0, cas_intr_task, sc); in cas_attach()
205 TASK_INIT(&sc->sc_tx_task, 1, cas_tx_task, ifp); in cas_attach()
206 sc->sc_tq = taskqueue_create_fast("cas_taskq", M_WAITOK, in cas_attach()
207 taskqueue_thread_enqueue, &sc->sc_tq); in cas_attach()
208 error = taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", in cas_attach()
209 device_get_nameunit(sc->sc_dev)); in cas_attach()
211 device_printf(sc->sc_dev, "could not start threads\n"); in cas_attach()
218 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, in cas_attach()
221 &sc->sc_pdmatag); in cas_attach()
225 error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0, in cas_attach()
227 CAS_PAGE_SIZE, 1, CAS_PAGE_SIZE, 0, NULL, NULL, &sc->sc_rdmatag); in cas_attach()
231 error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0, in cas_attach()
234 BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag); in cas_attach()
238 error = bus_dma_tag_create(sc->sc_pdmatag, CAS_TX_DESC_ALIGN, 0, in cas_attach()
242 NULL, NULL, &sc->sc_cdmatag); in cas_attach()
250 if ((error = bus_dmamem_alloc(sc->sc_cdmatag, in cas_attach()
251 (void **)&sc->sc_control_data, in cas_attach()
253 &sc->sc_cddmamap)) != 0) { in cas_attach()
254 device_printf(sc->sc_dev, in cas_attach()
259 sc->sc_cddma = 0; in cas_attach()
260 if ((error = bus_dmamap_load(sc->sc_cdmatag, sc->sc_cddmamap, in cas_attach()
261 sc->sc_control_data, sizeof(struct cas_control_data), in cas_attach()
262 cas_cddma_callback, sc, 0)) != 0 || sc->sc_cddma == 0) { in cas_attach()
263 device_printf(sc->sc_dev, in cas_attach()
272 STAILQ_INIT(&sc->sc_txfreeq); in cas_attach()
273 STAILQ_INIT(&sc->sc_txdirtyq); in cas_attach()
280 txs = &sc->sc_txsoft[i]; in cas_attach()
281 txs->txs_mbuf = NULL; in cas_attach()
282 txs->txs_ndescs = 0; in cas_attach()
283 if ((error = bus_dmamap_create(sc->sc_tdmatag, 0, in cas_attach()
284 &txs->txs_dmamap)) != 0) { in cas_attach()
285 device_printf(sc->sc_dev, in cas_attach()
290 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in cas_attach()
298 if ((error = bus_dmamem_alloc(sc->sc_rdmatag, in cas_attach()
299 &sc->sc_rxdsoft[i].rxds_buf, BUS_DMA_WAITOK, in cas_attach()
300 &sc->sc_rxdsoft[i].rxds_dmamap)) != 0) { in cas_attach()
301 device_printf(sc->sc_dev, in cas_attach()
307 sc->sc_rxdptr = i; in cas_attach()
308 sc->sc_rxdsoft[i].rxds_paddr = 0; in cas_attach()
309 if ((error = bus_dmamap_load(sc->sc_rdmatag, in cas_attach()
310 sc->sc_rxdsoft[i].rxds_dmamap, sc->sc_rxdsoft[i].rxds_buf, in cas_attach()
312 sc->sc_rxdsoft[i].rxds_paddr == 0) { in cas_attach()
313 device_printf(sc->sc_dev, in cas_attach()
320 if ((sc->sc_flags & CAS_SERDES) == 0) { in cas_attach()
329 v = CAS_READ_4(sc, CAS_MIF_CONF); in cas_attach()
330 if ((v & CAS_MIF_CONF_MDI1) != 0) { in cas_attach()
331 v |= CAS_MIF_CONF_PHY_SELECT; in cas_attach()
332 CAS_WRITE_4(sc, CAS_MIF_CONF, v); in cas_attach()
336 if (sc->sc_variant == CAS_SATURN) { in cas_attach()
345 error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, in cas_attach()
352 if (error != 0 && (v & CAS_MIF_CONF_MDI0) != 0) { in cas_attach()
353 v &= ~CAS_MIF_CONF_PHY_SELECT; in cas_attach()
354 CAS_WRITE_4(sc, CAS_MIF_CONF, v); in cas_attach()
358 if (sc->sc_variant == CAS_SATURN) { in cas_attach()
367 error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, in cas_attach()
378 if (sc->sc_variant == CAS_SATURN) { in cas_attach()
389 error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, in cas_attach()
394 device_printf(sc->sc_dev, "attaching PHYs failed\n"); in cas_attach()
397 sc->sc_mii = device_get_softc(sc->sc_miibus); in cas_attach()
406 v = CAS_READ_4(sc, CAS_TX_FIFO_SIZE); in cas_attach()
407 device_printf(sc->sc_dev, "%ukB RX FIFO, %ukB TX FIFO\n", in cas_attach()
408 CAS_RX_FIFO_SIZE / 1024, v / 16); in cas_attach()
411 ether_ifattach(ifp, sc->sc_enaddr); in cas_attach()
418 if ((sc->sc_flags & CAS_NO_CSUM) == 0) { in cas_attach()
432 if (sc->sc_rxdsoft[i].rxds_paddr != 0) in cas_attach()
433 bus_dmamap_unload(sc->sc_rdmatag, in cas_attach()
434 sc->sc_rxdsoft[i].rxds_dmamap); in cas_attach()
437 if (sc->sc_rxdsoft[i].rxds_buf != NULL) in cas_attach()
438 bus_dmamem_free(sc->sc_rdmatag, in cas_attach()
439 sc->sc_rxdsoft[i].rxds_buf, in cas_attach()
440 sc->sc_rxdsoft[i].rxds_dmamap); in cas_attach()
443 if (sc->sc_txsoft[i].txs_dmamap != NULL) in cas_attach()
444 bus_dmamap_destroy(sc->sc_tdmatag, in cas_attach()
445 sc->sc_txsoft[i].txs_dmamap); in cas_attach()
446 bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cddmamap); in cas_attach()
448 bus_dmamem_free(sc->sc_cdmatag, sc->sc_control_data, in cas_attach()
449 sc->sc_cddmamap); in cas_attach()
451 bus_dma_tag_destroy(sc->sc_cdmatag); in cas_attach()
453 bus_dma_tag_destroy(sc->sc_tdmatag); in cas_attach()
455 bus_dma_tag_destroy(sc->sc_rdmatag); in cas_attach()
457 bus_dma_tag_destroy(sc->sc_pdmatag); in cas_attach()
459 taskqueue_free(sc->sc_tq); in cas_attach()
467 if_t ifp = sc->sc_ifp; in cas_detach()
474 callout_drain(&sc->sc_tick_ch); in cas_detach()
475 callout_drain(&sc->sc_rx_ch); in cas_detach()
476 taskqueue_drain(sc->sc_tq, &sc->sc_intr_task); in cas_detach()
477 taskqueue_drain(sc->sc_tq, &sc->sc_tx_task); in cas_detach()
479 taskqueue_free(sc->sc_tq); in cas_detach()
480 device_delete_child(sc->sc_dev, sc->sc_miibus); in cas_detach()
483 if (sc->sc_rxdsoft[i].rxds_dmamap != NULL) in cas_detach()
484 bus_dmamap_sync(sc->sc_rdmatag, in cas_detach()
485 sc->sc_rxdsoft[i].rxds_dmamap, in cas_detach()
488 if (sc->sc_rxdsoft[i].rxds_paddr != 0) in cas_detach()
489 bus_dmamap_unload(sc->sc_rdmatag, in cas_detach()
490 sc->sc_rxdsoft[i].rxds_dmamap); in cas_detach()
492 if (sc->sc_rxdsoft[i].rxds_buf != NULL) in cas_detach()
493 bus_dmamem_free(sc->sc_rdmatag, in cas_detach()
494 sc->sc_rxdsoft[i].rxds_buf, in cas_detach()
495 sc->sc_rxdsoft[i].rxds_dmamap); in cas_detach()
497 if (sc->sc_txsoft[i].txs_dmamap != NULL) in cas_detach()
498 bus_dmamap_destroy(sc->sc_tdmatag, in cas_detach()
499 sc->sc_txsoft[i].txs_dmamap); in cas_detach()
501 bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cddmamap); in cas_detach()
502 bus_dmamem_free(sc->sc_cdmatag, sc->sc_control_data, in cas_detach()
503 sc->sc_cddmamap); in cas_detach()
504 bus_dma_tag_destroy(sc->sc_cdmatag); in cas_detach()
505 bus_dma_tag_destroy(sc->sc_tdmatag); in cas_detach()
506 bus_dma_tag_destroy(sc->sc_rdmatag); in cas_detach()
507 bus_dma_tag_destroy(sc->sc_pdmatag); in cas_detach()
513 if_t ifp = sc->sc_ifp; in cas_suspend()
523 if_t ifp = sc->sc_ifp; in cas_resume()
528 * after power-on. in cas_resume()
530 sc->sc_flags &= ~CAS_INITED; in cas_resume()
546 pktlen = m->m_pkthdr.len; in cas_rxcksum()
550 if (eh->ether_type != htons(ETHERTYPE_IP)) in cas_rxcksum()
553 if (ip->ip_v != IPVERSION) in cas_rxcksum()
556 hlen = ip->ip_hl << 2; in cas_rxcksum()
557 pktlen -= sizeof(struct ether_header); in cas_rxcksum()
560 if (ntohs(ip->ip_len) < hlen) in cas_rxcksum()
562 if (ntohs(ip->ip_len) != pktlen) in cas_rxcksum()
564 if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) in cas_rxcksum()
567 switch (ip->ip_p) { in cas_rxcksum()
576 if (uh->uh_sum == 0) in cas_rxcksum()
585 len = hlen - sizeof(struct ip); in cas_rxcksum()
588 for (; len > 0; len -= sizeof(uint16_t), opts++) { in cas_rxcksum()
589 temp32 = cksum - *opts; in cas_rxcksum()
594 m->m_pkthdr.csum_flags |= CSUM_DATA_VALID; in cas_rxcksum()
595 m->m_pkthdr.csum_data = cksum; in cas_rxcksum()
607 sc->sc_cddma = segs[0].ds_addr; in cas_cddma_callback()
619 sc->sc_rxdsoft[sc->sc_rxdptr].rxds_paddr = segs[0].ds_addr; in cas_rxdma_callback()
626 if_t ifp = sc->sc_ifp; in cas_tick()
627 uint32_t v; in cas_tick() local
637 v = CAS_READ_4(sc, CAS_MAC_EXCESS_COLL_CNT) + in cas_tick()
639 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, v); in cas_tick()
640 if_inc_counter(ifp, IFCOUNTER_OERRORS, v); in cas_tick()
659 mii_tick(sc->sc_mii); in cas_tick()
661 if (sc->sc_txfree != CAS_MAXTXFREE) in cas_tick()
666 callout_reset(&sc->sc_tick_ch, hz, cas_tick, sc); in cas_tick()
675 for (i = CAS_TRIES; i--; DELAY(100)) { in cas_bitwait()
688 CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__); in cas_reset()
697 * Do a full reset modulo the result of the last auto-negotiation in cas_reset()
701 ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0)); in cas_reset()
706 device_printf(sc->sc_dev, "cannot reset device\n"); in cas_reset()
716 CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__); in cas_stop()
719 callout_stop(&sc->sc_tick_ch); in cas_stop()
720 callout_stop(&sc->sc_rx_ch); in cas_stop()
731 while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) { in cas_stop()
732 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q); in cas_stop()
733 if (txs->txs_ndescs != 0) { in cas_stop()
734 bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap, in cas_stop()
736 bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap); in cas_stop()
737 if (txs->txs_mbuf != NULL) { in cas_stop()
738 m_freem(txs->txs_mbuf); in cas_stop()
739 txs->txs_mbuf = NULL; in cas_stop()
742 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in cas_stop()
749 sc->sc_flags &= ~CAS_LINK; in cas_stop()
750 sc->sc_wdog_timer = 0; in cas_stop()
766 device_printf(sc->sc_dev, "cannot disable RX DMA\n"); in cas_reset_rx()
770 ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0)); in cas_reset_rx()
774 device_printf(sc->sc_dev, "cannot reset receiver\n"); in cas_reset_rx()
793 device_printf(sc->sc_dev, "cannot disable TX DMA\n"); in cas_reset_tx()
797 ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0)); in cas_reset_tx()
801 device_printf(sc->sc_dev, "cannot reset transmitter\n"); in cas_reset_tx()
818 device_printf(sc->sc_dev, "cannot disable RX MAC\n"); in cas_disable_rx()
833 device_printf(sc->sc_dev, "cannot disable TX MAC\n"); in cas_disable_tx()
841 rxcomp->crc_word1 = 0; in cas_rxcompinit()
842 rxcomp->crc_word2 = 0; in cas_rxcompinit()
843 rxcomp->crc_word3 = in cas_rxcompinit()
845 rxcomp->crc_word4 = htole64(CAS_RC4_ZERO); in cas_rxcompinit()
859 sc->sc_txdescs[i].cd_flags = 0; in cas_meminit()
860 sc->sc_txdescs[i].cd_buf_ptr = 0; in cas_meminit()
862 sc->sc_txfree = CAS_MAXTXFREE; in cas_meminit()
863 sc->sc_txnext = 0; in cas_meminit()
864 sc->sc_txwin = 0; in cas_meminit()
870 cas_rxcompinit(&sc->sc_rxcomps[i]); in cas_meminit()
871 sc->sc_rxcptr = 0; in cas_meminit()
879 sc->sc_rxdptr = 0; in cas_meminit()
959 if_t ifp = sc->sc_ifp; in cas_init_locked()
960 uint32_t v; in cas_init_locked() local
968 CTR2(KTR_CAS, "%s: %s: calling stop", device_get_name(sc->sc_dev), in cas_init_locked()
975 * See also the STP2002-STQ document from Sun Microsystems. in cas_init_locked()
982 CTR2(KTR_CAS, "%s: %s: restarting", device_get_name(sc->sc_dev), in cas_init_locked()
986 if ((sc->sc_flags & CAS_SERDES) == 0) in cas_init_locked()
987 /* Re-initialize the MIF. */ in cas_init_locked()
1014 if ((sc->sc_flags & CAS_REG_PLUS) != 0) { in cas_init_locked()
1025 CAS_CDRXD2ADDR(sc, 0), sc->sc_cddma); in cas_init_locked()
1038 (sc->sc_flags & CAS_TABORT) == 0 ? CAS_INF_BURST_EN : in cas_init_locked()
1078 * enable DMA and disable pre-interrupt writeback completion. in cas_init_locked()
1080 v = cas_descsize(CAS_NTXDESC) << CAS_TX_CONF_DESC3_SHFT; in cas_init_locked()
1081 CAS_WRITE_4(sc, CAS_TX_CONF, v | CAS_TX_CONF_TXDMA_EN | in cas_init_locked()
1090 v = cas_rxcompsize(CAS_NRXCOMP) << CAS_RX_CONF_COMP_SHFT; in cas_init_locked()
1091 v |= cas_descsize(CAS_NRXDESC) << CAS_RX_CONF_DESC_SHFT; in cas_init_locked()
1092 if ((sc->sc_flags & CAS_REG_PLUS) != 0) in cas_init_locked()
1093 v |= cas_descsize(CAS_NRXDESC2) << CAS_RX_CONF_DESC2_SHFT; in cas_init_locked()
1095 v | (ETHER_ALIGN << CAS_RX_CONF_SOFF_SHFT)); in cas_init_locked()
1101 /* RX blanking */ in cas_init_locked()
1120 for (v = 0; v <= CAS_RX_REAS_DMA_ADDR_LC; v++) { in cas_init_locked()
1121 CAS_WRITE_4(sc, CAS_RX_REAS_DMA_ADDR, v); in cas_init_locked()
1138 v = CAS_READ_4(sc, CAS_MAC_RX_CONF); in cas_init_locked()
1139 v &= ~(CAS_MAC_RX_CONF_STRPPAD | CAS_MAC_RX_CONF_EN); in cas_init_locked()
1140 v |= CAS_MAC_RX_CONF_STRPFCS; in cas_init_locked()
1141 sc->sc_mac_rxcfg = v; in cas_init_locked()
1149 v = CAS_READ_4(sc, CAS_MAC_TX_CONF); in cas_init_locked()
1150 v |= CAS_MAC_TX_CONF_EN; in cas_init_locked()
1152 CAS_WRITE_4(sc, CAS_MAC_TX_CONF, v); in cas_init_locked()
1157 CAS_WRITE_4(sc, CAS_RX_KICK, CAS_NRXDESC - 4); in cas_init_locked()
1159 if ((sc->sc_flags & CAS_REG_PLUS) != 0) in cas_init_locked()
1160 CAS_WRITE_4(sc, CAS_RX_KICK2, CAS_NRXDESC2 - 4); in cas_init_locked()
1165 mii_mediachg(sc->sc_mii); in cas_init_locked()
1168 sc->sc_wdog_timer = 0; in cas_init_locked()
1169 callout_reset(&sc->sc_tick_ch, hz, cas_tick, sc); in cas_init_locked()
1185 if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) { in cas_load_txmbuf()
1191 if (((*m_head)->m_pkthdr.csum_flags & CAS_CSUM_FEATURES) != 0) { in cas_load_txmbuf()
1206 offset += (ip->ip_hl << 2); in cas_load_txmbuf()
1208 ((offset + m->m_pkthdr.csum_data) << in cas_load_txmbuf()
1213 error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, txs->txs_dmamap, in cas_load_txmbuf()
1223 error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, in cas_load_txmbuf()
1224 txs->txs_dmamap, *m_head, txsegs, &nsegs, in cas_load_txmbuf()
1246 * order to prevent wrap-around. in cas_load_txmbuf()
1248 if (nsegs > sc->sc_txfree - 1) { in cas_load_txmbuf()
1249 txs->txs_ndescs = 0; in cas_load_txmbuf()
1250 bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap); in cas_load_txmbuf()
1254 txs->txs_ndescs = nsegs; in cas_load_txmbuf()
1255 txs->txs_firstdesc = sc->sc_txnext; in cas_load_txmbuf()
1256 nexttx = txs->txs_firstdesc; in cas_load_txmbuf()
1264 sc->sc_txdescs[nexttx].cd_buf_ptr = in cas_load_txmbuf()
1269 sc->sc_txdescs[nexttx].cd_flags = in cas_load_txmbuf()
1271 txs->txs_lastdesc = nexttx; in cas_load_txmbuf()
1279 sc->sc_txdescs[txs->txs_lastdesc].cd_flags |= in cas_load_txmbuf()
1287 if (sc->sc_txwin += nsegs > CAS_MAXTXFREE * 2 / 3) { in cas_load_txmbuf()
1288 sc->sc_txwin = 0; in cas_load_txmbuf()
1289 sc->sc_txdescs[txs->txs_firstdesc].cd_flags |= in cas_load_txmbuf()
1292 sc->sc_txdescs[txs->txs_firstdesc].cd_flags |= in cas_load_txmbuf()
1296 bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap, in cas_load_txmbuf()
1301 __func__, txs->txs_firstdesc, txs->txs_lastdesc, in cas_load_txmbuf()
1302 txs->txs_ndescs); in cas_load_txmbuf()
1304 STAILQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q); in cas_load_txmbuf()
1305 STAILQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q); in cas_load_txmbuf()
1306 txs->txs_mbuf = *m_head; in cas_load_txmbuf()
1308 sc->sc_txnext = CAS_NEXTTX(txs->txs_lastdesc); in cas_load_txmbuf()
1309 sc->sc_txfree -= txs->txs_ndescs; in cas_load_txmbuf()
1318 const u_char *laddr = if_getlladdr(sc->sc_ifp); in cas_init_regs()
1323 if ((sc->sc_flags & CAS_INITED) == 0) { in cas_init_regs()
1349 i += CAS_MAC_ADDR4 - CAS_MAC_ADDR3) in cas_init_regs()
1366 i += CAS_MAC_HASH1 - CAS_MAC_HASH0) in cas_init_regs()
1369 sc->sc_flags |= CAS_INITED; in cas_init_regs()
1418 device_get_name(sc->sc_dev), __func__, sc->sc_txnext); in cas_txkick()
1421 CAS_WRITE_4(sc, CAS_TX_KICK3, sc->sc_txnext); in cas_txkick()
1434 IFF_DRV_RUNNING || (sc->sc_flags & CAS_LINK) == 0) { in cas_start()
1439 if (sc->sc_txfree < CAS_MAXTXFREE / 4) in cas_start()
1444 device_get_name(sc->sc_dev), __func__, sc->sc_txfree, in cas_start()
1445 sc->sc_txnext); in cas_start()
1449 for (; !if_sendq_empty(ifp) && sc->sc_txfree > 1;) { in cas_start()
1460 if ((sc->sc_txnext % 4) == 0) { in cas_start()
1474 device_get_name(sc->sc_dev), sc->sc_txnext); in cas_start()
1478 sc->sc_wdog_timer = 5; in cas_start()
1481 device_get_name(sc->sc_dev), __func__, in cas_start()
1482 sc->sc_wdog_timer); in cas_start()
1492 if_t ifp = sc->sc_ifp; in cas_tint()
1501 CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__); in cas_tint()
1510 while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) { in cas_tint()
1514 for (i = txs->txs_firstdesc;; i = CAS_NEXTTX(i)) { in cas_tint()
1518 sc->sc_txdescs[i].cd_flags)); in cas_tint()
1521 sc->sc_txdescs[i].cd_buf_ptr)); in cas_tint()
1522 if (i == txs->txs_lastdesc) in cas_tint()
1537 CTR4(KTR_CAS, "%s: txs->txs_firstdesc = %d, " in cas_tint()
1538 "txs->txs_lastdesc = %d, txlast = %d", in cas_tint()
1539 __func__, txs->txs_firstdesc, txs->txs_lastdesc, txlast); in cas_tint()
1541 if (txs->txs_firstdesc <= txs->txs_lastdesc) { in cas_tint()
1542 if ((txlast >= txs->txs_firstdesc) && in cas_tint()
1543 (txlast <= txs->txs_lastdesc)) in cas_tint()
1546 /* Ick -- this command wraps. */ in cas_tint()
1547 if ((txlast >= txs->txs_firstdesc) || in cas_tint()
1548 (txlast <= txs->txs_lastdesc)) in cas_tint()
1555 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q); in cas_tint()
1557 sc->sc_txfree += txs->txs_ndescs; in cas_tint()
1559 bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap, in cas_tint()
1561 bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap); in cas_tint()
1562 if (txs->txs_mbuf != NULL) { in cas_tint()
1563 m_freem(txs->txs_mbuf); in cas_tint()
1564 txs->txs_mbuf = NULL; in cas_tint()
1567 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in cas_tint()
1585 if (STAILQ_EMPTY(&sc->sc_txdirtyq)) in cas_tint()
1586 sc->sc_wdog_timer = 0; in cas_tint()
1591 device_get_name(sc->sc_dev), __func__, sc->sc_wdog_timer); in cas_tint()
1612 if_t ifp = sc->sc_ifp; in cas_rint()
1620 callout_stop(&sc->sc_rx_ch); in cas_rint()
1623 CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__); in cas_rint()
1630 KASSERT(sc->sc_rxcomps[sc->sc_rxcptr].crc_word ## n == 0, \ in cas_rint()
1634 word ## n = le64toh(sc->sc_rxcomps[sc->sc_rxcptr].crc_word ## n) in cas_rint()
1642 CTR4(KTR_CAS, "%s: sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d", in cas_rint()
1643 __func__, sc->sc_rxcptr, sc->sc_rxdptr, rxhead); in cas_rint()
1647 for (; sc->sc_rxcptr != rxhead; in cas_rint()
1648 sc->sc_rxcptr = CAS_NEXTRXCOMP(sc->sc_rxcptr)) { in cas_rint()
1654 --skip; in cas_rint()
1665 printf(" completion %d: ", sc->sc_rxcptr); in cas_rint()
1684 callout_reset(&sc->sc_rx_ch, CAS_RXOWN_TICKS, in cas_rint()
1692 device_printf(sc->sc_dev, in cas_rint()
1717 rxds = &sc->sc_rxdsoft[idx]; in cas_rint()
1720 refcount_acquire(&rxds->rxds_refcount); in cas_rint()
1721 bus_dmamap_sync(sc->sc_rdmatag, in cas_rint()
1722 rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD); in cas_rint()
1723 m_extadd(m, (char *)rxds->rxds_buf + in cas_rint()
1727 if ((m->m_flags & M_EXT) == 0) { in cas_rint()
1733 m->m_pkthdr.rcvif = ifp; in cas_rint()
1734 m->m_pkthdr.len = m->m_len = len; in cas_rint()
1747 refcount_release(&rxds->rxds_refcount) != 0) in cas_rint()
1756 rxds = &sc->sc_rxdsoft[idx]; in cas_rint()
1759 refcount_acquire(&rxds->rxds_refcount); in cas_rint()
1761 m->m_len = min(CAS_PAGE_SIZE - off, len); in cas_rint()
1762 bus_dmamap_sync(sc->sc_rdmatag, in cas_rint()
1763 rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD); in cas_rint()
1764 m_extadd(m, (char *)rxds->rxds_buf + off, in cas_rint()
1765 m->m_len, cas_free, sc, in cas_rint()
1768 if ((m->m_flags & M_EXT) == 0) { in cas_rint()
1786 rxds2 = &sc->sc_rxdsoft[idx2]; in cas_rint()
1791 &rxds2->rxds_refcount); in cas_rint()
1792 m2->m_len = len - m->m_len; in cas_rint()
1794 sc->sc_rdmatag, in cas_rint()
1795 rxds2->rxds_dmamap, in cas_rint()
1798 (char *)rxds2->rxds_buf, in cas_rint()
1799 m2->m_len, cas_free, sc, in cas_rint()
1802 if ((m2->m_flags & M_EXT) == in cas_rint()
1810 m->m_next = m2; in cas_rint()
1817 m->m_pkthdr.rcvif = ifp; in cas_rint()
1818 m->m_pkthdr.len = len; in cas_rint()
1831 refcount_release(&rxds->rxds_refcount) != 0) in cas_rint()
1834 refcount_release(&rxds2->rxds_refcount) != 0) in cas_rint()
1841 cas_rxcompinit(&sc->sc_rxcomps[sc->sc_rxcptr]); in cas_rint()
1846 CAS_WRITE_4(sc, CAS_RX_COMP_TAIL, sc->sc_rxcptr); in cas_rint()
1853 CTR4(KTR_CAS, "%s: done sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d", in cas_rint()
1854 __func__, sc->sc_rxcptr, sc->sc_rxdptr, in cas_rint()
1866 sc = m->m_ext.ext_arg1; in cas_free()
1867 idx = (uintptr_t)m->m_ext.ext_arg2; in cas_free()
1868 rxds = &sc->sc_rxdsoft[idx]; in cas_free()
1869 if (refcount_release(&rxds->rxds_refcount) == 0) in cas_free()
1889 bus_dmamap_sync(sc->sc_rdmatag, sc->sc_rxdsoft[idx].rxds_dmamap, in cas_add_rxdesc()
1891 CAS_UPDATE_RXDESC(sc, sc->sc_rxdptr, idx); in cas_add_rxdesc()
1892 sc->sc_rxdptr = CAS_NEXTRXDESC(sc->sc_rxdptr); in cas_add_rxdesc()
1900 if ((sc->sc_rxdptr % 4) == 0) { in cas_add_rxdesc()
1903 (sc->sc_rxdptr + CAS_NRXDESC - 4) & CAS_NRXDESC_MASK); in cas_add_rxdesc()
1910 if_t ifp = sc->sc_ifp; in cas_eint()
1916 device_printf(sc->sc_dev, "%s: status 0x%x", __func__, status); in cas_eint()
1921 status = pci_read_config(sc->sc_dev, PCIR_STATUS, 2); in cas_eint()
1923 pci_write_config(sc->sc_dev, PCIR_STATUS, status, 2); in cas_eint()
1931 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task); in cas_eint()
1935 cas_intr(void *v) in cas_intr() argument
1937 struct cas_softc *sc = v; in cas_intr()
1945 taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task); in cas_intr()
1954 if_t ifp = sc->sc_ifp; in cas_intr_task()
1969 device_get_name(sc->sc_dev), __func__, in cas_intr_task()
1980 device_printf(sc->sc_dev, in cas_intr_task()
1986 device_printf(sc->sc_dev, in cas_intr_task()
1992 device_printf(sc->sc_dev, in cas_intr_task()
1995 device_printf(sc->sc_dev, in cas_intr_task()
1996 "%s: transited to non-PAUSE state\n", __func__); in cas_intr_task()
1999 device_printf(sc->sc_dev, "%s: MIF interrupt\n", __func__); in cas_intr_task()
2016 device_printf(sc->sc_dev, in cas_intr_task()
2025 device_printf(sc->sc_dev, in cas_intr_task()
2037 device_printf(sc->sc_dev, in cas_intr_task()
2050 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task); in cas_intr_task()
2055 taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task); in cas_intr_task()
2060 /* Re-enable interrupts. */ in cas_intr_task()
2076 if_t ifp = sc->sc_ifp; in cas_watchdog()
2093 if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) in cas_watchdog()
2096 if ((sc->sc_flags & CAS_LINK) != 0) in cas_watchdog()
2097 device_printf(sc->sc_dev, "device timeout\n"); in cas_watchdog()
2099 device_printf(sc->sc_dev, "device timeout (no link)\n"); in cas_watchdog()
2106 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task); in cas_watchdog()
2139 uint32_t v; in cas_mii_readreg() local
2146 if ((sc->sc_flags & CAS_SERDES) != 0) { in cas_mii_readreg()
2166 device_printf(sc->sc_dev, in cas_mii_readreg()
2174 v = CAS_MIF_FRAME_READ | in cas_mii_readreg()
2178 CAS_WRITE_4(sc, CAS_MIF_FRAME, v); in cas_mii_readreg()
2183 v = CAS_READ_4(sc, CAS_MIF_FRAME); in cas_mii_readreg()
2184 if (v & CAS_MIF_FRAME_TA_LSB) in cas_mii_readreg()
2185 return (v & CAS_MIF_FRAME_DATA); in cas_mii_readreg()
2188 device_printf(sc->sc_dev, "%s: timed out\n", __func__); in cas_mii_readreg()
2197 uint32_t v; in cas_mii_writereg() local
2204 if ((sc->sc_flags & CAS_SERDES) != 0) { in cas_mii_writereg()
2218 device_printf(sc->sc_dev, in cas_mii_writereg()
2241 device_printf(sc->sc_dev, in cas_mii_writereg()
2252 v = CAS_MIF_FRAME_WRITE | in cas_mii_writereg()
2257 CAS_WRITE_4(sc, CAS_MIF_FRAME, v); in cas_mii_writereg()
2262 v = CAS_READ_4(sc, CAS_MIF_FRAME); in cas_mii_writereg()
2263 if (v & CAS_MIF_FRAME_TA_LSB) in cas_mii_writereg()
2267 device_printf(sc->sc_dev, "%s: timed out\n", __func__); in cas_mii_writereg()
2277 uint32_t rxcfg, txcfg, v; in cas_mii_statchg() local
2280 ifp = sc->sc_ifp; in cas_mii_statchg()
2286 device_printf(sc->sc_dev, "%s: status changen", __func__); in cas_mii_statchg()
2289 if ((sc->sc_mii->mii_media_status & IFM_ACTIVE) != 0 && in cas_mii_statchg()
2290 IFM_SUBTYPE(sc->sc_mii->mii_media_active) != IFM_NONE) in cas_mii_statchg()
2291 sc->sc_flags |= CAS_LINK; in cas_mii_statchg()
2293 sc->sc_flags &= ~CAS_LINK; in cas_mii_statchg()
2295 switch (IFM_SUBTYPE(sc->sc_mii->mii_media_active)) { in cas_mii_statchg()
2313 rxcfg = sc->sc_mac_rxcfg; in cas_mii_statchg()
2317 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0) in cas_mii_statchg()
2328 v = CAS_READ_4(sc, CAS_MAC_CTRL_CONF) & in cas_mii_statchg()
2330 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & in cas_mii_statchg()
2332 v |= CAS_MAC_CTRL_CONF_RXP; in cas_mii_statchg()
2333 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & in cas_mii_statchg()
2335 v |= CAS_MAC_CTRL_CONF_TXP; in cas_mii_statchg()
2336 CAS_WRITE_4(sc, CAS_MAC_CTRL_CONF, v); in cas_mii_statchg()
2340 * to be calculated when letting them strip the FCS in half- in cas_mii_statchg()
2344 * hardware checksumming in half-duplex mode though. in cas_mii_statchg()
2346 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0) { in cas_mii_statchg()
2349 } else if ((sc->sc_flags & CAS_NO_CSUM) == 0) { in cas_mii_statchg()
2354 if (sc->sc_variant == CAS_SATURN) { in cas_mii_statchg()
2355 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0) in cas_mii_statchg()
2362 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0 && in cas_mii_statchg()
2371 v = CAS_MAC_XIF_CONF_TX_OE | CAS_MAC_XIF_CONF_LNKLED; in cas_mii_statchg()
2372 if ((sc->sc_flags & CAS_SERDES) == 0) { in cas_mii_statchg()
2373 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0) in cas_mii_statchg()
2374 v |= CAS_MAC_XIF_CONF_NOECHO; in cas_mii_statchg()
2375 v |= CAS_MAC_XIF_CONF_BUF_OE; in cas_mii_statchg()
2378 v |= CAS_MAC_XIF_CONF_GMII; in cas_mii_statchg()
2379 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0) in cas_mii_statchg()
2380 v |= CAS_MAC_XIF_CONF_FDXLED; in cas_mii_statchg()
2381 CAS_WRITE_4(sc, CAS_MAC_XIF_CONF, v); in cas_mii_statchg()
2383 sc->sc_mac_rxcfg = rxcfg; in cas_mii_statchg()
2385 (sc->sc_flags & CAS_LINK) != 0) { in cas_mii_statchg()
2402 error = mii_mediachg(sc->sc_mii); in cas_mediachange()
2418 mii_pollstat(sc->sc_mii); in cas_mediastatus()
2419 ifmr->ifm_active = sc->sc_mii->mii_media_active; in cas_mediastatus()
2420 ifmr->ifm_status = sc->sc_mii->mii_media_status; in cas_mediastatus()
2437 ((if_getflags(ifp) ^ sc->sc_ifflags) & in cas_ioctl()
2444 sc->sc_ifflags = if_getflags(ifp); in cas_ioctl()
2449 if ((sc->sc_flags & CAS_NO_CSUM) != 0) { in cas_ioctl()
2454 if_setcapenable(ifp, ifr->ifr_reqcap); in cas_ioctl()
2469 if ((ifr->ifr_mtu < ETHERMIN) || in cas_ioctl()
2470 (ifr->ifr_mtu > ETHERMTU_JUMBO)) in cas_ioctl()
2473 if_setmtu(ifp, ifr->ifr_mtu); in cas_ioctl()
2477 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd); in cas_ioctl()
2496 hash[crc >> 4] |= 1 << (15 - (crc & 15)); in cas_hash_maddr()
2504 if_t ifp = sc->sc_ifp; in cas_setladrf()
2507 uint32_t v; in cas_setladrf() local
2515 v = sc->sc_mac_rxcfg & ~(CAS_MAC_RX_CONF_HFILTER | in cas_setladrf()
2517 CAS_WRITE_4(sc, CAS_MAC_RX_CONF, v); in cas_setladrf()
2522 device_printf(sc->sc_dev, in cas_setladrf()
2525 v &= ~(CAS_MAC_RX_CONF_PROMISC | CAS_MAC_RX_CONF_PGRP); in cas_setladrf()
2527 v |= CAS_MAC_RX_CONF_PROMISC; in cas_setladrf()
2531 v |= CAS_MAC_RX_CONF_PGRP; in cas_setladrf()
2547 v |= CAS_MAC_RX_CONF_HFILTER; in cas_setladrf()
2552 CAS_MAC_HASH0 + i * (CAS_MAC_HASH1 - CAS_MAC_HASH0), in cas_setladrf()
2556 sc->sc_mac_rxcfg = v; in cas_setladrf()
2557 CAS_WRITE_4(sc, CAS_MAC_RX_CONF, v | CAS_MAC_RX_CONF_EN); in cas_setladrf()
2604 nitems(cas_pci_devlist) - 1);
2627 { -1, 0 }
2630 #define CAS_LOCAL_MAC_ADDRESS "local-mac-address"
2631 #define CAS_PHY_INTERFACE "phy-interface"
2632 #define CAS_PHY_TYPE "phy-type"
2647 sc->sc_variant = CAS_UNKNOWN; in cas_pci_attach()
2651 sc->sc_variant = cas_pci_devlist[i].cpd_variant; in cas_pci_attach()
2655 if (sc->sc_variant == CAS_UNKNOWN) { in cas_pci_attach()
2665 sc->sc_dev = dev; in cas_pci_attach()
2666 if (sc->sc_variant == CAS_CAS && pci_get_devid(dev) < 0x02) in cas_pci_attach()
2668 sc->sc_flags |= CAS_NO_CSUM; in cas_pci_attach()
2669 if (sc->sc_variant == CAS_CASPLUS || sc->sc_variant == CAS_SATURN) in cas_pci_attach()
2670 sc->sc_flags |= CAS_REG_PLUS; in cas_pci_attach()
2671 if (sc->sc_variant == CAS_CAS || in cas_pci_attach()
2672 (sc->sc_variant == CAS_CASPLUS && pci_get_revid(dev) < 0x11)) in cas_pci_attach()
2673 sc->sc_flags |= CAS_TABORT; in cas_pci_attach()
2675 device_printf(dev, "flags=0x%x\n", sc->sc_flags); in cas_pci_attach()
2677 if (bus_alloc_resources(dev, cas_pci_res_spec, sc->sc_res)) { in cas_pci_attach()
2679 bus_release_resources(dev, cas_pci_res_spec, sc->sc_res); in cas_pci_attach()
2686 OF_getetheraddr(dev, sc->sc_enaddr); in cas_pci_attach()
2690 buf[sizeof(buf) - 1] = '\0'; in cas_pci_attach()
2692 sc->sc_flags |= CAS_SERDES; in cas_pci_attach()
2699 * SUNW,pci-ce and SUNW,pci-qge use the Enhanced VPD format described in cas_pci_attach()
2778 i -= PCI_VPD_SIZE + CAS_ROM_READ_1(sc, j + PCI_VPD_LEN), in cas_pci_attach()
2791 bus_read_region_1(sc->sc_res[CAS_RES_MEM], in cas_pci_attach()
2794 buf[sizeof(buf) - 1] = '\0'; in cas_pci_attach()
2797 bus_read_region_1(sc->sc_res[CAS_RES_MEM], in cas_pci_attach()
2811 bus_read_region_1(sc->sc_res[CAS_RES_MEM], in cas_pci_attach()
2814 buf[sizeof(buf) - 1] = '\0'; in cas_pci_attach()
2821 bus_read_region_1(sc->sc_res[CAS_RES_MEM], in cas_pci_attach()
2824 buf[sizeof(buf) - 1] = '\0'; in cas_pci_attach()
2848 memcpy(sc->sc_enaddr, enaddr[i], ETHER_ADDR_LEN); in cas_pci_attach()
2858 sc->sc_flags |= CAS_SERDES; in cas_pci_attach()
2866 if (bus_setup_intr(dev, sc->sc_res[CAS_RES_INTR], INTR_TYPE_NET | in cas_pci_attach()
2867 INTR_MPSAFE, cas_intr, NULL, sc, &sc->sc_ih) != 0) { in cas_pci_attach()
2876 bus_release_resources(dev, cas_pci_res_spec, sc->sc_res); in cas_pci_attach()
2886 bus_teardown_intr(dev, sc->sc_res[CAS_RES_INTR], sc->sc_ih); in cas_pci_detach()
2889 bus_release_resources(dev, cas_pci_res_spec, sc->sc_res); in cas_pci_detach()