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

📄 hisilicon-sf.c

📁 华为 HI3510 BOOTLOADER HIBOOT 源码包
💻 C
字号:
#include <linux-adapter.h>#include <command.h>#include "hisilicon-sf.h"#include "SF_Reg.h"#include "SF_RegStruct.h"#include "SF_TypeDef.h"#include <net.h>#define sf_print_mac(mac) 	do{ int i;\	printk(KERN_INFO "MAC:  ");\	for (i = 0; i < ETH_ALEN; i++)\		printk("%c%02X", i ? '-' : ' ', *(((unsigned char*)mac)+i));\	printk("\n");\	}while(0)static struct net_device *sf_devs[2]={NULL, NULL};#define sf_port_dev(n) sf_devs[(n)==0 ? 1:0]void *sf_rxtxbuf = NULL;static void eth_reset(void){	SF_SoftReset();	udelay(1000);}void string_to_mac(unsigned char *mac, char* s){	int i;	char *e;        for (i=0; i<ETH_ALEN; ++i) {                mac[i] = s ? simple_strtoul(s, &e, 16) : 0;                if (s) {                        s = (*e) ? e+1 : e;                }        }}static void sf_get_mac(unsigned char * p){        unsigned int tmac;        unsigned char* pt;        pt=(unsigned char*)&tmac;        tmac=*(UINT32 *) SF_GLB_DIO(5);        p[0]=pt[1];        p[1]=pt[0];        tmac=*(UINT32 *) SF_GLB_DIO(4);        p[2]=pt[3];        p[3]=pt[2];        p[4]=pt[1];        p[5]=pt[0];}static void sf_set_mac(struct net_device *dev, const unsigned char* mac){	unsigned char t[4]={0};	if(dev)		memcpy(dev->dev_addr,mac,ETH_ALEN);	sf_lock(lp);	t[0]=mac[1];	t[1]=mac[0];	*SF_GLB_DIO(5) = *((UINT32*)t);	t[0]=mac[5];	t[1]=mac[4];	t[2]=mac[3];	t[3]=mac[2];	*SF_GLB_DIO(4) = *((UINT32*)t);	sf_unlock(lp);}void init_sf_mac_env(void){	unsigned char mac[ETH_ALEN];	char* s=getenv("ethaddr");	if(s==NULL)		return;	eth_reset();	string_to_mac(mac,s);	sf_set_mac(sf_port_dev(0), mac);	sf_set_mac(sf_port_dev(1), mac);	sf_print_mac(mac);}#define cmp_mac(ma,mb) (\		(*((unsigned int*))ma==*((unsigned int*)mb)) && \			(((*((unsigned int*)((unsigned char*)ma+4)))&0x0000FFFF)==\			((*((unsigned int*)((unsigned char*)mb+4)))&0x0000FFFF))\			)static int net_port = 1;  		/* 0 is down-link,1 is up-link */static int adaptive_type = 0; 		/* 0 is adaptive,1 is non-adaptive */void get_eth_env(void){	char* s=getenv("netport");	if (s != NULL)	{		if(strcmp("eth0", s) == 0) {			net_port = 1;		}		if(strcmp("eth1", s) == 0) {			net_port = 0;		}	}	if(net_port == 1)		printf("Using Up port.\n");	else if(net_port == 0)		printf("Using Down port.\n");	else {		net_port = 1;		printf("Net port number error!\n");	}	s = getenv("adaptive");	if (s != NULL)	{		if(strcmp("auto", s) == 0) 		{			adaptive_type = 0;		}else		{			adaptive_type = 1;		}	}else	{		adaptive_type =1;	}}static int sf_dev_init(int unit){	struct net_device *dev;	struct sf_local* lp;	unsigned char _sf_mac[ETH_ALEN];	const char *init_stat;	if(unit>1 || unit<0)		return -ENODEV;	dev = alloc_etherdev(sizeof(struct sf_local));	if(dev == NULL)		return -ENOMEM;#if 0	SET_MODULE_OWNER(dev);	dev->base_addr		= SF_REG_BASE;	dev->irq		= HISILICON_SF_IRQ;	dev->open		= sf_open;	dev->stop		= sf_close;	dev->tx_timeout		= sf_tx_timeout;	dev->watchdog_timeo	= 5*HZ;	dev->hard_start_xmit 	= sf_hard_start_xmit;	dev->get_stats		= sf_get_stats;	dev->set_mac_address 	= sf_set_mac_address;	dev->set_config		= sf_set_config;#endif	lp = netdev_priv(dev);	lp->port		= (unit==0 ? 1:0);	spin_lock_init(&lp->lock);	sf_get_mac(_sf_mac);	sf_set_mac(dev,_sf_mac);	if(lp->port) {		lp->phy = hisilicon_phy_connect(SF_UPP_PHY_NAME, SF_UPP_PHY_ID);		init_stat = SF_UPP_INIT_STAT;	} else {		lp->phy = hisilicon_phy_connect(SF_DNP_PHY_NAME, SF_DNP_PHY_ID);		init_stat = SF_DNP_INIT_STAT;	}	lp->auto_conf	= init_stat[0]-'0';	lp->fetch_mod   = init_stat[1]-'0';	lp->link_stat   = init_stat[2]-'0';	lp->duplex_stat = init_stat[3]-'0';	lp->speed_stat  = init_stat[4]-'0';	lp->orig_fetch_mod   = lp->fetch_mod;	lp->phy->probe(lp->port);	sf_port_dev(lp->port) = dev;	netif_carrier_off(dev);	return register_netdev(dev);}static void _sf_stat_static_set(struct net_device *dev){	struct sf_local *lp = netdev_priv(dev);	sf_lock(lp);	SF_SetPortStatusFetchMode(lp->port, lp->fetch_mod==0?2:0);	SF_SetSpeedLinkDuplexMode(lp->port, lp->speed_stat, lp->enabled, lp->duplex_stat);	lp->phy->set_static_mod(lp->port,LP2PHY_STAT(lp));	SF_SetFrameConfiguration(lp->port, 0x03*lp->speed_stat, 90, 0x1FFF);	sf_unlock(lp);}static void _sf_stat_auto_set(struct net_device *dev){	struct sf_local *lp = netdev_priv(dev);	sf_lock(lp);	lp->orig_fetch_mod = lp->fetch_mod;	lp->fetch_mod = 1;	SF_SetPortStatusFetchMode(lp->port, 0);	lp->phy->set_auto_mod(lp->port);	sf_unlock(lp);}static int sf_port_startup(struct net_device *dev){	struct sf_local *lp = netdev_priv(dev);	lp->enabled = 1;	lp->phy->init(lp->port);	if(lp->auto_conf) {		_sf_stat_auto_set(dev);	} else {		lp->link_stat = 1;		_sf_stat_static_set(dev);		netif_carrier_on(dev);	}	return 0;}static int sf_open(struct net_device *dev){	struct sf_local *lp = netdev_priv(dev);	int ret=0;	if(lp->isopen)		return -EPERM;	lp->isopen = 1;	ret = sf_port_startup(dev);	netif_start_queue(dev);	return ret;}static int sf_buffer_init(void){	unsigned long __sf_rxtx_buffer = HISILICON_SF_RXTXBUF_ALIGN(_bss_end);	sf_rxtxbuf = (void*)HISILICON_SF_RXTXBUF_ALIGN(__sf_rxtx_buffer);	memset(sf_rxtxbuf, 0, HISILICON_SF_RXTXBUF_LEN + HISILICON_SF_NATBUF_LEN);        SF_SetExternSdramBufferAddress((unsigned long)sf_rxtxbuf);        SF_NATSetExternFormAddress((unsigned long)sf_rxtxbuf + HISILICON_SF_RXTXBUF_LEN);	printf("SFBuf: 0x%08X - 0x%08X\n", (unsigned int)sf_rxtxbuf, 			(unsigned int)sf_rxtxbuf + HISILICON_SF_RXTXBUF_LEN + HISILICON_SF_NATBUF_LEN - 1);}int eth_init(bd_t * bd){	unsigned long t, n;	struct net_device *dev = NULL;	struct sf_local *lp = NULL;	get_eth_env();	sf_buffer_init();	init_sf_mac_env();	sf_hdw_startup();	sf_dev_init(0);	sf_dev_init(1);	dev = sf_port_dev(net_port);	lp = netdev_priv(dev);	sf_open(sf_port_dev(net_port));	if(!lp->auto_conf) {		printf("Configuring network: ");		for(t=0, n=0; t<20 && n<3; t++) {			unsigned long stat;			udelay(300000);			stat = lp->phy->get_states(net_port);			if(stat == LP2PHY_STAT(lp)) {				printf("+");				if(t==0)					t = 100;				n++;			} else {				n = 0;				printf(">");			}		}		udelay(500000);		printf("\n");	}	return 0;}/* Get a data block via Ethernet */extern int eth_rx (void){	static int rx_idx=0;	UINT16 rxlen=0;	int ret;	int i;	for(i=1; i<=4; i++) {		rxlen=0;        	ret = SF_FrameReceive(i, (UINT32 *)NetRxPackets[rx_idx], &rxlen);		if(rxlen < 60 || net_port!=(ret&0x01))			continue;		NetReceive(NetRxPackets[rx_idx], rxlen);		rx_idx=(rx_idx + 1)%PKTBUFSRX;	}	return rxlen;}static void mem_dump(unsigned char *mem, int len){	int i;	for(i=0; i<len; i++)	{		if(!(i%16))			printf("\n0x%04X:",i);		if(!(i%8))			printf(" ");		printf("%02X",mem[i]);	}	putc('\n');}extern int eth_send (volatile void *packet, int length){ 	if(SF_FrameTransmit(1,net_port, 0,0,(unsigned int)length,0,0,(UINT8 *)packet) != 1) {		printf("Send packet faild, length = %d!\n", length);		mem_dump((unsigned char *)packet, length);	}	return 0;}static int sf_close(struct net_device *dev){	struct sf_local *lp = netdev_priv(dev);	netif_carrier_off(dev);	lp->enabled = 0;	lp->isopen = 0;	lp->link_stat = 0;	_sf_stat_static_set(dev);	lp->phy->exit(lp->port);	return 0;}void eth_halt (void){	int i;	for(i=0; i<2; i++) {		if(sf_port_dev(i)==NULL)			continue;		sf_close(sf_port_dev(i));		free_netdev(sf_port_dev(i));		sf_port_dev(i) = NULL;	}	eth_reset();        SF_SetExternSdramBufferAddress(0);        SF_NATSetExternFormAddress(0);}

⌨️ 快捷键说明

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