| /** @file hostsa_init.c |
| * |
| * @brief This file defines the initialize /free APIs for authenticator and supplicant. |
| * |
| * Copyright (C) 2014, Marvell International Ltd. |
| * |
| * This software file (the "File") is distributed by Marvell International |
| * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
| * (the "License"). You may use, redistribute and/or modify this File in |
| * accordance with the terms and conditions of the License, a copy of which |
| * is available by writing to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the |
| * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. |
| * |
| * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
| * ARE EXPRESSLY DISCLAIMED. The License provides additional details about |
| * this warranty disclaimer. |
| */ |
| |
| /****************************************************** |
| Change log: |
| 03/07/2014: Initial version |
| ******************************************************/ |
| #include "mlan.h" |
| #ifdef STA_SUPPORT |
| #include "mlan_join.h" |
| #endif |
| #include "mlan_ioctl.h" |
| #include "mlan_util.h" |
| #include "mlan_fw.h" |
| #include "mlan_main.h" |
| #include "mlan_init.h" |
| #include "mlan_wmm.h" |
| #include "hostsa_def.h" |
| |
| #include "authenticator_api.h" |
| |
| /********************* |
| Local Variables |
| *********************/ |
| |
| /********************* |
| Global Variables |
| *********************/ |
| |
| /********************* |
| Local Functions |
| *********************/ |
| |
| /********************* |
| Global Functions |
| *********************/ |
| |
| /********************* |
| Utility Handler |
| *********************/ |
| |
| /** |
| * @brief alloc mlan buffer |
| * |
| * @param pmlan_adapter A void pointer |
| * @param data_len request buffer len |
| * @param head_room head room len |
| * @param malloc_flag flag for mlan buffer |
| |
| * @return pointer to mlan buffer |
| */ |
| pmlan_buffer |
| hostsa_alloc_mlan_buffer(t_void *pmlan_adapter, |
| t_u32 data_len, t_u32 head_room, t_u32 malloc_flag) |
| { |
| mlan_adapter *pmadapter = (mlan_adapter *)pmlan_adapter; |
| pmlan_buffer newbuf = MNULL; |
| |
| newbuf = wlan_alloc_mlan_buffer(pmadapter, data_len, head_room, |
| malloc_flag); |
| |
| return newbuf; |
| } |
| |
| /** |
| * @brief free mlan buffer |
| * |
| * @param pmlan_adapter A void pointer |
| * @param pmbuf a pointer to mlan buffer |
| * |
| * @return |
| */ |
| void |
| hostsa_free_mlan_buffer(t_void *pmlan_adapter, mlan_buffer *pmbuf) |
| { |
| mlan_adapter *pmadapter = (mlan_adapter *)pmlan_adapter; |
| |
| ENTER(); |
| |
| wlan_free_mlan_buffer(pmadapter, pmbuf); |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief send packet |
| * |
| * @param pmlan_private A void pointer |
| * @param pmbuf a pointer to mlan buffer |
| * @param frameLen paket len |
| * |
| * @return |
| */ |
| void |
| hostsa_tx_packet(t_void *pmlan_private, pmlan_buffer pmbuf, t_u16 frameLen) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| t_u8 bss_role = GET_BSS_ROLE(pmpriv); |
| |
| ENTER(); |
| |
| pmbuf->bss_index = pmpriv->bss_index; |
| pmbuf->data_len = frameLen; |
| |
| wlan_add_buf_bypass_txqueue(pmadapter, pmbuf); |
| wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief set key to fw |
| * |
| * @param pmlan_private A void pointer |
| * @param encrypt_key key structure |
| * |
| * @return |
| */ |
| void |
| wlan_set_encrypt_key(t_void *pmlan_private, mlan_ds_encrypt_key *encrypt_key) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| |
| ENTER(); |
| |
| if (!encrypt_key->key_len) { |
| PRINTM(MCMND, "Skip set key with key_len = 0\n"); |
| LEAVE(); |
| return; |
| } |
| |
| ret = wlan_prepare_cmd(priv, |
| HostCmd_CMD_802_11_KEY_MATERIAL, |
| HostCmd_ACT_GEN_SET, |
| KEY_INFO_ENABLED, MNULL, encrypt_key); |
| |
| if (ret == MLAN_STATUS_SUCCESS) |
| wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); |
| |
| LEAVE(); |
| |
| } |
| |
| /** |
| * @brief clear key to fw |
| * |
| * @param pmlan_private A void pointer |
| * |
| * @return |
| */ |
| void |
| wlan_clr_encrypt_key(t_void *pmlan_private) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| mlan_ds_encrypt_key encrypt_key; |
| |
| ENTER(); |
| |
| memset(priv->adapter, &encrypt_key, 0, sizeof(mlan_ds_encrypt_key)); |
| encrypt_key.key_disable = MTRUE; |
| encrypt_key.key_flags = KEY_FLAG_REMOVE_KEY; |
| |
| ret = wlan_prepare_cmd(priv, |
| HostCmd_CMD_802_11_KEY_MATERIAL, |
| HostCmd_ACT_GEN_SET, |
| KEY_INFO_ENABLED, MNULL, &encrypt_key); |
| |
| if (ret == MLAN_STATUS_SUCCESS) |
| wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); |
| |
| LEAVE(); |
| |
| } |
| |
| /** |
| * @brief send deauth frame |
| * |
| * @param pmlan_private A void pointer |
| * @param addr destination mac address |
| * @param reason deauth reason |
| * |
| * @return |
| */ |
| void |
| hostsa_SendDeauth(t_void *pmlan_private, t_u8 *addr, t_u16 reason) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| mlan_deauth_param deauth; |
| |
| ENTER(); |
| |
| memcpy(pmadapter, deauth.mac_addr, addr, MLAN_MAC_ADDR_LENGTH); |
| deauth.reason_code = reason; |
| |
| ret = wlan_prepare_cmd(pmpriv, |
| HOST_CMD_APCMD_STA_DEAUTH, |
| HostCmd_ACT_GEN_SET, |
| 0, MNULL, (t_void *)&deauth); |
| if (ret == MLAN_STATUS_SUCCESS) |
| wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, |
| MNULL); |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief deauth all connected stations |
| * |
| * @param pmlan_private A void pointer |
| * @param reason deauth reason |
| * |
| * @return |
| */ |
| void |
| ApDisAssocAllSta(void *pmlan_private, t_u16 reason) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| sta_node *sta_ptr; |
| |
| ENTER(); |
| |
| sta_ptr = (sta_node *)util_peek_list(pmadapter->pmoal_handle, |
| &pmpriv->sta_list, |
| pmadapter->callbacks. |
| moal_spin_lock, |
| pmadapter->callbacks. |
| moal_spin_unlock); |
| |
| if (!sta_ptr) { |
| LEAVE(); |
| return; |
| } |
| |
| while (sta_ptr != (sta_node *)&pmpriv->sta_list) { |
| hostsa_SendDeauth((t_void *)pmpriv, sta_ptr->mac_addr, reason); |
| sta_ptr = sta_ptr->pnext; |
| } |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief get station entry |
| * |
| * @param pmlan_private A void pointer |
| * @param mac pointer to station mac address |
| * @param ppconPtr pointer to pointer to connection |
| * |
| * @return |
| */ |
| void |
| Hostsa_get_station_entry(t_void *pmlan_private, t_u8 *mac, t_void **ppconPtr) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| sta_node *sta_ptr = MNULL; |
| |
| ENTER(); |
| |
| sta_ptr = wlan_get_station_entry(priv, mac); |
| *ppconPtr = sta_ptr->cm_connectioninfo; |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief find a connection |
| * |
| * @param pmlan_private A void pointer |
| * @param ppconPtr a pointer to pointer to connection |
| * @param ppsta_node a pointer to pointer to sta node |
| * |
| * @return |
| */ |
| void |
| Hostsa_find_connection(t_void *pmlan_private, t_void **ppconPtr, |
| t_void **ppsta_node) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| sta_node *sta_ptr = MNULL; |
| |
| ENTER(); |
| |
| sta_ptr = (sta_node *)util_peek_list(priv->adapter->pmoal_handle, |
| &priv->sta_list, |
| priv->adapter->callbacks. |
| moal_spin_lock, |
| priv->adapter->callbacks. |
| moal_spin_unlock); |
| |
| if (!sta_ptr) { |
| LEAVE(); |
| return; |
| } |
| |
| *ppsta_node = (t_void *)sta_ptr; |
| *ppconPtr = sta_ptr->cm_connectioninfo; |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief find next connection |
| * |
| * @param pmlan_private A void pointer |
| * @param ppconPtr a pointer to pointer to connection |
| * @param ppsta_node a pointer to pointer to sta node |
| * |
| * @return |
| */ |
| void |
| Hostsa_find_next_connection(t_void *pmlan_private, t_void **ppconPtr, |
| t_void **ppsta_node) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| sta_node *sta_ptr = (sta_node *)*ppsta_node; |
| |
| ENTER(); |
| if (sta_ptr != (sta_node *)&priv->sta_list) |
| sta_ptr = sta_ptr->pnext; |
| |
| *ppsta_node = MNULL; |
| *ppconPtr = MNULL; |
| if ((sta_ptr != MNULL) && (sta_ptr != (sta_node *)&priv->sta_list)) { |
| *ppsta_node = (t_void *)sta_ptr; |
| *ppconPtr = sta_ptr->cm_connectioninfo; |
| } |
| LEAVE(); |
| } |
| |
| /** |
| * @brief set management ie for beacon or probe response |
| * |
| * @param pmlan_private A void pointer |
| * @param pbuf ie buf |
| * @param len ie len |
| * @param clearIE clear ie |
| * |
| * @return |
| */ |
| void |
| Hostsa_set_mgmt_ie(t_void *pmlan_private, t_u8 *pbuf, t_u16 len, t_u8 clearIE) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = priv->adapter; |
| mlan_ioctl_req *pioctl_req = MNULL; |
| mlan_ds_misc_cfg *pds_misc_cfg = MNULL; |
| custom_ie *pmgmt_ie = MNULL; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| |
| ENTER(); |
| |
| if (pmadapter == MNULL) { |
| LEAVE(); |
| return; |
| } |
| |
| /* allocate buffer for mlan_ioctl_req and mlan_ds_misc_cfg */ |
| /* FYI - will be freed as part of cmd_response handler */ |
| ret = pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle, |
| sizeof(mlan_ioctl_req) + |
| sizeof(mlan_ds_misc_cfg), |
| MLAN_MEM_DEF, |
| (t_u8 **)&pioctl_req); |
| if ((ret != MLAN_STATUS_SUCCESS) || !pioctl_req) { |
| PRINTM(MERROR, "%s(): Could not allocate ioctl req\n", |
| __func__); |
| LEAVE(); |
| return; |
| } |
| pds_misc_cfg = (mlan_ds_misc_cfg *)((t_u8 *)pioctl_req + |
| sizeof(mlan_ioctl_req)); |
| |
| /* prepare mlan_ioctl_req */ |
| memset(pmadapter, pioctl_req, 0x00, sizeof(mlan_ioctl_req)); |
| pioctl_req->req_id = MLAN_IOCTL_MISC_CFG; |
| pioctl_req->action = MLAN_ACT_SET; |
| pioctl_req->bss_index = priv->bss_index; |
| pioctl_req->pbuf = (t_u8 *)pds_misc_cfg; |
| pioctl_req->buf_len = sizeof(mlan_ds_misc_cfg); |
| |
| /* prepare mlan_ds_misc_cfg */ |
| memset(pmadapter, pds_misc_cfg, 0x00, sizeof(mlan_ds_misc_cfg)); |
| pds_misc_cfg->sub_command = MLAN_OID_MISC_CUSTOM_IE; |
| pds_misc_cfg->param.cust_ie.type = TLV_TYPE_MGMT_IE; |
| pds_misc_cfg->param.cust_ie.len = (sizeof(custom_ie) - MAX_IE_SIZE); |
| |
| /* configure custom_ie api settings */ |
| pmgmt_ie = (custom_ie *)&pds_misc_cfg->param.cust_ie.ie_data_list[0]; |
| pmgmt_ie->ie_index = 0xffff; /* Auto index */ |
| pmgmt_ie->ie_length = len; |
| pmgmt_ie->mgmt_subtype_mask = MBIT(8) | MBIT(5); /* add IE for |
| BEACON | |
| PROBE_RSP */ |
| if (clearIE) |
| pmgmt_ie->mgmt_subtype_mask = 0; |
| memcpy(pmadapter, pmgmt_ie->ie_buffer, pbuf, len); |
| |
| pds_misc_cfg->param.cust_ie.len += pmgmt_ie->ie_length; |
| |
| DBG_HEXDUMP(MCMD_D, "authenticator: RSN or WPA IE", |
| (t_u8 *)pmgmt_ie, pds_misc_cfg->param.cust_ie.len); |
| |
| ret = wlan_misc_ioctl_custom_ie_list(pmadapter, pioctl_req, MFALSE); |
| |
| if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING) { |
| PRINTM(MERROR, |
| "%s(): Could not set IE for priv=%p [priv_bss_idx=%d]!\n", |
| __func__, priv, priv->bss_index); |
| /* TODO: how to handle this error case?? ignore & continue? */ |
| } |
| /* free ioctl buffer memory before we leave */ |
| pmadapter->callbacks.moal_mfree(pmadapter->pmoal_handle, |
| (t_u8 *)pioctl_req); |
| |
| } |
| |
| t_void |
| StaControlledPortOpen(t_void *pmlan_private) |
| { |
| mlan_private *priv = (mlan_private *)pmlan_private; |
| |
| PRINTM(MERROR, "StaControlledPortOpen\n"); |
| if (priv->port_ctrl_mode == MTRUE) { |
| PRINTM(MINFO, "PORT_REL: port_status = OPEN\n"); |
| priv->port_open = MTRUE; |
| } |
| priv->adapter->scan_block = MFALSE; |
| wlan_recv_event(priv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL); |
| } |
| |
| void |
| hostsa_StaSendDeauth(t_void *pmlan_private, t_u8 *addr, t_u16 reason) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| mlan_deauth_param deauth; |
| |
| ENTER(); |
| |
| memcpy(pmadapter, deauth.mac_addr, addr, MLAN_MAC_ADDR_LENGTH); |
| deauth.reason_code = reason; |
| |
| ret = wlan_prepare_cmd(pmpriv, |
| HostCmd_CMD_802_11_DEAUTHENTICATE, |
| HostCmd_ACT_GEN_SET, |
| 0, MNULL, (t_void *)&deauth); |
| if (ret == MLAN_STATUS_SUCCESS) |
| wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, |
| MNULL); |
| |
| LEAVE(); |
| } |
| |
| t_u8 |
| Hostsa_get_bss_role(t_void *pmlan_private) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| |
| return GET_BSS_ROLE(pmpriv); |
| } |
| |
| /** |
| * @brief send event to moal to notice that 4 way handshake complete |
| * |
| * @param pmlan_private A void pointer |
| * @param addr pointer to station mac address |
| * |
| * @return |
| */ |
| t_void |
| Hostsa_sendEventRsnConnect(t_void *pmlan_private, t_u8 *addr) |
| { |
| mlan_private *pmpriv = (mlan_private *)pmlan_private; |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| t_u8 *event_buf = MNULL, *pos = MNULL; |
| t_u32 event_cause = 0; |
| mlan_event *pevent = MNULL; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| |
| ENTER(); |
| |
| ret = pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle, |
| MAX_EVENT_SIZE, MLAN_MEM_DEF, |
| &event_buf); |
| if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) { |
| PRINTM(MERROR, "Could not allocate buffer for event buf\n"); |
| goto done; |
| } |
| pevent = (pmlan_event)event_buf; |
| memset(pmadapter, event_buf, 0, MAX_EVENT_SIZE); |
| |
| pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; |
| pevent->bss_index = pmpriv->bss_index; |
| event_cause = wlan_cpu_to_le32(0x51); /* MICRO_AP_EV_ID_RSN_CONNECT */ |
| memcpy(pmadapter, (t_u8 *)pevent->event_buf, |
| (t_u8 *)&event_cause, sizeof(event_cause)); |
| pos = pevent->event_buf + sizeof(event_cause) + 2; /* reserved 2 |
| byte */ |
| memcpy(pmadapter, (t_u8 *)pos, addr, MLAN_MAC_ADDR_LENGTH); |
| |
| pevent->event_len = MLAN_MAC_ADDR_LENGTH + sizeof(event_cause) + 2; |
| wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_PASSTHRU, event_buf); |
| |
| done: |
| if (event_buf) |
| pmadapter->callbacks.moal_mfree(pmadapter->pmoal_handle, |
| event_buf); |
| |
| LEAVE(); |
| } |
| |
| /** |
| * @brief This function initializes callbacks that hostsa interface uses. |
| * |
| * @param pmpriv A pointer to mlan_private structure |
| * @param putil_fns A pointer to hostsa_util_fns structure |
| * @param pmlan_fns A pointer to hostsa_mlan_fns structure |
| * |
| * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE |
| */ |
| static t_void |
| hostsa_mlan_callbacks(IN pmlan_private pmpriv, |
| IN hostsa_util_fns *putil_fns, |
| IN hostsa_mlan_fns *pmlan_fns) |
| { |
| pmlan_adapter pmadapter = pmpriv->adapter; |
| pmlan_callbacks pcb = &pmadapter->callbacks; |
| |
| putil_fns->pmoal_handle = pmadapter->pmoal_handle; |
| putil_fns->moal_malloc = pcb->moal_malloc; |
| putil_fns->moal_mfree = pcb->moal_mfree; |
| putil_fns->moal_memset = pcb->moal_memset; |
| putil_fns->moal_memcpy = pcb->moal_memcpy; |
| putil_fns->moal_memmove = pcb->moal_memmove; |
| putil_fns->moal_memcmp = pcb->moal_memcmp; |
| putil_fns->moal_udelay = pcb->moal_udelay; |
| putil_fns->moal_get_system_time = pcb->moal_get_system_time; |
| putil_fns->moal_init_timer = pcb->moal_init_timer; |
| putil_fns->moal_free_timer = pcb->moal_free_timer; |
| putil_fns->moal_start_timer = pcb->moal_start_timer; |
| putil_fns->moal_stop_timer = pcb->moal_stop_timer; |
| putil_fns->moal_init_lock = pcb->moal_init_lock; |
| putil_fns->moal_free_lock = pcb->moal_free_lock; |
| putil_fns->moal_spin_lock = pcb->moal_spin_lock; |
| putil_fns->moal_spin_unlock = pcb->moal_spin_unlock; |
| putil_fns->moal_print = pcb->moal_print; |
| putil_fns->moal_print_netintf = pcb->moal_print_netintf; |
| |
| pmlan_fns->pmlan_private = pmpriv; |
| pmlan_fns->pmlan_adapter = pmpriv->adapter; |
| pmlan_fns->bss_index = pmpriv->bss_index; |
| pmlan_fns->bss_type = pmpriv->bss_type; |
| #if 0 |
| pmlan_fns->mlan_add_buf_txqueue = mlan_add_buf_txqueue; |
| pmlan_fns->mlan_select_wmm_queue = mlan_select_wmm_queue; |
| pmlan_fns->mlan_write_data_complete = mlan_write_data_complete; |
| #endif |
| pmlan_fns->hostsa_alloc_mlan_buffer = hostsa_alloc_mlan_buffer; |
| pmlan_fns->hostsa_tx_packet = hostsa_tx_packet; |
| pmlan_fns->hostsa_set_encrypt_key = wlan_set_encrypt_key; |
| pmlan_fns->hostsa_clr_encrypt_key = wlan_clr_encrypt_key; |
| pmlan_fns->hostsa_SendDeauth = hostsa_SendDeauth; |
| pmlan_fns->Hostsa_DisAssocAllSta = ApDisAssocAllSta; |
| pmlan_fns->hostsa_free_mlan_buffer = hostsa_free_mlan_buffer; |
| pmlan_fns->Hostsa_get_station_entry = Hostsa_get_station_entry; |
| pmlan_fns->Hostsa_set_mgmt_ie = Hostsa_set_mgmt_ie; |
| pmlan_fns->Hostsa_find_connection = Hostsa_find_connection; |
| pmlan_fns->Hostsa_find_next_connection = Hostsa_find_next_connection; |
| pmlan_fns->Hostsa_StaControlledPortOpen = StaControlledPortOpen; |
| pmlan_fns->hostsa_StaSendDeauth = hostsa_StaSendDeauth; |
| pmlan_fns->Hostsa_get_bss_role = Hostsa_get_bss_role; |
| pmlan_fns->Hostsa_sendEventRsnConnect = Hostsa_sendEventRsnConnect; |
| }; |
| |
| /** |
| * @brief Init hostsa data |
| * |
| * @param pmlan_private A pointer to mlan private data structure |
| * |
| * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE |
| */ |
| mlan_status |
| hostsa_init(pmlan_private pmpriv) |
| { |
| hostsa_util_fns util_fns; |
| hostsa_mlan_fns mlan_fns; |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| |
| ENTER(); |
| |
| hostsa_mlan_callbacks(pmpriv, &util_fns, &mlan_fns); |
| ret = supplicant_authenticator_init(&pmpriv->psapriv, &util_fns, |
| &mlan_fns, pmpriv->curr_addr); |
| |
| LEAVE(); |
| return ret; |
| } |
| |
| /** |
| * @brief Cleanup hostsa data |
| * |
| * @param pmlan_private A pointer to a mlan private data structure |
| * |
| * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE |
| */ |
| mlan_status |
| hostsa_cleanup(pmlan_private pmpriv) |
| { |
| mlan_status ret = MLAN_STATUS_SUCCESS; |
| |
| ENTER(); |
| |
| supplicant_authenticator_free(pmpriv->psapriv); |
| |
| LEAVE(); |
| return ret; |
| } |