Commit 122323f7 authored by David S. Miller's avatar David S. Miller

Merge branch 'nfp-extend-firmware-request-logic'

Jakub Kicinski says:

====================
nfp: extend firmware request logic

We have been pondering for some time how to support loading different
application firmwares onto NFP.  We want to support both users selecting
one of the firmware images provided by Netronome (which are optimized
for different use cases each) as well as firmware images created  by
users themselves or other companies.

In the end we decided to go with the simplest solution - depending on
the right firmware image being placed in /lib/firmware.  This vastly
simplifies driver logic and also doesn't require any new API.

Different NICs on one system may want to run different applications
therefore we first try to load firmware specific to the device (by
serial number of PCI slot) and if not present try the device model
based name we have been using so far.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 53d56f79 1680a370
...@@ -174,6 +174,21 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -174,6 +174,21 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
return nfp_pcie_sriov_enable(pdev, num_vfs); return nfp_pcie_sriov_enable(pdev, num_vfs);
} }
static const struct firmware *
nfp_net_fw_request(struct pci_dev *pdev, struct nfp_pf *pf, const char *name)
{
const struct firmware *fw = NULL;
int err;
err = request_firmware_direct(&fw, name, &pdev->dev);
nfp_info(pf->cpp, " %s: %s\n",
name, err ? "not found" : "found, loading...");
if (err)
return NULL;
return fw;
}
/** /**
* nfp_net_fw_find() - Find the correct firmware image for netdev mode * nfp_net_fw_find() - Find the correct firmware image for netdev mode
* @pdev: PCI Device structure * @pdev: PCI Device structure
...@@ -184,13 +199,32 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -184,13 +199,32 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
static const struct firmware * static const struct firmware *
nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf) nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
{ {
const struct firmware *fw = NULL;
struct nfp_eth_table_port *port; struct nfp_eth_table_port *port;
const struct firmware *fw;
const char *fw_model; const char *fw_model;
char fw_name[256]; char fw_name[256];
int spc, err = 0; const u8 *serial;
int i, j; u16 interface;
int spc, i, j;
nfp_info(pf->cpp, "Looking for firmware file in order of priority:\n");
/* First try to find a firmware image specific for this device */
interface = nfp_cpp_interface(pf->cpp);
nfp_cpp_serial(pf->cpp, &serial);
sprintf(fw_name, "netronome/serial-%pMF-%02hhx-%02hhx.nffw",
serial, interface >> 8, interface & 0xff);
fw = nfp_net_fw_request(pdev, pf, fw_name);
if (fw)
return fw;
/* Then try the PCI name */
sprintf(fw_name, "netronome/pci-%s.nffw", pci_name(pdev));
fw = nfp_net_fw_request(pdev, pf, fw_name);
if (fw)
return fw;
/* Finally try the card type and media */
if (!pf->eth_tbl) { if (!pf->eth_tbl) {
dev_err(&pdev->dev, "Error: can't identify media config\n"); dev_err(&pdev->dev, "Error: can't identify media config\n");
return NULL; return NULL;
...@@ -223,13 +257,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf) ...@@ -223,13 +257,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
if (spc <= 0) if (spc <= 0)
return NULL; return NULL;
err = request_firmware(&fw, fw_name, &pdev->dev); return nfp_net_fw_request(pdev, pf, fw_name);
if (err)
return NULL;
dev_info(&pdev->dev, "Loading FW image: %s\n", fw_name);
return fw;
} }
/** /**
......
...@@ -704,7 +704,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf) ...@@ -704,7 +704,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (!pf->rtbl) { if (!pf->rtbl) {
nfp_err(pf->cpp, "No %s, giving up.\n", nfp_err(pf->cpp, "No %s, giving up.\n",
pf->fw_loaded ? "symbol table" : "firmware found"); pf->fw_loaded ? "symbol table" : "firmware found");
return -EPROBE_DEFER; return -EINVAL;
} }
mutex_lock(&pf->lock); mutex_lock(&pf->lock);
......
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