mirror of
https://github.com/pine64/bl_iot_sdk.git
synced 2024-09-15 15:14:03 +00:00
612 lines
16 KiB
C
612 lines
16 KiB
C
/*
|
|
* Copyright (c) 2020 Bouffalolab.
|
|
*
|
|
* This file is part of
|
|
* *** Bouffalolab Software Dev Kit ***
|
|
* (see www.bouffalolab.com).
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <lwip/opt.h>
|
|
#include <lwip/def.h>
|
|
#include <lwip/mem.h>
|
|
#include <lwip/pbuf.h>
|
|
#include <netif/etharp.h>
|
|
#include <ethernetif.h>
|
|
#include <bl_wifi.h>
|
|
|
|
#include "bl_main.h"
|
|
#include "bl_defs.h"
|
|
#include "bl_utils.h"
|
|
#include "bl_platform.h"
|
|
#include "bl_msg_tx.h"
|
|
#include "bl_irqs.h"
|
|
#include "bl_tx.h"
|
|
|
|
#include <blog.h>
|
|
#define USER_UNUSED(a) ((void)(a))
|
|
#define RWNX_PRINT_CFM_ERR(req) \
|
|
os_printf("%s: Status Error(%d)\n", #req, (&req##_cfm)->status)
|
|
|
|
struct bl_hw wifi_hw;
|
|
|
|
int bl_cfg80211_connect(struct bl_hw *bl_hw, struct cfg80211_connect_params *sme);
|
|
|
|
static void bl_set_vers(struct bl_hw *bl_hw)
|
|
{
|
|
u32 vers = bl_hw->version_cfm.version_lmac;
|
|
|
|
USER_UNUSED(vers);
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
os_printf("[version] lmac %u.%u.%u.%u\r\n",
|
|
(unsigned int)((vers >> 24) & 0xFF),
|
|
(unsigned int)((vers >> 16) & 0xFF),
|
|
(unsigned int)((vers >> 8) & 0xFF),
|
|
(unsigned int)((vers >> 0) & 0xFF)
|
|
);
|
|
os_printf("[version] version_machw_1 %08X\r\n", (unsigned int)bl_hw->version_cfm.version_machw_1);
|
|
os_printf("[version] version_machw_2 %08X\r\n", (unsigned int)bl_hw->version_cfm.version_machw_2);
|
|
os_printf("[version] version_phy_1 %08X\r\n", (unsigned int)bl_hw->version_cfm.version_phy_1);
|
|
os_printf("[version] version_phy_2 %08X\r\n", (unsigned int)bl_hw->version_cfm.version_phy_2);
|
|
os_printf("[version] features %08X\r\n", (unsigned int)bl_hw->version_cfm.features);
|
|
|
|
RWNX_DBG(RWNX_FN_LEAVE_STR);
|
|
}
|
|
|
|
|
|
/**
|
|
****************************************************************************************
|
|
*
|
|
* @file bl_main.c
|
|
* Copyright (C) Bouffalo Lab 2016-2018
|
|
*
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
* int (*ndo_open)(struct net_device *dev);
|
|
* This function is called when network device transistions to the up
|
|
* state.
|
|
*
|
|
* - Start FW if this is the first interface opened
|
|
* - Add interface at fw level
|
|
*/
|
|
int bl_open(struct bl_hw *bl_hw)
|
|
{
|
|
#if 0
|
|
struct mm_add_if_cfm add_if_cfm;
|
|
#if 0
|
|
struct apm_start_cfm start_ap_cfm;
|
|
#endif
|
|
int error = 0;
|
|
const unsigned char mac[] = {0x00, 0x50, 0x43, 0xC9, 0x00, 0x01};
|
|
struct cfg80211_connect_params sme;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
// Check if it is the first opened VIF
|
|
if (bl_hw->vif_started == 0)
|
|
{
|
|
// Start the FW
|
|
os_printf("[WF] MM_START_REQ Sending\r\n");
|
|
error = bl_send_start(bl_hw);
|
|
os_printf("[WF] MM_START_REQ Done\r\n");
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
/* Device is now started */
|
|
bl_hw->drv_flags |= (1 << RWNX_DEV_STARTED);
|
|
}
|
|
|
|
#if 0
|
|
/* Forward the information to the LMAC,
|
|
* p2p value not used in FMAC configuration, iftype is sufficient */
|
|
os_printf("[WF] MM_ADD_IF_REQ Sending\r\n");
|
|
error = bl_send_add_if(bl_hw, mac, NL80211_IFTYPE_AP, false, &add_if_cfm);
|
|
os_printf("[WF] MM_ADD_IF_REQ Done\r\n");
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
if (add_if_cfm.status != 0) {
|
|
RWNX_PRINT_CFM_ERR(add_if);
|
|
return -EIO;
|
|
}
|
|
|
|
/* Save the index retrieved from LMAC */
|
|
bl_hw->vif_index = add_if_cfm.inst_nbr;
|
|
|
|
os_printf("[WF] vif_index from LAMC is %d\r\n", bl_hw->vif_index);
|
|
|
|
os_printf("[WF] APM_START_REQ Sending\r\n");
|
|
bl_send_apm_start_req(bl_hw, &start_ap_cfm);
|
|
os_printf("[WF] APM_START_REQ Done\r\n");
|
|
#else
|
|
/* Forward the information to the LMAC,
|
|
* p2p value not used in FMAC configuration, iftype is sufficient */
|
|
os_printf("[WF] MM_ADD_IF_REQ Sending\r\n");
|
|
error = bl_send_add_if(bl_hw, mac, NL80211_IFTYPE_STATION, false, &add_if_cfm);
|
|
os_printf("[WF] MM_ADD_IF_REQ Done\r\n");
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
if (add_if_cfm.status != 0) {
|
|
RWNX_PRINT_CFM_ERR(add_if);
|
|
return -EIO;
|
|
}
|
|
|
|
/* Save the index retrieved from LMAC */
|
|
bl_hw->vif_index = add_if_cfm.inst_nbr;
|
|
|
|
#undef os_printf
|
|
os_printf("[WF] vif_index from LAMC is %d\r\n", bl_hw->vif_index);
|
|
#define os_printf(...) do {} while(0)
|
|
|
|
#if 0
|
|
os_printf("[WF] SM_CONNECT_REQ Sending\r\n");
|
|
memset(&sme, 0, sizeof(struct cfg80211_connect_params));
|
|
sme.crypto.n_ciphers_pairwise = 0;
|
|
sme.ssid_len = 7;
|
|
sme.ssid = "LEDE_4G";
|
|
sme.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
|
bl_cfg80211_connect(bl_hw, &sme);
|
|
os_printf("[WF] SM_CONNECT_REQ Done\r\n");
|
|
#endif
|
|
#endif
|
|
|
|
return error;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int psk_len, const uint8_t *pmk, int pmk_len, const uint8_t *mac, const uint8_t band, const uint16_t freq)
|
|
{
|
|
struct cfg80211_connect_params sme;
|
|
|
|
memset(&sme, 0, sizeof(struct cfg80211_connect_params));
|
|
sme.crypto.n_ciphers_pairwise = 0;
|
|
sme.ssid_len = ssid_len;
|
|
sme.ssid = ssid;
|
|
sme.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
|
sme.key = psk;
|
|
sme.key_len = psk_len;
|
|
sme.pmk = pmk;
|
|
sme.pmk_len = pmk_len;
|
|
|
|
if (mac){
|
|
sme.bssid = mac;
|
|
}
|
|
|
|
if (freq > 0) {
|
|
sme.channel.center_freq = freq;
|
|
sme.channel.band = band;
|
|
sme.channel.flags = 0;
|
|
}
|
|
|
|
bl_cfg80211_connect(&wifi_hw, &sme);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_disconnect()
|
|
{
|
|
bl_send_sm_disconnect_req(&wifi_hw, 0x34);//XXX magic code
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_powersaving(int mode)
|
|
{
|
|
return bl_send_mm_powersaving_req(&wifi_hw, mode);
|
|
}
|
|
|
|
int bl_main_denoise(int mode)
|
|
{
|
|
return bl_send_mm_denoise_req(&wifi_hw, mode);
|
|
}
|
|
|
|
int bl_main_monitor()
|
|
{
|
|
struct mm_monitor_cfm cfm;
|
|
|
|
memset(&cfm, 0, sizeof(cfm));
|
|
bl_send_monitor_enable(&wifi_hw, &cfm);
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_phy_up()
|
|
{
|
|
int error = 0;
|
|
|
|
error = bl_send_start(&wifi_hw);
|
|
if (error) {
|
|
return -1;
|
|
}
|
|
wifi_hw.drv_flags |= (1 << RWNX_DEV_STARTED);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_channel_set(int channel)
|
|
{
|
|
bl_send_channel_set_req(&wifi_hw, channel);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_monitor_channel_set(int channel, int use_40MHZ)
|
|
{
|
|
struct mm_monitor_channel_cfm cfm;
|
|
|
|
bl_send_monitor_channel_set(&wifi_hw, &cfm, channel, use_40MHZ);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_if_remove(uint8_t vif_index)
|
|
{
|
|
os_printf("[WF] MM_REMOVE_IF_REQ Sending with vif_index %u...\r\n", vif_index);
|
|
bl_send_remove_if(&wifi_hw, vif_index);
|
|
os_printf("[WF] MM_REMOVE_IF_REQ Done\r\n");
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_raw_send(uint8_t *pkt , int len)
|
|
{
|
|
return bl_send_scanu_raw_send(&wifi_hw, pkt, len);
|
|
}
|
|
|
|
int bl_main_rate_config(uint8_t sta_idx, uint16_t fixed_rate_cfg)
|
|
{
|
|
return bl_send_me_rate_config_req(&wifi_hw, sta_idx, fixed_rate_cfg);
|
|
}
|
|
|
|
int bl_main_set_country_code(char *country_code)
|
|
{
|
|
blog_info("%s: country code: %s\r\n", __func__, country_code);
|
|
bl_msg_update_channel_cfg((const char *)country_code);
|
|
bl_send_me_chan_config_req(&wifi_hw);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_get_channel_nums()
|
|
{
|
|
return bl_msg_get_channel_nums();
|
|
}
|
|
|
|
int bl_main_if_add(int is_sta, struct netif *netif, uint8_t *vif_index)
|
|
{
|
|
struct mm_add_if_cfm add_if_cfm;
|
|
int error = 0;
|
|
|
|
os_printf("[WF] MM_ADD_IF_REQ Sending: %s\r\n", is_sta ? "STA" : "AP");
|
|
error = bl_send_add_if(
|
|
&wifi_hw,
|
|
netif->hwaddr,
|
|
is_sta ? NL80211_IFTYPE_STATION : NL80211_IFTYPE_AP,
|
|
false,
|
|
&add_if_cfm
|
|
);
|
|
os_printf("[WF] MM_ADD_IF_REQ Done\r\n");
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
if (add_if_cfm.status != 0) {
|
|
RWNX_PRINT_CFM_ERR(add_if);
|
|
return -EIO;
|
|
}
|
|
/* Save the index retrieved from LMAC */
|
|
if (is_sta) {
|
|
wifi_hw.vif_index_sta = add_if_cfm.inst_nbr;
|
|
} else {
|
|
wifi_hw.vif_index_ap = add_if_cfm.inst_nbr;
|
|
}
|
|
*vif_index = add_if_cfm.inst_nbr;
|
|
|
|
os_printf("[WF] vif_index from LAMC is %d\r\n", *vif_index);
|
|
wifi_hw.vif_table[add_if_cfm.inst_nbr].dev = netif;
|
|
wifi_hw.vif_table[add_if_cfm.inst_nbr].up = 1;
|
|
|
|
return error;
|
|
}
|
|
|
|
int bl_main_apm_start(char *ssid, char *password, int channel, uint8_t vif_index, uint8_t hidden_ssid)
|
|
{
|
|
int error = 0;
|
|
struct apm_start_cfm start_ap_cfm;
|
|
|
|
memset(&start_ap_cfm, 0, sizeof(start_ap_cfm));
|
|
os_printf("[WF] APM_START_REQ Sending with vif_index %u\r\n", vif_index);
|
|
error = bl_send_apm_start_req(&wifi_hw, &start_ap_cfm, ssid, password, channel, vif_index, hidden_ssid);
|
|
os_printf("[WF] APM_START_REQ Done\r\n");
|
|
os_printf("[WF] status is %02X\r\n", start_ap_cfm.status);
|
|
os_printf("[WF] vif_idx is %02X\r\n", start_ap_cfm.vif_idx);
|
|
os_printf("[WF] ch_idx is %02X\r\n", start_ap_cfm.ch_idx);
|
|
os_printf("[WF] bcmc_idx is %02X\r\n", start_ap_cfm.bcmc_idx);
|
|
wifi_hw.ap_bcmc_idx = start_ap_cfm.bcmc_idx;
|
|
|
|
return error;
|
|
}
|
|
|
|
int bl_main_apm_stop(uint8_t vif_index)
|
|
{
|
|
int error = 0;
|
|
|
|
os_printf("[WF] APM_STOP_REQ Sending with vif_index %u\r\n", vif_index);
|
|
error = bl_send_apm_stop_req(&wifi_hw, vif_index);
|
|
os_printf("[WF] APM_STOP_REQ Done\r\n");
|
|
|
|
return error;
|
|
}
|
|
|
|
int bl_main_apm_sta_cnt_get(uint8_t *sta_cnt)
|
|
{
|
|
struct bl_hw *bl_hw = &wifi_hw;
|
|
uint8_t cnt = 0, i;
|
|
struct bl_sta *sta;
|
|
uint8_t total_sta_cnt = sizeof(bl_hw->sta_table)/sizeof(bl_hw->sta_table[0]);
|
|
|
|
for (i = 0; i < total_sta_cnt; i++) {
|
|
sta = &(bl_hw->sta_table[i]);
|
|
if (0 == sta->is_used) {
|
|
/*empty entry*/
|
|
continue;
|
|
}
|
|
cnt++;
|
|
}
|
|
(*sta_cnt) = total_sta_cnt;
|
|
blog_info("Max limit sta cnt = %u, valid sta cnt = %u\r\n", total_sta_cnt, cnt);
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_apm_sta_info_get(struct wifi_apm_sta_info *apm_sta_info, uint8_t idx)
|
|
{
|
|
struct bl_hw *bl_hw = &wifi_hw;
|
|
struct bl_sta *sta;
|
|
|
|
sta = &(bl_hw->sta_table[idx]);
|
|
if (0 == sta->is_used) {
|
|
/*empty entry*/
|
|
return 0;
|
|
}
|
|
apm_sta_info->sta_idx = sta->sta_idx;
|
|
apm_sta_info->is_used = sta->is_used;
|
|
apm_sta_info->rssi = sta->rssi;
|
|
apm_sta_info->tsflo = sta->tsflo;
|
|
apm_sta_info->tsfhi = sta->tsfhi;
|
|
apm_sta_info->data_rate = sta->data_rate;
|
|
memcpy(apm_sta_info->sta_mac, sta->sta_addr.array, 6);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_apm_sta_delete(uint8_t sta_idx)
|
|
{
|
|
struct bl_hw *bl_hw = &wifi_hw;
|
|
struct bl_sta *sta;
|
|
struct apm_sta_del_cfm sta_del_cfm;
|
|
uint8_t vif_idx = 0;
|
|
|
|
sta = &(bl_hw->sta_table[sta_idx]);
|
|
if (sta == NULL)
|
|
return -1;
|
|
|
|
memset(&sta_del_cfm, 0, sizeof(struct apm_sta_del_cfm));
|
|
vif_idx = sta->vif_idx;
|
|
os_printf("[WF] APM_STA_DEL_REQ: sta_idx = %u, vif_idx = %u\r\n", sta_idx, vif_idx);
|
|
|
|
bl_send_apm_sta_del_req(bl_hw, &sta_del_cfm, sta_idx, vif_idx);
|
|
if (sta_del_cfm.status != 0) {
|
|
blog_info("del sta failure, cfm status = 0x%x\r\n", sta_del_cfm.status);
|
|
return -1;
|
|
}
|
|
|
|
memset(sta, 0, sizeof(struct bl_sta));
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_apm_remove_all_sta()
|
|
{
|
|
struct bl_hw *bl_hw = &wifi_hw;
|
|
struct bl_sta *sta;
|
|
uint8_t total_sta_cnt = sizeof(bl_hw->sta_table)/sizeof(bl_hw->sta_table[0]);
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < total_sta_cnt; i++) {
|
|
sta = &(bl_hw->sta_table[i]);
|
|
if (1 == sta->is_used) {
|
|
blog_info("del sta[%u]\r\n", i);
|
|
bl_main_apm_sta_delete(i);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int bl_main_conf_max_sta(uint8_t max_sta_supported)
|
|
{
|
|
return bl_send_apm_conf_max_sta_req(&wifi_hw, max_sta_supported);
|
|
}
|
|
|
|
int bl_main_cfg_task_req(uint32_t ops, uint32_t task, uint32_t element, uint32_t type, void *arg1, void *arg2)
|
|
{
|
|
return bl_send_cfg_task_req(&wifi_hw, ops, task, element, type, arg1, arg2);
|
|
}
|
|
|
|
int bl_main_scan()
|
|
{
|
|
bl_send_scanu_req(&wifi_hw);
|
|
return 0;
|
|
}
|
|
|
|
static int cfg80211_init(struct bl_hw *bl_hw)
|
|
{
|
|
int ret = 0;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
INIT_LIST_HEAD(&bl_hw->vifs);
|
|
|
|
bl_hw->mod_params = &bl_mod_params;
|
|
|
|
ret = bl_platform_on(bl_hw);
|
|
if (ret) {
|
|
os_printf("bl_platform_on Error\r\n");
|
|
goto err_out;
|
|
}
|
|
|
|
ipc_host_enable_irq(bl_hw->ipc_env, IPC_IRQ_E2A_ALL);
|
|
bl_wifi_enable_irq();
|
|
|
|
/* Reset FW */
|
|
ret = bl_send_reset(bl_hw);
|
|
if (ret) {
|
|
os_printf("bl_send_reset Error\r\n");
|
|
goto err_out;
|
|
}
|
|
os_thread_delay(5);
|
|
ret = bl_send_version_req(bl_hw, &bl_hw->version_cfm);
|
|
if (ret) {
|
|
goto err_out;
|
|
}
|
|
bl_set_vers(bl_hw);
|
|
ret = bl_handle_dynparams(bl_hw);
|
|
if (ret) {
|
|
os_printf("bl_handle_dynparams Error\r\n");
|
|
goto err_out;
|
|
}
|
|
|
|
/* Set parameters to firmware */
|
|
bl_send_me_config_req(bl_hw);
|
|
|
|
/* Set channel parameters to firmware (must be done after WiPHY registration) */
|
|
bl_send_me_chan_config_req(bl_hw);
|
|
|
|
|
|
bl_hw->status = RWNX_INTERFACE_STATUS_UP;
|
|
err_out:
|
|
RWNX_DBG(RWNX_FN_LEAVE_STR);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @scan: Request to do a scan. If returning zero, the scan request is given
|
|
* the driver, and will be valid until passed to cfg80211_scan_done().
|
|
* For scan results, call cfg80211_inform_bss(); you can call this outside
|
|
* the scan/scan_done bracket too.
|
|
*/
|
|
int bl_cfg80211_scan(struct bl_hw *bl_hw)
|
|
{
|
|
int error;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
error = bl_send_scanu_req(bl_hw);
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bl_cfg80211_connect(struct bl_hw *bl_hw, struct cfg80211_connect_params *sme)
|
|
{
|
|
struct sm_connect_cfm sm_connect_cfm;
|
|
int error = 0;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
/* Forward the information to the LMAC */
|
|
error = bl_send_sm_connect_req(bl_hw, sme, &sm_connect_cfm);
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
// Check the status
|
|
switch (sm_connect_cfm.status)
|
|
{
|
|
case CO_OK:
|
|
error = 0;
|
|
break;
|
|
case CO_BUSY:
|
|
error = -EINPROGRESS;
|
|
break;
|
|
case CO_OP_IN_PROGRESS:
|
|
error = -EALREADY;
|
|
break;
|
|
default:
|
|
error = -EIO;
|
|
break;
|
|
}
|
|
RWNX_DBG(RWNX_FN_LEAVE_STR);
|
|
|
|
return error;
|
|
}
|
|
|
|
int bl_cfg80211_disconnect(struct bl_hw *bl_hw, u16 reason_code)
|
|
{
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
return bl_send_sm_disconnect_req(bl_hw, reason_code);
|
|
}
|
|
|
|
void bl_main_event_handle()
|
|
{
|
|
bl_irq_bottomhalf(&wifi_hw);
|
|
bl_tx_try_flush();
|
|
}
|
|
|
|
void bl_main_lowlevel_init()
|
|
{
|
|
/*Call IRQ init here, since GroupEvent is used here*/
|
|
bl_irqs_init(&wifi_hw);
|
|
}
|
|
|
|
|
|
int bl_main_tx_still_free(void)
|
|
{
|
|
return ipc_host_txdesc_left(wifi_hw.ipc_env, 0, 0);
|
|
}
|
|
|
|
int bl_main_rtthread_start(struct bl_hw **bl_hw)
|
|
{
|
|
int ret;
|
|
|
|
/*start the bl606 wifi service*/
|
|
bl_main_lowlevel_init();
|
|
|
|
/*startup wifi firmware*/
|
|
*bl_hw = &wifi_hw;
|
|
ret = cfg80211_init(&wifi_hw);
|
|
//TODO check ret from cfg80211_init
|
|
ret = bl_open(*bl_hw);
|
|
return ret;
|
|
}
|