Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PW_SID:922834] Expand firmware-name property to load specific #2055

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .checkpatch.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--summary-file
--show-types

--ignore UNKNOWN_COMMIT_ID
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on: [pull_request]

jobs:
ci:
runs-on: ubuntu-latest
name: CI for Pull Request
steps:
- name: Checkout the source code
uses: actions/checkout@v3
with:
path: src/src

- name: CI
uses: tedd-an/bzcafe@dev
with:
task: ci
base_folder: src
space: kernel
github_token: ${{ secrets.GITHUB_TOKEN }}
email_token: ${{ secrets.EMAIL_TOKEN }}
patchwork_token: ${{ secrets.PATCHWORK_TOKEN }}
patchwork_user: ${{ secrets.PATCHWORK_USER }}
36 changes: 36 additions & 0 deletions .github/workflows/sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Snyc

on:
schedule:
- cron: "*/30 * * * *"

jobs:
sync_repo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: master

- name: Sync Repo
uses: tedd-an/bzcafe@dev
with:
task: sync
upstream_repo: "https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git"
github_token: ${{ secrets.GITHUB_TOKEN }}

sync_patchwork:
needs: sync_repo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Sync Patchwork
uses: tedd-an/bzcafe@dev
with:
task: patchwork
space: kernel
github_token: ${{ secrets.ACTION_TOKEN }}
email_token: ${{ secrets.EMAIL_TOKEN }}
patchwork_token: ${{ secrets.PATCHWORK_TOKEN }}
patchwork_user: ${{ secrets.PATCHWORK_USER }}
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ properties:
max-speed: true

firmware-name:
description: specify the name of nvm firmware to load
minItems: 1
items:
- description: specify the name of nvm firmware to load
- description: specify the name of rampatch firmware to load

local-bd-address: true

Expand Down
195 changes: 128 additions & 67 deletions drivers/bluetooth/btqca.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);

static bool qca_filename_has_extension(const char *filename)
{
const char *suffix = strrchr(filename, '.');

/* File extensions require a dot, but not as the first or last character */
if (!suffix || suffix == filename || *(suffix + 1) == '\0')
return 0;

/* Avoid matching directories with names that look like files with extensions */
return !strchr(suffix, '/');
}

static bool qca_get_alt_nvm_file(char *filename, size_t max_size)
{
char fwname[64];
const char *suffix;

/* nvm file name has an extension, replace with .bin */
if (qca_filename_has_extension(filename)) {
suffix = strrchr(filename, '.');
strscpy(fwname, filename, suffix - filename + 1);
snprintf(fwname + (suffix - filename),
sizeof(fwname) - (suffix - filename), ".bin");
/* If nvm file is already the default one, return false to skip the retry. */
if (strcmp(fwname, filename) == 0)
return false;

snprintf(filename, max_size, "%s", fwname);
return true;
}
return false;
}

static int qca_tlv_check_data(struct hci_dev *hdev,
struct qca_fw_config *config,
u8 *fw_data, size_t fw_size,
Expand Down Expand Up @@ -564,6 +597,19 @@ static int qca_download_firmware(struct hci_dev *hdev,
config->fwname, ret);
return ret;
}
}
/* If the board-specific file is missing, try loading the default
* one, unless that was attempted already.
*/
else if (config->type == TLV_TYPE_NVM &&
qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
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);
Expand Down Expand Up @@ -700,39 +746,43 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *co
return 0;
}

static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
static void qca_get_nvm_name_by_board(char *fwname, size_t max_size,
const char *stem, enum qca_btsoc_type soc_type,
struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
{
const char *variant;
const char *prefix;

/* hsp gf chip */
if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
variant = "g";
else
variant = "";
/* Set the default value to variant and prefix */
variant = "";
prefix = "b";

if (bid == 0x0)
snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);
else
snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
}
if (soc_type == QCA_QCA2066)
prefix = "";

static inline void qca_get_nvm_name_generic(struct qca_fw_config *cfg,
const char *stem, u8 rom_ver, u16 bid)
{
if (bid == 0x0)
snprintf(cfg->fwname, sizeof(cfg->fwname), "qca/%snv%02x.bin", stem, rom_ver);
else if (bid & 0xff00)
snprintf(cfg->fwname, sizeof(cfg->fwname),
"qca/%snv%02x.b%x", stem, rom_ver, bid);
else
snprintf(cfg->fwname, sizeof(cfg->fwname),
"qca/%snv%02x.b%02x", stem, rom_ver, bid);
if (soc_type == QCA_WCN6855 || soc_type == QCA_QCA2066) {
/* If the chip is manufactured by GlobalFoundries */
if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
variant = "g";
}

if (rom_ver != 0) {
if (bid == 0x0 || bid == 0xffff)
snprintf(fwname, max_size, "qca/%s%02x%s.bin", stem, rom_ver, variant);
else
snprintf(fwname, max_size, "qca/%s%02x%s.%s%02x", stem, rom_ver,
variant, prefix, bid);
} else {
if (bid == 0x0 || bid == 0xffff)
snprintf(fwname, max_size, "qca/%s%s.bin", stem, variant);
else
snprintf(fwname, max_size, "qca/%s%s.%s%02x", stem, variant, prefix, bid);
}
}

