⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arcnet.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	$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";#include <linux/module.h>#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/errno.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/if_arp.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/init.h>#include <linux/if_arcnet.h>#include <linux/arcdevice.h>#include <asm/system.h>#include <asm/bitops.h>#include <asm/io.h>#include <asm/dma.h>#include <net/arp.h>/* Define this if you want to make it easier to use the "call trace" when * a kernel NULL pointer assignment occurs.  Hopefully unnecessary, most of * the time.  It will make all the function names (and other things) show * up as kernel symbols.  (especially handy when using arcnet as a module) */#undef static/**************************************************************************//* These are now provided by the chipset driver. There's a performance * overhead in using them. */#define AINTMASK(x) ((*lp->asetmask)(dev, x))#define ARCSTATUS ((*lp->astatus)(dev))#define ACOMMAND(x) ((*lp->acommand)(dev, x))int arcnet_debug=ARCNET_DEBUG;/* Exported function prototypes */#ifdef MODULEint  init_module(void);void cleanup_module(void);#elsevoid arcnet_init(void);static int init_module(void);#ifdef CONFIG_ARCNET_COM90xxextern char com90xx_explicit;extern int arc90xx_probe(struct device *dev);#endif#endifvoid arcnet_tx_done(struct device *dev, struct arcnet_local *lp);void arcnet_use_count (int open);void arcnet_setup(struct device *dev);void arcnet_makename(char *device);void arcnetA_continue_tx(struct device *dev);int arcnet_go_tx(struct 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);EXPORT_SYMBOL(arcnet_use_count);EXPORT_SYMBOL(arcnet_setup);EXPORT_SYMBOL(arcnet_makename);EXPORT_SYMBOL(arcnetA_continue_tx);EXPORT_SYMBOL(arcnet_go_tx);EXPORT_SYMBOL(arcnet_interrupt);EXPORT_SYMBOL(arcnet_rx);#if ARCNET_DEBUG_MAX & D_SKBvoid arcnet_dump_skb(struct device *dev,struct sk_buff *skb,	char *desc);EXPORT_SYMBOL(arcnet_dump_skb);#else#	define arcnet_dump_skb(dev,skb,desc) ;#endif#if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX)void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,	char *desc);EXPORT_SYMBOL(arcnet_dump_packet);#else#	define arcnet_dump_packet(dev,buffer,ext,desc) ;#endif/* Internal function prototypes */static int arcnet_open(struct device *dev);static int arcnet_close(struct device *dev);static int arcnetA_header(struct sk_buff *skb,struct 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 device *dev);static int arcnetA_send_packet(struct sk_buff *skb, struct device *dev);static void arcnetA_rx(struct device *dev,u_char *buf,	int length,u_char saddr, u_char daddr);static struct net_device_stats *arcnet_get_stats(struct device *dev);static unsigned short arcnetA_type_trans(struct sk_buff *skb,					 struct device *dev);#ifdef CONFIG_ARCNET_ETH	/* functions specific to Ethernet-Encap */static int arcnetE_init(struct device *dev);static int arcnetE_open_close(struct device *dev);static int arcnetE_send_packet(struct sk_buff *skb, struct device *dev);static void arcnetE_rx(struct device *dev,u_char *arcsoft,	int length,u_char saddr, u_char daddr);#endif#ifdef CONFIG_ARCNET_1051	/* functions specific to RFC1051 */static int arcnetS_init(struct device *dev);static int arcnetS_open_close(struct device *dev);static int arcnetS_send_packet(struct sk_buff *skb, struct device *dev);static void arcnetS_rx(struct device *dev,u_char *buf,	int length,u_char saddr, u_char daddr);static int arcnetS_header(struct sk_buff *skb,struct 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 device *dev);#endif/**************************************************************************** *                                                                          * * Packet dumps for debugging                                               * *                                                                          * ****************************************************************************//* Dump the contents of an sk_buff */#if ARCNET_DEBUG_MAX & D_SKBvoid arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc){	int i;	long flags;	save_flags(flags);	cli();	printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc);        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);}#endif/* Dump the contents of an ARCnet buffer */#if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX)void arcnet_dump_packet(struct 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("\n");	restore_flags(flags);}#endif/* Setup a struct device for ARCnet.  This should really be in net_init.c * but since there are three different ARCnet devices ANYWAY... <gargle> * * Actually, the whole idea of having all this kernel-dependent stuff (ie. * "new-style flags") setup per-net-device is kind of weird anyway. * * Intelligent defaults?!  Nah. */void arcnet_setup(struct 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;	/* New-style flags. */	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;}/**************************************************************************** *                                                                          * * Open and close the driver                                                * *                                                                          * ****************************************************************************//* Open/initialize the board.  This is called sometime after booting when * the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * 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 intarcnet_open(struct 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;#ifdef CONFIG_ARCNET_ETH  /* Initialize the ethernet-encap protocol driver */  lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL);  if (lp->edev == NULL)    return -ENOMEM;  memcpy(lp->edev,dev,sizeof(struct 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 device *)kmalloc(sizeof(struct device),GFP_KERNEL);  memcpy(lp->sdev,dev,sizeof(struct device));  lp->sdev->name=(char *)kmalloc(10,GFP_KERNEL);  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);  /* 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;  /* Let it increase its use count */  (*lp->openclose_device)(1);  return 0;}/* The inverse routine to arcnet_open - shuts down the card. */static intarcnet_close(struct device *dev){  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");  dev->start=0;#ifdef CONFIG_ARCNET_1051  lp->sdev->tbusy=1;  lp->sdev->start=0;#endif#ifdef CONFIG_ARCNET_ETH  lp->edev->tbusy=1;  lp->edev->start=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -