blob: 5c0c9df84a1dab25d4a6e30b7d0cf7f737bf0e7c [file] [log] [blame]
Zhang Qian36794922018-01-03 16:33:24 +08001/*
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05302 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
Zhang Qian36794922018-01-03 16:33:24 +08003 *
Zhang Qian36794922018-01-03 16:33:24 +08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Zhang Qian36794922018-01-03 16:33:24 +080019#include "wmi_unified_api.h"
20#include "wmi.h"
21#include "wmi_version.h"
22#include "wmi_unified_priv.h"
23#include <wlan_defs.h>
24#include "target_if.h"
25#include "wma.h"
26#include "wlan_ocb_ucfg_api.h"
27#include "wlan_ocb_main.h"
28
29void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle);
30
31static inline struct wlan_ocb_rx_ops *
32target_if_ocb_get_rx_ops(struct wlan_objmgr_psoc *psoc)
33{
34 struct wlan_objmgr_pdev *pdev;
35 struct ocb_pdev_obj *pdev_obj;
36
37 pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
38 WLAN_OCB_SB_ID);
39 pdev_obj = (struct ocb_pdev_obj *)
40 wlan_objmgr_pdev_get_comp_private_obj(pdev,
41 WLAN_UMAC_COMP_OCB);
42 return &pdev_obj->ocb_rxops;
43}
44
45/**
46 * fake_vdev_create_cmd_tlv() - send VDEV create command to fw
47 * @wmi_handle: wmi handle
48 * @param: pointer to hold vdev create parameter
49 * @macaddr: vdev mac address
50 *
51 * Return: QDF_STATUS_SUCCESS for success or error code
52 */
53static QDF_STATUS fake_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
Srinivas Girigowda2751b6d2019-02-27 12:28:13 -080054 uint8_t macaddr[QDF_MAC_ADDR_SIZE],
Zhang Qian36794922018-01-03 16:33:24 +080055 struct vdev_create_params *param)
56{
57 WMI_LOGP("%s : called", __func__);
58 return QDF_STATUS_SUCCESS;
59}
60
61/**
62 * fake_vdev_delete_cmd_tlv() - send VDEV delete command to fw
63 * @wmi_handle: wmi handle
64 * @if_id: vdev id
65 *
66 * Return: QDF_STATUS_SUCCESS for success or error code
67 */
68static QDF_STATUS fake_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
69 uint8_t if_id)
70{
71 WMI_LOGP("%s : called", __func__);
72 return QDF_STATUS_SUCCESS;
73}
74
75/**
76 * fake_ocb_set_utc_time_cmd_tlv() - send the UTC time to the firmware
77 * @wmi_handle: pointer to the wmi handle
78 * @utc: pointer to the UTC time struct
79 *
80 * Return: 0 on succes
81 */
82static QDF_STATUS fake_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
83 struct ocb_utc_param *utc)
84{
85 WMI_LOGP("%s : called", __func__);
86 return QDF_STATUS_SUCCESS;
87}
88
89/**
90 * fake_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
91 * @wmi_handle: pointer to the wmi handle
92 * @request: pointer to the request
93 *
94 * Return: 0 on succes
95 */
96static QDF_STATUS fake_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
97 uint8_t vdev_id)
98{
99 QDF_STATUS status;
100 struct wlan_objmgr_psoc *psoc;
101 struct wlan_ocb_rx_ops *ocb_rx_ops;
102 struct ocb_get_tsf_timer_response response;
103 ol_scn_t scn = (ol_scn_t) wmi_handle->scn_handle;
104
105 WMI_LOGP("%s : called", __func__);
106 psoc = target_if_get_psoc_from_scn_hdl(scn);
107 if (!psoc) {
108 WMI_LOGP("null psoc");
109 return -EINVAL;
110 }
111 response.vdev_id = vdev_id;
112 response.timer_high = 0x1234;
113 response.timer_low = 0x5678;
114
115 ocb_rx_ops = target_if_ocb_get_rx_ops(psoc);
116 if (ocb_rx_ops->ocb_tsf_timer) {
117 status = ocb_rx_ops->ocb_tsf_timer(psoc, &response);
118 if (status != QDF_STATUS_SUCCESS) {
119 WMI_LOGP("ocb_tsf_timer failed.");
120 return -EINVAL;
121 }
122 } else {
123 WMI_LOGP("No ocb_tsf_timer callback");
124 return -EINVAL;
125 }
126 return QDF_STATUS_SUCCESS;
127}
128
129/**
130 * fake_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
131 * @wmi_handle: pointer to the wmi handle
132 * @vdev_id: vdev id
133 * @dcc_stats_bitmap: dcc status bitmap
134 *
135 * Return: 0 on succes
136 */
137static QDF_STATUS fake_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
138 uint32_t vdev_id, uint32_t dcc_stats_bitmap)
139{
140 WMI_LOGP("%s : called", __func__);
141 return QDF_STATUS_SUCCESS;
142}
143
144wmi_dcc_ndl_stats_per_channel chan1_info[2] = {
145 [0] = {.chan_info = 5860,
146 .tx_power_datarate = 23 | (10 << 8),
147 .carrier_sense_est_comm_range = 107 | (198 << 13),
148 .dcc_stats = 78 | (56 << 8) | (345 << 16),
149 .packet_stats = 1278 | (789 << 14),
150 .channel_busy_time = 1389,
151 },
152 [1] = {.chan_info = 5880,
153 .tx_power_datarate = 53 | (17 << 8),
154 .carrier_sense_est_comm_range = 137 | (198 << 13),
155 .dcc_stats = 78 | (66 << 8) | (245 << 16),
156 .packet_stats = 1278 | (889 << 14),
157 .channel_busy_time = 2389,
158 },
159};
160
161/**
162 * fake_dcc_get_stats_cmd_tlv() - get the DCC channel stats
163 * @wmi_handle: pointer to the wmi handle
164 * @get_stats_param: pointer to the dcc stats
165 *
166 * Return: 0 on succes
167 */
168static QDF_STATUS fake_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
169 struct ocb_dcc_get_stats_param *get_stats_param)
170{
171 QDF_STATUS status;
172 struct wlan_objmgr_psoc *psoc;
173 struct wlan_ocb_rx_ops *ocb_rx_ops;
174 ol_scn_t scn = (ol_scn_t) wmi_handle->scn_handle;
175 struct ocb_dcc_get_stats_response *response;
176 WMI_LOGP("%s : called", __func__);
177
178 psoc = target_if_get_psoc_from_scn_hdl(scn);
179 if (!psoc) {
180 WMI_LOGP("null psoc");
181 return -EINVAL;
182 }
183 response = qdf_mem_malloc(sizeof(*response) + 2 *
184 sizeof(wmi_dcc_ndl_stats_per_channel));
185 response->num_channels = 2;
186 response->channel_stats_array_len = 2 *
187 sizeof(wmi_dcc_ndl_stats_per_channel);
188 response->vdev_id = get_stats_param->vdev_id;
189 response->channel_stats_array = (uint8_t *)response + sizeof(*response);
190 qdf_mem_copy(response->channel_stats_array,
191 &chan1_info,
192 2 * sizeof(wmi_dcc_ndl_stats_per_channel));
193 WMI_LOGP("channel1 freq %d, channel2 freq %d", chan1_info[0].chan_info,
194 chan1_info[1].chan_info);
195 ocb_rx_ops = target_if_ocb_get_rx_ops(psoc);
196 if (ocb_rx_ops->ocb_dcc_stats_indicate) {
197 status = ocb_rx_ops->ocb_dcc_stats_indicate(psoc,
198 response, true);
199 if (status != QDF_STATUS_SUCCESS) {
200 WMI_LOGP("dcc_stats_indicate failed.");
201 status = -EINVAL;
202 } else {
203 status = 0;
204 }
205 } else {
206 WMI_LOGP("No dcc_stats_indicate callback");
207 status = -EINVAL;
208 }
209
210 qdf_mem_free(response);
211 return QDF_STATUS_SUCCESS;
212}
213
214/**
215 * fake_dcc_update_ndl_cmd_tlv() - command to update the NDL data
216 * @wmi_handle: pointer to the wmi handle
217 * @update_ndl_param: pointer to the request parameters
218 *
219 * Return: 0 on success
220 */
221static QDF_STATUS fake_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
222 struct ocb_dcc_update_ndl_param *update_ndl_param)
223{
224 QDF_STATUS status;
225 struct wlan_objmgr_psoc *psoc;
226 struct wlan_ocb_rx_ops *ocb_rx_ops;
227 ol_scn_t scn = (ol_scn_t) wmi_handle->scn_handle;
228 struct ocb_dcc_update_ndl_response *resp;
229 WMI_LOGP("%s : called", __func__);
230 /* Allocate and populate the response */
231 resp = qdf_mem_malloc(sizeof(*resp));
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530232 if (!resp)
Zhang Qian36794922018-01-03 16:33:24 +0800233 return -ENOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530234
Zhang Qian36794922018-01-03 16:33:24 +0800235 resp->vdev_id = update_ndl_param->vdev_id;
236 resp->status = 0;
237
238 psoc = target_if_get_psoc_from_scn_hdl(scn);
239 if (!psoc) {
240 WMI_LOGP("null psoc");
241 return -EINVAL;
242 }
243
244 ocb_rx_ops = target_if_ocb_get_rx_ops(psoc);
245 if (ocb_rx_ops->ocb_dcc_ndl_update) {
246 status = ocb_rx_ops->ocb_dcc_ndl_update(psoc, resp);
247 if (status != QDF_STATUS_SUCCESS) {
248 WMI_LOGP("dcc_ndl_update failed.");
249 status = -EINVAL;
250 } else {
251 status = 0;
252 }
253 } else {
254 WMI_LOGP("No dcc_ndl_update callback");
255 status = -EINVAL;
256 }
257
258 qdf_mem_free(resp);
259 return QDF_STATUS_SUCCESS;
260}
261
262/**
263 * fake_ocb_set_config_cmd_tlv() - send the OCB config to the FW
264 * @wmi_handle: pointer to the wmi handle
265 * @config: the OCB configuration
266 *
267 * Return: 0 on success
268 */
269static QDF_STATUS fake_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
270 struct ocb_config *config)
271{
272 u32 i;
273 QDF_STATUS status;
274 struct wlan_objmgr_psoc *psoc;
275 struct wlan_ocb_rx_ops *ocb_rx_ops;
276 ol_scn_t scn = (ol_scn_t) wmi_handle->scn_handle;
277
278 WMI_LOGP("%s : called", __func__);
279 WMI_LOGI("%s: vdev_id=%d, channel_count=%d, schedule_size=%d, flag=%x",
280 __func__, config->vdev_id, config->channel_count,
281 config->schedule_size, config->flags);
282
283 for (i = 0; i < config->channel_count; i++) {
284 WMI_LOGI("%s: channel info for channel %d"
285 " chan_freq=%d, bandwidth=%d, " QDF_MAC_ADDRESS_STR
286 " max_pwr=%d, min_pwr=%d, reg_pwr=%d, antenna_max=%d, "
287 "flags=%d", __func__, i, config->channels[i].chan_freq,
288 config->channels[i].bandwidth,
289 QDF_MAC_ADDR_ARRAY(
290 config->channels[i].mac_address.bytes),
291 config->channels[i].max_pwr,
292 config->channels[i].min_pwr,
293 config->channels[i].reg_pwr,
294 config->channels[i].antenna_max,
295 config->channels[i].flags);
296 }
297
298 for (i = 0; i < config->schedule_size; i++) {
299 WMI_LOGI("%s: schedule info for channel %d: "
300 "chan_fre=%d, total_duration=%d, guard_intreval=%d",
301 __func__, i, config->schedule[i].chan_freq,
302 config->schedule[i].total_duration,
303 config->schedule[i].guard_interval);
304 }
305 psoc = target_if_get_psoc_from_scn_hdl(scn);
306 if (!psoc) {
307 WMI_LOGP("null psoc");
308 return -EINVAL;
309 }
310
311 ocb_rx_ops = target_if_ocb_get_rx_ops(psoc);
312 if (ocb_rx_ops->ocb_set_config_status) {
313 status = ocb_rx_ops->ocb_set_config_status(psoc, 0);
314 if (status != QDF_STATUS_SUCCESS) {
315 WMI_LOGP("ocb_set_config_status failed.");
316 return -EINVAL;
317 }
318 } else {
319 WMI_LOGP("No ocb_set_config_status callback");
320 return -EINVAL;
321 }
322 return QDF_STATUS_SUCCESS;
323}
324
325/**
326 * fake_ocb_stop_timing_advert_cmd_tlv() - stop sending the
327 * timing advertisement frames on a channel
328 * @wmi_handle: pointer to the wmi handle
329 * @timing_advert: pointer to the timing advertisement struct
330 *
331 * Return: 0 on succes
332 */
333static QDF_STATUS fake_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
334 struct ocb_timing_advert_param *timing_advert)
335{
336 WMI_LOGP("%s : called", __func__);
337 return QDF_STATUS_SUCCESS;
338}
339
340/**
341 * fake_ocb_start_timing_advert_cmd_tlv() - start sending the
342 * timing advertisement frames on a channel
343 * @wmi_handle: pointer to the wmi handle
344 * @timing_advert: pointer to the timing advertisement struct
345 *
346 * Return: 0 on succes
347 */
348static QDF_STATUS
349fake_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
350 struct ocb_timing_advert_param *timing_advert)
351{
352 WMI_LOGP("%s : called", __func__);
353 return QDF_STATUS_SUCCESS;
354}
355
356/**
357 * fake_peer_create_cmd_tlv() - send peer create command to fw
358 * @wmi: wmi handle
359 * @peer_addr: peer mac address
360 * @peer_type: peer type
361 * @vdev_id: vdev id
362 *
363 * Return: QDF_STATUS_SUCCESS for success or error code
364 */
365static QDF_STATUS fake_peer_create_cmd_tlv(wmi_unified_t wmi,
366 struct peer_create_params *param)
367{
368 WMI_LOGP("%s : called", __func__);
369 return QDF_STATUS_SUCCESS;
370}
371
372/**
373 * fake_peer_delete_cmd_tlv() - send PEER delete command to fw
374 * @wmi: wmi handle
375 * @peer_addr: peer mac addr
376 * @vdev_id: vdev id
377 *
378 * Return: QDF_STATUS_SUCCESS for success or error code
379 */
380static QDF_STATUS fake_peer_delete_cmd_tlv(wmi_unified_t wmi,
Srinivas Girigowda2751b6d2019-02-27 12:28:13 -0800381 uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
Zhang Qian36794922018-01-03 16:33:24 +0800382 uint8_t vdev_id)
383{
384 WMI_LOGP("%s : called", __func__);
385 return QDF_STATUS_SUCCESS;
386}
387
388/**
389 * fake_vdev_start_cmd_tlv() - send vdev start request to fw
390 * @wmi_handle: wmi handle
391 * @req: vdev start params
392 *
393 * Return: QDF status
394 */
395static QDF_STATUS fake_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
396 struct vdev_start_params *req)
397{
398 tp_wma_handle wma = (tp_wma_handle) wmi_handle->scn_handle;
399 WMI_LOGP("%s : called", __func__);
400 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info is_dfs %d "
401 "beacon interval %d dtim %d center_chan %d center_freq2 %d "
402 "max_txpow: 0x%x "
403 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d",
Vivek08443272018-11-15 16:22:22 +0530404 __func__, (int)req->vdev_id, req->channel.mhz,
405 req->channel.phy_mode,
406 (int)req->channel.dfs_set, req->beacon_intval, req->dtim_period,
407 req->channel.cfreq1, req->channel.cfreq2,
408 req->channel.maxregpower,
Zhang Qian36794922018-01-03 16:33:24 +0800409 req->preferred_tx_streams, req->preferred_rx_streams,
410 (int)req->ldpc_rx_enabled, req->cac_duration_ms,
411 req->regdomain, req->he_ops);
Zhang Qian36794922018-01-03 16:33:24 +0800412 ucfg_ocb_config_channel(wma->pdev);
413 return QDF_STATUS_SUCCESS;
414}
415
416/**
417 * fake_vdev_down_cmd_tlv() - send vdev down command to fw
418 * @wmi: wmi handle
419 * @vdev_id: vdev id
420 *
421 * Return: QDF_STATUS_SUCCESS for success or error code
422 */
423static QDF_STATUS fake_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
424{
425 WMI_LOGP("%s : called", __func__);
426 return QDF_STATUS_SUCCESS;
427}
428
429/**
430 * fake_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
431 * @param wmi_handle : handle to WMI.
432 * @param macaddr : MAC address
433 * @param param : pointer to hold vdev set parameter
434 *
435 * Return: 0 on success and -ve on failure.
436 */
437static QDF_STATUS fake_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
438 struct vdev_set_params *param)
439{
440 WMI_LOGP("%s : called", __func__);
441 return QDF_STATUS_SUCCESS;
442}
443
444/**
445 * fake_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -
446 * faked API to enable/disable mcc scheduler
447 * @wmi_handle: wmi handle
448 * @mcc_adaptive_scheduler: enable/disable
449 *
450 * This function enable/disable mcc adaptive scheduler in fw.
451 *
Jeff Johnsonae1b3de2018-05-06 00:09:31 -0700452 * Return: QDF_STATUS_SUCCESS for success or error code
Zhang Qian36794922018-01-03 16:33:24 +0800453 */
454static QDF_STATUS fake_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
455 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
456 uint32_t pdev_id)
457{
458 WMI_LOGP("%s : called", __func__);
459 return QDF_STATUS_SUCCESS;
460}
461
462/*
463 * fake_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
464 * @wmi_handle: Pointer to WMi handle
465 * @ie_data: Pointer for ie data
466 *
467 * This function sends IE information to firmware
468 *
469 * Return: QDF_STATUS_SUCCESS for success otherwise failure
470 *
471 */
472static QDF_STATUS fake_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
473 struct vdev_ie_info_param *ie_info)
474{
475 WMI_LOGP("%s : called", __func__);
476 return QDF_STATUS_SUCCESS;
477}
478
479void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle)
480{
481 struct wmi_ops *wmi_ops;
482
483 if (!wmi_handle) {
484 WMI_LOGP("%s: null wmi handle", __func__);
485 return;
486 }
487
488 wmi_ops = wmi_handle->ops;
489 wmi_ops->send_vdev_create_cmd = fake_vdev_create_cmd_tlv;
490 wmi_ops->send_vdev_delete_cmd = fake_vdev_delete_cmd_tlv;
491 wmi_ops->send_vdev_down_cmd = fake_vdev_down_cmd_tlv;
492 wmi_ops->send_vdev_start_cmd = fake_vdev_start_cmd_tlv;
493 wmi_ops->send_peer_create_cmd = fake_peer_create_cmd_tlv;
494 wmi_ops->send_peer_delete_cmd = fake_peer_delete_cmd_tlv;
495 wmi_ops->send_vdev_set_param_cmd = fake_vdev_set_param_cmd_tlv;
496 wmi_ops->send_ocb_set_utc_time_cmd = fake_ocb_set_utc_time_cmd_tlv;
497 wmi_ops->send_ocb_get_tsf_timer_cmd = fake_ocb_get_tsf_timer_cmd_tlv;
498 wmi_ops->send_dcc_clear_stats_cmd = fake_dcc_clear_stats_cmd_tlv;
499 wmi_ops->send_dcc_get_stats_cmd = fake_dcc_get_stats_cmd_tlv;
500 wmi_ops->send_dcc_update_ndl_cmd = fake_dcc_update_ndl_cmd_tlv;
501 wmi_ops->send_ocb_set_config_cmd = fake_ocb_set_config_cmd_tlv;
502 wmi_ops->send_ocb_stop_timing_advert_cmd =
503 fake_ocb_stop_timing_advert_cmd_tlv;
504 wmi_ops->send_ocb_start_timing_advert_cmd =
505 fake_ocb_start_timing_advert_cmd_tlv;
506 wmi_ops->send_set_enable_disable_mcc_adaptive_scheduler_cmd =
507 fake_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv;
508 wmi_ops->send_process_set_ie_info_cmd =
509 fake_process_set_ie_info_cmd_tlv;
510}