dp_mon.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  7. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  8. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  9. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  10. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  11. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  12. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  13. */
  14. #include <dp_types.h>
  15. #include "dp_rx.h"
  16. #include "dp_peer.h"
  17. #include <dp_htt.h>
  18. #include <dp_rx_mon.h>
  19. #include <dp_mon_filter.h>
  20. #include <dp_mon.h>
  21. #define RNG_ERR "SRNG setup failed for"
  22. #define mon_init_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_DP_INIT, params)
  23. QDF_STATUS dp_srng_alloc(struct dp_soc *soc, struct dp_srng *srng,
  24. int ring_type, uint32_t num_entries,
  25. bool cached);
  26. void dp_srng_free(struct dp_soc *soc, struct dp_srng *srng);
  27. QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
  28. int ring_type, int ring_num, int mac_id);
  29. void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
  30. int ring_type, int ring_num);
  31. QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev);
  32. void dp_htt_ppdu_stats_detach(struct dp_pdev *pdev);
  33. void dp_neighbour_peers_detach(struct dp_pdev *pdev);
  34. void dp_pktlogmod_exit(struct dp_pdev *handle);
  35. #if !defined(DISABLE_MON_CONFIG)
  36. /**
  37. * dp_mon_rings_deinit() - Deinitialize monitor rings
  38. * @pdev: DP pdev handle
  39. *
  40. * Return: None
  41. *
  42. */
  43. static void dp_mon_rings_deinit(struct dp_pdev *pdev)
  44. {
  45. int mac_id = 0;
  46. struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
  47. struct dp_soc *soc = pdev->soc;
  48. pdev_cfg_ctx = pdev->wlan_cfg_ctx;
  49. for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
  50. int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
  51. pdev->pdev_id);
  52. dp_srng_deinit(soc, &soc->rxdma_mon_status_ring[lmac_id],
  53. RXDMA_MONITOR_STATUS, 0);
  54. if (!soc->wlan_cfg_ctx->rxdma1_enable)
  55. continue;
  56. dp_srng_deinit(soc, &soc->rxdma_mon_buf_ring[lmac_id],
  57. RXDMA_MONITOR_BUF, 0);
  58. dp_srng_deinit(soc, &soc->rxdma_mon_dst_ring[lmac_id],
  59. RXDMA_MONITOR_DST, 0);
  60. dp_srng_deinit(soc, &soc->rxdma_mon_desc_ring[lmac_id],
  61. RXDMA_MONITOR_DESC, 0);
  62. }
  63. }
  64. /**
  65. * dp_mon_rings_free() - free monitor rings
  66. * @pdev: Datapath pdev handle
  67. *
  68. * Return: None
  69. *
  70. */
  71. static void dp_mon_rings_free(struct dp_pdev *pdev)
  72. {
  73. int mac_id = 0;
  74. struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
  75. struct dp_soc *soc = pdev->soc;
  76. pdev_cfg_ctx = pdev->wlan_cfg_ctx;
  77. for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
  78. int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
  79. pdev->pdev_id);
  80. dp_srng_free(soc, &soc->rxdma_mon_status_ring[lmac_id]);
  81. if (!soc->wlan_cfg_ctx->rxdma1_enable)
  82. continue;
  83. dp_srng_free(soc, &soc->rxdma_mon_buf_ring[lmac_id]);
  84. dp_srng_free(soc, &soc->rxdma_mon_dst_ring[lmac_id]);
  85. dp_srng_free(soc, &soc->rxdma_mon_desc_ring[lmac_id]);
  86. }
  87. }
  88. /**
  89. * dp_mon_rings_init() - Initialize monitor srng rings
  90. * @pdev: Datapath pdev handle
  91. *
  92. * return: QDF_STATUS_SUCCESS on success
  93. * QDF_STATUS_E_NOMEM on failure
  94. */
  95. static
  96. QDF_STATUS dp_mon_rings_init(struct dp_soc *soc, struct dp_pdev *pdev)
  97. {
  98. int mac_id = 0;
  99. struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
  100. pdev_cfg_ctx = pdev->wlan_cfg_ctx;
  101. for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
  102. int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
  103. pdev->pdev_id);
  104. if (dp_srng_init(soc, &soc->rxdma_mon_status_ring[lmac_id],
  105. RXDMA_MONITOR_STATUS, 0, lmac_id)) {
  106. mon_init_err("%pK: " RNG_ERR "rxdma_mon_status_ring",
  107. soc);
  108. goto fail1;
  109. }
  110. if (!soc->wlan_cfg_ctx->rxdma1_enable)
  111. continue;
  112. if (dp_srng_init(soc, &soc->rxdma_mon_buf_ring[lmac_id],
  113. RXDMA_MONITOR_BUF, 0, lmac_id)) {
  114. mon_init_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ",
  115. soc);
  116. goto fail1;
  117. }
  118. if (dp_srng_init(soc, &soc->rxdma_mon_dst_ring[lmac_id],
  119. RXDMA_MONITOR_DST, 0, lmac_id)) {
  120. mon_init_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc);
  121. goto fail1;
  122. }
  123. if (dp_srng_init(soc, &soc->rxdma_mon_desc_ring[lmac_id],
  124. RXDMA_MONITOR_DESC, 0, lmac_id)) {
  125. mon_init_err("%pK: " RNG_ERR "rxdma_mon_desc_ring",
  126. soc);
  127. goto fail1;
  128. }
  129. }
  130. return QDF_STATUS_SUCCESS;
  131. fail1:
  132. dp_mon_rings_deinit(pdev);
  133. return QDF_STATUS_E_NOMEM;
  134. }
  135. /**
  136. * dp_mon_rings_alloc() - Allocate memory for monitor srng rings
  137. * @soc: Datapath soc handle
  138. * @pdev: Datapath pdev handle
  139. *
  140. * return: QDF_STATUS_SUCCESS on success
  141. * QDF_STATUS_E_NOMEM on failure
  142. */
  143. static
  144. QDF_STATUS dp_mon_rings_alloc(struct dp_soc *soc, struct dp_pdev *pdev)
  145. {
  146. int mac_id = 0;
  147. int entries;
  148. struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
  149. pdev_cfg_ctx = pdev->wlan_cfg_ctx;
  150. for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
  151. int lmac_id =
  152. dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id);
  153. entries = wlan_cfg_get_dma_mon_stat_ring_size(pdev_cfg_ctx);
  154. if (dp_srng_alloc(soc, &soc->rxdma_mon_status_ring[lmac_id],
  155. RXDMA_MONITOR_STATUS, entries, 0)) {
  156. mon_init_err("%pK: " RNG_ERR "rxdma_mon_status_ring",
  157. soc);
  158. goto fail1;
  159. }
  160. if (!soc->wlan_cfg_ctx->rxdma1_enable)
  161. continue;
  162. entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev_cfg_ctx);
  163. if (dp_srng_alloc(soc, &soc->rxdma_mon_buf_ring[lmac_id],
  164. RXDMA_MONITOR_BUF, entries, 0)) {
  165. mon_init_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ",
  166. soc);
  167. goto fail1;
  168. }
  169. entries = wlan_cfg_get_dma_mon_dest_ring_size(pdev_cfg_ctx);
  170. if (dp_srng_alloc(soc, &soc->rxdma_mon_dst_ring[lmac_id],
  171. RXDMA_MONITOR_DST, entries, 0)) {
  172. mon_init_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc);
  173. goto fail1;
  174. }
  175. entries = wlan_cfg_get_dma_mon_desc_ring_size(pdev_cfg_ctx);
  176. if (dp_srng_alloc(soc, &soc->rxdma_mon_desc_ring[lmac_id],
  177. RXDMA_MONITOR_DESC, entries, 0)) {
  178. mon_init_err("%pK: " RNG_ERR "rxdma_mon_desc_ring",
  179. soc);
  180. goto fail1;
  181. }
  182. }
  183. return QDF_STATUS_SUCCESS;
  184. fail1:
  185. dp_mon_rings_free(pdev);
  186. return QDF_STATUS_E_NOMEM;
  187. }
  188. #else
  189. static void dp_mon_rings_free(struct dp_pdev *pdev)
  190. {
  191. }
  192. static void dp_mon_rings_deinit(struct dp_pdev *pdev)
  193. {
  194. }
  195. static
  196. QDF_STATUS dp_mon_rings_init(struct dp_soc *soc, struct dp_pdev *pdev)
  197. {
  198. return QDF_STATUS_SUCCESS;
  199. }
  200. static
  201. QDF_STATUS dp_mon_rings_alloc(struct dp_soc *soc, struct dp_pdev *pdev)
  202. {
  203. return QDF_STATUS_SUCCESS;
  204. }
  205. #endif
  206. QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc)
  207. {
  208. return QDF_STATUS_SUCCESS;
  209. }
  210. QDF_STATUS dp_mon_pdev_attach(struct dp_pdev *pdev)
  211. {
  212. struct dp_soc *soc = pdev->soc;
  213. struct dp_mon_pdev *mon_pdev;
  214. mon_pdev = (struct dp_mon_pdev *)qdf_mem_malloc(sizeof(*mon_pdev));
  215. if (!mon_pdev) {
  216. mon_init_err("%pK: MONITOR pdev allocation failed", pdev);
  217. goto fail0;
  218. }
  219. if (dp_mon_rings_alloc(soc, pdev)) {
  220. mon_init_err("%pK: MONITOR rings setup failed", soc);
  221. goto fail1;
  222. }
  223. /* Rx monitor mode specific init */
  224. if (dp_rx_pdev_mon_desc_pool_alloc(pdev)) {
  225. mon_init_err("%pK: dp_rx_pdev_mon_attach failed", soc);
  226. goto fail2;
  227. }
  228. pdev->monitor_pdev = mon_pdev;
  229. return QDF_STATUS_SUCCESS;
  230. fail2:
  231. dp_mon_rings_free(pdev);
  232. fail1:
  233. pdev->monitor_pdev = NULL;
  234. qdf_mem_free(mon_pdev);
  235. fail0:
  236. return QDF_STATUS_E_NOMEM;
  237. }
  238. QDF_STATUS dp_mon_pdev_detach(struct dp_pdev *pdev)
  239. {
  240. struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
  241. dp_rx_pdev_mon_desc_pool_free(pdev);
  242. dp_mon_rings_free(pdev);
  243. pdev->monitor_pdev = NULL;
  244. qdf_mem_free(mon_pdev);
  245. return QDF_STATUS_SUCCESS;
  246. }
  247. QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev)
  248. {
  249. struct dp_soc *soc = pdev->soc;
  250. pdev->filter = dp_mon_filter_alloc(pdev);
  251. if (!pdev->filter) {
  252. mon_init_err("%pK: Memory allocation failed for monitor filter",
  253. soc);
  254. return QDF_STATUS_E_NOMEM;
  255. }
  256. qdf_spinlock_create(&pdev->ppdu_stats_lock);
  257. qdf_spinlock_create(&pdev->neighbour_peer_mutex);
  258. pdev->monitor_configured = false;
  259. pdev->mon_chan_band = REG_BAND_UNKNOWN;
  260. /* Monitor filter init */
  261. pdev->mon_filter_mode = MON_FILTER_ALL;
  262. TAILQ_INIT(&pdev->neighbour_peers_list);
  263. pdev->neighbour_peers_added = false;
  264. pdev->monitor_configured = false;
  265. /* Monitor filter init */
  266. pdev->mon_filter_mode = MON_FILTER_ALL;
  267. pdev->fp_mgmt_filter = FILTER_MGMT_ALL;
  268. pdev->fp_ctrl_filter = FILTER_CTRL_ALL;
  269. pdev->fp_data_filter = FILTER_DATA_ALL;
  270. pdev->mo_mgmt_filter = FILTER_MGMT_ALL;
  271. pdev->mo_ctrl_filter = FILTER_CTRL_ALL;
  272. pdev->mo_data_filter = FILTER_DATA_ALL;
  273. if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS)
  274. goto fail0;
  275. if (dp_mon_rings_init(soc, pdev)) {
  276. mon_init_err("%pK: MONITOR rings setup failed", soc);
  277. goto fail1;
  278. }
  279. /* initialize sw monitor rx descriptors */
  280. dp_rx_pdev_mon_desc_pool_init(pdev);
  281. /* allocate buffers and replenish the monitor RxDMA ring */
  282. dp_rx_pdev_mon_buffers_alloc(pdev);
  283. dp_tx_ppdu_stats_attach(pdev);
  284. return QDF_STATUS_SUCCESS;
  285. fail1:
  286. dp_htt_ppdu_stats_detach(pdev);
  287. fail0:
  288. qdf_spinlock_destroy(&pdev->neighbour_peer_mutex);
  289. qdf_spinlock_destroy(&pdev->ppdu_stats_lock);
  290. dp_mon_filter_dealloc(pdev);
  291. return QDF_STATUS_E_FAILURE;
  292. }
  293. QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev)
  294. {
  295. dp_tx_ppdu_stats_detach(pdev);
  296. dp_rx_pdev_mon_buffers_free(pdev);
  297. dp_rx_pdev_mon_desc_pool_deinit(pdev);
  298. dp_mon_rings_deinit(pdev);
  299. dp_htt_ppdu_stats_detach(pdev);
  300. qdf_spinlock_destroy(&pdev->ppdu_stats_lock);
  301. dp_neighbour_peers_detach(pdev);
  302. dp_pktlogmod_exit(pdev);
  303. if (pdev->filter)
  304. dp_mon_filter_dealloc(pdev);
  305. return QDF_STATUS_SUCCESS;
  306. }
  307. static struct dp_mon_ops monitor_ops = {
  308. .mon_soc_cfg_init = dp_mon_soc_cfg_init,
  309. .mon_pdev_attach = dp_mon_pdev_attach,
  310. .mon_pdev_detach = dp_mon_pdev_detach,
  311. .mon_pdev_init = dp_mon_pdev_init,
  312. .mon_pdev_deinit = dp_mon_pdev_deinit,
  313. };
  314. static inline void dp_mon_ops_register(struct dp_mon_soc *mon_soc)
  315. {
  316. mon_soc->mon_ops = &monitor_ops;
  317. }
  318. QDF_STATUS dp_mon_soc_attach(struct dp_soc *soc)
  319. {
  320. struct dp_mon_soc *mon_soc;
  321. mon_soc = (struct dp_mon_soc *)qdf_mem_malloc(sizeof(*mon_soc));
  322. if (!mon_soc) {
  323. mon_init_err("%pK: mem allocation failed", soc);
  324. return QDF_STATUS_E_NOMEM;
  325. }
  326. /* register monitor ops */
  327. dp_mon_ops_register(mon_soc);
  328. soc->monitor_soc = mon_soc;
  329. return QDF_STATUS_SUCCESS;
  330. }
  331. QDF_STATUS dp_mon_soc_detach(struct dp_soc *soc)
  332. {
  333. struct dp_mon_soc *mon_soc = soc->monitor_soc;
  334. soc->monitor_soc = NULL;
  335. qdf_mem_free(mon_soc);
  336. return QDF_STATUS_SUCCESS;
  337. }