]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
be00f4f9c8493dff2363d357744bf39b07fc1ed0
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / x_emacpsif_hw.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
20 /* Standard includes. */
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "Zynq/x_emacpsif.h"
26
27 /* FreeRTOS includes. */
28 #include "FreeRTOS.h"
29 #include "task.h"
30 #include "queue.h"
31
32 ///* FreeRTOS+TCP includes. */
33 /* FreeRTOS+TCP includes. */
34 #include "FreeRTOS_IP.h"
35 #include "FreeRTOS_Sockets.h"
36 #include "FreeRTOS_IP_Private.h"
37 #include "NetworkBufferManagement.h"
38
39 extern TaskHandle_t xEMACTaskHandle;
40
41 /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
42  *** to run it on a PEEP board
43  ***/
44
45 unsigned int link_speed = 100;
46
47 void setup_isr( xemacpsif_s *xemacpsif )
48 {
49         /*
50          * Setup callbacks
51          */
52         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
53                 (void *) emacps_send_handler,
54                 (void *) xemacpsif);
55
56         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
57                 (void *) emacps_recv_handler,
58                 (void *) xemacpsif);
59
60         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
61                 (void *) emacps_error_handler,
62                 (void *) xemacpsif);
63 }
64
65 void start_emacps (xemacpsif_s *xemacps)
66 {
67         /* start the temac */
68         XEmacPs_Start(&xemacps->emacps);
69 }
70
71 extern struct xtopology_t xXTopology;
72
73 volatile int error_msg_count = 0;
74 volatile const char *last_err_msg = "";
75
76 struct xERROR_MSG {
77         void *arg;
78         u8 Direction;
79         u32 ErrorWord;
80 };
81
82 static struct xERROR_MSG xErrorList[ 8 ];
83 static BaseType_t xErrorHead, xErrorTail;
84
85 void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
86 {
87         BaseType_t xHigherPriorityTaskWoken = pdFALSE;
88         xemacpsif_s *xemacpsif;
89         BaseType_t xNextHead = xErrorHead;
90
91         xemacpsif = (xemacpsif_s *)(arg);
92
93         if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
94         {
95                 if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
96                         xNextHead = 0;
97                 if( xNextHead != xErrorTail )
98                 {
99
100                         xErrorList[ xErrorHead ].arg = arg;
101                         xErrorList[ xErrorHead ].Direction = Direction;
102                         xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
103
104                         xErrorHead = xNextHead;
105
106                         xemacpsif = (xemacpsif_s *)(arg);
107                         xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
108                 }
109
110                 if( xEMACTaskHandle != NULL )
111                 {
112                         vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
113                 }
114
115         }
116
117         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
118 }
119
120 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
121
122 int emacps_check_errors( xemacpsif_s *xemacps )
123 {
124 int xResult;
125
126         ( void ) xemacps;
127
128         if( xErrorHead == xErrorTail )
129         {
130                 xResult = 0;
131         }
132         else
133         {
134                 xResult = 1;
135                 emacps_handle_error(
136                         xErrorList[ xErrorTail ].arg,
137                         xErrorList[ xErrorTail ].Direction,
138                         xErrorList[ xErrorTail ].ErrorWord );
139         }
140
141         return xResult;
142 }
143
144 BaseType_t xNetworkInterfaceInitialise( void );
145
146 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
147 {
148         xemacpsif_s   *xemacpsif;
149         struct xtopology_t *xtopologyp;
150         XEmacPs *xemacps;
151
152         xemacpsif = (xemacpsif_s *)(arg);
153
154         xtopologyp = &xXTopology;
155
156         xemacps = &xemacpsif->emacps;
157
158         /* Do not appear to be used. */
159         ( void ) xemacps;
160         ( void ) xtopologyp;
161
162         last_err_msg = NULL;
163
164         if( ErrorWord != 0 )
165         {
166                 switch (Direction) {
167                 case XEMACPS_RECV:
168                         if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
169                         {
170                                 last_err_msg = "Receive DMA error";
171                                 xNetworkInterfaceInitialise( );
172                         }
173                         if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
174                         {
175                                 last_err_msg = "Receive over run";
176                                 emacps_recv_handler(arg);
177                         }
178                         if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
179                         {
180                                 last_err_msg = "Receive buffer not available";
181                                 emacps_recv_handler(arg);
182                         }
183                         break;
184                 case XEMACPS_SEND:
185                         if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
186                         {
187                                 last_err_msg = "Transmit DMA error";
188                                 xNetworkInterfaceInitialise( );
189                         }
190                         if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
191                         {
192                                 last_err_msg = "Transmit under run";
193                                 HandleTxErrors( xemacpsif );
194                         }
195                         if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
196                         {
197                                 last_err_msg = "Transmit buffer exhausted";
198                                 HandleTxErrors( xemacpsif );
199                         }
200                         if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
201                         {
202                                 last_err_msg = "Transmit retry excessed limits";
203                                 HandleTxErrors( xemacpsif );
204                         }
205                         if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
206                         {
207                                 last_err_msg = "Transmit collision";
208                                 emacps_check_tx( xemacpsif );
209                         }
210                         break;
211                 }
212         }
213         // Break on this statement and inspect error_msg if you like
214         if( last_err_msg != NULL )
215         {
216                 error_msg_count++;
217                 FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
218         }
219 }
220
221 extern XEmacPs_Config mac_config;
222
223 void HandleTxErrors(xemacpsif_s *xemacpsif)
224 {
225         u32 netctrlreg;
226
227         //taskENTER_CRITICAL()
228         {
229                 netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
230                                                                                                         XEMACPS_NWCTRL_OFFSET);
231                 netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
232                 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
233                                                                                 XEMACPS_NWCTRL_OFFSET, netctrlreg);
234
235                 clean_dma_txdescs( xemacpsif );
236                 netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
237                                                                                                                 XEMACPS_NWCTRL_OFFSET);
238                 netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
239                 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
240                                                                                         XEMACPS_NWCTRL_OFFSET, netctrlreg);
241         }
242         //taskEXIT_CRITICAL( );
243 }