Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2433

kernel-2.6.18-238.el5.src.rpm

From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 3 Sep 2010 16:44:38 -0400
Subject: [net] bnx2x: load firmware in open instead of probe
Message-id: <20100903164438.25415.55433.stgit@brian.englab.brq.redhat.com>
Patchwork-id: 28115
O-Subject: [RHEL5.6 BZ572012 PATCH 41/46] bnx2x: Load firmware in open() instead
	of probe()
Bugzilla: 572012
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>

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>
(cherry picked from commit 6891dd25d3f82e50979b27fde1980aa96320b975)

RHEL: we're not loading the firmware from the filesystem.

Conflicts:

	drivers/net/bnx2x/bnx2x_cmn.c
	drivers/net/bnx2x/bnx2x_main.c

diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 3679841..ae21df8 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1232,12 +1232,29 @@ static void bnx2x_alloc_napi(struct bnx2x *bp)
 	}
 }
 
+static void bnx2x_release_firmware(struct bnx2x *bp)
+{
+	kfree(bp->init_ops_offsets);
+	kfree(bp->init_ops);
+	kfree(bp->init_data);
+#if 0 /* firmware is embedded in the RHEL kernel */
+	release_firmware(bp->firmware);
+#endif
+}
+
 /* 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;
@@ -1452,6 +1469,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
@@ -1477,6 +1496,8 @@ load_error1:
 	bnx2x_napi_disable(bp);
 	bnx2x_free_mem(bp);
 
+	bnx2x_release_firmware(bp);
+
 	return rc;
 }
 
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 377db39..2e75df7 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -115,6 +115,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.
  *
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 9b9ea84..9b97f22 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -7262,9 +7262,7 @@ static int bnx2x_request_firmware(const struct firmware **firmware_p,
 	return 0;
 }
 
-static inline void bnx2x_release_firmware(const struct firmware *fw) { }
-
-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;
@@ -7375,7 +7373,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)
 {
 	char fw_file_name[40] = {0};
 	struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7387,7 +7385,7 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 	else if (CHIP_IS_E1H(bp))
 		offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
 	else {
-		dev_err(dev, "Unsupported chip revision\n");
+		BNX2X_ERR("Unsupported chip revision\n");
 		return -EINVAL;
 	}
 
@@ -7397,17 +7395,17 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 		BCM_5710_FW_REVISION_VERSION,
 		BCM_5710_FW_ENGINEERING_VERSION);
 
-	dev_info(dev, "Loading %s\n", fw_file_name);
+	BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
 
-	rc = bnx2x_request_firmware(&bp->firmware, fw_file_name, dev);
+	rc = bnx2x_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;
 	}
 
@@ -7449,8 +7447,9 @@ init_offsets_alloc_err:
 init_ops_alloc_err:
 	kfree(bp->init_data);
 request_firmware_exit:
-	bnx2x_release_firmware(bp->firmware);
-
+#if 0 /* not in RHEL */
+	release_firmware(bp->firmware);
+#endif
 	return rc;
 }
 
@@ -7502,13 +7501,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");
@@ -7566,11 +7558,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);
-	bnx2x_release_firmware(bp->firmware);
-
 	if (bp->regview)
 		iounmap(bp->regview);