1 /* 2 * Copyright (c) 2021 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 19 #include "dp_types.h" 20 #include <dp_internal.h> 21 #include <dp_htt.h> 22 #include "dp_li.h" 23 #include "dp_li_tx.h" 24 #include "dp_li_rx.h" 25 #include "dp_peer.h" 26 27 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 28 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = { 29 {.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_LI_WBM_SW0_BM_ID, .for_ipa = 0}, 30 {1, 4, HAL_LI_WBM_SW4_BM_ID, 1}, /* For IPA */ 31 {2, 2, HAL_LI_WBM_SW2_BM_ID, 1} /* For IPA */}; 32 #else 33 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = { 34 {.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_LI_WBM_SW0_BM_ID, .for_ipa = 0}, 35 {1, 1, HAL_LI_WBM_SW1_BM_ID, 0}, 36 {2, 2, HAL_LI_WBM_SW2_BM_ID, 0} 37 }; 38 #endif 39 40 static void dp_soc_cfg_attach_li(struct dp_soc *soc) 41 { 42 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 43 44 wlan_cfg_set_rx_rel_ring_id(soc_cfg_ctx, WBM2SW_REL_ERR_RING_NUM); 45 46 soc_cfg_ctx->tcl_wbm_map_array = g_tcl_wbm_map_array; 47 } 48 49 qdf_size_t dp_get_context_size_li(enum dp_context_type context_type) 50 { 51 switch (context_type) { 52 case DP_CONTEXT_TYPE_SOC: 53 return sizeof(struct dp_soc_li); 54 case DP_CONTEXT_TYPE_PDEV: 55 return sizeof(struct dp_pdev_li); 56 case DP_CONTEXT_TYPE_VDEV: 57 return sizeof(struct dp_vdev_li); 58 case DP_CONTEXT_TYPE_PEER: 59 return sizeof(struct dp_peer_li); 60 default: 61 return 0; 62 } 63 } 64 65 static QDF_STATUS dp_soc_attach_li(struct dp_soc *soc) 66 { 67 soc->wbm_sw0_bm_id = hal_tx_get_wbm_sw0_bm_id(); 68 69 return QDF_STATUS_SUCCESS; 70 } 71 72 static QDF_STATUS dp_soc_detach_li(struct dp_soc *soc) 73 { 74 return QDF_STATUS_SUCCESS; 75 } 76 77 static QDF_STATUS dp_soc_init_li(struct dp_soc *soc) 78 { 79 return QDF_STATUS_SUCCESS; 80 } 81 82 static QDF_STATUS dp_soc_deinit_li(struct dp_soc *soc) 83 { 84 return QDF_STATUS_SUCCESS; 85 } 86 87 static QDF_STATUS dp_pdev_attach_li(struct dp_pdev *pdev) 88 { 89 return QDF_STATUS_SUCCESS; 90 } 91 92 static QDF_STATUS dp_pdev_detach_li(struct dp_pdev *pdev) 93 { 94 return QDF_STATUS_SUCCESS; 95 } 96 97 static QDF_STATUS dp_vdev_attach_li(struct dp_soc *soc, struct dp_vdev *vdev) 98 { 99 return QDF_STATUS_SUCCESS; 100 } 101 102 static QDF_STATUS dp_vdev_detach_li(struct dp_soc *soc, struct dp_vdev *vdev) 103 { 104 return QDF_STATUS_SUCCESS; 105 } 106 107 #ifdef AST_OFFLOAD_ENABLE 108 static void dp_peer_detach_li(struct dp_soc *soc) 109 { 110 dp_soc_wds_detach(soc); 111 dp_peer_ast_hash_detach(soc); 112 dp_peer_mec_hash_detach(soc); 113 } 114 115 static QDF_STATUS dp_peer_attach_li(struct dp_soc *soc) 116 { 117 QDF_STATUS status; 118 119 status = dp_peer_ast_table_attach(soc); 120 if (!QDF_IS_STATUS_SUCCESS(status)) 121 goto hash_detach; 122 123 status = dp_peer_ast_hash_attach(soc); 124 if (!QDF_IS_STATUS_SUCCESS(status)) 125 goto ast_table_detach; 126 127 status = dp_peer_mec_hash_attach(soc); 128 if (QDF_IS_STATUS_SUCCESS(status)) { 129 dp_soc_wds_attach(soc); 130 return status; 131 } 132 133 hash_detach: 134 dp_peer_ast_hash_detach(soc); 135 ast_table_detach: 136 dp_peer_ast_table_detach(soc); 137 138 return status; 139 } 140 #endif 141 142 qdf_size_t dp_get_soc_context_size_li(void) 143 { 144 return sizeof(struct dp_soc); 145 } 146 147 #ifdef NO_RX_PKT_HDR_TLV 148 /** 149 * dp_rxdma_ring_sel_cfg_li() - Setup RXDMA ring config 150 * @soc: Common DP soc handle 151 * 152 * Return: QDF_STATUS 153 */ 154 static QDF_STATUS 155 dp_rxdma_ring_sel_cfg_li(struct dp_soc *soc) 156 { 157 int i; 158 int mac_id; 159 struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; 160 QDF_STATUS status = QDF_STATUS_SUCCESS; 161 162 htt_tlv_filter.mpdu_start = 1; 163 htt_tlv_filter.msdu_start = 1; 164 htt_tlv_filter.mpdu_end = 1; 165 htt_tlv_filter.msdu_end = 1; 166 htt_tlv_filter.attention = 1; 167 htt_tlv_filter.packet = 1; 168 htt_tlv_filter.packet_header = 0; 169 170 htt_tlv_filter.ppdu_start = 0; 171 htt_tlv_filter.ppdu_end = 0; 172 htt_tlv_filter.ppdu_end_user_stats = 0; 173 htt_tlv_filter.ppdu_end_user_stats_ext = 0; 174 htt_tlv_filter.ppdu_end_status_done = 0; 175 htt_tlv_filter.enable_fp = 1; 176 htt_tlv_filter.enable_md = 0; 177 htt_tlv_filter.enable_md = 0; 178 htt_tlv_filter.enable_mo = 0; 179 180 htt_tlv_filter.fp_mgmt_filter = 0; 181 htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ; 182 htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST | 183 FILTER_DATA_MCAST | 184 FILTER_DATA_DATA); 185 htt_tlv_filter.mo_mgmt_filter = 0; 186 htt_tlv_filter.mo_ctrl_filter = 0; 187 htt_tlv_filter.mo_data_filter = 0; 188 htt_tlv_filter.md_data_filter = 0; 189 190 htt_tlv_filter.offset_valid = true; 191 192 htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size; 193 /*Not subscribing rx_pkt_header*/ 194 htt_tlv_filter.rx_header_offset = 0; 195 htt_tlv_filter.rx_mpdu_start_offset = 196 hal_rx_mpdu_start_offset_get(soc->hal_soc); 197 htt_tlv_filter.rx_mpdu_end_offset = 198 hal_rx_mpdu_end_offset_get(soc->hal_soc); 199 htt_tlv_filter.rx_msdu_start_offset = 200 hal_rx_msdu_start_offset_get(soc->hal_soc); 201 htt_tlv_filter.rx_msdu_end_offset = 202 hal_rx_msdu_end_offset_get(soc->hal_soc); 203 htt_tlv_filter.rx_attn_offset = 204 hal_rx_attn_offset_get(soc->hal_soc); 205 206 for (i = 0; i < MAX_PDEV_CNT; i++) { 207 struct dp_pdev *pdev = soc->pdev_list[i]; 208 209 if (!pdev) 210 continue; 211 212 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { 213 int mac_for_pdev = 214 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 215 /* 216 * Obtain lmac id from pdev to access the LMAC ring 217 * in soc context 218 */ 219 int lmac_id = 220 dp_get_lmac_id_for_pdev_id(soc, mac_id, 221 pdev->pdev_id); 222 223 htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 224 soc->rx_refill_buf_ring[lmac_id]. 225 hal_srng, 226 RXDMA_BUF, RX_DATA_BUFFER_SIZE, 227 &htt_tlv_filter); 228 } 229 } 230 return status; 231 } 232 #else 233 234 static QDF_STATUS 235 dp_rxdma_ring_sel_cfg_li(struct dp_soc *soc) 236 { 237 int i; 238 int mac_id; 239 struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; 240 struct dp_srng *rx_mac_srng; 241 QDF_STATUS status = QDF_STATUS_SUCCESS; 242 243 htt_tlv_filter.mpdu_start = 1; 244 htt_tlv_filter.msdu_start = 1; 245 htt_tlv_filter.mpdu_end = 1; 246 htt_tlv_filter.msdu_end = 1; 247 htt_tlv_filter.attention = 1; 248 htt_tlv_filter.packet = 1; 249 htt_tlv_filter.packet_header = 1; 250 251 htt_tlv_filter.ppdu_start = 0; 252 htt_tlv_filter.ppdu_end = 0; 253 htt_tlv_filter.ppdu_end_user_stats = 0; 254 htt_tlv_filter.ppdu_end_user_stats_ext = 0; 255 htt_tlv_filter.ppdu_end_status_done = 0; 256 htt_tlv_filter.enable_fp = 1; 257 htt_tlv_filter.enable_md = 0; 258 htt_tlv_filter.enable_md = 0; 259 htt_tlv_filter.enable_mo = 0; 260 261 htt_tlv_filter.fp_mgmt_filter = 0; 262 htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ; 263 htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST | 264 FILTER_DATA_MCAST | 265 FILTER_DATA_DATA); 266 htt_tlv_filter.mo_mgmt_filter = 0; 267 htt_tlv_filter.mo_ctrl_filter = 0; 268 htt_tlv_filter.mo_data_filter = 0; 269 htt_tlv_filter.md_data_filter = 0; 270 271 htt_tlv_filter.offset_valid = true; 272 273 htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size; 274 htt_tlv_filter.rx_header_offset = 275 hal_rx_pkt_tlv_offset_get(soc->hal_soc); 276 htt_tlv_filter.rx_mpdu_start_offset = 277 hal_rx_mpdu_start_offset_get(soc->hal_soc); 278 htt_tlv_filter.rx_mpdu_end_offset = 279 hal_rx_mpdu_end_offset_get(soc->hal_soc); 280 htt_tlv_filter.rx_msdu_start_offset = 281 hal_rx_msdu_start_offset_get(soc->hal_soc); 282 htt_tlv_filter.rx_msdu_end_offset = 283 hal_rx_msdu_end_offset_get(soc->hal_soc); 284 htt_tlv_filter.rx_attn_offset = 285 hal_rx_attn_offset_get(soc->hal_soc); 286 287 for (i = 0; i < MAX_PDEV_CNT; i++) { 288 struct dp_pdev *pdev = soc->pdev_list[i]; 289 290 if (!pdev) 291 continue; 292 293 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { 294 int mac_for_pdev = 295 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 296 /* 297 * Obtain lmac id from pdev to access the LMAC ring 298 * in soc context 299 */ 300 int lmac_id = 301 dp_get_lmac_id_for_pdev_id(soc, mac_id, 302 pdev->pdev_id); 303 304 rx_mac_srng = dp_get_rxdma_ring(pdev, lmac_id); 305 htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 306 rx_mac_srng->hal_srng, 307 RXDMA_BUF, RX_DATA_BUFFER_SIZE, 308 &htt_tlv_filter); 309 } 310 } 311 return status; 312 313 } 314 #endif 315 316 static void dp_soc_srng_deinit_li(struct dp_soc *soc) 317 { 318 } 319 320 static void dp_soc_srng_free_li(struct dp_soc *soc) 321 { 322 } 323 324 static QDF_STATUS dp_soc_srng_alloc_li(struct dp_soc *soc) 325 { 326 return QDF_STATUS_SUCCESS; 327 } 328 329 static QDF_STATUS dp_soc_srng_init_li(struct dp_soc *soc) 330 { 331 return QDF_STATUS_SUCCESS; 332 } 333 334 static void dp_tx_implicit_rbm_set_li(struct dp_soc *soc, 335 uint8_t tx_ring_id, 336 uint8_t bm_id) 337 { 338 } 339 340 void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops) 341 { 342 #ifndef QCA_HOST_MODE_WIFI_DISABLED 343 arch_ops->tx_hw_enqueue = dp_tx_hw_enqueue_li; 344 arch_ops->dp_rx_process = dp_rx_process_li; 345 arch_ops->tx_comp_get_params_from_hal_desc = 346 dp_tx_comp_get_params_from_hal_desc_li; 347 arch_ops->dp_wbm_get_rx_desc_from_hal_desc = 348 dp_wbm_get_rx_desc_from_hal_desc_li; 349 arch_ops->dp_tx_desc_pool_init = dp_tx_desc_pool_init_li; 350 arch_ops->dp_tx_desc_pool_deinit = dp_tx_desc_pool_deinit_li; 351 arch_ops->dp_rx_desc_pool_init = dp_rx_desc_pool_init_li; 352 arch_ops->dp_rx_desc_pool_deinit = dp_rx_desc_pool_deinit_li; 353 #else 354 arch_ops->dp_rx_desc_pool_init = dp_rx_desc_pool_init_generic; 355 arch_ops->dp_rx_desc_pool_deinit = dp_rx_desc_pool_deinit_generic; 356 #endif 357 arch_ops->txrx_get_context_size = dp_get_context_size_li; 358 arch_ops->txrx_soc_attach = dp_soc_attach_li; 359 arch_ops->txrx_soc_detach = dp_soc_detach_li; 360 arch_ops->txrx_soc_init = dp_soc_init_li; 361 arch_ops->txrx_soc_deinit = dp_soc_deinit_li; 362 arch_ops->txrx_soc_srng_alloc = dp_soc_srng_alloc_li; 363 arch_ops->txrx_soc_srng_init = dp_soc_srng_init_li; 364 arch_ops->txrx_soc_srng_deinit = dp_soc_srng_deinit_li; 365 arch_ops->txrx_soc_srng_free = dp_soc_srng_free_li; 366 arch_ops->txrx_pdev_attach = dp_pdev_attach_li; 367 arch_ops->txrx_pdev_detach = dp_pdev_detach_li; 368 arch_ops->txrx_vdev_attach = dp_vdev_attach_li; 369 arch_ops->txrx_vdev_detach = dp_vdev_detach_li; 370 #ifdef AST_OFFLOAD_ENABLE 371 arch_ops->txrx_peer_attach = dp_peer_attach_li; 372 arch_ops->txrx_peer_detach = dp_peer_detach_li; 373 #endif 374 arch_ops->dp_rx_desc_cookie_2_va = 375 dp_rx_desc_cookie_2_va_li; 376 arch_ops->dp_rxdma_ring_sel_cfg = dp_rxdma_ring_sel_cfg_li; 377 arch_ops->dp_rx_peer_metadata_peer_id_get = 378 dp_rx_peer_metadata_peer_id_get_li; 379 arch_ops->soc_cfg_attach = dp_soc_cfg_attach_li; 380 arch_ops->tx_implicit_rbm_set = dp_tx_implicit_rbm_set_li; 381 } 382 383