summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/qlogic
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2012-04-07 05:48:59 +0400
committerLen Brown <len.brown@intel.com>2012-04-07 05:48:59 +0400
commiteeaab2d8af2cf1d36d7086f22e9de42d6dd2995c (patch)
tree369b9c91a6d808944f07d2290fec6f9fe2731904 /drivers/net/ethernet/qlogic
parentee01e663373343c63e0e3d364d09f6155378dbcc (diff)
parentaaef292acf3a78d9c0bb6fb72226077d286b45d7 (diff)
downloadlinux-eeaab2d8af2cf1d36d7086f22e9de42d6dd2995c.tar.xz
Merge branches 'idle-fix' and 'misc' into release
Diffstat (limited to 'drivers/net/ethernet/qlogic')
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic.h441
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c296
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c109
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h1
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c637
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c17
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c138
-rw-r--r--drivers/net/ethernet/qlogic/qla3xxx.c3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c14
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c10
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c23
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_dbg.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_main.c86
15 files changed, 1561 insertions, 224 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
index a876dffd7101..b5de8a7b90f1 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 77
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.77"
+#define _NETXEN_NIC_LINUX_SUBVERSION 78
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.78"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -686,6 +686,18 @@ struct netxen_recv_context {
dma_addr_t phys_addr;
};
+struct _cdrp_cmd {
+ u32 cmd;
+ u32 arg1;
+ u32 arg2;
+ u32 arg3;
+};
+
+struct netxen_cmd_args {
+ struct _cdrp_cmd req;
+ struct _cdrp_cmd rsp;
+};
+
/* New HW context creation */
#define NX_OS_CRB_RETRY_COUNT 4000
@@ -942,7 +954,7 @@ typedef struct nx_mac_list_s {
struct nx_vlan_ip_list {
struct list_head list;
- u32 ip_addr;
+ __be32 ip_addr;
};
/*
@@ -1142,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))
@@ -1159,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;
@@ -1263,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);
@@ -1352,7 +1780,7 @@ int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
int netxen_config_rss(struct netxen_adapter *adapter, int enable);
-int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd);
+int netxen_config_ipaddr(struct netxen_adapter *adapter, __be32 ip, int cmd);
int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
void netxen_pci_camqm_read_2M(struct netxen_adapter *, u64, u64 *);
@@ -1365,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
*/
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
index a925392abd6f..f3c0057a802b 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
@@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
}
static u32
-netxen_issue_cmd(struct netxen_adapter *adapter,
- u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
+netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd)
{
u32 rsp;
u32 signature = 0;
u32 rcode = NX_RCODE_SUCCESS;
- signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
-
+ signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func,
+ NXHAL_VERSION);
/* Acquire semaphore before accessing CRB */
if (netxen_api_lock(adapter))
return NX_RCODE_TIMEOUT;
NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
- NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
+ NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1);
- NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
+ NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2);
- NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
+ NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3);
- NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
+ NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd));
rsp = netxen_poll_rsp(adapter);
@@ -83,28 +82,179 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
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)
+ cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET);
}
+ if (cmd->rsp.arg1)
+ cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
/* Release semaphore */
netxen_api_unlock(adapter);
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)
{
u32 rcode = NX_RCODE_SUCCESS;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct netxen_cmd_args cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.cmd = NX_CDRP_CMD_SET_MTU;
+ cmd.req.arg1 = recv_ctx->context_id;
+ cmd.req.arg2 = mtu;
+ cmd.req.arg3 = 0;
if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
- rcode = netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- recv_ctx->context_id,
- mtu,
- 0,
- NX_CDRP_CMD_SET_MTU);
+ netxen_issue_cmd(adapter, &cmd);
if (rcode != NX_RCODE_SUCCESS)
return -EIO;
@@ -116,15 +266,14 @@ int
nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter,
u32 speed, u32 duplex, u32 autoneg)
{
-
- return netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- speed,
- duplex,
- autoneg,
- NX_CDRP_CMD_CONFIG_GBE_PORT);
-
+ struct netxen_cmd_args cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT;
+ cmd.req.arg1 = speed;
+ cmd.req.arg2 = duplex;
+ cmd.req.arg3 = autoneg;
+ return netxen_issue_cmd(adapter, &cmd);
}
static int
@@ -139,6 +288,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
nx_cardrsp_sds_ring_t *prsp_sds;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct netxen_cmd_args cmd;
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr;
@@ -218,13 +368,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
}
phys_addr = hostrq_phys_addr;
- err = netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- (u32)(phys_addr >> 32),
- (u32)(phys_addr & 0xffffffff),
- rq_size,
- NX_CDRP_CMD_CREATE_RX_CTX);
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = (u32)(phys_addr >> 32);
+ cmd.req.arg2 = (u32)(phys_addr & 0xffffffff);
+ cmd.req.arg3 = rq_size;
+ cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX;
+ err = netxen_issue_cmd(adapter, &cmd);
if (err) {
printk(KERN_WARNING
"Failed to create rx ctx in firmware%d\n", err);
@@ -273,15 +422,15 @@ static void
nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct netxen_cmd_args cmd;
- if (netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- recv_ctx->context_id,
- NX_DESTROY_CTX_RESET,
- 0,
- NX_CDRP_CMD_DESTROY_RX_CTX)) {
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = recv_ctx->context_id;
+ cmd.req.arg2 = NX_DESTROY_CTX_RESET;
+ cmd.req.arg3 = 0;
+ cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX;
+ if (netxen_issue_cmd(adapter, &cmd)) {
printk(KERN_WARNING
"%s: Failed to destroy rx ctx in firmware\n",
netxen_nic_driver_name);
@@ -302,6 +451,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
dma_addr_t rq_phys_addr, rsp_phys_addr;
struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct netxen_cmd_args cmd;
rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -345,13 +495,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
phys_addr = rq_phys_addr;
- err = netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- (u32)(phys_addr >> 32),
- ((u32)phys_addr & 0xffffffff),
- rq_size,
- NX_CDRP_CMD_CREATE_TX_CTX);
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = (u32)(phys_addr >> 32);
+ cmd.req.arg2 = ((u32)phys_addr & 0xffffffff);
+ cmd.req.arg3 = rq_size;
+ cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX;
+ err = netxen_issue_cmd(adapter, &cmd);
if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
@@ -380,14 +529,14 @@ out_free_rq:
static void
nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
{
- if (netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- adapter->tx_context_id,
- NX_DESTROY_CTX_RESET,
- 0,
- NX_CDRP_CMD_DESTROY_TX_CTX)) {
-
+ struct netxen_cmd_args cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = adapter->tx_context_id;
+ cmd.req.arg2 = NX_DESTROY_CTX_RESET;
+ cmd.req.arg3 = 0;
+ cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX;
+ if (netxen_issue_cmd(adapter, &cmd)) {
printk(KERN_WARNING
"%s: Failed to destroy tx ctx in firmware\n",
netxen_nic_driver_name);
@@ -398,34 +547,37 @@ int
nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
{
u32 rcode;
-
- rcode = netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- reg,
- 0,
- 0,
- NX_CDRP_CMD_READ_PHY);
-
+ struct netxen_cmd_args cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = reg;
+ cmd.req.arg2 = 0;
+ cmd.req.arg3 = 0;
+ cmd.req.cmd = NX_CDRP_CMD_READ_PHY;
+ cmd.rsp.arg1 = 1;
+ rcode = netxen_issue_cmd(adapter, &cmd);
if (rcode != NX_RCODE_SUCCESS)
return -EIO;
- return NXRD32(adapter, NX_ARG1_CRB_OFFSET);
+ if (val == NULL)
+ return -EIO;
+
+ *val = cmd.rsp.arg1;
+ return 0;
}
int
nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
{
u32 rcode;
-
- rcode = netxen_issue_cmd(adapter,
- adapter->ahw.pci_func,
- NXHAL_VERSION,
- reg,
- val,
- 0,
- NX_CDRP_CMD_WRITE_PHY);
-
+ struct netxen_cmd_args cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.req.arg1 = reg;
+ cmd.req.arg2 = val;
+ cmd.req.arg3 = 0;
+ cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY;
+ rcode = netxen_issue_cmd(adapter, &cmd);
if (rcode != NX_RCODE_SUCCESS)
return -EIO;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
index 8a371985319f..8c39299331a2 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
@@ -248,6 +248,11 @@ skip:
}
}
+ if (!netif_running(dev) || !adapter->ahw.linkup) {
+ ecmd->duplex = DUPLEX_UNKNOWN;
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ }
+
return 0;
}
@@ -812,6 +817,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,
@@ -833,4 +939,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,
};
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
index dc1967c1f312..b1a897cd9a8d 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
@@ -969,6 +969,7 @@ enum {
#define NX_RCODE_FATAL_ERROR 0x80000000
#define NX_FWERROR_PEGNUM(code) ((code) & 0xff)
#define NX_FWERROR_CODE(code) ((code >> 8) & 0xfffff)
+#define NX_FWERROR_PEGSTAT1(code) ((code >> 8) & 0x1fffff)
#define FW_POLL_DELAY (2 * HZ)
#define FW_FAIL_THRESH 3
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
index 3f89e57cae50..de96a948bb7f 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
@@ -46,7 +46,6 @@ static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
void __iomem *addr, u32 data);
static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
void __iomem *addr);
-
#ifndef readq
static inline u64 readq(void __iomem *addr)
{
@@ -910,7 +909,7 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
return rv;
}
-int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd)
+int netxen_config_ipaddr(struct netxen_adapter *adapter, __be32 ip, int cmd)
{
nx_nic_req_t req;
u64 word;
@@ -923,7 +922,7 @@ int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd)
req.req_hdr = cpu_to_le64(word);
req.words[0] = cpu_to_le64(cmd);
- req.words[1] = cpu_to_le64(ip);
+ memcpy(&req.words[1], &ip, sizeof(u32));
rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
if (rv != 0) {
@@ -1051,7 +1050,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac)
if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
return -1;
- if (*mac == cpu_to_le64(~0ULL)) {
+ if (*mac == ~0ULL) {
offset = NX_OLD_MAC_ADDR_OFFSET +
(adapter->portnum * sizeof(u64));
@@ -1060,7 +1059,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac)
offset, sizeof(u64), pmac) == -1)
return -1;
- if (*mac == cpu_to_le64(~0ULL))
+ if (*mac == ~0ULL)
return -1;
}
return 0;
@@ -1974,3 +1973,631 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
return 0;
}
+
+static u32 netxen_md_cntrl(struct netxen_adapter *adapter,
+ struct netxen_minidump_template_hdr *template_hdr,
+ struct netxen_minidump_entry_crb *crtEntry)
+{
+ int loop_cnt, i, rv = 0, timeout_flag;
+ u32 op_count, stride;
+ u32 opcode, read_value, addr;
+ unsigned long timeout, timeout_jiffies;
+ addr = crtEntry->addr;
+ op_count = crtEntry->op_count;
+ stride = crtEntry->addr_stride;
+
+ for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
+ for (i = 0; i < sizeof(crtEntry->opcode) * 8; i++) {
+ opcode = (crtEntry->opcode & (0x1 << i));
+ if (opcode) {
+ switch (opcode) {
+ case NX_DUMP_WCRB:
+ NX_WR_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ crtEntry->value_1);
+ break;
+ case NX_DUMP_RWCRB:
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ NX_WR_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ read_value);
+ break;
+ case NX_DUMP_ANDCRB:
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ read_value &= crtEntry->value_2;
+ NX_WR_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ read_value);
+ break;
+ case NX_DUMP_ORCRB:
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ read_value |= crtEntry->value_3;
+ NX_WR_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ read_value);
+ break;
+ case NX_DUMP_POLLCRB:
+ timeout = crtEntry->poll_timeout;
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ timeout_jiffies =
+ msecs_to_jiffies(timeout) + jiffies;
+ for (timeout_flag = 0;
+ !timeout_flag
+ && ((read_value & crtEntry->value_2)
+ != crtEntry->value_1);) {
+ if (time_after(jiffies,
+ timeout_jiffies))
+ timeout_flag = 1;
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ }
+
+ if (timeout_flag) {
+ dev_err(&adapter->pdev->dev, "%s : "
+ "Timeout in poll_crb control operation.\n"
+ , __func__);
+ return -1;
+ }
+ break;
+ case NX_DUMP_RD_SAVE:
+ /* Decide which address to use */
+ if (crtEntry->state_index_a)
+ addr =
+ template_hdr->saved_state_array
+ [crtEntry->state_index_a];
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ template_hdr->saved_state_array
+ [crtEntry->state_index_v]
+ = read_value;
+ break;
+ case NX_DUMP_WRT_SAVED:
+ /* Decide which value to use */
+ if (crtEntry->state_index_v)
+ read_value =
+ template_hdr->saved_state_array
+ [crtEntry->state_index_v];
+ else
+ read_value = crtEntry->value_1;
+
+ /* Decide which address to use */
+ if (crtEntry->state_index_a)
+ addr =
+ template_hdr->saved_state_array
+ [crtEntry->state_index_a];
+
+ NX_WR_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ read_value);
+ break;
+ case NX_DUMP_MOD_SAVE_ST:
+ read_value =
+ template_hdr->saved_state_array
+ [crtEntry->state_index_v];
+ read_value <<= crtEntry->shl;
+ read_value >>= crtEntry->shr;
+ if (crtEntry->value_2)
+ read_value &=
+ crtEntry->value_2;
+ read_value |= crtEntry->value_3;
+ read_value += crtEntry->value_1;
+ /* Write value back to state area.*/
+ template_hdr->saved_state_array
+ [crtEntry->state_index_v]
+ = read_value;
+ break;
+ default:
+ rv = 1;
+ break;
+ }
+ }
+ }
+ addr = addr + stride;
+ }
+ return rv;
+}
+
+/* Read memory or MN */
+static u32
+netxen_md_rdmem(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_rdmem
+ *memEntry, u64 *data_buff)
+{
+ u64 addr, value = 0;
+ int i = 0, loop_cnt;
+
+ addr = (u64)memEntry->read_addr;
+ loop_cnt = memEntry->read_data_size; /* This is size in bytes */
+ loop_cnt /= sizeof(value);
+
+ for (i = 0; i < loop_cnt; i++) {
+ if (netxen_nic_pci_mem_read_2M(adapter, addr, &value))
+ goto out;
+ *data_buff++ = value;
+ addr += sizeof(value);
+ }
+out:
+ return i * sizeof(value);
+}
+
+/* Read CRB operation */
+static u32 netxen_md_rd_crb(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_crb
+ *crbEntry, u32 *data_buff)
+{
+ int loop_cnt;
+ u32 op_count, addr, stride, value;
+
+ addr = crbEntry->addr;
+ op_count = crbEntry->op_count;
+ stride = crbEntry->addr_stride;
+
+ for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
+ NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0, &value);
+ *data_buff++ = addr;
+ *data_buff++ = value;
+ addr = addr + stride;
+ }
+ return loop_cnt * (2 * sizeof(u32));
+}
+
+/* Read ROM */
+static u32
+netxen_md_rdrom(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_rdrom
+ *romEntry, __le32 *data_buff)
+{
+ int i, count = 0;
+ u32 size, lck_val;
+ u32 val;
+ u32 fl_addr, waddr, raddr;
+ fl_addr = romEntry->read_addr;
+ size = romEntry->read_data_size/4;
+lock_try:
+ lck_val = readl((void __iomem *)(adapter->ahw.pci_base0 +
+ NX_FLASH_SEM2_LK));
+ if (!lck_val && count < MAX_CTL_CHECK) {
+ msleep(20);
+ count++;
+ goto lock_try;
+ }
+ writel(adapter->ahw.pci_func, (void __iomem *)(adapter->ahw.pci_base0 +
+ NX_FLASH_LOCK_ID));
+ for (i = 0; i < size; i++) {
+ waddr = fl_addr & 0xFFFF0000;
+ NX_WR_DUMP_REG(FLASH_ROM_WINDOW, adapter->ahw.pci_base0, waddr);
+ raddr = FLASH_ROM_DATA + (fl_addr & 0x0000FFFF);
+ NX_RD_DUMP_REG(raddr, adapter->ahw.pci_base0, &val);
+ *data_buff++ = cpu_to_le32(val);
+ fl_addr += sizeof(val);
+ }
+ readl((void __iomem *)(adapter->ahw.pci_base0 + NX_FLASH_SEM2_ULK));
+ return romEntry->read_data_size;
+}
+
+/* Handle L2 Cache */
+static u32
+netxen_md_L2Cache(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_cache
+ *cacheEntry, u32 *data_buff)
+{
+ int loop_cnt, i, k, timeout_flag = 0;
+ u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
+ u32 tag_value, read_cnt;
+ u8 cntl_value_w, cntl_value_r;
+ unsigned long timeout, timeout_jiffies;
+
+ loop_cnt = cacheEntry->op_count;
+ read_addr = cacheEntry->read_addr;
+ cntrl_addr = cacheEntry->control_addr;
+ cntl_value_w = (u32) cacheEntry->write_value;
+ tag_reg_addr = cacheEntry->tag_reg_addr;
+ tag_value = cacheEntry->init_tag_value;
+ read_cnt = cacheEntry->read_addr_cnt;
+
+ for (i = 0; i < loop_cnt; i++) {
+ NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
+ if (cntl_value_w)
+ NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+ (u32)cntl_value_w);
+ if (cacheEntry->poll_mask) {
+ timeout = cacheEntry->poll_wait;
+ NX_RD_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+ &cntl_value_r);
+ timeout_jiffies = msecs_to_jiffies(timeout) + jiffies;
+ for (timeout_flag = 0; !timeout_flag &&
+ ((cntl_value_r & cacheEntry->poll_mask) != 0);) {
+ if (time_after(jiffies, timeout_jiffies))
+ timeout_flag = 1;
+ NX_RD_DUMP_REG(cntrl_addr,
+ adapter->ahw.pci_base0,
+ &cntl_value_r);
+ }
+ if (timeout_flag) {
+ dev_err(&adapter->pdev->dev,
+ "Timeout in processing L2 Tag poll.\n");
+ return -1;
+ }
+ }
+ addr = read_addr;
+ for (k = 0; k < read_cnt; k++) {
+ NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0,
+ &read_value);
+ *data_buff++ = read_value;
+ addr += cacheEntry->read_addr_stride;
+ }
+ tag_value += cacheEntry->tag_value_stride;
+ }
+ return read_cnt * loop_cnt * sizeof(read_value);
+}
+
+
+/* Handle L1 Cache */
+static u32 netxen_md_L1Cache(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_cache
+ *cacheEntry, u32 *data_buff)
+{
+ int i, k, loop_cnt;
+ u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
+ u32 tag_value, read_cnt;
+ u8 cntl_value_w;
+
+ loop_cnt = cacheEntry->op_count;
+ read_addr = cacheEntry->read_addr;
+ cntrl_addr = cacheEntry->control_addr;
+ cntl_value_w = (u32) cacheEntry->write_value;
+ tag_reg_addr = cacheEntry->tag_reg_addr;
+ tag_value = cacheEntry->init_tag_value;
+ read_cnt = cacheEntry->read_addr_cnt;
+
+ for (i = 0; i < loop_cnt; i++) {
+ NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
+ NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+ (u32) cntl_value_w);
+ addr = read_addr;
+ for (k = 0; k < read_cnt; k++) {
+ NX_RD_DUMP_REG(addr,
+ adapter->ahw.pci_base0,
+ &read_value);
+ *data_buff++ = read_value;
+ addr += cacheEntry->read_addr_stride;
+ }
+ tag_value += cacheEntry->tag_value_stride;
+ }
+ return read_cnt * loop_cnt * sizeof(read_value);
+}
+
+/* Reading OCM memory */
+static u32
+netxen_md_rdocm(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_rdocm
+ *ocmEntry, u32 *data_buff)
+{
+ int i, loop_cnt;
+ u32 value;
+ void __iomem *addr;
+ addr = (ocmEntry->read_addr + adapter->ahw.pci_base0);
+ loop_cnt = ocmEntry->op_count;
+
+ for (i = 0; i < loop_cnt; i++) {
+ value = readl(addr);
+ *data_buff++ = value;
+ addr += ocmEntry->read_addr_stride;
+ }
+ return i * sizeof(u32);
+}
+
+/* Read MUX data */
+static u32
+netxen_md_rdmux(struct netxen_adapter *adapter, struct netxen_minidump_entry_mux
+ *muxEntry, u32 *data_buff)
+{
+ int loop_cnt = 0;
+ u32 read_addr, read_value, select_addr, sel_value;
+
+ read_addr = muxEntry->read_addr;
+ sel_value = muxEntry->select_value;
+ select_addr = muxEntry->select_addr;
+
+ for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) {
+ NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, sel_value);
+ NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0, &read_value);
+ *data_buff++ = sel_value;
+ *data_buff++ = read_value;
+ sel_value += muxEntry->select_value_stride;
+ }
+ return loop_cnt * (2 * sizeof(u32));
+}
+
+/* Handling Queue State Reads */
+static u32
+netxen_md_rdqueue(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry_queue
+ *queueEntry, u32 *data_buff)
+{
+ int loop_cnt, k;
+ u32 queue_id, read_addr, read_value, read_stride, select_addr, read_cnt;
+
+ read_cnt = queueEntry->read_addr_cnt;
+ read_stride = queueEntry->read_addr_stride;
+ select_addr = queueEntry->select_addr;
+
+ for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count;
+ loop_cnt++) {
+ NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
+ read_addr = queueEntry->read_addr;
+ for (k = 0; k < read_cnt; k--) {
+ NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
+ &read_value);
+ *data_buff++ = read_value;
+ read_addr += read_stride;
+ }
+ queue_id += queueEntry->queue_id_stride;
+ }
+ return loop_cnt * (read_cnt * sizeof(read_value));
+}
+
+
+/*
+* We catch an error where driver does not read
+* as much data as we expect from the entry.
+*/
+
+static int netxen_md_entry_err_chk(struct netxen_adapter *adapter,
+ struct netxen_minidump_entry *entry, int esize)
+{
+ if (esize < 0) {
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ return esize;
+ }
+ if (esize != entry->hdr.entry_capture_size) {
+ entry->hdr.entry_capture_size = esize;
+ entry->hdr.driver_flags |= NX_DUMP_SIZE_ERR;
+ dev_info(&adapter->pdev->dev,
+ "Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
+ entry->hdr.entry_type, entry->hdr.entry_capture_mask,
+ esize, entry->hdr.entry_capture_size);
+ dev_info(&adapter->pdev->dev, "Aborting further dump capture\n");
+ }
+ return 0;
+}
+
+static int netxen_parse_md_template(struct netxen_adapter *adapter)
+{
+ int num_of_entries, buff_level, e_cnt, esize;
+ int end_cnt = 0, rv = 0, sane_start = 0, sane_end = 0;
+ char *dbuff;
+ void *template_buff = adapter->mdump.md_template;
+ char *dump_buff = adapter->mdump.md_capture_buff;
+ int capture_mask = adapter->mdump.md_capture_mask;
+ struct netxen_minidump_template_hdr *template_hdr;
+ struct netxen_minidump_entry *entry;
+
+ if ((capture_mask & 0x3) != 0x3) {
+ dev_err(&adapter->pdev->dev, "Capture mask %02x below minimum needed "
+ "for valid firmware dump\n", capture_mask);
+ return -EINVAL;
+ }
+ template_hdr = (struct netxen_minidump_template_hdr *) template_buff;
+ num_of_entries = template_hdr->num_of_entries;
+ entry = (struct netxen_minidump_entry *) ((char *) template_buff +
+ template_hdr->first_entry_offset);
+ memcpy(dump_buff, template_buff, adapter->mdump.md_template_size);
+ dump_buff = dump_buff + adapter->mdump.md_template_size;
+
+ if (template_hdr->entry_type == TLHDR)
+ sane_start = 1;
+
+ for (e_cnt = 0, buff_level = 0; e_cnt < num_of_entries; e_cnt++) {
+ if (!(entry->hdr.entry_capture_mask & capture_mask)) {
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ entry = (struct netxen_minidump_entry *)
+ ((char *) entry + entry->hdr.entry_size);
+ continue;
+ }
+ switch (entry->hdr.entry_type) {
+ case RDNOP:
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ break;
+ case RDEND:
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ if (!sane_end)
+ end_cnt = e_cnt;
+ sane_end += 1;
+ break;
+ case CNTRL:
+ rv = netxen_md_cntrl(adapter,
+ template_hdr, (void *)entry);
+ if (rv)
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ break;
+ case RDCRB:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rd_crb(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case RDMN:
+ case RDMEM:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rdmem(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case BOARD:
+ case RDROM:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rdrom(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case L2ITG:
+ case L2DTG:
+ case L2DAT:
+ case L2INS:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_L2Cache(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case L1DAT:
+ case L1INS:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_L1Cache(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case RDOCM:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rdocm(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case RDMUX:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rdmux(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ case QUEUE:
+ dbuff = dump_buff + buff_level;
+ esize = netxen_md_rdqueue(adapter,
+ (void *) entry, (void *) dbuff);
+ rv = netxen_md_entry_err_chk
+ (adapter, entry, esize);
+ if (rv < 0)
+ break;
+ buff_level += esize;
+ break;
+ default:
+ entry->hdr.driver_flags |= NX_DUMP_SKIP;
+ break;
+ }
+ /* Next entry in the template */
+ entry = (struct netxen_minidump_entry *)
+ ((char *) entry + entry->hdr.entry_size);
+ }
+ if (!sane_start || sane_end > 1) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware minidump template configuration error.\n");
+ }
+ return 0;
+}
+
+static int
+netxen_collect_minidump(struct netxen_adapter *adapter)
+{
+ int ret = 0;
+ struct netxen_minidump_template_hdr *hdr;
+ struct timespec val;
+ hdr = (struct netxen_minidump_template_hdr *)
+ adapter->mdump.md_template;
+ hdr->driver_capture_mask = adapter->mdump.md_capture_mask;
+ jiffies_to_timespec(jiffies, &val);
+ hdr->driver_timestamp = (u32) val.tv_sec;
+ hdr->driver_info_word2 = adapter->fw_version;
+ hdr->driver_info_word3 = NXRD32(adapter, CRB_DRIVER_VERSION);
+ ret = netxen_parse_md_template(adapter);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+
+void
+netxen_dump_fw(struct netxen_adapter *adapter)
+{
+ struct netxen_minidump_template_hdr *hdr;
+ int i, k, data_size = 0;
+ u32 capture_mask;
+ hdr = (struct netxen_minidump_template_hdr *)
+ adapter->mdump.md_template;
+ capture_mask = adapter->mdump.md_capture_mask;
+
+ for (i = 0x2, k = 1; (i & NX_DUMP_MASK_MAX); i <<= 1, k++) {
+ if (i & capture_mask)
+ data_size += hdr->capture_size_array[k];
+ }
+ if (!data_size) {
+ dev_err(&adapter->pdev->dev,
+ "Invalid cap sizes for capture_mask=0x%x\n",
+ adapter->mdump.md_capture_mask);
+ return;
+ }
+ adapter->mdump.md_capture_size = data_size;
+ adapter->mdump.md_dump_size = adapter->mdump.md_template_size +
+ adapter->mdump.md_capture_size;
+ if (!adapter->mdump.md_capture_buff) {
+ adapter->mdump.md_capture_buff =
+ vmalloc(adapter->mdump.md_dump_size);
+ if (!adapter->mdump.md_capture_buff) {
+ dev_info(&adapter->pdev->dev,
+ "Unable to allocate memory for minidump "
+ "capture_buffer(%d bytes).\n",
+ adapter->mdump.md_dump_size);
+ return;
+ }
+ memset(adapter->mdump.md_capture_buff, 0,
+ adapter->mdump.md_dump_size);
+ if (netxen_collect_minidump(adapter)) {
+ adapter->mdump.has_valid_dump = 0;
+ adapter->mdump.md_dump_size = 0;
+ vfree(adapter->mdump.md_capture_buff);
+ adapter->mdump.md_capture_buff = NULL;
+ dev_err(&adapter->pdev->dev,
+ "Error in collecting firmware minidump.\n");
+ } else {
+ adapter->mdump.md_timestamp = jiffies;
+ adapter->mdump.has_valid_dump = 1;
+ adapter->fw_mdump_rdy = 1;
+ dev_info(&adapter->pdev->dev, "%s Successfully "
+ "collected fw dump.\n", adapter->netdev->name);
+ }
+
+ } else {
+ dev_info(&adapter->pdev->dev,
+ "Cannot overwrite previously collected "
+ "firmware minidump.\n");
+ adapter->fw_mdump_rdy = 1;
+ return;
+ }
+}
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index a8259cc19a63..718b27440351 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -280,13 +280,10 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
}
rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
- if (rds_ring->rx_buf_arr == NULL) {
- printk(KERN_ERR "%s: Failed to allocate "
- "rx buffer ring %d\n",
- netdev->name, ring);
+ if (rds_ring->rx_buf_arr == NULL)
/* free whatever was already allocated */
goto err_out;
- }
+
INIT_LIST_HEAD(&rds_ring->free_list);
/*
* Now go through all of them, set reference handles
@@ -449,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)) {
@@ -480,11 +477,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter)
}
buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
- if (buf == NULL) {
- printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n",
- netxen_nic_driver_name);
+ if (buf == NULL)
return -ENOMEM;
- }
for (i = 0; i < n; i++) {
if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
@@ -1353,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:
@@ -1494,7 +1487,7 @@ netxen_alloc_rx_skb(struct netxen_adapter *adapter,
dma_addr_t dma;
struct pci_dev *pdev = adapter->pdev;
- buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+ buffer->skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size);
if (!buffer->skb)
return 1;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 7dd9a4b107e6..65a718f9ccd3 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -82,7 +82,6 @@ static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
static void netxen_create_diag_entries(struct netxen_adapter *adapter);
static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
-
static int nx_dev_request_aer(struct netxen_adapter *adapter);
static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
static int netxen_can_start_firmware(struct netxen_adapter *adapter);
@@ -519,7 +518,7 @@ static int netxen_nic_set_mac(struct net_device *netdev, void *p)
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
+ return -EADDRNOTAVAIL;
if (netif_running(netdev)) {
netif_device_detach(netdev);
@@ -802,16 +801,16 @@ err_out:
static void
netxen_check_options(struct netxen_adapter *adapter)
{
- u32 fw_major, fw_minor, fw_build;
+ u32 fw_major, fw_minor, fw_build, prev_fw_version;
char brd_name[NETXEN_MAX_SHORT_NAME];
char serial_num[32];
- int i, offset, val;
- int *ptr32;
+ int i, offset, val, err;
+ __le32 *ptr32;
struct pci_dev *pdev = adapter->pdev;
adapter->driver_mismatch = 0;
- ptr32 = (int *)&serial_num;
+ ptr32 = (__le32 *)&serial_num;
offset = NX_FW_SERIAL_NUM_OFFSET;
for (i = 0; i < 8; i++) {
if (netxen_rom_fast_read(adapter, offset, &val) == -1) {
@@ -826,9 +825,22 @@ netxen_check_options(struct netxen_adapter *adapter)
fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-
+ prev_fw_version = adapter->fw_version;
adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
+ /* Get FW Mini Coredump template and store it */
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ if (adapter->mdump.md_template == NULL ||
+ adapter->fw_version > prev_fw_version) {
+ kfree(adapter->mdump.md_template);
+ adapter->mdump.md_template = NULL;
+ err = netxen_setup_minidump(adapter);
+ if (err)
+ dev_err(&adapter->pdev->dev,
+ "Failed to setup minidump rcode = %d\n", err);
+ }
+ }
+
if (adapter->portnum == 0) {
get_brd_name_by_type(adapter->ahw.board_type, brd_name);
@@ -909,7 +921,12 @@ netxen_start_firmware(struct netxen_adapter *adapter)
if (err)
return err;
- if (!netxen_can_start_firmware(adapter))
+ err = netxen_can_start_firmware(adapter);
+
+ if (err < 0)
+ return err;
+
+ if (!err)
goto wait_init;
first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
@@ -1403,7 +1420,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev = alloc_etherdev(sizeof(struct netxen_adapter));
if(!netdev) {
- dev_err(&pdev->dev, "failed to allocate net_device\n");
err = -ENOMEM;
goto err_out_free_res;
}
@@ -1529,6 +1545,18 @@ err_out_disable_pdev:
return err;
}
+static
+void netxen_cleanup_minidump(struct netxen_adapter *adapter)
+{
+ kfree(adapter->mdump.md_template);
+ adapter->mdump.md_template = NULL;
+
+ if (adapter->mdump.md_capture_buff) {
+ vfree(adapter->mdump.md_capture_buff);
+ adapter->mdump.md_capture_buff = NULL;
+ }
+}
+
static void __devexit netxen_nic_remove(struct pci_dev *pdev)
{
struct netxen_adapter *adapter;
@@ -1564,8 +1592,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
netxen_release_firmware(adapter);
- if (NX_IS_REVISION_P3(pdev->revision))
+ if (NX_IS_REVISION_P3(pdev->revision)) {
+ netxen_cleanup_minidump(adapter);
pci_disable_pcie_error_reporting(pdev);
+ }
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -2317,7 +2347,7 @@ nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
static int
nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
{
- int count;
+ int count, state;
if (netxen_api_lock(adapter))
return -EIO;
@@ -2325,8 +2355,9 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
WARN_ON(count == 0);
NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+ state = NXRD32(adapter, NX_CRB_DEV_STATE);
- if (count == 0)
+ if (count == 0 && state != NX_DEV_FAILED)
NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
netxen_api_unlock(adapter);
@@ -2355,7 +2386,7 @@ nx_dev_request_aer(struct netxen_adapter *adapter)
return ret;
}
-static int
+int
nx_dev_request_reset(struct netxen_adapter *adapter)
{
u32 state;
@@ -2366,10 +2397,11 @@ nx_dev_request_reset(struct netxen_adapter *adapter)
state = NXRD32(adapter, NX_CRB_DEV_STATE);
- if (state == NX_DEV_NEED_RESET)
+ if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED)
ret = 0;
else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) {
NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
+ adapter->flags |= NETXEN_FW_RESET_OWNER;
ret = 0;
}
@@ -2384,8 +2416,10 @@ netxen_can_start_firmware(struct netxen_adapter *adapter)
int count;
int can_start = 0;
- if (netxen_api_lock(adapter))
- return 0;
+ if (netxen_api_lock(adapter)) {
+ nx_incr_dev_ref_cnt(adapter);
+ return -1;
+ }
count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
@@ -2457,8 +2491,31 @@ netxen_fwinit_work(struct work_struct *work)
struct netxen_adapter *adapter = container_of(work,
struct netxen_adapter, fw_work.work);
int dev_state;
-
+ int count;
dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
+ if (adapter->flags & NETXEN_FW_RESET_OWNER) {
+ count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+ WARN_ON(count == 0);
+ if (count == 1) {
+ if (adapter->mdump.md_enabled) {
+ rtnl_lock();
+ netxen_dump_fw(adapter);
+ rtnl_unlock();
+ }
+ adapter->flags &= ~NETXEN_FW_RESET_OWNER;
+ if (netxen_api_lock(adapter)) {
+ clear_bit(__NX_RESETTING, &adapter->state);
+ NXWR32(adapter, NX_CRB_DEV_STATE,
+ NX_DEV_FAILED);
+ return;
+ }
+ count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+ NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
+ dev_state = NX_DEV_COLD;
+ netxen_api_unlock(adapter);
+ }
+ }
switch (dev_state) {
case NX_DEV_COLD:
@@ -2471,11 +2528,9 @@ netxen_fwinit_work(struct work_struct *work)
case NX_DEV_NEED_RESET:
case NX_DEV_INITALIZING:
- if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
netxen_schedule_work(adapter,
netxen_fwinit_work, 2 * FW_POLL_DELAY);
return;
- }
case NX_DEV_FAILED:
default:
@@ -2483,6 +2538,15 @@ netxen_fwinit_work(struct work_struct *work)
break;
}
+ if (netxen_api_lock(adapter)) {
+ clear_bit(__NX_RESETTING, &adapter->state);
+ return;
+ }
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_FAILED);
+ netxen_api_unlock(adapter);
+ dev_err(&adapter->pdev->dev, "%s: Device initialization Failed\n",
+ adapter->netdev->name);
+
clear_bit(__NX_RESETTING, &adapter->state);
}
@@ -2492,7 +2556,7 @@ netxen_detach_work(struct work_struct *work)
struct netxen_adapter *adapter = container_of(work,
struct netxen_adapter, fw_work.work);
struct net_device *netdev = adapter->netdev;
- int ref_cnt, delay;
+ int ref_cnt = 0, delay;
u32 status;
netif_device_detach(netdev);
@@ -2511,7 +2575,8 @@ netxen_detach_work(struct work_struct *work)
if (adapter->temp == NX_TEMP_PANIC)
goto err_ret;
- ref_cnt = nx_decr_dev_ref_cnt(adapter);
+ if (!(adapter->flags & NETXEN_FW_RESET_OWNER))
+ ref_cnt = nx_decr_dev_ref_cnt(adapter);
if (ref_cnt == -EIO)
goto err_ret;
@@ -2531,6 +2596,7 @@ static int
netxen_check_health(struct netxen_adapter *adapter)
{
u32 state, heartbit;
+ u32 peg_status;
struct net_device *netdev = adapter->netdev;
state = NXRD32(adapter, NX_CRB_DEV_STATE);
@@ -2551,7 +2617,7 @@ netxen_check_health(struct netxen_adapter *adapter)
* Send request to destroy context in case of tx timeout only
* and doesn't required in case of Fw hang
*/
- if (state == NX_DEV_NEED_RESET) {
+ if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED) {
adapter->need_fw_reset = 1;
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
goto detach;
@@ -2577,8 +2643,24 @@ netxen_check_health(struct netxen_adapter *adapter)
clear_bit(__NX_FW_ATTACHED, &adapter->state);
- dev_info(&netdev->dev, "firmware hang detected\n");
-
+ dev_err(&netdev->dev, "firmware hang detected\n");
+ peg_status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+ dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n"
+ "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
+ "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
+ "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
+ "PEG_NET_4_PC: 0x%x\n",
+ peg_status,
+ NXRD32(adapter, NETXEN_PEG_HALT_STATUS2),
+ NXRD32(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c),
+ NXRD32(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c),
+ NXRD32(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c),
+ NXRD32(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c),
+ NXRD32(adapter, NETXEN_CRB_PEG_NET_4 + 0x3c));
+ if (NX_FWERROR_PEGSTAT1(peg_status) == 0x67)
+ dev_err(&adapter->pdev->dev,
+ "Firmware aborted with error code 0x00006700. "
+ "Device is being reset.\n");
detach:
if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
!test_and_set_bit(__NX_RESETTING, &adapter->state))
@@ -2848,13 +2930,12 @@ static struct bin_attribute bin_attr_mem = {
static void
netxen_create_sysfs_entries(struct netxen_adapter *adapter)
{
- struct net_device *netdev = adapter->netdev;
- struct device *dev = &netdev->dev;
+ struct device *dev = &adapter->pdev->dev;
if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
/* bridged_mode control */
if (device_create_file(dev, &dev_attr_bridged_mode)) {
- dev_warn(&netdev->dev,
+ dev_warn(dev,
"failed to create bridged_mode sysfs entry\n");
}
}
@@ -2863,8 +2944,7 @@ netxen_create_sysfs_entries(struct netxen_adapter *adapter)
static void
netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
{
- struct net_device *netdev = adapter->netdev;
- struct device *dev = &netdev->dev;
+ struct device *dev = &adapter->pdev->dev;
if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
device_remove_file(dev, &dev_attr_bridged_mode);
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index e61560e16385..df09b1cb742f 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -2836,7 +2836,7 @@ static int ql_create_send_free_list(struct ql3_adapter *qdev)
req_q_curr++;
tx_cb->oal = kmalloc(512, GFP_KERNEL);
if (tx_cb->oal == NULL)
- return -1;
+ return -ENOMEM;
}
return 0;
}
@@ -3804,7 +3804,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
ndev = alloc_etherdev(sizeof(struct ql3_adapter));
if (!ndev) {
- pr_err("%s could not alloc etherdev\n", pci_name(pdev));
err = -ENOMEM;
goto err_out_free_regions;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 60976fc4ccc6..385a4d5c7c25 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 25
-#define QLCNIC_LINUX_VERSIONID "5.0.25"
+#define _QLCNIC_LINUX_SUBVERSION 27
+#define QLCNIC_LINUX_VERSIONID "5.0.27"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index cc228cf3d84b..89ddf7f7d7df 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -155,7 +155,6 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
int check_sfp_module = 0;
- u16 pcifn = adapter->ahw->pci_func;
/* read which mode */
if (adapter->ahw->port_type == QLCNIC_GBE) {
@@ -194,10 +193,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
goto skip;
}
- val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
- ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
- P3P_LINK_SPEED_VAL(pcifn, val));
- ecmd->duplex = DUPLEX_FULL;
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
ecmd->autoneg = AUTONEG_DISABLE;
} else
return -EIO;
@@ -722,7 +719,7 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
int i, loop, cnt = 0;
for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
- skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE);
+ skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
skb_put(skb, QLCNIC_ILB_PKT_SIZE);
@@ -1155,7 +1152,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
if (!fw_dump->clr) {
netdev_info(netdev, "Dump not available\n");
- qlcnic_api_unlock(adapter);
return -EINVAL;
}
/* Copy template header first */
@@ -1174,7 +1170,7 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
vfree(fw_dump->data);
fw_dump->data = NULL;
fw_dump->clr = 0;
-
+ netdev_info(netdev, "extracted the FW dump Successfully\n");
return 0;
}
@@ -1192,7 +1188,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
return ret;
}
if (fw_dump->clr) {
- dev_info(&adapter->pdev->dev,
+ netdev_info(netdev,
"Previous dump not cleared, not forcing dump\n");
return ret;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index 38669583840c..d32cf0ddf1b9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -1369,7 +1369,13 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
adapter->module_type = module;
adapter->link_autoneg = autoneg;
- adapter->link_speed = link_speed;
+
+ if (link_status) {
+ adapter->link_speed = link_speed;
+ } else {
+ adapter->link_speed = SPEED_UNKNOWN;
+ adapter->link_duplex = DUPLEX_UNKNOWN;
+ }
}
static void
@@ -1434,7 +1440,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
dma_addr_t dma;
struct pci_dev *pdev = adapter->pdev;
- skb = dev_alloc_skb(rds_ring->skb_size);
+ skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size);
if (!skb) {
adapter->stats.skb_alloc_failure++;
return -ENOMEM;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 69b8e4ef14d9..75c32e875fef 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -301,7 +301,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
return -EOPNOTSUPP;
if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
+ return -EADDRNOTAVAIL;
if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
netif_device_detach(netdev);
@@ -1458,8 +1458,10 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter)
if (netif_running(netdev)) {
err = qlcnic_attach(adapter);
- if (!err)
+ if (!err) {
__qlcnic_up(adapter, netdev);
+ qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+ }
}
netif_device_attach(netdev);
@@ -1576,7 +1578,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev = alloc_etherdev(sizeof(struct qlcnic_adapter));
if (!netdev) {
- dev_err(&pdev->dev, "failed to allocate net_device\n");
err = -ENOMEM;
goto err_out_free_res;
}
@@ -3000,8 +3001,18 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
void
qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
{
- u32 state;
-
+ u32 state, xg_val = 0, gb_val = 0;
+
+ qlcnic_xg_set_xg0_mask(xg_val);
+ qlcnic_xg_set_xg1_mask(xg_val);
+ QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val);
+ qlcnic_gb_set_gb0_mask(gb_val);
+ qlcnic_gb_set_gb1_mask(gb_val);
+ qlcnic_gb_set_gb2_mask(gb_val);
+ qlcnic_gb_set_gb3_mask(gb_val);
+ QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val);
+ dev_info(&adapter->pdev->dev, "Pause control frames disabled"
+ " on all ports\n");
adapter->need_fw_reset = 1;
if (qlcnic_api_lock(adapter))
return;
@@ -3150,7 +3161,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c),
QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c));
peg_status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);
- if (LSW(MSB(peg_status)) == 0x67)
+ if (QLCNIC_FWERROR_CODE(peg_status) == 0x67)
dev_err(&adapter->pdev->dev,
"Firmware aborted with error code 0x00006700. "
"Device is being reset.\n");
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h
index b8478aab050e..5a639df33f18 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge.h
+++ b/drivers/net/ethernet/qlogic/qlge/qlge.h
@@ -18,7 +18,7 @@
*/
#define DRV_NAME "qlge"
#define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION "v1.00.00.29.00.00-01"
+#define DRV_VERSION "v1.00.00.30.00.00-01"
#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index fca804f36d61..58185b604b72 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -1824,10 +1824,8 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id)
pr_err("%s: Enter\n", __func__);
ptr = kmalloc(size, GFP_ATOMIC);
- if (ptr == NULL) {
- pr_err("%s: Couldn't allocate a buffer\n", __func__);
+ if (ptr == NULL)
return;
- }
if (ql_write_cfg(qdev, ptr, size, bit, q_id)) {
pr_err("%s: Failed to upload control block!\n", __func__);
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index b54898737284..49343ec21c82 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -375,13 +375,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
u32 lower =
(addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
(addr[5]);
-
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Adding %s address %pM at index %d in the CAM.\n",
- type == MAC_ADDR_TYPE_MULTI_MAC ?
- "MULTICAST" : "UNICAST",
- addr, index);
-
status =
ql_wait_reg_rdy(qdev,
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
@@ -430,12 +423,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
* addressing. It's either MAC_ADDR_E on or off.
* That's bit-27 we're talking about.
*/
- netif_info(qdev, ifup, qdev->ndev,
- "%s VLAN ID %d %s the CAM.\n",
- enable_bit ? "Adding" : "Removing",
- index,
- enable_bit ? "to" : "from");
-
status =
ql_wait_reg_rdy(qdev,
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
@@ -535,28 +522,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
int status = -EINVAL; /* Return error if no mask match. */
u32 value = 0;
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "%s %s mask %s the routing reg.\n",
- enable ? "Adding" : "Removing",
- index == RT_IDX_ALL_ERR_SLOT ? "MAC ERROR/ALL ERROR" :
- index == RT_IDX_IP_CSUM_ERR_SLOT ? "IP CSUM ERROR" :
- index == RT_IDX_TCP_UDP_CSUM_ERR_SLOT ? "TCP/UDP CSUM ERROR" :
- index == RT_IDX_BCAST_SLOT ? "BROADCAST" :
- index == RT_IDX_MCAST_MATCH_SLOT ? "MULTICAST MATCH" :
- index == RT_IDX_ALLMULTI_SLOT ? "ALL MULTICAST MATCH" :
- index == RT_IDX_UNUSED6_SLOT ? "UNUSED6" :
- index == RT_IDX_UNUSED7_SLOT ? "UNUSED7" :
- index == RT_IDX_RSS_MATCH_SLOT ? "RSS ALL/IPV4 MATCH" :
- index == RT_IDX_RSS_IPV6_SLOT ? "RSS IPV6" :
- index == RT_IDX_RSS_TCP4_SLOT ? "RSS TCP4" :
- index == RT_IDX_RSS_TCP6_SLOT ? "RSS TCP6" :
- index == RT_IDX_CAM_HIT_SLOT ? "CAM HIT" :
- index == RT_IDX_UNUSED013 ? "UNUSED13" :
- index == RT_IDX_UNUSED014 ? "UNUSED14" :
- index == RT_IDX_PROMISCUOUS_SLOT ? "PROMISCUOUS" :
- "(Bad index != RT_IDX)",
- enable ? "to" : "from");
-
switch (mask) {
case RT_IDX_CAM_HIT:
{
@@ -1178,14 +1143,16 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
int i;
while (rx_ring->lbq_free_cnt > 32) {
- for (i = 0; i < 16; i++) {
+ for (i = (rx_ring->lbq_clean_idx % 16); i < 16; i++) {
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
"lbq: try cleaning clean_idx = %d.\n",
clean_idx);
lbq_desc = &rx_ring->lbq[clean_idx];
if (ql_get_next_chunk(qdev, rx_ring, lbq_desc)) {
+ rx_ring->lbq_clean_idx = clean_idx;
netif_err(qdev, ifup, qdev->ndev,
- "Could not get a page chunk.\n");
+ "Could not get a page chunk, i=%d, clean_idx =%d .\n",
+ i, clean_idx);
return;
}
@@ -1230,7 +1197,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
int i;
while (rx_ring->sbq_free_cnt > 16) {
- for (i = 0; i < 16; i++) {
+ for (i = (rx_ring->sbq_clean_idx % 16); i < 16; i++) {
sbq_desc = &rx_ring->sbq[clean_idx];
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
"sbq: try cleaning clean_idx = %d.\n",
@@ -1576,13 +1543,14 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
} else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
(ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
/* Unfragmented ipv4 UDP frame. */
- struct iphdr *iph = (struct iphdr *) skb->data;
+ struct iphdr *iph =
+ (struct iphdr *) ((u8 *)addr + ETH_HLEN);
if (!(iph->frag_off &
cpu_to_be16(IP_MF|IP_OFFSET))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_printk(qdev, rx_status, KERN_DEBUG,
qdev->ndev,
- "TCP checksum done!\n");
+ "UDP checksum done!\n");
}
}
}
@@ -1690,7 +1658,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_printk(qdev, rx_status, KERN_DEBUG,
qdev->ndev,
- "TCP checksum done!\n");
+ "UDP checksum done!\n");
}
}
}
@@ -2312,13 +2280,9 @@ static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features)
struct ql_adapter *qdev = netdev_priv(ndev);
if (features & NETIF_F_HW_VLAN_RX) {
- netif_printk(qdev, ifup, KERN_DEBUG, ndev,
- "Turning on VLAN in NIC_RCV_CFG.\n");
ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK |
NIC_RCV_CFG_VLAN_MATCH_AND_NON);
} else {
- netif_printk(qdev, ifup, KERN_DEBUG, ndev,
- "Turning off VLAN in NIC_RCV_CFG.\n");
ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK);
}
}
@@ -3183,8 +3147,6 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
"Invalid rx_ring->type = %d.\n", rx_ring->type);
}
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Initializing rx work queue.\n");
err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb),
CFG_LCQ, rx_ring->cq_id);
if (err) {
@@ -3237,8 +3199,6 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
netif_err(qdev, ifup, qdev->ndev, "Failed to load tx_ring.\n");
return err;
}
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Successfully loaded WQICB.\n");
return err;
}
@@ -3488,12 +3448,8 @@ static void ql_free_irq(struct ql_adapter *qdev)
if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
free_irq(qdev->msi_x_entry[i].vector,
&qdev->rx_ring[i]);
- netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
- "freeing msix interrupt %d.\n", i);
} else {
free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
- netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
- "freeing msi interrupt %d.\n", i);
}
}
}
@@ -3522,17 +3478,6 @@ static int ql_request_irq(struct ql_adapter *qdev)
"Failed request for MSIX interrupt %d.\n",
i);
goto err_irq;
- } else {
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Hooked intr %d, queue type %s, with name %s.\n",
- i,
- qdev->rx_ring[i].type == DEFAULT_Q ?
- "DEFAULT_Q" :
- qdev->rx_ring[i].type == TX_Q ?
- "TX_Q" :
- qdev->rx_ring[i].type == RX_Q ?
- "RX_Q" : "",
- intr_context->name);
}
} else {
netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
@@ -3602,15 +3547,11 @@ static int ql_start_rss(struct ql_adapter *qdev)
memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Initializing RSS.\n");
-
status = ql_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0);
if (status) {
netif_err(qdev, ifup, qdev->ndev, "Failed to load RICB.\n");
return status;
}
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Successfully loaded RICB.\n");
return status;
}
@@ -3817,11 +3758,8 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
}
/* Start NAPI for the RSS queues. */
- for (i = 0; i < qdev->rss_ring_count; i++) {
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "Enabling NAPI for rx_ring[%d].\n", i);
+ for (i = 0; i < qdev->rss_ring_count; i++)
napi_enable(&qdev->rx_ring[i].napi);
- }
return status;
}
@@ -4121,10 +4059,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
rx_ring->lbq_size =
rx_ring->lbq_len * sizeof(__le64);
rx_ring->lbq_buf_size = (u16)lbq_buf_len;
- netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
- "lbq_buf_size %d, order = %d\n",
- rx_ring->lbq_buf_size,
- qdev->lbq_buf_order);
rx_ring->sbq_len = NUM_SMALL_BUFFERS;
rx_ring->sbq_size =
rx_ring->sbq_len * sizeof(__le64);