|
@@ -0,0 +1,182 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
|
|
+ *
|
|
|
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
|
+ * purpose with or without fee is hereby granted, provided that the above
|
|
|
+ * copyright notice and this permission notice appear in all copies.
|
|
|
+ *
|
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
+ */
|
|
|
+
|
|
|
+#include "dp_types.h"
|
|
|
+#include "qdf_mem.h"
|
|
|
+#include "qdf_nbuf.h"
|
|
|
+#include "cfg_dp.h"
|
|
|
+#include "wlan_cfg.h"
|
|
|
+#include "dp_types.h"
|
|
|
+#include "hal_rx_flow.h"
|
|
|
+#include "dp_htt.h"
|
|
|
+#include "dp_internal.h"
|
|
|
+
|
|
|
+#ifdef WLAN_SUPPORT_RX_FISA
|
|
|
+
|
|
|
+void dp_rx_dump_fisa_table(struct dp_soc *soc)
|
|
|
+{
|
|
|
+ hal_rx_dump_fse_table(soc->rx_fst->hal_rx_fst);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * dp_rx_fst_attach() - Initialize Rx FST and setup necessary parameters
|
|
|
+ * @soc: SoC handle
|
|
|
+ * @pdev: Pdev handle
|
|
|
+ *
|
|
|
+ * Return: Handle to flow search table entry
|
|
|
+ */
|
|
|
+QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev)
|
|
|
+{
|
|
|
+ struct dp_rx_fst *fst;
|
|
|
+ uint8_t *hash_key;
|
|
|
+ struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
|
|
|
+
|
|
|
+ /* Check if it is enabled in the INI */
|
|
|
+ if (!wlan_cfg_is_rx_fisa_enabled(cfg)) {
|
|
|
+ dp_err("RX FISA feature is disabled");
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef NOT_YET /* Not required for now */
|
|
|
+ /* Check if FW supports */
|
|
|
+ if (!wlan_psoc_nif_fw_ext_cap_get((void *)pdev->ctrl_pdev,
|
|
|
+ WLAN_SOC_CEXT_RX_FSE_SUPPORT)) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "rx fse disabled in FW\n");
|
|
|
+ wlan_cfg_set_rx_flow_tag_enabled(cfg, false);
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ if (soc->rx_fst) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "RX FST already allocated\n");
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ fst = qdf_mem_malloc(sizeof(struct dp_rx_fst));
|
|
|
+ if (!fst) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "RX FST allocation failed\n");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ fst->max_skid_length = wlan_cfg_rx_fst_get_max_search(cfg);
|
|
|
+ fst->max_entries = wlan_cfg_get_rx_flow_search_table_size(cfg);
|
|
|
+ hash_key = wlan_cfg_rx_fst_get_hash_key(cfg);
|
|
|
+
|
|
|
+ fst->hash_mask = fst->max_entries - 1;
|
|
|
+ fst->num_entries = 0;
|
|
|
+ dp_err("FST setup params FT size %d, hash_mask 0x%x, skid_length %d",
|
|
|
+ fst->max_entries, fst->hash_mask, fst->max_skid_length);
|
|
|
+
|
|
|
+ fst->base = (uint8_t *)qdf_mem_malloc(DP_RX_GET_SW_FT_ENTRY_SIZE *
|
|
|
+ fst->max_entries);
|
|
|
+
|
|
|
+ if (!fst->base) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "Rx fst->base allocation failed, #entries:%d\n",
|
|
|
+ fst->max_entries);
|
|
|
+
|
|
|
+ goto out2;
|
|
|
+ }
|
|
|
+
|
|
|
+ fst->hal_rx_fst = hal_rx_fst_attach(soc->osdev,
|
|
|
+ &fst->hal_rx_fst_base_paddr,
|
|
|
+ fst->max_entries,
|
|
|
+ fst->max_skid_length, hash_key);
|
|
|
+
|
|
|
+ if (qdf_unlikely(!fst->hal_rx_fst)) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "Rx Hal fst allocation failed, #entries:%d\n",
|
|
|
+ fst->max_entries);
|
|
|
+ goto out1;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_spinlock_create(&fst->dp_rx_fst_lock);
|
|
|
+
|
|
|
+ fst->soc_hdl = soc;
|
|
|
+ soc->rx_fst = fst;
|
|
|
+ soc->fisa_enable = true;
|
|
|
+
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "Rx FST attach successful, #entries:%d\n",
|
|
|
+ fst->max_entries);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+out1:
|
|
|
+ qdf_mem_free(fst->base);
|
|
|
+out2:
|
|
|
+ qdf_mem_free(fst);
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * dp_rx_flow_send_fst_fw_setup() - Program FST parameters in FW/HW post-attach
|
|
|
+ * @soc: SoC handle
|
|
|
+ * @pdev: Pdev handle
|
|
|
+ *
|
|
|
+ * Return: Success when fst parameters are programmed in FW, error otherwise
|
|
|
+ */
|
|
|
+QDF_STATUS dp_rx_flow_send_fst_fw_setup(struct dp_soc *soc,
|
|
|
+ struct dp_pdev *pdev)
|
|
|
+{
|
|
|
+ struct dp_htt_rx_flow_fst_setup fisa_hw_fst_setup_cmd = {0};
|
|
|
+ struct dp_rx_fst *fst = soc->rx_fst;
|
|
|
+ struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ /* mac_id = 0 is used to configure both macs with same FT */
|
|
|
+ fisa_hw_fst_setup_cmd.pdev_id = 0;
|
|
|
+ fisa_hw_fst_setup_cmd.max_entries = fst->max_entries;
|
|
|
+ fisa_hw_fst_setup_cmd.max_search = fst->max_skid_length;
|
|
|
+ fisa_hw_fst_setup_cmd.base_addr_lo = fst->hal_rx_fst_base_paddr &
|
|
|
+ 0xffffffff;
|
|
|
+ fisa_hw_fst_setup_cmd.base_addr_hi = (fst->hal_rx_fst_base_paddr >> 32);
|
|
|
+ fisa_hw_fst_setup_cmd.ip_da_sa_prefix = HTT_RX_IPV4_COMPATIBLE_IPV6;
|
|
|
+ fisa_hw_fst_setup_cmd.hash_key_len = HAL_FST_HASH_KEY_SIZE_BYTES;
|
|
|
+ fisa_hw_fst_setup_cmd.hash_key = wlan_cfg_rx_fst_get_hash_key(cfg);
|
|
|
+
|
|
|
+ status = dp_htt_rx_flow_fst_setup(pdev, &fisa_hw_fst_setup_cmd);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * dp_rx_fst_detach() - De-initialize Rx FST
|
|
|
+ * @soc: SoC handle
|
|
|
+ * @pdev: Pdev handle
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
|
|
+{
|
|
|
+ struct dp_rx_fst *dp_fst;
|
|
|
+
|
|
|
+ dp_fst = soc->rx_fst;
|
|
|
+ if (qdf_likely(dp_fst)) {
|
|
|
+ hal_rx_fst_detach(dp_fst->hal_rx_fst, soc->osdev);
|
|
|
+ qdf_mem_free(dp_fst->base);
|
|
|
+ qdf_spinlock_destroy(&dp_fst->dp_rx_fst_lock);
|
|
|
+ qdf_mem_free(dp_fst);
|
|
|
+ }
|
|
|
+ soc->rx_fst = NULL;
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "Rx FST detached\n");
|
|
|
+}
|
|
|
+#else /* WLAN_SUPPORT_RX_FISA */
|
|
|
+
|
|
|
+#endif /* !WLAN_SUPPORT_RX_FISA */
|
|
|
+
|