patch-2.1.19 linux/drivers/net/arcnet.c
Next file: linux/drivers/net/at1700.c
Previous file: linux/drivers/net/apricot.c
Back to the patch index
Back to the overall index
- Lines: 1575
- Date:
Tue Dec 31 10:29:59 1996
- Orig file:
v2.1.18/linux/drivers/net/arcnet.c
- Orig date:
Thu Dec 12 19:37:05 1996
diff -u --recursive --new-file v2.1.18/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
@@ -4,9 +4,9 @@
Contact Avery at: apenwarr@foxnet.net or
RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
+
**********************
-
+
The original copyright was as follows:
skeleton.c Written 1993 by Donald Becker.
@@ -14,9 +14,9 @@
Director, National Security Agency. This software may only be used
and distributed according to the terms of the GNU Public License as
modified by SRC, incorporated herein by reference.
-
+
**********************
-
+
v2.60 ALPHA (96/11/23)
- Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz>
and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work
@@ -43,13 +43,13 @@
The following has been SUMMARIZED. The complete ChangeLog is
available in the full Linux-ARCnet package at
http://www.foxnet.net/~apenwarr/arcnet
-
+
v2.50 (96/02/24)
- Massively improved autoprobe routines; they now work even as a
module. Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
for his ideas and help in this area.
- Changed printk's around quite a lot.
-
+
v2.22 (95/12/08)
- Major cleanups, speedups, and better code-sharing.
- Eliminated/changed many useless/meaningless/scary debug messages
@@ -73,7 +73,7 @@
send "Ethernet-Encapsulation" packets, which are compatible with
Windows for Workgroups and LAN Manager, and possibly other
software. See the README for more information.
-
+
v1.02 (95/06/21)
- A fix to make "exception" packets sent from Linux receivable
on other systems. (The protocol_id byte was sometimes being set
@@ -84,13 +84,13 @@
- Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski
<motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work
with dosemu!)
-
+
v1.00 (95/02/15)
- Initial non-alpha release.
-
-
+
+
TO DO: (semi-prioritized)
-
+
- Use cleaner "architecture-independent" shared memory access.
This is half-done in ARCnet 2.60, but still uses some
undocumented i386 stuff. (We shouldn't call phys_to_virt,
@@ -115,10 +115,10 @@
- Try to implement promiscuous (receive-all-packets) mode available
on some newer cards with COM20020 and similar chips. I don't have
one, but SMC sent me the specs.
- - ATA protocol support??
+ - ATA protocol support??
- VINES TCP/IP encapsulation?? (info needed)
-
+
Sources:
- Crynwr arcnet.com/arcether.com packet drivers.
- arcnet.c v0.00 dated 1/1/94 and apparently by
@@ -139,7 +139,7 @@
static const char *version =
"arcnet.c: v2.60 96/11/23 Avery Pennarun <apenwarr@foxnet.net>\n";
-
+
#include <linux/module.h>
#include <linux/config.h>
@@ -178,7 +178,7 @@
*/
#undef RIM_I_MODE
-/* Normally, the ARCnet device needs to be assigned a name (default arc0).
+/* Normally, the ARCnet device needs to be assigned a name (default arc0).
* Ethernet devices have a function to automatically try eth0, eth1, etc
* until a free name is found. To name the ARCnet device using an "eth?"
* device name, define this option.
@@ -206,9 +206,9 @@
* usually happens when a new computer on the network is powered on or when
* the cable is broken.
*
- * Define DETECT_RECONFIGS if you want to detect network reconfigurations.
+ * Define DETECT_RECONFIGS if you want to detect network reconfigurations.
* Recons may be a real nuisance on a larger ARCnet network; if you are a
- * network administrator you probably would like to count them.
+ * network administrator you probably would like to count them.
* Reconfigurations will be recorded in stats.tx_carrier_errors (the last
* field of the /proc/net/dev file).
*
@@ -317,7 +317,7 @@
* results in the cleanest mess possible.
*/
#define ADEV lp->adev
-
+
#ifdef CONFIG_ARCNET_ETH
#define EDEV lp->edev
#else
@@ -481,7 +481,7 @@
*/
u_char saddr, /* Source address - needed for IPX */
daddr; /* Destination address */
-
+
/* data that IS part of real packet */
u_char protocol_id, /* ARC_P_IP, ARC_P_ARP, etc */
split_flag; /* for use with split packets */
@@ -502,7 +502,7 @@
u_char saddr, /* Source address - needed for IPX */
daddr, /* Destination address */
junk; /* padding to make an even length */
-
+
/* data that IS part of real packet */
u_char protocol_id; /* ARC_P_IP, ARC_P_ARP, etc */
};
@@ -554,11 +554,11 @@
int num_recons, /* number of RECONs between first and last. */
network_down; /* do we think the network is down? */
#endif
-
+
struct timer_list timer; /* the timer interrupt struct */
struct Incoming incoming[256]; /* one from each address */
struct Outgoing outgoing; /* packet currently being sent */
-
+
struct device *adev; /* RFC1201 protocol device */
#ifdef CONFIG_ARCNET_ETH
@@ -655,13 +655,13 @@
****************************************************************************/
/* Dump the contents of an sk_buff
- */
+ */
#if ARCNET_DEBUG_MAX & D_SKB
void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc)
{
int i;
long flags;
-
+
save_flags(flags);
cli();
printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc);
@@ -683,7 +683,7 @@
{
int i;
long flags;
-
+
save_flags(flags);
cli();
printk(KERN_DEBUG "%6s: packet dump (%s) follows:",dev->name,desc);
@@ -696,7 +696,7 @@
printk("\n");
restore_flags(flags);
}
-#endif
+#endif
/****************************************************************************
* *
@@ -717,21 +717,21 @@
BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n");
BUGMSG(D_NORMAL,"Given: node %02lXh, shmem %lXh, irq %d\n",
dev->base_addr,dev->mem_start,dev->irq);
-
+
if (dev->mem_start<=0 || dev->irq<=0)
{
BUGMSG(D_NORMAL,"No autoprobe for RIM I; you "
"must specify the shmem and irq!\n");
return -ENODEV;
}
-
+
if (dev->base_addr<=0 || dev->base_addr>255)
{
BUGMSG(D_NORMAL,"You need to specify your card's station "
"ID!\n");
return -ENODEV;
}
-
+
return arcnet_found(dev,dev->base_addr,dev->irq,dev->mem_start);
}
@@ -762,7 +762,7 @@
unsigned long airqmask;
int *port;
u_long *shmem;
-
+
if (!init_once)
{
for (count=0x200; count<=0x3f0; count+=16)
@@ -778,7 +778,7 @@
sizeof(ports),sizeof(shmems),
sizeof(ports)+sizeof(shmems));
-
+
#if 1
BUGLVL(D_EXTRA)
{
@@ -801,13 +801,13 @@
}
else if (dev->base_addr > 0) /* Don't probe at all. */
return -ENXIO;
-
+
if (dev->mem_start)
{
shmems[0]=dev->mem_start;
numshmems=1;
}
-
+
/* Stage 1: abandon any reserved ports, or ones with status==0xFF
* (empty), and reset any others by reading the reset port.
@@ -824,9 +824,9 @@
numprint=1;
}
BUGMSG2(D_INIT,"%Xh ",*port);
-
+
ioaddr=*port;
-
+
if (check_region(*port, ARCNET_TOTAL_SIZE))
{
BUGMSG2(D_INIT_REASONS,"(check_region)\n");
@@ -837,7 +837,7 @@
port--;
continue;
}
-
+
if (ARCSTATUS == 0xFF)
{
BUGMSG2(D_INIT_REASONS,"(empty)\n");
@@ -848,7 +848,7 @@
port--;
continue;
}
-
+
ARCRESET; /* begin resetting card */
BUGMSG2(D_INIT_REASONS,"\n");
@@ -856,13 +856,13 @@
BUGLVL(D_INIT_REASONS) numprint=0;
}
BUGMSG2(D_INIT,"\n");
-
+
if (!numports)
{
BUGMSG(D_NORMAL,"Stage 1: No ARCnet cards found.\n");
return -ENODEV;
}
-
+
/* Stage 2: we have now reset any possible ARCnet cards, so we can't
* do anything until they finish. If D_INIT, print the list of
@@ -883,7 +883,7 @@
}
BUGMSG2(D_INIT,"\n");
JIFFER(RESETtime);
-
+
/* Stage 3: abandon any shmem addresses that don't have the signature
* 0xD1 byte in the right place, or are read-only.
@@ -902,9 +902,9 @@
numprint=1;
}
BUGMSG2(D_INIT,"%lXh ",*shmem);
-
+
ptr=(u_long)(*shmem);
-
+
if (readb(ptr) != TESTvalue)
{
BUGMSG2(D_INIT_REASONS,"(mem=%02Xh, not %02Xh)\n",
@@ -916,7 +916,7 @@
shmem--;
continue;
}
-
+
/* By writing 0x42 to the TESTvalue location, we also make
* sure no "mirror" shmem areas show up - if they occur
* in another pass through this loop, they will be discarded
@@ -932,7 +932,7 @@
shmem--;
continue;
}
-
+
BUGMSG2(D_INIT_REASONS,"\n");
BUGMSG(D_INIT_REASONS,"Stage 3: ");
BUGLVL(D_INIT_REASONS) numprint=0;
@@ -962,7 +962,7 @@
BUGMSG2(D_INIT,"%lXh ",*shmem);
}
BUGMSG2(D_INIT,"\n");
-
+
/* Stage 5: for any ports that have the correct status, can disable
* the RESET flag, and (if no irq is given) generate an autoirq,
@@ -983,10 +983,10 @@
numprint=1;
}
BUGMSG2(D_INIT,"%Xh ",*port);
-
+
ioaddr=*port;
status=ARCSTATUS;
-
+
if ((status & 0x9D)
!= (NORXflag|RECONflag|TXFREEflag|RESETflag))
{
@@ -1027,7 +1027,7 @@
udelay(1);
AINTMASK(0);
airq = probe_irq_off(airqmask);
-
+
if (airq<=0)
{
BUGMSG2(D_INIT_REASONS,"(airq=%d)\n",airq);
@@ -1043,10 +1043,10 @@
{
airq=dev->irq;
}
-
+
BUGMSG2(D_INIT,"(%d,", airq);
openparen=1;
-
+
/* Everything seems okay. But which shmem, if any, puts
* back its signature byte when the card is reset?
*
@@ -1074,7 +1074,7 @@
{
u_long ptr;
ptr=(u_long)(*shmem);
-
+
if (readb(ptr) == TESTvalue) /* found one */
{
BUGMSG2(D_INIT,"%lXh)\n", *shmem);
@@ -1087,7 +1087,7 @@
/* remove shmem from the list */
*shmem=shmems[numshmems-1];
numshmems--;
-
+
break;
}
else
@@ -1115,7 +1115,7 @@
*/
for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
writeb(TESTvalue,*shmem);
-
+
if (retval) BUGMSG(D_NORMAL,"Stage 5: No ARCnet cards found.\n");
return retval;
}
@@ -1131,7 +1131,7 @@
u_long first_mirror,last_mirror;
struct arcnet_local *lp;
int mirror_size;
-
+
/* reserve the irq */
if (request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL))
{
@@ -1150,9 +1150,9 @@
request_region(port,ARCNET_TOTAL_SIZE,"arcnet");
dev->base_addr=port;
#endif
-
+
/* find the real shared memory start/end points, including mirrors */
-
+
#define BUFFER_SIZE (512)
#define MIRROR_SIZE (BUFFER_SIZE*4)
@@ -1165,7 +1165,7 @@
&& readb(shmem-mirror_size)!=TESTvalue
&& readb(shmem-2*mirror_size)==TESTvalue)
mirror_size*=2;
-
+
first_mirror=last_mirror=shmem;
while (readb(first_mirror)==TESTvalue) first_mirror-=mirror_size;
first_mirror+=mirror_size;
@@ -1177,9 +1177,9 @@
dev->mem_end=last_mirror+MIRROR_SIZE-1;
dev->rmem_start=dev->mem_start+BUFFER_SIZE*0;
dev->rmem_end=dev->mem_start+BUFFER_SIZE*2-1;
-
+
/* Initialize the rest of the device structure. */
-
+
dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (dev->priv == NULL)
{
@@ -1190,7 +1190,7 @@
}
memset(dev->priv,0,sizeof(struct arcnet_local));
lp=(struct arcnet_local *)(dev->priv);
-
+
dev->open=arcnet_open;
dev->stop=arcnet_close;
dev->hard_start_xmit=arcnetA_send_packet;
@@ -1201,7 +1201,7 @@
* values.
*/
arcnet_setup(dev);
-
+
/* And now fill particular fields with arcnet values */
dev->mtu=1500; /* completely arbitrary - agrees with ether, though */
dev->hard_header_len=sizeof(struct ClientData);
@@ -1230,7 +1230,7 @@
lp->stationid,
dev->base_addr,dev->irq,dev->mem_start,
(dev->mem_end-dev->mem_start+1)/mirror_size,mirror_size);
-
+
return 0;
}
@@ -1247,11 +1247,11 @@
struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
short ioaddr=IOADDR;
int delayval,recbuf=lp->recbuf;
-
+
/* no IRQ's, please! */
lp->intmask=0;
SETMASK;
-
+
BUGMSG(D_INIT,"Resetting %s (status=%Xh)\n",
dev->name,ARCSTATUS);
@@ -1271,7 +1271,7 @@
BUGMSG(D_NORMAL,"reset failed: TESTvalue not present.\n");
return 1;
}
-
+
/* clear out status variables */
recbuf=lp->recbuf=0;
lp->txbuf=2;
@@ -1284,7 +1284,7 @@
BUGLVL(D_DURING)
memset_io(dev->mem_start,0x42,2048);
#endif
-
+
/* and enable receive of our first packet to the first buffer */
EnableReceiver();
@@ -1294,7 +1294,7 @@
lp->intmask|=RECONflag;
#endif
SETMASK;
-
+
/* done! return success. */
return 0;
}
@@ -1336,7 +1336,7 @@
* Open and close the driver *
* *
****************************************************************************/
-
+
/* Open/initialize the board. This is called sometime after booting when
* the 'ifconfig' program is run.
@@ -1350,7 +1350,7 @@
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
int ioaddr=IOADDR;
-
+
if (dev->metric>=1000)
{
arcnet_debug=dev->metric-1000;
@@ -1359,7 +1359,7 @@
}
BUGMSG(D_INIT,"arcnet_open: resetting card.\n");
-
+
#ifdef FAST_IFCONFIG
/* try to put the card in a defined state - if it fails the first
* time, actually reset it.
@@ -1372,17 +1372,17 @@
if (arcnet_reset(dev,1) && arcnet_reset(dev,1))
return -ENODEV;
#endif
-
+
dev->tbusy=0;
dev->interrupt=0;
lp->intx=0;
lp->in_txhandler=0;
-
+
/* The RFC1201 driver is the default - just store */
lp->adev=dev;
BUGMSG(D_NORMAL,"ARCnet RFC1201 protocol initialized.\n");
-#ifdef CONFIG_ARCNET_ETH
+#ifdef CONFIG_ARCNET_ETH
/* Initialize the ethernet-encap protocol driver */
lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL);
if (lp->edev == NULL)
@@ -1415,7 +1415,7 @@
/* we're started */
START=1;
-
+
/* make sure we're ready to receive IRQ's.
* arcnet_reset sets this for us, but if we receive one before
* START is set to 1, it could be ignored. So, we turn IRQ's
@@ -1427,7 +1427,7 @@
* necessary)
*/
SETMASK;
-
+
MOD_INC_USE_COUNT;
return 0;
}
@@ -1440,7 +1440,7 @@
{
int ioaddr=IOADDR;
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
-
+
TBUSY=1;
START=0;
@@ -1456,10 +1456,10 @@
/* reset more flags */
INTERRUPT=0;
-
+
/* do NOT free lp->adev!! It's static! */
lp->adev=NULL;
-
+
#ifdef CONFIG_ARCNET_ETH
/* free the ethernet-encap protocol device */
lp->edev->priv=NULL;
@@ -1501,10 +1501,10 @@
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
int ioaddr=IOADDR;
-
+
BUGMSG(D_DURING,"transmit requested (status=%Xh, inTX=%d)\n",
ARCSTATUS,lp->intx);
-
+
if (lp->in_txhandler)
{
BUGMSG(D_NORMAL,"send_packet called while in txhandler!\n");
@@ -1526,8 +1526,8 @@
int tickssofar = jiffies - dev->trans_start;
/*int recbuf=lp->recbuf;*/
int status=ARCSTATUS;
-
- if (tickssofar < TX_TIMEOUT)
+
+ if (tickssofar < TX_TIMEOUT)
{
BUGMSG(D_DURING,"premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n",
status,tickssofar,lp->outgoing.skb,
@@ -1538,7 +1538,7 @@
lp->intmask &= ~TXFREEflag;
SETMASK;
-
+
if (status&TXFREEflag) /* transmit _DID_ finish */
{
BUGMSG(D_NORMAL,"tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n",
@@ -1561,7 +1561,7 @@
lp->stats.tx_dropped++;
}
lp->outgoing.skb=NULL;
-
+
TBUSY=0;
lp->txready=0;
lp->sending=0;
@@ -1579,7 +1579,7 @@
dev_tint(dev);
return 0;
}
-
+
if (lp->txready) /* transmit already in progress! */
{
BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n",
@@ -1591,7 +1591,7 @@
lp->stats.tx_errors++;
lp->stats.tx_fifo_errors++;
lp->txready=0; /* we definitely need this line! */
-
+
return 1;
}
@@ -1620,24 +1620,24 @@
struct Outgoing *out=&(lp->outgoing);
lp->intx++;
-
+
bad=arcnet_send_packet_bad(skb,dev);
if (bad)
{
lp->intx--;
return bad;
}
-
+
TBUSY=1;
-
+
out->length = 1 < skb->len ? skb->len : 1;
out->hdr=(struct ClientData*)skb->data;
out->skb=skb;
-
+
BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx");
out->hdr->sequence=(lp->sequence++);
-
+
/* fits in one packet? */
if (out->length-EXTRA_CLIENTDATA<=XMTU)
{
@@ -1658,7 +1658,7 @@
/* done right away */
dev_kfree_skb(out->skb,FREE_WRITE);
out->skb=NULL;
-
+
if (arcnet_go_tx(dev,1))
{
/* inform upper layers */
@@ -1675,7 +1675,7 @@
out->dataleft=out->length-sizeof(struct ClientData);
out->numsegs=(out->dataleft+maxsegsize-1)/maxsegsize;
out->segnum=0;
-
+
BUGMSG(D_TX,"packet (%d bytes) split into %d fragments:\n",
out->length,out->numsegs);
@@ -1694,7 +1694,7 @@
arcnet_go_tx(dev,1);
}
}
-
+
/* if segnum==numsegs, the transmission is finished;
* free the skb right away.
*/
@@ -1710,7 +1710,7 @@
dev->trans_start=jiffies;
lp->intx--;
-
+
/* make sure we didn't ignore a TX IRQ while we were in here */
lp->intmask |= TXFREEflag;
SETMASK;
@@ -1728,16 +1728,16 @@
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
int ioaddr=IOADDR,maxsegsize=XMTU-4;
struct Outgoing *out=&(lp->outgoing);
-
+
BUGMSG(D_DURING,"continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n",
ARCSTATUS,lp->intx,lp->in_txhandler,lp->intmask);
-
+
if (lp->txready)
{
BUGMSG(D_NORMAL,"continue_tx: called with packet in buffer!\n");
return;
}
-
+
if (out->segnum>=out->numsegs)
{
BUGMSG(D_NORMAL,"continue_tx: building segment %d of %d!\n",
@@ -1751,7 +1751,7 @@
out->seglen=maxsegsize;
if (out->seglen>out->dataleft) out->seglen=out->dataleft;
-
+
BUGMSG(D_TX,"building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n",
out->segnum+1,out->seglen,out->numsegs,
out->length,out->hdr->split_flag);
@@ -1759,7 +1759,7 @@
arcnetAS_prepare_tx(dev,((char *)out->hdr)+EXTRA_CLIENTDATA,
sizeof(struct ClientData)-EXTRA_CLIENTDATA,
out->data,out->seglen,out->hdr->daddr,1);
-
+
out->dataleft-=out->seglen;
out->data+=out->seglen;
out->segnum++;
@@ -1775,16 +1775,16 @@
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
struct ClientData *arcsoft;
- union ArcPacket *arcpacket =
+ union ArcPacket *arcpacket =
(union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
int offset;
-
+
#ifdef SLOW_XMIT_COPY
char *iptr,*iend,*optr;
#endif
-
+
lp->txbuf=lp->txbuf^1; /* XOR with 1 to alternate between 2 and 3 */
-
+
length+=hdrlen;
BUGMSG(D_TX,"arcnetAS_prep_tx: hdr:%ph, length:%d, data:%ph\n",
@@ -1809,7 +1809,7 @@
{
arcpacket->hardheader.offset1=0;
arcpacket->hardheader.offset2=offset=512-length;
-
+
arcsoft=(struct ClientData *)
(&arcpacket->raw[offset]);
}
@@ -1819,7 +1819,7 @@
arcpacket->hardheader.offset2=offset=512-length-4;
arcsoft=(struct ClientData *)
(&arcpacket->raw[offset+4]);
-
+
/* exception-specific stuff - these four bytes
* make the packet long enough to fit in a 512-byte
* frame.
@@ -1857,10 +1857,10 @@
memcpy((u_char*)arcsoft+hdrlen,
data,length-hdrlen);
#endif
-
+
BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
daddr,length);
-
+
BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>MTU,"tx");
lp->lastload_dest=daddr;
lp->txready=lp->txbuf; /* packet is ready for sending */
@@ -1894,7 +1894,7 @@
}
return 0;
}
-
+
/* start sending */
ACOMMAND(TXcmd|(lp->txready<<3));
@@ -1930,14 +1930,14 @@
{
struct device *dev = (struct device *)(irq2dev_map[irq]);
int ioaddr;
-
+
if (dev==NULL)
{
BUGLVL(D_DURING)
printk(KERN_DEBUG "arcnet: irq %d for unknown device.\n", irq);
return;
}
-
+
BUGMSG(D_DURING,"in arcnet_interrupt\n");
/* RESET flag was enabled - if !dev->start, we must clear it right
@@ -1961,7 +1961,7 @@
*/
static void
arcnet_inthandler(struct device *dev)
-{
+{
struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
int ioaddr=IOADDR, status, boguscount = 3, didsomething;
@@ -1970,7 +1970,7 @@
BUGMSG(D_NORMAL,"DRIVER PROBLEM! Nested arcnet interrupts!\n");
return; /* don't even try. */
}
-
+
AINTMASK(0);
INTERRUPT = 1;
@@ -1981,7 +1981,7 @@
{
status = ARCSTATUS;
didsomething=0;
-
+
/* RESET flag was enabled - card is resetting and if RX
* is disabled, it's NOT because we just got a packet.
@@ -1991,12 +1991,12 @@
BUGMSG(D_NORMAL,"spurious reset (status=%Xh)\n",
status);
arcnet_reset(dev,0);
-
+
/* all other flag values are just garbage */
break;
}
-
-
+
+
/* RX is inhibited - we must have received something. */
if (status & lp->intmask & NORXflag)
{
@@ -2012,14 +2012,14 @@
arcnet_rx(dev,!recbuf);
didsomething++;
}
-
+
/* it can only be an xmit-done irq if we're xmitting :) */
/*if (status&TXFREEflag && !lp->in_txhandler && lp->sending)*/
if (status & lp->intmask & TXFREEflag)
{
struct Outgoing *out=&(lp->outgoing);
int was_sending=lp->sending;
-
+
lp->intmask &= ~TXFREEflag;
lp->in_txhandler++;
@@ -2027,7 +2027,7 @@
BUGMSG(D_DURING,"TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)\n",
status,out->numsegs,out->segnum,out->skb);
-
+
if (was_sending && !(status&TXACKflag))
{
if (lp->lasttrans_dest != 0)
@@ -2048,7 +2048,7 @@
/* send packet if there is one */
arcnet_go_tx(dev,0);
didsomething++;
-
+
if (lp->intx)
{
BUGMSG(D_DURING,"TXDONE while intx! (status=%Xh, intx=%d)\n",
@@ -2060,7 +2060,7 @@
if (!lp->outgoing.skb)
{
BUGMSG(D_DURING,"TX IRQ done: no split to continue.\n");
-
+
/* inform upper layers */
if (!lp->txready && IF_TBUSY)
{
@@ -2070,7 +2070,7 @@
lp->in_txhandler--;
continue;
}
-
+
/* if more than one segment, and not all segments
* are done, then continue xmit.
*/
@@ -2113,29 +2113,29 @@
{
ACOMMAND(CFLAGScmd|CONFIGclear);
lp->stats.tx_carrier_errors++;
-
+
#ifdef SHOW_RECONFIGS
BUGMSG(D_NORMAL,"Network reconfiguration detected (status=%Xh)\n",
status);
#endif /* SHOW_RECONFIGS */
-
+
#ifdef RECON_THRESHOLD
/* is the RECON info empty or old? */
- if (!lp->first_recon || !lp->last_recon ||
+ if (!lp->first_recon || !lp->last_recon ||
jiffies-lp->last_recon > HZ*10)
{
if (lp->network_down)
BUGMSG(D_NORMAL,"reconfiguration detected: cabling restored?\n");
lp->first_recon=lp->last_recon=jiffies;
lp->num_recons=lp->network_down=0;
-
+
BUGMSG(D_DURING,"recon: clearing counters.\n");
}
else /* add to current RECON counter */
{
lp->last_recon=jiffies;
lp->num_recons++;
-
+
BUGMSG(D_DURING,"recon: counter=%d, time=%lds, net=%d\n",
lp->num_recons,
(lp->last_recon-lp->first_recon)/HZ,
@@ -2174,7 +2174,7 @@
BUGMSG(D_NORMAL,"cabling restored?\n");
lp->first_recon=lp->last_recon=0;
lp->num_recons=lp->network_down=0;
-
+
BUGMSG(D_DURING,"not recon: clearing counters anyway.\n");
}
#endif
@@ -2212,12 +2212,12 @@
u_char *arcsoft;
short length,offset;
u_char daddr,saddr;
-
+
lp->stats.rx_packets++;
saddr=arcpacket->hardheader.source;
daddr=arcpacket->hardheader.destination;
-
+
/* if source is 0, it's a "used" packet! */
if (saddr==0)
{
@@ -2227,7 +2227,7 @@
return;
}
arcpacket->hardheader.source=0;
-
+
if (arcpacket->hardheader.offset1) /* Normal Packet */
{
offset=arcpacket->hardheader.offset1;
@@ -2241,7 +2241,7 @@
length=512-offset;
}
-
+
BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n",
saddr,daddr,length);
@@ -2307,10 +2307,10 @@
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
struct sk_buff *skb;
struct ClientData *arcsoft,*soft;
-
+
BUGMSG(D_DURING,"it's an RFC1201 packet (length=%d)\n",
length);
-
+
/* compensate for EXTRA_CLIENTDATA (which isn't actually in the
* packet)
*/
@@ -2326,14 +2326,14 @@
((u_char *)arcsoft + 4);
length-=4;
}
-
+
if (!arcsoft->split_flag) /* not split */
{
struct Incoming *in=&lp->incoming[saddr];
BUGMSG(D_RX,"incoming is not split (splitflag=%d)\n",
arcsoft->split_flag);
-
+
if (in->skb) /* already assembling one! */
{
BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
@@ -2344,7 +2344,7 @@
lp->stats.rx_missed_errors++;
in->skb=NULL;
}
-
+
in->sequence=arcsoft->sequence;
skb = alloc_skb(length, GFP_ATOMIC);
@@ -2354,16 +2354,16 @@
return;
}
soft=(struct ClientData *)skb->data;
-
+
skb->len = length;
skb->dev = dev;
-
+
memcpy((u_char *)soft+EXTRA_CLIENTDATA,
(u_char *)arcsoft+EXTRA_CLIENTDATA,
length-EXTRA_CLIENTDATA);
soft->daddr=daddr;
soft->saddr=saddr;
-
+
/* ARP packets have problems when sent from DOS.
* source address is always 0 on some systems! So we take
* the hardware source addr (which is impossible to fumble)
@@ -2378,7 +2378,7 @@
if (arp->ar_hln==1 && arp->ar_pln==4)
{
char *cptr=(char *)(arp)+sizeof(struct arphdr);
-
+
if (!*cptr) /* is saddr = 00? */
{
BUGMSG(D_EXTRA,"ARP source address was 00h, set to %02Xh.\n",
@@ -2400,7 +2400,7 @@
lp->stats.rx_crc_errors++;
}
}
-
+
BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
skb->protocol=arcnetA_type_trans(skb,dev);
@@ -2425,9 +2425,9 @@
* ARCnet card possible on the network. Seems rather like
* a waste of memory. Necessary?
*/
-
+
struct Incoming *in=&lp->incoming[saddr];
-
+
BUGMSG(D_RX,"packet is split (splitflag=%d, seq=%d)\n",
arcsoft->split_flag,in->sequence);
@@ -2442,7 +2442,7 @@
lp->stats.rx_missed_errors++;
in->lastpacket=in->numpackets=0;
}
-
+
if (arcsoft->split_flag & 1) /* first packet in split */
{
BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n",
@@ -2460,7 +2460,7 @@
in->sequence=arcsoft->sequence;
in->numpackets=((unsigned)arcsoft->split_flag>>1)+2;
in->lastpacket=1;
-
+
if (in->numpackets>16)
{
BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
@@ -2469,7 +2469,7 @@
lp->stats.rx_length_errors++;
return;
}
-
+
in->skb=skb=alloc_skb(508*in->numpackets
+ sizeof(struct ClientData),
GFP_ATOMIC);
@@ -2478,9 +2478,9 @@
lp->stats.rx_dropped++;
return;
}
-
+
soft=(struct ClientData *)skb->data;
-
+
skb->len=sizeof(struct ClientData);
skb->dev=dev;
@@ -2495,7 +2495,7 @@
/* if we're not assembling, there's no point
* trying to continue.
- */
+ */
if (!in->skb)
{
BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d)\n",
@@ -2517,7 +2517,7 @@
lp->stats.rx_frame_errors++;
return;
}
-
+
/* "bad" duplicate, kill reassembly */
BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
in->sequence,arcsoft->split_flag,
@@ -2532,18 +2532,18 @@
soft=(struct ClientData *)in->skb->data;
}
-
+
skb=in->skb;
-
+
memcpy(skb->data+skb->len,
(u_char *)arcsoft+sizeof(struct ClientData),
length-sizeof(struct ClientData));
skb->len+=length-sizeof(struct ClientData);
-
+
soft->daddr=daddr;
soft->saddr=saddr;
-
+
/* are we done? */
if (in->lastpacket == in->numpackets)
{
@@ -2556,11 +2556,11 @@
{
in->skb=NULL;
in->lastpacket=in->numpackets=0;
-
+
BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
-
+
skb->protocol=arcnetA_type_trans(skb,dev);
-
+
netif_rx(skb);
}
}
@@ -2649,7 +2649,7 @@
lp->stats.tx_errors++;
lp->stats.tx_aborted_errors++;
return 0;
- }
+ }
/*
* Set the source hardware address.
@@ -2675,7 +2675,7 @@
}
else
head->daddr=0; /* better fill one in anyway */
-
+
return -dev->hard_header_len;
}
@@ -2697,8 +2697,8 @@
*
* FIXME: Anyone want to spec IPv6 over ARCnet ?
*/
-
- if(head->protocol_id != ARC_P_IP)
+
+ if(head->protocol_id != ARC_P_IP)
{
BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
head->protocol_id,head->protocol_id);
@@ -2712,7 +2712,7 @@
/*
* Try to get ARP to resolve the header.
*/
-#ifdef CONFIG_INET
+#ifdef CONFIG_INET
BUGMSG(D_DURING,"rebuild header from %d to %d; protocol %Xh\n",
head->saddr,head->daddr,head->protocol_id);
status=arp_find(&(head->daddr),skb)? 1 : 0;
@@ -2720,8 +2720,8 @@
head->saddr,head->daddr,head->protocol_id);
return status;
#else
- return 0;
-#endif
+ return 0;
+#endif
}
@@ -2738,7 +2738,7 @@
skb->mac.raw=skb->data;
skb_pull(skb,dev->hard_header_len);
head=(struct ClientData *)skb->mac.raw;
-
+
if (head->daddr==0)
skb->pkt_type=PACKET_BROADCAST;
else if (dev->flags&IFF_PROMISC)
@@ -2747,7 +2747,7 @@
if (head->daddr != dev->dev_addr[0])
skb->pkt_type=PACKET_OTHERHOST;
}
-
+
/* now return the protocol number */
switch (head->protocol_id)
{
@@ -2790,7 +2790,7 @@
dev->hard_start_xmit=arcnetE_send_packet;
BUGMSG(D_NORMAL,"ARCnet Ethernet-Encap protocol initialized.\n");
-
+
return 0;
}
@@ -2811,13 +2811,13 @@
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
int ioaddr=IOADDR,bad;
- union ArcPacket *arcpacket =
+ union ArcPacket *arcpacket =
(union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
u_char *arcsoft,daddr;
short offset,length=skb->len+1;
lp->intx++;
-
+
bad=arcnet_send_packet_bad(skb,dev);
if (bad)
{
@@ -2826,7 +2826,7 @@
}
TBUSY=1;
-
+
if (length>XMTU)
{
BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n",
@@ -2837,7 +2837,7 @@
lp->intx--;
return 0;
}
-
+
BUGMSG(D_DURING,"starting tx sequence...\n");
lp->txbuf=lp->txbuf^1; /* XOR with 1 to alternate btw 2 & 3 */
@@ -2867,25 +2867,25 @@
{
arcpacket->hardheader.offset1=(offset-=256);
}
-
+
BUGMSG(D_DURING," length=%Xh, offset=%Xh, offset1=%Xh, offset2=%Xh\n",
length,offset,arcpacket->hardheader.offset1,
arcpacket->hardheader.offset2);
-
+
arcsoft=&arcpacket->raw[offset];
arcsoft[0]=ARC_P_ETHER;
arcsoft++;
-
+
/* copy the packet into ARCnet shmem
* - the first bytes of ClientData header are skipped
*/
BUGMSG(D_DURING,"ready to memcpy\n");
-
+
memcpy(arcsoft,skb->data,skb->len);
-
+
BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
daddr,length);
-
+
BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>=240,"tx");
lp->lastload_dest=daddr;
@@ -2902,7 +2902,7 @@
dev->trans_start=jiffies;
lp->intx--;
-
+
/* make sure we didn't ignore a TX IRQ while we were in here */
lp->intmask |= TXFREEflag;
SETMASK;
@@ -2919,7 +2919,7 @@
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
struct sk_buff *skb;
-
+
BUGMSG(D_DURING,"it's an ethernet-encap packet (length=%d)\n",
length);
@@ -2929,16 +2929,16 @@
lp->stats.rx_dropped++;
return;
}
-
+
skb->len = length;
skb->dev = dev;
-
+
memcpy(skb->data,(u_char *)arcsoft+1,length-1);
BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
skb->protocol=eth_type_trans(skb,dev);
-
+
netif_rx(skb);
}
@@ -2958,7 +2958,7 @@
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
arcnet_setup(dev);
-
+
/* And now fill particular fields with arcnet values */
dev->dev_addr[0]=lp->stationid;
dev->hard_header_len=sizeof(struct S_ClientData);
@@ -2994,14 +2994,14 @@
struct S_ClientData *hdr=(struct S_ClientData *)skb->data;
lp->intx++;
-
+
bad=arcnet_send_packet_bad(skb,dev);
if (bad)
{
lp->intx--;
return bad;
}
-
+
TBUSY=1;
length = 1 < skb->len ? skb->len : 1;
@@ -3020,7 +3020,7 @@
/* done right away */
dev_kfree_skb(skb,FREE_WRITE);
-
+
if (arcnet_go_tx(dev,1))
{
/* inform upper layers */
@@ -3035,7 +3035,7 @@
dev_kfree_skb(skb,FREE_WRITE);
lp->stats.tx_dropped++;
TBUSY=0;
- mark_bh(NET_BH);
+ mark_bh(NET_BH);
}
dev->trans_start=jiffies;
@@ -3049,7 +3049,7 @@
}
-/* Packet receiver for RFC1051 packets;
+/* Packet receiver for RFC1051 packets;
*/
static void
arcnetS_rx(struct device *dev,u_char *buf,
@@ -3058,16 +3058,16 @@
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
struct sk_buff *skb;
struct S_ClientData *arcsoft,*soft;
-
+
arcsoft=(struct S_ClientData *)(buf-S_EXTRA_CLIENTDATA);
length+=S_EXTRA_CLIENTDATA;
-
+
BUGMSG(D_DURING,"it's an RFC1051 packet (length=%d)\n",
length);
-
-
-
- { /* was "if not split" in A protocol, S is never split */
+
+
+
+ { /* was "if not split" in A protocol, S is never split */
skb = alloc_skb(length, GFP_ATOMIC);
if (skb == NULL) {
@@ -3080,14 +3080,14 @@
memcpy((u_char *)soft + sizeof(struct S_ClientData)
- S_EXTRA_CLIENTDATA,
(u_char *)arcsoft + sizeof(struct S_ClientData)
- - S_EXTRA_CLIENTDATA,
+ - S_EXTRA_CLIENTDATA,
length - sizeof(struct S_ClientData)
+ S_EXTRA_CLIENTDATA);
soft->protocol_id=arcsoft->protocol_id;
soft->daddr=daddr;
soft->saddr=saddr;
skb->dev = dev; /* is already lp->sdev */
-
+
BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
skb->protocol=arcnetS_type_trans(skb,dev);
@@ -3126,7 +3126,7 @@
lp->stats.tx_errors++;
lp->stats.tx_aborted_errors++;
return 0;
- }
+ }
/*
* Set the source hardware address.
@@ -3149,7 +3149,7 @@
}
else
head->daddr=0; /* better fill one in anyway */
-
+
return -dev->hard_header_len;
}
@@ -3167,8 +3167,8 @@
/*
* Only ARP and IP are currently supported
*/
-
- if(head->protocol_id != ARC_P_IP_RFC1051)
+
+ if(head->protocol_id != ARC_P_IP_RFC1051)
{
BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
head->protocol_id,head->protocol_id);
@@ -3182,14 +3182,14 @@
/*
* Try to get ARP to resolve the header.
*/
-#ifdef CONFIG_INET
+#ifdef CONFIG_INET
return arp_find(&(head->daddr),skb)? 1 : 0;
#else
- return 0;
-#endif
+ return 0;
+#endif
}
-
+
/* Determine a packet's protocol ID.
*
* With ARCnet we have to convert everything to Ethernet-style stuff.
@@ -3203,7 +3203,7 @@
skb->mac.raw=skb->data;
skb_pull(skb,dev->hard_header_len);
head=(struct S_ClientData *)skb->mac.raw;
-
+
if (head->daddr==0)
skb->pkt_type=PACKET_BROADCAST;
else if (dev->flags&IFF_PROMISC)
@@ -3212,7 +3212,7 @@
if (head->daddr != dev->dev_addr[0])
skb->pkt_type=PACKET_OTHERHOST;
}
-
+
/* now return the protocol number */
switch (head->protocol_id)
{
@@ -3246,14 +3246,18 @@
0, 0, /* I/O address, IRQ */
0, 0, 0, NULL, arcnet_probe
};
-
-
+
+
static int io=0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
static int irqnum=0; /* or use the insmod io= irq= shmem= options */
static int irq=0;
static int shmem=0;
static char *device = NULL; /* use eg. device="arc1" to change name */
+MODULE_PARM(io, "i");
+MODULE_PARM(irqnum, "i");
+MODULE_PARM(shmem, "i");
+
#ifdef RIM_I_MODE
static int node=0; /* you must specify the node ID for RIM I cards */
#endif
@@ -3272,7 +3276,7 @@
#endif
dev->base_addr=io;
-
+
if (irq) irqnum=irq;
dev->irq=irqnum;
if (dev->irq==2) dev->irq=9;
@@ -3310,7 +3314,7 @@
irq2dev_map[dev->irq] = NULL;
free_irq(dev->irq,NULL);
}
-
+
if (dev->base_addr) RELEASE_REGION(dev->base_addr,ARCNET_TOTAL_SIZE);
unregister_netdev(dev);
kfree(dev->priv);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov