|
@@ -621,6 +621,7 @@ struct nic {
|
|
u16 eeprom_wc;
|
|
u16 eeprom_wc;
|
|
__le16 eeprom[256];
|
|
__le16 eeprom[256];
|
|
spinlock_t mdio_lock;
|
|
spinlock_t mdio_lock;
|
|
|
|
+ const struct firmware *fw;
|
|
};
|
|
};
|
|
|
|
|
|
static inline void e100_write_flush(struct nic *nic)
|
|
static inline void e100_write_flush(struct nic *nic)
|
|
@@ -1222,9 +1223,9 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
|
|
static const struct firmware *e100_request_firmware(struct nic *nic)
|
|
static const struct firmware *e100_request_firmware(struct nic *nic)
|
|
{
|
|
{
|
|
const char *fw_name;
|
|
const char *fw_name;
|
|
- const struct firmware *fw;
|
|
|
|
|
|
+ const struct firmware *fw = nic->fw;
|
|
u8 timer, bundle, min_size;
|
|
u8 timer, bundle, min_size;
|
|
- int err;
|
|
|
|
|
|
+ int err = 0;
|
|
|
|
|
|
/* do not load u-code for ICH devices */
|
|
/* do not load u-code for ICH devices */
|
|
if (nic->flags & ich)
|
|
if (nic->flags & ich)
|
|
@@ -1240,12 +1241,20 @@ static const struct firmware *e100_request_firmware(struct nic *nic)
|
|
else /* No ucode on other devices */
|
|
else /* No ucode on other devices */
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- err = request_firmware(&fw, fw_name, &nic->pdev->dev);
|
|
|
|
|
|
+ /* If the firmware has not previously been loaded, request a pointer
|
|
|
|
+ * to it. If it was previously loaded, we are reinitializing the
|
|
|
|
+ * adapter, possibly in a resume from hibernate, in which case
|
|
|
|
+ * request_firmware() cannot be used.
|
|
|
|
+ */
|
|
|
|
+ if (!fw)
|
|
|
|
+ err = request_firmware(&fw, fw_name, &nic->pdev->dev);
|
|
|
|
+
|
|
if (err) {
|
|
if (err) {
|
|
DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
|
|
DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
|
|
fw_name, err);
|
|
fw_name, err);
|
|
return ERR_PTR(err);
|
|
return ERR_PTR(err);
|
|
}
|
|
}
|
|
|
|
+
|
|
/* Firmware should be precisely UCODE_SIZE (words) plus three bytes
|
|
/* Firmware should be precisely UCODE_SIZE (words) plus three bytes
|
|
indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
|
|
indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
|
|
if (fw->size != UCODE_SIZE * 4 + 3) {
|
|
if (fw->size != UCODE_SIZE * 4 + 3) {
|
|
@@ -1268,7 +1277,10 @@ static const struct firmware *e100_request_firmware(struct nic *nic)
|
|
release_firmware(fw);
|
|
release_firmware(fw);
|
|
return ERR_PTR(-EINVAL);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
}
|
|
- /* OK, firmware is validated and ready to use... */
|
|
|
|
|
|
+
|
|
|
|
+ /* OK, firmware is validated and ready to use. Save a pointer
|
|
|
|
+ * to it in the nic */
|
|
|
|
+ nic->fw = fw;
|
|
return fw;
|
|
return fw;
|
|
}
|
|
}
|
|
|
|
|