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 #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ 39 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ 40 RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ 41 RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ 42 RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) 43 44 /* 45 * hal_rx_msdu_start_nss_get_6390(): API to get the NSS 46 * Interval from rx_msdu_start 47 * 48 * @buf: pointer to the start of RX PKT TLV header 49 * Return: uint32_t(nss) 50 */ 51 static uint32_t 52 hal_rx_msdu_start_nss_get_6390(uint8_t *buf) 53 { 54 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 55 struct rx_msdu_start *msdu_start = 56 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 57 uint8_t mimo_ss_bitmap; 58 59 mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); 60 61 return qdf_get_hweight8(mimo_ss_bitmap); 62 } 63 64 /** 65 * hal_rx_mon_hw_desc_get_mpdu_status_6390(): Retrieve MPDU status 66 * 67 * @ hw_desc_addr: Start address of Rx HW TLVs 68 * @ rs: Status for monitor mode 69 * 70 * Return: void 71 */ 72 static void hal_rx_mon_hw_desc_get_mpdu_status_6390(void *hw_desc_addr, 73 struct mon_rx_status *rs) 74 { 75 struct rx_msdu_start *rx_msdu_start; 76 struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; 77 uint32_t reg_value; 78 const uint32_t sgi_hw_to_cdp[] = { 79 CDP_SGI_0_8_US, 80 CDP_SGI_0_4_US, 81 CDP_SGI_1_6_US, 82 CDP_SGI_3_2_US, 83 }; 84 85 rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; 86 87 HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); 88 89 rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, 90 RX_MSDU_START_5, USER_RSSI); 91 rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); 92 93 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); 94 rs->sgi = sgi_hw_to_cdp[reg_value]; 95 96 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); 97 switch (reg_value) { 98 case HAL_RX_PKT_TYPE_11N: 99 rs->ht_flags = 1; 100 break; 101 case HAL_RX_PKT_TYPE_11AC: 102 rs->vht_flags = 1; 103 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, 104 RECEIVE_BANDWIDTH); 105 rs->vht_flag_values2 = reg_value; 106 break; 107 case HAL_RX_PKT_TYPE_11AX: 108 rs->he_flags = 1; 109 break; 110 default: 111 break; 112 } 113 reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); 114 rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; 115 /* TODO: rs->beamformed should be set for SU beamforming also */ 116 } 117 118 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) 119 120 static uint32_t hal_get_link_desc_size_6390(void) 121 { 122 return LINK_DESC_SIZE; 123 } 124 125 /* 126 * hal_rx_get_tlv_6390(): API to get the tlv 127 * 128 * @rx_tlv: TLV data extracted from the rx packet 129 * Return: uint8_t 130 */ 131 static uint8_t hal_rx_get_tlv_6390(void *rx_tlv) 132 { 133 return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); 134 } 135 136 /** 137 * hal_rx_proc_phyrx_other_receive_info_tlv_6390() 138 * - process other receive info TLV 139 * @rx_tlv_hdr: pointer to TLV header 140 * @ppdu_info: pointer to ppdu_info 141 * 142 * Return: None 143 */ 144 static 145 void hal_rx_proc_phyrx_other_receive_info_tlv_6390(void *rx_tlv_hdr, 146 void *ppdu_info_handle) 147 { 148 uint32_t tlv_tag, tlv_len; 149 uint32_t temp_len, other_tlv_len, other_tlv_tag; 150 void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 151 void *other_tlv_hdr = NULL; 152 void *other_tlv = NULL; 153 154 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); 155 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); 156 temp_len = 0; 157 158 other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; 159 160 other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); 161 other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); 162 temp_len += other_tlv_len; 163 other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 164 165 switch (other_tlv_tag) { 166 default: 167 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 168 "%s unhandled TLV type: %d, TLV len:%d", 169 __func__, other_tlv_tag, other_tlv_len); 170 break; 171 } 172 } 173 174 /** 175 * hal_rx_dump_msdu_start_tlv_6390() : dump RX msdu_start TLV in structured 176 * human readable format. 177 * @ msdu_start: pointer the msdu_start TLV in pkt. 178 * @ dbg_level: log level. 179 * 180 * Return: void 181 */ 182 static void hal_rx_dump_msdu_start_tlv_6390(void *msdustart, uint8_t dbg_level) 183 { 184 struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; 185 186 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 187 "rx_msdu_start tlv - " 188 "rxpcu_mpdu_filter_in_category: %d " 189 "sw_frame_group_id: %d " 190 "phy_ppdu_id: %d " 191 "msdu_length: %d " 192 "ipsec_esp: %d " 193 "l3_offset: %d " 194 "ipsec_ah: %d " 195 "l4_offset: %d " 196 "msdu_number: %d " 197 "decap_format: %d " 198 "ipv4_proto: %d " 199 "ipv6_proto: %d " 200 "tcp_proto: %d " 201 "udp_proto: %d " 202 "ip_frag: %d " 203 "tcp_only_ack: %d " 204 "da_is_bcast_mcast: %d " 205 "ip4_protocol_ip6_next_header: %d " 206 "toeplitz_hash_2_or_4: %d " 207 "flow_id_toeplitz: %d " 208 "user_rssi: %d " 209 "pkt_type: %d " 210 "stbc: %d " 211 "sgi: %d " 212 "rate_mcs: %d " 213 "receive_bandwidth: %d " 214 "reception_type: %d " 215 "ppdu_start_timestamp: %d " 216 "sw_phy_meta_data: %d ", 217 msdu_start->rxpcu_mpdu_filter_in_category, 218 msdu_start->sw_frame_group_id, 219 msdu_start->phy_ppdu_id, 220 msdu_start->msdu_length, 221 msdu_start->ipsec_esp, 222 msdu_start->l3_offset, 223 msdu_start->ipsec_ah, 224 msdu_start->l4_offset, 225 msdu_start->msdu_number, 226 msdu_start->decap_format, 227 msdu_start->ipv4_proto, 228 msdu_start->ipv6_proto, 229 msdu_start->tcp_proto, 230 msdu_start->udp_proto, 231 msdu_start->ip_frag, 232 msdu_start->tcp_only_ack, 233 msdu_start->da_is_bcast_mcast, 234 msdu_start->ip4_protocol_ip6_next_header, 235 msdu_start->toeplitz_hash_2_or_4, 236 msdu_start->flow_id_toeplitz, 237 msdu_start->user_rssi, 238 msdu_start->pkt_type, 239 msdu_start->stbc, 240 msdu_start->sgi, 241 msdu_start->rate_mcs, 242 msdu_start->receive_bandwidth, 243 msdu_start->reception_type, 244 msdu_start->ppdu_start_timestamp, 245 msdu_start->sw_phy_meta_data); 246 } 247 248 /** 249 * hal_rx_dump_msdu_end_tlv_6390: dump RX msdu_end TLV in structured 250 * human readable format. 251 * @ msdu_end: pointer the msdu_end TLV in pkt. 252 * @ dbg_level: log level. 253 * 254 * Return: void 255 */ 256 static void hal_rx_dump_msdu_end_tlv_6390(void *msduend, 257 uint8_t dbg_level) 258 { 259 struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; 260 261 QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, 262 "rx_msdu_end tlv - " 263 "rxpcu_mpdu_filter_in_category: %d " 264 "sw_frame_group_id: %d " 265 "phy_ppdu_id: %d " 266 "ip_hdr_chksum: %d " 267 "tcp_udp_chksum: %d " 268 "key_id_octet: %d " 269 "cce_super_rule: %d " 270 "cce_classify_not_done_truncat: %d " 271 "cce_classify_not_done_cce_dis: %d " 272 "ext_wapi_pn_63_48: %d " 273 "ext_wapi_pn_95_64: %d " 274 "ext_wapi_pn_127_96: %d " 275 "reported_mpdu_length: %d " 276 "first_msdu: %d " 277 "last_msdu: %d " 278 "sa_idx_timeout: %d " 279 "da_idx_timeout: %d " 280 "msdu_limit_error: %d " 281 "flow_idx_timeout: %d " 282 "flow_idx_invalid: %d " 283 "wifi_parser_error: %d " 284 "amsdu_parser_error: %d " 285 "sa_is_valid: %d " 286 "da_is_valid: %d " 287 "da_is_mcbc: %d " 288 "l3_header_padding: %d " 289 "ipv6_options_crc: %d " 290 "tcp_seq_number: %d " 291 "tcp_ack_number: %d " 292 "tcp_flag: %d " 293 "lro_eligible: %d " 294 "window_size: %d " 295 "da_offset: %d " 296 "sa_offset: %d " 297 "da_offset_valid: %d " 298 "sa_offset_valid: %d " 299 "rule_indication_31_0: %d " 300 "rule_indication_63_32: %d " 301 "sa_idx: %d " 302 "da_idx: %d " 303 "msdu_drop: %d " 304 "reo_destination_indication: %d " 305 "flow_idx: %d " 306 "fse_metadata: %d " 307 "cce_metadata: %d " 308 "sa_sw_peer_id: %d ", 309 msdu_end->rxpcu_mpdu_filter_in_category, 310 msdu_end->sw_frame_group_id, 311 msdu_end->phy_ppdu_id, 312 msdu_end->ip_hdr_chksum, 313 msdu_end->tcp_udp_chksum, 314 msdu_end->key_id_octet, 315 msdu_end->cce_super_rule, 316 msdu_end->cce_classify_not_done_truncate, 317 msdu_end->cce_classify_not_done_cce_dis, 318 msdu_end->ext_wapi_pn_63_48, 319 msdu_end->ext_wapi_pn_95_64, 320 msdu_end->ext_wapi_pn_127_96, 321 msdu_end->reported_mpdu_length, 322 msdu_end->first_msdu, 323 msdu_end->last_msdu, 324 msdu_end->sa_idx_timeout, 325 msdu_end->da_idx_timeout, 326 msdu_end->msdu_limit_error, 327 msdu_end->flow_idx_timeout, 328 msdu_end->flow_idx_invalid, 329 msdu_end->wifi_parser_error, 330 msdu_end->amsdu_parser_error, 331 msdu_end->sa_is_valid, 332 msdu_end->da_is_valid, 333 msdu_end->da_is_mcbc, 334 msdu_end->l3_header_padding, 335 msdu_end->ipv6_options_crc, 336 msdu_end->tcp_seq_number, 337 msdu_end->tcp_ack_number, 338 msdu_end->tcp_flag, 339 msdu_end->lro_eligible, 340 msdu_end->window_size, 341 msdu_end->da_offset, 342 msdu_end->sa_offset, 343 msdu_end->da_offset_valid, 344 msdu_end->sa_offset_valid, 345 msdu_end->rule_indication_31_0, 346 msdu_end->rule_indication_63_32, 347 msdu_end->sa_idx, 348 msdu_end->da_idx_or_sw_peer_id, 349 msdu_end->msdu_drop, 350 msdu_end->reo_destination_indication, 351 msdu_end->flow_idx, 352 msdu_end->fse_metadata, 353 msdu_end->cce_metadata, 354 msdu_end->sa_sw_peer_id); 355 } 356 357 358 /* 359 * Get tid from RX_MPDU_START 360 */ 361 #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ 362 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ 363 RX_MPDU_INFO_3_TID_OFFSET)), \ 364 RX_MPDU_INFO_3_TID_MASK, \ 365 RX_MPDU_INFO_3_TID_LSB)) 366 367 static uint32_t hal_rx_mpdu_start_tid_get_6390(uint8_t *buf) 368 { 369 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 370 struct rx_mpdu_start *mpdu_start = 371 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; 372 uint32_t tid; 373 374 tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); 375 376 return tid; 377 } 378 379 #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ 380 (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ 381 RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ 382 RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ 383 RX_MSDU_START_5_RECEPTION_TYPE_LSB)) 384 385 /* 386 * hal_rx_msdu_start_reception_type_get(): API to get the reception type 387 * Interval from rx_msdu_start 388 * 389 * @buf: pointer to the start of RX PKT TLV header 390 * Return: uint32_t(reception_type) 391 */ 392 static 393 uint32_t hal_rx_msdu_start_reception_type_get_6390(uint8_t *buf) 394 { 395 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 396 struct rx_msdu_start *msdu_start = 397 &pkt_tlvs->msdu_start_tlv.rx_msdu_start; 398 uint32_t reception_type; 399 400 reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); 401 402 return reception_type; 403 } 404 405 #define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ 406 (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ 407 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ 408 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_MASK, \ 409 RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_LSB)) 410 411 /** 412 * hal_rx_msdu_end_da_idx_get_6390: API to get da_idx 413 * from rx_msdu_end TLV 414 * 415 * @ buf: pointer to the start of RX PKT TLV headers 416 * Return: da index 417 */ 418 static uint16_t hal_rx_msdu_end_da_idx_get_6390(uint8_t *buf) 419 { 420 struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; 421 struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; 422 uint16_t da_idx; 423 424 da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); 425 426 return da_idx; 427 } 428 429