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

📄 depca.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    } pktStats;    int txRingMask;                /* TX ring mask                           */    int rxRingMask;                /* RX ring mask                           */    s32 rx_rlen;                   /* log2(rxRingMask+1) for the descriptors */    s32 tx_rlen;                   /* log2(txRingMask+1) for the descriptors */};/*** The transmit ring full condition is described by the tx_old and tx_new** pointers by:**    tx_old            = tx_new    Empty ring**    tx_old            = tx_new+1  Full ring**    tx_old+txRingMask = tx_new    Full ring  (wrapped condition)*/#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\			 lp->tx_old+lp->txRingMask-lp->tx_new:\                         lp->tx_old               -lp->tx_new-1)/*** Public Functions*/static int    depca_open(struct net_device *dev);static int    depca_start_xmit(struct sk_buff *skb, struct net_device *dev);static void   depca_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int    depca_close(struct net_device *dev);static int    depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static void   depca_tx_timeout (struct net_device *dev);static struct net_device_stats *depca_get_stats(struct net_device *dev);static void   set_multicast_list(struct net_device *dev);/*** Private functions*/static int    depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot);static void   depca_init_ring(struct net_device *dev);static int    depca_rx(struct net_device *dev);static int    depca_tx(struct net_device *dev);static void   LoadCSRs(struct net_device *dev);static int    InitRestartDepca(struct net_device *dev);static void   DepcaSignature(char *name, u_long paddr);static int    DevicePresent(u_long ioaddr);static int    get_hw_addr(struct net_device *dev);static int    EISA_signature(char *name, s32 eisa_id);static void   SetMulticastFilter(struct net_device *dev);static void   isa_probe(struct net_device *dev, u_long iobase);static void   eisa_probe(struct net_device *dev, u_long iobase);#ifdef CONFIG_MCA      static void   mca_probe(struct net_device *dev, u_long iobase);#endifstatic struct net_device *alloc_device(struct net_device *dev, u_long iobase);static int    depca_dev_index(char *s);static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *));static int    load_packet(struct net_device *dev, struct sk_buff *skb);static void   depca_dbg_open(struct net_device *dev);#ifdef MODULEint           init_module(void);void          cleanup_module(void);static int    autoprobed = 1, loading_module = 1;# elsestatic u_char de1xx_irq[] __initdata = {2,3,4,5,7,9,0};static u_char de2xx_irq[] __initdata = {5,9,10,11,15,0};static u_char de422_irq[] __initdata = {5,9,10,11,0};static u_char *depca_irq;static int    autoprobed, loading_module;#endif /* MODULE */static char   name[DEPCA_STRLEN];static int    num_depcas, num_eth;static int    mem;                       /* For loadable module assignment                                              use insmod mem=0x????? .... */static char   *adapter_name = '\0';        /* If no PROM when loadable module					      use insmod adapter_name=DE??? ...					   *//*** Miscellaneous defines...*/#define STOP_DEPCA \    outw(CSR0, DEPCA_ADDR);\    outw(STOP, DEPCA_DATA)int __init depca_probe(struct net_device *dev){  int tmp = num_depcas, status = -ENODEV;  u_long iobase = dev->base_addr;  if ((iobase == 0) && loading_module){    printk("Autoprobing is not supported when loading a module based driver.\n");    status = -EIO;  } else {#ifdef CONFIG_MCA          mca_probe(dev, iobase);#endif    isa_probe(dev, iobase);    eisa_probe(dev, iobase);    if ((tmp == num_depcas) && (iobase != 0) && loading_module) {      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name, 	                                                               iobase);    }    /*    ** Walk the device list to check that at least one device    ** initialised OK    */    for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);    if (dev->priv) status = 0;    if (iobase == 0) autoprobed = 1;  }  return status;}static int __init depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot){	struct depca_private *lp;	int i, j, offset, netRAM, mem_len, status=0;	s16 nicsr;	u_long mem_start=0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;	STOP_DEPCA;	nicsr = inb(DEPCA_NICSR);	nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);	outb(nicsr, DEPCA_NICSR);	if (inw(DEPCA_DATA) != STOP) {		return -ENXIO;	}	do {		strcpy(name, (adapter_name ? adapter_name : ""));		mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);		DepcaSignature(name, mem_start);	} while (!mem && mem_base[mem_chkd] && (adapter == unknown));	if ((adapter == unknown) || !mem_start) { /* DEPCA device not found */		return -ENXIO;	}	dev->base_addr = ioaddr;	if (mca_slot != -1) {		printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name, 		                                          ioaddr, mca_slot);	} else if ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS) { /* EISA slot address */		printk("%s: %s at 0x%04lx (EISA slot %d)", 		       dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f));	} else {                             /* ISA port address */		printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);	}	printk(", h/w address ");	status = get_hw_addr(dev);	for (i=0; i<ETH_ALEN - 1; i++) { /* get the ethernet address */		printk("%2.2x:", dev->dev_addr[i]);	}	printk("%2.2x", dev->dev_addr[i]);	if (status != 0) {		printk("      which has an Ethernet PROM CRC error.\n");		return -ENXIO;	}	/* Set up the maximum amount of network RAM(kB) */	netRAM = ((adapter != DEPCA) ? 64 : 48);	if ((nicsr & _128KB) && (adapter == de422))		netRAM = 128;	offset = 0x0000;	/* Shared Memory Base Address */ 	if (nicsr & BUF) {		offset = 0x8000;        /* 32kbyte RAM offset*/		nicsr &= ~BS;           /* DEPCA RAM in top 32k */		netRAM -= 32;	}	mem_start += offset;            /* (E)ISA start address */	if ((mem_len = (NUM_RX_DESC*(sizeof(struct depca_rx_desc)+RX_BUFF_SZ) +			NUM_TX_DESC*(sizeof(struct depca_tx_desc)+TX_BUFF_SZ) +			sizeof(struct depca_init)))	    > (netRAM<<10)) {		printk(",\n       requests %dkB RAM: only %dkB is available!\n",		        (mem_len >> 10), netRAM);		return -ENXIO;	}	printk(",\n      has %dkB RAM at 0x%.5lx", netRAM, mem_start);	/* Enable the shadow RAM. */	if (adapter != DEPCA) {		nicsr |= SHE;		outb(nicsr, DEPCA_NICSR);	} 	/* Define the device private memory */	dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);	if (dev->priv == NULL)		return -ENOMEM;	lp = (struct depca_private *)dev->priv;	memset((char *)dev->priv, 0, sizeof(struct depca_private));	lp->adapter = adapter;	lp->mca_slot = mca_slot;	lp->lock = SPIN_LOCK_UNLOCKED; 	sprintf(lp->adapter_name,"%s (%s)", name, dev->name);	if (!request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name)) {		printk(KERN_ERR "depca: I/O resource 0x%x @ 0x%lx busy\n",		       DEPCA_TOTAL_SIZE, ioaddr);		return -EBUSY;	}	/* Initialisation Block */	lp->sh_mem = ioremap(mem_start, mem_len);	if (lp->sh_mem == NULL) {		printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n");		return -EIO;	}	lp->device_ram_start = mem_start & LA_MASK;		offset = 0;	offset += sizeof(struct depca_init);	/* Tx & Rx descriptors (aligned to a quadword boundary) */	offset = (offset + ALIGN) & ~ALIGN;	lp->rx_ring = (struct depca_rx_desc *)(lp->sh_mem + offset);	lp->rx_ring_offset = offset;	offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);	lp->tx_ring = (struct depca_tx_desc *)(lp->sh_mem + offset);	lp->tx_ring_offset = offset;	offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);	lp->buffs_offset = offset;	/* Finish initialising the ring information. */	lp->rxRingMask = NUM_RX_DESC - 1;	lp->txRingMask = NUM_TX_DESC - 1;	/* Calculate Tx/Rx RLEN size for the descriptors. */	for (i=0, j = lp->rxRingMask; j>0; i++) {		j >>= 1;	}	lp->rx_rlen = (s32)(i << 29);	for (i=0, j = lp->txRingMask; j>0; i++) {		j >>= 1;	}	lp->tx_rlen = (s32)(i << 29);	/* Load the initialisation block */	depca_init_ring(dev);	/* Initialise the control and status registers */	LoadCSRs(dev);	/* Enable DEPCA board interrupts for autoprobing */	nicsr = ((nicsr & ~IM)|IEN);	outb(nicsr, DEPCA_NICSR);	/* To auto-IRQ we enable the initialization-done and DMA err,	   interrupts. For now we will always get a DMA error. */	if (dev->irq < 2) {#ifndef MODULE		unsigned char irqnum;		autoirq_setup(0);		/* Assign the correct irq list */		switch (lp->adapter) {		case DEPCA:		case de100:		case de101:			depca_irq = de1xx_irq;			break;		case de200:		case de201:		case de202:		case de210:		case de212:			depca_irq = de2xx_irq;			break;		case de422:			depca_irq = de422_irq;			break;		}		/* Trigger an initialization just for the interrupt. */		outw(INEA | INIT, DEPCA_DATA);	  		irqnum = autoirq_report(1);		if (!irqnum) {			printk(" and failed to detect IRQ line.\n");			status = -ENXIO;		} else {			for (dev->irq=0,i=0; (depca_irq[i]) && (!dev->irq); i++) {				if (irqnum == depca_irq[i]) {					dev->irq = irqnum;					printk(" and uses IRQ%d.\n", dev->irq);				}			}	      			if (!dev->irq) {				printk(" but incorrect IRQ line detected.\n");				status = -ENXIO;			}		}#endif /* MODULE */	} else {		printk(" and assigned IRQ%d.\n", dev->irq);	}	if (!status) {		if (depca_debug > 1) {			printk(version);		}		/* The DEPCA-specific entries in the device structure. */		dev->open = &depca_open;		dev->hard_start_xmit = &depca_start_xmit;		dev->stop = &depca_close;		dev->get_stats = &depca_get_stats;		dev->set_multicast_list = &set_multicast_list;		dev->do_ioctl = &depca_ioctl;		dev->tx_timeout = depca_tx_timeout;		dev->watchdog_timeo = TX_TIMEOUT;		dev->mem_start = 0;		/* Fill in the generic field of the device structure. */		ether_setup(dev);	} else {          /* Incorrectly initialised hardware */		release_region(ioaddr, DEPCA_TOTAL_SIZE);		if (dev->priv) {			kfree(dev->priv);			dev->priv = NULL;		}	}	return status;}static intdepca_open(struct net_device *dev){  struct depca_private *lp = (struct depca_private *)dev->priv;  u_long ioaddr = dev->base_addr;  s16 nicsr;  int status = 0;  STOP_DEPCA;  nicsr = inb(DEPCA_NICSR);  /* Make sure the shadow RAM is enabled */  if (lp->adapter != DEPCA) {    nicsr |= SHE;    outb(nicsr, DEPCA_NICSR);  }  /* Re-initialize the DEPCA... */  depca_init_ring(dev);  LoadCSRs(dev);  depca_dbg_open(dev);  if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, dev)) {    printk("depca_open(): Requested IRQ%d is busy\n",dev->irq);    status = -EAGAIN;  } else {    /* Enable DEPCA board interrupts and turn off LED */    nicsr = ((nicsr & ~IM & ~LED)|IEN);    outb(nicsr, DEPCA_NICSR);    outw(CSR0,DEPCA_ADDR);        netif_start_queue(dev);        status = InitRestartDepca(dev);    if (depca_debug > 1){      printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));      printk("nicsr: 0x%02x\n",inb(DEPCA_NICSR));    }  }  MOD_INC_USE_COUNT;    return status;}/* Initialize the lance Rx and Tx descriptor rings. */static voiddepca_init_ring(struct net_device *dev){	struct depca_private *lp = (struct depca_private *)dev->priv;	u_int i;	u_long offset;	/* Lock out other processes whilst setting up the hardware */	netif_stop_queue(dev);	lp->rx_new = lp->tx_new = 0;	lp->rx_old = lp->tx_old = 0;	/* Initialize the base address and length of each buffer in the ring */	for (i = 0; i <= lp->rxRingMask; i++) {		offset = lp->buffs_offset + i*RX_BUFF_SZ;		writel((lp->device_ram_start + offset) | R_OWN,

⌨️ 快捷键说明

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