bnx2x: Load firmware in open() instead of probe()
authorDmitry Kravkov <dmitry@broadcom.com>
Tue, 3 Aug 2010 21:49:40 +0000 (21:49 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 17 Aug 2010 04:06:18 +0000 (21:06 -0700)
Loading firmware when actually bringing eth device up.
This also will allow driver to be insmoded when filesystem with
firmware files is not available yet.

Suggested by Stephen Hemminger <shemminger@vyatta.com>

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_cmn.h
drivers/net/bnx2x/bnx2x_main.c

index 02bf710629a3eec2b4b05f17943c1565b3912144..da96d1a18c20d759f4124d583286d4b53a9b3345 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <linux/firmware.h>
 #include "bnx2x_cmn.h"
 
 #ifdef BCM_VLAN
@@ -1206,12 +1207,27 @@ static int bnx2x_set_num_queues(struct bnx2x *bp)
        return rc;
 }
 
+static void bnx2x_release_firmware(struct bnx2x *bp)
+{
+       kfree(bp->init_ops_offsets);
+       kfree(bp->init_ops);
+       kfree(bp->init_data);
+       release_firmware(bp->firmware);
+}
+
 /* must be called with rtnl_lock */
 int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 {
        u32 load_code;
        int i, rc;
 
+       /* Set init arrays */
+       rc = bnx2x_init_firmware(bp);
+       if (rc) {
+               BNX2X_ERR("Error loading firmware\n");
+               return rc;
+       }
+
 #ifdef BNX2X_STOP_ON_ERROR
        if (unlikely(bp->panic))
                return -EPERM;
@@ -1427,6 +1443,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 #endif
        bnx2x_inc_load_cnt(bp);
 
+       bnx2x_release_firmware(bp);
+
        return 0;
 
 #ifdef BCM_CNIC
@@ -1454,6 +1472,8 @@ load_error1:
                netif_napi_del(&bnx2x_fp(bp, i, napi));
        bnx2x_free_mem(bp);
 
+       bnx2x_release_firmware(bp);
+
        return rc;
 }
 
index d1979b1a7ed276f391d3a860aaf41a10449c139b..32543c32805c82e9ffe8de8b2872d8c6c127ac28 100644 (file)
@@ -114,6 +114,15 @@ void bnx2x_int_enable(struct bnx2x *bp);
  */
 void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
 
+/**
+ * Loads device firmware
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_init_firmware(struct bnx2x *bp);
+
 /**
  * Init HW blocks according to current initialization stage:
  * COMMON, PORT or FUNCTION.
index b4ec2b02a465cf7d822f23700c119d6e93a2121b..13309f1717b976ea434af85d0f2fe589e57c4f85 100644 (file)
@@ -7254,7 +7254,7 @@ static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp,
        *speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
 }
 
-static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+static int bnx2x_check_firmware(struct bnx2x *bp)
 {
        const struct firmware *firmware = bp->firmware;
        struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7365,7 +7365,7 @@ do {                                                                      \
             (u8 *)bp->arr, len);                                       \
 } while (0)
 
-static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+int bnx2x_init_firmware(struct bnx2x *bp)
 {
        const char *fw_file_name;
        struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7376,21 +7376,21 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
        else if (CHIP_IS_E1H(bp))
                fw_file_name = FW_FILE_NAME_E1H;
        else {
-               dev_err(dev, "Unsupported chip revision\n");
+               BNX2X_ERR("Unsupported chip revision\n");
                return -EINVAL;
        }
 
-       dev_info(dev, "Loading %s\n", fw_file_name);
+       BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
 
-       rc = request_firmware(&bp->firmware, fw_file_name, dev);
+       rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
        if (rc) {
-               dev_err(dev, "Can't load firmware file %s\n", fw_file_name);
+               BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
                goto request_firmware_exit;
        }
 
        rc = bnx2x_check_firmware(bp);
        if (rc) {
-               dev_err(dev, "Corrupt firmware file %s\n", fw_file_name);
+               BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
                goto request_firmware_exit;
        }
 
@@ -7468,13 +7468,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        if (rc)
                goto init_one_exit;
 
-       /* Set init arrays */
-       rc = bnx2x_init_firmware(bp, &pdev->dev);
-       if (rc) {
-               dev_err(&pdev->dev, "Error loading firmware\n");
-               goto init_one_exit;
-       }
-
        rc = register_netdev(dev);
        if (rc) {
                dev_err(&pdev->dev, "Cannot register net device\n");
@@ -7525,11 +7518,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
        /* Make sure RESET task is not scheduled before continuing */
        cancel_delayed_work_sync(&bp->reset_task);
 
-       kfree(bp->init_ops_offsets);
-       kfree(bp->init_ops);
-       kfree(bp->init_data);
-       release_firmware(bp->firmware);
-
        if (bp->regview)
                iounmap(bp->regview);