int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
const char *firmware_name)
const char *firmware_name, const char *rampatch_name)
{
struct qca_fw_config config = {};
int err;
Expand Down Expand Up @@ -761,44 +811,48 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,

/* Download rampatch file */
config.type = TLV_TYPE_PATCH;
switch (soc_type) {
case QCA_WCN3990:
case QCA_WCN3991:
case QCA_WCN3998:
snprintf(config.fwname, sizeof(config.fwname),
"qca/crbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN3988:
snprintf(config.fwname, sizeof(config.fwname),
"qca/apbtfw%02x.tlv", rom_ver);
break;
case QCA_QCA2066:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hpbtfw%02x.tlv", rom_ver);
break;
case QCA_QCA6390:
snprintf(config.fwname, sizeof(config.fwname),
"qca/htbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN6750:
/* 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.mbn", rom_ver);
break;
case QCA_WCN6855:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hpbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN7850:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hmtbtfw%02x.tlv", rom_ver);
break;
default:
snprintf(config.fwname, sizeof(config.fwname),
"qca/rampatch_%08x.bin", soc_ver);
if (rampatch_name) {
snprintf(config.fwname, sizeof(config.fwname), "qca/%s", rampatch_name);
} else {
switch (soc_type) {
case QCA_WCN3990:
case QCA_WCN3991:
case QCA_WCN3998:
snprintf(config.fwname, sizeof(config.fwname),
"qca/crbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN3988:
snprintf(config.fwname, sizeof(config.fwname),
"qca/apbtfw%02x.tlv", rom_ver);
break;
case QCA_QCA2066:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hpbtfw%02x.tlv", rom_ver);
break;
case QCA_QCA6390:
snprintf(config.fwname, sizeof(config.fwname),
"qca/htbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN6750:
/* 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.mbn", rom_ver);
break;
case QCA_WCN6855:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hpbtfw%02x.tlv", rom_ver);
break;
case QCA_WCN7850:
snprintf(config.fwname, sizeof(config.fwname),
"qca/hmtbtfw%02x.tlv", rom_ver);
break;
default:
snprintf(config.fwname, sizeof(config.fwname),
"qca/rampatch_%08x.bin", soc_ver);
}
}

err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
Expand All @@ -816,8 +870,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
/* Download NVM configuration */
config.type = TLV_TYPE_NVM;
if (firmware_name) {
snprintf(config.fwname, sizeof(config.fwname),
"qca/%s", firmware_name);
/* The firmware name has an extension, use it directly */
if (qca_filename_has_extension(firmware_name)) {
snprintf(config.fwname, sizeof(config.fwname), "qca/%s", firmware_name);
} else {
qca_read_fw_board_id(hdev, &boardid);
qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
firmware_name, soc_type, ver, 0, boardid);
}
} else {
switch (soc_type) {
case QCA_WCN3990:
Expand All @@ -836,8 +896,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
"qca/apnv%02x.bin", rom_ver);
break;
case QCA_QCA2066:
qca_generate_hsp_nvm_name(config.fwname,
sizeof(config.fwname), ver, rom_ver, boardid);
qca_get_nvm_name_by_board(config.fwname,
sizeof(config.fwname), "hpnv", soc_type, ver,
rom_ver, boardid);
break;
case QCA_QCA6390:
snprintf(config.fwname, sizeof(config.fwname),
Expand All @@ -852,9 +913,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
"qca/hpnv%02x.bin", rom_ver);
break;
case QCA_WCN7850:
qca_get_nvm_name_generic(&config, "hmt", rom_ver, boardid);
qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
"hmtnv", soc_type, ver, rom_ver, boardid);
break;

default:
snprintf(config.fwname, sizeof(config.fwname),
"qca/nvm_%08x.bin", soc_ver);
Expand Down
5 changes: 3 additions & 2 deletions drivers/bluetooth/btqca.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ enum qca_btsoc_type {
int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
const char *firmware_name);
const char *firmware_name, const char *rampatch_name);
int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
enum qca_btsoc_type);
int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
Expand All @@ -176,7 +176,8 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad
static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
enum qca_btsoc_type soc_type,
struct qca_btsoc_version ver,
const char *firmware_name)
const char *firmware_name,
const char *rampatch_name)
{
return -EOPNOTSUPP;
}
Expand Down
Loading
Loading