pktlog_internal.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * Copyright (c) 2013-2020 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. /*
  19. *
  20. * Permission to use, copy, modify, and/or distribute this software for any
  21. * purpose with or without fee is hereby granted, provided that the above
  22. * copyright notice and this permission notice appear in all copies.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  25. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  26. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  27. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  28. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  29. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  30. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  31. */
  32. #ifndef REMOVE_PKT_LOG
  33. #include "ol_txrx_types.h"
  34. #include "ol_htt_tx_api.h"
  35. #include "ol_tx_desc.h"
  36. #include "qdf_mem.h"
  37. #include "htt.h"
  38. #include "htt_internal.h"
  39. #include "pktlog_ac_i.h"
  40. #include "wma_api.h"
  41. #include "wlan_logging_sock_svc.h"
  42. #ifdef PKTLOG_HAS_SPECIFIC_DATA
  43. static inline void
  44. pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr,
  45. uint32_t type_specific_data)
  46. {
  47. log_hdr->type_specific_data = type_specific_data;
  48. }
  49. static inline uint32_t
  50. pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr)
  51. {
  52. return log_hdr->type_specific_data;
  53. }
  54. static inline void
  55. pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg,
  56. uint32_t type_specific_data)
  57. {
  58. plarg->type_specific_data = type_specific_data;
  59. }
  60. static inline uint32_t
  61. pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg)
  62. {
  63. return plarg->type_specific_data;
  64. }
  65. #else
  66. static inline void
  67. pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr,
  68. uint32_t type_specific_data)
  69. {
  70. }
  71. static inline uint32_t
  72. pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr)
  73. {
  74. return 0;
  75. }
  76. static inline void
  77. pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg,
  78. uint32_t type_specific_data)
  79. {
  80. }
  81. static inline uint32_t
  82. pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg)
  83. {
  84. return 0;
  85. }
  86. #endif /* PKTLOG_HAS_SPECIFIC_DATA */
  87. void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
  88. {
  89. struct ath_pktlog_buf *log_buf;
  90. int32_t buf_size;
  91. struct ath_pktlog_hdr *log_hdr;
  92. int32_t cur_wr_offset;
  93. char *log_ptr;
  94. struct ath_pktlog_info *pl_info;
  95. uint16_t log_type;
  96. size_t log_size;
  97. uint32_t flags;
  98. #ifdef HELIUMPLUS
  99. uint8_t mac_id;
  100. #endif
  101. if (!plarg) {
  102. qdf_nofl_info("Invalid parg in %s", __func__);
  103. return;
  104. }
  105. pl_info = plarg->pl_info;
  106. #ifdef HELIUMPLUS
  107. mac_id = plarg->macId;
  108. log_type = plarg->log_type;
  109. #else
  110. log_type = plarg->log_type;
  111. #endif
  112. log_size = plarg->log_size;
  113. log_buf = pl_info->buf;
  114. flags = plarg->flags;
  115. if (!log_buf) {
  116. qdf_nofl_info("Invalid log_buf in %s", __func__);
  117. return;
  118. }
  119. buf_size = pl_info->buf_size;
  120. cur_wr_offset = log_buf->wr_offset;
  121. /* Move read offset to the next entry if there is a buffer overlap */
  122. if (log_buf->rd_offset >= 0) {
  123. if ((cur_wr_offset <= log_buf->rd_offset)
  124. && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) >
  125. log_buf->rd_offset) {
  126. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
  127. buf_size);
  128. }
  129. } else {
  130. log_buf->rd_offset = cur_wr_offset;
  131. }
  132. log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset);
  133. log_hdr->flags = flags;
  134. #ifdef HELIUMPLUS
  135. log_hdr->macId = mac_id;
  136. log_hdr->log_type = log_type;
  137. #else
  138. log_hdr->log_type = log_type;
  139. #endif
  140. log_hdr->size = (uint16_t) log_size;
  141. log_hdr->missed_cnt = plarg->missed_cnt;
  142. log_hdr->timestamp = plarg->timestamp;
  143. pktlog_hdr_set_specific_data(log_hdr,
  144. pktlog_arg_get_specific_data(plarg));
  145. cur_wr_offset += sizeof(*log_hdr);
  146. if ((buf_size - cur_wr_offset) < log_size) {
  147. while ((cur_wr_offset <= log_buf->rd_offset)
  148. && (log_buf->rd_offset < buf_size)) {
  149. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
  150. buf_size);
  151. }
  152. cur_wr_offset = 0;
  153. }
  154. while ((cur_wr_offset <= log_buf->rd_offset)
  155. && (cur_wr_offset + log_size) > log_buf->rd_offset) {
  156. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, buf_size);
  157. }
  158. log_ptr = &(log_buf->log_data[cur_wr_offset]);
  159. cur_wr_offset += log_hdr->size;
  160. log_buf->wr_offset = ((buf_size - cur_wr_offset) >=
  161. sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset :
  162. 0;
  163. plarg->buf = log_ptr;
  164. }
  165. char *pktlog_getbuf(struct pktlog_dev_t *pl_dev,
  166. struct ath_pktlog_info *pl_info,
  167. size_t log_size, struct ath_pktlog_hdr *pl_hdr)
  168. {
  169. struct ath_pktlog_arg plarg = { 0, };
  170. uint8_t flags = 0;
  171. plarg.pl_info = pl_info;
  172. #ifdef HELIUMPLUS
  173. plarg.macId = pl_hdr->macId;
  174. plarg.log_type = pl_hdr->log_type;
  175. #else
  176. plarg.log_type = pl_hdr->log_type;
  177. #endif
  178. plarg.log_size = log_size;
  179. plarg.flags = pl_hdr->flags;
  180. plarg.missed_cnt = pl_hdr->missed_cnt;
  181. plarg.timestamp = pl_hdr->timestamp;
  182. pktlog_arg_set_specific_data(&plarg,
  183. pktlog_hdr_get_specific_data(pl_hdr));
  184. if (flags & PHFLAGS_INTERRUPT_CONTEXT) {
  185. /*
  186. * We are already in interrupt context, no need to make it
  187. * intsafe. call the function directly.
  188. */
  189. pktlog_getbuf_intsafe(&plarg);
  190. } else {
  191. PKTLOG_LOCK(pl_info);
  192. pktlog_getbuf_intsafe(&plarg);
  193. PKTLOG_UNLOCK(pl_info);
  194. }
  195. return plarg.buf;
  196. }
  197. #ifdef HELIUMPLUS
  198. A_STATUS process_rate_find(void *pdev, void *data)
  199. {
  200. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  201. struct ath_pktlog_hdr pl_hdr;
  202. struct ath_pktlog_info *pl_info;
  203. size_t log_size;
  204. uint32_t len;
  205. struct ol_fw_data *fw_data;
  206. /*
  207. * Will be uncommented when the rate control find
  208. * for pktlog is implemented in the firmware.
  209. * Currently derived from the TX PPDU status
  210. */
  211. struct ath_pktlog_rc_find rcf_log;
  212. uint32_t *pl_tgt_hdr;
  213. if (!pdev || !data || !pl_dev) {
  214. qdf_print("%s: Invalid handle", __func__);
  215. return A_ERROR;
  216. }
  217. fw_data = (struct ol_fw_data *)data;
  218. len = fw_data->len;
  219. if (len < (sizeof(uint32_t) *
  220. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  221. len < (sizeof(uint32_t) *
  222. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  223. len < (sizeof(uint32_t) *
  224. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  225. len < (sizeof(uint32_t) *
  226. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  227. len < (sizeof(uint32_t) *
  228. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  229. len < (sizeof(uint32_t) *
  230. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  231. qdf_print("Invalid msdu len in %s", __func__);
  232. qdf_assert(0);
  233. return A_ERROR;
  234. }
  235. pl_tgt_hdr = (uint32_t *)fw_data->data;
  236. /*
  237. * Makes the short words (16 bits) portable b/w little endian
  238. * and big endian
  239. */
  240. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  241. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  242. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  243. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  244. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  245. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  246. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  247. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  248. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  249. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  250. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  251. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  252. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  253. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  254. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  255. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  256. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  257. pl_info = pl_dev->pl_info;
  258. log_size = pl_hdr.size;
  259. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  260. log_size, &pl_hdr);
  261. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  262. qdf_assert(0);
  263. return A_ERROR;
  264. }
  265. qdf_mem_copy(rcf_log.rcFind,
  266. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  267. pl_hdr.size);
  268. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  269. return A_OK;
  270. }
  271. #else
  272. A_STATUS process_rate_find(void *pdev, void *data)
  273. {
  274. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  275. struct ath_pktlog_hdr pl_hdr;
  276. struct ath_pktlog_info *pl_info;
  277. size_t log_size;
  278. uint32_t len;
  279. struct ol_fw_data *fw_data;
  280. /*
  281. * Will be uncommented when the rate control find
  282. * for pktlog is implemented in the firmware.
  283. * Currently derived from the TX PPDU status
  284. */
  285. struct ath_pktlog_rc_find rcf_log;
  286. uint32_t *pl_tgt_hdr;
  287. if (!pdev || !data || !pl_dev) {
  288. qdf_print("%s: Invalid handle", __func__);
  289. return A_ERROR;
  290. }
  291. fw_data = (struct ol_fw_data *)data;
  292. len = fw_data->len;
  293. if (len < (sizeof(uint32_t) *
  294. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  295. len < (sizeof(uint32_t) *
  296. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  297. len < (sizeof(uint32_t) *
  298. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  299. len < (sizeof(uint32_t) *
  300. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  301. len < (sizeof(uint32_t) *
  302. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  303. qdf_print("Invalid msdu len in %s", __func__);
  304. qdf_assert(0);
  305. return A_ERROR;
  306. }
  307. pl_tgt_hdr = (uint32_t *)fw_data->data;
  308. /*
  309. * Makes the short words (16 bits) portable b/w little endian
  310. * and big endian
  311. */
  312. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  313. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  314. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  315. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  316. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  317. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  318. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  319. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  320. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  321. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  322. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  323. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  324. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  325. pl_info = pl_dev->pl_info;
  326. log_size = pl_hdr.size;
  327. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  328. log_size, &pl_hdr);
  329. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  330. qdf_assert(0);
  331. return A_ERROR;
  332. }
  333. qdf_mem_copy(rcf_log.rcFind,
  334. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  335. pl_hdr.size);
  336. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  337. return A_OK;
  338. }
  339. #endif
  340. #ifdef HELIUMPLUS
  341. A_STATUS process_sw_event(void *pdev, void *data)
  342. {
  343. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  344. struct ath_pktlog_hdr pl_hdr;
  345. struct ath_pktlog_info *pl_info;
  346. size_t log_size;
  347. uint32_t len;
  348. struct ol_fw_data *fw_data;
  349. /*
  350. * Will be uncommented when the rate control find
  351. * for pktlog is implemented in the firmware.
  352. * Currently derived from the TX PPDU status
  353. */
  354. struct ath_pktlog_sw_event sw_event;
  355. uint32_t *pl_tgt_hdr;
  356. if (!pdev) {
  357. qdf_print("Invalid pdev in %s", __func__);
  358. return A_ERROR;
  359. }
  360. if (!data) {
  361. qdf_print("Invalid data in %s", __func__);
  362. return A_ERROR;
  363. }
  364. if (!pl_dev) {
  365. qdf_print("Invalid pl_dev in %s", __func__);
  366. return A_ERROR;
  367. }
  368. fw_data = (struct ol_fw_data *)data;
  369. len = fw_data->len;
  370. if (len < (sizeof(uint32_t) *
  371. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  372. len < (sizeof(uint32_t) *
  373. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  374. len < (sizeof(uint32_t) *
  375. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  376. len < (sizeof(uint32_t) *
  377. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  378. len < (sizeof(uint32_t) *
  379. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  380. len < (sizeof(uint32_t) *
  381. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  382. qdf_print("Invalid msdu len in %s", __func__);
  383. qdf_assert(0);
  384. return A_ERROR;
  385. }
  386. pl_tgt_hdr = (uint32_t *)fw_data->data;
  387. /*
  388. * Makes the short words (16 bits) portable b/w little endian
  389. * and big endian
  390. */
  391. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  392. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  393. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  394. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  395. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  396. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  397. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  398. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  399. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  400. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  401. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  402. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  403. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  404. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  405. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  406. pl_hdr.type_specific_data =
  407. *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
  408. pl_info = pl_dev->pl_info;
  409. log_size = pl_hdr.size;
  410. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  411. log_size, &pl_hdr);
  412. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  413. qdf_assert(0);
  414. return A_ERROR;
  415. }
  416. qdf_mem_copy(sw_event.sw_event,
  417. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  418. pl_hdr.size);
  419. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  420. return A_OK;
  421. }
  422. #else
  423. A_STATUS process_sw_event(void *pdev, void *data)
  424. {
  425. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  426. struct ath_pktlog_hdr pl_hdr;
  427. struct ath_pktlog_info *pl_info;
  428. size_t log_size;
  429. uint32_t len;
  430. struct ol_fw_data *fw_data;
  431. /*
  432. * Will be uncommented when the rate control find
  433. * for pktlog is implemented in the firmware.
  434. * Currently derived from the TX PPDU status
  435. */
  436. struct ath_pktlog_sw_event sw_event;
  437. uint32_t *pl_tgt_hdr;
  438. if (!pdev) {
  439. qdf_print("Invalid pdev in %s", __func__);
  440. return A_ERROR;
  441. }
  442. if (!data) {
  443. qdf_print("Invalid data in %s", __func__);
  444. return A_ERROR;
  445. }
  446. if (!pl_dev) {
  447. qdf_print("Invalid pl_dev in %s", __func__);
  448. return A_ERROR;
  449. }
  450. fw_data = (struct ol_fw_data *)data;
  451. len = fw_data->len;
  452. if (len < (sizeof(uint32_t) *
  453. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  454. len < (sizeof(uint32_t) *
  455. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  456. len < (sizeof(uint32_t) *
  457. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  458. len < (sizeof(uint32_t) *
  459. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  460. len < (sizeof(uint32_t) *
  461. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  462. qdf_print("Invalid msdu len in %s", __func__);
  463. qdf_assert(0);
  464. return A_ERROR;
  465. }
  466. pl_tgt_hdr = (uint32_t *)fw_data->data;
  467. /*
  468. * Makes the short words (16 bits) portable b/w little endian
  469. * and big endian
  470. */
  471. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  472. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  473. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  474. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  475. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  476. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  477. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  478. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  479. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  480. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  481. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  482. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  483. pktlog_hdr_set_specific_data(&pl_hdr,
  484. *(pl_tgt_hdr +
  485. ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET));
  486. pl_info = pl_dev->pl_info;
  487. log_size = pl_hdr.size;
  488. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  489. log_size, &pl_hdr);
  490. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  491. qdf_assert(0);
  492. return A_ERROR;
  493. }
  494. qdf_mem_copy(sw_event.sw_event,
  495. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  496. pl_hdr.size);
  497. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  498. return A_OK;
  499. }
  500. #endif
  501. #ifdef HELIUMPLUS
  502. A_STATUS process_rate_update(void *pdev, void *data)
  503. {
  504. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  505. struct ath_pktlog_hdr pl_hdr;
  506. size_t log_size;
  507. struct ath_pktlog_info *pl_info;
  508. struct ath_pktlog_rc_update rcu_log;
  509. uint32_t *pl_tgt_hdr;
  510. struct ol_fw_data *fw_data;
  511. uint32_t len;
  512. if (!pdev || !data || !pl_dev) {
  513. qdf_print("%s: Invalid handle", __func__);
  514. return A_ERROR;
  515. }
  516. fw_data = (struct ol_fw_data *)data;
  517. len = fw_data->len;
  518. if (len < (sizeof(uint32_t) *
  519. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  520. len < (sizeof(uint32_t) *
  521. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  522. len < (sizeof(uint32_t) *
  523. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  524. len < (sizeof(uint32_t) *
  525. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  526. len < (sizeof(uint32_t) *
  527. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  528. len < (sizeof(uint32_t) *
  529. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  530. qdf_print("Invalid msdu len in %s", __func__);
  531. qdf_assert(0);
  532. return A_ERROR;
  533. }
  534. pl_tgt_hdr = (uint32_t *)fw_data->data;
  535. /*
  536. * Makes the short words (16 bits) portable b/w little endian
  537. * and big endian
  538. */
  539. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  540. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  541. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  542. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  543. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  544. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  545. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  546. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  547. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  548. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  549. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  550. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  551. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  552. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  553. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  554. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  555. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  556. log_size = pl_hdr.size;
  557. pl_info = pl_dev->pl_info;
  558. /*
  559. * Will be uncommented when the rate control update
  560. * for pktlog is implemented in the firmware.
  561. * Currently derived from the TX PPDU status
  562. */
  563. rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
  564. log_size, &pl_hdr);
  565. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  566. qdf_assert(0);
  567. return A_ERROR;
  568. }
  569. qdf_mem_copy(rcu_log.txRateCtrl,
  570. ((char *)fw_data->data +
  571. sizeof(struct ath_pktlog_hdr)),
  572. pl_hdr.size);
  573. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
  574. return A_OK;
  575. }
  576. #else
  577. A_STATUS process_rate_update(void *pdev, void *data)
  578. {
  579. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  580. struct ath_pktlog_hdr pl_hdr;
  581. size_t log_size;
  582. struct ath_pktlog_info *pl_info;
  583. struct ath_pktlog_rc_update rcu_log;
  584. uint32_t *pl_tgt_hdr;
  585. struct ol_fw_data *fw_data;
  586. uint32_t len;
  587. if (!pdev || !data || !pl_dev) {
  588. qdf_print("%s: Invalid handle", __func__);
  589. return A_ERROR;
  590. }
  591. fw_data = (struct ol_fw_data *)data;
  592. len = fw_data->len;
  593. if (len < (sizeof(uint32_t) *
  594. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  595. len < (sizeof(uint32_t) *
  596. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  597. len < (sizeof(uint32_t) *
  598. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  599. len < (sizeof(uint32_t) *
  600. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  601. len < (sizeof(uint32_t) *
  602. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  603. qdf_print("Invalid msdu len in %s", __func__);
  604. qdf_assert(0);
  605. return A_ERROR;
  606. }
  607. pl_tgt_hdr = (uint32_t *)fw_data->data;
  608. /*
  609. * Makes the short words (16 bits) portable b/w little endian
  610. * and big endian
  611. */
  612. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  613. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  614. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  615. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  616. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  617. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  618. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  619. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  620. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  621. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  622. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  623. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  624. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  625. log_size = pl_hdr.size;
  626. pl_info = pl_dev->pl_info;
  627. /*
  628. * Will be uncommented when the rate control update
  629. * for pktlog is implemented in the firmware.
  630. * Currently derived from the TX PPDU status
  631. */
  632. rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
  633. log_size, &pl_hdr);
  634. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  635. qdf_assert(0);
  636. return A_ERROR;
  637. }
  638. qdf_mem_copy(rcu_log.txRateCtrl,
  639. ((char *)fw_data->data +
  640. sizeof(struct ath_pktlog_hdr)),
  641. pl_hdr.size);
  642. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
  643. return A_OK;
  644. }
  645. #endif
  646. #endif /*REMOVE_PKT_LOG */