Commit 8d37ba02 authored by Shahed Shaikh's avatar Shahed Shaikh Committed by David S. Miller

qlcnic: Collect firmware dump using DMA on 82xx adapters

o Add support to collect RDMEM section of firmware dump
  using PEX DMA method.
o This patch uses most of the code used for PEX DMA support
  on 83xx series adapters and some refactoring.
Signed-off-by: default avatarShahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d747c333
...@@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter) ...@@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK); QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
} }
int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
u32 *data, u32 count) u32 *data, u32 count)
{ {
int i, j, ret = 0; int i, j, ret = 0;
u32 temp; u32 temp;
int err = 0;
/* Check alignment */ /* Check alignment */
if (addr & 0xF) if (addr & 0xF)
return -EIO; return -EIO;
mutex_lock(&adapter->ahw->mem_lock); mutex_lock(&adapter->ahw->mem_lock);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0); qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
for (i = 0; i < count; i++, addr += 16) { for (i = 0; i < count; i++, addr += 16) {
if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET, if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
...@@ -3060,26 +3059,16 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, ...@@ -3060,26 +3059,16 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
return -EIO; return -EIO;
} }
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr); qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO, qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
*data++); qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI, qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
*data++); qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO, qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
*data++); qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_ENABLE);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_START);
for (j = 0; j < MAX_CTL_CHECK; j++) { for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err); temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
if (err == -EIO) {
mutex_unlock(&adapter->ahw->mem_lock);
return err;
}
if ((temp & TA_CTL_BUSY) == 0) if ((temp & TA_CTL_BUSY) == 0)
break; break;
......
...@@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *); ...@@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *);
void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); void qlcnic_83xx_napi_enable(struct qlcnic_adapter *);
void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); void qlcnic_83xx_napi_disable(struct qlcnic_adapter *);
int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32);
void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); int qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
int qlcnic_ind_rd(struct qlcnic_adapter *, u32); int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *);
int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *, int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *,
...@@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32); ...@@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32);
int qlcnic_83xx_lock_driver(struct qlcnic_adapter *); int qlcnic_83xx_lock_driver(struct qlcnic_adapter *);
void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *); void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *);
int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *); int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *); int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *);
int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int); int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int);
int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *); int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
...@@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *); ...@@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *);
u32 qlcnic_83xx_get_cap_size(void *, int); u32 qlcnic_83xx_get_cap_size(void *, int);
void qlcnic_83xx_set_sys_info(void *, int, u32); void qlcnic_83xx_set_sys_info(void *, int, u32);
void qlcnic_83xx_store_cap_mask(void *, u32); void qlcnic_83xx_store_cap_mask(void *, u32);
int qlcnic_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
#endif #endif
...@@ -1363,7 +1363,7 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter) ...@@ -1363,7 +1363,7 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter)
return ret; return ret;
} }
/* 16 byte write to MS memory */ /* 16 byte write to MS memory */
ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, ret = qlcnic_ms_mem_write128(adapter, dest, (u32 *)p_cache,
size / 16); size / 16);
if (ret) { if (ret) {
vfree(p_cache); vfree(p_cache);
...@@ -1389,7 +1389,7 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) ...@@ -1389,7 +1389,7 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
p_cache = (u32 *)fw->data; p_cache = (u32 *)fw->data;
addr = (u64)dest; addr = (u64)dest;
ret = qlcnic_83xx_ms_mem_write128(adapter, addr, ret = qlcnic_ms_mem_write128(adapter, addr,
p_cache, size / 16); p_cache, size / 16);
if (ret) { if (ret) {
dev_err(&adapter->pdev->dev, "MS memory write failed\n"); dev_err(&adapter->pdev->dev, "MS memory write failed\n");
...@@ -1405,7 +1405,7 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) ...@@ -1405,7 +1405,7 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
data[i] = fw->data[size + i]; data[i] = fw->data[size + i];
for (; i < 16; i++) for (; i < 16; i++)
data[i] = 0; data[i] = 0;
ret = qlcnic_83xx_ms_mem_write128(adapter, addr, ret = qlcnic_ms_mem_write128(adapter, addr,
(u32 *)data, 1); (u32 *)data, 1);
if (ret) { if (ret) {
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
......
...@@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr) ...@@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
return data; return data;
} }
void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) int qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
{ {
int ret = 0;
if (qlcnic_82xx_check(adapter)) if (qlcnic_82xx_check(adapter))
qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data);
else else
qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); ret = qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);
return ret;
} }
static int static int
......
...@@ -238,6 +238,8 @@ void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) ...@@ -238,6 +238,8 @@ void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
hdr->drv_cap_mask = hdr->cap_mask; hdr->drv_cap_mask = hdr->cap_mask;
fw_dump->cap_mask = hdr->cap_mask; fw_dump->cap_mask = hdr->cap_mask;
fw_dump->use_pex_dma = (hdr->capabilities & BIT_0) ? true : false;
} }
inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index) inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index)
...@@ -276,6 +278,8 @@ inline void qlcnic_83xx_set_saved_state(void *t_hdr, u32 index, ...@@ -276,6 +278,8 @@ inline void qlcnic_83xx_set_saved_state(void *t_hdr, u32 index,
hdr->saved_state[index] = value; hdr->saved_state[index] = value;
} }
#define QLCNIC_TEMPLATE_VERSION (0x20001)
void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
{ {
struct qlcnic_83xx_dump_template_hdr *hdr; struct qlcnic_83xx_dump_template_hdr *hdr;
...@@ -288,6 +292,9 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) ...@@ -288,6 +292,9 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
hdr->drv_cap_mask = hdr->cap_mask; hdr->drv_cap_mask = hdr->cap_mask;
fw_dump->cap_mask = hdr->cap_mask; fw_dump->cap_mask = hdr->cap_mask;
fw_dump->use_pex_dma = (fw_dump->version & 0xfffff) >=
QLCNIC_TEMPLATE_VERSION;
} }
inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index) inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index)
...@@ -658,29 +665,28 @@ static u32 qlcnic_read_memory_test_agent(struct qlcnic_adapter *adapter, ...@@ -658,29 +665,28 @@ static u32 qlcnic_read_memory_test_agent(struct qlcnic_adapter *adapter,
static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter,
struct __mem *mem) struct __mem *mem)
{ {
struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
u32 dma_no, dma_base_addr, temp_addr; u32 dma_no, dma_base_addr, temp_addr;
int i, ret, dma_sts; int i, ret, dma_sts;
void *tmpl_hdr;
tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr; tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr;
dma_no = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; dma_no = qlcnic_get_saved_state(adapter, tmpl_hdr,
QLC_83XX_DMA_ENGINE_INDEX);
dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no); dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no);
temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW; temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW;
ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, ret = qlcnic_ind_wr(adapter, temp_addr, mem->desc_card_addr);
mem->desc_card_addr);
if (ret) if (ret)
return ret; return ret;
temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI; temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI;
ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 0); ret = qlcnic_ind_wr(adapter, temp_addr, 0);
if (ret) if (ret)
return ret; return ret;
temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL; temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL;
ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, ret = qlcnic_ind_wr(adapter, temp_addr, mem->start_dma_cmd);
mem->start_dma_cmd);
if (ret) if (ret)
return ret; return ret;
...@@ -710,15 +716,16 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, ...@@ -710,15 +716,16 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
u32 temp, dma_base_addr, size = 0, read_size = 0; u32 temp, dma_base_addr, size = 0, read_size = 0;
struct qlcnic_pex_dma_descriptor *dma_descr; struct qlcnic_pex_dma_descriptor *dma_descr;
struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
dma_addr_t dma_phys_addr; dma_addr_t dma_phys_addr;
void *dma_buffer; void *dma_buffer;
void *tmpl_hdr;
tmpl_hdr = fw_dump->tmpl_hdr; tmpl_hdr = fw_dump->tmpl_hdr;
/* Check if DMA engine is available */ /* Check if DMA engine is available */
temp = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; temp = qlcnic_get_saved_state(adapter, tmpl_hdr,
QLC_83XX_DMA_ENGINE_INDEX);
dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp); dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp);
temp = qlcnic_ind_rd(adapter, temp = qlcnic_ind_rd(adapter,
dma_base_addr + QLC_DMA_CMD_STATUS_CTRL); dma_base_addr + QLC_DMA_CMD_STATUS_CTRL);
...@@ -764,7 +771,7 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, ...@@ -764,7 +771,7 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
/* Write DMA descriptor to MS memory*/ /* Write DMA descriptor to MS memory*/
temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16; temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16;
*ret = qlcnic_83xx_ms_mem_write128(adapter, mem->desc_card_addr, *ret = qlcnic_ms_mem_write128(adapter, mem->desc_card_addr,
(u32 *)dma_descr, temp); (u32 *)dma_descr, temp);
if (*ret) { if (*ret) {
dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n", dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n",
...@@ -1141,8 +1148,6 @@ static int __qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter, ...@@ -1141,8 +1148,6 @@ static int __qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter,
return err; return err;
} }
#define QLCNIC_TEMPLATE_VERSION (0x20001)
int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw; struct qlcnic_hardware_context *ahw;
...@@ -1203,12 +1208,6 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) ...@@ -1203,12 +1208,6 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
"Default minidump capture mask 0x%x\n", "Default minidump capture mask 0x%x\n",
fw_dump->cap_mask); fw_dump->cap_mask);
if (qlcnic_83xx_check(adapter) &&
(fw_dump->version & 0xfffff) >= QLCNIC_TEMPLATE_VERSION)
fw_dump->use_pex_dma = true;
else
fw_dump->use_pex_dma = false;
qlcnic_enable_fw_dump_state(adapter); qlcnic_enable_fw_dump_state(adapter);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment