/** * @brief This function registers MOAL to MLAN module. * * @param pmdevice A pointer to a mlan_device structure * allocated in MOAL * @param ppmlan_adapter A pointer to a t_void pointer to store * mlan_adapter structure pointer as the context * * @return MLAN_STATUS_SUCCESS * The registration succeeded. * MLAN_STATUS_FAILURE * The registration failed. * * mlan_status mlan_register ( * IN pmlan_device pmdevice, * OUT t_void **ppmlan_adapter * ); * * Comments * MOAL constructs mlan_device data structure to pass moal_handle and * mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to * the ppmlan_adapter buffer provided by MOAL. * Headers: * declared in mlan_decl.h * See Also * mlan_unregister */ mlan_status mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter) { mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_adapter pmadapter = MNULL; pmlan_callbacks pcb = MNULL; t_u8 i = 0; t_u32 j = 0; MASSERT(pmdevice); MASSERT(ppmlan_adapter); MASSERT(pmdevice->callbacks.moal_print); #ifdef DEBUG_LEVEL1 print_callback = pmdevice->callbacks.moal_print; get_sys_time_callback = pmdevice->callbacks.moal_get_system_time; #endif assert_callback = pmdevice->callbacks.moal_assert; ENTER(); MASSERT(pmdevice->callbacks.moal_malloc); MASSERT(pmdevice->callbacks.moal_memset); MASSERT(pmdevice->callbacks.moal_memmove); /* Allocate memory for adapter structure */ if (pmdevice->callbacks.moal_vmalloc && pmdevice->callbacks.moal_vfree) ret = pmdevice->callbacks.moal_vmalloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), (t_u8 **) & pmadapter); else ret = pmdevice->callbacks.moal_malloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), MLAN_MEM_DEF, (t_u8 **) & pmadapter); if ((ret != MLAN_STATUS_SUCCESS) || !pmadapter) { ret = MLAN_STATUS_FAILURE; goto exit_register; } pmdevice->callbacks.moal_memset(pmdevice->pmoal_handle, pmadapter, 0, sizeof(mlan_adapter)); pcb = &pmadapter->callbacks; /* Save callback functions */ pmdevice->callbacks.moal_memmove(pmadapter->pmoal_handle, pcb, &pmdevice->callbacks, sizeof(mlan_callbacks)); /* Assertion for all callback functions */ MASSERT(pcb->moal_init_fw_complete); MASSERT(pcb->moal_shutdown_fw_complete); MASSERT(pcb->moal_send_packet_complete); MASSERT(pcb->moal_recv_packet); MASSERT(pcb->moal_recv_event); MASSERT(pcb->moal_ioctl_complete); MASSERT(pcb->moal_write_reg); MASSERT(pcb->moal_read_reg); MASSERT(pcb->moal_alloc_mlan_buffer); MASSERT(pcb->moal_free_mlan_buffer); MASSERT(pcb->moal_write_data_sync); MASSERT(pcb->moal_read_data_sync); MASSERT(pcb->moal_mfree); MASSERT(pcb->moal_memcpy); MASSERT(pcb->moal_memcmp); MASSERT(pcb->moal_get_system_time); MASSERT(pcb->moal_init_timer); MASSERT(pcb->moal_free_timer); MASSERT(pcb->moal_start_timer); MASSERT(pcb->moal_stop_timer); MASSERT(pcb->moal_init_lock); MASSERT(pcb->moal_free_lock); MASSERT(pcb->moal_spin_lock); MASSERT(pcb->moal_spin_unlock); MASSERT(pcb->moal_tcp_ack_tx_ind); /* Save pmoal_handle */ pmadapter->pmoal_handle = pmdevice->pmoal_handle; if ((pmdevice->int_mode == INT_MODE_GPIO) && (pmdevice->gpio_pin == 0)) { PRINTM(MERROR, "SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n"); ret = MLAN_STATUS_FAILURE; goto error; } pmadapter->init_para.int_mode = pmdevice->int_mode; pmadapter->init_para.gpio_pin = pmdevice->gpio_pin; /* card specific probing has been deferred until now .. */ ret = wlan_sdio_probe(pmadapter); if (MLAN_STATUS_SUCCESS != ret) { ret = MLAN_STATUS_FAILURE; goto error; } #ifdef DEBUG_LEVEL1 mlan_drvdbg = pmdevice->drvdbg; #endif #ifdef MFG_CMD_SUPPORT pmadapter->init_para.mfg_mode = pmdevice->mfg_mode; #endif #ifdef SDIO_MULTI_PORT_TX_AGGR pmadapter->init_para.mpa_tx_cfg = pmdevice->mpa_tx_cfg; #endif #ifdef SDIO_MULTI_PORT_RX_AGGR pmadapter->init_para.mpa_rx_cfg = pmdevice->mpa_rx_cfg; #endif pmadapter->init_para.auto_ds = pmdevice->auto_ds; pmadapter->init_para.ps_mode = pmdevice->ps_mode; if (pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_2K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_4K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_8K) pmadapter->init_para.max_tx_buf = pmdevice->max_tx_buf; #ifdef STA_SUPPORT pmadapter->init_para.cfg_11d = pmdevice->cfg_11d; #else pmadapter->init_para.cfg_11d = 0; #endif pmadapter->init_para.dfs_master_radar_det_en = DFS_MASTER_RADAR_DETECT_EN; pmadapter->init_para.dfs_slave_radar_det_en = DFS_SLAVE_RADAR_DETECT_EN; pmadapter->init_para.fw_crc_check = pmdevice->fw_crc_check; pmadapter->rx_work_flag = pmdevice->rx_work; pmadapter->priv_num = 0; for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { pmadapter->priv[i] = MNULL; if (pmdevice->bss_attr[i].active == MTRUE) { /* 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) pmdevice->bss_attr[i].bss_type; pmadapter->priv[i]->frame_type = (t_u8) pmdevice->bss_attr[i].frame_type; pmadapter->priv[i]->bss_priority = (t_u8) pmdevice->bss_attr[i].bss_priority; if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_STA) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA; else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_UAP) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_UAP; #ifdef WIFI_DIRECT_SUPPORT else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_WIFIDIRECT) { pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA; if (pmdevice->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) pmdevice->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(pmadapter, &pmadapter->priv[i]->ops, mlan_ops[j], sizeof(mlan_operations)); } } } } /* Initialize lock variables */ if (wlan_init_lock_list(pmadapter) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } /* Allocate memory for member of adapter structure */ if (wlan_allocate_adapter(pmadapter)) { ret = MLAN_STATUS_FAILURE; goto error; } /* Initialize timers */ if (wlan_init_timer(pmadapter) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } /* Return pointer of mlan_adapter to MOAL */ *ppmlan_adapter = pmadapter; goto exit_register; error: PRINTM(MINFO, "Leave mlan_register with error\n"); /* Free timers */ wlan_free_timer(pmadapter); /* Free adapter structure */ wlan_free_adapter(pmadapter); /* Free lock variables */ wlan_free_lock_list(pmadapter); for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { if (pmadapter->priv[i]) { if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); } } if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); else pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); exit_register: LEAVE(); return ret; }
/** * @brief This function downloads the firmware * * @param pmlan_adapter A pointer to a t_void pointer to store * mlan_adapter structure pointer * @param pmfw A pointer to firmware image * * @return MLAN_STATUS_SUCCESS * The firmware download succeeded. * MLAN_STATUS_FAILURE * The firmware download failed. */ mlan_status mlan_dnld_fw(IN t_void * pmlan_adapter, IN pmlan_fw_image pmfw) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter; t_u32 poll_num = 1; t_u32 winner = 0; ENTER(); MASSERT(pmlan_adapter); /* Card specific probing */ ret = wlan_sdio_probe(pmadapter); if (ret == MLAN_STATUS_FAILURE) { PRINTM(MERROR, "WLAN SDIO probe failed\n", ret); LEAVE(); return ret; } /* Check if firmware is already running */ ret = wlan_check_fw_status(pmadapter, poll_num); if (ret == MLAN_STATUS_SUCCESS) { PRINTM(MMSG, "WLAN FW already running! Skip FW download\n"); goto done; } poll_num = MAX_FIRMWARE_POLL_TRIES; /* Check if other interface is downloading */ ret = wlan_check_winner_status(pmadapter, &winner); if (ret == MLAN_STATUS_FAILURE) { PRINTM(MFATAL, "WLAN read winner status failed!\n"); goto done; } if (winner) { PRINTM(MMSG, "WLAN is not the winner (0x%x). Skip FW download\n", winner); poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; goto poll_fw; } if (pmfw) { /* Download helper/firmware */ ret = wlan_dnld_fw(pmadapter, pmfw); if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MERROR, "wlan_dnld_fw fail ret=0x%x\n", ret); LEAVE(); return ret; } } poll_fw: /* Check if the firmware is downloaded successfully or not */ ret = wlan_check_fw_status(pmadapter, poll_num); if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MFATAL, "FW failed to be active in time!\n"); ret = MLAN_STATUS_FAILURE; LEAVE(); return ret; } done: /* re-enable host interrupt for mlan after fw dnld is successful */ wlan_enable_host_int(pmadapter); LEAVE(); return ret; }
/** * @brief This function registers MOAL to MLAN module. * * @param pmdevice A pointer to a mlan_device structure * allocated in MOAL * @param ppmlan_adapter A pointer to a t_void pointer to store * mlan_adapter structure pointer as the context * * @return MLAN_STATUS_SUCCESS * The registration succeeded. * MLAN_STATUS_FAILURE * The registration failed. * * mlan_status mlan_register ( * IN pmlan_device pmdevice, * OUT t_void **ppmlan_adapter * ); * * Comments * MOAL constructs mlan_device data structure to pass moal_handle and * mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to * the ppmlan_adapter buffer provided by MOAL. * Headers: * declared in mlan_decl.h * See Also * mlan_unregister */ mlan_status mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter) { mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_adapter pmadapter = MNULL; pmlan_callbacks pcb = MNULL; t_u8 i = 0; t_u32 j = 0; MASSERT(pmdevice); MASSERT(ppmlan_adapter); MASSERT(pmdevice->callbacks.moal_print); #ifdef DEBUG_LEVEL1 print_callback = pmdevice->callbacks.moal_print; #endif assert_callback = pmdevice->callbacks.moal_assert; ENTER(); MASSERT(pmdevice->callbacks.moal_malloc); MASSERT(pmdevice->callbacks.moal_memset); MASSERT(pmdevice->callbacks.moal_memmove); /* Allocate memory for adapter structure */ if ((pmdevice->callbacks. moal_malloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), MLAN_MEM_DEF, (t_u8 **) & pmadapter) != MLAN_STATUS_SUCCESS) || !pmadapter) { ret = MLAN_STATUS_FAILURE; goto exit_register; } pmdevice->callbacks.moal_memset(pmadapter, pmadapter, 0, sizeof(mlan_adapter)); pcb = &pmadapter->callbacks; /* Save callback functions */ pmdevice->callbacks.moal_memmove(pmadapter->pmoal_handle, pcb, &pmdevice->callbacks, sizeof(mlan_callbacks)); /* Assertion for all callback functions */ MASSERT(pcb->moal_init_fw_complete); MASSERT(pcb->moal_shutdown_fw_complete); MASSERT(pcb->moal_send_packet_complete); MASSERT(pcb->moal_recv_packet); MASSERT(pcb->moal_recv_event); MASSERT(pcb->moal_ioctl_complete); MASSERT(pcb->moal_write_reg); MASSERT(pcb->moal_read_reg); MASSERT(pcb->moal_alloc_mlan_buffer); MASSERT(pcb->moal_free_mlan_buffer); MASSERT(pcb->moal_write_data_sync); MASSERT(pcb->moal_read_data_sync); MASSERT(pcb->moal_mfree); MASSERT(pcb->moal_memcpy); MASSERT(pcb->moal_memcmp); MASSERT(pcb->moal_get_system_time); MASSERT(pcb->moal_init_timer); MASSERT(pcb->moal_free_timer); MASSERT(pcb->moal_start_timer); MASSERT(pcb->moal_stop_timer); MASSERT(pcb->moal_init_lock); MASSERT(pcb->moal_free_lock); MASSERT(pcb->moal_spin_lock); MASSERT(pcb->moal_spin_unlock); /* Save pmoal_handle */ pmadapter->pmoal_handle = pmdevice->pmoal_handle; if ((pmdevice->int_mode == INT_MODE_GPIO) && (pmdevice->gpio_pin == 0)) { PRINTM(MERROR, "SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n"); ret = MLAN_STATUS_FAILURE; goto error; } pmadapter->init_para.int_mode = pmdevice->int_mode; pmadapter->init_para.gpio_pin = pmdevice->gpio_pin; /* card specific probing has been deferred until now .. */ if (MLAN_STATUS_SUCCESS != (ret = wlan_sdio_probe(pmadapter))) { ret = MLAN_STATUS_FAILURE; goto error; } #ifdef MFG_CMD_SUPPORT pmadapter->init_para.mfg_mode = pmdevice->mfg_mode; #endif #ifdef SDIO_MULTI_PORT_TX_AGGR pmadapter->init_para.mpa_tx_cfg = pmdevice->mpa_tx_cfg; #endif #ifdef SDIO_MULTI_PORT_RX_AGGR pmadapter->init_para.mpa_rx_cfg = pmdevice->mpa_rx_cfg; #endif pmadapter->init_para.auto_ds = pmdevice->auto_ds; pmadapter->init_para.ps_mode = pmdevice->ps_mode; if (pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_2K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_4K || pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_8K) pmadapter->init_para.max_tx_buf = pmdevice->max_tx_buf; for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { pmadapter->priv[i] = MNULL; if (pmdevice->bss_attr[i].active == MTRUE) { /* For valid bss_attr, allocate memory for private structure */ if ((pcb-> moal_malloc(pmadapter->pmoal_handle, sizeof(mlan_private), MLAN_MEM_DEF, (t_u8 **) & pmadapter->priv[i]) != MLAN_STATUS_SUCCESS) || !pmadapter->priv[i]) { ret = MLAN_STATUS_FAILURE; goto error; } 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) pmdevice->bss_attr[i].bss_type; pmadapter->priv[i]->frame_type = (t_u8) pmdevice->bss_attr[i].frame_type; pmadapter->priv[i]->bss_priority = (t_u8) pmdevice->bss_attr[i].bss_priority; /* Save bss_index and bss_num */ pmadapter->priv[i]->bss_index = i; pmadapter->priv[i]->bss_num = (t_u8) pmdevice->bss_attr[i].bss_num; /* init function table */ for (j = 0; j < (sizeof(ops) / sizeof(ops[0])); j++) { if (ops[j].bss_type == pmadapter->priv[i]->bss_type) { memcpy(pmadapter, &pmadapter->priv[i]->ops, &ops[j], sizeof(mlan_operations)); } } } } /* Initialize locks */ if (pcb->moal_init_lock(pmadapter->pmoal_handle, &pmadapter->pmlan_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } if (pcb->moal_init_lock(pmadapter->pmoal_handle, &pmadapter->pint_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } 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->pmlan_cmd_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto error; } 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; } /* Return pointer of mlan_adapter to MOAL */ *ppmlan_adapter = pmadapter; goto exit_register; error: PRINTM(MINFO, "Leave mlan_register with error\n"); /* Free resources */ if (pmadapter->pmlan_cmd_timer) pcb->moal_free_timer(pmadapter->pmoal_handle, pmadapter->pmlan_cmd_timer); if (pmadapter->pmlan_cmd_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmlan_cmd_lock); if (pmadapter->pmain_proc_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmain_proc_lock); if (pmadapter->pint_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pint_lock); if (pmadapter->pmlan_lock) pcb->moal_free_lock(pmadapter->pmoal_handle, pmadapter->pmlan_lock); for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { if (pmadapter->priv[i]) pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter->priv[i]); } pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter); exit_register: LEAVE(); return ret; }