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