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 #ifndef _HAL_GENERIC_API_H_ 19 #define _HAL_GENERIC_API_H_ 20 21 #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ 22 ((struct rx_msdu_desc_info *) \ 23 _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ 24 UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) 25 /** 26 * hal_rx_msdu_desc_info_get_ptr_generic() - Get msdu desc info ptr 27 * @msdu_details_ptr - Pointer to msdu_details_ptr 28 * Return - Pointer to rx_msdu_desc_info structure. 29 * 30 */ 31 static void *hal_rx_msdu_desc_info_get_ptr_generic(void *msdu_details_ptr) 32 { 33 return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); 34 } 35 36 37 #define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ 38 ((struct rx_msdu_details *) \ 39 _OFFSET_TO_BYTE_PTR((link_desc),\ 40 UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) 41 /** 42 * hal_rx_link_desc_msdu0_ptr_generic - Get pointer to rx_msdu details 43 * @link_desc - Pointer to link desc 44 * Return - Pointer to rx_msdu_details structure 45 * 46 */ 47 48 static void *hal_rx_link_desc_msdu0_ptr_generic(void *link_desc) 49 { 50 return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); 51 } 52 53 /** 54 * hal_tx_comp_get_status() - TQM Release reason 55 * @hal_desc: completion ring Tx status 56 * 57 * This function will parse the WBM completion descriptor and populate in 58 * HAL structure 59 * 60 * Return: none 61 */ 62 #if defined(WCSS_VERSION) && \ 63 ((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \ 64 (defined(CONFIG_MCL) && (WCSS_VERSION >= 72))) 65 static inline void hal_tx_comp_get_status_generic(void *desc, 66 void *ts1) 67 { 68 uint8_t rate_stats_valid = 0; 69 uint32_t rate_stats = 0; 70 struct hal_tx_completion_status *ts = 71 (struct hal_tx_completion_status *)ts1; 72 73 ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3, 74 TQM_STATUS_NUMBER); 75 ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, 76 ACK_FRAME_RSSI); 77 ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU); 78 ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU); 79 ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, 80 MSDU_PART_OF_AMSDU); 81 82 ts->peer_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, SW_PEER_ID); 83 ts->tid = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, TID); 84 ts->transmit_cnt = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3, 85 TRANSMIT_COUNT); 86 87 rate_stats = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_5, 88 TX_RATE_STATS); 89 90 rate_stats_valid = HAL_TX_MS(TX_RATE_STATS_INFO_0, 91 TX_RATE_STATS_INFO_VALID, rate_stats); 92 93 ts->valid = rate_stats_valid; 94 95 if (rate_stats_valid) { 96 ts->bw = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_BW, 97 rate_stats); 98 ts->pkt_type = HAL_TX_MS(TX_RATE_STATS_INFO_0, 99 TRANSMIT_PKT_TYPE, rate_stats); 100 ts->stbc = HAL_TX_MS(TX_RATE_STATS_INFO_0, 101 TRANSMIT_STBC, rate_stats); 102 ts->ldpc = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_LDPC, 103 rate_stats); 104 ts->sgi = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_SGI, 105 rate_stats); 106 ts->mcs = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_MCS, 107 rate_stats); 108 ts->ofdma = HAL_TX_MS(TX_RATE_STATS_INFO_0, OFDMA_TRANSMISSION, 109 rate_stats); 110 ts->tones_in_ru = HAL_TX_MS(TX_RATE_STATS_INFO_0, TONES_IN_RU, 111 rate_stats); 112 } 113 114 ts->release_src = hal_tx_comp_get_buffer_source(desc); 115 ts->status = hal_tx_comp_get_release_reason(desc); 116 117 ts->tsf = HAL_TX_DESC_GET(desc, UNIFIED_WBM_RELEASE_RING_6, 118 TX_RATE_STATS_INFO_TX_RATE_STATS); 119 } 120 #else 121 static inline void hal_tx_comp_get_status_generic(void *desc, 122 struct hal_tx_completion_status *ts) 123 { 124 125 ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3, 126 TQM_STATUS_NUMBER); 127 ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, 128 ACK_FRAME_RSSI); 129 ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU); 130 ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU); 131 ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, 132 MSDU_PART_OF_AMSDU); 133 134 ts->release_src = hal_tx_comp_get_buffer_source(desc); 135 ts->status = hal_tx_comp_get_release_reason(desc); 136 } 137 #endif 138 139 140 /** 141 * hal_tx_desc_set_buf_addr - Fill Buffer Address information in Tx Descriptor 142 * @desc: Handle to Tx Descriptor 143 * @paddr: Physical Address 144 * @pool_id: Return Buffer Manager ID 145 * @desc_id: Descriptor ID 146 * @type: 0 - Address points to a MSDU buffer 147 * 1 - Address points to MSDU extension descriptor 148 * 149 * Return: void 150 */ 151 static inline void hal_tx_desc_set_buf_addr_generic(void *desc, 152 dma_addr_t paddr, uint8_t pool_id, 153 uint32_t desc_id, uint8_t type) 154 { 155 /* Set buffer_addr_info.buffer_addr_31_0 */ 156 HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_0, BUFFER_ADDR_INFO_BUF_ADDR_INFO) = 157 HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0, paddr); 158 159 /* Set buffer_addr_info.buffer_addr_39_32 */ 160 HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1, 161 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |= 162 HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32, 163 (((uint64_t) paddr) >> 32)); 164 165 /* Set buffer_addr_info.return_buffer_manager = pool id */ 166 HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1, 167 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |= 168 HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, 169 RETURN_BUFFER_MANAGER, (pool_id + HAL_WBM_SW0_BM_ID)); 170 171 /* Set buffer_addr_info.sw_buffer_cookie = desc_id */ 172 HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1, 173 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |= 174 HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE, desc_id); 175 176 /* Set Buffer or Ext Descriptor Type */ 177 HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_2, 178 BUF_OR_EXT_DESC_TYPE) |= 179 HAL_TX_SM(UNIFIED_TCL_DATA_CMD_2, BUF_OR_EXT_DESC_TYPE, type); 180 } 181 182 /** 183 * hal_rx_status_get_tlv_info() - process receive info TLV 184 * @rx_tlv_hdr: pointer to TLV header 185 * @ppdu_info: pointer to ppdu_info 186 * 187 * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv 188 */ 189 static inline uint32_t 190 hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, 191 void *halsoc) 192 { 193 struct hal_soc *hal = (struct hal_soc *)halsoc; 194 uint32_t tlv_tag, user_id, tlv_len, value; 195 uint8_t group_id = 0; 196 uint8_t he_dcm = 0; 197 uint8_t he_stbc = 0; 198 uint16_t he_gi = 0; 199 uint16_t he_ltf = 0; 200 void *rx_tlv; 201 bool unhandled = false; 202 struct hal_rx_ppdu_info *ppdu_info = 203 (struct hal_rx_ppdu_info *)ppduinfo; 204 205 tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); 206 user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv_hdr); 207 tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); 208 209 rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; 210 switch (tlv_tag) { 211 212 case WIFIRX_PPDU_START_E: 213 ppdu_info->com_info.ppdu_id = 214 HAL_RX_GET(rx_tlv, RX_PPDU_START_0, 215 PHY_PPDU_ID); 216 /* channel number is set in PHY meta data */ 217 ppdu_info->rx_status.chan_num = 218 HAL_RX_GET(rx_tlv, RX_PPDU_START_1, 219 SW_PHY_META_DATA); 220 ppdu_info->com_info.ppdu_timestamp = 221 HAL_RX_GET(rx_tlv, RX_PPDU_START_2, 222 PPDU_START_TIMESTAMP); 223 ppdu_info->rx_state = HAL_RX_MON_PPDU_START; 224 break; 225 226 case WIFIRX_PPDU_START_USER_INFO_E: 227 break; 228 229 case WIFIRX_PPDU_END_E: 230 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 231 "[%s][%d] ppdu_end_e len=%d", 232 __func__, __LINE__, tlv_len); 233 /* This is followed by sub-TLVs of PPDU_END */ 234 ppdu_info->rx_state = HAL_RX_MON_PPDU_END; 235 break; 236 237 case WIFIRXPCU_PPDU_END_INFO_E: 238 ppdu_info->rx_status.tsft = 239 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, 240 WB_TIMESTAMP_UPPER_32); 241 ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) | 242 HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0, 243 WB_TIMESTAMP_LOWER_32); 244 ppdu_info->rx_status.duration = 245 HAL_RX_GET(rx_tlv, UNIFIED_RXPCU_PPDU_END_INFO_8, 246 RX_PPDU_DURATION); 247 break; 248 249 case WIFIRX_PPDU_END_USER_STATS_E: 250 { 251 unsigned long tid = 0; 252 uint16_t seq = 0; 253 254 ppdu_info->rx_status.ast_index = 255 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4, 256 AST_INDEX); 257 258 tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12, 259 RECEIVED_QOS_DATA_TID_BITMAP); 260 ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8); 261 262 if (ppdu_info->rx_status.tid == (sizeof(tid) * 8)) 263 ppdu_info->rx_status.tid = HAL_TID_INVALID; 264 265 ppdu_info->rx_status.tcp_msdu_count = 266 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9, 267 TCP_MSDU_COUNT) + 268 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10, 269 TCP_ACK_MSDU_COUNT); 270 ppdu_info->rx_status.udp_msdu_count = 271 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9, 272 UDP_MSDU_COUNT); 273 ppdu_info->rx_status.other_msdu_count = 274 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10, 275 OTHER_MSDU_COUNT); 276 277 ppdu_info->rx_status.frame_control_info_valid = 278 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 279 DATA_SEQUENCE_CONTROL_INFO_VALID); 280 281 seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5, 282 FIRST_DATA_SEQ_CTRL); 283 if (ppdu_info->rx_status.frame_control_info_valid) 284 ppdu_info->rx_status.first_data_seq_ctrl = seq; 285 286 ppdu_info->rx_status.preamble_type = 287 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 288 HT_CONTROL_FIELD_PKT_TYPE); 289 switch (ppdu_info->rx_status.preamble_type) { 290 case HAL_RX_PKT_TYPE_11N: 291 ppdu_info->rx_status.ht_flags = 1; 292 ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT; 293 break; 294 case HAL_RX_PKT_TYPE_11AC: 295 ppdu_info->rx_status.vht_flags = 1; 296 break; 297 case HAL_RX_PKT_TYPE_11AX: 298 ppdu_info->rx_status.he_flags = 1; 299 break; 300 default: 301 break; 302 } 303 304 ppdu_info->com_info.mpdu_cnt_fcs_ok = 305 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, 306 MPDU_CNT_FCS_OK); 307 ppdu_info->com_info.mpdu_cnt_fcs_err = 308 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2, 309 MPDU_CNT_FCS_ERR); 310 if ((ppdu_info->com_info.mpdu_cnt_fcs_ok | 311 ppdu_info->com_info.mpdu_cnt_fcs_err) > 1) 312 ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG; 313 else 314 ppdu_info->rx_status.rs_flags &= 315 (~IEEE80211_AMPDU_FLAG); 316 break; 317 } 318 319 case WIFIRX_PPDU_END_USER_STATS_EXT_E: 320 break; 321 322 case WIFIRX_PPDU_END_STATUS_DONE_E: 323 return HAL_TLV_STATUS_PPDU_DONE; 324 325 case WIFIDUMMY_E: 326 return HAL_TLV_STATUS_BUF_DONE; 327 328 case WIFIPHYRX_HT_SIG_E: 329 { 330 uint8_t *ht_sig_info = (uint8_t *)rx_tlv + 331 HAL_RX_OFFSET(UNIFIED_PHYRX_HT_SIG_0, 332 HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS); 333 value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1, 334 FEC_CODING); 335 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 336 1 : 0; 337 ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info, 338 HT_SIG_INFO_0, MCS); 339 ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info, 340 HT_SIG_INFO_0, CBW); 341 ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info, 342 HT_SIG_INFO_1, SHORT_GI); 343 break; 344 } 345 346 case WIFIPHYRX_L_SIG_B_E: 347 { 348 uint8_t *l_sig_b_info = (uint8_t *)rx_tlv + 349 HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_B_0, 350 L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS); 351 352 value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE); 353 switch (value) { 354 case 1: 355 ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS; 356 break; 357 case 2: 358 ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS; 359 break; 360 case 3: 361 ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS; 362 break; 363 case 4: 364 ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS; 365 break; 366 case 5: 367 ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS; 368 break; 369 case 6: 370 ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS; 371 break; 372 case 7: 373 ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS; 374 break; 375 default: 376 break; 377 } 378 ppdu_info->rx_status.cck_flag = 1; 379 break; 380 } 381 382 case WIFIPHYRX_L_SIG_A_E: 383 { 384 uint8_t *l_sig_a_info = (uint8_t *)rx_tlv + 385 HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_A_0, 386 L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS); 387 388 value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE); 389 switch (value) { 390 case 8: 391 ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS; 392 break; 393 case 9: 394 ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS; 395 break; 396 case 10: 397 ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS; 398 break; 399 case 11: 400 ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS; 401 break; 402 case 12: 403 ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS; 404 break; 405 case 13: 406 ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS; 407 break; 408 case 14: 409 ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS; 410 break; 411 case 15: 412 ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS; 413 break; 414 default: 415 break; 416 } 417 ppdu_info->rx_status.ofdm_flag = 1; 418 break; 419 } 420 421 case WIFIPHYRX_VHT_SIG_A_E: 422 { 423 uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv + 424 HAL_RX_OFFSET(UNIFIED_PHYRX_VHT_SIG_A_0, 425 VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS); 426 427 value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, 428 SU_MU_CODING); 429 ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? 430 1 : 0; 431 group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID); 432 ppdu_info->rx_status.vht_flag_values5 = group_id; 433 ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info, 434 VHT_SIG_A_INFO_1, MCS); 435 ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info, 436 VHT_SIG_A_INFO_1, GI_SETTING); 437 438 switch (hal->target_type) { 439 case TARGET_TYPE_QCA8074: 440 case TARGET_TYPE_QCA8074V2: 441 ppdu_info->rx_status.is_stbc = 442 HAL_RX_GET(vht_sig_a_info, 443 VHT_SIG_A_INFO_0, STBC); 444 value = HAL_RX_GET(vht_sig_a_info, 445 VHT_SIG_A_INFO_0, N_STS); 446 if (ppdu_info->rx_status.is_stbc && (value > 0)) 447 value = ((value + 1) >> 1) - 1; 448 ppdu_info->rx_status.nss = 449 ((value & VHT_SIG_SU_NSS_MASK) + 1); 450 451 break; 452 case TARGET_TYPE_QCA6290: 453 #if !defined(QCA_WIFI_QCA6290_11AX) 454 ppdu_info->rx_status.is_stbc = 455 HAL_RX_GET(vht_sig_a_info, 456 VHT_SIG_A_INFO_0, STBC); 457 value = HAL_RX_GET(vht_sig_a_info, 458 VHT_SIG_A_INFO_0, N_STS); 459 if (ppdu_info->rx_status.is_stbc && (value > 0)) 460 value = ((value + 1) >> 1) - 1; 461 ppdu_info->rx_status.nss = 462 ((value & VHT_SIG_SU_NSS_MASK) + 1); 463 #else 464 ppdu_info->rx_status.nss = 0; 465 #endif 466 break; 467 #ifdef QCA_WIFI_QCA6390 468 case TARGET_TYPE_QCA6390: 469 ppdu_info->rx_status.nss = 0; 470 break; 471 #endif 472 default: 473 break; 474 } 475 ppdu_info->rx_status.vht_flag_values3[0] = 476 (((ppdu_info->rx_status.mcs) << 4) 477 | ppdu_info->rx_status.nss); 478 ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info, 479 VHT_SIG_A_INFO_0, BANDWIDTH); 480 ppdu_info->rx_status.vht_flag_values2 = 481 ppdu_info->rx_status.bw; 482 ppdu_info->rx_status.vht_flag_values4 = 483 HAL_RX_GET(vht_sig_a_info, 484 VHT_SIG_A_INFO_1, SU_MU_CODING); 485 486 ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info, 487 VHT_SIG_A_INFO_1, BEAMFORMED); 488 489 break; 490 } 491 case WIFIPHYRX_HE_SIG_A_SU_E: 492 { 493 uint8_t *he_sig_a_su_info = (uint8_t *)rx_tlv + 494 HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_A_SU_0, 495 HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS); 496 ppdu_info->rx_status.he_flags = 1; 497 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, 498 FORMAT_INDICATION); 499 if (value == 0) { 500 ppdu_info->rx_status.he_data1 = 501 QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE; 502 } else { 503 ppdu_info->rx_status.he_data1 = 504 QDF_MON_STATUS_HE_SU_FORMAT_TYPE; 505 } 506 507 /* data1 */ 508 ppdu_info->rx_status.he_data1 |= 509 QDF_MON_STATUS_HE_BSS_COLOR_KNOWN | 510 QDF_MON_STATUS_HE_BEAM_CHANGE_KNOWN | 511 QDF_MON_STATUS_HE_DL_UL_KNOWN | 512 QDF_MON_STATUS_HE_MCS_KNOWN | 513 QDF_MON_STATUS_HE_DCM_KNOWN | 514 QDF_MON_STATUS_HE_CODING_KNOWN | 515 QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN | 516 QDF_MON_STATUS_HE_STBC_KNOWN | 517 QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN | 518 QDF_MON_STATUS_HE_DOPPLER_KNOWN; 519 520 /* data2 */ 521 ppdu_info->rx_status.he_data2 = 522 QDF_MON_STATUS_HE_GI_KNOWN; 523 ppdu_info->rx_status.he_data2 |= 524 QDF_MON_STATUS_TXBF_KNOWN | 525 QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN | 526 QDF_MON_STATUS_TXOP_KNOWN | 527 QDF_MON_STATUS_LTF_SYMBOLS_KNOWN | 528 QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN | 529 QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN; 530 531 /* data3 */ 532 value = HAL_RX_GET(he_sig_a_su_info, 533 HE_SIG_A_SU_INFO_0, BSS_COLOR_ID); 534 ppdu_info->rx_status.he_data3 = value; 535 value = HAL_RX_GET(he_sig_a_su_info, 536 HE_SIG_A_SU_INFO_0, BEAM_CHANGE); 537 value = value << QDF_MON_STATUS_BEAM_CHANGE_SHIFT; 538 ppdu_info->rx_status.he_data3 |= value; 539 value = HAL_RX_GET(he_sig_a_su_info, 540 HE_SIG_A_SU_INFO_0, DL_UL_FLAG); 541 value = value << QDF_MON_STATUS_DL_UL_SHIFT; 542 ppdu_info->rx_status.he_data3 |= value; 543 544 value = HAL_RX_GET(he_sig_a_su_info, 545 HE_SIG_A_SU_INFO_0, TRANSMIT_MCS); 546 ppdu_info->rx_status.mcs = value; 547 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 548 ppdu_info->rx_status.he_data3 |= value; 549 550 value = HAL_RX_GET(he_sig_a_su_info, 551 HE_SIG_A_SU_INFO_0, DCM); 552 he_dcm = value; 553 value = value << QDF_MON_STATUS_DCM_SHIFT; 554 ppdu_info->rx_status.he_data3 |= value; 555 value = HAL_RX_GET(he_sig_a_su_info, 556 HE_SIG_A_SU_INFO_1, CODING); 557 value = value << QDF_MON_STATUS_CODING_SHIFT; 558 ppdu_info->rx_status.he_data3 |= value; 559 value = HAL_RX_GET(he_sig_a_su_info, 560 HE_SIG_A_SU_INFO_1, 561 LDPC_EXTRA_SYMBOL); 562 value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT; 563 ppdu_info->rx_status.he_data3 |= value; 564 value = HAL_RX_GET(he_sig_a_su_info, 565 HE_SIG_A_SU_INFO_1, STBC); 566 he_stbc = value; 567 value = value << QDF_MON_STATUS_STBC_SHIFT; 568 ppdu_info->rx_status.he_data3 |= value; 569 570 /* data4 */ 571 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, 572 SPATIAL_REUSE); 573 ppdu_info->rx_status.he_data4 = value; 574 575 /* data5 */ 576 value = HAL_RX_GET(he_sig_a_su_info, 577 HE_SIG_A_SU_INFO_0, TRANSMIT_BW); 578 ppdu_info->rx_status.he_data5 = value; 579 ppdu_info->rx_status.bw = value; 580 value = HAL_RX_GET(he_sig_a_su_info, 581 HE_SIG_A_SU_INFO_0, CP_LTF_SIZE); 582 switch (value) { 583 case 0: 584 he_gi = HE_GI_0_8; 585 he_ltf = HE_LTF_1_X; 586 break; 587 case 1: 588 he_gi = HE_GI_0_8; 589 he_ltf = HE_LTF_2_X; 590 break; 591 case 2: 592 he_gi = HE_GI_1_6; 593 he_ltf = HE_LTF_2_X; 594 break; 595 case 3: 596 if (he_dcm && he_stbc) { 597 he_gi = HE_GI_0_8; 598 he_ltf = HE_LTF_4_X; 599 } else { 600 he_gi = HE_GI_3_2; 601 he_ltf = HE_LTF_4_X; 602 } 603 break; 604 } 605 ppdu_info->rx_status.sgi = he_gi; 606 value = he_gi << QDF_MON_STATUS_GI_SHIFT; 607 ppdu_info->rx_status.he_data5 |= value; 608 value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT; 609 ppdu_info->rx_status.he_data5 |= value; 610 611 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS); 612 value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT); 613 ppdu_info->rx_status.he_data5 |= value; 614 615 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 616 PACKET_EXTENSION_A_FACTOR); 617 value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT; 618 ppdu_info->rx_status.he_data5 |= value; 619 620 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF); 621 value = value << QDF_MON_STATUS_TXBF_SHIFT; 622 ppdu_info->rx_status.he_data5 |= value; 623 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 624 PACKET_EXTENSION_PE_DISAMBIGUITY); 625 value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT; 626 ppdu_info->rx_status.he_data5 |= value; 627 628 /* data6 */ 629 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS); 630 value++; 631 ppdu_info->rx_status.nss = value; 632 ppdu_info->rx_status.he_data6 = value; 633 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 634 DOPPLER_INDICATION); 635 value = value << QDF_MON_STATUS_DOPPLER_SHIFT; 636 ppdu_info->rx_status.he_data6 |= value; 637 value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, 638 TXOP_DURATION); 639 value = value << QDF_MON_STATUS_TXOP_SHIFT; 640 ppdu_info->rx_status.he_data6 |= value; 641 642 ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info, 643 HE_SIG_A_SU_INFO_1, TXBF); 644 break; 645 } 646 case WIFIPHYRX_HE_SIG_A_MU_DL_E: 647 { 648 uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv + 649 HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_A_MU_DL_0, 650 HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS); 651 652 ppdu_info->rx_status.he_mu_flags = 1; 653 654 /* HE Flags */ 655 /*data1*/ 656 ppdu_info->rx_status.he_data1 = 657 QDF_MON_STATUS_HE_MU_FORMAT_TYPE; 658 ppdu_info->rx_status.he_data1 |= 659 QDF_MON_STATUS_HE_BSS_COLOR_KNOWN | 660 QDF_MON_STATUS_HE_DL_UL_KNOWN | 661 QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN | 662 QDF_MON_STATUS_HE_STBC_KNOWN | 663 QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN | 664 QDF_MON_STATUS_HE_DOPPLER_KNOWN; 665 666 /* data2 */ 667 ppdu_info->rx_status.he_data2 = 668 QDF_MON_STATUS_HE_GI_KNOWN; 669 ppdu_info->rx_status.he_data2 |= 670 QDF_MON_STATUS_LTF_SYMBOLS_KNOWN | 671 QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN | 672 QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN | 673 QDF_MON_STATUS_TXOP_KNOWN | 674 QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN; 675 676 /*data3*/ 677 value = HAL_RX_GET(he_sig_a_mu_dl_info, 678 HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID); 679 ppdu_info->rx_status.he_data3 = value; 680 681 value = HAL_RX_GET(he_sig_a_mu_dl_info, 682 HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG); 683 value = value << QDF_MON_STATUS_DL_UL_SHIFT; 684 ppdu_info->rx_status.he_data3 |= value; 685 686 value = HAL_RX_GET(he_sig_a_mu_dl_info, 687 HE_SIG_A_MU_DL_INFO_1, 688 LDPC_EXTRA_SYMBOL); 689 value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT; 690 ppdu_info->rx_status.he_data3 |= value; 691 692 value = HAL_RX_GET(he_sig_a_mu_dl_info, 693 HE_SIG_A_MU_DL_INFO_1, STBC); 694 he_stbc = value; 695 value = value << QDF_MON_STATUS_STBC_SHIFT; 696 ppdu_info->rx_status.he_data3 |= value; 697 698 /*data4*/ 699 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0, 700 SPATIAL_REUSE); 701 ppdu_info->rx_status.he_data4 = value; 702 703 /*data5*/ 704 value = HAL_RX_GET(he_sig_a_mu_dl_info, 705 HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW); 706 ppdu_info->rx_status.he_data5 = value; 707 ppdu_info->rx_status.bw = value; 708 709 value = HAL_RX_GET(he_sig_a_mu_dl_info, 710 HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE); 711 switch (value) { 712 case 0: 713 he_gi = HE_GI_0_8; 714 he_ltf = HE_LTF_4_X; 715 break; 716 case 1: 717 he_gi = HE_GI_0_8; 718 he_ltf = HE_LTF_2_X; 719 break; 720 case 2: 721 he_gi = HE_GI_1_6; 722 he_ltf = HE_LTF_2_X; 723 break; 724 case 3: 725 he_gi = HE_GI_3_2; 726 he_ltf = HE_LTF_4_X; 727 break; 728 } 729 ppdu_info->rx_status.sgi = he_gi; 730 value = he_gi << QDF_MON_STATUS_GI_SHIFT; 731 ppdu_info->rx_status.he_data5 |= value; 732 733 value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT; 734 ppdu_info->rx_status.he_data5 |= value; 735 736 value = HAL_RX_GET(he_sig_a_mu_dl_info, 737 HE_SIG_A_MU_DL_INFO_1, NUM_LTF_SYMBOLS); 738 value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT); 739 ppdu_info->rx_status.he_data5 |= value; 740 741 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 742 PACKET_EXTENSION_A_FACTOR); 743 value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT; 744 ppdu_info->rx_status.he_data5 |= value; 745 746 747 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 748 PACKET_EXTENSION_PE_DISAMBIGUITY); 749 value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT; 750 ppdu_info->rx_status.he_data5 |= value; 751 752 /*data6*/ 753 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0, 754 DOPPLER_INDICATION); 755 value = value << QDF_MON_STATUS_DOPPLER_SHIFT; 756 ppdu_info->rx_status.he_data6 |= value; 757 758 value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1, 759 TXOP_DURATION); 760 value = value << QDF_MON_STATUS_TXOP_SHIFT; 761 ppdu_info->rx_status.he_data6 |= value; 762 763 /* HE-MU Flags */ 764 /* HE-MU-flags1 */ 765 ppdu_info->rx_status.he_flags1 = 766 QDF_MON_STATUS_SIG_B_MCS_KNOWN | 767 QDF_MON_STATUS_SIG_B_DCM_KNOWN | 768 QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN | 769 QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN | 770 QDF_MON_STATUS_RU_0_KNOWN; 771 772 value = HAL_RX_GET(he_sig_a_mu_dl_info, 773 HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B); 774 ppdu_info->rx_status.he_flags1 |= value; 775 value = HAL_RX_GET(he_sig_a_mu_dl_info, 776 HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B); 777 value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT; 778 ppdu_info->rx_status.he_flags1 |= value; 779 780 /* HE-MU-flags2 */ 781 ppdu_info->rx_status.he_flags2 = 782 QDF_MON_STATUS_BW_KNOWN; 783 784 value = HAL_RX_GET(he_sig_a_mu_dl_info, 785 HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW); 786 ppdu_info->rx_status.he_flags2 |= value; 787 value = HAL_RX_GET(he_sig_a_mu_dl_info, 788 HE_SIG_A_MU_DL_INFO_0, COMP_MODE_SIG_B); 789 value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT; 790 ppdu_info->rx_status.he_flags2 |= value; 791 value = HAL_RX_GET(he_sig_a_mu_dl_info, 792 HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS); 793 value = value - 1; 794 value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT; 795 ppdu_info->rx_status.he_flags2 |= value; 796 break; 797 } 798 case WIFIPHYRX_HE_SIG_B1_MU_E: 799 { 800 801 uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv + 802 HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B1_MU_0, 803 HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS); 804 805 ppdu_info->rx_status.he_sig_b_common_known |= 806 QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; 807 /* TODO: Check on the availability of other fields in 808 * sig_b_common 809 */ 810 811 value = HAL_RX_GET(he_sig_b1_mu_info, 812 HE_SIG_B1_MU_INFO_0, RU_ALLOCATION); 813 ppdu_info->rx_status.he_RU[0] = value; 814 break; 815 } 816 case WIFIPHYRX_HE_SIG_B2_MU_E: 817 { 818 uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv + 819 HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_MU_0, 820 HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS); 821 /* 822 * Not all "HE" fields can be updated from 823 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E 824 * to populate rest of the "HE" fields for MU scenarios. 825 */ 826 827 /* HE-data1 */ 828 ppdu_info->rx_status.he_data1 |= 829 QDF_MON_STATUS_HE_MCS_KNOWN | 830 QDF_MON_STATUS_HE_CODING_KNOWN; 831 832 /* HE-data2 */ 833 834 /* HE-data3 */ 835 value = HAL_RX_GET(he_sig_b2_mu_info, 836 HE_SIG_B2_MU_INFO_0, STA_MCS); 837 ppdu_info->rx_status.mcs = value; 838 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 839 ppdu_info->rx_status.he_data3 |= value; 840 841 842 value = HAL_RX_GET(he_sig_b2_mu_info, 843 HE_SIG_B2_MU_INFO_0, STA_CODING); 844 value = value << QDF_MON_STATUS_CODING_SHIFT; 845 ppdu_info->rx_status.he_data3 |= value; 846 847 /* HE-data4 */ 848 value = HAL_RX_GET(he_sig_b2_mu_info, 849 HE_SIG_B2_MU_INFO_0, STA_ID); 850 value = value << QDF_MON_STATUS_STA_ID_SHIFT; 851 ppdu_info->rx_status.he_data4 |= value; 852 853 /* HE-data5 */ 854 855 /* HE-data6 */ 856 value = HAL_RX_GET(he_sig_b2_mu_info, 857 HE_SIG_B2_MU_INFO_0, NSTS); 858 /* value n indicates n+1 spatial streams */ 859 value++; 860 ppdu_info->rx_status.nss = value; 861 ppdu_info->rx_status.he_data6 |= value; 862 863 break; 864 865 } 866 case WIFIPHYRX_HE_SIG_B2_OFDMA_E: 867 { 868 uint8_t *he_sig_b2_ofdma_info = 869 (uint8_t *)rx_tlv + 870 HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0, 871 HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS); 872 873 /* 874 * Not all "HE" fields can be updated from 875 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E 876 * to populate rest of "HE" fields for MU OFDMA scenarios. 877 */ 878 879 /* HE-data1 */ 880 ppdu_info->rx_status.he_data1 |= 881 QDF_MON_STATUS_HE_MCS_KNOWN | 882 QDF_MON_STATUS_HE_DCM_KNOWN | 883 QDF_MON_STATUS_HE_CODING_KNOWN; 884 885 /* HE-data2 */ 886 ppdu_info->rx_status.he_data2 |= 887 QDF_MON_STATUS_TXBF_KNOWN; 888 889 /* HE-data3 */ 890 value = HAL_RX_GET(he_sig_b2_ofdma_info, 891 HE_SIG_B2_OFDMA_INFO_0, STA_MCS); 892 ppdu_info->rx_status.mcs = value; 893 value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT; 894 ppdu_info->rx_status.he_data3 |= value; 895 896 value = HAL_RX_GET(he_sig_b2_ofdma_info, 897 HE_SIG_B2_OFDMA_INFO_0, STA_DCM); 898 he_dcm = value; 899 value = value << QDF_MON_STATUS_DCM_SHIFT; 900 ppdu_info->rx_status.he_data3 |= value; 901 902 value = HAL_RX_GET(he_sig_b2_ofdma_info, 903 HE_SIG_B2_OFDMA_INFO_0, STA_CODING); 904 value = value << QDF_MON_STATUS_CODING_SHIFT; 905 ppdu_info->rx_status.he_data3 |= value; 906 907 /* HE-data4 */ 908 value = HAL_RX_GET(he_sig_b2_ofdma_info, 909 HE_SIG_B2_OFDMA_INFO_0, STA_ID); 910 value = value << QDF_MON_STATUS_STA_ID_SHIFT; 911 ppdu_info->rx_status.he_data4 |= value; 912 913 /* HE-data5 */ 914 value = HAL_RX_GET(he_sig_b2_ofdma_info, 915 HE_SIG_B2_OFDMA_INFO_0, TXBF); 916 value = value << QDF_MON_STATUS_TXBF_SHIFT; 917 ppdu_info->rx_status.he_data5 |= value; 918 919 /* HE-data6 */ 920 value = HAL_RX_GET(he_sig_b2_ofdma_info, 921 HE_SIG_B2_OFDMA_INFO_0, NSTS); 922 /* value n indicates n+1 spatial streams */ 923 value++; 924 ppdu_info->rx_status.nss = value; 925 ppdu_info->rx_status.he_data6 |= value; 926 927 break; 928 } 929 case WIFIPHYRX_RSSI_LEGACY_E: 930 { 931 uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + 932 HAL_RX_OFFSET(UNIFIED_PHYRX_RSSI_LEGACY_3, 933 RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS); 934 935 ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv, 936 PHYRX_RSSI_LEGACY_35, RSSI_COMB); 937 ppdu_info->rx_status.bw = hal->ops->hal_rx_get_tlv(rx_tlv); 938 ppdu_info->rx_status.he_re = 0; 939 940 ppdu_info->rx_status.reception_type = HAL_RX_GET(rx_tlv, 941 PHYRX_RSSI_LEGACY_0, RECEPTION_TYPE); 942 943 value = HAL_RX_GET(rssi_info_tlv, 944 RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); 945 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 946 "RSSI_PRI20_CHAIN0: %d\n", value); 947 948 value = HAL_RX_GET(rssi_info_tlv, 949 RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0); 950 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 951 "RSSI_EXT20_CHAIN0: %d\n", value); 952 953 value = HAL_RX_GET(rssi_info_tlv, 954 RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0); 955 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 956 "RSSI_EXT40_LOW20_CHAIN0: %d\n", value); 957 958 value = HAL_RX_GET(rssi_info_tlv, 959 RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0); 960 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 961 "RSSI_EXT40_HIGH20_CHAIN0: %d\n", value); 962 963 value = HAL_RX_GET(rssi_info_tlv, 964 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0); 965 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 966 "RSSI_EXT80_LOW20_CHAIN0: %d\n", value); 967 968 value = HAL_RX_GET(rssi_info_tlv, 969 RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0); 970 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 971 "RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value); 972 973 value = HAL_RX_GET(rssi_info_tlv, 974 RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0); 975 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 976 "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value); 977 978 value = HAL_RX_GET(rssi_info_tlv, 979 RECEIVE_RSSI_INFO_1, 980 RSSI_EXT80_HIGH20_CHAIN0); 981 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 982 "RSSI_EXT80_HIGH20_CHAIN0: %d\n", value); 983 break; 984 } 985 case WIFIPHYRX_OTHER_RECEIVE_INFO_E: 986 hal_rx_proc_phyrx_other_receive_info_tlv(hal, rx_tlv_hdr, 987 ppdu_info); 988 break; 989 case WIFIRX_HEADER_E: 990 ppdu_info->msdu_info.first_msdu_payload = rx_tlv; 991 ppdu_info->msdu_info.payload_len = tlv_len; 992 break; 993 case WIFIRX_MPDU_START_E: 994 { 995 uint8_t *rx_mpdu_start = 996 (uint8_t *)rx_tlv + HAL_RX_OFFSET(UNIFIED_RX_MPDU_START_0, 997 RX_MPDU_INFO_RX_MPDU_INFO_DETAILS); 998 uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, 999 PHY_PPDU_ID); 1000 uint8_t filter_category = 0; 1001 1002 ppdu_info->nac_info.fc_valid = 1003 HAL_RX_GET(rx_mpdu_start, 1004 RX_MPDU_INFO_2, 1005 MPDU_FRAME_CONTROL_VALID); 1006 1007 ppdu_info->nac_info.to_ds_flag = 1008 HAL_RX_GET(rx_mpdu_start, 1009 RX_MPDU_INFO_2, 1010 TO_DS); 1011 1012 ppdu_info->nac_info.mac_addr2_valid = 1013 HAL_RX_GET(rx_mpdu_start, 1014 RX_MPDU_INFO_2, 1015 MAC_ADDR_AD2_VALID); 1016 1017 *(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] = 1018 HAL_RX_GET(rx_mpdu_start, 1019 RX_MPDU_INFO_16, 1020 MAC_ADDR_AD2_15_0); 1021 1022 *(uint32_t *)&ppdu_info->nac_info.mac_addr2[2] = 1023 HAL_RX_GET(rx_mpdu_start, 1024 RX_MPDU_INFO_17, 1025 MAC_ADDR_AD2_47_16); 1026 1027 if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) { 1028 ppdu_info->rx_status.prev_ppdu_id = ppdu_id; 1029 ppdu_info->rx_status.ppdu_len = 1030 HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13, 1031 MPDU_LENGTH); 1032 } else { 1033 ppdu_info->rx_status.ppdu_len += 1034 HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13, 1035 MPDU_LENGTH); 1036 } 1037 1038 filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, 1039 RXPCU_MPDU_FILTER_IN_CATEGORY); 1040 if (filter_category == 1) 1041 ppdu_info->rx_status.monitor_direct_used = 1; 1042 break; 1043 } 1044 case 0: 1045 return HAL_TLV_STATUS_PPDU_DONE; 1046 1047 default: 1048 unhandled = true; 1049 break; 1050 } 1051 1052 if (!unhandled) 1053 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1054 "%s TLV type: %d, TLV len:%d %s", 1055 __func__, tlv_tag, tlv_len, 1056 unhandled == true ? "unhandled" : ""); 1057 1058 qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 1059 rx_tlv, tlv_len); 1060 1061 return HAL_TLV_STATUS_PPDU_NOT_DONE; 1062 } 1063 /** 1064 * hal_reo_status_get_header_generic - Process reo desc info 1065 * @d - Pointer to reo descriptior 1066 * @b - tlv type info 1067 * @h1 - Pointer to hal_reo_status_header where info to be stored 1068 * 1069 * Return - none. 1070 * 1071 */ 1072 static void hal_reo_status_get_header_generic(uint32_t *d, int b, void *h1) 1073 { 1074 1075 uint32_t val1 = 0; 1076 struct hal_reo_status_header *h = 1077 (struct hal_reo_status_header *)h1; 1078 1079 switch (b) { 1080 case HAL_REO_QUEUE_STATS_STATUS_TLV: 1081 val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, 1082 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1083 break; 1084 case HAL_REO_FLUSH_QUEUE_STATUS_TLV: 1085 val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, 1086 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1087 break; 1088 case HAL_REO_FLUSH_CACHE_STATUS_TLV: 1089 val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, 1090 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1091 break; 1092 case HAL_REO_UNBLK_CACHE_STATUS_TLV: 1093 val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, 1094 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1095 break; 1096 case HAL_REO_TIMOUT_LIST_STATUS_TLV: 1097 val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, 1098 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1099 break; 1100 case HAL_REO_DESC_THRES_STATUS_TLV: 1101 val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, 1102 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1103 break; 1104 case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: 1105 val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, 1106 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; 1107 break; 1108 default: 1109 pr_err("ERROR: Unknown tlv\n"); 1110 break; 1111 } 1112 h->cmd_num = 1113 HAL_GET_FIELD( 1114 UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, 1115 val1); 1116 h->exec_time = 1117 HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, 1118 CMD_EXECUTION_TIME, val1); 1119 h->status = 1120 HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, 1121 REO_CMD_EXECUTION_STATUS, val1); 1122 switch (b) { 1123 case HAL_REO_QUEUE_STATS_STATUS_TLV: 1124 val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, 1125 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1126 break; 1127 case HAL_REO_FLUSH_QUEUE_STATUS_TLV: 1128 val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, 1129 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1130 break; 1131 case HAL_REO_FLUSH_CACHE_STATUS_TLV: 1132 val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, 1133 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1134 break; 1135 case HAL_REO_UNBLK_CACHE_STATUS_TLV: 1136 val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, 1137 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1138 break; 1139 case HAL_REO_TIMOUT_LIST_STATUS_TLV: 1140 val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, 1141 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1142 break; 1143 case HAL_REO_DESC_THRES_STATUS_TLV: 1144 val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, 1145 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1146 break; 1147 case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: 1148 val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, 1149 UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; 1150 break; 1151 default: 1152 pr_err("ERROR: Unknown tlv\n"); 1153 break; 1154 } 1155 h->tstamp = 1156 HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); 1157 } 1158 1159 /** 1160 * hal_reo_setup - Initialize HW REO block 1161 * 1162 * @hal_soc: Opaque HAL SOC handle 1163 * @reo_params: parameters needed by HAL for REO config 1164 */ 1165 static void hal_reo_setup_generic(void *hal_soc, 1166 void *reoparams) 1167 { 1168 struct hal_soc *soc = (struct hal_soc *)hal_soc; 1169 uint32_t reg_val; 1170 struct hal_reo_params *reo_params = (struct hal_reo_params *)reoparams; 1171 1172 reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR( 1173 SEQ_WCSS_UMAC_REO_REG_OFFSET)); 1174 1175 reg_val &= ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK | 1176 HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | 1177 HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); 1178 1179 reg_val |= HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, 1180 FRAGMENT_DEST_RING, reo_params->frag_dst_ring) | 1181 HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_LIST_ENABLE, 1) | 1182 HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_FLUSH_ENABLE, 1); 1183 1184 HAL_REG_WRITE(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR( 1185 SEQ_WCSS_UMAC_REO_REG_OFFSET), reg_val); 1186 1187 /* Other ring enable bits and REO_ENABLE will be set by FW */ 1188 1189 /* TODO: Setup destination ring mapping if enabled */ 1190 1191 /* TODO: Error destination ring setting is left to default. 1192 * Default setting is to send all errors to release ring. 1193 */ 1194 1195 HAL_REG_WRITE(soc, 1196 HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR( 1197 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1198 HAL_DEFAULT_REO_TIMEOUT_MS * 1000); 1199 1200 HAL_REG_WRITE(soc, 1201 HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR( 1202 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1203 (HAL_DEFAULT_REO_TIMEOUT_MS * 1000)); 1204 1205 HAL_REG_WRITE(soc, 1206 HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR( 1207 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1208 (HAL_DEFAULT_REO_TIMEOUT_MS * 1000)); 1209 1210 HAL_REG_WRITE(soc, 1211 HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR( 1212 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1213 (HAL_DEFAULT_REO_TIMEOUT_MS * 1000)); 1214 1215 /* 1216 * When hash based routing is enabled, routing of the rx packet 1217 * is done based on the following value: 1 _ _ _ _ The last 4 1218 * bits are based on hash[3:0]. This means the possible values 1219 * are 0x10 to 0x1f. This value is used to look-up the 1220 * ring ID configured in Destination_Ring_Ctrl_IX_* register. 1221 * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3 1222 * registers need to be configured to set-up the 16 entries to 1223 * map the hash values to a ring number. There are 3 bits per 1224 * hash entry which are mapped as follows: 1225 * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI), 1226 * 7: NOT_USED. 1227 */ 1228 if (reo_params->rx_hash_enabled) { 1229 HAL_REG_WRITE(soc, 1230 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( 1231 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1232 reo_params->remap1); 1233 1234 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 1235 FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x"), 1236 HAL_REG_READ(soc, 1237 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( 1238 SEQ_WCSS_UMAC_REO_REG_OFFSET))); 1239 1240 HAL_REG_WRITE(soc, 1241 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( 1242 SEQ_WCSS_UMAC_REO_REG_OFFSET), 1243 reo_params->remap2); 1244 1245 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 1246 FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x"), 1247 HAL_REG_READ(soc, 1248 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( 1249 SEQ_WCSS_UMAC_REO_REG_OFFSET))); 1250 } 1251 1252 1253 /* TODO: Check if the following registers shoould be setup by host: 1254 * AGING_CONTROL 1255 * HIGH_MEMORY_THRESHOLD 1256 * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2] 1257 * GLOBAL_LINK_DESC_COUNT_CTRL 1258 */ 1259 } 1260 1261 /** 1262 * hal_srng_src_hw_init - Private function to initialize SRNG 1263 * source ring HW 1264 * @hal_soc: HAL SOC handle 1265 * @srng: SRNG ring pointer 1266 */ 1267 static inline void hal_srng_src_hw_init_generic(void *halsoc, 1268 struct hal_srng *srng) 1269 { 1270 struct hal_soc *hal = (struct hal_soc *)halsoc; 1271 uint32_t reg_val = 0; 1272 uint64_t tp_addr = 0; 1273 1274 HIF_DBG("%s: hw_init srng %d", __func__, srng->ring_id); 1275 1276 if (srng->flags & HAL_SRNG_MSI_INTR) { 1277 SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB, 1278 srng->msi_addr & 0xffffffff); 1279 reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR), 1280 (uint64_t)(srng->msi_addr) >> 32) | 1281 SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, 1282 MSI1_ENABLE), 1); 1283 SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val); 1284 SRNG_SRC_REG_WRITE(srng, MSI1_DATA, srng->msi_data); 1285 } 1286 1287 SRNG_SRC_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff); 1288 reg_val = SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_BASE_ADDR_MSB), 1289 ((uint64_t)(srng->ring_base_paddr) >> 32)) | 1290 SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_SIZE), 1291 srng->entry_size * srng->num_entries); 1292 SRNG_SRC_REG_WRITE(srng, BASE_MSB, reg_val); 1293 1294 #if defined(WCSS_VERSION) && \ 1295 ((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \ 1296 (defined(CONFIG_MCL) && (WCSS_VERSION >= 72))) 1297 reg_val = SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size); 1298 #else 1299 reg_val = SRNG_SM(SRNG_SRC_FLD(ID, RING_ID), srng->ring_id) | 1300 SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size); 1301 #endif 1302 SRNG_SRC_REG_WRITE(srng, ID, reg_val); 1303 1304 /** 1305 * Interrupt setup: 1306 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE 1307 * if level mode is required 1308 */ 1309 reg_val = 0; 1310 1311 /* 1312 * WAR - Hawkeye v1 has a hardware bug which requires timer value to be 1313 * programmed in terms of 1us resolution instead of 8us resolution as 1314 * given in MLD. 1315 */ 1316 if (srng->intr_timer_thres_us) { 1317 reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0, 1318 INTERRUPT_TIMER_THRESHOLD), 1319 srng->intr_timer_thres_us); 1320 /* For HK v2 this should be (srng->intr_timer_thres_us >> 3) */ 1321 } 1322 1323 if (srng->intr_batch_cntr_thres_entries) { 1324 reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0, 1325 BATCH_COUNTER_THRESHOLD), 1326 srng->intr_batch_cntr_thres_entries * 1327 srng->entry_size); 1328 } 1329 SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val); 1330 1331 reg_val = 0; 1332 if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) { 1333 reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1, 1334 LOW_THRESHOLD), srng->u.src_ring.low_threshold); 1335 } 1336 1337 SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX1, reg_val); 1338 1339 /* As per HW team, TP_ADDR and HP_ADDR for Idle link ring should 1340 * remain 0 to avoid some WBM stability issues. Remote head/tail 1341 * pointers are not required since this ring is completely managed 1342 * by WBM HW 1343 */ 1344 if (srng->ring_id != HAL_SRNG_WBM_IDLE_LINK) { 1345 tp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr + 1346 ((unsigned long)(srng->u.src_ring.tp_addr) - 1347 (unsigned long)(hal->shadow_rdptr_mem_vaddr))); 1348 SRNG_SRC_REG_WRITE(srng, TP_ADDR_LSB, tp_addr & 0xffffffff); 1349 SRNG_SRC_REG_WRITE(srng, TP_ADDR_MSB, tp_addr >> 32); 1350 } 1351 1352 /* Initilaize head and tail pointers to indicate ring is empty */ 1353 SRNG_SRC_REG_WRITE(srng, HP, 0); 1354 SRNG_SRC_REG_WRITE(srng, TP, 0); 1355 *(srng->u.src_ring.tp_addr) = 0; 1356 1357 reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ? 1358 SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) | 1359 ((srng->flags & HAL_SRNG_RING_PTR_SWAP) ? 1360 SRNG_SM(SRNG_SRC_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) | 1361 ((srng->flags & HAL_SRNG_MSI_SWAP) ? 1362 SRNG_SM(SRNG_SRC_FLD(MISC, MSI_SWAP_BIT), 1) : 0); 1363 1364 /* Loop count is not used for SRC rings */ 1365 reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, LOOPCNT_DISABLE), 1); 1366 1367 /* 1368 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1); 1369 * todo: update fw_api and replace with above line 1370 * (when SRNG_ENABLE field for the MISC register is available in fw_api) 1371 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC) 1372 */ 1373 reg_val |= 0x40; 1374 1375 SRNG_SRC_REG_WRITE(srng, MISC, reg_val); 1376 1377 } 1378 1379 /** 1380 * hal_srng_dst_hw_init - Private function to initialize SRNG 1381 * destination ring HW 1382 * @hal_soc: HAL SOC handle 1383 * @srng: SRNG ring pointer 1384 */ 1385 static inline void hal_srng_dst_hw_init_generic(void *halsoc, 1386 struct hal_srng *srng) 1387 { 1388 struct hal_soc *hal = (struct hal_soc *)halsoc; 1389 uint32_t reg_val = 0; 1390 uint64_t hp_addr = 0; 1391 1392 HIF_DBG("%s: hw_init srng %d", __func__, srng->ring_id); 1393 1394 if (srng->flags & HAL_SRNG_MSI_INTR) { 1395 SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB, 1396 srng->msi_addr & 0xffffffff); 1397 reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR), 1398 (uint64_t)(srng->msi_addr) >> 32) | 1399 SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, 1400 MSI1_ENABLE), 1); 1401 SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val); 1402 SRNG_DST_REG_WRITE(srng, MSI1_DATA, srng->msi_data); 1403 } 1404 1405 SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff); 1406 reg_val = SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_BASE_ADDR_MSB), 1407 ((uint64_t)(srng->ring_base_paddr) >> 32)) | 1408 SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_SIZE), 1409 srng->entry_size * srng->num_entries); 1410 SRNG_DST_REG_WRITE(srng, BASE_MSB, reg_val); 1411 1412 reg_val = SRNG_SM(SRNG_DST_FLD(ID, RING_ID), srng->ring_id) | 1413 SRNG_SM(SRNG_DST_FLD(ID, ENTRY_SIZE), srng->entry_size); 1414 SRNG_DST_REG_WRITE(srng, ID, reg_val); 1415 1416 1417 /** 1418 * Interrupt setup: 1419 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE 1420 * if level mode is required 1421 */ 1422 reg_val = 0; 1423 if (srng->intr_timer_thres_us) { 1424 reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP, 1425 INTERRUPT_TIMER_THRESHOLD), 1426 srng->intr_timer_thres_us >> 3); 1427 } 1428 1429 if (srng->intr_batch_cntr_thres_entries) { 1430 reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP, 1431 BATCH_COUNTER_THRESHOLD), 1432 srng->intr_batch_cntr_thres_entries * 1433 srng->entry_size); 1434 } 1435 1436 SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val); 1437 hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr + 1438 ((unsigned long)(srng->u.dst_ring.hp_addr) - 1439 (unsigned long)(hal->shadow_rdptr_mem_vaddr))); 1440 SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, hp_addr & 0xffffffff); 1441 SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32); 1442 1443 /* Initilaize head and tail pointers to indicate ring is empty */ 1444 SRNG_DST_REG_WRITE(srng, HP, 0); 1445 SRNG_DST_REG_WRITE(srng, TP, 0); 1446 *(srng->u.dst_ring.hp_addr) = 0; 1447 1448 reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ? 1449 SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) | 1450 ((srng->flags & HAL_SRNG_RING_PTR_SWAP) ? 1451 SRNG_SM(SRNG_DST_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) | 1452 ((srng->flags & HAL_SRNG_MSI_SWAP) ? 1453 SRNG_SM(SRNG_DST_FLD(MISC, MSI_SWAP_BIT), 1) : 0); 1454 1455 /* 1456 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1); 1457 * todo: update fw_api and replace with above line 1458 * (when SRNG_ENABLE field for the MISC register is available in fw_api) 1459 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC) 1460 */ 1461 reg_val |= 0x40; 1462 1463 SRNG_DST_REG_WRITE(srng, MISC, reg_val); 1464 1465 } 1466 #endif 1467