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

📄 hub.c

📁 RDC R2886 Ethernet hub功能 源码,paradigm c++上运行测试
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 	R2886 sample driver, 09/05/2003 V09C
   RDC semiconductor Co. Ltd
   6F-1, No.2, Lihsin Rd 3, Science-Base Park, HsinChu 300, Taiwan, R.O.C.
   Tel: 886-3-666-2866, FAX: 886-3-563-1498, http://www.rdc.com.tw

   This sample code is very simple. It uses the interrupt driven for
   transmit and receive. It works like as two port HUB. MAC1 receieved
   packet then MAC2 will send. MAC2 received packet then MAC1 will send.

   In normal process, it do nothing.

   In interrupt handler, MAC1 received then MAC2 send. MAC2 received
   then MAC1 send.


   Modification List:
   11/07/2003	Start

*/

#include <systypes.h>					/* Paradigm C++ standard types */
#include <stdio.h>
#include <dos.h>
#include <alloc.h>
#include <embedded.h>
#include "hub.h"

#define 	__CPPARGS
#define	CACHE_CTRL			0x0	/* Cache Control: b15 IC, b14 DC, b11 NCR3, b10 NCR2, b9 NCR1, b8 NCR0, b7 WIR */
#define	REFRESH_COUNT_D	1000		/* Host Clock 100Mhz, 10 us */
#define	SDRAM_MODE_D		0x0030	/* FEF2h, CAS latency 2 */
#define	SDRAM_CTRL_D		0x0009	/* FEF4h, 4M*16bits, SDRAM enable */
#define	SDRAM_TIMING_D		0xF933	/* FEF6h, Tsrx 15clk, Mrx 9clk, Mpc 3clk, RCD 3clk */
#define	SDRAM_DELAYL_D		0x0577	/* FFFAh, Delay Line */

#define	DESC_COUNT		16
#define BUF_SIZE		1536
#define MCR0_DEFAULT	(MC_PRO)
#define	MCR1_DEFAULT	MC_MXLEN1
#define	MBCR_DEFAULT   BC_BLW32 | BC_RHPT32
#define	TXINTC			0		/* TX Interrupt Count */
#define	TXTIMER			0		/* TX interrupt timeout */
#define	RXINTC			0		/* RX Interrupt Count */
#define	RXTIMER			0		/* RX interrupt timeout */
#define 	PFTH				0x0700 /* Pause Frame Threshold */
#define	MAC_ADDRL		0x0000
#define	MAC_ADDRM		0x6000
#define	MAC_ADDRH		0x5001
#define	HOST_CLOCK	125000000L		/* 125M hz */
#define	BAUD_RATE	115200				/* Baud Rate */
#define	UARTBASE0	0xff80
#define	UARTBASE1	0xff10

/* Select Target Board, only can chioce one */
//#define	DEMO_BOARD				/* With SWITCH chip and Kendin PHY chip KS6103 */
#define	EVB_BOARD				/* With INTEL PHY chip LXT972 */

#ifdef	DEMO_BOARD
#define	SWITCH_EN			  /* With SWITCH Chip in EVB */
#define	KEDDIN_PHY_KS6103		/* Keddin PHY chip KS6103 */
#endif

#ifdef	EVB_BOARD
//#define	INTEL_PHY_LXT972	  /* INTEL PHY chip LXT972 */
#define	IP101  			  /* INTEL PHY chip IP101 */
#endif

int	dummy_reserved;
MAC_STRU mac1_info, mac2_info;

void init_system(void);
void init_mac_info(void);
uint32 linear_to_real(uint32);
void init_mac_desc(MAC_STRU *, RDC_DESCRIPTOR *, char *);
int init_mac_reg(MAC_STRU *);
int find_phy_addr(MAC_STRU *);
int mii_write(MAC_STRU *, int, int);
int mii_read(MAC_STRU *, int);
int send_pkt(MAC_STRU *, char *, int);
void send_complete(MAC_STRU *);
void receive_pkt(MAC_STRU *);
void alloc_rx_buf(MAC_STRU *);
void _interrupt int4_handler(__CPPARGS);
void mac_handler(MAC_STRU *);
void mac_tx_handler(MAC_STRU *);
void mac_rx_handler(MAC_STRU *);
void delaye(void);
void Loops(void);
void FlashLed(void);
void _interrupt uart0_handler(__CPPARGS);
void _interrupt uart1_handler(__CPPARGS);
uint32 linear_to_real(uint32 linear_addr);
void PutStr(int p,char *pstr);
void PutCh(int p,char ch);



