]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/lwIP_port/netif/xemacpsif_dma.c
Add lwIP driver into Zynq demo - not yet fully functional.
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo / src / Full_Demo / lwIP_port / netif / xemacpsif_dma.c
1 /*
2  * Copyright (c) 2010-2013 Xilinx, Inc.  All rights reserved.
3  *
4  * Xilinx, Inc.
5  * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
6  * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
7  * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
8  * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
9  * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
10  * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
11  * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
12  * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
13  * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
14  * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  */
18
19 #include "lwipopts.h"
20 #include "lwip/stats.h"
21 #include "lwip/sys.h"
22 #include "lwip/inet_chksum.h"
23
24 #include "netif/xadapter.h"
25 #include "netif/xemacpsif.h"
26 #include "xstatus.h"
27
28 #include "xlwipconfig.h"
29 #include "xparameters.h"
30 #include "xparameters_ps.h"
31 #include "xil_exception.h"
32 #include "xil_mmu.h"
33 #ifdef CONFIG_XTRACE
34 #include "xtrace.h"
35 #endif
36 #ifdef OS_IS_FREERTOS
37 #include "FreeRTOS.h"
38 #include "semphr.h"
39 #include "timers.h"
40 #endif
41
42 /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
43  *** to run it on a PEEP board
44  ***/
45
46 #define INTC_BASE_ADDR          XPAR_SCUGIC_CPU_BASEADDR
47 #define INTC_DIST_BASE_ADDR     XPAR_SCUGIC_DIST_BASEADDR
48
49 /* Byte alignment of BDs */
50 #define BD_ALIGNMENT (XEMACPS_DMABD_MINIMUM_ALIGNMENT*2)
51
52 static int tx_pbufs_storage[XLWIP_CONFIG_N_TX_DESC];
53 static int rx_pbufs_storage[XLWIP_CONFIG_N_RX_DESC];
54
55 static int EmacIntrNum;
56 extern u8 _end;
57
58 #ifdef OS_IS_FREERTOS
59 long xInsideISR = 0;
60 #endif
61
62 #define XEMACPS_BD_TO_INDEX(ringptr, bdptr)                             \
63         (((u32)bdptr - (u32)(ringptr)->BaseBdAddr) / (ringptr)->Separation)
64
65
66 int is_tx_space_available(xemacpsif_s *emac)
67 {
68         XEmacPs_BdRing *txring;
69         int freecnt = 0;
70
71         txring = &(XEmacPs_GetTxRing(&emac->emacps));
72
73         /* tx space is available as long as there are valid BD's */
74         freecnt = XEmacPs_BdRingGetFreeCnt(txring);
75         return freecnt;
76 }
77
78 void process_sent_bds(XEmacPs_BdRing *txring)
79 {
80         XEmacPs_Bd *txbdset;
81         XEmacPs_Bd *CurBdPntr;
82         int n_bds;
83         XStatus Status;
84         int n_pbufs_freed = 0;
85         unsigned int BdIndex;
86         struct pbuf *p;
87         unsigned int *Temp;
88
89         while (1) {
90                 /* obtain processed BD's */
91                 n_bds = XEmacPs_BdRingFromHwTx(txring,
92                                                                 XLWIP_CONFIG_N_TX_DESC, &txbdset);
93                 if (n_bds == 0)  {
94                         return;
95                 }
96                 /* free the processed BD's */
97                 n_pbufs_freed = n_bds;
98                 CurBdPntr = txbdset;
99                 while (n_pbufs_freed > 0) {
100                         BdIndex = XEMACPS_BD_TO_INDEX(txring, CurBdPntr);
101                         Temp = (unsigned int *)CurBdPntr;
102                         *Temp = 0;
103                         Temp++;
104                         *Temp = 0x80000000;
105                         if (BdIndex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
106                                 *Temp = 0xC0000000;
107                         }
108
109                         p = (struct pbuf *)tx_pbufs_storage[BdIndex];
110                         if(p != NULL) {
111                                 pbuf_free(p);
112                         }
113                         tx_pbufs_storage[BdIndex] = 0;
114                         CurBdPntr = XEmacPs_BdRingNext(txring, CurBdPntr);
115                         n_pbufs_freed--;
116                         dsb();
117                 }
118
119                 Status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
120                 if (Status != XST_SUCCESS) {
121                         LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
122                 }
123         }
124         return;
125 }
126
127 void emacps_send_handler(void *arg)
128 {
129         struct xemac_s *xemac;
130         xemacpsif_s   *xemacpsif;
131         XEmacPs_BdRing *TxRingPtr;
132         unsigned int regval;
133 #ifdef OS_IS_FREERTOS
134         xInsideISR++;
135 #endif
136         xemac = (struct xemac_s *)(arg);
137         xemacpsif = (xemacpsif_s *)(xemac->state);
138         TxRingPtr = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
139         regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
140         XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval);
141
142         /* If Transmit done interrupt is asserted, process completed BD's */
143         process_sent_bds(TxRingPtr);
144 #ifdef OS_IS_FREERTOS
145         xInsideISR--;
146 #endif
147 }
148
149 XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p)
150 {
151         struct pbuf *q;
152         int n_pbufs;
153         XEmacPs_Bd *txbdset, *txbd, *last_txbd = NULL;
154         XEmacPs_Bd *temp_txbd;
155         XStatus Status;
156         XEmacPs_BdRing *txring;
157         unsigned int BdIndex;
158         unsigned int lev;
159
160         lev = mfcpsr();
161         mtcpsr(lev | 0x000000C0);
162
163 #ifdef PEEP
164     while((XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
165                                                                         XEMACPS_TXSR_OFFSET)) & 0x08);
166 #endif
167         txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
168
169         /* first count the number of pbufs */
170         for (q = p, n_pbufs = 0; q != NULL; q = q->next)
171                 n_pbufs++;
172
173         /* obtain as many BD's */
174         Status = XEmacPs_BdRingAlloc(txring, n_pbufs, &txbdset);
175         if (Status != XST_SUCCESS) {
176                 mtcpsr(lev);
177                 LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error allocating TxBD\r\n"));
178                 return ERR_IF;
179         }
180
181         for(q = p, txbd = txbdset; q != NULL; q = q->next) {
182                 BdIndex = XEMACPS_BD_TO_INDEX(txring, txbd);
183                 if (tx_pbufs_storage[BdIndex] != 0) {
184                         mtcpsr(lev);
185                         LWIP_DEBUGF(NETIF_DEBUG, ("PBUFS not available\r\n"));
186                         return ERR_IF;
187                 }
188
189                 /* Send the data from the pbuf to the interface, one pbuf at a
190                    time. The size of the data in each pbuf is kept in the ->len
191                    variable. */
192                 Xil_DCacheFlushRange((unsigned int)q->payload, (unsigned)q->len);
193
194                 XEmacPs_BdSetAddressTx(txbd, (u32)q->payload);
195                 if (q->len > (XEMACPS_MAX_FRAME_SIZE - 18))
196                         XEmacPs_BdSetLength(txbd, (XEMACPS_MAX_FRAME_SIZE - 18) & 0x3FFF);
197                 else
198                         XEmacPs_BdSetLength(txbd, q->len & 0x3FFF);
199
200                 tx_pbufs_storage[BdIndex] = (int)q;
201
202                 pbuf_ref(q);
203                 last_txbd = txbd;
204                 XEmacPs_BdClearLast(txbd);
205                 dsb();
206                 txbd = XEmacPs_BdRingNext(txring, txbd);
207         }
208         XEmacPs_BdSetLast(last_txbd);
209         dsb();
210         /* For fragmented packets, remember the 1st BD allocated for the 1st
211            packet fragment. The used bit for this BD should be cleared at the end
212            after clearing out used bits for other fragments. For packets without
213            just remember the allocated BD. */
214         temp_txbd = txbdset;
215         txbd = txbdset;
216         txbd = XEmacPs_BdRingNext(txring, txbd);
217         q = p->next;
218         for(; q != NULL; q = q->next) {
219                 XEmacPs_BdClearTxUsed(txbd);
220                 txbd = XEmacPs_BdRingNext(txring, txbd);
221         }
222         XEmacPs_BdClearTxUsed(temp_txbd);
223         dsb();
224
225         Status = XEmacPs_BdRingToHw(txring, n_pbufs, txbdset);
226         if (Status != XST_SUCCESS) {
227                 mtcpsr(lev);
228                 LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error submitting TxBD\r\n"));
229                 return ERR_IF;
230         }
231         dsb();
232         /* Start transmit */
233         XEmacPs_WriteReg((xemacpsif->emacps).Config.BaseAddress,
234         XEMACPS_NWCTRL_OFFSET,
235         (XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
236         XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK));
237         dsb();
238         mtcpsr(lev);
239         return Status;
240 }
241
242 void setup_rx_bds(XEmacPs_BdRing *rxring)
243 {
244         XEmacPs_Bd *rxbd;
245         XStatus Status;
246         struct pbuf *p;
247         unsigned int FreeBds;
248         unsigned int BdIndex;
249         unsigned int *Temp;
250
251         FreeBds = XEmacPs_BdRingGetFreeCnt (rxring);
252         while (FreeBds > 0) {
253                 FreeBds--;
254                 Status = XEmacPs_BdRingAlloc(rxring, 1, &rxbd);
255                 if (Status != XST_SUCCESS) {
256                         LWIP_DEBUGF(NETIF_DEBUG, ("setup_rx_bds: Error allocating RxBD\r\n"));
257                         return;
258                 }
259                 BdIndex = XEMACPS_BD_TO_INDEX(rxring, rxbd);
260                 Temp = (unsigned int *)rxbd;
261                 *Temp = 0;
262                 if (BdIndex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
263                         *Temp = 0x00000002;
264                 }
265                 Temp++;
266                 *Temp = 0;
267
268                 p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
269                 if (!p) {
270 #if LINK_STATS
271                         lwip_stats.link.memerr++;
272                         lwip_stats.link.drop++;
273 #endif
274                         LWIP_DEBUGF(NETIF_DEBUG, ("unable to alloc pbuf in recv_handler\r\n"));
275                         XEmacPs_BdRingUnAlloc(rxring, 1, rxbd);
276                         dsb();
277                         return;
278                 }
279                 XEmacPs_BdSetAddressRx(rxbd, (u32)p->payload);
280                 dsb();
281
282                 rx_pbufs_storage[BdIndex] = (int)p;
283                 Status = XEmacPs_BdRingToHw(rxring, 1, rxbd);
284                 if (Status != XST_SUCCESS) {
285                         LWIP_DEBUGF(NETIF_DEBUG, ("Error committing RxBD to hardware: "));
286                         if (Status == XST_DMA_SG_LIST_ERROR)
287                                 LWIP_DEBUGF(NETIF_DEBUG, ("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with XEmacPs_BdRingAlloc()\r\n"));
288                         else
289                                 LWIP_DEBUGF(NETIF_DEBUG, ("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"));
290                         return;
291                 }
292         }
293 }
294
295 void emacps_recv_handler(void *arg)
296 {
297         struct pbuf *p;
298         XEmacPs_Bd *rxbdset, *CurBdPtr;
299         struct xemac_s *xemac;
300         xemacpsif_s *xemacpsif;
301         XEmacPs_BdRing *rxring;
302         volatile int bd_processed;
303         int rx_bytes, k;
304         unsigned int BdIndex;
305         unsigned int regval;
306
307         xemac = (struct xemac_s *)(arg);
308         xemacpsif = (xemacpsif_s *)(xemac->state);
309         rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
310
311 #ifdef OS_IS_FREERTOS
312         xInsideISR++;
313 #endif
314         /*
315          * If Reception done interrupt is asserted, call RX call back function
316          * to handle the processed BDs and then raise the according flag.
317          */
318         regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
319         XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval);
320
321         resetrx_on_no_rxdata(xemacpsif);
322
323         while(1) {
324
325                 bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset);
326
327                 if (bd_processed <= 0) {
328                         break;
329                 }
330
331                 for (k = 0, CurBdPtr=rxbdset; k < bd_processed; k++) {
332
333                         BdIndex = XEMACPS_BD_TO_INDEX(rxring, CurBdPtr);
334                         p = (struct pbuf *)rx_pbufs_storage[BdIndex];
335
336                         /*
337                          * Adjust the buffer size to the actual number of bytes received.
338                          */
339                         rx_bytes = XEmacPs_BdGetLength(CurBdPtr);
340                         pbuf_realloc(p, rx_bytes);
341                         Xil_DCacheInvalidateRange((unsigned int)p->payload, (unsigned)XEMACPS_MAX_FRAME_SIZE);
342                         /* store it in the receive queue,
343                          * where it'll be processed by a different handler
344                          */
345                         if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) {
346 #if LINK_STATS
347                                 lwip_stats.link.memerr++;
348                                 lwip_stats.link.drop++;
349 #endif
350                                 pbuf_free(p);
351                         } else {
352 #if !NO_SYS
353                                 sys_sem_signal(&xemac->sem_rx_data_available);
354 #endif
355                         }
356                         CurBdPtr = XEmacPs_BdRingNext( rxring, CurBdPtr);
357                 }
358                 /* free up the BD's */
359                 XEmacPs_BdRingFree(rxring, bd_processed, rxbdset);
360                 setup_rx_bds(rxring);
361         }
362
363 #ifdef OS_IS_FREERTOS
364         xInsideISR--;
365 #endif
366         return;
367 }
368
369 void clean_dma_txdescs(struct xemac_s *xemac)
370 {
371         XEmacPs_Bd BdTemplate;
372         XEmacPs_BdRing *TxRingPtr;
373         xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
374
375         TxRingPtr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
376
377         XEmacPs_BdClear(&BdTemplate);
378         XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);
379
380         /*
381          * Create the TxBD ring
382          */
383         XEmacPs_BdRingCreate(TxRingPtr, (u32) xemacpsif->tx_bdspace,
384                         (u32) xemacpsif->tx_bdspace, BD_ALIGNMENT,
385                                  XLWIP_CONFIG_N_TX_DESC);
386         XEmacPs_BdRingClone(TxRingPtr, &BdTemplate, XEMACPS_SEND);
387 }
388
389
390 XStatus init_dma(struct xemac_s *xemac)
391 {
392         XEmacPs_Bd BdTemplate;
393         XEmacPs_BdRing *RxRingPtr, *TxRingPtr;
394         XEmacPs_Bd *rxbd;
395         struct pbuf *p;
396         XStatus Status;
397         int i;
398         unsigned int BdIndex;
399         char *endAdd = &_end;
400         /*
401          * Align the BD starte address to 1 MB boundary.
402          */
403         char *endAdd_aligned = (char *)(((int)endAdd + 0x100000) & (~0xFFFFF));
404         xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
405         struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
406
407         /*
408          * The BDs need to be allocated in uncached memory. Hence the 1 MB
409          * address range that starts at address 0xFF00000 is made uncached
410          * by setting appropriate attributes in the translation table.
411          */
412         Xil_SetTlbAttributes((int)endAdd_aligned, 0xc02); // addr, attr
413
414         RxRingPtr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
415         TxRingPtr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
416         LWIP_DEBUGF(NETIF_DEBUG, ("RxRingPtr: 0x%08x\r\n", RxRingPtr));
417         LWIP_DEBUGF(NETIF_DEBUG, ("TxRingPtr: 0x%08x\r\n", TxRingPtr));
418
419         xemacpsif->rx_bdspace = (void *)endAdd_aligned;
420         /*
421          * We allocate 65536 bytes for Rx BDs which can accomodate a
422          * maximum of 8192 BDs which is much more than any application
423          * will ever need.
424          */
425         xemacpsif->tx_bdspace = (void *)(endAdd_aligned + 0x10000);
426
427         LWIP_DEBUGF(NETIF_DEBUG, ("rx_bdspace: 0x%08x\r\n", xemacpsif->rx_bdspace));
428         LWIP_DEBUGF(NETIF_DEBUG, ("tx_bdspace: 0x%08x\r\n", xemacpsif->tx_bdspace));
429
430         if (!xemacpsif->rx_bdspace || !xemacpsif->tx_bdspace) {
431                 xil_printf("%s@%d: Error: Unable to allocate memory for TX/RX buffer descriptors",
432                                 __FILE__, __LINE__);
433                 return XST_FAILURE;
434         }
435
436         /*
437          * Setup RxBD space.
438          *
439          * Setup a BD template for the Rx channel. This template will be copied to
440          * every RxBD. We will not have to explicitly set these again.
441          */
442         XEmacPs_BdClear(&BdTemplate);
443
444         /*
445          * Create the RxBD ring
446          */
447
448         Status = XEmacPs_BdRingCreate(RxRingPtr, (u32) xemacpsif->rx_bdspace,
449                                 (u32) xemacpsif->rx_bdspace, BD_ALIGNMENT,
450                                      XLWIP_CONFIG_N_RX_DESC);
451
452         if (Status != XST_SUCCESS) {
453                 LWIP_DEBUGF(NETIF_DEBUG, ("Error setting up RxBD space\r\n"));
454                 return XST_FAILURE;
455         }
456
457         Status = XEmacPs_BdRingClone(RxRingPtr, &BdTemplate, XEMACPS_RECV);
458         if (Status != XST_SUCCESS) {
459                 LWIP_DEBUGF(NETIF_DEBUG, ("Error initializing RxBD space\r\n"));
460                 return XST_FAILURE;
461         }
462
463         XEmacPs_BdClear(&BdTemplate);
464         XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);
465         /*
466          * Create the TxBD ring
467          */
468         Status = XEmacPs_BdRingCreate(TxRingPtr, (u32) xemacpsif->tx_bdspace,
469                                 (u32) xemacpsif->tx_bdspace, BD_ALIGNMENT,
470                                      XLWIP_CONFIG_N_TX_DESC);
471
472         if (Status != XST_SUCCESS) {
473                 return XST_FAILURE;
474         }
475
476         /* We reuse the bd template, as the same one will work for both rx and tx. */
477         Status = XEmacPs_BdRingClone(TxRingPtr, &BdTemplate, XEMACPS_SEND);
478         if (Status != XST_SUCCESS) {
479                 return ERR_IF;
480         }
481
482         /*
483          * Allocate RX descriptors, 1 RxBD at a time.
484          */
485         for (i = 0; i < XLWIP_CONFIG_N_RX_DESC; i++) {
486                 Status = XEmacPs_BdRingAlloc(RxRingPtr, 1, &rxbd);
487                 if (Status != XST_SUCCESS) {
488                         LWIP_DEBUGF(NETIF_DEBUG, ("init_dma: Error allocating RxBD\r\n"));
489                         return ERR_IF;
490                 }
491
492                 p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
493                 if (!p) {
494 #if LINK_STATS
495                         lwip_stats.link.memerr++;
496                         lwip_stats.link.drop++;
497 #endif
498                         LWIP_DEBUGF(NETIF_DEBUG, ("unable to alloc pbuf in recv_handler\r\n"));
499                         return -1;
500                 }
501
502                 XEmacPs_BdSetAddressRx(rxbd, (u32)p->payload);
503
504                 BdIndex = XEMACPS_BD_TO_INDEX(RxRingPtr, rxbd);
505                 rx_pbufs_storage[BdIndex] = (int)p;
506
507                 /* Enqueue to HW */
508                 Status = XEmacPs_BdRingToHw(RxRingPtr, 1, rxbd);
509                 if (Status != XST_SUCCESS) {
510                         LWIP_DEBUGF(NETIF_DEBUG, ("Error: committing RxBD to HW\r\n"));
511                         return XST_FAILURE;
512                 }
513         }
514
515         /*
516          * Connect the device driver handler that will be called when an
517          * interrupt for the device occurs, the handler defined above performs
518          * the specific interrupt processing for the device.
519          */
520         XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
521                                 (Xil_ExceptionHandler)XEmacPs_IntrHandler,
522                                                 (void *)&xemacpsif->emacps);
523         /*
524          * Enable the interrupt for emacps.
525          */
526         XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, (u32) xtopologyp->scugic_emac_intr);
527         EmacIntrNum = (u32) xtopologyp->scugic_emac_intr;
528         return 0;
529 }
530
531 /*
532  * resetrx_on_no_rxdata():
533  *
534  * It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
535  * called by the user.
536  * The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
537  * Under heavy Rx traffic because of the HW bug there are times when the Rx path
538  * becomes unresponsive. The workaround for it is to check for the Rx path for
539  * traffic (by reading the stats registers regularly). If the stats register
540  * does not increment for sometime (proving no Rx traffic), the function resets
541  * the Rx data path.
542  *
543  */
544
545 void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
546 {
547         unsigned long regctrl;
548         unsigned long tempcntr;
549
550         tempcntr = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET);
551         if ((!tempcntr) && (!(xemacpsif->last_rx_frms_cntr))) {
552                 regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
553                                 XEMACPS_NWCTRL_OFFSET);
554                 regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
555                 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
556                                 XEMACPS_NWCTRL_OFFSET, regctrl);
557                 regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
558                 regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
559                 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
560         }
561         xemacpsif->last_rx_frms_cntr = tempcntr;
562 }
563
564 void FreeTxRxPBufs(void)
565 {
566         int Index;
567         struct pbuf *p;
568
569         for (Index = 0; Index < XLWIP_CONFIG_N_TX_DESC; Index++) {
570                 if (tx_pbufs_storage[Index] != 0) {
571                         p = (struct pbuf *)tx_pbufs_storage[Index];
572                         pbuf_free(p);
573                         tx_pbufs_storage[Index] = 0;
574                 }
575         }
576
577         for (Index = 0; Index < XLWIP_CONFIG_N_RX_DESC; Index++) {
578                 p = (struct pbuf *)rx_pbufs_storage[Index];
579                 pbuf_free(p);
580
581         }
582 }
583
584 void FreeOnlyTxPBufs(void)
585 {
586         int Index;
587         struct pbuf *p;
588
589         for (Index = 0; Index < XLWIP_CONFIG_N_TX_DESC; Index++) {
590                 if (tx_pbufs_storage[Index] != 0) {
591                         p = (struct pbuf *)tx_pbufs_storage[Index];
592                         pbuf_free(p);
593                         tx_pbufs_storage[Index] = 0;
594                 }
595         }
596 }
597
598 void EmacDisableIntr(void)
599 {
600         XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, EmacIntrNum);
601 }
602
603 void EmacEnableIntr(void)
604 {
605         XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, EmacIntrNum);
606 }