ne.c
来自「移植网卡驱动时有用: uboot-1.1.4 中的rtl8019驱动: 分别」· C语言 代码 · 共 1,013 行 · 第 1/3 页
C
1,013 行
while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) if (jiffies - reset_start_time > 2*HZ/100) { if (bad_card) { printk(" (warning: no reset ack)"); break; } else { printk(" not found (no reset ack).\n"); ret = -ENODEV; goto err_out; } } outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ } /* Read the 16 bytes of station address PROM. We must first initialize registers, similar to NS8390_init(eifdev, 0). We can't reliably read the SAPROM address without this. (I learned the hard way!). */ { struct {unsigned char value, offset; } program_seq[] = { {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ {0x00, EN0_RCNTLO}, /* Clear the count regs. */ {0x00, EN0_RCNTHI}, {0x00, EN0_IMR}, /* Mask completion irq. */ {0xFF, EN0_ISR}, {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ {32, EN0_RCNTLO}, {0x00, EN0_RCNTHI}, {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ {0x00, EN0_RSARHI}, {E8390_RREAD+E8390_START, E8390_CMD}, }; for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); } for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { SA_prom[i] = inb(ioaddr + NE_DATAPORT); SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);// printk("%p=%x,%x\n", ioaddr + NE_DATAPORT, SA_prom[i], SA_prom[i+1]); if (SA_prom[i] != SA_prom[i+1]) wordlength = 1; }#if defined(CONFIG_M5307) || defined(CONFIG_M5407) { outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); for(i = 0; i < 6; i++) { SA_prom[i] = inb(ioaddr + i + 1); } SA_prom[14] = SA_prom[15] = 0x57; }#endif /* CONFIG_M5307 || CONFIG_M5407 */#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) { unsigned char *ep; static int nr = 0; ep = (unsigned char *) (0xf0006000 + (nr++ * 6)); /* * MAC address should be in FLASH, check that it is valid. * If good use it, otherwise use the default. */ if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) && (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) || ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) && (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) { ep = (unsigned char *) &ne_defethaddr[0]; ne_defethaddr[5]++; } for(i = 0; i < 6; i++) SA_prom[i] = ep[i]; SA_prom[14] = SA_prom[15] = 0x57;#if 0 { unsigned char val; /* * Set ethernet interface to be AUI. */ val = inb_p(ioaddr + EN0_RCNTHI); outb_p(0x01 , (ioaddr + EN0_RCNTHI)); }#endif#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) wordlength = 1; /* We must set the 8390 for 8bit mode. */ outb_p(0x48, ioaddr + EN0_DCFG);#endif start_page = NESM_START_PG; stop_page = NESM_STOP_PG; }#elif defined(CONFIG_CFV240) { unsigned char *ep = (unsigned char *) 0xffc0406b; /* * MAC address should be in FLASH, check that it is valid. * If good use it, otherwise use the default. */ if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) && (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) || ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) && (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) { ep = (unsigned char *) &ne_defethaddr[0]; ne_defethaddr[5]++; } outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); for(i = 0; i < 6; i++) SA_prom[i] = ep[i]; SA_prom[14] = SA_prom[15] = 0x57; }#elif defined(CONFIG_M5206e) { outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); for(i = 0; i < 6; i++) { SA_prom[i] = inb(ioaddr + i + 1); } SA_prom[14] = SA_prom[15] = 0x57; }#elif defined(CONFIG_BOARD_MBA44) { unsigned char ne_defethaddr[6] = {0x00, 0x80, 0x49, 0x12, 0x34, 0x56};// ne_defethaddr[5]++; printk("NE2000 driver modified by http://www.21spacetime.net\n"); outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); for(i = 0; i < 6; i++) { SA_prom[i] = ne_defethaddr[i]; } SA_prom[14] = SA_prom[15] = 0x57; #if (ETH_ADDR_SFT==0) wordlength = 1; /* We must set the 8390 for 8bit mode. */ outb_p(0x48, ioaddr + EN0_DCFG); #else wordlength = 2; /* We must set the 8390 for 16bit mode. */ outb_p(0x49, ioaddr + EN0_DCFG); //test---------------------------- printk("wordlength = 2\n"); //test---------------------------- #endif }#endif /* CONFIG_BOARD_MBA44 */#if !(defined(CONFIG_M5206e) && defined(CONFIG_NETtel)) if (wordlength == 2) { #ifndef CONFIG_COLDFIRE for (i = 0; i < 16; i++) SA_prom[i] = SA_prom[i+i]; //test---------------------------- printk("SA_prom[0]=%x,SA_prom[1]=%x,,SA_prom[2]=%x,SA_prom[3]=%x,SA_prom[4]=%x,SA_prom[5]=%x\n",SA_prom[0],SA_prom[1],SA_prom[2],SA_prom[3],SA_prom[4],SA_prom[5]); //test---------------------------- #endif /* We must set the 8390 for word mode. */ outb_p(0x49, ioaddr + EN0_DCFG); start_page = NESM_START_PG; stop_page = NESM_STOP_PG; //test---------------------------- printk("start_page test\n"); //test---------------------------- } else { start_page = NE1SM_START_PG; stop_page = NE1SM_STOP_PG; }#endif#if defined(CONFIG_CPU_H8300H) start_page = NESM_START_PG; stop_page = NESM_STOP_PG; H8300_INIT_NE();#endif#if defined(CONFIG_BOARD_MBA44) start_page = NESM_START_PG; stop_page = NESM_STOP_PG; //test---------------------------- printk("start_page test\n"); //test----------------------------#endif //test SA_prom[14] SA_prom[15] SA_prom[0] SA_prom[1] SA_prom[2] printk("SA_prom[14]=%x,SA_prom[15]=%x,,SA_prom[0]=%x,SA_prom[1]=%x,SA_prom[2]=%x\n",SA_prom[14],SA_prom[15],SA_prom[0],SA_prom[1],SA_prom[2]); //test---------------------------- neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); /* Set up the rest of the parameters. */ if (!(neX000 || bad_card || copam)) { name = (wordlength == 2) ? "NE2000" : "NE1000"; } else if (ctron) { name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; start_page = 0x01; stop_page = (wordlength == 2) ? 0x40 : 0x20; } else { #ifdef SUPPORT_NE_BAD_CLONES /* Ack! Well, there might be a *bad* NE*000 clone there. Check for total bogus addresses. */ for (i = 0; bad_clone_list[i].name8; i++) { if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && SA_prom[1] == bad_clone_list[i].SAprefix[1] && SA_prom[2] == bad_clone_list[i].SAprefix[2]) { if (wordlength == 2) { name = bad_clone_list[i].name16; } else { name = bad_clone_list[i].name8; } break; } } if (bad_clone_list[i].name8 == NULL) { printk(" not found (invalid signature %2.2x %2.2x).\n", SA_prom[14], SA_prom[15]); ret = -ENXIO; goto err_out; }#else printk(" not found.\n"); ret = -ENXIO; goto err_out;#endif } if (dev->irq < 2) { unsigned long cookie = probe_irq_on(); outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ outb_p(0x00, ioaddr + EN0_RCNTLO); outb_p(0x00, ioaddr + EN0_RCNTHI); outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ mdelay(10); /* wait 10ms for interrupt to propagate */ outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ dev->irq = probe_irq_off(cookie); if (ei_debug > 2) printk(" autoirq is %d\n", dev->irq); } else if (dev->irq == 2) /* Fixup for users that don't know that IRQ 2 is really IRQ 9, or don't know which one to set. */ dev->irq = 9; if (! dev->irq) { printk(" failed to detect IRQ line.\n"); ret = -EAGAIN; goto err_out; } /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); ret = -ENOMEM; goto err_out; } /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);#ifdef CONFIG_COLDFIRE if (ret == 0) ne2000_irqsetup(dev->irq);#endif if (ret) { printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); goto err_out_kfree; } dev->base_addr = ioaddr; for(i = 0; i < ETHER_ADDR_LEN; i++) { printk(" %2.2x", SA_prom[i]); dev->dev_addr[i] = SA_prom[i]; } printk("\n%s: %s found at %#x, using IRQ %d\n", dev->name, name, ioaddr, dev->irq); ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = (wordlength == 2); ei_status.rx_start_page = start_page + TX_PAGES;#ifdef PACKETBUF_MEMSIZE /* Allow the packet buffer size to be overridden by know-it-alls. */ ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;#endif ei_status.reset_8390 = &ne_reset_8390; ei_status.block_input = &ne_block_input; ei_status.block_output = &ne_block_output; ei_status.get_8390_hdr = &ne_get_8390_hdr; ei_status.priv = 0; dev->open = &ne_open; dev->stop = &ne_close; NS8390_init(dev, 0); return 0;err_out_kfree: kfree(dev->priv); dev->priv = NULL;err_out:#if !defined(CONFIG_COLDFIRE) && !defined(CONFIG_CPU_H8300H) release_region(ioaddr, NE_IO_EXTENT);#endif return ret;}static int ne_open(struct net_device *dev){ ei_open(dev); return 0;}static int ne_close(struct net_device *dev){ if (ei_debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); ei_close(dev); return 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?