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

📄 sl_lepus_gmac.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** Copyright  Storlink Corp 2005.  All rights reserved.                *--------------------------------------------------------------------------* Name			: emac_sl2312.c* Description	: *		Ethernet device driver for Storlink SL2312 Chip** History**	Date		Writer		Description*	-----------	-----------	-------------------------------------------------*	04/25/2005	Gary Chen	Create and implement from Jason's Redboot code*****************************************************************************/#include <define.h>#include <board_config.h>#include <sl2312.h>#if defined(LEPUS_FPGA) || defined(LEPUS_ASIC)#include "sl_lepus_gmac.h"#define SKB_RESERVE_BYTES	16	// to reserve SKB header pointer#define RX_INSERT_BYTES		RX_INSERT_2_BYTE#define GMAC_TXQ_NUM		6#define hal_cache_consistent_sync#define GMAC_EXISTED_FLAG	0x5566abcd/************************************************************* *         Global Variable *************************************************************/static int	gmac_initialized = 0;static TOE_INFO_T toe_private_data;//unsigned int FLAG_SWITCH;extern char broadcast_mac[6];int mac_dump_rxpkt;int mac_dump_txpkt;int mac_status_error;int txbuf_ptr[TOE_SW_TXQ_NUM*TOE_GMAC1_SWTXQ_DESC_NUM];static UINT32 gmac_poll_phy_ticks;#define toe_gmac_enable_interrupt(irq)	REG32(SL2312_INTERRUPT_BASE + SL2312_IRQ_MASK) &= ~(1<<SL2312_INTERRUPT_GMAC0)#define toe_gmac_disable_interrupt(irq)	REG32(SL2312_INTERRUPT_BASE + SL2312_IRQ_MASK) |=  (1<<SL2312_INTERRUPT_GMAC0)void toe_gmac_enable_tx_rx(void);void toe_gmac_disable_tx_rx(void);void gmac_set_mac_address(GMAC_INFO_T *tp, unsigned char *mac1, unsigned char *mac2);unsigned int gmac_num;/*----------------------------------------------------------------------*	gmac_read_reg*----------------------------------------------------------------------*/// static inline unsigned int gmac_read_reg(unsigned int base, unsigned int offset)unsigned int gmac_read_reg(unsigned int base, unsigned int offset){    volatile unsigned int reg_val;    reg_val = readl(base + offset);	return (reg_val);}/*----------------------------------------------------------------------*	gmac_write_reg*----------------------------------------------------------------------*/// static inline void gmac_write_reg(unsigned int base, unsigned int offset,unsigned int data,unsigned int bit_mask)void gmac_write_reg(unsigned int base, unsigned int offset,unsigned int data,unsigned int bit_mask){	volatile unsigned int reg_val;    unsigned int *addr;	reg_val = ( gmac_read_reg(base, offset) & (~bit_mask) ) | (data & bit_mask);	addr = (unsigned int *)(base + offset);    writel(reg_val,addr);	return;}/*----------------------------------------------------------------------* dm_byte*----------------------------------------------------------------------*/void dm_byte(UINT32 location, int length){	UINT8		*start_p, *end_p, *curr_p;	int			in_flash_range = 0;	char		*datap, *cp, data, *bufp;	int			i;	//if (length > 1024)	//	length = 1024;			start_p = (UINT8 *)location;	end_p = start_p + length;		bufp = datap = (char *)malloc(length+128);	if (datap == NULL)	{		dbg_printf(("No free memory!\n"));		return;	}		if (location >= (UINT32)SL2312_FLASH_SHADOW && location <= (UINT32)((UINT32)SL2312_FLASH_SHADOW + 0x10000000))		in_flash_range = 1; 			// read data	if (in_flash_range) hal_flash_enable();	curr_p=(UINT8 *)(location & 0xfffffff0);	cp = datap;	for (; curr_p<end_p;)		*cp++ = *curr_p++;	if (in_flash_range) hal_flash_disable();		curr_p=(UINT8 *)(location & 0xfffffff0);	while (curr_p < end_p)	{		UINT8 *p1, *p2;        printf("0x%08x: ",(UINT32)curr_p & 0xfffffff0);        p1 = curr_p;        p2 = datap;		// dump data		        		for (i=0; i<16; i++)        {			if (curr_p < start_p || curr_p >= end_p)				printf("   ");			else			{				data = *datap;				printf("%02X ", data);			}			if (i==7)				printf("- ");			curr_p++;			datap++;        }		// dump ascii	        		curr_p = p1;		datap = p2;		for (i=0; i<16; i++)		{			if (curr_p < start_p || curr_p >= end_p)				printf(".");			else			{				data = *datap ;				if (data<0x20 || data>0x7f || data==0x25) 					printf(".");				else					printf("%c", data);;			}			curr_p++;			datap++;		}		printf("\n");	} 		free(bufp);}/*----------------------------------------------------------------------*	toe_gmac_disable_tx_rx*----------------------------------------------------------------------*/void toe_gmac_disable_tx_rx(void){	TOE_INFO_T		*toe;	GMAC_INFO_T 	*tp;	GMAC_CONFIG0_T	config0,config0_mask;		toe = (TOE_INFO_T *)&toe_private_data;	tp = (GMAC_INFO_T *)&toe->gmac;		//GMAC_INFO_T		*tp = sc->driver_private;    /* enable TX/RX */    config0.bits32 = 0;    config0_mask.bits32 = 0;    config0.bits.dis_rx = 1;  /* disable rx */    config0.bits.dis_tx = 1;  /* disable tx */    config0_mask.bits.dis_rx = 1;    config0_mask.bits.dis_tx = 1;    gmac_write_reg(tp->base_addr, GMAC_CONFIG0, config0.bits32,config0_mask.bits32);            //printf("toe_gmac_disable_tx_rx tp->base_addr %x  gmac_read_reg(tp->base_addr, GMAC_CONFIG0) : %x\n",tp->base_addr,gmac_read_reg(tp->base_addr, GMAC_CONFIG0));    //printf("toe->gmac.port_id : %x\n",toe->gmac.port_id);}    /*----------------------------------------------------------------------* toe_gmac_sw_reset*----------------------------------------------------------------------*/static void toe_gmac_sw_reset(void){    //REG32(GMAC_GLOBAL_BASE_ADDR + GLOBAL_RESET) |= 0x00000060;    unsigned int	reg_val;	reg_val = REG32(GMAC_GLOBAL_BASE_ADDR+GLOBAL_RESET) | 0x00000060;   /* GMAC0 S/W reset */    REG32(GMAC_GLOBAL_BASE_ADDR+GLOBAL_RESET) = reg_val;    hal_delay_us(100);    return;        return;}/*----------------------------------------------------------------------*	toe_gmac_init_chip*----------------------------------------------------------------------*/static int toe_gmac_init_chip(GMAC_INFO_T *tp){		GMAC_CONFIG0_T	config0,config0_mask;	GMAC_CONFIG1_T	config1;	GMAC_CONFIG2_T	config2_val;	GMAC_CONFIG3_T	config3_val;	unsigned int    status;	GMAC_TX_WCR0_T	hw_weigh;	GMAC_TX_WCR1_T	sw_weigh;	 	/* set PHY operation mode */	status = tp->phy_mode<<5 | 0x11;	if (tp->auto_nego_cfg)    	status |= (tp->full_duplex_status<<3) | (tp->speed_status<<1);	else    	status |= (tp->full_duplex_cfg<<3) | (tp->speed_cfg<<1);    if(gmac_num)    	status = 0x7d;    gmac_write_reg(tp->base_addr, GMAC_STATUS,status, 0x0000007f);    gmac_set_mac_address(tp, tp->mac_addr1, tp->mac_addr2);    /* set RX_FLTR register to receive all multicast packet */    // gmac_write_reg(tp->base_addr, GMAC_RX_FLTR, 0x0000001F,0x0000001f);    //gmac_write_reg(tp->base_addr, GMAC_RX_FLTR, 0x000001f,0x0000001f);    gmac_write_reg(tp->base_addr, GMAC_RX_FLTR,0x000000005,0x00000005);	/* set flow control threshold */	config1.bits32 = 0;	config1.bits.set_threshold = 8;	config1.bits.rel_threshold = 32;    gmac_write_reg(tp->base_addr, GMAC_CONFIG1, config1.bits32,0xffffffff);	/* set SW free queue flow control threshold */	config2_val.bits32 = 0;	config2_val.bits.set_threshold = TOE_SW_FREEQ_DESC_NUM/4;	config2_val.bits.rel_threshold = TOE_SW_FREEQ_DESC_NUM*3/4;	gmac_write_reg(tp->base_addr, GMAC_CONFIG2, config2_val.bits32,0xffffffff);	/* set HW free queue flow control threshold */	config3_val.bits32 = 0;	config3_val.bits.set_threshold = TOE_HW_FREEQ_DESC_NUM/4;	config3_val.bits.rel_threshold = TOE_HW_FREEQ_DESC_NUM*3/4;	gmac_write_reg(tp->base_addr, GMAC_CONFIG3, config3_val.bits32,0xffffffff);    /* disable TX/RX and disable internal loop back */    config0.bits32 = 0;    config0_mask.bits32 = 0;    config0.bits.max_len = 2;    if (tp->flow_control_enable==1)    {        config0.bits.tx_fc_en = 1; /* enable tx flow control */        config0.bits.rx_fc_en = 1; /* enable rx flow control */        //printk("Enable MAC Flow Control...\n");    }    else    {        config0.bits.tx_fc_en = 0; /* disable tx flow control */        config0.bits.rx_fc_en = 0; /* disable rx flow control */        //printk("Disable MAC Flow Control...\n");    }   config0.bits.dis_rx = 1;  /* disable rx */    config0.bits.dis_tx = 1;  /* disable tx */    config0.bits.loop_back = 0; /* enable/disable GMAC loopback */	config0.bits.rgmii_en = 0;#ifdef LEPUS_ASIC	config0.bits.rgmm_edge = 1;	config0.bits.rxc_inv = 0;#else		config0.bits.rgmm_edge =0 ;	config0.bits.rxc_inv = 0;#endif		config0.bits.ipv4_rx_chksum = 1;  /* enable H/W to check ip checksum */	config0.bits.ipv6_rx_chksum = 1;  /* enable H/W to check ip checksum */	config0.bits.port0_chk_hwq = 1;	config0.bits.port1_chk_hwq = 1;	config0.bits.port0_chk_toeq = 1;	config0.bits.port1_chk_toeq = 1;	config0.bits.port0_chk_classq = 1;	config0.bits.port1_chk_classq = 1;	config0.bits.rx_err_detect = 1;    config0_mask.bits.max_len = 7;    config0_mask.bits.tx_fc_en = 1;    config0_mask.bits.rx_fc_en = 1;    config0_mask.bits.dis_rx = 1;    config0_mask.bits.dis_tx = 1;    config0_mask.bits.loop_back = 1;    config0_mask.bits.rgmii_en = 1;    config0_mask.bits.rgmm_edge = 1;    config0_mask.bits.rxc_inv = 1;	config0_mask.bits.ipv4_rx_chksum = 1;  	config0_mask.bits.ipv6_rx_chksum = 1;  	config0_mask.bits.port0_chk_hwq = 1;	config0_mask.bits.port1_chk_hwq = 1;	config0_mask.bits.port0_chk_toeq = 1;	config0_mask.bits.port1_chk_toeq = 1;	config0_mask.bits.port0_chk_classq = 1;	config0_mask.bits.port1_chk_classq = 1;	config0_mask.bits.rx_err_detect = 1;     gmac_write_reg(tp->base_addr, GMAC_CONFIG0, config0.bits32, config0_mask.bits32);         if(gmac_num)    {    	status = 0x796c200;    	gmac_write_reg(tp->base_addr, GMAC_CONFIG0, status, 0xffffffff);	}#if 0	hw_weigh.bits32 = 0;	hw_weigh.bits.hw_tq3 = 1;	hw_weigh.bits.hw_tq2 = 1;	hw_weigh.bits.hw_tq1 = 1;	hw_weigh.bits.hw_tq0 = 1;    gmac_write_reg(tp->dma_base_addr, GMAC_TX_WEIGHTING_CTRL_0_REG, hw_weigh.bits32, 0xffffffff);		sw_weigh.bits32 = 0;	sw_weigh.bits.sw_tq5 = 1;	sw_weigh.bits.sw_tq4 = 1;	sw_weigh.bits.sw_tq3 = 1;	sw_weigh.bits.sw_tq2 = 1;	sw_weigh.bits.sw_tq1 = 1;	sw_weigh.bits.sw_tq0 = 1;    gmac_write_reg(tp->dma_base_addr, GMAC_TX_WEIGHTING_CTRL_1_REG, sw_weigh.bits32, 0xffffffff);#endif	if(gmac_num)    {    	tp->pre_phy_status == LINK_UP;		toe_gmac_enable_tx_rx();    }	return (0);}/*----------------------------------------------------------------------* gmac_set_mac_address*	set mac address*----------------------------------------------------------------------*/void gmac_set_mac_address(GMAC_INFO_T *tp, unsigned char *mac1, unsigned char *mac2){		UINT32 			data;	memcpy(tp->mac_addr1, mac1, ETHER_ADDR_LEN);	memcpy(tp->mac_addr2, mac2, ETHER_ADDR_LEN);	data = mac1[0] + (mac1[1]<<8) + (mac1[2]<<16) + (mac1[3]<<24);	gmac_write_reg(tp->base_addr, GMAC_STA_ADD0, data, 0xffffffff);	data = mac1[4] + (mac1[5]<<8) + (mac2[0]<<16) + (mac2[1]<<24);	gmac_write_reg(tp->base_addr, GMAC_STA_ADD1, data, 0xffffffff);	data = mac2[2] + (mac2[3]<<8) + (mac2[4]<<16) + (mac2[5]<<24);	gmac_write_reg(tp->base_addr, GMAC_STA_ADD2, data, 0xffffffff);}/*----------------------------------------------------------------------*	toe_gmac_enable_tx_rx*----------------------------------------------------------------------*/void toe_gmac_enable_tx_rx(void){	int tmp;	TOE_INFO_T		*toe;	GMAC_INFO_T 	*tp;	GMAC_CONFIG0_T	config0,config0_mask;		toe = (TOE_INFO_T *)&toe_private_data;	tp = (GMAC_INFO_T *)&toe->gmac;	//printf("toe_gmac_disable_tx_rx tp->base_addr %x\n",tp->base_addr);    /* enable TX/RX */    config0.bits32 = 0;    config0_mask.bits32 = 0;    config0.bits.dis_rx = 0;  /* enable rx */    config0.bits.dis_tx = 0;  /* enable tx */    config0_mask.bits.dis_rx = 1;    config0_mask.bits.dis_tx = 1;    gmac_write_reg(tp->base_addr, GMAC_CONFIG0, config0.bits32,config0_mask.bits32);        //printf("toe_gmac_enable_tx_rx tp->base_addr %x  gmac_read_reg(tp->base_addr, GMAC_CONFIG0) : %x\n",tp->base_addr,gmac_read_reg(tp->base_addr, GMAC_CONFIG0));    //printf("toe->gmac.port_id : %x\n",toe->gmac.port_id);    //if(gmac_num)

⌨️ 快捷键说明

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