patch-2.3.44 linux/drivers/net/ni5010.c
Next file: linux/drivers/net/ni52.c
Previous file: linux/drivers/net/ne2.c
Back to the patch index
Back to the overall index
- Lines: 206
- Date:
Fri Feb 11 13:20:53 2000
- Orig file:
v2.3.43/linux/drivers/net/ni5010.c
- Orig date:
Thu Feb 10 17:11:10 2000
diff -u --recursive --new-file v2.3.43/linux/drivers/net/ni5010.c linux/drivers/net/ni5010.c
@@ -106,6 +106,7 @@
static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void ni5010_rx(struct net_device *dev);
+static void ni5010_timeout(struct net_device *dev);
static int ni5010_close(struct net_device *dev);
static struct net_device_stats *ni5010_get_stats(struct net_device *dev);
static void ni5010_set_multicast_list(struct net_device *dev);
@@ -320,15 +321,13 @@
dev->stop = ni5010_close;
dev->hard_start_xmit = ni5010_send_packet;
dev->get_stats = ni5010_get_stats;
- dev->set_multicast_list = &ni5010_set_multicast_list;
+ dev->set_multicast_list = ni5010_set_multicast_list;
+ dev->tx_timeout = ni5010_timeout;
+ dev->watchdog_timeo = HZ/20;
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 0;
-
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
/* Shut up the ni5010 */
@@ -403,10 +402,8 @@
outb(0, EDLC_RESET); /* Un-reset the ni5010 */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
+
if (NI5010_DEBUG) show_registers(dev);
MOD_INC_USE_COUNT;
@@ -426,42 +423,31 @@
outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */
}
+static void ni5010_timeout(struct net_device *dev)
+{
+ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+ tx_done(dev) ? "IRQ conflict" : "network cable problem");
+ /* Try to restart the adaptor. */
+ /* FIXME: Give it a real kick here */
+ chipset_init(dev, 1);
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+}
+
static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
{
+ int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name));
- if (dev->tbusy) {
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- printk("tbusy\n");
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
- /* Try to restart the adaptor. */
- /* FIXME: Give it a real kick here */
- chipset_init(dev, 1);
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
/*
- * Block a timer-based transmit from overlapping. This could better be
- * done with atomic_swap(1, dev->tbusy), but test_and_set_bit() works as well.
+ * Block sending
*/
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
- return 1;
- } else {
- int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
- hardware_send_packet(dev, (unsigned char *)skb->data, length);
- dev->trans_start = jiffies;
- }
+
+ netif_stop_queue(dev);
+ hardware_send_packet(dev, (unsigned char *)skb->data, length);
+ dev->trans_start = jiffies;
dev_kfree_skb (skb);
-
return 0;
}
@@ -469,23 +455,13 @@
* The typical workload of the driver:
* Handle the network interface interrupts.
*/
-static void
-ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct ni5010_local *lp;
int ioaddr, status;
int xmit_was_error = 0;
- if (dev == NULL || dev->irq != irq) {
- printk(KERN_WARNING "%s: irq %d for unknown device.\n",
- boardname, irq);
- return;
- }
-
- if (dev->interrupt) printk(KERN_WARNING "%s: Reentering IRQ-handler!\n", dev->name);
- dev->interrupt = 1;
-
PRINTK2((KERN_DEBUG "%s: entering ni5010_interrupt\n", dev->name));
ioaddr = dev->base_addr;
@@ -507,8 +483,6 @@
if (!xmit_was_error)
reset_receiver(dev);
-
- dev->interrupt = 0;
return;
}
@@ -530,8 +504,7 @@
}
/* We have a good packet, get it out of the buffer. */
-static void
-ni5010_rx(struct net_device *dev)
+static void ni5010_rx(struct net_device *dev)
{
struct ni5010_local *lp = (struct ni5010_local *)dev->priv;
int ioaddr = dev->base_addr;
@@ -624,8 +597,7 @@
lp->stats.tx_packets++;
lp->stats.tx_bytes += lp->o_pkt_size;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev);
PRINTK2((KERN_DEBUG "%s: sent packet, size=%#4.4x\n",
dev->name, lp->o_pkt_size));
@@ -634,8 +606,7 @@
}
/* The inverse routine to ni5010_open(). */
-static int
-ni5010_close(struct net_device *dev)
+static int ni5010_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
@@ -647,9 +618,8 @@
outb(0, IE_MMODE);
outb(RS_RESET, EDLC_RESET);
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
MOD_DEC_USE_COUNT;
PRINTK((KERN_DEBUG "%s: %s closed down\n", dev->name, boardname));
return 0;
@@ -658,8 +628,7 @@
/* Get the current statistics. This may be called with the card open or
closed. */
-static struct net_device_stats *
-ni5010_get_stats(struct net_device *dev)
+static struct net_device_stats *ni5010_get_stats(struct net_device *dev)
{
struct ni5010_local *lp = (struct ni5010_local *)dev->priv;
@@ -681,8 +650,7 @@
num_addrs > 0 Multicast mode, receive normal and MC packets, and do
best-effort filtering.
*/
-static void
-ni5010_set_multicast_list(struct net_device *dev)
+static void ni5010_set_multicast_list(struct net_device *dev)
{
short ioaddr = dev->base_addr;
@@ -748,6 +716,8 @@
restore_flags(flags);
+ netif_wake_queue(dev);
+
if (NI5010_DEBUG) show_registers(dev);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)