aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShahed Shaikh <shahed.shaikh@qlogic.com>2014-05-09 02:51:32 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-09 13:08:58 -0400
commit8d37ba023f0ccab342df9ba216650e23aa147109 (patch)
tree41375f25e82baed963eff5cdd0168abc0c1ad10a
parentd747c3337484afac9953c44ea56a912869778559 (diff)
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: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c31
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c12
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c8
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c37
5 files changed, 42 insertions, 50 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 7c125d7fb547..a4a4ec0b68f8 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
3037 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK); 3037 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3038} 3038}
3039 3039
3040int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, 3040int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
3041 u32 *data, u32 count) 3041 u32 *data, u32 count)
3042{ 3042{
3043 int i, j, ret = 0; 3043 int i, j, ret = 0;
3044 u32 temp; 3044 u32 temp;
3045 int err = 0;
3046 3045
3047 /* Check alignment */ 3046 /* Check alignment */
3048 if (addr & 0xF) 3047 if (addr & 0xF)
3049 return -EIO; 3048 return -EIO;
3050 3049
3051 mutex_lock(&adapter->ahw->mem_lock); 3050 mutex_lock(&adapter->ahw->mem_lock);
3052 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0); 3051 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
3053 3052
3054 for (i = 0; i < count; i++, addr += 16) { 3053 for (i = 0; i < count; i++, addr += 16) {
3055 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET, 3054 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 return -EIO; 3059 return -EIO;
3061 } 3060 }
3062 3061
3063 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr); 3062 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
3064 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO, 3063 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
3065 *data++); 3064 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
3066 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI, 3065 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
3067 *data++); 3066 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
3068 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO, 3067 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
3069 *data++); 3068 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
3070 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
3071 *data++);
3072 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
3073 QLCNIC_TA_WRITE_ENABLE);
3074 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
3075 QLCNIC_TA_WRITE_START);
3076 3069
3077 for (j = 0; j < MAX_CTL_CHECK; j++) { 3070 for (j = 0; j < MAX_CTL_CHECK; j++) {
3078 temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err); 3071 temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
3079 if (err == -EIO) {
3080 mutex_unlock(&adapter->ahw->mem_lock);
3081 return err;
3082 }
3083 3072
3084 if ((temp & TA_CTL_BUSY) == 0) 3073 if ((temp & TA_CTL_BUSY) == 0)
3085 break; 3074 break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 88d809c35633..97784d09933f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *);
560void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); 560void qlcnic_83xx_napi_enable(struct qlcnic_adapter *);
561void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); 561void qlcnic_83xx_napi_disable(struct qlcnic_adapter *);
562int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); 562int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32);
563void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); 563int qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
564int qlcnic_ind_rd(struct qlcnic_adapter *, u32); 564int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
565int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); 565int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *);
566int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *, 566int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *,
@@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32);
617int qlcnic_83xx_lock_driver(struct qlcnic_adapter *); 617int qlcnic_83xx_lock_driver(struct qlcnic_adapter *);
618void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *); 618void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *);
619int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *); 619int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *);
620int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
621int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *); 620int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *);
622int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int); 621int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int);
623int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *); 622int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
@@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *);
659u32 qlcnic_83xx_get_cap_size(void *, int); 658u32 qlcnic_83xx_get_cap_size(void *, int);
660void qlcnic_83xx_set_sys_info(void *, int, u32); 659void qlcnic_83xx_set_sys_info(void *, int, u32);
661void qlcnic_83xx_store_cap_mask(void *, u32); 660void qlcnic_83xx_store_cap_mask(void *, u32);
661int qlcnic_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
662#endif 662#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 34d273794e96..f33559b72528 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -1363,8 +1363,8 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter)
1363 return ret; 1363 return ret;
1364 } 1364 }
1365 /* 16 byte write to MS memory */ 1365 /* 16 byte write to MS memory */
1366 ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, 1366 ret = qlcnic_ms_mem_write128(adapter, dest, (u32 *)p_cache,
1367 size / 16); 1367 size / 16);
1368 if (ret) { 1368 if (ret) {
1369 vfree(p_cache); 1369 vfree(p_cache);
1370 return ret; 1370 return ret;
@@ -1389,8 +1389,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
1389 p_cache = (u32 *)fw->data; 1389 p_cache = (u32 *)fw->data;
1390 addr = (u64)dest; 1390 addr = (u64)dest;
1391 1391
1392 ret = qlcnic_83xx_ms_mem_write128(adapter, addr, 1392 ret = qlcnic_ms_mem_write128(adapter, addr,
1393 p_cache, size / 16); 1393 p_cache, size / 16);
1394 if (ret) { 1394 if (ret) {
1395 dev_err(&adapter->pdev->dev, "MS memory write failed\n"); 1395 dev_err(&adapter->pdev->dev, "MS memory write failed\n");
1396 release_firmware(fw); 1396 release_firmware(fw);
@@ -1405,8 +1405,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
1405 data[i] = fw->data[size + i]; 1405 data[i] = fw->data[size + i];
1406 for (; i < 16; i++) 1406 for (; i < 16; i++)
1407 data[i] = 0; 1407 data[i] = 0;
1408 ret = qlcnic_83xx_ms_mem_write128(adapter, addr, 1408 ret = qlcnic_ms_mem_write128(adapter, addr,
1409 (u32 *)data, 1); 1409 (u32 *)data, 1);
1410 if (ret) { 1410 if (ret) {
1411 dev_err(&adapter->pdev->dev, 1411 dev_err(&adapter->pdev->dev,
1412 "MS memory write failed\n"); 1412 "MS memory write failed\n");
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index e5352b70314a..c9e8574959b7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
373 return data; 373 return data;
374} 374}
375 375
376void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) 376int qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
377{ 377{
378 int ret = 0;
379
378 if (qlcnic_82xx_check(adapter)) 380 if (qlcnic_82xx_check(adapter))
379 qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); 381 qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data);
380 else 382 else
381 qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); 383 ret = qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);
384
385 return ret;
382} 386}
383 387
384static int 388static int
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
index 37b979b1266b..f7694da8ed5d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
@@ -238,6 +238,8 @@ void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
238 238
239 hdr->drv_cap_mask = hdr->cap_mask; 239 hdr->drv_cap_mask = hdr->cap_mask;
240 fw_dump->cap_mask = hdr->cap_mask; 240 fw_dump->cap_mask = hdr->cap_mask;
241
242 fw_dump->use_pex_dma = (hdr->capabilities & BIT_0) ? true : false;
241} 243}
242 244
243inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index) 245inline 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 hdr->saved_state[index] = value; 278 hdr->saved_state[index] = value;
277} 279}
278 280
281#define QLCNIC_TEMPLATE_VERSION (0x20001)
282
279void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) 283void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
280{ 284{
281 struct qlcnic_83xx_dump_template_hdr *hdr; 285 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 292
289 hdr->drv_cap_mask = hdr->cap_mask; 293 hdr->drv_cap_mask = hdr->cap_mask;
290 fw_dump->cap_mask = hdr->cap_mask; 294 fw_dump->cap_mask = hdr->cap_mask;
295
296 fw_dump->use_pex_dma = (fw_dump->version & 0xfffff) >=
297 QLCNIC_TEMPLATE_VERSION;
291} 298}
292 299
293inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index) 300inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index)
@@ -658,29 +665,28 @@ out:
658static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, 665static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter,
659 struct __mem *mem) 666 struct __mem *mem)
660{ 667{
661 struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
662 struct device *dev = &adapter->pdev->dev; 668 struct device *dev = &adapter->pdev->dev;
663 u32 dma_no, dma_base_addr, temp_addr; 669 u32 dma_no, dma_base_addr, temp_addr;
664 int i, ret, dma_sts; 670 int i, ret, dma_sts;
671 void *tmpl_hdr;
665 672
666 tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr; 673 tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr;
667 dma_no = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; 674 dma_no = qlcnic_get_saved_state(adapter, tmpl_hdr,
675 QLC_83XX_DMA_ENGINE_INDEX);
668 dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no); 676 dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no);
669 677
670 temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW; 678 temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW;
671 ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 679 ret = qlcnic_ind_wr(adapter, temp_addr, mem->desc_card_addr);
672 mem->desc_card_addr);
673 if (ret) 680 if (ret)
674 return ret; 681 return ret;
675 682
676 temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI; 683 temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI;
677 ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 0); 684 ret = qlcnic_ind_wr(adapter, temp_addr, 0);
678 if (ret) 685 if (ret)
679 return ret; 686 return ret;
680 687
681 temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL; 688 temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL;
682 ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 689 ret = qlcnic_ind_wr(adapter, temp_addr, mem->start_dma_cmd);
683 mem->start_dma_cmd);
684 if (ret) 690 if (ret)
685 return ret; 691 return ret;
686 692
@@ -710,15 +716,16 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
710 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 716 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
711 u32 temp, dma_base_addr, size = 0, read_size = 0; 717 u32 temp, dma_base_addr, size = 0, read_size = 0;
712 struct qlcnic_pex_dma_descriptor *dma_descr; 718 struct qlcnic_pex_dma_descriptor *dma_descr;
713 struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
714 struct device *dev = &adapter->pdev->dev; 719 struct device *dev = &adapter->pdev->dev;
715 dma_addr_t dma_phys_addr; 720 dma_addr_t dma_phys_addr;
716 void *dma_buffer; 721 void *dma_buffer;
722 void *tmpl_hdr;
717 723
718 tmpl_hdr = fw_dump->tmpl_hdr; 724 tmpl_hdr = fw_dump->tmpl_hdr;
719 725
720 /* Check if DMA engine is available */ 726 /* Check if DMA engine is available */
721 temp = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; 727 temp = qlcnic_get_saved_state(adapter, tmpl_hdr,
728 QLC_83XX_DMA_ENGINE_INDEX);
722 dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp); 729 dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp);
723 temp = qlcnic_ind_rd(adapter, 730 temp = qlcnic_ind_rd(adapter,
724 dma_base_addr + QLC_DMA_CMD_STATUS_CTRL); 731 dma_base_addr + QLC_DMA_CMD_STATUS_CTRL);
@@ -764,8 +771,8 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
764 771
765 /* Write DMA descriptor to MS memory*/ 772 /* Write DMA descriptor to MS memory*/
766 temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16; 773 temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16;
767 *ret = qlcnic_83xx_ms_mem_write128(adapter, mem->desc_card_addr, 774 *ret = qlcnic_ms_mem_write128(adapter, mem->desc_card_addr,
768 (u32 *)dma_descr, temp); 775 (u32 *)dma_descr, temp);
769 if (*ret) { 776 if (*ret) {
770 dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n", 777 dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n",
771 mem->desc_card_addr); 778 mem->desc_card_addr);
@@ -1141,8 +1148,6 @@ free_mem:
1141 return err; 1148 return err;
1142} 1149}
1143 1150
1144#define QLCNIC_TEMPLATE_VERSION (0x20001)
1145
1146int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) 1151int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
1147{ 1152{
1148 struct qlcnic_hardware_context *ahw; 1153 struct qlcnic_hardware_context *ahw;
@@ -1203,12 +1208,6 @@ flash_temp:
1203 "Default minidump capture mask 0x%x\n", 1208 "Default minidump capture mask 0x%x\n",
1204 fw_dump->cap_mask); 1209 fw_dump->cap_mask);
1205 1210
1206 if (qlcnic_83xx_check(adapter) &&
1207 (fw_dump->version & 0xfffff) >= QLCNIC_TEMPLATE_VERSION)
1208 fw_dump->use_pex_dma = true;
1209 else
1210 fw_dump->use_pex_dma = false;
1211
1212 qlcnic_enable_fw_dump_state(adapter); 1211 qlcnic_enable_fw_dump_state(adapter);
1213 1212
1214 return 0; 1213 return 0;