void adjust_buffer(void)
{
   RDC_DESCRIPTOR *rxd_ptr, *txd_ptr;
   int i;

   /* Let MAC1 TX buffer same to MAC2 RX buffer */
   rxd_ptr = mac2_info.rx_insert_ptr;
   txd_ptr = mac1_info.tx_insert_ptr;

   for (i = 0; i < DESC_COUNT; i++) {
   	txd_ptr->buf_ptr = rxd_ptr->buf_ptr;
   	txd_ptr->vbuf_ptr = rxd_ptr->vbuf_ptr;
      txd_ptr = txd_ptr->vndesc_ptr;
      rxd_ptr = rxd_ptr->vndesc_ptr;
	}

   /* Let MAC2 TX buffer same to MAC1 RX buffer */
   txd_ptr = mac2_info.tx_insert_ptr;
   rxd_ptr = mac1_info.rx_insert_ptr;

   for (i = 0; i < DESC_COUNT; i++) {
   	txd_ptr->buf_ptr = rxd_ptr->buf_ptr;
   	txd_ptr->vbuf_ptr = rxd_ptr->vbuf_ptr;
      txd_ptr = txd_ptr->vndesc_ptr;
      rxd_ptr = rxd_ptr->vndesc_ptr;
	}
}

/* Cache Function Setting                          */
void cache_set(char * buf_pool)
{
	uint32 real_addr;
   uint16 loww, highw;

   real_addr = linear_to_real((uint32)buf_pool);

   /* Non-Cache Region0 for MAC descriptor and buffer */
	loww = (uint16)real_addr & 0xFFFF;
   highw = (uint16)(real_addr >> 16);
   outport(0xfec2, loww);			/* NCR0 start low word */
   outport(0xfec4, highw);			/* NCR0 start high word */
   real_addr += (0x1020 + BUF_SIZE * DESC_COUNT);
	loww = (uint16)real_addr & 0xFFFF;
   highw = (uint16)(real_addr >> 16);
   outport(0xfec6, loww);			/* NCR0 end low word */
   outport(0xfec8, highw);			/* NCR0 end high word */

   /* Cache Control Setting */
   outport(0xfec0, CACHE_CTRL | 0x0100);	/* NCR0 enable */
}


/* Main routine for HUB Program */
void main(void)
{
	char 	*mac_memory_ptr, *buf_ptr;
                RDC_DESCRIPTOR *desc_ptr;


	/* Init sysytem */
   init_system();

   /* Allocate MAC information structure */
   mac_memory_ptr = (char *)malloc(0x1020 + BUF_SIZE * DESC_COUNT * 2);
   mac_memory_ptr = (char *) (((unsigned long)mac_memory_ptr + 0xf) & ~0xf);

   /* Cache Setting */
   cache_set(mac_memory_ptr);

   /* Init MAC information */
   init_mac_info();

   /* Init descriptor */
   desc_ptr = (RDC_DESCRIPTOR *) mac_memory_ptr;
   buf_ptr = (char *) (mac_memory_ptr + 0x1000);	/* Allocate 4K for descriptor area */
   init_mac_desc(&mac1_info, desc_ptr, buf_ptr);
   init_mac_desc(&mac2_info, desc_ptr + DESC_COUNT * 2, buf_ptr + BUF_SIZE * DESC_COUNT);
	/* For HUB function, MAC1 TX same to MAC2 RX, MAC1 RX same to MAC2 TX */
   adjust_buffer();

	/* Init & Activate MAC */
   init_mac_reg(&mac1_info);
   init_mac_reg(&mac2_info);

   /* Enable INT4 and level trigger mode */
   outport(INTC_INT4, 0x0017);
   outport(0xff28, 0xfeff);
 
 //  outport(0xff28, 0x06fd);
   
     /* Enable UART0 interrupt */
   outport(0xff44, 0x0000);	/* UART0 priority 0, enable */
//   outport(0xff28, 0x03fd);	/* UART0 interrupt enable */

   /* Enable UART1 interrupt */
   outport(0xff42, 0x0000);	/* UART1 priority 0, enable */
   outport(0xff28, 0x00fd);	/* UART0 and UART1 interrupt enable */
   
   /* Register Interrupt 4 handler */
   setvect(INT4_TYPE, int4_handler);
   
       /* Register UART0 Interrupt handler */
   setvect(UART0_TYPE, uart0_handler);

   /* Register UART1 Interrupt handler */
   setvect(UART1_TYPE, uart1_handler);
   
   /* normal process */
   do {
   	outport(PIO_DATA1_REG, (unsigned int)mac1_info.TxSuccCounter);
   	   	FlashLed();	
   } while(1);

}





