Lines Matching full:sc

67 static void	glc_set_multicast(struct glc_softc *sc);
68 static int glc_add_rxbuf(struct glc_softc *sc, int idx);
69 static int glc_add_rxbuf_dma(struct glc_softc *sc, int idx);
70 static int glc_encap(struct glc_softc *sc, struct mbuf **m_head,
119 struct glc_softc *sc; in glc_attach() local
124 sc = device_get_softc(dev); in glc_attach()
126 sc->sc_bus = ps3bus_get_bus(dev); in glc_attach()
127 sc->sc_dev = ps3bus_get_device(dev); in glc_attach()
128 sc->sc_self = dev; in glc_attach()
130 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, in glc_attach()
132 callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0); in glc_attach()
133 sc->next_txdma_slot = 0; in glc_attach()
134 sc->bsy_txdma_slots = 0; in glc_attach()
135 sc->sc_next_rxdma_slot = 0; in glc_attach()
136 sc->first_used_txdma_slot = -1; in glc_attach()
142 lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_attach()
143 lv1_net_stop_rx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_attach()
145 sc->sc_ifp = if_alloc(IFT_ETHER); in glc_attach()
146 if_setsoftc(sc->sc_ifp, sc); in glc_attach()
152 lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_MAC_ADDRESS, in glc_attach()
154 memcpy(sc->sc_enaddr, &((uint8_t *)&mac64)[2], sizeof(sc->sc_enaddr)); in glc_attach()
155 sc->sc_tx_vlan = sc->sc_rx_vlan = -1; in glc_attach()
156 err = lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_VLAN_ID, in glc_attach()
159 sc->sc_tx_vlan = val; in glc_attach()
160 err = lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_VLAN_ID, in glc_attach()
163 sc->sc_rx_vlan = val; in glc_attach()
168 sc->sc_irqid = 0; in glc_attach()
169 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid, in glc_attach()
171 if (sc->sc_irq == NULL) { in glc_attach()
173 mtx_destroy(&sc->sc_mtx); in glc_attach()
177 bus_setup_intr(dev, sc->sc_irq, in glc_attach()
179 glc_intr_filter, glc_intr, sc, &sc->sc_irqctx); in glc_attach()
180 sc->sc_hwirq_status = (uint64_t *)contigmalloc(8, M_GLC, M_ZERO, 0, in glc_attach()
182 lv1_net_set_interrupt_status_indicator(sc->sc_bus, sc->sc_dev, in glc_attach()
183 vtophys(sc->sc_hwirq_status), 0); in glc_attach()
184 lv1_net_set_interrupt_mask(sc->sc_bus, sc->sc_dev, in glc_attach()
195 0, NULL,NULL, &sc->sc_dmadesc_tag); in glc_attach()
197 err = bus_dmamem_alloc(sc->sc_dmadesc_tag, (void **)&sc->sc_txdmadesc, in glc_attach()
199 &sc->sc_txdmadesc_map); in glc_attach()
200 err = bus_dmamap_load(sc->sc_dmadesc_tag, sc->sc_txdmadesc_map, in glc_attach()
201 sc->sc_txdmadesc, 128*sizeof(struct glc_dmadesc), glc_getphys, in glc_attach()
202 &sc->sc_txdmadesc_phys, 0); in glc_attach()
203 err = bus_dmamem_alloc(sc->sc_dmadesc_tag, (void **)&sc->sc_rxdmadesc, in glc_attach()
205 &sc->sc_rxdmadesc_map); in glc_attach()
206 err = bus_dmamap_load(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map, in glc_attach()
207 sc->sc_rxdmadesc, 128*sizeof(struct glc_dmadesc), glc_getphys, in glc_attach()
208 &sc->sc_rxdmadesc_phys, 0); in glc_attach()
213 &sc->sc_rxdma_tag); in glc_attach()
217 &sc->sc_txdma_tag); in glc_attach()
220 STAILQ_INIT(&sc->sc_txfreeq); in glc_attach()
221 STAILQ_INIT(&sc->sc_txdirtyq); in glc_attach()
226 txs = &sc->sc_txsoft[i]; in glc_attach()
228 err = bus_dmamap_create(sc->sc_txdma_tag, 0, &txs->txs_dmamap); in glc_attach()
234 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in glc_attach()
239 err = bus_dmamap_create(sc->sc_rxdma_tag, 0, in glc_attach()
240 &sc->sc_rxsoft[i].rxs_dmamap); in glc_attach()
246 sc->sc_rxsoft[i].rxs_mbuf = NULL; in glc_attach()
253 if_initname(sc->sc_ifp, device_get_name(dev), device_get_unit(dev)); in glc_attach()
254 if_setmtu(sc->sc_ifp, ETHERMTU); in glc_attach()
255 if_setflags(sc->sc_ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); in glc_attach()
256 if_sethwassist(sc->sc_ifp, CSUM_TCP | CSUM_UDP); in glc_attach()
257 if_setcapabilities(sc->sc_ifp, IFCAP_HWCSUM | IFCAP_RXCSUM); in glc_attach()
258 if_setcapenable(sc->sc_ifp, IFCAP_HWCSUM | IFCAP_RXCSUM); in glc_attach()
259 if_setstartfn(sc->sc_ifp, glc_start); in glc_attach()
260 if_setioctlfn(sc->sc_ifp, glc_ioctl); in glc_attach()
261 if_setinitfn(sc->sc_ifp, glc_init); in glc_attach()
263 ifmedia_init(&sc->sc_media, IFM_IMASK, glc_media_change, in glc_attach()
265 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T, 0, NULL); in glc_attach()
266 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); in glc_attach()
267 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX, 0, NULL); in glc_attach()
268 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); in glc_attach()
269 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); in glc_attach()
270 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); in glc_attach()
271 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); in glc_attach()
273 if_setsendqlen(sc->sc_ifp, GLC_MAX_TX_PACKETS); in glc_attach()
274 if_setsendqready(sc->sc_ifp); in glc_attach()
276 ether_ifattach(sc->sc_ifp, sc->sc_enaddr); in glc_attach()
277 if_sethwassist(sc->sc_ifp, 0); in glc_attach()
281 mtx_destroy(&sc->sc_mtx); in glc_attach()
282 if_free(sc->sc_ifp); in glc_attach()
287 glc_init_locked(struct glc_softc *sc) in glc_init_locked() argument
293 mtx_assert(&sc->sc_mtx, MA_OWNED); in glc_init_locked()
295 lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_init_locked()
296 lv1_net_stop_rx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_init_locked()
298 glc_set_multicast(sc); in glc_init_locked()
301 rxs = &sc->sc_rxsoft[i]; in glc_init_locked()
305 glc_add_rxbuf(sc, i); in glc_init_locked()
313 glc_add_rxbuf_dma(sc, i); in glc_init_locked()
314 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map, in glc_init_locked()
319 while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) { in glc_init_locked()
320 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q); in glc_init_locked()
321 bus_dmamap_unload(sc->sc_txdma_tag, txs->txs_dmamap); in glc_init_locked()
328 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in glc_init_locked()
330 sc->first_used_txdma_slot = -1; in glc_init_locked()
331 sc->bsy_txdma_slots = 0; in glc_init_locked()
333 error = lv1_net_start_rx_dma(sc->sc_bus, sc->sc_dev, in glc_init_locked()
334 sc->sc_rxsoft[0].rxs_desc, 0); in glc_init_locked()
336 device_printf(sc->sc_self, in glc_init_locked()
339 if_setdrvflagbits(sc->sc_ifp, IFF_DRV_RUNNING, 0); in glc_init_locked()
340 if_setdrvflagbits(sc->sc_ifp, 0, IFF_DRV_OACTIVE); in glc_init_locked()
341 sc->sc_ifpflags = if_getflags(sc->sc_ifp); in glc_init_locked()
343 sc->sc_wdog_timer = 0; in glc_init_locked()
344 callout_reset(&sc->sc_tick_ch, hz, glc_tick, sc); in glc_init_locked()
350 struct glc_softc *sc = xsc; in glc_stop() local
352 mtx_assert(&sc->sc_mtx, MA_OWNED); in glc_stop()
354 lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_stop()
355 lv1_net_stop_rx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_stop()
361 struct glc_softc *sc = xsc; in glc_init() local
363 mtx_lock(&sc->sc_mtx); in glc_init()
364 glc_init_locked(sc); in glc_init()
365 mtx_unlock(&sc->sc_mtx); in glc_init()
371 struct glc_softc *sc = xsc; in glc_tick() local
373 mtx_assert(&sc->sc_mtx, MA_OWNED); in glc_tick()
380 lv1_net_start_rx_dma(sc->sc_bus, sc->sc_dev, in glc_tick()
381 sc->sc_rxsoft[sc->sc_next_rxdma_slot].rxs_desc, 0); in glc_tick()
383 if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) { in glc_tick()
384 callout_reset(&sc->sc_tick_ch, hz, glc_tick, sc); in glc_tick()
389 device_printf(sc->sc_self, "device timeout\n"); in glc_tick()
391 glc_init_locked(sc); in glc_tick()
397 struct glc_softc *sc = if_getsoftc(ifp); in glc_start_locked() local
403 mtx_assert(&sc->sc_mtx, MA_OWNED); in glc_start_locked()
410 if (STAILQ_EMPTY(&sc->sc_txdirtyq)) in glc_start_locked()
420 if (sc->bsy_txdma_slots > 125) { in glc_start_locked()
429 if (sc->sc_tx_vlan >= 0) in glc_start_locked()
430 mb_head = ether_vlanencap(mb_head, sc->sc_tx_vlan); in glc_start_locked()
432 if (glc_encap(sc, &mb_head, &pktdesc)) { in glc_start_locked()
442 error = lv1_net_start_tx_dma(sc->sc_bus, sc->sc_dev, first, 0); in glc_start_locked()
444 device_printf(sc->sc_self, in glc_start_locked()
446 sc->sc_wdog_timer = 5; in glc_start_locked()
453 struct glc_softc *sc = if_getsoftc(ifp); in glc_start() local
455 mtx_lock(&sc->sc_mtx); in glc_start()
457 mtx_unlock(&sc->sc_mtx); in glc_start()
463 struct glc_softc *sc = if_getsoftc(ifp); in glc_ioctl() local
469 mtx_lock(&sc->sc_mtx); in glc_ioctl()
472 ((if_getflags(ifp) ^ sc->sc_ifpflags) & in glc_ioctl()
474 glc_set_multicast(sc); in glc_ioctl()
476 glc_init_locked(sc); in glc_ioctl()
479 glc_stop(sc); in glc_ioctl()
480 sc->sc_ifpflags = if_getflags(ifp); in glc_ioctl()
481 mtx_unlock(&sc->sc_mtx); in glc_ioctl()
485 mtx_lock(&sc->sc_mtx); in glc_ioctl()
486 glc_set_multicast(sc); in glc_ioctl()
487 mtx_unlock(&sc->sc_mtx); in glc_ioctl()
491 err = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); in glc_ioctl()
504 struct glc_softc *sc = arg; in glc_add_maddr() local
517 lv1_net_add_multicast_address(sc->sc_bus, sc->sc_dev, addr, 0); in glc_add_maddr()
523 glc_set_multicast(struct glc_softc *sc) in glc_set_multicast() argument
525 if_t ifp = sc->sc_ifp; in glc_set_multicast()
529 lv1_net_remove_multicast_address(sc->sc_bus, sc->sc_dev, 0, 1); in glc_set_multicast()
532 lv1_net_add_multicast_address(sc->sc_bus, sc->sc_dev, in glc_set_multicast()
536 lv1_net_add_multicast_address(sc->sc_bus, sc->sc_dev, 0, 1); in glc_set_multicast()
538 naddrs = if_foreach_llmaddr(ifp, glc_add_maddr, sc); in glc_set_multicast()
540 lv1_net_add_multicast_address(sc->sc_bus, in glc_set_multicast()
541 sc->sc_dev, 0, 1); in glc_set_multicast()
546 glc_add_rxbuf(struct glc_softc *sc, int idx) in glc_add_rxbuf() argument
548 struct glc_rxsoft *rxs = &sc->sc_rxsoft[idx]; in glc_add_rxbuf()
559 bus_dmamap_sync(sc->sc_rxdma_tag, rxs->rxs_dmamap, in glc_add_rxbuf()
561 bus_dmamap_unload(sc->sc_rxdma_tag, rxs->rxs_dmamap); in glc_add_rxbuf()
564 error = bus_dmamap_load_mbuf_sg(sc->sc_rxdma_tag, rxs->rxs_dmamap, m, in glc_add_rxbuf()
567 device_printf(sc->sc_self, in glc_add_rxbuf()
578 bus_dmamap_sync(sc->sc_rxdma_tag, rxs->rxs_dmamap, BUS_DMASYNC_PREREAD); in glc_add_rxbuf()
584 glc_add_rxbuf_dma(struct glc_softc *sc, int idx) in glc_add_rxbuf_dma() argument
586 struct glc_rxsoft *rxs = &sc->sc_rxsoft[idx]; in glc_add_rxbuf_dma()
588 bzero(&sc->sc_rxdmadesc[idx], sizeof(sc->sc_rxdmadesc[idx])); in glc_add_rxbuf_dma()
589 sc->sc_rxdmadesc[idx].paddr = rxs->segment.ds_addr; in glc_add_rxbuf_dma()
590 sc->sc_rxdmadesc[idx].len = rxs->segment.ds_len; in glc_add_rxbuf_dma()
591 sc->sc_rxdmadesc[idx].next = sc->sc_rxdmadesc_phys + in glc_add_rxbuf_dma()
592 ((idx + 1) % GLC_MAX_RX_PACKETS)*sizeof(sc->sc_rxdmadesc[idx]); in glc_add_rxbuf_dma()
593 sc->sc_rxdmadesc[idx].cmd_stat = GELIC_DESCR_OWNED; in glc_add_rxbuf_dma()
596 rxs->rxs_desc = sc->sc_rxdmadesc_phys + idx*sizeof(struct glc_dmadesc); in glc_add_rxbuf_dma()
602 glc_encap(struct glc_softc *sc, struct mbuf **m_head, bus_addr_t *pktdesc) in glc_encap() argument
612 nsegs_max = 128 - sc->bsy_txdma_slots; in glc_encap()
614 if (nsegs_max > 16 || sc->first_used_txdma_slot < 0) in glc_encap()
618 if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) { in glc_encap()
637 err = bus_dmamap_load_mbuf_sg(sc->sc_txdma_tag, txs->txs_dmamap, in glc_encap()
645 KASSERT(nsegs <= 128 - sc->bsy_txdma_slots, in glc_encap()
647 nsegs, 128 - sc->bsy_txdma_slots)); in glc_encap()
656 txs->txs_firstdesc = sc->next_txdma_slot; in glc_encap()
659 firstslotphys = sc->sc_txdmadesc_phys + in glc_encap()
663 bzero(&sc->sc_txdmadesc[idx], sizeof(sc->sc_txdmadesc[idx])); in glc_encap()
664 sc->sc_txdmadesc[idx].paddr = segs[i].ds_addr; in glc_encap()
665 sc->sc_txdmadesc[idx].len = segs[i].ds_len; in glc_encap()
666 sc->sc_txdmadesc[idx].next = sc->sc_txdmadesc_phys + in glc_encap()
668 sc->sc_txdmadesc[idx].cmd_stat |= GELIC_CMDSTAT_NOIPSEC; in glc_encap()
672 sc->sc_txdmadesc[idx].next = 0; in glc_encap()
673 sc->sc_txdmadesc[idx].cmd_stat |= GELIC_CMDSTAT_LAST; in glc_encap()
677 sc->sc_txdmadesc[idx].cmd_stat |= GELIC_CMDSTAT_CSUM_TCP; in glc_encap()
679 sc->sc_txdmadesc[idx].cmd_stat |= GELIC_CMDSTAT_CSUM_UDP; in glc_encap()
680 sc->sc_txdmadesc[idx].cmd_stat |= GELIC_DESCR_OWNED; in glc_encap()
684 sc->next_txdma_slot = idx; in glc_encap()
685 sc->bsy_txdma_slots += nsegs; in glc_encap()
691 if (sc->first_used_txdma_slot < 0) in glc_encap()
692 sc->first_used_txdma_slot = txs->txs_firstdesc; in glc_encap()
694 bus_dmamap_sync(sc->sc_txdma_tag, txs->txs_dmamap, in glc_encap()
696 sc->sc_txdmadesc[idx].next = firstslotphys; in glc_encap()
698 STAILQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q); in glc_encap()
699 STAILQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q); in glc_encap()
707 glc_rxintr(struct glc_softc *sc) in glc_rxintr() argument
711 if_t ifp = sc->sc_ifp; in glc_rxintr()
713 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map, in glc_rxintr()
717 while ((sc->sc_rxdmadesc[sc->sc_next_rxdma_slot].cmd_stat & in glc_rxintr()
719 i = sc->sc_next_rxdma_slot; in glc_rxintr()
720 sc->sc_next_rxdma_slot++; in glc_rxintr()
721 if (sc->sc_next_rxdma_slot >= GLC_MAX_RX_PACKETS) in glc_rxintr()
722 sc->sc_next_rxdma_slot = 0; in glc_rxintr()
724 if (sc->sc_rxdmadesc[i].cmd_stat & GELIC_CMDSTAT_CHAIN_END) in glc_rxintr()
727 if (sc->sc_rxdmadesc[i].rxerror & GELIC_RXERRORS) { in glc_rxintr()
732 m = sc->sc_rxsoft[i].rxs_mbuf; in glc_rxintr()
733 if (sc->sc_rxdmadesc[i].data_stat & GELIC_RX_IPCSUM) { in glc_rxintr()
737 if (sc->sc_rxdmadesc[i].data_stat & GELIC_RX_TCPUDPCSUM) { in glc_rxintr()
743 if (glc_add_rxbuf(sc, i)) { in glc_rxintr()
750 m->m_len = sc->sc_rxdmadesc[i].valid_size; in glc_rxintr()
759 mtx_unlock(&sc->sc_mtx); in glc_rxintr()
761 mtx_lock(&sc->sc_mtx); in glc_rxintr()
764 glc_add_rxbuf_dma(sc, i); in glc_rxintr()
767 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map, in glc_rxintr()
771 error = lv1_net_start_rx_dma(sc->sc_bus, sc->sc_dev, in glc_rxintr()
772 sc->sc_rxsoft[sc->sc_next_rxdma_slot].rxs_desc, 0); in glc_rxintr()
774 device_printf(sc->sc_self, in glc_rxintr()
780 glc_txintr(struct glc_softc *sc) in glc_txintr() argument
782 if_t ifp = sc->sc_ifp; in glc_txintr()
786 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_txdmadesc_map, in glc_txintr()
789 while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) { in glc_txintr()
790 if (sc->sc_txdmadesc[txs->txs_lastdesc].cmd_stat in glc_txintr()
794 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q); in glc_txintr()
795 bus_dmamap_unload(sc->sc_txdma_tag, txs->txs_dmamap); in glc_txintr()
796 sc->bsy_txdma_slots -= txs->txs_ndescs; in glc_txintr()
803 if ((sc->sc_txdmadesc[txs->txs_lastdesc].cmd_stat & 0xf0000000) in glc_txintr()
805 lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0); in glc_txintr()
810 if (sc->sc_txdmadesc[txs->txs_lastdesc].cmd_stat & in glc_txintr()
814 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q); in glc_txintr()
820 sc->first_used_txdma_slot = txs->txs_firstdesc; in glc_txintr()
822 sc->first_used_txdma_slot = -1; in glc_txintr()
826 error = lv1_net_start_tx_dma(sc->sc_bus, sc->sc_dev, in glc_txintr()
827 sc->sc_txdmadesc_phys + in glc_txintr()
831 device_printf(sc->sc_self, in glc_txintr()
841 sc->sc_wdog_timer = STAILQ_EMPTY(&sc->sc_txdirtyq) ? 0 : 5; in glc_txintr()
852 struct glc_softc *sc = xsc; in glc_intr_filter() local
855 atomic_set_64(&sc->sc_interrupt_status, *sc->sc_hwirq_status); in glc_intr_filter()
862 struct glc_softc *sc = xsc; in glc_intr() local
865 mtx_lock(&sc->sc_mtx); in glc_intr()
867 status = atomic_readandclear_64(&sc->sc_interrupt_status); in glc_intr()
870 mtx_unlock(&sc->sc_mtx); in glc_intr()
875 glc_rxintr(sc); in glc_intr()
878 glc_txintr(sc); in glc_intr()
881 lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_LINK_STATUS, in glc_intr()
886 if_link_state_change(sc->sc_ifp, linkstat); in glc_intr()
889 mtx_unlock(&sc->sc_mtx); in glc_intr()
895 struct glc_softc *sc = if_getsoftc(ifp); in glc_media_status() local
901 lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_LINK_STATUS, in glc_media_status()
923 struct glc_softc *sc = if_getsoftc(ifp); in glc_media_change() local
927 if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER) in glc_media_change()
930 switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { in glc_media_change()
947 if (IFM_OPTIONS(sc->sc_media.ifm_media) & IFM_FDX) in glc_media_change()
950 result = lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_SET_LINK_MODE, in glc_media_change()