1 /* 2 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #include "qdf_util.h" 30 #include "qdf_types.h" 31 #include "qdf_lock.h" 32 #include "qdf_mem.h" 33 #include "qdf_nbuf.h" 34 #include "tcl_data_cmd.h" 35 #include "mac_tcl_reg_seq_hwioreg.h" 36 #include "phyrx_rssi_legacy.h" 37 #include "rx_msdu_start.h" 38 #include "tlv_tag_def.h" 39 #include "hal_hw_headers.h" 40 #include "hal_internal.h" 41 #include "cdp_txrx_mon_struct.h" 42 #include "qdf_trace.h" 43 #include "hal_rx.h" 44 #include "hal_tx.h" 45 #include "dp_types.h" 46 #include "hal_api_mon.h" 47 #include "phyrx_other_receive_info_ru_details.h" 48 49 #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ 50 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ 51 RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ 52 RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ 53 RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) 54 55 /* 56 * hal_rx_msdu_start_nss_get_6390(): API to get the NSS 57 * Interval from rx_msdu_start 58 * 59 * @buf: pointer to the start of RX PKT TLV header 60 * Return: uint32_t(nss) 61 */ 62 static uint32_t 63 hal_rx_msdu_start_nss_get_6390(uint8_t *buf) 64 { 65 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 66 struct rx_msdu_start *msdu_start = 67 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 68 uint8_t mimo_ss_bitmap; 69 70 mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); 71 72 return qdf_get_hweight8(mimo_ss_bitmap); 73 } 74 75 /** 76 * hal_rx_mon_hw_desc_get_mpdu_status_6390(): Retrieve MPDU status 77 * 78 * @ hw_desc_addr: Start address of Rx HW TLVs 79 * @ rs: Status for monitor mode 80 * 81 * Return: void 82 */ 83 static void hal_rx_mon_hw_desc_get_mpdu_status_6390(void *hw_desc_addr, 84 struct mon_rx_status *rs) 85 { 86 struct rx_msdu_start *rx_msdu_start; 87 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 88 uint32_t reg_value; 89 const uint32_t sgi_hw_to_cdp[] = { 90 CDP_SGI_0_8_US, 91 CDP_SGI_0_4_US, 92 CDP_SGI_1_6_US, 93 CDP_SGI_3_2_US, 94 }; 95 96 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 97 98 HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); 99 100 rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, 101 RX_MSDU_START_5, USER_RSSI); 102 rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); 103 104 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); 105 rs->sgi = sgi_hw_to_cdp[reg_value]; 106 107 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); 108 switch (reg_value) { 109 case HAL_RX_PKT_TYPE_11N: 110 rs->ht_flags = 1; 111 break; 112 case HAL_RX_PKT_TYPE_11AC: 113 rs->vht_flags = 1; 114 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, 115 RECEIVE_BANDWIDTH); 116 rs->vht_flag_values2 = reg_value; 117 break; 118 case HAL_RX_PKT_TYPE_11AX: 119 rs->he_flags = 1; 120 break; 121 default: 122 break; 123 } 124 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); 125 rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; 126 /* TODO: rs->beamformed should be set for SU beamforming also */ 127 } 128 129 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) 130 131 static uint32_t hal_get_link_desc_size_6390(void) 132 { 133 return LINK_DESC_SIZE; 134 } 135 136 /* 137 * hal_rx_get_tlv_6390(): API to get the tlv 138 * 139 * @rx_tlv: TLV data extracted from the rx packet 140 * Return: uint8_t 141 */ 142 static uint8_t hal_rx_get_tlv_6390(void *rx_tlv) 143 { 144 return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); 145 } 146 147 /** 148 * hal_rx_proc_phyrx_other_receive_info_tlv_6390() 149 * - process other receive info TLV 150 * @rx_tlv_hdr: pointer to TLV header 151 * @ppdu_info: pointer to ppdu_info 152 * 153 * Return: None 154 */ 155 static 156 void hal_rx_proc_phyrx_other_receive_info_tlv_6390(void *rx_tlv_hdr, 157 void *ppdu_info_handle) 158 { 159 uint32_t tlv_tag, tlv_len; 160 uint32_t temp_len, other_tlv_len, other_tlv_tag; 161 void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 162 void *other_tlv_hdr = NULL; 163 void *other_tlv = NULL; 164 165 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); 166 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); 167 temp_len = 0; 168 169 other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; 170 171 other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); 172 other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); 173 temp_len += other_tlv_len; 174 other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 175 176 switch (other_tlv_tag) { 177 default: 178 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 179 "%s unhandled TLV type: %d, TLV len:%d", 180 __func__, other_tlv_tag, other_tlv_len); 181 break; 182 } 183 } 184 185 /** 186 * hal_rx_dump_msdu_start_tlv_6390() : dump RX msdu_start TLV in structured 187 * human readable format. 188 * @ msdu_start: pointer the msdu_start TLV in pkt. 189 * @ dbg_level: log level. 190 * 191 * Return: void 192 */ 193 static void hal_rx_dump_msdu_start_tlv_6390(void *msdustart, uint8_t dbg_level) 194 { 195 struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; 196 197 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 198 "rx_msdu_start tlv - " 199 "rxpcu_mpdu_filter_in_category: %d " 200 "sw_frame_group_id: %d " 201 "phy_ppdu_id: %d " 202 "msdu_length: %d " 203 "ipsec_esp: %d " 204 "l3_offset: %d " 205 "ipsec_ah: %d " 206 "l4_offset: %d " 207 "msdu_number: %d " 208 "decap_format: %d " 209 "ipv4_proto: %d " 210 "ipv6_proto: %d " 211 "tcp_proto: %d " 212 "udp_proto: %d " 213 "ip_frag: %d " 214 "tcp_only_ack: %d " 215 "da_is_bcast_mcast: %d " 216 "ip4_protocol_ip6_next_header: %d " 217 "toeplitz_hash_2_or_4: %d " 218 "flow_id_toeplitz: %d " 219 "user_rssi: %d " 220 "pkt_type: %d " 221 "stbc: %d " 222 "sgi: %d " 223 "rate_mcs: %d " 224 "receive_bandwidth: %d " 225 "reception_type: %d " 226 "ppdu_start_timestamp: %d " 227 "sw_phy_meta_data: %d ", 228 msdu_start->rxpcu_mpdu_filter_in_category, 229 msdu_start->sw_frame_group_id, 230 msdu_start->phy_ppdu_id, 231 msdu_start->msdu_length, 232 msdu_start->ipsec_esp, 233 msdu_start->l3_offset, 234 msdu_start->ipsec_ah, 235 msdu_start->l4_offset, 236 msdu_start->msdu_number, 237 msdu_start->decap_format, 238 msdu_start->ipv4_proto, 239 msdu_start->ipv6_proto, 240 msdu_start->tcp_proto, 241 msdu_start->udp_proto, 242 msdu_start->ip_frag, 243 msdu_start->tcp_only_ack, 244 msdu_start->da_is_bcast_mcast, 245 msdu_start->ip4_protocol_ip6_next_header, 246 msdu_start->toeplitz_hash_2_or_4, 247 msdu_start->flow_id_toeplitz, 248 msdu_start->user_rssi, 249 msdu_start->pkt_type, 250 msdu_start->stbc, 251 msdu_start->sgi, 252 msdu_start->rate_mcs, 253 msdu_start->receive_bandwidth, 254 msdu_start->reception_type, 255 msdu_start->ppdu_start_timestamp, 256 msdu_start->sw_phy_meta_data); 257 } 258 259 /** 260 * hal_rx_dump_msdu_end_tlv_6390: dump RX msdu_end TLV in structured 261 * human readable format. 262 * @ msdu_end: pointer the msdu_end TLV in pkt. 263 * @ dbg_level: log level. 264 * 265 * Return: void 266 */ 267 static void hal_rx_dump_msdu_end_tlv_6390(void *msduend, 268 uint8_t dbg_level) 269 { 270 struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; 271 272 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 273 "rx_msdu_end tlv - " 274 "rxpcu_mpdu_filter_in_category: %d " 275 "sw_frame_group_id: %d " 276 "phy_ppdu_id: %d " 277 "ip_hdr_chksum: %d " 278 "tcp_udp_chksum: %d " 279 "key_id_octet: %d " 280 "cce_super_rule: %d " 281 "cce_classify_not_done_truncat: %d " 282 "cce_classify_not_done_cce_dis: %d " 283 "ext_wapi_pn_63_48: %d " 284 "ext_wapi_pn_95_64: %d " 285 "ext_wapi_pn_127_96: %d " 286 "reported_mpdu_length: %d " 287 "first_msdu: %d " 288 "last_msdu: %d " 289 "sa_idx_timeout: %d " 290 "da_idx_timeout: %d " 291 "msdu_limit_error: %d " 292 "flow_idx_timeout: %d " 293 "flow_idx_invalid: %d " 294 "wifi_parser_error: %d " 295 "amsdu_parser_error: %d " 296 "sa_is_valid: %d " 297 "da_is_valid: %d " 298 "da_is_mcbc: %d " 299 "l3_header_padding: %d " 300 "ipv6_options_crc: %d " 301 "tcp_seq_number: %d " 302 "tcp_ack_number: %d " 303 "tcp_flag: %d " 304 "lro_eligible: %d " 305 "window_size: %d " 306 "da_offset: %d " 307 "sa_offset: %d " 308 "da_offset_valid: %d " 309 "sa_offset_valid: %d " 310 "rule_indication_31_0: %d " 311 "rule_indication_63_32: %d " 312 "sa_idx: %d " 313 "da_idx: %d " 314 "msdu_drop: %d " 315 "reo_destination_indication: %d " 316 "flow_idx: %d " 317 "fse_metadata: %d " 318 "cce_metadata: %d " 319 "sa_sw_peer_id: %d ", 320 msdu_end->rxpcu_mpdu_filter_in_category, 321 msdu_end->sw_frame_group_id, 322 msdu_end->phy_ppdu_id, 323 msdu_end->ip_hdr_chksum, 324 msdu_end->tcp_udp_chksum, 325 msdu_end->key_id_octet, 326 msdu_end->cce_super_rule, 327 msdu_end->cce_classify_not_done_truncate, 328 msdu_end->cce_classify_not_done_cce_dis, 329 msdu_end->ext_wapi_pn_63_48, 330 msdu_end->ext_wapi_pn_95_64, 331 msdu_end->ext_wapi_pn_127_96, 332 msdu_end->reported_mpdu_length, 333 msdu_end->first_msdu, 334 msdu_end->last_msdu, 335 msdu_end->sa_idx_timeout, 336 msdu_end->da_idx_timeout, 337 msdu_end->msdu_limit_error, 338 msdu_end->flow_idx_timeout, 339 msdu_end->flow_idx_invalid, 340 msdu_end->wifi_parser_error, 341 msdu_end->amsdu_parser_error, 342 msdu_end->sa_is_valid, 343 msdu_end->da_is_valid, 344 msdu_end->da_is_mcbc, 345 msdu_end->l3_header_padding, 346 msdu_end->ipv6_options_crc, 347 msdu_end->tcp_seq_number, 348 msdu_end->tcp_ack_number, 349 msdu_end->tcp_flag, 350 msdu_end->lro_eligible, 351 msdu_end->window_size, 352 msdu_end->da_offset, 353 msdu_end->sa_offset, 354 msdu_end->da_offset_valid, 355 msdu_end->sa_offset_valid, 356 msdu_end->rule_indication_31_0, 357 msdu_end->rule_indication_63_32, 358 msdu_end->sa_idx, 359 msdu_end->da_idx_or_sw_peer_id, 360 msdu_end->msdu_drop, 361 msdu_end->reo_destination_indication, 362 msdu_end->flow_idx, 363 msdu_end->fse_metadata, 364 msdu_end->cce_metadata, 365 msdu_end->sa_sw_peer_id); 366 } 367 368 369 /* 370 * Get tid from RX_MPDU_START 371 */ 372 #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ 373 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ 374 RX_MPDU_INFO_3_TID_OFFSET)), \ 375 RX_MPDU_INFO_3_TID_MASK, \ 376 RX_MPDU_INFO_3_TID_LSB)) 377 378 static uint32_t hal_rx_mpdu_start_tid_get_6390(uint8_t *buf) 379 { 380 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 381 struct rx_mpdu_start *mpdu_start = 382 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; 383 uint32_t tid; 384 385 tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); 386 387 return tid; 388 } 389 390 #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ 391 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ 392 RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ 393 RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ 394 RX_MSDU_START_5_RECEPTION_TYPE_LSB)) 395 396 /* 397 * hal_rx_msdu_start_reception_type_get(): API to get the reception type 398 * Interval from rx_msdu_start 399 * 400 * @buf: pointer to the start of RX PKT TLV header 401 * Return: uint32_t(reception_type) 402 */ 403 static 404 uint32_t hal_rx_msdu_start_reception_type_get_6390(uint8_t *buf) 405 { 406 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 407 struct rx_msdu_start *msdu_start = 408 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 409 uint32_t reception_type; 410 411 reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); 412 413 return reception_type; 414 } 415 416 #define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ 417 (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ 418 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ 419 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_MASK, \ 420 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_LSB)) 421 422 /** 423 * hal_rx_msdu_end_da_idx_get_6390: API to get da_idx 424 * from rx_msdu_end TLV 425 * 426 * @ buf: pointer to the start of RX PKT TLV headers 427 * Return: da index 428 */ 429 static uint16_t hal_rx_msdu_end_da_idx_get_6390(uint8_t *buf) 430 { 431 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 432 struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; 433 uint16_t da_idx; 434 435 da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); 436 437 return da_idx; 438 } 439 440