请教Intel82559网卡驱动初始化问题

killer302vs   2009-12-25 20:12 楼主
最近在移植Intel82559网卡驱动,发现初始化过程就出错,一直找不到时什么原因,请大家帮忙看一下。
我用的代码是参考freebsd的,初始化过程中发现给SCB COMMAND寄存器写入值时,状态寄存器没有任何变化,这会是什么原因呢?

回复评论 (8)

你写寄存器没有任何变化,是指你仿真看到寄存器没有变化? 还是其他?

首先确保的电路正确,通讯正常,否则如果是硬件的问题,到时你就白郁闷了、
点赞  2009-12-25 21:02
硬件我保证是没问题的,我跑VxWorks的BSP网卡是正常的。我现在移植到新的系统里。网卡初始化的时候需要通过command寄存器写命令进行配置,我看到datasheet里有这样一段话:The actual command execution may not start instantaneously and will depend on current receive and transmit DMA activity.The Command byte is set by CPU and cleared by 8255x indicating command acceptance.
按照最后一句话的说法,如果我给command寄存器写值成功的话,网卡会马上把command寄存器清除,而我现在写了以后再读仍然是原来写入的值。
还有,在初始化的时候网卡的中断时屏蔽掉的,我不太明白current receive and transmit DMA 是怎么工作的,对command寄存器有什么影响?
点赞  2009-12-25 23:28
下面是网上初始化过程部分代码,请大牛帮我看看啊,万分感谢:
static void
fxp_init(void *xsc)
{
        struct fxp_softc *sc = xsc;
        struct ifnet *ifp = &sc->sc_if;
        struct fxp_cb_config *cbp;
        struct fxp_cb_ias *cb_ias;
        struct fxp_cb_tx *txp;
        int i, prm, s;

        DBGLVL_PRINTK(2,"fxp_init called\n");
  
        s = splimp();
        /*
         * Cancel any pending I/O
         */
    /*
     * Add line suggested by "Eugene Denisov"
     * on Tue, 16 Mar 2004 13:10:15 +0300
     */
       
//        printf("In fxp_init begin [%d][%d][%d] and daemonTid is [%d]\n", sc->pciBus, sc->pciDevice, sc->pciFunc, sc->daemonTid);
    sc->stat_ch = fxp_timeout_stopped;
        fxp_stop(sc);

        prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;

        DBGLVL_PRINTK(5,"fxp_init: Initializing base of CBL and RFA memory\n");
        /*
         * Initialize base of CBL and RFA memory. Loading with zero
         * sets it up for regular linear addressing.
         */
        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);

        fxp_scb_wait(sc);
        fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);

        /*
         * Initialize base of dump-stats buffer.
         */
        DBGLVL_PRINTK(5,"fxp_init: Initializing base of dump-stats buffer\n");
        fxp_scb_wait(sc);
        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(sc->fxp_stats));
        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);

        /*
         * We temporarily use memory that contains the TxCB list to
         * construct the config CB. The TxCB list memory is rebuilt
         * later.
         */
        cbp = (struct fxp_cb_config *) sc->cbl_base;
        DBGLVL_PRINTK(5,"fxp_init: cbp = 0x%x\n",cbp);

        /*
         * This bcopy is kind of disgusting, but there are a bunch of must be
         * zero and must be one bits in this structure and this is the easiest
         * way to initialize them all to proper values.
         */
        bcopy(fxp_cb_config_template,
                (void *)(u_int32_t *)(volatile void *)&cbp->cb_status,
                sizeof(fxp_cb_config_template));

        cbp->cb_status =        0;
        cbp->cb_command =        CPU_swap_u16(FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL);
        cbp->link_addr =        -1;        /* (no) next command */
        cbp->byte_count =        22;        /* (22) bytes to config */
        cbp->rx_fifo_limit =        8;        /* rx fifo threshold (32 bytes) */
        cbp->tx_fifo_limit =        0;        /* tx fifo threshold (0 bytes) */
        cbp->adaptive_ifs =        0;        /* (no) adaptive interframe spacing */
        cbp->mwi_enable =        sc->flags & FXP_FLAG_MWI_ENABLE ? 1 : 0;
        cbp->type_enable =        0;        /* actually reserved */
        cbp->read_align_en =        sc->flags & FXP_FLAG_READ_ALIGN ? 1 : 0;
        cbp->end_wr_on_cl =        sc->flags & FXP_FLAG_WRITE_ALIGN ? 1 : 0;
        cbp->rx_dma_bytecount =        0;        /* (no) rx DMA max */
        cbp->tx_dma_bytecount =        0;        /* (no) tx DMA max */
        cbp->dma_mbce =                0;        /* (disable) dma max counters */
        cbp->late_scb =                0;        /* (don't) defer SCB update */
        cbp->direct_dma_dis =        1;        /* disable direct rcv dma mode */
        cbp->tno_int_or_tco_en =0;        /* (disable) tx not okay interrupt */
        cbp->ci_int =                1;        /* interrupt on CU idle */
        cbp->ext_txcb_dis =         sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1;
        cbp->ext_stats_dis =         1;        /* disable extended counters */
        cbp->keep_overrun_rx =         0;        /* don't pass overrun frames to host */
        cbp->save_bf =                sc->chip == FXP_CHIP_82557 ? 1 : prm;
        cbp->disc_short_rx =        !prm;        /* discard short packets */
        cbp->underrun_retry =        1;        /* retry mode (once) on DMA underrun */
        cbp->two_frames =        0;        /* do not limit FIFO to 2 frames */
        cbp->dyn_tbd =                0;        /* (no) dynamic TBD mode */
        cbp->mediatype =        sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1;
        cbp->csma_dis =                0;        /* (don't) disable link */
        cbp->tcp_udp_cksum =        0;        /* (don't) enable checksum */
        cbp->vlan_tco =                0;        /* (don't) enable vlan wakeup */
        cbp->link_wake_en =        0;        /* (don't) assert PME# on link change */
        cbp->arp_wake_en =        0;        /* (don't) assert PME# on arp */
        cbp->mc_wake_en =        0;        /* (don't) enable PME# on mcmatch */
        cbp->nsai =                1;        /* (don't) disable source addr insert */
        cbp->preamble_length =        2;        /* (7 byte) preamble */
        cbp->loopback =                0;        /* (don't) loopback */
        cbp->linear_priority =        0;        /* (normal CSMA/CD operation) */
        cbp->linear_pri_mode =        0;        /* (wait after xmit only) */
        cbp->interfrm_spacing =        6;        /* (96 bits of) interframe spacing */
        cbp->promiscuous =        prm;        /* promiscuous mode */
        cbp->bcast_disable =        0;        /* (don't) disable broadcasts */
        cbp->wait_after_win =        0;        /* (don't) enable modified backoff alg*/
        cbp->ignore_ul =        0;        /* consider U/L bit in IA matching */
        cbp->crc16_en =                0;        /* (don't) enable crc-16 algorithm */
        cbp->crscdt =                sc->flags & FXP_FLAG_SERIAL_MEDIA ? 1 : 0;

        cbp->stripping =        !prm;        /* truncate rx packet to byte count */
        cbp->padding =                1;        /* (do) pad short tx packets */
        cbp->rcv_crc_xfer =        0;        /* (don't) xfer CRC to host */
        cbp->long_rx_en =        sc->flags & FXP_FLAG_LONG_PKT_EN ? 1 : 0;
        cbp->ia_wake_en =        0;        /* (don't) wake up on address match */
        cbp->magic_pkt_dis =        0;        /* (don't) disable magic packet */
                                        /* must set wake_en in PMCSR also */
        cbp->force_fdx =        0;        /* (don't) force full duplex */
        cbp->fdx_pin_en =        1;        /* (enable) FDX# pin */
        cbp->multi_ia =                0;        /* (don't) accept multiple IAs */
        cbp->mc_all =                sc->flags & FXP_FLAG_ALL_MCAST ? 1 : 0;

        DBGLVL_PRINTK(5,"fxp_init: cbp initialized\n");
        if (sc->chip == FXP_CHIP_82557) {
                /*
                 * The 82557 has no hardware flow control, the values
                 * below are the defaults for the chip.
                 */
                cbp->fc_delay_lsb =        0;
                cbp->fc_delay_msb =        0x40;
                cbp->pri_fc_thresh =        3;
                cbp->tx_fc_dis =        0;
                cbp->rx_fc_restop =        0;
                cbp->rx_fc_restart =        0;
                cbp->fc_filter =        0;
                cbp->pri_fc_loc =        1;
        } else {
                cbp->fc_delay_lsb =        0x1f;
                cbp->fc_delay_msb =        0x01;
                cbp->pri_fc_thresh =        3;
                cbp->tx_fc_dis =        0;        /* enable transmit FC */
                cbp->rx_fc_restop =        1;        /* enable FC restop frames */
                cbp->rx_fc_restart =        1;        /* enable FC restart frames */
                cbp->fc_filter =        !prm;        /* drop FC frames to host */
                cbp->pri_fc_loc =        1;        /* FC pri location (byte31) */
        }

        /*
         * Start the config command/DMA.
         */
        DBGLVL_PRINTK(5,"fxp_init: starting config command/DMA\n");
        fxp_scb_wait(sc);
