diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/e100.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index ff83efd47b0d..f428c5f72f18 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -621,6 +621,7 @@ struct nic { u16 eeprom_wc; __le16 eeprom[256]; spinlock_t mdio_lock; + const struct firmware *fw; }; 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) { const char *fw_name; - const struct firmware *fw; + const struct firmware *fw = nic->fw; u8 timer, bundle, min_size; - int err; + int err = 0; /* do not load u-code for ICH devices */ if (nic->flags & ich) @@ -1240,12 +1241,20 @@ static const struct firmware *e100_request_firmware(struct nic *nic) else /* No ucode on other devices */ 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) { DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", fw_name, err); return ERR_PTR(err); } + /* Firmware should be precisely UCODE_SIZE (words) plus three bytes indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ if (fw->size != UCODE_SIZE * 4 + 3) { @@ -1268,7 +1277,10 @@ static const struct firmware *e100_request_firmware(struct nic *nic) release_firmware(fw); 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; } |