예제 #1
0
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;
		}
	}
}
예제 #2
0
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;
}
예제 #3
0
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
}
예제 #4
0
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
}