Deleted Added
sdiff udiff text old ( 217044 ) new ( 223324 )
full compact
1/*-
2 * Copyright (C) 2010 Nathan Whitehorn
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 8 unchanged lines hidden (view full) ---

17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * $FreeBSD: head/sys/powerpc/ps3/if_glc.c 223324 2011-06-20 02:17:34Z nwhitehorn $
26 */
27
28#include <sys/param.h>
29#include <sys/systm.h>
30#include <sys/sockio.h>
31#include <sys/endian.h>
32#include <sys/mbuf.h>
33#include <sys/module.h>

--- 96 unchanged lines hidden (view full) ---

130 sc->sc_dev = ps3bus_get_device(dev);
131 sc->sc_self = dev;
132
133 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
134 MTX_DEF);
135 callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
136 sc->next_txdma_slot = 0;
137 sc->bsy_txdma_slots = 0;
138 sc->sc_next_rxdma_slot = 0;
139 sc->first_used_txdma_slot = -1;
140
141 /*
142 * Shut down existing tasks.
143 */
144
145 lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0);
146 lv1_net_stop_rx_dma(sc->sc_bus, sc->sc_dev, 0);

--- 224 unchanged lines hidden (view full) ---

371
372static void
373glc_tick(void *xsc)
374{
375 struct glc_softc *sc = xsc;
376
377 mtx_assert(&sc->sc_mtx, MA_OWNED);
378
379 /*
380 * XXX: Sometimes the RX queue gets stuck. Poke it periodically until
381 * we figure out why. This will fail harmlessly if the RX queue is
382 * already running.
383 */
384 lv1_net_start_rx_dma(sc->sc_bus, sc->sc_dev,
385 sc->sc_rxsoft[sc->sc_next_rxdma_slot].rxs_desc, 0);
386
387 if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) {
388 callout_reset(&sc->sc_tick_ch, hz, glc_tick, sc);
389 return;
390 }
391
392 /* Problems */
393 device_printf(sc->sc_self, "device timeout\n");
394

--- 316 unchanged lines hidden (view full) ---

711static void
712glc_rxintr(struct glc_softc *sc)
713{
714 int i, restart_rxdma, error;
715 struct mbuf *m;
716 struct ifnet *ifp = sc->sc_ifp;
717
718 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map,
719 BUS_DMASYNC_POSTREAD);
720
721 restart_rxdma = 0;
722 while ((sc->sc_rxdmadesc[sc->sc_next_rxdma_slot].cmd_stat &
723 GELIC_DESCR_OWNED) == 0) {
724 i = sc->sc_next_rxdma_slot;
725 sc->sc_next_rxdma_slot++;
726 if (sc->sc_next_rxdma_slot >= GLC_MAX_RX_PACKETS)
727 sc->sc_next_rxdma_slot = 0;
728
729 if (sc->sc_rxdmadesc[i].cmd_stat & GELIC_CMDSTAT_CHAIN_END)
730 restart_rxdma = 1;
731
732 if (sc->sc_rxdmadesc[i].rxerror & GELIC_RXERRORS) {
733 ifp->if_ierrors++;
734 goto requeue;
735 }
736
737 m = sc->sc_rxsoft[i].rxs_mbuf;
738 if (sc->sc_rxdmadesc[i].data_stat & GELIC_RX_IPCSUM) {
739 m->m_pkthdr.csum_flags |=

--- 9 unchanged lines hidden (view full) ---

749 ifp->if_ierrors++;
750 goto requeue;
751 }
752
753 ifp->if_ipackets++;
754 m->m_pkthdr.rcvif = ifp;
755 m->m_len = sc->sc_rxdmadesc[i].valid_size;
756 m->m_pkthdr.len = m->m_len;
757
758 if (sc->sc_rx_vlan >= 0)
759 m_adj(m, 2);
760
761 mtx_unlock(&sc->sc_mtx);
762 (*ifp->if_input)(ifp, m);
763 mtx_lock(&sc->sc_mtx);
764
765 requeue:
766 glc_add_rxbuf_dma(sc, i);
767 }
768
769 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map,
770 BUS_DMASYNC_PREWRITE);
771
772 if (restart_rxdma) {
773 error = lv1_net_start_rx_dma(sc->sc_bus, sc->sc_dev,
774 sc->sc_rxsoft[sc->sc_next_rxdma_slot].rxs_desc, 0);
775 if (error != 0)
776 device_printf(sc->sc_self,
777 "lv1_net_start_rx_dma error: %d\n", error);
778 }
779}
780
781static void
782glc_txintr(struct glc_softc *sc)
783{
784 struct ifnet *ifp = sc->sc_ifp;
785 struct glc_txsoft *txs;
786 int progress = 0, kickstart = 0, error;
787
788 bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_txdmadesc_map,
789 BUS_DMASYNC_POSTREAD);
790
791 while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
792 if (sc->sc_txdmadesc[txs->txs_lastdesc].cmd_stat
793 & GELIC_DESCR_OWNED)
794 break;
795
796 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
797 bus_dmamap_unload(sc->sc_txdma_tag, txs->txs_dmamap);
798 sc->bsy_txdma_slots -= txs->txs_ndescs;

--- 19 unchanged lines hidden (view full) ---

818 progress = 1;
819 }
820
821 if (txs != NULL)
822 sc->first_used_txdma_slot = txs->txs_firstdesc;
823 else
824 sc->first_used_txdma_slot = -1;
825
826 if (kickstart || txs != NULL) {
827 /* Speculatively (or necessarily) start the TX queue again */
828 error = lv1_net_start_tx_dma(sc->sc_bus, sc->sc_dev,
829 sc->sc_txdmadesc_phys +
830 txs->txs_firstdesc*sizeof(struct glc_dmadesc), 0);
831 if (error != 0)
832 device_printf(sc->sc_self,
833 "lv1_net_start_tx_dma error: %d\n", error);
834 }
835

--- 122 unchanged lines hidden ---