1 /* 2 * Copyright (c) 2016-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 #include "qdf_util.h" 19 #include "qdf_types.h" 20 #include "qdf_lock.h" 21 #include "qdf_mem.h" 22 #include "qdf_nbuf.h" 23 #include "tcl_data_cmd.h" 24 #include "mac_tcl_reg_seq_hwioreg.h" 25 #include "phyrx_rssi_legacy.h" 26 #include "rx_msdu_start.h" 27 #include "tlv_tag_def.h" 28 #include "hal_hw_headers.h" 29 #include "hal_internal.h" 30 #include "cdp_txrx_mon_struct.h" 31 #include "qdf_trace.h" 32 #include "hal_rx.h" 33 #include "hal_tx.h" 34 #include "dp_types.h" 35 #include "hal_api_mon.h" 36 #include "phyrx_other_receive_info_ru_details.h" 37 38 #if defined(QCA_WIFI_QCA6290_11AX) 39 #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ 40 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ 41 RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ 42 RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ 43 RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) 44 45 /* 46 * hal_rx_msdu_start_nss_get_6290(): API to get the NSS 47 * Interval from rx_msdu_start 48 * 49 * @buf: pointer to the start of RX PKT TLV header 50 * Return: uint32_t(nss) 51 */ 52 static uint32_t 53 hal_rx_msdu_start_nss_get_6290(uint8_t *buf) 54 { 55 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 56 struct rx_msdu_start *msdu_start = 57 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 58 uint8_t mimo_ss_bitmap; 59 60 mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); 61 62 return qdf_get_hweight8(mimo_ss_bitmap); 63 } 64 #else 65 static uint32_t 66 hal_rx_msdu_start_nss_get_6290(uint8_t *buf) 67 { 68 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 69 struct rx_msdu_start *msdu_start = 70 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 71 uint32_t nss; 72 73 nss = HAL_RX_MSDU_START_NSS_GET(msdu_start); 74 return nss; 75 } 76 #endif 77 78 /** 79 * hal_rx_mon_hw_desc_get_mpdu_status_6290(): Retrieve MPDU status 80 * 81 * @ hw_desc_addr: Start address of Rx HW TLVs 82 * @ rs: Status for monitor mode 83 * 84 * Return: void 85 */ 86 static void hal_rx_mon_hw_desc_get_mpdu_status_6290(void *hw_desc_addr, 87 struct mon_rx_status *rs) 88 { 89 struct rx_msdu_start *rx_msdu_start; 90 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 91 uint32_t reg_value; 92 const uint32_t sgi_hw_to_cdp[] = { 93 CDP_SGI_0_8_US, 94 CDP_SGI_0_4_US, 95 CDP_SGI_1_6_US, 96 CDP_SGI_3_2_US, 97 }; 98 99 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 100 101 HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); 102 103 rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, 104 RX_MSDU_START_5, USER_RSSI); 105 rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); 106 107 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); 108 rs->sgi = sgi_hw_to_cdp[reg_value]; 109 #if !defined(QCA_WIFI_QCA6290_11AX) 110 rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); 111 #endif 112 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); 113 switch (reg_value) { 114 case HAL_RX_PKT_TYPE_11N: 115 rs->ht_flags = 1; 116 break; 117 case HAL_RX_PKT_TYPE_11AC: 118 rs->vht_flags = 1; 119 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, 120 RECEIVE_BANDWIDTH); 121 rs->vht_flag_values2 = reg_value; 122 break; 123 case HAL_RX_PKT_TYPE_11AX: 124 rs->he_flags = 1; 125 break; 126 default: 127 break; 128 } 129 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); 130 rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; 131 /* TODO: rs->beamformed should be set for SU beamforming also */ 132 } 133 134 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) 135 136 static uint32_t hal_get_link_desc_size_6290(void) 137 { 138 return LINK_DESC_SIZE; 139 } 140 141 142 #ifdef QCA_WIFI_QCA6290_11AX 143 /* 144 * hal_rx_get_tlv_6290(): API to get the tlv 145 * 146 * @rx_tlv: TLV data extracted from the rx packet 147 * Return: uint8_t 148 */ 149 static uint8_t hal_rx_get_tlv_6290(void *rx_tlv) 150 { 151 return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); 152 } 153 #else 154 static uint8_t hal_rx_get_tlv_6290(void *rx_tlv) 155 { 156 return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH); 157 } 158 #endif 159 160 #ifdef QCA_WIFI_QCA6290_11AX 161 /** 162 * hal_rx_proc_phyrx_other_receive_info_tlv_6290() 163 * - process other receive info TLV 164 * @rx_tlv_hdr: pointer to TLV header 165 * @ppdu_info: pointer to ppdu_info 166 * 167 * Return: None 168 */ 169 static 170 void hal_rx_proc_phyrx_other_receive_info_tlv_6290(void *rx_tlv_hdr, 171 void *ppdu_info_handle) 172 { 173 uint32_t tlv_tag, tlv_len; 174 uint32_t temp_len, other_tlv_len, other_tlv_tag; 175 void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 176 void *other_tlv_hdr = NULL; 177 void *other_tlv = NULL; 178 uint32_t ru_details_channel_0; 179 struct hal_rx_ppdu_info *ppdu_info = 180 (struct hal_rx_ppdu_info *)ppdu_info_handle; 181 182 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); 183 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); 184 temp_len = 0; 185 186 other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; 187 188 other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); 189 other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); 190 temp_len += other_tlv_len; 191 other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 192 193 switch (other_tlv_tag) { 194 case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E: 195 ru_details_channel_0 = 196 HAL_RX_GET(other_tlv, 197 PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0, 198 RU_DETAILS_CHANNEL_0); 199 200 qdf_mem_copy(ppdu_info->rx_status.he_RU, 201 &ru_details_channel_0, 202 sizeof(ppdu_info->rx_status.he_RU)); 203 204 if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20) 205 ppdu_info->rx_status.he_sig_b_common_known |= 206 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; 207 208 if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40) 209 ppdu_info->rx_status.he_sig_b_common_known |= 210 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1; 211 212 if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80) 213 ppdu_info->rx_status.he_sig_b_common_known |= 214 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2; 215 216 if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160) 217 ppdu_info->rx_status.he_sig_b_common_known |= 218 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3; 219 break; 220 default: 221 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 222 "%s unhandled TLV type: %d, TLV len:%d", 223 __func__, other_tlv_tag, other_tlv_len); 224 break; 225 } 226 } 227 #else 228 static 229 void hal_rx_proc_phyrx_other_receive_info_tlv_6290(void *rx_tlv_hdr, 230 void *ppdu_info_handle) 231 { 232 } 233 #endif /* QCA_WIFI_QCA6290_11AX */ 234 235 /** 236 * hal_rx_dump_msdu_start_tlv_6290() : dump RX msdu_start TLV in structured 237 * human readable format. 238 * @ msdu_start: pointer the msdu_start TLV in pkt. 239 * @ dbg_level: log level. 240 * 241 * Return: void 242 */ 243 static void hal_rx_dump_msdu_start_tlv_6290(void *msdustart, 244 uint8_t dbg_level) 245 { 246 struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; 247 248 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 249 "rx_msdu_start tlv - " 250 "rxpcu_mpdu_filter_in_category: %d " 251 "sw_frame_group_id: %d " 252 "phy_ppdu_id: %d " 253 "msdu_length: %d " 254 "ipsec_esp: %d " 255 "l3_offset: %d " 256 "ipsec_ah: %d " 257 "l4_offset: %d " 258 "msdu_number: %d " 259 "decap_format: %d " 260 "ipv4_proto: %d " 261 "ipv6_proto: %d " 262 "tcp_proto: %d " 263 "udp_proto: %d " 264 "ip_frag: %d " 265 "tcp_only_ack: %d " 266 "da_is_bcast_mcast: %d " 267 "ip4_protocol_ip6_next_header: %d " 268 "toeplitz_hash_2_or_4: %d " 269 "flow_id_toeplitz: %d " 270 "user_rssi: %d " 271 "pkt_type: %d " 272 "stbc: %d " 273 "sgi: %d " 274 "rate_mcs: %d " 275 "receive_bandwidth: %d " 276 "reception_type: %d " 277 #if !defined(QCA_WIFI_QCA6290_11AX) 278 "toeplitz_hash: %d " 279 "nss: %d " 280 #endif 281 "ppdu_start_timestamp: %d " 282 "sw_phy_meta_data: %d ", 283 msdu_start->rxpcu_mpdu_filter_in_category, 284 msdu_start->sw_frame_group_id, 285 msdu_start->phy_ppdu_id, 286 msdu_start->msdu_length, 287 msdu_start->ipsec_esp, 288 msdu_start->l3_offset, 289 msdu_start->ipsec_ah, 290 msdu_start->l4_offset, 291 msdu_start->msdu_number, 292 msdu_start->decap_format, 293 msdu_start->ipv4_proto, 294 msdu_start->ipv6_proto, 295 msdu_start->tcp_proto, 296 msdu_start->udp_proto, 297 msdu_start->ip_frag, 298 msdu_start->tcp_only_ack, 299 msdu_start->da_is_bcast_mcast, 300 msdu_start->ip4_protocol_ip6_next_header, 301 msdu_start->toeplitz_hash_2_or_4, 302 msdu_start->flow_id_toeplitz, 303 msdu_start->user_rssi, 304 msdu_start->pkt_type, 305 msdu_start->stbc, 306 msdu_start->sgi, 307 msdu_start->rate_mcs, 308 msdu_start->receive_bandwidth, 309 msdu_start->reception_type, 310 #if !defined(QCA_WIFI_QCA6290_11AX) 311 msdu_start->toeplitz_hash, 312 msdu_start->nss, 313 #endif 314 msdu_start->ppdu_start_timestamp, 315 msdu_start->sw_phy_meta_data); 316 } 317 318 /** 319 * hal_rx_dump_msdu_end_tlv_6290: dump RX msdu_end TLV in structured 320 * human readable format. 321 * @ msdu_end: pointer the msdu_end TLV in pkt. 322 * @ dbg_level: log level. 323 * 324 * Return: void 325 */ 326 static void hal_rx_dump_msdu_end_tlv_6290(void *msduend, 327 uint8_t dbg_level) 328 { 329 struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; 330 331 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 332 "rx_msdu_end tlv - " 333 "rxpcu_mpdu_filter_in_category: %d " 334 "sw_frame_group_id: %d " 335 "phy_ppdu_id: %d " 336 "ip_hdr_chksum: %d " 337 "tcp_udp_chksum: %d " 338 "key_id_octet: %d " 339 "cce_super_rule: %d " 340 "cce_classify_not_done_truncat: %d " 341 "cce_classify_not_done_cce_dis: %d " 342 "ext_wapi_pn_63_48: %d " 343 "ext_wapi_pn_95_64: %d " 344 "ext_wapi_pn_127_96: %d " 345 "reported_mpdu_length: %d " 346 "first_msdu: %d " 347 "last_msdu: %d " 348 "sa_idx_timeout: %d " 349 "da_idx_timeout: %d " 350 "msdu_limit_error: %d " 351 "flow_idx_timeout: %d " 352 "flow_idx_invalid: %d " 353 "wifi_parser_error: %d " 354 "amsdu_parser_error: %d " 355 "sa_is_valid: %d " 356 "da_is_valid: %d " 357 "da_is_mcbc: %d " 358 "l3_header_padding: %d " 359 "ipv6_options_crc: %d " 360 "tcp_seq_number: %d " 361 "tcp_ack_number: %d " 362 "tcp_flag: %d " 363 "lro_eligible: %d " 364 "window_size: %d " 365 "da_offset: %d " 366 "sa_offset: %d " 367 "da_offset_valid: %d " 368 "sa_offset_valid: %d " 369 "rule_indication_31_0: %d " 370 "rule_indication_63_32: %d " 371 "sa_idx: %d " 372 "da_idx: %d " 373 "msdu_drop: %d " 374 "reo_destination_indication: %d " 375 "flow_idx: %d " 376 "fse_metadata: %d " 377 "cce_metadata: %d " 378 "sa_sw_peer_id: %d ", 379 msdu_end->rxpcu_mpdu_filter_in_category, 380 msdu_end->sw_frame_group_id, 381 msdu_end->phy_ppdu_id, 382 msdu_end->ip_hdr_chksum, 383 msdu_end->tcp_udp_chksum, 384 msdu_end->key_id_octet, 385 msdu_end->cce_super_rule, 386 msdu_end->cce_classify_not_done_truncate, 387 msdu_end->cce_classify_not_done_cce_dis, 388 msdu_end->ext_wapi_pn_63_48, 389 msdu_end->ext_wapi_pn_95_64, 390 msdu_end->ext_wapi_pn_127_96, 391 msdu_end->reported_mpdu_length, 392 msdu_end->first_msdu, 393 msdu_end->last_msdu, 394 msdu_end->sa_idx_timeout, 395 msdu_end->da_idx_timeout, 396 msdu_end->msdu_limit_error, 397 msdu_end->flow_idx_timeout, 398 msdu_end->flow_idx_invalid, 399 msdu_end->wifi_parser_error, 400 msdu_end->amsdu_parser_error, 401 msdu_end->sa_is_valid, 402 msdu_end->da_is_valid, 403 msdu_end->da_is_mcbc, 404 msdu_end->l3_header_padding, 405 msdu_end->ipv6_options_crc, 406 msdu_end->tcp_seq_number, 407 msdu_end->tcp_ack_number, 408 msdu_end->tcp_flag, 409 msdu_end->lro_eligible, 410 msdu_end->window_size, 411 msdu_end->da_offset, 412 msdu_end->sa_offset, 413 msdu_end->da_offset_valid, 414 msdu_end->sa_offset_valid, 415 msdu_end->rule_indication_31_0, 416 msdu_end->rule_indication_63_32, 417 msdu_end->sa_idx, 418 msdu_end->da_idx, 419 msdu_end->msdu_drop, 420 msdu_end->reo_destination_indication, 421 msdu_end->flow_idx, 422 msdu_end->fse_metadata, 423 msdu_end->cce_metadata, 424 msdu_end->sa_sw_peer_id); 425 } 426 427 428 /* 429 * Get tid from RX_MPDU_START 430 */ 431 #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ 432 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ 433 RX_MPDU_INFO_3_TID_OFFSET)), \ 434 RX_MPDU_INFO_3_TID_MASK, \ 435 RX_MPDU_INFO_3_TID_LSB)) 436 437 static uint32_t hal_rx_mpdu_start_tid_get_6290(uint8_t *buf) 438 { 439 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 440 struct rx_mpdu_start *mpdu_start = 441 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; 442 uint32_t tid; 443 444 tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); 445 446 return tid; 447 } 448 449 #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ 450 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ 451 RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ 452 RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ 453 RX_MSDU_START_5_RECEPTION_TYPE_LSB)) 454 455 /* 456 * hal_rx_msdu_start_reception_type_get(): API to get the reception type 457 * Interval from rx_msdu_start 458 * 459 * @buf: pointer to the start of RX PKT TLV header 460 * Return: uint32_t(reception_type) 461 */ 462 static uint32_t hal_rx_msdu_start_reception_type_get_6290(uint8_t *buf) 463 { 464 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 465 struct rx_msdu_start *msdu_start = 466 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 467 uint32_t reception_type; 468 469 reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); 470 471 return reception_type; 472 } 473 474 #define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ 475 (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ 476 RX_MSDU_END_13_DA_IDX_OFFSET)), \ 477 RX_MSDU_END_13_DA_IDX_MASK, \ 478 RX_MSDU_END_13_DA_IDX_LSB)) 479 480 /** 481 * hal_rx_msdu_end_da_idx_get_6290: API to get da_idx 482 * from rx_msdu_end TLV 483 * 484 * @ buf: pointer to the start of RX PKT TLV headers 485 * Return: da index 486 */ 487 static uint16_t hal_rx_msdu_end_da_idx_get_6290(uint8_t *buf) 488 { 489 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 490 struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; 491 uint16_t da_idx; 492 493 da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); 494 495 return da_idx; 496 } 497 498