patch-2.4.20 linux-2.4.20/drivers/net/sis900.c
Next file: linux-2.4.20/drivers/net/sis900.h
Previous file: linux-2.4.20/drivers/net/sgiseeq.h
Back to the patch index
Back to the overall index
- Lines: 157
- Date:
Thu Nov 28 15:53:14 2002
- Orig file:
linux-2.4.19/drivers/net/sis900.c
- Orig date:
Fri Aug 2 17:39:44 2002
diff -urN linux-2.4.19/drivers/net/sis900.c linux-2.4.20/drivers/net/sis900.c
@@ -1,6 +1,6 @@
/* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
Copyright 1999 Silicon Integrated System Corporation
- Revision: 1.08.04 Apr. 25 2002
+ Revision: 1.08.06 Sep. 24 2002
Modified from the driver which is originally written by Donald Becker.
@@ -18,6 +18,8 @@
preliminary Rev. 1.0 Jan. 18, 1998
http://www.sis.com.tw/support/databook.htm
+ Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
+ Rev 1.08.05 Jun. 6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary
Rev 1.08.04 Apr. 25 2002 Mufasa Yang <mufasa@sis.com.tw> added SiS962 support
Rev 1.08.03 Feb. 1 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
Rev 1.08.02 Nov. 30 2001 Hui-Fen Hsu workaround for EDB & bug fix for dhcp problem
@@ -72,7 +74,7 @@
#include "sis900.h"
#define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.04 4/25/2002"
+#define SIS900_DRV_VERSION "v1.08.06 9/24/2002"
static char version[] __devinitdata =
KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -309,31 +311,38 @@
}
/**
- * sis962_get_mac_addr: - Get MAC address for SiS962 model
+ * sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
* @pci_dev: the sis900 pci device
* @net_dev: the net device to get address for
*
- * SiS962 model, use EEPROM to store MAC address. And EEPROM is shared by
+ * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
+ * is shared by
* LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
* and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
* by LAN, otherwise is not. After MAC address is read from EEPROM, send
* EEDONE signal to refuse EEPROM access by LAN.
+ * The EEPROM map of SiS962 or SiS963 is different to SiS900.
+ * The signature field in SiS962 or SiS963 spec is meaningless.
* MAC address is read into @net_dev->dev_addr.
*/
-static int __devinit sis962_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
{
long ioaddr = net_dev->base_addr;
long ee_addr = ioaddr + mear;
u32 waittime = 0;
- int ret = 0;
+ int i;
outl(EEREQ, ee_addr);
while(waittime < 2000) {
if(inl(ee_addr) & EEGNT) {
- ret = sis900_get_mac_addr(pci_dev, net_dev);
+
+ /* get MAC address from EEPROM */
+ for (i = 0; i < 3; i++)
+ ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
+
outl(EEDONE, ee_addr);
- return(ret);
+ return 1;
} else {
udelay(1);
waittime ++;
@@ -443,8 +452,8 @@
ret = sis630e_get_mac_addr(pci_dev, net_dev);
else if ((revision > 0x81) && (revision <= 0x90) )
ret = sis635_get_mac_addr(pci_dev, net_dev);
- else if (revision == SIS962_900_REV)
- ret = sis962_get_mac_addr(pci_dev, net_dev);
+ else if (revision == SIS96x_900_REV)
+ ret = sis96x_get_mac_addr(pci_dev, net_dev);
else
ret = sis900_get_mac_addr(pci_dev, net_dev);
@@ -702,7 +711,7 @@
outl(0, ee_addr);
eeprom_delay();
- outl(EECLK, ee_addr);
+ outl(EECS, ee_addr);
eeprom_delay();
/* Shift the read command (9) bits out. */
@@ -713,7 +722,7 @@
outl(dataval | EECLK, ee_addr);
eeprom_delay();
}
- outb(EECS, ee_addr);
+ outl(EECS, ee_addr);
eeprom_delay();
/* read the 16-bits data in */
@@ -729,7 +738,6 @@
/* Terminate the EEPROM access. */
outl(0, ee_addr);
eeprom_delay();
- outl(EECLK, ee_addr);
return (retval);
}
@@ -1432,8 +1440,8 @@
net_dev->trans_start = jiffies;
- /* FIXME: Should we restart the transmission thread here ?? */
- outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
+ /* load Transmit Descriptor Register */
+ outl(sis_priv->tx_ring_dma, ioaddr + txdp);
/* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
@@ -1457,6 +1465,8 @@
long ioaddr = net_dev->base_addr;
unsigned int entry;
unsigned long flags;
+ unsigned int index_cur_tx, index_dirty_tx;
+ unsigned int count_dirty_tx;
/* Don't transmit data before the complete of auto-negotiation */
if(!sis_priv->autong_complete){
@@ -1476,7 +1486,18 @@
sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
- if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
+ sis_priv->cur_tx ++;
+ index_cur_tx = sis_priv->cur_tx;
+ index_dirty_tx = sis_priv->dirty_tx;
+
+ for (count_dirty_tx = 0; index_cur_tx != index_dirty_tx; index_dirty_tx++)
+ count_dirty_tx ++;
+
+ if (index_cur_tx == index_dirty_tx) {
+ /* dirty_tx is met in the cycle of cur_tx, buffer full */
+ sis_priv->tx_full = 1;
+ netif_stop_queue(net_dev);
+ } else if (count_dirty_tx < NUM_TX_DESC) {
/* Typical path, tell upper layer that more transmission is possible */
netif_start_queue(net_dev);
} else {
@@ -1709,7 +1730,7 @@
{
struct sis900_private *sis_priv = net_dev->priv;
- for (; sis_priv->dirty_tx < sis_priv->cur_tx; sis_priv->dirty_tx++) {
+ for (; sis_priv->dirty_tx != sis_priv->cur_tx; sis_priv->dirty_tx++) {
struct sk_buff *skb;
unsigned int entry;
u32 tx_status;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)