nfp: fail probe if serial or interface id is missing
On some platforms with broken ACPI tables we may not have access to the Serial Number PCIe capability. This capability is crucial for us for switchdev operation as we use serial number as switch ID, and for communication with management FW where interface ID is used. If we can't determine the Serial Number we have to fail device probe. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f055a9dfee
commit
18aa5b180f
|
@ -1248,7 +1248,7 @@ static void nfp6000_free(struct nfp_cpp *cpp)
|
|||
kfree(nfp);
|
||||
}
|
||||
|
||||
static void nfp6000_read_serial(struct device *dev, u8 *serial)
|
||||
static int nfp6000_read_serial(struct device *dev, u8 *serial)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int pos;
|
||||
|
@ -1256,25 +1256,29 @@ static void nfp6000_read_serial(struct device *dev, u8 *serial)
|
|||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN);
|
||||
if (!pos) {
|
||||
memset(serial, 0, NFP_SERIAL_LEN);
|
||||
return;
|
||||
dev_err(dev, "can't find PCIe Serial Number Capability\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pci_read_config_dword(pdev, pos + 4, ®);
|
||||
put_unaligned_be16(reg >> 16, serial + 4);
|
||||
pci_read_config_dword(pdev, pos + 8, ®);
|
||||
put_unaligned_be32(reg, serial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 nfp6000_get_interface(struct device *dev)
|
||||
static int nfp6000_get_interface(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int pos;
|
||||
u32 reg;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN);
|
||||
if (!pos)
|
||||
return NFP_CPP_INTERFACE(NFP_CPP_INTERFACE_TYPE_PCI, 0, 0xff);
|
||||
if (!pos) {
|
||||
dev_err(dev, "can't find PCIe Serial Number Capability\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pci_read_config_dword(pdev, pos + 4, ®);
|
||||
|
||||
|
|
|
@ -364,8 +364,8 @@ struct nfp_cpp_operations {
|
|||
int (*init)(struct nfp_cpp *cpp);
|
||||
void (*free)(struct nfp_cpp *cpp);
|
||||
|
||||
void (*read_serial)(struct device *dev, u8 *serial);
|
||||
u16 (*get_interface)(struct device *dev);
|
||||
int (*read_serial)(struct device *dev, u8 *serial);
|
||||
int (*get_interface)(struct device *dev);
|
||||
|
||||
int (*area_init)(struct nfp_cpp_area *area,
|
||||
u32 dest, unsigned long long address,
|
||||
|
|
|
@ -1163,10 +1163,10 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
|
|||
{
|
||||
const u32 arm = NFP_CPP_ID(NFP_CPP_TARGET_ARM, NFP_CPP_ACTION_RW, 0);
|
||||
struct nfp_cpp *cpp;
|
||||
int ifc, err;
|
||||
u32 mask[2];
|
||||
u32 xpbaddr;
|
||||
size_t tgt;
|
||||
int err;
|
||||
|
||||
cpp = kzalloc(sizeof(*cpp), GFP_KERNEL);
|
||||
if (!cpp) {
|
||||
|
@ -1176,9 +1176,19 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
|
|||
|
||||
cpp->op = ops;
|
||||
cpp->priv = priv;
|
||||
cpp->interface = ops->get_interface(parent);
|
||||
if (ops->read_serial)
|
||||
ops->read_serial(parent, cpp->serial);
|
||||
|
||||
ifc = ops->get_interface(parent);
|
||||
if (ifc < 0) {
|
||||
err = ifc;
|
||||
goto err_free_cpp;
|
||||
}
|
||||
cpp->interface = ifc;
|
||||
if (ops->read_serial) {
|
||||
err = ops->read_serial(parent, cpp->serial);
|
||||
if (err)
|
||||
goto err_free_cpp;
|
||||
}
|
||||
|
||||
rwlock_init(&cpp->resource_lock);
|
||||
init_waitqueue_head(&cpp->waitq);
|
||||
lockdep_set_class(&cpp->resource_lock, &nfp_cpp_resource_lock_key);
|
||||
|
@ -1191,7 +1201,7 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
|
|||
err = device_register(&cpp->dev);
|
||||
if (err < 0) {
|
||||
put_device(&cpp->dev);
|
||||
goto err_dev;
|
||||
goto err_free_cpp;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&cpp->dev, cpp);
|
||||
|
@ -1238,7 +1248,7 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
|
|||
|
||||
err_out:
|
||||
device_unregister(&cpp->dev);
|
||||
err_dev:
|
||||
err_free_cpp:
|
||||
kfree(cpp);
|
||||
err_malloc:
|
||||
return ERR_PTR(err);
|
||||
|
|
Loading…
Reference in New Issue