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