⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_ep93xx.c

📁 ecos实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    } while ((stat & MAC_BMStat_TxAct) == 0) ;    HAL_WRITE_UINT32(MAC_TxCtl, MAC_TxCtl_TxON);}// ------------------------------------------------------------------------static bool ep93xx_init(struct cyg_netdevtab_entry *tab){    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;    cyg_uint32 stat;    int i;    cyg_uint32 uncached;#ifdef ETHDEBUG    dprintf("ep93xx_init\n");#endif // ETHDEBUG    // Set up uncached addresses for our data structures    HAL_VIRT_TO_UNCACHED_ADDRESS( &cpd->_rxhdrs[0], uncached );    cpd->rxhdrs = (RxHdr *)uncached;    HAL_VIRT_TO_UNCACHED_ADDRESS( &cpd->_rxstat[0], uncached );    cpd->rxstat = (RxStat *)uncached;    HAL_VIRT_TO_UNCACHED_ADDRESS( &cpd->_txhdrs[0], uncached );    cpd->txhdrs = (TxHdr *)uncached;    HAL_VIRT_TO_UNCACHED_ADDRESS( &cpd->_txstat[0], uncached );    cpd->txstat = (TxStat *)uncached;#ifdef CYGPKG_NET    // Initialize environment, setup interrupt handler    cyg_drv_interrupt_create(ETHERNET_INTERRUPT,                             99, // Priority - what goes here?                             (cyg_addrword_t)sc, //  Data item passed to interrupt handler                             (cyg_ISR_t *)ep93xx_isr,                             (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR                             &cpd->interrupt_handle,                             &cpd->interrupt);    cyg_drv_interrupt_attach(cpd->interrupt_handle);    cyg_drv_interrupt_acknowledge(ETHERNET_INTERRUPT);    cyg_drv_interrupt_unmask(ETHERNET_INTERRUPT);#endif // CYGPKG_NET    // Configure and enable PHY (wire) interfaces    doPHY();    // Reset the device    HAL_WRITE_UINT32(MAC_SelfCtl, MAC_SelfCtl_Reset);    do     {        HAL_READ_UINT32(MAC_SelfCtl, stat);    } while (stat & MAC_SelfCtl_Reset);    //Set MDC clock to be divided by 8, and enable PreambleSurpress    // for Tx and Rx frames.    HAL_WRITE_UINT32(MAC_SelfCtl, 0x0f00);    // Set the hardware address    if ( ! cpd->hardwired_esa ) {#if defined(CYGPKG_REDBOOT) && \    defined(CYGSEM_REDBOOT_FLASH_CONFIG)        if(flash_get_config("ep93xx_esa", &cpd->enaddr[0], CONFIG_ESA) == false)        {            diag_printf("\nFailed to get ep93xx_esa\n");        } #else#error FIXME#endif    }    HAL_WRITE_UINT32(MAC_AFP, 0);  // Individual address slot #0    for (i = 0;  i < ETHER_ADDR_LEN;  i++) {        HAL_WRITE_UINT8(MAC_IAD+i, cpd->enaddr[i]);    }    // Reset Rx    ep93xx_RxReset(cpd);    cpd->rxmode = MAC_RxCtl_Broadcast | MAC_RxCtl_IA0 | MAC_RxCtl_SRxON |         MAC_RxCtl_RCRCA;    // ***FIXME: PROMISCUOUS MODE: add MAC_RxCtl_Prom    // And move a load of this into start().    HAL_WRITE_UINT32(MAC_RxCtl, cpd->rxmode);    // Reset Tx    ep93xx_TxReset(cpd);    cpd->txbusy = 0;    cpd->txnext = 0;    HAL_WRITE_UINT32(MAC_IntStat, 0xFFFFFFFF);    // Clear any pending interrupts    // Set up interrupts    HAL_WRITE_UINT32(MAC_IntEnab, MAC_IntEnab_Rx | MAC_IntEnab_Tx );    HAL_WRITE_UINT32(MAC_IntStat, 0xFFFFFFFF);    // Clear again// ***FIXME: this register is NOT DOCUMENTED AT ALL ***//    HAL_WRITE_UINT32(MAC_IntCtl, MAC_IntCtl_Enable);    // Initialize upper level driver    (sc->funs->eth_drv->init)(sc, &cpd->enaddr[0]);#ifdef ETHDEBUG    dprintf("ep93xx_init exit\n");#endif // ETHDEBUG    return true;}//// This function is used to shutdown an interface.//static voidep93xx_stop(struct eth_drv_sc *sc){#ifdef ETHDEBUG    dprintf("ep93xx_stop()\n");#endif // ETHDEBUG}//// This function is called to "start up" the interface.  It may be called// multiple times, even when the hardware is already running.  It will be// called whenever something "hardware oriented" changes and should leave// the hardware ready to send/receive packets.//static voidep93xx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags){#ifdef ETHDEBUG    dprintf("ep93xx_start()\n");#endif // ETHDEBUG}//// This routine is called to perform special "control" opertions//static intep93xx_control(struct eth_drv_sc *sc, unsigned long key,               void *data, int data_length){#ifdef ETHDEBUG    dprintf("ep93xx_control()\n");#endif // ETHDEBUG        switch (key) {    case ETH_DRV_SET_MAC_ADDRESS:        return 0;        break;    default:        return 1;        break;    }}//// This routine is called to see if it is possible to send another packet.// It will return non-zero if a transmit is possible, zero otherwise.//static intep93xx_can_send(struct eth_drv_sc *sc){    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;#ifdef ETHDEBUG    dprintf("ep93xx_can_send()\n");#endif // ETHDEBUG#ifdef NOTYET    unsigned short stat;    stat = get_reg(PP_LineStat);    if ((stat & PP_LineStat_LinkOK) == 0) {        return false;  // Link not connected    }#endif // NOTYET    return (cpd->txbusy < CYGNUM_DEVS_ETH_ARM_EP93XX_TxNUM);}//// This routine is called to send data to the hardware.static void ep93xx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,             int total_len, unsigned long key){    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;    TxHdr * volatile hdr;    int i;    int len;    unsigned char * volatile data, * volatile bp;    cyg_uint32 phys;#ifdef ETHDEBUG    dprintf("ep93xx_send()\n");#endif // ETHDEBUG        if(cpd == 0)    {#ifdef ETHDEBUG        dprintf("ep93xx_send cpd is NULL!");#endif // ETHDEBUG        while (1);    }    if (cpd->txbusy >= CYGNUM_DEVS_ETH_ARM_EP93XX_TxNUM)    {        diag_printf("ep93xx_send you are hosed!");        while (1);        return;    }    if(cpd->txkey[cpd->txnext] != 0)    {        diag_printf("ep93xx_send outta places you are hosed!");        while (1);    }    // Mark xmitter busy    cpd->txkey[cpd->txnext] = key;    cpd->txbusy++;    // Fill in the header    hdr = &cpd->txhdrs[cpd->txnext];    HAL_VIRT_TO_PHYS_ADDRESS((cyg_uint32)&cpd->_txbufs[cpd->txnext][0], phys);    hdr->bufaddr = (void *)phys;    hdr->eof = 1;  // Complete frame    hdr->bi = cpd->txnext;    hdr->len = total_len;    if (++cpd->txnext >= CYGNUM_DEVS_ETH_ARM_EP93XX_TxNUM)    {        cpd->txnext = 0;    }    // Put data into buffer    // TODO is this correct??? this was not here before I added it PJJ//    HAL_VIRT_TO_UNCACHED_ADDRESS( hdr->bufaddr, bp );    bp = hdr->bufaddr;    for (i = 0;  i < sg_len;  i++)    {        data = (unsigned char *)sg_list[i].buf;        len = sg_list[i].len;        if(bp == 0)        {            diag_printf("ep93xx_send() bp was 0\n");            while (1);        }        if(data == 0)        {            diag_printf("ep93xx_send() data was 0\n");            while (1);        }        memcpy(bp, data, len);        bp += len;        if(bp > ((unsigned char *)hdr->bufaddr + CYGNUM_DEVS_ETH_ARM_EP93XX_BUFSIZE))        {            diag_printf("ep93xx_send() out of bounds\n");            while (1);        }    }        // Tell the device it's ready    HAL_WRITE_UINT32(MAC_TxDEQ, 1);  // Increments number of "valid" descriptors#ifdef ETHDEBUG    dprintf("ep93xx_send() exit\n");#endif // ETHDEBUG}//// This function is called when a packet has been sentstatic voidep93xx_TxEvent(struct eth_drv_sc *sc, unsigned long stat){    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;    int i, bi;    TxStat *sp;#ifdef ETHDEBUG    dprintf("ep93xx_TxEvent()\n");#endif // ETHDEBUG    if(cpd == 0)    {#ifdef ETHDEBUG        dprintf("ep93xx_TxEvent cpd is NULL!");#endif // ETHDEBUG    }        sp = cpd->txstat;    for (i = 0;  i < CYGNUM_DEVS_ETH_ARM_EP93XX_TxNUM;  i++, sp++)    {        if (sp->fp)        {            // This status is valid            bi = sp->bi;            cpd->txbusy--;            sp->fp = 0;            (sc->funs->eth_drv->tx_done)(sc, cpd->txkey[bi], 0);            cpd->txkey[bi] = 0;        }    }#ifdef ETHDEBUG    dprintf("ep93xx_TxEventExit()\n");#endif // ETHDEBUG}// ------------------------------------------------------------------------// This functio n is called when a packet has been received.  Its job is// to prepare to unload the packet from the hardware.  Once the length of// the packet is known, the upper layer of the driver can be told.  When// the upper layer is ready to unload the packet, the internal function// 'ep93xx_recv' will be called to actually fetch it from the hardware.//static voidep93xx_RxEvent(struct eth_drv_sc *sc){    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;    static int events=0;#ifdef ETHDEBUG    dprintf("ep93xx_RxEvent()\n");#endif // ETHDEBUG    if(cpd == 0)    {#ifdef ETHDEBUG        dprintf("ep93xx_RxEvent cpd is NULL!\n");#endif // ETHDEBUG        while (1);    }    if(sc == 0)    {#ifdef ETHDEBUG        dprintf("ep93xx_RxEvent sc is NULL!\n");#endif // ETHDEBUG                while (1);    }        while (cpd->rxsp->fp)    {#ifdef ETHDEBUG        dprintf("recv fp = %08x sc=%08x events %08x len=%08x.\n",cpd->rxsp->fp,sc, events, cpd->rxsp->len);#endif // ETHDEBUG        if((events++ < 40) || (cpd->rxsp->len != 0x3a))        {            (sc->funs->eth_drv->recv)(sc, cpd->rxsp->len);        }         cpd->rxsp->fp = 0;        cpd->rxsp->rfp = 0;        cpd->rxsp->len = 0;        cpd->rxsp++;        if (cpd->rxsp >= &cpd->rxstat[CYGNUM_DEVS_ETH_ARM_EP93XX_RxNUM])        {            cpd->rxsp = cpd->rxstat;        }        // Tell device we took the data        HAL_WRITE_UINT32(MAC_RxDEQ, 1);        HAL_WRITE_UINT32(MAC_RxSEQ, 1);    }#ifdef ETHDEBUG    dprintf("ep93xx_RxEvent() Exit\n");#endif // ETHDEBUG}//// This function is called as a result of the "eth_drv_recv()" call above.// It's job is to actually fetch data for a packet from the hardware once// memory buffers have been allocated for the packet.  Note that the buffers// may come in pieces, using a scatter-gather list.  This allows for more// efficient processing in the upper layers of the stack.//static voidep93xx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len){    struct ep93xx_priv_data *cpd = (struct ep93xx_priv_data *)sc->driver_private;    int i, mlen;    cyg_uint8 *data, *bp;    int tot_len = 0;    cyg_uint32 pp, uu;#ifdef ETHDEBUG    dprintf("ep93xx_recv()\n");#endif // ETHDEBUG    if(cpd == 0)    {        diag_printf("ep93xx_recv cpd is NULL!");        while(1);    }    if (cpd->rxsp->bi >= CYGNUM_DEVS_ETH_ARM_EP93XX_RxNUM)    {        dprintf("ep93xx_recv bi is > %03x!",CYGNUM_DEVS_ETH_ARM_EP93XX_RxNUM);        while(1);    }    HAL_PHYS_TO_VIRT_ADDRESS(cpd->rxhdrs[cpd->rxsp->bi].bufaddr, pp);    HAL_VIRT_TO_UNCACHED_ADDRESS(pp, uu);    bp = (cyg_uint8 *)uu; // uncached access to the data    for (i = 0;  i < sg_len;  i++)    {        data = (cyg_uint8 *)sg_list[i].buf;        mlen = sg_list[i].len;        if(data == 0)        {            dprintf("ep93xx_recv() data was NULL i=%08x len=%08x sg_list=%08x\n",i,mlen,sg_list);            continue;        }        if(bp == 0)        {            dprintf("ep93xx_recv() bp was NULL\n");        }//        diag_printf("ep93xx_recv() data=%08x bp=%08x len=%08x\n",data, bp, mlen);        memcpy(data, bp, mlen);        bp += mlen;        tot_len += mlen;    }#ifdef ETHDEBUG    dprintf("ep93xx_recv()\n");#endif // ETHDEBUG}// ------------------------------------------------------------------------//// ------------------------------------------------------------------------static voidep93xx_poll(struct eth_drv_sc *sc){    unsigned long status;    //, orig_status;//    unsigned short seq;    HAL_READ_UINT32(MAC_IntStat, status);//    orig_status = status;//#if 1//    // The chip does not seem to present the RxSQ interrupt//    HAL_READ_UINT16(MAC_RxSEQ_Count, seq);//    if (seq != CYGNUM_DEVS_ETH_ARM_EP93XX_RxNUM)//    //        status |= (MAC_IntStat_RxSQ);//    }//#endif    if (MAC_IntStat_Tx & status)    {        ep93xx_TxEvent(sc, status);    }    if (MAC_IntStat_Rx & status)    {        ep93xx_RxEvent(sc);    }        //    // Clear the interrupts    //    HAL_WRITE_UINT32(MAC_IntStat, status);}  // ------------------------------------------------------------------------// EOF if_ep93xx.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -