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