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; } } }
static err_t low_level_output(struct netif *netif, struct pbuf *p) { SYS_ARCH_DECL_PROTECT(lev); err_t err; struct xemac_s *xemac = (struct xemac_s *)(netif->state); xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state); /* * With AXI Ethernet on Zynq, we observed unexplained delays for * BD Status update. As a result, we are hitting a condition where * there are no BDs free to transmit packets. So, we have added * this logic where we look for the status update in a definite * loop. */ XAxiDma_BdRing *txring = XAxiDma_GetTxRing(&xaxiemacif->axidma); int count = 100; SYS_ARCH_PROTECT(lev); while (count) { /* check if space is available to send */ if (is_tx_space_available(xaxiemacif)) { _unbuffered_low_level_output(xaxiemacif, p); err = ERR_OK; break; } else { #if LINK_STATS lwip_stats.link.drop++; #endif process_sent_bds(txring); count--; } } if (count == 0) { print("pack dropped, no space\r\n"); err = ERR_MEM; } SYS_ARCH_UNPROTECT(lev); return err; }
void emacps_send_handler(void *arg) { struct xemac_s *xemac; xemacpsif_s *xemacpsif; XEmacPs_BdRing *TxRingPtr; #ifdef OS_IS_FREERTOS xInsideISR++; #endif xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); TxRingPtr = &(XEmacPs_GetTxRing(&xemacpsif->emacps)); /* If Transmit done interrupt is asserted, process completed BD's */ process_sent_bds(TxRingPtr); #ifdef OS_IS_FREERTOS xInsideISR--; #endif }
void emacps_send_handler(void *arg) { struct xemac_s *xemac; xemacpsif_s *xemacpsif; XEmacPs_BdRing *txringptr; u32_t regval; #ifdef OS_IS_FREERTOS xInsideISR++; #endif xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); txringptr = &(XEmacPs_GetTxRing(&xemacpsif->emacps)); regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET); XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval); /* If Transmit done interrupt is asserted, process completed BD's */ process_sent_bds(txringptr); #ifdef OS_IS_FREERTOS xInsideISR--; #endif }