dp_rx_mon_feature.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * Copyright (c) 2017-2019 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 "hal_hw_headers.h"
  19. #include "dp_types.h"
  20. #include "dp_rx.h"
  21. #include "dp_peer.h"
  22. #include "hal_rx.h"
  23. #include "hal_api.h"
  24. #include "qdf_trace.h"
  25. #include "qdf_nbuf.h"
  26. #include "hal_api_mon.h"
  27. #include "dp_rx_mon.h"
  28. #include "dp_internal.h"
  29. #include "qdf_mem.h" /* qdf_mem_malloc,free */
  30. #ifdef WLAN_RX_PKT_CAPTURE_ENH
  31. static inline void
  32. dp_rx_free_msdu_list(struct msdu_list *msdu_list)
  33. {
  34. qdf_nbuf_list_free(msdu_list->head);
  35. msdu_list->head = NULL;
  36. msdu_list->tail = NULL;
  37. msdu_list->sum_len = 0;
  38. }
  39. /**
  40. * dp_nbuf_set_data_and_len() - set nbuf data and len
  41. * @buf: Network buf instance
  42. * @data: pointer to nbuf data
  43. * @len: nbuf data length
  44. *
  45. * Return: none
  46. */
  47. static inline void dp_nbuf_set_data_and_len(qdf_nbuf_t buf, unsigned char *data
  48. , int len)
  49. {
  50. qdf_nbuf_set_data_pointer(buf, data);
  51. qdf_nbuf_set_len(buf, len);
  52. qdf_nbuf_set_tail_pointer(buf, len);
  53. }
  54. /*
  55. * dp_rx_populate_cdp_indication_mpdu_info() - Populate cdp rx indication
  56. * MPDU info structure
  57. * @pdev: pdev ctx
  58. * @ppdu_info: ppdu info structure from monitor status ring
  59. * @cdp_mpdu_info: cdp rx indication MPDU info structure
  60. * @user: user ID
  61. *
  62. * Return: none
  63. */
  64. void
  65. dp_rx_populate_cdp_indication_mpdu_info(
  66. struct dp_pdev *pdev,
  67. struct hal_rx_ppdu_info *ppdu_info,
  68. struct cdp_rx_indication_mpdu_info *cdp_mpdu_info,
  69. uint32_t user)
  70. {
  71. int i;
  72. cdp_mpdu_info->ppdu_id = ppdu_info->com_info.ppdu_id;
  73. cdp_mpdu_info->channel = ppdu_info->rx_status.chan_num;
  74. cdp_mpdu_info->duration = ppdu_info->rx_status.duration;
  75. cdp_mpdu_info->timestamp = ppdu_info->rx_status.tsft;
  76. cdp_mpdu_info->bw = ppdu_info->rx_status.bw;
  77. if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) &&
  78. (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC))
  79. cdp_mpdu_info->gi = CDP_SGI_0_4_US;
  80. else
  81. cdp_mpdu_info->gi = ppdu_info->rx_status.sgi;
  82. cdp_mpdu_info->ldpc = ppdu_info->rx_status.ldpc;
  83. cdp_mpdu_info->preamble = ppdu_info->rx_status.preamble_type;
  84. cdp_mpdu_info->ppdu_type = ppdu_info->rx_status.reception_type;
  85. cdp_mpdu_info->rssi_comb = ppdu_info->rx_status.rssi_comb;
  86. cdp_mpdu_info->nf = ppdu_info->rx_status.chan_noise_floor;
  87. cdp_mpdu_info->timestamp = ppdu_info->rx_status.tsft;
  88. if (ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_OFDMA) {
  89. cdp_mpdu_info->nss = ppdu_info->rx_user_status[user].nss;
  90. cdp_mpdu_info->mcs = ppdu_info->rx_user_status[user].mcs;
  91. } else {
  92. cdp_mpdu_info->nss = ppdu_info->rx_status.nss;
  93. cdp_mpdu_info->mcs = ppdu_info->rx_status.mcs;
  94. }
  95. cdp_mpdu_info->rate = ppdu_info->rx_status.rate;
  96. for (i = 0; i < MAX_CHAIN; i++)
  97. cdp_mpdu_info->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i];
  98. }
  99. /*
  100. * dp_rx_handle_enh_capture() - Deliver Rx enhanced capture data
  101. * @pdev: pdev ctx
  102. * @ppdu_info: ppdu info structure from monitor status ring
  103. *
  104. * Return: QDF status
  105. */
  106. QDF_STATUS
  107. dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev,
  108. struct hal_rx_ppdu_info *ppdu_info)
  109. {
  110. qdf_nbuf_t nbuf;
  111. uint32_t user;
  112. qdf_nbuf_queue_t *mpdu_q;
  113. struct cdp_rx_indication_mpdu *mpdu_ind;
  114. struct cdp_rx_indication_mpdu_info *mpdu_info;
  115. struct msdu_list *msdu_list;
  116. user = 0;
  117. mpdu_q = &pdev->mpdu_q[user];
  118. while (!qdf_nbuf_is_queue_empty(mpdu_q)) {
  119. msdu_list = &pdev->msdu_list[user];
  120. dp_rx_free_msdu_list(msdu_list);
  121. mpdu_ind = &pdev->mpdu_ind[user];
  122. mpdu_info = &mpdu_ind->mpdu_info;
  123. dp_rx_populate_cdp_indication_mpdu_info(
  124. pdev, &pdev->ppdu_info, mpdu_info, user);
  125. while (!qdf_nbuf_is_queue_empty(mpdu_q)) {
  126. nbuf = qdf_nbuf_queue_remove(mpdu_q);
  127. mpdu_ind->nbuf = nbuf;
  128. mpdu_info->fcs_err = QDF_NBUF_CB_RX_FCS_ERR(nbuf);
  129. dp_wdi_event_handler(WDI_EVENT_RX_MPDU,
  130. soc, mpdu_ind, HTT_INVALID_PEER,
  131. WDI_NO_VAL, pdev->pdev_id);
  132. }
  133. user++;
  134. mpdu_q = &pdev->mpdu_q[user];
  135. }
  136. return QDF_STATUS_SUCCESS;
  137. }
  138. /*
  139. * dp_rx_mon_enh_capture_process() - Rx enhanced capture mode
  140. * processing.
  141. * @pdev: pdev structure
  142. * @tlv_status: processed TLV status
  143. * @status_nbuf: monitor status ring buffer
  144. * @ppdu_info: ppdu info structure from monitor status ring
  145. * @nbuf_used: nbuf need a clone
  146. * @rx_enh_capture_mode: Rx enhanced capture mode
  147. *
  148. * Return: none
  149. */
  150. void
  151. dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
  152. qdf_nbuf_t status_nbuf,
  153. struct hal_rx_ppdu_info *ppdu_info,
  154. bool *nbuf_used,
  155. uint32_t rx_enh_capture_mode)
  156. {
  157. qdf_nbuf_t nbuf;
  158. struct msdu_list *msdu_list;
  159. uint32_t user_id;
  160. if (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_DISABLED)
  161. return;
  162. user_id = ppdu_info->user_id;
  163. if ((tlv_status == HAL_TLV_STATUS_HEADER) && (
  164. (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU) ||
  165. ((rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) &&
  166. pdev->is_mpdu_hdr[user_id]))) {
  167. if (*nbuf_used) {
  168. nbuf = qdf_nbuf_clone(status_nbuf);
  169. } else {
  170. *nbuf_used = true;
  171. nbuf = status_nbuf;
  172. }
  173. dp_nbuf_set_data_and_len(nbuf, ppdu_info->data,
  174. ppdu_info->hdr_len - 4);
  175. if (pdev->is_mpdu_hdr[user_id]) {
  176. qdf_nbuf_queue_add(&pdev->mpdu_q[user_id],
  177. nbuf);
  178. pdev->is_mpdu_hdr[user_id] = false;
  179. } else {
  180. msdu_list = &pdev->msdu_list[user_id];
  181. if (!msdu_list->head)
  182. msdu_list->head = nbuf;
  183. else
  184. msdu_list->tail->next = nbuf;
  185. msdu_list->tail = nbuf;
  186. msdu_list->sum_len += qdf_nbuf_len(nbuf);
  187. }
  188. }
  189. if (tlv_status == HAL_TLV_STATUS_MPDU_END) {
  190. msdu_list = &pdev->msdu_list[user_id];
  191. nbuf = qdf_nbuf_queue_last(&pdev->mpdu_q[user_id]);
  192. if (nbuf) {
  193. qdf_nbuf_append_ext_list(nbuf,
  194. msdu_list->head,
  195. msdu_list->sum_len);
  196. msdu_list->head = NULL;
  197. msdu_list->tail = NULL;
  198. msdu_list->sum_len = 0;
  199. QDF_NBUF_CB_RX_FCS_ERR(nbuf) = ppdu_info->fcs_err;
  200. pdev->is_mpdu_hdr[user_id] = true;
  201. } else {
  202. dp_rx_free_msdu_list(msdu_list);
  203. }
  204. }
  205. }
  206. /*
  207. * dp_config_enh_rx_capture()- API to enable/disable enhanced rx capture
  208. * @pdev_handle: DP_PDEV handle
  209. * @val: user provided value
  210. *
  211. * Return: 0 for success. nonzero for failure.
  212. */
  213. QDF_STATUS
  214. dp_config_enh_rx_capture(struct cdp_pdev *pdev_handle, int val)
  215. {
  216. struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
  217. if (pdev->mcopy_mode || (val < CDP_RX_ENH_CAPTURE_DISABLED) ||
  218. (val > CDP_RX_ENH_CAPTURE_MPDU_MSDU)) {
  219. dp_err("Invalid mode");
  220. return QDF_STATUS_E_INVAL;
  221. }
  222. if (pdev->rx_enh_capture_mode)
  223. dp_reset_monitor_mode(pdev_handle);
  224. pdev->rx_enh_capture_mode = val;
  225. return dp_pdev_configure_monitor_rings(pdev);
  226. }
  227. #endif