Skip to content

Commit

Permalink
brcmfmac: Unify methods to define and map firmware files.
Browse files Browse the repository at this point in the history
All bus drivers (sdio, usb and pcie) require firmware files which
needs to be downloaded to the device, The definitions and mapping
of device id and revision to firmware and nvram file is done by
each bus driver. This patch creates common functions and defines
to simplify and unify the definition of these firmware and nvram
files and mapping.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  • Loading branch information
Hante Meuleman authored and Kalle Valo committed Nov 30, 2015
1 parent b4fd63c commit 46d703a
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 317 deletions.
44 changes: 42 additions & 2 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */

char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
static char brcmf_firmware_path[BRCMF_FW_NAME_LEN];
module_param_string(alternative_fw_path, brcmf_firmware_path,
BRCMF_FW_PATH_LEN, 0440);
BRCMF_FW_NAME_LEN, 0440);

enum nvram_parser_state {
IDLE,
Expand Down Expand Up @@ -539,3 +539,43 @@ int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
0);
}

int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
struct brcmf_firmware_mapping mapping_table[],
u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
char nvram_name[BRCMF_FW_NAME_LEN])
{
u32 i;
char end;

for (i = 0; i < table_size; i++) {
if (mapping_table[i].chipid == chip &&
mapping_table[i].revmask & BIT(chiprev))
break;
}

if (i == table_size) {
brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev);
return -ENODEV;
}

/* check if firmware path is provided by module parameter */
if (brcmf_firmware_path[0] != '\0') {
strlcpy(fw_name, brcmf_firmware_path, BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram))
strlcpy(nvram_name, brcmf_firmware_path,
BRCMF_FW_NAME_LEN);

end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
if (end != '/') {
strlcat(fw_name, "/", BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram))
strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN);
}
}
strlcat(fw_name, mapping_table[i].fw, BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram))
strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN);

return 0;
}

46 changes: 43 additions & 3 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,51 @@
#define BRCMF_FW_REQ_FLAGS 0x00F0
#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010

#define BRCMF_FW_PATH_LEN 256
#define BRCMF_FW_NAME_LEN 32
#define BRCMF_FW_NAME_LEN 320

extern char brcmf_firmware_path[];
#define BRCMF_FW_DEFAULT_PATH "brcm/"

/**
* struct brcmf_firmware_mapping - Used to map chipid/revmask to firmware
* filename and nvram filename. Each bus type implementation should create
* a table of firmware mappings (using the macros defined below).
*
* @chipid: ID of chip.
* @revmask: bitmask of revisions, e.g. 0x10 means rev 4 only, 0xf means rev 0-3
* @fw: name of the firmware file.
* @nvram: name of nvram file.
*/
struct brcmf_firmware_mapping {
u32 chipid;
u32 revmask;
const char *fw;
const char *nvram;
};

#define BRCMF_FW_NVRAM_DEF(fw_nvram_name, fw, nvram) \
static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \
BRCMF_FW_DEFAULT_PATH fw; \
static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \
BRCMF_FW_DEFAULT_PATH nvram; \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH nvram)

#define BRCMF_FW_DEF(fw_name, fw) \
static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \
BRCMF_FW_DEFAULT_PATH fw; \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw) \

