octeon_ep: defer probe if firmware not ready
authorVeerasenareddy Burru <vburru@marvell.com>
Fri, 24 Mar 2023 17:46:56 +0000 (10:46 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Mar 2023 07:37:54 +0000 (08:37 +0100)
Defer probe if firmware is not ready for device usage.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
Signed-off-by: Satananda Burla <sburla@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeon_ep/octep_main.c

index fdce78ceea87e85057b2efc5c9c17cd6f2477d8a..0a50da52dc2722feea7e77f96c3fb3ed1e6feeb7 100644 (file)
@@ -1016,6 +1016,26 @@ static void octep_device_cleanup(struct octep_device *oct)
        oct->conf = NULL;
 }
 
+static bool get_fw_ready_status(struct pci_dev *pdev)
+{
+       u32 pos = 0;
+       u16 vsec_id;
+       u8 status;
+
+       while ((pos = pci_find_next_ext_capability(pdev, pos,
+                                                  PCI_EXT_CAP_ID_VNDR))) {
+               pci_read_config_word(pdev, pos + 4, &vsec_id);
+#define FW_STATUS_VSEC_ID  0xA3
+               if (vsec_id != FW_STATUS_VSEC_ID)
+                       continue;
+
+               pci_read_config_byte(pdev, (pos + 8), &status);
+               dev_info(&pdev->dev, "Firmware ready status = %u\n", status);
+               return status;
+       }
+       return false;
+}
+
 /**
  * octep_probe() - Octeon PCI device probe handler.
  *
@@ -1051,6 +1071,12 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
 
+       if (!get_fw_ready_status(pdev)) {
+               dev_notice(&pdev->dev, "Firmware not ready; defer probe.\n");
+               err = -EPROBE_DEFER;
+               goto err_alloc_netdev;
+       }
+
        netdev = alloc_etherdev_mq(sizeof(struct octep_device),
                                   OCTEP_MAX_QUEUES);
        if (!netdev) {