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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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