#define BRCMF_FW_NVRAM_ENTRY(chipid, mask, name) \
{ chipid, mask, \
BRCM_ ## name ## _FIRMWARE_NAME, BRCM_ ## name ## _NVRAM_NAME }

#define BRCMF_FW_ENTRY(chipid, mask, name) \
{ chipid, mask, BRCM_ ## name ## _FIRMWARE_NAME, NULL }

int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
struct brcmf_firmware_mapping mapping_table[],
u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
char nvram_name[BRCMF_FW_NAME_LEN]);
void brcmf_fw_nvram_free(void *nvram);
/*
* Request firmware(s) asynchronously. When the asynchronous request
Expand Down
149 changes: 29 additions & 120 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,29 @@ enum brcmf_pcie_state {
BRCMFMAC_PCIE_STATE_UP
};


#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin"
#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt"
#define BRCMF_PCIE_4350_FW_NAME "brcm/brcmfmac4350-pcie.bin"
#define BRCMF_PCIE_4350_NVRAM_NAME "brcm/brcmfmac4350-pcie.txt"
#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin"
#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt"
#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin"
#define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt"
#define BRCMF_PCIE_4358_FW_NAME "brcm/brcmfmac4358-pcie.bin"
#define BRCMF_PCIE_4358_NVRAM_NAME "brcm/brcmfmac4358-pcie.txt"
#define BRCMF_PCIE_4359_FW_NAME "brcm/brcmfmac4359-pcie.bin"
#define BRCMF_PCIE_4359_NVRAM_NAME "brcm/brcmfmac4359-pcie.txt"
#define BRCMF_PCIE_4365_FW_NAME "brcm/brcmfmac4365b-pcie.bin"
#define BRCMF_PCIE_4365_NVRAM_NAME "brcm/brcmfmac4365b-pcie.txt"
#define BRCMF_PCIE_4366_FW_NAME "brcm/brcmfmac4366b-pcie.bin"
#define BRCMF_PCIE_4366_NVRAM_NAME "brcm/brcmfmac4366b-pcie.txt"
#define BRCMF_PCIE_4371_FW_NAME "brcm/brcmfmac4371-pcie.bin"
#define BRCMF_PCIE_4371_NVRAM_NAME "brcm/brcmfmac4371-pcie.txt"
BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt");
BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt");
BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt");
BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt");
BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt");
BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt");
BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt");
BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");

static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFFFF, 4350),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFFF, 4366B),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
};

#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */

Expand Down Expand Up @@ -202,26 +206,6 @@ enum brcmf_pcie_state {
#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3


MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4350_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4350_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4359_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4359_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4365_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4365_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4366_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4366_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4371_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4371_NVRAM_NAME);


struct brcmf_pcie_console {
u32 base_addr;
u32 buf_addr;
Expand Down Expand Up @@ -258,8 +242,8 @@ struct brcmf_pciedev_info {
enum brcmf_pcie_state state;
bool in_irq;
struct pci_dev *pdev;
char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
char fw_name[BRCMF_FW_NAME_LEN];
char nvram_name[BRCMF_FW_NAME_LEN];
void __iomem *regs;
void __iomem *tcm;
u32 tcm_size;
Expand Down Expand Up @@ -1478,84 +1462,6 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
}


static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo)
{
char *fw_name;
char *nvram_name;
uint fw_len, nv_len;
char end;

brcmf_dbg(PCIE, "Enter, chip 0x%04x chiprev %d\n", devinfo->ci->chip,
devinfo->ci->chiprev);

switch (devinfo->ci->chip) {
case BRCM_CC_43602_CHIP_ID:
fw_name = BRCMF_PCIE_43602_FW_NAME;
nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
break;
case BRCM_CC_4350_CHIP_ID:
fw_name = BRCMF_PCIE_4350_FW_NAME;
nvram_name = BRCMF_PCIE_4350_NVRAM_NAME;
break;
case BRCM_CC_4356_CHIP_ID:
fw_name = BRCMF_PCIE_4356_FW_NAME;
nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
break;
case BRCM_CC_43567_CHIP_ID:
case BRCM_CC_43569_CHIP_ID:
case BRCM_CC_43570_CHIP_ID:
fw_name = BRCMF_PCIE_43570_FW_NAME;
nvram_name = BRCMF_PCIE_43570_NVRAM_NAME;
break;
case BRCM_CC_4358_CHIP_ID:
fw_name = BRCMF_PCIE_4358_FW_NAME;
nvram_name = BRCMF_PCIE_4358_NVRAM_NAME;
break;
case BRCM_CC_4359_CHIP_ID:
fw_name = BRCMF_PCIE_4359_FW_NAME;
nvram_name = BRCMF_PCIE_4359_NVRAM_NAME;
break;
case BRCM_CC_4365_CHIP_ID:
fw_name = BRCMF_PCIE_4365_FW_NAME;
nvram_name = BRCMF_PCIE_4365_NVRAM_NAME;
break;
case BRCM_CC_4366_CHIP_ID:
fw_name = BRCMF_PCIE_4366_FW_NAME;
nvram_name = BRCMF_PCIE_4366_NVRAM_NAME;
break;
case BRCM_CC_4371_CHIP_ID:
fw_name = BRCMF_PCIE_4371_FW_NAME;
nvram_name = BRCMF_PCIE_4371_NVRAM_NAME;
break;
default:
brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
return -ENODEV;
}

fw_len = sizeof(devinfo->fw_name) - 1;
nv_len = sizeof(devinfo->nvram_name) - 1;
/* check if firmware path is provided by module parameter */
if (brcmf_firmware_path[0] != '\0') {
strncpy(devinfo->fw_name, brcmf_firmware_path, fw_len);
strncpy(devinfo->nvram_name, brcmf_firmware_path, nv_len);
fw_len -= strlen(devinfo->fw_name);
nv_len -= strlen(devinfo->nvram_name);

end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
if (end != '/') {
strncat(devinfo->fw_name, "/", fw_len);
strncat(devinfo->nvram_name, "/", nv_len);
fw_len--;
nv_len--;
}
}
strncat(devinfo->fw_name, fw_name, fw_len);
strncat(devinfo->nvram_name, nvram_name, nv_len);

return 0;
}


static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
const struct firmware *fw, void *nvram,
u32 nvram_len)
Expand Down Expand Up @@ -1891,7 +1797,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
dev_set_drvdata(&pdev->dev, bus);

ret = brcmf_pcie_get_fwnames(devinfo);
ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
devinfo->fw_name, devinfo->nvram_name);
if (ret)
goto fail_bus;

Expand Down
Loading

0 comments on commit 46d703a

Please sign in to comment.