• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Davicom公司DM9000A和DM9010 ISA NIC 以太網(wǎng)驅(qū)動(dòng)分析

    Davicom公司DM9000A和DM9010 ISA NIC 以太網(wǎng)驅(qū)動(dòng)分析

    作者: 時(shí)間:2012-11-02 來(lái)源:網(wǎng)絡(luò) 收藏

    #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

    */

    static void dmfe_packet_receive(struct net_device *dev)

    {

    board_info_t *db = (board_info_t *)dev->priv;

    struct sk_buff *skb;

    u8 rxbyte, val;

    u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;

    u32 tmpdata;

    rx_t rx;

    u16 * ptr = (u16*)rx;

    u8* rdptr;

    DMFE_DBUG(0, dmfe_packet_receive(), 0);

    do {

    /*store the value of Memory Data Read address register*/

    MDRAH=ior(db, DM9KS_MDRAH);

    MDRAL=ior(db, DM9KS_MDRAL);

    ior(db, DM9KS_MRCMDX); /* Dummy read */

    rxbyte = inb(db->io_data); /* Got most updated data */

    /* packet ready to receive check */

    if(!(val = check_rx_ready(rxbyte))) break;

    /* A packet ready now Get status/length */

    GoodPacket = TRUE;

    outb(DM9KS_MRCMD, db->io_addr);

    /* Read packet status length */

    switch (db->io_mode)

    {

    case DM9KS_BYTE_MODE:

    *ptr = inb(db->io_data) +

    (inb(db->io_data) 8);

    *(ptr+1) = inb(db->io_data) +

    (inb(db->io_data) 8);

    break;

    case DM9KS_WORD_MODE:

    *ptr = inw(db->io_data);

    *(ptr+1) = inw(db->io_data);

    break;

    case DM9KS_DWORD_MODE:

    tmpdata = inl(db->io_data);

    *ptr = tmpdata;

    *(ptr+1) = tmpdata >> 16;

    break;

    default:

    break;

    }

    /* Packet status check */

    if (rx.desc.status 0xbf)

    {

    GoodPacket = FALSE;

    if (rx.desc.status 0x01)

    {

    db->stats.rx_fifo_errors++;

    printk(n);

    }

    if (rx.desc.status 0x02)

    {

    db->stats.rx_crc_errors++;

    printk(n);

    }

    if (rx.desc.status 0x80)

    {

    db->stats.rx_length_errors++;

    printk(n);

    }

    if (rx.desc.status 0x08)

    printk(n);

    }

    if (!GoodPacket)

    {

    // drop this packet!!!

    switch (db->io_mode)

    {

    case DM9KS_BYTE_MODE:

    for (i=0; i

    inb(db->io_data);

    break;

    case DM9KS_WORD_MODE:

    tmplen = (rx.desc.length + 1) / 2;

    for (i = 0; i tmplen; i++)

    inw(db->io_data);

    break;

    case DM9KS_DWORD_MODE:

    tmplen = (rx.desc.length + 3) / 4;

    for (i = 0; i tmplen; i++)

    inl(db->io_data);

    break;

    }

    continue;/*next the packet*/

    }

    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,DM9KS_MDRAH,MDRAH);

    iow(db,DM9KS_MDRAL,MDRAL);

    return;

    }

    else

    {

    /* Move data from DM9000 */

    skb->dev = dev;

    skb_reserve(skb, 2);

    rdptr = (u8*)skb_put(skb, rx.desc.length - 4);

    /* Read received packet from RX SARM */

    switch (db->io_mode)

    {

    case DM9KS_BYTE_MODE:

    for (i=0; i

    rdptr[i]=inb(db->io_data);

    break;

    case DM9KS_WORD_MODE:

    tmplen = (rx.desc.length + 1) / 2;

    for (i = 0; i tmplen; i++)

    ((u16 *)rdptr)[i] = inw(db->io_data);

    break;

    case DM9KS_DWORD_MODE:

    tmplen = (rx.desc.length + 3) / 4;

    for (i = 0; i tmplen; i++)

    ((u32 *)rdptr)[i] = inl(db->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

    netif_rx(skb);

    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)

    {

    dmfe_tx_done(0);

    break;

    }

    }

    }while((rxbyte 0x01) == DM9KS_PKT_RDY);

    DMFE_DBUG(0, [END]dmfe_packet_receive(), 0);

    }

    /*

    Read a word data from SROM

    */

    static u16 read_srom_word(board_info_t *db, int offset)

    {

    iow(db, DM9KS_EPAR, offset);

    iow(db, DM9KS_EPCR, 0x4);

    udelay(200);

    iow(db, DM9KS_EPCR, 0x0);

    pid控制相關(guān)文章:pid控制原理




    評(píng)論


    相關(guān)推薦

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 襄垣县| 同心县| 棋牌| 滨州市| 华容县| 商水县| 泽库县| 饶平县| 北票市| 集贤县| 揭东县| 梁河县| 伊金霍洛旗| 武夷山市| 宣恩县| 同德县| 古丈县| 邹城市| 延津县| 宣化县| 曲水县| 建湖县| 庆阳市| 定远县| 鹤庆县| 油尖旺区| 环江| 金湖县| 高州市| 枝江市| 沐川县| 东乡县| 天柱县| 靖边县| 鄂伦春自治旗| 长汀县| 石楼县| 东阳市| 维西| 景泰县| 思茅市|