summaryrefslogtreecommitdiffstats
path: root/drivers/net/hamradio
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-24 00:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-24 00:12:35 +0000
commit482368b1a8e45430672c58c9a42e7d2004367126 (patch)
treece2a1a567d4d62dee7c2e71a46a99cf72cf1d606 /drivers/net/hamradio
parente4d0251c6f56ab2e191afb70f80f382793e23f74 (diff)
Merge with 2.3.47. Guys, this is buggy as shit. You've been warned.
Diffstat (limited to 'drivers/net/hamradio')
-rw-r--r--drivers/net/hamradio/6pack.c143
-rw-r--r--drivers/net/hamradio/baycom_epp.c202
-rw-r--r--drivers/net/hamradio/baycom_par.c64
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c29
-rw-r--r--drivers/net/hamradio/baycom_ser_hdx.c25
-rw-r--r--drivers/net/hamradio/bpqether.c41
-rw-r--r--drivers/net/hamradio/dmascc.c43
-rw-r--r--drivers/net/hamradio/hdlcdrv.c91
-rw-r--r--drivers/net/hamradio/scc.c133
-rw-r--r--drivers/net/hamradio/soundmodem/sm.c31
-rw-r--r--drivers/net/hamradio/yam.c27
11 files changed, 350 insertions, 479 deletions
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 16dc8a976..b1871485a 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -158,24 +158,6 @@ sp_free(struct sixpack *sp)
}
-/* Set the "sending" flag. */
-static inline void
-sp_lock(struct sixpack *sp)
-{
- if (test_and_set_bit(0, (void *) &sp->dev->tbusy))
- printk(KERN_WARNING "%s: trying to lock already locked device!\n", sp->dev->name);
-}
-
-
-/* Clear the "sending" flag. */
-static inline void
-sp_unlock(struct sixpack *sp)
-{
- if (!test_and_clear_bit(0, (void *)&sp->dev->tbusy))
- printk(KERN_WARNING "%s: trying to unlock already unlocked device!\n", sp->dev->name);
-}
-
-
/* Send one completely decapsulated IP datagram to the IP layer. */
/* This is the routine that sends the received data to the kernel AX.25.
@@ -226,7 +208,7 @@ sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
len = sp->mtu;
printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n", sp->dev->name);
sp->tx_dropped++;
- sp_unlock(sp);
+ netif_start_queue(sp->dev);
return;
}
@@ -235,21 +217,21 @@ sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
if (p[0] > 5)
{
printk(KERN_DEBUG "%s: invalid KISS command -- dropped\n", sp->dev->name);
- sp_unlock(sp);
+ netif_start_queue(sp->dev);
return;
}
if ((p[0] != 0) && (len > 2))
{
printk(KERN_DEBUG "%s: KISS control packet too long -- dropped\n", sp->dev->name);
- sp_unlock(sp);
+ netif_start_queue(sp->dev);
return;
}
if ((p[0] == 0) && (len < 15))
{
printk(KERN_DEBUG "%s: bad AX.25 packet to transmit -- dropped\n", sp->dev->name);
- sp_unlock(sp);
+ netif_start_queue(sp->dev);
sp->tx_dropped++;
return;
}
@@ -301,17 +283,18 @@ static void sixpack_write_wakeup(struct tty_struct *tty)
struct sixpack *sp = (struct sixpack *) tty->disc_data;
/* First make sure we're connected. */
- if (!sp || sp->magic != SIXPACK_MAGIC || !sp->dev->start) {
+ if (!sp || sp->magic != SIXPACK_MAGIC ||
+ !netif_running(sp->dev)) {
return;
}
+
if (sp->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
sp->tx_packets++;
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
- sp_unlock(sp);
sp->tx_enable = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(sp->dev);
return;
}
@@ -331,18 +314,9 @@ sp_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct sixpack *sp = (struct sixpack*)(dev->priv);
- if (!dev->start)
- {
- printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
- return 1;
- }
-
- if (dev->tbusy)
- return 1;
-
/* We were not busy, so we are now... :-) */
if (skb != NULL) {
- sp_lock(sp);
+ netif_stop_queue(dev);
sp->tx_bytes+=skb->len; /*---2.1.x---*/
sp_encaps(sp, skb->data, skb->len);
dev_kfree_skb(skb);
@@ -458,8 +432,7 @@ sp_open(struct net_device *dev)
sp->tnc_ok = 0;
sp->tx_enable = 0;
- dev->tbusy = 0;
- dev->start = 1;
+ netif_start_queue(dev);
init_timer(&sp->tx_t);
init_timer(&sp->resync_t);
@@ -477,9 +450,8 @@ sp_close(struct net_device *dev)
return -EBUSY;
}
sp->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
- dev->tbusy = 1;
- dev->start = 0;
+ netif_stop_queue(dev);
return 0;
}
@@ -506,7 +478,8 @@ sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, i
struct sixpack *sp = (struct sixpack *) tty->disc_data;
- if (!sp || sp->magic != SIXPACK_MAGIC || !sp->dev->start || !count)
+ if (!sp || sp->magic != SIXPACK_MAGIC ||
+ !netif_running(sp->dev) || !count)
return;
save_flags(flags);
@@ -723,17 +696,13 @@ static int sp_open_dev(struct net_device *dev)
/* Initialize 6pack control device -- register 6pack line discipline */
-#ifdef MODULE
-static int sixpack_init_ctrl_dev(void)
-#else /* !MODULE */
-int __init sixpack_init_ctrl_dev(struct net_device *dummy)
-#endif /* !MODULE */
+static int __init sixpack_init_ctrl_dev(void)
{
int status;
if (sixpack_maxdev < 4) sixpack_maxdev = 4; /* Sanity */
- printk(KERN_INFO "6pack: %s (dynamic channels, max=%d)\n",
+ printk(KERN_INFO "AX.25: 6pack driver, %s (dynamic channels, max=%d)\n",
SIXPACK_VERSION, sixpack_maxdev);
sixpack_ctrls = (sixpack_ctrl_t **) kmalloc(sizeof(void*)*sixpack_maxdev, GFP_KERNEL);
@@ -766,16 +735,40 @@ int __init sixpack_init_ctrl_dev(struct net_device *dummy)
printk(KERN_WARNING "6pack: can't register line discipline (err = %d)\n", status);
}
-#ifdef MODULE
return status;
-#else
- /* Return "not found", so that dev_init() will unlink
- * the placeholder device entry for us.
- */
- return ENODEV;
-#endif
}
+static void __exit sixpack_cleanup_driver(void)
+{
+ int i;
+
+ if (sixpack_ctrls != NULL)
+ {
+ for (i = 0; i < sixpack_maxdev; i++)
+ {
+ if (sixpack_ctrls[i])
+ {
+ /*
+ * VSV = if dev->start==0, then device
+ * unregistered while close proc.
+ */
+ if (netif_running(sixpack_ctrls[i]->dev))
+ unregister_netdev(&(sixpack_ctrls[i]->dev));
+
+ kfree(sixpack_ctrls[i]);
+ sixpack_ctrls[i] = NULL;
+ }
+ }
+ kfree(sixpack_ctrls);
+ sixpack_ctrls = NULL;
+ }
+ if ((i = tty_register_ldisc(N_6PACK, NULL)))
+ {
+ printk(KERN_WARNING "6pack: can't unregister line discipline (err = %d)\n", i);
+ }
+}
+
+
/* Initialize the 6pack driver. Called by DDI. */
int
sixpack_init(struct net_device *dev)
@@ -809,6 +802,7 @@ sixpack_init(struct net_device *dev)
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
dev->rebuild_header = sp_rebuild_header;
+ dev->tx_timeout = NULL;
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); /* Only activated in AX.25 mode */
memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); /* "" "" "" "" */
@@ -821,45 +815,8 @@ sixpack_init(struct net_device *dev)
return 0;
}
-#ifdef MODULE
-
-int
-init_module(void)
-{
- return sixpack_init_ctrl_dev();
-}
-
-void
-cleanup_module(void)
-{
- int i;
- if (sixpack_ctrls != NULL)
- {
- for (i = 0; i < sixpack_maxdev; i++)
- {
- if (sixpack_ctrls[i])
- {
- /*
- * VSV = if dev->start==0, then device
- * unregistered while close proc.
- */
- if (sixpack_ctrls[i]->dev.start)
- unregister_netdev(&(sixpack_ctrls[i]->dev));
- kfree(sixpack_ctrls[i]);
- sixpack_ctrls[i] = NULL;
- }
- }
- kfree(sixpack_ctrls);
- sixpack_ctrls = NULL;
- }
- if ((i = tty_register_ldisc(N_6PACK, NULL)))
- {
- printk(KERN_WARNING "6pack: can't unregister line discipline (err = %d)\n", i);
- }
-}
-#endif /* MODULE */
/* ----> 6pack timer interrupt handler and friends. <---- */
static void
@@ -1127,3 +1084,9 @@ void decode_data(byte inbyte, struct sixpack *sp)
sp->rx_count = 0;
}
}
+
+
+MODULE_AUTHOR("Andreas Könsgen <ajk@ccac.rwth-aachen.de>");
+MODULE_DESCRIPTION("6pack driver for AX.25");
+module_init(sixpack_init_ctrl_dev);
+module_exit(sixpack_cleanup_driver);
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index d4191258d..98d228b91 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -3,7 +3,7 @@
/*
* baycom_epp.c -- baycom epp radio modem driver.
*
- * Copyright (C) 1998-1999
+ * Copyright (C) 1998-2000
* Thomas Sailer (sailer@ife.ee.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,14 +26,15 @@
*
*
* History:
- * 0.1 xx.xx.98 Initial version by Matthias Welwarsky (dg2fef)
- * 0.2 21.04.98 Massive rework by Thomas Sailer
- * Integrated FPGA EPP modem configuration routines
- * 0.3 11.05.98 Took FPGA config out and moved it into a separate program
- * 0.4 26.07.99 Adapted to new lowlevel parport driver interface
- * 0.5 03.08.99 adapt to Linus' new __setup/__initcall
- * removed some pre-2.2 kernel compatibility cruft
- * 0.6 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.1 xx.xx.1998 Initial version by Matthias Welwarsky (dg2fef)
+ * 0.2 21.04.1998 Massive rework by Thomas Sailer
+ * Integrated FPGA EPP modem configuration routines
+ * 0.3 11.05.1998 Took FPGA config out and moved it into a separate program
+ * 0.4 26.07.1999 Adapted to new lowlevel parport driver interface
+ * 0.5 03.08.1999 adapt to Linus' new __setup/__initcall
+ * removed some pre-2.2 kernel compatibility cruft
+ * 0.6 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.7 12.02.2000 adapted to softnet driver interface
*
*/
@@ -47,8 +48,10 @@
#include <linux/tqueue.h>
#include <linux/fs.h>
#include <linux/parport.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/if_arp.h>
+#include <linux/kmod.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
#include <linux/soundmodem.h>
@@ -89,8 +92,8 @@ static const char paranoia_str[] = KERN_ERR
/* --------------------------------------------------------------------- */
static const char bc_drvname[] = "baycom_epp";
-static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-1999 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_epp: version 0.5 compiled " __TIME__ " " __DATE__ "\n";
+static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
@@ -228,8 +231,7 @@ struct baycom_state {
struct net_device_stats stats;
unsigned int ptt_keyed;
- struct sk_buff_head send_queue; /* Packets awaiting transmission */
-
+ struct sk_buff *skb; /* next transmit packet */
#ifdef BAYCOM_DEBUG
struct debug_vals {
@@ -394,15 +396,11 @@ static int exec_eppfpga(void *b)
sprintf(portarg, "%ld", bc->pdev->port->base);
printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
- for (i = 0; i < current->files->max_fds; i++ )
- if (current->files->fd[i])
- close(i);
- set_fs(KERNEL_DS); /* Allow execve args to be in kernel space. */
- current->uid = current->euid = current->fsuid = 0;
- if (execve(eppconfig_path, argv, envp) < 0) {
+ i = exec_usermodehelper(eppconfig_path, argv, envp);
+ if (i < 0) {
printk(KERN_ERR "%s: failed to exec %s -s -p %s -m %s, errno = %d\n",
- bc_drvname, eppconfig_path, portarg, modearg, errno);
- return -errno;
+ bc_drvname, eppconfig_path, portarg, modearg, i);
+ return i;
}
return 0;
}
@@ -515,71 +513,63 @@ static void encode_hdlc(struct baycom_state *bc)
if (bc->hdlctx.bufcnt > 0)
return;
- while ((skb = skb_dequeue(&bc->send_queue))) {
- if (skb->data[0] != 0) {
- do_kiss_params(bc, skb->data, skb->len);
- dev_kfree_skb(skb);
- continue;
- }
- pkt_len = skb->len-1; /* strip KISS byte */
- if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
- dev_kfree_skb(skb);
- continue;
- }
- wp = bc->hdlctx.buf;
- bp = skb->data+1;
- crc = calc_crc_ccitt(bp, pkt_len);
- crcarr[0] = crc;
- crcarr[1] = crc >> 8;
- *wp++ = 0x7e;
- bitstream = bitbuf = numbit = 0;
- while (pkt_len > -2) {
- bitstream >>= 8;
- bitstream |= ((unsigned int)*bp) << 8;
- bitbuf |= ((unsigned int)*bp) << numbit;
- notbitstream = ~bitstream;
- bp++;
- pkt_len--;
- if (!pkt_len)
- bp = crcarr;
- ENCODEITERA(0);
- ENCODEITERA(1);
- ENCODEITERA(2);
- ENCODEITERA(3);
- ENCODEITERA(4);
- ENCODEITERA(5);
- ENCODEITERA(6);
- ENCODEITERA(7);
- goto enditer;
- ENCODEITERB(0);
- ENCODEITERB(1);
- ENCODEITERB(2);
- ENCODEITERB(3);
- ENCODEITERB(4);
- ENCODEITERB(5);
- ENCODEITERB(6);
- ENCODEITERB(7);
- enditer:
- numbit += 8;
- while (numbit >= 8) {
- *wp++ = bitbuf;
- bitbuf >>= 8;
- numbit -= 8;
- }
- }
- bitbuf |= 0x7e7e << numbit;
- numbit += 16;
- while (numbit >= 8) {
- *wp++ = bitbuf;
- bitbuf >>= 8;
- numbit -= 8;
- }
- bc->hdlctx.bufptr = bc->hdlctx.buf;
- bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
- dev_kfree_skb(skb);
- bc->stats.tx_packets++;
+ skb = bc->skb;
+ if (!skb)
return;
+ bc->skb = NULL;
+ pkt_len = skb->len-1; /* strip KISS byte */
+ wp = bc->hdlctx.buf;
+ bp = skb->data+1;
+ crc = calc_crc_ccitt(bp, pkt_len);
+ crcarr[0] = crc;
+ crcarr[1] = crc >> 8;
+ *wp++ = 0x7e;
+ bitstream = bitbuf = numbit = 0;
+ while (pkt_len > -2) {
+ bitstream >>= 8;
+ bitstream |= ((unsigned int)*bp) << 8;
+ bitbuf |= ((unsigned int)*bp) << numbit;
+ notbitstream = ~bitstream;
+ bp++;
+ pkt_len--;
+ if (!pkt_len)
+ bp = crcarr;
+ ENCODEITERA(0);
+ ENCODEITERA(1);
+ ENCODEITERA(2);
+ ENCODEITERA(3);
+ ENCODEITERA(4);
+ ENCODEITERA(5);
+ ENCODEITERA(6);
+ ENCODEITERA(7);
+ goto enditer;
+ ENCODEITERB(0);
+ ENCODEITERB(1);
+ ENCODEITERB(2);
+ ENCODEITERB(3);
+ ENCODEITERB(4);
+ ENCODEITERB(5);
+ ENCODEITERB(6);
+ ENCODEITERB(7);
+ enditer:
+ numbit += 8;
+ while (numbit >= 8) {
+ *wp++ = bitbuf;
+ bitbuf >>= 8;
+ numbit -= 8;
+ }
}
+ bitbuf |= 0x7e7e << numbit;
+ numbit += 16;
+ while (numbit >= 8) {
+ *wp++ = bitbuf;
+ bitbuf >>= 8;
+ numbit -= 8;
+ }
+ bc->hdlctx.bufptr = bc->hdlctx.buf;
+ bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
+ dev_kfree_skb(skb);
+ bc->stats.tx_packets++;
}
/* ---------------------------------------------------------------------- */
@@ -944,6 +934,8 @@ static void epp_bh(struct net_device *dev)
bc->debug_vals.demod_cycles = time3 - time2;
#endif /* BAYCOM_DEBUG */
queue_task(&bc->run_bh, &tq_timer);
+ if (!bc->skb)
+ netif_wake_queue(dev);
return;
epptimeout:
printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname);
@@ -960,8 +952,20 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
baycom_paranoia_check(dev, "baycom_send_packet", 0);
bc = (struct baycom_state *)dev->priv;
- skb_queue_tail(&bc->send_queue, skb);
- dev->trans_start = jiffies;
+ if (skb->data[0] != 0) {
+ do_kiss_params(bc, skb->data, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ if (bc->skb)
+ return -1;
+ /* strip KISS byte */
+ if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ netif_stop_queue(dev);
+ bc->skb = skb;
return 0;
}
@@ -1030,8 +1034,6 @@ static int epp_open(struct net_device *dev)
baycom_paranoia_check(dev, "epp_open", -ENXIO);
bc = (struct baycom_state *)dev->priv;
- if (dev->start)
- return 0;
pp = parport_enumerate();
while (pp && pp->base != dev->base_addr)
pp = pp->next;
@@ -1122,11 +1124,9 @@ static int epp_open(struct net_device *dev)
bc->hdlctx.bufcnt = 0;
bc->hdlctx.slotcnt = bc->ch_params.slottime;
bc->hdlctx.calibrate = 0;
- dev->start = 1;
- dev->tbusy = 0;
- dev->interrupt = 0;
/* start the bottom half stuff */
queue_task(&bc->run_bh, &tq_timer);
+ netif_start_queue(dev);
MOD_INC_USE_COUNT;
return 0;
@@ -1144,17 +1144,12 @@ static int epp_close(struct net_device *dev)
{
struct baycom_state *bc;
struct parport *pp;
- struct sk_buff *skb;
unsigned char tmp[1];
baycom_paranoia_check(dev, "epp_close", -EINVAL);
- if (!dev->start)
- return 0;
bc = (struct baycom_state *)dev->priv;
pp = bc->pdev->port;
bc->bh_running = 0;
- dev->start = 0;
- dev->tbusy = 1;
run_task_queue(&tq_timer); /* dequeue bottom half */
bc->stat = EPP_DCDBIT;
tmp[0] = 0;
@@ -1162,9 +1157,9 @@ static int epp_close(struct net_device *dev)
parport_write_control(pp, 0); /* reset the adapter */
parport_release(bc->pdev);
parport_unregister_device(bc->pdev);
- /* Free any buffers left in the hardware transmit queue */
- while ((skb = skb_dequeue(&bc->send_queue)))
- dev_kfree_skb(skb);
+ if (bc->skb)
+ dev_kfree_skb(bc->skb);
+ bc->skb = NULL;
printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n",
bc_drvname, dev->base_addr, dev->irq);
MOD_DEC_USE_COUNT;
@@ -1280,7 +1275,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
case HDLCDRVCTL_SETMODEMPAR:
- if ((!suser()) || dev->start)
+ if ((!suser()) || netif_running(dev))
return -EACCES;
dev->base_addr = hi.data.mp.iobase;
dev->irq = /*hi.data.mp.irq*/0;
@@ -1319,7 +1314,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
case HDLCDRVCTL_SETMODE:
- if (!suser() || dev->start)
+ if (!suser() || netif_running(dev))
return -EACCES;
hi.data.modename[sizeof(hi.data.modename)-1] = '\0';
return baycom_setmode(bc, hi.data.modename);
@@ -1385,7 +1380,7 @@ static int baycom_probe(struct net_device *dev)
/* Fill in the fields of the device structure */
dev_init_buffers(dev);
- skb_queue_head_init(&bc->send_queue);
+ bc->skb = NULL;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
dev->hard_header = ax25_encapsulate;
@@ -1402,6 +1397,7 @@ static int baycom_probe(struct net_device *dev)
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;
@@ -1461,8 +1457,6 @@ static int __init init_baycomepp(void)
dev->name = bc->ifname;
dev->if_port = 0;
dev->init = baycom_probe;
- dev->start = 0;
- dev->tbusy = 1;
dev->base_addr = iobase[i];
dev->irq = 0;
dev->dma = 0;
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index 0bd2a1725..b68063b07 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -3,7 +3,7 @@
/*
* baycom_par.c -- baycom par96 and picpar radio modem 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
@@ -53,14 +53,16 @@
*
*
* History:
- * 0.1 26.06.96 Adapted from baycom.c and made network driver interface
- * 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
- * 0.3 26.04.97 init code/data tagged
- * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints)
- * 0.5 11.11.97 split into separate files for ser12/par96
- * 0.6 03.08.99 adapt to Linus' new __setup/__initcall
- * removed some pre-2.2 kernel compatibility cruft
- * 0.7 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
+ * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
+ * 0.3 26.04.1997 init code/data tagged
+ * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
+ * 0.5 11.11.1997 split into separate files for ser12/par96
+ * 0.6 03.08.1999 adapt to Linus' new __setup/__initcall
+ * removed some pre-2.2 kernel compatibility cruft
+ * 0.7 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.8 12.02.2000 adapted to softnet driver interface
+ * removed direct parport access, uses parport driver methods
*/
/*****************************************************************************/
@@ -77,7 +79,6 @@
#include <linux/string.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -99,8 +100,8 @@
/* --------------------------------------------------------------------- */
static const char bc_drvname[] = "baycom_par";
-static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_par: version 0.6 compiled " __TIME__ " " __DATE__ "\n";
+static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "baycom_par: version 0.8 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
@@ -110,13 +111,6 @@ static struct net_device baycom_device[NR_PORTS];
/* --------------------------------------------------------------------- */
-#define SER12_EXTENT 8
-
-#define LPT_DATA(dev) ((dev)->base_addr+0)
-#define LPT_STATUS(dev) ((dev)->base_addr+1)
-#define LPT_CONTROL(dev) ((dev)->base_addr+2)
-#define LPT_IRQ_ENABLE 0x10
-
#define PAR96_BURSTBITS 16
#define PAR96_BURST 4
#define PAR96_PTT 2
@@ -207,6 +201,7 @@ static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc)
{
int i;
unsigned int data = hdlcdrv_getbits(&bc->hdrv);
+ struct parport *pp = bc->pdev->port;
for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) {
unsigned char val = PAR97_POWER;
@@ -219,8 +214,8 @@ static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc)
(PAR96_SCRAM_TAPN << 1);
if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
val |= PAR96_TXBIT;
- outb(val, LPT_DATA(dev));
- outb(val | PAR96_BURST, LPT_DATA(dev));
+ pp->ops->write_data(pp, val);
+ pp->ops->write_data(pp, val | PAR96_BURST);
}
}
@@ -230,24 +225,25 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc)
{
int i;
unsigned int data, mask, mask2, descx;
+ struct parport *pp = bc->pdev->port;
/*
* do receiver; differential decode and descramble on the fly
*/
for(data = i = 0; i < PAR96_BURSTBITS; i++) {
bc->modem.par96.descram = (bc->modem.par96.descram << 1);
- if (inb(LPT_STATUS(dev)) & PAR96_RXBIT)
+ if (pp->ops->read_status(pp) & PAR96_RXBIT)
bc->modem.par96.descram |= 1;
descx = bc->modem.par96.descram ^
(bc->modem.par96.descram >> 1);
/* now the diff decoded data is inverted in descram */
- outb(PAR97_POWER | PAR96_PTT, LPT_DATA(dev));
+ pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT);
descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^
(descx >> PAR96_DESCRAM_TAPSH2));
data >>= 1;
if (!(descx & 1))
data |= 0x8000;
- outb(PAR97_POWER | PAR96_PTT | PAR96_BURST, LPT_DATA(dev));
+ pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT | PAR96_BURST);
}
hdlcdrv_putbits(&bc->hdrv, data);
/*
@@ -272,7 +268,7 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc)
bc->modem.par96.dcd_count -= 2;
hdlcdrv_setdcd(&bc->hdrv, bc->modem.par96.dcd_count > 0);
} else {
- hdlcdrv_setdcd(&bc->hdrv, !!(inb(LPT_STATUS(dev)) & PAR96_DCD));
+ hdlcdrv_setdcd(&bc->hdrv, !!(pp->ops->read_status(pp) & PAR96_DCD));
}
}
@@ -353,13 +349,12 @@ static int par96_open(struct net_device *dev)
parport_unregister_device(bc->pdev);
return -EBUSY;
}
+ pp = bc->pdev->port;
dev->irq = pp->irq;
- /* bc->pdev->port->ops->change_mode(bc->pdev->port, PARPORT_MODE_PCSPP); not yet implemented */
+ pp->ops->data_forward(pp);
bc->hdrv.par.bitrate = 9600;
- /* switch off PTT */
- outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev));
- /*bc->pdev->port->ops->enable_irq(bc->pdev->port); not yet implemented */
- outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev));
+ pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER); /* switch off PTT */
+ pp->ops->enable_irq(pp);
printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
bc_drvname, dev->base_addr, dev->irq, bc->options);
MOD_INC_USE_COUNT;
@@ -371,14 +366,15 @@ static int par96_open(struct net_device *dev)
static int par96_close(struct net_device *dev)
{
struct baycom_state *bc = (struct baycom_state *)dev->priv;
+ struct parport *pp;
if (!dev || !bc)
return -EINVAL;
+ pp = bc->pdev->port;
/* disable interrupt */
- outb(0, LPT_CONTROL(dev));
- /*bc->pdev->port->ops->disable_irq(bc->pdev->port); not yet implemented */
+ pp->ops->disable_irq(pp);
/* switch off PTT */
- outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev));
+ pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER);
parport_release(bc->pdev);
parport_unregister_device(bc->pdev);
printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
@@ -449,7 +445,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
return 0;
case HDLCDRVCTL_SETMODE:
- if (dev->start || !suser())
+ if (netif_running(dev) || !suser())
return -EACCES;
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
return baycom_setmode(bc, hi->data.modename);
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 9c6e69cf6..cdcab2621 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -3,7 +3,7 @@
/*
* baycom_ser_fdx.c -- baycom ser12 fullduplex radio modem 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
@@ -55,16 +55,17 @@
*
*
* History:
- * 0.1 26.06.96 Adapted from baycom.c and made network driver interface
- * 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
- * 0.3 26.04.97 init code/data tagged
- * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints)
- * 0.5 11.11.97 ser12/par96 split into separate files
- * 0.6 24.01.98 Thorsten Kranzkowski, dl8bcu and Thomas Sailer:
- * reduced interrupt load in transmit case
- * reworked receiver
- * 0.7 03.08.99 adapt to Linus' new __setup/__initcall
- * 0.8 10.08.99 use module_init/module_exit
+ * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
+ * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
+ * 0.3 26.04.1997 init code/data tagged
+ * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
+ * 0.5 11.11.1997 ser12/par96 split into separate files
+ * 0.6 24.01.1998 Thorsten Kranzkowski, dl8bcu and Thomas Sailer:
+ * reduced interrupt load in transmit case
+ * reworked receiver
+ * 0.7 03.08.1999 adapt to Linus' new __setup/__initcall
+ * 0.8 10.08.1999 use module_init/module_exit
+ * 0.9 12.02.2000 adapted to softnet driver interface
*/
/*****************************************************************************/
@@ -86,8 +87,8 @@
/* --------------------------------------------------------------------- */
static const char bc_drvname[] = "baycom_ser_fdx";
-static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_ser_fdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
+static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "baycom_ser_fdx: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
@@ -554,7 +555,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
return 0;
case HDLCDRVCTL_SETMODE:
- if (dev->start || !suser())
+ if (netif_running(dev) || !suser())
return -EACCES;
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
return baycom_setmode(bc, hi->data.modename);
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
index c44395f84..64b27286c 100644
--- a/drivers/net/hamradio/baycom_ser_hdx.c
+++ b/drivers/net/hamradio/baycom_ser_hdx.c
@@ -3,7 +3,7 @@
/*
* baycom_ser_hdx.c -- baycom ser12 halfduplex radio modem 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
@@ -47,14 +47,15 @@
*
*
* History:
- * 0.1 26.06.96 Adapted from baycom.c and made network driver interface
- * 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
- * 0.3 26.04.97 init code/data tagged
- * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints)
- * 0.5 11.11.97 ser12/par96 split into separate files
- * 0.6 14.04.98 cleanups
- * 0.7 03.08.99 adapt to Linus' new __setup/__initcall
- * 0.8 10.08.99 use module_init/module_exit
+ * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
+ * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
+ * 0.3 26.04.1997 init code/data tagged
+ * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
+ * 0.5 11.11.1997 ser12/par96 split into separate files
+ * 0.6 14.04.1998 cleanups
+ * 0.7 03.08.1999 adapt to Linus' new __setup/__initcall
+ * 0.8 10.08.1999 use module_init/module_exit
+ * 0.9 12.02.2000 adapted to softnet driver interface
*/
/*****************************************************************************/
@@ -76,8 +77,8 @@
/* --------------------------------------------------------------------- */
static const char bc_drvname[] = "baycom_ser_hdx";
-static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_ser_hdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
+static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "baycom_ser_hdx: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
@@ -597,7 +598,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
return 0;
case HDLCDRVCTL_SETMODE:
- if (dev->start || !suser())
+ if (netif_running(dev) || !suser())
return -EACCES;
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
return baycom_setmode(bc, hi->data.modename);
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 55ed5254e..0cc9aa7c1 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -222,7 +222,7 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
dev = bpq_get_ax25_dev(dev);
- if (dev == NULL || dev->start == 0) {
+ if (dev == NULL || !netif_running(dev)) {
kfree_skb(skb);
return 0;
}
@@ -275,7 +275,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
* Just to be *really* sure not to send anything if the interface
* is down, the ethernet device may have gone.
*/
- if (!dev->start) {
+ if (!netif_running(dev)) {
bpq_check_devices(dev);
kfree_skb(skb);
return -ENODEV;
@@ -324,7 +324,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
bpq->stats.tx_bytes+=skb->len;
dev_queue_xmit(skb);
-
+ netif_wake_queue(dev);
return 0;
}
@@ -407,22 +407,17 @@ static int bpq_open(struct net_device *dev)
{
if (bpq_check_devices(dev))
return -ENODEV; /* oops, it's gone */
-
- dev->tbusy = 0;
- dev->start = 1;
-
+
MOD_INC_USE_COUNT;
+ netif_start_queue(dev);
return 0;
}
static int bpq_close(struct net_device *dev)
{
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
MOD_DEC_USE_COUNT;
-
return 0;
}
@@ -621,7 +616,7 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
* Initialize driver. To be called from af_ax25 if not compiled as a
* module
*/
-int __init bpq_init(void)
+static int __init bpq_init_driver(void)
{
struct net_device *dev;
@@ -630,7 +625,7 @@ int __init bpq_init(void)
register_netdevice_notifier(&bpq_dev_notifier);
- printk(KERN_INFO "AX.25 ethernet driver version 0.01\n");
+ printk(KERN_INFO "AX.25: bpqether driver version 0.01\n");
proc_net_create ("bpqether", 0, bpq_get_info);
@@ -643,22 +638,10 @@ int __init bpq_init(void)
}
}
read_unlock_bh(&dev_base_lock);
-out:
return 0;
}
-#ifdef MODULE
-EXPORT_NO_SYMBOLS;
-
-MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@lykos.oche.de>");
-MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
-
-int init_module(void)
-{
- return bpq_init();
-}
-
-void cleanup_module(void)
+static void __exit bpq_cleanup_driver(void)
{
struct bpqdev *bpq;
@@ -671,4 +654,8 @@ void cleanup_module(void)
for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
unregister_netdev(&bpq->axdev);
}
-#endif
+
+MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@poboxes.com>");
+MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
+module_init(bpq_init_driver);
+module_exit(bpq_cleanup_driver);
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index afba5cb14..3e7cd8e44 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -643,7 +643,6 @@ static int scc_open(struct net_device *dev)
}
/* Initialize local variables */
- dev->tbusy = 0;
priv->rx_ptr = 0;
priv->rx_over = 0;
priv->rx_head = priv->rx_tail = priv->rx_count = 0;
@@ -732,7 +731,7 @@ static int scc_open(struct net_device *dev)
/* Configure PI2 DMA */
if (info->type <= TYPE_PI2) outb_p(1, io + PI_DREQ_MASK);
- dev->start = 1;
+ netif_start_queue(dev);
info->open++;
MOD_INC_USE_COUNT;
@@ -747,9 +746,8 @@ static int scc_close(struct net_device *dev)
int io = dev->base_addr;
int cmd = priv->cmd;
- dev->start = 0;
+ netif_stop_queue(dev);
info->open--;
- MOD_DEC_USE_COUNT;
if (info->type == TYPE_TWIN)
/* Drop DTR */
@@ -768,6 +766,7 @@ static int scc_close(struct net_device *dev)
if (info->type <= TYPE_PI2) outb_p(0, io + PI_DREQ_MASK);
free_irq(dev->irq, info);
}
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -779,16 +778,16 @@ static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) {
case SIOCGSCCPARAM:
- rc = verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(struct scc_param));
- if (rc) return rc;
- copy_to_user(ifr->ifr_data, &priv->param, sizeof(struct scc_param));
+ if(copy_to_user(ifr->ifr_data, &priv->param, sizeof(struct scc_param)))
+ return -EFAULT;
return 0;
case SIOCSSCCPARAM:
- if (!suser()) return -EPERM;
- rc = verify_area(VERIFY_READ, ifr->ifr_data, sizeof(struct scc_param));
- if (rc) return rc;
- if (dev->start) return -EAGAIN;
- copy_from_user(&priv->param, ifr->ifr_data, sizeof(struct scc_param));
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if (netif_running(dev))
+ return -EAGAIN;
+ if(copy_from_user(&priv->param, ifr->ifr_data, sizeof(struct scc_param)))
+ return -EFAULT;
dev->dma = priv->param.dma;
return 0;
default:
@@ -806,18 +805,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
int i;
/* Block a timer-based transmit from overlapping */
- if (test_and_set_bit(0, (void *) &priv->tx_sem) != 0) {
- atomic_inc((void *) &priv->stats.tx_dropped);
- dev_kfree_skb(skb);
- return 0;
- }
-
- /* Return with an error if we cannot accept more data */
- if (dev->tbusy) {
- priv->tx_sem = 0;
- return -1;
- }
-
+ netif_stop_queue(dev);
+
/* Transfer data to DMA buffer */
i = priv->tx_head;
memcpy(priv->tx_buf[i], skb->data+1, skb->len-1);
@@ -829,7 +818,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
/* Set the busy flag if we just filled up the last buffer */
priv->tx_head = (i + 1) % NUM_TX_BUF;
priv->tx_count++;
- if (priv->tx_count == NUM_TX_BUF) dev->tbusy = 1;
+ if (priv->tx_count != NUM_TX_BUF)
+ netif_wake_queue(dev);
/* Set new TX state */
if (priv->tx_state == TX_IDLE) {
@@ -1139,7 +1129,6 @@ static void es_isr(struct net_device *dev)
/* Remove frame from FIFO */
priv->tx_tail = (i + 1) % NUM_TX_BUF;
priv->tx_count--;
- dev->tbusy = 0;
/* Check if another frame is available and we are allowed to transmit */
if (priv->tx_count && (jiffies - priv->tx_start) < priv->param.txtime) {
if (dev->dma) {
@@ -1171,7 +1160,7 @@ static void es_isr(struct net_device *dev)
priv->stats.tx_packets++;
}
/* Inform upper layers */
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
/* DCD transition */
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 67a835b02..a3560c207 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/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,29 +367,25 @@ void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
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;
s->hdlctx.numflags = 1;
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
break;
}
memcpy(s->hdlctx.buffer, skb->data+1, pkt_len);
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
s->hdlctx.bp = s->hdlctx.buffer;
append_crc_ccitt(s->hdlctx.buffer, pkt_len);
s->hdlctx.len = pkt_len+2; /* the appended CRC */
@@ -454,8 +451,7 @@ static inline unsigned short random_num(void)
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 @@ static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
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 @@ static int hdlcdrv_open(struct net_device *dev)
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 @@ static int hdlcdrv_open(struct net_device *dev)
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_open(struct net_device *dev)
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 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
case HDLCDRVCTL_SETMODEMPAR:
- if ((!suser()) || dev->start)
+ if ((!suser()) || netif_running(dev))
return -EACCES;
dev->base_addr = bi.data.mp.iobase;
dev->irq = bi.data.mp.irq;
@@ -801,10 +790,9 @@ static int hdlcdrv_probe(struct net_device *dev)
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 @@ static int hdlcdrv_probe(struct net_device *dev)
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 @@ int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *o
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 @@ int hdlcdrv_unregister_hdlcdrv(struct net_device *dev)
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 @@ MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
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;
}
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 4de421874..09bb422f1 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1,7 +1,7 @@
#define RCS_ID "$Id: scc.c,v 1.75 1998/11/04 15:15:01 jreuter Exp jreuter $"
#define VERSION "3.0"
-#define BANNER "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n"
+#define BANNER "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n"
/*
* Please use z8530drv-utils-3.0 with this version.
@@ -19,7 +19,7 @@
********************************************************************
- Copyright (c) 1993, 1998 Joerg Reuter DL1BKE
+ Copyright (c) 1993, 2000 Joerg Reuter DL1BKE
portions (c) 1993 Guido ten Dolle PE1NNZ
@@ -104,6 +104,9 @@
flags that aren't... Restarting the DPLL does not help
either, it resynchronizes too slow and the first received
frame gets lost.
+ 2000-02-13 Fixed for new network driver interface changes, still
+ does TX timeouts itself since it uses its own queue
+ scheme.
Thanks to all who contributed to this driver with ideas and bug
reports!
@@ -236,9 +239,6 @@ static unsigned char Driver_Initialized = 0;
static int Nchips = 0;
static io_port Vector_Latch = 0;
-MODULE_AUTHOR("Joerg Reuter <jreuter@poboxes.com>");
-MODULE_DESCRIPTION("Network Device Driver for Z8530 based HDLC cards for Amateur Packet Radio");
-MODULE_SUPPORTED_DEVICE("scc");
/* ******************************************************************** */
/* * Port Access Functions * */
@@ -314,17 +314,6 @@ static inline void scc_sti(int irq)
/* * Some useful macros * */
/* ******************************************************************** */
-
-static inline void scc_lock_dev(struct scc_channel *scc)
-{
- scc->dev->tbusy = 1;
-}
-
-static inline void scc_unlock_dev(struct scc_channel *scc)
-{
- scc->dev->tbusy = 0;
-}
-
static inline void scc_discard_buffers(struct scc_channel *scc)
{
unsigned long flags;
@@ -382,7 +371,7 @@ static inline void flush_rx_FIFO(struct scc_channel *scc)
if(scc->rx_buff != NULL) /* did we receive something? */
{
scc->stat.rxerrs++; /* then count it as an error */
- kfree_skb(scc->rx_buff);
+ dev_kfree_skb_irq(scc->rx_buff);
scc->rx_buff = NULL;
}
}
@@ -411,7 +400,7 @@ static inline void scc_txint(struct scc_channel *scc)
{
skb = skb_dequeue(&scc->tx_queue);
scc->tx_buff = skb;
- scc_unlock_dev(scc);
+ netif_wake_queue(scc->dev);
if (skb == NULL)
{
@@ -422,7 +411,7 @@ static inline void scc_txint(struct scc_channel *scc)
if (skb->len == 0) /* Paranoia... */
{
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
scc->tx_buff = NULL;
scc_tx_done(scc);
Outb(scc->ctrl, RES_Tx_P);
@@ -448,7 +437,7 @@ static inline void scc_txint(struct scc_channel *scc)
{
Outb(scc->ctrl, RES_Tx_P); /* reset pending int */
cl(scc, R10, ABUNDER); /* send CRC */
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
scc->tx_buff = NULL;
scc->stat.tx_state = TXS_NEWFRAME; /* next frame... */
return;
@@ -533,7 +522,7 @@ static inline void scc_exint(struct scc_channel *scc)
if (scc->tx_buff != NULL)
{
- dev_kfree_skb(scc->tx_buff);
+ dev_kfree_skb_irq(scc->tx_buff);
scc->tx_buff = NULL;
}
@@ -583,7 +572,7 @@ static inline void scc_rxint(struct scc_channel *scc)
#ifdef notdef
printk(KERN_DEBUG "z8530drv: oops, scc_rxint() received huge frame...\n");
#endif
- kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
scc->rx_buff = NULL;
Inb(scc->data);
or(scc, R3, ENT_HM);
@@ -613,7 +602,7 @@ static inline void scc_spint(struct scc_channel *scc)
or(scc,R3,ENT_HM); /* enter hunt mode for next flag */
if (skb != NULL)
- kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
scc->rx_buff = NULL;
}
@@ -629,7 +618,7 @@ static inline void scc_spint(struct scc_channel *scc)
scc->rx_buff = NULL;
scc->stat.rxframes++;
} else { /* a bad frame */
- kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
scc->rx_buff = NULL;
scc->stat.rxerrs++;
}
@@ -1112,7 +1101,7 @@ static void scc_tx_done(struct scc_channel *scc)
scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime);
}
- scc_unlock_dev(scc);
+ netif_wake_queue(scc->dev);
}
@@ -1163,7 +1152,7 @@ static void t_dwait(unsigned long channel)
if (skb_queue_len(&scc->tx_queue) == 0) /* nothing to send */
{
scc->stat.tx_state = TXS_IDLE;
- scc_unlock_dev(scc); /* t_maxkeyup locked it. */
+ netif_wake_queue(scc->dev); /* t_maxkeyup locked it. */
return;
}
@@ -1243,7 +1232,7 @@ static void t_tail(unsigned long channel)
}
scc->stat.tx_state = TXS_IDLE;
- scc_unlock_dev(scc);
+ netif_wake_queue(scc->dev);
}
@@ -1257,14 +1246,13 @@ static void t_busy(unsigned long channel)
struct scc_channel *scc = (struct scc_channel *) channel;
del_timer(&scc->tx_t);
- scc_lock_dev(scc);
+ netif_stop_queue(scc->dev); /* don't pile on the wabbit! */
scc_discard_buffers(scc);
-
scc->stat.txerrs++;
scc->stat.tx_state = TXS_IDLE;
-
- scc_unlock_dev(scc);
+
+ netif_wake_queue(scc->dev);
}
/* MAXKEYUP timeout
@@ -1285,7 +1273,7 @@ static void t_maxkeyup(unsigned long channel)
* accept new data.
*/
- scc_lock_dev(scc);
+ netif_stop_queue(scc->dev);
scc_discard_buffers(scc);
del_timer(&scc->tx_t);
@@ -1460,8 +1448,7 @@ static void scc_stop_calibrate(unsigned long channel)
Outb(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */
Outb(scc->ctrl,RES_EXT_INT);
- scc_unlock_dev(scc);
-
+ netif_wake_queue(scc->dev);
restore_flags(flags);
}
@@ -1474,7 +1461,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
save_flags(flags);
cli();
- scc_lock_dev(scc);
+ netif_stop_queue(scc->dev);
scc_discard_buffers(scc);
del_timer(&scc->tx_wdog);
@@ -1497,7 +1484,6 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
Outb(scc->ctrl,RES_EXT_INT);
scc_key_trx(scc, TX_ON);
-
restore_flags(flags);
}
@@ -1583,7 +1569,9 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev
dev = scc->dev;
memset(dev, 0, sizeof(struct net_device));
- buf = (unsigned char *) kmalloc(10, GFP_KERNEL);
+ if ((buf = (unsigned char *) kmalloc(10, GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
strcpy(buf, name);
dev->priv = (void *) scc;
@@ -1627,6 +1615,7 @@ static int scc_net_init(struct net_device *dev)
dev->set_mac_address = scc_net_set_mac_address;
dev->get_stats = scc_net_get_stats;
dev->do_ioctl = scc_net_ioctl;
+ dev->tx_timeout = NULL;
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
@@ -1647,22 +1636,17 @@ static int scc_net_open(struct net_device *dev)
{
struct scc_channel *scc = (struct scc_channel *) dev->priv;
- if (scc == NULL || scc->magic != SCC_MAGIC)
- return -ENODEV;
-
if (!scc->init)
return -EINVAL;
MOD_INC_USE_COUNT;
-
+
scc->tx_buff = NULL;
skb_queue_head_init(&scc->tx_queue);
init_channel(scc);
- dev->tbusy = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
return 0;
}
@@ -1673,10 +1657,7 @@ static int scc_net_close(struct net_device *dev)
struct scc_channel *scc = (struct scc_channel *) dev->priv;
unsigned long flags;
- if (scc == NULL || scc->magic != SCC_MAGIC)
- return -ENODEV;
-
- MOD_DEC_USE_COUNT;
+ netif_stop_queue(dev);
save_flags(flags);
cli();
@@ -1692,9 +1673,7 @@ static int scc_net_close(struct net_device *dev)
scc_discard_buffers(scc);
- dev->tbusy = 1;
- dev->start = 0;
-
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -1704,7 +1683,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
{
if (skb->len == 0)
{
- kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
return;
}
@@ -1726,12 +1705,6 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
struct scc_channel *scc = (struct scc_channel *) dev->priv;
unsigned long flags;
char kisscmd;
-
- if (scc == NULL || scc->magic != SCC_MAGIC || dev->tbusy)
- {
- dev_kfree_skb(skb);
- return 0;
- }
if (skb->len > scc->stat.bufsize || skb->len < 2)
{
@@ -1759,12 +1732,12 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len)
{
struct sk_buff *skb_del;
- skb_del = __skb_dequeue(&scc->tx_queue);
+ skb_del = skb_dequeue(&scc->tx_queue);
dev_kfree_skb(skb_del);
}
- __skb_queue_tail(&scc->tx_queue, skb);
-
+ skb_queue_tail(&scc->tx_queue, skb);
dev->trans_start = jiffies;
+
/*
* Start transmission if the trx state is idle or
@@ -1781,8 +1754,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
scc_start_tx_timer(scc, t_dwait, 0);
}
- restore_flags(flags);
-
+ restore_flags(flags);
return 0;
}
@@ -1811,9 +1783,6 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct scc_channel *scc;
scc = (struct scc_channel *) dev->priv;
- if (scc == NULL || scc->magic != SCC_MAGIC)
- return -EINVAL;
-
arg = (void *) ifr->ifr_data;
if (!Driver_Initialized)
@@ -2052,9 +2021,6 @@ static struct net_device_stats *scc_net_get_stats(struct net_device *dev)
{
struct scc_channel *scc = (struct scc_channel *) dev->priv;
- if (scc == NULL || scc->magic != SCC_MAGIC)
- return NULL;
-
scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over;
scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under;
scc->dev_stat.rx_fifo_errors = scc->stat.rx_over;
@@ -2186,7 +2152,7 @@ done:
/* * Init SCC driver * */
/* ******************************************************************** */
-int __init scc_init (void)
+static int __init scc_init_driver (void)
{
int chip, chan, k, result;
char devname[10];
@@ -2222,25 +2188,7 @@ int __init scc_init (void)
return 0;
}
-/* ******************************************************************** */
-/* * Module support * */
-/* ******************************************************************** */
-
-
-#ifdef MODULE
-int init_module(void)
-{
- int result = 0;
-
- result = scc_init();
-
- if (result == 0)
- printk(KERN_INFO "Copyright 1993,1998 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n");
-
- return result;
-}
-
-void cleanup_module(void)
+static void __exit scc_cleanup_driver(void)
{
long flags;
io_port ctrl;
@@ -2283,4 +2231,9 @@ void cleanup_module(void)
scc_net_procfs_remove();
}
-#endif
+
+MODULE_AUTHOR("Joerg Reuter <jreuter@poboxes.com>");
+MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards");
+MODULE_SUPPORTED_DEVICE("scc");
+module_init(scc_init_driver);
+module_exit(scc_cleanup_driver);
diff --git a/drivers/net/hamradio/soundmodem/sm.c b/drivers/net/hamradio/soundmodem/sm.c
index 6fa4aca6b..4e5e3e9b9 100644
--- a/drivers/net/hamradio/soundmodem/sm.c
+++ b/drivers/net/hamradio/soundmodem/sm.c
@@ -3,7 +3,7 @@
/*
* sm.c -- soundcard radio modem 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
@@ -34,17 +34,18 @@
*
*
* History:
- * 0.1 21.09.96 Started
- * 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
- * 0.4 21.01.97 Separately compileable soundcard/modem modules
- * 0.5 03.03.97 fixed LPT probing (check_lpt result was interpreted the wrong way round)
- * 0.6 16.04.97 init code/data tagged
- * 0.7 30.07.97 fixed halfduplex interrupt handlers/hotfix for CS423X
- * 0.8 14.04.98 cleanups
- * 0.9 03.08.99 adapt to Linus' new __setup/__initcall
- * use parport lowlevel drivers instead of directly writing to a parallel port
- * removed some pre-2.2 kernel compatibility cruft
- * 0.10 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.1 21.09.1996 Started
+ * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
+ * 0.4 21.01.1997 Separately compileable soundcard/modem modules
+ * 0.5 03.03.1997 fixed LPT probing (check_lpt result was interpreted the wrong way round)
+ * 0.6 16.04.1997 init code/data tagged
+ * 0.7 30.07.1997 fixed halfduplex interrupt handlers/hotfix for CS423X
+ * 0.8 14.04.1998 cleanups
+ * 0.9 03.08.1999 adapt to Linus' new __setup/__initcall
+ * use parport lowlevel drivers instead of directly writing to a parallel port
+ * removed some pre-2.2 kernel compatibility cruft
+ * 0.10 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
+ * 0.11 12.02.2000 adapted to softnet driver interface
*/
/*****************************************************************************/
@@ -63,8 +64,8 @@
/* --------------------------------------------------------------------- */
/*static*/ const char sm_drvname[] = "soundmodem";
-static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "soundmodem: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
+static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "soundmodem: version 0.11 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
@@ -508,7 +509,7 @@ static int sm_ioctl(struct net_device *dev, struct ifreq *ifr,
return 0;
case HDLCDRVCTL_SETMODE:
- if (dev->start || !suser())
+ if (netif_running(dev) || !suser())
return -EACCES;
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
return sethw(dev, sm, hi->data.modename);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index e99d4c7a9..400facbf8 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -649,7 +649,7 @@ static void yam_dotimer(unsigned long dummy)
for (i = 0; i < NR_PORTS; i++) {
struct net_device *dev = &yam_ports[i].dev;
- if (dev->start)
+ if (netif_running(dev))
yam_arbitrate(dev);
}
yam_timer.expires = jiffies + HZ / 100;
@@ -748,7 +748,7 @@ static void yam_interrupt(int irq, void *dev_id, struct pt_regs *regs)
yp = &yam_ports[i];
dev = &yp->dev;
- if (!dev->start)
+ if (!netif_running(dev))
continue;
while ((iir = IIR_MASK & inb(IIR(dev->base_addr))) != IIR_NOPEND) {
@@ -794,7 +794,7 @@ static int yam_net_get_info(char *buffer, char **start, off_t offset, int length
if (yam_ports[i].iobase == 0 || yam_ports[i].irq == 0)
continue;
len += sprintf(buffer + len, "Device %s\n", yam_ports[i].name);
- len += sprintf(buffer + len, " Up %d\n", yam_ports[i].dev.start);
+ len += sprintf(buffer + len, " Up %d\n", netif_running(&yam_ports[i].dev));
len += sprintf(buffer + len, " Speed %u\n", yam_ports[i].bitrate);
len += sprintf(buffer + len, " IoBase 0x%x\n", yam_ports[i].iobase);
len += sprintf(buffer + len, " BaudRate %u\n", yam_ports[i].baudrate);
@@ -903,7 +903,9 @@ static int yam_open(struct net_device *dev)
request_region(dev->base_addr, YAM_EXTENT, dev->name);
yam_set_uart(dev);
- dev->start = 1;
+
+ netif_start_queue(dev);
+
yp->slotcnt = yp->slot / 10;
/* Reset overruns for all ports - FPGA programming makes overruns */
@@ -935,8 +937,7 @@ static int yam_close(struct net_device *dev)
/* Remove IRQ handler if last */
free_irq(dev->irq, NULL);
release_region(dev->base_addr, YAM_EXTENT);
- dev->start = 0;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
while ((skb = skb_dequeue(&yp->send_queue)))
dev_kfree_skb(skb);
@@ -973,7 +974,7 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EINVAL; /* unused */
case SIOCYAMSMCS:
- if (dev->start)
+ if (netif_running(dev))
return -EINVAL; /* Cannot change this parameter when up */
ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_ATOMIC);
ym->bitrate = 9600;
@@ -989,13 +990,13 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (copy_from_user(&yi, ifr->ifr_data, sizeof(struct yamdrv_ioctl_cfg)))
return -EFAULT;
- if ((yi.cfg.mask & YAM_IOBASE) && dev->start)
+ if ((yi.cfg.mask & YAM_IOBASE) && netif_running(dev))
return -EINVAL; /* Cannot change this parameter when up */
- if ((yi.cfg.mask & YAM_IRQ) && dev->start)
+ if ((yi.cfg.mask & YAM_IRQ) && netif_running(dev))
return -EINVAL; /* Cannot change this parameter when up */
- if ((yi.cfg.mask & YAM_BITRATE) && dev->start)
+ if ((yi.cfg.mask & YAM_BITRATE) && netif_running(dev))
return -EINVAL; /* Cannot change this parameter when up */
- if ((yi.cfg.mask & YAM_BAUDRATE) && dev->start)
+ if ((yi.cfg.mask & YAM_BAUDRATE) && netif_running(dev))
return -EINVAL; /* Cannot change this parameter when up */
if (yi.cfg.mask & YAM_IOBASE) {
@@ -1164,8 +1165,6 @@ int __init yam_init(void)
dev->irq = yam_ports[i].irq;
dev->init = yam_probe;
dev->if_port = 0;
- dev->start = 0;
- dev->tbusy = 1;
if (register_netdev(dev)) {
printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name);
@@ -1211,7 +1210,7 @@ void cleanup_module(void)
struct net_device *dev = &yam_ports[i].dev;
if (!dev->priv)
continue;
- if (dev->start)
+ if (netif_running(dev))
yam_close(dev);
unregister_netdev(dev);
}