📄 dm9ks_ucos.c
字号:
#include "dm9ks.h"
#include "netif.h"
#include "eth.h"
#include "dm9ks_ucos.h"
//#include "define.h"
#define DM9000AE_INT_HI /* interrupt polarity high active */
#define LEDMODE1
#define DM9008AE
#define DM9KS_BYTE_MODE 2
#define DM9KS_WORD_MODE 0
#define DM9KS_DWORD_MODE 1
#define NUM_MAX_NETBUF 32
#define TRUE 1
#define FALSE 0
typedef unsigned char u8;
typedef unsigned long u32;
#define DM9KS_ID 0x90000A46
#define DM9010_ID 0x90100A46
/*-------register name-----------------------*/
#define DM9KS_NCR 0x00 /* Network control Reg.*/
#define DM9KS_NSR 0x01 /* Network Status Reg.*/
#define DM9KS_TCR 0x02 /* TX control Reg.*/
#define DM9KS_TSRI 0x03
#define DM9KS_TSRII 0x04
#define DM9KS_RXCR 0x05 /* RX control Reg.*/
#define DM9KS_RSR 0x06
#define DM9KS_ROCR 0x07
#define DM9KS_BPTR 0x08
#define DM9KS_FCTR 0x09
#define DM9KS_FCR 0x0a
#define DM9KS_EPCR 0x0b
#define DM9KS_EPAR 0x0c
#define DM9KS_EPDRL 0x0d
#define DM9KS_EPDRH 0x0e
#define DM9KS_WCR 0x0f
#define DM9KS_GPCR 0x1e
#define DM9KS_GPR 0x1f /* General purpose register */
#define DM9KS_TRPAL 0x22
#define DM9KS_TRPAH 0x23
#define DM9KS_RWPAL 0x24
#define DM9KS_RWPAH 0x25
#define DM9KS_VID_L 0x28
#define DM9KS_VID_H 0x29
#define DM9KS_PID_L 0x2A
#define DM9KS_PID_H 0x2B
#define DM9KS_CHIPR 0x2C
#define DM9KS_TCR2 0x2d
#define DM9KS_OCR 0x2E
#define DM9KS_SMCR 0x2f /* Special Mode Control Reg.*/
#define DM9KS_ETXCSR 0x30 /* Early Transmit control/status Reg.*/
#define DM9KS_TCCR 0x31 /* Checksum cntrol Reg. */
#define DM9KS_RCSR 0x32 /* Receive Checksum status Reg.*/
#define DM9KS_MPAR 0x33
#define DM9KS_LEDCR 0x34
#define DM9KS_BUSCR 0x38
#define DM9KS_INTCR 0x39
#define DM9KS_SCCR 0x50
#define DM9KS_RSCCR 0x51
#define DM9KS_MRCMDX 0xf0
#define DM9KS_MRCMDX1 0xf1
#define DM9KS_MRCMD 0xf2
#define DM9KS_MDRAL 0xf4
#define DM9KS_MDRAH 0xf5
#define DM9KS_MWCMDX 0xf6
#define DM9KS_MWCMD 0xf8
#define DM9KS_MWRL 0xfa
#define DM9KS_MWRH 0xfb
#define DM9KS_TXPLL 0xfc
#define DM9KS_TXPLH 0xfd
#define DM9KS_ISR 0xfe
#define DM9KS_IMR 0xff
/*---------------------------------------------*/
#define DM9KS_REG05 0x30 /* SKIP_CRC/SKIP_LONG */
#define DM9KS_REGFF 0x83 /* IMR */
#define DM9KS_DISINTR 0x80
#define DM9KS_PHY 0x40 /* PHY address 0x01 */
#define DM9KS_PKT_RDY 0x01 /* Packet ready to receive */
#define DM9KS_RX_INTR 0x01
#define DM9KS_TX_INTR 0x02
#define DM9KS_LINK_INTR 0x20
#define iobase 0x01200000
#define iodata 0x01200008
extern int OK;
extern int ERR;
extern int Recv;
extern int DEBUG_OUT();
extern int netbuf_alloc();
extern struct NETBUF netbuf[NUM_MAX_NETBUF];
extern struct DM_NETIF netif;
void delay_1us (u32 dly)
{
u32 i;
for(;dly>0;dly--)
for(i=0;i<50000;i++);
}
/* Global variable declaration ----------------------------- */
/*static int dmfe_debug = 0;*/
//static struct net_device * dmfe_dev = NULL;
/* For module input parameter */
static int media_mode = DM9KS_AUTO;
/* function declaration ------------------------------------- */
int dmfe_open(void);
//void dmfe_tx_done(unsigned long);
void dmfe_packet_receive(void);
int dmfe_stop(void);
//void dmfe_timer(unsigned long);
void dmfe_init_dm9000(void);
//unsigned long cal_CRC(unsigned char *, unsigned int, u8);
u8 ior(u8, u32);
void iow(u8, u8);
u16 phy_read(u8);
void phy_write(u8, u16);
u16 read_srom_word(u8);
void dm9000_hash_table(void);
//static void dmfe_timeout(struct net_device *);
//static void dmfe_reset(struct net_device *);
#if defined(CHECKSUM)
static u8 check_rx_ready(u8);
#endif
static int queue_pkt_len;
//DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);
/* DM9000 network baord routine ---------------------------- */
/*
Open the interface.
The interface is opened whenever "ifconfig" actives it.
*/
void delay_1ms(u32 no)
{
u32 i;
for(i=0;i<1000;i++)
{
delay_1us(1000);
}
}
#define udelay delay_1us
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void outb(u8 reg, u32 addr){
*(volatile u8 *)addr = reg;
}
void outw(u16 reg, u32 addr){
*(volatile u16 *)addr = reg;
}
void outl(u32 reg, u32 addr){
*(volatile u32 *)addr = reg;
}
/**/
u8 inb(u32 addr){
return (u8)(*(volatile u8 *)addr);
}
u16 inw(u32 addr){
return (u16)(*(volatile u16 *)addr);
}
u32 inl(u32 addr){
return (u32)(*(volatile u32 *)addr);
}/**/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int dmfe_open(void)
{
u32 id_val;
netif.io_addr = iobase;
netif.io_data = iodata;
outb(DM9KS_VID_L, netif.io_addr);
id_val = inb(netif.io_data);
outb(DM9KS_VID_H, netif.io_addr);
id_val |= inb(netif.io_data) << 8;
outb(DM9KS_PID_L, netif.io_addr);
id_val |= inb(netif.io_data) << 16;
outb(DM9KS_PID_H, netif.io_addr);
id_val |= inb(netif.io_data) << 24;
DEBUG_OUT(" <DM9KS> I/O: 0x%x, VID: 0x%x \r\n\r\n",netif.io_addr, id_val);
if (id_val == DM9KS_ID || id_val == DM9010_ID)
{
/* Initilize DM9000A board */
dmfe_init_dm9000();
/* Init driver variable */
netif.reset_counter = 0;
netif.reset_tx_timeout = 0;
if (phy_read(0) & 0x2000)
netif.Speed = 100;
else
netif.Speed = 10;
return OK;
}else{
DEBUG_OUT("\r\n************ERROR! NO Davicom NIC!\r\n");
return ERR;
}
}
/* Set PHY operationg mode
*/
void set_PHY_mode()
{
u16 phy_reg0 = 0x1200; /* Auto-negotiation & Restart Auto-negotiation */
u16 phy_reg4 = 0x01e1; /* Default flow control disable*/
if ( !(netif.op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */
{
switch(netif.op_mode) {
case DM9KS_10MHD:
phy_reg4 = 0x21; phy_reg0 = 0x1000;
break;
case DM9KS_10MFD:
phy_reg4 = 0x41; phy_reg0 = 0x1100;
break;
case DM9KS_100MHD:
phy_reg4 = 0x81; phy_reg0 = 0x3000;
break;
case DM9KS_100MFD:
phy_reg4 = 0x101; phy_reg0 = 0x3100;
break;
default:
break;
} // end of switch
} // end of if
phy_write(0, phy_reg0);
phy_write(4, phy_reg4);
}
/*
Initilize dm9000 board
*/
void dmfe_init_dm9000(void)
{
// DEBUG_OUT("dmfe_init_dm9000() --->");
iow(DM9KS_GPR, 1); /* Power-Down PHY */
udelay(2000);
/* set the internal PHY power-on, GPIOs normal, and wait 2ms */
iow( DM9KS_GPR, 0); /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
udelay(2000); /* wait 2ms for PHY power-on ready */
/* do a software reset and wait 20us */
iow( DM9KS_NCR, 3);
udelay(20); /* wait 20us at least for software reset ok */
iow( DM9KS_NCR, 3); /* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on. Added by SPenser */
udelay(20); /* wait 20us at least for software reset ok */
/* I/O mode */
netif.io_mode = ior( DM9KS_ISR, netif.io_addr) >> 6; /* ISR bit7:6 keeps I/O mode */
DEBUG_OUT("\r\n io_mode = 0x%x \r\n",netif.io_mode);
/* Set PHY */
netif.op_mode = media_mode;
set_PHY_mode();
/* Program operating register */
iow(DM9KS_NCR, 0);
iow(DM9KS_TCR, 0); /* TX Polling clear */
#if defined(LEDMODE1)
iow(DM9KS_TCR2, 0x80); /* LED mode */
#endif
iow(DM9KS_BPTR, 0x3f); /* Less 3kb, 600us */
iow(DM9KS_SMCR, 0); /* Special Mode */
iow(DM9KS_NSR, 0x2c); /* clear TX status */
#if defined(DM9000AE_INT_HI) /* interrupt high active */
iow(DM9KS_INTCR, 0x00);
#else
iow(DM9KS_INTCR, 0x01);
#endif
iow(DM9KS_ISR, 0x0f); /* Clear interrupt status */
/* Added by jackal at 03/29/2004 */
#if defined(CHECKSUM)
iow( DM9KS_TCCR, 0x07); /* TX UDP/TCP/IP checksum enable */
iow( DM9KS_RCSR, 0x02); /* Receive checksum enable */
#endif
#if defined(ETRANS)
iow(netif, DM9KS_ETXCSR, 0x83);
#endif
/* Set address filter table */
dm9000_hash_table();
/* Activate DM9000A/DM9010 */
iow(DM9KS_RXCR, DM9KS_REG05 | 1); /* RX enable */
iow(DM9KS_IMR, DM9KS_REGFF); // Enable TX/RX interrupt mask
/* Init Driver variable */
netif.tx_pkt_cnt = 0;
netif.tx_packets = 0;
netif.tx_bytes = 0;
netif.rx_fifo_errors = 0;
netif.rx_crc_errors = 0;
netif.rx_length_errors = 0;
netif.rx_packets = 0;
netif.rx_bytes = 0;
netif.reset_counter = 0;
netif.reset_tx_timeout = 0;
netif.ip_crc_err = 0;
netif.tcp_crc_err = 0;
netif.udp_crc_err = 0;
netif.num = 0;
// netif_carrier_on(dev);
// spin_lock_init(&netif.lock);
}
/*
Hardware start transmission.
Send a packet to media from the upper layer.
*/
//static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
int dmfe_start_xmit(char * pdata, u16 len)
{
char * data_ptr;
int i, tmplen;
if(netif.Speed == 10)
{if (netif.tx_pkt_cnt >= 1) return ERR;}
else
{if (netif.tx_pkt_cnt >= 2) return ERR;}
/* Disable all interrupt */
iow( DM9KS_IMR, DM9KS_DISINTR);
/* Move data to TX SRAM */
data_ptr = (char *)pdata;
outb(DM9KS_MWCMD, netif.io_addr); /* Write data into SRAM trigger */
switch(netif.io_mode)
{
case DM9KS_BYTE_MODE:
for (i = 0; i < len; i++)
outb((data_ptr[i] & 0xff), netif.io_data);
break;
case DM9KS_WORD_MODE:
tmplen = (len + 1) / 2;
for (i = 0; i < tmplen; i++)
outw(((u16 *)data_ptr)[i], netif.io_data);
break;
case DM9KS_DWORD_MODE:
tmplen = (len + 3) / 4;
for (i = 0; i< tmplen; i++)
outl(((u32 *)data_ptr)[i], netif.io_data);
break;
}
if(netif.tx_pkt_cnt==0)
{
/* Set TX length to reg. 0xfc & 0xfd */
iow( DM9KS_TXPLL, (len & 0xff));
iow( DM9KS_TXPLH, (len >> 8) & 0xff);
#if !defined(ETRANS)
/* Issue TX polling command */
iow( DM9KS_TCR, 0x1); /* Cleared after TX complete*/
#endif
netif.tx_packets++;
netif.tx_bytes+=len;
}else{
/* Second packet */
queue_pkt_len = len;
}
/* packet counting */
netif.tx_pkt_cnt++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -