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

📄 eth.c

📁 U BOOT源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************Etherboot -  BOOTP/TFTP Bootstrap ProgramSkeleton NIC driver for Etherboot***************************************************************************//* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. *//* * This file is a modified version from the Galileo polled mode * network driver for the ethernet contained within the GT64260 * chip. It has been modified to fit into the U-Boot framework, from * the original (etherboot) setup.  Also, additional cleanup and features * were added. * * - Josh Huber <huber@mclx.com> */#include <common.h>#include <malloc.h>#include <galileo/gt64260R.h>#include <galileo/core.h>#include <asm/cache.h>#include <miiphy.h>#include <net.h>#include "eth.h"#include "eth_addrtbl.h"#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)#define GT6426x_ETH_BUF_SIZE	1536/* if you like verbose output, turn this on! */#undef DEBUG/* Restart autoneg if we detect link is up on phy init. *//* * The GT doc's say that after Rst is deasserted, and the PHY * reports autoneg complete, it runs through its autoneg * procedures. This doesn't seem to be the case for MII * PHY's. To work around this check for link up && autoneg * complete when initilizing the port. If they are both set, * then restart PHY autoneg. Of course, it may be something * completly different. */#ifdef CONFIG_ETHER_PORT_MII# define RESTART_AUTONEG#endif/* do this if you dont want to use snooping */#define USE_SOFTWARE_CACHE_MANAGEMENT#ifdef USE_SOFTWARE_CACHE_MANAGEMENT#define FLUSH_DCACHE(a,b)                if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));}#define INVALIDATE_DCACHE(a,b)           if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));}#else/* bummer - w/o flush, nothing works, even with snooping - FIXME *//* #define FLUSH_DCACHE(a,b) */#define FLUSH_DCACHE(a,b)                if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}#define FLUSH_AND_INVALIDATE_DCACHE(a,b)#define INVALIDATE_DCACHE(a,b)#endifstruct eth_dev_s {	eth0_tx_desc_single *eth_tx_desc;	eth0_rx_desc_single *eth_rx_desc;	char *eth_tx_buffer;	char *eth_rx_buffer[NR];	int tdn, rdn;	int dev;	unsigned int reg_base;};#ifdef CONFIG_INTEL_LXT97X/* for intel LXT972 */static const char ether_port_phy_addr[3]={0,1,2};#elsestatic const char ether_port_phy_addr[3]={4,5,6};#endifstatic inline unsigned shortmiiphy_read_ret(unsigned short phy, unsigned short reg){    unsigned short val;    miiphy_read(phy,reg,&val);    return val;}/**************************************************************************RESET - Reset adapter***************************************************************************/voidgt6426x_eth_reset(void *v){	/*  we should do something here...	struct eth_device *wp = (struct eth_device *)v;	struct eth_dev_s *p = wp->priv;	*/	printf ("RESET\n");	/* put the card in its initial state */}static void gt6426x_handle_SMI(struct eth_dev_s *p, unsigned int icr){#ifdef DEBUG    printf("SMI interrupt: ");    if(icr&0x20000000) {	printf("SMI done\n");    }#endif    if(icr&0x10000000) {	unsigned int psr;	psr=GTREGREAD(ETHERNET0_PORT_STATUS_REGISTER + p->reg_base);#ifdef DEBUG	printf("PHY state change:\n"	       "  GT:%s:%s:%s:%s\n",		psr&1?"100":" 10",		psr&8?" Link":"nLink",		psr&2?"FD":"HD",		psr&4?" FC":"nFC");#ifdef CONFIG_INTEL_LXT97X /* non-standard mii reg (intel lxt972a) */	{	unsigned short mii_11;	mii_11=miiphy_read_ret(ether_port_phy_addr[p->dev],0x11);	printf(" mii:%s:%s:%s:%s %s:%s %s\n",		mii_11&(1<<14)?"100":" 10",		mii_11&(1<<10)?" Link":"nLink",		mii_11&(1<<9)?"FD":"HD",		mii_11&(1<<4)?" FC":"nFC",		mii_11&(1<<7)?"ANc":"ANnc",		mii_11&(1<<8)?"AN":"Manual",		""		);	}#endif /* CONFIG_INTEL_LXT97X */#endif /* DEBUG */    }}static intgt6426x_eth_receive(struct eth_dev_s *p,unsigned int icr){	int eth_len=0;	char *eth_data;	eth0_rx_desc_single *rx=&p->eth_rx_desc[(p->rdn)];	INVALIDATE_DCACHE((unsigned int)rx,(unsigned int)(rx+1));	if (rx->command_status & 0x80000000) {		return 0; /* No packet received */	}	eth_len = (unsigned int)		(rx->buff_size_byte_count) & 0x0000ffff;	eth_data = (char *) p->eth_rx_buffer[p->rdn];#ifdef DEBUG	if (eth_len) {		printf ("%s: Recived %d byte Packet @ 0x%p\n",			__FUNCTION__, eth_len, eth_data);	}#endif	/*	 * packet is now in:	 * eth0_rx_buffer[RDN_ETH0];	 */	/* let the upper layer handle the packet */	NetReceive (eth_data, eth_len);	rx->buff_size_byte_count = GT6426x_ETH_BUF_SIZE<<16;	/* GT96100 Owner */	rx->command_status = 0x80000000;	FLUSH_DCACHE((unsigned int)rx,(unsigned int)(rx+1));	p->rdn ++;	if (p->rdn == NR) {p->rdn = 0;}	sync();	/* Start Rx*/	GT_REG_WRITE (ETHERNET0_SDMA_COMMAND_REGISTER + p->reg_base, 0x00000080);#ifdef DEBUG	{	    int i;	    for (i=0;i<12;i++) {		printf(" %02x", eth_data[i]);	    }	}	printf(": %d bytes\n", eth_len);#endif	INVALIDATE_DCACHE((unsigned int)eth_data,		(unsigned int)eth_data+eth_len);	return eth_len;}/**************************************************************************POLL - look for an rx frame, handle other conditions***************************************************************************/intgt6426x_eth_poll(void *v){	struct eth_device *wp = (struct eth_device *)v;	struct eth_dev_s *p = wp->priv;	unsigned int icr=GTREGREAD(ETHERNET0_INTERRUPT_CAUSE_REGISTER + p->reg_base);	if(icr) {	    GT_REG_WRITE(ETHERNET0_INTERRUPT_CAUSE_REGISTER +p->reg_base, 0);#ifdef DEBUG	    printf("poll got ICR %08x\n", icr);#endif	    /* SMI done or PHY state change*/	    if(icr&0x30000000) gt6426x_handle_SMI(p, icr);	}	/* always process. We aren't using RX interrupts */	return gt6426x_eth_receive(p, icr);}/**************************************************************************TRANSMIT - Transmit a frame***************************************************************************/intgt6426x_eth_transmit(void *v, volatile char *p, unsigned int s){	struct eth_device *wp = (struct eth_device *)v;	struct eth_dev_s *dev = (struct eth_dev_s *)wp->priv;#ifdef DEBUG	unsigned int old_command_stat,old_psr;#endif	eth0_tx_desc_single *tx=&dev->eth_tx_desc[dev->tdn];	/* wait for tx to be ready */	INVALIDATE_DCACHE((unsigned int)tx,(unsigned int)(tx+1));	while (tx->command_status & 0x80000000) {	    int i;	    for(i=0;i<1000;i++);			INVALIDATE_DCACHE((unsigned int)tx,(unsigned int)(tx+1));	}	GT_REG_WRITE (ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 + dev->reg_base,		      (unsigned int)tx);#ifdef DEBUG	printf("copying to tx_buffer [%p], length %x, desc = %p\n",	       dev->eth_tx_buffer, s, dev->eth_tx_desc);#endif	memcpy(dev->eth_tx_buffer, (char *) p, s);	tx->buff_pointer = dev->eth_tx_buffer;	tx->bytecount_reserved = ((__u16)s) << 16;	/*    31 - own	 *    22 - gencrc	 * 18:16 - pad, last, first */	tx->command_status = (1<<31) | (1<<22) | (7<<16);#if 0	/* FEr #18 */	tx->next_desc = NULL;#else	tx->next_desc =		(struct eth0_tx_desc_struct *)		&dev->eth_tx_desc[(dev->tdn+1)%NT].bytecount_reserved;	/* cpu owned */	dev->eth_tx_desc[(dev->tdn+1)%NT].command_status = (7<<16);	/* pad, last, first */#endif#ifdef DEBUG	old_command_stat=tx->command_status,	old_psr=GTREGREAD(ETHERNET0_PORT_STATUS_REGISTER + dev->reg_base);#endif	FLUSH_DCACHE((unsigned int)tx,		(unsigned int)&dev->eth_tx_desc[(dev->tdn+2)%NT]);	FLUSH_DCACHE((unsigned int)dev->eth_tx_buffer,(unsigned int)dev->eth_tx_buffer+s);	GT_REG_WRITE(ETHERNET0_SDMA_COMMAND_REGISTER + dev->reg_base, 0x01000000);#ifdef DEBUG	{	    unsigned int command_stat=0;	    printf("cmd_stat: %08x PSR: %08x\n", old_command_stat, old_psr);	    /* wait for tx to be ready */	    do {		unsigned int psr=GTREGREAD(ETHERNET0_PORT_STATUS_REGISTER + dev->reg_base);		command_stat=tx->command_status;		if(command_stat!=old_command_stat || psr !=old_psr) {		    printf("cmd_stat: %08x PSR: %08x\n", command_stat, psr);		    old_command_stat = command_stat;		    old_psr = psr;		}		/* gt6426x_eth0_poll(); */	    } while (command_stat & 0x80000000);	    printf("sent %d byte frame\n", s);	    if((command_stat & (3<<15)) == 3) {		printf("frame had error (stat=%08x)\n", command_stat);	    }	}#endif	return 0;}/**************************************************************************DISABLE - Turn off ethernet interface***************************************************************************/voidgt6426x_eth_disable(void *v){	struct eth_device *wp = (struct eth_device *)v;	struct eth_dev_s *p = (struct eth_dev_s *)wp->priv;	GT_REG_WRITE(ETHERNET0_SDMA_COMMAND_REGISTER + p->reg_base, 0x80008000);}/**************************************************************************MII utilities - write: write to an MII register via SMI***************************************************************************/intmiiphy_write(unsigned char phy, unsigned char reg,    unsigned short data){    unsigned int temp= (reg<<21) | (phy<<16) | data;    while(GTREGREAD(ETHERNET_SMI_REGISTER) & (1<<28));	/* wait for !Busy */    GT_REG_WRITE(ETHERNET_SMI_REGISTER, temp);    return 0;}/**************************************************************************MII utilities - read: read from an MII register via SMI***************************************************************************/intmiiphy_read(unsigned char phy, unsigned char reg,			unsigned short *val){    unsigned int temp= (reg<<21) | (phy<<16) | 1<<26;    while(GTREGREAD(ETHERNET_SMI_REGISTER) & (1<<28));	/* wait for !Busy */    GT_REG_WRITE(ETHERNET_SMI_REGISTER, temp);    while(1) {	temp=GTREGREAD(ETHERNET_SMI_REGISTER);	if(temp & (1<<27)) break;		/* wait for ReadValid */    }    *val = temp & 0xffff;    return 0;}#ifdef DEBUG/**************************************************************************MII utilities - dump mii registers***************************************************************************/static voidgt6426x_dump_mii(bd_t *bis, unsigned short phy){	printf("mii reg 0 - 3:   %04x %04x %04x %04x\n",		miiphy_read_ret(phy, 0x0),		miiphy_read_ret(phy, 0x1),		miiphy_read_ret(phy, 0x2),		miiphy_read_ret(phy, 0x3)		);	printf("        4 - 7:   %04x %04x %04x %04x\n",		miiphy_read_ret(phy, 0x4),		miiphy_read_ret(phy, 0x5),		miiphy_read_ret(phy, 0x6),		miiphy_read_ret(phy, 0x7)		);	printf("        8:       %04x\n",		miiphy_read_ret(phy, 0x8)		);	printf("        16-19:   %04x %04x %04x %04x\n",		miiphy_read_ret(phy, 0x10),		miiphy_read_ret(phy, 0x11),

⌨️ 快捷键说明

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