dp_reo.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (c) 2017 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include "dp_types.h"
  19. #include "hal_reo.h"
  20. QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, enum hal_reo_cmd_type type,
  21. struct hal_reo_cmd_params *params,
  22. void (*callback_fn), void *data)
  23. {
  24. struct dp_reo_cmd_info *reo_cmd;
  25. int num;
  26. switch (type) {
  27. case CMD_GET_QUEUE_STATS:
  28. num = hal_reo_cmd_queue_stats(soc->reo_cmd_ring.hal_srng,
  29. soc->hal_soc, params);
  30. break;
  31. case CMD_FLUSH_QUEUE:
  32. num = hal_reo_cmd_flush_queue(soc->reo_cmd_ring.hal_srng,
  33. soc->hal_soc, params);
  34. break;
  35. case CMD_FLUSH_CACHE:
  36. num = hal_reo_cmd_flush_cache(soc->reo_cmd_ring.hal_srng,
  37. soc->hal_soc, params);
  38. break;
  39. case CMD_UNBLOCK_CACHE:
  40. num = hal_reo_cmd_unblock_cache(soc->reo_cmd_ring.hal_srng,
  41. soc->hal_soc, params);
  42. break;
  43. case CMD_FLUSH_TIMEOUT_LIST:
  44. num = hal_reo_cmd_flush_timeout_list(soc->reo_cmd_ring.hal_srng,
  45. soc->hal_soc, params);
  46. break;
  47. case CMD_UPDATE_RX_REO_QUEUE:
  48. num = hal_reo_cmd_update_rx_queue(soc->reo_cmd_ring.hal_srng,
  49. soc->hal_soc, params);
  50. break;
  51. default:
  52. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  53. "%s: Invalid REO command type\n", __func__);
  54. return QDF_STATUS_E_FAILURE;
  55. };
  56. if (num == QDF_STATUS_E_FAILURE) {
  57. qdf_print("%s: Error with sending REO command\n", __func__);
  58. return QDF_STATUS_E_FAILURE;
  59. }
  60. if (callback_fn) {
  61. reo_cmd = qdf_mem_malloc(sizeof(*reo_cmd));
  62. if (!reo_cmd) {
  63. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  64. "%s: alloc failed for REO cmd:%d!!\n",
  65. __func__, type);
  66. return QDF_STATUS_E_NOMEM;
  67. }
  68. reo_cmd->cmd = num;
  69. reo_cmd->cmd_type = type;
  70. reo_cmd->handler = callback_fn;
  71. reo_cmd->data = data;
  72. qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
  73. TAILQ_INSERT_TAIL(&soc->rx.reo_cmd_list, reo_cmd,
  74. reo_cmd_list_elem);
  75. qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
  76. }
  77. return QDF_STATUS_SUCCESS;
  78. }
  79. void dp_reo_status_ring_handler(struct dp_soc *soc)
  80. {
  81. uint32_t *reo_desc;
  82. struct dp_reo_cmd_info *reo_cmd = NULL;
  83. union hal_reo_status reo_status;
  84. int num;
  85. if (hal_srng_access_start(soc->hal_soc,
  86. soc->reo_status_ring.hal_srng)) {
  87. return;
  88. }
  89. reo_desc = hal_srng_dst_get_next(soc->hal_soc,
  90. soc->reo_status_ring.hal_srng);
  91. while (reo_desc) {
  92. uint16_t tlv = HAL_GET_TLV(reo_desc);
  93. switch (tlv) {
  94. case HAL_REO_QUEUE_STATS_STATUS_TLV:
  95. hal_reo_queue_stats_status(reo_desc,
  96. &reo_status.queue_status);
  97. num = reo_status.queue_status.header.cmd_num;
  98. break;
  99. case HAL_REO_FLUSH_QUEUE_STATUS_TLV:
  100. hal_reo_flush_queue_status(reo_desc,
  101. &reo_status.fl_queue_status);
  102. num = reo_status.fl_queue_status.header.cmd_num;
  103. break;
  104. case HAL_REO_FLUSH_CACHE_STATUS_TLV:
  105. hal_reo_flush_cache_status(reo_desc, soc->hal_soc,
  106. &reo_status.fl_cache_status);
  107. num = reo_status.fl_cache_status.header.cmd_num;
  108. break;
  109. case HAL_REO_UNBLK_CACHE_STATUS_TLV:
  110. hal_reo_unblock_cache_status(reo_desc, soc->hal_soc,
  111. &reo_status.unblk_cache_status);
  112. num = reo_status.unblk_cache_status.header.cmd_num;
  113. break;
  114. case HAL_REO_TIMOUT_LIST_STATUS_TLV:
  115. hal_reo_flush_timeout_list_status(reo_desc,
  116. &reo_status.fl_timeout_status);
  117. num = reo_status.fl_timeout_status.header.cmd_num;
  118. break;
  119. case HAL_REO_DESC_THRES_STATUS_TLV:
  120. hal_reo_desc_thres_reached_status(reo_desc,
  121. &reo_status.thres_status);
  122. num = reo_status.thres_status.header.cmd_num;
  123. break;
  124. case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV:
  125. hal_reo_rx_update_queue_status(reo_desc,
  126. &reo_status.rx_queue_status);
  127. num = reo_status.rx_queue_status.header.cmd_num;
  128. break;
  129. default:
  130. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_WARN,
  131. "%s, no handler for TLV:%d\n", __func__, tlv);
  132. goto next;
  133. } /* switch */
  134. qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
  135. TAILQ_FOREACH(reo_cmd, &soc->rx.reo_cmd_list,
  136. reo_cmd_list_elem) {
  137. if (reo_cmd->cmd == num) {
  138. TAILQ_REMOVE(&soc->rx.reo_cmd_list, reo_cmd,
  139. reo_cmd_list_elem);
  140. break;
  141. }
  142. }
  143. qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
  144. if (reo_cmd) {
  145. reo_cmd->handler(soc, reo_cmd->data,
  146. &reo_status);
  147. qdf_mem_free(reo_cmd);
  148. }
  149. next:
  150. reo_desc = hal_srng_dst_get_next(soc,
  151. soc->reo_status_ring.hal_srng);
  152. } /* while */
  153. hal_srng_access_end(soc->hal_soc, soc->reo_status_ring.hal_srng);
  154. }