1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
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 #include <osdep.h>
21 #include "wmi.h"
22 #include "wmi_unified_priv.h"
23 #include "wmi_unified_dbr_param.h"
24 #include "wmi_unified_dbr_api.h"
25
26 /**
27 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX
28 * @wmi_handle: wmi handle
29 * @cfg: dma cfg req
30 *
31 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
32 */
send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,struct direct_buf_rx_cfg_req * cfg)33 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle,
34 struct direct_buf_rx_cfg_req *cfg)
35 {
36 wmi_buf_t buf;
37 wmi_dma_ring_cfg_req_fixed_param *cmd;
38 QDF_STATUS ret;
39 int32_t len = sizeof(*cmd);
40
41 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
42 if (!buf) {
43 wmi_err("wmi_buf_alloc failed");
44 return QDF_STATUS_E_FAILURE;
45 }
46
47 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf);
48
49 WMITLV_SET_HDR(&cmd->tlv_header,
50 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param,
51 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param));
52
53 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target(
54 wmi_handle,
55 cfg->pdev_id);
56 cmd->mod_id = cfg->mod_id;
57 cmd->base_paddr_lo = cfg->base_paddr_lo;
58 cmd->base_paddr_hi = cfg->base_paddr_hi;
59 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo;
60 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi;
61 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo;
62 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi;
63 cmd->num_elems = cfg->num_elems;
64 cmd->buf_size = cfg->buf_size;
65 cmd->num_resp_per_event = cfg->num_resp_per_event;
66 cmd->event_timeout_ms = cfg->event_timeout_ms;
67
68 wmi_debug("wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d"
69 "base paddr lo %x base paddr hi %x head idx paddr lo %x"
70 "head idx paddr hi %x tail idx paddr lo %x"
71 "tail idx addr hi %x num elems %d buf size %d num resp %d"
72 "event timeout %d", cmd->pdev_id,
73 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi,
74 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi,
75 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi,
76 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event,
77 cmd->event_timeout_ms);
78 wmi_mtrace(WMI_PDEV_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0);
79 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
80 WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
81 if (QDF_IS_STATUS_ERROR(ret)) {
82 wmi_err(":wmi cmd send failed");
83 wmi_buf_free(buf);
84 }
85
86 return ret;
87 }
88
extract_scaling_params_service_ready_ext_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint8_t idx,struct wlan_psoc_host_spectral_scaling_params * param)89 static QDF_STATUS extract_scaling_params_service_ready_ext_tlv(
90 wmi_unified_t wmi_handle,
91 uint8_t *event, uint8_t idx,
92 struct wlan_psoc_host_spectral_scaling_params *param)
93 {
94 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
95 wmi_spectral_bin_scaling_params *spectral_bin_scaling_params;
96
97 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
98 if (!param_buf)
99 return QDF_STATUS_E_INVAL;
100
101 spectral_bin_scaling_params = ¶m_buf->wmi_bin_scaling_params[idx];
102
103 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host(
104 wmi_handle,
105 spectral_bin_scaling_params->pdev_id);
106 param->low_level_offset = spectral_bin_scaling_params->low_level_offset;
107 param->formula_id = spectral_bin_scaling_params->formula_id;
108 param->high_level_offset =
109 spectral_bin_scaling_params->high_level_offset;
110 param->rssi_thr = spectral_bin_scaling_params->rssi_thr;
111 param->default_agc_max_gain =
112 spectral_bin_scaling_params->default_agc_max_gain;
113
114 return QDF_STATUS_SUCCESS;
115 }
116
extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,uint8_t * event,struct direct_buf_rx_rsp * param)117 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle,
118 uint8_t *event, struct direct_buf_rx_rsp *param)
119 {
120 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
121 wmi_dma_buf_release_fixed_param *ev;
122
123 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
124 if (!param_buf)
125 return QDF_STATUS_E_INVAL;
126
127 ev = param_buf->fixed_param;
128 if (!ev)
129 return QDF_STATUS_E_INVAL;
130
131 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host(
132 wmi_handle,
133 ev->pdev_id);
134 param->mod_id = ev->mod_id;
135 if ((!param_buf->num_entries) ||
136 param_buf->num_entries < ev->num_buf_release_entry) {
137 wmi_err("actual num of buf release entries less than provided entries");
138 return QDF_STATUS_E_INVAL;
139 }
140 param->num_buf_release_entry = ev->num_buf_release_entry;
141 if (((!param_buf->num_meta_data) ||
142 param_buf->num_meta_data < ev->num_meta_data_entry) &&
143 ((!param_buf->num_cv_meta_data) ||
144 param_buf->num_cv_meta_data < ev->num_meta_data_entry) &&
145 ((!param_buf->num_cqi_meta_data) ||
146 param_buf->num_cqi_meta_data < ev->num_meta_data_entry)) {
147 wmi_err(" actual num of meta data entries less than provided entries");
148 return QDF_STATUS_E_INVAL;
149 }
150 param->num_meta_data_entry = param_buf->num_meta_data;
151 param->num_cv_meta_data_entry = param_buf->num_cv_meta_data;
152 param->num_cqi_meta_data_entry = param_buf->num_cqi_meta_data;
153 wmi_debug("pdev id %d mod id %d num buf release entry %d",
154 param->pdev_id, param->mod_id, param->num_buf_release_entry);
155
156 return QDF_STATUS_SUCCESS;
157 }
158
extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint8_t idx,struct direct_buf_rx_entry * param)159 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle,
160 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param)
161 {
162 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
163 wmi_dma_buf_release_entry *entry;
164
165 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
166 if (!param_buf)
167 return QDF_STATUS_E_INVAL;
168
169 entry = ¶m_buf->entries[idx];
170
171 if (!entry) {
172 wmi_err("Entry is NULL");
173 return QDF_STATUS_E_FAILURE;
174 }
175
176 wmi_debug("paddr_lo[%d] = %x", idx, entry->paddr_lo);
177
178 param->paddr_lo = entry->paddr_lo;
179 param->paddr_hi = entry->paddr_hi;
180
181 return QDF_STATUS_SUCCESS;
182 }
183
extract_dbr_buf_metadata_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint8_t idx,struct direct_buf_rx_metadata * param)184 static QDF_STATUS extract_dbr_buf_metadata_tlv(
185 wmi_unified_t wmi_handle, uint8_t *event,
186 uint8_t idx, struct direct_buf_rx_metadata *param)
187 {
188 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
189 wmi_dma_buf_release_spectral_meta_data *entry;
190
191 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
192 if (!param_buf)
193 return QDF_STATUS_E_INVAL;
194
195 entry = ¶m_buf->meta_data[idx];
196
197 if (!entry) {
198 wmi_err("Entry is NULL");
199 return QDF_STATUS_E_FAILURE;
200 }
201
202 qdf_mem_copy(param->noisefloor, entry->noise_floor,
203 qdf_min(sizeof(entry->noise_floor),
204 sizeof(param->noisefloor)));
205 param->reset_delay = entry->reset_delay;
206 param->cfreq1 = entry->freq1;
207 param->cfreq2 = entry->freq2;
208 param->ch_width = entry->ch_width;
209
210 return QDF_STATUS_SUCCESS;
211 }
212
extract_dbr_buf_cv_metadata_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint8_t idx,struct direct_buf_rx_cv_metadata * param)213 static QDF_STATUS extract_dbr_buf_cv_metadata_tlv(
214 wmi_unified_t wmi_handle, uint8_t *event,
215 uint8_t idx, struct direct_buf_rx_cv_metadata *param)
216 {
217 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
218 wmi_dma_buf_release_cv_upload_meta_data *ev;
219
220 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
221 if (!param_buf)
222 return QDF_STATUS_E_INVAL;
223
224 ev = ¶m_buf->cv_meta_data[idx];
225
226 if (!ev) {
227 wmi_err("CV metadata is NULL");
228 return QDF_STATUS_E_FAILURE;
229 }
230
231 param->is_valid = ev->is_valid;
232 param->fb_type = ev->fb_type;
233 param->asnr_len =
234 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_LENGTH(ev->asnr_params);
235 param->asnr_offset =
236 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_OFFSET(ev->asnr_params);
237 param->dsnr_len =
238 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_DSNR_LENGTH(ev->dsnr_params);
239 param->dsnr_offset =
240 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_DSNR_OFFSET(ev->dsnr_params);
241 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_mac_address,
242 ¶m->peer_mac.bytes[0]);
243 param->fb_params = ev->fb_params;
244
245 return QDF_STATUS_SUCCESS;
246 }
247
extract_dbr_buf_cqi_metadata_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint8_t idx,struct direct_buf_rx_cqi_metadata * param)248 static QDF_STATUS extract_dbr_buf_cqi_metadata_tlv(
249 wmi_unified_t wmi_handle, uint8_t *event,
250 uint8_t idx, struct direct_buf_rx_cqi_metadata *param)
251 {
252 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf;
253 wmi_dma_buf_release_cqi_upload_meta_data *ev;
254 uint16_t asnr_len, asnr_offset;
255 uint8_t num_users = 0;
256 uint8_t i;
257
258 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event;
259 if (!param_buf)
260 return QDF_STATUS_E_INVAL;
261
262 ev = ¶m_buf->cqi_meta_data[idx];
263
264 if (!ev) {
265 wmi_err("CQI metadata is NULL");
266 return QDF_STATUS_E_FAILURE;
267 }
268
269 param->fb_params = ev->fb_params_cqi;
270 asnr_len =
271 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_LENGTH(ev->asnr_params);
272 asnr_offset =
273 WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_OFFSET(ev->asnr_params);
274 for (i = 0; i < MAX_NUM_CQI_USERS_IN_STANDALONE_SND; i++) {
275 if (WMI_DMA_BUF_RELEASE_CQI_UPLOAD_GET_FB_PARAMS_IS_VALID(
276 param->fb_params, i)) {
277 WMI_DMA_BUF_RELEASE_CQI_UPLOAD_SET_FB_PARAMS_IS_VALID(
278 param->is_valid, 1, i);
279 param->user_info[i].asnr_len = asnr_len;
280 param->user_info[i].asnr_offset =
281 asnr_offset + CQI_USER_DATA_OFFSET(i);
282 param->user_info[i].fb_params =
283 WMI_DMA_BUF_RELEASE_CQI_UPLOAD_GET_FB_PARAMS_NC(
284 param->fb_params, i);
285
286 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_mac_address[i],
287 ¶m->user_info[i].peer_mac.bytes[0]);
288 num_users++;
289 }
290 }
291 param->num_users = num_users;
292
293 return QDF_STATUS_SUCCESS;
294 }
295
wmi_dbr_attach_tlv(wmi_unified_t wmi_handle)296 void wmi_dbr_attach_tlv(wmi_unified_t wmi_handle)
297 {
298 struct wmi_ops *ops = wmi_handle->ops;
299
300 ops->send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv;
301 ops->extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv;
302 ops->extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv;
303 ops->extract_dbr_buf_cv_metadata = extract_dbr_buf_cv_metadata_tlv;
304 ops->extract_dbr_buf_cqi_metadata = extract_dbr_buf_cqi_metadata_tlv;
305 ops->extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv;
306 ops->extract_scaling_params_service_ready_ext =
307 extract_scaling_params_service_ready_ext_tlv;
308 }
309