/* Linear address to physical address */
uint32 linear_to_real(uint32 linear_addr)
{
	uint32 real_addr;

   real_addr = (linear_addr & 0xffff0000L) >> 8;
   real_addr += (linear_addr & 0x0000ffffL);
   return real_addr;
}
/* Intilize MAC information structure */
void init_mac_info(void)
{
	/* MAC1 information structure */
   mac1_info.io_base = 0xfd00;
   mac1_info.TxFreeDesc = DESC_COUNT;
   mac1_info.RxFreeDesc = DESC_COUNT;
   mac1_info.next_mac = &mac2_info;
   mac1_info.sn = 0;
   mac1_info.phy_addr = PHY1_ADDR;	//Miles
   
	/* MAC2 information structure */
   mac2_info.io_base = 0xfe00;
   mac2_info.TxFreeDesc = DESC_COUNT;
   mac2_info.RxFreeDesc = DESC_COUNT;
   mac2_info.next_mac = &mac1_info;
   mac2_info.sn = 1;
   mac2_info.phy_addr = PHY2_ADDR;	//Miles
}

/* Initilize MAC control registers */
int init_mac_reg(MAC_STRU *mac_ipr)
{
	unsigned int	tmpv, phy_status, mac_duplex, mac_mctl;
	int	io_base = mac_ipr->io_base;

   /* Software Reset MAC */
   outport(io_base + IO_MCR1, 0x01);
   while(inport(io_base + IO_MCR1) & 0x01);

   /* Set TX/RX descriptor start address */
	outport(io_base + IO_MTDSR0, (uint16)(mac_ipr->txd_raddr & 0xffff));
	outport(io_base + IO_MTDSR1, (uint16)(mac_ipr->txd_raddr >> 16));
	outport(io_base + IO_MRDSR0, (uint16)(mac_ipr->rxd_raddr & 0xffff));
	outport(io_base + IO_MRDSR1, (uint16)(mac_ipr->rxd_raddr >> 16));

   /* Set Special Control Register */
   outport(io_base + IO_MCR1, MCR1_DEFAULT);

   /* Set MAC control register */
   outport(io_base + IO_MCR0, MCR0_DEFAULT);

   /* Enabel TX threshold function */
   //outport(io_base + IO_MTSCF, inport(io_base + IO_MTSCF) | 0x0004);

   /* Set Bus Control register */
   outport(io_base + IO_MBCR, MBCR_DEFAULT);

   /* RX descriptor count register */
   outport(io_base + IO_MRDC, DESC_COUNT | PFTH);

   /* RX buffer size register */
   outport(io_base + IO_MRBS, BUF_SIZE > 2047 ? 2046:BUF_SIZE);

   /* TX interrupt count & timer */
   outport(io_base + IO_MTICR, TXINTC * 0x100 + TXTIMER);

   /* RX interrupt count & timer */
   outport(io_base + IO_MRICR, RXINTC * 0x100 + RXTIMER);

   /* SWITCH CHIP, MAC2 directly connect SWITCH chip and always use full-duplex mode */
#ifdef SWITCH_EN
	if (mac_ipr->sn == 1) {
		mac_duplex = MC_FULLD;
      goto set_mac_duplex;
   }
#endif

   /* Find PHY address */
   //if (find_phy_addr(mac_ipr)) return 1;


   /* INTEL PHY Special setting */
#ifdef INTEL_PHY_LXT972
   mii_write(mac_ipr, 0x14, 0x0DE2);	/* LED mode */
   mii_write(mac_ipr, 0x12, 0x00F2);	/* PHY INT request enable */
   mii_read(mac_ipr, 0x13);				/* Clear INT request status */
#endif

   /* PHY media mode check */
   /* Wait PHY link OK */
   outport(0x80, 0x03);
   while(!((phy_status = mii_read(mac_ipr, 0x1)) & 0x4));

   /* PHY mode check */
   phy_status = mii_read(mac_ipr, 0x0);
   if (phy_status & 0x1000) { /* N-WAY mode */
	   /* Wait PHY N-WAY complete */
   	while(!(mii_read(mac_ipr, 0x1) & 0x20));
      phy_status = mii_read(mac_ipr, 0x05);
      phy_status &= mii_read(mac_ipr, 0x04);
      mac_duplex = (phy_status & 0x0140) ? MC_FULLD:0;
   } else { /* Force Mode */
      mac_duplex = (phy_status & 0x0100) ? MC_FULLD:0;
   }
   outport(0x80, 0x0c);

   /* MAC duplex mode */
set_mac_duplex:
   mac_mctl = (MCR0_DEFAULT & ~MC_FULLD) | mac_duplex;
   outport(io_base + IO_MCR0, mac_mctl);

   /* Set MAC address and multi-case address,
   	Now no multicast address. Let all address regsiter
   	have same MAC address 	  											*/
   tmpv = io_base + IO_MID0L;
   do {
   	outport(tmpv, MAC_ADDRL);
   	outport(tmpv + 2, MAC_ADDRM);
   	outport(tmpv + 4, MAC_ADDRH);
      tmpv += 8;
	} while(tmpv < (io_base + IO_MID3H));

   /* Everything Done, Now activate TX/RX machine */
   tmpv = inport(io_base + IO_MCR0) | MC_XMTEN | MC_RCVEN;
   outport(io_base + IO_MCR0, tmpv);

   /* Enable interrupt */
   outport(io_base + IO_MIMR, INT_TXEE | INT_RXEE);

   return 0;
}