//        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
        sysOutLong(sc->pci_regs_base + FXP_CSR_SCB_GENERAL ,(long)(&cbp->cb_status));
        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);      
        /* ...and wait for it to complete. */
        fxp_dma_wait(&cbp->cb_status, sc);              /////前面都是好的,这里就等待超时了,状态寄存器的值一直都没有变化
     。。。。。。
}

fxp_dma_wait代码如下:
static __inline void
fxp_dma_wait(volatile u_int16_t *status, struct fxp_softc *sc)
{
        int i = 10000;

        while (!(CPU_swap_u16(*status) & FXP_CB_STATUS_C) && --i)
                DELAY(2);
        if (i == 0)
                printf("DMA timeout\n");
}
点赞  2009-12-27 13:14
还是没解决。实在找不到问题所在了,郁闷。
点赞  2009-12-28 13:27
你的没写进去是什么意思?读出来是0?
点赞  2009-12-29 10:13
学习一下
点赞  2009-12-29 10:18
我帮你顶一下,事成之后给我点分。嘿嘿!
点赞  2009-12-30 08:58
楼主,结合“

cbp->direct_dma_dis = 1; /* disable direct rcv dma mode */ ”

找找spec看看有没有DMA disable, enalbe的register 需要写,在你读status register前
点赞  2009-12-31 17:39
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复