diff --git a/Kbuild b/Kbuild index f2a625838270..fb7a24e6ef26 100644 --- a/Kbuild +++ b/Kbuild @@ -1155,6 +1155,11 @@ WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_api.o WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_tlv.o endif +ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y) +WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_api.o +WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_tlv.o +endif + ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y) WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_api.o WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_tlv.o @@ -1437,6 +1442,25 @@ CP_STATS_OBJS := $(CP_STATS_TGT_SRC)/target_if_mc_cp_stats.o \ $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_mc_ucfg_api.o endif +###### 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 +INTEROP_ISSUES_AP_CORE_SRC := components/interop_issues_ap/core/src +INTEROP_ISSUES_AP_DISPATCHER_SRC := components/interop_issues_ap/dispatcher/src + +INTEROP_ISSUES_AP_OS_IF_INC := -I$(WLAN_ROOT)/os_if/interop_issues_ap/inc +INTEROP_ISSUES_AP_TGT_INC := -I$(WLAN_ROOT)/components/target_if/interop_issues_ap/inc +INTEROP_ISSUES_AP_DISPATCHER_INC := -I$(WLAN_ROOT)/components/interop_issues_ap/dispatcher/inc +INTEROP_ISSUES_AP_CORE_INC := -I$(WLAN_ROOT)/components/interop_issues_ap/core/inc + +ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y) +INTEROP_ISSUES_AP_OBJS := $(INTEROP_ISSUES_AP_TGT_SRC)/target_if_interop_issues_ap.o \ + $(INTEROP_ISSUES_AP_CORE_SRC)/wlan_interop_issues_ap_api.o \ + $(INTEROP_ISSUES_AP_OS_IF_SRC)/wlan_cfg80211_interop_issues_ap.o \ + $(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_tgt_api.o \ + $(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_ucfg_api.o +endif + ######################### NAN ######################### NAN_CORE_DIR := components/nan/core/src NAN_CORE_INC := -I$(WLAN_ROOT)/components/nan/core/inc @@ -1773,6 +1797,11 @@ INCS += $(WIFI_POS_OS_IF_INC) INCS += $(CP_STATS_OS_IF_INC) INCS += $(CP_STATS_TGT_INC) INCS += $(CP_STATS_DISPATCHER_INC) +################ INTEROP ISSUES AP ################ +INCS += $(INTEROP_ISSUES_AP_OS_IF_INC) +INCS += $(INTEROP_ISSUES_AP_TGT_INC) +INCS += $(INTEROP_ISSUES_AP_DISPATCHER_INC) +INCS += $(INTEROP_ISSUES_AP_CORE_INC) ################ NAN POS ################ INCS += $(NAN_CORE_INC) INCS += $(NAN_UCFG_INC) @@ -1867,6 +1896,7 @@ endif OBJS += $(UMAC_OBJMGR_OBJS) OBJS += $(WIFI_POS_OBJS) OBJS += $(CP_STATS_OBJS) +OBJS += $(INTEROP_ISSUES_AP_OBJS) OBJS += $(WLAN_NAN_OBJS) OBJS += $(UMAC_MGMT_TXRX_OBJS) OBJS += $(TDLS_OBJS) @@ -1975,6 +2005,7 @@ cppflags-$(CONFIG_WLAN_LOGGING_SOCK_SVC) += -DWLAN_LOGGING_SOCK_SVC_ENABLE cppflags-$(CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY) += -DWLAN_LOGGING_BUFFERS_DYNAMICALLY cppflags-$(CONFIG_WLAN_FEATURE_FILS) += -DWLAN_FEATURE_FILS_SK cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_CP_STATS +cppflags-$(CONFIG_FEATURE_INTEROP_ISSUES_AP) += -DWLAN_FEATURE_INTEROP_ISSUES_AP cppflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE cppflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING diff --git a/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h b/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h new file mode 100644 index 000000000000..b3de4ca59f32 --- /dev/null +++ b/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: wlan_interop_issues_ap_api.h + * + * This header file provide API declarations required for interop issues + * ap global context specific to offload + */ + +#ifndef __WLAN_INTEROP_ISSUES_AP_API_H__ +#define __WLAN_INTEROP_ISSUES_AP_API_H__ + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP +#include +#include +#include +#include +#include + +#define interop_issues_ap_debug(args ...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_INTEROP_ISSUES_AP, ## args) +#define interop_issues_ap_err(args ...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_INTEROP_ISSUES_AP, ## args) + +/** + * struct interop_issues_ap_psoc_priv_obj - psoc private object + * @lock: qdf spin lock + * @soc: pointer to psoc object + * @cbs: interop issues ap ps event callbacks + * @tx_ops: interop issues ap ps tx ops + */ +struct interop_issues_ap_psoc_priv_obj { + qdf_spinlock_t lock; + struct wlan_objmgr_psoc *soc; + struct wlan_interop_issues_ap_callbacks cbs; + struct wlan_interop_issues_ap_tx_ops tx_ops; +}; + +/** + * wlan_interop_issues_ap_psoc_enable() - interop issues ap psoc enable + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *soc); + +/** + * wlan_interop_issues_ap_psoc_disable() - interop issues ap psoc disable + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *soc); + +/** + * wlan_interop_issues_ap_init() - API to init component + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wlan_interop_issues_ap_init(void); + +/** + * wlan_interop_issues_ap_deinit() - API to deinit component + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wlan_interop_issues_ap_deinit(void); + +/** + * interop_issues_ap_get_psoc_priv_obj() - get priv object from psoc object + * @psoc: pointer to psoc object + * + * Return: pointer to interop issues ap psoc private object + */ +static inline +struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_get_psoc_priv_obj( + struct wlan_objmgr_psoc *psoc) +{ + struct interop_issues_ap_psoc_priv_obj *obj; + + if (!psoc) + return NULL; + + obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_INTEROP_ISSUES_AP); + + return obj; +} + +/** + * interop_issues_ap_psoc_get_tx_ops() - get TX ops from the private object + * @psoc: pointer to psoc object + * + * Return: pointer to TX op callback + */ +static inline +struct wlan_interop_issues_ap_tx_ops *interop_issues_ap_psoc_get_tx_ops( + struct wlan_objmgr_psoc *psoc) +{ + struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_priv; + + if (!psoc) + return NULL; + + interop_issues_ap_priv = interop_issues_ap_get_psoc_priv_obj(psoc); + if (!interop_issues_ap_priv) { + interop_issues_ap_err("psoc private object is null"); + return NULL; + } + + return &interop_issues_ap_priv->tx_ops; +} + +/** + * interop_issues_ap_psoc_get_cbs() - get RX ops from private object + * @psoc: pointer to psoc object + * + * Return: pointer to RX op callback + */ +static inline +struct wlan_interop_issues_ap_callbacks *interop_issues_ap_psoc_get_cbs( + struct wlan_objmgr_psoc *psoc) +{ + struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_priv; + + if (!psoc) + return NULL; + + interop_issues_ap_priv = interop_issues_ap_get_psoc_priv_obj(psoc); + if (!interop_issues_ap_priv) { + interop_issues_ap_err("psoc private object is null"); + return NULL; + } + + return &interop_issues_ap_priv->cbs; +} +#endif +#endif diff --git a/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c b/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c new file mode 100644 index 000000000000..88d08fbeb198 --- /dev/null +++ b/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: wlan_interop_issues_ap_api.c + */ +#include +#include +#include + +/** + * interop_issues_ap_psoc_obj_created_notification() - PSOC obj create callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is created. + * + * Return: Success or Failure + */ +static QDF_STATUS +interop_issues_ap_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj; + + interop_issues_ap_obj = qdf_mem_malloc(sizeof(*interop_issues_ap_obj)); + if (!interop_issues_ap_obj) + return QDF_STATUS_E_NOMEM; + + qdf_spinlock_create(&interop_issues_ap_obj->lock); + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_obj, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("obj attach with psoc failed"); + goto interop_issues_ap_psoc_attach_failed; + } + + target_if_interop_issues_ap_register_tx_ops(psoc, + &interop_issues_ap_obj->tx_ops); + + return QDF_STATUS_SUCCESS; + +interop_issues_ap_psoc_attach_failed: + qdf_spinlock_destroy(&interop_issues_ap_obj->lock); + qdf_mem_free(interop_issues_ap_obj); + return status; +} + +/** + * interop_issues_ap_psoc_obj_destroyed_notification() - obj delete callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is deleted. + * + * Return: Success or Failure + */ +static QDF_STATUS +interop_issues_ap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj; + + interop_issues_ap_obj = interop_issues_ap_get_psoc_priv_obj(psoc); + + if (!interop_issues_ap_obj) { + interop_issues_ap_err("interop_issues_ap_obj is NULL"); + return QDF_STATUS_E_FAULT; + } + target_if_interop_issues_ap_unregister_tx_ops(psoc, + &interop_issues_ap_obj->tx_ops); + + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_obj); + if (QDF_IS_STATUS_ERROR(status)) + interop_issues_ap_err("interop_issues_ap_obj detach failed"); + + qdf_spinlock_destroy(&interop_issues_ap_obj->lock); + qdf_mem_free(interop_issues_ap_obj); + + return status; +} + +QDF_STATUS wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return target_if_interop_issues_ap_register_event_handler(psoc); +} + +QDF_STATUS wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return target_if_interop_issues_ap_unregister_event_handler(psoc); +} + +QDF_STATUS wlan_interop_issues_ap_init(void) +{ + QDF_STATUS status; + + /* register psoc create handler functions. */ + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_psoc_obj_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("register create handler failed"); + return status; + } + + /* register psoc delete handler functions. */ + status = wlan_objmgr_register_psoc_destroy_handler( + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_psoc_obj_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("register destroy handler failed"); + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_psoc_obj_created_notification, + NULL); + } + + return status; +} + +QDF_STATUS wlan_interop_issues_ap_deinit(void) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS, status; + + /* unregister psoc delete handler functions. */ + status = wlan_objmgr_unregister_psoc_destroy_handler( + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_psoc_obj_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("unregister destroy handler failed"); + ret = status; + } + + /* unregister psoc create handler functions. */ + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_INTEROP_ISSUES_AP, + interop_issues_ap_psoc_obj_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("unregister create handler failed"); + ret = status; + } + + return ret; +} diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h new file mode 100644 index 000000000000..2afd61c0974b --- /dev/null +++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: contains interop issues ap structure definations + */ + +#ifndef _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_ +#define _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_ + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP +#include +#include + +#define MAX_INTEROP_ISSUES_AP_NUM 20 + +/** + * struct wlan_interop_issues_ap_info - interop issues ap info + * @count: the number of interop issues ap + * @rap_items: interop issues ap items + */ +struct wlan_interop_issues_ap_info { + uint32_t count; + struct qdf_mac_addr rap_items[MAX_INTEROP_ISSUES_AP_NUM]; +}; + +/** + * struct wlan_interop_issues_ap_event - interop issues ap event + * @pdev: pdev object + * @psoc: psoc object + * @pdev_id: pdev id number + * @rap_addr: interop issues ap mac address + */ +struct wlan_interop_issues_ap_event { + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; + uint32_t pdev_id; + struct qdf_mac_addr rap_addr; +}; + +/** + * struct wlan_interop_issues_ap_callbacks - interop issues ap callbacks + * @os_if_interop_issues_ap_event_handler: OS IF callback for handling events + */ +struct wlan_interop_issues_ap_callbacks { + void (*os_if_interop_issues_ap_event_handler) + (struct wlan_interop_issues_ap_event *event); +}; + +/** + * struct wlan_interop_issues_ap_tx_ops - structure of tx func pointers + * @set_rap_ps: handler for TX operations for the interop issues ap ps config + */ +struct wlan_interop_issues_ap_tx_ops { + QDF_STATUS (*set_rap_ps)(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_info *rap); +}; +#endif +#endif /* _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_ */ diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h new file mode 100644 index 000000000000..6f5b2c8d6354 --- /dev/null +++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: wlan_interop_issues_ap_tgt_api.h + * + * This header file provide with API declarations to interface with Southbound + */ +#ifndef __WLAN_INTEROP_ISSUES_AP_TGT_API_H__ +#define __WLAN_INTEROP_ISSUES_AP_TGT_API_H__ + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP +/** + * tgt_interop_issues_ap_info_callback() - interop issues ap info callback + * @psoc: the pointer to psoc object manager + * @rap: the interop issues ap mac address + * + * Return: QDF_STATUS + */ +QDF_STATUS +tgt_interop_issues_ap_info_callback(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_event *rap); + +/** + * tgt_set_interop_issues_ap_req(): API to set interop issues ap to lmac + * @rx_ops: rx ops struct + * @rap: the pointer to interop issues ap info + * + * Return: status of operation + */ +QDF_STATUS +tgt_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_info *rap); +#endif +#endif /* __WLAN_INTEROP_ISSUES_AP_TGT_API_H__ */ diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h new file mode 100644 index 000000000000..4d9508712e5c --- /dev/null +++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: wlan_interop_issues_ap_ucfg_api.h + * + * This header file maintain API declaration required for northbound interaction + */ + +#ifndef __WLAN_INTEROP_ISSUES_AP_UCFG_API_H__ +#define __WLAN_INTEROP_ISSUES_AP_UCFG_API_H__ + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP +#include +#include +#include + +/** + * ucfg_interop_issues_ap_psoc_enable() - interop issues ap component enable + * @psoc: the point to psoc object + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_interop_issues_ap_psoc_disable() - interop issues ap component disable + * @psoc: the point to psoc object + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_interop_issues_ap_init() - interop issues ap component initialization + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_interop_issues_ap_init(void); + +/** + * ucfg_interop_issues_ap_deinit() - interop issues ap component de-init + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_interop_issues_ap_deinit(void); + +/** + * ucfg_register_interop_issues_ap_callback() - API to register callback + * @cbs: pointer to callback structure + * + * Return: none + */ +void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev, + struct wlan_interop_issues_ap_callbacks *cbs); + +/** + * ucfg_set_interop_issues_ap_config() - API to set interop issues ap + * @vdev: the pointer of vdev object + * @rap: the pointer of interop issues ap info + * + * Return: none + */ +QDF_STATUS ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev, + struct wlan_interop_issues_ap_info *rap); +#else +static inline +QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS ucfg_interop_issues_ap_init(void) { return QDF_STATUS_SUCCESS; } + +static inline +QDF_STATUS ucfg_interop_issues_ap_deinit(void) { return QDF_STATUS_SUCCESS; } +#endif /* WLAN_FEATURE_INTEROP_ISSUES_AP */ +#endif /* __WLAN_RAP_PS_UCFG_API_H__ */ diff --git a/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c new file mode 100644 index 000000000000..dd6cdaea0ad9 --- /dev/null +++ b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC:wlan_interop_issues_ap_tgt_api.c + * + * This file provide API definitions to update interop issues ap from interface + */ +#include +#include +#include +#include +#include + +static QDF_STATUS wlan_interop_issues_ap_flush_cbk(struct scheduler_msg *msg) +{ + if (msg->bodyptr) { + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + } + + return QDF_STATUS_SUCCESS; +} + +static void wlan_interop_issues_ap_info_cbk(struct scheduler_msg *msg) +{ + struct wlan_interop_issues_ap_event *data; + struct wlan_interop_issues_ap_callbacks *cbs; + + data = msg->bodyptr; + data->pdev = wlan_objmgr_get_pdev_by_id(data->psoc, + data->pdev_id, + WLAN_INTEROP_ISSUES_AP_ID); + if (!data->pdev) { + interop_issues_ap_err("pdev is null."); + goto err; + } + + cbs = interop_issues_ap_psoc_get_cbs(data->psoc); + if (cbs && cbs->os_if_interop_issues_ap_event_handler) + cbs->os_if_interop_issues_ap_event_handler(msg->bodyptr); + + wlan_objmgr_pdev_release_ref(data->pdev, WLAN_INTEROP_ISSUES_AP_ID); +err: + qdf_mem_free(data); + msg->bodyptr = NULL; +} + +QDF_STATUS tgt_interop_issues_ap_info_callback(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_event *rap) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status; + struct wlan_interop_issues_ap_event *data; + + data = qdf_mem_malloc(sizeof(*data)); + if (!data) + return QDF_STATUS_E_NOMEM; + + qdf_mem_copy(data, rap, sizeof(*data)); + + msg.bodyptr = data; + msg.callback = wlan_interop_issues_ap_info_cbk; + msg.flush_callback = wlan_interop_issues_ap_flush_cbk; + + status = scheduler_post_message(QDF_MODULE_ID_INTEROP_ISSUES_AP, + QDF_MODULE_ID_INTEROP_ISSUES_AP, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + interop_issues_ap_err("scheduler msg posting failed"); + qdf_mem_free(msg.bodyptr); + msg.bodyptr = NULL; + } + + return status; +} + +QDF_STATUS tgt_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_info *rap) +{ + struct interop_issues_ap_psoc_priv_obj *obj; + + obj = interop_issues_ap_get_psoc_priv_obj(psoc); + if (!obj || !obj->tx_ops.set_rap_ps) + return QDF_STATUS_E_NULL_VALUE; + + return obj->tx_ops.set_rap_ps(psoc, rap); +} diff --git a/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c new file mode 100644 index 000000000000..e53524cbcfbe --- /dev/null +++ b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: This file contains interop issues ap north bound interface definitions + */ +#include +#include +#include +#include +#include + +QDF_STATUS +ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev, + struct wlan_interop_issues_ap_info *rap) +{ + return tgt_set_interop_issues_ap_req(wlan_vdev_get_psoc(vdev), rap); +} + +void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev, + struct wlan_interop_issues_ap_callbacks *cb) +{ + struct wlan_objmgr_psoc *psoc; + struct interop_issues_ap_psoc_priv_obj *obj; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + interop_issues_ap_err("psoc object is NULL"); + return; + } + + obj = interop_issues_ap_get_psoc_priv_obj(psoc); + if (!obj) { + interop_issues_ap_err("interop issues ap priv obj is NULL"); + return; + } + + obj->cbs.os_if_interop_issues_ap_event_handler = + cb->os_if_interop_issues_ap_event_handler; +} + +QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_interop_issues_ap_psoc_enable(psoc); +} + +QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_interop_issues_ap_psoc_disable(psoc); +} + +QDF_STATUS ucfg_interop_issues_ap_init(void) +{ + return wlan_interop_issues_ap_init(); +} + +QDF_STATUS ucfg_interop_issues_ap_deinit(void) +{ + return wlan_interop_issues_ap_deinit(); +} diff --git a/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h b/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h new file mode 100644 index 000000000000..b65314a0d69e --- /dev/null +++ b/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: offload lmac interface APIs for interop issues ap + */ +#ifndef __TARGET_IF_INTEROP_ISSUES_AP_H__ +#define __TARGET_IF_INTEROP_ISSUES_AP_H__ + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP +#include +#include +#include +#include +#include + +/** + * target_if_interop_issues_ap_register_event_handler() - register callback + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_interop_issues_ap_register_event_handler( + struct wlan_objmgr_psoc *psoc); + +/** + * target_if_interop_issues_ap_unregister_event_handler() - unregister callback + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_interop_issues_ap_unregister_event_handler( + struct wlan_objmgr_psoc *psoc); + +/** + * target_if_interop_issues_ap_register_tx_ops() - register tx ops funcs + * @psoc: the pointer of psoc object + * @tx_ops: pointer to rap_ps tx ops + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +target_if_interop_issues_ap_register_tx_ops(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_tx_ops *tx_ops); +/** + * target_if_interop_issues_ap_unregister_tx_ops() - unregister tx ops funcs + * @psoc: the pointer of psoc object + * @tx_ops: pointer to rap_ps tx ops + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +target_if_interop_issues_ap_unregister_tx_ops(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_tx_ops *tx_ops); +#endif +#endif /* __TARGET_IF_INTEROP_ISSUES_AP_H__ */ diff --git a/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c b/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c new file mode 100644 index 000000000000..5cbed5b4e1ed --- /dev/null +++ b/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: target_if_interop_issues_ap.c + * + * This file provide definition for APIs registered through lmac Tx Ops + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * target_if_interop_issues_ap_event_handler() - callback for event + * @event: firmware event + * @len: the event length + * + * Return: 0 or error status + */ +static int target_if_interop_issues_ap_event_handler(ol_scn_t sc, + uint8_t *event, + uint32_t len) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct wlan_interop_issues_ap_event data = {0}; + int ret; + + TARGET_IF_ENTER(); + + psoc = target_if_get_psoc_from_scn_hdl(sc); + if (!psoc) { + target_if_err("psoc ptr is NULL"); + return -EINVAL; + } + data.psoc = psoc; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null."); + return -EINVAL; + } + + ret = wmi_extract_interop_issues_ap_ev_param(wmi_handle, event, &data); + if (ret) + return -EINVAL; + + target_if_debug("interop issues ap macaddr: " QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_ARRAY(data.rap_addr.bytes)); + + return tgt_interop_issues_ap_info_callback(psoc, &data); +} + +/** + * target_if_interop_issues_ap_register_event_handler() - register callback + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_interop_issues_ap_register_event_handler( + struct wlan_objmgr_psoc *psoc) +{ + int ret_val; + struct wmi_unified *wmi_handle; + + if (!psoc) { + target_if_err("PSOC is NULL!"); + return QDF_STATUS_E_NULL_VALUE; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + ret_val = + wmi_unified_register_event_handler(wmi_handle, + wmi_pdev_interop_issues_ap_event_id, + target_if_interop_issues_ap_event_handler, + WMI_RX_WORK_CTX); + if (ret_val) + target_if_err("Failed to register event cb"); + + return qdf_status_from_os_return(ret_val); +} + +/** + * target_if_interop_issues_ap_unregister_event_handler() - unregister callback + * @psoc: the pointer to psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_interop_issues_ap_unregister_event_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wmi_unified *wmi_handle; + + if (!psoc) { + target_if_err("PSOC is NULL!"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + wmi_unified_unregister_event_handler(wmi_handle, + wmi_pdev_interop_issues_ap_event_id); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_set_interop_issues_ap_req() - API to send stats request to wmi + * @psoc: pointer to psoc object + * @raq: pointer to interop issues ap info + * + * Return: status of operation. + */ +static QDF_STATUS +target_if_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_info *rap) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null."); + return QDF_STATUS_E_NULL_VALUE; + } + + return wmi_unified_set_rap_ps_cmd(wmi_handle, rap); +} + +QDF_STATUS +target_if_interop_issues_ap_register_tx_ops(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_tx_ops *tx_ops) +{ + if (!tx_ops) { + target_if_err("tx ops is NULL!"); + return QDF_STATUS_E_INVAL; + } + + tx_ops->set_rap_ps = target_if_set_interop_issues_ap_req; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +target_if_interop_issues_ap_unregister_tx_ops(struct wlan_objmgr_psoc *psoc, + struct wlan_interop_issues_ap_tx_ops *tx_ops) +{ + if (!tx_ops) { + target_if_err("tx ops is NULL!"); + return QDF_STATUS_E_INVAL; + } + + tx_ops->set_rap_ps = NULL; + + return QDF_STATUS_SUCCESS; +} diff --git a/configs/default_defconfig b/configs/default_defconfig index 2bd50db10ec3..943be7283a84 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -646,6 +646,7 @@ CONFIG_WIFI_POS_LEGACY := y endif CONFIG_CP_STATS := y +CONFIG_FEATURE_INTEROP_ISSUES_AP := y CONFIG_FEATURE_WLAN_WAPI := y diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 5493683c268d..894dfe779b39 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -137,6 +137,7 @@ #include "nan_ucfg_api.h" #include "wlan_fwol_ucfg_api.h" #include "wlan_cfg80211_crypto.h" +#include "wlan_cfg80211_interop_issues_ap.h" #include "wlan_scan_ucfg_api.h" #include "wlan_hdd_coex_config.h" #include "wlan_hdd_bcn_recv.h" @@ -1462,6 +1463,8 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = }, #endif /*FEATURE_LFR_SUBNET_DETECTION */ + FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX + [QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX] = { .vendor_id = QCA_NL80211_VENDOR_ID, .subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP @@ -12803,6 +12806,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { }, #endif FEATURE_RSSI_MONITOR_VENDOR_COMMANDS + FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS #ifdef WLAN_NS_OFFLOAD { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index ccf6d2dffff4..a295be7be746 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -152,6 +152,7 @@ #include "wlan_mlme_main.h" #include "wlan_p2p_cfg_api.h" #include "wlan_cfg80211_p2p.h" +#include "wlan_cfg80211_interop_issues_ap.h" #include "wlan_tdls_cfg_api.h" #include #include "wlan_mlme_ucfg_api.h" @@ -165,6 +166,7 @@ #include #include "wlan_green_ap_ucfg_api.h" #include +#include #include #include @@ -319,6 +321,7 @@ static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, + [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, }; struct notifier_block hdd_netdev_notifier; @@ -11945,6 +11948,7 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx) ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); hdd_debugfs_mws_coex_info_init(hdd_ctx); + wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); hdd_exit(); @@ -13102,10 +13106,14 @@ static QDF_STATUS hdd_component_init(void) if (QDF_IS_STATUS_ERROR(status)) goto nan_deinit; - status = policy_mgr_init(); + status = ucfg_interop_issues_ap_init(); if (QDF_IS_STATUS_ERROR(status)) goto p2p_deinit; + status = policy_mgr_init(); + if (QDF_IS_STATUS_ERROR(status)) + goto interop_issues_ap_deinit; + status = ucfg_tdls_init(); if (QDF_IS_STATUS_ERROR(status)) goto policy_deinit; @@ -13114,6 +13122,8 @@ static QDF_STATUS hdd_component_init(void) policy_deinit: policy_mgr_deinit(); +interop_issues_ap_deinit: + ucfg_interop_issues_ap_deinit(); p2p_deinit: ucfg_p2p_deinit(); nan_deinit: @@ -13152,6 +13162,7 @@ static void hdd_component_deinit(void) /* deinitialize non-converged components */ ucfg_tdls_deinit(); policy_mgr_deinit(); + ucfg_interop_issues_ap_deinit(); ucfg_p2p_deinit(); nan_deinit(); ucfg_action_oui_deinit(); @@ -13228,6 +13239,7 @@ void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc) disa_psoc_enable(psoc); nan_psoc_enable(psoc); p2p_psoc_enable(psoc); + ucfg_interop_issues_ap_psoc_enable(psoc); policy_mgr_psoc_enable(psoc); ucfg_tdls_psoc_enable(psoc); } @@ -13236,6 +13248,7 @@ void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc) { ucfg_tdls_psoc_disable(psoc); policy_mgr_psoc_disable(psoc); + ucfg_interop_issues_ap_psoc_disable(psoc); p2p_psoc_disable(psoc); nan_psoc_disable(psoc); disa_psoc_disable(psoc); diff --git a/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h b/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h new file mode 100644 index 000000000000..24a7cd25c539 --- /dev/null +++ b/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: wlan_cfg80211_interop_issues_ap.h + * + * This Header file provide declaration for cfg80211 command handler API + */ + +#ifndef __WLAN_CFG80211_INTEROP_ISSUES_AP_H__ +#define __WLAN_CFG80211_INTEROP_ISSUES_AP_H__ + +#include +#include +#include + +#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP + +#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = wlan_cfg80211_set_interop_issues_ap_config \ +}, + +#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX \ + [QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP_INDEX] = { \ + .vendor_id = QCA_NL80211_VENDOR_ID, \ + .subcmd = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP \ + }, + +/** + * wlan_cfg80211_init_interop_issues_ap() - init interop issues ap setting + * @pdev: the pointer of pdev object + * + * Return: none + */ +void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_cfg80211_set_interop_issues_ap_config() - set interop issues ap config + * @wiphy: pointer to wireless wiphy structure + * @wdev: pointer to wireless_dev structure + * @data: Pointer to the data to be passed via vendor interface + * @data_len: Length of the data to be passed + * + * Return: Return the Success or Failure code + */ +int wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); +#else +static inline +void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev) {} +#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS +#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX +#endif +#endif /* __WLAN_CFG80211_INTEROP_ISSUES_AP_H__ */ diff --git a/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c b/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c new file mode 100644 index 000000000000..dc65abe56aea --- /dev/null +++ b/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * DOC: defines driver functions interfacing with linux kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_hdd_main.h" +#include "cfg_ucfg_api.h" + +const struct nla_policy +interop_issues_ap_policy[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID] = { + .type = NLA_UNSPEC, + .len = QDF_MAC_ADDR_SIZE }, +}; + +/** + * wlan_cfg80211_send_interop_issues_ap_cb() - report information + * @data: interop issues ap mac received from fw + * + * Generate a wlan interop issues ap info package and send it to user + * space daemon through netlink. + * + * Return: none + */ +static void +wlan_cfg80211_send_interop_issues_ap_cb( + struct wlan_interop_issues_ap_event *data) +{ + struct wlan_objmgr_pdev *pdev; + struct pdev_osif_priv *os_priv; + struct sk_buff *skb; + uint32_t index, len; + + if (!data) { + cfg80211_err("Invalid result."); + return; + } + + pdev = data->pdev; + if (!pdev) { + cfg80211_err("pdev is null."); + return; + } + os_priv = wlan_pdev_get_ospriv(pdev); + if (!os_priv) { + cfg80211_err("os_priv is null."); + return; + } + + index = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP_INDEX; + len = nla_total_size(QDF_MAC_ADDR_SIZE + NLMSG_HDRLEN); + skb = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, len, index, + GFP_KERNEL); + if (!skb) { + cfg80211_err("skb alloc failed"); + return; + } + + cfg80211_debug("interop issues ap mac:" QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_ARRAY(data->rap_addr.bytes)); + + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID, + QDF_MAC_ADDR_SIZE, data->rap_addr.bytes)) { + cfg80211_err("nla put fail"); + kfree_skb(skb); + return; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); +} + +static void wlan_interop_issues_ap_register_cbk(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_interop_issues_ap_callbacks cb; + + cb.os_if_interop_issues_ap_event_handler = + wlan_cfg80211_send_interop_issues_ap_cb; + ucfg_register_interop_issues_ap_callback(pdev, &cb); +} + +/** + * wlan_parse_interop_issues_ap() - parse the interop issues ap info + * @interop_issues_ap: the pointer of interop issues ap + * @attr: list of attributes + * + * Return: 0 on success; error number on failure + */ +static int +wlan_parse_interop_issues_ap(struct qdf_mac_addr *interop_issues_ap, + struct nlattr *attr) +{ + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1]; + struct nlattr *curr_attr = NULL; + uint32_t rem; + qdf_size_t i = 0; + + nla_for_each_nested(curr_attr, attr, rem) { + if (i == MAX_INTEROP_ISSUES_AP_NUM) { + cfg80211_err("Ignoring excess"); + break; + } + + if (wlan_cfg80211_nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX, + nla_data(curr_attr), + nla_len(curr_attr), + interop_issues_ap_policy)) { + cfg80211_err("nla_parse failed"); + return -EINVAL; + } + if (!tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID]) { + cfg80211_err("attr addr failed"); + return -EINVAL; + } + nla_memcpy(interop_issues_ap[i].bytes, + tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID], + QDF_MAC_ADDR_SIZE); + cfg80211_debug(QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_ARRAY(interop_issues_ap[i].bytes)); + i++; + } + + return i; +} + +/** + * __wlan_cfg80211_set_interop_issues_ap_config() - set config status + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * Return: 0 on success and errno on failure + */ +static int +__wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1]; + struct nlattr *attr; + uint32_t count = 0; + struct wlan_interop_issues_ap_info interop_issues_ap = {0}; + + if (wlan_cfg80211_nla_parse(tb, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX, + data, data_len, + interop_issues_ap_policy)) { + cfg80211_err("Invalid ATTR"); + return -EINVAL; + } + + attr = tb[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST]; + if (attr) { + count = + wlan_parse_interop_issues_ap(interop_issues_ap.rap_items, + attr); + if (count < 0) + return -EINVAL; + } + + cfg80211_debug("Num of interop issues ap: %d", count); + interop_issues_ap.count = count; + + /* + * need to figure out a converged way of obtaining the vdev for + * a given netdev that doesn't involve the legacy mechanism. + */ + ucfg_set_interop_issues_ap_config(adapter->vdev, &interop_issues_ap); + + return 0; +} + +int wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int ret; + + ret = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (ret) + return ret; + + ret = __wlan_cfg80211_set_interop_issues_ap_config(wiphy, wdev, + data, data_len); + osif_psoc_sync_op_stop(psoc_sync); + + return ret; +} + +void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev) +{ + /* + * the special mac is used to trigger uplayer sets + * interop issues ap list to fw when driver reloads but + * cnss-daemon does not restart. + */ + uint8_t fmac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct wlan_interop_issues_ap_event data; + + wlan_interop_issues_ap_register_cbk(pdev); + + data.pdev = pdev; + qdf_mem_copy(data.rap_addr.bytes, fmac, QDF_MAC_ADDR_SIZE); + + wlan_cfg80211_send_interop_issues_ap_cb(&data); +}