/* Initilize MAC TX/RX descriptor */
void init_mac_desc(MAC_STRU *mac_ipr, RDC_DESCRIPTOR *desc_ptr, char *buf_ptr)
{
	uint32 r_desc_addr, r_buf_addr;
	int	i;

   mac_ipr->tx_insert_ptr = desc_ptr;
   mac_ipr->tx_remove_ptr = desc_ptr;
   mac_ipr->rx_insert_ptr = (desc_ptr + DESC_COUNT);
   mac_ipr->rx_remove_ptr = mac_ipr->rx_insert_ptr;
   r_desc_addr = linear_to_real((uint32)desc_ptr);
   r_buf_addr = linear_to_real((uint32)buf_ptr);

   /* Init TX descriptor: Don't allocate TX buffer */
   mac_ipr->txd_raddr = r_desc_addr;
   for (i = 0; i < DESC_COUNT; i++) {
		desc_ptr->status = 0;
      desc_ptr->len = 0;
      desc_ptr->ndesc_ptr = r_desc_addr + RDC_DESC_SIZE;
      desc_ptr->vndesc_ptr = desc_ptr + 1;
      r_desc_addr += RDC_DESC_SIZE;
		buf_ptr = (buf_ptr + BUF_SIZE);
      desc_ptr = desc_ptr + 1;
   }
   (desc_ptr - 1)->ndesc_ptr = mac_ipr->txd_raddr;
   (desc_ptr - 1)->vndesc_ptr = mac_ipr->tx_insert_ptr;

   /* Init RX descriptor: Allocate RX buffer */
   mac_ipr->rxd_raddr = r_desc_addr;
   for (i = 0; i < DESC_COUNT; i++) {
      desc_ptr->len = 0;
      desc_ptr->buf_ptr = r_buf_addr;
      desc_ptr->ndesc_ptr = r_desc_addr + RDC_DESC_SIZE;
      desc_ptr->vbuf_ptr = buf_ptr;

⌨️ 快捷键说明

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