wlcore/wl12xx: add hw_init operation
Move all the wl12xx-specific hw initialization procedures into a new hw_init op. Move some commands and ACX functions to wl12xx. Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
f83985bb5f
commit
9d68d1eea7
13 changed files with 499 additions and 405 deletions
|
@ -1,3 +1,3 @@
|
|||
wl12xx-objs = main.o
|
||||
wl12xx-objs = main.o cmd.o acx.o
|
||||
|
||||
obj-$(CONFIG_WL12XX) += wl12xx.o
|
||||
|
|
53
drivers/net/wireless/ti/wl12xx/acx.c
Normal file
53
drivers/net/wireless/ti/wl12xx/acx.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* This file is part of wl12xx
|
||||
*
|
||||
* Copyright (C) 2008-2009 Nokia Corporation
|
||||
* Copyright (C) 2011 Texas Instruments Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wlcore/cmd.h"
|
||||
#include "../wlcore/debug.h"
|
||||
#include "../wlcore/acx.h"
|
||||
|
||||
#include "acx.h"
|
||||
|
||||
int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
|
||||
{
|
||||
struct wl1271_acx_host_config_bitmap *bitmap_conf;
|
||||
int ret;
|
||||
|
||||
bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
|
||||
if (!bitmap_conf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
|
||||
bitmap_conf, sizeof(*bitmap_conf));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(bitmap_conf);
|
||||
|
||||
return ret;
|
||||
}
|
36
drivers/net/wireless/ti/wl12xx/acx.h
Normal file
36
drivers/net/wireless/ti/wl12xx/acx.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of wl12xx
|
||||
*
|
||||
* Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __WL12XX_ACX_H__
|
||||
#define __WL12XX_ACX_H__
|
||||
|
||||
#include "../wlcore/wlcore.h"
|
||||
|
||||
struct wl1271_acx_host_config_bitmap {
|
||||
struct acx_header header;
|
||||
|
||||
__le32 host_cfg_bitmap;
|
||||
} __packed;
|
||||
|
||||
int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
|
||||
|
||||
#endif /* __WL12XX_ACX_H__ */
|
252
drivers/net/wireless/ti/wl12xx/cmd.c
Normal file
252
drivers/net/wireless/ti/wl12xx/cmd.c
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* This file is part of wl12xx
|
||||
*
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Copyright (C) 2011 Texas Instruments Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wlcore/cmd.h"
|
||||
#include "../wlcore/debug.h"
|
||||
|
||||
#include "cmd.h"
|
||||
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
|
||||
struct conf_rf_settings *rf = &wl->conf.rf;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
|
||||
if (!ext_radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
|
||||
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
|
||||
rf->tx_per_channel_power_compensation_2,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_2);
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
|
||||
rf->tx_per_channel_power_compensation_5,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_5);
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
|
||||
ext_radio_parms, sizeof(*ext_radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
|
||||
|
||||
kfree(ext_radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_general_parms_cmd *gen_parms;
|
||||
struct wl1271_ini_general_params *gp =
|
||||
&((struct wl1271_nvs_file *)wl->nvs)->general_params;
|
||||
bool answer = false;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from INI out of bounds");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
|
||||
|
||||
memcpy(&gen_parms->general_params, gp, sizeof(*gp));
|
||||
|
||||
if (gp->tx_bip_fem_auto_detect)
|
||||
answer = true;
|
||||
|
||||
/* Override the REF CLK from the NVS with the one from platform data */
|
||||
gen_parms->general_params.ref_clock = wl->ref_clock;
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from FW out of bounds");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
out:
|
||||
kfree(gen_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl128x_cmd_general_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl128x_general_parms_cmd *gen_parms;
|
||||
struct wl128x_ini_general_params *gp =
|
||||
&((struct wl128x_nvs_file *)wl->nvs)->general_params;
|
||||
bool answer = false;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from ini out of bounds");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
|
||||
|
||||
memcpy(&gen_parms->general_params, gp, sizeof(*gp));
|
||||
|
||||
if (gp->tx_bip_fem_auto_detect)
|
||||
answer = true;
|
||||
|
||||
/* Replace REF and TCXO CLKs with the ones from platform data */
|
||||
gen_parms->general_params.ref_clock = wl->ref_clock;
|
||||
gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from FW out of bounds");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
out:
|
||||
kfree(gen_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
|
||||
struct wl1271_radio_parms_cmd *radio_parms;
|
||||
struct wl1271_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
|
||||
if (!radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl1271_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl1271_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
memcpy(&radio_parms->static_params_5,
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl1271_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl1271_ini_fem_params_5));
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
|
||||
radio_parms, sizeof(*radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
|
||||
|
||||
kfree(radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl128x_cmd_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
|
||||
struct wl128x_radio_parms_cmd *radio_parms;
|
||||
struct wl128x_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
|
||||
if (!radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl128x_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl128x_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
memcpy(&radio_parms->static_params_5,
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl128x_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl128x_ini_fem_params_5));
|
||||
|
||||
radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
|
||||
radio_parms, sizeof(*radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
|
||||
|
||||
kfree(radio_parms);
|
||||
return ret;
|
||||
}
|
110
drivers/net/wireless/ti/wl12xx/cmd.h
Normal file
110
drivers/net/wireless/ti/wl12xx/cmd.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This file is part of wl12xx
|
||||
*
|
||||
* Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __WL12XX_CMD_H__
|
||||
#define __WL12XX_CMD_H__
|
||||
|
||||
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
|
||||
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
|
||||
|
||||
struct wl1271_general_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
struct wl1271_ini_general_params general_params;
|
||||
|
||||
u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
|
||||
u8 sr_sen_n_p;
|
||||
u8 sr_sen_n_p_gain;
|
||||
u8 sr_sen_nrn;
|
||||
u8 sr_sen_prn;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
struct wl128x_general_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
struct wl128x_ini_general_params general_params;
|
||||
|
||||
u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
|
||||
u8 sr_sen_n_p;
|
||||
u8 sr_sen_n_p_gain;
|
||||
u8 sr_sen_nrn;
|
||||
u8 sr_sen_prn;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
struct wl1271_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
/* Static radio parameters */
|
||||
struct wl1271_ini_band_params_2 static_params_2;
|
||||
struct wl1271_ini_band_params_5 static_params_5;
|
||||
|
||||
/* Dynamic radio parameters */
|
||||
struct wl1271_ini_fem_params_2 dyn_params_2;
|
||||
u8 padding2;
|
||||
struct wl1271_ini_fem_params_5 dyn_params_5;
|
||||
u8 padding3[2];
|
||||
} __packed;
|
||||
|
||||
struct wl128x_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
/* Static radio parameters */
|
||||
struct wl128x_ini_band_params_2 static_params_2;
|
||||
struct wl128x_ini_band_params_5 static_params_5;
|
||||
|
||||
u8 fem_vendor_and_options;
|
||||
|
||||
/* Dynamic radio parameters */
|
||||
struct wl128x_ini_fem_params_2 dyn_params_2;
|
||||
u8 padding2;
|
||||
struct wl128x_ini_fem_params_5 dyn_params_5;
|
||||
} __packed;
|
||||
|
||||
#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
|
||||
|
||||
struct wl1271_ext_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
|
||||
u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl);
|
||||
int wl128x_cmd_general_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_radio_parms(struct wl1271 *wl);
|
||||
int wl128x_cmd_radio_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
|
||||
|
||||
#endif /* __WL12XX_CMD_H__ */
|
|
@ -36,6 +36,8 @@
|
|||
#include "../wlcore/boot.h"
|
||||
|
||||
#include "reg.h"
|
||||
#include "cmd.h"
|
||||
#include "acx.h"
|
||||
|
||||
#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
|
||||
#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
|
||||
|
@ -800,6 +802,43 @@ static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
|
|||
wl1271_tx_complete(wl);
|
||||
}
|
||||
|
||||
static int wl12xx_hw_init(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||
u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
|
||||
|
||||
ret = wl128x_cmd_general_parms(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = wl128x_cmd_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
|
||||
/* Enable SDIO padding */
|
||||
host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
|
||||
|
||||
/* Must be before wl1271_acx_init_mem_config() */
|
||||
ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
} else {
|
||||
ret = wl1271_cmd_general_parms(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = wl1271_cmd_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = wl1271_cmd_ext_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
|
||||
{
|
||||
bool supported = false;
|
||||
|
@ -875,6 +914,7 @@ static struct wlcore_ops wl12xx_ops = {
|
|||
.get_rx_packet_len = wl12xx_get_rx_packet_len,
|
||||
.tx_immediate_compl = NULL,
|
||||
.tx_delayed_compl = wl12xx_tx_delayed_compl,
|
||||
.hw_init = wl12xx_hw_init,
|
||||
.get_pg_ver = wl12xx_get_pg_ver,
|
||||
.get_mac = wl12xx_get_mac,
|
||||
};
|
||||
|
|
|
@ -997,32 +997,6 @@ int wl12xx_acx_mem_cfg(struct wl1271 *wl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
|
||||
{
|
||||
struct wl1271_acx_host_config_bitmap *bitmap_conf;
|
||||
int ret;
|
||||
|
||||
bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
|
||||
if (!bitmap_conf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
|
||||
bitmap_conf, sizeof(*bitmap_conf));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(bitmap_conf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_init_mem_config(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -824,16 +824,11 @@ struct wl1271_acx_keep_alive_config {
|
|||
__le32 period;
|
||||
} __packed;
|
||||
|
||||
/* TODO: maybe this needs to be moved somewhere else? */
|
||||
#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
|
||||
#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
|
||||
#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
|
||||
|
||||
struct wl1271_acx_host_config_bitmap {
|
||||
struct acx_header header;
|
||||
|
||||
__le32 host_cfg_bitmap;
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
WL1271_ACX_TRIG_TYPE_LEVEL = 0,
|
||||
WL1271_ACX_TRIG_TYPE_EDGE,
|
||||
|
@ -1274,7 +1269,6 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
|
|||
int wl1271_acx_tx_config_options(struct wl1271 *wl);
|
||||
int wl12xx_acx_mem_cfg(struct wl1271 *wl);
|
||||
int wl1271_acx_init_mem_config(struct wl1271 *wl);
|
||||
int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
|
||||
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
|
||||
int wl1271_acx_smart_reflex(struct wl1271 *wl);
|
||||
int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
|
|
|
@ -112,232 +112,6 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_general_parms_cmd *gen_parms;
|
||||
struct wl1271_ini_general_params *gp =
|
||||
&((struct wl1271_nvs_file *)wl->nvs)->general_params;
|
||||
bool answer = false;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from INI out of bounds");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
|
||||
|
||||
memcpy(&gen_parms->general_params, gp, sizeof(*gp));
|
||||
|
||||
if (gp->tx_bip_fem_auto_detect)
|
||||
answer = true;
|
||||
|
||||
/* Override the REF CLK from the NVS with the one from platform data */
|
||||
gen_parms->general_params.ref_clock = wl->ref_clock;
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from FW out of bounds");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
out:
|
||||
kfree(gen_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl128x_cmd_general_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl128x_general_parms_cmd *gen_parms;
|
||||
struct wl128x_ini_general_params *gp =
|
||||
&((struct wl128x_nvs_file *)wl->nvs)->general_params;
|
||||
bool answer = false;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from ini out of bounds");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
|
||||
|
||||
memcpy(&gen_parms->general_params, gp, sizeof(*gp));
|
||||
|
||||
if (gp->tx_bip_fem_auto_detect)
|
||||
answer = true;
|
||||
|
||||
/* Replace REF and TCXO CLKs with the ones from platform data */
|
||||
gen_parms->general_params.ref_clock = wl->ref_clock;
|
||||
gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
wl1271_warning("FEM index from FW out of bounds");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
out:
|
||||
kfree(gen_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
|
||||
struct wl1271_radio_parms_cmd *radio_parms;
|
||||
struct wl1271_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
|
||||
if (!radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl1271_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl1271_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
memcpy(&radio_parms->static_params_5,
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl1271_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl1271_ini_fem_params_5));
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
|
||||
radio_parms, sizeof(*radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
|
||||
|
||||
kfree(radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl128x_cmd_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
|
||||
struct wl128x_radio_parms_cmd *radio_parms;
|
||||
struct wl128x_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
|
||||
if (!radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl128x_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl128x_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
memcpy(&radio_parms->static_params_5,
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl128x_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
sizeof(struct wl128x_ini_fem_params_5));
|
||||
|
||||
radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
|
||||
radio_parms, sizeof(*radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
|
||||
|
||||
kfree(radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
|
||||
struct conf_rf_settings *rf = &wl->conf.rf;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
|
||||
if (!ext_radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
|
||||
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
|
||||
rf->tx_per_channel_power_compensation_2,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_2);
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
|
||||
rf->tx_per_channel_power_compensation_5,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_5);
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
|
||||
ext_radio_parms, sizeof(*ext_radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
|
||||
|
||||
kfree(ext_radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll the mailbox event field until any of the bits in the mask is set or a
|
||||
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
|
||||
|
@ -913,6 +687,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wl1271_cmd_test);
|
||||
|
||||
/**
|
||||
* read acx from firmware
|
||||
|
@ -969,6 +744,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
|
||||
|
||||
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
|
||||
{
|
||||
|
|
|
@ -31,11 +31,6 @@ struct acx_header;
|
|||
|
||||
int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
|
||||
size_t res_len);
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl);
|
||||
int wl128x_cmd_general_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_radio_parms(struct wl1271 *wl);
|
||||
int wl128x_cmd_radio_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
|
||||
int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
|
||||
u8 *role_id);
|
||||
int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
|
||||
|
@ -494,83 +489,6 @@ enum wl1271_channel_tune_bands {
|
|||
|
||||
#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
|
||||
|
||||
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
|
||||
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
|
||||
#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
|
||||
|
||||
struct wl1271_general_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
struct wl1271_ini_general_params general_params;
|
||||
|
||||
u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
|
||||
u8 sr_sen_n_p;
|
||||
u8 sr_sen_n_p_gain;
|
||||
u8 sr_sen_nrn;
|
||||
u8 sr_sen_prn;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
struct wl128x_general_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
struct wl128x_ini_general_params general_params;
|
||||
|
||||
u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
|
||||
u8 sr_sen_n_p;
|
||||
u8 sr_sen_n_p_gain;
|
||||
u8 sr_sen_nrn;
|
||||
u8 sr_sen_prn;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
struct wl1271_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
/* Static radio parameters */
|
||||
struct wl1271_ini_band_params_2 static_params_2;
|
||||
struct wl1271_ini_band_params_5 static_params_5;
|
||||
|
||||
/* Dynamic radio parameters */
|
||||
struct wl1271_ini_fem_params_2 dyn_params_2;
|
||||
u8 padding2;
|
||||
struct wl1271_ini_fem_params_5 dyn_params_5;
|
||||
u8 padding3[2];
|
||||
} __packed;
|
||||
|
||||
struct wl128x_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
/* Static radio parameters */
|
||||
struct wl128x_ini_band_params_2 static_params_2;
|
||||
struct wl128x_ini_band_params_5 static_params_5;
|
||||
|
||||
u8 fem_vendor_and_options;
|
||||
|
||||
/* Dynamic radio parameters */
|
||||
struct wl128x_ini_fem_params_2 dyn_params_2;
|
||||
u8 padding2;
|
||||
struct wl128x_ini_fem_params_5 dyn_params_5;
|
||||
} __packed;
|
||||
|
||||
struct wl1271_ext_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
|
||||
u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* There are three types of disconnections:
|
||||
*
|
||||
|
|
|
@ -493,26 +493,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
|||
return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
|
||||
}
|
||||
|
||||
int wl1271_chip_specific_init(struct wl1271 *wl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||
u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
|
||||
|
||||
if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
|
||||
/* Enable SDIO padding */
|
||||
host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
|
||||
|
||||
/* Must be before wl1271_acx_init_mem_config() */
|
||||
ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vif-specifc initialization */
|
||||
static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
{
|
||||
|
@ -665,27 +645,8 @@ int wl1271_hw_init(struct wl1271 *wl)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||
ret = wl128x_cmd_general_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = wl128x_cmd_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = wl1271_cmd_general_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = wl1271_cmd_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = wl1271_cmd_ext_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Chip-specific init */
|
||||
ret = wl1271_chip_specific_init(wl);
|
||||
/* Chip-specific hw init */
|
||||
ret = wl->ops->hw_init(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -672,28 +672,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20)
|
||||
ret = wl128x_cmd_general_parms(wl);
|
||||
else
|
||||
ret = wl1271_cmd_general_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20)
|
||||
ret = wl128x_cmd_radio_parms(wl);
|
||||
else
|
||||
ret = wl1271_cmd_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (wl->chip.id != CHIP_ID_1283_PG20) {
|
||||
ret = wl1271_cmd_ext_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Chip-specific initializations */
|
||||
ret = wl1271_chip_specific_init(wl);
|
||||
ret = wl->ops->hw_init(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ struct wlcore_ops {
|
|||
u32 data_len);
|
||||
void (*tx_delayed_compl)(struct wl1271 *wl);
|
||||
void (*tx_immediate_compl)(struct wl1271 *wl);
|
||||
int (*hw_init)(struct wl1271 *wl);
|
||||
s8 (*get_pg_ver)(struct wl1271 *wl);
|
||||
void (*get_mac)(struct wl1271 *wl);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue