1 /* 2 * Copyright (c) 2017-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 #ifndef _HAL_API_MON_H_ 20 #define _HAL_API_MON_H_ 21 22 #include "qdf_types.h" 23 #include "hal_internal.h" 24 #include <target_type.h> 25 26 #define HAL_RX_OFFSET(block, field) block##_##field##_OFFSET 27 #define HAL_RX_LSB(block, field) block##_##field##_LSB 28 #define HAL_RX_MASk(block, field) block##_##field##_MASK 29 30 #define HAL_RX_GET(_ptr, block, field) \ 31 (((*((volatile uint32_t *)_ptr + (HAL_RX_OFFSET(block, field)>>2))) & \ 32 HAL_RX_MASk(block, field)) >> \ 33 HAL_RX_LSB(block, field)) 34 35 #define HAL_RX_PHY_DATA_RADAR 0x01 36 #define HAL_SU_MU_CODING_LDPC 0x01 37 38 #define HAL_RX_FCS_LEN (4) 39 #define KEY_EXTIV 0x20 40 41 #define HAL_RX_USER_TLV32_TYPE_OFFSET 0x00000000 42 #define HAL_RX_USER_TLV32_TYPE_LSB 1 43 #define HAL_RX_USER_TLV32_TYPE_MASK 0x000003FE 44 45 #define HAL_RX_USER_TLV32_LEN_OFFSET 0x00000000 46 #define HAL_RX_USER_TLV32_LEN_LSB 10 47 #define HAL_RX_USER_TLV32_LEN_MASK 0x003FFC00 48 49 #define HAL_RX_USER_TLV32_USERID_OFFSET 0x00000000 50 #define HAL_RX_USER_TLV32_USERID_LSB 26 51 #define HAL_RX_USER_TLV32_USERID_MASK 0xFC000000 52 53 #define HAL_ALIGN(x, a) HAL_ALIGN_MASK(x, (a)-1) 54 #define HAL_ALIGN_MASK(x, mask) (typeof(x))(((uint32)(x) + (mask)) & ~(mask)) 55 56 #define HAL_RX_TLV32_HDR_SIZE 4 57 58 #define HAL_RX_GET_USER_TLV32_TYPE(rx_status_tlv_ptr) \ 59 ((*((uint32_t *)(rx_status_tlv_ptr)) & \ 60 HAL_RX_USER_TLV32_TYPE_MASK) >> \ 61 HAL_RX_USER_TLV32_TYPE_LSB) 62 63 #define HAL_RX_GET_USER_TLV32_LEN(rx_status_tlv_ptr) \ 64 ((*((uint32_t *)(rx_status_tlv_ptr)) & \ 65 HAL_RX_USER_TLV32_LEN_MASK) >> \ 66 HAL_RX_USER_TLV32_LEN_LSB) 67 68 #define HAL_RX_GET_USER_TLV32_USERID(rx_status_tlv_ptr) \ 69 ((*((uint32_t *)(rx_status_tlv_ptr)) & \ 70 HAL_RX_USER_TLV32_USERID_MASK) >> \ 71 HAL_RX_USER_TLV32_USERID_LSB) 72 73 #define HAL_TLV_STATUS_PPDU_NOT_DONE 0 74 #define HAL_TLV_STATUS_PPDU_DONE 1 75 #define HAL_TLV_STATUS_BUF_DONE 2 76 #define HAL_TLV_STATUS_PPDU_NON_STD_DONE 3 77 78 79 #define HAL_MAX_UL_MU_USERS 8 80 81 #define HAL_RX_PKT_TYPE_11A 0 82 #define HAL_RX_PKT_TYPE_11B 1 83 #define HAL_RX_PKT_TYPE_11N 2 84 #define HAL_RX_PKT_TYPE_11AC 3 85 #define HAL_RX_PKT_TYPE_11AX 4 86 87 #define HAL_RX_RECEPTION_TYPE_SU 0 88 #define HAL_RX_RECEPTION_TYPE_MU_MIMO 1 89 #define HAL_RX_RECEPTION_TYPE_OFDMA 2 90 #define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3 91 92 /* Multiply rate by 2 to avoid float point 93 * and get rate in units of 500kbps 94 */ 95 #define HAL_11B_RATE_0MCS 11*2 96 #define HAL_11B_RATE_1MCS 5.5*2 97 #define HAL_11B_RATE_2MCS 2*2 98 #define HAL_11B_RATE_3MCS 1*2 99 #define HAL_11B_RATE_4MCS 11*2 100 #define HAL_11B_RATE_5MCS 5.5*2 101 #define HAL_11B_RATE_6MCS 2*2 102 103 #define HAL_11A_RATE_0MCS 48*2 104 #define HAL_11A_RATE_1MCS 24*2 105 #define HAL_11A_RATE_2MCS 12*2 106 #define HAL_11A_RATE_3MCS 6*2 107 #define HAL_11A_RATE_4MCS 54*2 108 #define HAL_11A_RATE_5MCS 36*2 109 #define HAL_11A_RATE_6MCS 18*2 110 #define HAL_11A_RATE_7MCS 9*2 111 112 #define HE_GI_0_8 0 113 #define HE_GI_1_6 1 114 #define HE_GI_3_2 2 115 116 #define HT_SGI_PRESENT 0x80 117 118 #define HE_LTF_1_X 0 119 #define HE_LTF_2_X 1 120 #define HE_LTF_4_X 2 121 #define VHT_SIG_SU_NSS_MASK 0x7 122 123 #define HAL_TID_INVALID 31 124 #define HAL_AST_IDX_INVALID 0xFFFF 125 126 #ifdef GET_MSDU_AGGREGATION 127 #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)\ 128 {\ 129 struct rx_msdu_end *rx_msdu_end;\ 130 bool first_msdu, last_msdu; \ 131 rx_msdu_end = &rx_desc->msdu_end_tlv.rx_msdu_end;\ 132 first_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, FIRST_MSDU);\ 133 last_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, LAST_MSDU);\ 134 if (first_msdu && last_msdu)\ 135 rs->rs_flags &= (~IEEE80211_AMSDU_FLAG);\ 136 else\ 137 rs->rs_flags |= (IEEE80211_AMSDU_FLAG); \ 138 } \ 139 140 #else 141 #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs) 142 #endif 143 144 #define HAL_MAC_ADDR_LEN 6 145 146 enum { 147 HAL_HW_RX_DECAP_FORMAT_RAW = 0, 148 HAL_HW_RX_DECAP_FORMAT_NWIFI, 149 HAL_HW_RX_DECAP_FORMAT_ETH2, 150 HAL_HW_RX_DECAP_FORMAT_8023, 151 }; 152 153 enum { 154 DP_PPDU_STATUS_START, 155 DP_PPDU_STATUS_DONE, 156 }; 157 158 static inline 159 uint32_t HAL_RX_MON_HW_RX_DESC_SIZE(void) 160 { 161 /* return the HW_RX_DESC size */ 162 return sizeof(struct rx_pkt_tlvs); 163 } 164 165 static inline 166 uint8_t *HAL_RX_MON_DEST_GET_DESC(uint8_t *data) 167 { 168 return data; 169 } 170 171 static inline 172 uint32_t HAL_RX_DESC_GET_MPDU_LENGTH_ERR(void *hw_desc_addr) 173 { 174 struct rx_attention *rx_attn; 175 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 176 177 rx_attn = &rx_desc->attn_tlv.rx_attn; 178 179 return HAL_RX_GET(rx_attn, RX_ATTENTION_1, MPDU_LENGTH_ERR); 180 } 181 182 static inline 183 uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr) 184 { 185 struct rx_attention *rx_attn; 186 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 187 188 rx_attn = &rx_desc->attn_tlv.rx_attn; 189 190 return HAL_RX_GET(rx_attn, RX_ATTENTION_1, FCS_ERR); 191 } 192 193 static inline 194 uint32_t 195 HAL_RX_DESC_GET_DECAP_FORMAT(void *hw_desc_addr) { 196 struct rx_msdu_start *rx_msdu_start; 197 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 198 199 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 200 201 return HAL_RX_GET(rx_msdu_start, RX_MSDU_START_2, DECAP_FORMAT); 202 } 203 204 static inline 205 uint8_t * 206 HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) { 207 uint8_t *rx_pkt_hdr; 208 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 209 210 rx_pkt_hdr = &rx_desc->pkt_hdr_tlv.rx_pkt_hdr[0]; 211 212 return rx_pkt_hdr; 213 } 214 215 static inline 216 uint32_t HAL_RX_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) 217 { 218 struct rx_mpdu_info *rx_mpdu_info; 219 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 220 221 rx_mpdu_info = 222 &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; 223 224 return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); 225 } 226 227 /* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ 228 static inline 229 uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) 230 { 231 struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; 232 struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; 233 234 return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); 235 } 236 237 #define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \ 238 (_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \ 239 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \ 240 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK, \ 241 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB)) 242 243 #define HAL_RX_REO_ENT_BUFFER_ADDR_39_32_GET(reo_ent_desc) \ 244 (HAL_RX_BUFFER_ADDR_39_32_GET(& \ 245 (((struct reo_entrance_ring *)reo_ent_desc) \ 246 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 247 248 #define HAL_RX_REO_ENT_BUFFER_ADDR_31_0_GET(reo_ent_desc) \ 249 (HAL_RX_BUFFER_ADDR_31_0_GET(& \ 250 (((struct reo_entrance_ring *)reo_ent_desc) \ 251 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 252 253 #define HAL_RX_REO_ENT_BUF_COOKIE_GET(reo_ent_desc) \ 254 (HAL_RX_BUF_COOKIE_GET(& \ 255 (((struct reo_entrance_ring *)reo_ent_desc) \ 256 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 257 258 /** 259 * hal_rx_reo_ent_buf_paddr_get: Gets the physical address and 260 * cookie from the REO entrance ring element 261 * 262 * @ hal_rx_desc_cookie: Opaque cookie pointer used by HAL to get to 263 * the current descriptor 264 * @ buf_info: structure to return the buffer information 265 * @ msdu_cnt: pointer to msdu count in MPDU 266 * Return: void 267 */ 268 static inline 269 void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, 270 struct hal_buf_info *buf_info, 271 void **pp_buf_addr_info, 272 uint32_t *msdu_cnt 273 ) 274 { 275 struct reo_entrance_ring *reo_ent_ring = 276 (struct reo_entrance_ring *)rx_desc; 277 struct buffer_addr_info *buf_addr_info; 278 struct rx_mpdu_desc_info *rx_mpdu_desc_info_details; 279 uint32_t loop_cnt; 280 281 rx_mpdu_desc_info_details = 282 &reo_ent_ring->reo_level_mpdu_frame_info.rx_mpdu_desc_info_details; 283 284 *msdu_cnt = HAL_RX_GET(rx_mpdu_desc_info_details, 285 RX_MPDU_DESC_INFO_0, MSDU_COUNT); 286 287 loop_cnt = HAL_RX_GET(reo_ent_ring, REO_ENTRANCE_RING_7, LOOPING_COUNT); 288 289 buf_addr_info = 290 &reo_ent_ring->reo_level_mpdu_frame_info.msdu_link_desc_addr_info; 291 292 buf_info->paddr = 293 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 294 ((uint64_t) 295 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 296 297 buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); 298 299 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 300 "[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d", 301 __func__, __LINE__, reo_ent_ring, buf_addr_info, 302 (unsigned long long)buf_info->paddr, loop_cnt); 303 304 *pp_buf_addr_info = (void *)buf_addr_info; 305 } 306 307 static inline 308 void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc, 309 struct hal_buf_info *buf_info, void **pp_buf_addr_info) 310 { 311 struct rx_msdu_link *msdu_link = 312 (struct rx_msdu_link *)rx_msdu_link_desc; 313 struct buffer_addr_info *buf_addr_info; 314 315 buf_addr_info = &msdu_link->next_msdu_link_desc_addr_info; 316 317 buf_info->paddr = 318 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 319 ((uint64_t) 320 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 321 322 buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); 323 324 *pp_buf_addr_info = (void *)buf_addr_info; 325 } 326 327 /** 328 * hal_rx_msdu_link_desc_set: Retrieves MSDU Link Descriptor to WBM 329 * 330 * @ soc : HAL version of the SOC pointer 331 * @ src_srng_desc : void pointer to the WBM Release Ring descriptor 332 * @ buf_addr_info : void pointer to the buffer_addr_info 333 * 334 * Return: void 335 */ 336 337 static inline void hal_rx_mon_msdu_link_desc_set(struct hal_soc *soc, 338 void *src_srng_desc, void *buf_addr_info) 339 { 340 struct buffer_addr_info *wbm_srng_buffer_addr_info = 341 (struct buffer_addr_info *)src_srng_desc; 342 uint64_t paddr; 343 struct buffer_addr_info *p_buffer_addr_info = 344 (struct buffer_addr_info *)buf_addr_info; 345 346 paddr = 347 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 348 ((uint64_t) 349 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 350 351 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 352 "[%s][%d] src_srng_desc=%pK, buf_addr=0x%llx, cookie=0x%llx", 353 __func__, __LINE__, src_srng_desc, (unsigned long long)paddr, 354 (unsigned long long)p_buffer_addr_info->sw_buffer_cookie); 355 356 /* Structure copy !!! */ 357 *wbm_srng_buffer_addr_info = 358 *((struct buffer_addr_info *)buf_addr_info); 359 } 360 361 static inline 362 uint32 hal_get_rx_msdu_link_desc_size(void) 363 { 364 return sizeof(struct rx_msdu_link); 365 } 366 367 enum { 368 HAL_PKT_TYPE_OFDM = 0, 369 HAL_PKT_TYPE_CCK, 370 HAL_PKT_TYPE_HT, 371 HAL_PKT_TYPE_VHT, 372 HAL_PKT_TYPE_HE, 373 }; 374 375 enum { 376 HAL_SGI_0_8_US, 377 HAL_SGI_0_4_US, 378 HAL_SGI_1_6_US, 379 HAL_SGI_3_2_US, 380 }; 381 382 enum { 383 HAL_FULL_RX_BW_20, 384 HAL_FULL_RX_BW_40, 385 HAL_FULL_RX_BW_80, 386 HAL_FULL_RX_BW_160, 387 }; 388 389 enum { 390 HAL_RX_TYPE_SU, 391 HAL_RX_TYPE_MU_MIMO, 392 HAL_RX_TYPE_MU_OFDMA, 393 HAL_RX_TYPE_MU_OFDMA_MIMO, 394 }; 395 396 /** 397 * enum 398 * @HAL_RX_MON_PPDU_START: PPDU start TLV is decoded in HAL 399 * @HAL_RX_MON_PPDU_END: PPDU end TLV is decided in HAL 400 */ 401 enum { 402 HAL_RX_MON_PPDU_START = 0, 403 HAL_RX_MON_PPDU_END, 404 }; 405 406 struct hal_rx_ppdu_user_info { 407 408 }; 409 410 struct hal_rx_ppdu_common_info { 411 uint32_t ppdu_id; 412 uint32_t last_ppdu_id; 413 uint32_t ppdu_timestamp; 414 uint32_t mpdu_cnt_fcs_ok; 415 uint32_t mpdu_cnt_fcs_err; 416 }; 417 418 struct hal_rx_msdu_payload_info { 419 uint8_t *first_msdu_payload; 420 uint32_t payload_len; 421 }; 422 423 /** 424 * struct hal_rx_nac_info - struct for neighbour info 425 * @fc_valid: flag indicate if it has valid frame control information 426 * @to_ds_flag: flag indicate to_ds bit 427 * @mac_addr2_valid: flag indicate if mac_addr2 is valid 428 * @mac_addr2: mac address2 in wh 429 */ 430 struct hal_rx_nac_info { 431 uint8_t fc_valid; 432 uint8_t to_ds_flag; 433 uint8_t mac_addr2_valid; 434 uint8_t mac_addr2[HAL_MAC_ADDR_LEN]; 435 }; 436 437 struct hal_rx_ppdu_info { 438 struct hal_rx_ppdu_common_info com_info; 439 struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; 440 struct mon_rx_status rx_status; 441 struct hal_rx_msdu_payload_info msdu_info; 442 struct hal_rx_nac_info nac_info; 443 /* status ring PPDU start and end state */ 444 uint32_t rx_state; 445 }; 446 447 static inline uint32_t 448 hal_get_rx_status_buf_size(void) { 449 /* RX status buffer size is hard coded for now */ 450 return 2048; 451 } 452 453 static inline uint8_t* 454 hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { 455 uint32_t tlv_len, tlv_tag; 456 457 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); 458 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); 459 460 /* The actual length of PPDU_END is the combined length of many PHY 461 * TLVs that follow. Skip the TLV header and 462 * rx_rxpcu_classification_overview that follows the header to get to 463 * next TLV. 464 */ 465 if (tlv_tag == WIFIRX_PPDU_END_E) 466 tlv_len = sizeof(struct rx_rxpcu_classification_overview); 467 468 return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len + 469 HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3))); 470 } 471 472 static void hal_rx_proc_phyrx_other_receive_info_tlv(struct hal_soc *hal_soc, 473 void *rx_tlv_hdr, 474 struct hal_rx_ppdu_info 475 *ppdu_info) 476 { 477 hal_soc->ops->hal_rx_proc_phyrx_other_receive_info_tlv(rx_tlv_hdr, 478 (void *)ppdu_info); 479 } 480 481 /** 482 * hal_rx_status_get_tlv_info() - process receive info TLV 483 * @rx_tlv_hdr: pointer to TLV header 484 * @ppdu_info: pointer to ppdu_info 485 * 486 * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv 487 */ 488 static inline uint32_t 489 hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info, 490 struct hal_soc *hal) 491 { 492 uint32_t tlv_tag, user_id, tlv_len, value; 493 uint8_t group_id = 0; 494 uint8_t he_dcm = 0; 495 uint8_t he_stbc = 0; 496 uint16_t he_gi = 0; 497 uint16_t he_ltf = 0; 498 void *rx_tlv; 499 bool unhandled = false; 500 501 502 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); 503 user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv_hdr); 504 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); 505 506 rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 507 switch (tlv_tag) { 508 509 case WIFIRX_PPDU_START_E: 510 ppdu_info->com_info.ppdu_id = 511 HAL_RX_GET(rx_tlv, RX_PPDU_START_0, 512 PHY_PPDU_ID); 513 /* channel number is set in PHY meta data */ 514 ppdu_info->rx_status.chan_num = 515 HAL_RX_GET(rx_tlv, RX_PPDU_START_1, 516 SW_PHY_META_DATA); 517 ppdu_info->com_info.ppdu_timestamp = 518 HAL_RX_GET(rx_tlv, RX_PPDU_START_2, 519 PPDU_START_TIMESTAMP); 520 ppdu_info->rx_status.ppdu_timestamp = 521 ppdu_info->com_info.ppdu_timestamp; 522 ppdu_info->rx_state = HAL_RX_MON_PPDU_START; 523 break; 524 525 case WIFIRX_PPDU_START_USER_INFO_E: 526 break; 527 528 case WIFIRX_PPDU_END_E: 529 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 530 "[%s][%d] ppdu_end_e len=%d", 531 __func__, __LINE__, tlv_len); 532 /* This is followed by sub-TLVs of PPDU_END */ 533 ppdu_info->rx_state = HAL_RX_MON_PPDU_END; 534 break; 535 536 case WIFIRXPCU_PPDU_END_INFO_E: 537 ppdu_info->rx_status.tsft = 538 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, 539 WB_TIMESTAMP_UPPER_32); 540 ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) | 541 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0, 542 WB_TIMESTAMP_LOWER_32); 543 ppdu_info->rx_status.duration = 544 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_8, 545 RX_PPDU_DURATION); 546 break; 547 548 case WIFIRX_PPDU_END_USER_STATS_E: 549 { 550 unsigned long tid = 0; 551 uint16_t seq = 0; 552 553 ppdu_info->rx_status.ast_index = 554 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4, 555 AST_INDEX); 556 557 tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12, 558 RECEIVED_QOS_DATA_TID_BITMAP); 559 ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8); 560 561 if (ppdu_info->rx_status.tid == (sizeof(tid) * 8)) 562 ppdu_info->rx_status.tid = HAL_TID_INVALID; 563 564 ppdu_info->rx_status.tcp_msdu_count = 565 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9, 566 TCP_MSDU_COUNT) + 567 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10, 568 TCP_ACK_MSDU_COUNT); 569 ppdu_info->rx_status.udp_msdu_count = 570 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9, 571 UDP_MSDU_COUNT); 572 ppdu_info->rx_status.other_msdu_count = 573 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10, 574 OTHER_MSDU_COUNT); 575 576 ppdu_info->rx_status.frame_control_info_valid = 577 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 578 DATA_SEQUENCE_CONTROL_INFO_VALID); 579 580 seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5, 581 FIRST_DATA_SEQ_CTRL); 582 if (ppdu_info->rx_status.frame_control_info_valid) 583 ppdu_info->rx_status.first_data_seq_ctrl = seq; 584 585 ppdu_info->rx_status.preamble_type = 586 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 587 HT_CONTROL_FIELD_PKT_TYPE); 588 switch (ppdu_info->rx_status.preamble_type) { 589 case HAL_RX_PKT_TYPE_11N: 590 ppdu_info->rx_status.ht_flags = 1; 591 ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT; 592 break; 593 case HAL_RX_PKT_TYPE_11AC: 594 ppdu_info->rx_status.vht_flags = 1; 595 break; 596 case HAL_RX_PKT_TYPE_11AX: 597 ppdu_info->rx_status.he_flags = 1; 598 break; 599 default: 600 break; 601 } 602 603 ppdu_info->com_info.mpdu_cnt_fcs_ok = 604 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 605 MPDU_CNT_FCS_OK); 606 ppdu_info->com_info.mpdu_cnt_fcs_err = 607 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2, 608 MPDU_CNT_FCS_ERR); 609 if ((ppdu_info->com_info.mpdu_cnt_fcs_ok | 610 ppdu_info->com_info.mpdu_cnt_fcs_err) > 1) 611 ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG; 612 else 613 ppdu_info->rx_status.rs_flags &= 614 (~IEEE80211_AMPDU_FLAG); 615 break; 616 } 617 618 case WIFIRX_PPDU_END_USER_STATS_EXT_E: 619 break; 620 621 case WIFIRX_PPDU_END_STATUS_DONE_E: 622 return HAL_TLV_STATUS_PPDU_DONE; 623 624 case WIFIDUMMY_E: 625 return HAL_TLV_STATUS_BUF_DONE; 626 627 case WIFIPHYRX_HT_SIG_E: 628 { 629 uint8_t *ht_sig_info = (uint8_t *)rx_tlv + 630 HAL_RX_OFFSET(PHYRX_HT_SIG_0, 631 HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS); 632 value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1, 633 FEC_CODING); 634 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 635 1 : 0; 636 ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info, 637 HT_SIG_INFO_0, MCS); 638 ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info, 639 HT_SIG_INFO_0, CBW); 640 ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info, 641 HT_SIG_INFO_1, SHORT_GI); 642 break; 643 } 644 645 case WIFIPHYRX_L_SIG_B_E: 646 { 647 uint8_t *l_sig_b_info = (uint8_t *)rx_tlv + 648 HAL_RX_OFFSET(PHYRX_L_SIG_B_0, 649 L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS); 650 651 value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE); 652 ppdu_info->rx_status.l_sig_b_info = *((uint32_t *)l_sig_b_info); 653 switch (value) { 654 case 1: 655 ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS; 656 break; 657 case 2: 658 ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS; 659 break; 660 case 3: 661 ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS; 662 break; 663 case 4: 664 ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS; 665 break; 666 case 5: 667 ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS; 668 break; 669 case 6: 670 ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS; 671 break; 672 case 7: 673 ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS; 674 break; 675 default: 676 break; 677 } 678 ppdu_info->rx_status.cck_flag = 1; 679 break; 680 } 681 682 case WIFIPHYRX_L_SIG_A_E: 683 { 684 uint8_t *l_sig_a_info = (uint8_t *)rx_tlv + 685 HAL_RX_OFFSET(PHYRX_L_SIG_A_0, 686 L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS); 687 688 value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE); 689 ppdu_info->rx_status.l_sig_a_info = *((uint32_t *)l_sig_a_info); 690 switch (value) { 691 case 8: 692 ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS; 693 break; 694 case 9: 695 ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS; 696 break; 697 case 10: 698 ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS; 699 break; 700 case 11: 701 ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS; 702 break; 703 case 12: 704 ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS; 705 break; 706 case 13: 707 ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS; 708 break; 709 case 14: 710 ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS; 711 break; 712 case 15: 713 ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS; 714 break; 715 default: 716 break; 717 } 718 ppdu_info->rx_status.ofdm_flag = 1; 719 break; 720 } 721 722 case WIFIPHYRX_VHT_SIG_A_E: 723 { 724 uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv + 725 HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0, 726 VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS); 727 728 value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, 729 SU_MU_CODING); 730 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 731 1 : 0; 732 group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID); 733 ppdu_info->rx_status.vht_flag_values5 = group_id; 734 ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info, 735 VHT_SIG_A_INFO_1, MCS); 736 ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info, 737 VHT_SIG_A_INFO_1, GI_SETTING); 738 739 switch (hal->target_type) { 740 case TARGET_TYPE_QCA8074: 741 case TARGET_TYPE_QCA8074V2: 742 ppdu_info->rx_status.is_stbc = 743 HAL_RX_GET(vht_sig_a_info, 744 VHT_SIG_A_INFO_0, STBC); 745 value = HAL_RX_GET(vht_sig_a_info, 746 VHT_SIG_A_INFO_0, N_STS); 747 if (ppdu_info->rx_status.is_stbc && (value > 0)) 748 value = ((value + 1) >> 1) - 1; 749 ppdu_info->rx_status.nss = 750 ((value & VHT_SIG_SU_NSS_MASK) + 1); 751 752 break; 753 case TARGET_TYPE_QCA6290: 754 #if !defined(QCA_WIFI_QCA6290_11AX) 755 ppdu_info->rx_status.is_stbc = 756 HAL_RX_GET(vht_sig_a_info, 757 VHT_SIG_A_INFO_0, STBC); 758 value = HAL_RX_GET(vht_sig_a_info, 759 VHT_SIG_A_INFO_0, N_STS); 760 if (ppdu_info->rx_status.is_stbc && (value > 0)) 761 value = ((value + 1) >> 1) - 1; 762 ppdu_info->rx_status.nss = 763 ((value & VHT_SIG_SU_NSS_MASK) + 1); 764 #else 765 ppdu_info->rx_status.nss = 0; 766 #endif 767 break; 768 #ifdef QCA_WIFI_QCA6390 769 case TARGET_TYPE_QCA6390: 770 ppdu_info->rx_status.nss = 0; 771 break; 772 #endif 773 default: 774 break; 775 } 776 ppdu_info->rx_status.vht_flag_values3[0] = 777 (((ppdu_info->rx_status.mcs) << 4) 778 | ppdu_info->rx_status.nss); 779 ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info, 780 VHT_SIG_A_INFO_0, BANDWIDTH); 781 ppdu_info->rx_status.vht_flag_values2 = 782 ppdu_info->rx_status.bw; 783 ppdu_info->rx_status.vht_flag_values4 = 784 HAL_RX_GET(vht_sig_a_info, 785 VHT_SIG_A_INFO_1, SU_MU_CODING); 786 787 ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info, 788 VHT_SIG_A_INFO_1, BEAMFORMED); 789 790 break; 791 } 792 case WIFIPHYRX_HE_SIG_A_SU_E: 793 { 794 uint8_t *he_sig_a_su_info = (uint8_t *)rx_tlv + 795 HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0, 796 HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS); 797 ppdu_info->rx_status.he_flags = 1; 798 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, 799 FORMAT_INDICATION); 800 if (value == 0) { 801 ppdu_info->rx_status.he_data1 = 802 QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE; 803 } else { 804 ppdu_info->rx_status.he_data1 = 805 QDF_MON_STATUS_HE_SU_FORMAT_TYPE; 806 } 807 808 /* data1 */ 809 ppdu_info->rx_status.he_data1 |= 810 QDF_MON_STATUS_HE_BSS_COLOR_KNOWN | 811 QDF_MON_STATUS_HE_BEAM_CHANGE_KNOWN | 812 QDF_MON_STATUS_HE_DL_UL_KNOWN | 813 QDF_MON_STATUS_HE_MCS_KNOWN | 814 QDF_MON_STATUS_HE_DCM_KNOWN | 815 QDF_MON_STATUS_HE_CODING_KNOWN | 816 QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN | 817 QDF_MON_STATUS_HE_STBC_KNOWN | 818 QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN | 819 QDF_MON_STATUS_HE_DOPPLER_KNOWN; 820 821 /* data2 */ 822 ppdu_info->rx_status.he_data2 = 823 QDF_MON_STATUS_HE_GI_KNOWN; 824 ppdu_info->rx_status.he_data2 |= 825 QDF_MON_STATUS_TXBF_KNOWN | 826 QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN | 827 QDF_MON_STATUS_TXOP_KNOWN | 828 QDF_MON_STATUS_LTF_SYMBOLS_KNOWN | 829 QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN | 830 QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN; 831 832 /* data3 */ 833 value = HAL_RX_GET(he_sig_a_su_info, 834 HE_SIG_A_SU_INFO_0, BSS_COLOR_ID); 835 ppdu_info->rx_status.he_data3 = value; 836 value = HAL_RX_GET(he_sig_a_su_info, 837 HE_SIG_A_SU_INFO_0, BEAM_CHANGE); 838 value = value << QDF_MON_STATUS_BEAM_CHANGE_SHIFT; 839 ppdu_info->rx_status.he_data3 |= value; 840 value = HAL_RX_GET(he_sig_a_su_info, 841 HE_SIG_A_SU_INFO_0, DL_UL_FLAG); 842 value = value << QDF_MON_STATUS_DL_UL_SHIFT; 843 ppdu_info->rx_status.he_data3 |= value; 844 845 value = HAL_RX_GET(he_sig_a_su_info, 846 HE_SIG_A_SU_INFO_0, TRANSMIT_MCS); 847 ppdu_info->rx_status.mcs = value; 848 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 849 ppdu_info->rx_status.he_data3 |= value; 850 851 value = HAL_RX_GET(he_sig_a_su_info, 852 HE_SIG_A_SU_INFO_0, DCM); 853 he_dcm = value; 854 value = value << QDF_MON_STATUS_DCM_SHIFT; 855 ppdu_info->rx_status.he_data3 |= value; 856 value = HAL_RX_GET(he_sig_a_su_info, 857 HE_SIG_A_SU_INFO_1, CODING); 858 value = value << QDF_MON_STATUS_CODING_SHIFT; 859 ppdu_info->rx_status.he_data3 |= value; 860 value = HAL_RX_GET(he_sig_a_su_info, 861 HE_SIG_A_SU_INFO_1, 862 LDPC_EXTRA_SYMBOL); 863 value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT; 864 ppdu_info->rx_status.he_data3 |= value; 865 value = HAL_RX_GET(he_sig_a_su_info, 866 HE_SIG_A_SU_INFO_1, STBC); 867 he_stbc = value; 868 value = value << QDF_MON_STATUS_STBC_SHIFT; 869 ppdu_info->rx_status.he_data3 |= value; 870 871 /* data4 */ 872 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, 873 SPATIAL_REUSE); 874 ppdu_info->rx_status.he_data4 = value; 875 876 /* data5 */ 877 value = HAL_RX_GET(he_sig_a_su_info, 878 HE_SIG_A_SU_INFO_0, TRANSMIT_BW); 879 ppdu_info->rx_status.he_data5 = value; 880 ppdu_info->rx_status.bw = value; 881 value = HAL_RX_GET(he_sig_a_su_info, 882 HE_SIG_A_SU_INFO_0, CP_LTF_SIZE); 883 switch (value) { 884 case 0: 885 he_gi = HE_GI_0_8; 886 he_ltf = HE_LTF_1_X; 887 break; 888 case 1: 889 he_gi = HE_GI_0_8; 890 he_ltf = HE_LTF_2_X; 891 break; 892 case 2: 893 he_gi = HE_GI_1_6; 894 he_ltf = HE_LTF_2_X; 895 break; 896 case 3: 897 if (he_dcm && he_stbc) { 898 he_gi = HE_GI_0_8; 899 he_ltf = HE_LTF_4_X; 900 } else { 901 he_gi = HE_GI_3_2; 902 he_ltf = HE_LTF_4_X; 903 } 904 break; 905 } 906 ppdu_info->rx_status.sgi = he_gi; 907 value = he_gi << QDF_MON_STATUS_GI_SHIFT; 908 ppdu_info->rx_status.he_data5 |= value; 909 value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT; 910 ppdu_info->rx_status.he_data5 |= value; 911 912 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS); 913 value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT); 914 ppdu_info->rx_status.he_data5 |= value; 915 916 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 917 PACKET_EXTENSION_A_FACTOR); 918 value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT; 919 ppdu_info->rx_status.he_data5 |= value; 920 921 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF); 922 value = value << QDF_MON_STATUS_TXBF_SHIFT; 923 ppdu_info->rx_status.he_data5 |= value; 924 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 925 PACKET_EXTENSION_PE_DISAMBIGUITY); 926 value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT; 927 ppdu_info->rx_status.he_data5 |= value; 928 929 /* data6 */ 930 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS); 931 value++; 932 ppdu_info->rx_status.nss = value; 933 ppdu_info->rx_status.he_data6 = value; 934 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 935 DOPPLER_INDICATION); 936 value = value << QDF_MON_STATUS_DOPPLER_SHIFT; 937 ppdu_info->rx_status.he_data6 |= value; 938 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 939 TXOP_DURATION); 940 value = value << QDF_MON_STATUS_TXOP_SHIFT; 941 ppdu_info->rx_status.he_data6 |= value; 942 943 ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info, 944 HE_SIG_A_SU_INFO_1, TXBF); 945 break; 946 } 947 case WIFIPHYRX_HE_SIG_A_MU_DL_E: 948 { 949 uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv + 950 HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0, 951 HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS); 952 953 ppdu_info->rx_status.he_mu_flags = 1; 954 955 /* HE Flags */ 956 /*data1*/ 957 ppdu_info->rx_status.he_data1 = 958 QDF_MON_STATUS_HE_MU_FORMAT_TYPE; 959 ppdu_info->rx_status.he_data1 |= 960 QDF_MON_STATUS_HE_BSS_COLOR_KNOWN | 961 QDF_MON_STATUS_HE_DL_UL_KNOWN | 962 QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN | 963 QDF_MON_STATUS_HE_STBC_KNOWN | 964 QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN | 965 QDF_MON_STATUS_HE_DOPPLER_KNOWN; 966 967 /* data2 */ 968 ppdu_info->rx_status.he_data2 = 969 QDF_MON_STATUS_HE_GI_KNOWN; 970 ppdu_info->rx_status.he_data2 |= 971 QDF_MON_STATUS_LTF_SYMBOLS_KNOWN | 972 QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN | 973 QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN | 974 QDF_MON_STATUS_TXOP_KNOWN | 975 QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN; 976 977 /*data3*/ 978 value = HAL_RX_GET(he_sig_a_mu_dl_info, 979 HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID); 980 ppdu_info->rx_status.he_data3 = value; 981 982 value = HAL_RX_GET(he_sig_a_mu_dl_info, 983 HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG); 984 value = value << QDF_MON_STATUS_DL_UL_SHIFT; 985 ppdu_info->rx_status.he_data3 |= value; 986 987 value = HAL_RX_GET(he_sig_a_mu_dl_info, 988 HE_SIG_A_MU_DL_INFO_1, 989 LDPC_EXTRA_SYMBOL); 990 value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT; 991 ppdu_info->rx_status.he_data3 |= value; 992 993 value = HAL_RX_GET(he_sig_a_mu_dl_info, 994 HE_SIG_A_MU_DL_INFO_1, STBC); 995 he_stbc = value; 996 value = value << QDF_MON_STATUS_STBC_SHIFT; 997 ppdu_info->rx_status.he_data3 |= value; 998 999 /*data4*/ 1000 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0, 1001 SPATIAL_REUSE); 1002 ppdu_info->rx_status.he_data4 = value; 1003 1004 /*data5*/ 1005 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1006 HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW); 1007 ppdu_info->rx_status.he_data5 = value; 1008 ppdu_info->rx_status.bw = value; 1009 1010 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1011 HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE); 1012 switch (value) { 1013 case 0: 1014 he_gi = HE_GI_0_8; 1015 he_ltf = HE_LTF_4_X; 1016 break; 1017 case 1: 1018 he_gi = HE_GI_0_8; 1019 he_ltf = HE_LTF_2_X; 1020 break; 1021 case 2: 1022 he_gi = HE_GI_1_6; 1023 he_ltf = HE_LTF_2_X; 1024 break; 1025 case 3: 1026 he_gi = HE_GI_3_2; 1027 he_ltf = HE_LTF_4_X; 1028 break; 1029 } 1030 ppdu_info->rx_status.sgi = he_gi; 1031 value = he_gi << QDF_MON_STATUS_GI_SHIFT; 1032 ppdu_info->rx_status.he_data5 |= value; 1033 1034 value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT; 1035 ppdu_info->rx_status.he_data5 |= value; 1036 1037 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1038 HE_SIG_A_MU_DL_INFO_1, NUM_LTF_SYMBOLS); 1039 value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT); 1040 ppdu_info->rx_status.he_data5 |= value; 1041 1042 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 1043 PACKET_EXTENSION_A_FACTOR); 1044 value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT; 1045 ppdu_info->rx_status.he_data5 |= value; 1046 1047 1048 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 1049 PACKET_EXTENSION_PE_DISAMBIGUITY); 1050 value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT; 1051 ppdu_info->rx_status.he_data5 |= value; 1052 1053 /*data6*/ 1054 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0, 1055 DOPPLER_INDICATION); 1056 value = value << QDF_MON_STATUS_DOPPLER_SHIFT; 1057 ppdu_info->rx_status.he_data6 |= value; 1058 1059 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 1060 TXOP_DURATION); 1061 value = value << QDF_MON_STATUS_TXOP_SHIFT; 1062 ppdu_info->rx_status.he_data6 |= value; 1063 1064 /* HE-MU Flags */ 1065 /* HE-MU-flags1 */ 1066 ppdu_info->rx_status.he_flags1 = 1067 QDF_MON_STATUS_SIG_B_MCS_KNOWN | 1068 QDF_MON_STATUS_SIG_B_DCM_KNOWN | 1069 QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN | 1070 QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN | 1071 QDF_MON_STATUS_RU_0_KNOWN; 1072 1073 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1074 HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B); 1075 ppdu_info->rx_status.he_flags1 |= value; 1076 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1077 HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B); 1078 value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT; 1079 ppdu_info->rx_status.he_flags1 |= value; 1080 1081 /* HE-MU-flags2 */ 1082 ppdu_info->rx_status.he_flags2 = 1083 QDF_MON_STATUS_BW_KNOWN; 1084 1085 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1086 HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW); 1087 ppdu_info->rx_status.he_flags2 |= value; 1088 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1089 HE_SIG_A_MU_DL_INFO_0, COMP_MODE_SIG_B); 1090 value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT; 1091 ppdu_info->rx_status.he_flags2 |= value; 1092 value = HAL_RX_GET(he_sig_a_mu_dl_info, 1093 HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS); 1094 value = value - 1; 1095 value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT; 1096 ppdu_info->rx_status.he_flags2 |= value; 1097 break; 1098 } 1099 case WIFIPHYRX_HE_SIG_B1_MU_E: 1100 { 1101 1102 uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv + 1103 HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0, 1104 HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS); 1105 1106 ppdu_info->rx_status.he_sig_b_common_known |= 1107 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; 1108 /* TODO: Check on the availability of other fields in 1109 * sig_b_common 1110 */ 1111 1112 value = HAL_RX_GET(he_sig_b1_mu_info, 1113 HE_SIG_B1_MU_INFO_0, RU_ALLOCATION); 1114 ppdu_info->rx_status.he_RU[0] = value; 1115 break; 1116 } 1117 case WIFIPHYRX_HE_SIG_B2_MU_E: 1118 { 1119 uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv + 1120 HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0, 1121 HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS); 1122 /* 1123 * Not all "HE" fields can be updated from 1124 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E 1125 * to populate rest of the "HE" fields for MU scenarios. 1126 */ 1127 1128 /* HE-data1 */ 1129 ppdu_info->rx_status.he_data1 |= 1130 QDF_MON_STATUS_HE_MCS_KNOWN | 1131 QDF_MON_STATUS_HE_CODING_KNOWN; 1132 1133 /* HE-data2 */ 1134 1135 /* HE-data3 */ 1136 value = HAL_RX_GET(he_sig_b2_mu_info, 1137 HE_SIG_B2_MU_INFO_0, STA_MCS); 1138 ppdu_info->rx_status.mcs = value; 1139 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 1140 ppdu_info->rx_status.he_data3 |= value; 1141 1142 1143 value = HAL_RX_GET(he_sig_b2_mu_info, 1144 HE_SIG_B2_MU_INFO_0, STA_CODING); 1145 value = value << QDF_MON_STATUS_CODING_SHIFT; 1146 ppdu_info->rx_status.he_data3 |= value; 1147 1148 /* HE-data4 */ 1149 value = HAL_RX_GET(he_sig_b2_mu_info, 1150 HE_SIG_B2_MU_INFO_0, STA_ID); 1151 value = value << QDF_MON_STATUS_STA_ID_SHIFT; 1152 ppdu_info->rx_status.he_data4 |= value; 1153 1154 /* HE-data5 */ 1155 1156 /* HE-data6 */ 1157 value = HAL_RX_GET(he_sig_b2_mu_info, 1158 HE_SIG_B2_MU_INFO_0, NSTS); 1159 /* value n indicates n+1 spatial streams */ 1160 value++; 1161 ppdu_info->rx_status.nss = value; 1162 ppdu_info->rx_status.he_data6 |= value; 1163 1164 break; 1165 1166 } 1167 case WIFIPHYRX_HE_SIG_B2_OFDMA_E: 1168 { 1169 uint8_t *he_sig_b2_ofdma_info = 1170 (uint8_t *)rx_tlv + 1171 HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0, 1172 HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS); 1173 1174 /* 1175 * Not all "HE" fields can be updated from 1176 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E 1177 * to populate rest of "HE" fields for MU OFDMA scenarios. 1178 */ 1179 1180 /* HE-data1 */ 1181 ppdu_info->rx_status.he_data1 |= 1182 QDF_MON_STATUS_HE_MCS_KNOWN | 1183 QDF_MON_STATUS_HE_DCM_KNOWN | 1184 QDF_MON_STATUS_HE_CODING_KNOWN; 1185 1186 /* HE-data2 */ 1187 ppdu_info->rx_status.he_data2 |= 1188 QDF_MON_STATUS_TXBF_KNOWN; 1189 1190 /* HE-data3 */ 1191 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1192 HE_SIG_B2_OFDMA_INFO_0, STA_MCS); 1193 ppdu_info->rx_status.mcs = value; 1194 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 1195 ppdu_info->rx_status.he_data3 |= value; 1196 1197 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1198 HE_SIG_B2_OFDMA_INFO_0, STA_DCM); 1199 he_dcm = value; 1200 value = value << QDF_MON_STATUS_DCM_SHIFT; 1201 ppdu_info->rx_status.he_data3 |= value; 1202 1203 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1204 HE_SIG_B2_OFDMA_INFO_0, STA_CODING); 1205 value = value << QDF_MON_STATUS_CODING_SHIFT; 1206 ppdu_info->rx_status.he_data3 |= value; 1207 1208 /* HE-data4 */ 1209 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1210 HE_SIG_B2_OFDMA_INFO_0, STA_ID); 1211 value = value << QDF_MON_STATUS_STA_ID_SHIFT; 1212 ppdu_info->rx_status.he_data4 |= value; 1213 1214 /* HE-data5 */ 1215 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1216 HE_SIG_B2_OFDMA_INFO_0, TXBF); 1217 value = value << QDF_MON_STATUS_TXBF_SHIFT; 1218 ppdu_info->rx_status.he_data5 |= value; 1219 1220 /* HE-data6 */ 1221 value = HAL_RX_GET(he_sig_b2_ofdma_info, 1222 HE_SIG_B2_OFDMA_INFO_0, NSTS); 1223 /* value n indicates n+1 spatial streams */ 1224 value++; 1225 ppdu_info->rx_status.nss = value; 1226 ppdu_info->rx_status.he_data6 |= value; 1227 1228 break; 1229 } 1230 case WIFIPHYRX_RSSI_LEGACY_E: 1231 { 1232 uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + 1233 HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3, 1234 RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS); 1235 1236 ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv, 1237 PHYRX_RSSI_LEGACY_35, RSSI_COMB); 1238 ppdu_info->rx_status.bw = hal->ops->hal_rx_get_tlv(rx_tlv); 1239 ppdu_info->rx_status.he_re = 0; 1240 1241 ppdu_info->rx_status.reception_type = HAL_RX_GET(rx_tlv, 1242 PHYRX_RSSI_LEGACY_0, RECEPTION_TYPE); 1243 1244 value = HAL_RX_GET(rssi_info_tlv, 1245 RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); 1246 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1247 "RSSI_PRI20_CHAIN0: %d", value); 1248 1249 value = HAL_RX_GET(rssi_info_tlv, 1250 RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0); 1251 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1252 "RSSI_EXT20_CHAIN0: %d", value); 1253 1254 value = HAL_RX_GET(rssi_info_tlv, 1255 RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0); 1256 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1257 "RSSI_EXT40_LOW20_CHAIN0: %d", value); 1258 1259 value = HAL_RX_GET(rssi_info_tlv, 1260 RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0); 1261 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1262 "RSSI_EXT40_HIGH20_CHAIN0: %d", value); 1263 1264 value = HAL_RX_GET(rssi_info_tlv, 1265 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0); 1266 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1267 "RSSI_EXT80_LOW20_CHAIN0: %d", value); 1268 1269 value = HAL_RX_GET(rssi_info_tlv, 1270 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0); 1271 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1272 "RSSI_EXT80_LOW_HIGH20_CHAIN0: %d", value); 1273 1274 value = HAL_RX_GET(rssi_info_tlv, 1275 RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0); 1276 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1277 "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d", value); 1278 1279 value = HAL_RX_GET(rssi_info_tlv, 1280 RECEIVE_RSSI_INFO_1, 1281 RSSI_EXT80_HIGH20_CHAIN0); 1282 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1283 "RSSI_EXT80_HIGH20_CHAIN0: %d", value); 1284 break; 1285 } 1286 case WIFIPHYRX_OTHER_RECEIVE_INFO_E: 1287 hal_rx_proc_phyrx_other_receive_info_tlv(hal, rx_tlv_hdr, 1288 ppdu_info); 1289 break; 1290 case WIFIRX_HEADER_E: 1291 ppdu_info->msdu_info.first_msdu_payload = rx_tlv; 1292 ppdu_info->msdu_info.payload_len = tlv_len; 1293 break; 1294 case WIFIRX_MPDU_START_E: 1295 { 1296 uint8_t *rx_mpdu_start = 1297 (uint8_t *)rx_tlv + HAL_RX_OFFSET(RX_MPDU_START_0, 1298 RX_MPDU_INFO_RX_MPDU_INFO_DETAILS); 1299 uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, 1300 PHY_PPDU_ID); 1301 1302 ppdu_info->nac_info.fc_valid = 1303 HAL_RX_GET(rx_mpdu_start, 1304 RX_MPDU_INFO_2, 1305 MPDU_FRAME_CONTROL_VALID); 1306 1307 ppdu_info->nac_info.to_ds_flag = 1308 HAL_RX_GET(rx_mpdu_start, 1309 RX_MPDU_INFO_2, 1310 TO_DS); 1311 1312 ppdu_info->nac_info.mac_addr2_valid = 1313 HAL_RX_GET(rx_mpdu_start, 1314 RX_MPDU_INFO_2, 1315 MAC_ADDR_AD2_VALID); 1316 1317 *(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] = 1318 HAL_RX_GET(rx_mpdu_start, 1319 RX_MPDU_INFO_16, 1320 MAC_ADDR_AD2_15_0); 1321 1322 *(uint32_t *)&ppdu_info->nac_info.mac_addr2[2] = 1323 HAL_RX_GET(rx_mpdu_start, 1324 RX_MPDU_INFO_17, 1325 MAC_ADDR_AD2_47_16); 1326 1327 if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) { 1328 ppdu_info->rx_status.prev_ppdu_id = ppdu_id; 1329 ppdu_info->rx_status.ppdu_len = 1330 HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13, 1331 MPDU_LENGTH); 1332 } else { 1333 ppdu_info->rx_status.ppdu_len += 1334 HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13, 1335 MPDU_LENGTH); 1336 } 1337 break; 1338 } 1339 case 0: 1340 return HAL_TLV_STATUS_PPDU_DONE; 1341 1342 default: 1343 unhandled = true; 1344 break; 1345 } 1346 1347 if (!unhandled) 1348 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1349 "%s TLV type: %d, TLV len:%d %s", 1350 __func__, tlv_tag, tlv_len, 1351 unhandled == true ? "unhandled" : ""); 1352 1353 qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, rx_tlv, tlv_len); 1354 1355 return HAL_TLV_STATUS_PPDU_NOT_DONE; 1356 } 1357 1358 static inline 1359 uint32_t hal_get_rx_status_done_tlv_size(void *hal_soc) 1360 { 1361 return HAL_RX_TLV32_HDR_SIZE; 1362 } 1363 1364 static inline QDF_STATUS 1365 hal_get_rx_status_done(uint8_t *rx_tlv) 1366 { 1367 uint32_t tlv_tag; 1368 1369 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); 1370 1371 if (tlv_tag == WIFIRX_STATUS_BUFFER_DONE_E) 1372 return QDF_STATUS_SUCCESS; 1373 else 1374 return QDF_STATUS_E_EMPTY; 1375 } 1376 1377 static inline QDF_STATUS 1378 hal_clear_rx_status_done(uint8_t *rx_tlv) 1379 { 1380 *(uint32_t *)rx_tlv = 0; 1381 return QDF_STATUS_SUCCESS; 1382 } 1383 1384 #endif 1385