Date: Thu, 19 Dec 2002 14:57:30 +0000 From: Steve Burton <steve@sliderule.demon.co.uk> To: Thomas Nystrom <thn@saeab.se> Cc: stable@freebsd.org Subject: Re: Fix for hanging of vr interface (Rhine Ethernet) Message-ID: <3E01DE5A.265553D0@sliderule.demon.co.uk> References: <3DFBACE7.1D60335F@saeab.se>
next in thread | previous in thread | raw e-mail | index | archive | help
Thomas,
I hope you're not taking the lack of replies for lack of interest. I for
one am very interested in seeing the vr bug fixed as I hope to (soon)
build a VIA mini-itx based PC and the VIA motherboards have an embedded
Rhine II controller. I just don't happen to have a Rhine II board
anywhere about at the moment.
Steve.
Thomas Nystrom wrote:
>
> Hello list!
>
> There have been some issues with hanging of the vr-type of
> ethernetcontrollers. I have made a patch that solves some problems and I'm
> now seeking people to test it. Please apply the attached patch to your
> vr-driver and see if it solves any problems for you. I have tested (and
> made) the patch on a 4.7-RELEASE with the latest vr-drivers.
>
> /thn
>
> --
> ---------------------------------------------------------------
> Svensk Aktuell Elektronik AB Thomas Nystrm
> Box 10 Phone: +46 8 35 92 85
> S-191 21 Sollentuna Fax: +46 8 59 47 45 36
> Sweden Email: thn@saeab.se
> ---------------------------------------------------------------
>
> ------------------------------------------------------------------------
> --- /root/vr/if_vr.c Thu Dec 12 15:05:50 2002
> +++ if_vr.c Fri Dec 13 15:25:13 2002
> @@ -991,33 +991,23 @@
> */
> if (rxstat & VR_RXSTAT_RXERR) {
> ifp->if_ierrors++;
> - printf("vr%d: rx error: ", sc->vr_unit);
> - switch(rxstat & 0x000000FF) {
> - case VR_RXSTAT_CRCERR:
> - printf("crc error\n");
> - break;
> - case VR_RXSTAT_FRAMEALIGNERR:
> - printf("frame alignment error\n");
> - break;
> - case VR_RXSTAT_FIFOOFLOW:
> - printf("FIFO overflow\n");
> - break;
> - case VR_RXSTAT_GIANT:
> - printf("received giant packet\n");
> - break;
> - case VR_RXSTAT_RUNT:
> - printf("received runt packet\n");
> - break;
> - case VR_RXSTAT_BUSERR:
> - printf("system bus error\n");
> - break;
> - case VR_RXSTAT_BUFFERR:
> - printf("rx buffer error\n");
> - break;
> - default:
> - printf("unknown rx error\n");
> - break;
> - }
> + printf("vr%d: rx error (%02x):",
> + sc->vr_unit, rxstat & 0x000000ff);
> + if (rxstat & VR_RXSTAT_CRCERR)
> + printf(" crc error");
> + if (rxstat & VR_RXSTAT_FRAMEALIGNERR)
> + printf(" frame alignment error\n");
> + if (rxstat & VR_RXSTAT_FIFOOFLOW)
> + printf(" FIFO overflow");
> + if (rxstat & VR_RXSTAT_GIANT)
> + printf(" received giant packet");
> + if (rxstat & VR_RXSTAT_RUNT)
> + printf(" received runt packet");
> + if (rxstat & VR_RXSTAT_BUSERR)
> + printf(" system bus error");
> + if (rxstat & VR_RXSTAT_BUFFERR)
> + printf("rx buffer error");
> + printf("\n");
> vr_newbuf(sc, cur_rx, m);
> continue;
> }
> @@ -1058,9 +1048,29 @@
> void vr_rxeoc(sc)
> struct vr_softc *sc;
> {
> + struct ifnet *ifp;
> + int i;
> +
> + ifp = &sc->arpcom.ac_if;
> +
> + ifp->if_ierrors++;
> +
> + VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_RX_ON);
> + DELAY(10000);
> +
> + for (i = 0x400;
> + i && (CSR_READ_2(sc, VR_COMMAND) & VR_CMD_RX_ON);
> + i--)
> + ; /* Wait for receiver to stop */
> +
> + if (!i) {
> + printf("vr%d: rx shutdown error!\n", sc->vr_unit);
> + sc->vr_flags |= VR_F_RESTART;
> + return;
> + }
>
> vr_rxeof(sc);
> - VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_RX_ON);
> +
> CSR_WRITE_4(sc, VR_RXADDR, vtophys(sc->vr_cdata.vr_rx_head->vr_ptr));
> VR_SETBIT16(sc, VR_COMMAND, VR_CMD_RX_ON);
> VR_SETBIT16(sc, VR_COMMAND, VR_CMD_RX_GO);
> @@ -1094,14 +1104,22 @@
> */
> while(sc->vr_cdata.vr_tx_head->vr_mbuf != NULL) {
> u_int32_t txstat;
> + int i;
>
> cur_tx = sc->vr_cdata.vr_tx_head;
> txstat = cur_tx->vr_ptr->vr_status;
>
> if ((txstat & VR_TXSTAT_ABRT) ||
> (txstat & VR_TXSTAT_UDF)) {
> - while (CSR_READ_2(sc, VR_COMMAND) & VR_CMD_TX_ON)
> + for (i = 0x400;
> + i && (CSR_READ_2(sc, VR_COMMAND) & VR_CMD_TX_ON);
> + i--)
> ; /* Wait for chip to shutdown */
> + if (!i) {
> + printf("vr%d: tx shutdown timeout\n", sc->vr_unit);
> + sc->vr_flags |= VR_F_RESTART;
> + break;
> + }
> VR_TXOWN(cur_tx) = VR_TXSTAT_OWN;
> CSR_WRITE_4(sc, VR_TXADDR, vtophys(cur_tx->vr_ptr));
> break;
> @@ -1167,6 +1185,14 @@
> s = splimp();
>
> sc = xsc;
> + if (sc->vr_flags & VR_F_RESTART) {
> + printf("vr%d: restarting\n", sc->vr_unit);
> + vr_stop(sc);
> + vr_reset(sc);
> + vr_init(sc);
> + sc->vr_flags &= ~VR_F_RESTART;
> + }
> +
> mii = device_get_softc(sc->vr_miibus);
> mii_tick(mii);
>
> @@ -1208,10 +1234,22 @@
> if (status & VR_ISR_RX_OK)
> vr_rxeof(sc);
>
> + if (status & VR_ISR_RX_DROPPED) {
> + printf("vr%d: rx packet lost\n", sc->vr_unit);
> + ifp->if_ierrors++;
> + }
> +
> if ((status & VR_ISR_RX_ERR) || (status & VR_ISR_RX_NOBUF) ||
> - (status & VR_ISR_RX_NOBUF) || (status & VR_ISR_RX_OFLOW) ||
> - (status & VR_ISR_RX_DROPPED)) {
> - vr_rxeof(sc);
> + (status & VR_ISR_RX_NOBUF) || (status & VR_ISR_RX_OFLOW)) {
> + printf("vr%d: receive error (%04x)",
> + sc->vr_unit, status);
> + if (status & VR_ISR_RX_NOBUF)
> + printf(" no buffers");
> + if (status & VR_ISR_RX_OFLOW)
> + printf(" overflow");
> + if (status & VR_ISR_RX_DROPPED)
> + printf(" packet lost");
> + printf("\n");
> vr_rxeoc(sc);
> }
>
> @@ -1430,13 +1468,13 @@
> * so we must set both.
> */
> VR_CLRBIT(sc, VR_BCR0, VR_BCR0_RX_THRESH);
> - VR_SETBIT(sc, VR_BCR0, VR_BCR0_RXTHRESHSTORENFWD);
> + VR_SETBIT(sc, VR_BCR0, VR_BCR0_RXTHRESH128BYTES);
>
> VR_CLRBIT(sc, VR_BCR1, VR_BCR1_TX_THRESH);
> VR_SETBIT(sc, VR_BCR1, VR_BCR1_TXTHRESHSTORENFWD);
>
> VR_CLRBIT(sc, VR_RXCFG, VR_RXCFG_RX_THRESH);
> - VR_SETBIT(sc, VR_RXCFG, VR_RXTHRESH_STORENFWD);
> + VR_SETBIT(sc, VR_RXCFG, VR_RXTHRESH_128BYTES);
>
> VR_CLRBIT(sc, VR_TXCFG, VR_TXCFG_TX_THRESH);
> VR_SETBIT(sc, VR_TXCFG, VR_TXTHRESH_STORENFWD);
> --- /root/vr/if_vrreg.h Thu Dec 12 15:07:25 2002
> +++ if_vrreg.h Thu Dec 12 14:35:44 2002
> @@ -464,10 +464,13 @@
> u_int8_t vr_unit; /* interface number */
> u_int8_t vr_type;
> u_int8_t vr_revid; /* Rhine chip revision */
> + u_int8_t vr_flags; /* See VR_F_* below */
> struct vr_list_data *vr_ldata;
> struct vr_chain_data vr_cdata;
> struct callout_handle vr_stat_ch;
> };
> +
> +#define VR_F_RESTART 0x01 /* Restart unit on next tick */
>
> /*
> * register space access macros
--
Steve Burton
Webmaster & Sub-optimal Coder
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E01DE5A.265553D0>
