|
@@ -1,5 +1,6 @@
|
|
|
/*
|
|
|
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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
|
|
@@ -204,23 +205,26 @@ qdf_export_symbol(hal_rx_flow_get_cmem_fse_timestamp);
|
|
|
|
|
|
/**
|
|
|
* hal_rx_flow_delete_entry() - Delete a flow from the Rx Flow Search Table
|
|
|
+ * @hal_soc_hdl: HAL SOC handle
|
|
|
* @fst: Pointer to the Rx Flow Search Table
|
|
|
* @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST
|
|
|
*
|
|
|
* Return: Success/Failure
|
|
|
*/
|
|
|
QDF_STATUS
|
|
|
-hal_rx_flow_delete_entry(struct hal_rx_fst *fst, void *hal_rx_fse)
|
|
|
+hal_rx_flow_delete_entry(hal_soc_handle_t hal_soc_hdl,
|
|
|
+ struct hal_rx_fst *fst, void *hal_rx_fse)
|
|
|
{
|
|
|
- uint8_t *fse = (uint8_t *)hal_rx_fse;
|
|
|
-
|
|
|
- if (!HAL_GET_FLD(fse, HAL_RX_FLOW_SEARCH_ENTRY, VALID))
|
|
|
- return QDF_STATUS_E_NOENT;
|
|
|
+ struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
|
|
|
|
|
- HAL_CLR_FLD(fse, HAL_RX_FLOW_SEARCH_ENTRY, VALID);
|
|
|
+ if (hal_soc->ops->hal_rx_flow_delete_entry) {
|
|
|
+ return hal_soc->ops->hal_rx_flow_delete_entry((uint8_t *)fst,
|
|
|
+ hal_rx_fse);
|
|
|
+ }
|
|
|
|
|
|
- return QDF_STATUS_SUCCESS;
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
}
|
|
|
+
|
|
|
qdf_export_symbol(hal_rx_flow_delete_entry);
|
|
|
|
|
|
#ifndef WLAN_SUPPORT_RX_FISA
|
|
@@ -270,70 +274,41 @@ static inline void *hal_rx_fst_get_base(struct hal_rx_fst *fst)
|
|
|
*
|
|
|
* Return: size of each entry/flow in Rx FST
|
|
|
*/
|
|
|
-static inline uint32_t hal_rx_fst_get_fse_size(void)
|
|
|
+static inline uint32_t
|
|
|
+hal_rx_fst_get_fse_size(hal_soc_handle_t hal_soc_hdl)
|
|
|
{
|
|
|
- return HAL_RX_FST_ENTRY_SIZE;
|
|
|
+ struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
|
|
+
|
|
|
+ if (hal_soc->ops->hal_rx_fst_get_fse_size)
|
|
|
+ return hal_soc->ops->hal_rx_fst_get_fse_size();
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hal_rx_flow_get_tuple_info() - Retrieve the 5-tuple flow info for an entry
|
|
|
- * @hal_fse: Pointer to the Flow in Rx FST
|
|
|
+ * hal_rx_flow_get_tuple_info() - Get a flow search entry in HW FST
|
|
|
+ * @hal_soc_hdl: HAL SOC handle
|
|
|
+ * @fst: Pointer to the Rx Flow Search Table
|
|
|
+ * @hal_hash: HAL 5 tuple hash
|
|
|
* @tuple_info: 5-tuple info of the flow returned to the caller
|
|
|
*
|
|
|
* Return: Success/Failure
|
|
|
*/
|
|
|
-QDF_STATUS hal_rx_flow_get_tuple_info(void *hal_fse,
|
|
|
- struct hal_flow_tuple_info *tuple_info)
|
|
|
+void *
|
|
|
+hal_rx_flow_get_tuple_info(hal_soc_handle_t hal_soc_hdl,
|
|
|
+ struct hal_rx_fst *fst,
|
|
|
+ uint32_t hal_hash,
|
|
|
+ struct hal_flow_tuple_info *tuple_info)
|
|
|
{
|
|
|
- if (!hal_fse || !tuple_info)
|
|
|
- return QDF_STATUS_E_INVAL;
|
|
|
-
|
|
|
- if (!HAL_GET_FLD(hal_fse, HAL_RX_FLOW_SEARCH_ENTRY, VALID))
|
|
|
- return QDF_STATUS_E_NOENT;
|
|
|
-
|
|
|
- tuple_info->src_ip_127_96 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- SRC_IP_127_96));
|
|
|
- tuple_info->src_ip_95_64 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- SRC_IP_95_64));
|
|
|
- tuple_info->src_ip_63_32 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- SRC_IP_63_32));
|
|
|
- tuple_info->src_ip_31_0 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- SRC_IP_31_0));
|
|
|
- tuple_info->dest_ip_127_96 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- DEST_IP_127_96));
|
|
|
- tuple_info->dest_ip_95_64 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- DEST_IP_95_64));
|
|
|
- tuple_info->dest_ip_63_32 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- DEST_IP_63_32));
|
|
|
- tuple_info->dest_ip_31_0 =
|
|
|
- qdf_ntohl(HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- DEST_IP_31_0));
|
|
|
- tuple_info->dest_port = HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- DEST_PORT);
|
|
|
- tuple_info->src_port = HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- SRC_PORT);
|
|
|
- tuple_info->l4_protocol = HAL_GET_FLD(hal_fse,
|
|
|
- HAL_RX_FLOW_SEARCH_ENTRY,
|
|
|
- L4_PROTOCOL);
|
|
|
+ struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
|
|
|
|
|
- return QDF_STATUS_SUCCESS;
|
|
|
+ if (hal_soc->ops->hal_rx_flow_get_tuple_info)
|
|
|
+ return hal_soc->ops->hal_rx_flow_get_tuple_info(
|
|
|
+ (uint8_t *)fst,
|
|
|
+ hal_hash,
|
|
|
+ (uint8_t *)tuple_info);
|
|
|
+
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
#ifndef WLAN_SUPPORT_RX_FISA
|
|
@@ -417,11 +392,13 @@ static void hal_flow_toeplitz_create_cache(struct hal_rx_fst *fst)
|
|
|
* Return:
|
|
|
*/
|
|
|
struct hal_rx_fst *
|
|
|
-hal_rx_fst_attach(qdf_device_t qdf_dev,
|
|
|
+hal_rx_fst_attach(hal_soc_handle_t hal_soc_hdl,
|
|
|
+ qdf_device_t qdf_dev,
|
|
|
uint64_t *hal_fst_base_paddr, uint16_t max_entries,
|
|
|
uint16_t max_search, uint8_t *hash_key)
|
|
|
{
|
|
|
struct hal_rx_fst *fst = qdf_mem_malloc(sizeof(struct hal_rx_fst));
|
|
|
+ uint32_t fst_entry_size;
|
|
|
|
|
|
if (!fst) {
|
|
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
@@ -436,13 +413,16 @@ hal_rx_fst_attach(qdf_device_t qdf_dev,
|
|
|
fst->max_entries = max_entries;
|
|
|
fst->hash_mask = max_entries - 1;
|
|
|
|
|
|
+ fst_entry_size = hal_rx_fst_get_fse_size(hal_soc_hdl);
|
|
|
+
|
|
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
|
|
"HAL FST allocation %pK %d * %d\n", fst,
|
|
|
- fst->max_entries, HAL_RX_FST_ENTRY_SIZE);
|
|
|
+ fst->max_entries, fst_entry_size);
|
|
|
+
|
|
|
|
|
|
fst->base_vaddr = (uint8_t *)qdf_mem_alloc_consistent(qdf_dev,
|
|
|
qdf_dev->dev,
|
|
|
- (fst->max_entries * HAL_RX_FST_ENTRY_SIZE),
|
|
|
+ (fst->max_entries * fst_entry_size),
|
|
|
&fst->base_paddr);
|
|
|
|
|
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
|
|
@@ -457,7 +437,7 @@ hal_rx_fst_attach(qdf_device_t qdf_dev,
|
|
|
(void *)fst->key, HAL_FST_HASH_KEY_SIZE_BYTES);
|
|
|
|
|
|
qdf_mem_set((uint8_t *)fst->base_vaddr,
|
|
|
- (fst->max_entries * HAL_RX_FST_ENTRY_SIZE), 0);
|
|
|
+ (fst->max_entries * fst_entry_size), 0);
|
|
|
|
|
|
hal_rx_fst_key_configure(fst);
|
|
|
hal_flow_toeplitz_create_cache(fst);
|
|
@@ -469,19 +449,25 @@ qdf_export_symbol(hal_rx_fst_attach);
|
|
|
/**
|
|
|
* hal_rx_fst_detach() - De-init the Rx flow search table from HW
|
|
|
*
|
|
|
+ * @hal_soc_hdl: HAL SOC handler
|
|
|
* @rx_fst: Pointer to the Rx FST
|
|
|
* @qdf_dev: QDF device handle
|
|
|
*
|
|
|
* Return:
|
|
|
*/
|
|
|
-void hal_rx_fst_detach(struct hal_rx_fst *rx_fst,
|
|
|
+void hal_rx_fst_detach(hal_soc_handle_t hal_soc_hdl,
|
|
|
+ struct hal_rx_fst *rx_fst,
|
|
|
qdf_device_t qdf_dev)
|
|
|
{
|
|
|
+ uint32_t fst_entry_size;
|
|
|
+
|
|
|
if (!rx_fst || !qdf_dev)
|
|
|
return;
|
|
|
|
|
|
+ fst_entry_size = hal_rx_fst_get_fse_size(hal_soc_hdl);
|
|
|
+
|
|
|
qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
|
|
|
- rx_fst->max_entries * HAL_RX_FST_ENTRY_SIZE,
|
|
|
+ rx_fst->max_entries * fst_entry_size,
|
|
|
rx_fst->base_vaddr, rx_fst->base_paddr, 0);
|
|
|
|
|
|
qdf_mem_free(rx_fst);
|
|
@@ -566,7 +552,7 @@ qdf_export_symbol(hal_rx_get_hal_hash);
|
|
|
|
|
|
/**
|
|
|
* hal_rx_insert_flow_entry() - Add a flow into the FST table
|
|
|
- *
|
|
|
+ * @hal_soc: HAL SOC handle
|
|
|
* @hal_fst: HAL Rx FST Handle
|
|
|
* @flow_hash: Flow hash computed from flow tuple
|
|
|
* @flow_tuple_info: Flow tuple used to compute the hash
|
|
@@ -575,21 +561,21 @@ qdf_export_symbol(hal_rx_get_hal_hash);
|
|
|
* Return: Success if flow is inserted into the table, error otherwise
|
|
|
*/
|
|
|
QDF_STATUS
|
|
|
-hal_rx_insert_flow_entry(struct hal_rx_fst *fst, uint32_t flow_hash,
|
|
|
+hal_rx_insert_flow_entry(hal_soc_handle_t hal_soc,
|
|
|
+ struct hal_rx_fst *fst, uint32_t flow_hash,
|
|
|
void *flow_tuple_info, uint32_t *flow_idx)
|
|
|
{
|
|
|
int i;
|
|
|
void *hal_fse = NULL;
|
|
|
uint32_t hal_hash = 0;
|
|
|
struct hal_flow_tuple_info hal_tuple_info = { 0 };
|
|
|
- QDF_STATUS status;
|
|
|
|
|
|
for (i = 0; i < fst->max_skid_length; i++) {
|
|
|
hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i));
|
|
|
- hal_fse = (uint8_t *)fst->base_vaddr +
|
|
|
- (hal_hash * HAL_RX_FST_ENTRY_SIZE);
|
|
|
- status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info);
|
|
|
- if (status == QDF_STATUS_E_NOENT)
|
|
|
+
|
|
|
+ hal_fse = hal_rx_flow_get_tuple_info(hal_soc, fst, hal_hash,
|
|
|
+ &hal_tuple_info);
|
|
|
+ if (!hal_fse)
|
|
|
break;
|
|
|
|
|
|
/* Find the matching flow entry in HW FST */
|
|
@@ -624,21 +610,21 @@ qdf_export_symbol(hal_rx_insert_flow_entry);
|
|
|
* Return: Success if matching flow is found in the table, error otherwise
|
|
|
*/
|
|
|
QDF_STATUS
|
|
|
-hal_rx_find_flow_from_tuple(struct hal_rx_fst *fst, uint32_t flow_hash,
|
|
|
+hal_rx_find_flow_from_tuple(hal_soc_handle_t hal_soc_hdl,
|
|
|
+ struct hal_rx_fst *fst, uint32_t flow_hash,
|
|
|
void *flow_tuple_info, uint32_t *flow_idx)
|
|
|
{
|
|
|
int i;
|
|
|
void *hal_fse = NULL;
|
|
|
uint32_t hal_hash = 0;
|
|
|
struct hal_flow_tuple_info hal_tuple_info = { 0 };
|
|
|
- QDF_STATUS status;
|
|
|
|
|
|
for (i = 0; i < fst->max_skid_length; i++) {
|
|
|
hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i));
|
|
|
- hal_fse = (uint8_t *)fst->base_vaddr +
|
|
|
- (hal_hash * HAL_RX_FST_ENTRY_SIZE);
|
|
|
- status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info);
|
|
|
- if (status != QDF_STATUS_SUCCESS)
|
|
|
+
|
|
|
+ hal_fse = hal_rx_flow_get_tuple_info(hal_soc_hdl, fst, hal_hash,
|
|
|
+ &hal_tuple_info);
|
|
|
+ if (!hal_fse)
|
|
|
continue;
|
|
|
|
|
|
/* Find the matching flow entry in HW FST */
|