?? hub.c
字號(hào):
/*
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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -