patch-2.3.45 linux/drivers/net/sis900.c
Next file: linux/drivers/net/sk_g16.c
Previous file: linux/drivers/net/seeq8005.c
Back to the patch index
Back to the overall index
- Lines: 118
- Date:
Sun Feb 13 18:51:08 2000
- Orig file:
v2.3.44/linux/drivers/net/sis900.c
- Orig date:
Sat Feb 12 11:22:10 2000
diff -u --recursive --new-file v2.3.44/linux/drivers/net/sis900.c linux/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.06.03 Dec 23 1999
+ Revision: 1.06.04 Feb 11 2000
Modified from the driver which is originally written by Donald Becker.
@@ -135,7 +135,7 @@
int LinkOn;
};
-MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>");
+MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
MODULE_PARM(multicast_filter_limit, "i");
MODULE_PARM(max_interrupt_work, "i");
@@ -257,7 +257,7 @@
net_dev->irq = irq;
sis_priv->pci_dev = pci_dev;
sis_priv->mac = mac;
- sis_priv->lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&sis_priv->lock);
/* probe for mii transciver */
if (sis900_mii_probe(net_dev) == 0) {
@@ -668,8 +668,8 @@
next_tick = 5*HZ;
/* change what cur_phy means */
if (mii_phy->phy_addr != sis_priv->cur_phy) {
- printk(KERN_INFO "%s: Changing transceiver to %s\n", net_dev->name,
- mii_phy->chip_info->name);
+ printk(KERN_INFO "%s: Changing transceiver to %s\n",
+ net_dev->name, mii_phy->chip_info->name);
status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
mdio_write(net_dev, sis_priv->cur_phy,
MII_CONTROL, status | MII_CNTL_ISOLATE);
@@ -798,9 +798,10 @@
/* Disable interrupts by clearing the interrupt mask. */
outl(0x0000, ioaddr + imr);
- /* discard unsent packets, should this code section be protected by
- cli(), sti() ?? */
+ /* use spinlock to prevent interrupt handler accessing buffer ring */
spin_lock_irqsave(&sis_priv->lock, flags);
+
+ /* discard unsent packets */
sis_priv->dirty_tx = sis_priv->cur_tx = 0;
for (i = 0; i < NUM_TX_DESC; i++) {
if (sis_priv->tx_skbuff[i] != NULL) {
@@ -811,13 +812,15 @@
sis_priv->stats.tx_dropped++;
}
}
+ sis_priv->tx_full = 0;
+ netif_wake_queue(net_dev);
+
spin_unlock_irqrestore(&sis_priv->lock, flags);
net_dev->trans_start = jiffies;
- sis_priv->tx_full = 0;
- netif_start_queue(net_dev);
/* FIXME: Should we restart the transmission thread here ?? */
+ outl(TxENA, ioaddr + cr);
/* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
@@ -830,6 +833,9 @@
struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
long ioaddr = net_dev->base_addr;
unsigned int entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sis_priv->lock, flags);
/* Calculate the next Tx descriptor entry. */
entry = sis_priv->cur_tx % NUM_TX_DESC;
@@ -841,14 +847,16 @@
outl(TxENA, ioaddr + cr);
if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
- /* Typical path, clear tbusy to indicate more
- transmission is possible */
+ /* Typical path, tell upper layer that more transmission is possible */
netif_start_queue(net_dev);
} else {
- /* no more transmit descriptor avaiable, tbusy remain set */
+ /* buffer full, tell upper layer no more transmission */
sis_priv->tx_full = 1;
+ netif_stop_queue(net_dev);
}
+ spin_unlock_irqrestore(&sis_priv->lock, flags);
+
net_dev->trans_start = jiffies;
if (sis900_debug > 3)
@@ -922,7 +930,7 @@
if (sis900_debug > 3)
printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
"status:0x%8.8x\n",
- sis_priv->cur_rx, sis_priv->dirty_rx,rx_status);
+ sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
while (rx_status & OWN) {
unsigned int rx_size;
@@ -1060,8 +1068,8 @@
if (sis_priv->tx_full && test_bit(LINK_STATE_XOFF, &net_dev->flags) &&
sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC - 4) {
- /* The ring is no longer full, clear tbusy, tx_full and
- schedule more transmission by marking NET_BH */
+ /* The ring is no longer full, clear tx_full and schedule more transmission
+ by netif_wake_queue(net_dev) */
sis_priv->tx_full = 0;
netif_wake_queue (net_dev);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)