summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
diff options
context:
space:
mode:
authorSony Chacko <sony.chacko@qlogic.com>2013-01-01 03:20:25 (GMT)
committerDavid S. Miller <davem@davemloft.net>2013-01-02 10:43:27 (GMT)
commit81d0aeb0a4fff6c274f956644a837caac14a7c21 (patch)
tree1e6c0714c981a94bbadaa3981fa3897f94fd688f /drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
parent629263acaea3613a7da4d602ac1d143533d251cc (diff)
downloadlinux-fsl-qoriq-81d0aeb0a4fff6c274f956644a837caac14a7c21.tar.xz
qlcnic: flash template based firmware reset recovery
Flash template provides instructions to stop, restart and initalize the firmware. These instructions are abstracted as a series of read, write and poll operations on hardware registers. Register information and operation specifics are not exposed to the driver. Driver reads the template from flash and executes the instructions located at pre-defined offsets. Template based firmware reset recovery and initialization mechanism minimize driver changes as firmware evolves. Signed-off-by: Sony Chacko <sony.chacko@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 8fdc4e6..9cd51cb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2343,3 +2343,43 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
return ret;
}
+
+int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
+ u8 *p_data, int count)
+{
+ int i, ret;
+ u32 word, addr = flash_addr;
+ ulong indirect_addr;
+
+ if (qlcnic_83xx_lock_flash(adapter) != 0)
+ return -EIO;
+
+ if (addr & 0x3) {
+ dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (qlcnic_83xx_wrt_reg_indirect(adapter,
+ QLC_83XX_FLASH_DIRECT_WINDOW,
+ (addr))) {
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+
+ indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
+ ret = qlcnic_83xx_rd_reg_indirect(adapter,
+ indirect_addr);
+ if (ret == -EIO)
+ return -EIO;
+ word = ret;
+ *p_data = word;
+ p_data = p_data + 4;
+ addr = addr + 4;
+ }
+
+ qlcnic_83xx_unlock_flash(adapter);
+
+ return 0;
+}