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