Loading drivers/net/ethernet/qlogic/netxen/netxen_nic.h +420 −1 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,7 @@ typedef struct { #define NETXEN_NIC_LRO_DISABLED 0x00 #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_FW_RESET_OWNER 0x40 #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) Loading @@ -1171,6 +1172,419 @@ typedef struct { #define __NX_DEV_UP 1 #define __NX_RESETTING 2 /* Mini Coredump FW supported version */ #define NX_MD_SUPPORT_MAJOR 4 #define NX_MD_SUPPORT_MINOR 0 #define NX_MD_SUPPORT_SUBVERSION 579 #define LSW(x) ((uint16_t)(x)) #define LSD(x) ((uint32_t)((uint64_t)(x))) #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) /* Mini Coredump mask level */ #define NX_DUMP_MASK_MIN 0x03 #define NX_DUMP_MASK_DEF 0x1f #define NX_DUMP_MASK_MAX 0xff /* Mini Coredump CDRP commands */ #define NX_CDRP_CMD_TEMP_SIZE 0x0000002f #define NX_CDRP_CMD_GET_TEMP_HDR 0x00000030 #define NX_DUMP_STATE_ARRAY_LEN 16 #define NX_DUMP_CAP_SIZE_ARRAY_LEN 8 /* Mini Coredump sysfs entries flags*/ #define NX_FORCE_FW_DUMP_KEY 0xdeadfeed #define NX_ENABLE_FW_DUMP 0xaddfeed #define NX_DISABLE_FW_DUMP 0xbadfeed #define NX_FORCE_FW_RESET 0xdeaddead /* Flash read/write address */ #define NX_FW_DUMP_REG1 0x00130060 #define NX_FW_DUMP_REG2 0x001e0000 #define NX_FLASH_SEM2_LK 0x0013C010 #define NX_FLASH_SEM2_ULK 0x0013C014 #define NX_FLASH_LOCK_ID 0x001B2100 #define FLASH_ROM_WINDOW 0x42110030 #define FLASH_ROM_DATA 0x42150000 /* Mini Coredump register read/write routine */ #define NX_RD_DUMP_REG(addr, bar0, data) do { \ writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ NX_FW_DUMP_REG1)); \ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ *data = readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + \ LSW(addr))); \ } while (0) #define NX_WR_DUMP_REG(addr, bar0, data) do { \ writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ NX_FW_DUMP_REG1)); \ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ writel(data, (void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr)));\ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr))); \ } while (0) /* Entry Type Defines */ #define RDNOP 0 #define RDCRB 1 #define RDMUX 2 #define QUEUE 3 #define BOARD 4 #define RDSRE 5 #define RDOCM 6 #define PREGS 7 #define L1DTG 8 #define L1ITG 9 #define CACHE 10 #define L1DAT 11 #define L1INS 12 #define RDSTK 13 #define RDCON 14 #define L2DTG 21 #define L2ITG 22 #define L2DAT 23 #define L2INS 24 #define RDOC3 25 #define MEMBK 32 #define RDROM 71 #define RDMEM 72 #define RDMN 73 #define INFOR 81 #define CNTRL 98 #define TLHDR 99 #define RDEND 255 #define PRIMQ 103 #define SQG2Q 104 #define SQG3Q 105 /* * Opcodes for Control Entries. * These Flags are bit fields. */ #define NX_DUMP_WCRB 0x01 #define NX_DUMP_RWCRB 0x02 #define NX_DUMP_ANDCRB 0x04 #define NX_DUMP_ORCRB 0x08 #define NX_DUMP_POLLCRB 0x10 #define NX_DUMP_RD_SAVE 0x20 #define NX_DUMP_WRT_SAVED 0x40 #define NX_DUMP_MOD_SAVE_ST 0x80 /* Driver Flags */ #define NX_DUMP_SKIP 0x80 /* driver skipped this entry */ #define NX_DUMP_SIZE_ERR 0x40 /*entry size vs capture size mismatch*/ #define NX_PCI_READ_32(ADDR) readl((ADDR)) #define NX_PCI_WRITE_32(DATA, ADDR) writel(DATA, (ADDR)) struct netxen_minidump { u32 pos; /* position in the dump buffer */ u8 fw_supports_md; /* FW supports Mini cordump */ u8 has_valid_dump; /* indicates valid dump */ u8 md_capture_mask; /* driver capture mask */ u8 md_enabled; /* Turn Mini Coredump on/off */ u32 md_dump_size; /* Total FW Mini Coredump size */ u32 md_capture_size; /* FW dump capture size */ u32 md_template_size; /* FW template size */ u32 md_template_ver; /* FW template version */ u64 md_timestamp; /* FW Mini dump timestamp */ void *md_template; /* FW template will be stored */ void *md_capture_buff; /* FW dump will be stored */ }; struct netxen_minidump_template_hdr { u32 entry_type; u32 first_entry_offset; u32 size_of_template; u32 capture_mask; u32 num_of_entries; u32 version; u32 driver_timestamp; u32 checksum; u32 driver_capture_mask; u32 driver_info_word2; u32 driver_info_word3; u32 driver_info_word4; u32 saved_state_array[NX_DUMP_STATE_ARRAY_LEN]; u32 capture_size_array[NX_DUMP_CAP_SIZE_ARRAY_LEN]; u32 rsvd[0]; }; /* Common Entry Header: Common to All Entry Types */ /* * Driver Code is for driver to write some info about the entry. * Currently not used. */ struct netxen_common_entry_hdr { u32 entry_type; u32 entry_size; u32 entry_capture_size; union { struct { u8 entry_capture_mask; u8 entry_code; u8 driver_code; u8 driver_flags; }; u32 entry_ctrl_word; }; }; /* Generic Entry Including Header */ struct netxen_minidump_entry { struct netxen_common_entry_hdr hdr; u32 entry_data00; u32 entry_data01; u32 entry_data02; u32 entry_data03; u32 entry_data04; u32 entry_data05; u32 entry_data06; u32 entry_data07; }; /* Read ROM Header */ struct netxen_minidump_entry_rdrom { struct netxen_common_entry_hdr h; union { struct { u32 select_addr_reg; }; u32 rsvd_0; }; union { struct { u8 addr_stride; u8 addr_cnt; u16 data_size; }; u32 rsvd_1; }; union { struct { u32 op_count; }; u32 rsvd_2; }; union { struct { u32 read_addr_reg; }; u32 rsvd_3; }; union { struct { u32 write_mask; }; u32 rsvd_4; }; union { struct { u32 read_mask; }; u32 rsvd_5; }; u32 read_addr; u32 read_data_size; }; /* Read CRB and Control Entry Header */ struct netxen_minidump_entry_crb { struct netxen_common_entry_hdr h; u32 addr; union { struct { u8 addr_stride; u8 state_index_a; u16 poll_timeout; }; u32 addr_cntrl; }; u32 data_size; u32 op_count; union { struct { u8 opcode; u8 state_index_v; u8 shl; u8 shr; }; u32 control_value; }; u32 value_1; u32 value_2; u32 value_3; }; /* Read Memory and MN Header */ struct netxen_minidump_entry_rdmem { struct netxen_common_entry_hdr h; union { struct { u32 select_addr_reg; }; u32 rsvd_0; }; union { struct { u8 addr_stride; u8 addr_cnt; u16 data_size; }; u32 rsvd_1; }; union { struct { u32 op_count; }; u32 rsvd_2; }; union { struct { u32 read_addr_reg; }; u32 rsvd_3; }; union { struct { u32 cntrl_addr_reg; }; u32 rsvd_4; }; union { struct { u8 wr_byte0; u8 wr_byte1; u8 poll_mask; u8 poll_cnt; }; u32 rsvd_5; }; u32 read_addr; u32 read_data_size; }; /* Read Cache L1 and L2 Header */ struct netxen_minidump_entry_cache { struct netxen_common_entry_hdr h; u32 tag_reg_addr; union { struct { u16 tag_value_stride; u16 init_tag_value; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 control_addr; union { struct { u16 write_value; u8 poll_mask; u8 poll_wait; }; u32 control_value; }; u32 read_addr; union { struct { u8 read_addr_stride; u8 read_addr_cnt; u16 rsvd_1; }; u32 read_addr_cntrl; }; }; /* Read OCM Header */ struct netxen_minidump_entry_rdocm { struct netxen_common_entry_hdr h; u32 rsvd_0; union { struct { u32 rsvd_1; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 rsvd_2; u32 rsvd_3; u32 read_addr; union { struct { u32 read_addr_stride; }; u32 read_addr_cntrl; }; }; /* Read MUX Header */ struct netxen_minidump_entry_mux { struct netxen_common_entry_hdr h; u32 select_addr; union { struct { u32 rsvd_0; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 select_value; u32 select_value_stride; u32 read_addr; u32 rsvd_1; }; /* Read Queue Header */ struct netxen_minidump_entry_queue { struct netxen_common_entry_hdr h; u32 select_addr; union { struct { u16 queue_id_stride; u16 rsvd_0; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 rsvd_1; u32 rsvd_2; u32 read_addr; union { struct { u8 read_addr_stride; u8 read_addr_cnt; u16 rsvd_3; }; u32 read_addr_cntrl; }; }; struct netxen_dummy_dma { void *addr; dma_addr_t phys_addr; Loading Loading @@ -1275,6 +1689,8 @@ struct netxen_adapter { __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; const struct firmware *fw; struct netxen_minidump mdump; /* mdump ptr */ int fw_mdump_rdy; /* for mdump ready */ }; int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val); Loading Loading @@ -1377,13 +1793,16 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable); int netxen_send_lro_cleanup(struct netxen_adapter *adapter); int netxen_setup_minidump(struct netxen_adapter *adapter); void netxen_dump_fw(struct netxen_adapter *adapter); void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring); /* Functions from netxen_nic_main.c */ int netxen_nic_reset_context(struct netxen_adapter *); int nx_dev_request_reset(struct netxen_adapter *adapter); /* * NetXen Board information */ Loading drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +143 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); } else if (rsp == NX_CDRP_RSP_OK) { cmd->rsp.cmd = NX_RCODE_SUCCESS; if (cmd->rsp.arg2) cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET); if (cmd->rsp.arg3) Loading @@ -97,6 +98,148 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) return rcode; } static int netxen_get_minidump_template_size(struct netxen_adapter *adapter) { struct netxen_cmd_args cmd; memset(&cmd, 0, sizeof(cmd)); cmd.req.cmd = NX_CDRP_CMD_TEMP_SIZE; memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); netxen_issue_cmd(adapter, &cmd); if (cmd.rsp.cmd != NX_RCODE_SUCCESS) { dev_info(&adapter->pdev->dev, "Can't get template size %d\n", cmd.rsp.cmd); return -EIO; } adapter->mdump.md_template_size = cmd.rsp.arg2; adapter->mdump.md_template_ver = cmd.rsp.arg3; return 0; } static int netxen_get_minidump_template(struct netxen_adapter *adapter) { dma_addr_t md_template_addr; void *addr; u32 size; struct netxen_cmd_args cmd; size = adapter->mdump.md_template_size; if (size == 0) { dev_err(&adapter->pdev->dev, "Can not capture Minidump " "template. Invalid template size.\n"); return NX_RCODE_INVALID_ARGS; } addr = pci_alloc_consistent(adapter->pdev, size, &md_template_addr); if (!addr) { dev_err(&adapter->pdev->dev, "Unable to allocate dmable memory for template.\n"); return -ENOMEM; } memset(addr, 0, size); memset(&cmd, 0, sizeof(cmd)); memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); cmd.req.cmd = NX_CDRP_CMD_GET_TEMP_HDR; cmd.req.arg1 = LSD(md_template_addr); cmd.req.arg2 = MSD(md_template_addr); cmd.req.arg3 |= size; netxen_issue_cmd(adapter, &cmd); if ((cmd.rsp.cmd == NX_RCODE_SUCCESS) && (size == cmd.rsp.arg2)) { memcpy(adapter->mdump.md_template, addr, size); } else { dev_err(&adapter->pdev->dev, "Failed to get minidump template, " "err_code : %d, requested_size : %d, actual_size : %d\n ", cmd.rsp.cmd, size, cmd.rsp.arg2); } pci_free_consistent(adapter->pdev, size, addr, md_template_addr); return 0; } static u32 netxen_check_template_checksum(struct netxen_adapter *adapter) { u64 sum = 0 ; u32 *buff = adapter->mdump.md_template; int count = adapter->mdump.md_template_size/sizeof(uint32_t) ; while (count-- > 0) sum += *buff++ ; while (sum >> 32) sum = (sum & 0xFFFFFFFF) + (sum >> 32) ; return ~sum; } int netxen_setup_minidump(struct netxen_adapter *adapter) { int err = 0, i; u32 *template, *tmp_buf; struct netxen_minidump_template_hdr *hdr; err = netxen_get_minidump_template_size(adapter); if (err) { adapter->mdump.fw_supports_md = 0; if ((err == NX_RCODE_CMD_INVALID) || (err == NX_RCODE_CMD_NOT_IMPL)) { dev_info(&adapter->pdev->dev, "Flashed firmware version does not support minidump, " "minimum version required is [ %u.%u.%u ].\n ", NX_MD_SUPPORT_MAJOR, NX_MD_SUPPORT_MINOR, NX_MD_SUPPORT_SUBVERSION); } return err; } if (!adapter->mdump.md_template_size) { dev_err(&adapter->pdev->dev, "Error : Invalid template size " ",should be non-zero.\n"); return -EIO; } adapter->mdump.md_template = kmalloc(adapter->mdump.md_template_size, GFP_KERNEL); if (!adapter->mdump.md_template) { dev_err(&adapter->pdev->dev, "Unable to allocate memory " "for minidump template.\n"); return -ENOMEM; } err = netxen_get_minidump_template(adapter); if (err) { if (err == NX_RCODE_CMD_NOT_IMPL) adapter->mdump.fw_supports_md = 0; goto free_template; } if (netxen_check_template_checksum(adapter)) { dev_err(&adapter->pdev->dev, "Minidump template checksum Error\n"); err = -EIO; goto free_template; } adapter->mdump.md_capture_mask = NX_DUMP_MASK_DEF; tmp_buf = (u32 *) adapter->mdump.md_template; template = (u32 *) adapter->mdump.md_template; for (i = 0; i < adapter->mdump.md_template_size/sizeof(u32); i++) *template++ = __le32_to_cpu(*tmp_buf++); hdr = (struct netxen_minidump_template_hdr *) adapter->mdump.md_template; adapter->mdump.md_capture_buff = NULL; adapter->mdump.fw_supports_md = 1; adapter->mdump.md_enabled = 1; return err; free_template: kfree(adapter->mdump.md_template); adapter->mdump.md_template = NULL; return err; } int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) { Loading drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +104 −0 Original line number Diff line number Diff line Loading @@ -812,6 +812,107 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } static int netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; if (adapter->fw_mdump_rdy) dump->len = mdump->md_dump_size; else dump->len = 0; dump->flag = mdump->md_capture_mask; dump->version = adapter->fw_version; return 0; } static int netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) { int ret = 0; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; switch (val->flag) { case NX_FORCE_FW_DUMP_KEY: if (!mdump->md_enabled) mdump->md_enabled = 1; if (adapter->fw_mdump_rdy) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); return ret; } netdev_info(netdev, "Forcing a fw dump\n"); nx_dev_request_reset(adapter); break; case NX_DISABLE_FW_DUMP: if (mdump->md_enabled) { netdev_info(netdev, "Disabling FW Dump\n"); mdump->md_enabled = 0; } break; case NX_ENABLE_FW_DUMP: if (!mdump->md_enabled) { netdev_info(netdev, "Enabling FW dump\n"); mdump->md_enabled = 1; } break; case NX_FORCE_FW_RESET: netdev_info(netdev, "Forcing FW reset\n"); nx_dev_request_reset(adapter); adapter->flags &= ~NETXEN_FW_RESET_OWNER; break; default: if (val->flag <= NX_DUMP_MASK_MAX && val->flag >= NX_DUMP_MASK_MIN) { mdump->md_capture_mask = val->flag & 0xff; netdev_info(netdev, "Driver mask changed to: 0x%x\n", mdump->md_capture_mask); break; } netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag); return -EINVAL; } return ret; } static int netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, void *buffer) { int i, copy_sz; u32 *hdr_ptr, *data; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; if (!adapter->fw_mdump_rdy) { netdev_info(netdev, "Dump not available\n"); return -EINVAL; } /* Copy template header first */ copy_sz = mdump->md_template_size; hdr_ptr = (u32 *) mdump->md_template; data = buffer; for (i = 0; i < copy_sz/sizeof(u32); i++) *data++ = cpu_to_le32(*hdr_ptr++); /* Copy captured dump data */ memcpy(buffer + copy_sz, mdump->md_capture_buff + mdump->md_template_size, mdump->md_capture_size); dump->len = copy_sz + mdump->md_capture_size; dump->flag = mdump->md_capture_mask; /* Free dump area once data has been captured */ vfree(mdump->md_capture_buff); mdump->md_capture_buff = NULL; adapter->fw_mdump_rdy = 0; netdev_info(netdev, "extracted the fw dump Successfully\n"); return 0; } const struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, Loading @@ -833,4 +934,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { .get_sset_count = netxen_get_sset_count, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, .get_dump_flag = netxen_get_dump_flag, .get_dump_data = netxen_get_dump_data, .set_dump = netxen_set_dump, }; drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +628 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +1 −2 Original line number Diff line number Diff line Loading @@ -446,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) /* resetall */ netxen_rom_lock(adapter); NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xfeffffff); netxen_rom_unlock(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { Loading Loading @@ -1347,7 +1347,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) do { val = NXRD32(adapter, CRB_CMDPEG_STATE); switch (val) { case PHAN_INITIALIZE_COMPLETE: case PHAN_INITIALIZE_ACK: Loading Loading
drivers/net/ethernet/qlogic/netxen/netxen_nic.h +420 −1 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,7 @@ typedef struct { #define NETXEN_NIC_LRO_DISABLED 0x00 #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_FW_RESET_OWNER 0x40 #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) Loading @@ -1171,6 +1172,419 @@ typedef struct { #define __NX_DEV_UP 1 #define __NX_RESETTING 2 /* Mini Coredump FW supported version */ #define NX_MD_SUPPORT_MAJOR 4 #define NX_MD_SUPPORT_MINOR 0 #define NX_MD_SUPPORT_SUBVERSION 579 #define LSW(x) ((uint16_t)(x)) #define LSD(x) ((uint32_t)((uint64_t)(x))) #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) /* Mini Coredump mask level */ #define NX_DUMP_MASK_MIN 0x03 #define NX_DUMP_MASK_DEF 0x1f #define NX_DUMP_MASK_MAX 0xff /* Mini Coredump CDRP commands */ #define NX_CDRP_CMD_TEMP_SIZE 0x0000002f #define NX_CDRP_CMD_GET_TEMP_HDR 0x00000030 #define NX_DUMP_STATE_ARRAY_LEN 16 #define NX_DUMP_CAP_SIZE_ARRAY_LEN 8 /* Mini Coredump sysfs entries flags*/ #define NX_FORCE_FW_DUMP_KEY 0xdeadfeed #define NX_ENABLE_FW_DUMP 0xaddfeed #define NX_DISABLE_FW_DUMP 0xbadfeed #define NX_FORCE_FW_RESET 0xdeaddead /* Flash read/write address */ #define NX_FW_DUMP_REG1 0x00130060 #define NX_FW_DUMP_REG2 0x001e0000 #define NX_FLASH_SEM2_LK 0x0013C010 #define NX_FLASH_SEM2_ULK 0x0013C014 #define NX_FLASH_LOCK_ID 0x001B2100 #define FLASH_ROM_WINDOW 0x42110030 #define FLASH_ROM_DATA 0x42150000 /* Mini Coredump register read/write routine */ #define NX_RD_DUMP_REG(addr, bar0, data) do { \ writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ NX_FW_DUMP_REG1)); \ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ *data = readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + \ LSW(addr))); \ } while (0) #define NX_WR_DUMP_REG(addr, bar0, data) do { \ writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ NX_FW_DUMP_REG1)); \ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ writel(data, (void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr)));\ readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr))); \ } while (0) /* Entry Type Defines */ #define RDNOP 0 #define RDCRB 1 #define RDMUX 2 #define QUEUE 3 #define BOARD 4 #define RDSRE 5 #define RDOCM 6 #define PREGS 7 #define L1DTG 8 #define L1ITG 9 #define CACHE 10 #define L1DAT 11 #define L1INS 12 #define RDSTK 13 #define RDCON 14 #define L2DTG 21 #define L2ITG 22 #define L2DAT 23 #define L2INS 24 #define RDOC3 25 #define MEMBK 32 #define RDROM 71 #define RDMEM 72 #define RDMN 73 #define INFOR 81 #define CNTRL 98 #define TLHDR 99 #define RDEND 255 #define PRIMQ 103 #define SQG2Q 104 #define SQG3Q 105 /* * Opcodes for Control Entries. * These Flags are bit fields. */ #define NX_DUMP_WCRB 0x01 #define NX_DUMP_RWCRB 0x02 #define NX_DUMP_ANDCRB 0x04 #define NX_DUMP_ORCRB 0x08 #define NX_DUMP_POLLCRB 0x10 #define NX_DUMP_RD_SAVE 0x20 #define NX_DUMP_WRT_SAVED 0x40 #define NX_DUMP_MOD_SAVE_ST 0x80 /* Driver Flags */ #define NX_DUMP_SKIP 0x80 /* driver skipped this entry */ #define NX_DUMP_SIZE_ERR 0x40 /*entry size vs capture size mismatch*/ #define NX_PCI_READ_32(ADDR) readl((ADDR)) #define NX_PCI_WRITE_32(DATA, ADDR) writel(DATA, (ADDR)) struct netxen_minidump { u32 pos; /* position in the dump buffer */ u8 fw_supports_md; /* FW supports Mini cordump */ u8 has_valid_dump; /* indicates valid dump */ u8 md_capture_mask; /* driver capture mask */ u8 md_enabled; /* Turn Mini Coredump on/off */ u32 md_dump_size; /* Total FW Mini Coredump size */ u32 md_capture_size; /* FW dump capture size */ u32 md_template_size; /* FW template size */ u32 md_template_ver; /* FW template version */ u64 md_timestamp; /* FW Mini dump timestamp */ void *md_template; /* FW template will be stored */ void *md_capture_buff; /* FW dump will be stored */ }; struct netxen_minidump_template_hdr { u32 entry_type; u32 first_entry_offset; u32 size_of_template; u32 capture_mask; u32 num_of_entries; u32 version; u32 driver_timestamp; u32 checksum; u32 driver_capture_mask; u32 driver_info_word2; u32 driver_info_word3; u32 driver_info_word4; u32 saved_state_array[NX_DUMP_STATE_ARRAY_LEN]; u32 capture_size_array[NX_DUMP_CAP_SIZE_ARRAY_LEN]; u32 rsvd[0]; }; /* Common Entry Header: Common to All Entry Types */ /* * Driver Code is for driver to write some info about the entry. * Currently not used. */ struct netxen_common_entry_hdr { u32 entry_type; u32 entry_size; u32 entry_capture_size; union { struct { u8 entry_capture_mask; u8 entry_code; u8 driver_code; u8 driver_flags; }; u32 entry_ctrl_word; }; }; /* Generic Entry Including Header */ struct netxen_minidump_entry { struct netxen_common_entry_hdr hdr; u32 entry_data00; u32 entry_data01; u32 entry_data02; u32 entry_data03; u32 entry_data04; u32 entry_data05; u32 entry_data06; u32 entry_data07; }; /* Read ROM Header */ struct netxen_minidump_entry_rdrom { struct netxen_common_entry_hdr h; union { struct { u32 select_addr_reg; }; u32 rsvd_0; }; union { struct { u8 addr_stride; u8 addr_cnt; u16 data_size; }; u32 rsvd_1; }; union { struct { u32 op_count; }; u32 rsvd_2; }; union { struct { u32 read_addr_reg; }; u32 rsvd_3; }; union { struct { u32 write_mask; }; u32 rsvd_4; }; union { struct { u32 read_mask; }; u32 rsvd_5; }; u32 read_addr; u32 read_data_size; }; /* Read CRB and Control Entry Header */ struct netxen_minidump_entry_crb { struct netxen_common_entry_hdr h; u32 addr; union { struct { u8 addr_stride; u8 state_index_a; u16 poll_timeout; }; u32 addr_cntrl; }; u32 data_size; u32 op_count; union { struct { u8 opcode; u8 state_index_v; u8 shl; u8 shr; }; u32 control_value; }; u32 value_1; u32 value_2; u32 value_3; }; /* Read Memory and MN Header */ struct netxen_minidump_entry_rdmem { struct netxen_common_entry_hdr h; union { struct { u32 select_addr_reg; }; u32 rsvd_0; }; union { struct { u8 addr_stride; u8 addr_cnt; u16 data_size; }; u32 rsvd_1; }; union { struct { u32 op_count; }; u32 rsvd_2; }; union { struct { u32 read_addr_reg; }; u32 rsvd_3; }; union { struct { u32 cntrl_addr_reg; }; u32 rsvd_4; }; union { struct { u8 wr_byte0; u8 wr_byte1; u8 poll_mask; u8 poll_cnt; }; u32 rsvd_5; }; u32 read_addr; u32 read_data_size; }; /* Read Cache L1 and L2 Header */ struct netxen_minidump_entry_cache { struct netxen_common_entry_hdr h; u32 tag_reg_addr; union { struct { u16 tag_value_stride; u16 init_tag_value; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 control_addr; union { struct { u16 write_value; u8 poll_mask; u8 poll_wait; }; u32 control_value; }; u32 read_addr; union { struct { u8 read_addr_stride; u8 read_addr_cnt; u16 rsvd_1; }; u32 read_addr_cntrl; }; }; /* Read OCM Header */ struct netxen_minidump_entry_rdocm { struct netxen_common_entry_hdr h; u32 rsvd_0; union { struct { u32 rsvd_1; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 rsvd_2; u32 rsvd_3; u32 read_addr; union { struct { u32 read_addr_stride; }; u32 read_addr_cntrl; }; }; /* Read MUX Header */ struct netxen_minidump_entry_mux { struct netxen_common_entry_hdr h; u32 select_addr; union { struct { u32 rsvd_0; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 select_value; u32 select_value_stride; u32 read_addr; u32 rsvd_1; }; /* Read Queue Header */ struct netxen_minidump_entry_queue { struct netxen_common_entry_hdr h; u32 select_addr; union { struct { u16 queue_id_stride; u16 rsvd_0; }; u32 select_addr_cntrl; }; u32 data_size; u32 op_count; u32 rsvd_1; u32 rsvd_2; u32 read_addr; union { struct { u8 read_addr_stride; u8 read_addr_cnt; u16 rsvd_3; }; u32 read_addr_cntrl; }; }; struct netxen_dummy_dma { void *addr; dma_addr_t phys_addr; Loading Loading @@ -1275,6 +1689,8 @@ struct netxen_adapter { __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; const struct firmware *fw; struct netxen_minidump mdump; /* mdump ptr */ int fw_mdump_rdy; /* for mdump ready */ }; int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val); Loading Loading @@ -1377,13 +1793,16 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable); int netxen_send_lro_cleanup(struct netxen_adapter *adapter); int netxen_setup_minidump(struct netxen_adapter *adapter); void netxen_dump_fw(struct netxen_adapter *adapter); void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring); /* Functions from netxen_nic_main.c */ int netxen_nic_reset_context(struct netxen_adapter *); int nx_dev_request_reset(struct netxen_adapter *adapter); /* * NetXen Board information */ Loading
drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +143 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); } else if (rsp == NX_CDRP_RSP_OK) { cmd->rsp.cmd = NX_RCODE_SUCCESS; if (cmd->rsp.arg2) cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET); if (cmd->rsp.arg3) Loading @@ -97,6 +98,148 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) return rcode; } static int netxen_get_minidump_template_size(struct netxen_adapter *adapter) { struct netxen_cmd_args cmd; memset(&cmd, 0, sizeof(cmd)); cmd.req.cmd = NX_CDRP_CMD_TEMP_SIZE; memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); netxen_issue_cmd(adapter, &cmd); if (cmd.rsp.cmd != NX_RCODE_SUCCESS) { dev_info(&adapter->pdev->dev, "Can't get template size %d\n", cmd.rsp.cmd); return -EIO; } adapter->mdump.md_template_size = cmd.rsp.arg2; adapter->mdump.md_template_ver = cmd.rsp.arg3; return 0; } static int netxen_get_minidump_template(struct netxen_adapter *adapter) { dma_addr_t md_template_addr; void *addr; u32 size; struct netxen_cmd_args cmd; size = adapter->mdump.md_template_size; if (size == 0) { dev_err(&adapter->pdev->dev, "Can not capture Minidump " "template. Invalid template size.\n"); return NX_RCODE_INVALID_ARGS; } addr = pci_alloc_consistent(adapter->pdev, size, &md_template_addr); if (!addr) { dev_err(&adapter->pdev->dev, "Unable to allocate dmable memory for template.\n"); return -ENOMEM; } memset(addr, 0, size); memset(&cmd, 0, sizeof(cmd)); memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); cmd.req.cmd = NX_CDRP_CMD_GET_TEMP_HDR; cmd.req.arg1 = LSD(md_template_addr); cmd.req.arg2 = MSD(md_template_addr); cmd.req.arg3 |= size; netxen_issue_cmd(adapter, &cmd); if ((cmd.rsp.cmd == NX_RCODE_SUCCESS) && (size == cmd.rsp.arg2)) { memcpy(adapter->mdump.md_template, addr, size); } else { dev_err(&adapter->pdev->dev, "Failed to get minidump template, " "err_code : %d, requested_size : %d, actual_size : %d\n ", cmd.rsp.cmd, size, cmd.rsp.arg2); } pci_free_consistent(adapter->pdev, size, addr, md_template_addr); return 0; } static u32 netxen_check_template_checksum(struct netxen_adapter *adapter) { u64 sum = 0 ; u32 *buff = adapter->mdump.md_template; int count = adapter->mdump.md_template_size/sizeof(uint32_t) ; while (count-- > 0) sum += *buff++ ; while (sum >> 32) sum = (sum & 0xFFFFFFFF) + (sum >> 32) ; return ~sum; } int netxen_setup_minidump(struct netxen_adapter *adapter) { int err = 0, i; u32 *template, *tmp_buf; struct netxen_minidump_template_hdr *hdr; err = netxen_get_minidump_template_size(adapter); if (err) { adapter->mdump.fw_supports_md = 0; if ((err == NX_RCODE_CMD_INVALID) || (err == NX_RCODE_CMD_NOT_IMPL)) { dev_info(&adapter->pdev->dev, "Flashed firmware version does not support minidump, " "minimum version required is [ %u.%u.%u ].\n ", NX_MD_SUPPORT_MAJOR, NX_MD_SUPPORT_MINOR, NX_MD_SUPPORT_SUBVERSION); } return err; } if (!adapter->mdump.md_template_size) { dev_err(&adapter->pdev->dev, "Error : Invalid template size " ",should be non-zero.\n"); return -EIO; } adapter->mdump.md_template = kmalloc(adapter->mdump.md_template_size, GFP_KERNEL); if (!adapter->mdump.md_template) { dev_err(&adapter->pdev->dev, "Unable to allocate memory " "for minidump template.\n"); return -ENOMEM; } err = netxen_get_minidump_template(adapter); if (err) { if (err == NX_RCODE_CMD_NOT_IMPL) adapter->mdump.fw_supports_md = 0; goto free_template; } if (netxen_check_template_checksum(adapter)) { dev_err(&adapter->pdev->dev, "Minidump template checksum Error\n"); err = -EIO; goto free_template; } adapter->mdump.md_capture_mask = NX_DUMP_MASK_DEF; tmp_buf = (u32 *) adapter->mdump.md_template; template = (u32 *) adapter->mdump.md_template; for (i = 0; i < adapter->mdump.md_template_size/sizeof(u32); i++) *template++ = __le32_to_cpu(*tmp_buf++); hdr = (struct netxen_minidump_template_hdr *) adapter->mdump.md_template; adapter->mdump.md_capture_buff = NULL; adapter->mdump.fw_supports_md = 1; adapter->mdump.md_enabled = 1; return err; free_template: kfree(adapter->mdump.md_template); adapter->mdump.md_template = NULL; return err; } int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) { Loading
drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +104 −0 Original line number Diff line number Diff line Loading @@ -812,6 +812,107 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } static int netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; if (adapter->fw_mdump_rdy) dump->len = mdump->md_dump_size; else dump->len = 0; dump->flag = mdump->md_capture_mask; dump->version = adapter->fw_version; return 0; } static int netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) { int ret = 0; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; switch (val->flag) { case NX_FORCE_FW_DUMP_KEY: if (!mdump->md_enabled) mdump->md_enabled = 1; if (adapter->fw_mdump_rdy) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); return ret; } netdev_info(netdev, "Forcing a fw dump\n"); nx_dev_request_reset(adapter); break; case NX_DISABLE_FW_DUMP: if (mdump->md_enabled) { netdev_info(netdev, "Disabling FW Dump\n"); mdump->md_enabled = 0; } break; case NX_ENABLE_FW_DUMP: if (!mdump->md_enabled) { netdev_info(netdev, "Enabling FW dump\n"); mdump->md_enabled = 1; } break; case NX_FORCE_FW_RESET: netdev_info(netdev, "Forcing FW reset\n"); nx_dev_request_reset(adapter); adapter->flags &= ~NETXEN_FW_RESET_OWNER; break; default: if (val->flag <= NX_DUMP_MASK_MAX && val->flag >= NX_DUMP_MASK_MIN) { mdump->md_capture_mask = val->flag & 0xff; netdev_info(netdev, "Driver mask changed to: 0x%x\n", mdump->md_capture_mask); break; } netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag); return -EINVAL; } return ret; } static int netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, void *buffer) { int i, copy_sz; u32 *hdr_ptr, *data; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; if (!adapter->fw_mdump_rdy) { netdev_info(netdev, "Dump not available\n"); return -EINVAL; } /* Copy template header first */ copy_sz = mdump->md_template_size; hdr_ptr = (u32 *) mdump->md_template; data = buffer; for (i = 0; i < copy_sz/sizeof(u32); i++) *data++ = cpu_to_le32(*hdr_ptr++); /* Copy captured dump data */ memcpy(buffer + copy_sz, mdump->md_capture_buff + mdump->md_template_size, mdump->md_capture_size); dump->len = copy_sz + mdump->md_capture_size; dump->flag = mdump->md_capture_mask; /* Free dump area once data has been captured */ vfree(mdump->md_capture_buff); mdump->md_capture_buff = NULL; adapter->fw_mdump_rdy = 0; netdev_info(netdev, "extracted the fw dump Successfully\n"); return 0; } const struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, Loading @@ -833,4 +934,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { .get_sset_count = netxen_get_sset_count, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, .get_dump_flag = netxen_get_dump_flag, .get_dump_data = netxen_get_dump_data, .set_dump = netxen_set_dump, };
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +628 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +1 −2 Original line number Diff line number Diff line Loading @@ -446,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) /* resetall */ netxen_rom_lock(adapter); NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xfeffffff); netxen_rom_unlock(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { Loading Loading @@ -1347,7 +1347,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) do { val = NXRD32(adapter, CRB_CMDPEG_STATE); switch (val) { case PHAN_INITIALIZE_COMPLETE: case PHAN_INITIALIZE_ACK: Loading