Balamurugan Mahalingam | 6cf4c27 | 2018-07-05 16:50:09 +0530 | [diff] [blame^] | 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 | 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 | qdf_export_symbol(hal_rx_msdu_start_nss_get_6390); |
| 76 | /** |
| 77 | * hal_rx_mon_hw_desc_get_mpdu_status_6390(): Retrieve MPDU status |
| 78 | * |
| 79 | * @ hw_desc_addr: Start address of Rx HW TLVs |
| 80 | * @ rs: Status for monitor mode |
| 81 | * |
| 82 | * Return: void |
| 83 | */ |
| 84 | void hal_rx_mon_hw_desc_get_mpdu_status_6390(void *hw_desc_addr, |
| 85 | struct mon_rx_status *rs) |
| 86 | { |
| 87 | struct rx_msdu_start *rx_msdu_start; |
| 88 | struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; |
| 89 | uint32_t reg_value; |
| 90 | const uint32_t sgi_hw_to_cdp[] = { |
| 91 | CDP_SGI_0_8_US, |
| 92 | CDP_SGI_0_4_US, |
| 93 | CDP_SGI_1_6_US, |
| 94 | CDP_SGI_3_2_US, |
| 95 | }; |
| 96 | |
| 97 | rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; |
| 98 | |
| 99 | HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); |
| 100 | |
| 101 | rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, |
| 102 | RX_MSDU_START_5, USER_RSSI); |
| 103 | rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); |
| 104 | |
| 105 | reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); |
| 106 | rs->sgi = sgi_hw_to_cdp[reg_value]; |
| 107 | |
| 108 | reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); |
| 109 | switch (reg_value) { |
| 110 | case HAL_RX_PKT_TYPE_11N: |
| 111 | rs->ht_flags = 1; |
| 112 | break; |
| 113 | case HAL_RX_PKT_TYPE_11AC: |
| 114 | rs->vht_flags = 1; |
| 115 | reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, |
| 116 | RECEIVE_BANDWIDTH); |
| 117 | rs->vht_flag_values2 = reg_value; |
| 118 | break; |
| 119 | case HAL_RX_PKT_TYPE_11AX: |
| 120 | rs->he_flags = 1; |
| 121 | break; |
| 122 | default: |
| 123 | break; |
| 124 | } |
| 125 | reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); |
| 126 | rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; |
| 127 | /* TODO: rs->beamformed should be set for SU beamforming also */ |
| 128 | } |
| 129 | |
| 130 | qdf_export_symbol(hal_rx_mon_hw_desc_get_mpdu_status_6390); |
| 131 | |
| 132 | #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) |
| 133 | |
| 134 | uint32_t hal_get_link_desc_size_6390(void) |
| 135 | { |
| 136 | return LINK_DESC_SIZE; |
| 137 | } |
| 138 | |
| 139 | qdf_export_symbol(hal_get_link_desc_size_6390); |
| 140 | |
| 141 | /* |
| 142 | * hal_rx_get_tlv_6390(): API to get the tlv |
| 143 | * |
| 144 | * @rx_tlv: TLV data extracted from the rx packet |
| 145 | * Return: uint8_t |
| 146 | */ |
| 147 | uint8_t hal_rx_get_tlv_6390(void *rx_tlv) |
| 148 | { |
| 149 | return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); |
| 150 | } |
| 151 | |
| 152 | qdf_export_symbol(hal_rx_get_tlv_6390); |
| 153 | |
| 154 | /** |
| 155 | * hal_rx_proc_phyrx_other_receive_info_tlv_6390() |
| 156 | * - process other receive info TLV |
| 157 | * @rx_tlv_hdr: pointer to TLV header |
| 158 | * @ppdu_info: pointer to ppdu_info |
| 159 | * |
| 160 | * Return: None |
| 161 | */ |
| 162 | void hal_rx_proc_phyrx_other_receive_info_tlv_6390(void *rx_tlv_hdr, |
| 163 | void *ppdu_info_handle) |
| 164 | { |
| 165 | uint32_t tlv_tag, tlv_len; |
| 166 | uint32_t temp_len, other_tlv_len, other_tlv_tag; |
| 167 | void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; |
| 168 | void *other_tlv_hdr = NULL; |
| 169 | void *other_tlv = NULL; |
| 170 | uint32_t ru_details_channel_0; |
| 171 | struct hal_rx_ppdu_info *ppdu_info = |
| 172 | (struct hal_rx_ppdu_info *)ppdu_info_handle; |
| 173 | |
| 174 | tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); |
| 175 | tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); |
| 176 | temp_len = 0; |
| 177 | |
| 178 | other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; |
| 179 | |
| 180 | other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); |
| 181 | other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); |
| 182 | temp_len += other_tlv_len; |
| 183 | other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; |
| 184 | |
| 185 | switch (other_tlv_tag) { |
| 186 | case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E: |
| 187 | ru_details_channel_0 = |
| 188 | HAL_RX_GET(other_tlv, |
| 189 | PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0, |
| 190 | RU_DETAILS_CHANNEL_0); |
| 191 | |
| 192 | qdf_mem_copy(ppdu_info->rx_status.he_RU, |
| 193 | &ru_details_channel_0, |
| 194 | sizeof(ppdu_info->rx_status.he_RU)); |
| 195 | |
| 196 | if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20) |
| 197 | ppdu_info->rx_status.he_sig_b_common_known |= |
| 198 | QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; |
| 199 | |
| 200 | if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40) |
| 201 | ppdu_info->rx_status.he_sig_b_common_known |= |
| 202 | QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1; |
| 203 | |
| 204 | if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80) |
| 205 | ppdu_info->rx_status.he_sig_b_common_known |= |
| 206 | QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2; |
| 207 | |
| 208 | if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160) |
| 209 | ppdu_info->rx_status.he_sig_b_common_known |= |
| 210 | QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3; |
| 211 | break; |
| 212 | default: |
| 213 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 214 | "%s unhandled TLV type: %d, TLV len:%d", |
| 215 | __func__, other_tlv_tag, other_tlv_len); |
| 216 | break; |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | qdf_export_symbol(hal_rx_proc_phyrx_other_receive_info_tlv_6390); |
| 221 | |
| 222 | /** |
| 223 | * hal_rx_dump_msdu_start_tlv_6390() : dump RX msdu_start TLV in structured |
| 224 | * human readable format. |
| 225 | * @ msdu_start: pointer the msdu_start TLV in pkt. |
| 226 | * @ dbg_level: log level. |
| 227 | * |
| 228 | * Return: void |
| 229 | */ |
| 230 | void hal_rx_dump_msdu_start_tlv_6390(void *msdustart, uint8_t dbg_level) |
| 231 | { |
| 232 | struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; |
| 233 | |
| 234 | QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, |
| 235 | "rx_msdu_start tlv - " |
| 236 | "rxpcu_mpdu_filter_in_category: %d " |
| 237 | "sw_frame_group_id: %d " |
| 238 | "phy_ppdu_id: %d " |
| 239 | "msdu_length: %d " |
| 240 | "ipsec_esp: %d " |
| 241 | "l3_offset: %d " |
| 242 | "ipsec_ah: %d " |
| 243 | "l4_offset: %d " |
| 244 | "msdu_number: %d " |
| 245 | "decap_format: %d " |
| 246 | "ipv4_proto: %d " |
| 247 | "ipv6_proto: %d " |
| 248 | "tcp_proto: %d " |
| 249 | "udp_proto: %d " |
| 250 | "ip_frag: %d " |
| 251 | "tcp_only_ack: %d " |
| 252 | "da_is_bcast_mcast: %d " |
| 253 | "ip4_protocol_ip6_next_header: %d " |
| 254 | "toeplitz_hash_2_or_4: %d " |
| 255 | "flow_id_toeplitz: %d " |
| 256 | "user_rssi: %d " |
| 257 | "pkt_type: %d " |
| 258 | "stbc: %d " |
| 259 | "sgi: %d " |
| 260 | "rate_mcs: %d " |
| 261 | "receive_bandwidth: %d " |
| 262 | "reception_type: %d " |
| 263 | "ppdu_start_timestamp: %d " |
| 264 | "sw_phy_meta_data: %d ", |
| 265 | msdu_start->rxpcu_mpdu_filter_in_category, |
| 266 | msdu_start->sw_frame_group_id, |
| 267 | msdu_start->phy_ppdu_id, |
| 268 | msdu_start->msdu_length, |
| 269 | msdu_start->ipsec_esp, |
| 270 | msdu_start->l3_offset, |
| 271 | msdu_start->ipsec_ah, |
| 272 | msdu_start->l4_offset, |
| 273 | msdu_start->msdu_number, |
| 274 | msdu_start->decap_format, |
| 275 | msdu_start->ipv4_proto, |
| 276 | msdu_start->ipv6_proto, |
| 277 | msdu_start->tcp_proto, |
| 278 | msdu_start->udp_proto, |
| 279 | msdu_start->ip_frag, |
| 280 | msdu_start->tcp_only_ack, |
| 281 | msdu_start->da_is_bcast_mcast, |
| 282 | msdu_start->ip4_protocol_ip6_next_header, |
| 283 | msdu_start->toeplitz_hash_2_or_4, |
| 284 | msdu_start->flow_id_toeplitz, |
| 285 | msdu_start->user_rssi, |
| 286 | msdu_start->pkt_type, |
| 287 | msdu_start->stbc, |
| 288 | msdu_start->sgi, |
| 289 | msdu_start->rate_mcs, |
| 290 | msdu_start->receive_bandwidth, |
| 291 | msdu_start->reception_type, |
| 292 | msdu_start->ppdu_start_timestamp, |
| 293 | msdu_start->sw_phy_meta_data); |
| 294 | } |
| 295 | |
| 296 | qdf_export_symbol(hal_rx_dump_msdu_start_tlv_6390); |
| 297 | |
| 298 | /* |
| 299 | * Get tid from RX_MPDU_START |
| 300 | */ |
| 301 | #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ |
| 302 | (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ |
| 303 | RX_MPDU_INFO_3_TID_OFFSET)), \ |
| 304 | RX_MPDU_INFO_3_TID_MASK, \ |
| 305 | RX_MPDU_INFO_3_TID_LSB)) |
| 306 | |
| 307 | uint32_t hal_rx_mpdu_start_tid_get_6390(uint8_t *buf) |
| 308 | { |
| 309 | struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; |
| 310 | struct rx_mpdu_start *mpdu_start = |
| 311 | &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; |
| 312 | uint32_t tid; |
| 313 | |
| 314 | tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); |
| 315 | |
| 316 | return tid; |
| 317 | } |
| 318 | |
| 319 | qdf_export_symbol(hal_rx_mpdu_start_tid_get_6390); |
| 320 | |
| 321 | #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ |
| 322 | (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ |
| 323 | RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ |
| 324 | RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ |
| 325 | RX_MSDU_START_5_RECEPTION_TYPE_LSB)) |
| 326 | |
| 327 | /* |
| 328 | * hal_rx_msdu_start_reception_type_get(): API to get the reception type |
| 329 | * Interval from rx_msdu_start |
| 330 | * |
| 331 | * @buf: pointer to the start of RX PKT TLV header |
| 332 | * Return: uint32_t(reception_type) |
| 333 | */ |
| 334 | uint32_t hal_rx_msdu_start_reception_type_get_6390(uint8_t *buf) |
| 335 | { |
| 336 | struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; |
| 337 | struct rx_msdu_start *msdu_start = |
| 338 | &pkt_tlvs->msdu_start_tlv.rx_msdu_start; |
| 339 | uint32_t reception_type; |
| 340 | |
| 341 | reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); |
| 342 | |
| 343 | return reception_type; |
| 344 | } |
| 345 | |
| 346 | qdf_export_symbol(hal_rx_msdu_start_reception_type_get_6390); |
| 347 | |