1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name /**
21*5113495bSYour Name * DOC: wlan_hdd_disa.c
22*5113495bSYour Name *
23*5113495bSYour Name * WLAN Host Device Driver file for DISA certification
24*5113495bSYour Name *
25*5113495bSYour Name */
26*5113495bSYour Name
27*5113495bSYour Name #include "wlan_hdd_disa.h"
28*5113495bSYour Name #include "osif_sync.h"
29*5113495bSYour Name #include "wlan_disa_ucfg_api.h"
30*5113495bSYour Name #include "wlan_osif_request_manager.h"
31*5113495bSYour Name #include "sme_api.h"
32*5113495bSYour Name #include <qca_vendor.h>
33*5113495bSYour Name
34*5113495bSYour Name #define WLAN_WAIT_TIME_ENCRYPT_DECRYPT 1000
35*5113495bSYour Name
36*5113495bSYour Name
37*5113495bSYour Name /**
38*5113495bSYour Name * struct hdd_encrypt_decrypt_msg_context - hdd encrypt/decrypt message context
39*5113495bSYour Name * @status: status of response. 0: no error, -ENOMEM: unable to allocate
40*5113495bSYour Name * memory for the response payload
41*5113495bSYour Name * @request: encrypt/decrypt request
42*5113495bSYour Name * @response: encrypt/decrypt response
43*5113495bSYour Name */
44*5113495bSYour Name struct hdd_encrypt_decrypt_msg_context {
45*5113495bSYour Name int status;
46*5113495bSYour Name struct disa_encrypt_decrypt_req_params request;
47*5113495bSYour Name struct disa_encrypt_decrypt_resp_params response;
48*5113495bSYour Name };
49*5113495bSYour Name
50*5113495bSYour Name /**
51*5113495bSYour Name * hdd_encrypt_decrypt_msg_cb () - encrypt/decrypt response message handler
52*5113495bSYour Name * @cookie: hdd request cookie
53*5113495bSYour Name * @resp: encrypt/decrypt response parameters
54*5113495bSYour Name *
55*5113495bSYour Name * Return: none
56*5113495bSYour Name */
hdd_encrypt_decrypt_msg_cb(void * cookie,struct disa_encrypt_decrypt_resp_params * resp)57*5113495bSYour Name static void hdd_encrypt_decrypt_msg_cb(void *cookie,
58*5113495bSYour Name struct disa_encrypt_decrypt_resp_params *resp)
59*5113495bSYour Name {
60*5113495bSYour Name struct osif_request *request;
61*5113495bSYour Name struct hdd_encrypt_decrypt_msg_context *context;
62*5113495bSYour Name
63*5113495bSYour Name hdd_enter();
64*5113495bSYour Name
65*5113495bSYour Name if (!resp) {
66*5113495bSYour Name hdd_err("rsp params is NULL");
67*5113495bSYour Name return;
68*5113495bSYour Name }
69*5113495bSYour Name
70*5113495bSYour Name request = osif_request_get(cookie);
71*5113495bSYour Name if (!request) {
72*5113495bSYour Name hdd_err("Obsolete request");
73*5113495bSYour Name return;
74*5113495bSYour Name }
75*5113495bSYour Name
76*5113495bSYour Name print_hex_dump(KERN_INFO, "Data in hdd_encrypt_decrypt_msg_cb: ",
77*5113495bSYour Name DUMP_PREFIX_NONE, 16, 1,
78*5113495bSYour Name resp->data,
79*5113495bSYour Name resp->data_len, 0);
80*5113495bSYour Name
81*5113495bSYour Name hdd_debug("vdev_id: %d status:%d data_length: %d",
82*5113495bSYour Name resp->vdev_id,
83*5113495bSYour Name resp->status,
84*5113495bSYour Name resp->data_len);
85*5113495bSYour Name
86*5113495bSYour Name context = osif_request_priv(request);
87*5113495bSYour Name context->response = *resp;
88*5113495bSYour Name context->status = 0;
89*5113495bSYour Name if (resp->data_len) {
90*5113495bSYour Name context->response.data =
91*5113495bSYour Name qdf_mem_malloc(sizeof(uint8_t) *
92*5113495bSYour Name resp->data_len);
93*5113495bSYour Name if (!context->response.data) {
94*5113495bSYour Name context->status = -ENOMEM;
95*5113495bSYour Name } else {
96*5113495bSYour Name qdf_mem_copy(context->response.data,
97*5113495bSYour Name resp->data,
98*5113495bSYour Name resp->data_len);
99*5113495bSYour Name }
100*5113495bSYour Name } else {
101*5113495bSYour Name /* make sure we don't have a rogue pointer */
102*5113495bSYour Name context->response.data = NULL;
103*5113495bSYour Name }
104*5113495bSYour Name
105*5113495bSYour Name osif_request_complete(request);
106*5113495bSYour Name osif_request_put(request);
107*5113495bSYour Name hdd_exit();
108*5113495bSYour Name }
109*5113495bSYour Name
110*5113495bSYour Name /**
111*5113495bSYour Name * hdd_post_encrypt_decrypt_msg_rsp () - send encrypt/decrypt data to user space
112*5113495bSYour Name * @hdd_ctx: HDD context
113*5113495bSYour Name * @resp: encrypt/decrypt response parameters
114*5113495bSYour Name *
115*5113495bSYour Name * Return: none
116*5113495bSYour Name */
hdd_post_encrypt_decrypt_msg_rsp(struct hdd_context * hdd_ctx,struct disa_encrypt_decrypt_resp_params * resp)117*5113495bSYour Name static int hdd_post_encrypt_decrypt_msg_rsp(struct hdd_context *hdd_ctx,
118*5113495bSYour Name struct disa_encrypt_decrypt_resp_params *resp)
119*5113495bSYour Name {
120*5113495bSYour Name struct sk_buff *skb;
121*5113495bSYour Name uint32_t nl_buf_len;
122*5113495bSYour Name
123*5113495bSYour Name hdd_enter();
124*5113495bSYour Name
125*5113495bSYour Name nl_buf_len = resp->data_len + NLA_HDRLEN;
126*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
127*5113495bSYour Name nl_buf_len);
128*5113495bSYour Name if (!skb) {
129*5113495bSYour Name hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
130*5113495bSYour Name return -ENOMEM;
131*5113495bSYour Name }
132*5113495bSYour Name
133*5113495bSYour Name if (resp->data_len) {
134*5113495bSYour Name if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA,
135*5113495bSYour Name resp->data_len, resp->data)) {
136*5113495bSYour Name hdd_err("put fail");
137*5113495bSYour Name goto nla_put_failure;
138*5113495bSYour Name }
139*5113495bSYour Name }
140*5113495bSYour Name
141*5113495bSYour Name wlan_cfg80211_vendor_cmd_reply(skb);
142*5113495bSYour Name hdd_exit();
143*5113495bSYour Name return 0;
144*5113495bSYour Name
145*5113495bSYour Name nla_put_failure:
146*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
147*5113495bSYour Name return -EINVAL;
148*5113495bSYour Name }
149*5113495bSYour Name
150*5113495bSYour Name const struct nla_policy
151*5113495bSYour Name encrypt_decrypt_policy[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1] = {
152*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION] = {
153*5113495bSYour Name .type = NLA_FLAG},
154*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER] = {
155*5113495bSYour Name .type = NLA_U32},
156*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID] = {
157*5113495bSYour Name .type = NLA_U8},
158*5113495bSYour Name };
159*5113495bSYour Name
160*5113495bSYour Name /**
161*5113495bSYour Name * hdd_fill_encrypt_decrypt_params () - parses data from user space
162*5113495bSYour Name * and fills encrypt/decrypt parameters
163*5113495bSYour Name * @encrypt_decrypt_params: encrypt/decrypt request parameters
164*5113495bSYour Name * @adapter : adapter context
165*5113495bSYour Name * @data: Pointer to data
166*5113495bSYour Name * @data_len: Data length
167*5113495bSYour Name *
168*5113495bSYour Name * Return: 0 on success, negative errno on failure
169*5113495bSYour Name */
170*5113495bSYour Name static int
hdd_fill_encrypt_decrypt_params(struct disa_encrypt_decrypt_req_params * encrypt_decrypt_params,struct hdd_adapter * adapter,const void * data,int data_len)171*5113495bSYour Name hdd_fill_encrypt_decrypt_params(struct disa_encrypt_decrypt_req_params
172*5113495bSYour Name *encrypt_decrypt_params,
173*5113495bSYour Name struct hdd_adapter *adapter,
174*5113495bSYour Name const void *data,
175*5113495bSYour Name int data_len)
176*5113495bSYour Name {
177*5113495bSYour Name struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1];
178*5113495bSYour Name uint8_t len, mac_hdr_len;
179*5113495bSYour Name uint8_t *tmp;
180*5113495bSYour Name uint8_t fc[2];
181*5113495bSYour Name
182*5113495bSYour Name if (wlan_cfg80211_nla_parse(tb,
183*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX,
184*5113495bSYour Name data, data_len, encrypt_decrypt_policy)) {
185*5113495bSYour Name hdd_err("Invalid ATTR");
186*5113495bSYour Name return -EINVAL;
187*5113495bSYour Name }
188*5113495bSYour Name
189*5113495bSYour Name encrypt_decrypt_params->vdev_id = adapter->deflink->vdev_id;
190*5113495bSYour Name hdd_debug("vdev_id: %d", encrypt_decrypt_params->vdev_id);
191*5113495bSYour Name
192*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION]) {
193*5113495bSYour Name hdd_err("attr flag NEEDS_DECRYPTION not present");
194*5113495bSYour Name encrypt_decrypt_params->key_flag = WMI_ENCRYPT;
195*5113495bSYour Name } else {
196*5113495bSYour Name hdd_err("attr flag NEEDS_DECRYPTION present");
197*5113495bSYour Name encrypt_decrypt_params->key_flag = WMI_DECRYPT;
198*5113495bSYour Name }
199*5113495bSYour Name hdd_debug("Key flag: %d", encrypt_decrypt_params->key_flag);
200*5113495bSYour Name
201*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]) {
202*5113495bSYour Name hdd_err("attr key id failed");
203*5113495bSYour Name return -EINVAL;
204*5113495bSYour Name }
205*5113495bSYour Name encrypt_decrypt_params->key_idx = nla_get_u8(tb
206*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]);
207*5113495bSYour Name hdd_debug("Key Idx: %d", encrypt_decrypt_params->key_idx);
208*5113495bSYour Name
209*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]) {
210*5113495bSYour Name hdd_err("attr Cipher failed");
211*5113495bSYour Name return -EINVAL;
212*5113495bSYour Name }
213*5113495bSYour Name encrypt_decrypt_params->key_cipher = nla_get_u32(tb
214*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]);
215*5113495bSYour Name hdd_debug("key_cipher: %d", encrypt_decrypt_params->key_cipher);
216*5113495bSYour Name
217*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]) {
218*5113495bSYour Name hdd_err("attr TK failed");
219*5113495bSYour Name return -EINVAL;
220*5113495bSYour Name }
221*5113495bSYour Name encrypt_decrypt_params->key_len =
222*5113495bSYour Name nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
223*5113495bSYour Name if (!encrypt_decrypt_params->key_len) {
224*5113495bSYour Name hdd_err("Invalid TK length");
225*5113495bSYour Name return -EINVAL;
226*5113495bSYour Name }
227*5113495bSYour Name hdd_debug("Key len: %d", encrypt_decrypt_params->key_len);
228*5113495bSYour Name
229*5113495bSYour Name if (encrypt_decrypt_params->key_len > SIR_MAC_MAX_KEY_LENGTH)
230*5113495bSYour Name encrypt_decrypt_params->key_len = SIR_MAC_MAX_KEY_LENGTH;
231*5113495bSYour Name
232*5113495bSYour Name tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
233*5113495bSYour Name
234*5113495bSYour Name qdf_mem_copy(encrypt_decrypt_params->key_data, tmp,
235*5113495bSYour Name encrypt_decrypt_params->key_len);
236*5113495bSYour Name
237*5113495bSYour Name print_hex_dump(KERN_INFO, "Key : ", DUMP_PREFIX_NONE, 16, 1,
238*5113495bSYour Name &encrypt_decrypt_params->key_data,
239*5113495bSYour Name encrypt_decrypt_params->key_len, 0);
240*5113495bSYour Name
241*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]) {
242*5113495bSYour Name hdd_err("attr PN failed");
243*5113495bSYour Name return -EINVAL;
244*5113495bSYour Name }
245*5113495bSYour Name len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
246*5113495bSYour Name if (!len || len > sizeof(encrypt_decrypt_params->pn)) {
247*5113495bSYour Name hdd_err("Invalid PN length %u", len);
248*5113495bSYour Name return -EINVAL;
249*5113495bSYour Name }
250*5113495bSYour Name
251*5113495bSYour Name tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
252*5113495bSYour Name
253*5113495bSYour Name qdf_mem_copy(encrypt_decrypt_params->pn, tmp, len);
254*5113495bSYour Name
255*5113495bSYour Name print_hex_dump(KERN_INFO, "PN received : ", DUMP_PREFIX_NONE, 16, 1,
256*5113495bSYour Name &encrypt_decrypt_params->pn, len, 0);
257*5113495bSYour Name
258*5113495bSYour Name if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]) {
259*5113495bSYour Name hdd_err("attr header failed");
260*5113495bSYour Name return -EINVAL;
261*5113495bSYour Name }
262*5113495bSYour Name len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
263*5113495bSYour Name if (len < MIN_MAC_HEADER_LEN) {
264*5113495bSYour Name hdd_err("Invalid header and payload length %u", len);
265*5113495bSYour Name return -EINVAL;
266*5113495bSYour Name }
267*5113495bSYour Name
268*5113495bSYour Name hdd_debug("Header and Payload length: %d", len);
269*5113495bSYour Name
270*5113495bSYour Name tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
271*5113495bSYour Name
272*5113495bSYour Name print_hex_dump(KERN_INFO, "Header and Payload received: ",
273*5113495bSYour Name DUMP_PREFIX_NONE, 16, 1,
274*5113495bSYour Name tmp, len, 0);
275*5113495bSYour Name
276*5113495bSYour Name mac_hdr_len = MIN_MAC_HEADER_LEN;
277*5113495bSYour Name
278*5113495bSYour Name /*
279*5113495bSYour Name * Check to find out address 4. Address 4 is present if ToDS and FromDS
280*5113495bSYour Name * are 1 and data representation is little endian.
281*5113495bSYour Name */
282*5113495bSYour Name fc[1] = *tmp;
283*5113495bSYour Name fc[0] = *(tmp + 1);
284*5113495bSYour Name if ((fc[0] & 0x03) == 0x03) {
285*5113495bSYour Name hdd_err("Address 4 is present");
286*5113495bSYour Name mac_hdr_len += QDF_MAC_ADDR_SIZE;
287*5113495bSYour Name }
288*5113495bSYour Name
289*5113495bSYour Name /*
290*5113495bSYour Name * Check to find out Qos control field. Qos control field is present
291*5113495bSYour Name * if msb of subtype field is 1 and data representation is
292*5113495bSYour Name * little endian.
293*5113495bSYour Name */
294*5113495bSYour Name if (fc[1] & 0x80) {
295*5113495bSYour Name hdd_err("Qos control is present");
296*5113495bSYour Name mac_hdr_len += QOS_CONTROL_LEN;
297*5113495bSYour Name }
298*5113495bSYour Name
299*5113495bSYour Name hdd_debug("mac_hdr_len: %d", mac_hdr_len);
300*5113495bSYour Name
301*5113495bSYour Name if (len < mac_hdr_len) {
302*5113495bSYour Name hdd_err("Invalid header and payload length %u", len);
303*5113495bSYour Name return -EINVAL;
304*5113495bSYour Name }
305*5113495bSYour Name qdf_mem_copy(encrypt_decrypt_params->mac_header,
306*5113495bSYour Name tmp, mac_hdr_len);
307*5113495bSYour Name
308*5113495bSYour Name print_hex_dump(KERN_INFO, "Header received in request: ",
309*5113495bSYour Name DUMP_PREFIX_NONE, 16, 1,
310*5113495bSYour Name encrypt_decrypt_params->mac_header,
311*5113495bSYour Name mac_hdr_len, 0);
312*5113495bSYour Name
313*5113495bSYour Name encrypt_decrypt_params->data_len =
314*5113495bSYour Name len - mac_hdr_len;
315*5113495bSYour Name
316*5113495bSYour Name hdd_debug("Payload length: %d", encrypt_decrypt_params->data_len);
317*5113495bSYour Name
318*5113495bSYour Name if (encrypt_decrypt_params->data_len) {
319*5113495bSYour Name encrypt_decrypt_params->data =
320*5113495bSYour Name qdf_mem_malloc(sizeof(uint8_t) *
321*5113495bSYour Name encrypt_decrypt_params->data_len);
322*5113495bSYour Name
323*5113495bSYour Name if (!encrypt_decrypt_params->data)
324*5113495bSYour Name return -ENOMEM;
325*5113495bSYour Name
326*5113495bSYour Name qdf_mem_copy(encrypt_decrypt_params->data,
327*5113495bSYour Name tmp + mac_hdr_len,
328*5113495bSYour Name encrypt_decrypt_params->data_len);
329*5113495bSYour Name
330*5113495bSYour Name print_hex_dump(KERN_INFO, "Data received in request: ",
331*5113495bSYour Name DUMP_PREFIX_NONE, 16, 1,
332*5113495bSYour Name encrypt_decrypt_params->data,
333*5113495bSYour Name encrypt_decrypt_params->data_len, 0);
334*5113495bSYour Name }
335*5113495bSYour Name
336*5113495bSYour Name return 0;
337*5113495bSYour Name }
338*5113495bSYour Name
hdd_encrypt_decrypt_context_dealloc(void * priv)339*5113495bSYour Name static void hdd_encrypt_decrypt_context_dealloc(void *priv)
340*5113495bSYour Name {
341*5113495bSYour Name struct hdd_encrypt_decrypt_msg_context *context = priv;
342*5113495bSYour Name
343*5113495bSYour Name qdf_mem_free(context->request.data);
344*5113495bSYour Name qdf_mem_free(context->response.data);
345*5113495bSYour Name }
346*5113495bSYour Name
347*5113495bSYour Name /**
348*5113495bSYour Name * hdd_encrypt_decrypt_msg () - process encrypt/decrypt message
349*5113495bSYour Name * @adapter : adapter context
350*5113495bSYour Name * @hdd_ctx: hdd context
351*5113495bSYour Name * @data: Pointer to data
352*5113495bSYour Name * @data_len: Data length
353*5113495bSYour Name *
354*5113495bSYour Name * Return: 0 on success, negative errno on failure
355*5113495bSYour Name */
hdd_encrypt_decrypt_msg(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx,const void * data,int data_len)356*5113495bSYour Name static int hdd_encrypt_decrypt_msg(struct hdd_adapter *adapter,
357*5113495bSYour Name struct hdd_context *hdd_ctx,
358*5113495bSYour Name const void *data,
359*5113495bSYour Name int data_len)
360*5113495bSYour Name {
361*5113495bSYour Name QDF_STATUS qdf_status;
362*5113495bSYour Name int ret;
363*5113495bSYour Name void *cookie;
364*5113495bSYour Name struct osif_request *request;
365*5113495bSYour Name struct hdd_encrypt_decrypt_msg_context *context;
366*5113495bSYour Name static const struct osif_request_params params = {
367*5113495bSYour Name .priv_size = sizeof(*context),
368*5113495bSYour Name .timeout_ms = WLAN_WAIT_TIME_ENCRYPT_DECRYPT,
369*5113495bSYour Name .dealloc = hdd_encrypt_decrypt_context_dealloc,
370*5113495bSYour Name };
371*5113495bSYour Name
372*5113495bSYour Name request = osif_request_alloc(¶ms);
373*5113495bSYour Name if (!request) {
374*5113495bSYour Name hdd_err("Request allocation failure");
375*5113495bSYour Name return -ENOMEM;
376*5113495bSYour Name }
377*5113495bSYour Name context = osif_request_priv(request);
378*5113495bSYour Name
379*5113495bSYour Name ret = hdd_fill_encrypt_decrypt_params(&context->request, adapter,
380*5113495bSYour Name data, data_len);
381*5113495bSYour Name if (ret)
382*5113495bSYour Name goto cleanup;
383*5113495bSYour Name
384*5113495bSYour Name cookie = osif_request_cookie(request);
385*5113495bSYour Name
386*5113495bSYour Name qdf_status = ucfg_disa_encrypt_decrypt_req(hdd_ctx->psoc,
387*5113495bSYour Name &context->request,
388*5113495bSYour Name hdd_encrypt_decrypt_msg_cb,
389*5113495bSYour Name cookie);
390*5113495bSYour Name
391*5113495bSYour Name if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
392*5113495bSYour Name hdd_err("Unable to post encrypt/decrypt message");
393*5113495bSYour Name ret = -EINVAL;
394*5113495bSYour Name goto cleanup;
395*5113495bSYour Name }
396*5113495bSYour Name
397*5113495bSYour Name ret = osif_request_wait_for_response(request);
398*5113495bSYour Name if (ret) {
399*5113495bSYour Name hdd_err("Target response timed out");
400*5113495bSYour Name goto cleanup;
401*5113495bSYour Name }
402*5113495bSYour Name
403*5113495bSYour Name ret = context->status;
404*5113495bSYour Name if (ret) {
405*5113495bSYour Name hdd_err("Target response processing failed");
406*5113495bSYour Name goto cleanup;
407*5113495bSYour Name }
408*5113495bSYour Name
409*5113495bSYour Name ret = hdd_post_encrypt_decrypt_msg_rsp(hdd_ctx, &context->response);
410*5113495bSYour Name if (ret)
411*5113495bSYour Name hdd_err("Failed to post encrypt/decrypt message response");
412*5113495bSYour Name
413*5113495bSYour Name cleanup:
414*5113495bSYour Name osif_request_put(request);
415*5113495bSYour Name
416*5113495bSYour Name hdd_exit();
417*5113495bSYour Name return ret;
418*5113495bSYour Name }
419*5113495bSYour Name
420*5113495bSYour Name /**
421*5113495bSYour Name * __wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
422*5113495bSYour Name * @wiphy: Pointer to wireless phy
423*5113495bSYour Name * @wdev: Pointer to wireless device
424*5113495bSYour Name * @data: Pointer to data
425*5113495bSYour Name * @data_len: Data length
426*5113495bSYour Name *
427*5113495bSYour Name * Return: 0 on success, negative errno on failure
428*5113495bSYour Name */
__wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)429*5113495bSYour Name static int __wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
430*5113495bSYour Name struct wireless_dev *wdev,
431*5113495bSYour Name const void *data,
432*5113495bSYour Name int data_len)
433*5113495bSYour Name {
434*5113495bSYour Name struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
435*5113495bSYour Name struct net_device *dev = wdev->netdev;
436*5113495bSYour Name struct hdd_adapter *adapter = NULL;
437*5113495bSYour Name int ret;
438*5113495bSYour Name bool is_bmps_enabled;
439*5113495bSYour Name
440*5113495bSYour Name hdd_enter_dev(dev);
441*5113495bSYour Name
442*5113495bSYour Name if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
443*5113495bSYour Name hdd_err("Command not allowed in FTM mode");
444*5113495bSYour Name return -EPERM;
445*5113495bSYour Name }
446*5113495bSYour Name
447*5113495bSYour Name ret = wlan_hdd_validate_context(hdd_ctx);
448*5113495bSYour Name if (ret)
449*5113495bSYour Name return ret;
450*5113495bSYour Name
451*5113495bSYour Name adapter = WLAN_HDD_GET_PRIV_PTR(dev);
452*5113495bSYour Name
453*5113495bSYour Name ucfg_mlme_is_bmps_enabled(hdd_ctx->psoc, &is_bmps_enabled);
454*5113495bSYour Name if (is_bmps_enabled) {
455*5113495bSYour Name hdd_debug("DISA is not supported when PS is enabled");
456*5113495bSYour Name return -EINVAL;
457*5113495bSYour Name }
458*5113495bSYour Name
459*5113495bSYour Name ret = hdd_encrypt_decrypt_msg(adapter, hdd_ctx, data, data_len);
460*5113495bSYour Name
461*5113495bSYour Name return ret;
462*5113495bSYour Name }
463*5113495bSYour Name
464*5113495bSYour Name /**
465*5113495bSYour Name * wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
466*5113495bSYour Name * @wiphy: Pointer to wireless phy
467*5113495bSYour Name * @wdev: Pointer to wireless device
468*5113495bSYour Name * @data: Pointer to data
469*5113495bSYour Name * @data_len: Data length
470*5113495bSYour Name *
471*5113495bSYour Name * Return: 0 on success, negative errno on failure
472*5113495bSYour Name */
wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)473*5113495bSYour Name int wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
474*5113495bSYour Name struct wireless_dev *wdev,
475*5113495bSYour Name const void *data,
476*5113495bSYour Name int data_len)
477*5113495bSYour Name {
478*5113495bSYour Name int errno;
479*5113495bSYour Name struct osif_vdev_sync *vdev_sync;
480*5113495bSYour Name
481*5113495bSYour Name errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
482*5113495bSYour Name if (errno)
483*5113495bSYour Name return errno;
484*5113495bSYour Name
485*5113495bSYour Name errno = __wlan_hdd_cfg80211_encrypt_decrypt_msg(wiphy, wdev,
486*5113495bSYour Name data, data_len);
487*5113495bSYour Name
488*5113495bSYour Name osif_vdev_sync_op_stop(vdev_sync);
489*5113495bSYour Name
490*5113495bSYour Name return errno;
491*5113495bSYour Name }
492