pktlog_internal.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402
  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. #define TX_DESC_ID_LOW_MASK 0xffff
  43. #define TX_DESC_ID_LOW_SHIFT 0
  44. #define TX_DESC_ID_HIGH_MASK 0xffff0000
  45. #define TX_DESC_ID_HIGH_SHIFT 16
  46. #ifdef PKTLOG_HAS_SPECIFIC_DATA
  47. static inline void
  48. pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr,
  49. uint32_t type_specific_data)
  50. {
  51. log_hdr->type_specific_data = type_specific_data;
  52. }
  53. static inline uint32_t
  54. pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr)
  55. {
  56. return log_hdr->type_specific_data;
  57. }
  58. static inline void
  59. pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg,
  60. uint32_t type_specific_data)
  61. {
  62. plarg->type_specific_data = type_specific_data;
  63. }
  64. static inline uint32_t
  65. pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg)
  66. {
  67. return plarg->type_specific_data;
  68. }
  69. #else
  70. static inline void
  71. pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr,
  72. uint32_t type_specific_data)
  73. {
  74. }
  75. static inline uint32_t
  76. pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr)
  77. {
  78. return 0;
  79. }
  80. static inline void
  81. pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg,
  82. uint32_t type_specific_data)
  83. {
  84. }
  85. static inline uint32_t
  86. pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg)
  87. {
  88. return 0;
  89. }
  90. #endif
  91. void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
  92. {
  93. struct ath_pktlog_buf *log_buf;
  94. int32_t buf_size;
  95. struct ath_pktlog_hdr *log_hdr;
  96. int32_t cur_wr_offset;
  97. char *log_ptr;
  98. struct ath_pktlog_info *pl_info;
  99. uint16_t log_type;
  100. size_t log_size;
  101. uint32_t flags;
  102. #ifdef HELIUMPLUS
  103. uint8_t mac_id;
  104. #endif
  105. if (!plarg) {
  106. qdf_nofl_info("Invalid parg in %s", __func__);
  107. return;
  108. }
  109. pl_info = plarg->pl_info;
  110. #ifdef HELIUMPLUS
  111. mac_id = plarg->macId;
  112. log_type = plarg->log_type;
  113. #else
  114. log_type = plarg->log_type;
  115. #endif
  116. log_size = plarg->log_size;
  117. log_buf = pl_info->buf;
  118. flags = plarg->flags;
  119. if (!log_buf) {
  120. qdf_nofl_info("Invalid log_buf in %s", __func__);
  121. return;
  122. }
  123. buf_size = pl_info->buf_size;
  124. cur_wr_offset = log_buf->wr_offset;
  125. /* Move read offset to the next entry if there is a buffer overlap */
  126. if (log_buf->rd_offset >= 0) {
  127. if ((cur_wr_offset <= log_buf->rd_offset)
  128. && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) >
  129. log_buf->rd_offset) {
  130. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
  131. buf_size);
  132. }
  133. } else {
  134. log_buf->rd_offset = cur_wr_offset;
  135. }
  136. log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset);
  137. log_hdr->flags = flags;
  138. #ifdef HELIUMPLUS
  139. log_hdr->macId = mac_id;
  140. log_hdr->log_type = log_type;
  141. #else
  142. log_hdr->log_type = log_type;
  143. #endif
  144. log_hdr->size = (uint16_t) log_size;
  145. log_hdr->missed_cnt = plarg->missed_cnt;
  146. log_hdr->timestamp = plarg->timestamp;
  147. pktlog_hdr_set_specific_data(log_hdr,
  148. pktlog_arg_get_specific_data(plarg));
  149. cur_wr_offset += sizeof(*log_hdr);
  150. if ((buf_size - cur_wr_offset) < log_size) {
  151. while ((cur_wr_offset <= log_buf->rd_offset)
  152. && (log_buf->rd_offset < buf_size)) {
  153. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
  154. buf_size);
  155. }
  156. cur_wr_offset = 0;
  157. }
  158. while ((cur_wr_offset <= log_buf->rd_offset)
  159. && (cur_wr_offset + log_size) > log_buf->rd_offset) {
  160. PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, buf_size);
  161. }
  162. log_ptr = &(log_buf->log_data[cur_wr_offset]);
  163. cur_wr_offset += log_hdr->size;
  164. log_buf->wr_offset = ((buf_size - cur_wr_offset) >=
  165. sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset :
  166. 0;
  167. plarg->buf = log_ptr;
  168. }
  169. char *pktlog_getbuf(struct pktlog_dev_t *pl_dev,
  170. struct ath_pktlog_info *pl_info,
  171. size_t log_size, struct ath_pktlog_hdr *pl_hdr)
  172. {
  173. struct ath_pktlog_arg plarg = { 0, };
  174. uint8_t flags = 0;
  175. plarg.pl_info = pl_info;
  176. #ifdef HELIUMPLUS
  177. plarg.macId = pl_hdr->macId;
  178. plarg.log_type = pl_hdr->log_type;
  179. #else
  180. plarg.log_type = pl_hdr->log_type;
  181. #endif
  182. plarg.log_size = log_size;
  183. plarg.flags = pl_hdr->flags;
  184. plarg.missed_cnt = pl_hdr->missed_cnt;
  185. plarg.timestamp = pl_hdr->timestamp;
  186. pktlog_arg_set_specific_data(&plarg,
  187. pktlog_hdr_get_specific_data(pl_hdr));
  188. if (flags & PHFLAGS_INTERRUPT_CONTEXT) {
  189. /*
  190. * We are already in interrupt context, no need to make it
  191. * intsafe. call the function directly.
  192. */
  193. pktlog_getbuf_intsafe(&plarg);
  194. } else {
  195. PKTLOG_LOCK(pl_info);
  196. pktlog_getbuf_intsafe(&plarg);
  197. PKTLOG_UNLOCK(pl_info);
  198. }
  199. return plarg.buf;
  200. }
  201. static struct txctl_frm_hdr frm_hdr;
  202. #ifndef HELIUMPLUS
  203. static void process_ieee_hdr(void *data)
  204. {
  205. uint8_t dir;
  206. struct ieee80211_frame *wh = (struct ieee80211_frame *)(data);
  207. frm_hdr.framectrl = *(uint16_t *) (wh->i_fc);
  208. frm_hdr.seqctrl = *(uint16_t *) (wh->i_seq);
  209. dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK);
  210. if (dir == IEEE80211_FC1_DIR_TODS) {
  211. frm_hdr.bssid_tail =
  212. (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  213. i_addr1
  214. [QDF_MAC_ADDR_SIZE
  215. - 1]);
  216. frm_hdr.sa_tail =
  217. (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  218. i_addr2
  219. [QDF_MAC_ADDR_SIZE
  220. - 1]);
  221. frm_hdr.da_tail =
  222. (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  223. i_addr3
  224. [QDF_MAC_ADDR_SIZE
  225. - 1]);
  226. } else if (dir == IEEE80211_FC1_DIR_FROMDS) {
  227. frm_hdr.bssid_tail =
  228. (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  229. i_addr2
  230. [QDF_MAC_ADDR_SIZE
  231. - 1]);
  232. frm_hdr.sa_tail =
  233. (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  234. i_addr3
  235. [QDF_MAC_ADDR_SIZE
  236. - 1]);
  237. frm_hdr.da_tail =
  238. (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  239. i_addr1
  240. [QDF_MAC_ADDR_SIZE
  241. - 1]);
  242. } else {
  243. frm_hdr.bssid_tail =
  244. (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  245. i_addr3
  246. [QDF_MAC_ADDR_SIZE
  247. - 1]);
  248. frm_hdr.sa_tail =
  249. (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  250. i_addr2
  251. [QDF_MAC_ADDR_SIZE
  252. - 1]);
  253. frm_hdr.da_tail =
  254. (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
  255. i_addr1
  256. [QDF_MAC_ADDR_SIZE
  257. - 1]);
  258. }
  259. }
  260. /**
  261. * fill_ieee80211_hdr_data() - fill ieee802.11 data header
  262. * @txrx_pdev: txrx pdev
  263. * @pl_msdu_info: msdu info
  264. * @data: data received from event
  265. *
  266. * Return: none
  267. */
  268. /* TODO: Platform specific function */
  269. static void
  270. fill_ieee80211_hdr_data(struct cdp_pdev *pdev,
  271. struct ath_pktlog_msdu_info *pl_msdu_info, void *data)
  272. {
  273. uint32_t i;
  274. uint32_t *htt_tx_desc;
  275. struct ol_tx_desc_t *tx_desc;
  276. uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET;
  277. uint16_t tx_desc_id;
  278. uint32_t *msdu_id_info = (uint32_t *)
  279. ((void *)data + sizeof(struct ath_pktlog_hdr));
  280. uint32_t *msdu_id = (uint32_t *) ((char *)msdu_id_info +
  281. msdu_id_offset);
  282. uint8_t *addr, *vap_addr;
  283. uint8_t vdev_id;
  284. qdf_nbuf_t netbuf;
  285. uint32_t len;
  286. struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev;
  287. pl_msdu_info->num_msdu = *msdu_id_info;
  288. pl_msdu_info->priv_size = sizeof(uint32_t) *
  289. pl_msdu_info->num_msdu + sizeof(uint32_t);
  290. if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) {
  291. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  292. "%s: Invalid num_msdu count",
  293. __func__);
  294. qdf_assert(0);
  295. return;
  296. }
  297. for (i = 0; i < pl_msdu_info->num_msdu; i++) {
  298. /*
  299. * Handle big endianness
  300. * Increment msdu_id once after retrieving
  301. * lower 16 bits and uppper 16 bits
  302. */
  303. if (!(i % 2)) {
  304. tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK)
  305. >> TX_DESC_ID_LOW_SHIFT);
  306. } else {
  307. tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK)
  308. >> TX_DESC_ID_HIGH_SHIFT);
  309. msdu_id += 1;
  310. }
  311. if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) {
  312. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
  313. "%s: drop due to invalid msdu id = %x",
  314. __func__, tx_desc_id);
  315. return;
  316. }
  317. tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id);
  318. qdf_assert(tx_desc);
  319. netbuf = tx_desc->netbuf;
  320. htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc;
  321. qdf_assert(htt_tx_desc);
  322. qdf_nbuf_peek_header(netbuf, &addr, &len);
  323. if (len < (2 * QDF_MAC_ADDR_SIZE)) {
  324. qdf_print("TX frame does not have a valid address");
  325. return;
  326. }
  327. /* Adding header information for the TX data frames */
  328. vdev_id = (uint8_t) (*(htt_tx_desc +
  329. HTT_TX_VDEV_ID_WORD) >>
  330. HTT_TX_VDEV_ID_SHIFT) &
  331. HTT_TX_VDEV_ID_MASK;
  332. vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id);
  333. frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) |
  334. (addr[QDF_MAC_ADDR_SIZE - 1]);
  335. frm_hdr.sa_tail =
  336. (addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) |
  337. (addr[2 * QDF_MAC_ADDR_SIZE - 1]);
  338. if (vap_addr) {
  339. frm_hdr.bssid_tail =
  340. (vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) |
  341. (vap_addr[QDF_MAC_ADDR_SIZE - 1]);
  342. } else {
  343. frm_hdr.bssid_tail = 0x0000;
  344. }
  345. pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc +
  346. HTT_TX_MSDU_LEN_DWORD)
  347. & HTT_TX_MSDU_LEN_MASK;
  348. /*
  349. * Add more information per MSDU
  350. * e.g., protocol information
  351. */
  352. }
  353. }
  354. #endif
  355. #ifdef HELIUMPLUS
  356. A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
  357. {
  358. /*
  359. * Must include to process different types
  360. * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
  361. */
  362. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  363. struct ath_pktlog_hdr pl_hdr;
  364. struct ath_pktlog_info *pl_info;
  365. uint32_t *pl_tgt_hdr;
  366. struct ol_fw_data *fw_data;
  367. uint32_t len;
  368. if (!txrx_pdev) {
  369. qdf_nofl_info("Invalid pdev in %s", __func__);
  370. return A_ERROR;
  371. }
  372. if (!pl_dev) {
  373. qdf_nofl_err("Invalid pktlog handle in %s", __func__);
  374. qdf_assert(pl_dev);
  375. return A_ERROR;
  376. }
  377. qdf_assert(data);
  378. fw_data = (struct ol_fw_data *)data;
  379. len = fw_data->len;
  380. if (len < (sizeof(uint32_t) *
  381. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  382. len < (sizeof(uint32_t) *
  383. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  384. len < (sizeof(uint32_t) *
  385. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  386. len < (sizeof(uint32_t) *
  387. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  388. len < (sizeof(uint32_t) *
  389. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  390. len < (sizeof(uint32_t) *
  391. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  392. qdf_print("Invalid msdu len in %s", __func__);
  393. qdf_assert(0);
  394. return A_ERROR;
  395. }
  396. pl_tgt_hdr = (uint32_t *)fw_data->data;
  397. /*
  398. * Makes the short words (16 bits) portable b/w little endian
  399. * and big endian
  400. */
  401. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  402. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  403. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  404. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  405. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  406. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  407. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  408. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  409. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  410. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  411. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  412. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  413. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  414. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  415. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  416. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  417. pl_hdr.type_specific_data =
  418. *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
  419. pl_info = pl_dev->pl_info;
  420. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  421. qdf_assert(0);
  422. return A_ERROR;
  423. }
  424. if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) {
  425. size_t log_size = sizeof(frm_hdr) + pl_hdr.size;
  426. void *txdesc_hdr_ctl = (void *)
  427. pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
  428. qdf_assert(txdesc_hdr_ctl);
  429. qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t)));
  430. qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr));
  431. qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr),
  432. ((void *)fw_data->data +
  433. sizeof(struct ath_pktlog_hdr)),
  434. pl_hdr.size);
  435. pl_hdr.size = log_size;
  436. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  437. txdesc_hdr_ctl);
  438. }
  439. if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) {
  440. struct ath_pktlog_tx_status txstat_log;
  441. size_t log_size = pl_hdr.size;
  442. txstat_log.ds_status = (void *)
  443. pktlog_getbuf(pl_dev, pl_info,
  444. log_size, &pl_hdr);
  445. qdf_assert(txstat_log.ds_status);
  446. qdf_mem_copy(txstat_log.ds_status,
  447. ((void *)fw_data->data +
  448. sizeof(struct ath_pktlog_hdr)),
  449. pl_hdr.size);
  450. /* TODO: MCL specific API */
  451. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  452. txstat_log.ds_status);
  453. }
  454. return A_OK;
  455. }
  456. #else
  457. A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
  458. {
  459. /*
  460. * Must include to process different types
  461. * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
  462. */
  463. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  464. struct ath_pktlog_hdr pl_hdr;
  465. struct ath_pktlog_info *pl_info;
  466. uint32_t *pl_tgt_hdr;
  467. struct ol_fw_data *fw_data;
  468. uint32_t len;
  469. if (!txrx_pdev) {
  470. qdf_print("Invalid pdev in %s", __func__);
  471. return A_ERROR;
  472. }
  473. if (!pl_dev) {
  474. qdf_nofl_err("Invalid pktlog handle in %s", __func__);
  475. qdf_assert(pl_dev);
  476. return A_ERROR;
  477. }
  478. qdf_assert(data);
  479. fw_data = (struct ol_fw_data *)data;
  480. len = fw_data->len;
  481. if (len < (sizeof(uint32_t) *
  482. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  483. len < (sizeof(uint32_t) *
  484. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  485. len < (sizeof(uint32_t) *
  486. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  487. len < (sizeof(uint32_t) *
  488. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  489. len < (sizeof(uint32_t) *
  490. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  491. qdf_print("Invalid msdu len in %s", __func__);
  492. qdf_assert(0);
  493. return A_ERROR;
  494. }
  495. pl_tgt_hdr = (uint32_t *)fw_data->data;
  496. /*
  497. * Makes the short words (16 bits) portable b/w little endian
  498. * and big endian
  499. */
  500. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  501. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  502. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  503. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  504. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  505. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  506. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  507. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  508. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  509. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  510. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  511. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  512. pktlog_hdr_set_specific_data(&pl_hdr,
  513. *(pl_tgt_hdr +
  514. ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET));
  515. pl_info = pl_dev->pl_info;
  516. if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) {
  517. /* Valid only for the TX CTL */
  518. process_ieee_hdr(fw_data->data + sizeof(pl_hdr));
  519. }
  520. if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) {
  521. uint32_t desc_id = (uint32_t) *((uint32_t *)(fw_data->data +
  522. sizeof(pl_hdr)));
  523. uint32_t vdev_id = desc_id;
  524. /* if the pkt log msg is for the bcn frame the vdev id
  525. * is piggybacked in desc_id and the MSB of the desc ID
  526. * would be set to FF
  527. */
  528. #define BCN_DESC_ID 0xFF
  529. if ((desc_id >> 24) == BCN_DESC_ID) {
  530. void *data;
  531. uint32_t buf_size;
  532. vdev_id &= 0x00FFFFFF;
  533. /* TODO: MCL specific API */
  534. data = wma_get_beacon_buffer_by_vdev_id(vdev_id,
  535. &buf_size);
  536. if (data) {
  537. /* TODO: platform specific API */
  538. process_ieee_hdr(data);
  539. qdf_mem_free(data);
  540. }
  541. } else {
  542. /*
  543. * TODO: get the hdr content for mgmt frames from
  544. * Tx mgmt desc pool
  545. */
  546. }
  547. }
  548. if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) {
  549. struct ath_pktlog_txctl txctl_log;
  550. size_t log_size = sizeof(txctl_log.priv);
  551. txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev,
  552. pl_info,
  553. log_size,
  554. &pl_hdr);
  555. if (!txctl_log.txdesc_hdr_ctl) {
  556. qdf_nofl_info
  557. ("failed to get txctl_log.txdesc_hdr_ctl buf");
  558. return A_ERROR;
  559. }
  560. /*
  561. * frm hdr is currently Valid only for local frames
  562. * Add capability to include the fmr hdr for remote frames
  563. */
  564. txctl_log.priv.frm_hdr = frm_hdr;
  565. qdf_assert(txctl_log.priv.txdesc_ctl);
  566. qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl));
  567. pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl))
  568. ? sizeof(txctl_log.priv.txdesc_ctl) :
  569. pl_hdr.size;
  570. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  571. qdf_assert(0);
  572. return A_ERROR;
  573. }
  574. qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl,
  575. ((void *)fw_data->data +
  576. sizeof(struct ath_pktlog_hdr)),
  577. pl_hdr.size);
  578. qdf_assert(txctl_log.txdesc_hdr_ctl);
  579. qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv,
  580. sizeof(txctl_log.priv));
  581. pl_hdr.size = log_size;
  582. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  583. txctl_log.txdesc_hdr_ctl);
  584. /* Add Protocol information and HT specific information */
  585. }
  586. if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) {
  587. struct ath_pktlog_tx_status txstat_log;
  588. size_t log_size = pl_hdr.size;
  589. txstat_log.ds_status = (void *)
  590. pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
  591. qdf_assert(txstat_log.ds_status);
  592. qdf_mem_copy(txstat_log.ds_status,
  593. ((void *)fw_data->data +
  594. sizeof(struct ath_pktlog_hdr)),
  595. pl_hdr.size);
  596. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  597. txstat_log.ds_status);
  598. }
  599. if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) {
  600. struct ath_pktlog_msdu_info pl_msdu_info;
  601. size_t log_size;
  602. qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info));
  603. log_size = sizeof(pl_msdu_info.priv);
  604. if (pl_dev->mt_pktlog_enabled == false)
  605. fill_ieee80211_hdr_data(txrx_pdev,
  606. &pl_msdu_info, fw_data->data);
  607. pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info,
  608. log_size, &pl_hdr);
  609. qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info,
  610. ((void *)fw_data->data +
  611. sizeof(struct ath_pktlog_hdr)),
  612. sizeof(pl_msdu_info.priv.msdu_id_info));
  613. qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv,
  614. sizeof(pl_msdu_info.priv));
  615. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  616. pl_msdu_info.ath_msdu_info);
  617. }
  618. return A_OK;
  619. }
  620. #endif
  621. /* TODO: hardware dependent function */
  622. A_STATUS process_rx_info_remote(void *pdev, void *data)
  623. {
  624. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  625. struct ath_pktlog_info *pl_info;
  626. struct htt_host_rx_desc_base *rx_desc;
  627. struct ath_pktlog_hdr pl_hdr;
  628. struct ath_pktlog_rx_info rxstat_log;
  629. size_t log_size;
  630. struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data;
  631. qdf_nbuf_t msdu;
  632. if (!pdev || !r_data || !pl_dev) {
  633. qdf_print("%s: Invalid handle", __func__);
  634. return A_ERROR;
  635. }
  636. pl_info = pl_dev->pl_info;
  637. msdu = r_data->msdu;
  638. while (msdu) {
  639. rx_desc =
  640. (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1;
  641. log_size =
  642. sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base);
  643. /*
  644. * Construct the pktlog header pl_hdr
  645. * Because desc is DMA'd to the host memory
  646. */
  647. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  648. pl_hdr.missed_cnt = 0;
  649. #if defined(HELIUMPLUS)
  650. pl_hdr.macId = r_data->mac_id;
  651. pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
  652. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  653. #else
  654. pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
  655. #endif
  656. pl_hdr.size = sizeof(*rx_desc) -
  657. sizeof(struct htt_host_fw_desc_base);
  658. #if defined(HELIUMPLUS)
  659. pl_hdr.timestamp =
  660. rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
  661. pl_hdr.type_specific_data = 0xDEADAA;
  662. #else
  663. pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp;
  664. #endif /* !defined(HELIUMPLUS) */
  665. pktlog_hdr_set_specific_data(&pl_hdr, 0xDEADAA);
  666. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  667. log_size, &pl_hdr);
  668. qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc +
  669. sizeof(struct htt_host_fw_desc_base), pl_hdr.size);
  670. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  671. rxstat_log.rx_desc);
  672. msdu = qdf_nbuf_next(msdu);
  673. }
  674. return A_OK;
  675. }
  676. #ifdef HELIUMPLUS
  677. A_STATUS process_rx_info(void *pdev, void *data)
  678. {
  679. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  680. struct ath_pktlog_info *pl_info;
  681. struct ath_pktlog_rx_info rxstat_log;
  682. struct ath_pktlog_hdr pl_hdr;
  683. size_t log_size;
  684. uint32_t *pl_tgt_hdr;
  685. struct ol_fw_data *fw_data;
  686. uint32_t len;
  687. if (!pdev) {
  688. qdf_nofl_info("Invalid pdev in %s", __func__);
  689. return A_ERROR;
  690. }
  691. pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
  692. if (!pl_dev) {
  693. qdf_nofl_info("Invalid pl_dev in %s", __func__);
  694. return A_ERROR;
  695. }
  696. fw_data = (struct ol_fw_data *)data;
  697. len = fw_data->len;
  698. if (len < (sizeof(uint32_t) *
  699. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  700. len < (sizeof(uint32_t) *
  701. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  702. len < (sizeof(uint32_t) *
  703. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  704. len < (sizeof(uint32_t) *
  705. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  706. len < (sizeof(uint32_t) *
  707. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  708. len < (sizeof(uint32_t) *
  709. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  710. qdf_print("Invalid msdu len in %s", __func__);
  711. qdf_assert(0);
  712. return A_ERROR;
  713. }
  714. pl_info = pl_dev->pl_info;
  715. pl_tgt_hdr = (uint32_t *)fw_data->data;
  716. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  717. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  718. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  719. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  720. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  721. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  722. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  723. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  724. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  725. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  726. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  727. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  728. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  729. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  730. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  731. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  732. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  733. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  734. qdf_assert(0);
  735. return A_ERROR;
  736. }
  737. log_size = pl_hdr.size;
  738. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  739. log_size, &pl_hdr);
  740. qdf_mem_copy(rxstat_log.rx_desc,
  741. (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
  742. pl_hdr.size);
  743. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  744. return A_OK;
  745. }
  746. #else
  747. A_STATUS process_rx_info(void *pdev, void *data)
  748. {
  749. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  750. struct ath_pktlog_info *pl_info;
  751. struct ath_pktlog_rx_info rxstat_log;
  752. struct ath_pktlog_hdr pl_hdr;
  753. size_t log_size;
  754. uint32_t *pl_tgt_hdr;
  755. struct ol_fw_data *fw_data;
  756. uint32_t len;
  757. if (!pdev) {
  758. qdf_nofl_info("Invalid pdev in %s", __func__);
  759. return A_ERROR;
  760. }
  761. pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
  762. if (!pl_dev) {
  763. qdf_nofl_info("Invalid pl_dev in %s", __func__);
  764. return A_ERROR;
  765. }
  766. fw_data = (struct ol_fw_data *)data;
  767. len = fw_data->len;
  768. if (len < (sizeof(uint32_t) *
  769. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  770. len < (sizeof(uint32_t) *
  771. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  772. len < (sizeof(uint32_t) *
  773. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  774. len < (sizeof(uint32_t) *
  775. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  776. len < (sizeof(uint32_t) *
  777. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  778. qdf_print("Invalid msdu len in %s", __func__);
  779. qdf_assert(0);
  780. return A_ERROR;
  781. }
  782. pl_info = pl_dev->pl_info;
  783. pl_tgt_hdr = (uint32_t *)fw_data->data;
  784. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  785. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  786. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  787. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  788. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  789. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  790. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  791. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  792. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  793. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  794. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  795. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  796. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  797. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  798. qdf_assert(0);
  799. return A_ERROR;
  800. }
  801. log_size = pl_hdr.size;
  802. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  803. log_size, &pl_hdr);
  804. qdf_mem_copy(rxstat_log.rx_desc,
  805. (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
  806. pl_hdr.size);
  807. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  808. return A_OK;
  809. }
  810. #endif
  811. #ifdef HELIUMPLUS
  812. A_STATUS process_rate_find(void *pdev, void *data)
  813. {
  814. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  815. struct ath_pktlog_hdr pl_hdr;
  816. struct ath_pktlog_info *pl_info;
  817. size_t log_size;
  818. uint32_t len;
  819. struct ol_fw_data *fw_data;
  820. /*
  821. * Will be uncommented when the rate control find
  822. * for pktlog is implemented in the firmware.
  823. * Currently derived from the TX PPDU status
  824. */
  825. struct ath_pktlog_rc_find rcf_log;
  826. uint32_t *pl_tgt_hdr;
  827. if (!pdev || !data || !pl_dev) {
  828. qdf_print("%s: Invalid handle", __func__);
  829. return A_ERROR;
  830. }
  831. fw_data = (struct ol_fw_data *)data;
  832. len = fw_data->len;
  833. if (len < (sizeof(uint32_t) *
  834. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  835. len < (sizeof(uint32_t) *
  836. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  837. len < (sizeof(uint32_t) *
  838. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  839. len < (sizeof(uint32_t) *
  840. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  841. len < (sizeof(uint32_t) *
  842. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  843. len < (sizeof(uint32_t) *
  844. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  845. qdf_print("Invalid msdu len in %s", __func__);
  846. qdf_assert(0);
  847. return A_ERROR;
  848. }
  849. pl_tgt_hdr = (uint32_t *)fw_data->data;
  850. /*
  851. * Makes the short words (16 bits) portable b/w little endian
  852. * and big endian
  853. */
  854. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  855. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  856. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  857. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  858. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  859. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  860. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  861. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  862. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  863. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  864. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  865. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  866. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  867. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  868. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  869. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  870. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  871. pl_info = pl_dev->pl_info;
  872. log_size = pl_hdr.size;
  873. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  874. log_size, &pl_hdr);
  875. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  876. qdf_assert(0);
  877. return A_ERROR;
  878. }
  879. qdf_mem_copy(rcf_log.rcFind,
  880. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  881. pl_hdr.size);
  882. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  883. return A_OK;
  884. }
  885. #else
  886. A_STATUS process_rate_find(void *pdev, void *data)
  887. {
  888. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  889. struct ath_pktlog_hdr pl_hdr;
  890. struct ath_pktlog_info *pl_info;
  891. size_t log_size;
  892. uint32_t len;
  893. struct ol_fw_data *fw_data;
  894. /*
  895. * Will be uncommented when the rate control find
  896. * for pktlog is implemented in the firmware.
  897. * Currently derived from the TX PPDU status
  898. */
  899. struct ath_pktlog_rc_find rcf_log;
  900. uint32_t *pl_tgt_hdr;
  901. if (!pdev || !data || !pl_dev) {
  902. qdf_print("%s: Invalid handle", __func__);
  903. return A_ERROR;
  904. }
  905. fw_data = (struct ol_fw_data *)data;
  906. len = fw_data->len;
  907. if (len < (sizeof(uint32_t) *
  908. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  909. len < (sizeof(uint32_t) *
  910. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  911. len < (sizeof(uint32_t) *
  912. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  913. len < (sizeof(uint32_t) *
  914. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  915. len < (sizeof(uint32_t) *
  916. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  917. qdf_print("Invalid msdu len in %s", __func__);
  918. qdf_assert(0);
  919. return A_ERROR;
  920. }
  921. pl_tgt_hdr = (uint32_t *)fw_data->data;
  922. /*
  923. * Makes the short words (16 bits) portable b/w little endian
  924. * and big endian
  925. */
  926. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  927. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  928. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  929. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  930. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  931. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  932. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  933. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  934. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  935. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  936. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  937. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  938. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  939. pl_info = pl_dev->pl_info;
  940. log_size = pl_hdr.size;
  941. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  942. log_size, &pl_hdr);
  943. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  944. qdf_assert(0);
  945. return A_ERROR;
  946. }
  947. qdf_mem_copy(rcf_log.rcFind,
  948. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  949. pl_hdr.size);
  950. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  951. return A_OK;
  952. }
  953. #endif
  954. #ifdef HELIUMPLUS
  955. A_STATUS process_sw_event(void *pdev, void *data)
  956. {
  957. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  958. struct ath_pktlog_hdr pl_hdr;
  959. struct ath_pktlog_info *pl_info;
  960. size_t log_size;
  961. uint32_t len;
  962. struct ol_fw_data *fw_data;
  963. /*
  964. * Will be uncommented when the rate control find
  965. * for pktlog is implemented in the firmware.
  966. * Currently derived from the TX PPDU status
  967. */
  968. struct ath_pktlog_sw_event sw_event;
  969. uint32_t *pl_tgt_hdr;
  970. if (!pdev) {
  971. qdf_print("Invalid pdev in %s", __func__);
  972. return A_ERROR;
  973. }
  974. if (!data) {
  975. qdf_print("Invalid data in %s", __func__);
  976. return A_ERROR;
  977. }
  978. if (!pl_dev) {
  979. qdf_print("Invalid pl_dev in %s", __func__);
  980. return A_ERROR;
  981. }
  982. fw_data = (struct ol_fw_data *)data;
  983. len = fw_data->len;
  984. if (len < (sizeof(uint32_t) *
  985. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  986. len < (sizeof(uint32_t) *
  987. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  988. len < (sizeof(uint32_t) *
  989. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  990. len < (sizeof(uint32_t) *
  991. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  992. len < (sizeof(uint32_t) *
  993. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  994. len < (sizeof(uint32_t) *
  995. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  996. qdf_print("Invalid msdu len in %s", __func__);
  997. qdf_assert(0);
  998. return A_ERROR;
  999. }
  1000. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1001. /*
  1002. * Makes the short words (16 bits) portable b/w little endian
  1003. * and big endian
  1004. */
  1005. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1006. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1007. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1008. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1009. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1010. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1011. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1012. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1013. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1014. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  1015. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  1016. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  1017. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1018. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1019. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1020. pl_hdr.type_specific_data =
  1021. *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
  1022. pl_info = pl_dev->pl_info;
  1023. log_size = pl_hdr.size;
  1024. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  1025. log_size, &pl_hdr);
  1026. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1027. qdf_assert(0);
  1028. return A_ERROR;
  1029. }
  1030. qdf_mem_copy(sw_event.sw_event,
  1031. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  1032. pl_hdr.size);
  1033. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  1034. return A_OK;
  1035. }
  1036. #else
  1037. A_STATUS process_sw_event(void *pdev, void *data)
  1038. {
  1039. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1040. struct ath_pktlog_hdr pl_hdr;
  1041. struct ath_pktlog_info *pl_info;
  1042. size_t log_size;
  1043. uint32_t len;
  1044. struct ol_fw_data *fw_data;
  1045. /*
  1046. * Will be uncommented when the rate control find
  1047. * for pktlog is implemented in the firmware.
  1048. * Currently derived from the TX PPDU status
  1049. */
  1050. struct ath_pktlog_sw_event sw_event;
  1051. uint32_t *pl_tgt_hdr;
  1052. if (!pdev) {
  1053. qdf_print("Invalid pdev in %s", __func__);
  1054. return A_ERROR;
  1055. }
  1056. if (!data) {
  1057. qdf_print("Invalid data in %s", __func__);
  1058. return A_ERROR;
  1059. }
  1060. if (!pl_dev) {
  1061. qdf_print("Invalid pl_dev in %s", __func__);
  1062. return A_ERROR;
  1063. }
  1064. fw_data = (struct ol_fw_data *)data;
  1065. len = fw_data->len;
  1066. if (len < (sizeof(uint32_t) *
  1067. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1068. len < (sizeof(uint32_t) *
  1069. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1070. len < (sizeof(uint32_t) *
  1071. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1072. len < (sizeof(uint32_t) *
  1073. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1074. len < (sizeof(uint32_t) *
  1075. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1076. qdf_print("Invalid msdu len in %s", __func__);
  1077. qdf_assert(0);
  1078. return A_ERROR;
  1079. }
  1080. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1081. /*
  1082. * Makes the short words (16 bits) portable b/w little endian
  1083. * and big endian
  1084. */
  1085. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1086. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1087. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1088. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1089. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1090. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1091. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1092. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1093. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1094. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1095. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1096. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1097. pktlog_hdr_set_specific_data(&pl_hdr,
  1098. *(pl_tgt_hdr +
  1099. ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET));
  1100. pl_info = pl_dev->pl_info;
  1101. log_size = pl_hdr.size;
  1102. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  1103. log_size, &pl_hdr);
  1104. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1105. qdf_assert(0);
  1106. return A_ERROR;
  1107. }
  1108. qdf_mem_copy(sw_event.sw_event,
  1109. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  1110. pl_hdr.size);
  1111. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  1112. return A_OK;
  1113. }
  1114. #endif
  1115. #ifdef HELIUMPLUS
  1116. A_STATUS process_rate_update(void *pdev, void *data)
  1117. {
  1118. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1119. struct ath_pktlog_hdr pl_hdr;
  1120. size_t log_size;
  1121. struct ath_pktlog_info *pl_info;
  1122. struct ath_pktlog_rc_update rcu_log;
  1123. uint32_t *pl_tgt_hdr;
  1124. struct ol_fw_data *fw_data;
  1125. uint32_t len;
  1126. if (!pdev || !data || !pl_dev) {
  1127. qdf_print("%s: Invalid handle", __func__);
  1128. return A_ERROR;
  1129. }
  1130. fw_data = (struct ol_fw_data *)data;
  1131. len = fw_data->len;
  1132. if (len < (sizeof(uint32_t) *
  1133. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1134. len < (sizeof(uint32_t) *
  1135. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1136. len < (sizeof(uint32_t) *
  1137. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1138. len < (sizeof(uint32_t) *
  1139. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  1140. len < (sizeof(uint32_t) *
  1141. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1142. len < (sizeof(uint32_t) *
  1143. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1144. qdf_print("Invalid msdu len in %s", __func__);
  1145. qdf_assert(0);
  1146. return A_ERROR;
  1147. }
  1148. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1149. /*
  1150. * Makes the short words (16 bits) portable b/w little endian
  1151. * and big endian
  1152. */
  1153. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1154. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1155. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1156. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1157. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1158. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1159. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1160. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1161. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1162. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1163. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  1164. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  1165. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  1166. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  1167. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1168. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1169. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1170. log_size = pl_hdr.size;
  1171. pl_info = pl_dev->pl_info;
  1172. /*
  1173. * Will be uncommented when the rate control update
  1174. * for pktlog is implemented in the firmware.
  1175. * Currently derived from the TX PPDU status
  1176. */
  1177. rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
  1178. log_size, &pl_hdr);
  1179. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1180. qdf_assert(0);
  1181. return A_ERROR;
  1182. }
  1183. qdf_mem_copy(rcu_log.txRateCtrl,
  1184. ((char *)fw_data->data +
  1185. sizeof(struct ath_pktlog_hdr)),
  1186. pl_hdr.size);
  1187. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
  1188. return A_OK;
  1189. }
  1190. #else
  1191. A_STATUS process_rate_update(void *pdev, void *data)
  1192. {
  1193. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1194. struct ath_pktlog_hdr pl_hdr;
  1195. size_t log_size;
  1196. struct ath_pktlog_info *pl_info;
  1197. struct ath_pktlog_rc_update rcu_log;
  1198. uint32_t *pl_tgt_hdr;
  1199. struct ol_fw_data *fw_data;
  1200. uint32_t len;
  1201. if (!pdev || !data || !pl_dev) {
  1202. qdf_print("%s: Invalid handle", __func__);
  1203. return A_ERROR;
  1204. }
  1205. fw_data = (struct ol_fw_data *)data;
  1206. len = fw_data->len;
  1207. if (len < (sizeof(uint32_t) *
  1208. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1209. len < (sizeof(uint32_t) *
  1210. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1211. len < (sizeof(uint32_t) *
  1212. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1213. len < (sizeof(uint32_t) *
  1214. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1215. len < (sizeof(uint32_t) *
  1216. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1217. qdf_print("Invalid msdu len in %s", __func__);
  1218. qdf_assert(0);
  1219. return A_ERROR;
  1220. }
  1221. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1222. /*
  1223. * Makes the short words (16 bits) portable b/w little endian
  1224. * and big endian
  1225. */
  1226. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1227. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1228. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1229. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1230. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1231. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1232. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1233. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1234. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1235. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1236. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1237. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1238. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1239. log_size = pl_hdr.size;
  1240. pl_info = pl_dev->pl_info;
  1241. /*
  1242. * Will be uncommented when the rate control update
  1243. * for pktlog is implemented in the firmware.
  1244. * Currently derived from the TX PPDU status
  1245. */
  1246. rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
  1247. log_size, &pl_hdr);
  1248. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1249. qdf_assert(0);
  1250. return A_ERROR;
  1251. }
  1252. qdf_mem_copy(rcu_log.txRateCtrl,
  1253. ((char *)fw_data->data +
  1254. sizeof(struct ath_pktlog_hdr)),
  1255. pl_hdr.size);
  1256. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
  1257. return A_OK;
  1258. }
  1259. #endif
  1260. #endif /*REMOVE_PKT_LOG */