📄 dp83815.c
字号:
/*---------------------------------------------------------------*/ buf = TxNetBuf[TxFreeBD - &BufDesc[BEG_TX_BD]]; tcpRetBuf(&buf); } }}/***********************************************************************//* prep_txbd: Prepare next transmit buffer descriptor *//* *//***********************************************************************/static void prep_txbd(void *bufptr, int length, ui32 status){ /*-------------------------------------------------------------------*/ /* Set descriptor's buffer pointer and command/status fields. */ /*-------------------------------------------------------------------*/ TxNextBD->bufptr = htopl((ui32)bufptr); TxNextBD->cmdsts = htopl(status | length); /*-------------------------------------------------------------------*/ /* Copy buffer and then descriptor from cache. */ /*-------------------------------------------------------------------*/ _cache_copyback(bufptr, length); if (status) _cache_copyback(TxNextBD, sizeof(BufDescType)); /*-------------------------------------------------------------------*/ /* Increment busy descriptor count. */ /*-------------------------------------------------------------------*/ ++NumBusyTxBds; /*-------------------------------------------------------------------*/ /* Set status bit and advance TxNextBD. */ /*-------------------------------------------------------------------*/ if (TxNextBD == &BufDesc[END_TX_BD]) TxNextBD = &BufDesc[BEG_TX_BD]; else ++TxNextBD;}/***********************************************************************//* fill_tx_ring: Move buffers from the outbound queue to the transmit *//* buffer descriptor ring, if possible. *//* *//***********************************************************************/static void fill_tx_ring(void){ int added; NetBuf *buf; /*-------------------------------------------------------------------*/ /* Fill any empty transmit descriptors, setting flag if any filled. */ /*-------------------------------------------------------------------*/ for (added = FALSE;; added = TRUE) { /*-----------------------------------------------------------------*/ /* Break if no outbound buffers are queued. */ /*-----------------------------------------------------------------*/ buf = TxMsgQHead; if (buf == NULL) break; /*-----------------------------------------------------------------*/ /* Break if there are not enough free descriptors. */ /*-----------------------------------------------------------------*/ if ((NUM_TX_BDS - NumBusyTxBds) <= buf->order) break; /*-----------------------------------------------------------------*/ /* Extract the top outbound buffer. */ /*-----------------------------------------------------------------*/ TxMsgQHead = TxMsgQHead->next; /*-----------------------------------------------------------------*/ /* Check if there is only one data region. */ /*-----------------------------------------------------------------*/ if (buf->app_len == 0) prep_txbd(buf->ip_pkt, buf->length, DP_DESC_CMDSTS_OWN); /*-----------------------------------------------------------------*/ /* Else multiple buffer descriptors need to be prepared. */ /*-----------------------------------------------------------------*/ else { int first_len = buf->length; BufDescType *first_bd = TxNextBD; /*---------------------------------------------------------------*/ /* Prepare the first buffer descriptor. */ /*---------------------------------------------------------------*/ prep_txbd(buf->ip_pkt, first_len, 0); /*---------------------------------------------------------------*/ /* If there are three data regions, prepare middle and last. */ /*---------------------------------------------------------------*/ if (buf->app_len2) { prep_txbd(buf->app_data, buf->app_len, DP_DESC_CMDSTS_OWN | DP_DESC_CMDSTS_MORE); prep_txbd(buf->app_data2, buf->app_len2, DP_DESC_CMDSTS_OWN); } /*---------------------------------------------------------------*/ /* Else just prepare a buffer descriptor for the last region. */ /*---------------------------------------------------------------*/ else prep_txbd(buf->app_data, buf->app_len, DP_DESC_CMDSTS_OWN); /*---------------------------------------------------------------*/ /* Finish initial descriptor, enabling start of transmission. */ /*---------------------------------------------------------------*/ first_bd->cmdsts = htopl(DP_DESC_CMDSTS_OWN | DP_DESC_CMDSTS_MORE | first_len); _cache_copyback(first_bd, sizeof(BufDescType)); } /*-----------------------------------------------------------------*/ /* Save NetBuf pointer for tcpRetBuf() after transmission. */ /*-----------------------------------------------------------------*/ TxNetBuf[TxNextBD - &BufDesc[BEG_TX_BD]] = buf; } /*-------------------------------------------------------------------*/ /* Re-enable DP83815 transmitter if any buffers were added. */ /*-------------------------------------------------------------------*/ if (added) DP_REG32_SET(DP_CR, DP_CR_TXE);}/***********************************************************************//* fill_rx_ring: Assign buffers to "used" receive buffer descriptors, *//* marking them as empty, available to be filled again *//* by the receiver. *//* *//***********************************************************************/static void fill_rx_ring(void){ NetBuf *buf; int added; ui8 *cp; /*-------------------------------------------------------------------*/ /* Check for empty receive descriptors. Set flag if any were added. */ /*-------------------------------------------------------------------*/ for (added = FALSE;; added = TRUE) { /*-----------------------------------------------------------------*/ /* Exit if receive buffer descriptor ring is filled with buffers. */ /*-----------------------------------------------------------------*/ if (RxFillBD->bufptr) break; /*-----------------------------------------------------------------*/ /* Allocate 60 bytes for conversion from 4 to 64-byte alignment */ /* and 1518 for truncation limit. Exit if no buffers available. */ /*-----------------------------------------------------------------*/ buf = tcpGetBuf(60 + 1518); if (buf == NULL) break; /*-----------------------------------------------------------------*/ /* Save NetBuf pointer for processing after reception. */ /*-----------------------------------------------------------------*/ RxNetBuf[RxFillBD - &BufDesc[BEG_RX_BD]] = buf; /*-----------------------------------------------------------------*/ /* Buffer pointer must be aligned on 64-byte boundary. */ /*-----------------------------------------------------------------*/ cp = (ui8 *)((ui32)(buf->data + 63) & ~63); /*-----------------------------------------------------------------*/ /* Ensure no stale data is left marked as valid. */ /*-----------------------------------------------------------------*/ _cache_invalidate(cp, 1514); /*-----------------------------------------------------------------*/ /* Initialize buffer descriptor and write from cache. */ /*-----------------------------------------------------------------*/ RxFillBD->bufptr = htopl((ui32)cp); RxFillBD->cmdsts = htopl(1536); /* size in 32 byte multiples */ _cache_copyback(RxFillBD, sizeof(BufDescType)); /*-----------------------------------------------------------------*/ /* Advance to next buffer descriptor. */ /*-----------------------------------------------------------------*/ if (RxFillBD == &BufDesc[END_RX_BD]) RxFillBD = &BufDesc[BEG_RX_BD]; else ++RxFillBD; } /*-------------------------------------------------------------------*/ /* Re-enable DP83815 receiver if any buffers were added. */ /*-------------------------------------------------------------------*/ if (added) DP_REG32_SET(DP_CR, DP_CR_RXE);}/***********************************************************************//* receive_bufs: Process all received buffers *//* *//***********************************************************************/static void receive_bufs(void){ uint length; ui32 status; FRAME *frame; NetBuf *buf; /*-------------------------------------------------------------------*/ /* Loop to process received buffers. */ /*-------------------------------------------------------------------*/ for (;;) { /*-----------------------------------------------------------------*/ /* Exit upon reaching a buffer we've already processed. */ /*-----------------------------------------------------------------*/ if (RxNextBD->bufptr == 0) break; /*-----------------------------------------------------------------*/ /* Invalidate any stale descriptor data in cache. */ /*-----------------------------------------------------------------*/ _cache_invalidate(RxNextBD, sizeof(BufDescType)); /*-----------------------------------------------------------------*/ /* Exit upon reaching a buffer we don't own. */ /*-----------------------------------------------------------------*/ status = ptohl(RxNextBD->cmdsts); if ((status & DP_DESC_CMDSTS_OWN) == 0) break; /*-----------------------------------------------------------------*/ /* Get frame pointer and then mark descriptor as free. */ /*-----------------------------------------------------------------*/ frame = (FRAME *)RxNextBD->bufptr; RxNextBD->bufptr = 0; /*-----------------------------------------------------------------*/ /* Record that another packet has been received. */ /*-----------------------------------------------------------------*/ ++dp83815Ni.ipkts; /*-----------------------------------------------------------------*/ /* Load pointer to network buffer that holds this packet. */ /*-----------------------------------------------------------------*/ buf = RxNetBuf[RxNextBD - &BufDesc[BEG_RX_BD]]; /*-----------------------------------------------------------------*/ /* Advance to the next buffer descriptor and reenable interrupts. */ /*-----------------------------------------------------------------*/ if (RxNextBD == &BufDesc[END_RX_BD]) RxNextBD = &BufDesc[BEG_RX_BD]; else ++RxNextBD; /*-----------------------------------------------------------------*/ /* If there are errors, recycle buffer. Else pass up the frame. */ /*-----------------------------------------------------------------*/ if (status & DP_DESC_CMDSTS_RX_ERRORS) { ++dp83815Ni.ierrs; tcpRetBuf(&buf); } /*-----------------------------------------------------------------*/ /* Else need to report valid buffer received. */ /*-----------------------------------------------------------------*/ else { /*---------------------------------------------------------------*/ /* Determine packet length. */ /*---------------------------------------------------------------*/ length = (status & DP_DESC_CMDSTS_SIZE) - (ETH_HDR_LEN + ETH_CRC_LEN); /*---------------------------------------------------------------*/ /* If IEEE encapsulation, skip past LLC/SNAP headers. */ /*---------------------------------------------------------------*/ if (length >= ntohs(frame->type)) { length -= IEEE_OFFSET; frame = (FRAME *)((ui8 *)frame + IEEE_OFFSET); } /*---------------------------------------------------------------*/ /* Initialize buffer fields and then pass to TargetTCP. */ /*---------------------------------------------------------------*/ buf->ni = &dp83815Ni; buf->type = ntohs(frame->type); buf->length = length; buf->ip_pkt = (ui8 *)frame + ETH_HDR_LEN; tcpDataInd(buf); } }}/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* dp83815Init: Initialize TargetTCP DP83815 Ethernet driver *//* *//***********************************************************************/void dp83815Init(ui32 ip_addr, ui32 ip_mask, uint flags){ /*-------------------------------------------------------------------*/ /* Configure the method of IP address assignment. */ /*-------------------------------------------------------------------*/ if (flags & NIF_USE_DHCP) dp83815Ni.flags = NIF_USE_DHCP | NIF_DEF_GW; else if (flags & NIF_USE_RARP) dp83815Ni.flags = NIF_USE_RARP; else dp83815Ni.flags = 0; dp83815Ni.ip_addr = ip_addr; dp83815Ni.ip_mask = ip_mask; /*-------------------------------------------------------------------*/ /* Complete the network interface structure. */ /*-------------------------------------------------------------------*/ dp83815Ni.mtu = ETH_MTU; dp83815Ni.hw_addr = OurAddress.byte; dp83815Ni.hw_type = ETH_DIX_HW; dp83815Ni.ha_len = ETH_ALEN; dp83815Ni.transmit = transmit; dp83815Ni.broadcast = broadcast; dp83815Ni.poll = poll; dp83815Ni.name = "DP83815"; /*-------------------------------------------------------------------*/ /* Initialize hardware. If successful, add interface to TargetTCP. */ /*-------------------------------------------------------------------*/ if (ni_init() == 0) tcpAddNi(&dp83815Ni);}/***********************************************************************//* dp83815_dump: *//* *//***********************************************************************/void dp83815_dump(void){ printf("rx: tot=%u errs=%u\n", dp83815Ni.ipkts, dp83815Ni.ierrs); printf("tx: tot=%u errs=%u\n", dp83815Ni.opkts, dp83815Ni.oerrs); printf("isr: tot=%u rx=%u tx=%u\n", IsrCount, RxIsrCount, TxIsrCount);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -