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