Commit 255ca28a authored by Andrejs Cainikovs's avatar Andrejs Cainikovs Committed by Kalle Valo

mwifiex: Select firmware based on strapping

Some WiFi/Bluetooth modules might have different host connection
options, allowing to either use SDIO for both WiFi and Bluetooth,
or SDIO for WiFi and UART for Bluetooth. It is possible to detect
whether a module has SDIO-SDIO or SDIO-UART connection by reading
its host strap register.

This change introduces a way to automatically select appropriate
firmware depending of the connection method, and removes a need
of symlinking or overwriting the original firmware file with a
required one.

Host strap register used in this commit comes from the NXP driver [1]
hosted at Code Aurora.

[1] https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c?h=rel_imx_5.4.70_2.3.2&id=688b67b2c7220b01521ffe560da7eee33042c7bd#n1274Signed-off-by: default avatarAndrejs Cainikovs <andrejs.cainikovs@toradex.com>
Reviewed-by: default avatarAlvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220422090313.125857-2-andrejs.cainikovs@toradex.com
parent 68d57a07
...@@ -182,6 +182,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8997 = { ...@@ -182,6 +182,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8997 = {
.host_int_rsr_reg = 0x4, .host_int_rsr_reg = 0x4,
.host_int_status_reg = 0x0C, .host_int_status_reg = 0x0C,
.host_int_mask_reg = 0x08, .host_int_mask_reg = 0x08,
.host_strap_reg = 0xF4,
.host_strap_mask = 0x01,
.host_strap_value = 0x00,
.status_reg_0 = 0xE8, .status_reg_0 = 0xE8,
.status_reg_1 = 0xE9, .status_reg_1 = 0xE9,
.sdio_int_mask = 0xff, .sdio_int_mask = 0xff,
...@@ -283,6 +286,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8987 = { ...@@ -283,6 +286,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8987 = {
.host_int_rsr_reg = 0x4, .host_int_rsr_reg = 0x4,
.host_int_status_reg = 0x0C, .host_int_status_reg = 0x0C,
.host_int_mask_reg = 0x08, .host_int_mask_reg = 0x08,
.host_strap_reg = 0xF4,
.host_strap_mask = 0x01,
.host_strap_value = 0x00,
.status_reg_0 = 0xE8, .status_reg_0 = 0xE8,
.status_reg_1 = 0xE9, .status_reg_1 = 0xE9,
.sdio_int_mask = 0xff, .sdio_int_mask = 0xff,
...@@ -536,6 +542,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) ...@@ -536,6 +542,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
struct mwifiex_sdio_device *data = (void *)id->driver_data; struct mwifiex_sdio_device *data = (void *)id->driver_data;
card->firmware = data->firmware; card->firmware = data->firmware;
card->firmware_sdiouart = data->firmware_sdiouart;
card->reg = data->reg; card->reg = data->reg;
card->max_ports = data->max_ports; card->max_ports = data->max_ports;
card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
...@@ -2439,6 +2446,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) ...@@ -2439,6 +2446,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
int ret; int ret;
struct sdio_mmc_card *card = adapter->card; struct sdio_mmc_card *card = adapter->card;
struct sdio_func *func = card->func; struct sdio_func *func = card->func;
const char *firmware = card->firmware;
/* save adapter pointer in card */ /* save adapter pointer in card */
card->adapter = adapter; card->adapter = adapter;
...@@ -2455,7 +2463,18 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) ...@@ -2455,7 +2463,18 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
return ret; return ret;
} }
strcpy(adapter->fw_name, card->firmware); /* Select correct firmware (sdsd or sdiouart) firmware based on the strapping
* option
*/
if (card->firmware_sdiouart) {
u8 val;
mwifiex_read_reg(adapter, card->reg->host_strap_reg, &val);
if ((val & card->reg->host_strap_mask) == card->reg->host_strap_value)
firmware = card->firmware_sdiouart;
}
strcpy(adapter->fw_name, firmware);
if (card->fw_dump_enh) { if (card->fw_dump_enh) {
adapter->mem_type_mapping_tbl = generic_mem_type_map; adapter->mem_type_mapping_tbl = generic_mem_type_map;
adapter->num_mem_types = 1; adapter->num_mem_types = 1;
......
...@@ -196,6 +196,9 @@ struct mwifiex_sdio_card_reg { ...@@ -196,6 +196,9 @@ struct mwifiex_sdio_card_reg {
u8 host_int_rsr_reg; u8 host_int_rsr_reg;
u8 host_int_status_reg; u8 host_int_status_reg;
u8 host_int_mask_reg; u8 host_int_mask_reg;
u8 host_strap_reg;
u8 host_strap_mask;
u8 host_strap_value;
u8 status_reg_0; u8 status_reg_0;
u8 status_reg_1; u8 status_reg_1;
u8 sdio_int_mask; u8 sdio_int_mask;
...@@ -241,6 +244,7 @@ struct sdio_mmc_card { ...@@ -241,6 +244,7 @@ struct sdio_mmc_card {
struct completion fw_done; struct completion fw_done;
const char *firmware; const char *firmware;
const char *firmware_sdiouart;
const struct mwifiex_sdio_card_reg *reg; const struct mwifiex_sdio_card_reg *reg;
u8 max_ports; u8 max_ports;
u8 mp_agg_pkt_limit; u8 mp_agg_pkt_limit;
...@@ -274,6 +278,7 @@ struct sdio_mmc_card { ...@@ -274,6 +278,7 @@ struct sdio_mmc_card {
struct mwifiex_sdio_device { struct mwifiex_sdio_device {
const char *firmware; const char *firmware;
const char *firmware_sdiouart;
const struct mwifiex_sdio_card_reg *reg; const struct mwifiex_sdio_card_reg *reg;
u8 max_ports; u8 max_ports;
u8 mp_agg_pkt_limit; u8 mp_agg_pkt_limit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment