新聞中心

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

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

        作者: 時間:2012-11-02 來源:網(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控制原理




        評論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 准格尔旗| 曲沃县| 前郭尔| 库车县| 灵石县| 临夏市| 仁化县| 饶阳县| 武汉市| 乳源| 唐山市| 海林市| 新化县| 宜章县| 仙桃市| 思茅市| 金坛市| 杨浦区| 昌宁县| 潜江市| 安达市| 剑川县| 鹤峰县| 太仆寺旗| 秦安县| 治多县| 濮阳市| 上高县| 西藏| 阳江市| 闸北区| 榕江县| 青浦区| 应城市| 木兰县| 郸城县| 马关县| 泾阳县| 南涧| 烟台市| 庆云县|