Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jul 2000 22:15:45 +0200 (CEST)
From:      =?ISO-8859-1?Q?G=E9rard_Roudier?= <groudier@club-internet.fr>
To:        Andrew Gallatin <gallatin@cs.duke.edu>
Cc:        Bernd Walter <ticso@cicely8.cicely.de>, dg@root.com, mjacob@feral.com, Mike Smith <msmith@FreeBSD.ORG>, freebsd-alpha@FreeBSD.ORG
Subject:   Re: fxp0 hangs on a PC164 using STABLE
Message-ID:  <Pine.LNX.4.10.10007182135430.1638-100000@linux.local>
In-Reply-To: <14707.48450.371071.494543@grasshopper.cs.duke.edu>

next in thread | previous in thread | raw e-mail | index | archive | help



On Mon, 17 Jul 2000, Andrew Gallatin wrote:
 
> Bernd Walter writes:
>  > On Fri, Jul 14, 2000 at 05:23:21PM -0400, Andrew Gallatin wrote:
>  > > As for the bug. I can duplicate it I run both the sender & receiver
>  > > fairly hard, like 2 100Mb/tcp connections running in opposite
>  > > directions.   When I do this, it looks like the xmit side locks up but 
>  > > the recv. side is at least partially OK.  And I'm still getting stats
>  > > updates. 
>  > 
>  > Looks like you are on the right way.
>  > I can download a big file to the host without any problems but cvsup gets
>  > the interface stoped quite soon.
> 
> The problem is that the status & command field share a 32-bit word.
> The programming API of the eepro apparently requires that you update
> the status field of a transmit slot that you've given to the card.
> Since alphas can only operate on 32-bit chunks of memory, both the
> status & command fields are loaded into memory & operated on in
> registers when the following line of C is executed:
> 
> 		/*
> 		 * Advance the end of list forward.
> 		 */
> 		sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;

I am not an Alpha expert, but my reading of the Alpha Architecture
Handbook rev. 4 let me think that not too old Alpha Systems should allow
atomic WORD and BYTE memory access from agents on the system BUS. CPUs
with AMASK bit 0 set support proper intructions for doing such kind of
access.
If the C compiler does not want to generate the corresponding code, then 
assembly is to be used. The assembly will force compiler barrier, but if 
C can be used, may-be a volatile cast should be used to force such a 
barrier.
You may also want to add a memory barrier in places where some strong 
ordering regarding how LOADs and STOREs are carried out to the system 
BUS is expected.

> The race is caused by the card DMA'ing up the status at just the wrong
> time -- after it has been loaded into a register & before it has been
> written back.  The old value of the status is written back, clobbering
> the status the card just DMA'ed up. The fact that the card has sent
> this frame is missed & the transmit engine appears to hang.
> 
> I think I have a fix.  It feels like overkill, but if the programming
> interface of the chip does not allow for something better why not just
> turn off DMA while we update cb_command?
> 
> Can anybody having problems with fxp's please try the appended patch?
> Without this patch, I have a test case that can lock the xmitter in <
> 5 seconds 100% of the time.  With the patch, I've been unable to get
> it to lock up using this test case.
> 
> Can a PCI expert comment on its safety?  Mike?

As a PCI non-expert, I may comment on its apparent brokenness. ;-)
Clearing the PCI BUS MASTER ENABLE bit is generally not a documented way
to tell a `running' PCI device to suspend DMA and wait for the bit to be
set again prior to continuing operations. This is likely to confuse most
PCI devices, in my opinion.

I hope I haven't been too wrong. :-)

  Gérard.

> Index: pci/if_fxp.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/pci/if_fxp.c,v
> retrieving revision 1.77.2.4
> diff -u -r1.77.2.4 if_fxp.c
> --- pci/if_fxp.c	2000/07/13 07:53:06	1.77.2.4
> +++ pci/if_fxp.c	2000/07/18 02:07:04
> @@ -527,6 +527,8 @@
>  
>  	callout_handle_init(&sc->stat_ch);
>  
> +	sc->dev = dev;
> +
>  	s = splimp();
>  
>  	/*
> @@ -535,6 +537,7 @@
>  	val = pci_read_config(dev, PCIR_COMMAND, 2);
>  	val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
>  	pci_write_config(dev, PCIR_COMMAND, val, 2);
> +	sc->cmd = val;
>  
>  	/*
>  	 * Map control/status registers.
> @@ -960,6 +963,7 @@
>  {
>  	struct fxp_softc *sc = ifp->if_softc;
>  	struct fxp_cb_tx *txp;
> +	int s;
>  
>  	/*
>  	 * See if we need to suspend xmit until the multicast filter
> @@ -1052,10 +1056,24 @@
>  		}
>  		txp->tx_threshold = tx_threshold;
>  	
> +#ifdef __alpha__
> +		/*
> +		 * Prevent the card from DMA'ing up the status while
> +		 * we update the command field.  This could cause
> +		 * us to overwrite the completion status.
> +		 */
> +		s = splhigh();
> +		pci_write_config(sc->dev, PCIR_COMMAND, 
> +		    (sc->cmd & ~PCIM_CMD_BUSMASTEREN), 2);
> +#endif /*alpha*/
>  		/*
>  		 * Advance the end of list forward.
>  		 */
>  		sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
> +#ifdef __alpha__
> +		pci_write_config(sc->dev, PCIR_COMMAND, sc->cmd, 2);
> +		splx(s);
> +#endif /*alpha*/
>  		sc->cbl_last = txp;
>  
>  		/*
> Index: pci/if_fxpvar.h
> ===================================================================
> RCS file: /home/ncvs/src/sys/pci/if_fxpvar.h,v
> retrieving revision 1.9.2.1
> diff -u -r1.9.2.1 if_fxpvar.h
> --- pci/if_fxpvar.h	2000/03/29 02:02:39	1.9.2.1
> +++ pci/if_fxpvar.h	2000/07/18 02:03:50
> @@ -48,6 +48,7 @@
>  	struct resource *mem;		/* resource descriptor for registers */
>  	struct resource *irq;		/* resource descriptor for interrupt */
>  	void *ih;			/* interrupt handler cookie */
> +	device_t dev;			/* newbus device pointer */
>  #endif /* __NetBSD__ */
>  	bus_space_tag_t sc_st;		/* bus space tag */
>  	bus_space_handle_t sc_sh;	/* bus space handle */
> @@ -68,6 +69,7 @@
>  	int phy_primary_device;		/* device type of primary PHY */
>  	int phy_10Mbps_only;		/* PHY is 10Mbps-only device */
>  	int eeprom_size;		/* size of serial EEPROM */
> +	u_long cmd;			/* contents of pci CMD register */
>  };
>  
>  /* Macros to ease CSR access. */
> 
> 
> Cheers,
> 
> Drew
> ------------------------------------------------------------------------------
> Andrew Gallatin, Sr Systems Programmer	http://www.cs.duke.edu/~gallatin
> Duke University				Email: gallatin@cs.duke.edu
> Department of Computer Science		Phone: (919) 660-6590



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.4.10.10007182135430.1638-100000>