isl_38xx.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2002 Intersil Americas Inc.
  4. * Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
  5. */
  6. #include <linux/module.h>
  7. #include <linux/types.h>
  8. #include <linux/delay.h>
  9. #include <linux/ktime.h>
  10. #include <linux/uaccess.h>
  11. #include <asm/io.h>
  12. #include "prismcompat.h"
  13. #include "isl_38xx.h"
  14. #include "islpci_dev.h"
  15. #include "islpci_mgt.h"
  16. /******************************************************************************
  17. Device Interface & Control functions
  18. ******************************************************************************/
  19. /**
  20. * isl38xx_disable_interrupts - disable all interrupts
  21. * @device: pci memory base address
  22. *
  23. * Instructs the device to disable all interrupt reporting by asserting
  24. * the IRQ line. New events may still show up in the interrupt identification
  25. * register located at offset %ISL38XX_INT_IDENT_REG.
  26. */
  27. void
  28. isl38xx_disable_interrupts(void __iomem *device)
  29. {
  30. isl38xx_w32_flush(device, 0x00000000, ISL38XX_INT_EN_REG);
  31. udelay(ISL38XX_WRITEIO_DELAY);
  32. }
  33. void
  34. isl38xx_handle_sleep_request(isl38xx_control_block *control_block,
  35. int *powerstate, void __iomem *device_base)
  36. {
  37. /* device requests to go into sleep mode
  38. * check whether the transmit queues for data and management are empty */
  39. if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ))
  40. /* data tx queue not empty */
  41. return;
  42. if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ))
  43. /* management tx queue not empty */
  44. return;
  45. /* check also whether received frames are pending */
  46. if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_DATA_LQ))
  47. /* data rx queue not empty */
  48. return;
  49. if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ))
  50. /* management rx queue not empty */
  51. return;
  52. #if VERBOSE > SHOW_ERROR_MESSAGES
  53. DEBUG(SHOW_TRACING, "Device going to sleep mode\n");
  54. #endif
  55. /* all queues are empty, allow the device to go into sleep mode */
  56. *powerstate = ISL38XX_PSM_POWERSAVE_STATE;
  57. /* assert the Sleep interrupt in the Device Interrupt Register */
  58. isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_SLEEP,
  59. ISL38XX_DEV_INT_REG);
  60. udelay(ISL38XX_WRITEIO_DELAY);
  61. }
  62. void
  63. isl38xx_handle_wakeup(isl38xx_control_block *control_block,
  64. int *powerstate, void __iomem *device_base)
  65. {
  66. /* device is in active state, update the powerstate flag */
  67. *powerstate = ISL38XX_PSM_ACTIVE_STATE;
  68. /* now check whether there are frames pending for the card */
  69. if (!isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ)
  70. && !isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ))
  71. return;
  72. #if VERBOSE > SHOW_ERROR_MESSAGES
  73. DEBUG(SHOW_ANYTHING, "Wake up handler trigger the device\n");
  74. #endif
  75. /* either data or management transmit queue has a frame pending
  76. * trigger the device by setting the Update bit in the Device Int reg */
  77. isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
  78. ISL38XX_DEV_INT_REG);
  79. udelay(ISL38XX_WRITEIO_DELAY);
  80. }
  81. void
  82. isl38xx_trigger_device(int asleep, void __iomem *device_base)
  83. {
  84. u32 reg;
  85. #if VERBOSE > SHOW_ERROR_MESSAGES
  86. u32 counter = 0;
  87. struct timespec64 current_ts64;
  88. DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
  89. #endif
  90. /* check whether the device is in power save mode */
  91. if (asleep) {
  92. /* device is in powersave, trigger the device for wakeup */
  93. #if VERBOSE > SHOW_ERROR_MESSAGES
  94. ktime_get_real_ts64(&current_ts64);
  95. DEBUG(SHOW_TRACING, "%lld.%09ld Device wakeup triggered\n",
  96. (s64)current_ts64.tv_sec, current_ts64.tv_nsec);
  97. DEBUG(SHOW_TRACING, "%lld.%09ld Device register read %08x\n",
  98. (s64)current_ts64.tv_sec, current_ts64.tv_nsec,
  99. readl(device_base + ISL38XX_CTRL_STAT_REG));
  100. #endif
  101. reg = readl(device_base + ISL38XX_INT_IDENT_REG);
  102. if (reg == 0xabadface) {
  103. #if VERBOSE > SHOW_ERROR_MESSAGES
  104. ktime_get_real_ts64(&current_ts64);
  105. DEBUG(SHOW_TRACING,
  106. "%lld.%09ld Device register abadface\n",
  107. (s64)current_ts64.tv_sec, current_ts64.tv_nsec);
  108. #endif
  109. /* read the Device Status Register until Sleepmode bit is set */
  110. while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
  111. (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
  112. udelay(ISL38XX_WRITEIO_DELAY);
  113. #if VERBOSE > SHOW_ERROR_MESSAGES
  114. counter++;
  115. #endif
  116. }
  117. #if VERBOSE > SHOW_ERROR_MESSAGES
  118. DEBUG(SHOW_TRACING,
  119. "%lld.%09ld Device register read %08x\n",
  120. (s64)current_ts64.tv_sec, current_ts64.tv_nsec,
  121. readl(device_base + ISL38XX_CTRL_STAT_REG));
  122. ktime_get_real_ts64(&current_ts64);
  123. DEBUG(SHOW_TRACING,
  124. "%lld.%09ld Device asleep counter %i\n",
  125. (s64)current_ts64.tv_sec, current_ts64.tv_nsec,
  126. counter);
  127. #endif
  128. }
  129. /* assert the Wakeup interrupt in the Device Interrupt Register */
  130. isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP,
  131. ISL38XX_DEV_INT_REG);
  132. #if VERBOSE > SHOW_ERROR_MESSAGES
  133. udelay(ISL38XX_WRITEIO_DELAY);
  134. /* perform another read on the Device Status Register */
  135. reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
  136. ktime_get_real_ts64(&current_ts64);
  137. DEBUG(SHOW_TRACING, "%lld.%00ld Device register read %08x\n",
  138. (s64)current_ts64.tv_sec, current_ts64.tv_nsec, reg);
  139. #endif
  140. } else {
  141. /* device is (still) awake */
  142. #if VERBOSE > SHOW_ERROR_MESSAGES
  143. DEBUG(SHOW_TRACING, "Device is in active state\n");
  144. #endif
  145. /* trigger the device by setting the Update bit in the Device Int reg */
  146. isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
  147. ISL38XX_DEV_INT_REG);
  148. }
  149. }
  150. void
  151. isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
  152. {
  153. #if VERBOSE > SHOW_ERROR_MESSAGES
  154. DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset\n");
  155. #endif
  156. /* load the address of the control block in the device */
  157. isl38xx_w32_flush(device_base, host_address, ISL38XX_CTRL_BLK_BASE_REG);
  158. udelay(ISL38XX_WRITEIO_DELAY);
  159. /* set the reset bit in the Device Interrupt Register */
  160. isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET, ISL38XX_DEV_INT_REG);
  161. udelay(ISL38XX_WRITEIO_DELAY);
  162. /* enable the interrupt for detecting initialization */
  163. /* Note: Do not enable other interrupts here. We want the
  164. * device to have come up first 100% before allowing any other
  165. * interrupts. */
  166. isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
  167. udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */
  168. }
  169. void
  170. isl38xx_enable_common_interrupts(void __iomem *device_base)
  171. {
  172. u32 reg;
  173. reg = ISL38XX_INT_IDENT_UPDATE | ISL38XX_INT_IDENT_SLEEP |
  174. ISL38XX_INT_IDENT_WAKEUP;
  175. isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
  176. udelay(ISL38XX_WRITEIO_DELAY);
  177. }
  178. int
  179. isl38xx_in_queue(isl38xx_control_block *cb, int queue)
  180. {
  181. const s32 delta = (le32_to_cpu(cb->driver_curr_frag[queue]) -
  182. le32_to_cpu(cb->device_curr_frag[queue]));
  183. /* determine the amount of fragments in the queue depending on the type
  184. * of the queue, either transmit or receive */
  185. BUG_ON(delta < 0); /* driver ptr must be ahead of device ptr */
  186. switch (queue) {
  187. /* send queues */
  188. case ISL38XX_CB_TX_MGMTQ:
  189. BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
  190. /* fall through */
  191. case ISL38XX_CB_TX_DATA_LQ:
  192. case ISL38XX_CB_TX_DATA_HQ:
  193. BUG_ON(delta > ISL38XX_CB_TX_QSIZE);
  194. return delta;
  195. /* receive queues */
  196. case ISL38XX_CB_RX_MGMTQ:
  197. BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
  198. return ISL38XX_CB_MGMT_QSIZE - delta;
  199. case ISL38XX_CB_RX_DATA_LQ:
  200. case ISL38XX_CB_RX_DATA_HQ:
  201. BUG_ON(delta > ISL38XX_CB_RX_QSIZE);
  202. return ISL38XX_CB_RX_QSIZE - delta;
  203. }
  204. BUG();
  205. return 0;
  206. }