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

📄 nicstar.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
      error = ns_init_card(i, pcidev);      if (error)         cards[i--] = NULL;	/* Try to find another card but don't increment index */   }   if (i == 0 && error)      return -EIO;   TXPRINTK("nicstar: TX debug enabled.\n");   RXPRINTK("nicstar: RX debug enabled.\n");   PRINTK("nicstar: General debug enabled.\n");#ifdef PHY_LOOPBACK   printk("nicstar: using PHY loopback.\n");#endif /* PHY_LOOPBACK */   XPRINTK("nicstar: init_module() returned.\n");   init_timer(&ns_timer);   ns_timer.expires = jiffies + NS_POLL_PERIOD;   ns_timer.data = 0UL;   ns_timer.function = ns_poll;   add_timer(&ns_timer);   return i;}#endif /* MODULE */static u32 ns_read_sram(ns_dev *card, u32 sram_address){   unsigned long flags;   u32 data;   sram_address <<= 2;   sram_address &= 0x0007FFFC;	/* address must be dword aligned */   sram_address |= 0x50000000;	/* SRAM read command */   ns_grab_res_lock(card, flags);   while (CMD_BUSY(card));   writel(sram_address, card->membase + CMD);   while (CMD_BUSY(card));   data = readl(card->membase + DR0);   spin_unlock_irqrestore(&card->res_lock, flags);   return data;}   static void ns_write_sram(ns_dev *card, u32 sram_address, u32 *value, int count){   unsigned long flags;   int i, c;   count--;	/* count range now is 0..3 instead of 1..4 */   c = count;   c <<= 2;	/* to use increments of 4 */   ns_grab_res_lock(card, flags);   while (CMD_BUSY(card));   for (i = 0; i <= c; i += 4)      writel(*(value++), card->membase + i);   /* Note: DR# registers are the first 4 dwords in nicstar's memspace,            so card->membase + DR0 == card->membase */   sram_address <<= 2;   sram_address &= 0x0007FFFC;   sram_address |= (0x40000000 | count);   writel(sram_address, card->membase + CMD);   spin_unlock_irqrestore(&card->res_lock, flags);}static int __init ns_init_card(int i, struct pci_dev *pcidev){   int j;   struct ns_dev *card = NULL;   unsigned short pci_command;   unsigned char pci_latency;   unsigned error;   u32 data;   u32 u32d[4];   u32 ns_cfg_rctsize;   int bcount;   error = 0;   if (pci_enable_device(pcidev))   {      printk("nicstar%d: can't enable PCI device\n", i);      error = 2;      ns_init_card_error(card, error);      return error;   }   if ((card = kmalloc(sizeof(ns_dev), GFP_KERNEL)) == NULL)   {      printk("nicstar%d: can't allocate memory for device structure.\n", i);      error = 2;      ns_init_card_error(card, error);      return error;   }   cards[i] = card;   spin_lock_init(&card->int_lock);   spin_lock_init(&card->res_lock);         card->index = i;   card->atmdev = NULL;   card->pcidev = pcidev;   card->membase = pci_resource_start(pcidev, 1);#ifdef __powerpc__   /* Compensate for different memory map between host CPU and PCI bus.      Shouldn't we use a macro for this? */   card->membase += KERNELBASE;#endif /* __powerpc__ */   card->membase = (unsigned long) ioremap(card->membase, NS_IOREMAP_SIZE);   if (card->membase == 0)   {      printk("nicstar%d: can't ioremap() membase.\n",i);      error = 3;      ns_init_card_error(card, error);      return error;   }   PRINTK("nicstar%d: membase at 0x%x.\n", i, card->membase);   if (pci_read_config_word(pcidev, PCI_COMMAND, &pci_command) != 0)   {      printk("nicstar%d: can't read PCI_COMMAND.\n", i);      error = 4;      ns_init_card_error(card, error);      return error;   }   pci_command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);   if (pci_write_config_word(pcidev, PCI_COMMAND, pci_command) != 0)   {      printk("nicstar%d: can't write PCI_COMMAND.\n", i);      error = 5;      ns_init_card_error(card, error);      return error;   }   if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0)   {      printk("nicstar%d: can't read PCI latency timer.\n", i);      error = 6;      ns_init_card_error(card, error);      return error;   }#ifdef NS_PCI_LATENCY   if (pci_latency < NS_PCI_LATENCY)   {      PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i, NS_PCI_LATENCY);      for (j = 1; j < 4; j++)      {         if (pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0)	    break;      }      if (j == 4)      {         printk("nicstar%d: can't set PCI latency timer to %d.\n", i, NS_PCI_LATENCY);         error = 7;         ns_init_card_error(card, error);	 return error;      }   }#endif /* NS_PCI_LATENCY */         /* Clear timer overflow */   data = readl(card->membase + STAT);   if (data & NS_STAT_TMROF)      writel(NS_STAT_TMROF, card->membase + STAT);   /* Software reset */   writel(NS_CFG_SWRST, card->membase + CFG);   NS_DELAY;   writel(0x00000000, card->membase + CFG);   /* PHY reset */   writel(0x00000008, card->membase + GP);   NS_DELAY;   writel(0x00000001, card->membase + GP);   NS_DELAY;   while (CMD_BUSY(card));   writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD);	/* Sync UTOPIA with SAR clock */   NS_DELAY;         /* Detect PHY type */   while (CMD_BUSY(card));   writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD);   while (CMD_BUSY(card));   data = readl(card->membase + DR0);   switch(data) {      case 0x00000009:         printk("nicstar%d: PHY seems to be 25 Mbps.\n", i);         card->max_pcr = ATM_25_PCR;         while(CMD_BUSY(card));         writel(0x00000008, card->membase + DR0);         writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD);         /* Clear an eventual pending interrupt */         writel(NS_STAT_SFBQF, card->membase + STAT);#ifdef PHY_LOOPBACK         while(CMD_BUSY(card));         writel(0x00000022, card->membase + DR0);         writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD);#endif /* PHY_LOOPBACK */	 break;      case 0x00000030:      case 0x00000031:         printk("nicstar%d: PHY seems to be 155 Mbps.\n", i);         card->max_pcr = ATM_OC3_PCR;#ifdef PHY_LOOPBACK         while(CMD_BUSY(card));         writel(0x00000002, card->membase + DR0);         writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD);#endif /* PHY_LOOPBACK */	 break;      default:         printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data);         error = 8;         ns_init_card_error(card, error);         return error;   }   writel(0x00000000, card->membase + GP);   /* Determine SRAM size */   data = 0x76543210;   ns_write_sram(card, 0x1C003, &data, 1);   data = 0x89ABCDEF;   ns_write_sram(card, 0x14003, &data, 1);   if (ns_read_sram(card, 0x14003) == 0x89ABCDEF &&       ns_read_sram(card, 0x1C003) == 0x76543210)       card->sram_size = 128;   else      card->sram_size = 32;   PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size);   card->rct_size = NS_MAX_RCTSIZE;#if (NS_MAX_RCTSIZE == 4096)   if (card->sram_size == 128)      printk("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n", i);#elif (NS_MAX_RCTSIZE == 16384)   if (card->sram_size == 32)   {      printk("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n", i);      card->rct_size = 4096;   }#else#error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c#endif   card->vpibits = NS_VPIBITS;   if (card->rct_size == 4096)      card->vcibits = 12 - NS_VPIBITS;   else /* card->rct_size == 16384 */      card->vcibits = 14 - NS_VPIBITS;   /* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */   if (mac[i] == NULL)      nicstar_init_eprom(card->membase);   if (request_irq(pcidev->irq, &ns_irq_handler, SA_INTERRUPT | SA_SHIRQ, "nicstar", card) != 0)   {      printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);      error = 9;      ns_init_card_error(card, error);      return error;   }   /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */   writel(0x00000000, card->membase + VPM);         /* Initialize TSQ */   card->tsq.org = kmalloc(NS_TSQSIZE + NS_TSQ_ALIGNMENT, GFP_KERNEL);   if (card->tsq.org == NULL)   {      printk("nicstar%d: can't allocate TSQ.\n", i);      error = 10;      ns_init_card_error(card, error);      return error;   }   card->tsq.base = (ns_tsi *) ALIGN_ADDRESS(card->tsq.org, NS_TSQ_ALIGNMENT);   card->tsq.next = card->tsq.base;   card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1);   for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++)      ns_tsi_init(card->tsq.base + j);   writel(0x00000000, card->membase + TSQH);   writel((u32) virt_to_bus(card->tsq.base), card->membase + TSQB);   PRINTK("nicstar%d: TSQ base at 0x%x  0x%x  0x%x.\n", i, (u32) card->tsq.base,          (u32) virt_to_bus(card->tsq.base), readl(card->membase + TSQB));         /* Initialize RSQ */   card->rsq.org = kmalloc(NS_RSQSIZE + NS_RSQ_ALIGNMENT, GFP_KERNEL);   if (card->rsq.org == NULL)   {      printk("nicstar%d: can't allocate RSQ.\n", i);      error = 11;      ns_init_card_error(card, error);      return error;   }   card->rsq.base = (ns_rsqe *) ALIGN_ADDRESS(card->rsq.org, NS_RSQ_ALIGNMENT);   card->rsq.next = card->rsq.base;   card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1);   for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++)      ns_rsqe_init(card->rsq.base + j);   writel(0x00000000, card->membase + RSQH);   writel((u32) virt_to_bus(card->rsq.base), card->membase + RSQB);   PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base);         /* Initialize SCQ0, the only VBR SCQ used */   card->scq1 = (scq_info *) NULL;   card->scq2 = (scq_info *) NULL;   card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0);   if (card->scq0 == (scq_info *) NULL)   {      printk("nicstar%d: can't get SCQ0.\n", i);      error = 12;      ns_init_card_error(card, error);      return error;   }   u32d[0] = (u32) virt_to_bus(card->scq0->base);   u32d[1] = (u32) 0x00000000;   u32d[2] = (u32) 0xffffffff;   u32d[3] = (u32) 0x00000000;   ns_write_sram(card, NS_VRSCD0, u32d, 4);   ns_write_sram(card, NS_VRSCD1, u32d, 4);	/* These last two won't be used */   ns_write_sram(card, NS_VRSCD2, u32d, 4);	/* but are initialized, just in case... */   card->scq0->scd = NS_VRSCD0;   PRINTK("nicstar%d: VBR-SCQ0 base at 0x%x.\n", i, (u32) card->scq0->base);   /* Initialize TSTs */   card->tst_addr = NS_TST0;   card->tst_free_entries = NS_TST_NUM_ENTRIES;   data = NS_TST_OPCODE_VARIABLE;   for (j = 0; j < NS_TST_NUM_ENTRIES; j++)      ns_write_sram(card, NS_TST0 + j, &data, 1);   data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0);   ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1);   for (j = 0; j < NS_TST_NUM_ENTRIES; j++)      ns_write_sram(card, NS_TST1 + j, &data, 1);   data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1);   ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1);   for (j = 0; j < NS_TST_NUM_ENTRIES; j++)      card->tste2vc[j] = NULL;   writel(NS_TST0 << 2, card->membase + TSTB);   /* Initialize RCT. AAL type is set on opening the VC. */#ifdef RCQ_SUPPORT   u32d[0] = NS_RCTE_RAWCELLINTEN;#else   u32d[0] = 0x00000000;#endif /* RCQ_SUPPORT */   u32d[1] = 0x00000000;   u32d[2] = 0x00000000;   u32d[3] = 0xFFFFFFFF;   for (j = 0; j < card->rct_size; j++)      ns_write_sram(card, j * 4, u32d, 4);               memset(card->vcmap, 0, NS_MAX_RCTSIZE * sizeof(vc_map));         for (j = 0; j < NS_FRSCD_NUM; j++)      card->scd2vc[j] = NULL;   /* Initialize buffer levels */   card->sbnr.min = MIN_SB;   card->sbnr.init = NUM_SB;   card->sbnr.max = MAX_SB;   card->lbnr.min = MIN_LB;   card->lbnr.init = NUM_LB;   card->lbnr.max = MAX_LB;   card->iovnr.min = MIN_IOVB;   card->iovnr.init = NUM_IOVB;   card->iovnr.max = MAX_IOVB;   card->hbnr.min = MIN_HB;   card->hbnr.init = NUM_HB;   card->hbnr.max = MAX_HB;      card->sm_handle = 0x00000000;   card->sm_addr = 0x00000000;   card->lg_handle = 0x00000000;   card->lg_addr = 0x00000000;      card->efbie = 1;	/* To prevent push_rxbufs from enabling the interrupt */   /* Pre-allocate some huge buffers */   skb_queue_head_init(&card->hbpool.queue);   card->hbpool.count = 0;   for (j = 0; j < NUM_HB; j++)   {      struct sk_buff *hb;      hb = alloc_skb(NS_HBUFSIZE, GFP_KERNEL);      if (hb == NULL)      {         printk("nicstar%d: can't allocate %dth of %d huge buffers.\n",                i, j, NUM_HB);         error = 13;         ns_init_card_error(card, error);	 return error;      }      skb_queue_tail(&card->hbpool.queue, hb);      card->hbpool.count++;   }   /* Allocate large buffers */   skb_queue_head_init(&card->lbpool.queue);   card->lbpool.count = 0;			/* Not used */   for (j = 0; j < NUM_LB; j++)   {      struct sk_buff *lb;      lb = alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);      if (lb == NULL)      {         printk("nicstar%d: can't allocate %dth of %d large buffers.\n",                i, j, NUM_LB);         error = 14;         ns_init_card_error(card, error);	 return error;      }      skb_queue_tail(&card->lbpool.queue, lb);      skb_reserve(lb, NS_SMBUFSIZE);      push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);      /* Due to the implementation of push_rxbufs() this is 1, not 0 */      if (j == 1)      {         card->rcbuf = lb;         card->rawch = (u32) virt_to_bus(lb->data);      }   }   /* Test for strange behaviour which leads to crashes */   if ((bcount = ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min)   {      printk("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n",             i, j, bcount);      error = 14;      ns_init_card_error(card, error);      return error;   }         /* Allocate small buffers */   skb_queue_head_init(&card->sbpool.queue);   card->sbpool.count = 0;			/* Not used */   for (j = 0; j < NUM_SB; j++)   {      struct sk_buff *sb;      sb = alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);      if (sb == NULL)      {         printk("nicstar%d: can't allocate %dth of %d small buffers.\n",

⌨️ 快捷键说明

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