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

📄 eepro100.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		udelay (10 * 1000);		read_hw_addr (dev, bis);	}	return card_number;}static int eepro100_init (struct eth_device *dev, bd_t * bis){	int i, status = 0;	int tx_cur;	struct descriptor *ias_cmd, *cfg_cmd;	/* Reset the ethernet controller	 */	OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);	udelay (20);	OUTL (dev, I82559_RESET, SCBPort);	udelay (20);	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, 0, SCBPointer);	OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, 0, SCBPointer);	OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);	/* Initialize Rx and Tx rings.	 */	init_rx_ring (dev);	purge_tx_ring (dev);	/* Tell the adapter where the RX ring is located.	 */	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);	OUTW (dev, SCB_M | RUC_START, SCBCmd);	/* Send the Configure frame */	tx_cur = tx_next;	tx_next = ((tx_next + 1) % NUM_TX_DESC);	cfg_cmd = (struct descriptor *) &tx_ring[tx_cur];	cfg_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_CONFIGURE));	cfg_cmd->status = 0;	cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));	memcpy (cfg_cmd->params, i82558_config_cmd,			sizeof (i82558_config_cmd));	if (!wait_for_eepro100 (dev)) {		printf ("Error---CFG_CMD_CONFIGURE: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);	OUTW (dev, SCB_M | CU_START, SCBCmd);	for (i = 0;	     !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);	     i++) {		if (i >= TOUT_LOOP) {			printf ("%s: Tx error buffer not ready\n", dev->name);			goto Done;		}	}	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {		printf ("TX error status = 0x%08X\n",			le16_to_cpu (tx_ring[tx_cur].status));		goto Done;	}	/* Send the Individual Address Setup frame	 */	tx_cur = tx_next;	tx_next = ((tx_next + 1) % NUM_TX_DESC);	ias_cmd = (struct descriptor *) &tx_ring[tx_cur];	ias_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_IAS));	ias_cmd->status = 0;	ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));	memcpy (ias_cmd->params, dev->enetaddr, 6);	/* Tell the adapter where the TX ring is located.	 */	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);	OUTW (dev, SCB_M | CU_START, SCBCmd);	for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);		 i++) {		if (i >= TOUT_LOOP) {			printf ("%s: Tx error buffer not ready\n",				dev->name);			goto Done;		}	}	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {		printf ("TX error status = 0x%08X\n",			le16_to_cpu (tx_ring[tx_cur].status));		goto Done;	}	status = 1;  Done:	return status;}static int eepro100_send (struct eth_device *dev, volatile void *packet, int length){	int i, status = -1;	int tx_cur;	if (length <= 0) {		printf ("%s: bad packet size: %d\n", dev->name, length);		goto Done;	}	tx_cur = tx_next;	tx_next = (tx_next + 1) % NUM_TX_DESC;	tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT |						TxCB_CMD_SF	|						TxCB_CMD_S	|						TxCB_CMD_EL );	tx_ring[tx_cur].status = 0;	tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold);	tx_ring[tx_cur].link =		cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));	tx_ring[tx_cur].tx_desc_addr =		cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0));	tx_ring[tx_cur].tx_buf_addr0 =		cpu_to_le32 (phys_to_bus ((u_long) packet));	tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length);	if (!wait_for_eepro100 (dev)) {		printf ("%s: Tx error ethernet controller not ready.\n",				dev->name);		goto Done;	}	/* Send the packet.	 */	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);	OUTW (dev, SCB_M | CU_START, SCBCmd);	for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);		 i++) {		if (i >= TOUT_LOOP) {			printf ("%s: Tx error buffer not ready\n", dev->name);			goto Done;		}	}	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {		printf ("TX error status = 0x%08X\n",			le16_to_cpu (tx_ring[tx_cur].status));		goto Done;	}	status = length;  Done:	return status;}static int eepro100_recv (struct eth_device *dev){	u16 status, stat;	int rx_prev, length = 0;	stat = INW (dev, SCBStatus);	OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus);	for (;;) {		status = le16_to_cpu (rx_ring[rx_next].status);		if (!(status & RFD_STATUS_C)) {			break;		}		/* Valid frame status.		 */		if ((status & RFD_STATUS_OK)) {			/* A valid frame received.			 */			length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff;			/* Pass the packet up to the protocol			 * layers.			 */			NetReceive (rx_ring[rx_next].data, length);		} else {			/* There was an error.			 */			printf ("RX error status = 0x%08X\n", status);		}		rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S);		rx_ring[rx_next].status = 0;		rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);		rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC;		rx_ring[rx_prev].control = 0;		/* Update entry information.		 */		rx_next = (rx_next + 1) % NUM_RX_DESC;	}	if (stat & SCB_STATUS_RNR) {		printf ("%s: Receiver is not ready, restart it !\n", dev->name);		/* Reinitialize Rx ring.		 */		init_rx_ring (dev);		if (!wait_for_eepro100 (dev)) {			printf ("Error: Can not restart ethernet controller.\n");			goto Done;		}		OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);		OUTW (dev, SCB_M | RUC_START, SCBCmd);	}  Done:	return length;}static void eepro100_halt (struct eth_device *dev){	/* Reset the ethernet controller	 */	OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);	udelay (20);	OUTL (dev, I82559_RESET, SCBPort);	udelay (20);	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, 0, SCBPointer);	OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);	if (!wait_for_eepro100 (dev)) {		printf ("Error: Can not reset ethernet controller.\n");		goto Done;	}	OUTL (dev, 0, SCBPointer);	OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);  Done:	return;}	/* SROM Read.	 */static int read_eeprom (struct eth_device *dev, int location, int addr_len){	unsigned short retval = 0;	int read_cmd = location | EE_READ_CMD;	int i;	OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);	OUTW (dev, EE_ENB, SCBeeprom);	/* Shift the read command bits out. */	for (i = 12; i >= 0; i--) {		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;		OUTW (dev, EE_ENB | dataval, SCBeeprom);		udelay (1);		OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);		udelay (1);	}	OUTW (dev, EE_ENB, SCBeeprom);	for (i = 15; i >= 0; i--) {		OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);		udelay (1);		retval = (retval << 1) |				((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);		OUTW (dev, EE_ENB, SCBeeprom);		udelay (1);	}	/* Terminate the EEPROM access. */	OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);	return retval;}#ifdef CONFIG_EEPRO100_SROM_WRITEint eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data){    unsigned short dataval;    int enable_cmd = 0x3f | EE_EWENB_CMD;    int write_cmd  = location | EE_WRITE_CMD;    int i;    unsigned long datalong, tmplong;    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);    udelay(1);    OUTW(dev, EE_ENB, SCBeeprom);    /* Shift the enable command bits out. */    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)    {	dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0;	OUTW(dev, EE_ENB | dataval, SCBeeprom);	udelay(1);	OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);	udelay(1);    }    OUTW(dev, EE_ENB, SCBeeprom);    udelay(1);    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);    udelay(1);    OUTW(dev, EE_ENB, SCBeeprom);    /* Shift the write command bits out. */    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)    {	dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;	OUTW(dev, EE_ENB | dataval, SCBeeprom);	udelay(1);	OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);	udelay(1);    }    /* Write the data */    datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8));    for (i = 0; i< EE_DATA_BITS; i++)    {    /* Extract and move data bit to bit DI */    dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0;    OUTW(dev, EE_ENB | dataval, SCBeeprom);    udelay(1);    OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);    udelay(1);    OUTW(dev, EE_ENB | dataval, SCBeeprom);    udelay(1);    datalong = datalong << 1;	/* Adjust significant data bit*/    }    /* Finish up command  (toggle CS) */    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);    udelay(1);			/* delay for more than 250 ns */    OUTW(dev, EE_ENB, SCBeeprom);    /* Wait for programming ready (D0 = 1) */    tmplong = 10;    do    {	dataval = INW(dev, SCBeeprom);	if (dataval & EE_DATA_READ)	    break;	udelay(10000);    }    while (-- tmplong);    if (tmplong == 0)    {	printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n");	return -1;    }    /* Terminate the EEPROM access. */    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);    return 0;}#endifstatic void init_rx_ring (struct eth_device *dev){	int i;	for (i = 0; i < NUM_RX_DESC; i++) {		rx_ring[i].status = 0;		rx_ring[i].control =				(i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0;		rx_ring[i].link =				cpu_to_le32 (phys_to_bus							 ((u32) & rx_ring[(i + 1) % NUM_RX_DESC]));		rx_ring[i].rx_buf_addr = 0xffffffff;		rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);	}	rx_next = 0;}static void purge_tx_ring (struct eth_device *dev){	int i;	tx_next = 0;	tx_threshold = 0x01208000;	for (i = 0; i < NUM_TX_DESC; i++) {		tx_ring[i].status = 0;		tx_ring[i].command = 0;		tx_ring[i].link = 0;		tx_ring[i].tx_desc_addr = 0;		tx_ring[i].count = 0;		tx_ring[i].tx_buf_addr0 = 0;		tx_ring[i].tx_buf_size0 = 0;		tx_ring[i].tx_buf_addr1 = 0;		tx_ring[i].tx_buf_size1 = 0;	}}static void read_hw_addr (struct eth_device *dev, bd_t * bis){	u16 eeprom[0x40];	u16 sum = 0;	int i, j;	int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6;	for (j = 0, i = 0; i < 0x40; i++) {		u16 value = read_eeprom (dev, i, addr_len);		eeprom[i] = value;		sum += value;		if (i < 3) {			dev->enetaddr[j++] = value;			dev->enetaddr[j++] = value >> 8;		}	}	if (sum != 0xBABA) {		memset (dev->enetaddr, 0, ETH_ALEN);#ifdef DEBUG		printf ("%s: Invalid EEPROM checksum %#4.4x, "			"check settings before activating this device!\n",			dev->name, sum);#endif	}}#endif

⌨️ 快捷键说明

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