static void xllfifo_recv_handler(struct xemac_s *xemac) { u32_t frame_length; struct pbuf *p; xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state); XLlFifo *llfifo = &xaxiemacif->axififo; /* While there is data in the fifo ... */ while (XLlFifo_RxOccupancy(llfifo)) { /* find packet length */ frame_length = XLlFifo_RxGetLen(llfifo); /* allocate a pbuf */ p = pbuf_alloc(PBUF_RAW, frame_length, PBUF_POOL); if (!p) { char tmp_frame[XAE_MAX_FRAME_SIZE]; #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif /* receive and drop packet to keep data & len registers in sync */ XLlFifo_Read(llfifo, tmp_frame, frame_length); continue; } /* receive packet */ XLlFifo_Read(llfifo, p->payload, frame_length); #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* store it in the receive queue, where it'll be processed by xemacif input thread */ if (pq_enqueue(xaxiemacif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); continue; } #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif #if LINK_STATS lwip_stats.link.recv++; #endif } }
/** * * This example uses polled mode to queue up multiple frames in the packet * FIFOs before sending them in a single burst. Receive packets are handled in * a similar way. * * @param None. * * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. * * @note None. * ******************************************************************************/ int TemacMultipleFramesPolledExample(void) { u32 FramesToLoopback; u32 PayloadSize; u32 TxFrameLength; u32 RxFrameLength; u32 FifoFreeBytes; u32 Index; /* * Start the TEMAC device */ XLlTemac_Start(&TemacInstance); /* * Setup the number of frames to loopback (FramesToLoopback) and the size * of the frame (PayloadSize) to loopback. The default settings should * work for every case. Modifying the settings can cause problems, see * discussion below: * * If PayloadSize is set small and FramesToLoopback high, then it is * possible to cause the transmit status FIFO to overflow. * * If PayloadSize is set large and FramesToLoopback high, then it is * possible to cause the transmit packet FIFO to overflow. * * Either of these scenarios may be worth trying out to observe how the * driver reacts. The exact values to cause these types of errors * will vary due to the sizes of the FIFOs selected at hardware build * time. But the following settings should create problems for all * FIFO sizes: * * Transmit status FIFO overflow * PayloadSize = 1 * FramesToLoopback = 1000 * * Transmit packet FIFO overflow * PayloadSize = 1500 * FramesToLoopback = 16 * * These values should always work without error * PayloadSize = 100 * FramesToLoopback = 5 */ PayloadSize = 100; FramesToLoopback = 5; /* * Calculate Tx frame length (not including FCS) */ TxFrameLength = XTE_HDR_SIZE + PayloadSize; /* * Setup the packet to be transmitted */ TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC); TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize); TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize); /****************/ /* Send packets */ /****************/ /* * Since we may be interested to see what happens when FIFOs overflow, don't * check for room in the transmit packet FIFO prior to writing to it. */ /* * Write frame data to FIFO * Fifo core only allows loading and sending one frame at a time. */ for (Index = 0; Index < FramesToLoopback; Index++) { /* Make sure there is room in the FIFO */ do { FifoFreeBytes = XLlFifo_TxVacancy(&FifoInstance); } while (FifoFreeBytes < TxFrameLength); XLlFifo_Write(&FifoInstance, TxFrame, TxFrameLength); XLlFifo_TxSetLen(&FifoInstance, TxFrameLength); switch (TemacPollForTxStatus()) { case XST_SUCCESS: /* Got a sucessfull transmit status */ break; case XST_NO_DATA: /* Timed out */ TemacUtilErrorTrap("Tx timeout"); return XST_FAILURE; break; default: /* Some other error */ TemacResetDevice(); return XST_FAILURE; } } /**********************/ /* Receive the packet */ /**********************/ /* * Wait for the packets to arrive * The Fifo core only allows us to pull out one frame at a time. */ for (Index = 0; Index < FramesToLoopback; Index++) { /* * Wait for packet Rx */ switch (TemacPollForRxStatus()) { case XST_SUCCESS: /* Got a successfull receive status */ break; case XST_NO_DATA: /* Timed out */ TemacUtilErrorTrap("Rx timeout"); return XST_FAILURE; break; default: /* Some other error */ TemacResetDevice(); return XST_FAILURE; } while(XLlFifo_RxOccupancy(&FifoInstance)) { /* * A packet has arrived, get its length */ RxFrameLength = XLlFifo_RxGetLen(&FifoInstance); /* * Verify the received frame length */ if ((RxFrameLength) != TxFrameLength) { TemacUtilErrorTrap("Receive length incorrect"); return XST_FAILURE; } /* * Read the received packet data */ XLlFifo_Read(&FifoInstance, &RxFrame, RxFrameLength); if (TemacUtilFrameVerify(&TxFrame, &RxFrame) != 0) { TemacUtilErrorTrap("Receive Data Mismatch"); return XST_FAILURE; } } } /* * Stop device */ XLlTemac_Stop(&TemacInstance); return XST_SUCCESS; }
/** * * This function demonstrates the usage of the TEMAC by sending and receiving * a single frame in polled mode. * * @param None. * * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. * * @note None. * ******************************************************************************/ int TemacSingleFramePolledExample(void) { u32 FifoFreeBytes; int PayloadSize = 100; u32 TxFrameLength; u32 RxFrameLength; /* * Start the TEMAC device */ XLlTemac_Start(&TemacInstance); /* * Setup the packet to be transmitted */ TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC); TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize); TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize); /* * Clear out the receive packet memory area */ TemacUtilFrameMemClear(&RxFrame); /* * Calculate frame length (not including FCS) */ TxFrameLength = XTE_HDR_SIZE + PayloadSize; /*******************/ /* Send the packet */ /*******************/ /* * Wait for enough room in FIFO to become available */ do { FifoFreeBytes = XLlFifo_TxVacancy(&FifoInstance); } while (FifoFreeBytes < TxFrameLength); /* * Write the frame data to FIFO */ XLlFifo_Write(&FifoInstance, TxFrame, TxFrameLength); /* * Initiate transmit */ XLlFifo_TxSetLen(&FifoInstance, TxFrameLength); /* * Wait for status of the transmitted packet */ switch (TemacPollForTxStatus()) { case XST_SUCCESS: /* Got a sucessfull transmit status */ break; case XST_NO_DATA: /* Timed out */ TemacUtilErrorTrap("Tx timeout"); return XST_FAILURE; default: /* Some other error */ return XST_FAILURE; } /**********************/ /* Receive the packet */ /**********************/ /* * Wait for packet Rx */ switch (TemacPollForRxStatus()) { case XST_SUCCESS: /* Got a sucessfull receive status */ break; case XST_NO_DATA: /* Timed out */ TemacUtilErrorTrap("Rx timeout"); return XST_FAILURE; default: /* Some other error */ return XST_FAILURE; } while(XLlFifo_RxOccupancy(&FifoInstance)) { /* * A packet as arrived, get its length */ RxFrameLength = XLlFifo_RxGetLen(&FifoInstance); /* * Read the received packet data */ XLlFifo_Read(&FifoInstance, &RxFrame, RxFrameLength); /* * Verify the received frame length */ if ((RxFrameLength) != TxFrameLength) { TemacUtilErrorTrap("Receive length incorrect"); return XST_FAILURE; } /* * Validate frame data */ if (TemacUtilFrameVerify(&TxFrame, &RxFrame) != 0) { TemacUtilErrorTrap("Receive Data mismatch"); return XST_FAILURE; } } /* * Stop device */ XLlTemac_Stop(&TemacInstance); return XST_SUCCESS; }