#define VERSION "arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al.\n"
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <net/arp.h>
#include <linux/init.h>
#include <linux/arcdevice.h>
-
+#include <linux/jiffies.h>
/* "do nothing" functions for protocol drivers */
static void null_rx(struct net_device *dev, int bufnum,
static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
int length, int bufnum);
+static void arcnet_rx(struct net_device *dev, int bufnum);
/*
* one ArcProto per possible proto ID. None of the elements of
* arc_proto_default instead. It also must not be NULL; if you would like
* to set it to NULL, set it to &arc_proto_null instead.
*/
-struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto;
+ struct ArcProto *arc_proto_map[256], *arc_proto_default,
+ *arc_bcast_proto, *arc_raw_proto;
-struct ArcProto arc_proto_null =
+static struct ArcProto arc_proto_null =
{
.suffix = '?',
.mtu = XMTU,
+ .is_ip = 0,
.rx = null_rx,
.build_header = null_build_header,
.prepare_tx = null_prepare_tx,
+ .continue_tx = NULL,
+ .ack_tx = NULL
};
-static spinlock_t arcnet_lock = SPIN_LOCK_UNLOCKED;
-
/* Exported function prototypes */
int arcnet_debug = ARCNET_DEBUG;
EXPORT_SYMBOL(arc_proto_map);
EXPORT_SYMBOL(arc_proto_default);
EXPORT_SYMBOL(arc_bcast_proto);
-EXPORT_SYMBOL(arc_proto_null);
+EXPORT_SYMBOL(arc_raw_proto);
EXPORT_SYMBOL(arcnet_unregister_proto);
EXPORT_SYMBOL(arcnet_debug);
-EXPORT_SYMBOL(arcdev_setup);
EXPORT_SYMBOL(alloc_arcdev);
EXPORT_SYMBOL(arcnet_interrupt);
static int go_tx(struct net_device *dev);
static int debug = ARCNET_DEBUG;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
MODULE_LICENSE("GPL");
static int __init arcnet_init(void)
arcnet_debug = debug;
- printk(VERSION);
+ printk("arcnet loaded.\n");
#ifdef ALPHA_WARNING
BUGLVL(D_EXTRA) {
#endif
/* initialize the protocol map */
- arc_proto_default = arc_bcast_proto = &arc_proto_null;
+ arc_raw_proto = arc_proto_default = arc_bcast_proto = &arc_proto_null;
for (count = 0; count < 256; count++)
arc_proto_map[count] = arc_proto_default;
* Dump the contents of an sk_buff
*/
#if ARCNET_DEBUG_MAX & D_SKB
-void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
+void arcnet_dump_skb(struct net_device *dev,
+ struct sk_buff *skb, char *desc)
{
int i;
* Dump the contents of an ARCnet buffer
*/
#if (ARCNET_DEBUG_MAX & (D_RX | D_TX))
-void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc)
+static void arcnet_dump_packet(struct net_device *dev, int bufnum,
+ char *desc, int take_arcnet_lock)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int i, length;
- unsigned long flags;
+ unsigned long flags = 0;
static uint8_t buf[512];
/* hw.copy_from_card expects IRQ context so take the IRQ lock
to keep it single threaded */
- spin_lock_irqsave(&arcnet_lock, flags);
+ if(take_arcnet_lock)
+ spin_lock_irqsave(&lp->lock, flags);
+
lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
- spin_unlock_irqrestore(&arcnet_lock, flags);
+ if(take_arcnet_lock)
+ spin_unlock_irqrestore(&lp->lock, flags);
/* if the offset[0] byte is nonzero, this is a 256-byte packet */
length = (buf[2] ? 256 : 512);
}
-EXPORT_SYMBOL(arcnet_dump_packet);
+#else
+
+#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) do { } while (0)
+
#endif
arc_proto_default = &arc_proto_null;
if (arc_bcast_proto == proto)
arc_bcast_proto = arc_proto_default;
+ if (arc_raw_proto == proto)
+ arc_raw_proto = arc_proto_default;
for (count = 0; count < 256; count++) {
if (arc_proto_map[count] == proto)
*/
static void release_arcbuf(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int i;
lp->buf_queue[lp->first_free_buf++] = bufnum;
BUGLVL(D_DURING) {
BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ",
bufnum);
- for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
+ for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
BUGMSG2(D_DURING, "\n");
}
*/
static int get_arcbuf(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int buf = -1, i;
- if (!atomic_dec_and_test(&lp->buf_lock)) /* already in this function */
- BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", lp->buf_lock.counter);
+ if (!atomic_dec_and_test(&lp->buf_lock)) {
+ /* already in this function */
+ BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n",
+ lp->buf_lock.counter);
+ }
else { /* we can continue */
if (lp->next_buf >= 5)
lp->next_buf -= 5;
BUGLVL(D_DURING) {
BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf);
- for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
+ for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
BUGMSG2(D_DURING, "\n");
}
/* Setup a struct device for ARCnet. */
-void arcdev_setup(struct net_device *dev)
+static void arcdev_setup(struct net_device *dev)
{
dev->type = ARPHRD_ARCNET;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
dev->addr_len = ARCNET_ALEN;
- dev->tx_queue_len = 30;
+ dev->tx_queue_len = 100;
dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */
dev->watchdog_timeo = TX_TIMEOUT;
struct net_device *alloc_arcdev(char *name)
{
- return alloc_netdev(sizeof(struct arcnet_local),
- name && *name ? name : "arc%d", arcdev_setup);
+ struct net_device *dev;
+
+ dev = alloc_netdev(sizeof(struct arcnet_local),
+ name && *name ? name : "arc%d", arcdev_setup);
+ if(dev) {
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ spin_lock_init(&lp->lock);
+ }
+
+ return dev;
}
/*
*/
static int arcnet_open(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int count, newmtu, error;
+ BUGMSG(D_INIT,"opened.");
+
if (!try_module_get(lp->hw.owner))
return -ENODEV;
if (newmtu < dev->mtu)
dev->mtu = newmtu;
+ BUGMSG(D_INIT, "arcnet_open: mtu: %d.\n", dev->mtu);
+
/* autodetect the encapsulation for each host. */
memset(lp->default_proto, 0, sizeof(lp->default_proto));
/* initialize buffers */
atomic_set(&lp->buf_lock, 1);
+
lp->next_buf = lp->first_free_buf = 0;
release_arcbuf(dev, 0);
release_arcbuf(dev, 1);
lp->rfc1201.sequence = 1;
/* bring up the hardware driver */
- lp->hw.open(dev);
+ if (lp->hw.open)
+ lp->hw.open(dev);
if (dev->dev_addr[0] == 0)
BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved "
BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
"DOS networking programs!\n");
- if (ASTATUS() & RESETflag)
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ if (ASTATUS() & RESETflag) {
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
ACOMMAND(CFLAGScmd | RESETclear);
+ }
+
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
/* make sure we're ready to receive IRQ's. */
AINTMASK(0);
udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
*/
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
lp->intmask = NORXflag | RECONflag;
AINTMASK(lp->intmask);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
netif_start_queue(dev);
/* The inverse routine to arcnet_open - shuts down the card. */
static int arcnet_close(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
netif_stop_queue(dev);
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
uint8_t _daddr, proto_num;
struct ArcProto *proto;
daddr ? *(uint8_t *) daddr : -1,
type, type, len);
- if (len != skb->len)
+ if (skb->len!=0 && len != skb->len)
BUGMSG(D_NORMAL, "arcnet_header: Yikes! skb->len(%d) != len(%d)!\n",
skb->len, len);
- /*
- * if the dest addr isn't provided, we can't choose an encapsulation!
- * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
- * real header when we do rebuild_header.
- */
- if (!daddr) {
+
+ /* Type is host order - ? */
+ if(type == ETH_P_ARCNET) {
+ proto = arc_raw_proto;
+ BUGMSG(D_DEBUG, "arc_raw_proto used. proto='%c'\n",proto->suffix);
+ _daddr = daddr ? *(uint8_t *) daddr : 0;
+ }
+ else if (!daddr) {
+ /*
+ * if the dest addr isn't provided, we can't choose an encapsulation!
+ * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
+ * real header when we do rebuild_header.
+ */
*(uint16_t *) skb_push(skb, 2) = type;
if (skb->nh.raw - skb->mac.raw != 2)
BUGMSG(D_NORMAL, "arcnet_header: Yikes! diff (%d) is not 2!\n",
(int)(skb->nh.raw - skb->mac.raw));
return -2; /* return error -- can't transmit yet! */
}
- /* otherwise, we can just add the header as usual. */
- _daddr = *(uint8_t *) daddr;
- proto_num = lp->default_proto[_daddr];
- proto = arc_proto_map[proto_num];
- BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
- proto_num, proto->suffix);
- if (proto == &arc_proto_null && arc_bcast_proto != proto) {
- BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
- arc_bcast_proto->suffix);
- proto = arc_bcast_proto;
+ else {
+ /* otherwise, we can just add the header as usual. */
+ _daddr = *(uint8_t *) daddr;
+ proto_num = lp->default_proto[_daddr];
+ proto = arc_proto_map[proto_num];
+ BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
+ proto_num, proto->suffix);
+ if (proto == &arc_proto_null && arc_bcast_proto != proto) {
+ BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
+ arc_bcast_proto->suffix);
+ proto = arc_bcast_proto;
+ }
}
return proto->build_header(skb, dev, type, _daddr);
}
static int arcnet_rebuild_header(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int status = 0; /* default is failure */
unsigned short type;
uint8_t daddr=0;
return 0;
}
type = *(uint16_t *) skb_pull(skb, 2);
+ BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type);
if (type == ETH_P_IP) {
#ifdef CONFIG_INET
/* Called by the kernel in order to transmit a packet. */
static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
struct archdr *pkt;
struct arc_rfc1201 *soft;
struct ArcProto *proto;
int txbuf;
+ unsigned long flags;
+ int freeskb, retval;
BUGMSG(D_DURING,
- "transmit requested (status=%Xh, txbufs=%d/%d, len=%d)\n",
- ASTATUS(), lp->cur_tx, lp->next_tx, skb->len);
+ "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
+ ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol);
pkt = (struct archdr *) skb->data;
soft = &pkt->soft.rfc1201;
if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) {
BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
dev_kfree_skb(skb);
- return 0; /* don't try again */
+ return NETDEV_TX_OK; /* don't try again */
}
/* We're busy transmitting a packet... */
netif_stop_queue(dev);
+ spin_lock_irqsave(&lp->lock, flags);
AINTMASK(0);
-
- txbuf = get_arcbuf(dev);
+ if(lp->next_tx == -1)
+ txbuf = get_arcbuf(dev);
+ else {
+ txbuf = -1;
+ }
if (txbuf != -1) {
- if (proto->prepare_tx(dev, pkt, skb->len, txbuf)) {
- /* done right away */
+ if (proto->prepare_tx(dev, pkt, skb->len, txbuf) &&
+ !proto->ack_tx) {
+ /* done right away and we don't want to acknowledge
+ the package later - forget about it now */
lp->stats.tx_bytes += skb->len;
- dev_kfree_skb(skb);
+ freeskb = 1;
} else {
/* do it the 'split' way */
lp->outgoing.proto = proto;
lp->outgoing.skb = skb;
lp->outgoing.pkt = pkt;
- if (!proto->continue_tx)
- BUGMSG(D_NORMAL, "bug! prep_tx==0, but no continue_tx!\n");
- else if (proto->continue_tx(dev, txbuf)) {
- BUGMSG(D_NORMAL,
- "bug! continue_tx finished the first time! "
- "(proto='%c')\n", proto->suffix);
+ freeskb = 0;
+
+ if (proto->continue_tx &&
+ proto->continue_tx(dev, txbuf)) {
+ BUGMSG(D_NORMAL,
+ "bug! continue_tx finished the first time! "
+ "(proto='%c')\n", proto->suffix);
}
}
-
+ retval = NETDEV_TX_OK;
+ dev->trans_start = jiffies;
lp->next_tx = txbuf;
- } else
- dev_kfree_skb(skb);
+ } else {
+ retval = NETDEV_TX_BUSY;
+ freeskb = 0;
+ }
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
/* make sure we didn't ignore a TX IRQ while we were in here */
AINTMASK(0);
- lp->intmask |= TXFREEflag;
+
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ lp->intmask |= TXFREEflag|EXCNAKflag;
AINTMASK(lp->intmask);
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
- return 0; /* no need to try again */
+ spin_unlock_irqrestore(&lp->lock, flags);
+ if (freeskb) {
+ dev_kfree_skb(skb);
+ }
+ return retval; /* no need to try again */
}
*/
static int go_tx(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
if (lp->cur_tx != -1 || lp->next_tx == -1)
return 0;
- BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx");
+ BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0);
lp->cur_tx = lp->next_tx;
lp->next_tx = -1;
/* start sending */
ACOMMAND(TXcmd | (lp->cur_tx << 3));
- dev->trans_start = jiffies;
lp->stats.tx_packets++;
lp->lasttrans_dest = lp->lastload_dest;
lp->lastload_dest = 0;
- lp->intmask |= TXFREEflag;
+ lp->excnak_pending = 0;
+ lp->intmask |= TXFREEflag|EXCNAKflag;
return 1;
}
static void arcnet_timeout(struct net_device *dev)
{
unsigned long flags;
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
int status = ASTATUS();
char *msg;
- spin_lock_irqsave(&arcnet_lock, flags);
+ spin_lock_irqsave(&lp->lock, flags);
if (status & TXFREEflag) { /* transmit _DID_ finish */
msg = " - missed IRQ?";
} else {
}
lp->stats.tx_errors++;
- /* make sure we didn't miss a TX IRQ */
+ /* make sure we didn't miss a TX or a EXC NAK IRQ */
AINTMASK(0);
- lp->intmask |= TXFREEflag;
+ lp->intmask |= TXFREEflag|EXCNAKflag;
AINTMASK(lp->intmask);
- spin_unlock_irqrestore(&arcnet_lock, flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
- if (jiffies - lp->last_timeout > 10*HZ) {
+ if (time_after(jiffies, lp->last_timeout + 10*HZ)) {
BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n",
msg, status, lp->intmask, lp->lasttrans_dest);
lp->last_timeout = jiffies;
* interrupts. Establish which device needs attention, and call the correct
* chipset interrupt handler.
*/
-irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t arcnet_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct arcnet_local *lp;
- int recbuf, status, didsomething, boguscount;
+ int recbuf, status, diagstatus, didsomething, boguscount;
+ int retval = IRQ_NONE;
BUGMSG(D_DURING, "\n");
BUGMSG(D_DURING, "in arcnet_interrupt\n");
-
- spin_lock(&arcnet_lock);
- lp = (struct arcnet_local *) dev->priv;
- if (!lp)
- BUG();
+ lp = dev->priv;
+ BUG_ON(!lp);
+ spin_lock(&lp->lock);
+
/*
* RESET flag was enabled - if device is not running, we must clear it right
* away (but nothing else).
if (ASTATUS() & RESETflag)
ACOMMAND(CFLAGScmd | RESETclear);
AINTMASK(0);
- spin_unlock(&arcnet_lock);
+ spin_unlock(&lp->lock);
return IRQ_HANDLED;
}
boguscount = 5;
do {
status = ASTATUS();
+ diagstatus = (status >> 8) & 0xFF;
+
+ BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
+ __FILE__,__LINE__,__FUNCTION__,status);
didsomething = 0;
/*
}
didsomething++;
}
+
+ if((diagstatus & EXCNAKflag)) {
+ BUGMSG(D_DURING, "EXCNAK IRQ (diagstat=%Xh)\n",
+ diagstatus);
+
+ ACOMMAND(NOTXcmd); /* disable transmit */
+ lp->excnak_pending = 1;
+
+ ACOMMAND(EXCNAKclear);
+ lp->intmask &= ~(EXCNAKflag);
+ didsomething++;
+ }
+
+
/* a transmit finished, and we're interested in it. */
if ((status & lp->intmask & TXFREEflag) || lp->timed_out) {
- lp->intmask &= ~TXFREEflag;
+ lp->intmask &= ~(TXFREEflag|EXCNAKflag);
BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
- if (lp->cur_tx != -1 && !(status & TXACKflag) && !lp->timed_out) {
- if (lp->lasttrans_dest != 0) {
- BUGMSG(D_EXTRA, "transmit was not acknowledged! "
- "(status=%Xh, dest=%02Xh)\n",
- status, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_carrier_errors++;
- } else {
- BUGMSG(D_DURING,
- "broadcast was not acknowledged; that's normal "
- "(status=%Xh, dest=%02Xh)\n",
- status, lp->lasttrans_dest);
+ if (lp->cur_tx != -1 && !lp->timed_out) {
+ if(!(status & TXACKflag)) {
+ if (lp->lasttrans_dest != 0) {
+ BUGMSG(D_EXTRA,
+ "transmit was not acknowledged! "
+ "(status=%Xh, dest=%02Xh)\n",
+ status, lp->lasttrans_dest);
+ lp->stats.tx_errors++;
+ lp->stats.tx_carrier_errors++;
+ } else {
+ BUGMSG(D_DURING,
+ "broadcast was not acknowledged; that's normal "
+ "(status=%Xh, dest=%02Xh)\n",
+ status, lp->lasttrans_dest);
+ }
+ }
+
+ if (lp->outgoing.proto &&
+ lp->outgoing.proto->ack_tx) {
+ int ackstatus;
+ if(status & TXACKflag)
+ ackstatus=2;
+ else if(lp->excnak_pending)
+ ackstatus=1;
+ else
+ ackstatus=0;
+
+ lp->outgoing.proto
+ ->ack_tx(dev, ackstatus);
}
}
if (lp->cur_tx != -1)
if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
/* that was the last segment */
lp->stats.tx_bytes += lp->outgoing.skb->len;
- dev_kfree_skb_irq(lp->outgoing.skb);
- lp->outgoing.proto = NULL;
+ if(!lp->outgoing.proto->ack_tx)
+ {
+ dev_kfree_skb_irq(lp->outgoing.skb);
+ lp->outgoing.proto = NULL;
+ }
}
lp->next_tx = txbuf;
}
}
/* now process the received packet, if any */
if (recbuf != -1) {
- BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq");
+ BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq", 0);
arcnet_rx(dev, recbuf);
release_arcbuf(dev, recbuf);
BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
status);
+ /* MYRECON bit is at bit 7 of diagstatus */
+ if(diagstatus & 0x80)
+ BUGMSG(D_RECON,"Put out that recon myself\n");
/* is the RECON info empty or old? */
if (!lp->first_recon || !lp->last_recon ||
BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
}
+
+ if(didsomething) {
+ retval |= IRQ_HANDLED;
+ }
}
while (--boguscount && didsomething);
udelay(1);
AINTMASK(lp->intmask);
- spin_unlock(&arcnet_lock);
- return IRQ_RETVAL(didsomething);
+ spin_unlock(&lp->lock);
+ return retval;
}
* This is a generic packet receiver that calls arcnet??_rx depending on the
* protocol ID found.
*/
-void arcnet_rx(struct net_device *dev, int bufnum)
+static void arcnet_rx(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
struct archdr pkt;
struct arc_rfc1201 *soft;
int length, ofs;
}
/* get the full header, if possible */
- if (sizeof(pkt.soft) < length)
+ if (sizeof(pkt.soft) <= length)
lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
else {
memset(&pkt.soft, 0, sizeof(pkt.soft));
lp->stats.rx_bytes += length + ARC_HDR_SIZE;
/* call the right receiver for the protocol */
- if (arc_proto_map[soft->proto] != &arc_proto_null) {
+ if (arc_proto_map[soft->proto]->is_ip) {
BUGLVL(D_PROTO) {
struct ArcProto
*oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
*/
static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
return &lp->stats;
}
static int null_build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
BUGMSG(D_PROTO,
"tx: can't build header for encap %02Xh; load a protocol driver.\n",
static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
int length, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = dev->priv;
struct arc_hardware newpkt;
BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");