fxmac_intr.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fxmac_intr.c
  15. * Date: 2022-04-06 14:46:52
  16. * LastEditTime: 2022-04-06 14:46:58
  17. * Description:  This file is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. #include "fxmac.h"
  24. #include "fxmac_hw.h"
  25. #include "fassert.h"
  26. /************************** Constant Definitions *****************************/
  27. /**************************** Type Definitions *******************************/
  28. /***************** Macros (Inline Functions) Definitions *********************/
  29. /************************** Function Prototypes ******************************/
  30. /************************** Variable Definitions *****************************/
  31. /**
  32. * @name: FXmacSetHandler
  33. * @msg: Install an asynchronous handler function for the given handler_type:
  34. *
  35. * @param instance_p is a pointer to the instance to be worked on.
  36. * @param handler_type indicates what interrupt handler type is.
  37. * FXMAC_HANDLER_DMASEND, FXMAC_HANDLER_DMARECV and
  38. * FXMAC_HANDLER_ERROR.
  39. * @param func_pointer is the pointer to the callback function
  40. * @param call_back_ref is the upper layer callback reference passed back when
  41. * when the callback function is invoked.
  42. *
  43. * @return {FError} FT_SUCCESS set is ok
  44. */
  45. FError FXmacSetHandler(FXmac *instance_p, u32 handler_type,
  46. void *func_pointer, void *call_back_ref)
  47. {
  48. FError status;
  49. FASSERT(instance_p != NULL);
  50. FASSERT(func_pointer != NULL);
  51. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  52. status = (FError)(FT_SUCCESS);
  53. switch (handler_type)
  54. {
  55. case FXMAC_HANDLER_DMASEND:
  56. instance_p->send_irq_handler = ((FXmacIrqHandler)(void *)func_pointer);
  57. instance_p->send_args = call_back_ref;
  58. break;
  59. case FXMAC_HANDLER_DMARECV:
  60. instance_p->recv_irq_handler = ((FXmacIrqHandler)(void *)func_pointer);
  61. instance_p->recv_args = call_back_ref;
  62. break;
  63. case FXMAC_HANDLER_ERROR:
  64. instance_p->error_irq_handler = ((FXmacErrorIrqHandler)(void *)func_pointer);
  65. instance_p->error_args = call_back_ref;
  66. break;
  67. case FXMAC_HANDLER_LINKCHANGE:
  68. instance_p->link_change_handler = ((FXmacIrqHandler)(void *)func_pointer);
  69. instance_p->link_change_args = call_back_ref;
  70. break;
  71. case FXMAC_HANDLER_RESTART:
  72. instance_p->restart_handler = ((FXmacIrqHandler)(void *)func_pointer);
  73. instance_p->restart_args = call_back_ref;
  74. break;
  75. default:
  76. status = (FError)(FXMAC_ERR_INVALID_PARAM);
  77. break;
  78. }
  79. return status;
  80. }
  81. /**
  82. * @name: FXmacIntrHandler
  83. * @msg: 中断处理函数
  84. * @param {s32} vector is interrrupt num
  85. * @param {void} *args is a arguments variables
  86. * @return {*}
  87. * @note 目前中断只支持单queue的情况
  88. */
  89. void FXmacIntrHandler(s32 vector, void *args)
  90. {
  91. u32 reg_isr;
  92. u32 reg_qx_isr;
  93. u32 reg_temp;
  94. u32 reg_ctrl;
  95. u32 tx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */
  96. u32 rx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */
  97. FXmac *instance_p = (FXmac *)args;
  98. FASSERT(instance_p != NULL);
  99. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  100. tx_queue_id = instance_p->tx_bd_queue.queue_id;
  101. rx_queue_id = instance_p->rx_bd_queue.queue_id;
  102. FASSERT((rx_queue_id < FT_XMAC_QUEUE_MAX_NUM) && (tx_queue_id < FT_XMAC_QUEUE_MAX_NUM))
  103. /* This ISR will try to handle as many interrupts as it can in a single
  104. * call. However, in most of the places where the user's error handler
  105. * is called, this ISR exits because it is expected that the user will
  106. * reset the device in nearly all instances.
  107. */
  108. if ((u32)vector == instance_p->config.queue_irq_num[tx_queue_id])
  109. {
  110. if (tx_queue_id == 0)
  111. {
  112. reg_isr = FXMAC_READREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET);
  113. if ((reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U)
  114. {
  115. /* Clear TX status register TX complete indication but preserve
  116. * error bits if there is any */
  117. FXMAC_WRITEREG32(instance_p->config.base_address,
  118. FXMAC_TXSR_OFFSET,
  119. ((u32)FXMAC_TXSR_TXCOMPL_MASK |
  120. (u32)FXMAC_TXSR_USEDREAD_MASK));
  121. if (instance_p->send_irq_handler)
  122. {
  123. /* code */
  124. instance_p->send_irq_handler(instance_p->send_args);
  125. }
  126. /* add */
  127. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXCOMPL_MASK);
  128. }
  129. /* Transmit error conditions interrupt */
  130. if (((reg_isr & FXMAC_IXR_TX_ERR_MASK) != 0x00000000U) &&
  131. (!(reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U))
  132. {
  133. /* Clear TX status register */
  134. reg_temp = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET);
  135. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET, reg_temp);
  136. if (instance_p->error_irq_handler)
  137. {
  138. instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND, reg_temp);
  139. }
  140. /* add */
  141. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TX_ERR_MASK);
  142. }
  143. /* add restart */
  144. if ((reg_isr & FXMAC_IXR_TXUSED_MASK) != 0x00000000U)
  145. {
  146. /* add */
  147. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXUSED_MASK);
  148. if (instance_p->restart_handler)
  149. {
  150. instance_p->restart_handler(instance_p->restart_args);
  151. }
  152. }
  153. /* link chaged */
  154. if ((reg_isr & FXMAC_IXR_LINKCHANGE_MASK) != 0x00000000U)
  155. {
  156. if (instance_p->link_change_handler)
  157. {
  158. instance_p->link_change_handler(instance_p->link_change_args);
  159. }
  160. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_LINKCHANGE_MASK);
  161. }
  162. }
  163. else /* use queue number more than 0 */
  164. {
  165. reg_isr = FXMAC_READREG32(instance_p->config.base_address,
  166. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id));
  167. /* Transmit Q1 complete interrupt */
  168. if (((reg_isr & FXMAC_INTQUESR_TXCOMPL_MASK) != 0x00000000U))
  169. {
  170. /* Clear TX status register TX complete indication but preserve
  171. * error bits if there is any */
  172. FXMAC_WRITEREG32(instance_p->config.base_address,
  173. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id),
  174. FXMAC_INTQUESR_TXCOMPL_MASK);
  175. FXMAC_WRITEREG32(instance_p->config.base_address,
  176. FXMAC_TXSR_OFFSET,
  177. ((u32)FXMAC_TXSR_TXCOMPL_MASK |
  178. (u32)FXMAC_TXSR_USEDREAD_MASK));
  179. instance_p->send_irq_handler(instance_p->send_args);
  180. }
  181. /* Transmit Q1 error conditions interrupt */
  182. if (((reg_isr & FXMAC_INTQ1SR_TXERR_MASK) != 0x00000000U) &&
  183. ((reg_isr & FXMAC_INTQ1SR_TXCOMPL_MASK) != 0x00000000U))
  184. {
  185. /* Clear Interrupt Q1 status register */
  186. FXMAC_WRITEREG32(instance_p->config.base_address,
  187. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id), reg_isr);
  188. instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND,
  189. reg_isr);
  190. }
  191. }
  192. }
  193. if ((u32)vector == instance_p->config.queue_irq_num[rx_queue_id])
  194. {
  195. if (rx_queue_id == 0)
  196. {
  197. reg_isr = FXMAC_READREG32(instance_p->config.base_address,
  198. FXMAC_ISR_OFFSET);
  199. /* Receive complete interrupt */
  200. if ((reg_isr & FXMAC_IXR_RXCOMPL_MASK) != 0x00000000U)
  201. {
  202. /* Clear RX status register RX complete indication but preserve
  203. * error bits if there is any */
  204. FXMAC_WRITEREG32(instance_p->config.base_address,
  205. FXMAC_RXSR_OFFSET,
  206. ((u32)FXMAC_RXSR_FRAMERX_MASK |
  207. (u32)FXMAC_RXSR_BUFFNA_MASK));
  208. instance_p->recv_irq_handler(instance_p->recv_args);
  209. /* add */
  210. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXCOMPL_MASK);
  211. }
  212. /* Receive error conditions interrupt */
  213. if ((reg_isr & FXMAC_IXR_RX_ERR_MASK) != 0x00000000U)
  214. {
  215. /* Clear RX status register */
  216. reg_temp = FXMAC_READREG32(instance_p->config.base_address,
  217. FXMAC_RXSR_OFFSET);
  218. FXMAC_WRITEREG32(instance_p->config.base_address,
  219. FXMAC_RXSR_OFFSET, reg_temp);
  220. /* Fix for CR # 692702. Write to bit 18 of net_ctrl
  221. * register to flush a packet out of Rx SRAM upon
  222. * an error for receive buffer not available. */
  223. if ((reg_isr & FXMAC_IXR_RXUSED_MASK) != 0x00000000U)
  224. {
  225. reg_ctrl = FXMAC_READREG32(instance_p->config.base_address,
  226. FXMAC_NWCTRL_OFFSET);
  227. reg_ctrl |= (u32)FXMAC_NWCTRL_FLUSH_DPRAM_MASK;
  228. /* add */
  229. reg_ctrl &= (u32)(~FXMAC_NWCTRL_RXEN_MASK);
  230. FXMAC_WRITEREG32(instance_p->config.base_address,
  231. FXMAC_NWCTRL_OFFSET, reg_ctrl);
  232. /* add */
  233. reg_ctrl |= (u32)FXMAC_NWCTRL_RXEN_MASK;
  234. FXMAC_WRITEREG32(instance_p->config.base_address,
  235. FXMAC_NWCTRL_OFFSET, reg_ctrl);
  236. }
  237. /* add */
  238. if ((reg_isr & FXMAC_IXR_RXOVR_MASK) != 0x00000000U)
  239. {
  240. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXOVR_MASK);
  241. }
  242. /* add */
  243. if ((reg_isr & FXMAC_IXR_HRESPNOK_MASK) != 0x00000000U)
  244. {
  245. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_HRESPNOK_MASK);
  246. }
  247. if (reg_temp != 0)
  248. {
  249. instance_p->error_irq_handler(instance_p->error_args,
  250. FXMAC_RECV, reg_temp);
  251. }
  252. }
  253. }
  254. else /* use queue number more than 0 */
  255. {
  256. reg_isr = FXMAC_READREG32(instance_p->config.base_address,
  257. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id));
  258. /* Receive complete interrupt */
  259. if ((reg_isr & FXMAC_INTQUESR_RCOMP_MASK) != 0x00000000U)
  260. {
  261. /* Clear RX status register RX complete indication but preserve
  262. * error bits if there is any */
  263. FXMAC_WRITEREG32(instance_p->config.base_address,
  264. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id),
  265. FXMAC_INTQUESR_RCOMP_MASK);
  266. instance_p->recv_irq_handler(instance_p->recv_args);
  267. }
  268. /* Receive error conditions interrupt */
  269. if ((reg_isr & FXMAC_IXR_RX_ERR_MASK) != 0x00000000U)
  270. {
  271. reg_ctrl =
  272. FXMAC_READREG32(instance_p->config.base_address,
  273. FXMAC_NWCTRL_OFFSET);
  274. reg_ctrl &= ~(u32)FXMAC_NWCTRL_RXEN_MASK;
  275. FXMAC_WRITEREG32(instance_p->config.base_address,
  276. FXMAC_NWCTRL_OFFSET, reg_ctrl);
  277. /* Clear RX status register */
  278. reg_temp = FXMAC_READREG32(instance_p->config.base_address,
  279. FXMAC_RXSR_OFFSET);
  280. FXMAC_WRITEREG32(instance_p->config.base_address,
  281. FXMAC_RXSR_OFFSET, reg_temp);
  282. /* Fix for CR # 692702. Write to bit 18 of net_ctrl
  283. * register to flush a packet out of Rx SRAM upon
  284. * an error for receive buffer not available. */
  285. if ((reg_isr & FXMAC_IXR_RXUSED_MASK) != 0x00000000U)
  286. {
  287. reg_ctrl =
  288. FXMAC_READREG32(instance_p->config.base_address,
  289. FXMAC_NWCTRL_OFFSET);
  290. reg_ctrl |= (u32)FXMAC_NWCTRL_FLUSH_DPRAM_MASK;
  291. FXMAC_WRITEREG32(instance_p->config.base_address,
  292. FXMAC_NWCTRL_OFFSET, reg_ctrl);
  293. }
  294. /* Clear RX status register RX complete indication but preserve
  295. * error bits if there is any */
  296. FXMAC_WRITEREG32(instance_p->config.base_address,
  297. FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id),
  298. FXMAC_INTQUESR_RXUBR_MASK);
  299. instance_p->recv_irq_handler(instance_p->recv_args);
  300. if (reg_temp != 0)
  301. {
  302. instance_p->error_irq_handler(instance_p->error_args,
  303. FXMAC_RECV, reg_temp);
  304. }
  305. }
  306. }
  307. }
  308. }
  309. /**
  310. * @name: FXmacQueueIrqDisable
  311. * @msg: Disable queue irq
  312. * @param {FXmac} *instance_p a pointer to the instance to be worked on.
  313. * @param {u32} queue_num queue number
  314. * @param {u32} mask is interrupt disable value mask
  315. */
  316. void FXmacQueueIrqDisable(FXmac *instance_p, u32 queue_num, u32 mask)
  317. {
  318. FXmacConfig *config_p;
  319. FASSERT(instance_p != NULL);
  320. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  321. FASSERT(instance_p->config.max_queue_num > queue_num);
  322. config_p = &instance_p->config;
  323. if (queue_num == 0)
  324. {
  325. FXMAC_WRITEREG32(config_p->base_address, FXMAC_IDR_OFFSET, mask & FXMAC_IXR_ALL_MASK);
  326. }
  327. else
  328. {
  329. FXMAC_WRITEREG32(config_p->base_address, FXMAC_INTQX_IDR_SIZE_OFFSET(queue_num), mask & FXMAC_IXR_ALL_MASK);
  330. }
  331. }
  332. /**
  333. * @name: FXmacQueueIrqEnable
  334. * @msg: Enable queue irq
  335. * @param {FXmac} *instance_p a pointer to the instance to be worked on.
  336. * @param {u32} queue_num is queue number
  337. * @param {u32} mask is interrupt Enable value mask
  338. */
  339. void FXmacQueueIrqEnable(FXmac *instance_p, u32 queue_num, u32 mask)
  340. {
  341. FXmacConfig *config_p;
  342. FASSERT(instance_p != NULL);
  343. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  344. FASSERT(instance_p->config.max_queue_num > queue_num);
  345. config_p = &instance_p->config;
  346. if (queue_num == 0)
  347. {
  348. FXMAC_WRITEREG32(config_p->base_address, FXMAC_IER_OFFSET, mask & FXMAC_IXR_ALL_MASK);
  349. }
  350. else
  351. {
  352. FXMAC_WRITEREG32(config_p->base_address, FXMAC_INTQX_IER_SIZE_OFFSET(queue_num), mask & FXMAC_IXR_ALL_MASK);
  353. }
  354. }