pktlog_internal.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. /*
  2. * Copyright (c) 2013-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. /*
  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. printk("Invalid parg in %s\n", __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. printk("Invalid log_buf in %s\n", __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. printk("Invalid pdev in %s\n", __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. printk
  557. ("failed to get buf for txctl_log.txdesc_hdr_ctl\n");
  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. /**
  622. * process_offload_pktlog() - Process full pktlog events
  623. * pdev: abstract pdev handle
  624. * data: pktlog buffer
  625. *
  626. * Return: zero on success, non-zero on failure
  627. */
  628. A_STATUS
  629. process_offload_pktlog(struct cdp_pdev *pdev, void *data)
  630. {
  631. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  632. struct ath_pktlog_info *pl_info;
  633. struct ath_pktlog_hdr pl_hdr;
  634. uint32_t *pl_tgt_hdr;
  635. void *txdesc_hdr_ctl = NULL;
  636. size_t log_size = 0;
  637. size_t tmp_log_size = 0;
  638. if (!pl_dev) {
  639. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  640. "Invalid context in %s\n", __func__);
  641. return A_ERROR;
  642. }
  643. if (!data) {
  644. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  645. "Invalid data in %s\n", __func__);
  646. return A_ERROR;
  647. }
  648. pl_tgt_hdr = (uint32_t *)data;
  649. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  650. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  651. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  652. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  653. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  654. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  655. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  656. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  657. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  658. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  659. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  660. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  661. pktlog_hdr_set_specific_data(&pl_hdr,
  662. *(pl_tgt_hdr +
  663. ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET));
  664. if (pl_hdr.size > MAX_PKTLOG_RECV_BUF_SIZE) {
  665. pl_dev->invalid_packets++;
  666. return A_ERROR;
  667. }
  668. /*
  669. * Must include to process different types
  670. * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
  671. */
  672. pl_info = pl_dev->pl_info;
  673. tmp_log_size = sizeof(frm_hdr) + pl_hdr.size;
  674. log_size = pl_hdr.size;
  675. txdesc_hdr_ctl =
  676. (void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
  677. if (!txdesc_hdr_ctl) {
  678. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  679. "Failed to allocate pktlog descriptor");
  680. return A_NO_MEMORY;
  681. }
  682. qdf_assert(txdesc_hdr_ctl);
  683. qdf_assert(pl_hdr->size < PKTLOG_MAX_TX_WORDS * sizeof(u_int32_t));
  684. qdf_mem_copy(txdesc_hdr_ctl,
  685. ((void *)data + sizeof(struct ath_pktlog_hdr)),
  686. pl_hdr.size);
  687. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, txdesc_hdr_ctl);
  688. return A_OK;
  689. }
  690. /* TODO: hardware dependent function */
  691. A_STATUS process_rx_info_remote(void *pdev, void *data)
  692. {
  693. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  694. struct ath_pktlog_info *pl_info;
  695. struct htt_host_rx_desc_base *rx_desc;
  696. struct ath_pktlog_hdr pl_hdr;
  697. struct ath_pktlog_rx_info rxstat_log;
  698. size_t log_size;
  699. struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data;
  700. qdf_nbuf_t msdu;
  701. if (!pdev || !r_data || !pl_dev) {
  702. qdf_print("%s: Invalid handle", __func__);
  703. return A_ERROR;
  704. }
  705. pl_info = pl_dev->pl_info;
  706. msdu = r_data->msdu;
  707. while (msdu) {
  708. rx_desc =
  709. (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1;
  710. log_size =
  711. sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base);
  712. /*
  713. * Construct the pktlog header pl_hdr
  714. * Because desc is DMA'd to the host memory
  715. */
  716. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  717. pl_hdr.missed_cnt = 0;
  718. #if defined(HELIUMPLUS)
  719. pl_hdr.macId = r_data->mac_id;
  720. pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
  721. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  722. #else
  723. pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
  724. #endif
  725. pl_hdr.size = sizeof(*rx_desc) -
  726. sizeof(struct htt_host_fw_desc_base);
  727. #if defined(HELIUMPLUS)
  728. pl_hdr.timestamp =
  729. rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
  730. pl_hdr.type_specific_data = 0xDEADAA;
  731. #else
  732. pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp;
  733. #endif /* !defined(HELIUMPLUS) */
  734. pktlog_hdr_set_specific_data(&pl_hdr, 0xDEADAA);
  735. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  736. log_size, &pl_hdr);
  737. qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc +
  738. sizeof(struct htt_host_fw_desc_base), pl_hdr.size);
  739. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  740. rxstat_log.rx_desc);
  741. msdu = qdf_nbuf_next(msdu);
  742. }
  743. return A_OK;
  744. }
  745. #ifdef HELIUMPLUS
  746. A_STATUS process_rx_info(void *pdev, void *data)
  747. {
  748. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  749. struct ath_pktlog_info *pl_info;
  750. struct ath_pktlog_rx_info rxstat_log;
  751. struct ath_pktlog_hdr pl_hdr;
  752. size_t log_size;
  753. uint32_t *pl_tgt_hdr;
  754. struct ol_fw_data *fw_data;
  755. uint32_t len;
  756. if (!pdev) {
  757. printk("Invalid pdev in %s", __func__);
  758. return A_ERROR;
  759. }
  760. pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
  761. if (!pl_dev) {
  762. printk("Invalid pl_dev in %s", __func__);
  763. return A_ERROR;
  764. }
  765. fw_data = (struct ol_fw_data *)data;
  766. len = fw_data->len;
  767. if (len < (sizeof(uint32_t) *
  768. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  769. len < (sizeof(uint32_t) *
  770. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  771. len < (sizeof(uint32_t) *
  772. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  773. len < (sizeof(uint32_t) *
  774. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  775. len < (sizeof(uint32_t) *
  776. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  777. len < (sizeof(uint32_t) *
  778. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  779. qdf_print("Invalid msdu len in %s", __func__);
  780. qdf_assert(0);
  781. return A_ERROR;
  782. }
  783. pl_info = pl_dev->pl_info;
  784. pl_tgt_hdr = (uint32_t *)fw_data->data;
  785. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  786. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  787. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  788. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  789. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  790. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  791. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  792. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  793. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  794. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  795. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  796. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  797. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  798. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  799. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  800. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  801. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  802. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  803. qdf_assert(0);
  804. return A_ERROR;
  805. }
  806. log_size = pl_hdr.size;
  807. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  808. log_size, &pl_hdr);
  809. qdf_mem_copy(rxstat_log.rx_desc,
  810. (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
  811. pl_hdr.size);
  812. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  813. return A_OK;
  814. }
  815. #else
  816. A_STATUS process_rx_info(void *pdev, void *data)
  817. {
  818. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  819. struct ath_pktlog_info *pl_info;
  820. struct ath_pktlog_rx_info rxstat_log;
  821. struct ath_pktlog_hdr pl_hdr;
  822. size_t log_size;
  823. uint32_t *pl_tgt_hdr;
  824. struct ol_fw_data *fw_data;
  825. uint32_t len;
  826. if (!pdev) {
  827. printk("Invalid pdev in %s", __func__);
  828. return A_ERROR;
  829. }
  830. pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
  831. if (!pl_dev) {
  832. printk("Invalid pl_dev in %s", __func__);
  833. return A_ERROR;
  834. }
  835. fw_data = (struct ol_fw_data *)data;
  836. len = fw_data->len;
  837. if (len < (sizeof(uint32_t) *
  838. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  839. len < (sizeof(uint32_t) *
  840. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  841. len < (sizeof(uint32_t) *
  842. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  843. len < (sizeof(uint32_t) *
  844. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  845. len < (sizeof(uint32_t) *
  846. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  847. qdf_print("Invalid msdu len in %s", __func__);
  848. qdf_assert(0);
  849. return A_ERROR;
  850. }
  851. pl_info = pl_dev->pl_info;
  852. pl_tgt_hdr = (uint32_t *)fw_data->data;
  853. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  854. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  855. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  856. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  857. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  858. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  859. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  860. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  861. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  862. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  863. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  864. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  865. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  866. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  867. qdf_assert(0);
  868. return A_ERROR;
  869. }
  870. log_size = pl_hdr.size;
  871. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  872. log_size, &pl_hdr);
  873. qdf_mem_copy(rxstat_log.rx_desc,
  874. (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
  875. pl_hdr.size);
  876. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  877. return A_OK;
  878. }
  879. #endif
  880. #ifdef HELIUMPLUS
  881. A_STATUS process_rate_find(void *pdev, void *data)
  882. {
  883. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  884. struct ath_pktlog_hdr pl_hdr;
  885. struct ath_pktlog_info *pl_info;
  886. size_t log_size;
  887. uint32_t len;
  888. struct ol_fw_data *fw_data;
  889. /*
  890. * Will be uncommented when the rate control find
  891. * for pktlog is implemented in the firmware.
  892. * Currently derived from the TX PPDU status
  893. */
  894. struct ath_pktlog_rc_find rcf_log;
  895. uint32_t *pl_tgt_hdr;
  896. if (!pdev || !data || !pl_dev) {
  897. qdf_print("%s: Invalid handle", __func__);
  898. return A_ERROR;
  899. }
  900. fw_data = (struct ol_fw_data *)data;
  901. len = fw_data->len;
  902. if (len < (sizeof(uint32_t) *
  903. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  904. len < (sizeof(uint32_t) *
  905. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  906. len < (sizeof(uint32_t) *
  907. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  908. len < (sizeof(uint32_t) *
  909. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  910. len < (sizeof(uint32_t) *
  911. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  912. len < (sizeof(uint32_t) *
  913. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  914. qdf_print("Invalid msdu len in %s", __func__);
  915. qdf_assert(0);
  916. return A_ERROR;
  917. }
  918. pl_tgt_hdr = (uint32_t *)fw_data->data;
  919. /*
  920. * Makes the short words (16 bits) portable b/w little endian
  921. * and big endian
  922. */
  923. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  924. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  925. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  926. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  927. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  928. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  929. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  930. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  931. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  932. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  933. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  934. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  935. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  936. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  937. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  938. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  939. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  940. pl_info = pl_dev->pl_info;
  941. log_size = pl_hdr.size;
  942. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  943. log_size, &pl_hdr);
  944. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  945. qdf_assert(0);
  946. return A_ERROR;
  947. }
  948. qdf_mem_copy(rcf_log.rcFind,
  949. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  950. pl_hdr.size);
  951. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  952. return A_OK;
  953. }
  954. #else
  955. A_STATUS process_rate_find(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_rc_find rcf_log;
  969. uint32_t *pl_tgt_hdr;
  970. if (!pdev || !data || !pl_dev) {
  971. qdf_print("%s: Invalid handle", __func__);
  972. return A_ERROR;
  973. }
  974. fw_data = (struct ol_fw_data *)data;
  975. len = fw_data->len;
  976. if (len < (sizeof(uint32_t) *
  977. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  978. len < (sizeof(uint32_t) *
  979. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  980. len < (sizeof(uint32_t) *
  981. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  982. len < (sizeof(uint32_t) *
  983. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  984. len < (sizeof(uint32_t) *
  985. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  986. qdf_print("Invalid msdu len in %s", __func__);
  987. qdf_assert(0);
  988. return A_ERROR;
  989. }
  990. pl_tgt_hdr = (uint32_t *)fw_data->data;
  991. /*
  992. * Makes the short words (16 bits) portable b/w little endian
  993. * and big endian
  994. */
  995. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  996. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  997. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  998. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  999. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1000. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1001. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1002. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1003. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1004. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1005. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1006. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1007. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1008. pl_info = pl_dev->pl_info;
  1009. log_size = pl_hdr.size;
  1010. rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
  1011. log_size, &pl_hdr);
  1012. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1013. qdf_assert(0);
  1014. return A_ERROR;
  1015. }
  1016. qdf_mem_copy(rcf_log.rcFind,
  1017. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  1018. pl_hdr.size);
  1019. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
  1020. return A_OK;
  1021. }
  1022. #endif
  1023. #ifdef HELIUMPLUS
  1024. A_STATUS process_sw_event(void *pdev, void *data)
  1025. {
  1026. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1027. struct ath_pktlog_hdr pl_hdr;
  1028. struct ath_pktlog_info *pl_info;
  1029. size_t log_size;
  1030. uint32_t len;
  1031. struct ol_fw_data *fw_data;
  1032. /*
  1033. * Will be uncommented when the rate control find
  1034. * for pktlog is implemented in the firmware.
  1035. * Currently derived from the TX PPDU status
  1036. */
  1037. struct ath_pktlog_sw_event sw_event;
  1038. uint32_t *pl_tgt_hdr;
  1039. if (!pdev) {
  1040. qdf_print("Invalid pdev in %s", __func__);
  1041. return A_ERROR;
  1042. }
  1043. if (!data) {
  1044. qdf_print("Invalid data in %s", __func__);
  1045. return A_ERROR;
  1046. }
  1047. if (!pl_dev) {
  1048. qdf_print("Invalid pl_dev in %s", __func__);
  1049. return A_ERROR;
  1050. }
  1051. fw_data = (struct ol_fw_data *)data;
  1052. len = fw_data->len;
  1053. if (len < (sizeof(uint32_t) *
  1054. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1055. len < (sizeof(uint32_t) *
  1056. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1057. len < (sizeof(uint32_t) *
  1058. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1059. len < (sizeof(uint32_t) *
  1060. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  1061. len < (sizeof(uint32_t) *
  1062. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1063. len < (sizeof(uint32_t) *
  1064. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1065. qdf_print("Invalid msdu len in %s", __func__);
  1066. qdf_assert(0);
  1067. return A_ERROR;
  1068. }
  1069. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1070. /*
  1071. * Makes the short words (16 bits) portable b/w little endian
  1072. * and big endian
  1073. */
  1074. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1075. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1076. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1077. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1078. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1079. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1080. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1081. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1082. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1083. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  1084. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  1085. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  1086. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1087. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1088. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1089. pl_hdr.type_specific_data =
  1090. *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
  1091. pl_info = pl_dev->pl_info;
  1092. log_size = pl_hdr.size;
  1093. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  1094. log_size, &pl_hdr);
  1095. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1096. qdf_assert(0);
  1097. return A_ERROR;
  1098. }
  1099. qdf_mem_copy(sw_event.sw_event,
  1100. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  1101. pl_hdr.size);
  1102. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  1103. return A_OK;
  1104. }
  1105. #else
  1106. A_STATUS process_sw_event(void *pdev, void *data)
  1107. {
  1108. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1109. struct ath_pktlog_hdr pl_hdr;
  1110. struct ath_pktlog_info *pl_info;
  1111. size_t log_size;
  1112. uint32_t len;
  1113. struct ol_fw_data *fw_data;
  1114. /*
  1115. * Will be uncommented when the rate control find
  1116. * for pktlog is implemented in the firmware.
  1117. * Currently derived from the TX PPDU status
  1118. */
  1119. struct ath_pktlog_sw_event sw_event;
  1120. uint32_t *pl_tgt_hdr;
  1121. if (!pdev) {
  1122. qdf_print("Invalid pdev in %s", __func__);
  1123. return A_ERROR;
  1124. }
  1125. if (!data) {
  1126. qdf_print("Invalid data in %s", __func__);
  1127. return A_ERROR;
  1128. }
  1129. if (!pl_dev) {
  1130. qdf_print("Invalid pl_dev in %s", __func__);
  1131. return A_ERROR;
  1132. }
  1133. fw_data = (struct ol_fw_data *)data;
  1134. len = fw_data->len;
  1135. if (len < (sizeof(uint32_t) *
  1136. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1137. len < (sizeof(uint32_t) *
  1138. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1139. len < (sizeof(uint32_t) *
  1140. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1141. len < (sizeof(uint32_t) *
  1142. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1143. len < (sizeof(uint32_t) *
  1144. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1145. qdf_print("Invalid msdu len in %s", __func__);
  1146. qdf_assert(0);
  1147. return A_ERROR;
  1148. }
  1149. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1150. /*
  1151. * Makes the short words (16 bits) portable b/w little endian
  1152. * and big endian
  1153. */
  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.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1164. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1165. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1166. pktlog_hdr_set_specific_data(&pl_hdr,
  1167. *(pl_tgt_hdr +
  1168. ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET));
  1169. pl_info = pl_dev->pl_info;
  1170. log_size = pl_hdr.size;
  1171. sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
  1172. log_size, &pl_hdr);
  1173. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1174. qdf_assert(0);
  1175. return A_ERROR;
  1176. }
  1177. qdf_mem_copy(sw_event.sw_event,
  1178. ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
  1179. pl_hdr.size);
  1180. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
  1181. return A_OK;
  1182. }
  1183. #endif
  1184. #ifdef HELIUMPLUS
  1185. A_STATUS process_rate_update(void *pdev, void *data)
  1186. {
  1187. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1188. struct ath_pktlog_hdr pl_hdr;
  1189. size_t log_size;
  1190. struct ath_pktlog_info *pl_info;
  1191. struct ath_pktlog_rc_update rcu_log;
  1192. uint32_t *pl_tgt_hdr;
  1193. struct ol_fw_data *fw_data;
  1194. uint32_t len;
  1195. if (!pdev || !data || !pl_dev) {
  1196. qdf_print("%s: Invalid handle", __func__);
  1197. return A_ERROR;
  1198. }
  1199. fw_data = (struct ol_fw_data *)data;
  1200. len = fw_data->len;
  1201. if (len < (sizeof(uint32_t) *
  1202. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1203. len < (sizeof(uint32_t) *
  1204. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1205. len < (sizeof(uint32_t) *
  1206. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1207. len < (sizeof(uint32_t) *
  1208. (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
  1209. len < (sizeof(uint32_t) *
  1210. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1211. len < (sizeof(uint32_t) *
  1212. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1213. qdf_print("Invalid msdu len in %s", __func__);
  1214. qdf_assert(0);
  1215. return A_ERROR;
  1216. }
  1217. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1218. /*
  1219. * Makes the short words (16 bits) portable b/w little endian
  1220. * and big endian
  1221. */
  1222. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1223. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1224. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1225. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1226. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1227. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1228. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1229. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1230. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1231. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1232. pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
  1233. ATH_PKTLOG_HDR_MAC_ID_MASK) >>
  1234. ATH_PKTLOG_HDR_MAC_ID_SHIFT;
  1235. pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
  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. #else
  1260. A_STATUS process_rate_update(void *pdev, void *data)
  1261. {
  1262. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1263. struct ath_pktlog_hdr pl_hdr;
  1264. size_t log_size;
  1265. struct ath_pktlog_info *pl_info;
  1266. struct ath_pktlog_rc_update rcu_log;
  1267. uint32_t *pl_tgt_hdr;
  1268. struct ol_fw_data *fw_data;
  1269. uint32_t len;
  1270. if (!pdev || !data || !pl_dev) {
  1271. qdf_print("%s: Invalid handle", __func__);
  1272. return A_ERROR;
  1273. }
  1274. fw_data = (struct ol_fw_data *)data;
  1275. len = fw_data->len;
  1276. if (len < (sizeof(uint32_t) *
  1277. (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
  1278. len < (sizeof(uint32_t) *
  1279. (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
  1280. len < (sizeof(uint32_t) *
  1281. (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
  1282. len < (sizeof(uint32_t) *
  1283. (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
  1284. len < (sizeof(uint32_t) *
  1285. (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
  1286. qdf_print("Invalid msdu len in %s", __func__);
  1287. qdf_assert(0);
  1288. return A_ERROR;
  1289. }
  1290. pl_tgt_hdr = (uint32_t *)fw_data->data;
  1291. /*
  1292. * Makes the short words (16 bits) portable b/w little endian
  1293. * and big endian
  1294. */
  1295. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1296. pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
  1297. ATH_PKTLOG_HDR_FLAGS_MASK) >>
  1298. ATH_PKTLOG_HDR_FLAGS_SHIFT;
  1299. pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
  1300. ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
  1301. ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
  1302. pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
  1303. ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
  1304. ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
  1305. pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
  1306. ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
  1307. pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
  1308. log_size = pl_hdr.size;
  1309. pl_info = pl_dev->pl_info;
  1310. /*
  1311. * Will be uncommented when the rate control update
  1312. * for pktlog is implemented in the firmware.
  1313. * Currently derived from the TX PPDU status
  1314. */
  1315. rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
  1316. log_size, &pl_hdr);
  1317. if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
  1318. qdf_assert(0);
  1319. return A_ERROR;
  1320. }
  1321. qdf_mem_copy(rcu_log.txRateCtrl,
  1322. ((char *)fw_data->data +
  1323. sizeof(struct ath_pktlog_hdr)),
  1324. pl_hdr.size);
  1325. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
  1326. return A_OK;
  1327. }
  1328. #endif
  1329. #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
  1330. defined(QCA_WIFI_QCA6490)
  1331. int process_rx_desc_remote(void *pdev, void *data)
  1332. {
  1333. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1334. struct ath_pktlog_hdr pl_hdr;
  1335. struct ath_pktlog_rx_info rxstat_log;
  1336. size_t log_size;
  1337. struct ath_pktlog_info *pl_info;
  1338. qdf_nbuf_t log_nbuf = (qdf_nbuf_t)data;
  1339. if (!pl_dev) {
  1340. qdf_err("Pktlog handle is NULL");
  1341. return -EINVAL;
  1342. }
  1343. pl_info = pl_dev->pl_info;
  1344. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1345. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  1346. pl_hdr.missed_cnt = 0;
  1347. pl_hdr.log_type = PKTLOG_TYPE_RX_STATBUF;
  1348. pl_hdr.size = qdf_nbuf_len(log_nbuf);
  1349. pl_hdr.timestamp = 0;
  1350. log_size = pl_hdr.size;
  1351. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  1352. log_size, &pl_hdr);
  1353. if (!rxstat_log.rx_desc) {
  1354. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  1355. "%s: Rx descriptor is NULL", __func__);
  1356. return -EINVAL;
  1357. }
  1358. qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
  1359. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  1360. rxstat_log.rx_desc);
  1361. return 0;
  1362. }
  1363. int
  1364. process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
  1365. {
  1366. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1367. struct ath_pktlog_info *pl_info;
  1368. struct ath_pktlog_hdr pl_hdr;
  1369. struct ath_pktlog_rx_info rxstat_log;
  1370. size_t log_size;
  1371. qdf_nbuf_t log_nbuf = (qdf_nbuf_t)log_data;
  1372. if (!pl_dev) {
  1373. qdf_err("Pktlog handle is NULL");
  1374. return -EINVAL;
  1375. }
  1376. pl_info = pl_dev->pl_info;
  1377. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1378. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  1379. pl_hdr.missed_cnt = 0;
  1380. pl_hdr.log_type = log_type;
  1381. pl_hdr.size = qdf_nbuf_len(log_nbuf);
  1382. pl_hdr.timestamp = 0;
  1383. log_size = pl_hdr.size;
  1384. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  1385. log_size, &pl_hdr);
  1386. if (!rxstat_log.rx_desc) {
  1387. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  1388. "%s: Rx descriptor is NULL", __func__);
  1389. return -EINVAL;
  1390. }
  1391. qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
  1392. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  1393. return 0;
  1394. }
  1395. #else
  1396. int process_rx_desc_remote(void *pdev, void *data)
  1397. {
  1398. return 0;
  1399. }
  1400. int
  1401. process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
  1402. {
  1403. return 0;
  1404. }
  1405. #endif
  1406. #endif /*REMOVE_PKT_LOG */