1 /*
2 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022 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: wlan_wfa_tgt_if_tx_api.c
20 *
21 * Implementation for the Common WFA config interfaces.
22 */
23
24 #include "wlan_objmgr_psoc_obj.h"
25 #include "wlan_psoc_mlme_api.h"
26 #include "wlan_mlme_ucfg_api.h"
27 #include "wlan_wfa_tgt_if_tx_api.h"
28 #include "wlan_mlme_public_struct.h"
29 #include "wlan_vdev_mgr_tgt_if_tx_api.h"
30 #include "wma.h"
31
32 static inline struct wlan_wfa_cmd_tx_ops *
wlan_wfatest_get_tx_ops_from_vdev(struct wlan_objmgr_vdev * vdev)33 wlan_wfatest_get_tx_ops_from_vdev(struct wlan_objmgr_vdev *vdev)
34 {
35 mlme_psoc_ext_t *mlme_priv;
36 struct wlan_wfa_cmd_tx_ops *tx_ops;
37 struct wlan_objmgr_psoc *psoc;
38
39 psoc = wlan_vdev_get_psoc(vdev);
40 if (!psoc) {
41 mlme_legacy_err("psoc object is NULL");
42 return NULL;
43 }
44
45 mlme_priv = wlan_psoc_mlme_get_ext_hdl(psoc);
46 if (!mlme_priv) {
47 mlme_legacy_err("vdev legacy private object is NULL");
48 return NULL;
49 }
50
51 tx_ops = &mlme_priv->wfa_testcmd.tx_ops;
52
53 return tx_ops;
54 }
55
56 static QDF_STATUS
wlan_wfa_set_test_feature_flags(struct wlan_objmgr_psoc * psoc,enum wlan_wfa_test_feature_flags feature,uint8_t value)57 wlan_wfa_set_test_feature_flags(struct wlan_objmgr_psoc *psoc,
58 enum wlan_wfa_test_feature_flags feature,
59 uint8_t value)
60 {
61 mlme_psoc_ext_t *mlme_priv;
62
63 if (!psoc) {
64 mlme_legacy_err("psoc object is NULL");
65 return QDF_STATUS_E_INVAL;
66 }
67
68 mlme_priv = wlan_psoc_mlme_get_ext_hdl(psoc);
69 if (!mlme_priv) {
70 mlme_legacy_err("vdev legacy private object is NULL");
71 return QDF_STATUS_E_INVAL;
72 }
73
74 switch (feature) {
75 case WFA_TEST_IGNORE_RSNXE:
76 if (value)
77 mlme_priv->wfa_testcmd.flags |= WFA_TEST_IGNORE_RSNXE;
78 else
79 mlme_priv->wfa_testcmd.flags &= ~WFA_TEST_IGNORE_RSNXE;
80 break;
81 default:
82 mlme_legacy_debug("Invalid feature flag: 0x%x", feature);
83 break;
84 }
85
86 return QDF_STATUS_SUCCESS;
87 }
88
wlan_wfa_get_test_feature_flags(struct wlan_objmgr_psoc * psoc,enum wlan_wfa_test_feature_flags feature)89 bool wlan_wfa_get_test_feature_flags(struct wlan_objmgr_psoc *psoc,
90 enum wlan_wfa_test_feature_flags feature)
91 {
92 mlme_psoc_ext_t *mlme_priv;
93 bool set = false;
94
95 if (!psoc) {
96 mlme_legacy_err("psoc object is NULL");
97 return set;
98 }
99
100 mlme_priv = wlan_psoc_mlme_get_ext_hdl(psoc);
101 if (!mlme_priv) {
102 mlme_legacy_err("psoc legacy private object is NULL");
103 return set;
104 }
105
106 switch (feature) {
107 case WFA_TEST_IGNORE_RSNXE:
108 set = !!(mlme_priv->wfa_testcmd.flags & WFA_TEST_IGNORE_RSNXE);
109 if (set)
110 mlme_legacy_debug("IGNORE_RSNXE is set");
111 break;
112 default:
113 mlme_legacy_debug("Invalid feature flag: 0x%x", feature);
114 break;
115 }
116
117 return set;
118 }
119
120 QDF_STATUS
wlan_send_wfatest_cmd(struct wlan_objmgr_vdev * vdev,struct set_wfatest_params * wmi_wfatest)121 wlan_send_wfatest_cmd(struct wlan_objmgr_vdev *vdev,
122 struct set_wfatest_params *wmi_wfatest)
123 {
124 QDF_STATUS status = QDF_STATUS_E_FAILURE;
125 struct wlan_wfa_cmd_tx_ops *tx_ops;
126 struct vdev_mlme_obj *mlme_obj;
127 struct config_fils_params param = {0};
128
129 if (!vdev || !wmi_wfatest) {
130 mlme_legacy_err("vdev or test params is NULL");
131 return status;
132 }
133
134 if (wmi_wfatest->cmd == WFA_FILS_DISCV_FRAMES) {
135 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
136 if (!mlme_obj) {
137 wma_err("failed to get mlme_obj");
138 return QDF_STATUS_E_INVAL;
139 }
140
141 param.vdev_id = wmi_wfatest->vdev_id;
142 if (wmi_wfatest->value)
143 param.fd_period = DEFAULT_FILS_DISCOVERY_PERIOD;
144
145 return tgt_vdev_mgr_fils_enable_send(mlme_obj, ¶m);
146 } else if (wmi_wfatest->cmd == WFA_IGNORE_H2E_RSNXE) {
147 return wlan_wfa_set_test_feature_flags(wlan_vdev_get_psoc(vdev),
148 WFA_TEST_IGNORE_RSNXE,
149 wmi_wfatest->value);
150 }
151
152 tx_ops = wlan_wfatest_get_tx_ops_from_vdev(vdev);
153 if (!tx_ops || !tx_ops->send_wfa_test_cmd) {
154 mlme_legacy_err("Failed to send WFA test cmd");
155 return QDF_STATUS_E_FAILURE;
156 }
157
158 return tx_ops->send_wfa_test_cmd(vdev, wmi_wfatest);
159 }
160