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

📄 depca.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
**    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 device *dev);static int    depca_start_xmit(struct sk_buff *skb, struct device *dev);static void   depca_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int    depca_close(struct device *dev);static int    depca_ioctl(struct device *dev, struct ifreq *rq, int cmd);static struct net_device_stats *depca_get_stats(struct device *dev);static void   set_multicast_list(struct device *dev);/*** Private functions*/static int    depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot);static void   depca_init_ring(struct device *dev);static int    depca_rx(struct device *dev);static int    depca_tx(struct device *dev);static void   LoadCSRs(struct device *dev);static int    InitRestartDepca(struct device *dev);static void   DepcaSignature(char *name, u_long paddr);static int    DevicePresent(u_long ioaddr);static int    get_hw_addr(struct device *dev);static int    EISA_signature(char *name, s32 eisa_id);static void   SetMulticastFilter(struct device *dev);static void   isa_probe(struct device *dev, u_long iobase);static void   eisa_probe(struct device *dev, u_long iobase);#ifdef CONFIG_MCA      static void   mca_probe(struct device *dev, u_long iobase);#endifstatic struct device *alloc_device(struct device *dev, u_long iobase);static int    depca_dev_index(char *s);static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *));static int    load_packet(struct device *dev, struct sk_buff *skb);static void   depca_dbg_open(struct 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 = 0, loading_module = 0;#endif /* MODULE */static char   name[DEPCA_STRLEN];static int    num_depcas = 0, num_eth = 0;static int    mem=0;                       /* 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)__initfunc(intdepca_probe(struct 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;}__initfunc(static intdepca_hw_init(struct 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) {    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) {        /* found a DEPCA device */      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) {	/* 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      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; 	  sprintf(lp->adapter_name,"%s (%s)", name, dev->name);	  request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name);	  /* Initialisation Block */	  lp->sh_mem = mem_start;	  mem_start += sizeof(struct depca_init);	  /* Tx & Rx descriptors (aligned to a quadword boundary) */	  mem_start = (mem_start + ALIGN) & ~ALIGN;	  lp->rx_ring = (struct depca_rx_desc *)mem_start;	  mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);	  lp->tx_ring = (struct depca_tx_desc *)mem_start;	  mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);	  lp->bus_offset = mem_start & 0x00ff0000;	  mem_start &= LA_MASK;           /* LANCE re-mapped start address */	  lp->dma_buffs = mem_start;	  /* 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) release_region(ioaddr, DEPCA_TOTAL_SIZE);	} else {	  printk(",\n      requests %dkB RAM: only %dkB is available!\n", 	         	                                (mem_len>>10), netRAM);	  status = -ENXIO;	}      } else {	printk("      which has an Ethernet PROM CRC error.\n");	status = -ENXIO;      }    } else {      status = -ENXIO;    }    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->mem_start = 0;	      /* Fill in the generic field of the device structure. */      ether_setup(dev);    } else {                           /* Incorrectly initialised hardware */      if (dev->priv) {	kfree_s(dev->priv, sizeof(struct depca_private));	dev->priv = NULL;      }    }  } else {    status = -ENXIO;  }  return status;}static intdepca_open(struct 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 (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);        dev->tbusy = 0;                             dev->interrupt = 0;    dev->start = 1;        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 device *dev){  struct depca_private *lp = (struct depca_private *)dev->priv;  u_int i;  u_long p;  /* Lock out other processes whilst setting up the hardware */  test_and_set_bit(0, (void *)&dev->tbusy);  lp->rx_new = lp->tx_new = 0;  lp->rx_old = lp->tx_old = 0;  /* Initialize the base addresses and length of each buffer in the ring */  for (i = 0; i <= lp->rxRingMask; i++) {    writel((p=lp->dma_buffs+i*RX_BUFF_SZ) | R_OWN, &lp->rx_ring[i].base);    writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);    lp->rx_memcpy[i]=(char *)(p+lp->bus_offset);  }  for (i = 0; i <= lp->txRingMask; i++) {    writel((p=lp->dma_buffs+(i+lp->txRingMask+1)*TX_BUFF_SZ) & 0x00ffffff,	                                                 &lp->tx_ring[i].base);    lp->tx_memcpy[i]=(char *)(p+lp->bus_offset);  }  /* Set up the initialization block */  lp->init_block.rx_ring = ((u32)((u_long)lp->rx_ring)&LA_MASK) | lp->rx_rlen;  lp->init_block.tx_ring = ((u32)((u_long)lp->tx_ring)&LA_MASK) | lp->tx_rlen;  SetMulticastFilter(dev);  for (i = 0; i < ETH_ALEN; i++) {    lp->init_block.phys_addr[i] = dev->dev_addr[i];  }

⌨️ 快捷键说明

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