mwifiex/mxm_wifiex/wlan_src/mlan/mlan_init.c
Sherry Sun 8ffae47921 mxm_wifiex: update to mxm5x17283 release
changes:
1. WCSWREL-191: Fixed the error when loading module param from user config for SD8801
2. WCSWREL-186: Fixed the issue of mlanutl failing on kernel higher than L5.15
3. Fixed low throughput issue for WPA3 SAE
4. Added driver change for WLAN throughput improvement on 8997 SoC
5. Updated README to recommend not to use WEP/TKIP for all chipsets
6. WCSWREL-180: Fix P2P test fail on kernel higher than L5.12
7. WCSWREL-156: kernel_write/kernel_read not allowed by drivers for L5.10 kernel GKI buildou
8. Alternative for pm_qos_add_request/pm_qos_remove_request

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Approved-by: Tian Yang <yang.tian@nxp.com>
2021-10-12 12:16:50 +08:00

2050 lines
59 KiB
C

/** @file mlan_init.c
*
* @brief This file contains the initialization for FW
* and HW.
*
*
* Copyright 2008-2021 NXP
*
* This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991
* (the License). You may use, redistribute and/or modify the 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:
10/13/2008: initial version
********************************************************/
#include "mlan.h"
#ifdef STA_SUPPORT
#include "mlan_join.h"
#endif
#include "mlan_util.h"
#include "mlan_fw.h"
#include "mlan_main.h"
#include "mlan_init.h"
#include "mlan_wmm.h"
#include "mlan_11n.h"
#include "mlan_11ac.h"
#include "mlan_11h.h"
#include "mlan_meas.h"
#ifdef SDIO
#include "mlan_sdio.h"
#endif
#ifdef PCIE
#include "mlan_pcie.h"
#endif /* PCIE */
#if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
#include "hostsa_init.h"
#endif
#include "mlan_11ax.h"
/********************************************************
Global Variables
********************************************************/
/*******************************************************
Local Functions
********************************************************/
/**
* @brief This function adds a BSS priority table
*
* @param priv A pointer to mlan_private structure
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
static mlan_status wlan_add_bsspriotbl(pmlan_private priv)
{
pmlan_adapter pmadapter = priv->adapter;
mlan_bssprio_node *pbssprio = MNULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
status = pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle,
sizeof(mlan_bssprio_node),
MLAN_MEM_DEF,
(t_u8 **)&pbssprio);
if (status) {
PRINTM(MERROR, "Failed to allocate bsspriotbl\n");
LEAVE();
return status;
}
pbssprio->priv = priv;
util_init_list((pmlan_linked_list)pbssprio);
if (!pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur)
pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
pbssprio;
util_enqueue_list_tail(
pmadapter->pmoal_handle,
&pmadapter->bssprio_tbl[priv->bss_priority].bssprio_head,
(pmlan_linked_list)pbssprio,
pmadapter->callbacks.moal_spin_lock,
pmadapter->callbacks.moal_spin_unlock);
LEAVE();
return status;
}
/**
* @brief This function deletes the BSS priority table
*
* @param priv A pointer to mlan_private structure
*
* @return N/A
*/
static t_void wlan_delete_bsspriotbl(pmlan_private priv)
{
int i;
pmlan_adapter pmadapter = priv->adapter;
mlan_bssprio_node *pbssprio_node = MNULL, *ptmp_node = MNULL,
**ppcur = MNULL;
pmlan_list_head phead;
ENTER();
for (i = 0; i < pmadapter->priv_num; ++i) {
phead = &pmadapter->bssprio_tbl[i].bssprio_head;
ppcur = &pmadapter->bssprio_tbl[i].bssprio_cur;
PRINTM(MINFO,
"Delete BSS priority table, index = %d, i = %d, phead = %p, pcur = %p\n",
priv->bss_index, i, phead, *ppcur);
if (*ppcur) {
pbssprio_node = (mlan_bssprio_node *)util_peek_list(
pmadapter->pmoal_handle, phead,
pmadapter->callbacks.moal_spin_lock,
pmadapter->callbacks.moal_spin_unlock);
while (pbssprio_node &&
((pmlan_list_head)pbssprio_node != phead)) {
ptmp_node = pbssprio_node->pnext;
if (pbssprio_node->priv == priv) {
PRINTM(MINFO,
"Delete node, pnode = %p, pnext = %p\n",
pbssprio_node, ptmp_node);
util_unlink_list(
pmadapter->pmoal_handle, phead,
(pmlan_linked_list)pbssprio_node,
pmadapter->callbacks
.moal_spin_lock,
pmadapter->callbacks
.moal_spin_unlock);
pmadapter->callbacks.moal_mfree(
pmadapter->pmoal_handle,
(t_u8 *)pbssprio_node);
}
pbssprio_node = ptmp_node;
}
*ppcur = (mlan_bssprio_node *)phead;
}
}
LEAVE();
}
/**
* @brief The function handles VDLL init
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS
*
*/
static mlan_status vdll_init(pmlan_adapter pmadapter)
{
mlan_status status = MLAN_STATUS_SUCCESS;
vdll_dnld_ctrl *ctrl = &pmadapter->vdll_ctrl;
ENTER();
memset(pmadapter, ctrl, 0, sizeof(vdll_dnld_ctrl));
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type)) {
ctrl->cmd_buf =
wlan_alloc_mlan_buffer(pmadapter,
MRVDRV_SIZE_OF_CMD_BUFFER, 0,
MOAL_MALLOC_BUFFER);
if (!ctrl->cmd_buf) {
PRINTM(MERROR,
"vdll init: fail to alloc command buffer");
status = MLAN_STATUS_FAILURE;
}
}
#endif
LEAVE();
return status;
}
/**
* @brief The function handles VDLL deinit
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS
*
*/
static t_void vdll_deinit(pmlan_adapter pmadapter)
{
pmlan_callbacks pcb = &pmadapter->callbacks;
ENTER();
if (pmadapter->vdll_ctrl.vdll_mem != MNULL) {
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->vdll_ctrl.vdll_mem);
else
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->vdll_ctrl.vdll_mem);
pmadapter->vdll_ctrl.vdll_mem = MNULL;
pmadapter->vdll_ctrl.vdll_len = 0;
}
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type) &&
pmadapter->vdll_ctrl.cmd_buf != MNULL) {
wlan_free_mlan_buffer(pmadapter, pmadapter->vdll_ctrl.cmd_buf);
pmadapter->vdll_ctrl.cmd_buf = MNULL;
}
#endif
LEAVE();
}
/********************************************************
Global Functions
********************************************************/
/**
* @brief This function allocates buffer for the members of adapter
* structure like command buffer and BSSID list.
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_allocate_adapter(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
#ifdef STA_SUPPORT
t_u32 beacon_buffer_size;
t_u32 buf_size;
BSSDescriptor_t *ptemp_scan_table = MNULL;
t_u8 chan_2g[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
t_u8 chan_5g[] = {12, 16, 34, 38, 42, 46, 36, 40, 44, 48, 52,
56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140, 144, 149, 153, 157, 161, 165};
#endif
#ifdef SDIO
t_u32 max_mp_regs = 0;
t_u32 mp_tx_aggr_buf_size = 0;
t_u32 mp_rx_aggr_buf_size = 0;
#endif
ENTER();
#ifdef SDIO
if (IS_SD(pmadapter->card_type)) {
max_mp_regs = pmadapter->pcard_sd->reg->max_mp_regs;
mp_tx_aggr_buf_size = pmadapter->pcard_sd->mp_tx_aggr_buf_size;
mp_rx_aggr_buf_size = pmadapter->pcard_sd->mp_rx_aggr_buf_size;
}
#endif
#ifdef STA_SUPPORT
/* Allocate buffer to store the BSSID list */
buf_size = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
if (pmadapter->callbacks.moal_vmalloc &&
pmadapter->callbacks.moal_vfree)
ret = pmadapter->callbacks.moal_vmalloc(
pmadapter->pmoal_handle, buf_size,
(t_u8 **)&ptemp_scan_table);
else
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle, buf_size, MLAN_MEM_DEF,
(t_u8 **)&ptemp_scan_table);
if (ret != MLAN_STATUS_SUCCESS || !ptemp_scan_table) {
PRINTM(MERROR, "Failed to allocate scan table\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
pmadapter->pscan_table = ptemp_scan_table;
if (pmadapter->fixed_beacon_buffer)
beacon_buffer_size = MAX_SCAN_BEACON_BUFFER;
else
beacon_buffer_size = DEFAULT_SCAN_BEACON_BUFFER;
if (pmadapter->callbacks.moal_vmalloc &&
pmadapter->callbacks.moal_vfree)
ret = pmadapter->callbacks.moal_vmalloc(
pmadapter->pmoal_handle, beacon_buffer_size,
(t_u8 **)&pmadapter->bcn_buf);
else
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle, beacon_buffer_size,
MLAN_MEM_DEF, (t_u8 **)&pmadapter->bcn_buf);
if (ret != MLAN_STATUS_SUCCESS || !pmadapter->bcn_buf) {
PRINTM(MERROR, "Failed to allocate bcn buf\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
pmadapter->bcn_buf_size = beacon_buffer_size;
pmadapter->num_in_chan_stats = sizeof(chan_2g);
pmadapter->num_in_chan_stats += sizeof(chan_5g);
buf_size = sizeof(ChanStatistics_t) * pmadapter->num_in_chan_stats;
if (pmadapter->callbacks.moal_vmalloc &&
pmadapter->callbacks.moal_vfree)
ret = pmadapter->callbacks.moal_vmalloc(
pmadapter->pmoal_handle, buf_size,
(t_u8 **)&pmadapter->pchan_stats);
else
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle, buf_size, MLAN_MEM_DEF,
(t_u8 **)&pmadapter->pchan_stats);
if (ret != MLAN_STATUS_SUCCESS || !pmadapter->pchan_stats) {
PRINTM(MERROR, "Failed to allocate channel statistics\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
#endif
/* Allocate command buffer */
ret = wlan_alloc_cmd_buffer(pmadapter);
if (ret != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to allocate command buffer\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
#ifdef SDIO
if (IS_SD(pmadapter->card_type)) {
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle, max_mp_regs + DMA_ALIGNMENT,
MLAN_MEM_DEF | MLAN_MEM_DMA,
(t_u8 **)&pmadapter->pcard_sd->mp_regs_buf);
if (ret != MLAN_STATUS_SUCCESS ||
!pmadapter->pcard_sd->mp_regs_buf) {
PRINTM(MERROR, "Failed to allocate mp_regs_buf\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
pmadapter->pcard_sd->mp_regs = (t_u8 *)ALIGN_ADDR(
pmadapter->pcard_sd->mp_regs_buf, DMA_ALIGNMENT);
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle, MAX_SUPPORT_AMSDU_SIZE,
MLAN_MEM_DEF | MLAN_MEM_DMA,
(t_u8 **)&pmadapter->pcard_sd->rx_buffer);
if (ret != MLAN_STATUS_SUCCESS ||
!pmadapter->pcard_sd->rx_buffer) {
PRINTM(MERROR, "Failed to allocate receive buffer\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
pmadapter->pcard_sd->rx_buf = (t_u8 *)ALIGN_ADDR(
pmadapter->pcard_sd->rx_buffer, DMA_ALIGNMENT);
pmadapter->pcard_sd->max_sp_tx_size = MAX_SUPPORT_AMSDU_SIZE;
pmadapter->pcard_sd->max_sp_rx_size = MAX_SUPPORT_AMSDU_SIZE;
ret = wlan_alloc_sdio_mpa_buffers(
pmadapter, mp_tx_aggr_buf_size, mp_rx_aggr_buf_size);
if (ret != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR,
"Failed to allocate sdio mp-a buffers\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
#ifdef DEBUG_LEVEL1
if (mlan_drvdbg & MMPA_D) {
pmadapter->pcard_sd->mpa_buf_size =
SDIO_MP_DBG_NUM *
pmadapter->pcard_sd->mp_aggr_pkt_limit *
MLAN_SDIO_BLOCK_SIZE;
if (pmadapter->callbacks.moal_vmalloc &&
pmadapter->callbacks.moal_vfree)
ret = pmadapter->callbacks.moal_vmalloc(
pmadapter->pmoal_handle,
pmadapter->pcard_sd->mpa_buf_size,
(t_u8 **)&pmadapter->pcard_sd->mpa_buf);
else
ret = pmadapter->callbacks.moal_malloc(
pmadapter->pmoal_handle,
pmadapter->pcard_sd->mpa_buf_size,
MLAN_MEM_DEF,
(t_u8 **)&pmadapter->pcard_sd->mpa_buf);
if (ret != MLAN_STATUS_SUCCESS ||
!pmadapter->pcard_sd->mpa_buf) {
PRINTM(MERROR, "Failed to allocate mpa buf\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
}
#endif
}
#endif
pmadapter->psleep_cfm =
wlan_alloc_mlan_buffer(pmadapter,
sizeof(opt_sleep_confirm_buffer), 0,
MOAL_MALLOC_BUFFER);
#ifdef PCIE
/* Initialize PCIE ring buffer */
if (IS_PCIE(pmadapter->card_type)) {
ret = wlan_alloc_pcie_ring_buf(pmadapter);
if (MLAN_STATUS_SUCCESS != ret) {
PRINTM(MERROR,
"Failed to allocate PCIE host buffers\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
}
#endif /* PCIE */
vdll_init(pmadapter);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function initializes the private structure
* and sets default values to the members of mlan_private.
*
* @param priv A pointer to mlan_private structure
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_init_priv(pmlan_private priv)
{
t_u32 i;
pmlan_adapter pmadapter = priv->adapter;
mlan_status ret = MLAN_STATUS_SUCCESS;
#ifdef USB
pusb_tx_aggr_params pusb_tx_aggr = MNULL;
#endif
ENTER();
priv->media_connected = MFALSE;
memset(pmadapter, priv->curr_addr, 0xff, MLAN_MAC_ADDR_LENGTH);
#ifdef STA_SUPPORT
priv->pkt_tx_ctrl = 0;
priv->bss_mode = MLAN_BSS_MODE_INFRA;
priv->data_rate = 0; /* Initially indicate the rate as auto */
priv->is_data_rate_auto = MTRUE;
priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
priv->sec_info.wep_status = Wlan802_11WEPDisabled;
priv->sec_info.authentication_mode = MLAN_AUTH_MODE_AUTO;
priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE;
for (i = 0; i < MRVL_NUM_WEP_KEY; i++)
memset(pmadapter, &priv->wep_key[i], 0, sizeof(mrvl_wep_key_t));
priv->wep_key_curr_index = 0;
priv->ewpa_query = MFALSE;
priv->curr_pkt_filter = HostCmd_ACT_MAC_STATIC_DYNAMIC_BW_ENABLE |
HostCmd_ACT_MAC_RTS_CTS_ENABLE |
HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
HostCmd_ACT_MAC_ETHERNETII_ENABLE;
priv->beacon_period = MLAN_BEACON_INTERVAL;
priv->pattempted_bss_desc = MNULL;
memset(pmadapter, &priv->gtk_rekey, 0,
sizeof(mlan_ds_misc_gtk_rekey_data));
memset(pmadapter, &priv->curr_bss_params, 0,
sizeof(priv->curr_bss_params));
priv->listen_interval = MLAN_DEFAULT_LISTEN_INTERVAL;
memset(pmadapter, &priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
priv->assoc_rsp_size = 0;
wlan_11d_priv_init(priv);
wlan_11h_priv_init(priv);
#ifdef UAP_SUPPORT
priv->is_11n_enabled = MFALSE;
priv->is_11ac_enabled = MFALSE;
priv->is_11ax_enabled = MFALSE;
priv->uap_bss_started = MFALSE;
priv->uap_host_based = MFALSE;
memset(pmadapter, &priv->uap_state_chan_cb, 0,
sizeof(priv->uap_state_chan_cb));
#endif
#ifdef UAP_SUPPORT
priv->num_drop_pkts = 0;
#endif
#if defined(STA_SUPPORT)
priv->adhoc_state_prev = ADHOC_IDLE;
memset(pmadapter, &priv->adhoc_last_start_ssid, 0,
sizeof(priv->adhoc_last_start_ssid));
#endif
priv->atim_window = 0;
priv->adhoc_state = ADHOC_IDLE;
priv->tx_power_level = 0;
priv->max_tx_power_level = 0;
priv->min_tx_power_level = 0;
priv->tx_rate = 0;
priv->rxpd_rate_info = 0;
priv->rx_pkt_info = MFALSE;
/* refer to V15 CMD_TX_RATE_QUERY */
priv->rxpd_vhtinfo = 0;
priv->rxpd_rate = 0;
priv->data_rssi_last = 0;
priv->data_rssi_avg = 0;
priv->data_nf_avg = 0;
priv->data_nf_last = 0;
priv->bcn_rssi_last = 0;
priv->bcn_rssi_avg = 0;
priv->bcn_nf_avg = 0;
priv->bcn_nf_last = 0;
priv->sec_info.ewpa_enabled = MFALSE;
priv->sec_info.wpa_enabled = MFALSE;
priv->sec_info.wpa2_enabled = MFALSE;
memset(pmadapter, &priv->wpa_ie, 0, sizeof(priv->wpa_ie));
memset(pmadapter, &priv->aes_key, 0, sizeof(priv->aes_key));
priv->wpa_ie_len = 0;
priv->wpa_is_gtk_set = MFALSE;
#if defined(STA_SUPPORT)
priv->pmfcfg.mfpc = 0;
priv->pmfcfg.mfpr = 0;
memset(pmadapter, &priv->pmfcfg, 0, sizeof(priv->pmfcfg));
#endif
priv->sec_info.wapi_enabled = MFALSE;
priv->wapi_ie_len = 0;
priv->sec_info.wapi_key_on = MFALSE;
priv->osen_ie_len = 0;
memset(pmadapter, &priv->osen_ie, 0, sizeof(priv->osen_ie));
memset(pmadapter, &priv->wps, 0, sizeof(priv->wps));
memset(pmadapter, &priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
priv->gen_ie_buf_len = 0;
#endif /* STA_SUPPORT */
priv->wmm_required = MTRUE;
priv->wmm_enabled = MFALSE;
priv->disconnect_reason_code = 0;
priv->wmm_qosinfo = 0;
priv->saved_wmm_qosinfo = 0;
priv->host_tdls_cs_support = MTRUE;
priv->host_tdls_uapsd_support = MTRUE;
priv->tdls_cs_channel = 0;
priv->supp_regulatory_class_len = 0;
priv->chan_supp_len = 0;
memset(pmadapter, &priv->chan_supp, 0, sizeof(priv->chan_supp));
memset(pmadapter, &priv->supp_regulatory_class, 0,
sizeof(priv->supp_regulatory_class));
priv->tdls_idle_time = TDLS_IDLE_TIMEOUT;
priv->txaggrctrl = MTRUE;
for (i = 0; i < MAX_MGMT_IE_INDEX; i++)
memset(pmadapter, &priv->mgmt_ie[i], 0, sizeof(custom_ie));
priv->mgmt_frame_passthru_mask = 0;
#ifdef STA_SUPPORT
priv->pcurr_bcn_buf = MNULL;
priv->curr_bcn_size = 0;
memset(pmadapter, &priv->ext_cap, 0, sizeof(priv->ext_cap));
SET_EXTCAP_OPERMODENTF(priv->ext_cap);
SET_EXTCAP_TDLS(priv->ext_cap);
SET_EXTCAP_QOS_MAP(priv->ext_cap);
/* Save default Extended Capability */
memcpy_ext(priv->adapter, &priv->def_ext_cap, &priv->ext_cap,
sizeof(priv->ext_cap), sizeof(priv->def_ext_cap));
#endif /* STA_SUPPORT */
priv->amsdu_rx_cnt = 0;
priv->msdu_in_rx_amsdu_cnt = 0;
priv->amsdu_tx_cnt = 0;
priv->msdu_in_tx_amsdu_cnt = 0;
for (i = 0; i < MAX_NUM_TID; i++)
priv->addba_reject[i] = ADDBA_RSP_STATUS_ACCEPT;
priv->addba_reject[6] = ADDBA_RSP_STATUS_REJECT;
priv->addba_reject[7] = ADDBA_RSP_STATUS_REJECT;
memcpy_ext(priv->adapter, priv->ibss_addba_reject, priv->addba_reject,
sizeof(priv->addba_reject), sizeof(priv->ibss_addba_reject));
priv->max_amsdu = 0;
#ifdef STA_SUPPORT
if (priv->bss_type == MLAN_BSS_TYPE_STA) {
priv->add_ba_param.tx_win_size = MLAN_STA_AMPDU_DEF_TXWINSIZE;
priv->add_ba_param.rx_win_size = MLAN_STA_AMPDU_DEF_RXWINSIZE;
}
#endif
#ifdef WIFI_DIRECT_SUPPORT
if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
priv->add_ba_param.tx_win_size = MLAN_WFD_AMPDU_DEF_TXRXWINSIZE;
priv->add_ba_param.rx_win_size = MLAN_WFD_AMPDU_DEF_TXRXWINSIZE;
}
#endif
#ifdef UAP_SUPPORT
if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
priv->add_ba_param.tx_win_size = MLAN_UAP_AMPDU_DEF_TXWINSIZE;
priv->add_ba_param.rx_win_size = MLAN_UAP_AMPDU_DEF_RXWINSIZE;
priv->aggr_prio_tbl[6].ampdu_user =
priv->aggr_prio_tbl[7].ampdu_user =
BA_STREAM_NOT_ALLOWED;
}
#endif
priv->user_rxwinsize = priv->add_ba_param.rx_win_size;
memset(pmadapter, priv->rx_seq, 0, sizeof(priv->rx_seq));
priv->port_ctrl_mode = MTRUE;
priv->port_open = MFALSE;
priv->prior_port_status = MFALSE;
priv->tx_pause = MFALSE;
priv->hotspot_cfg = 0;
priv->intf_hr_len = pmadapter->ops.intf_header_len;
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
pusb_tx_aggr =
wlan_get_usb_tx_aggr_params(pmadapter, priv->port);
if (pusb_tx_aggr && pusb_tx_aggr->aggr_ctrl.aggr_mode ==
MLAN_USB_AGGR_MODE_LEN_V2) {
priv->intf_hr_len = MLAN_USB_TX_AGGR_HEADER;
}
priv->port = pmadapter->tx_data_ep;
}
#endif
ret = wlan_add_bsspriotbl(priv);
#if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
hostsa_init(priv);
#endif
LEAVE();
return ret;
}
/**
* @brief This function initializes the adapter structure
* and sets default values to the members of adapter.
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return N/A
*/
t_void wlan_init_adapter(pmlan_adapter pmadapter)
{
opt_sleep_confirm_buffer *sleep_cfm_buf = MNULL;
#ifdef USB
t_s32 i = 0;
#endif
ENTER();
if (pmadapter->psleep_cfm) {
sleep_cfm_buf = (opt_sleep_confirm_buffer
*)(pmadapter->psleep_cfm->pbuf +
pmadapter->psleep_cfm->data_offset);
}
#ifdef MFG_CMD_SUPPORT
if (pmadapter->init_para.mfg_mode == MLAN_INIT_PARA_DISABLED)
pmadapter->mfg_mode = MFALSE;
else
pmadapter->mfg_mode = pmadapter->init_para.mfg_mode;
#endif
#ifdef STA_SUPPORT
pmadapter->pwarm_reset_ioctl_req = MNULL;
#endif
pmadapter->pscan_ioctl_req = MNULL;
pmadapter->cmd_sent = MFALSE;
pmadapter->mlan_processing = MFALSE;
pmadapter->main_process_cnt = 0;
pmadapter->mlan_rx_processing = MFALSE;
pmadapter->more_rx_task_flag = MFALSE;
pmadapter->more_task_flag = MFALSE;
pmadapter->delay_task_flag = MFALSE;
pmadapter->data_sent = MFALSE;
pmadapter->data_sent_cnt = 0;
#ifdef SDIO
if (IS_SD(pmadapter->card_type)) {
pmadapter->pcard_sd->int_mode = pmadapter->init_para.int_mode;
pmadapter->pcard_sd->gpio_pin = pmadapter->init_para.gpio_pin;
pmadapter->data_sent = MTRUE;
pmadapter->pcard_sd->mp_rd_bitmap = 0;
pmadapter->pcard_sd->mp_wr_bitmap = 0;
pmadapter->pcard_sd->curr_rd_port =
pmadapter->pcard_sd->reg->start_rd_port;
pmadapter->pcard_sd->curr_wr_port =
pmadapter->pcard_sd->reg->start_wr_port;
pmadapter->pcard_sd->mp_data_port_mask =
pmadapter->pcard_sd->reg->data_port_mask;
pmadapter->pcard_sd->mp_invalid_update = 0;
memset(pmadapter, pmadapter->pcard_sd->mp_update, 0,
sizeof(pmadapter->pcard_sd->mp_update));
pmadapter->pcard_sd->mpa_tx.buf_len = 0;
pmadapter->pcard_sd->mpa_tx.pkt_cnt = 0;
pmadapter->pcard_sd->mpa_tx.start_port =
pmadapter->pcard_sd->reg->start_wr_port;
if (!pmadapter->init_para.mpa_tx_cfg)
pmadapter->pcard_sd->mpa_tx.enabled = MFALSE;
else if (pmadapter->init_para.mpa_tx_cfg ==
MLAN_INIT_PARA_DISABLED)
pmadapter->pcard_sd->mpa_tx.enabled = MFALSE;
else
pmadapter->pcard_sd->mpa_tx.enabled = MTRUE;
pmadapter->pcard_sd->mpa_tx.pkt_aggr_limit =
pmadapter->pcard_sd->mp_aggr_pkt_limit;
pmadapter->pcard_sd->mpa_rx.buf_len = 0;
pmadapter->pcard_sd->mpa_rx.pkt_cnt = 0;
pmadapter->pcard_sd->mpa_rx.start_port =
pmadapter->pcard_sd->reg->start_rd_port;
if (!pmadapter->init_para.mpa_rx_cfg)
pmadapter->pcard_sd->mpa_rx.enabled = MFALSE;
else if (pmadapter->init_para.mpa_rx_cfg ==
MLAN_INIT_PARA_DISABLED)
pmadapter->pcard_sd->mpa_rx.enabled = MFALSE;
else
pmadapter->pcard_sd->mpa_rx.enabled = MTRUE;
pmadapter->pcard_sd->mpa_rx.pkt_aggr_limit =
pmadapter->pcard_sd->mp_aggr_pkt_limit;
}
#endif
pmadapter->rx_pkts_queued = 0;
pmadapter->cmd_resp_received = MFALSE;
pmadapter->event_received = MFALSE;
pmadapter->data_received = MFALSE;
pmadapter->seq_num = 0;
pmadapter->num_cmd_timeout = 0;
pmadapter->last_init_cmd = 0;
pmadapter->pending_ioctl = MFALSE;
pmadapter->scan_processing = MFALSE;
pmadapter->cmd_timer_is_set = MFALSE;
pmadapter->dnld_cmd_in_secs = 0;
/* PnP and power profile */
pmadapter->surprise_removed = MFALSE;
/* FW hang report */
pmadapter->fw_hang_report = MFALSE;
pmadapter->ecsa_enable = MFALSE;
pmadapter->getlog_enable = MFALSE;
if (!pmadapter->init_para.ps_mode) {
pmadapter->ps_mode = DEFAULT_PS_MODE;
} else if (pmadapter->init_para.ps_mode == MLAN_INIT_PARA_DISABLED)
pmadapter->ps_mode = Wlan802_11PowerModeCAM;
else
pmadapter->ps_mode = Wlan802_11PowerModePSP;
pmadapter->ps_state = PS_STATE_AWAKE;
pmadapter->need_to_wakeup = MFALSE;
#ifdef STA_SUPPORT
pmadapter->scan_block = MFALSE;
/* Scan type */
pmadapter->scan_type = MLAN_SCAN_TYPE_ACTIVE;
/* Scan mode */
pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
/* Scan time */
pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
if (!pmadapter->init_para.passive_to_active_scan)
pmadapter->passive_to_active_scan = MLAN_PASS_TO_ACT_SCAN_EN;
else if (pmadapter->init_para.passive_to_active_scan ==
MLAN_INIT_PARA_DISABLED)
pmadapter->passive_to_active_scan = MLAN_PASS_TO_ACT_SCAN_DIS;
else
pmadapter->passive_to_active_scan = MLAN_PASS_TO_ACT_SCAN_EN;
pmadapter->scan_chan_gap = 0;
pmadapter->num_in_scan_table = 0;
memset(pmadapter, pmadapter->pscan_table, 0,
(sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST));
pmadapter->active_scan_triggered = MFALSE;
if (!pmadapter->init_para.ext_scan)
pmadapter->ext_scan = EXT_SCAN_TYPE_ENH;
else if (pmadapter->init_para.ext_scan == EXT_SCAN_TYPE_ENH)
pmadapter->ext_scan = EXT_SCAN_TYPE_ENH;
else
pmadapter->ext_scan = MTRUE;
pmadapter->ext_scan_enh = MFALSE;
pmadapter->ext_scan_timeout = MFALSE;
pmadapter->scan_probes = DEFAULT_PROBES;
memset(pmadapter, pmadapter->bcn_buf, 0, pmadapter->bcn_buf_size);
pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
pmadapter->radio_on = RADIO_ON;
if (!pmadapter->multiple_dtim)
pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
pmadapter->local_listen_interval = 0; /* default value in firmware will
be used */
#endif /* STA_SUPPORT */
pmadapter->is_deep_sleep = MFALSE;
pmadapter->idle_time = DEEP_SLEEP_IDLE_TIME;
if (!pmadapter->init_para.auto_ds)
pmadapter->init_auto_ds = DEFAULT_AUTO_DS_MODE;
else if (pmadapter->init_para.auto_ds == MLAN_INIT_PARA_DISABLED)
pmadapter->init_auto_ds = MFALSE;
else
pmadapter->init_auto_ds = MTRUE;
pmadapter->delay_null_pkt = MFALSE;
pmadapter->delay_to_ps = DELAY_TO_PS_DEFAULT;
pmadapter->enhanced_ps_mode = PS_MODE_AUTO;
pmadapter->gen_null_pkt = MFALSE; /* Disable NULL Pkt generation-default
*/
pmadapter->pps_uapsd_mode = MFALSE; /* Disable pps/uapsd mode -default
*/
pmadapter->pm_wakeup_card_req = MFALSE;
pmadapter->pm_wakeup_timeout = 0;
pmadapter->pm_wakeup_fw_try = MFALSE;
if (!pmadapter->init_para.max_tx_buf)
pmadapter->max_tx_buf_size =
pmadapter->pcard_info->max_tx_buf_size;
else
pmadapter->max_tx_buf_size =
(t_u16)pmadapter->init_para.max_tx_buf;
pmadapter->tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
pmadapter->curr_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.enable =
MFALSE;
pmadapter->pcard_usb->usb_tx_aggr[i]
.aggr_ctrl.aggr_mode =
MLAN_USB_AGGR_MODE_LEN_V2;
pmadapter->pcard_usb->usb_tx_aggr[i]
.aggr_ctrl.aggr_align =
MLAN_USB_TX_AGGR_V2_ALIGN;
pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.aggr_max =
MLAN_USB_TX_AGGR_MAX_LEN;
pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.aggr_tmo =
MLAN_USB_TX_AGGR_TIMEOUT_MSEC * 1000;
pmadapter->pcard_usb->usb_tx_aggr[i].pmbuf_aggr = MNULL;
pmadapter->pcard_usb->usb_tx_aggr[i].aggr_len = 0;
pmadapter->pcard_usb->usb_tx_aggr[i].hold_timeout_msec =
MLAN_USB_TX_AGGR_TIMEOUT_MSEC;
pmadapter->pcard_usb->usb_tx_aggr[i].port =
pmadapter->tx_data_ep;
pmadapter->pcard_usb->usb_tx_aggr[i].phandle =
(t_void *)pmadapter;
}
pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.enable = MFALSE;
pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.aggr_mode =
MLAN_USB_AGGR_MODE_NUM;
pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.aggr_align =
MLAN_USB_RX_ALIGN_SIZE;
pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.aggr_max =
MLAN_USB_RX_MAX_AGGR_NUM;
pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.aggr_tmo =
MLAN_USB_RX_DEAGGR_TIMEOUT_USEC;
pmadapter->pcard_usb->fw_usb_aggr = MTRUE;
}
#endif
pmadapter->is_hs_configured = MFALSE;
pmadapter->hs_cfg.conditions = HOST_SLEEP_DEF_COND;
pmadapter->hs_cfg.gpio = HOST_SLEEP_DEF_GPIO;
pmadapter->hs_cfg.gap = HOST_SLEEP_DEF_GAP;
pmadapter->hs_activated = MFALSE;
pmadapter->min_wake_holdoff = HOST_SLEEP_DEF_WAKE_HOLDOFF;
pmadapter->hs_inactivity_timeout = HOST_SLEEP_DEF_INACTIVITY_TIMEOUT;
memset(pmadapter, pmadapter->event_body, 0,
sizeof(pmadapter->event_body));
pmadapter->hw_dot_11n_dev_cap = 0;
pmadapter->hw_dev_mcs_support = 0;
pmadapter->coex_rx_winsize = 1;
#ifdef STA_SUPPORT
pmadapter->chan_bandwidth = 0;
pmadapter->tdls_status = TDLS_NOT_SETUP;
#endif /* STA_SUPPORT */
pmadapter->min_ba_threshold = MIN_BA_THRESHOLD;
pmadapter->hw_dot_11ac_dev_cap = 0;
pmadapter->hw_dot_11ac_mcs_support = 0;
pmadapter->max_sta_conn = 0;
/* Initialize 802.11d */
wlan_11d_init(pmadapter);
wlan_11h_init(pmadapter);
wlan_wmm_init(pmadapter);
wlan_init_wmm_param(pmadapter);
pmadapter->bypass_pkt_count = 0;
if (pmadapter->psleep_cfm) {
pmadapter->psleep_cfm->buf_type = MLAN_BUF_TYPE_CMD;
pmadapter->psleep_cfm->data_len = sizeof(OPT_Confirm_Sleep);
memset(pmadapter, &sleep_cfm_buf->ps_cfm_sleep, 0,
sizeof(OPT_Confirm_Sleep));
sleep_cfm_buf->ps_cfm_sleep.command =
wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
sleep_cfm_buf->ps_cfm_sleep.size =
wlan_cpu_to_le16(sizeof(OPT_Confirm_Sleep));
sleep_cfm_buf->ps_cfm_sleep.result = 0;
sleep_cfm_buf->ps_cfm_sleep.action =
wlan_cpu_to_le16(SLEEP_CONFIRM);
sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl =
wlan_cpu_to_le16(RESP_NEEDED);
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
sleep_cfm_buf->hdr =
wlan_cpu_to_le32(MLAN_USB_TYPE_CMD);
pmadapter->psleep_cfm->data_len += MLAN_TYPE_LEN;
}
#endif
}
memset(pmadapter, &pmadapter->sleep_params, 0,
sizeof(pmadapter->sleep_params));
memset(pmadapter, &pmadapter->sleep_period, 0,
sizeof(pmadapter->sleep_period));
memset(pmadapter, &pmadapter->saved_sleep_period, 0,
sizeof(pmadapter->saved_sleep_period));
pmadapter->tx_lock_flag = MFALSE;
pmadapter->rx_lock_flag = MFALSE;
pmadapter->main_lock_flag = MFALSE;
pmadapter->null_pkt_interval = 0;
pmadapter->fw_bands = 0;
pmadapter->config_bands = 0;
pmadapter->adhoc_start_band = 0;
pmadapter->pscan_channels = MNULL;
pmadapter->fw_release_number = 0;
pmadapter->fw_cap_info = 0;
memset(pmadapter, &pmadapter->upld_buf, 0, sizeof(pmadapter->upld_buf));
pmadapter->upld_len = 0;
pmadapter->event_cause = 0;
pmadapter->pmlan_buffer_event = MNULL;
memset(pmadapter, &pmadapter->region_channel, 0,
sizeof(pmadapter->region_channel));
pmadapter->region_code = 0;
memcpy_ext(pmadapter, pmadapter->country_code,
MRVDRV_DEFAULT_COUNTRY_CODE, COUNTRY_CODE_LEN,
COUNTRY_CODE_LEN);
pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
#ifdef STA_SUPPORT
memset(pmadapter, &pmadapter->arp_filter, 0,
sizeof(pmadapter->arp_filter));
pmadapter->arp_filter_size = 0;
#endif /* STA_SUPPORT */
#ifdef PCIE
if (IS_PCIE(pmadapter->card_type)) {
pmadapter->pcard_pcie->txbd_wrptr = 0;
pmadapter->pcard_pcie->txbd_rdptr = 0;
pmadapter->pcard_pcie->rxbd_rdptr = 0;
pmadapter->pcard_pcie->evtbd_rdptr = 0;
#if defined(PCIE8997) || defined(PCIE8897)
if (!pmadapter->pcard_pcie->reg->use_adma) {
pmadapter->pcard_pcie->rxbd_wrptr =
pmadapter->pcard_pcie->reg
->txrx_rw_ptr_rollover_ind;
pmadapter->pcard_pcie->evtbd_wrptr =
EVT_RW_PTR_ROLLOVER_IND;
}
#endif
#if defined(PCIE9098) || defined(PCIE9097)
if (pmadapter->pcard_pcie->reg->use_adma) {
pmadapter->pcard_pcie->rxbd_wrptr =
pmadapter->pcard_pcie->txrx_bd_size;
pmadapter->pcard_pcie->evtbd_wrptr = MLAN_MAX_EVT_BD;
}
#endif
}
#endif
LEAVE();
return;
}
/**
* @brief This function intializes the lock variables and
* the list heads for interface
*
* @param pmadapter A pointer to a mlan_adapter structure
* @param start_index start index of mlan private
*
* @return MLAN_STATUS_SUCCESS -- on success,
* otherwise MLAN_STATUS_FAILURE
*
*/
mlan_status wlan_init_priv_lock_list(pmlan_adapter pmadapter, t_u8 start_index)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private priv = MNULL;
pmlan_callbacks pcb = &pmadapter->callbacks;
t_s32 i = 0;
t_u32 j = 0;
for (i = start_index; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
priv = pmadapter->priv[i];
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&priv->rx_pkt_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&priv->wmm.ra_list_spinlock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
#ifdef STA_SUPPORT
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&priv->curr_bcn_buf_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
#endif
}
}
for (i = start_index; i < pmadapter->priv_num; ++i) {
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->bssprio_tbl[i].bssprio_head,
MTRUE, pmadapter->callbacks.moal_init_lock);
pmadapter->bssprio_tbl[i].bssprio_cur = MNULL;
}
for (i = start_index; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
priv = pmadapter->priv[i];
for (j = 0; j < MAX_NUM_TID; ++j) {
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->wmm.tid_tbl_ptr[j].ra_list,
MTRUE,
priv->adapter->callbacks.moal_init_lock);
}
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->tx_ba_stream_tbl_ptr, MTRUE,
pmadapter->callbacks.moal_init_lock);
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->rx_reorder_tbl_ptr, MTRUE,
pmadapter->callbacks.moal_init_lock);
util_scalar_init((t_void *)pmadapter->pmoal_handle,
&priv->wmm.tx_pkts_queued, 0,
priv->wmm.ra_list_spinlock,
pmadapter->callbacks.moal_init_lock);
util_scalar_init((t_void *)pmadapter->pmoal_handle,
&priv->wmm.highest_queued_prio,
HIGH_PRIO_TID,
priv->wmm.ra_list_spinlock,
pmadapter->callbacks.moal_init_lock);
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->sta_list, MTRUE,
pmadapter->callbacks.moal_init_lock);
/* Initialize tdls_pending_txq */
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->tdls_pending_txq, MTRUE,
pmadapter->callbacks.moal_init_lock);
/* Initialize bypass_txq */
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->bypass_txq, MTRUE,
pmadapter->callbacks.moal_init_lock);
}
}
error:
LEAVE();
return ret;
}
/**
* @brief This function intializes the lock variables and
* the list heads.
*
* @param pmadapter A pointer to a mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS -- on success,
* otherwise MLAN_STATUS_FAILURE
*
*/
mlan_status wlan_init_lock_list(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
#if defined(USB)
t_s32 i = 0;
#endif
ENTER();
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pmlan_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type)) {
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pint_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
}
#endif
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pmain_proc_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->prx_proc_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pmlan_cmd_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pcard_usb
->usb_tx_aggr[i]
.paggr_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
}
}
#endif
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->rx_data_queue, MTRUE,
pmadapter->callbacks.moal_init_lock);
util_scalar_init((t_void *)pmadapter->pmoal_handle,
&pmadapter->pending_bridge_pkts, 0, MNULL,
pmadapter->callbacks.moal_init_lock);
/* Initialize cmd_free_q */
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->cmd_free_q, MTRUE,
pmadapter->callbacks.moal_init_lock);
/* Initialize cmd_pending_q */
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->cmd_pending_q, MTRUE,
pmadapter->callbacks.moal_init_lock);
/* Initialize scan_pending_q */
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->scan_pending_q, MTRUE,
pmadapter->callbacks.moal_init_lock);
/* Initialize ioctl_pending_q */
util_init_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->ioctl_pending_q, MTRUE,
pmadapter->callbacks.moal_init_lock);
error:
LEAVE();
return ret;
}
/**
* @brief This function releases the lock variables
*
* @param pmadapter A pointer to a mlan_adapter structure
*
* @return None
*
*/
t_void wlan_free_lock_list(pmlan_adapter pmadapter)
{
pmlan_private priv = MNULL;
pmlan_callbacks pcb = &pmadapter->callbacks;
t_s32 i = 0;
t_s32 j = 0;
ENTER();
if (pmadapter->pmlan_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pmlan_lock);
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type) && pmadapter->pint_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pint_lock);
#endif
if (pmadapter->prx_proc_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->prx_proc_lock);
if (pmadapter->pmain_proc_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pmain_proc_lock);
if (pmadapter->pmlan_cmd_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pmlan_cmd_lock);
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pmadapter->pcard_usb->usb_tx_aggr[i].paggr_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pcard_usb
->usb_tx_aggr[i]
.paggr_lock);
}
}
#endif
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
priv = pmadapter->priv[i];
if (priv->rx_pkt_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
priv->rx_pkt_lock);
if (priv->wmm.ra_list_spinlock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
priv->wmm.ra_list_spinlock);
#ifdef STA_SUPPORT
if (priv->curr_bcn_buf_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
priv->curr_bcn_buf_lock);
#endif
}
}
/* Free lists */
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->rx_data_queue, pcb->moal_free_lock);
util_scalar_free((t_void *)pmadapter->pmoal_handle,
&pmadapter->pending_bridge_pkts, pcb->moal_free_lock);
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->cmd_free_q,
pmadapter->callbacks.moal_free_lock);
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->cmd_pending_q,
pmadapter->callbacks.moal_free_lock);
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->scan_pending_q,
pmadapter->callbacks.moal_free_lock);
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->ioctl_pending_q,
pmadapter->callbacks.moal_free_lock);
for (i = 0; i < pmadapter->priv_num; i++)
util_free_list_head((t_void *)pmadapter->pmoal_handle,
&pmadapter->bssprio_tbl[i].bssprio_head,
pcb->moal_free_lock);
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
priv = pmadapter->priv[i];
util_free_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->sta_list,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->tdls_pending_txq,
pmadapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->bypass_txq,
pmadapter->callbacks.moal_free_lock);
for (j = 0; j < MAX_NUM_TID; ++j)
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.tid_tbl_ptr[j].ra_list,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->tx_ba_stream_tbl_ptr,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->rx_reorder_tbl_ptr,
priv->adapter->callbacks.moal_free_lock);
util_scalar_free(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.tx_pkts_queued,
priv->adapter->callbacks.moal_free_lock);
util_scalar_free(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.highest_queued_prio,
priv->adapter->callbacks.moal_free_lock);
}
}
LEAVE();
return;
}
/**
* @brief This function intializes the timers
*
* @param pmadapter A pointer to a mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS -- on success,
* otherwise MLAN_STATUS_FAILURE
*
*/
mlan_status wlan_init_timer(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
#if defined(USB)
t_s32 i = 0;
#endif
ENTER();
if (pcb->moal_init_timer(
pmadapter->pmoal_handle, &pmadapter->pmlan_cmd_timer,
wlan_cmd_timeout_func, pmadapter) != MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pcb->moal_init_timer(
pmadapter->pmoal_handle,
&pmadapter->pcard_usb->usb_tx_aggr[i]
.paggr_hold_timer,
wlan_usb_tx_aggr_timeout_func,
&pmadapter->pcard_usb->usb_tx_aggr[i]) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
}
}
#endif
if (pcb->moal_init_timer(pmadapter->pmoal_handle,
&pmadapter->pwakeup_fw_timer,
wlan_wakeup_card_timeout_func,
pmadapter) != MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
pmadapter->wakeup_fw_timer_is_set = MFALSE;
error:
LEAVE();
return ret;
}
/**
* @brief This function releases the timers
*
* @param pmadapter A pointer to a mlan_adapter structure
*
* @return None
*
*/
t_void wlan_free_timer(pmlan_adapter pmadapter)
{
pmlan_callbacks pcb = &pmadapter->callbacks;
#if defined(USB)
t_s32 i = 0;
#endif
ENTER();
if (pmadapter->pmlan_cmd_timer)
pcb->moal_free_timer(pmadapter->pmoal_handle,
pmadapter->pmlan_cmd_timer);
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pmadapter->pcard_usb->usb_tx_aggr[i]
.paggr_hold_timer)
pcb->moal_free_timer(pmadapter->pmoal_handle,
pmadapter->pcard_usb
->usb_tx_aggr[i]
.paggr_hold_timer);
}
}
#endif
if (pmadapter->pwakeup_fw_timer)
pcb->moal_free_timer(pmadapter->pmoal_handle,
pmadapter->pwakeup_fw_timer);
LEAVE();
return;
}
/**
* @brief This function initializes firmware
*
* @param pmadapter A pointer to mlan_adapter
*
* @return MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING or
* MLAN_STATUS_FAILURE
*/
mlan_status wlan_init_fw(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
#ifdef PCIE
pmlan_private priv = pmadapter->priv[0];
#endif
ENTER();
/* Initialize adapter structure */
wlan_init_adapter(pmadapter);
#ifdef MFG_CMD_SUPPORT
if (pmadapter->mfg_mode != MTRUE) {
#endif
wlan_adapter_get_hw_spec(pmadapter);
#ifdef MFG_CMD_SUPPORT
}
#ifdef PCIE
else if (IS_PCIE(pmadapter->card_type)) {
if (MLAN_STATUS_SUCCESS != wlan_set_pcie_buf_config(priv)) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
#endif /* PCIE */
#endif /* MFG_CMD_SUPPORT */
if (wlan_is_cmd_pending(pmadapter)) {
/* Send the first command in queue and return */
if (mlan_main_process(pmadapter) == MLAN_STATUS_FAILURE)
ret = MLAN_STATUS_FAILURE;
else
ret = MLAN_STATUS_PENDING;
#if defined(MFG_CMD_SUPPORT) && defined(PCIE)
if (IS_PCIE(pmadapter->card_type) && pmadapter->mfg_mode) {
ret = MLAN_STATUS_SUCCESS;
}
#endif
}
#ifdef PCIE
done:
#endif
#ifdef MFG_CMD_SUPPORT
if (pmadapter->mfg_mode == MTRUE) {
pmadapter->hw_status = WlanHardwareStatusInitializing;
ret = wlan_get_hw_spec_complete(pmadapter);
}
#endif
LEAVE();
return ret;
}
/**
* @brief This function udpate hw spec info to each interface
*
* @param pmadapter A pointer to mlan_adapter
*
* @return MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING or
* MLAN_STATUS_FAILURE
*/
static void wlan_update_hw_spec(pmlan_adapter pmadapter)
{
t_u32 i;
ENTER();
#ifdef STA_SUPPORT
if (IS_SUPPORT_MULTI_BANDS(pmadapter))
pmadapter->fw_bands = (t_u8)GET_FW_DEFAULT_BANDS(pmadapter);
else
pmadapter->fw_bands = BAND_B;
if ((pmadapter->fw_bands & BAND_A) && (pmadapter->fw_bands & BAND_GN))
pmadapter->fw_bands |= BAND_AN;
if (!(pmadapter->fw_bands & BAND_G) && (pmadapter->fw_bands & BAND_GN))
pmadapter->fw_bands &= ~BAND_GN;
pmadapter->config_bands = pmadapter->fw_bands;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
pmadapter->priv[i]->config_bands = pmadapter->fw_bands;
}
}
if (pmadapter->fw_bands & BAND_A) {
if (pmadapter->fw_bands & BAND_AN) {
pmadapter->config_bands |= BAND_AN;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->config_bands |=
BAND_AN;
}
}
if (pmadapter->fw_bands & BAND_AAC) {
pmadapter->config_bands |= BAND_AAC;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->config_bands |=
BAND_AAC;
}
}
pmadapter->adhoc_start_band = BAND_A;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->adhoc_channel =
DEFAULT_AD_HOC_CHANNEL_A;
}
} else if (pmadapter->fw_bands & BAND_G) {
pmadapter->adhoc_start_band = BAND_G | BAND_B;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->adhoc_channel =
DEFAULT_AD_HOC_CHANNEL;
}
} else if (pmadapter->fw_bands & BAND_B) {
pmadapter->adhoc_start_band = BAND_B;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->adhoc_channel =
DEFAULT_AD_HOC_CHANNEL;
}
}
#endif /* STA_SUPPORT */
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]->curr_addr[0] == 0xff)
memmove(pmadapter, pmadapter->priv[i]->curr_addr,
pmadapter->permanent_addr,
MLAN_MAC_ADDR_LENGTH);
}
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
wlan_update_11n_cap(pmadapter->priv[i]);
}
if (ISSUPP_BEAMFORMING(pmadapter->hw_dot_11n_dev_cap)) {
PRINTM(MCMND, "Enable Beamforming\n");
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
pmadapter->priv[i]->tx_bf_cap =
pmadapter->pcard_info
->default_11n_tx_bf_cap;
}
}
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
wlan_update_11ac_cap(pmadapter->priv[i]);
}
if (IS_FW_SUPPORT_11AX(pmadapter)) {
if (pmadapter->hw_2g_hecap_len) {
pmadapter->fw_bands |= BAND_GAX;
pmadapter->config_bands |= BAND_GAX;
}
if (pmadapter->hw_hecap_len) {
pmadapter->fw_bands |= BAND_AAX;
pmadapter->config_bands |= BAND_AAX;
}
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
pmadapter->priv[i]->config_bands =
pmadapter->config_bands;
pmadapter->priv[i]->user_2g_hecap_len =
pmadapter->hw_2g_hecap_len;
memcpy_ext(pmadapter,
pmadapter->priv[i]->user_2g_he_cap,
pmadapter->hw_2g_he_cap,
pmadapter->hw_2g_hecap_len,
sizeof(pmadapter->priv[i]
->user_2g_he_cap));
pmadapter->priv[i]->user_hecap_len =
pmadapter->hw_hecap_len;
memcpy_ext(
pmadapter,
pmadapter->priv[i]->user_he_cap,
pmadapter->hw_he_cap,
pmadapter->hw_hecap_len,
sizeof(pmadapter->priv[i]->user_he_cap));
}
}
}
LEAVE();
return;
}
/**
* @brief This function initializes firmware for interface
*
* @param pmadapter A pointer to mlan_adapter
*
* @return MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING or
* MLAN_STATUS_FAILURE
*/
static mlan_status wlan_init_priv_fw(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private priv = MNULL;
t_u8 i = 0;
ENTER();
wlan_init_priv_lock_list(pmadapter, 1);
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
priv = pmadapter->priv[i];
/* Initialize private structure */
ret = wlan_init_priv(priv);
if (ret) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
}
#ifdef MFG_CMD_SUPPORT
if (pmadapter->mfg_mode != MTRUE) {
#endif
wlan_update_hw_spec(pmadapter);
/* Issue firmware initialize commands for first BSS,
* for other interfaces it will be called after getting
* the last init command response of previous interface
*/
priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
if (!priv) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = priv->ops.init_cmd(priv, MTRUE);
if (ret == MLAN_STATUS_FAILURE)
goto done;
#ifdef MFG_CMD_SUPPORT
}
#endif /* MFG_CMD_SUPPORT */
if (wlan_is_cmd_pending(pmadapter)) {
/* Send the first command in queue and return */
if (mlan_main_process(pmadapter) == MLAN_STATUS_FAILURE)
ret = MLAN_STATUS_FAILURE;
else
ret = MLAN_STATUS_PENDING;
#if defined(MFG_CMD_SUPPORT) && defined(PCIE)
if (IS_PCIE(pmadapter->card_type) && pmadapter->mfg_mode) {
ret = MLAN_STATUS_SUCCESS;
pmadapter->hw_status = WlanHardwareStatusReady;
}
#endif
} else {
pmadapter->hw_status = WlanHardwareStatusReady;
}
done:
LEAVE();
return ret;
}
/**
* @brief This function frees the structure of adapter
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return N/A
*/
t_void wlan_free_adapter(pmlan_adapter pmadapter)
{
mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
#if defined(USB)
t_s32 i = 0;
#endif
ENTER();
if (!pmadapter) {
PRINTM(MERROR, "The adapter is NULL\n");
LEAVE();
return;
}
wlan_cancel_all_pending_cmd(pmadapter, MTRUE);
/* Free command buffer */
PRINTM(MINFO, "Free Command buffer\n");
wlan_free_cmd_buffer(pmadapter);
if (pmadapter->cmd_timer_is_set) {
/* Cancel command timeout timer */
pcb->moal_stop_timer(pmadapter->pmoal_handle,
pmadapter->pmlan_cmd_timer);
pmadapter->cmd_timer_is_set = MFALSE;
}
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pmadapter->pcard_usb->usb_tx_aggr[i]
.aggr_hold_timer_is_set) {
/* Cancel usb_tx_aggregation timeout timer */
pcb->moal_stop_timer(pmadapter->pmoal_handle,
pmadapter->pcard_usb
->usb_tx_aggr[i]
.paggr_hold_timer);
pmadapter->pcard_usb->usb_tx_aggr[i]
.aggr_hold_timer_is_set = MFALSE;
}
}
}
#endif
if (pmadapter->wakeup_fw_timer_is_set) {
/* Cancel wakeup card timer */
pcb->moal_stop_timer(pmadapter->pmoal_handle,
pmadapter->pwakeup_fw_timer);
pmadapter->wakeup_fw_timer_is_set = MFALSE;
}
wlan_free_fw_cfp_tables(pmadapter);
#ifdef STA_SUPPORT
PRINTM(MINFO, "Free ScanTable\n");
if (pmadapter->pscan_table) {
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pscan_table);
else
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pscan_table);
pmadapter->pscan_table = MNULL;
}
if (pmadapter->pchan_stats) {
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pchan_stats);
else
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pchan_stats);
pmadapter->pchan_stats = MNULL;
}
if (pmadapter->bcn_buf) {
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->bcn_buf);
else
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->bcn_buf);
pmadapter->bcn_buf = MNULL;
}
#endif
wlan_11h_cleanup(pmadapter);
#ifdef SDIO
if (IS_SD(pmadapter->card_type)) {
if (pmadapter->pcard_sd->mp_regs_buf) {
pcb->moal_mfree(
pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_sd->mp_regs_buf);
pmadapter->pcard_sd->mp_regs_buf = MNULL;
pmadapter->pcard_sd->mp_regs = MNULL;
}
if (pmadapter->pcard_sd->rx_buffer) {
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_sd->rx_buffer);
pmadapter->pcard_sd->rx_buffer = MNULL;
pmadapter->pcard_sd->rx_buf = MNULL;
}
wlan_free_sdio_mpa_buffers(pmadapter);
#ifdef DEBUG_LEVEL1
if (pmadapter->pcard_sd->mpa_buf) {
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(
pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_sd->mpa_buf);
else
pcb->moal_mfree(
pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_sd->mpa_buf);
pmadapter->pcard_sd->mpa_buf = MNULL;
pmadapter->pcard_sd->mpa_buf_size = 0;
}
#endif
}
#endif
wlan_free_mlan_buffer(pmadapter, pmadapter->psleep_cfm);
pmadapter->psleep_cfm = MNULL;
#ifdef PCIE
if (IS_PCIE(pmadapter->card_type)) {
/* Free ssu dma buffer just in case */
wlan_free_ssu_pcie_buf(pmadapter);
/* Free PCIE ring buffers */
wlan_free_pcie_ring_buf(pmadapter);
}
#endif
/* Free timers */
wlan_free_timer(pmadapter);
/* Free lock variables */
wlan_free_lock_list(pmadapter);
#ifdef SDIO
if (pmadapter->pcard_sd) {
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_sd);
pmadapter->pcard_sd = MNULL;
}
#endif
#ifdef PCIE
if (pmadapter->pcard_pcie) {
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_pcie);
pmadapter->pcard_pcie = MNULL;
}
#endif
#ifdef USB
if (pmadapter->pcard_usb) {
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)pmadapter->pcard_usb);
pmadapter->pcard_usb = MNULL;
}
#endif
vdll_deinit(pmadapter);
LEAVE();
return;
}
/**
* @brief This function frees the structure of priv
*
* @param pmpriv A pointer to mlan_private structure
*
* @return N/A
*/
t_void wlan_free_priv(mlan_private *pmpriv)
{
ENTER();
wlan_clean_txrx(pmpriv);
wlan_delete_bsspriotbl(pmpriv);
#ifdef STA_SUPPORT
wlan_free_curr_bcn(pmpriv);
#endif /* STA_SUPPORT */
#if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
hostsa_cleanup(pmpriv);
#endif /*EMBEDDED AUTHENTICATOR*/
wlan_delete_station_list(pmpriv);
LEAVE();
}
/**
* @brief This function init interface based on pmadapter's bss_attr table
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return N/A
*/
static mlan_status wlan_init_interface(pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = MNULL;
t_u8 i = 0;
t_u32 j = 0;
ENTER();
pcb = &pmadapter->callbacks;
for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
if (pmadapter->bss_attr[i].active == MTRUE) {
if (!pmadapter->priv[i]) {
/* For valid bss_attr, allocate memory for
* private structure */
if (pcb->moal_vmalloc && pcb->moal_vfree)
ret = pcb->moal_vmalloc(
pmadapter->pmoal_handle,
sizeof(mlan_private),
(t_u8 **)&pmadapter->priv[i]);
else
ret = pcb->moal_malloc(
pmadapter->pmoal_handle,
sizeof(mlan_private),
MLAN_MEM_DEF,
(t_u8 **)&pmadapter->priv[i]);
if (ret != MLAN_STATUS_SUCCESS ||
!pmadapter->priv[i]) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
pmadapter->priv_num++;
memset(pmadapter, pmadapter->priv[i], 0,
sizeof(mlan_private));
}
pmadapter->priv[i]->adapter = pmadapter;
/* Save bss_type, frame_type & bss_priority */
pmadapter->priv[i]->bss_type =
(t_u8)pmadapter->bss_attr[i].bss_type;
pmadapter->priv[i]->frame_type =
(t_u8)pmadapter->bss_attr[i].frame_type;
pmadapter->priv[i]->bss_priority =
(t_u8)pmadapter->bss_attr[i].bss_priority;
if (pmadapter->bss_attr[i].bss_type ==
MLAN_BSS_TYPE_STA)
pmadapter->priv[i]->bss_role =
MLAN_BSS_ROLE_STA;
else if (pmadapter->bss_attr[i].bss_type ==
MLAN_BSS_TYPE_UAP)
pmadapter->priv[i]->bss_role =
MLAN_BSS_ROLE_UAP;
#ifdef WIFI_DIRECT_SUPPORT
else if (pmadapter->bss_attr[i].bss_type ==
MLAN_BSS_TYPE_WIFIDIRECT) {
pmadapter->priv[i]->bss_role =
MLAN_BSS_ROLE_STA;
if (pmadapter->bss_attr[i].bss_virtual)
pmadapter->priv[i]->bss_virtual = MTRUE;
}
#endif
/* Save bss_index and bss_num */
pmadapter->priv[i]->bss_index = i;
pmadapter->priv[i]->bss_num =
(t_u8)pmadapter->bss_attr[i].bss_num;
/* init function table */
for (j = 0; mlan_ops[j]; j++) {
if (mlan_ops[j]->bss_role ==
GET_BSS_ROLE(pmadapter->priv[i])) {
memcpy_ext(pmadapter,
&pmadapter->priv[i]->ops,
mlan_ops[j],
sizeof(mlan_operations),
sizeof(mlan_operations));
break;
}
}
}
}
/*wmm init*/
wlan_wmm_init(pmadapter);
/* Initialize firmware, may return PENDING */
ret = wlan_init_priv_fw(pmadapter);
PRINTM(MINFO, "wlan_init_priv_fw returned ret=0x%x\n", ret);
error:
LEAVE();
return ret;
}
/**
* @brief The cmdresp handler calls this function for init_fw_complete callback
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS
* The firmware initialization callback succeeded.
*/
mlan_status wlan_get_hw_spec_complete(pmlan_adapter pmadapter)
{
mlan_status status = MLAN_STATUS_SUCCESS;
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_hw_info info;
mlan_bss_tbl bss_tbl;
ENTER();
#ifdef MFG_CMD_SUPPORT
if (pmadapter->mfg_mode != MTRUE) {
#endif
/* Check if hardware is ready */
if (pmadapter->hw_status != WlanHardwareStatusInitializing)
status = MLAN_STATUS_FAILURE;
else {
memset(pmadapter, &info, 0, sizeof(info));
info.fw_cap = pmadapter->fw_cap_info;
info.fw_cap_ext = pmadapter->fw_cap_ext;
memset(pmadapter, &bss_tbl, 0, sizeof(bss_tbl));
memcpy_ext(pmadapter, bss_tbl.bss_attr,
pmadapter->bss_attr, sizeof(mlan_bss_tbl),
sizeof(mlan_bss_tbl));
}
/* Invoke callback */
ret = pcb->moal_get_hw_spec_complete(pmadapter->pmoal_handle,
status, &info, &bss_tbl);
if (ret == MLAN_STATUS_SUCCESS && status == MLAN_STATUS_SUCCESS)
memcpy_ext(pmadapter, pmadapter->bss_attr,
bss_tbl.bss_attr, sizeof(mlan_bss_tbl),
sizeof(mlan_bss_tbl));
else {
pmadapter->hw_status = WlanHardwareStatusNotReady;
wlan_init_fw_complete(pmadapter);
}
#ifdef MFG_CMD_SUPPORT
}
#endif
if (pmadapter->hw_status == WlanHardwareStatusInitializing)
ret = wlan_init_interface(pmadapter);
LEAVE();
return ret;
}
/**
* @brief The cmdresp handler calls this function for init_fw_complete callback
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS
* The firmware initialization callback succeeded.
*/
mlan_status wlan_init_fw_complete(pmlan_adapter pmadapter)
{
mlan_status status = MLAN_STATUS_SUCCESS;
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_private *pmpriv = MNULL;
ENTER();
/* Check if hardware is ready */
if (pmadapter->hw_status != WlanHardwareStatusReady)
status = MLAN_STATUS_FAILURE;
/* Reconfigure wmm parameter*/
if (status == MLAN_STATUS_SUCCESS) {
pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_STA);
if (pmpriv)
status = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_WMM_PARAM_CONFIG,
HostCmd_ACT_GEN_SET, 0, MNULL,
&pmadapter->ac_params);
}
/* Invoke callback */
ret = pcb->moal_init_fw_complete(pmadapter->pmoal_handle, status);
LEAVE();
return ret;
}
/**
* @brief The cmdresp handler calls this function
* for shutdown_fw_complete callback
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return MLAN_STATUS_SUCCESS
* The firmware shutdown callback succeeded.
*/
mlan_status wlan_shutdown_fw_complete(pmlan_adapter pmadapter)
{
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_status status = MLAN_STATUS_SUCCESS;
mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
pmadapter->hw_status = WlanHardwareStatusNotReady;
/* Invoke callback */
ret = pcb->moal_shutdown_fw_complete(pmadapter->pmoal_handle, status);
LEAVE();
return ret;
}