#!/bin/sh
file2patch="linux/drivers/net/arm/ns9750_eth.c";
if test ! -f $file2patch \
	|| test "b269eee6317783f596cb5e39a8adc759" == "`md5sum \"$file2patch\" | cut -b 1-32`" \
	|| grep -E -e "^AC_INIT\(\[LxNETES\], \[3.2p4\]\)" configure.ac >/dev/null; then
		echo "Either the current working directory is not an"
		echo "installation of LxNETES-3.2 with patch3 applied"
		echo "or this patch is already applied."
	exit 2;
fi
patch -p0 << \EOF
*** linux/drivers/net/arm/ns9750_eth.c	Fri Aug  4 11:06:10 2006
--- linux/drivers/net/arm/ns9750_eth.c	Fri Aug  4 11:30:39 2006
***************
*** 3,9 ****
   * Copyright (C) 2004 by FS Forth-Systeme GmbH.
   * All rights reserved.
   *
!  * $Id: ns9750_eth.c,v 1.6.2.1 2005/10/26 11:15:01 uzeisberger Exp $
   * @Author: Markus Pietrek
   * @Descr: Ethernet driver for the NS9750.
   * @References: [1] NS9750 Hardware Reference, December 2003
--- 3,9 ----
   * Copyright (C) 2004 by FS Forth-Systeme GmbH.
   * All rights reserved.
   *
!  * $Id: ns9750_eth.c,v 1.6.2.2 2006-07-10 08:25:39 tkuhlman Exp $
   * @Author: Markus Pietrek
   * @Descr: Ethernet driver for the NS9750.
   * @References: [1] NS9750 Hardware Reference, December 2003
***************
*** 12,17 ****
--- 12,18 ----
   *              [4] u-boot-1.0.2/drivers/ns9750_eth.c
   *              [5] drivers/net/pci_skeleton.c
   *              [6] drivers/net/isa_skeleton.c
+  *              [7] appnote_ethernetrx_9750.pdf
   * @TODO:
   *    o add media change interrupts, cable looses etc.
   *    o split sizes for RX DMA  descriptors
***************
*** 43,48 ****
--- 44,50 ----
   ***********************************************************************/
  /***********************************************************************
   *  @History:
+  *	2006/05/11 : Ethernet Receive Data FIFO Overflow fixed [7]
   *	2005/09/14 : CC9C added
   *	2005/06/02 : multicast, promiscuous and all multicast mode added (Bernd Westermann)
   *	2005/03/04 : NS9360 added
***************
*** 111,117 ****
  			__FUNCTION__,__LINE__,#expr);		      \
          	func }
  #else /* DEBUG */
! # define printk(...) do {} while( 0 )
  # define DEBUG_ARGS0( FLG, a0 ) do {} while( 0 )
  # define DEBUG_ARGS1( FLG, a0, a1 ) do {} while( 0 )
  # define DEBUG_ARGS2( FLG, a0, a1, a2 ) do {} while( 0 )
--- 113,119 ----
  			__FUNCTION__,__LINE__,#expr);		      \
          	func }
  #else /* DEBUG */
! // # define printk(...) do {} while( 0 )
  # define DEBUG_ARGS0( FLG, a0 ) do {} while( 0 )
  # define DEBUG_ARGS1( FLG, a0, a1 ) do {} while( 0 )
  # define DEBUG_ARGS2( FLG, a0, a1, a2 ) do {} while( 0 )
***************
*** 274,280 ****
  	flags:			IFF_MULTICAST | IFF_BROADCAST
  };
  
! static const char* version = "Ethernet: NS9xx0 driver $Revision: 1.6.2.1 $\n";
  
  static unsigned int phy_mdio_max_clk = PHY_MDIO_MAX_CLK;
  static unsigned char link_mode       = FS_EEPROM_AUTONEG_ENABLE;
--- 276,282 ----
  	flags:			IFF_MULTICAST | IFF_BROADCAST
  };
  
! static const char* version = "Ethernet: NS9xx0 driver $Revision: 1.6.2.2 $\n";
  
  static unsigned int phy_mdio_max_clk = PHY_MDIO_MAX_CLK;
  static unsigned char link_mode       = FS_EEPROM_AUTONEG_ENABLE;
***************
*** 526,531 ****
--- 528,565 ----
  
  }
  
+ static void ns_eth_recover_rxovl_stall( struct net_device* dev )
+ {
+         ns_eth_private_t* priv = dev->priv;
+ 	int i;
+ 	
+ 	rmwl( NS_ETH_EGCR1, & ~(NS_ETH_EGCR1_ERX | NS_ETH_EGCR1_ERXDMA ) );
+ 	rmwl( NS_ETH_MAC1, & ~NS_ETH_MAC1_RXEN );
+ 	rmwl( NS_ETH_EINTR, | NS_ETH_EINTR_RXOVL_DATA );
+ 	
+ 	for( i = 0; i < NS_RX_DESC; i++ )
+ 	{		
+ 		priv->rx_desc[ i ].len = NS_ETH_FRAME_LEN;
+ 		/* mark only the last desc in the ring to be wrap */
+ 		priv->rx_desc[ i ].s.bits.wrap=!((i+1)%(NS_RX_DESC_RING))?1:0;
+ 		priv->rx_desc[ i ].s.bits.intr = 0;
+ 		priv->rx_desc[ i ].s.bits.enable = 1;
+ 		priv->rx_desc[ i ].s.bits.full = 0;
+ 	}
+ 	
+ 	for( i = 0; i < NS_RX_RINGS; i++ )
+ 		writel((unsigned int) (priv->rx_dma_desc + i*NS_RX_DESC_RING),
+ 			NS_ETH_RXAPTR + i * 4 );
+ 	
+ 	rmwl( NS_ETH_EGSR, | NS_ETH_EGSR_RXINIT );
+ 	rmwl( NS_ETH_EGCR1, | NS_ETH_EGCR1_ERX );
+ 	
+ 	ns_eth_update_rx_desc( dev );
+ 	
+ 	rmwl( NS_ETH_MAC1, | NS_ETH_MAC1_RXEN );
+ 	
+ }
+ 
  static irqreturn_t ns_eth_rx_int( int irq, void* dev_id,struct pt_regs* regs )
  {
  	struct net_device* dev = (struct net_device*) dev_id;
***************
*** 546,553 ****
--- 580,593 ----
  		      NS_ETH_EINTR_RXBUFFUL |
  		      NS_ETH_EINTR_RXOVL_DATA |
  		      NS_ETH_EINTR_RXOVL_STAT) )
+ 	{
  		printk( KERN_CRIT "%s: rx error status: 0x%x\n",
  			__FUNCTION__, status );
+ 			
+ 		if( status & NS_ETH_EINTR_RXOVL_DATA )
+ 			ns_eth_recover_rxovl_stall( dev );
+ 	}
+ 			
  
  	mask = NS_ETH_EINTR_RXDONEA;
  	for( ring = 0; ring < NS_RX_RINGS; ring++ ) {

EOF
echo "patching file configure.ac";
perl -p -i -e 's/^AC_INIT\(\[LxNETES\], \[3.2p3\]\)/AC_INIT\(\[LxNETES\], \[3.2p4\]\)/' configure.ac;
