xemac_intr.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /******************************************************************************
  2. *
  3. * Author: Xilinx, Inc.
  4. *
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. *
  11. *
  12. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
  13. * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
  14. * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
  15. * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
  16. * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
  17. * ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
  18. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
  19. * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
  20. * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
  21. * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22. * FITNESS FOR A PARTICULAR PURPOSE.
  23. *
  24. *
  25. * Xilinx hardware products are not intended for use in life support
  26. * appliances, devices, or systems. Use in such applications is
  27. * expressly prohibited.
  28. *
  29. *
  30. * (c) Copyright 2002-2004 Xilinx Inc.
  31. * All rights reserved.
  32. *
  33. *
  34. * You should have received a copy of the GNU General Public License along
  35. * with this program; if not, write to the Free Software Foundation, Inc.,
  36. * 675 Mass Ave, Cambridge, MA 02139, USA.
  37. *
  38. ******************************************************************************/
  39. /*****************************************************************************/
  40. /**
  41. *
  42. * @file xemac_intr.c
  43. *
  44. * This file contains general interrupt-related functions of the XEmac driver.
  45. *
  46. * <pre>
  47. * MODIFICATION HISTORY:
  48. *
  49. * Ver Who Date Changes
  50. * ----- ---- -------- -----------------------------------------------
  51. * 1.00a rpm 07/31/01 First release
  52. * 1.00b rpm 02/20/02 Repartitioned files and functions
  53. * 1.00c rpm 12/05/02 New version includes support for simple DMA
  54. * 1.00c rpm 03/31/03 Added comment to indicate that no Receive Length FIFO
  55. * overrun interrupts occur in v1.00l and later of the EMAC
  56. * device. This avoids the need to reset the device on
  57. * receive overruns.
  58. * </pre>
  59. *
  60. ******************************************************************************/
  61. /***************************** Include Files *********************************/
  62. #include "xbasic_types.h"
  63. #include "xemac_i.h"
  64. #include "xio.h"
  65. #include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
  66. /************************** Constant Definitions *****************************/
  67. /**************************** Type Definitions *******************************/
  68. /***************** Macros (Inline Functions) Definitions *********************/
  69. /************************** Variable Definitions *****************************/
  70. /************************** Function Prototypes ******************************/
  71. /*****************************************************************************/
  72. /**
  73. *
  74. * Set the callback function for handling asynchronous errors. The upper layer
  75. * software should call this function during initialization.
  76. *
  77. * The error callback is invoked by the driver within interrupt context, so it
  78. * needs to do its job quickly. If there are potentially slow operations within
  79. * the callback, these should be done at task-level.
  80. *
  81. * The Xilinx errors that must be handled by the callback are:
  82. * - XST_DMA_ERROR indicates an unrecoverable DMA error occurred. This is
  83. * typically a bus error or bus timeout. The handler must reset and
  84. * re-configure the device.
  85. * - XST_FIFO_ERROR indicates an unrecoverable FIFO error occurred. This is a
  86. * deadlock condition in the packet FIFO. The handler must reset and
  87. * re-configure the device.
  88. * - XST_RESET_ERROR indicates an unrecoverable MAC error occurred, usually an
  89. * overrun or underrun. The handler must reset and re-configure the device.
  90. * - XST_DMA_SG_NO_LIST indicates an attempt was made to access a scatter-gather
  91. * DMA list that has not yet been created.
  92. * - XST_DMA_SG_LIST_EMPTY indicates the driver tried to get a descriptor from
  93. * the receive descriptor list, but the list was empty.
  94. *
  95. * @param InstancePtr is a pointer to the XEmac instance to be worked on.
  96. * @param CallBackRef is a reference pointer to be passed back to the adapter in
  97. * the callback. This helps the adapter correlate the callback to a
  98. * particular driver.
  99. * @param FuncPtr is the pointer to the callback function.
  100. *
  101. * @return
  102. *
  103. * None.
  104. *
  105. * @note
  106. *
  107. * None.
  108. *
  109. ******************************************************************************/
  110. void
  111. XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
  112. XEmac_ErrorHandler FuncPtr)
  113. {
  114. XASSERT_VOID(InstancePtr != NULL);
  115. XASSERT_VOID(FuncPtr != NULL);
  116. XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
  117. InstancePtr->ErrorHandler = FuncPtr;
  118. InstancePtr->ErrorRef = CallBackRef;
  119. }
  120. /****************************************************************************/
  121. /*
  122. *
  123. * Check the interrupt status bits of the Ethernet MAC for errors. Errors
  124. * currently handled are:
  125. * - Receive length FIFO overrun. Indicates data was lost due to the receive
  126. * length FIFO becoming full during the reception of a packet. Only a device
  127. * reset clears this condition.
  128. * - Receive length FIFO underrun. An attempt to read an empty FIFO. Only a
  129. * device reset clears this condition.
  130. * - Transmit status FIFO overrun. Indicates data was lost due to the transmit
  131. * status FIFO becoming full following the transmission of a packet. Only a
  132. * device reset clears this condition.
  133. * - Transmit status FIFO underrun. An attempt to read an empty FIFO. Only a
  134. * device reset clears this condition.
  135. * - Transmit length FIFO overrun. Indicates data was lost due to the transmit
  136. * length FIFO becoming full following the transmission of a packet. Only a
  137. * device reset clears this condition.
  138. * - Transmit length FIFO underrun. An attempt to read an empty FIFO. Only a
  139. * device reset clears this condition.
  140. * - Receive data FIFO overrun. Indicates data was lost due to the receive data
  141. * FIFO becoming full during the reception of a packet.
  142. * - Receive data errors:
  143. * - Receive missed frame error. Valid data was lost by the MAC.
  144. * - Receive collision error. Data was lost by the MAC due to a collision.
  145. * - Receive FCS error. Data was dicarded by the MAC due to FCS error.
  146. * - Receive length field error. Data was dicarded by the MAC due to an invalid
  147. * length field in the packet.
  148. * - Receive short error. Data was dicarded by the MAC because a packet was
  149. * shorter than allowed.
  150. * - Receive long error. Data was dicarded by the MAC because a packet was
  151. * longer than allowed.
  152. * - Receive alignment error. Data was truncated by the MAC because its length
  153. * was not byte-aligned.
  154. *
  155. * @param InstancePtr is a pointer to the XEmac instance to be worked on.
  156. * @param IntrStatus is the contents of the interrupt status register to be checked
  157. *
  158. * @return
  159. *
  160. * None.
  161. *
  162. * @note
  163. *
  164. * This function is intended for internal use only.
  165. *
  166. ******************************************************************************/
  167. void
  168. XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus)
  169. {
  170. u32 ResetError = FALSE;
  171. /*
  172. * First check for receive fifo overrun/underrun errors. Most require a
  173. * reset by the user to clear, but the data FIFO overrun error does not.
  174. */
  175. if (IntrStatus & XEM_EIR_RECV_DFIFO_OVER_MASK) {
  176. InstancePtr->Stats.RecvOverrunErrors++;
  177. InstancePtr->Stats.FifoErrors++;
  178. }
  179. if (IntrStatus & XEM_EIR_RECV_LFIFO_OVER_MASK) {
  180. /*
  181. * Receive Length FIFO overrun interrupts no longer occur in v1.00l
  182. * and later of the EMAC device. Frames are just dropped by the EMAC
  183. * if the length FIFO is full. The user would notice the Receive Missed
  184. * Frame count incrementing without any other errors being reported.
  185. * This code is left here for backward compatibility with v1.00k and
  186. * older EMAC devices.
  187. */
  188. InstancePtr->Stats.RecvOverrunErrors++;
  189. InstancePtr->Stats.FifoErrors++;
  190. ResetError = TRUE; /* requires a reset */
  191. }
  192. if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
  193. InstancePtr->Stats.RecvUnderrunErrors++;
  194. InstancePtr->Stats.FifoErrors++;
  195. ResetError = TRUE; /* requires a reset */
  196. }
  197. /*
  198. * Now check for general receive errors. Get the latest count where
  199. * available, otherwise just bump the statistic so we know the interrupt
  200. * occurred.
  201. */
  202. if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
  203. if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
  204. /*
  205. * Caused by length FIFO or data FIFO overruns on receive side
  206. */
  207. InstancePtr->Stats.RecvMissedFrameErrors =
  208. XIo_In32(InstancePtr->BaseAddress +
  209. XEM_RMFC_OFFSET);
  210. }
  211. if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
  212. InstancePtr->Stats.RecvCollisionErrors =
  213. XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
  214. }
  215. if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
  216. InstancePtr->Stats.RecvFcsErrors =
  217. XIo_In32(InstancePtr->BaseAddress +
  218. XEM_RFCSEC_OFFSET);
  219. }
  220. if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
  221. InstancePtr->Stats.RecvLengthFieldErrors++;
  222. }
  223. if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
  224. InstancePtr->Stats.RecvShortErrors++;
  225. }
  226. if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
  227. InstancePtr->Stats.RecvLongErrors++;
  228. }
  229. if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
  230. InstancePtr->Stats.RecvAlignmentErrors =
  231. XIo_In32(InstancePtr->BaseAddress +
  232. XEM_RAEC_OFFSET);
  233. }
  234. /*
  235. * Bump recv interrupts stats only if not scatter-gather DMA (this
  236. * stat gets bumped elsewhere in that case)
  237. */
  238. if (!XEmac_mIsSgDma(InstancePtr)) {
  239. InstancePtr->Stats.RecvInterrupts++; /* TODO: double bump? */
  240. }
  241. }
  242. /*
  243. * Check for transmit errors. These apply to both DMA and non-DMA modes
  244. * of operation. The entire device should be reset after overruns or
  245. * underruns.
  246. */
  247. if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
  248. XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
  249. InstancePtr->Stats.XmitOverrunErrors++;
  250. InstancePtr->Stats.FifoErrors++;
  251. ResetError = TRUE;
  252. }
  253. if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
  254. XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
  255. InstancePtr->Stats.XmitUnderrunErrors++;
  256. InstancePtr->Stats.FifoErrors++;
  257. ResetError = TRUE;
  258. }
  259. if (ResetError) {
  260. /*
  261. * If a reset error occurred, disable the EMAC interrupts since the
  262. * reset-causing interrupt(s) is latched in the EMAC - meaning it will
  263. * keep occurring until the device is reset. In order to give the higher
  264. * layer software time to reset the device, we have to disable the
  265. * overrun/underrun interrupts until that happens. We trust that the
  266. * higher layer resets the device. We are able to get away with disabling
  267. * all EMAC interrupts since the only interrupts it generates are for
  268. * error conditions, and we don't care about any more errors right now.
  269. */
  270. XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
  271. /*
  272. * Invoke the error handler callback, which should result in a reset
  273. * of the device by the upper layer software.
  274. */
  275. InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
  276. XST_RESET_ERROR);
  277. }
  278. }
  279. /*****************************************************************************/
  280. /*
  281. *
  282. * Check the receive packet FIFO for errors. FIFO error interrupts are:
  283. * - Deadlock. See the XPacketFifo component for a description of deadlock on a
  284. * FIFO.
  285. *
  286. * @param InstancePtr is a pointer to the XEmac instance to be worked on.
  287. *
  288. * @return
  289. *
  290. * Although the function returns void, it can return an asynchronous error to the
  291. * application through the error handler. It can return XST_FIFO_ERROR if a FIFO
  292. * error occurred.
  293. *
  294. * @note
  295. *
  296. * This function is intended for internal use only.
  297. *
  298. ******************************************************************************/
  299. void
  300. XEmac_CheckFifoRecvError(XEmac * InstancePtr)
  301. {
  302. /*
  303. * Although the deadlock is currently the only interrupt from a packet
  304. * FIFO, make sure it is deadlocked before taking action. There is no
  305. * need to clear this interrupt since it requires a reset of the device.
  306. */
  307. if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
  308. u32 IntrEnable;
  309. InstancePtr->Stats.FifoErrors++;
  310. /*
  311. * Invoke the error callback function, which should result in a reset
  312. * of the device by the upper layer software. We first need to disable
  313. * the FIFO interrupt, since otherwise the upper layer thread that
  314. * handles the reset may never run because this interrupt condition
  315. * doesn't go away until a reset occurs (there is no way to ack it).
  316. */
  317. IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
  318. XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
  319. IntrEnable & ~XEM_IPIF_RECV_FIFO_MASK);
  320. InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
  321. XST_FIFO_ERROR);
  322. }
  323. }
  324. /*****************************************************************************/
  325. /*
  326. *
  327. * Check the send packet FIFO for errors. FIFO error interrupts are:
  328. * - Deadlock. See the XPacketFifo component for a description of deadlock on a
  329. * FIFO.
  330. *
  331. * @param InstancePtr is a pointer to the XEmac instance to be worked on.
  332. *
  333. * @return
  334. *
  335. * Although the function returns void, it can return an asynchronous error to the
  336. * application through the error handler. It can return XST_FIFO_ERROR if a FIFO
  337. * error occurred.
  338. *
  339. * @note
  340. *
  341. * This function is intended for internal use only.
  342. *
  343. ******************************************************************************/
  344. void
  345. XEmac_CheckFifoSendError(XEmac * InstancePtr)
  346. {
  347. /*
  348. * Although the deadlock is currently the only interrupt from a packet
  349. * FIFO, make sure it is deadlocked before taking action. There is no
  350. * need to clear this interrupt since it requires a reset of the device.
  351. */
  352. if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
  353. u32 IntrEnable;
  354. InstancePtr->Stats.FifoErrors++;
  355. /*
  356. * Invoke the error callback function, which should result in a reset
  357. * of the device by the upper layer software. We first need to disable
  358. * the FIFO interrupt, since otherwise the upper layer thread that
  359. * handles the reset may never run because this interrupt condition
  360. * doesn't go away until a reset occurs (there is no way to ack it).
  361. */
  362. IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
  363. XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
  364. IntrEnable & ~XEM_IPIF_SEND_FIFO_MASK);
  365. InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
  366. XST_FIFO_ERROR);
  367. }
  368. }