1 /*
2  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /*
19  * DOC: contains coex north bound interface definitions
20  */
21 
22 #include <wlan_coex_main.h>
23 #include <wlan_coex_ucfg_api.h>
24 #include "wmi_unified.h"
25 #include "wlan_coex_public_structs.h"
26 #include "wlan_coex_tgt_api.h"
27 
28 QDF_STATUS
ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc * psoc,enum coex_config_type type,update_coex_cb handler)29 ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc,
30 				       enum coex_config_type type,
31 				       update_coex_cb handler)
32 {
33 	struct coex_psoc_obj *coex_obj;
34 
35 	if (type >= COEX_CONFIG_TYPE_MAX) {
36 		coex_err("invalid coex type: %d", type);
37 		return QDF_STATUS_E_INVAL;
38 	}
39 
40 	coex_obj = wlan_psoc_get_coex_obj(psoc);
41 	if (!coex_obj)
42 		return QDF_STATUS_E_INVAL;
43 
44 	coex_obj->coex_config_updated[type] = handler;
45 
46 	return QDF_STATUS_SUCCESS;
47 }
48 
49 QDF_STATUS
ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc * psoc,enum coex_btc_chain_mode val)50 ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
51 				  enum coex_btc_chain_mode val)
52 {
53 	return wlan_coex_psoc_set_btc_chain_mode(psoc, val);
54 }
55 
56 QDF_STATUS
ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc * psoc,enum coex_btc_chain_mode * val)57 ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
58 				  enum coex_btc_chain_mode *val)
59 {
60 	return wlan_coex_psoc_get_btc_chain_mode(psoc, val);
61 }
62 
63 QDF_STATUS
ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev * vdev,enum coex_btc_chain_mode mode)64 ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
65 			      enum coex_btc_chain_mode mode)
66 {
67 	struct coex_config_params param = {0};
68 
69 	if (mode > WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
70 		return QDF_STATUS_E_INVAL;
71 
72 	param.vdev_id = wlan_vdev_get_id(vdev);
73 	param.config_type = WMI_COEX_CONFIG_BTCOEX_SEPARATE_CHAIN_MODE;
74 	param.config_arg1 = mode;
75 
76 	coex_debug("send btc chain mode %d for vdev %d", mode, param.vdev_id);
77 
78 	return wlan_coex_config_send(vdev, &param);
79 }
80 
81 QDF_STATUS
ucfg_coex_send_multi_config(struct wlan_objmgr_vdev * vdev,struct coex_multi_config * param)82 ucfg_coex_send_multi_config(struct wlan_objmgr_vdev *vdev,
83 			    struct coex_multi_config *param)
84 {
85 	return wlan_coex_multi_config_send(vdev, param);
86 }
87 
88 #ifdef WLAN_FEATURE_DBAM_CONFIG
89 QDF_STATUS
ucfg_coex_send_dbam_config(struct wlan_objmgr_vdev * vdev,struct coex_dbam_config_params * param,void (* clbk)(void * ctx,enum coex_dbam_comp_status * rsp),void * context)90 ucfg_coex_send_dbam_config(struct wlan_objmgr_vdev *vdev,
91 			   struct coex_dbam_config_params *param,
92 			   void (*clbk)(void *ctx,
93 			   enum coex_dbam_comp_status *rsp),
94 			   void *context)
95 {
96 	struct wlan_objmgr_psoc *psoc;
97 	struct coex_psoc_obj *coex_obj;
98 	struct wlan_coex_callback *cbk;
99 
100 	if (!vdev) {
101 		coex_err("Null vdev");
102 		return QDF_STATUS_E_INVAL;
103 	}
104 
105 	psoc = wlan_vdev_get_psoc(vdev);
106 	if (!psoc) {
107 		coex_err("psoc is null");
108 		return QDF_STATUS_E_INVAL;
109 	}
110 
111 	coex_obj = wlan_psoc_get_coex_obj(psoc);
112 	if (!coex_obj) {
113 		coex_err("failed to get coex_obj");
114 		return QDF_STATUS_E_INVAL;
115 	}
116 
117 	cbk = &coex_obj->cb;
118 	cbk->set_dbam_config_cb = clbk;
119 	cbk->set_dbam_config_ctx = context;
120 
121 	coex_debug("send dbam config mode %d for vdev_id %d",
122 		   param->dbam_mode, param->vdev_id);
123 
124 	return wlan_dbam_config_send(vdev, param);
125 }
126 #endif
127 
128 #define COEX_CONFIG_ENABLE_CONT_INFO 12
129 
130 QDF_STATUS
ucfg_coex_send_logging_config(struct wlan_objmgr_psoc * psoc,uint32_t * apps_args)131 ucfg_coex_send_logging_config(struct wlan_objmgr_psoc *psoc,
132 			      uint32_t *apps_args)
133 {
134 	struct coex_config_params param = {0};
135 	struct wlan_objmgr_vdev *vdev;
136 	QDF_STATUS status;
137 
138 	if (apps_args[0] != COEX_CONFIG_ENABLE_CONT_INFO) {
139 		coex_err("invalid cmd %d", apps_args[0]);
140 		return QDF_STATUS_E_FAILURE;
141 	}
142 
143 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_STA_MODE,
144 							WLAN_COEX_ID);
145 
146 	if (!vdev) {
147 		coex_err("vdev is null");
148 		return QDF_STATUS_E_INVAL;
149 	}
150 
151 	param.vdev_id = wlan_vdev_get_id(vdev);
152 	param.config_type = WMI_COEX_CONFIG_ENABLE_CONT_INFO;
153 	param.config_arg1 = apps_args[1];
154 	param.config_arg2 = apps_args[2];
155 	param.config_arg3 = apps_args[3];
156 	param.config_arg4 = apps_args[4];
157 	param.config_arg5 = apps_args[5];
158 	param.config_arg6 = apps_args[6];
159 
160 	coex_debug("send logging_config arg: %u for vdev %d", *apps_args,
161 		   param.vdev_id);
162 
163 	status = wlan_coex_config_send(vdev, &param);
164 	wlan_objmgr_vdev_release_ref(vdev, WLAN_COEX_ID);
165 
166 	return status;
167 }
168