📄 dm9ks_ucos.c
字号:
/* Saved the time stamp */
// dev->trans_start = jiffies;
/* Free this SKB */
// dev_kfree_skb();
/* Re-enable interrupt */
iow( DM9KS_IMR, DM9KS_REGFF);
return OK;
}
/*
Stop the interface.
The interface is stopped when it is brought.
*/
int dmfe_stop(void)
{
DEBUG_OUT("dmfe_stop !!!");
/* deleted timer */
// del_timer(&netif.timer);
// netif_stop_queue();
/* free interrupt */
// free_irq(dev->irq, dev);
/* RESET devie */
phy_write( 0x00, 0x8000); /* PHY RESET */
iow( DM9KS_GPR, 0x01); /* Power-Down PHY */
iow( DM9KS_IMR, DM9KS_DISINTR); /* Disable all interrupt */
iow( DM9KS_RXCR, 0x00); /* Disable RX */
/* Dump Statistic counter */
#if FALSE
printk("\nRX FIFO OVERFLOW %lx\n", netif.stats.rx_fifo_errors);
printk("RX CRC %lx\n", netif.stats.rx_crc_errors);
printk("RX LEN Err %lx\n", netif.stats.rx_length_errors);
printk("RESET %x\n", netif.reset_counter);
printk("RESET: TX Timeout %x\n", netif.reset_tx_timeout);
printk("g_TX_nsr %x\n", g_TX_nsr);
#endif
return 0;
}
void dmfe_tx_done(unsigned long unused)
{
int tx_status;
// DEBUG_OUT("dmfe_tx_done()");
tx_status = ior(DM9KS_NSR, netif.io_addr);
if (tx_status & 0xc)
{
/* One packet sent complete */
netif.tx_pkt_cnt--;
if (netif.tx_pkt_cnt < 0)
{
//printk("[dmfe_tx_done] tx_pkt_cnt ERROR!!\n");
netif.tx_pkt_cnt =0;
}
/* Queue packet check & send */
if (netif.tx_pkt_cnt > 0)
{
/* Set TX length to DM9000 */
iow( DM9KS_TXPLL, (queue_pkt_len & 0xff));
iow( DM9KS_TXPLH, (queue_pkt_len >> 8) & 0xff);
/* Issue TX polling command */
//iow( DM9KS_TCR, 0x1); /* Cleared after TX complete */
netif.tx_packets++;
netif.tx_bytes+=queue_pkt_len;
}
}
}
/*
DM9000 insterrupt handler
receive the packet to upper layer, free the transmitted packet
*/
void dmfe_interrupt(void)
{
int int_status;
u8 reg_save;
// DEBUG_OUT("dmfe_interrupt() ---> ");
/* A real interrupt coming
netif = (board_info_t *)dev->priv;
spin_lock(&netif.lock);*/
/* Save previous register address */
reg_save = inb(netif.io_addr);
/* Disable all interrupt */
iow( DM9KS_IMR, DM9KS_DISINTR);
/* Got DM9000A/DM9010 interrupt status */
int_status = ior(DM9KS_ISR, netif.io_addr); /* Got ISR */
iow( DM9KS_ISR, int_status); /* Clear ISR status */
/* Received the coming packet */
if (int_status & DM9KS_RX_INTR)
dmfe_packet_receive();
/* Trnasmit Interrupt check */
if (int_status & DM9KS_TX_INTR)
dmfe_tx_done(0);
/* Link status change */
if (int_status & DM9KS_LINK_INTR)
{
}
/* Re-enable interrupt mask */
iow( DM9KS_IMR, DM9KS_REGFF);
/* Restore previous register address */
outb(reg_save, netif.io_addr);
}
#if !defined(CHECKSUM)
#define check_rx_ready(a) ((a) == 0x01)
#else
inline u8 check_rx_ready(u8 rxbyte)
{
if (!(rxbyte & 0x01))
return 0;
return ((rxbyte >> 4) | 0x01);
}
#endif
/*
Received a packet and pass to upper layer
*/
void dmfe_packet_receive(void)
{
int index;
u8 rxbyte, temp;
u16 i, GoodPacket, RxStatus, RxLen, tmplen, MDRAH, MDRAL;
u32 tmpdata;
u8* rdptr;
// DEBUG_OUT("dmfe_packet_receive()\r\n\r\n");
do {
/*store the value of Memory Data Read address register*/
MDRAH=ior( DM9KS_MDRAH, netif.io_addr);
MDRAL=ior( DM9KS_MDRAL, netif.io_addr);
ior( DM9KS_MRCMDX, netif.io_addr); /* Dummy read */
rxbyte = inb(netif.io_data); /* Got most updated data */
/* packet ready to receive check */
if (rxbyte != 0x01) break;
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
outb(DM9KS_MRCMD, netif.io_addr);
RxStatus = (u16)0;
RxLen = (u16)0;
/* Read packet status & length */
switch (netif.io_mode)
{
case DM9KS_BYTE_MODE:
RxStatus = inb(netif.io_data) +
(inb(netif.io_data) << 8);
RxLen = inb(netif.io_data) +
(inb(netif.io_data) << 8);
break;
case DM9KS_WORD_MODE:
RxStatus = inw(netif.io_data);
RxLen = inw(netif.io_data);
break;
case DM9KS_DWORD_MODE:
tmpdata = inl(netif.io_data);
RxStatus = tmpdata;
RxLen = tmpdata >> 16;
break;
default:
break;
}
/* Packet status check */
temp = (u8)(RxStatus>>8);
if (temp & 0xbf)
{
GoodPacket = FALSE;
if (temp & 0x01)
{
netif.rx_fifo_errors++;
//DEBUG_OUT("<RX FIFO error>\n");
}
if (temp & 0x02)
{
netif.rx_crc_errors++;
//DEBUG_OUT("<RX CRC error>\n");
}
if (temp & 0x80)
{
netif.rx_length_errors++;
//DEBUG_OUT("<RX Length error>\n");
}
if (temp & 0x08)
;
//DEBUG_OUT("<Physical Layer error>\n");
}
if (!GoodPacket)
{
// drop this packet!!!
switch (netif.io_mode)
{
case DM9KS_BYTE_MODE:
for (i=0; i<RxLen; i++)
inb(netif.io_data);
break;
case DM9KS_WORD_MODE:
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
inw(netif.io_data);
break;
case DM9KS_DWORD_MODE:
tmplen = (RxLen + 3) / 4;
for (i = 0; i < tmplen; i++)
inl(netif.io_data);
break;
}
continue;/*next the packet*/
}
index = netbuf_alloc();
if (index == -1 )
{
//DEBUG_OUT("%s: Memory squeeze.\n", netif.name);
/*re-load the value into Memory data read address register*/
iow(DM9KS_MDRAH,MDRAH);
iow(DM9KS_MDRAL,MDRAL);
return;
}
else
{
/* Move data from DM9000 */
//skb->dev = dev;
//skb_reserve(skb, 2);
rdptr = (u8*)&netbuf[index].data[0] ;
/* Read received packet from RX SARM */
switch (netif.io_mode)
{
case DM9KS_BYTE_MODE:
for (i=0; i<RxLen; i++)
netbuf[index].data[i]=inb(netif.io_data);
break;
case DM9KS_WORD_MODE:
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++){
((u16 *)rdptr)[i] = inw(netif.io_data);
}
break;
case DM9KS_DWORD_MODE:
tmplen = (RxLen + 3) / 4;
for (i = 0; i < tmplen; i++)
((u32 *)rdptr)[i] = inl(netif.io_data);
break;
}
/* Pass to upper layer
//skb->protocol = eth_type_trans(skb,dev);
#if defined(CHECKSUM)
if (val == 0x01)
skb->ip_summed = CHECKSUM_UNNECESSARY;
#endif
*/
netbuf[index].flags = Recv;
netbuf[index].eth_len = RxLen;
netif.rx_packets++;
netif.rx_bytes += RxLen;
}
}while((rxbyte & 0x01) == DM9KS_PKT_RDY);
}
/*
Read a word data from SROM
*/
u16 read_srom_word(u8 offset)
{
iow( DM9KS_EPAR, offset);
iow( DM9KS_EPCR, 0x4);
udelay(200);
iow( DM9KS_EPCR, 0x0);
return (ior( DM9KS_EPDRL, netif.io_addr) + (ior( DM9KS_EPDRH, netif.io_addr) << 8) );
}
/*
Set DM9000A/DM9010 multicast address
*/
void dm9000_hash_table(void)
{
// u32 hash_val;
u16 i, oft, hash_table[4];
DEBUG_OUT("dm9000_hash_table() --->");
/* Set Node address */
iow(0x10, netif.hw_addr[0]);
iow(0x11, netif.hw_addr[1]);
iow(0x12, netif.hw_addr[2]);
iow(0x13, netif.hw_addr[3]);
iow(0x14, netif.hw_addr[4]);
iow(0x15, netif.hw_addr[5]);
/* Clear Hash Table */
for (i = 0; i < 4; i++)
hash_table[i] = 0x0;
/* broadcast address */
hash_table[3] = 0x8000;
#if 0
/* the multicast address in Hash Table : 64 bits */
for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f;
hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
}
#endif
/* Write the hash table to MAC MD table */
for (i = 0, oft = 0x16; i < 4; i++) {
iow( oft++, hash_table[i] & 0xff);
iow( oft++, (hash_table[i] >> 8) & 0xff);
}
DEBUG_OUT("\r\n0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ",ior(0x10, netif.io_addr),
ior(0x11, netif.io_addr),ior(0x12, netif.io_addr),
ior(0x13, netif.io_addr),ior(0x14, netif.io_addr),ior(0x15, netif.io_addr));
}
#if 0
/*
Calculate the CRC valude of the Rx packet
flag = 1 : return the reverse CRC (for the received packet CRC)
0 : return the normal CRC (for Hash Table index)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{
u32 crc = ether_crc_le(Len, Data);
if (flag)
return ~crc;
return crc;
}
#endif
/*
Read a byte from I/O port
*/
u8 ior(u8 reg, u32 addr)
{
outb(reg, addr);
return inb(netif.io_data);
}
/*
Write a byte to I/O port
*/
void iow(u8 reg, u8 value)
{
outb(reg, netif.io_addr);
outb(value, netif.io_data);
}
/*
Read a word from phyxcer
*/
u16 phy_read(u8 reg)
{
/* Fill the phyxcer register into REG_0C */
iow( DM9KS_EPAR, DM9KS_PHY | reg);
iow( DM9KS_EPCR, 0xc); /* Issue phyxcer read command */
udelay(100); /* Wait read complete */
iow( DM9KS_EPCR, 0x0); /* Clear phyxcer read command */
/* The read data keeps on REG_0D & REG_0E */
return ( ior( DM9KS_EPDRH, netif.io_addr) << 8 ) | ior( DM9KS_EPDRL, netif.io_addr);
}
/*
Write a word to phyxcer
*/
void phy_write(u8 reg, u16 value)
{
/* Fill the phyxcer register into REG_0C */
iow( DM9KS_EPAR, DM9KS_PHY | reg);
/* Fill the written data into REG_0D & REG_0E */
iow( DM9KS_EPDRL, (value & 0xff));
iow( DM9KS_EPDRH, ( (value >> 8) & 0xff));
iow( DM9KS_EPCR, 0xa); /* Issue phyxcer write command */
udelay(500); /* Wait write complete */
iow( DM9KS_EPCR, 0x0); /* Clear phyxcer write command */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -