"); //-->
DM9003 发送及接收packet程序
MWCMDX 写SRAM,地址指针不变
MWCMD 写SRAM,地址指针自动增加
MRCMDX 预处理读SRAM,地址指针不变
MRCMDX1/MRCMD 读SRAM,地址指针增加
/*
Hardware start transmission.
Send a packet to media from the upper layer.
*/
static int dm9013_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
char * data_ptr;
DM9013_DBUG(0, "dm9013_start_xmit()", 0);
if (db->tx_pkt_cnt >= 2)
{
netif_stop_queue(dev);
db->stop_transmit =1;
return 1;
}
//发送数据统计
/* packet counting */
db->tx_pkt_cnt++;
db->stats.tx_packets++;
db->stats.tx_bytes+=skb->len;
// FIFO has fulled already
if (db->tx_pkt_cnt == 2)
{
netif_stop_queue(dev);
db->stop_transmit =1;
}
//所有中断禁止
/* Disable all interrupt */
dm9013_disable_interrupt(db);
//发送数据包长度
/* Set TX length to reg. 0xfc & 0xfd */
iow(db, DM9013_TXPLL, (skb->len & 0xff));
iow(db, DM9013_TXPLH, (skb->len >> 8) & 0xff);
//copy发送数据到SRAM
/* Move data to TX SRAM */
data_ptr = (char *)skb->data;
outb(DM9013_MWCMD, db->io_addr); /* Write data into SRAM trigger */
db->MoveData(db, data_ptr, skb->len, 1);
//发送请求
/* Issue TX polling command */
iow(db, DM9013_TCR, TCR_TX_Request);
//发送时间
/* Saved the time stamp */
dev->trans_start = jiffies;
db->cont_rx_pkt_cnt =0;
//释放系统发送数据块
/* Free this SKB */
dev_kfree_skb(skb);
//使能DM9003所有中断
/* Re-enable interrupt */
dm9013_enable_interrupt(db);
return 0;
}
/*
* Received a packet and pass to upper layer
*/
static void dm9013_packet_receive(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
struct sk_buff *skb;
u8 rxbyte, val;
u16 MDRAH, MDRAL;
rx_t rx;
u8 * ptr = (u8*)℞
u8* rdptr;
DM9013_DBUG(0, "dm9013_packet_receive()", 0);
db->cont_rx_pkt_cnt=0;
do {
//保留读数据地址到MDR(读数据地址寄存器)
/*store the value of Memory Data Read address register*/
MDRAH=ior(db, DM9013_MDRAH);
MDRAL=ior(db, DM9013_MDRAL);
//预读数据
rxbyte =ior(db, DM9013_MRCMDX);/* Dummy read */
rxbyte =inb(db->io_data); /* read the byte of packet ready */
//检查数据包是否OK,第一个byte为0x01
/* packet ready to receive check */
if(!(val = check_rx_ready(rxbyte))) break;
//开始从SRAM读数据
/* A packet ready now & Get status/length */
outb(DM9013_MRCMD, db->io_addr);
/* Read packet status & length */
db->MoveData(db,ptr,4,0);
//检查数据包状态
/* Packet status check */
if (rx.desc.status & 0x03) //0xbf)
{
//printk("DM9013:RX ERROR\n");
db->stats.rx_errors++;
if (rx.desc.status & RX_FIFO_over)
db->stats.rx_fifo_errors++;
if (rx.desc.status & RX_CRCErr)
db->stats.rx_crc_errors++;
/* drop this packet */
db->MoveData(db, NULL, rx.desc.length, 0);
db->stats.rx_dropped++;
continue;
}
//Move SRAM数据至系统
skb = dev_alloc_skb(rx.desc.length+4);
if (skb == NULL ) //系统申请数据块失败
{
printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
/*re-load the value into Memory data read address register*/
iow(db,DM9013_MDRAH,MDRAH);
iow(db,DM9013_MDRAL,MDRAL);
return;
}
else //申请到数据块
{
/* Move data from DM9000 */
skb->dev = dev;
skb_reserve(skb, 2);
rdptr = (u8*)skb_put(skb, rx.desc.length - 4);
db->MoveData(db, rdptr, rx.desc.length, 0);
/* Pass to upper layer */
skb->protocol = eth_type_trans(skb,dev);
#ifdef CHECKSUM
skb->ip_summed = CHECKSUM_UNNECESSARY; // V1.03 (3)
if ((rxbyte&0xE0)||(rxbyte==0x01))
skb->ip_summed = CHECKSUM_NECESSARY; /* receive packet no checksum fail */
#endif
netif_rx(skb); //系统处理数据至网络memory
dev->last_rx=jiffies;
db->stats.rx_packets++;
db->stats.rx_bytes += rx.desc.length;
db->cont_rx_pkt_cnt++;
if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
{
printk("RX out \n");
dm9013_tx_done(0);
break;
}
}
}while((rxbyte & 0x01) == DM9013_PKT_RDY);
DM9013_DBUG(0, "[END]dm9013_packet_receive()", 0);
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。