patch-2.3.44 linux/drivers/net/hamradio/hdlcdrv.c
Next file: linux/drivers/net/hamradio/soundmodem/sm.c
Previous file: linux/drivers/net/hamradio/baycom_ser_hdx.c
Back to the patch index
Back to the overall index
- Lines: 205
- Date:
Sat Feb 12 09:50:29 2000
- Orig file:
v2.3.43/linux/drivers/net/hamradio/hdlcdrv.c
- Orig date:
Wed Aug 18 11:38:50 1999
diff -u --recursive --new-file v2.3.43/linux/drivers/net/hamradio/hdlcdrv.c linux/drivers/net/hamradio/hdlcdrv.c
@@ -3,7 +3,7 @@
/*
* hdlcdrv.c -- HDLC packet radio network driver.
*
- * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,16 +27,17 @@
* Written 1993-94 by Donald Becker.
*
* History:
- * 0.1 21.09.96 Started
- * 18.10.96 Changed to new user space access routines
- * (copy_{to,from}_user)
- * 0.2 21.11.96 various small changes
- * 0.3 03.03.97 fixed (hopefully) IP not working with ax.25 as a module
- * 0.4 16.04.97 init code/data tagged
- * 0.5 30.07.97 made HDLC buffers bigger (solves a problem with the
- * soundmodem driver)
- * 0.6 05.04.98 add spinlocks
- * 0.7 03.08.99 removed some old compatibility cruft
+ * 0.1 21.09.1996 Started
+ * 18.10.1996 Changed to new user space access routines
+ * (copy_{to,from}_user)
+ * 0.2 21.11.1996 various small changes
+ * 0.3 03.03.1997 fixed (hopefully) IP not working with ax.25 as a module
+ * 0.4 16.04.1997 init code/data tagged
+ * 0.5 30.07.1997 made HDLC buffers bigger (solves a problem with the
+ * soundmodem driver)
+ * 0.6 05.04.1998 add spinlocks
+ * 0.7 03.08.1999 removed some old compatibility cruft
+ * 0.8 12.02.2000 adapted to softnet driver interface
*/
/*****************************************************************************/
@@ -366,20 +367,16 @@
clear_bit(0, &s->hdlctx.in_hdlc_tx);
return;
}
- if (!(skb = skb_dequeue(&s->send_queue))) {
- int flgs = tenms_to_2flags
- (s, s->ch_params.tx_tail);
+ if (!(skb = s->skb)) {
+ int flgs = tenms_to_2flags(s, s->ch_params.tx_tail);
if (flgs < 2)
flgs = 2;
s->hdlctx.tx_state = 1;
s->hdlctx.numflags = flgs;
break;
}
- if (skb->data[0] != 0) {
- do_kiss_params(s, skb->data, skb->len);
- dev_kfree_skb(skb);
- break;
- }
+ s->skb = NULL;
+ netif_wake_queue(dev);
pkt_len = skb->len-1; /* strip KISS byte */
if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
s->hdlctx.tx_state = 0;
@@ -454,8 +451,7 @@
void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
{
- if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt ||
- skb_queue_empty(&s->send_queue))
+ if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb)
return;
if (s->ch_params.fulldup) {
start_tx(dev, s);
@@ -499,8 +495,15 @@
if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet"))
return 0;
sm = (struct hdlcdrv_state *)dev->priv;
- skb_queue_tail(&sm->send_queue, skb);
- dev->trans_start = jiffies;
+ if (skb->data[0] != 0) {
+ do_kiss_params(sm, skb->data, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ if (sm->skb)
+ return -1;
+ netif_stop_queue(dev);
+ sm->skb = skb;
return 0;
}
@@ -550,12 +553,9 @@
return -EINVAL;
s = (struct hdlcdrv_state *)dev->priv;
- if (dev->start)
- return 0;
if (!s->ops || !s->ops->open)
return -ENODEV;
- dev->start = 1;
/*
* initialise some variables
*/
@@ -573,14 +573,9 @@
s->hdlctx.calibrate = 0;
i = s->ops->open(dev);
- if (i) {
- dev->start = 0;
+ if (i)
return i;
- }
-
- dev->tbusy = 0;
- dev->interrupt = 0;
-
+ netif_start_queue(dev);
return 0;
}
@@ -592,23 +587,17 @@
static int hdlcdrv_close(struct net_device *dev)
{
struct hdlcdrv_state *s;
- struct sk_buff *skb;
int i = 0;
if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close"))
return -EINVAL;
s = (struct hdlcdrv_state *)dev->priv;
- if (!dev->start)
- return 0;
- dev->start = 0;
- dev->tbusy = 1;
-
if (s->ops && s->ops->close)
i = s->ops->close(dev);
- /* Free any buffers left in the hardware transmit queue */
- while ((skb = skb_dequeue(&s->send_queue)))
- dev_kfree_skb(skb);
+ if (s->skb)
+ dev_kfree_skb(s->skb);
+ s->skb = NULL;
return i;
}
@@ -667,7 +656,7 @@
break;
case HDLCDRVCTL_SETMODEMPAR:
- if ((!suser()) || dev->start)
+ if ((!suser()) || test_bit(LINK_STATE_START, &dev->state))
return -EACCES;
dev->base_addr = bi.data.mp.iobase;
dev->irq = bi.data.mp.irq;
@@ -801,10 +790,9 @@
dev->get_stats = hdlcdrv_get_stats;
/* Fill in the fields of the device structure */
-
dev_init_buffers(dev);
- skb_queue_head_init(&s->send_queue);
+ s->skb = NULL;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
dev->hard_header = ax25_encapsulate;
@@ -821,6 +809,7 @@
dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
+ dev->tx_queue_len = 16;
/* New style flags */
dev->flags = 0;
@@ -857,8 +846,6 @@
dev->name = s->ifname;
dev->if_port = 0;
dev->init = hdlcdrv_probe;
- dev->start = 0;
- dev->tbusy = 1;
dev->base_addr = baseaddr;
dev->irq = irq;
dev->dma = dma;
@@ -884,7 +871,7 @@
return -EINVAL;
if (s->magic != HDLCDRV_MAGIC)
return -EINVAL;
- if (dev->start && s->ops->close)
+ if (s->ops->close)
s->ops->close(dev);
unregister_netdev(dev);
kfree(s);
@@ -911,8 +898,8 @@
int __init init_module(void)
{
- printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
- printk(KERN_INFO "hdlcdrv: version 0.7 compiled " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "hdlcdrv: (C) 1996-2000 Thomas Sailer HB9JNX/AE4WA\n");
+ printk(KERN_INFO "hdlcdrv: version 0.8 compiled " __TIME__ " " __DATE__ "\n");
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)