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

📄 eepro100.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		} while (self_test_results[1] == -1  &&  --boguscnt >= 0);		if (boguscnt < 0) {		/* Test optimized out. */			printk(KERN_ERR "Self test failed, status %8.8x:\n"				   KERN_ERR " Failure to initialize the i82557.\n"				   KERN_ERR " Verify that the card is a bus-master"				   " capable slot.\n",				   self_test_results[1]);		} else			printk(KERN_INFO "  General self-test: %s.\n"				   KERN_INFO "  Serial sub-system self-test: %s.\n"				   KERN_INFO "  Internal registers self-test: %s.\n"				   KERN_INFO "  ROM checksum self-test: %s (%#8.8x).\n",				   self_test_results[1] & 0x1000 ? "failed" : "passed",				   self_test_results[1] & 0x0020 ? "failed" : "passed",				   self_test_results[1] & 0x0008 ? "failed" : "passed",				   self_test_results[1] & 0x0004 ? "failed" : "passed",				   self_test_results[0]);	}#endif  /* kernel_bloat */	outl(PortReset, ioaddr + SCBPort);	inl(ioaddr + SCBPort);	udelay(10);	/* Return the chip to its original power state. */	pci_set_power_state(pdev, acpi_idle_state);	pci_set_drvdata (pdev, dev);	dev->base_addr = ioaddr;	dev->irq = pdev->irq;	sp = dev->priv;	sp->pdev = pdev;	sp->acpi_pwr = acpi_idle_state;	sp->tx_ring = tx_ring_space;	sp->tx_ring_dma = tx_ring_dma;	sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE);	sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE);	init_timer(&sp->timer); /* used in ioctl() */	sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;	if (card_idx >= 0) {		if (full_duplex[card_idx] >= 0)			sp->full_duplex = full_duplex[card_idx];	}	sp->default_port = option >= 0 ? (option & 0x0f) : 0;	sp->phy[0] = eeprom[6];	sp->phy[1] = eeprom[7];	sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;	if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) 	    || (pdev->device == 0x2449)) {	    	sp->chip_id = 1;	}	if (sp->rx_bug)		printk(KERN_INFO "  Receiver lock-up workaround activated.\n");	/* The Speedo-specific entries in the device structure. */	dev->open = &speedo_open;	dev->hard_start_xmit = &speedo_start_xmit;	netif_set_tx_timeout(dev, &speedo_tx_timeout, TX_TIMEOUT);	dev->stop = &speedo_close;	dev->get_stats = &speedo_get_stats;	dev->set_multicast_list = &set_rx_mode;	dev->do_ioctl = &speedo_ioctl;	return 0;}/* Serial EEPROM section.   A "bit" grungy, but we work our way through bit-by-bit :->. *//*  EEPROM_Ctrl bits. */#define EE_SHIFT_CLK	0x01	/* EEPROM shift clock. */#define EE_CS			0x02	/* EEPROM chip select. */#define EE_DATA_WRITE	0x04	/* EEPROM chip data in. */#define EE_DATA_READ	0x08	/* EEPROM chip data out. */#define EE_ENB			(0x4800 | EE_CS)#define EE_WRITE_0		0x4802#define EE_WRITE_1		0x4806#define EE_OFFSET		SCBeeprom/* The fixes for the code were kindly provided by Dragan Stancevic   <visitor@valinux.com> to strictly follow Intel specifications of EEPROM   access timing.   The publicly available sheet 64486302 (sec. 3.1) specifies 1us access   interval for serial EEPROM.  However, it looks like that there is an   additional requirement dictating larger udelay's in the code below.   2000/05/24  SAW */static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len){	unsigned retval = 0;	long ee_addr = ioaddr + SCBeeprom;	io_outw(EE_ENB, ee_addr); udelay(2);	io_outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);	/* Shift the command bits out. */	do {		short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;		io_outw(dataval, ee_addr); udelay(2);		io_outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);		retval = (retval << 1) | ((io_inw(ee_addr) & EE_DATA_READ) ? 1 : 0);	} while (--cmd_len >= 0);	io_outw(EE_ENB, ee_addr); udelay(2);	/* Terminate the EEPROM access. */	io_outw(EE_ENB & ~EE_CS, ee_addr);	return retval;}static int mdio_read(long ioaddr, int phy_id, int location){	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */	outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);	do {		val = inl(ioaddr + SCBCtrlMDI);		if (--boguscnt < 0) {			printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);			break;		}	} while (! (val & 0x10000000));	return val & 0xffff;}static int mdio_write(long ioaddr, int phy_id, int location, int value){	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */	outl(0x04000000 | (location<<16) | (phy_id<<21) | value,		 ioaddr + SCBCtrlMDI);	do {		val = inl(ioaddr + SCBCtrlMDI);		if (--boguscnt < 0) {			printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);			break;		}	} while (! (val & 0x10000000));	return val & 0xffff;}static intspeedo_open(struct net_device *dev){	struct speedo_private *sp = (struct speedo_private *)dev->priv;	long ioaddr = dev->base_addr;	int retval;	if (speedo_debug > 1)		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);	MOD_INC_USE_COUNT;	pci_set_power_state(sp->pdev, 0);	/* Set up the Tx queue early.. */	sp->cur_tx = 0;	sp->dirty_tx = 0;	sp->last_cmd = 0;	sp->tx_full = 0;	spin_lock_init(&sp->lock);	sp->in_interrupt = 0;	/* .. we can safely take handler calls during init. */	retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev);	if (retval) {		MOD_DEC_USE_COUNT;		return retval;	}	dev->if_port = sp->default_port;#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us	/* Retrigger negotiation to reset previous errors. */	if ((sp->phy[0] & 0x8000) == 0) {		int phy_addr = sp->phy[0] & 0x1f ;		/* Use 0x3300 for restarting NWay, other values to force xcvr:		   0x0000 10-HD		   0x0100 10-FD		   0x2000 100-HD		   0x2100 100-FD		*/#ifdef honor_default_port		mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]);#else		mdio_write(ioaddr, phy_addr, 0, 0x3300);#endif	}#endif	speedo_init_rx_ring(dev);	/* Fire up the hardware. */	outw(SCBMaskAll, ioaddr + SCBCmd);	speedo_resume(dev);	netdevice_start(dev);	netif_start_queue(dev);	/* Setup the chip and configure the multicast list. */	sp->mc_setup_head = NULL;	sp->mc_setup_tail = NULL;	sp->flow_ctrl = sp->partner = 0;	sp->rx_mode = -1;			/* Invalid -> always reset the mode. */	set_rx_mode(dev);	if ((sp->phy[0] & 0x8000) == 0)		sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4);	if (mdio_read(ioaddr, sp->phy[0] & 0x1f, MII_BMSR) & BMSR_LSTATUS)		netif_carrier_on(dev);	else		netif_carrier_off(dev);	if (speedo_debug > 2) {		printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",			   dev->name, inw(ioaddr + SCBStatus));	}	/* Set the timer.  The timer serves a dual purpose:	   1) to monitor the media interface (e.g. link beat) and perhaps switch	   to an alternate media type	   2) to monitor Rx activity, and restart the Rx process if the receiver	   hangs. */	sp->timer.expires = RUN_AT((24*HZ)/10); 			/* 2.4 sec. */	sp->timer.data = (unsigned long)dev;	sp->timer.function = &speedo_timer;					/* timer handler */	add_timer(&sp->timer);	/* No need to wait for the command unit to accept here. */	if ((sp->phy[0] & 0x8000) == 0)		mdio_read(ioaddr, sp->phy[0] & 0x1f, 0);	return 0;}/* Start the chip hardware after a full reset. */static void speedo_resume(struct net_device *dev){	struct speedo_private *sp = (struct speedo_private *)dev->priv;	long ioaddr = dev->base_addr;	/* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */	sp->tx_threshold = 0x01208000;	/* Set the segment registers to '0'. */	wait_for_cmd_done(ioaddr + SCBCmd);	outl(0, ioaddr + SCBPointer);	/* impose a delay to avoid a bug */	inl(ioaddr + SCBPointer);	udelay(10);	outb(RxAddrLoad, ioaddr + SCBCmd);	wait_for_cmd_done(ioaddr + SCBCmd);	outb(CUCmdBase, ioaddr + SCBCmd);	/* Load the statistics block and rx ring addresses. */	wait_for_cmd_done(ioaddr + SCBCmd);	outl(sp->lstats_dma, ioaddr + SCBPointer);	outb(CUStatsAddr, ioaddr + SCBCmd);	sp->lstats->done_marker = 0;	if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {		if (speedo_debug > 2)			printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",					dev->name);	} else {		wait_for_cmd_done(ioaddr + SCBCmd);		outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],			 ioaddr + SCBPointer);		outb(RxStart, ioaddr + SCBCmd);	}	wait_for_cmd_done(ioaddr + SCBCmd);	outb(CUDumpStats, ioaddr + SCBCmd);	udelay(30);	/* Fill the first command with our physical address. */	{		struct descriptor *ias_cmd;		ias_cmd =			(struct descriptor *)&sp->tx_ring[sp->cur_tx++ % TX_RING_SIZE];		/* Avoid a bug(?!) here by marking the command already completed. */		ias_cmd->cmd_status = cpu_to_le32((CmdSuspend | CmdIASetup) | 0xa000);		ias_cmd->link =			cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));		memcpy(ias_cmd->params, dev->dev_addr, 6);		sp->last_cmd = ias_cmd;	}	/* Start the chip's Tx process and unmask interrupts. */	wait_for_cmd_done(ioaddr + SCBCmd);	outl(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),		 ioaddr + SCBPointer);	/* We are not ACK-ing FCP and ER in the interrupt handler yet so they should	   remain masked --Dragan */	outw(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);}/* Media monitoring and control. */static void speedo_timer(unsigned long data){	struct net_device *dev = (struct net_device *)data;	struct speedo_private *sp = (struct speedo_private *)dev->priv;	long ioaddr = dev->base_addr;	int phy_num = sp->phy[0] & 0x1f;	/* We have MII and lost link beat. */	if ((sp->phy[0] & 0x8000) == 0) {		int partner = mdio_read(ioaddr, phy_num, 5);		if (partner != sp->partner) {			int flow_ctrl = sp->advertising & partner & 0x0400 ? 1 : 0;			if (speedo_debug > 2) {				printk(KERN_DEBUG "%s: Link status change.\n", dev->name);				printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n",					   dev->name, sp->partner, partner, sp->advertising);			}			sp->partner = partner;			if (flow_ctrl != sp->flow_ctrl) {				sp->flow_ctrl = flow_ctrl;				sp->rx_mode = -1;	/* Trigger a reload. */			}			/* Clear sticky bit. */			mdio_read(ioaddr, phy_num, 1);			/* If link beat has returned... */			if (mdio_read(ioaddr, phy_num, 1) & 0x0004)				netif_carrier_on(dev);			else				netif_carrier_off(dev);		}	}	if (speedo_debug > 3) {		printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",			   dev->name, inw(ioaddr + SCBStatus));	}	if (sp->rx_mode < 0  ||		(sp->rx_bug  && jiffies - sp->last_rx_time > 2*HZ)) {		/* We haven't received a packet in a Long Time.  We might have been		   bitten by the receiver hang bug.  This can be cleared by sending		   a set multicast list command. */		if (speedo_debug > 3)			printk(KERN_DEBUG "%s: Sending a multicast list set command"				   " from a timer routine,"				   " m=%d, j=%ld, l=%ld.\n",				   dev->name, sp->rx_mode, jiffies, sp->last_rx_time);		set_rx_mode(dev);	}	/* We must continue to monitor the media. */	sp->timer.expires = RUN_AT(2*HZ); 			/* 2.0 sec. */	add_timer(&sp->timer);#if defined(timer_exit)	timer_exit(&sp->timer);#endif}static void speedo_show_state(struct net_device *dev){	struct speedo_private *sp = (struct speedo_private *)dev->priv;	int i;	/* Print a few items for debugging. */	if (speedo_debug > 0) {		int i;		printk(KERN_DEBUG "%s: Tx ring dump,  Tx queue %u / %u:\n", dev->name,			   sp->cur_tx, sp->dirty_tx);		for (i = 0; i < TX_RING_SIZE; i++)			printk(KERN_DEBUG "%s:  %c%c%2d %8.8x.\n", dev->name,				   i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',				   i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',				   i, sp->tx_ring[i].status);	}	printk(KERN_DEBUG "%s: Printing Rx ring"		   " (next to receive into %u, dirty index %u).\n",		   dev->name, sp->cur_rx, sp->dirty_rx);	for (i = 0; i < RX_RING_SIZE; i++)		printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name,			   sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ',			   i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ',			   i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ',			   i, (sp->rx_ringp[i] != NULL) ?					   (unsigned)sp->rx_ringp[i]->status : 0);#if 0	{		long ioaddr = dev->base_addr;		int phy_num = sp->phy[0] & 0x1f;

⌨️ 快捷键说明

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