xref: /wlan-dirver/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs_partial_offload.c (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
4  *
5  *
6  * Permission to use, copy, modify, and/or distribute this software for
7  * any purpose with or without fee is hereby granted, provided that the
8  * above copyright notice and this permission notice appear in all
9  * copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18  * PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /**
22  * DOC: target_if_dfs_partial_offload.c
23  * This file contains dfs target interface for partial offload
24  */
25 
26 #include <target_if.h>
27 #include "target_type.h"
28 #include "target_if_dfs_partial_offload.h"
29 #include "target_if_dfs.h"
30 
31 QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc)
32 {
33 	/* TODO: dfs non-offload case */
34 	return QDF_STATUS_SUCCESS;
35 }
36 
37 QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev,
38 		struct wlan_dfs_caps *dfs_caps)
39 {
40 	struct wlan_objmgr_psoc *psoc = NULL;
41 	struct target_psoc_info *tgt_psoc_info;
42 
43 	if (!dfs_caps) {
44 		target_if_err("null dfs_caps");
45 		return QDF_STATUS_E_FAILURE;
46 	}
47 
48 	dfs_caps->wlan_dfs_combined_rssi_ok = 0;
49 	dfs_caps->wlan_dfs_ext_chan_ok = 0;
50 	dfs_caps->wlan_dfs_use_enhancement = 0;
51 	dfs_caps->wlan_strong_signal_diversiry = 0;
52 	dfs_caps->wlan_fastdiv_val = 0;
53 	dfs_caps->wlan_chip_is_bb_tlv = 1;
54 	dfs_caps->wlan_chip_is_over_sampled = 0;
55 	dfs_caps->wlan_chip_is_ht160 = 0;
56 	dfs_caps->wlan_chip_is_false_detect = 0;
57 
58 	psoc = wlan_pdev_get_psoc(pdev);
59 	if (!psoc) {
60 		target_if_err("null psoc");
61 		return QDF_STATUS_E_FAILURE;
62 	}
63 
64 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
65 	if (!tgt_psoc_info) {
66 		target_if_err("null tgt_psoc_info");
67 		return QDF_STATUS_E_FAILURE;
68 	}
69 
70 	switch (target_psoc_get_target_type(tgt_psoc_info)) {
71 	case TARGET_TYPE_AR900B:
72 		break;
73 
74 	case TARGET_TYPE_AR9888:
75 		dfs_caps->wlan_chip_is_over_sampled = 1;
76 		break;
77 
78 	case TARGET_TYPE_QCA9984:
79 	case TARGET_TYPE_QCA9888:
80 		dfs_caps->wlan_chip_is_ht160 = 1;
81 		break;
82 	default:
83 		break;
84 	}
85 
86 	return QDF_STATUS_SUCCESS;
87 }
88 
89 #if defined(HOST_DFS_SPOOF_TEST)
90 QDF_STATUS target_if_dfs_send_avg_params_to_fw(
91 		struct wlan_objmgr_pdev *pdev,
92 		struct dfs_radar_found_params *params)
93 {
94 	QDF_STATUS status;
95 	wmi_unified_t wmi_handle;
96 
97 	if (!pdev) {
98 		target_if_err("null pdev");
99 		return QDF_STATUS_E_FAILURE;
100 	}
101 
102 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
103 	if (!wmi_handle) {
104 		target_if_err("null wmi_handle");
105 		return QDF_STATUS_E_FAILURE;
106 	}
107 
108 	status = wmi_unified_dfs_send_avg_params_cmd(wmi_handle,
109 						     params);
110 	if (QDF_IS_STATUS_ERROR(status))
111 		target_if_err("dfs radar found average parameters send failed: %d",
112 			      status);
113 
114 	return status;
115 }
116 
117 int target_if_dfs_status_check_event_handler(ol_scn_t scn,
118 					     uint8_t *data,
119 					     uint32_t datalen)
120 {
121 	struct wlan_objmgr_psoc *psoc;
122 	struct wlan_objmgr_pdev *pdev;
123 	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
124 	u_int32_t dfs_status_check;
125 	wmi_unified_t wmi_hdl;
126 
127 	if (!scn || !data) {
128 		target_if_err("scn: %pK, data: %pK", scn, data);
129 		return -EINVAL;
130 	}
131 
132 	psoc = target_if_get_psoc_from_scn_hdl(scn);
133 	if (!psoc) {
134 		target_if_err("null psoc");
135 		return -EINVAL;
136 	}
137 
138 	/* Since Partial Offload chipsets have only one pdev per psoc, the first
139 	 * pdev from the pdev list is used.
140 	 */
141 	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_DFS_ID);
142 	if (!pdev) {
143 		target_if_err("null pdev");
144 		return -EINVAL;
145 	}
146 
147 	dfs_rx_ops = target_if_dfs_get_rx_ops(psoc);
148 	if (!dfs_rx_ops) {
149 		target_if_err("null dfs_rx_ops");
150 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
151 		return -EINVAL;
152 	}
153 
154 	if (!dfs_rx_ops->dfs_action_on_status) {
155 		target_if_err("dfs_rx_ops->dfs_action_on_status is NULL");
156 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
157 		return -EINVAL;
158 	}
159 
160 	wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev);
161 	if (!wmi_hdl) {
162 		target_if_err("wmi_hdl is NULL");
163 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
164 		return -EINVAL;
165 	}
166 
167 	if (wmi_extract_dfs_status_from_fw(wmi_hdl, data, &dfs_status_check) !=
168 			QDF_STATUS_SUCCESS) {
169 		target_if_err("failed to extract status response from FW");
170 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
171 		return -EINVAL;
172 	}
173 
174 	if (dfs_rx_ops->dfs_action_on_status(pdev, &dfs_status_check) !=
175 		QDF_STATUS_SUCCESS) {
176 		target_if_err("dfs action on host dfs status from FW failed");
177 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
178 		return -EINVAL;
179 	}
180 
181 	wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
182 
183 	return 0;
184 }
185 #endif
186