1 /* 2 * Copyright (c) 2017 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 #define HAL_11B_RATE_0MCS 11 90 #define HAL_11B_RATE_1MCS 5.5 91 #define HAL_11B_RATE_2MCS 2 92 #define HAL_11B_RATE_3MCS 1 93 #define HAL_11B_RATE_4MCS 11 94 #define HAL_11B_RATE_5MCS 5.5 95 #define HAL_11B_RATE_6MCS 2 96 97 #define HAL_11A_RATE_0MCS 48 98 #define HAL_11A_RATE_1MCS 24 99 #define HAL_11A_RATE_2MCS 12 100 #define HAL_11A_RATE_3MCS 6 101 #define HAL_11A_RATE_4MCS 54 102 #define HAL_11A_RATE_5MCS 36 103 #define HAL_11A_RATE_6MCS 18 104 #define HAL_11A_RATE_7MCS 9 105 106 enum { 107 HAL_HW_RX_DECAP_FORMAT_RAW = 0, 108 HAL_HW_RX_DECAP_FORMAT_NWIFI, 109 HAL_HW_RX_DECAP_FORMAT_ETH2, 110 HAL_HW_RX_DECAP_FORMAT_8023, 111 }; 112 113 enum { 114 DP_PPDU_STATUS_START, 115 DP_PPDU_STATUS_DONE, 116 }; 117 118 static inline 119 uint32_t HAL_RX_MON_HW_RX_DESC_SIZE(void) 120 { 121 /* return the HW_RX_DESC size */ 122 return sizeof(struct rx_pkt_tlvs); 123 } 124 125 static inline 126 uint8_t *HAL_RX_MON_DEST_GET_DESC(uint8_t *data) 127 { 128 return data; 129 } 130 131 static inline 132 uint32_t HAL_RX_DESC_GET_MPDU_LENGTH_ERR(void *hw_desc_addr) 133 { 134 struct rx_attention *rx_attn; 135 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 136 137 rx_attn = &rx_desc->attn_tlv.rx_attn; 138 139 return HAL_RX_GET(rx_attn, RX_ATTENTION_1, MPDU_LENGTH_ERR); 140 } 141 142 static inline 143 uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr) 144 { 145 struct rx_attention *rx_attn; 146 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 147 148 rx_attn = &rx_desc->attn_tlv.rx_attn; 149 150 return HAL_RX_GET(rx_attn, RX_ATTENTION_1, FCS_ERR); 151 } 152 153 static inline 154 uint32_t 155 HAL_RX_DESC_GET_DECAP_FORMAT(void *hw_desc_addr) { 156 struct rx_msdu_start *rx_msdu_start; 157 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 158 159 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 160 161 return HAL_RX_GET(rx_msdu_start, RX_MSDU_START_2, DECAP_FORMAT); 162 } 163 164 static inline 165 uint8_t * 166 HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) { 167 uint8_t *rx_pkt_hdr; 168 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 169 170 rx_pkt_hdr = &rx_desc->pkt_hdr_tlv.rx_pkt_hdr[0]; 171 172 return rx_pkt_hdr; 173 } 174 175 static inline 176 uint32_t HAL_RX_MON_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) 177 { 178 struct rx_mpdu_info *rx_mpdu_info; 179 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 180 181 rx_mpdu_info = 182 &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; 183 184 return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); 185 } 186 187 /* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ 188 static inline 189 uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) 190 { 191 struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; 192 struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; 193 194 return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); 195 } 196 197 #define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \ 198 (_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \ 199 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \ 200 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK, \ 201 BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB)) 202 203 #define HAL_RX_REO_ENT_BUFFER_ADDR_39_32_GET(reo_ent_desc) \ 204 (HAL_RX_BUFFER_ADDR_39_32_GET(& \ 205 (((struct reo_entrance_ring *)reo_ent_desc) \ 206 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 207 208 #define HAL_RX_REO_ENT_BUFFER_ADDR_31_0_GET(reo_ent_desc) \ 209 (HAL_RX_BUFFER_ADDR_31_0_GET(& \ 210 (((struct reo_entrance_ring *)reo_ent_desc) \ 211 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 212 213 #define HAL_RX_REO_ENT_BUF_COOKIE_GET(reo_ent_desc) \ 214 (HAL_RX_BUF_COOKIE_GET(& \ 215 (((struct reo_entrance_ring *)reo_ent_desc) \ 216 ->reo_level_mpdu_frame_info.msdu_link_desc_addr_info))) 217 218 /** 219 * hal_rx_reo_ent_buf_paddr_get: Gets the physical address and 220 * cookie from the REO entrance ring element 221 * 222 * @ hal_rx_desc_cookie: Opaque cookie pointer used by HAL to get to 223 * the current descriptor 224 * @ buf_info: structure to return the buffer information 225 * @ msdu_cnt: pointer to msdu count in MPDU 226 * Return: void 227 */ 228 static inline 229 void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, 230 struct hal_buf_info *buf_info, 231 void **pp_buf_addr_info, 232 uint32_t *msdu_cnt 233 ) 234 { 235 struct reo_entrance_ring *reo_ent_ring = 236 (struct reo_entrance_ring *)rx_desc; 237 struct buffer_addr_info *buf_addr_info; 238 struct rx_mpdu_desc_info *rx_mpdu_desc_info_details; 239 uint32_t loop_cnt; 240 241 rx_mpdu_desc_info_details = 242 &reo_ent_ring->reo_level_mpdu_frame_info.rx_mpdu_desc_info_details; 243 244 *msdu_cnt = HAL_RX_GET(rx_mpdu_desc_info_details, 245 RX_MPDU_DESC_INFO_0, MSDU_COUNT); 246 247 loop_cnt = HAL_RX_GET(reo_ent_ring, REO_ENTRANCE_RING_7, LOOPING_COUNT); 248 249 buf_addr_info = 250 &reo_ent_ring->reo_level_mpdu_frame_info.msdu_link_desc_addr_info; 251 252 buf_info->paddr = 253 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 254 ((uint64_t) 255 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 256 257 buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); 258 259 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 260 "[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d\n", 261 __func__, __LINE__, reo_ent_ring, buf_addr_info, 262 (unsigned long long)buf_info->paddr, loop_cnt); 263 264 *pp_buf_addr_info = (void *)buf_addr_info; 265 } 266 267 static inline 268 void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc, 269 struct hal_buf_info *buf_info, void **pp_buf_addr_info) 270 { 271 struct rx_msdu_link *msdu_link = 272 (struct rx_msdu_link *)rx_msdu_link_desc; 273 struct buffer_addr_info *buf_addr_info; 274 275 buf_addr_info = &msdu_link->next_msdu_link_desc_addr_info; 276 277 buf_info->paddr = 278 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 279 ((uint64_t) 280 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 281 282 buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); 283 284 *pp_buf_addr_info = (void *)buf_addr_info; 285 } 286 287 /** 288 * hal_rx_msdu_link_desc_set: Retrieves MSDU Link Descriptor to WBM 289 * 290 * @ soc : HAL version of the SOC pointer 291 * @ src_srng_desc : void pointer to the WBM Release Ring descriptor 292 * @ buf_addr_info : void pointer to the buffer_addr_info 293 * 294 * Return: void 295 */ 296 297 static inline void hal_rx_mon_msdu_link_desc_set(struct hal_soc *soc, 298 void *src_srng_desc, void *buf_addr_info) 299 { 300 struct buffer_addr_info *wbm_srng_buffer_addr_info = 301 (struct buffer_addr_info *)src_srng_desc; 302 uint64_t paddr; 303 struct buffer_addr_info *p_buffer_addr_info = 304 (struct buffer_addr_info *)buf_addr_info; 305 306 paddr = 307 (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) | 308 ((uint64_t) 309 (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); 310 311 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 312 "[%s][%d] src_srng_desc=%pK, buf_addr=0x%llx, cookie=0x%llx\n", 313 __func__, __LINE__, src_srng_desc, (unsigned long long)paddr, 314 (unsigned long long)p_buffer_addr_info->sw_buffer_cookie); 315 316 /* Structure copy !!! */ 317 *wbm_srng_buffer_addr_info = 318 *((struct buffer_addr_info *)buf_addr_info); 319 } 320 321 static inline 322 uint32 hal_get_rx_msdu_link_desc_size(void) 323 { 324 return sizeof(struct rx_msdu_link); 325 } 326 327 enum { 328 HAL_PKT_TYPE_OFDM = 0, 329 HAL_PKT_TYPE_CCK, 330 HAL_PKT_TYPE_HT, 331 HAL_PKT_TYPE_VHT, 332 HAL_PKT_TYPE_HE, 333 }; 334 335 enum { 336 HAL_SGI_0_8_US, 337 HAL_SGI_0_4_US, 338 HAL_SGI_1_6_US, 339 HAL_SGI_3_2_US, 340 }; 341 342 enum { 343 HAL_FULL_RX_BW_20, 344 HAL_FULL_RX_BW_40, 345 HAL_FULL_RX_BW_80, 346 HAL_FULL_RX_BW_160, 347 }; 348 349 enum { 350 HAL_RX_TYPE_SU, 351 HAL_RX_TYPE_MU_MIMO, 352 HAL_RX_TYPE_MU_OFDMA, 353 HAL_RX_TYPE_MU_OFDMA_MIMO, 354 }; 355 356 /** 357 * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status 358 * 359 * @ hw_desc_addr: Start address of Rx HW TLVs 360 * @ rs: Status for monitor mode 361 * 362 * Return: void 363 */ 364 static inline 365 void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr, 366 struct mon_rx_status *rs) 367 { 368 struct rx_msdu_start *rx_msdu_start; 369 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 370 uint32_t reg_value; 371 uint8_t nss = 0; 372 static uint32_t sgi_hw_to_cdp[] = { 373 CDP_SGI_0_8_US, 374 CDP_SGI_0_4_US, 375 CDP_SGI_1_6_US, 376 CDP_SGI_3_2_US, 377 }; 378 379 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 380 381 rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, 382 RX_MSDU_START_5, USER_RSSI); 383 rs->mcs = HAL_RX_GET(rx_msdu_start, 384 RX_MSDU_START_5, RATE_MCS); 385 rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); 386 387 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); 388 rs->sgi = sgi_hw_to_cdp[reg_value]; 389 rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); 390 391 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); 392 switch (reg_value) { 393 case HAL_RX_PKT_TYPE_11N: 394 rs->ht_flags = 1; 395 rs->bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, 396 RECEIVE_BANDWIDTH); 397 break; 398 case HAL_RX_PKT_TYPE_11AC: 399 rs->vht_flags = 1; 400 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, 401 RECEIVE_BANDWIDTH); 402 rs->vht_flag_values2 = reg_value; 403 nss = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); 404 nss = nss + 1; 405 rs->vht_flag_values3[0] = (rs->mcs << 4) | nss ; 406 break; 407 case HAL_RX_PKT_TYPE_11AX: 408 rs->he_flags = 1; 409 break; 410 default: 411 break; 412 } 413 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); 414 rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; 415 /* TODO: rs->beamformed should be set for SU beamforming also */ 416 } 417 418 struct hal_rx_ppdu_user_info { 419 420 }; 421 422 struct hal_rx_ppdu_common_info { 423 uint32_t ppdu_id; 424 uint32_t ppdu_timestamp; 425 }; 426 427 struct hal_rx_ppdu_info { 428 struct hal_rx_ppdu_common_info com_info; 429 struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; 430 struct mon_rx_status rx_status; 431 }; 432 433 static inline uint32_t 434 hal_get_rx_status_buf_size(void) { 435 /* RX status buffer size is hard coded for now */ 436 return 2048; 437 } 438 439 static inline uint8_t* 440 hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { 441 uint32_t tlv_len, tlv_tag; 442 443 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); 444 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); 445 446 /* The actual length of PPDU_END is the combined lenght of many PHY 447 * TLVs that follow. Skip the TLV header and 448 * rx_rxpcu_classification_overview that follows the header to get to 449 * next TLV. 450 */ 451 if (tlv_tag == WIFIRX_PPDU_END_E) 452 tlv_len = sizeof(struct rx_rxpcu_classification_overview); 453 454 return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len + 455 HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3))); 456 } 457 458 static inline uint32_t 459 hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) 460 { 461 uint32_t tlv_tag, user_id, tlv_len, value; 462 uint8_t group_id = 0; 463 464 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); 465 user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv); 466 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); 467 468 rx_tlv = (uint8_t *) rx_tlv + HAL_RX_TLV32_HDR_SIZE; 469 470 switch (tlv_tag) { 471 472 case WIFIRX_PPDU_START_E: 473 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, 474 "[%s][%d] ppdu_start_e len=%d\n", 475 __func__, __LINE__, tlv_len); 476 ppdu_info->com_info.ppdu_id = 477 HAL_RX_GET(rx_tlv, RX_PPDU_START_0, 478 PHY_PPDU_ID); 479 /* TODO: Ensure channel number is set in PHY meta data */ 480 ppdu_info->rx_status.chan_freq = 481 HAL_RX_GET(rx_tlv, RX_PPDU_START_1, 482 SW_PHY_META_DATA); 483 ppdu_info->com_info.ppdu_timestamp = 484 HAL_RX_GET(rx_tlv, RX_PPDU_START_2, 485 PPDU_START_TIMESTAMP); 486 break; 487 488 case WIFIRX_PPDU_START_USER_INFO_E: 489 break; 490 491 case WIFIRX_PPDU_END_E: 492 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, 493 "[%s][%d] ppdu_end_e len=%d\n", 494 __func__, __LINE__, tlv_len); 495 /* This is followed by sub-TLVs of PPDU_END */ 496 497 ppdu_info->rx_status.duration = 498 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_8, 499 RX_PPDU_DURATION); 500 break; 501 502 case WIFIRXPCU_PPDU_END_INFO_E: 503 ppdu_info->rx_status.tsft = 504 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, 505 WB_TIMESTAMP_UPPER_32); 506 ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) | 507 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0, 508 WB_TIMESTAMP_LOWER_32); 509 break; 510 511 case WIFIRX_PPDU_END_USER_STATS_E: 512 { 513 unsigned long tid = 0; 514 515 ppdu_info->rx_status.ast_index = 516 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4, 517 AST_INDEX); 518 tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12, 519 RECEIVED_QOS_DATA_TID_BITMAP); 520 ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8); 521 ppdu_info->rx_status.mcs = 522 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, 523 MCS); 524 ppdu_info->rx_status.nss = 525 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, 526 NSS); 527 ppdu_info->rx_status.first_data_seq_ctrl = 528 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 529 DATA_SEQUENCE_CONTROL_INFO_VALID); 530 break; 531 } 532 533 case WIFIRX_PPDU_END_USER_STATS_EXT_E: 534 break; 535 536 case WIFIRX_PPDU_END_STATUS_DONE_E: 537 return HAL_TLV_STATUS_PPDU_DONE; 538 539 case WIFIDUMMY_E: 540 return HAL_TLV_STATUS_BUF_DONE; 541 542 case WIFIPHYRX_HT_SIG_E: 543 { 544 uint8_t *ht_sig_info = (uint8_t *)rx_tlv + 545 HAL_RX_OFFSET(PHYRX_HT_SIG_0, 546 HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS); 547 value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1, 548 FEC_CODING); 549 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 550 1 : 0; 551 break; 552 } 553 554 case WIFIPHYRX_L_SIG_B_E: 555 { 556 uint8_t *l_sig_b_info = (uint8_t *)rx_tlv + 557 HAL_RX_OFFSET(PHYRX_L_SIG_B_0, 558 L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS); 559 560 value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE); 561 switch (value) { 562 case 1: 563 ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS; 564 break; 565 case 2: 566 ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS; 567 break; 568 case 3: 569 ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS; 570 break; 571 case 4: 572 ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS; 573 break; 574 case 5: 575 ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS; 576 break; 577 case 6: 578 ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS; 579 break; 580 case 7: 581 ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS; 582 break; 583 default: 584 break; 585 } 586 break; 587 } 588 589 case WIFIPHYRX_L_SIG_A_E: 590 { 591 uint8_t *l_sig_a_info = (uint8_t *)rx_tlv + 592 HAL_RX_OFFSET(PHYRX_L_SIG_A_0, 593 L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS); 594 595 value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE); 596 switch (value) { 597 case 8: 598 ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS; 599 break; 600 case 9: 601 ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS; 602 break; 603 case 10: 604 ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS; 605 break; 606 case 11: 607 ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS; 608 break; 609 case 12: 610 ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS; 611 break; 612 case 13: 613 ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS; 614 break; 615 case 14: 616 ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS; 617 break; 618 case 15: 619 ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS; 620 break; 621 default: 622 break; 623 } 624 break; 625 } 626 627 case WIFIPHYRX_VHT_SIG_A_E: 628 { 629 uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv + 630 HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0, 631 VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS); 632 633 value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, 634 SU_MU_CODING); 635 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 636 1 : 0; 637 group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID); 638 ppdu_info->rx_status.vht_flag_values5 = group_id; 639 break; 640 } 641 case WIFIPHYRX_HE_SIG_A_SU_E: 642 ppdu_info->rx_status.he_sig_A1 = 643 *((uint32_t *)((uint8_t *)rx_tlv + 644 HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0, 645 HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); 646 ppdu_info->rx_status.he_sig_A1 |= 647 QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU; 648 /* TODO: Enabling all known bits. Check if this should be 649 * enabled selectively 650 */ 651 ppdu_info->rx_status.he_sig_A1_known = 652 QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL; 653 ppdu_info->rx_status.he_sig_A2 = 654 *((uint32_t *)((uint8_t *)rx_tlv + 655 HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_1, 656 HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); 657 ppdu_info->rx_status.he_sig_A2_known = 658 QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL; 659 break; 660 case WIFIPHYRX_HE_SIG_A_MU_DL_E: 661 ppdu_info->rx_status.he_sig_A1 = 662 *((uint32_t *)((uint8_t *)rx_tlv + 663 HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0, 664 HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); 665 ppdu_info->rx_status.he_sig_A1 |= 666 QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU; 667 ppdu_info->rx_status.he_sig_A1_known = 668 QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL; 669 670 ppdu_info->rx_status.he_sig_A2 = 671 *((uint32_t *)((uint8_t *)rx_tlv + 672 HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_1, 673 HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); 674 ppdu_info->rx_status.he_sig_A2_known = 675 QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL; 676 break; 677 case WIFIPHYRX_HE_SIG_B1_MU_E: 678 { 679 uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv + 680 *((uint32_t *)((uint8_t *)rx_tlv + 681 HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0, 682 HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS))); 683 684 ppdu_info->rx_status.he_sig_b_common_RU[0] = 685 HAL_RX_GET(he_sig_b1_mu_info, HE_SIG_B1_MU_INFO_0, 686 RU_ALLOCATION); 687 688 ppdu_info->rx_status.he_sig_b_common_known = 689 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; 690 /* TODO: Check on the availability of other fields in 691 * sig_b_common 692 */ 693 break; 694 } 695 case WIFIPHYRX_HE_SIG_B2_MU_E: 696 ppdu_info->rx_status.he_sig_b_user = 697 *((uint32_t *)((uint8_t *)rx_tlv + 698 HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0, 699 HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS))); 700 ppdu_info->rx_status.he_sig_b_user_known = 701 QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; 702 break; 703 case WIFIPHYRX_HE_SIG_B2_OFDMA_E: 704 ppdu_info->rx_status.he_sig_b_user = 705 *((uint32_t *)((uint8_t *)rx_tlv + 706 HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0, 707 HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS))); 708 ppdu_info->rx_status.he_sig_b_user_known = 709 QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; 710 break; 711 case WIFIPHYRX_RSSI_LEGACY_E: 712 { 713 uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + 714 HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3, 715 RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS); 716 717 ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rssi_info_tlv, 718 PHYRX_RSSI_LEGACY_35, RSSI_COMB); 719 ppdu_info->rx_status.bw = HAL_RX_GET(rssi_info_tlv, 720 PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH); 721 ppdu_info->rx_status.preamble_type = HAL_RX_GET(rssi_info_tlv, 722 PHYRX_RSSI_LEGACY_0, RECEPTION_TYPE); 723 ppdu_info->rx_status.he_re = 0; 724 725 value = HAL_RX_GET(rssi_info_tlv, 726 RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); 727 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 728 "RSSI_PRI20_CHAIN0: %d\n", value); 729 730 value = HAL_RX_GET(rssi_info_tlv, 731 RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0); 732 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 733 "RSSI_EXT20_CHAIN0: %d\n", value); 734 735 value = HAL_RX_GET(rssi_info_tlv, 736 RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0); 737 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 738 "RSSI_EXT40_LOW20_CHAIN0: %d\n", value); 739 740 value = HAL_RX_GET(rssi_info_tlv, 741 RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0); 742 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 743 "RSSI_EXT40_HIGH20_CHAIN0: %d\n", value); 744 745 value = HAL_RX_GET(rssi_info_tlv, 746 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0); 747 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 748 "RSSI_EXT80_LOW20_CHAIN0: %d\n", value); 749 750 value = HAL_RX_GET(rssi_info_tlv, 751 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0); 752 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 753 "RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value); 754 755 value = HAL_RX_GET(rssi_info_tlv, 756 RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0); 757 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 758 "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value); 759 760 value = HAL_RX_GET(rssi_info_tlv, 761 RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0); 762 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 763 "RSSI_EXT80_HIGH20_CHAIN0: %d\n", value); 764 break; 765 } 766 case 0: 767 return HAL_TLV_STATUS_PPDU_DONE; 768 769 default: 770 break; 771 } 772 773 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, 774 "%s TLV type: %d, TLV len:%d\n", 775 __func__, tlv_tag, tlv_len); 776 777 return HAL_TLV_STATUS_PPDU_NOT_DONE; 778 } 779 780 static inline 781 uint32_t hal_get_rx_status_done_tlv_size(void *hal_soc) 782 { 783 return HAL_RX_TLV32_HDR_SIZE; 784 } 785 786 static inline QDF_STATUS 787 hal_get_rx_status_done(uint8_t *rx_tlv) 788 { 789 uint32_t tlv_tag; 790 791 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); 792 793 if (tlv_tag == WIFIRX_STATUS_BUFFER_DONE_E) 794 return QDF_STATUS_SUCCESS; 795 else 796 return QDF_STATUS_E_EMPTY; 797 } 798 799 static inline QDF_STATUS 800 hal_clear_rx_status_done(uint8_t *rx_tlv) 801 { 802 *(uint32_t *)rx_tlv = 0; 803 return QDF_STATUS_SUCCESS; 804 } 805 806 #endif 807