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

📄 xircom_cb.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * xircom_cb: A driver for the (tulip-like) Xircom Cardbus ethernet cards  * * This software is Copyright 2001 by the respective authors, and licensed under the GPL * License. * * Written by Arjan van de Ven for Red Hat, Inc. * Based on work by Jeff Garzik, Doug Ledford, Donald Becker and Ion Badulescu * *  	This software may be used and distributed according to the terms *      of the GNU General Public License, incorporated herein by reference. * * * 	$Id: xircom_cb.c,v 1.11 2001/06/05 09:50:57 fenrus Exp $ */#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/delay.h>#include <asm/io.h>#ifdef DEBUG#define enter()   printk("Enter: %s, %s line %i\n",__FUNCTION__,__FILE__,__LINE__)#define leave()   printk("Leave: %s, %s line %i\n",__FUNCTION__,__FILE__,__LINE__)#else#define enter()   do {} while (0)#define leave()   do {} while (0)#endifMODULE_DESCRIPTION("Xircom Cardbus ethernet driver");MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");MODULE_LICENSE("GPL");/* IO registers on the card, offsets */#define CSR0	0x00#define CSR1	0x08#define CSR2	0x10#define CSR3	0x18#define CSR4	0x20#define CSR5	0x28#define CSR6	0x30#define CSR7	0x38#define CSR8	0x40#define CSR9	0x48#define CSR10	0x50#define CSR11	0x58#define CSR12	0x60#define CSR13	0x68#define CSR14	0x70#define CSR15	0x78#define CSR16	0x80/* PCI registers */#define PCI_POWERMGMT 	0x40/* Offsets of the buffers within the descriptor pages, in bytes */#define NUMDESCRIPTORS 4#define RXTXBUFSIZE 8192#define MAX_PACKETSIZE 1536#define DescOwnedCard	0x80000000#define DescOwnedDriver	0x00000000#define PromiscBit		(1<<6)#define CollisionBit 		(1<<8)#define TxActiveBit		(1<<13)#define RxActiveBit		(1<<1)#define LastDescBit	 	(1<<25)#define LinkStatusBit 		(1<<27)#define PowerMgmtBits		( (1<<31)|(1<<30) )static const unsigned int bufferoffsets[NUMDESCRIPTORS] = {128,2048,4096,6144};/* note: this struct is assumed to be packed as this is the "hardware" layout */struct descriptor {	u32	status;	u32	control;	u32	address1;	u32	address2;};struct xircom_private {	/* Send and receive buffers, kernel-addressable and dma addressable forms */	unsigned char *rx_buffer;	unsigned char *tx_buffer;		struct descriptor *rx_desc;	struct descriptor *tx_desc;	dma_addr_t rx_dma_handle;	dma_addr_t tx_dma_handle;	struct sk_buff *tx_skb[NUMDESCRIPTORS];	unsigned long io_port;		/* transmit_used is the rotating counter that indicates which transmit	   descriptor has to be used next */	unsigned int transmit_used;	/* Spinlock to serialize register operations.	   It must be helt while manipulating the following registers:	   CSR0, CSR6, CSR7, CSR9, CSR10, CSR15	 */	spinlock_t lock;	struct pci_dev *pdev;	struct net_device *dev;	struct net_device_stats stats;};/* Function prototypes */static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id);static void xircom_remove(struct pci_dev *pdev);static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);static int xircom_open(struct net_device *dev);static int xircom_close(struct net_device *dev);static void xircom_up(struct xircom_private *card);static struct net_device_stats *xircom_get_stats(struct net_device *dev);static void investigate_rx_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset);static unsigned int investigate_tx_descriptor(struct net_device *dev, struct xircom_private *card, unsigned int descnr, unsigned int bufferoffset);static void read_mac_address(struct xircom_private *card);static void tranceiver_voodoo(struct xircom_private *card);static void initialize_card(struct xircom_private *card);static inline void trigger_transmit(struct xircom_private *card);static inline void trigger_receive(struct xircom_private *card);static void setup_descriptors(struct xircom_private *card);static inline void remove_descriptors(struct xircom_private *card);static inline unsigned int link_status_changed(struct xircom_private *card);static void activate_receiver(struct xircom_private *card);static void deactivate_receiver(struct xircom_private *card);static void activate_transmitter(struct xircom_private *card);static void deactivate_transmitter(struct xircom_private *card);static void enable_transmit_interrupt(struct xircom_private *card);static void enable_receive_interrupt(struct xircom_private *card);static void enable_link_interrupt(struct xircom_private *card);static void disable_all_interrupts(struct xircom_private *card);static inline unsigned int link_status(struct xircom_private *card);static int mdio_read(struct xircom_private *card, int phy_id, int location);static void mdio_write(struct xircom_private *card, int phy_id, int location, int value);static struct pci_device_id xircom_pci_table[] __devinitdata = {	{0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,},	{0,},};MODULE_DEVICE_TABLE(pci, xircom_pci_table);static struct pci_driver xircom_ops = {	name:		"xircom_cb", 	id_table:	xircom_pci_table, 	probe:		xircom_probe, 	remove:		__devexit_p(xircom_remove), };#ifdef DEBUGstatic void print_binary(unsigned int number){	int i,i2;	char buffer[64];	memset(buffer,0,64);	i2=0;	for (i=31;i>=0;i--) {		if (number & (1<<i))			buffer[i2++]='1';		else			buffer[i2++]='0';		if ((i&3)==0) 			buffer[i2++]=' ';	}	printk("%s\n",buffer);}#endif/* xircom_probe is the code that gets called on device insertion.   it sets up the hardware and registers the device to the networklayer.      TODO: Send 1 or 2 "dummy" packets here as the card seems to discard the         first two packets that get send, and pump hates that.          */static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id){	struct net_device *dev = NULL;	struct xircom_private *private;	u8 chip_rev;	unsigned long flags;	u32 tmp32;	u16 tmp16;	int ret;	enter();		/* First do the PCI initialisation */	ret = pci_enable_device(pdev);	if (ret)		return ret;	/* disable all powermanagement */	pci_read_config_dword(pdev, PCI_POWERMGMT,&tmp32);	tmp32 &= ~PowerMgmtBits; 	pci_write_config_dword(pdev, PCI_POWERMGMT, tmp32);		pci_set_master(pdev); 	/* clear PCI status, if any */ 	pci_read_config_word (pdev,PCI_STATUS, &tmp16); 	pci_write_config_word (pdev, PCI_STATUS,tmp16);		pci_read_config_byte(pdev, PCI_REVISION_ID, &chip_rev);		if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {		printk(KERN_ERR "xircom_probe: failed to allocate io-region\n");		return -ENODEV;	}		dev = init_etherdev(dev, sizeof(*private));	if (dev == NULL) {		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");		return -ENODEV;	}	SET_MODULE_OWNER(dev);	private = dev->priv;	if (private==NULL) {		printk(KERN_ERR "xircom_probe: failed to allocate private device struct\n");		return -ENODEV;	}			/* Allocate the send/receive buffers */	private->rx_buffer = pci_alloc_consistent(pdev,RXTXBUFSIZE,&private->rx_dma_handle);	if (private->rx_buffer == NULL) { 		printk(KERN_ERR "xircom_probe: no memory for rx buffer \n"); 		kfree(private);		return -ENODEV;	}		/* the descriptors are stored in the first bytes of the rx_buffer, hence the ugly cast */	private->rx_desc = (struct descriptor *)private->rx_buffer;	private->tx_buffer = pci_alloc_consistent(pdev,RXTXBUFSIZE,&private->tx_dma_handle);	if (private->tx_buffer == NULL) {		printk(KERN_ERR "xircom_probe: no memory for tx buffer \n");		kfree(private->rx_buffer);		kfree(private);		return -ENODEV;	}	/* the descriptors are stored in the first bytes of the tx_buffer, hence the ugly cast */	private->tx_desc = (struct descriptor *)private->tx_buffer;			printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);	private->dev = dev;	private->pdev = pdev;	private->io_port = pci_resource_start(pdev, 0);	private->lock = SPIN_LOCK_UNLOCKED;	dev->irq = pdev->irq;	dev->base_addr = private->io_port;			initialize_card(private);	read_mac_address(private);	setup_descriptors(private);		dev->open = &xircom_open;	dev->hard_start_xmit = &xircom_start_xmit;	dev->stop = &xircom_close;	dev->get_stats = &xircom_get_stats;	dev->priv = private;	pci_set_drvdata(pdev,dev);		/* start the transmitter to get a heartbeat; don't do	   that when there already is one though; Cisco's 	   really don't like that. */	if (!link_status(private))		tranceiver_voodoo(private);		spin_lock_irqsave(&private->lock,flags);	  activate_transmitter(private);	  activate_receiver(private);	spin_unlock_irqrestore(&private->lock,flags);	/* TODO: send 2 dummy packets here */		trigger_receive(private);		leave();	return 0;}/* xircom_remove is called on module-unload or on device-eject. it unregisters the irq, io-region and network device. Interrupts and such are already stopped in the "ifconfig ethX down" code. */static void __devexit xircom_remove(struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	struct xircom_private *card;	enter();		card=dev->priv;	if (card->rx_buffer!=NULL)		pci_free_consistent(pdev,RXTXBUFSIZE,card->rx_buffer,card->rx_dma_handle);	card->rx_buffer = NULL;	card->rx_desc = NULL;	if (card->tx_buffer!=NULL)		pci_free_consistent(pdev,RXTXBUFSIZE,card->tx_buffer,card->tx_dma_handle);	card->tx_buffer = NULL;				card->tx_desc = NULL;	release_region(dev->base_addr, 128);	unregister_netdev(dev);	kfree(dev);	pci_set_drvdata(pdev,NULL);	leave();} static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs){	struct net_device *dev = dev_instance;	struct xircom_private *card = dev->priv;	u32 status;	unsigned int xmit_free_count;	unsigned int i;	enter();	spin_lock(&card->lock);	status = inl(card->io_port+CSR5);	if (status==0xffffffff) {/* card has been ejected / powered down */		spin_unlock(&card->lock);		return;	}	/* Todo: check if there were any events at all; to speed up	   returning if we're on a shared interrupt */		if (link_status_changed(card)) {		int newlink;		printk(KERN_DEBUG "xircom_cb: Link status has changed \n");		newlink = link_status(card);		if (newlink) {			printk(KERN_INFO  "xircom_cb: Link is %i mbit \n",newlink);			netif_carrier_on(dev);		} else {			printk(KERN_INFO  "xircom_cb: Link is absent \n");			netif_carrier_off(dev);		}	}	/* Clear all remaining interrupt events */		status |= 0xffffffff; /* FIXME: make this clear only the				        real existing bits */	outl(status,card->io_port+CSR5);		xmit_free_count = 0;	for (i=0;i<NUMDESCRIPTORS;i++) 		xmit_free_count += investigate_tx_descriptor(dev,card,i,bufferoffsets[i]);	for (i=0;i<NUMDESCRIPTORS;i++) 		investigate_rx_descriptor(dev,card,i,bufferoffsets[i]);		if (xmit_free_count)		netif_start_queue(dev);			spin_unlock(&card->lock);	leave();}static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev){	struct xircom_private *card;	unsigned long flags;	unsigned int nextdescriptor;	unsigned int desc;	enter();		card = (struct xircom_private*)dev->priv;	spin_lock_irqsave(&card->lock,flags);		nextdescriptor = (card->transmit_used +1) % (NUMDESCRIPTORS);	desc = card->transmit_used;		/* only send the packet if the descriptor is free */	if (card->tx_desc[desc].status==0) {			/* Copy the packet data; zero the memory first as the card			   sometimes sends more than you ask it to. */						memset(&card->tx_buffer[bufferoffsets[desc]],0,MAX_PACKETSIZE);			memcpy(&(card->tx_buffer[bufferoffsets[desc]]),skb->data,skb->len);					/* FIXME: The specification tells us that the length we send HAS to be a multiple of			   4 bytes. */			   			card->tx_desc[desc].control = skb->len;			if (desc == NUMDESCRIPTORS-1)				card->tx_desc[desc].control |= LastDescBit;  /* bit 25: last descriptor of the ring */			card->tx_desc[desc].control |= 0xF0000000;						 /* 0xF0... means want interrupts*/ 			card->tx_skb[desc] = skb;						wmb();			/* This gives the descriptor to the card */			card->tx_desc[desc].status = DescOwnedCard;			trigger_transmit(card);			if (((int)card->tx_desc[nextdescriptor].status)<0) {	/* next descriptor is occupied... */				netif_stop_queue(dev);			}			card->transmit_used = nextdescriptor;			spin_unlock_irqrestore(&card->lock,flags);			leave();			return 0;	}		/* Uh oh... no free descriptor... drop the packet */	/* This should not happen in theory...*/	netif_stop_queue(dev);	spin_unlock_irqrestore(&card->lock,flags);	trigger_transmit(card);	leave();		return -EIO;}static int xircom_open(struct net_device *dev){	struct xircom_private *xp = (struct xircom_private *) dev->priv;	int retval;	enter();	printk(KERN_INFO "Xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq);	retval = request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev);	if (retval) {		printk(KERN_ERR "xircom_cb: Unable to aquire IRQ %i, aborting.\n",dev->irq);		leave();		return retval;

⌨️ 快捷键说明

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