Skip to content

Commit

Permalink
Bluetooth: btqca: Add support for firmware image with mbn type for WC…
Browse files Browse the repository at this point in the history
…N6750

1. Added support to download firmware image with mbn type for wcn6750
   as it supports mbn type image.
2. If mbn type image is not present then check for tlv type image.
3. Added debug logs for mbn type image.

Signed-off-by: Venkata Lakshmi Narayana Gubba <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
  • Loading branch information
Venkata Lakshmi Narayana Gubba authored and holtmann committed Jun 26, 2021
1 parent d8f97da commit ecf6b2d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
69 changes: 52 additions & 17 deletions drivers/bluetooth/btqca.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);

static void qca_tlv_check_data(struct qca_fw_config *config,
static void qca_tlv_check_data(struct hci_dev *hdev,
struct qca_fw_config *config,
u8 *fw_data, enum qca_btsoc_type soc_type)
{
const u8 *data;
Expand All @@ -194,19 +195,21 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
struct tlv_type_nvm *tlv_nvm;
uint8_t nvm_baud_rate = config->user_baud_rate;

tlv = (struct tlv_type_hdr *)fw_data;

type_len = le32_to_cpu(tlv->type_len);
length = (type_len >> 8) & 0x00ffffff;

BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
BT_DBG("Length\t\t : %d bytes", length);

config->dnld_mode = QCA_SKIP_EVT_NONE;
config->dnld_type = QCA_SKIP_EVT_NONE;

switch (config->type) {
case ELF_TYPE_PATCH:
config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
config->dnld_type = QCA_SKIP_EVT_VSE_CC;

bt_dev_dbg(hdev, "File Class : 0x%x", fw_data[4]);
bt_dev_dbg(hdev, "Data Encoding : 0x%x", fw_data[5]);
bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]);
break;
case TLV_TYPE_PATCH:
tlv = (struct tlv_type_hdr *)fw_data;
type_len = le32_to_cpu(tlv->type_len);
tlv_patch = (struct tlv_type_patch *)tlv->data;

/* For Rome version 1.1 to 3.1, all segment commands
Expand All @@ -218,6 +221,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
config->dnld_mode = tlv_patch->download_mode;
config->dnld_type = config->dnld_mode;

BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
BT_DBG("Total Length : %d bytes",
le32_to_cpu(tlv_patch->total_size));
BT_DBG("Patch Data Length : %d bytes",
Expand All @@ -243,6 +247,14 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
break;

case TLV_TYPE_NVM:
tlv = (struct tlv_type_hdr *)fw_data;

type_len = le32_to_cpu(tlv->type_len);
length = (type_len >> 8) & 0x00ffffff;

BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
BT_DBG("Length\t\t : %d bytes", length);

idx = 0;
data = tlv->data;
while (idx < length) {
Expand Down Expand Up @@ -387,7 +399,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev)

static int qca_download_firmware(struct hci_dev *hdev,
struct qca_fw_config *config,
enum qca_btsoc_type soc_type)
enum qca_btsoc_type soc_type,
u8 rom_ver)
{
const struct firmware *fw;
u8 *data;
Expand All @@ -398,9 +411,27 @@ static int qca_download_firmware(struct hci_dev *hdev,

ret = request_firmware(&fw, config->fwname, &hdev->dev);
if (ret) {
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
return ret;
/* For WCN6750, if mbn file is not present then check for
* tlv file.
*/
if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) {
bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
config->type = TLV_TYPE_PATCH;
snprintf(config->fwname, sizeof(config->fwname),
"qca/msbtfw%02x.tlv", rom_ver);
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
ret = request_firmware(&fw, config->fwname, &hdev->dev);
if (ret) {
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
return ret;
}
} else {
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
return ret;
}
}

size = fw->size;
Expand All @@ -415,7 +446,7 @@ static int qca_download_firmware(struct hci_dev *hdev,
memcpy(data, fw->data, size);
release_firmware(fw);

qca_tlv_check_data(config, data, soc_type);
qca_tlv_check_data(hdev, config, data, soc_type);

segment = data;
remain = size;
Expand Down Expand Up @@ -533,14 +564,18 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
} else if (soc_type == QCA_WCN6750) {
rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
(soc_ver & 0x0000000f);
/* Choose mbn file by default.If mbn file is not found
* then choose tlv file
*/
config.type = ELF_TYPE_PATCH;
snprintf(config.fwname, sizeof(config.fwname),
"qca/msbtfw%02x.tlv", rom_ver);
"qca/msbtfw%02x.mbn", rom_ver);
} else {
snprintf(config.fwname, sizeof(config.fwname),
"qca/rampatch_%08x.bin", soc_ver);
}

err = qca_download_firmware(hdev, &config, soc_type);
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
if (err < 0) {
bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
return err;
Expand Down Expand Up @@ -573,7 +608,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
snprintf(config.fwname, sizeof(config.fwname),
"qca/nvm_%08x.bin", soc_ver);

err = qca_download_firmware(hdev, &config, soc_type);
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
if (err < 0) {
bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
return err;
Expand Down
3 changes: 2 additions & 1 deletion drivers/bluetooth/btqca.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ enum qca_tlv_dnld_mode {

enum qca_tlv_type {
TLV_TYPE_PATCH = 1,
TLV_TYPE_NVM
TLV_TYPE_NVM,
ELF_TYPE_PATCH,
};

struct qca_fw_config {
Expand Down

0 comments on commit ecf6b2d

Please sign in to comment.