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

📄 gmac_sl2312.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** 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>#ifdef MIDWAY#include "gmac_sl2312.h"#define diag_printf			printf    /************************************************************* *         Global Variable *************************************************************/unsigned int FLAG_SWITCH = 0;	/* if 1-->switch chip presented. if 0-->switch chip unpresented */int vlan_enabled;GMAC_INFO_T gmac_private_data;//static unsigned int     tx_free_desc = TX_DESC_NUM;static unsigned int     flow_control_enable = 0;//static unsigned int     tx_desc_virtual_base = 0;//static unsigned int     rx_desc_virtual_base = 0;//static unsigned int     tx_buf_virtual_base = 0;//static unsigned int     rx_buf_virtual_base = 0;unsigned int     		full_duplex = 1;unsigned int			chip_id=0;void gmac_disable_tx_rx(void);void gmac_enable_tx_rx(void);#ifdef BOARD_DCACHE_ON	typedef struct {		unsigned char	tx_desc_array[TX_DESC_NUM * sizeof(GMAC_DESCRIPTOR_T)] __attribute__((aligned(32)));		unsigned char	rx_desc_array[RX_DESC_NUM * sizeof(GMAC_DESCRIPTOR_T)]  __attribute__((aligned(32)));		unsigned char	tx_buf_array[TX_BUF_TOT_LEN] __attribute__((aligned(32)));		unsigned char	rx_buf_array[RX_BUF_TOT_LEN] __attribute__((aligned(32)));		unsigned long	last_word;	} GMAC_NONCACHE_MEM_T;	GMAC_NONCACHE_MEM_T 	*gmac_noncache_mem = (GMAC_NONCACHE_MEM_T *)BOARD_DRAM_NONCACHE_BASE;	static unsigned char    *tx_desc_array;	static unsigned char    *rx_desc_array;	static unsigned char	*rx_buf_array;	static unsigned char    *tx_buf_array;#else	static unsigned char    tx_desc_array[TX_DESC_NUM * sizeof(GMAC_DESCRIPTOR_T)] __attribute__((aligned(32))); 	static unsigned char    rx_desc_array[RX_DESC_NUM * sizeof(GMAC_DESCRIPTOR_T)] __attribute__((aligned(32)));	static unsigned char    tx_buf_array[TX_BUF_TOT_LEN] __attribute__((aligned(32)));	static unsigned char    rx_buf_array[RX_BUF_TOT_LEN] __attribute__((aligned(32)));#endif/************************************************//*                 function declare             *//************************************************/void gmac_set_mac_addr(unsigned char *mac1, unsigned char *mac2);extern void gmac_set_phy_status(void);extern void gmac_get_phy_status(void);extern char *sys_get_mac_addr(int index);static void gmac_sl2312_start(void);void sl2312_gmac_deliver(void);void sl2312_gmac_diag_poll(void);void gmac_sl2312_send(char *bufp, int total_len);inline void gmac_sl2312_send_diag(GMAC_INFO_T *tp, char *bufp, int total_len);#define sl2312_eth_enable_interrupt()	REG32(SL2312_INTERRUPT_BASE + SL2312_IRQ_MASK) &= ~(1<<SL2312_INTERRUPT_GMAC0)#define sl2312_eth_disable_interrupt()	REG32(SL2312_INTERRUPT_BASE + SL2312_IRQ_MASK) |=  (1<<SL2312_INTERRUPT_GMAC0)/****************************************//*	SPI Function Declare		*//****************************************/extern void SPI_default(int vlan_enabled);extern unsigned int SPI_get_identifier(void);extern void enet_get_mac_addr(unsigned char* mac);/****************************************//*	VLAN Function Declare		        *//****************************************//************************************************//*                 function body                *//************************************************/#define gmac_read_reg(offset)					REG32(GMAC_BASE_ADDR + offset)#define gmac_write_reg(offset, data, mask)		REG32(GMAC_BASE_ADDR + offset) = 	\												(gmac_read_reg(offset) & (~mask)) | \												(data & mask)//static int __init gmac_init_module(void)int gmac_sl2312_init(void){	chip_id = REG32(SL2312_GLOBAL_BASE + GLOBAL_ID) & 0xff;	FLAG_SWITCH = 0 ;	FLAG_SWITCH = SPI_get_identifier();	if(FLAG_SWITCH)	{			diag_printf("\nConfig ADM699X...\n");		SPI_default(vlan_enabled);	//Add by jason for ADM6996 config	}#ifdef GEMINI_ASIC	/* set GMAC global register */    REG32(SL2312_GLOBAL_BASE+0x10)=0x00520000;    REG32(SL2312_GLOBAL_BASE+0x1c)=0x077707f0;    REG32(SL2312_GLOBAL_BASE+0x20)=0x77770000;#endif		gmac_sl2312_start();	    return TRUE;}	/*----------------------------------------------------------------------* gmac_set_mac_addr*	set mac address*----------------------------------------------------------------------*/void gmac_set_mac_addr(unsigned char *mac1, unsigned char *mac2){	UINT32 data;	data = mac1[0] + (mac1[1]<<8) + (mac1[2]<<16) + (mac1[3]<<24);	gmac_write_reg(GMAC_STA_ADD0, data, 0xffffffff);	data = mac1[4] + (mac1[5]<<8) + (mac2[0]<<16) + (mac2[1]<<24);	gmac_write_reg(GMAC_STA_ADD1, data, 0xffffffff);	data = mac2[2] + (mac2[3]<<8) + (mac2[4]<<16) + (mac2[5]<<24);	gmac_write_reg(GMAC_STA_ADD2, data, 0xffffffff);}        			/*----------------------------------------------------------------------* gmac_init_chip*----------------------------------------------------------------------*/static int gmac_init_chip(void){	GMAC_RBNR_T		rbnr_val,rbnr_mask;	GMAC_CONFIG2_T	config2_val;	GMAC_CONFIG0_T	config0,config0_mask;	GMAC_CONFIG1_T	config1;	UINT32 data;	/* chip reset */	     /* set RMII mode for testing */    if (full_duplex == 1)    {        gmac_write_reg(GMAC_STATUS,0x0000001b,0x0000001f);  /* 100M full duplex */    }    else    {            gmac_write_reg(GMAC_STATUS,0x00000013,0x0000001f);    /* 100M half duplex */	}    gmac_get_phy_status();        gmac_set_mac_addr(sys_get_mac_addr(0), sys_get_mac_addr(1));        /* set RX_FLTR register to receive all multicast packet */    gmac_write_reg(GMAC_RX_FLTR,0x0000000f,0x0000001f);//    gmac_write_reg(GMAC_RX_FLTR,0x00000001,0x0000001f);	/* set per packet buffer size */	config1.bits32 = 0;    config1.bits.buf_size = 11; /* buffer size = 2048-byte */    gmac_write_reg(GMAC_CONFIG1,config1.bits32,0x0000000f);		/* set flow control threshold */	config2_val.bits32 = 0;	config2_val.bits.set_threshold = RX_DESC_NUM/4;	config2_val.bits.rel_threshold = RX_DESC_NUM*3/4;	gmac_write_reg(GMAC_CONFIG2,config2_val.bits32,0xffffffff);	/* init remaining buffer number register */	rbnr_val.bits32 = 0;	rbnr_val.bits.buf_remain = RX_DESC_NUM;	rbnr_mask.bits32 = 0;	rbnr_mask.bits.buf_remain = 0xffff;	 	gmac_write_reg(GMAC_RBNR,rbnr_val.bits32,rbnr_mask.bits32);    /* disable TX/RX and disable internal loop back */    config0.bits32 = 0;    config0_mask.bits32 = 0;    config0.bits.max_len = 2;    config0.bits.tx_fc_en = 1; /* enable tx flow control */    config0.bits.rx_fc_en = 1; /* enable rx flow control */    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.inv_rx_clk = 0;	config0.bits.rising_latch = 1;    config0_mask.bits.max_len = 3;    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.inv_rx_clk = 1;	config0_mask.bits.rising_latch = 1;    gmac_write_reg(GMAC_CONFIG0,config0.bits32,config0_mask.bits32);    	flow_control_enable = 1; /* enable flow control flag */	//flow_control_enable = 0; /* enable flow control flag */	return (0);}/*----------------------------------------------------------------------* gmac_enable_tx_rx*----------------------------------------------------------------------*/void gmac_enable_tx_rx(void){	GMAC_CONFIG0_T	config0,config0_mask;    /* 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(GMAC_CONFIG0,config0.bits32,config0_mask.bits32);    }/*----------------------------------------------------------------------* gmac_disable_tx_rx*----------------------------------------------------------------------*/void gmac_disable_tx_rx(void){	GMAC_CONFIG0_T	config0,config0_mask;    /* 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(GMAC_CONFIG0,config0.bits32,config0_mask.bits32);    }    /*----------------------------------------------------------------------* gmac_hw_start*----------------------------------------------------------------------*/static void gmac_hw_start(void){	GMAC_INFO_T     		*tp = (GMAC_INFO_T *)&gmac_private_data;	GMAC_TXDMA_CURR_DESC_T	tx_desc;	GMAC_RXDMA_CURR_DESC_T	rx_desc;    GMAC_TXDMA_CTRL_T       txdma_ctrl,txdma_ctrl_mask;    GMAC_RXDMA_CTRL_T       rxdma_ctrl,rxdma_ctrl_mask;	GMAC_DMA_STATUS_T       dma_status,dma_status_mask;		/* program TxDMA Current Descriptor Address register for first descriptor */	tx_desc.bits32 = (unsigned int)(tp->tx_desc_dma);	tx_desc.bits.eofie = 1;//	tx_desc.bits.dec = 0;	tx_desc.bits.sof_eof = 0x03;	gmac_write_reg(GMAC_TXDMA_CURR_DESC,tx_desc.bits32,0xffffffff);	gmac_write_reg(0xff2c,tx_desc.bits32,0xffffffff);   /* tx next descriptor address */		/* program RxDMA Current Descriptor Address register for first descriptor */	rx_desc.bits32 = (unsigned int)(tp->rx_desc_dma);	rx_desc.bits.eofie = 1;//	rx_desc.bits.dec = 0;	rx_desc.bits.sof_eof = 0x03;	gmac_write_reg(GMAC_RXDMA_CURR_DESC,rx_desc.bits32,0xffffffff);	gmac_write_reg(0xff3c,rx_desc.bits32,0xffffffff);   /* rx next descriptor address */	    		/* enable GMAC interrupt & disable loopback */	dma_status.bits32 = 0;	dma_status.bits.loop_back = 0;  /* disable DMA loop-back mode */	dma_status.bits.m_cnt_full = 1;	dma_status.bits.m_rx_pause_on = 1;	dma_status.bits.m_tx_pause_on = 1;	dma_status.bits.m_rx_pause_off = 1;	dma_status.bits.m_tx_pause_off = 1;	dma_status.bits.m_rx_overrun = 1;	dma_status_mask.bits32 = 0;	dma_status_mask.bits.loop_back = 1;	dma_status_mask.bits.m_cnt_full = 1;	dma_status_mask.bits.m_rx_pause_on = 1;	dma_status_mask.bits.m_tx_pause_on = 1;	dma_status_mask.bits.m_rx_pause_off = 1;	dma_status_mask.bits.m_tx_pause_off = 1;	dma_status_mask.bits.m_rx_overrun = 1;	gmac_write_reg(GMAC_DMA_STATUS,dma_status.bits32,dma_status_mask.bits32);    /* program tx dma control register */		txdma_ctrl.bits32 = 0;	txdma_ctrl.bits.td_start = 0;    	txdma_ctrl.bits.td_continue = 0; 	txdma_ctrl.bits.td_chain_mode = 1; /* chain mode */	txdma_ctrl.bits.td_prot = 0;	txdma_ctrl.bits.td_burst_size = 2;	txdma_ctrl.bits.td_bus = 0;	txdma_ctrl.bits.td_endian = 0;	txdma_ctrl.bits.td_finish_en = 1;	txdma_ctrl.bits.td_fail_en = 1;	txdma_ctrl.bits.td_perr_en = 1;	txdma_ctrl.bits.td_eod_en = 0; /* disable Tx End of Descriptor Interrupt */	txdma_ctrl.bits.td_eof_en = 1;	txdma_ctrl_mask.bits32 = 0;	txdma_ctrl_mask.bits.td_start = 1;    	txdma_ctrl_mask.bits.td_continue = 1; 	txdma_ctrl_mask.bits.td_chain_mode = 1;	txdma_ctrl_mask.bits.td_prot = 15;	txdma_ctrl_mask.bits.td_burst_size = 3;	txdma_ctrl_mask.bits.td_bus = 1;	txdma_ctrl_mask.bits.td_endian = 1;	txdma_ctrl_mask.bits.td_finish_en = 1;	txdma_ctrl_mask.bits.td_fail_en = 1;	txdma_ctrl_mask.bits.td_perr_en = 1;	txdma_ctrl_mask.bits.td_eod_en = 1;	txdma_ctrl_mask.bits.td_eof_en = 1;	gmac_write_reg(GMAC_TXDMA_CTRL,txdma_ctrl.bits32,txdma_ctrl_mask.bits32);	    /* program rx dma control register */		rxdma_ctrl.bits32 = 0;	rxdma_ctrl.bits.rd_start = 1;    /* start RX DMA transfer */	rxdma_ctrl.bits.rd_continue = 1; /* continue RX DMA operation */	rxdma_ctrl.bits.rd_chain_mode = 1;   /* chain mode */	rxdma_ctrl.bits.rd_prot = 0;	rxdma_ctrl.bits.rd_burst_size = 2;	rxdma_ctrl.bits.rd_bus = 0;	rxdma_ctrl.bits.rd_endian = 0;	rxdma_ctrl.bits.rd_finish_en = 1;	rxdma_ctrl.bits.rd_fail_en = 1;	rxdma_ctrl.bits.rd_perr_en = 1;	rxdma_ctrl.bits.rd_eod_en = 0; /* disable Rx End of Descriptor Interrupt */	rxdma_ctrl.bits.rd_eof_en = 1;	rxdma_ctrl_mask.bits32 = 0;	rxdma_ctrl_mask.bits.rd_start = 1;    	rxdma_ctrl_mask.bits.rd_continue = 1; 	rxdma_ctrl_mask.bits.rd_chain_mode = 1;	rxdma_ctrl_mask.bits.rd_prot = 15;	rxdma_ctrl_mask.bits.rd_burst_size = 3;	rxdma_ctrl_mask.bits.rd_bus = 1;	rxdma_ctrl_mask.bits.rd_endian = 1;	rxdma_ctrl_mask.bits.rd_finish_en = 1;	rxdma_ctrl_mask.bits.rd_fail_en = 1;	rxdma_ctrl_mask.bits.rd_perr_en = 1;	rxdma_ctrl_mask.bits.rd_eod_en = 1;	rxdma_ctrl_mask.bits.rd_eof_en = 1;	gmac_write_reg(GMAC_RXDMA_CTRL,rxdma_ctrl.bits32,rxdma_ctrl_mask.bits32);    return;	}	/*----------------------------------------------------------------------* gmac_hw_stop*----------------------------------------------------------------------*/static void gmac_hw_stop(void){    GMAC_TXDMA_CTRL_T       txdma_ctrl,txdma_ctrl_mask;    GMAC_RXDMA_CTRL_T       rxdma_ctrl,rxdma_ctrl_mask;    /* program tx dma control register */		txdma_ctrl.bits32 = 0;	txdma_ctrl.bits.td_start = 0;    	txdma_ctrl.bits.td_continue = 0; 	txdma_ctrl_mask.bits32 = 0;	txdma_ctrl_mask.bits.td_start = 1;    	txdma_ctrl_mask.bits.td_continue = 1; 		gmac_write_reg(GMAC_TXDMA_CTRL,txdma_ctrl.bits32,txdma_ctrl_mask.bits32);    /* program rx dma control register */		rxdma_ctrl.bits32 = 0;	rxdma_ctrl.bits.rd_start = 0;    /* stop RX DMA transfer */	rxdma_ctrl.bits.rd_continue = 0; /* stop continue RX DMA operation */	rxdma_ctrl_mask.bits32 = 0;	rxdma_ctrl_mask.bits.rd_start = 1;    	rxdma_ctrl_mask.bits.rd_continue = 1; 	gmac_write_reg(GMAC_RXDMA_CTRL,rxdma_ctrl.bits32,rxdma_ctrl_mask.bits32);}/*----------------------------------------------------------------------* gmac_init_desc_buf*----------------------------------------------------------------------*/static int gmac_init_desc_buf(void){	GMAC_INFO_T  *tp = (GMAC_INFO_T *)&gmac_private_data;	dma_addr_t   tx_first_desc_dma;	dma_addr_t   rx_first_desc_dma;	dma_addr_t   tx_first_buf_dma;	dma_addr_t   rx_first_buf_dma;	int    i;#ifdef BOARD_DCACHE_ON	tx_desc_array = (unsigned char *)&gmac_noncache_mem->tx_desc_array[0];	rx_desc_array = (unsigned char *)&gmac_noncache_mem->rx_desc_array[0];	tx_buf_array  = (unsigned char *)&gmac_noncache_mem->tx_buf_array[0];	rx_buf_array  = (unsigned char *)&gmac_noncache_mem->rx_buf_array[0];#endif	/* allocates TX/RX DMA packet buffer */	tp->tx_bufs = (unsigned char *)tx_buf_array;	// memset(tp->tx_bufs,0x00,TX_BUF_TOT_LEN);	tp->rx_bufs = (unsigned char *)rx_buf_array;	// memset(tp->rx_bufs,0x00,RX_BUF_TOT_LEN);    tp->tx_bufs_dma = (unsigned int)tp->tx_bufs;    tp->rx_bufs_dma = (unsigned int)tp->rx_bufs;//    diag_printf("tx_bufs = %08x\n",(unsigned int)tp->tx_bufs);//    diag_printf("rx_bufs = %08x\n",(unsigned int)tp->rx_bufs);		/* allocates TX/RX descriptors */	tp->tx_desc = (GMAC_DESCRIPTOR_T *)tx_desc_array;    memset(tp->tx_desc,0x00,TX_DESC_NUM*sizeof(GMAC_DESCRIPTOR_T));	tp->rx_desc = (GMAC_DESCRIPTOR_T *)rx_desc_array;    memset(tp->rx_desc,0x00,RX_DESC_NUM*sizeof(GMAC_DESCRIPTOR_T));   // diag_printf("tx_desc = %08x\n",(unsigned int)tp->tx_desc);   // diag_printf("rx_desc = %08x\n",(unsigned int)tp->rx_desc);		/* TX descriptors initial */	tp->tx_cur_desc = tp->tx_desc;  /* virtual address */	tp->tx_finished_desc = tp->tx_desc; /* virtual address */	tp->tx_desc_dma = (unsigned int)tp->tx_desc;	tx_first_desc_dma = tp->tx_desc_dma; /* physical address */    tx_first_buf_dma = tp->tx_bufs_dma;	for (i = 1; i < TX_DESC_NUM; i++)	{		tp->tx_desc->frame_ctrl.bits_tx_out.own = CPU; /* set owner to CPU */

⌨️ 快捷键说明

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