void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord) { struct xemac_s *xemac; xemacpsif_s *xemacpsif; struct xtopology_t *xtopologyp; XEmacPs *xemacps; XEmacPs_BdRing *rxring; XEmacPs_BdRing *txring; xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps); txring = &XEmacPs_GetRxRing(&xemacpsif->emacps); xtopologyp = &xtopology[xemac->topology_index]; xemacps = &xemacpsif->emacps; if (ErrorWord != 0) { switch (Direction) { case XEMACPS_RECV: if (ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Receive DMA error\r\n")); HandleEmacPsError(xemac); } if (ErrorWord & XEMACPS_RXSR_RXOVR_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Receive over run\r\n")); emacps_recv_handler(arg); setup_rx_bds(rxring); } if (ErrorWord & XEMACPS_RXSR_BUFFNA_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Receive buffer not available\r\n")); emacps_recv_handler(arg); setup_rx_bds(rxring); } break; case XEMACPS_SEND: if (ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Transmit DMA error\r\n")); HandleEmacPsError(xemac); } if (ErrorWord & XEMACPS_TXSR_URUN_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Transmit under run\r\n")); HandleTxErrors(xemac); } if (ErrorWord & XEMACPS_TXSR_BUFEXH_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Transmit buffer exhausted\r\n")); HandleTxErrors(xemac); } if (ErrorWord & XEMACPS_TXSR_RXOVR_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Transmit retry excessed limits\r\n")); HandleTxErrors(xemac); } if (ErrorWord & XEMACPS_TXSR_FRAMERX_MASK) { LWIP_DEBUGF(NETIF_DEBUG, ("Transmit collision\r\n")); process_sent_bds(txring); } break; } } }
void emacps_recv_handler(void *arg) { struct pbuf *p; XEmacPs_Bd *rxbdset, *curbdptr; struct xemac_s *xemac; xemacpsif_s *xemacpsif; XEmacPs_BdRing *rxring; volatile s32_t bd_processed; s32_t rx_bytes, k; u32_t bdindex; u32_t regval; xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps); #ifdef OS_IS_FREERTOS xInsideISR++; #endif /* * If Reception done interrupt is asserted, call RX call back function * to handle the processed BDs and then raise the according flag. */ regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET); XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval); resetrx_on_no_rxdata(xemacpsif); while(1) { bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset); if (bd_processed <= 0) { break; } for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) { bdindex = XEMACPS_BD_TO_INDEX(rxring, curbdptr); p = (struct pbuf *)rx_pbufs_storage[bdindex]; /* * Adjust the buffer size to the actual number of bytes received. */ rx_bytes = XEmacPs_BdGetLength(curbdptr); pbuf_realloc(p, rx_bytes); /* store it in the receive queue, * where it'll be processed by a different handler */ if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); } else { #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif } curbdptr = XEmacPs_BdRingNext( rxring, curbdptr); } /* free up the BD's */ XEmacPs_BdRingFree(rxring, bd_processed, rxbdset); setup_rx_bds(rxring); } #ifdef OS_IS_FREERTOS xInsideISR--; #endif return; }