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, &param);
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