pktlog_internal.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565
  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. int process_rx_desc_remote(void *pdev, void *data)
  1331. {
  1332. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1333. struct ath_pktlog_hdr pl_hdr;
  1334. struct ath_pktlog_rx_info rxstat_log;
  1335. size_t log_size;
  1336. struct ath_pktlog_info *pl_info;
  1337. qdf_nbuf_t log_nbuf = (qdf_nbuf_t)data;
  1338. if (!pl_dev) {
  1339. qdf_err("Pktlog handle is NULL");
  1340. return -EINVAL;
  1341. }
  1342. pl_info = pl_dev->pl_info;
  1343. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1344. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  1345. pl_hdr.missed_cnt = 0;
  1346. pl_hdr.log_type = PKTLOG_TYPE_RX_STATBUF;
  1347. pl_hdr.size = qdf_nbuf_len(log_nbuf);
  1348. pl_hdr.timestamp = 0;
  1349. log_size = pl_hdr.size;
  1350. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  1351. log_size, &pl_hdr);
  1352. if (!rxstat_log.rx_desc) {
  1353. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  1354. "%s: Rx descriptor is NULL", __func__);
  1355. return -EINVAL;
  1356. }
  1357. qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
  1358. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
  1359. rxstat_log.rx_desc);
  1360. return 0;
  1361. }
  1362. int
  1363. process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
  1364. {
  1365. struct pktlog_dev_t *pl_dev = get_pktlog_handle();
  1366. struct ath_pktlog_info *pl_info;
  1367. struct ath_pktlog_hdr pl_hdr;
  1368. struct ath_pktlog_rx_info rxstat_log;
  1369. size_t log_size;
  1370. qdf_nbuf_t log_nbuf = (qdf_nbuf_t)log_data;
  1371. if (!pl_dev) {
  1372. qdf_err("Pktlog handle is NULL");
  1373. return -EINVAL;
  1374. }
  1375. pl_info = pl_dev->pl_info;
  1376. qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
  1377. pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
  1378. pl_hdr.missed_cnt = 0;
  1379. pl_hdr.log_type = log_type;
  1380. pl_hdr.size = qdf_nbuf_len(log_nbuf);
  1381. pl_hdr.timestamp = 0;
  1382. log_size = pl_hdr.size;
  1383. rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
  1384. log_size, &pl_hdr);
  1385. if (!rxstat_log.rx_desc) {
  1386. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  1387. "%s: Rx descriptor is NULL", __func__);
  1388. return -EINVAL;
  1389. }
  1390. qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
  1391. cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
  1392. return 0;
  1393. }
  1394. #else
  1395. int process_rx_desc_remote(void *pdev, void *data)
  1396. {
  1397. return 0;
  1398. }
  1399. int
  1400. process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
  1401. {
  1402. return 0;
  1403. }
  1404. #endif
  1405. #endif /*REMOVE_PKT_LOG */