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

📄 if_edb7xxx.c

📁 移植到WLIT项目的redboot源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
// the hardware ready to send/receive packets.//static voidcs8900_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags){    unsigned short stat;    put_reg(PP_BusCtl, PP_BusCtl_MemoryE);  // Disable interrupts, memory mode    put_reg(PP_IntReg, PP_IntReg_IRQ0);  // Only possibility    put_reg(PP_RxCFG, PP_RxCFG_RxOK | PP_RxCFG_CRC |                       PP_RxCFG_RUNT | PP_RxCFG_EXTRA);    put_reg(PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_Broadcast |                       PP_RxCTL_IA);    put_reg(PP_TxCFG, PP_TxCFG_TxOK | PP_TxCFG_Collision |                       PP_TxCFG_CRS | PP_TxCFG_SQE | PP_TxCFG_Late |                       PP_TxCFG_Jabber | PP_TxCFG_16Collisions);    put_reg(PP_BufCFG, PP_BufCFG_TxRDY | PP_BufCFG_TxUE | PP_BufCFG_RxMiss |                        PP_BufCFG_TxCol | PP_BufCFG_Miss | PP_BufCFG_SWI);    put_reg(PP_IntReg, PP_IntReg_IRQ0);  // Only possibility    put_reg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);    // Clear Interrupt Status Queue before enabling interrupts    while ((stat = CS8900_ISQ) != 0) ;    put_reg(PP_BusCtl, PP_BusCtl_EnableIRQ);}//// This routine is called to perform special "control" opertions//static intcs8900_control(struct eth_drv_sc *sc, unsigned long key,               void *data, int data_length){    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 intcs8900_can_send(struct eth_drv_sc *sc){    struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private;    unsigned short stat;    stat = get_reg(PP_LineStat);    if ((stat & PP_LineStat_LinkOK) == 0) {        return false;  // Link not connected    }#ifdef CYGPKG_NET    // Horrible hack!    if (cpd->txbusy > 0) {        cyg_tick_count_t now = cyg_current_time();        if ((now - cpd->txstart) > 25) {            // 250ms is more than enough to transmit one frame            diag_printf("CS8900: Tx interrupt lost\n");            cpd->txbusy = 0;            // Free up the buffer (with error indication)            (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 1);        }    }#endif    return (cpd->txbusy == 0);}//// This routine is called to send data to the hardware.static void cs8900_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,             int total_len, unsigned long key){    struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private;    int i;    int len;    unsigned char *data;    unsigned short saved_data = 0, *sdata;    unsigned short stat;    bool odd_byte = false;    // Mark xmitter busy    cpd->txbusy = 1;    cpd->txkey = key;#ifdef CYGPKG_NET    cpd->txstart = cyg_current_time();#endif    // Start the xmit sequence// Note: this can go back once the 'dump' is removed    CS8900_TxCMD = PP_TxCmd_TxStart_5;  // Start more-or-less immediately//    CS8900_TxCMD = PP_TxCmd_TxStart_Full;  // Start only when all data sent to chip    CS8900_TxLEN = total_len;    stat = get_reg(PP_BusStat);  // This actually starts the xmit    // Put data into buffer    for (i = 0;  i < sg_len;  i++) {        data = (unsigned char *)sg_list[i].buf;        len = sg_list[i].len;        if (len > 0) {            /* Finish the last word. */            if (odd_byte) {                saved_data |= (*data++ << 8);                CS8900_RTDATA = saved_data;                len--;                odd_byte = false;            }            /* Output contiguous words. */            sdata = (unsigned short *)data;            while (len > 1) {                CS8900_RTDATA = *sdata++;                len -= sizeof(unsigned short);            }            /* Save last byte, if necessary. */            if (len == 1) {                data = (unsigned char *)sdata;                saved_data = *data;                odd_byte = true;            }        }    }    if (odd_byte) {        CS8900_RTDATA = saved_data;    }}//// This function is called when a packet has been received.  It's 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// 'cs8900_recv' will be called to actually fetch it from the hardware.//static voidcs8900_RxEvent(struct eth_drv_sc *sc){    unsigned short stat, len;    stat = CS8900_RTDATA;    len = CS8900_RTDATA;    if (net_debug) {        diag_printf("RxEvent - stat: %x, len: %d\n", stat, len);    }    (sc->funs->eth_drv->recv)(sc, len);}//// 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 voidcs8900_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len){    int i, mlen;    unsigned short *data, val;    unsigned char *cp, cval;    for (i = 0;  i < sg_len;  i++) {        data = (unsigned short *)sg_list[i].buf;        mlen = sg_list[i].len;        while (mlen >= sizeof(*data)) {            val = CS8900_RTDATA;            if (data) {                *data++ = val;            }            mlen -= sizeof(*data);        }        if (mlen) {            // Fetch last odd byte            cval = CS8900_RTDATA & 0xFF;            if ((cp = (unsigned char *)data) != 0) {                *cp = cval;            }        }    }}static voidcs8900_TxEvent(struct eth_drv_sc *sc, int stat){    struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private;    stat = get_reg(PP_TER);    if (net_debug) {        diag_printf("Tx event: %x\n", stat);    }    cpd->txbusy = 0;    (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);}static voidcs8900_BufEvent(struct eth_drv_sc *sc, int stat){    if (stat & PP_BufCFG_RxMiss) {    }    if (stat & PP_BufCFG_TxUE) {    }}static voidcs8900_int(struct eth_drv_sc *sc){    unsigned short event;    while ((event = CS8900_ISQ) != 0) {        switch (event & ISQ_EventMask) {        case ISQ_RxEvent:            cs8900_RxEvent(sc);            break;        case ISQ_TxEvent:            cs8900_TxEvent(sc, event);            break;        case ISQ_BufEvent:            cs8900_BufEvent(sc, event);            break;        case ISQ_RxMissEvent:            // Receive miss counter has overflowed            break;        case ISQ_TxColEvent:            // Transmit collision counter has overflowed            break;        default:            diag_printf("%s: Unknown event: %x\n", __FUNCTION__, event);            break;        }    }}#ifdef INTS_DONT_WORKvoidcs8900_fake_int(cyg_addrword_t param){    int s;    while (true) {        cyg_thread_delay(5);        s = splnet();        cs8900_int(&edb7xxx_sc);        splx(s);    }}#endif

⌨️ 快捷键说明

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