1 /** @file mlan_uap_ioctl.c
2  *
3  *  @brief  This file provides handling of AP mode ioctls
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 /********************************************************
12 Change log:
13     02/05/2009: initial version
14 ********************************************************/
15 
16 #include <mlan_api.h>
17 
18 /* Additional WMSDK header files */
19 #include <wmerrno.h>
20 #include <osa.h>
21 
22 /* Always keep this include at the end of all include files */
23 #include <mlan_remap_mem_operations.h>
24 
25 #if defined(WAPI_AP) || defined(HOST_AUTHENTICATOR) || (CONFIG_WPA_SUPP_AP)
26 /**
27  *  @brief Set encrypt key
28  *
29  *  @param pmadapter	A pointer to mlan_adapter structure
30  *  @param pioctl_req	A pointer to ioctl request buffer
31  *
32  *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success, otherwise fail
33  */
wlan_uap_sec_ioctl_set_encrypt_key(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)34 static mlan_status wlan_uap_sec_ioctl_set_encrypt_key(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
35 {
36     mlan_status ret      = MLAN_STATUS_SUCCESS;
37     mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
38     mlan_ds_sec_cfg *sec = MNULL;
39 
40     ENTER();
41     sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
42     if (pioctl_req->action != MLAN_ACT_SET)
43     {
44         pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
45         LEAVE();
46         return MLAN_STATUS_FAILURE;
47     }
48 #ifdef KEY_PARAM_SET_V2
49     if (!sec->param.encrypt_key.key_remove && !sec->param.encrypt_key.key_len)
50     {
51 #else
52     if (!sec->param.encrypt_key.key_len)
53     {
54 #endif /* KEY_PARAM_SET_V2 */
55         PRINTM(MCMND, "Skip set key with key_len = 0\n");
56         LEAVE();
57         return ret;
58     }
59     ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL, HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
60                            (t_void *)pioctl_req, &sec->param.encrypt_key);
61 
62     if (ret == MLAN_STATUS_SUCCESS)
63         ret = MLAN_STATUS_PENDING;
64     LEAVE();
65     return ret;
66 }
67 #endif
68 
69 #if CONFIG_ECSA
70 /**
71  *  @brief Handle channel switch
72  *
73  *  @param pmadapter	A pointer to mlan_adapter structure
74  *  @param pioctl_req	A pointer to ioctl request buffer
75  *
76  *  @return		MLAN_STATUS_PENDING --success, otherwise fail
77  */
78 mlan_status wlan_uap_bss_ioctl_action_chan_switch(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
79 {
80     mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
81     mlan_status ret      = MLAN_STATUS_SUCCESS;
82     t_u16 cmd_action     = 0;
83 
84     ENTER();
85 
86     cmd_action = HostCmd_ACT_GEN_SET;
87 
88     /* Send request to firmware */
89     ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action, 0, (t_void *)pioctl_req, MNULL);
90 
91     if (ret == MLAN_STATUS_SUCCESS)
92         ret = MLAN_STATUS_PENDING;
93 
94     LEAVE();
95     return ret;
96 }
97 #endif
98 
99 /**
100  *  @brief MLAN uap ioctl handler
101  *
102  *  @param adapter	A pointer to mlan_adapter structure
103  *  @param pioctl_req	A pointer to ioctl request buffer
104  *
105  *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
106  */
107 mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
108 {
109     pmlan_adapter pmadapter = (pmlan_adapter)adapter;
110     mlan_status status      = MLAN_STATUS_SUCCESS;
111 #if CONFIG_ECSA
112     mlan_ds_misc_cfg *misc = MNULL;
113     mlan_ds_bss *bss       = MNULL;
114 #endif
115 #if defined(WAPI_AP) || defined(HOST_AUTHENTICATOR) || (CONFIG_WPA_SUPP_AP)
116     mlan_ds_sec_cfg *sec = MNULL;
117 #endif
118     mlan_ds_rate *rate = MNULL;
119 
120     ENTER();
121 
122     switch (pioctl_req->req_id)
123     {
124 #if defined(WAPI_AP) || defined(HOST_AUTHENTICATOR) || (CONFIG_WPA_SUPP_AP)
125         case MLAN_IOCTL_SEC_CFG:
126             sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
127             if (sec->sub_command == MLAN_OID_SEC_CFG_ENCRYPT_KEY)
128                 status = wlan_uap_sec_ioctl_set_encrypt_key(pmadapter, pioctl_req);
129 #ifdef WAPI_AP
130             if (sec->sub_command == MLAN_OID_SEC_CFG_WAPI_ENABLED)
131                 status = wlan_uap_sec_ioctl_wapi_enable(pmadapter, pioctl_req);
132 #endif
133             break;
134 #endif /* WAPI_AP || HOST_AUTHENTICATOR */
135         case MLAN_IOCTL_RATE:
136             rate = (mlan_ds_rate *)(void *)pioctl_req->pbuf;
137             if (rate->sub_command == MLAN_OID_RATE_CFG)
138             {
139                 status = wlan_rate_ioctl_cfg(pmadapter, pioctl_req);
140             }
141             break;
142 #if CONFIG_ECSA
143         case MLAN_IOCTL_MISC_CFG:
144             misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
145             if (misc->sub_command == MLAN_OID_MISC_OPER_CLASS)
146                 status = wlan_misc_ioctl_oper_class(pmadapter, pioctl_req);
147             if (misc->sub_command == MLAN_OID_MISC_OPER_CLASS_CHECK)
148                 status = wlan_misc_ioctl_operclass_validation(pmadapter, pioctl_req);
149             break;
150         case MLAN_IOCTL_BSS:
151             bss = (mlan_ds_bss *)pioctl_req->pbuf;
152             if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH)
153                 status = wlan_uap_bss_ioctl_action_chan_switch(pmadapter, pioctl_req);
154             break;
155 #endif
156 #if CONFIG_11AX
157         case MLAN_IOCTL_11AX_CFG:
158             status = wlan_11ax_cfg_ioctl(pmadapter, pioctl_req);
159             break;
160 #endif
161         default:
162             pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
163             break;
164     }
165     LEAVE();
166     return status;
167 }
168