Browse Source

qcacld-3.0: Add AFC osif vendor command support

Add HDD osif AFC vendor command support and PLD send AFC response
data to target support. Call AFC common API to init/deinit AFC
component.

CRs-Fixed: 3375786
Change-Id: I84342b6ea3b2f14c75eba8745cb17070f404b8d1
Will Huang 2 years ago
parent
commit
2150c9edd1

+ 25 - 0
Kbuild

@@ -149,6 +149,10 @@ HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wext.o \
 	    $(HDD_SRC_DIR)/wlan_hdd_hostapd_wext.o
 endif
 
+ifeq ($(CONFIG_AFC_SUPPORT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_afc.o
+endif
+
 ifeq ($(CONFIG_DCS), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_dcs.o
 endif
@@ -2485,6 +2489,23 @@ endif
 
 $(call add-wlan-objs,dcs,$(DCS_OBJS))
 
+####### AFC ######
+AFC_CMN_OSIF_SRC  := $(WLAN_COMMON_ROOT)/os_if/linux/afc/src
+AFC_CMN_CORE_SRC  := $(WLAN_COMMON_ROOT)/umac/afc/core/src
+AFC_CMN_DISP_SRC  := $(WLAN_COMMON_ROOT)/umac/afc/dispatcher/src
+
+AFC_CMN_OSIF_INC  := -I$(WLAN_COMMON_INC)/os_if/linux/afc/inc
+AFC_CMN_DISP_INC  := -I$(WLAN_COMMON_INC)/umac/afc/dispatcher/inc
+AFC_CMN_CORE_INC  := -I$(WLAN_COMMON_INC)/umac/afc/core/inc
+
+ifeq ($(CONFIG_AFC_SUPPORT), y)
+AFC_OBJS := $(AFC_CMN_OSIF_SRC)/wlan_cfg80211_afc.o \
+	    $(AFC_CMN_CORE_SRC)/wlan_afc_main.o \
+	    $(AFC_CMN_DISP_SRC)/wlan_afc_ucfg_api.o
+endif
+
+$(call add-wlan-objs,afc,$(AFC_OBJS))
+
 ###### INTEROP ISSUES AP ########
 INTEROP_ISSUES_AP_OS_IF_SRC      := os_if/interop_issues_ap/src
 INTEROP_ISSUES_AP_TGT_SRC        := components/target_if/interop_issues_ap/src
@@ -3180,6 +3201,10 @@ INCS +=		$(TWT_CONV_INCS)
 ################ Dynamic ACS ####################
 INCS +=		$(DCS_TGT_IF_INC)
 INCS +=		$(DCS_DISP_INC)
+################ AFC #################
+INCS +=		$(AFC_CMN_OSIF_INC)
+INCS +=		$(AFC_CMN_DISP_INC)
+INCS +=		$(AFC_CMN_CORE_INC)
 ################ INTEROP ISSUES AP ################
 INCS +=		$(INTEROP_ISSUES_AP_OS_IF_INC)
 INCS +=		$(INTEROP_ISSUES_AP_TGT_INC)

+ 78 - 0
core/hdd/inc/wlan_hdd_afc.h

@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023 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
+ * 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.
+ */
+
+/**
+ * DOC: wlan_hdd_afc.h
+ *
+ * This file has the AFC osif interface with linux kernel.
+ */
+
+#ifndef __WLAN_HDD_AFC_H__
+#define __WLAN_HDD_AFC_H__
+#include <wlan_cfg80211.h>
+#include <qca_vendor.h>
+#include <wlan_objmgr_cmn.h>
+#include <wlan_cfg80211_afc.h>
+
+#ifdef CONFIG_AFC_SUPPORT
+
+#define FEATURE_AFC_VENDOR_COMMANDS \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_AFC_RESPONSE, \
+	.doit = wlan_hdd_vendor_afc_response, \
+	vendor_command_policy(wlan_cfg80211_afc_response_policy, \
+			      QCA_WLAN_VENDOR_ATTR_AFC_RESP_MAX) \
+},
+
+#define FEATURE_AFC_VENDOR_EVENTS \
+[QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT_INDEX] = {		   \
+	.vendor_id = QCA_NL80211_VENDOR_ID,		   \
+	.subcmd = QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT,	   \
+},
+
+/**
+ * wlan_hdd_vendor_afc_response() - OSIF callback function of NL vendor AFC
+ * response command.
+ * @wiphy: Pointer to WIPHY object
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to NL vendor command of AFC response
+ * @data_len: Length of NL vendor command of AFC response
+ *
+ * Return: 0 if success, otherwise error code
+ */
+int wlan_hdd_vendor_afc_response(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data,
+				 int data_len);
+
+/**
+ * wlan_hdd_register_afc_pld_cb() - API to register AFC PLD function to pass
+ * AFC response data to target.
+ * @psoc: Pointer to PSOC object
+ *
+ * Return: None
+ */
+void wlan_hdd_register_afc_pld_cb(struct wlan_objmgr_psoc *psoc);
+#else
+#define FEATURE_AFC_VENDOR_COMMANDS
+#define FEATURE_AFC_VENDOR_EVENTS
+
+static inline void wlan_hdd_register_afc_pld_cb(struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+#endif

+ 107 - 0
core/hdd/src/wlan_hdd_afc.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2023 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
+ * 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.
+ */
+
+/*
+ * DOC: wlan_hdd_afc.c
+ *
+ * This file has the AFC osif interface with linux kernel.
+ */
+
+#include <wlan_hdd_afc.h>
+#include <osif_psoc_sync.h>
+#include <wlan_cfg80211_afc.h>
+#include <wlan_hdd_main.h>
+#include <pld_common.h>
+#include <wlan_afc_ucfg_api.h>
+
+int wlan_hdd_vendor_afc_response(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data,
+				 int data_len)
+{
+	struct osif_psoc_sync *psoc_sync;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter();
+
+	ret = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
+	if (ret)
+		return ret;
+
+	hdd_ctx = wiphy_priv(wiphy);
+
+	if (!hdd_ctx->psoc) {
+		osif_err("psoc is null");
+		ret = -EINVAL;
+		goto sync_stop;
+	}
+
+	if (!hdd_ctx->pdev) {
+		osif_err("pdev is null");
+		ret = -EINVAL;
+		goto sync_stop;
+	}
+
+	ret = wlan_cfg80211_vendor_afc_response(hdd_ctx->psoc,
+						hdd_ctx->pdev,
+						data,
+						data_len);
+sync_stop:
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_send_response_to_afcmem() - Callback function register to AFC
+ * common component.
+ * @psoc: Pointer to PSOC object
+ * @pdev: Pointer to PDEV object
+ * @data: Pointer to AFC response data pass to target
+ * @len: Length of AFC response data pass to target
+ *
+ * Return: 0 if success, otherwise error code
+ */
+static int wlan_hdd_send_response_to_afcmem(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_pdev *pdev,
+					    struct wlan_afc_host_resp *data,
+					    uint32_t len)
+{
+	qdf_device_t qdf_dev;
+	int pdev_id;
+	const uint8_t *afcdb = (const uint8_t *)data;
+
+	qdf_dev = wlan_psoc_get_qdf_dev(psoc);
+	if (!qdf_dev) {
+		osif_err("Invalid qdf dev");
+		return -EINVAL;
+	}
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+
+	return pld_send_buffer_to_afcmem(qdf_dev->dev,
+					 afcdb,
+					 len,
+					 pdev_id);
+}
+
+void wlan_hdd_register_afc_pld_cb(struct wlan_objmgr_psoc *psoc)
+{
+	ucfg_afc_register_data_send_cb(psoc, wlan_hdd_send_response_to_afcmem);
+}

+ 3 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -163,6 +163,7 @@
 #include "wlan_cm_roam_ucfg_api.h"
 #include "hif.h"
 #include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_afc.h"
 #include "wlan_hdd_twt.h"
 #include "wlan_hdd_gpio.h"
 #include "wlan_hdd_medium_assess.h"
@@ -1964,6 +1965,7 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
 		.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG,
 	},
 #endif
+	FEATURE_AFC_VENDOR_EVENTS
 };
 
 /**
@@ -19633,6 +19635,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 	},
 	FEATURE_COAP_OFFLOAD_COMMANDS
 	FEATURE_ML_LINK_STATE_COMMANDS
+	FEATURE_AFC_VENDOR_COMMANDS
 };
 
 struct hdd_context *hdd_cfg80211_wiphy_alloc(void)

+ 11 - 0
core/hdd/src/wlan_hdd_main.c

@@ -138,6 +138,8 @@
 #include "nan_public_structs.h"
 #include "nan_ucfg_api.h"
 #include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_afc.h"
+#include "wlan_afc_ucfg_api.h"
 #include "wlan_dfs_ucfg_api.h"
 #include "wlan_hdd_rx_monitor.h"
 #include "sme_power_save_api.h"
@@ -4783,6 +4785,8 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
 
 		wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc);
 
+		wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc);
+
 		status = cds_pre_enable();
 		if (!QDF_IS_STATUS_SUCCESS(status)) {
 			hdd_err("Failed to pre-enable CDS; status: %d", status);
@@ -18102,8 +18106,14 @@ static QDF_STATUS hdd_component_init(void)
 	if (QDF_IS_STATUS_ERROR(status))
 		goto qmi_deinit;
 
+	status = ucfg_afc_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto ll_sap_deinit;
+
 	return QDF_STATUS_SUCCESS;
 
+ll_sap_deinit:
+	ucfg_ll_sap_deinit();
 qmi_deinit:
 	ucfg_qmi_deinit();
 dp_deinit:
@@ -18156,6 +18166,7 @@ mlme_global_deinit:
 static void hdd_component_deinit(void)
 {
 	/* deinitialize non-converged components */
+	ucfg_afc_deinit();
 	ucfg_ll_sap_deinit();
 	ucfg_qmi_deinit();
 	ucfg_dp_deinit();

+ 37 - 0
core/pld/inc/pld_common.h

@@ -1892,6 +1892,43 @@ static inline int pld_nbuf_pre_alloc_free(struct sk_buff *skb)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_AFC_SUPPORT
+/**
+ * pld_send_buffer_to_afcmem() - Send afc data to afc memory
+ * @dev: The device structure
+ * @afcdb: Pointer to afc data buffer
+ * @len: Length of afc data
+ * @slotid: Slot id of afc memory
+ *
+ * Return: Non-zero code for error; zero for success
+ */
+int pld_send_buffer_to_afcmem(struct device *dev, const uint8_t *afcdb,
+			      uint32_t len, uint8_t slotid);
+
+/**
+ * pld_reset_afcmem() - Reset afc data in afc memory
+ * @dev: The device structure
+ * @slotid: Slot id of afc memory
+ *
+ * Return: Non-zero code for error; zero for success
+ */
+int pld_reset_afcmem(struct device *dev, uint8_t slotid);
+#else
+static inline
+int pld_send_buffer_to_afcmem(struct device *dev, const uint8_t *afcdb,
+			      uint32_t len, uint8_t slotid)
+{
+	return -EINVAL;
+}
+
+static inline
+int pld_reset_afcmem(struct device *dev, uint8_t slotid)
+{
+	return -EINVAL;
+}
+#endif
+
 /**
  * pld_get_bus_type() - Bus type of the device
  * @dev: device

+ 13 - 0
core/pld/src/pld_common.c

@@ -2745,6 +2745,19 @@ bool pld_is_one_msi(struct device *dev)
 	return ret;
 }
 
+#ifdef CONFIG_AFC_SUPPORT
+int pld_send_buffer_to_afcmem(struct device *dev, const uint8_t *afcdb,
+			      uint32_t len, uint8_t slotid)
+{
+	return cnss_send_buffer_to_afcmem(dev, afcdb, len, slotid);
+}
+
+int pld_reset_afcmem(struct device *dev, uint8_t slotid)
+{
+	return cnss_reset_afcmem(dev, slotid);
+}
+#endif
+
 #ifdef FEATURE_DIRECT_LINK
 int pld_audio_smmu_map(struct device *dev, phys_addr_t paddr, dma_addr_t iova,
 		       size_t size)