diff options
Diffstat (limited to 'drivers/net/arcnet.c')
-rw-r--r-- | drivers/net/arcnet.c | 2827 |
1 files changed, 1354 insertions, 1473 deletions
diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index 353b44dc8..906d3fab7 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -1,184 +1,184 @@ -/* $Id: arcnet.c,v 1.34 1997/11/09 11:04:55 mj Exp $ - - Written 1994-1996 by Avery Pennarun, - derived from skeleton.c by Donald Becker. - - ********************** - - The original copyright was as follows: - - skeleton.c Written 1993 by Donald Becker. - Copyright 1993 United States Government as represented by the - 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. - - ********************** - - v3.02 (98/06/07) - - Use register_netdevice() instead of register_netdev() to create - new devices for RFC1051 and Ethernet encapsulation in arcnet_open. - Likewise for unregistering them later. This avoids the deadlock - encountered because the original routines call rtnl_lock() when - it's already locked. [dw] - - v3.01 (98/04/17) - - Interrupt handler now also checks dev->[se]dev are non-NULL - to avoid crashes in interrupts during card init. [dw] - - v3.00 (97/11/09) - - Minor cleanup of debugging messages. [mj] - - v2.93 ALPHA (97/11/06) - - irq2dev mapping removed. - - Interrupt handler now checks whether dev->priv is non-null in order - to avoid crashes in interrupts which come during card init. [mj] - - v2.92 ALPHA (97/09/02) - - Code cleanup [Martin Mares <mj@atrey.karlin.mff.cuni.cz>] - - Better probing for the COM90xx chipset, although only as - a temporary solution until we implement adding of all found - devices at once. [mj] - - v2.91 ALPHA (97/08/19) - - Add counting of octets in/out. - - v2.90 ALPHA (97/08/08) - - Add support for kernel command line parsing so that chipset - drivers are usable when compiled in. - - v2.80 ALPHA (97/08/01) - - Split source into multiple files; generic arcnet support and - individual chipset drivers. <Dave@imladris.demon.co.uk> - - v2.61 ALPHA (97/07/30) by David Woodhouse (Dave@imladris.demon.co.uk) - for Nortel (Northern Telecom). - - Added support for IO-mapped modes and for SMC COM20020 chipset. - - Fixed (avoided) race condition in send_packet routines which was - discovered when the buffer copy routines got slow (?). - - Fixed support for device naming at load time. - - Added backplane, clock and timeout options for COM20020. - - Added support for promiscuous mode. - - 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 - with the new Linux 2.1.x memory management. I modified their - patch quite a bit though; bugs are my fault. More changes should - be made to get eliminate any remaining phys_to_virt calls. - - Quietly ignore protocol id's 0, 1, 8, and 243. Thanks to Jake - Messinger <jake@ams.com> for reporting these codes and their - meanings. - - Smarter shmem probe for cards with 4k mirrors. (does it work?) - - Initial support for RIM I type cards which use no I/O ports at - all. To use this option, you need to compile with RIM_I_MODE - enabled. Thanks to Kolja Waschk <kawk@yo.com> for explaining - RIM I programming to me. Now, does my RIM I code actually - work? - - v2.56 (96/10/18) - - Turned arc0e/arc0s startup messages back on by default, as most - people will probably not notice the additional devices - otherwise. This causes undue confusion. - - Fixed a tiny but noticeable bug in the packet debugging routines - (thanks Tomasz) - - The following has been SUMMARIZED. The complete ChangeLog is - available in the full Linux-ARCnet package at - http://www.worldvisions.ca/~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 - (and, in most cases, the bugs that caused them). - - Better IPX support. - - lp->stats updated properly. - - RECON checking now by default only prints a message if there are - excessive errors (ie. your cable is probably broken). - - New RFC1051-compliant "arc0s" virtual device by Tomasz - Motylewski. - - Excess debug messages can be compiled out to reduce code size. - - v2.00 (95/09/06) - - ARCnet RECON messages are now detected and logged as "carrier" - errors. - - The TXACK flag is now checked, and errors are logged. - - Debug levels are now completely different. See the README. - - Massive code cleanups, with several no-longer-necessary and some - completely useless options removed. - - Multiprotocol support. You can now use the "arc0e" device to - 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 - incorrectly, and Linux wasn't checking it on receive so it - didn't show up) - - v1.01 (95/03/24) - - 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, - for example.) - - Allow use of RFC1051 or Ether devices without RFC1201. - - Keep separate stats for each device. - - Support "arpless" mode like NetBSD does, and as recommended - by the (obsoleted) RFC1051. - - Smarter recovery from RECON-during-transmit conditions. (ie. - retransmit immediately) - - Add support for the new 1.3.x IP header cache, and other features. - - Replace setting of debug level with the "metric" flag hack by - something that still exists. SIOCDEVPRIVATE is a good candidate, - but it would require an extra user-level utility. - - - What about cards with shared memory that can be "turned off?" - (or that have none at all, like the SMC PC500longboard) - Does this work now, with IO_MAPPED_BUFFERS? - - - Autoconfigure PDI5xxPlus cards. (I now have a PDI508Plus to play - with temporarily.) Update: yes, the Pure Data config program - for DOS works fine, but the PDI508Plus I have doesn't! :) - - 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 - Donald Becker - it didn't work :) - - skeleton.c v0.05 dated 11/16/93 by Donald Becker - (from Linux Kernel 1.1.45) - - RFC's 1201 and 1051 - re: TCP/IP over ARCnet - - The official ARCnet COM9026 data sheets (!) thanks to Ken - Cornetet <kcornete@nyx10.cs.du.edu> - - The official ARCnet COM20020 data sheets. - - Information on some more obscure ARCnet controller chips, thanks - to the nice people at SMC. - - net/inet/eth.c (from kernel 1.1.50) for header-building info. - - Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su> - - Textual information and more alternate source from Joachim Koenig - <jojo@repas.de> -*/ +/* $Id: arcnet.c,v 1.34 1997/11/09 11:04:55 mj Exp $ + + Written 1994-1996 by Avery Pennarun, + derived from skeleton.c by Donald Becker. + + ********************** + + The original copyright was as follows: + + skeleton.c Written 1993 by Donald Becker. + Copyright 1993 United States Government as represented by the + 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. + + ********************** + + v3.02 (98/06/07) + - Use register_netdevice() instead of register_netdev() to create + new devices for RFC1051 and Ethernet encapsulation in arcnet_open. + Likewise for unregistering them later. This avoids the deadlock + encountered because the original routines call rtnl_lock() when + it's already locked. [dw] + + v3.01 (98/04/17) + - Interrupt handler now also checks dev->[se]dev are non-NULL + to avoid crashes in interrupts during card init. [dw] + + v3.00 (97/11/09) + - Minor cleanup of debugging messages. [mj] + + v2.93 ALPHA (97/11/06) + - irq2dev mapping removed. + - Interrupt handler now checks whether dev->priv is non-null in order + to avoid crashes in interrupts which come during card init. [mj] + + v2.92 ALPHA (97/09/02) + - Code cleanup [Martin Mares <mj@atrey.karlin.mff.cuni.cz>] + - Better probing for the COM90xx chipset, although only as + a temporary solution until we implement adding of all found + devices at once. [mj] + + v2.91 ALPHA (97/08/19) + - Add counting of octets in/out. + + v2.90 ALPHA (97/08/08) + - Add support for kernel command line parsing so that chipset + drivers are usable when compiled in. + + v2.80 ALPHA (97/08/01) + - Split source into multiple files; generic arcnet support and + individual chipset drivers. <Dave@imladris.demon.co.uk> + + v2.61 ALPHA (97/07/30) by David Woodhouse (Dave@imladris.demon.co.uk) + for Nortel (Northern Telecom). + - Added support for IO-mapped modes and for SMC COM20020 chipset. + - Fixed (avoided) race condition in send_packet routines which was + discovered when the buffer copy routines got slow (?). + - Fixed support for device naming at load time. + - Added backplane, clock and timeout options for COM20020. + - Added support for promiscuous mode. + + 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 + with the new Linux 2.1.x memory management. I modified their + patch quite a bit though; bugs are my fault. More changes should + be made to get eliminate any remaining phys_to_virt calls. + - Quietly ignore protocol id's 0, 1, 8, and 243. Thanks to Jake + Messinger <jake@ams.com> for reporting these codes and their + meanings. + - Smarter shmem probe for cards with 4k mirrors. (does it work?) + - Initial support for RIM I type cards which use no I/O ports at + all. To use this option, you need to compile with RIM_I_MODE + enabled. Thanks to Kolja Waschk <kawk@yo.com> for explaining + RIM I programming to me. Now, does my RIM I code actually + work? + + v2.56 (96/10/18) + - Turned arc0e/arc0s startup messages back on by default, as most + people will probably not notice the additional devices + otherwise. This causes undue confusion. + - Fixed a tiny but noticeable bug in the packet debugging routines + (thanks Tomasz) + + The following has been SUMMARIZED. The complete ChangeLog is + available in the full Linux-ARCnet package at + http://www.worldvisions.ca/~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 + (and, in most cases, the bugs that caused them). + - Better IPX support. + - lp->stats updated properly. + - RECON checking now by default only prints a message if there are + excessive errors (ie. your cable is probably broken). + - New RFC1051-compliant "arc0s" virtual device by Tomasz + Motylewski. + - Excess debug messages can be compiled out to reduce code size. + + v2.00 (95/09/06) + - ARCnet RECON messages are now detected and logged as "carrier" + errors. + - The TXACK flag is now checked, and errors are logged. + - Debug levels are now completely different. See the README. + - Massive code cleanups, with several no-longer-necessary and some + completely useless options removed. + - Multiprotocol support. You can now use the "arc0e" device to + 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 + incorrectly, and Linux wasn't checking it on receive so it + didn't show up) + + v1.01 (95/03/24) + - 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, + for example.) + - Allow use of RFC1051 or Ether devices without RFC1201. + - Keep separate stats for each device. + - Support "arpless" mode like NetBSD does, and as recommended + by the (obsoleted) RFC1051. + - Smarter recovery from RECON-during-transmit conditions. (ie. + retransmit immediately) + - Add support for the new 1.3.x IP header cache, and other features. + - Replace setting of debug level with the "metric" flag hack by + something that still exists. SIOCDEVPRIVATE is a good candidate, + but it would require an extra user-level utility. + + - What about cards with shared memory that can be "turned off?" + (or that have none at all, like the SMC PC500longboard) + Does this work now, with IO_MAPPED_BUFFERS? + + - Autoconfigure PDI5xxPlus cards. (I now have a PDI508Plus to play + with temporarily.) Update: yes, the Pure Data config program + for DOS works fine, but the PDI508Plus I have doesn't! :) + - 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 + Donald Becker - it didn't work :) + - skeleton.c v0.05 dated 11/16/93 by Donald Becker + (from Linux Kernel 1.1.45) + - RFC's 1201 and 1051 - re: TCP/IP over ARCnet + - The official ARCnet COM9026 data sheets (!) thanks to Ken + Cornetet <kcornete@nyx10.cs.du.edu> + - The official ARCnet COM20020 data sheets. + - Information on some more obscure ARCnet controller chips, thanks + to the nice people at SMC. + - net/inet/eth.c (from kernel 1.1.50) for header-building info. + - Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su> + - Textual information and more alternate source from Joachim Koenig + <jojo@repas.de> + */ static const char *version = - "arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n"; +"arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n"; #include <linux/module.h> #include <linux/config.h> @@ -230,15 +230,15 @@ static const char *version = #define ARCSTATUS ((*lp->astatus)(dev)) #define ACOMMAND(x) ((*lp->acommand)(dev, x)) -int arcnet_debug=ARCNET_DEBUG; +int arcnet_debug = ARCNET_DEBUG; /* Exported function prototypes */ #ifdef MODULE -int init_module(void); +int init_module(void); void cleanup_module(void); #else -void arcnet_init(void); +int arcnet_init(void); static int init_module(void); #ifdef CONFIG_ARCNET_COM90xx extern char com90xx_explicit; @@ -247,13 +247,13 @@ extern int arc90xx_probe(struct net_device *dev); #endif void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp); -void arcnet_use_count (int open); +void arcnet_use_count(int open); void arcnet_setup(struct net_device *dev); void arcnet_makename(char *device); void arcnetA_continue_tx(struct net_device *dev); -int arcnet_go_tx(struct net_device *dev,int enable_irq); -void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs); -void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr); +int arcnet_go_tx(struct net_device *dev, int enable_irq); +void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); +void arcnet_rx(struct arcnet_local *lp, u_char * arcsoft, short length, int saddr, int daddr); EXPORT_SYMBOL(arcnet_debug); EXPORT_SYMBOL(arcnet_tx_done); @@ -266,32 +266,32 @@ EXPORT_SYMBOL(arcnet_interrupt); EXPORT_SYMBOL(arcnet_rx); #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); EXPORT_SYMBOL(arcnet_dump_skb); #else -# define arcnet_dump_skb(dev,skb,desc) ; +#define arcnet_dump_skb(dev,skb,desc) ; #endif #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext, - char *desc); +void arcnet_dump_packet(struct net_device *dev, u_char * buffer, int ext, + char *desc); EXPORT_SYMBOL(arcnet_dump_packet); #else -# define arcnet_dump_packet(dev,buffer,ext,desc) ; +#define arcnet_dump_packet(dev,buffer,ext,desc) ; #endif /* Internal function prototypes */ static int arcnet_open(struct net_device *dev); static int arcnet_close(struct net_device *dev); -static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len); +static int arcnetA_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len); static int arcnetA_rebuild_header(struct sk_buff *skb); -static int arcnet_send_packet_bad(struct sk_buff *skb,struct net_device *dev); +static int arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev); static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetA_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr); +static void arcnetA_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr); static struct net_device_stats *arcnet_get_stats(struct net_device *dev); static unsigned short arcnetA_type_trans(struct sk_buff *skb, struct net_device *dev); @@ -302,8 +302,8 @@ static unsigned short arcnetA_type_trans(struct sk_buff *skb, static int arcnetE_init(struct net_device *dev); static int arcnetE_open_close(struct net_device *dev); static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, - int length,u_char saddr, u_char daddr); +static void arcnetE_rx(struct net_device *dev, u_char * arcsoft, + int length, u_char saddr, u_char daddr); #endif @@ -312,12 +312,12 @@ static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, static int arcnetS_init(struct net_device *dev); static int arcnetS_open_close(struct net_device *dev); static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetS_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr); -static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len); +static void arcnetS_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr); +static int arcnetS_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len); static int arcnetS_rebuild_header(struct sk_buff *skb); -static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev); +static unsigned short arcnetS_type_trans(struct sk_buff *skb, struct net_device *dev); #endif @@ -330,22 +330,21 @@ static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device * /* 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; long flags; save_flags(flags); cli(); - printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc); - for(i=0; i<skb->len; i++) - { - if (i%16==0) - printk("\n" KERN_DEBUG "[%04X] ",i); - printk("%02X ",((u_char *)skb->data)[i]); + printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc); + for (i = 0; i < skb->len; i++) { + if (i % 16 == 0) + printk("\n" KERN_DEBUG "[%04X] ", i); + printk("%02X ", ((u_char *) skb->data)[i]); } - printk("\n"); - restore_flags(flags); + printk("\n"); + restore_flags(flags); } #endif @@ -353,19 +352,18 @@ void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb,char *desc) /* Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext,char *desc) +void arcnet_dump_packet(struct net_device *dev, u_char * buffer, int ext, char *desc) { int i; long flags; save_flags(flags); cli(); - printk(KERN_DEBUG "%6s: packet dump (%s) follows:",dev->name,desc); - for (i=0; i<256+(ext!=0)*256; i++) - { - if (i%16==0) - printk("\n" KERN_DEBUG "[%04X] ",i); - printk("%02X ",buffer[i]); + printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc); + for (i = 0; i < 256 + (ext != 0) * 256; i++) { + if (i % 16 == 0) + printk("\n" KERN_DEBUG "[%04X] ", i); + printk("%02X ", buffer[i]); } printk("\n"); restore_flags(flags); @@ -386,24 +384,24 @@ void arcnet_setup(struct net_device *dev) { dev_init_buffers(dev); - dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ - dev->addr_len = 1; - dev->type = ARPHRD_ARCNET; - dev->tx_queue_len = 30; + dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ + dev->addr_len = 1; + dev->type = ARPHRD_ARCNET; + dev->tx_queue_len = 30; /* New-style flags. */ - dev->flags = IFF_BROADCAST; + dev->flags = IFF_BROADCAST; /* Put in this stuff here, so we don't have to export the symbols * to the chipset drivers. */ - dev->open=arcnet_open; - dev->stop=arcnet_close; - dev->hard_start_xmit=arcnetA_send_packet; - dev->get_stats=arcnet_get_stats; - dev->hard_header=arcnetA_header; - dev->rebuild_header=arcnetA_rebuild_header; + dev->open = arcnet_open; + dev->stop = arcnet_close; + dev->hard_start_xmit = arcnetA_send_packet; + dev->get_stats = arcnet_get_stats; + dev->hard_header = arcnetA_header; + dev->rebuild_header = arcnetA_rebuild_header; } @@ -420,167 +418,164 @@ void arcnet_setup(struct net_device *dev) * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ -static int -arcnet_open(struct net_device *dev) +static int arcnet_open(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - - /* if (dev->metric>=1000) - * { - * arcnet_debug=dev->metric-1000; - * printk(KERN_INFO "%6s: debug level set to %d\n",dev->name,arcnet_debug); - * dev->metric=1; - *} - */ - BUGMSG(D_INIT,"arcnet_open: resetting card.\n"); - - /* try to put the card in a defined state - if it fails the first - * time, actually reset it. - */ - if ((*lp->arcnet_reset)(dev,0) && (*lp->arcnet_reset)(dev,1)) - return -ENODEV; - - dev->tbusy=0; - dev->interrupt=0; - lp->intx=0; - lp->in_txhandler=0; - - /* The RFC1201 driver is the default - just store */ - lp->adev=dev; - - /* we're started */ - dev->start=1; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + + /* if (dev->metric>=1000) + * { + * arcnet_debug=dev->metric-1000; + * printk(KERN_INFO "%6s: debug level set to %d\n",dev->name,arcnet_debug); + * dev->metric=1; + *} + */ + BUGMSG(D_INIT, "arcnet_open: resetting card.\n"); + + /* try to put the card in a defined state - if it fails the first + * time, actually reset it. + */ + if ((*lp->arcnet_reset) (dev, 0) && (*lp->arcnet_reset) (dev, 1)) + return -ENODEV; + + dev->tbusy = 0; + dev->interrupt = 0; + lp->intx = 0; + lp->in_txhandler = 0; + + /* The RFC1201 driver is the default - just store */ + lp->adev = dev; + + /* we're started */ + dev->start = 1; #ifdef CONFIG_ARCNET_ETH - /* Initialize the ethernet-encap protocol driver */ - lp->edev=(struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL); - if (lp->edev == NULL) - return -ENOMEM; - memcpy(lp->edev,dev,sizeof(struct net_device)); - lp->edev->type=ARPHRD_ETHER; - lp->edev->name=(char *)kmalloc(10,GFP_KERNEL); - if (lp->edev->name == NULL) { - kfree(lp->edev); - lp->edev = NULL; - return -ENOMEM; - } - sprintf(lp->edev->name,"%se",dev->name); - lp->edev->init=arcnetE_init; - register_netdevice(lp->edev); + /* Initialize the ethernet-encap protocol driver */ + lp->edev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL); + if (lp->edev == NULL) + return -ENOMEM; + memcpy(lp->edev, dev, sizeof(struct net_device)); + lp->edev->type = ARPHRD_ETHER; + lp->edev->name = (char *) kmalloc(10, GFP_KERNEL); + if (lp->edev->name == NULL) { + kfree(lp->edev); + lp->edev = NULL; + return -ENOMEM; + } + sprintf(lp->edev->name, "%se", dev->name); + lp->edev->init = arcnetE_init; + register_netdevice(lp->edev); #endif #ifdef CONFIG_ARCNET_1051 - /* Initialize the RFC1051-encap protocol driver */ - lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); - if(lp->sdev == NULL) - { + /* Initialize the RFC1051-encap protocol driver */ + lp->sdev = (struct net_device *) kmalloc(sizeof(struct net_device) + 10, GFP_KERNEL); + if (lp->sdev == NULL) { #ifdef CONFIG_ARCNET_ETH - if(lp->edev) - kfree(lp->edev); - lp->edev=NULL; - return -ENOMEM; -#endif - } - memcpy(lp->sdev,dev,sizeof(struct net_device)); - lp->sdev->name=(char *)(lp+1); - sprintf(lp->sdev->name,"%ss",dev->name); - lp->sdev->init=arcnetS_init; - register_netdevice(lp->sdev); + if (lp->edev) + kfree(lp->edev); + lp->edev = NULL; + return -ENOMEM; +#endif + } + memcpy(lp->sdev, dev, sizeof(struct net_device)); + lp->sdev->name = (char *) (lp + 1); + sprintf(lp->sdev->name, "%ss", dev->name); + lp->sdev->init = arcnetS_init; + register_netdevice(lp->sdev); #endif - /* Enable TX if we need to */ - if (lp->en_dis_able_TX) - (*lp->en_dis_able_TX)(dev, 1); + /* Enable TX if we need to */ + if (lp->en_dis_able_TX) + (*lp->en_dis_able_TX) (dev, 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 - * off, then on again to clean out the IRQ controller. - */ + /* 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 + * off, then on again to clean out the IRQ controller. + */ - AINTMASK(0); - udelay(1); /* give it time to set the mask before - * we reset it again. (may not even be - * necessary) - */ - SETMASK; + AINTMASK(0); + udelay(1); /* give it time to set the mask before + * we reset it again. (may not even be + * necessary) + */ + SETMASK; - /* Let it increase its use count */ - (*lp->openclose_device)(1); + /* Let it increase its use count */ + (*lp->openclose_device) (1); - return 0; + return 0; } /* The inverse routine to arcnet_open - shuts down the card. */ -static int -arcnet_close(struct net_device *dev) +static int arcnet_close(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - if (test_and_set_bit(0, (int *)&dev->tbusy)) - BUGMSG(D_NORMAL, "arcnet_close: tbusy already set!\n"); + if (test_and_set_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_NORMAL, "arcnet_close: tbusy already set!\n"); - dev->start=0; + dev->start = 0; #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=1; - lp->sdev->start=0; + lp->sdev->tbusy = 1; + lp->sdev->start = 0; #endif #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=1; - lp->edev->start=0; + lp->edev->tbusy = 1; + lp->edev->start = 0; #endif - /* Shut down the card */ + /* Shut down the card */ - /* Disable TX if we need to */ - if (lp->en_dis_able_TX) - (*lp->en_dis_able_TX)(dev, 0); + /* Disable TX if we need to */ + if (lp->en_dis_able_TX) + (*lp->en_dis_able_TX) (dev, 0); - (*lp->arcnet_reset)(dev, 3); /* reset IRQ won't run if START=0 */ + (*lp->arcnet_reset) (dev, 3); /* reset IRQ won't run if START=0 */ #if 0 - lp->intmask=0; - SETMASK; /* no IRQ's (except RESET, of course) */ - ACOMMAND(NOTXcmd); /* stop transmit */ - ACOMMAND(NORXcmd); /* disable receive */ + lp->intmask = 0; + SETMASK; /* no IRQ's (except RESET, of course) */ + ACOMMAND(NOTXcmd); /* stop transmit */ + ACOMMAND(NORXcmd); /* disable receive */ #endif - /* reset more flags */ - dev->interrupt=0; + /* reset more flags */ + dev->interrupt = 0; #ifdef CONFIG_ARCNET_ETH - lp->edev->interrupt=0; + lp->edev->interrupt = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->interrupt=0; + lp->sdev->interrupt = 0; #endif - /* do NOT free lp->adev!! It's static! */ - lp->adev=NULL; + /* 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; - unregister_netdevice(lp->edev); - kfree(lp->edev->name); - kfree(lp->edev); - lp->edev=NULL; + /* free the ethernet-encap protocol device */ + lp->edev->priv = NULL; + unregister_netdevice(lp->edev); + kfree(lp->edev->name); + kfree(lp->edev); + lp->edev = NULL; #endif #ifdef CONFIG_ARCNET_1051 - /* free the RFC1051-encap protocol device */ - lp->sdev->priv=NULL; - unregister_netdevice(lp->sdev); - kfree(lp->sdev); - lp->sdev=NULL; + /* free the RFC1051-encap protocol device */ + lp->sdev->priv = NULL; + unregister_netdevice(lp->sdev); + kfree(lp->sdev); + lp->sdev = NULL; #endif - /* Update the statistics here. (not necessary in ARCnet) */ + /* Update the statistics here. (not necessary in ARCnet) */ - /* Decrease the use count */ - (*lp->openclose_device)(0); + /* Decrease the use count */ + (*lp->openclose_device) (0); - return 0; + return 0; } @@ -592,241 +587,213 @@ arcnet_close(struct net_device *dev) /* Generic error checking routine for arcnet??_send_packet */ -static int -arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) +static int arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - - 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"); - lp->stats.tx_dropped++; - return 1; - } - - if (lp->intx>1) - { - BUGMSG(D_NORMAL,"send_packet called while intx!\n"); - lp->stats.tx_dropped++; - return 1; - } - - if (test_bit(0, (int *)&dev->tbusy)) - { - /* If we get here, some higher level has decided we are broken. - There should really be a "kick me" function call instead. */ - int tickssofar = jiffies - dev->trans_start; - - int status=ARCSTATUS; - - 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, - lp->outgoing.numsegs, - lp->outgoing.segnum); - return 1; - } + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - lp->intmask &= ~TXFREEflag; - SETMASK; + BUGMSG(D_DURING, "transmit requested (status=%Xh, inTX=%d)\n", + ARCSTATUS, lp->intx); - if (status&TXFREEflag) /* transmit _DID_ finish */ - { - BUGMSG(D_NORMAL,"tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n", - status,tickssofar,lp->intmask,lp->lasttrans_dest); - lp->stats.tx_errors++; + if (lp->in_txhandler) { + BUGMSG(D_NORMAL, "send_packet called while in txhandler!\n"); + lp->stats.tx_dropped++; + return 1; } - else - { - BUGMSG(D_EXTRA,"tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n", - status,tickssofar,lp->intmask,lp->lasttrans_dest); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - - ACOMMAND(NOTXcmd); + if (lp->intx > 1) { + BUGMSG(D_NORMAL, "send_packet called while intx!\n"); + lp->stats.tx_dropped++; + return 1; } + if (test_bit(0, (int *) &dev->tbusy)) { + /* If we get here, some higher level has decided we are broken. + There should really be a "kick me" function call instead. */ + int tickssofar = jiffies - dev->trans_start; + + int status = ARCSTATUS; + + 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, + lp->outgoing.numsegs, + lp->outgoing.segnum); + return 1; + } + 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", + status, tickssofar, lp->intmask, lp->lasttrans_dest); + lp->stats.tx_errors++; + } else { + BUGMSG(D_EXTRA, "tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n", + status, tickssofar, lp->intmask, lp->lasttrans_dest); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + + ACOMMAND(NOTXcmd); + } - if (lp->outgoing.skb) - { - dev_kfree_skb(lp->outgoing.skb); - lp->stats.tx_dropped++; - } - lp->outgoing.skb=NULL; + if (lp->outgoing.skb) { + dev_kfree_skb(lp->outgoing.skb); + lp->stats.tx_dropped++; + } + lp->outgoing.skb = NULL; #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=0; + lp->edev->tbusy = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=0; + lp->sdev->tbusy = 0; #endif - if (!test_and_clear_bit(0,(int *)&dev->tbusy)) - BUGMSG(D_EXTRA, "after timing out, tbusy was clear!\n"); - - lp->txready=0; - lp->sending=0; - - return 1; - } - - if (lp->txready) /* transmit already in progress! */ - { - BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n", - ARCSTATUS); - lp->intmask &= ~TXFREEflag; - SETMASK; - ACOMMAND(NOTXcmd); /* abort current send */ - (*lp->inthandler)(dev); /* fake an interrupt */ - lp->stats.tx_errors++; - lp->stats.tx_fifo_errors++; - lp->txready=0; /* we definitely need this line! */ - - return 1; - } - - /* Block a timer-based transmit from overlapping. This could better be - done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ - if (test_and_set_bit(0, (int *)&lp->adev->tbusy)) - { - BUGMSG(D_NORMAL,"transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", - ARCSTATUS,lp->intx,jiffies-dev->trans_start); - lp->stats.tx_errors++; - lp->stats.tx_fifo_errors++; - return -EBUSY; - } + if (!test_and_clear_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_EXTRA, "after timing out, tbusy was clear!\n"); + + lp->txready = 0; + lp->sending = 0; + + return 1; + } + if (lp->txready) { /* transmit already in progress! */ + BUGMSG(D_NORMAL, "trying to start new packet while busy! (status=%Xh)\n", + ARCSTATUS); + lp->intmask &= ~TXFREEflag; + SETMASK; + ACOMMAND(NOTXcmd); /* abort current send */ + (*lp->inthandler) (dev); /* fake an interrupt */ + lp->stats.tx_errors++; + lp->stats.tx_fifo_errors++; + lp->txready = 0; /* we definitely need this line! */ + + return 1; + } + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit(0, (int *) &lp->adev->tbusy)) { + BUGMSG(D_NORMAL, "transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", + ARCSTATUS, lp->intx, jiffies - dev->trans_start); + lp->stats.tx_errors++; + lp->stats.tx_fifo_errors++; + return -EBUSY; + } #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=1; + lp->sdev->tbusy = 1; #endif #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=1; + lp->edev->tbusy = 1; #endif - return 0; + return 0; } /* Called by the kernel in order to transmit a packet. */ -static int -arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,oldmask=0; - struct Outgoing *out=&(lp->outgoing); - - lp->intx++; - - oldmask |= lp->intmask; - lp->intmask=0; - SETMASK; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - lp->intmask=oldmask; - SETMASK; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - lp->intmask = oldmask & ~TXFREEflag; - SETMASK; - - 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) - { - BUGMSG(D_DURING,"not splitting %d-byte packet. (split_flag=%d)\n", - out->length,out->hdr->split_flag); - if (out->hdr->split_flag) - BUGMSG(D_NORMAL,"short packet has split_flag set?! (split_flag=%d)\n", - out->hdr->split_flag); - out->numsegs=1; - out->segnum=1; - (*lp->prepare_tx)(dev, - ((char *)out->hdr)+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA, - ((char *)skb->data)+sizeof(struct ClientData), - out->length-sizeof(struct ClientData), - out->hdr->daddr,1,0); - - /* done right away */ - lp->stats.tx_bytes += out->skb->len; - dev_kfree_skb(out->skb); - out->skb=NULL; - - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(dev, lp); - } - } - else /* too big for one - split it */ - { - int maxsegsize=XMTU-4; - - out->data=(u_char *)skb->data - + sizeof(struct ClientData); - 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); - - /* if a packet waiting, launch it */ - arcnet_go_tx(dev,1); - - if (!lp->txready) - { - /* prepare a packet, launch it and prepare - * another. - */ - arcnetA_continue_tx(dev); - if (arcnet_go_tx(dev,1)) - { - arcnetA_continue_tx(dev); - arcnet_go_tx(dev,1); - } + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, oldmask = 0; + struct Outgoing *out = &(lp->outgoing); + + lp->intx++; + + oldmask |= lp->intmask; + lp->intmask = 0; + SETMASK; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + lp->intmask = oldmask; + SETMASK; + return bad; } + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ + + lp->intmask = oldmask & ~TXFREEflag; + SETMASK; - /* if segnum==numsegs, the transmission is finished; - * free the skb right away. - */ - - if (out->segnum==out->numsegs) - { - /* transmit completed */ - out->segnum++; - if (out->skb) - { - lp->stats.tx_bytes += skb->len; - dev_kfree_skb(out->skb); - } - out->skb=NULL; + 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) { + BUGMSG(D_DURING, "not splitting %d-byte packet. (split_flag=%d)\n", + out->length, out->hdr->split_flag); + if (out->hdr->split_flag) + BUGMSG(D_NORMAL, "short packet has split_flag set?! (split_flag=%d)\n", + out->hdr->split_flag); + out->numsegs = 1; + out->segnum = 1; + (*lp->prepare_tx) (dev, + ((char *) out->hdr) + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA, + ((char *) skb->data) + sizeof(struct ClientData), + out->length - sizeof(struct ClientData), + out->hdr->daddr, 1, 0); + + /* done right away */ + lp->stats.tx_bytes += out->skb->len; + dev_kfree_skb(out->skb); + out->skb = NULL; + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(dev, lp); + } + } else { /* too big for one - split it */ + int maxsegsize = XMTU - 4; + + out->data = (u_char *) skb->data + + sizeof(struct ClientData); + 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); + + /* if a packet waiting, launch it */ + arcnet_go_tx(dev, 1); + + if (!lp->txready) { + /* prepare a packet, launch it and prepare + * another. + */ + arcnetA_continue_tx(dev); + if (arcnet_go_tx(dev, 1)) { + arcnetA_continue_tx(dev); + arcnet_go_tx(dev, 1); + } + } + /* if segnum==numsegs, the transmission is finished; + * free the skb right away. + */ + + if (out->segnum == out->numsegs) { + /* transmit completed */ + out->segnum++; + if (out->skb) { + lp->stats.tx_bytes += skb->len; + dev_kfree_skb(out->skb); + } + out->skb = NULL; + } } - } - dev->trans_start=jiffies; - lp->intx--; + dev->trans_start = jiffies; + lp->intx--; - /* make sure we didn't ignore a TX IRQ while we were in here */ - lp->intmask |= TXFREEflag; - SETMASK; + /* make sure we didn't ignore a TX IRQ while we were in here */ + lp->intmask |= TXFREEflag; + SETMASK; - return 0; + return 0; } @@ -836,44 +803,41 @@ arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) */ void arcnetA_continue_tx(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int 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", - out->segnum+1,out->numsegs); - } - - if (!out->segnum) /* first packet */ - out->hdr->split_flag=((out->numsegs-2)<<1)+1; - else - out->hdr->split_flag=out->segnum<<1; - - 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); - - (*lp->prepare_tx)(dev,((char *)out->hdr)+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA, - out->data,out->seglen,out->hdr->daddr,1,0); - - out->dataleft-=out->seglen; - out->data+=out->seglen; - out->segnum++; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int 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", + out->segnum + 1, out->numsegs); + } + if (!out->segnum) /* first packet */ + out->hdr->split_flag = ((out->numsegs - 2) << 1) + 1; + else + out->hdr->split_flag = out->segnum << 1; + + 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); + + (*lp->prepare_tx) (dev, ((char *) out->hdr) + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA, + out->data, out->seglen, out->hdr->daddr, 1, 0); + + out->dataleft -= out->seglen; + out->data += out->seglen; + out->segnum++; } @@ -887,36 +851,34 @@ void arcnetA_continue_tx(struct net_device *dev) * to the card; TXFREEflag is always OR'ed into the memory variable either * way. */ -int arcnet_go_tx(struct net_device *dev,int enable_irq) +int arcnet_go_tx(struct net_device *dev, int enable_irq) { - struct arcnet_local *lp=(struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - BUGMSG(D_DURING,"go_tx: status=%Xh, intmask=%Xh, txready=%d, sending=%d\n", - ARCSTATUS,lp->intmask,lp->txready,lp->sending); + BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, txready=%d, sending=%d\n", + ARCSTATUS, lp->intmask, lp->txready, lp->sending); - if (lp->sending || !lp->txready) - { - if (enable_irq && lp->sending) - { + if (lp->sending || !lp->txready) { + if (enable_irq && lp->sending) { lp->intmask |= TXFREEflag; SETMASK; } return 0; } - /* start sending */ - ACOMMAND(TXcmd|(lp->txready<<3)); + ACOMMAND(TXcmd | (lp->txready << 3)); lp->stats.tx_packets++; - lp->txready=0; + lp->txready = 0; lp->sending++; - lp->lasttrans_dest=lp->lastload_dest; - lp->lastload_dest=0; + lp->lasttrans_dest = lp->lastload_dest; + lp->lastload_dest = 0; lp->intmask |= TXFREEflag; - if (enable_irq) SETMASK; + if (enable_irq) + SETMASK; return 1; } @@ -933,85 +895,75 @@ int arcnet_go_tx(struct net_device *dev,int enable_irq) * interrupts. Establish which device needs attention, and call the correct * chipset interrupt handler. */ -void -arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) +void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct arcnet_local *lp; - if (dev==NULL) - { - BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq); - return; - } - - BUGMSG(D_DURING,"in arcnet_interrupt\n"); - - lp=(struct arcnet_local *)dev->priv; - if (!lp) - { - BUGMSG(D_DURING, "arcnet: irq ignored.\n"); - return; - } + if (dev == NULL) { + BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq); + return; + } + BUGMSG(D_DURING, "in arcnet_interrupt\n"); + lp = (struct arcnet_local *) dev->priv; + if (!lp) { + BUGMSG(D_DURING, "arcnet: irq ignored.\n"); + return; + } /* RESET flag was enabled - if !dev->start, we must clear it right * away (but nothing else) since inthandler() is never called. */ - if (!dev->start) - { - if (ARCSTATUS & RESETflag) - ACOMMAND(CFLAGScmd|RESETclear); - return; - } - - - if (test_and_set_bit(0, (int *)&dev->interrupt)) - { - BUGMSG(D_NORMAL,"DRIVER PROBLEM! Nested arcnet interrupts!\n"); - return; /* don't even try. */ - } + if (!dev->start) { + if (ARCSTATUS & RESETflag) + ACOMMAND(CFLAGScmd | RESETclear); + return; + } + if (test_and_set_bit(0, (int *) &dev->interrupt)) { + BUGMSG(D_NORMAL, "DRIVER PROBLEM! Nested arcnet interrupts!\n"); + return; /* don't even try. */ + } #ifdef CONFIG_ARCNET_1051 if (lp->sdev) - lp->sdev->interrupt=1; + lp->sdev->interrupt = 1; #endif #ifdef CONFIG_ARCNET_ETH if (lp->edev) - lp->edev->interrupt=1; + lp->edev->interrupt = 1; #endif /* Call the "real" interrupt handler. */ - (*lp->inthandler)(dev); + (*lp->inthandler) (dev); #ifdef CONFIG_ARCNET_ETH if (lp->edev) - lp->edev->interrupt=0; + lp->edev->interrupt = 0; #endif #ifdef CONFIG_ARCNET_1051 if (lp->sdev) - lp->sdev->interrupt=0; + lp->sdev->interrupt = 0; #endif - if (!test_and_clear_bit(0, (int *)&dev->interrupt)) - BUGMSG(D_NORMAL, "Someone cleared our dev->interrupt flag!\n"); + if (!test_and_clear_bit(0, (int *) &dev->interrupt)) + BUGMSG(D_NORMAL, "Someone cleared our dev->interrupt flag!\n"); } void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) { - if (dev->tbusy) - { + if (dev->tbusy) { #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=0; + lp->edev->tbusy = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=0; + lp->sdev->tbusy = 0; #endif - if (!test_and_clear_bit(0, (int *)&dev->tbusy)) - BUGMSG(D_NORMAL, "In arcnet_tx_done: Someone cleared our dev->tbusy" - " flag!\n"); + if (!test_and_clear_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_NORMAL, "In arcnet_tx_done: Someone cleared our dev->tbusy" + " flag!\n"); - mark_bh(NET_BH); - } + mark_bh(NET_BH); + } } @@ -1026,53 +978,52 @@ void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) * protocol ID found. */ -void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr) +void arcnet_rx(struct arcnet_local *lp, u_char * arcsoft, short length, int saddr, int daddr) { - struct net_device *dev=lp->adev; - - BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n", - saddr,daddr,length); - - /* call the right receiver for the protocol */ - switch (arcsoft[0]) - { - case ARC_P_IP: - case ARC_P_ARP: - case ARC_P_RARP: - case ARC_P_IPX: - case ARC_P_NOVELL_EC: - arcnetA_rx(lp->adev,arcsoft,length,saddr,daddr); - break; + struct net_device *dev = lp->adev; + + BUGMSG(D_DURING, "received packet from %02Xh to %02Xh (%d bytes)\n", + saddr, daddr, length); + + /* call the right receiver for the protocol */ + switch (arcsoft[0]) { + case ARC_P_IP: + case ARC_P_ARP: + case ARC_P_RARP: + case ARC_P_IPX: + case ARC_P_NOVELL_EC: + arcnetA_rx(lp->adev, arcsoft, length, saddr, daddr); + break; #ifdef CONFIG_ARCNET_ETH - case ARC_P_ETHER: - arcnetE_rx(lp->edev,arcsoft,length,saddr,daddr); - break; + case ARC_P_ETHER: + arcnetE_rx(lp->edev, arcsoft, length, saddr, daddr); + break; #endif #ifdef CONFIG_ARCNET_1051 - case ARC_P_IP_RFC1051: - case ARC_P_ARP_RFC1051: - arcnetS_rx(lp->sdev,arcsoft,length,saddr,daddr); - break; + case ARC_P_IP_RFC1051: + case ARC_P_ARP_RFC1051: + arcnetS_rx(lp->sdev, arcsoft, length, saddr, daddr); + break; #endif - case ARC_P_DATAPOINT_BOOT: - case ARC_P_DATAPOINT_MOUNT: - break; - case ARC_P_POWERLAN_BEACON: - case ARC_P_POWERLAN_BEACON2: - break; - case ARC_P_LANSOFT: /* don't understand. fall through. */ - default: - BUGMSG(D_EXTRA,"received unknown protocol %d (%Xh) from station %d.\n", - arcsoft[0],arcsoft[0],saddr); - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - break; - } - - /* If any worth-while packets have been received, a mark_bh(NET_BH) - * has been done by netif_rx and Linux will handle them after we - * return. - */ + case ARC_P_DATAPOINT_BOOT: + case ARC_P_DATAPOINT_MOUNT: + break; + case ARC_P_POWERLAN_BEACON: + case ARC_P_POWERLAN_BEACON2: + break; + case ARC_P_LANSOFT: /* don't understand. fall through. */ + default: + BUGMSG(D_EXTRA, "received unknown protocol %d (%Xh) from station %d.\n", + arcsoft[0], arcsoft[0], saddr); + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + break; + } + + /* If any worth-while packets have been received, a mark_bh(NET_BH) + * has been done by netif_rx and Linux will handle them after we + * return. + */ } @@ -1081,275 +1032,238 @@ void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr /* Packet receiver for "standard" RFC1201-style packets */ -static void -arcnetA_rx(struct net_device *dev,u_char *buf, - int length, u_char saddr, u_char daddr) +static void arcnetA_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr) { - 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) - */ - arcsoft=(struct ClientData *)(buf-EXTRA_CLIENTDATA); - length+=EXTRA_CLIENTDATA; - - if (arcsoft->split_flag==0xFF) /* Exception Packet */ - { - BUGMSG(D_DURING,"compensating for exception packet\n"); - - /* skip over 4-byte junkola */ - arcsoft=(struct ClientData *) - ((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", - in->sequence,arcsoft->split_flag, - arcsoft->sequence); - lp->aborted_seq=arcsoft->sequence; - kfree_skb(in->skb); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->skb=NULL; + 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) + */ + arcsoft = (struct ClientData *) (buf - EXTRA_CLIENTDATA); + length += EXTRA_CLIENTDATA; + + if (arcsoft->split_flag == 0xFF) { /* Exception Packet */ + BUGMSG(D_DURING, "compensating for exception packet\n"); + + /* skip over 4-byte junkola */ + arcsoft = (struct ClientData *) + ((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", + in->sequence, arcsoft->split_flag, + arcsoft->sequence); + lp->aborted_seq = arcsoft->sequence; + kfree_skb(in->skb); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->skb = NULL; + } + in->sequence = arcsoft->sequence; - in->sequence=arcsoft->sequence; - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - soft=(struct ClientData *)skb->data; - - skb_put(skb,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) - * and insert it ourselves. - */ - if (soft->protocol_id == ARC_P_ARP) - { - struct arphdr *arp=(struct arphdr *) - ((char *)soft+sizeof(struct ClientData)); - - /* make sure addresses are the right length */ - 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", - saddr); - lp->stats.rx_crc_errors++; - *cptr=saddr; + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; } - else - { - BUGMSG(D_DURING,"ARP source address (%Xh) is fine.\n", - *cptr); + soft = (struct ClientData *) skb->data; + + skb_put(skb, 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) + * and insert it ourselves. + */ + if (soft->protocol_id == ARC_P_ARP) { + struct arphdr *arp = (struct arphdr *) + ((char *) soft + sizeof(struct ClientData)); + + /* make sure addresses are the right length */ + 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", + saddr); + lp->stats.rx_crc_errors++; + *cptr = saddr; + } else { + BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n", + *cptr); + } + } else { + BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n", + arp->ar_hln, arp->ar_pln); + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + } } - } - else - { - BUGMSG(D_NORMAL,"funny-shaped ARP packet. (%Xh, %Xh)\n", - arp->ar_hln,arp->ar_pln); - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - } - } + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetA_type_trans(skb, dev); + netif_rx(skb); + } else { /* split packet */ + /* NOTE: MSDOS ARP packet correction should only need to + * apply to unsplit packets, since ARP packets are so short. + * + * My interpretation of the RFC1201 (ARCnet) document is that + * if a packet is received out of order, the entire assembly + * process should be aborted. + * + * The RFC also mentions "it is possible for successfully + * received packets to be retransmitted." As of 0.40 all + * previously received packets are allowed, not just the + * most recent one. + * + * We allow multiple assembly processes, one for each + * ARCnet card possible on the network. Seems rather like + * a waste of memory. Necessary? + */ - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetA_type_trans(skb,dev); - netif_rx(skb); - } - else /* split packet */ - { - /* NOTE: MSDOS ARP packet correction should only need to - * apply to unsplit packets, since ARP packets are so short. - * - * My interpretation of the RFC1201 (ARCnet) document is that - * if a packet is received out of order, the entire assembly - * process should be aborted. - * - * The RFC also mentions "it is possible for successfully - * received packets to be retransmitted." As of 0.40 all - * previously received packets are allowed, not just the - * most recent one. - * - * We allow multiple assembly processes, one for each - * 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); - - if (in->skb && in->sequence!=arcsoft->sequence) - { - BUGMSG(D_EXTRA,"wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n", - saddr,in->sequence,arcsoft->sequence, - arcsoft->split_flag); - kfree_skb(in->skb); - in->skb=NULL; - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->lastpacket=in->numpackets=0; - } + struct Incoming *in = &lp->incoming[saddr]; - if (arcsoft->split_flag & 1) /* first packet in split */ - { - BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n", - arcsoft->split_flag); - if (in->skb) /* already assembling one! */ - { - BUGMSG(D_EXTRA,"aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n", - in->sequence,arcsoft->split_flag, - arcsoft->sequence); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - kfree_skb(in->skb); - } - - 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", - arcsoft->split_flag); - lp->stats.rx_errors++; - lp->stats.rx_length_errors++; - return; - } - - in->skb=skb=alloc_skb(508*in->numpackets - + sizeof(struct ClientData), - GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"(split) memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - - soft=(struct ClientData *)skb->data; - - skb_put(skb,sizeof(struct ClientData)); - skb->dev=dev; - - memcpy((u_char *)soft+EXTRA_CLIENTDATA, - (u_char *)arcsoft+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA); - soft->split_flag=0; /* final packet won't be split */ - } - else /* not first packet */ - { - int packetnum=((unsigned)arcsoft->split_flag>>1) + 1; - - /* if we're not assembling, there's no point - * trying to continue. - */ - if (!in->skb) - { - if (lp->aborted_seq != arcsoft->sequence) - { - BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n", - arcsoft->split_flag,arcsoft->sequence, lp->aborted_seq); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; + BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n", + arcsoft->split_flag, in->sequence); + + if (in->skb && in->sequence != arcsoft->sequence) { + BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n", + saddr, in->sequence, arcsoft->sequence, + arcsoft->split_flag); + kfree_skb(in->skb); + in->skb = NULL; + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->lastpacket = in->numpackets = 0; } - return; - } - - in->lastpacket++; - if (packetnum!=in->lastpacket) /* not the right flag! */ - { - /* harmless duplicate? ignore. */ - if (packetnum<=in->lastpacket-1) - { - BUGMSG(D_EXTRA,"duplicate splitpacket ignored! (splitflag=%d)\n", - arcsoft->split_flag); - lp->stats.rx_errors++; - lp->stats.rx_frame_errors++; - return; + if (arcsoft->split_flag & 1) { /* first packet in split */ + BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n", + arcsoft->split_flag); + if (in->skb) { /* already assembling one! */ + BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n", + in->sequence, arcsoft->split_flag, + arcsoft->sequence); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + kfree_skb(in->skb); + } + 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", + arcsoft->split_flag); + lp->stats.rx_errors++; + lp->stats.rx_length_errors++; + return; + } + in->skb = skb = alloc_skb(508 * in->numpackets + + sizeof(struct ClientData), + GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + soft = (struct ClientData *) skb->data; + + skb_put(skb, sizeof(struct ClientData)); + skb->dev = dev; + + memcpy((u_char *) soft + EXTRA_CLIENTDATA, + (u_char *) arcsoft + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA); + soft->split_flag = 0; /* final packet won't be split */ + } else { /* not first packet */ + int packetnum = ((unsigned) arcsoft->split_flag >> 1) + 1; + + /* if we're not assembling, there's no point + * trying to continue. + */ + if (!in->skb) { + if (lp->aborted_seq != arcsoft->sequence) { + BUGMSG(D_EXTRA, "can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n", + arcsoft->split_flag, arcsoft->sequence, lp->aborted_seq); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + } + return; + } + in->lastpacket++; + if (packetnum != in->lastpacket) { /* not the right flag! */ + /* harmless duplicate? ignore. */ + if (packetnum <= in->lastpacket - 1) { + BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n", + arcsoft->split_flag); + lp->stats.rx_errors++; + 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, + arcsoft->sequence); + lp->aborted_seq = arcsoft->sequence; + kfree_skb(in->skb); + in->skb = NULL; + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->lastpacket = in->numpackets = 0; + return; + } + soft = (struct ClientData *) in->skb->data; } - /* "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, - arcsoft->sequence); - lp->aborted_seq=arcsoft->sequence; - kfree_skb(in->skb); - in->skb=NULL; - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->lastpacket=in->numpackets=0; - return; - } - - 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_put(skb, length - sizeof(struct ClientData)); - skb=in->skb; - - memcpy(skb->data+skb->len, - (u_char *)arcsoft+sizeof(struct ClientData), - length-sizeof(struct ClientData)); - skb_put(skb,length-sizeof(struct ClientData)); - - soft->daddr=daddr; - soft->saddr=saddr; - - /* are we done? */ - if (in->lastpacket == in->numpackets) - { - if (!skb || !in->skb) - { - BUGMSG(D_NORMAL,"?!? done reassembling packet, no skb? (skb=%ph, in->skb=%ph)\n", - skb,in->skb); - } - else - { - in->skb=NULL; - in->lastpacket=in->numpackets=0; - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetA_type_trans(skb,dev); - netif_rx(skb); - } + soft->daddr = daddr; + soft->saddr = saddr; + + /* are we done? */ + if (in->lastpacket == in->numpackets) { + if (!skb || !in->skb) { + BUGMSG(D_NORMAL, "?!? done reassembling packet, no skb? (skb=%ph, in->skb=%ph)\n", + skb, in->skb); + } else { + in->skb = NULL; + in->lastpacket = in->numpackets = 0; + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetA_type_trans(skb, dev); + netif_rx(skb); + } + } } - } } @@ -1359,89 +1273,86 @@ arcnetA_rx(struct net_device *dev,u_char *buf, * * ****************************************************************************/ -/* Get the current statistics. This may be called with the card open or +/* Get the current statistics. This may be called with the card open or * closed. */ 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 = (struct arcnet_local *) dev->priv; - return &lp->stats; + return &lp->stats; } /* Create the ARCnet ClientData header for an arbitrary protocol layer - * - * saddr=NULL means use device source address (always will anyway) - * daddr=NULL means leave destination address (eg unresolved arp) + + * saddr=NULL means use device source address (always will anyway) + * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len) +static int arcnetA_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) { - struct ClientData *head = (struct ClientData *) - skb_push(skb,dev->hard_header_len); - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - BUGMSG(D_DURING,"create header from %d to %d; protocol %d (%Xh); size %u.\n", - saddr ? *(u_char*)saddr : -1, - daddr ? *(u_char*)daddr : -1, - type,type,len); - - /* set the protocol ID according to RFC1201 */ - switch(type) - { - case ETH_P_IP: - head->protocol_id=ARC_P_IP; - break; - case ETH_P_ARP: - head->protocol_id=ARC_P_ARP; - break; - case ETH_P_RARP: - head->protocol_id=ARC_P_RARP; - break; - case ETH_P_IPX: - case ETH_P_802_3: - case ETH_P_802_2: - head->protocol_id=ARC_P_IPX; - break; - case ETH_P_ATALK: - head->protocol_id=ARC_P_ATALK; - break; - default: - BUGMSG(D_NORMAL,"I don't understand protocol %d (%Xh)\n", - type,type); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - return 0; - } - - /* - * Set the source hardware address. - * - * This is pretty pointless for most purposes, but it can help - * in debugging. saddr is stored in the ClientData header and - * removed before sending the packet (since ARCnet does not allow - * us to change the source address in the actual packet sent) - */ - if(saddr) - head->saddr=((u_char*)saddr)[0]; - else - head->saddr=((u_char*)(dev->dev_addr))[0]; - - head->split_flag=0; /* split packets are done elsewhere */ - head->sequence=0; /* so are sequence numbers */ - - /* supposedly if daddr is NULL, we should ignore it... */ - if(daddr) - { - head->daddr=((u_char*)daddr)[0]; - return dev->hard_header_len; - } - else - head->daddr=0; /* better fill one in anyway */ - - return -dev->hard_header_len; + struct ClientData *head = (struct ClientData *) + skb_push(skb, dev->hard_header_len); + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + BUGMSG(D_DURING, "create header from %d to %d; protocol %d (%Xh); size %u.\n", + saddr ? *(u_char *) saddr : -1, + daddr ? *(u_char *) daddr : -1, + type, type, len); + + /* set the protocol ID according to RFC1201 */ + switch (type) { + case ETH_P_IP: + head->protocol_id = ARC_P_IP; + break; + case ETH_P_ARP: + head->protocol_id = ARC_P_ARP; + break; + case ETH_P_RARP: + head->protocol_id = ARC_P_RARP; + break; + case ETH_P_IPX: + case ETH_P_802_3: + case ETH_P_802_2: + head->protocol_id = ARC_P_IPX; + break; + case ETH_P_ATALK: + head->protocol_id = ARC_P_ATALK; + break; + default: + BUGMSG(D_NORMAL, "I don't understand protocol %d (%Xh)\n", + type, type); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + return 0; + } + + /* + * Set the source hardware address. + * + * This is pretty pointless for most purposes, but it can help + * in debugging. saddr is stored in the ClientData header and + * removed before sending the packet (since ARCnet does not allow + * us to change the source address in the actual packet sent) + */ + if (saddr) + head->saddr = ((u_char *) saddr)[0]; + else + head->saddr = ((u_char *) (dev->dev_addr))[0]; + + head->split_flag = 0; /* split packets are done elsewhere */ + head->sequence = 0; /* so are sequence numbers */ + + /* supposedly if daddr is NULL, we should ignore it... */ + if (daddr) { + head->daddr = ((u_char *) daddr)[0]; + return dev->hard_header_len; + } else + head->daddr = 0; /* better fill one in anyway */ + + return -dev->hard_header_len; } @@ -1451,86 +1362,84 @@ static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, */ static int arcnetA_rebuild_header(struct sk_buff *skb) { - struct ClientData *head = (struct ClientData *)skb->data; - struct net_device *dev=skb->dev; - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); + struct ClientData *head = (struct ClientData *) skb->data; + struct net_device *dev = skb->dev; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); #ifdef CONFIG_INET - int status; + int status; #endif - /* - * Only ARP and IP are currently supported - * - * FIXME: Anyone want to spec IPv6 over ARCnet ? - */ - - 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); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - head->daddr=0; - /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len);*/ - return 0; - } - - /* - * Try to get ARP to resolve the header. - */ + /* + * Only ARP and IP are currently supported + * + * FIXME: Anyone want to spec IPv6 over ARCnet ? + */ + + 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); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + head->daddr = 0; + /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len); */ + return 0; + } + /* + * Try to get ARP to resolve the header. + */ #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; - BUGMSG(D_DURING," rebuilt: from %d to %d; protocol %Xh\n", - head->saddr,head->daddr,head->protocol_id); - return status; + 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; + BUGMSG(D_DURING, " rebuilt: from %d to %d; protocol %Xh\n", + head->saddr, head->daddr, head->protocol_id); + return status; #else - return 0; + return 0; #endif } /* Determine a packet's protocol ID. - * + * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device *dev) +static unsigned short arcnetA_type_trans(struct sk_buff *skb, struct net_device *dev) { - struct ClientData *head; - struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); - - /* Pull off the arcnet header. */ - 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) - { - /* if we're not sending to ourselves :) */ - if (head->daddr != dev->dev_addr[0]) - skb->pkt_type=PACKET_OTHERHOST; - } - - /* now return the protocol number */ - switch (head->protocol_id) - { - case ARC_P_IP: return htons(ETH_P_IP); - case ARC_P_ARP: return htons(ETH_P_ARP); - case ARC_P_RARP: return htons(ETH_P_RARP); - - case ARC_P_IPX: - case ARC_P_NOVELL_EC: - return htons(ETH_P_802_3); - default: - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - return 0; - } - - return htons(ETH_P_IP); + struct ClientData *head; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* Pull off the arcnet header. */ + 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) { + /* if we're not sending to ourselves :) */ + if (head->daddr != dev->dev_addr[0]) + skb->pkt_type = PACKET_OTHERHOST; + } + /* now return the protocol number */ + switch (head->protocol_id) { + case ARC_P_IP: + return htons(ETH_P_IP); + case ARC_P_ARP: + return htons(ETH_P_ARP); + case ARC_P_RARP: + return htons(ETH_P_RARP); + + case ARC_P_IPX: + case ARC_P_NOVELL_EC: + return htons(ETH_P_802_3); + default: + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + return 0; + } + + return htons(ETH_P_IP); } @@ -1545,17 +1454,17 @@ static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device * */ static int arcnetE_init(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - ether_setup(dev); /* we're emulating ether here, not ARCnet */ - dev->dev_addr[0]=0; - dev->dev_addr[5]=lp->stationid; - dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len-1; - dev->open=arcnetE_open_close; - dev->stop=arcnetE_open_close; - dev->hard_start_xmit=arcnetE_send_packet; + ether_setup(dev); /* we're emulating ether here, not ARCnet */ + dev->dev_addr[0] = 0; + dev->dev_addr[5] = lp->stationid; + dev->mtu = 512 - sizeof(struct archdr) - dev->hard_header_len - 1; + dev->open = arcnetE_open_close; + dev->stop = arcnetE_open_close; + dev->hard_start_xmit = arcnetE_send_packet; - return 0; + return 0; } @@ -1564,86 +1473,77 @@ static int arcnetE_init(struct net_device *dev) */ static int arcnetE_open_close(struct net_device *dev) { - return 0; + return 0; } /* Called by the kernel in order to transmit an ethernet-type packet. */ -static int -arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,oldmask=0; - u_char daddr; - short offset,length=skb->len+1; - u_char proto=ARC_P_ETHER; - - lp->intx++; - - oldmask |= lp->intmask; - lp->intmask=0; - SETMASK; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - lp->intmask=oldmask; - SETMASK; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - lp->intmask=oldmask; - SETMASK; - - if (length>XMTU) - { - BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n", - length); - BUGMSG(D_NORMAL,"transmit aborted.\n"); - - dev_kfree_skb(skb); - lp->intx--; - return 0; - } - - BUGMSG(D_DURING,"starting tx sequence...\n"); - - /* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */ - if (((struct ethhdr*)(skb->data))->h_dest[0] == 0xFF) - daddr=0; - else - daddr=((struct ethhdr*)(skb->data))->h_dest[5]; - - /* load packet into shared memory */ - offset=512-length; - if (length>MTU) /* long/exception packet */ - { - if (length<MinTU) offset-=3; - } - else /* short packet */ - { - offset-=256; - } - - BUGMSG(D_DURING," length=%Xh, offset=%Xh\n", - length,offset); - - (*lp->prepare_tx)(dev, &proto, 1, skb->data, length-1, daddr, 0, - offset); + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, oldmask = 0; + u_char daddr; + short offset, length = skb->len + 1; + u_char proto = ARC_P_ETHER; + + lp->intx++; + + oldmask |= lp->intmask; + lp->intmask = 0; + SETMASK; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + lp->intmask = oldmask; + SETMASK; + return bad; + } + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - dev_kfree_skb(skb); + lp->intmask = oldmask; + SETMASK; + + if (length > XMTU) { + BUGMSG(D_NORMAL, "MTU must be <= 493 for ethernet encap (length=%d).\n", + length); + BUGMSG(D_NORMAL, "transmit aborted.\n"); + + dev_kfree_skb(skb); + lp->intx--; + return 0; + } + BUGMSG(D_DURING, "starting tx sequence...\n"); + + /* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */ + if (((struct ethhdr *) (skb->data))->h_dest[0] == 0xFF) + daddr = 0; + else + daddr = ((struct ethhdr *) (skb->data))->h_dest[5]; + + /* load packet into shared memory */ + offset = 512 - length; + if (length > MTU) { /* long/exception packet */ + if (length < MinTU) + offset -= 3; + } else { /* short packet */ + offset -= 256; + } - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(lp->adev, lp); - } + BUGMSG(D_DURING, " length=%Xh, offset=%Xh\n", + length, offset); - dev->trans_start=jiffies; + (*lp->prepare_tx) (dev, &proto, 1, skb->data, length - 1, daddr, 0, + offset); + + dev_kfree_skb(skb); + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(lp->adev, lp); + } + dev->trans_start = jiffies; lp->intx--; /* make sure we didn't ignore a TX IRQ while we were in here */ @@ -1656,37 +1556,35 @@ arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) /* Packet receiver for ethernet-encap packets. */ -static void -arcnetE_rx(struct net_device *dev,u_char *arcsoft, - int length,u_char saddr, u_char daddr) +static void arcnetE_rx(struct net_device *dev, u_char * arcsoft, + int length, u_char saddr, u_char daddr) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + 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); - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } + BUGMSG(D_DURING, "it's an ethernet-encap packet (length=%d)\n", + length); - skb_put(skb,length); + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + skb_put(skb, length); - skb->dev = dev; + skb->dev = dev; - memcpy(skb->data,(u_char *)arcsoft+1,length-1); + memcpy(skb->data, (u_char *) arcsoft + 1, length - 1); - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); lp->stats.rx_bytes += skb->len; - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); } -#endif /* CONFIG_ARCNET_ETH */ +#endif /* CONFIG_ARCNET_ETH */ #ifdef CONFIG_ARCNET_1051 /**************************************************************************** @@ -1699,22 +1597,22 @@ arcnetE_rx(struct net_device *dev,u_char *arcsoft, */ static int arcnetS_init(struct net_device *dev) { - 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); - dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len - + S_EXTRA_CLIENTDATA; - dev->open=arcnetS_open_close; - dev->stop=arcnetS_open_close; - dev->hard_start_xmit=arcnetS_send_packet; - dev->hard_header=arcnetS_header; - dev->rebuild_header=arcnetS_rebuild_header; - - return 0; + 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); + dev->mtu = 512 - sizeof(struct archdr) - dev->hard_header_len + + S_EXTRA_CLIENTDATA; + dev->open = arcnetS_open_close; + dev->stop = arcnetS_open_close; + dev->hard_start_xmit = arcnetS_send_packet; + dev->hard_header = arcnetS_header; + dev->rebuild_header = arcnetS_rebuild_header; + + return 0; } @@ -1723,171 +1621,160 @@ static int arcnetS_init(struct net_device *dev) */ static int arcnetS_open_close(struct net_device *dev) { - return 0; + return 0; } /* Called by the kernel in order to transmit an RFC1051-type packet. */ -static int -arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,length; - struct S_ClientData *hdr=(struct S_ClientData *)skb->data; - - lp->intx++; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - length = 1 < skb->len ? skb->len : 1; - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx"); - - /* fits in one packet? */ - if (length-S_EXTRA_CLIENTDATA<=XMTU) - { - (*lp->prepare_tx)(dev, - skb->data+S_EXTRA_CLIENTDATA, - sizeof(struct S_ClientData)-S_EXTRA_CLIENTDATA, - skb->data+sizeof(struct S_ClientData), - length-sizeof(struct S_ClientData), - hdr->daddr,0,0); - - /* done right away */ - dev_kfree_skb(skb); - - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(lp->adev, lp); + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, length; + struct S_ClientData *hdr = (struct S_ClientData *) skb->data; + + lp->intx++; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + return bad; } - } - else /* too big for one - not accepted */ - { - BUGMSG(D_NORMAL,"packet too long (length=%d)\n", - length); - dev_kfree_skb(skb); - lp->stats.tx_dropped++; - arcnet_tx_done(lp->adev, lp); - } - - dev->trans_start=jiffies; - lp->intx--; - - /* make sure we didn't ignore a TX IRQ while we were in here */ - lp->intmask |= TXFREEflag; - SETMASK; - - return 0; + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ + + length = 1 < skb->len ? skb->len : 1; + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx"); + + /* fits in one packet? */ + if (length - S_EXTRA_CLIENTDATA <= XMTU) { + (*lp->prepare_tx) (dev, + skb->data + S_EXTRA_CLIENTDATA, + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, + skb->data + sizeof(struct S_ClientData), + length - sizeof(struct S_ClientData), + hdr->daddr, 0, 0); + + /* done right away */ + dev_kfree_skb(skb); + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(lp->adev, lp); + } + } else { /* too big for one - not accepted */ + BUGMSG(D_NORMAL, "packet too long (length=%d)\n", + length); + dev_kfree_skb(skb); + lp->stats.tx_dropped++; + arcnet_tx_done(lp->adev, lp); + } + + dev->trans_start = jiffies; + lp->intx--; + + /* make sure we didn't ignore a TX IRQ while we were in here */ + lp->intmask |= TXFREEflag; + SETMASK; + + return 0; } /* Packet receiver for RFC1051 packets; */ -static void -arcnetS_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr) +static void arcnetS_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr) { - 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 */ - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - soft=(struct S_ClientData *)skb->data; - skb_put(skb,length); - - memcpy((u_char *)soft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, - (u_char *)arcsoft + sizeof(struct S_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"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetS_type_trans(skb,dev); - netif_rx(skb); - } + 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 */ + + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + soft = (struct S_ClientData *) skb->data; + skb_put(skb, length); + + memcpy((u_char *) soft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, + (u_char *) arcsoft + sizeof(struct S_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"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetS_type_trans(skb, dev); + netif_rx(skb); + } } /* Create the ARCnet ClientData header for an arbitrary protocol layer - * - * saddr=NULL means use device source address (always will anyway) - * daddr=NULL means leave destination address (eg unresolved arp) + + * saddr=NULL means use device source address (always will anyway) + * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len) +static int arcnetS_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) { - struct S_ClientData *head = (struct S_ClientData *) - skb_push(skb,dev->hard_header_len); - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - /* set the protocol ID according to RFC1051 */ - switch(type) - { - case ETH_P_IP: - head->protocol_id=ARC_P_IP_RFC1051; - BUGMSG(D_DURING,"S_header: IP_RFC1051 packet.\n"); - break; - case ETH_P_ARP: - head->protocol_id=ARC_P_ARP_RFC1051; - BUGMSG(D_DURING,"S_header: ARP_RFC1051 packet.\n"); - break; - default: - BUGMSG(D_NORMAL,"I don't understand protocol %d (%Xh)\n", - type,type); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - return 0; - } - - /* - * Set the source hardware address. - * - * This is pretty pointless for most purposes, but it can help - * in debugging. saddr is stored in the ClientData header and - * removed before sending the packet (since ARCnet does not allow - * us to change the source address in the actual packet sent) - */ - if(saddr) - head->saddr=((u_char*)saddr)[0]; - else - head->saddr=((u_char*)(dev->dev_addr))[0]; - - /* supposedly if daddr is NULL, we should ignore it... */ - if(daddr) - { - head->daddr=((u_char*)daddr)[0]; + struct S_ClientData *head = (struct S_ClientData *) + skb_push(skb, dev->hard_header_len); + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* set the protocol ID according to RFC1051 */ + switch (type) { + case ETH_P_IP: + head->protocol_id = ARC_P_IP_RFC1051; + BUGMSG(D_DURING, "S_header: IP_RFC1051 packet.\n"); + break; + case ETH_P_ARP: + head->protocol_id = ARC_P_ARP_RFC1051; + BUGMSG(D_DURING, "S_header: ARP_RFC1051 packet.\n"); + break; + default: + BUGMSG(D_NORMAL, "I don't understand protocol %d (%Xh)\n", + type, type); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + return 0; + } + + /* + * Set the source hardware address. + * + * This is pretty pointless for most purposes, but it can help + * in debugging. saddr is stored in the ClientData header and + * removed before sending the packet (since ARCnet does not allow + * us to change the source address in the actual packet sent) + */ + if (saddr) + head->saddr = ((u_char *) saddr)[0]; + else + head->saddr = ((u_char *) (dev->dev_addr))[0]; + + /* supposedly if daddr is NULL, we should ignore it... */ + if (daddr) { + head->daddr = ((u_char *) daddr)[0]; return dev->hard_header_len; - } - else - head->daddr=0; /* better fill one in anyway */ + } else + head->daddr = 0; /* better fill one in anyway */ - return -dev->hard_header_len; + return -dev->hard_header_len; } @@ -1897,75 +1784,73 @@ static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, */ static int arcnetS_rebuild_header(struct sk_buff *skb) { - struct net_device *dev=skb->dev; - struct S_ClientData *head = (struct S_ClientData *)skb->data; - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - /* - * Only ARP and IP are currently supported - */ - - 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); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - head->daddr=0; - /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len);*/ - return 0; - } - - /* - * Try to get ARP to resolve the header. - */ + struct net_device *dev = skb->dev; + struct S_ClientData *head = (struct S_ClientData *) skb->data; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* + * Only ARP and IP are currently supported + */ + + 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); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + head->daddr = 0; + /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len); */ + return 0; + } + /* + * Try to get ARP to resolve the header. + */ #ifdef CONFIG_INET - return arp_find(&(head->daddr),skb)? 1 : 0; + return arp_find(&(head->daddr), skb) ? 1 : 0; #else - return 0; + return 0; #endif } /* Determine a packet's protocol ID. - * + * With ARCnet we have to convert everything to Ethernet-style stuff. */ -unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) +unsigned short arcnetS_type_trans(struct sk_buff *skb, struct net_device *dev) { - struct S_ClientData *head; - struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); - - /* Pull off the arcnet header. */ - 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) - { - /* if we're not sending to ourselves :) */ - if (head->daddr != dev->dev_addr[0]) - skb->pkt_type=PACKET_OTHERHOST; - } - - /* now return the protocol number */ - switch (head->protocol_id) - { - case ARC_P_IP_RFC1051: return htons(ETH_P_IP); - case ARC_P_ARP_RFC1051: return htons(ETH_P_ARP); - case ARC_P_ATALK: return htons(ETH_P_ATALK); /* untested appletalk */ - default: - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - return 0; - } - - return htons(ETH_P_IP); + struct S_ClientData *head; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* Pull off the arcnet header. */ + 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) { + /* if we're not sending to ourselves :) */ + if (head->daddr != dev->dev_addr[0]) + skb->pkt_type = PACKET_OTHERHOST; + } + /* now return the protocol number */ + switch (head->protocol_id) { + case ARC_P_IP_RFC1051: + return htons(ETH_P_IP); + case ARC_P_ARP_RFC1051: + return htons(ETH_P_ARP); + case ARC_P_ATALK: + return htons(ETH_P_ATALK); /* untested appletalk */ + default: + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + return 0; + } + + return htons(ETH_P_IP); } -#endif /* CONFIG_ARCNET_1051 */ +#endif /* CONFIG_ARCNET_1051 */ /**************************************************************************** @@ -1978,15 +1863,15 @@ unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) void cleanup_module(void) { - printk("Generic arcnet support removed.\n"); + printk("Generic arcnet support removed.\n"); } void arcnet_use_count(int open) { - if (open) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; + if (open) + MOD_INC_USE_COUNT; + else + MOD_DEC_USE_COUNT; } #else @@ -1996,54 +1881,52 @@ void arcnet_use_count(int open) } struct net_device arcnet_devs[MAX_ARCNET_DEVS]; -int arcnet_num_devs=0; +int arcnet_num_devs = 0; char arcnet_dev_names[MAX_ARCNET_DEVS][10]; -void __init arcnet_init(void) +int __init arcnet_init(void) { - int c; + int c; - init_module(); + init_module(); - /* Don't register_netdev here. The chain hasn't been initialised. */ + /* Don't register_netdev here. The chain hasn't been initialised. */ #ifdef CONFIG_ARCNET_COM90xx - if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS) - { - arcnet_devs[arcnet_num_devs].init=arc90xx_probe; - arcnet_devs[arcnet_num_devs].name= - (char *)&arcnet_dev_names[arcnet_num_devs]; - arcnet_num_devs++; - } + if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS) { + arcnet_devs[arcnet_num_devs].init = arc90xx_probe; + arcnet_devs[arcnet_num_devs].name = + (char *) &arcnet_dev_names[arcnet_num_devs]; + arcnet_num_devs++; + } #endif - if (!arcnet_num_devs) - { - printk("Don't forget to load the chipset driver.\n"); - return; - } - - /* Link into the device chain */ + if (!arcnet_num_devs) { + printk("Don't forget to load the chipset driver.\n"); + return 0; + } + /* Link into the device chain */ - /* Q: Should we put ourselves at the beginning or the end of the chain? */ - /* Probably the end, because we're not so fast, but... */ + /* Q: Should we put ourselves at the beginning or the end of the chain? */ + /* Probably the end, because we're not so fast, but... */ - for (c=0; c< (arcnet_num_devs-1); c++) - arcnet_devs[c].next=&arcnet_devs[c+1]; + for (c = 0; c < (arcnet_num_devs - 1); c++) + arcnet_devs[c].next = &arcnet_devs[c + 1]; - write_lock_bh(&dev_base_lock); - arcnet_devs[c].next=dev_base; - dev_base=&arcnet_devs[0]; - write_unlock_bh(&dev_base_lock); + write_lock_bh(&dev_base_lock); + arcnet_devs[c].next = dev_base; + dev_base = &arcnet_devs[0]; + write_unlock_bh(&dev_base_lock); - /* Give names to those without them */ + /* Give names to those without them */ - for (c=0; c< arcnet_num_devs; c++) - if (!arcnet_dev_names[c][0]) - arcnet_makename((char *)&arcnet_dev_names[c]); + for (c = 0; c < arcnet_num_devs; c++) + if (!arcnet_dev_names[c][0]) + arcnet_makename((char *) &arcnet_dev_names[c]); + return 0; } -#endif /* MODULE */ +#endif /* MODULE */ #ifdef MODULE @@ -2053,48 +1936,46 @@ static int __init init_module(void) #endif { #ifdef ALPHA_WARNING - BUGLVL(D_EXTRA) - { - printk("arcnet: ***\n"); - printk("arcnet: * Read arcnet.txt for important release notes!\n"); - printk("arcnet: *\n"); - printk("arcnet: * This is an ALPHA version! (Last stable release: v2.56) E-mail me if\n"); - printk("arcnet: * you have any questions, comments, or bug reports.\n"); - printk("arcnet: ***\n"); - } + BUGLVL(D_EXTRA) { + printk("arcnet: ***\n"); + printk("arcnet: * Read arcnet.txt for important release notes!\n"); + printk("arcnet: *\n"); + printk("arcnet: * This is an ALPHA version! (Last stable release: v2.56) E-mail me if\n"); + printk("arcnet: * you have any questions, comments, or bug reports.\n"); + printk("arcnet: ***\n"); + } #endif - printk("%sAvailable protocols: ARCnet RFC1201" + printk("%sAvailable protocols: ARCnet RFC1201" #ifdef CONFIG_ARCNET_ETH - ", Ethernet-Encap" + ", Ethernet-Encap" #endif #ifdef CONFIG_ARCNET_1051 - ", ARCnet RFC1051" + ", ARCnet RFC1051" #endif #ifdef MODULE - ".\nDon't forget to load the chipset driver" + ".\nDon't forget to load the chipset driver" #endif - ".\n",version); - return 0; + ".\n", version); + return 0; } void arcnet_makename(char *device) { - struct net_device *dev; - int arcnum; - - arcnum = 0; - for (;;) - { - sprintf(device, "arc%d", arcnum); - read_lock_bh(&dev_base_lock); - for (dev = dev_base; dev; dev=dev->next) - if (dev->name != device && !strcmp(dev->name, device)) - break; - read_unlock_bh(&dev_base_lock); - if (!dev) - return; - arcnum++; - } + struct net_device *dev; + int arcnum; + + arcnum = 0; + for (;;) { + sprintf(device, "arc%d", arcnum); + read_lock_bh(&dev_base_lock); + for (dev = dev_base; dev; dev = dev->next) + if (dev->name != device && !strcmp(dev->name, device)) + break; + read_unlock_bh(&dev_base_lock); + if (!dev) + return; + arcnum++; + } } |