summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/brocade/bna/bnad_ethtool.c')
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad_ethtool.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index 9b44ec8096ba..ab753d7334a6 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -946,7 +946,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
if (!flash_attr)
- return -ENOMEM;
+ return 0;
fcomp.bnad = bnad;
fcomp.comp_status = 0;
@@ -958,7 +958,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
if (ret != BFA_STATUS_OK) {
spin_unlock_irqrestore(&bnad->bna_lock, flags);
kfree(flash_attr);
- goto out_err;
+ return 0;
}
spin_unlock_irqrestore(&bnad->bna_lock, flags);
wait_for_completion(&fcomp.comp);
@@ -978,8 +978,6 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
}
kfree(flash_attr);
return flash_part;
-out_err:
- return -EINVAL;
}
static int
@@ -1006,7 +1004,7 @@ bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
/* Query the flash partition based on the offset */
flash_part = bnad_get_flash_partition_by_offset(bnad,
eeprom->offset, &base_offset);
- if (flash_part <= 0)
+ if (flash_part == 0)
return -EFAULT;
fcomp.bnad = bnad;
@@ -1048,7 +1046,7 @@ bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
/* Query the flash partition based on the offset */
flash_part = bnad_get_flash_partition_by_offset(bnad,
eeprom->offset, &base_offset);
- if (flash_part <= 0)
+ if (flash_part == 0)
return -EFAULT;
fcomp.bnad = bnad;
@@ -1072,6 +1070,47 @@ done:
return ret;
}
+static int
+bnad_flash_device(struct net_device *netdev, struct ethtool_flash *eflash)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bnad_iocmd_comp fcomp;
+ const struct firmware *fw;
+ int ret = 0;
+
+ ret = request_firmware(&fw, eflash->data, &bnad->pcidev->dev);
+ if (ret) {
+ pr_err("BNA: Can't locate firmware %s\n", eflash->data);
+ goto out;
+ }
+
+ fcomp.bnad = bnad;
+ fcomp.comp_status = 0;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irq(&bnad->bna_lock);
+ ret = bfa_nw_flash_update_part(&bnad->bna.flash, BFA_FLASH_PART_FWIMG,
+ bnad->id, (u8 *)fw->data, fw->size, 0,
+ bnad_cb_completion, &fcomp);
+ if (ret != BFA_STATUS_OK) {
+ pr_warn("BNA: Flash update failed with err: %d\n", ret);
+ ret = -EIO;
+ spin_unlock_irq(&bnad->bna_lock);
+ goto out;
+ }
+
+ spin_unlock_irq(&bnad->bna_lock);
+ wait_for_completion(&fcomp.comp);
+ if (fcomp.comp_status != BFA_STATUS_OK) {
+ ret = -EIO;
+ pr_warn("BNA: Firmware image update to flash failed with: %d\n",
+ fcomp.comp_status);
+ }
+out:
+ release_firmware(fw);
+ return ret;
+}
+
static const struct ethtool_ops bnad_ethtool_ops = {
.get_settings = bnad_get_settings,
.set_settings = bnad_set_settings,
@@ -1090,6 +1129,7 @@ static const struct ethtool_ops bnad_ethtool_ops = {
.get_eeprom_len = bnad_get_eeprom_len,
.get_eeprom = bnad_get_eeprom,
.set_eeprom = bnad_set_eeprom,
+ .flash_device = bnad_flash_device,
};
void