Skip site navigation (1)Skip section navigation (2)
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>