summaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r--drivers/net/netxen/Makefile9
-rw-r--r--drivers/net/netxen/netxen_nic.h572
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c116
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c123
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h125
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c854
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h132
-rw-r--r--drivers/net/netxen/netxen_nic_init.c400
-rw-r--r--drivers/net/netxen/netxen_nic_main.c1462
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c550
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h178
11 files changed, 2203 insertions, 2318 deletions
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile
index cf01a9130c9..11d94e2434e 100644
--- a/drivers/net/netxen/Makefile
+++ b/drivers/net/netxen/Makefile
@@ -1,4 +1,5 @@
# Copyright (C) 2003 - 2009 NetXen, Inc.
+# Copyright (C) 2009 - QLogic Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or
@@ -19,16 +20,10 @@
# The full GNU General Public License is included in this distribution
# in the file called LICENSE.
#
-# Contact Information:
-# info@netxen.com
-# NetXen Inc,
-# 18922 Forge Drive
-# Cupertino, CA 95014-0701
-#
#
obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o
netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \
- netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ctx.o
+ netxen_nic_ethtool.o netxen_nic_ctx.o
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index a9c1fcca5e7..7384f59df61 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#ifndef _NETXEN_NIC_H_
@@ -53,12 +48,13 @@
#include <asm/io.h>
#include <asm/byteorder.h>
+#include "netxen_nic_hdr.h"
#include "netxen_nic_hw.h"
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 30
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.30"
+#define _NETXEN_NIC_LINUX_SUBVERSION 50
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.50"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -143,18 +139,14 @@
#define NX_ETHERMTU 1500
#define NX_MAX_ETHERHDR 32 /* This contains some padding */
-#define NX_RX_NORMAL_BUF_MAX_LEN (NX_MAX_ETHERHDR + NX_ETHERMTU)
+#define NX_P2_RX_BUF_MAX_LEN 1760
+#define NX_P3_RX_BUF_MAX_LEN (NX_MAX_ETHERHDR + NX_ETHERMTU)
#define NX_P2_RX_JUMBO_BUF_MAX_LEN (NX_MAX_ETHERHDR + P2_MAX_MTU)
#define NX_P3_RX_JUMBO_BUF_MAX_LEN (NX_MAX_ETHERHDR + P3_MAX_MTU)
#define NX_CT_DEFAULT_RX_BUF_LEN 2048
+#define NX_LRO_BUFFER_EXTRA 2048
-#define MAX_RX_BUFFER_LENGTH 1760
-#define MAX_RX_JUMBO_BUFFER_LENGTH 8062
-#define MAX_RX_LRO_BUFFER_LENGTH (8062)
-#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2)
-#define RX_JUMBO_DMA_MAP_LEN \
- (MAX_RX_JUMBO_BUFFER_LENGTH - 2)
-#define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2)
+#define NX_RX_LRO_BUFFER_LENGTH (8060)
/*
* Maximum number of ring contexts
@@ -181,6 +173,7 @@
#define MAX_BUFFERS_PER_CMD 32
#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4)
+#define NX_MAX_TX_TIMEOUTS 2
/*
* Following are the states of the Phantom. Phantom will set them and
@@ -200,13 +193,20 @@
#define RCV_RING_JUMBO 1
#define RCV_RING_LRO 2
-#define MAX_CMD_DESCRIPTORS 4096
-#define MAX_RCV_DESCRIPTORS 16384
-#define MAX_CMD_DESCRIPTORS_HOST 1024
-#define MAX_RCV_DESCRIPTORS_1G 2048
-#define MAX_RCV_DESCRIPTORS_10G 4096
-#define MAX_JUMBO_RCV_DESCRIPTORS 1024
+#define MIN_CMD_DESCRIPTORS 64
+#define MIN_RCV_DESCRIPTORS 64
+#define MIN_JUMBO_DESCRIPTORS 32
+
+#define MAX_CMD_DESCRIPTORS 1024
+#define MAX_RCV_DESCRIPTORS_1G 4096
+#define MAX_RCV_DESCRIPTORS_10G 8192
+#define MAX_JUMBO_RCV_DESCRIPTORS_1G 512
+#define MAX_JUMBO_RCV_DESCRIPTORS_10G 1024
#define MAX_LRO_RCV_DESCRIPTORS 8
+
+#define DEFAULT_RCV_DESCRIPTORS_1G 2048
+#define DEFAULT_RCV_DESCRIPTORS_10G 4096
+
#define NETXEN_CTX_SIGNATURE 0xdee0
#define NETXEN_CTX_SIGNATURE_V2 0x0002dee0
#define NETXEN_CTX_RESET 0xbad0
@@ -225,7 +225,7 @@
#define MPORT_SINGLE_FUNCTION_MODE 0x1111
#define MPORT_MULTI_FUNCTION_MODE 0x2222
-#include "netxen_nic_phan_reg.h"
+#define NX_MAX_PCI_FUNC 8
/*
* NetXen host-peg signal message structure
@@ -302,6 +302,10 @@ struct netxen_ring_ctx {
#define FLAGS_IPSEC_SA_ADD 0x04
#define FLAGS_IPSEC_SA_DELETE 0x08
#define FLAGS_VLAN_TAGGED 0x10
+#define FLAGS_VLAN_OOB 0x40
+
+#define netxen_set_tx_vlan_tci(cmd_desc, v) \
+ (cmd_desc)->vlan_TCI = cpu_to_le16(v);
#define netxen_set_cmd_desc_port(cmd_desc, var) \
((cmd_desc)->port_ctxid |= ((var) & 0x0F))
@@ -316,58 +320,33 @@ struct netxen_ring_ctx {
cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))
#define netxen_set_tx_frags_len(_desc, _frags, _len) \
- (_desc)->num_of_buffers_total_length = \
+ (_desc)->nfrags__length = \
cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8))
struct cmd_desc_type0 {
u8 tcp_hdr_offset; /* For LSO only */
u8 ip_hdr_offset; /* For LSO only */
- /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */
- __le16 flags_opcode;
- /* Bit pattern: 0-7 total number of segments,
- 8-31 Total size of the packet */
- __le32 num_of_buffers_total_length;
- union {
- struct {
- __le32 addr_low_part2;
- __le32 addr_high_part2;
- };
- __le64 addr_buffer2;
- };
+ __le16 flags_opcode; /* 15:13 unused, 12:7 opcode, 6:0 flags */
+ __le32 nfrags__length; /* 31:8 total len, 7:0 frag count */
- __le16 reference_handle; /* changed to u16 to add mss */
- __le16 mss; /* passed by NDIS_PACKET for LSO */
- /* Bit pattern 0-3 port, 0-3 ctx id */
- u8 port_ctxid;
+ __le64 addr_buffer2;
+
+ __le16 reference_handle;
+ __le16 mss;
+ u8 port_ctxid; /* 7:4 ctxid 3:0 port */
u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */
__le16 conn_id; /* IPSec offoad only */
- union {
- struct {
- __le32 addr_low_part3;
- __le32 addr_high_part3;
- };
- __le64 addr_buffer3;
- };
- union {
- struct {
- __le32 addr_low_part1;
- __le32 addr_high_part1;
- };
- __le64 addr_buffer1;
- };
+ __le64 addr_buffer3;
+ __le64 addr_buffer1;
__le16 buffer_length[4];
- union {
- struct {
- __le32 addr_low_part4;
- __le32 addr_high_part4;
- };
- __le64 addr_buffer4;
- };
+ __le64 addr_buffer4;
- __le64 unused;
+ __le32 reserved2;
+ __le16 reserved;
+ __le16 vlan_TCI;
} __attribute__ ((aligned(64)));
@@ -380,9 +359,11 @@ struct rcv_desc {
};
/* opcode field in status_desc */
+#define NETXEN_NIC_SYN_OFFLOAD 0x03
#define NETXEN_NIC_RXPKT_DESC 0x04
#define NETXEN_OLD_RXPKT_DESC 0x3f
#define NETXEN_NIC_RESPONSE_DESC 0x05
+#define NETXEN_NIC_LRO_DESC 0x12
/* for status field in status_desc */
#define STATUS_NEED_CKSUM (1)
@@ -416,6 +397,24 @@ struct rcv_desc {
#define netxen_get_sts_opcode(sts_data) \
(((sts_data) >> 58) & 0x03F)
+#define netxen_get_lro_sts_refhandle(sts_data) \
+ ((sts_data) & 0x0FFFF)
+#define netxen_get_lro_sts_length(sts_data) \
+ (((sts_data) >> 16) & 0x0FFFF)
+#define netxen_get_lro_sts_l2_hdr_offset(sts_data) \
+ (((sts_data) >> 32) & 0x0FF)
+#define netxen_get_lro_sts_l4_hdr_offset(sts_data) \
+ (((sts_data) >> 40) & 0x0FF)
+#define netxen_get_lro_sts_timestamp(sts_data) \
+ (((sts_data) >> 48) & 0x1)
+#define netxen_get_lro_sts_type(sts_data) \
+ (((sts_data) >> 49) & 0x7)
+#define netxen_get_lro_sts_push_flag(sts_data) \
+ (((sts_data) >> 52) & 0x1)
+#define netxen_get_lro_sts_seq_number(sts_data) \
+ ((sts_data) & 0x0FFFFFFFF)
+
+
struct status_desc {
__le64 status_desc_data[2];
} __attribute__ ((aligned(16)));
@@ -459,154 +458,6 @@ struct status_desc {
#define NETXEN_BRDTYPE_P3_10G_XFP 0x0032
#define NETXEN_BRDTYPE_P3_10G_TP 0x0080
-struct netxen_board_info {
- u32 header_version;
-
- u32 board_mfg;
- u32 board_type;
- u32 board_num;
- u32 chip_id;
- u32 chip_minor;
- u32 chip_major;
- u32 chip_pkg;
- u32 chip_lot;
-
- u32 port_mask; /* available niu ports */
- u32 peg_mask; /* available pegs */
- u32 icache_ok; /* can we run with icache? */
- u32 dcache_ok; /* can we run with dcache? */
- u32 casper_ok;
-
- u32 mac_addr_lo_0;
- u32 mac_addr_lo_1;
- u32 mac_addr_lo_2;
- u32 mac_addr_lo_3;
-
- /* MN-related config */
- u32 mn_sync_mode; /* enable/ sync shift cclk/ sync shift mclk */
- u32 mn_sync_shift_cclk;
- u32 mn_sync_shift_mclk;
- u32 mn_wb_en;
- u32 mn_crystal_freq; /* in MHz */
- u32 mn_speed; /* in MHz */
- u32 mn_org;
- u32 mn_depth;
- u32 mn_ranks_0; /* ranks per slot */
- u32 mn_ranks_1; /* ranks per slot */
- u32 mn_rd_latency_0;
- u32 mn_rd_latency_1;
- u32 mn_rd_latency_2;
- u32 mn_rd_latency_3;
- u32 mn_rd_latency_4;
- u32 mn_rd_latency_5;
- u32 mn_rd_latency_6;
- u32 mn_rd_latency_7;
- u32 mn_rd_latency_8;
- u32 mn_dll_val[18];
- u32 mn_mode_reg; /* MIU DDR Mode Register */
- u32 mn_ext_mode_reg; /* MIU DDR Extended Mode Register */
- u32 mn_timing_0; /* MIU Memory Control Timing Rgister */
- u32 mn_timing_1; /* MIU Extended Memory Ctrl Timing Register */
- u32 mn_timing_2; /* MIU Extended Memory Ctrl Timing2 Register */
-
- /* SN-related config */
- u32 sn_sync_mode; /* enable/ sync shift cclk / sync shift mclk */
- u32 sn_pt_mode; /* pass through mode */
- u32 sn_ecc_en;
- u32 sn_wb_en;
- u32 sn_crystal_freq;
- u32 sn_speed;
- u32 sn_org;
- u32 sn_depth;
- u32 sn_dll_tap;
- u32 sn_rd_latency;
-
- u32 mac_addr_hi_0;
- u32 mac_addr_hi_1;
- u32 mac_addr_hi_2;
- u32 mac_addr_hi_3;
-
- u32 magic; /* indicates flash has been initialized */
-
- u32 mn_rdimm;
- u32 mn_dll_override;
-
-};
-
-#define FLASH_NUM_PORTS (4)
-
-struct netxen_flash_mac_addr {
- u32 flash_addr[32];
-};
-
-struct netxen_user_old_info {
- u8 flash_md5[16];
- u8 crbinit_md5[16];
- u8 brdcfg_md5[16];
- /* bootloader */
- u32 bootld_version;
- u32 bootld_size;
- u8 bootld_md5[16];
- /* image */
- u32 image_version;
- u32 image_size;
- u8 image_md5[16];
- /* primary image status */
- u32 primary_status;
- u32 secondary_present;
-
- /* MAC address , 4 ports */
- struct netxen_flash_mac_addr mac_addr[FLASH_NUM_PORTS];
-};
-#define FLASH_NUM_MAC_PER_PORT 32
-struct netxen_user_info {
- u8 flash_md5[16 * 64];
- /* bootloader */
- u32 bootld_version;
- u32 bootld_size;
- /* image */
- u32 image_version;
- u32 image_size;
- /* primary image status */
- u32 primary_status;
- u32 secondary_present;
-
- /* MAC address , 4 ports, 32 address per port */
- u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
- u32 sub_sys_id;
- u8 serial_num[32];
-
- /* Any user defined data */
-};
-
-/*
- * Flash Layout - new format.
- */
-struct netxen_new_user_info {
- u8 flash_md5[16 * 64];
- /* bootloader */
- u32 bootld_version;
- u32 bootld_size;
- /* image */
- u32 image_version;
- u32 image_size;
- /* primary image status */
- u32 primary_status;
- u32 secondary_present;
-
- /* MAC address , 4 ports, 32 address per port */
- u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
- u32 sub_sys_id;
- u8 serial_num[32];
-
- /* Any user defined data */
-};
-
-#define SECONDARY_IMAGE_PRESENT 0xb3b4b5b6
-#define SECONDARY_IMAGE_ABSENT 0xffffffff
-#define PRIMARY_IMAGE_GOOD 0x5a5a5a5a
-#define PRIMARY_IMAGE_BAD 0xffffffff
-
/* Flash memory map */
#define NETXEN_CRBINIT_START 0 /* crbinit section */
#define NETXEN_BRDCFG_START 0x4000 /* board config */
@@ -617,28 +468,25 @@ struct netxen_new_user_info {
#define NETXEN_PXE_START 0x3E0000 /* PXE boot rom */
#define NETXEN_USER_START 0x3E8000 /* Firmare info */
#define NETXEN_FIXED_START 0x3F0000 /* backup of crbinit */
+#define NETXEN_USER_START_OLD NETXEN_PXE_START /* very old flash */
+#define NX_OLD_MAC_ADDR_OFFSET (NETXEN_USER_START)
#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
+#define NX_FW_MAC_ADDR_OFFSET (NETXEN_USER_START+0x418)
+#define NX_FW_SERIAL_NUM_OFFSET (NETXEN_USER_START+0x81c)
#define NX_BIOS_VERSION_OFFSET (NETXEN_USER_START+0x83c)
+
+#define NX_HDR_VERSION_OFFSET (NETXEN_BRDCFG_START)
+#define NX_BRDTYPE_OFFSET (NETXEN_BRDCFG_START+0x8)
#define NX_FW_MAGIC_OFFSET (NETXEN_BRDCFG_START+0x128)
+
#define NX_FW_MIN_SIZE (0x3fffff)
#define NX_P2_MN_ROMIMAGE 0
#define NX_P3_CT_ROMIMAGE 1
#define NX_P3_MN_ROMIMAGE 2
#define NX_FLASH_ROMIMAGE 3
-#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
-
-#define NETXEN_FLASH_START (NETXEN_CRBINIT_START)
-#define NETXEN_INIT_SECTOR (0)
-#define NETXEN_PRIMARY_START (NETXEN_BOOTLD_START)
-#define NETXEN_FLASH_CRBINIT_SIZE (0x4000)
-#define NETXEN_FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info))
-#define NETXEN_FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32))
-#define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START)
-#define NETXEN_NUM_PRIMARY_SECTORS (0x20)
-#define NETXEN_NUM_CONFIG_SECTORS (1)
extern char netxen_nic_driver_name[];
/* Number of status descriptors to handle per interrupt */
@@ -653,17 +501,11 @@ struct netxen_skb_frag {
u64 length;
};
-#define _netxen_set_bits(config_word, start, bits, val) {\
- unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));\
- unsigned long long __tvalue = (val); \
- (config_word) &= ~__tmask; \
- (config_word) |= (((__tvalue) << (start)) & __tmask); \
-}
-
-#define _netxen_clear_bits(config_word, start, bits) {\
- unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start)); \
- (config_word) &= ~__tmask; \
-}
+struct netxen_recv_crb {
+ u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
+ u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+ u32 sw_int_mask[NUM_STS_DESC_RINGS];
+};
/* Following defines are for the state of the buffers */
#define NETXEN_BUFFER_FREE 0
@@ -706,8 +548,8 @@ struct netxen_hardware_context {
int qdr_sn_window;
int ddr_mn_window;
- unsigned long mn_win_crb;
- unsigned long ms_win_crb;
+ u32 mn_win_crb;
+ u32 ms_win_crb;
u8 cut_through;
u8 revision_id;
@@ -726,7 +568,8 @@ struct netxen_adapter_stats {
u64 rxdropped;
u64 txdropped;
u64 csummed;
- u64 no_rcv;
+ u64 rx_pkts;
+ u64 lro_pkts;
u64 rxbytes;
u64 txbytes;
};
@@ -737,11 +580,11 @@ struct netxen_adapter_stats {
*/
struct nx_host_rds_ring {
u32 producer;
- u32 crb_rcv_producer;
u32 num_desc;
u32 dma_size;
u32 skb_size;
u32 flags;
+ void __iomem *crb_rcv_producer;
struct rcv_desc *desc_head;
struct netxen_rx_buffer *rx_buf_arr;
struct list_head free_list;
@@ -751,9 +594,9 @@ struct nx_host_rds_ring {
struct nx_host_sds_ring {
u32 consumer;
- u32 crb_sts_consumer;
- u32 crb_intr_mask;
u32 num_desc;
+ void __iomem *crb_sts_consumer;
+ void __iomem *crb_intr_mask;
struct status_desc *desc_head;
struct netxen_adapter *adapter;
@@ -770,8 +613,8 @@ struct nx_host_tx_ring {
u32 producer;
__le32 *hw_consumer;
u32 sw_consumer;
- u32 crb_cmd_producer;
- u32 crb_cmd_consumer;
+ void __iomem *crb_cmd_producer;
+ void __iomem *crb_cmd_consumer;
u32 num_desc;
struct netdev_queue *txq;
@@ -840,7 +683,19 @@ struct netxen_recv_context {
#define NX_CDRP_CMD_GET_STATISTICS 0x0000000f
#define NX_CDRP_CMD_DELETE_STATISTICS 0x00000010
#define NX_CDRP_CMD_SET_MTU 0x00000012
-#define NX_CDRP_CMD_MAX 0x00000013
+#define NX_CDRP_CMD_READ_PHY 0x00000013
+#define NX_CDRP_CMD_WRITE_PHY 0x00000014
+#define NX_CDRP_CMD_READ_HW_REG 0x00000015
+#define NX_CDRP_CMD_GET_FLOW_CTL 0x00000016
+#define NX_CDRP_CMD_SET_FLOW_CTL 0x00000017
+#define NX_CDRP_CMD_READ_MAX_MTU 0x00000018
+#define NX_CDRP_CMD_READ_MAX_LRO 0x00000019
+#define NX_CDRP_CMD_CONFIGURE_TOE 0x0000001a
+#define NX_CDRP_CMD_FUNC_ATTRIB 0x0000001b
+#define NX_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c
+#define NX_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d
+#define NX_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e
+#define NX_CDRP_CMD_MAX 0x0000001f
#define NX_RCODE_SUCCESS 0
#define NX_RCODE_NO_HOST_MEM 1
@@ -881,6 +736,7 @@ struct netxen_recv_context {
#define NX_CAP0_LSO NX_CAP_BIT(0, 6)
#define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7)
#define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8)
+#define NX_CAP0_HW_LRO NX_CAP_BIT(0, 10)
/*
* Context state
@@ -1078,6 +934,9 @@ typedef struct {
#define NX_MAC_EVENT 0x1
+#define NX_IP_UP 2
+#define NX_IP_DOWN 3
+
/*
* Driver --> Firmware
*/
@@ -1104,7 +963,9 @@ typedef struct {
#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20
#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21
#define NX_NIC_C2C_OPCODE 22
-#define NX_NIC_H2C_OPCODE_LAST 23
+#define NX_NIC_H2C_OPCODE_CONFIG_BRIDGING 23
+#define NX_NIC_H2C_OPCODE_CONFIG_HW_LRO 24
+#define NX_NIC_H2C_OPCODE_LAST 25
/*
* Firmware --> Driver
@@ -1130,8 +991,25 @@ typedef struct {
#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */
+#define NX_NIC_LRO_REQUEST_FIRST 0
+#define NX_NIC_LRO_REQUEST_ADD_FLOW 1
+#define NX_NIC_LRO_REQUEST_DELETE_FLOW 2
+#define NX_NIC_LRO_REQUEST_TIMER 3
+#define NX_NIC_LRO_REQUEST_CLEANUP 4
+#define NX_NIC_LRO_REQUEST_ADD_FLOW_SCHEDULED 5
+#define NX_TOE_LRO_REQUEST_ADD_FLOW 6
+#define NX_TOE_LRO_REQUEST_ADD_FLOW_RESPONSE 7
+#define NX_TOE_LRO_REQUEST_DELETE_FLOW 8
+#define NX_TOE_LRO_REQUEST_DELETE_FLOW_RESPONSE 9
+#define NX_TOE_LRO_REQUEST_TIMER 10
+#define NX_NIC_LRO_REQUEST_LAST 11
+
#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5)
#define NX_FW_CAPABILITY_SWITCHING (1 << 6)
+#define NX_FW_CAPABILITY_PEXQ (1 << 7)
+#define NX_FW_CAPABILITY_BDG (1 << 8)
+#define NX_FW_CAPABILITY_FVLANTX (1 << 9)
+#define NX_FW_CAPABILITY_HW_LRO (1 << 10)
/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
@@ -1206,6 +1084,8 @@ typedef struct {
#define NETXEN_NIC_MSI_ENABLED 0x02
#define NETXEN_NIC_MSIX_ENABLED 0x04
+#define NETXEN_NIC_LRO_ENABLED 0x08
+#define NETXEN_NIC_BRIDGE_ENABLED 0X10
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
@@ -1219,6 +1099,10 @@ typedef struct {
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
+#define __NX_FW_ATTACHED 0
+#define __NX_DEV_UP 1
+#define __NX_RESETTING 2
+
struct netxen_dummy_dma {
void *addr;
dma_addr_t phys_addr;
@@ -1255,7 +1139,10 @@ struct netxen_adapter {
u8 max_mc_count;
u8 rss_supported;
u8 link_changed;
- u32 resv3;
+ u8 fw_wait_cnt;
+ u8 fw_fail_cnt;
+ u8 tx_timeo_cnt;
+ u8 need_fw_reset;
u8 has_link_events;
u8 fw_type;
@@ -1273,79 +1160,64 @@ struct netxen_adapter {
u32 irq;
u32 temp;
- u32 msi_tgt_status;
- u32 resv4;
+ u32 int_vec_bit;
+ u32 heartbit;
struct netxen_adapter_stats stats;
struct netxen_recv_context recv_ctx;
struct nx_host_tx_ring *tx_ring;
- int (*enable_phy_interrupts) (struct netxen_adapter *);
- int (*disable_phy_interrupts) (struct netxen_adapter *);
int (*macaddr_set) (struct netxen_adapter *, u8 *);
int (*set_mtu) (struct netxen_adapter *, int);
int (*set_promisc) (struct netxen_adapter *, u32);
void (*set_multi) (struct net_device *);
- int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
- int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
+ int (*phy_read) (struct netxen_adapter *, u32 reg, u32 *);
+ int (*phy_write) (struct netxen_adapter *, u32 reg, u32 val);
int (*init_port) (struct netxen_adapter *, int);
int (*stop_port) (struct netxen_adapter *);
- u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
- int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
+ u32 (*crb_read)(struct netxen_adapter *, ulong);
+ int (*crb_write)(struct netxen_adapter *, ulong, u32);
+
int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
- int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
- u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
+
unsigned long (*pci_set_window)(struct netxen_adapter *,
unsigned long long);
- struct netxen_legacy_intr_set legacy_intr;
+ u32 (*io_read)(struct netxen_adapter *, void __iomem *);
+ void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
+
+ void __iomem *tgt_mask_reg;
+ void __iomem *pci_int_reg;
+ void __iomem *tgt_status_reg;
+ void __iomem *crb_int_state_reg;
+ void __iomem *isr_int_vec;
struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
struct netxen_dummy_dma dummy_dma;
- struct work_struct watchdog_task;
- struct timer_list watchdog_timer;
+ struct delayed_work fw_work;
+
struct work_struct tx_timeout_task;
struct net_device_stats net_stats;
nx_nic_intr_coalesce_t coal;
- u32 fw_major;
+ unsigned long state;
+ u32 resv5;
u32 fw_version;
const struct firmware *fw;
};
-/*
- * NetXen dma watchdog control structure
- *
- * Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive
- * Bit 1 : disable_request => 1 req disable dma watchdog
- * Bit 2 : enable_request => 1 req enable dma watchdog
- * Bit 3-31 : unused
- */
+int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
+int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
-#define netxen_set_dma_watchdog_disable_req(config_word) \
- _netxen_set_bits(config_word, 1, 1, 1)
-#define netxen_set_dma_watchdog_enable_req(config_word) \
- _netxen_set_bits(config_word, 2, 1, 1)
-#define netxen_get_dma_watchdog_enabled(config_word) \
- ((config_word) & 0x1)
-#define netxen_get_dma_watchdog_disabled(config_word) \
- (((config_word) >> 1) & 0x1)
-
-int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
- __u32 * readval);
-int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
- long reg, __u32 val);
+int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val);
+int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val);
/* Functions available from netxen_nic_hw.c */
int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
@@ -1355,51 +1227,45 @@ int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
#define NXRD32(adapter, off) \
- (adapter->hw_read_wx(adapter, off))
+ (adapter->crb_read(adapter, off))
#define NXWR32(adapter, off, val) \
- (adapter->hw_write_wx(adapter, off, val))
+ (adapter->crb_write(adapter, off, val))
+#define NXRDIO(adapter, addr) \
+ (adapter->io_read(adapter, addr))
+#define NXWRIO(adapter, addr, val) \
+ (adapter->io_write(adapter, addr, val))
+
+int netxen_pcie_sem_lock(struct netxen_adapter *, int, u32);
+void netxen_pcie_sem_unlock(struct netxen_adapter *, int);
+
+#define netxen_rom_lock(a) \
+ netxen_pcie_sem_lock((a), 2, NETXEN_ROM_LOCK_ID)
+#define netxen_rom_unlock(a) \
+ netxen_pcie_sem_unlock((a), 2)
+#define netxen_phy_lock(a) \
+ netxen_pcie_sem_lock((a), 3, NETXEN_PHY_LOCK_ID)
+#define netxen_phy_unlock(a) \
+ netxen_pcie_sem_unlock((a), 3)
+#define netxen_api_lock(a) \
+ netxen_pcie_sem_lock((a), 5, 0)
+#define netxen_api_unlock(a) \
+ netxen_pcie_sem_unlock((a), 5)
+#define netxen_sw_lock(a) \
+ netxen_pcie_sem_lock((a), 6, 0)
+#define netxen_sw_unlock(a) \
+ netxen_pcie_sem_unlock((a), 6)
+#define crb_win_lock(a) \
+ netxen_pcie_sem_lock((a), 7, NETXEN_CRB_WIN_LOCK_ID)
+#define crb_win_unlock(a) \
+ netxen_pcie_sem_unlock((a), 7)
int netxen_nic_get_board_info(struct netxen_adapter *adapter);
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
int netxen_nic_wol_supported(struct netxen_adapter *adapter);
-u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
- ulong off, u32 data);
-int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
- u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
- u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
- unsigned long long addr);
-void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
- u32 wndw);
-
-u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
- ulong off, u32 data);
-int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
- u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
- u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
- unsigned long long addr);
-
/* Functions from netxen_nic_init.c */
-void netxen_free_adapter_offload(struct netxen_adapter *adapter);
-int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
+int netxen_init_dummy_dma(struct netxen_adapter *adapter);
+void netxen_free_dummy_dma(struct netxen_adapter *adapter);
+
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
int netxen_load_firmware(struct netxen_adapter *adapter);
int netxen_need_fw_reset(struct netxen_adapter *adapter);
@@ -1423,13 +1289,15 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr);
int netxen_alloc_sw_resources(struct netxen_adapter *adapter);
void netxen_free_sw_resources(struct netxen_adapter *adapter);
+void netxen_setup_hwops(struct netxen_adapter *adapter);
+void __iomem *netxen_get_ioaddr(struct netxen_adapter *, u32);
+
int netxen_alloc_hw_resources(struct netxen_adapter *adapter);
void netxen_free_hw_resources(struct netxen_adapter *adapter);
void netxen_release_rx_buffers(struct netxen_adapter *adapter);
void netxen_release_tx_buffers(struct netxen_adapter *adapter);
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
int netxen_init_firmware(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
@@ -1440,14 +1308,19 @@ int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
void netxen_p2_nic_set_multi(struct net_device *netdev);
void netxen_p3_nic_set_multi(struct net_device *netdev);
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
+int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode);
int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
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_linkevent_request(struct netxen_adapter *adapter, int enable);
void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
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_nic_set_mac(struct net_device *netdev, void *p);
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
@@ -1455,6 +1328,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
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 *);
+
/*
* NetXen Board information
*/
@@ -1505,56 +1381,6 @@ static inline void get_brd_name_by_type(u32 type, char *name)
name = "Unknown";
}
-static inline int
-dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
-{
- u32 ctrl;
-
- /* check if already inactive */
- ctrl = adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
- if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
- return 1;
-
- /* Send the disable request */
- netxen_set_dma_watchdog_disable_req(ctrl);
- NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
-
- return 0;
-}
-
-static inline int
-dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
-{
- u32 ctrl;
-
- ctrl = adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
- return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
-}
-
-static inline int
-dma_watchdog_wakeup(struct netxen_adapter *adapter)
-{
- u32 ctrl;
-
- ctrl = adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
- if (netxen_get_dma_watchdog_enabled(ctrl))
- return 1;
-
- /* send the wakeup request */
- netxen_set_dma_watchdog_enable_req(ctrl);
-
- NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
-
- return 0;
-}
-
-
static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring)
{
smp_mb();
@@ -1569,6 +1395,6 @@ extern void netxen_change_ringparam(struct netxen_adapter *adapter);
extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
int *valp);
-extern struct ethtool_ops netxen_nic_ethtool_ops;
+extern const struct ethtool_ops netxen_nic_ethtool_ops;
#endif /* __NETXEN_NIC_H_ */
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 9f8ae4719e2..9cb8f687804 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,55 +21,13 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
-#include "netxen_nic_phan_reg.h"
#define NXHAL_VERSION 1
-static int
-netxen_api_lock(struct netxen_adapter *adapter)
-{
- u32 done = 0, timeout = 0;
-
- for (;;) {
- /* Acquire PCIE HW semaphore5 */
- done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
-
- if (done == 1)
- break;
-
- if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
- printk(KERN_ERR "%s: lock timeout.\n", __func__);
- return -1;
- }
-
- msleep(1);
- }
-
-#if 0
- NXWR32(adapter,
- NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
-#endif
- return 0;
-}
-
-static int
-netxen_api_unlock(struct netxen_adapter *adapter)
-{
- /* Release PCIE HW semaphore5 */
- NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
- return 0;
-}
-
static u32
netxen_poll_rsp(struct netxen_adapter *adapter)
{
@@ -265,7 +224,8 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[i];
reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
- rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200);
+ rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter,
+ NETXEN_NIC_REG(reg - 0x200));
}
prsp_sds = ((nx_cardrsp_sds_ring_t *)
@@ -275,10 +235,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
sds_ring = &recv_ctx->sds_rings[i];
reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
- sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+ sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter,
+ NETXEN_NIC_REG(reg - 0x200));
reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
- sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter,
+ NETXEN_NIC_REG(reg - 0x200));
}
recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -378,7 +340,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
- tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
+ tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+ NETXEN_NIC_REG(temp - 0x200));
#if 0
adapter->tx_state =
le32_to_cpu(prsp->host_ctx_state);
@@ -416,6 +379,44 @@ nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
}
}
+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);
+
+ if (rcode != NX_RCODE_SUCCESS)
+ return -EIO;
+
+ return NXRD32(adapter, NX_ARG1_CRB_OFFSET);
+}
+
+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);
+
+ if (rcode != NX_RCODE_SUCCESS)
+ return -EIO;
+
+ return 0;
+}
+
static u64 ctx_addr_sig_regs[][3] = {
{NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
{NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
@@ -647,9 +648,10 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
}
rds_ring->desc_head = (struct rcv_desc *)addr;
- if (adapter->fw_major < 4)
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
rds_ring->crb_rcv_producer =
- recv_crb_registers[port].crb_rcv_producer[ring];
+ netxen_get_ioaddr(adapter,
+ recv_crb_registers[port].crb_rcv_producer[ring]);
}
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -668,14 +670,19 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
sds_ring->desc_head = (struct status_desc *)addr;
sds_ring->crb_sts_consumer =
- recv_crb_registers[port].crb_sts_consumer[ring];
+ netxen_get_ioaddr(adapter,
+ recv_crb_registers[port].crb_sts_consumer[ring]);
sds_ring->crb_intr_mask =
- recv_crb_registers[port].sw_int_mask[ring];
+ netxen_get_ioaddr(adapter,
+ recv_crb_registers[port].sw_int_mask[ring]);
}
- if (adapter->fw_major >= 4) {
+ if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state))
+ goto done;
+
err = nx_fw_cmd_create_rx_ctx(adapter);
if (err)
goto err_out_free;
@@ -688,6 +695,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
goto err_out_free;
}
+done:
return 0;
err_out_free:
@@ -705,7 +713,10 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
int port = adapter->portnum;
- if (adapter->fw_major >= 4) {
+ if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state))
+ goto done;
+
nx_fw_cmd_destroy_rx_ctx(adapter);
nx_fw_cmd_destroy_tx_ctx(adapter);
} else {
@@ -718,6 +729,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
/* Allow dma queues to drain after context reset */
msleep(20);
+done:
recv_ctx = &adapter->recv_ctx;
if (recv_ctx->hwctx != NULL) {
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index e16ea46c24b..714f38791a9 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#include <linux/types.h>
@@ -37,7 +32,6 @@
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
struct netxen_nic_stats {
char stat_string[ETH_GSTRING_LEN];
@@ -57,7 +51,8 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
{"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
{"csummed", NETXEN_NIC_STAT(stats.csummed)},
- {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
+ {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
+ {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
{"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
{"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
};
@@ -84,18 +79,17 @@ static void
netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- unsigned long flags;
u32 fw_major = 0;
u32 fw_minor = 0;
u32 fw_build = 0;
strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
- write_lock_irqsave(&adapter->adapter_lock, flags);
+ read_lock(&adapter->adapter_lock);
fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
+ read_unlock(&adapter->adapter_lock);
sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
@@ -490,28 +484,86 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
}
static void
-netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
+netxen_nic_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- ring->rx_pending = 0;
- ring->rx_jumbo_pending = 0;
- ring->rx_pending += adapter->recv_ctx.
- rds_rings[RCV_RING_NORMAL].num_desc;
- ring->rx_jumbo_pending += adapter->recv_ctx.
- rds_rings[RCV_RING_JUMBO].num_desc;
+ ring->rx_pending = adapter->num_rxd;
+ ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
+ ring->rx_jumbo_pending += adapter->num_lro_rxd;
ring->tx_pending = adapter->num_txd;
- if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
- else
+ ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+ } else {
ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
- ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
- ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
+ ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+ }
+
+ ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
+
ring->rx_mini_max_pending = 0;
ring->rx_mini_pending = 0;
}
+static u32
+netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
+{
+ u32 num_desc;
+ num_desc = max(val, min);
+ num_desc = min(num_desc, max);
+ num_desc = roundup_pow_of_two(num_desc);
+
+ if (val != num_desc) {
+ printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
+ netxen_nic_driver_name, r_name, num_desc, val);
+ }
+
+ return num_desc;
+}
+
+static int
+netxen_nic_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
+ u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+ u16 num_rxd, num_jumbo_rxd, num_txd;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return -EOPNOTSUPP;
+
+ if (ring->rx_mini_pending)
+ return -EOPNOTSUPP;
+
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
+ max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
+ max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+ }
+
+ num_rxd = netxen_validate_ringparam(ring->rx_pending,
+ MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
+
+ num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
+ MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
+
+ num_txd = netxen_validate_ringparam(ring->tx_pending,
+ MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
+
+ if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
+ num_jumbo_rxd == adapter->num_jumbo_rxd)
+ return 0;
+
+ adapter->num_rxd = num_rxd;
+ adapter->num_jumbo_rxd = num_jumbo_rxd;
+ adapter->num_txd = num_txd;
+
+ return netxen_nic_reset_context(adapter);
+}
+
static void
netxen_nic_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *pause)
@@ -883,7 +935,29 @@ static int netxen_get_intr_coalesce(struct net_device *netdev,
return 0;
}
-struct ethtool_ops netxen_nic_ethtool_ops = {
+static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
+{
+ struct netxen_adapter *adapter = netdev_priv(netdev);
+ int hw_lro;
+
+ if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
+ return -EINVAL;
+
+ ethtool_op_set_flags(netdev, data);
+
+ hw_lro = (data & ETH_FLAG_LRO) ? NETXEN_NIC_LRO_ENABLED : 0;
+
+ if (netxen_config_hw_lro(adapter, hw_lro))
+ return -EIO;
+
+ if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
+ return -EIO;
+
+
+ return 0;
+}
+
+const struct ethtool_ops netxen_nic_ethtool_ops = {
.get_settings = netxen_nic_get_settings,
.set_settings = netxen_nic_set_settings,
.get_drvinfo = netxen_nic_get_drvinfo,
@@ -893,6 +967,7 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.get_eeprom_len = netxen_nic_get_eeprom_len,
.get_eeprom = netxen_nic_get_eeprom,
.get_ringparam = netxen_nic_get_ringparam,
+ .set_ringparam = netxen_nic_set_ringparam,
.get_pauseparam = netxen_nic_get_pauseparam,
.set_pauseparam = netxen_nic_set_pauseparam,
.set_tx_csum = ethtool_op_set_tx_csum,
@@ -909,4 +984,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.set_rx_csum = netxen_nic_set_rx_csum,
.get_coalesce = netxen_get_intr_coalesce,
.set_coalesce = netxen_set_intr_coalesce,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = netxen_nic_set_flags,
};
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 82410367564..7a7177421d7 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#ifndef __NETXEN_NIC_HDR_H_
@@ -433,6 +428,7 @@ enum {
#define NETXEN_CRB_PEG_NET_1 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN1)
#define NETXEN_CRB_PEG_NET_2 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN2)
#define NETXEN_CRB_PEG_NET_3 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN3)
+#define NETXEN_CRB_PEG_NET_4 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SQS2)
#define NETXEN_CRB_PEG_NET_D NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND)
#define NETXEN_CRB_PEG_NET_I NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI)
#define NETXEN_CRB_DDR_NET NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN)
@@ -723,9 +719,92 @@ enum {
#define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154))
#define NETXEN_FW_VERSION_SUB (NETXEN_CAM_RAM(0x158))
#define NETXEN_ROM_LOCK_ID (NETXEN_CAM_RAM(0x100))
+#define NETXEN_PHY_LOCK_ID (NETXEN_CAM_RAM(0x120))
#define NETXEN_CRB_WIN_LOCK_ID (NETXEN_CAM_RAM(0x124))
-#define NETXEN_PHY_LOCK_ID (NETXEN_CAM_RAM(0x120))
+#define NIC_CRB_BASE (NETXEN_CAM_RAM(0x200))
+#define NIC_CRB_BASE_2 (NETXEN_CAM_RAM(0x700))
+#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
+#define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X))
+
+#define NX_CDRP_CRB_OFFSET (NETXEN_NIC_REG(0x18))
+#define NX_ARG1_CRB_OFFSET (NETXEN_NIC_REG(0x1c))
+#define NX_ARG2_CRB_OFFSET (NETXEN_NIC_REG(0x20))
+#define NX_ARG3_CRB_OFFSET (NETXEN_NIC_REG(0x24))
+#define NX_SIGN_CRB_OFFSET (NETXEN_NIC_REG(0x28))
+
+#define CRB_HOST_DUMMY_BUF_ADDR_HI (NETXEN_NIC_REG(0x3c))
+#define CRB_HOST_DUMMY_BUF_ADDR_LO (NETXEN_NIC_REG(0x40))
+
+#define CRB_CMDPEG_STATE (NETXEN_NIC_REG(0x50))
+#define CRB_RCVPEG_STATE (NETXEN_NIC_REG(0x13c))
+
+#define CRB_XG_STATE (NETXEN_NIC_REG(0x94))
+#define CRB_XG_STATE_P3 (NETXEN_NIC_REG(0x98))
+#define CRB_PF_LINK_SPEED_1 (NETXEN_NIC_REG(0xe8))
+#define CRB_PF_LINK_SPEED_2 (NETXEN_NIC_REG(0xec))
+
+#define CRB_MPORT_MODE (NETXEN_NIC_REG(0xc4))
+#define CRB_DMA_SHIFT (NETXEN_NIC_REG(0xcc))
+#define CRB_INT_VECTOR (NETXEN_NIC_REG(0xd4))
+
+#define CRB_CMD_PRODUCER_OFFSET (NETXEN_NIC_REG(0x08))
+#define CRB_CMD_CONSUMER_OFFSET (NETXEN_NIC_REG(0x0c))
+#define CRB_CMD_PRODUCER_OFFSET_1 (NETXEN_NIC_REG(0x1ac))
+#define CRB_CMD_CONSUMER_OFFSET_1 (NETXEN_NIC_REG(0x1b0))
+#define CRB_CMD_PRODUCER_OFFSET_2 (NETXEN_NIC_REG(0x1b8))
+#define CRB_CMD_CONSUMER_OFFSET_2 (NETXEN_NIC_REG(0x1bc))
+#define CRB_CMD_PRODUCER_OFFSET_3 (NETXEN_NIC_REG(0x1d0))
+#define CRB_CMD_CONSUMER_OFFSET_3 (NETXEN_NIC_REG(0x1d4))
+#define CRB_TEMP_STATE (NETXEN_NIC_REG(0x1b4))
+
+#define CRB_V2P_0 (NETXEN_NIC_REG(0x290))
+#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
+#define CRB_DRIVER_VERSION (NETXEN_NIC_REG(0x2a0))
+
+#define CRB_SW_INT_MASK_0 (NETXEN_NIC_REG(0x1d8))
+#define CRB_SW_INT_MASK_1 (NETXEN_NIC_REG(0x1e0))
+#define CRB_SW_INT_MASK_2 (NETXEN_NIC_REG(0x1e4))
+#define CRB_SW_INT_MASK_3 (NETXEN_NIC_REG(0x1e8))
+
+#define CRB_FW_CAPABILITIES_1 (NETXEN_CAM_RAM(0x128))
+#define CRB_MAC_BLOCK_START (NETXEN_CAM_RAM(0x1c0))
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
+#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
+#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270)
+#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
+
+#define INTR_SCHEME_PERPORT 0x1
+#define MSI_MODE_MULTIFUNC 0x1
+
+/* used for ethtool tests */
+#define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280)
+
+/*
+ * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
+ * which can be read by the Phantom host to get producer/consumer indexes from
+ * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
+ * registers will be used for the addresses of the ring's shared memory
+ * on the Phantom.
+ */
+
+#define nx_get_temp_val(x) ((x) >> 16)
+#define nx_get_temp_state(x) ((x) & 0xffff)
+#define nx_encode_temp(val, state) (((val) << 16) | (state))
+
+/*
+ * Temperature control.
+ */
+enum {
+ NX_TEMP_NORMAL = 0x1, /* Normal operating range */
+ NX_TEMP_WARN, /* Sound alert, temperature getting high */
+ NX_TEMP_PANIC /* Fatal error, hardware has shut down. */
+};
/* Lock IDs for PHY lock */
#define PHY_LOCK_DRIVER 0x44524956
@@ -816,16 +895,24 @@ enum {
#define PCIE_DCR 0x00d8
+#define PCIE_SEM0_LOCK (0x1c000)
+#define PCIE_SEM0_UNLOCK (0x1c004)
+#define PCIE_SEM1_LOCK (0x1c008)
+#define PCIE_SEM1_UNLOCK (0x1c00c)
#define PCIE_SEM2_LOCK (0x1c010) /* Flash lock */
#define PCIE_SEM2_UNLOCK (0x1c014) /* Flash unlock */
#define PCIE_SEM3_LOCK (0x1c018) /* Phy lock */
#define PCIE_SEM3_UNLOCK (0x1c01c) /* Phy unlock */
+#define PCIE_SEM4_LOCK (0x1c020)
+#define PCIE_SEM4_UNLOCK (0x1c024)
#define PCIE_SEM5_LOCK (0x1c028) /* API lock */
#define PCIE_SEM5_UNLOCK (0x1c02c) /* API unlock */
#define PCIE_SEM6_LOCK (0x1c030) /* sw lock */
#define PCIE_SEM6_UNLOCK (0x1c034) /* sw unlock */
#define PCIE_SEM7_LOCK (0x1c038) /* crb win lock */
#define PCIE_SEM7_UNLOCK (0x1c03c) /* crbwin unlock*/
+#define PCIE_SEM_LOCK(N) (PCIE_SEM0_LOCK + 8*(N))
+#define PCIE_SEM_UNLOCK(N) (PCIE_SEM0_UNLOCK + 8*(N))
#define PCIE_SETUP_FUNCTION (0x12040)
#define PCIE_SETUP_FUNCTION2 (0x12048)
@@ -852,8 +939,30 @@ enum {
#define NX_PEG_TUNE_MN_PRESENT 0x1
#define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c))
-#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
+#define NETXEN_DMA_WATCHDOG_CTRL (NETXEN_CAM_RAM(0x14))
#define NETXEN_PEG_ALIVE_COUNTER (NETXEN_CAM_RAM(0xb0))
+#define NETXEN_PEG_HALT_STATUS1 (NETXEN_CAM_RAM(0xa8))
+#define NETXEN_PEG_HALT_STATUS2 (NETXEN_CAM_RAM(0xac))
+#define NX_CRB_DEV_REF_COUNT (NETXEN_CAM_RAM(0x138))
+#define NX_CRB_DEV_STATE (NETXEN_CAM_RAM(0x140))
+
+/* Device State */
+#define NX_DEV_COLD 1
+#define NX_DEV_INITALIZING 2
+#define NX_DEV_READY 3
+#define NX_DEV_NEED_RESET 4
+#define NX_DEV_NEED_QUISCENT 5
+#define NX_DEV_FAILED 6
+
+#define NX_RCODE_DRIVER_INFO 0x20000000
+#define NX_RCODE_DRIVER_CAN_RELOAD 0x40000000
+#define NX_RCODE_FATAL_ERROR 0x80000000
+#define NX_FWERROR_PEGNUM(code) ((code) & 0xff)
+#define NX_FWERROR_CODE(code) ((code >> 8) & 0xfffff)
+
+#define FW_POLL_DELAY (2 * HZ)
+#define FW_FAIL_THRESH 3
+#define FW_POLL_THRESH 10
#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index b9123d445c9..32314000dfc 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,17 +21,10 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
#include <net/ip.h>
@@ -87,7 +81,6 @@ static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
return NULL;
}
-#define CRB_WIN_LOCK_TIMEOUT 100000000
static crb_128M_2M_block_map_t
crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
{{{0, 0, 0, 0} } }, /* 0: PCI */
@@ -321,6 +314,64 @@ static unsigned crb_hub_agt[64] =
#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
+#define NETXEN_PCIE_SEM_TIMEOUT 10000
+
+int
+netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
+{
+ int done = 0, timeout = 0;
+
+ while (!done) {
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_LOCK(sem)));
+ if (done == 1)
+ break;
+ if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
+ return -1;
+ msleep(1);
+ }
+
+ if (id_reg)
+ NXWR32(adapter, id_reg, adapter->portnum);
+
+ return 0;
+}
+
+void
+netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
+{
+ int val;
+ val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+}
+
+int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
+{
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
+ }
+
+ return 0;
+}
+
+/* Disable an XG interface */
+int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
+{
+ __u32 mac_cfg;
+ u32 port = adapter->physical_port;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ return 0;
+
+ if (port > NETXEN_NIU_MAX_XG_PORTS)
+ return -EINVAL;
+
+ mac_cfg = 0;
+ if (NXWR32(adapter,
+ NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
+ return -EIO;
+ return 0;
+}
+
#define NETXEN_UNICAST_ADDR(port, index) \
(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
#define NETXEN_MCAST_ADDR(port, index) \
@@ -330,6 +381,56 @@ static unsigned crb_hub_agt[64] =
#define MAC_LO(addr) \
((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
+int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+{
+ __u32 reg;
+ u32 port = adapter->physical_port;
+
+ if (port > NETXEN_NIU_MAX_XG_PORTS)
+ return -EINVAL;
+
+ reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
+ if (mode == NETXEN_NIU_PROMISC_MODE)
+ reg = (reg | 0x2000UL);
+ else
+ reg = (reg & ~0x2000UL);
+
+ if (mode == NETXEN_NIU_ALLMULTI_MODE)
+ reg = (reg | 0x1000UL);
+ else
+ reg = (reg & ~0x1000UL);
+
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+
+ return 0;
+}
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+ u32 mac_hi, mac_lo;
+ u32 reg_hi, reg_lo;
+
+ u8 phy = adapter->physical_port;
+
+ if (phy >= NETXEN_NIU_MAX_XG_PORTS)
+ return -EINVAL;
+
+ mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
+ mac_hi = addr[2] | ((u32)addr[3] << 8) |
+ ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
+
+ reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
+ reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
+
+ /* write twice to flush */
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
+
+ return 0;
+}
+
static int
netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
{
@@ -460,6 +561,9 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
i = 0;
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return -EIO;
+
tx_ring = adapter->tx_ring;
__netif_tx_lock_bh(tx_ring->txq);
@@ -643,7 +747,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
memset(&req, 0, sizeof(nx_nic_req_t));
- req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
req.req_hdr = cpu_to_le64(word);
@@ -659,6 +763,66 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
return rv;
}
+int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv = 0;
+
+ if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable)
+ return 0;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ req.words[0] = cpu_to_le64(enable);
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "ERROR. Could not send "
+ "configure hw lro request\n");
+ }
+
+ adapter->flags ^= NETXEN_NIC_LRO_ENABLED;
+
+ return rv;
+}
+
+int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv = 0;
+
+ if (!!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED) == enable)
+ return rv;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_BRIDGING |
+ ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ req.words[0] = cpu_to_le64(enable);
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "ERROR. Could not send "
+ "configure bridge mode request\n");
+ }
+
+ adapter->flags ^= NETXEN_NIC_BRIDGE_ENABLED;
+
+ return rv;
+}
+
+
#define RSS_HASHTYPE_IP_TCP 0x3
int netxen_config_rss(struct netxen_adapter *adapter, int enable)
@@ -706,6 +870,30 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
return rv;
}
+int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ req.words[0] = cpu_to_le64(cmd);
+ req.words[1] = cpu_to_le64(ip);
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not notify %s IP 0x%x reuqest\n",
+ adapter->netdev->name,
+ (cmd == NX_IP_UP) ? "Add" : "Remove", ip);
+ }
+ return rv;
+}
+
int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
{
nx_nic_req_t req;
@@ -728,6 +916,29 @@ int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
return rv;
}
+int netxen_send_lro_cleanup(struct netxen_adapter *adapter)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_LRO_REQUEST |
+ ((u64)adapter->portnum << 16) |
+ ((u64)NX_NIC_LRO_REQUEST_CLEANUP << 56) ;
+
+ req.req_hdr = cpu_to_le64(word);
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not cleanup lro flows\n",
+ adapter->netdev->name);
+ }
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
@@ -792,18 +1003,15 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
__le32 *pmac = (__le32 *) mac;
u32 offset;
- offset = NETXEN_USER_START +
- offsetof(struct netxen_new_user_info, mac_addr) +
- adapter->portnum * sizeof(u64);
+ offset = NX_FW_MAC_ADDR_OFFSET + (adapter->portnum * sizeof(u64));
if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
return -1;
if (*mac == cpu_to_le64(~0ULL)) {
- offset = NETXEN_USER_START_OLD +
- offsetof(struct netxen_user_old_info, mac_addr) +
- adapter->portnum * sizeof(u64);
+ offset = NX_OLD_MAC_ADDR_OFFSET +
+ (adapter->portnum * sizeof(u64));
if (netxen_get_flash_block(adapter,
offset, sizeof(u64), pmac) == -1)
@@ -834,37 +1042,10 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
return 0;
}
-#define CRB_WIN_LOCK_TIMEOUT 100000000
-
-static int crb_win_lock(struct netxen_adapter *adapter)
-{
- int done = 0, timeout = 0;
-
- while (!done) {
- /* acquire semaphore3 from PCI HW block */
- done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
- if (done == 1)
- break;
- if (timeout >= CRB_WIN_LOCK_TIMEOUT)
- return -1;
- timeout++;
- udelay(1);
- }
- NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
- return 0;
-}
-
-static void crb_win_unlock(struct netxen_adapter *adapter)
-{
- int val;
-
- val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
-}
-
/*
* Changes the CRB window to the specified window.
*/
-void
+static void
netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
{
void __iomem *offset;
@@ -977,61 +1158,68 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
(ulong)adapter->ahw.pci_base0;
}
-int
+static int
netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
{
+ unsigned long flags;
void __iomem *addr;
- if (ADDR_IN_WINDOW1(off)) {
+ if (ADDR_IN_WINDOW1(off))
addr = NETXEN_CRB_NORMALIZE(adapter, off);
+ else
+ addr = pci_base_offset(adapter, off);
+
+ BUG_ON(!addr);
+
+ if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
+ read_lock(&adapter->adapter_lock);
+ writel(data, addr);
+ read_unlock(&adapter->adapter_lock);
} else { /* Window 0 */
+ write_lock_irqsave(&adapter->adapter_lock, flags);
addr = pci_base_offset(adapter, off);
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
- }
-
- if (!addr) {
+ writel(data, addr);
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
- return 1;
+ write_unlock_irqrestore(&adapter->adapter_lock, flags);
}
- writel(data, addr);
-
- if (!ADDR_IN_WINDOW1(off))
- netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-
return 0;
}
-u32
+static u32
netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
{
+ unsigned long flags;
void __iomem *addr;
u32 data;
- if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
+ if (ADDR_IN_WINDOW1(off))
addr = NETXEN_CRB_NORMALIZE(adapter, off);
- } else { /* Window 0 */
+ else
addr = pci_base_offset(adapter, off);
- netxen_nic_pci_change_crbwindow_128M(adapter, 0);
- }
-
- if (!addr) {
- netxen_nic_pci_change_crbwindow_128M(adapter, 1);
- return 1;
- }
- data = readl(addr);
+ BUG_ON(!addr);
- if (!ADDR_IN_WINDOW1(off))
+ if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
+ read_lock(&adapter->adapter_lock);
+ data = readl(addr);
+ read_unlock(&adapter->adapter_lock);
+ } else { /* Window 0 */
+ write_lock_irqsave(&adapter->adapter_lock, flags);
+ netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+ data = readl(addr);
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+ write_unlock_irqrestore(&adapter->adapter_lock, flags);
+ }
return data;
}
-int
+static int
netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
{
- unsigned long flags = 0;
+ unsigned long flags;
int rv;
rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
@@ -1057,10 +1245,10 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
return 0;
}
-u32
+static u32
netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
{
- unsigned long flags = 0;
+ unsigned long flags;
int rv;
u32 data;
@@ -1086,28 +1274,9 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
return data;
}
-/*
- * check memory access boundary.
- * used by test agent. support ddr access only for now
- */
-static unsigned long
-netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
- unsigned long long addr, int size)
-{
- if (!ADDR_IN_RANGE(addr,
- NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
- !ADDR_IN_RANGE(addr+size-1,
- NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
- ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
- return 0;
- }
-
- return 1;
-}
-
static int netxen_pci_set_window_warning_count;
-unsigned long
+static unsigned long
netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
unsigned long long addr)
{
@@ -1171,22 +1340,56 @@ netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
return addr;
}
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
- u64 off, u32 data)
+/* window 1 registers only */
+static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
+ void __iomem *addr, u32 data)
{
- writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
- return 0;
+ read_lock(&adapter->adapter_lock);
+ writel(data, addr);
+ read_unlock(&adapter->adapter_lock);
}
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
+static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
+ void __iomem *addr)
{
- return readl((void __iomem *)(pci_base_offset(adapter, off)));
+ u32 val;
+
+ read_lock(&adapter->adapter_lock);
+ val = readl(addr);
+ read_unlock(&adapter->adapter_lock);
+
+ return val;
}
-unsigned long
+static void netxen_nic_io_write_2M(struct netxen_adapter *adapter,
+ void __iomem *addr, u32 data)
+{
+ writel(data, addr);
+}
+
+static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter,
+ void __iomem *addr)
+{
+ return readl(addr);
+}
+
+void __iomem *
+netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
+{
+ ulong off = offset;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ if (offset < NETXEN_CRB_PCIX_HOST2 &&
+ offset > NETXEN_CRB_PCIX_HOST)
+ return PCI_OFFSET_SECOND_RANGE(adapter, offset);
+ return NETXEN_CRB_NORMALIZE(adapter, offset);
+ }
+
+ BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off));
+ return (void __iomem *)off;
+}
+
+static unsigned long
netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
unsigned long long addr)
{
@@ -1197,10 +1400,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* DDR network side */
window = MN_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- window);
- win_read = NXRD32(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
+ NXWR32(adapter, adapter->ahw.mn_win_crb, window);
+ win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
if ((win_read << 17) != window) {
printk(KERN_INFO "Written MNwin (0x%x) != "
"Read MNwin (0x%x)\n", window, win_read);
@@ -1215,10 +1416,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
window = OCM_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- window);
- win_read = NXRD32(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
+ NXWR32(adapter, adapter->ahw.mn_win_crb, window);
+ win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
if ((win_read >> 7) != window) {
printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
"Read OCMwin (0x%x)\n",
@@ -1231,10 +1430,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* QDR network side */
window = MS_WIN(addr);
adapter->ahw.qdr_sn_window = window;
- NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
- window);
- win_read = NXRD32(adapter,
- adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
+ NXWR32(adapter, adapter->ahw.ms_win_crb, window);
+ win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
if (win_read != window) {
printk(KERN_INFO "%s: Written MSwin (0x%x) != "
"Read MSwin (0x%x)\n",
@@ -1257,180 +1454,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
return addr;
}
-static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter,
- unsigned long long addr)
-{
- int window;
- unsigned long long qdr_max;
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
- else
- qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
-
- if (ADDR_IN_RANGE(addr,
- NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
- /* DDR network side */
- BUG(); /* MN access can not come here */
- } else if (ADDR_IN_RANGE(addr,
- NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
- return 1;
- } else if (ADDR_IN_RANGE(addr,
- NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
- return 1;
- } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
- /* QDR network side */
- window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f;
- if (adapter->ahw.qdr_sn_window == window)
- return 1;
- }
-
- return 0;
-}
-
-static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
- u64 off, void *data, int size)
-{
- unsigned long flags;
- void __iomem *addr, *mem_ptr = NULL;
- int ret = 0;
- u64 start;
- unsigned long mem_base;
- unsigned long mem_page;
-
- write_lock_irqsave(&adapter->adapter_lock, flags);
-
- /*
- * If attempting to access unknown address or straddle hw windows,
- * do not access.
- */
- start = adapter->pci_set_window(adapter, off);
- if ((start == -1UL) ||
- (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
- printk(KERN_ERR "%s out of bound pci memory access. "
- "offset is 0x%llx\n", netxen_nic_driver_name,
- (unsigned long long)off);
- return -1;
- }
-
- addr = pci_base_offset(adapter, start);
- if (!addr) {
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
- mem_base = pci_resource_start(adapter->pdev, 0);
- mem_page = start & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- consecutive pages.
- */
- if (mem_page != ((start + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == NULL) {
- *(uint8_t *)data = 0;
- return -1;
- }
- addr = mem_ptr;
- addr += start & (PAGE_SIZE - 1);
- write_lock_irqsave(&adapter->adapter_lock, flags);
- }
-
- switch (size) {
- case 1:
- *(uint8_t *)data = readb(addr);
- break;
- case 2:
- *(uint16_t *)data = readw(addr);
- break;
- case 4:
- *(uint32_t *)data = readl(addr);
- break;
- case 8:
- *(uint64_t *)data = readq(addr);
- break;
- default:
- ret = -1;
- break;
- }
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
-
- if (mem_ptr)
- iounmap(mem_ptr);
- return ret;
-}
-
-static int
-netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
- void *data, int size)
-{
- unsigned long flags;
- void __iomem *addr, *mem_ptr = NULL;
- int ret = 0;
- u64 start;
- unsigned long mem_base;
- unsigned long mem_page;
-
- write_lock_irqsave(&adapter->adapter_lock, flags);
-
- /*
- * If attempting to access unknown address or straddle hw windows,
- * do not access.
- */
- start = adapter->pci_set_window(adapter, off);
- if ((start == -1UL) ||
- (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
- printk(KERN_ERR "%s out of bound pci memory access. "
- "offset is 0x%llx\n", netxen_nic_driver_name,
- (unsigned long long)off);
- return -1;
- }
-
- addr = pci_base_offset(adapter, start);
- if (!addr) {
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
- mem_base = pci_resource_start(adapter->pdev, 0);
- mem_page = start & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- * consecutive pages.
- */
- if (mem_page != ((start + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == NULL)
- return -1;
- addr = mem_ptr;
- addr += start & (PAGE_SIZE - 1);
- write_lock_irqsave(&adapter->adapter_lock, flags);
- }
-
- switch (size) {
- case 1:
- writeb(*(uint8_t *)data, addr);
- break;
- case 2:
- writew(*(uint16_t *)data, addr);
- break;
- case 4:
- writel(*(uint32_t *)data, addr);
- break;
- case 8:
- writeq(*(uint64_t *)data, addr);
- break;
- default:
- ret = -1;
- break;
- }
- write_unlock_irqrestore(&adapter->adapter_lock, flags);
- if (mem_ptr)
- iounmap(mem_ptr);
- return ret;
-}
-
#define MAX_CTL_CHECK 1000
-int
+static int
netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
@@ -1440,19 +1466,28 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
uint64_t off8, tmpw, word[2] = {0, 0};
void __iomem *mem_crb;
- /*
- * If not MN, go check for MS or invalid.
- */
- if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
- return netxen_nic_pci_mem_write_direct(adapter,
- off, data, size);
+ if (size != 8)
+ return -EIO;
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+ NETXEN_ADDR_QDR_NET_MAX_P2)) {
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+ goto correct;
+ }
+
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ goto correct;
+ }
+
+ return -EIO;
+
+correct:
off8 = off & 0xfffffff8;
off0 = off & 0x7;
sz[0] = (size < (8 - off0)) ? size : (8 - off0);
sz[1] = size - sz[0];
loop = ((off0 + size - 1) >> 3) + 1;
- mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
if ((size != 8) || (off0 != 0)) {
for (i = 0; i < loop; i++) {
@@ -1523,7 +1558,7 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
return ret;
}
-int
+static int
netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
@@ -1533,20 +1568,29 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
uint64_t off8, val, word[2] = {0, 0};
void __iomem *mem_crb;
+ if (size != 8)
+ return -EIO;
- /*
- * If not MN, go check for MS or invalid.
- */
- if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
- return netxen_nic_pci_mem_read_direct(adapter, off, data, size);
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+ NETXEN_ADDR_QDR_NET_MAX_P2)) {
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+ goto correct;
+ }
+
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ goto correct;
+ }
+
+ return -EIO;
+correct:
off8 = off & 0xfffffff8;
off0[0] = off & 0x7;
off0[1] = 0;
sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
sz[1] = size - sz[0];
loop = ((off0[0] + size - 1) >> 3) + 1;
- mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
write_lock_irqsave(&adapter->adapter_lock, flags);
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
@@ -1614,26 +1658,32 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
return 0;
}
-int
+static int
netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
int i, j, ret = 0, loop, sz[2], off0;
uint32_t temp;
- uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
+ uint64_t off8, tmpw, word[2] = {0, 0};
+ void __iomem *mem_crb;
- /*
- * If not MN, go check for MS or invalid.
- */
- if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
- mem_crb = NETXEN_CRB_QDR_NET;
- else {
- mem_crb = NETXEN_CRB_DDR_NET;
- if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
- return netxen_nic_pci_mem_write_direct(adapter,
- off, data, size);
+ if (size != 8)
+ return -EIO;
+
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+ NETXEN_ADDR_QDR_NET_MAX_P3)) {
+ mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+ goto correct;
}
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+ mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+ goto correct;
+ }
+
+ return -EIO;
+
+correct:
off8 = off & 0xfffffff8;
off0 = off & 0x7;
sz[0] = (size < (8 - off0)) ? size : (8 - off0);
@@ -1642,8 +1692,8 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
if ((size != 8) || (off0 != 0)) {
for (i = 0; i < loop; i++) {
- if (adapter->pci_mem_read(adapter, off8 + (i << 3),
- &word[i], 8))
+ if (adapter->pci_mem_read(adapter,
+ off8 + (i << 3), &word[i], 8))
return -1;
}
}
@@ -1679,21 +1729,18 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
*/
for (i = 0; i < loop; i++) {
- temp = off8 + (i << 3);
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
- temp = 0;
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
- temp = word[i] & 0xffffffff;
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
- temp = (word[i] >> 32) & 0xffffffff;
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
- temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
- temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
+ writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO);
+ writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI);
+ writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO);
+ writel((word[i] >> 32) & 0xffffffff,
+ mem_crb+MIU_TEST_AGT_WRDATA_HI);
+ writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
+ mem_crb+MIU_TEST_AGT_CTRL);
+ writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
+ mem_crb+MIU_TEST_AGT_CTRL);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
+ temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -1714,27 +1761,32 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
return ret;
}
-int
+static int
netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
int i, j = 0, k, start, end, loop, sz[2], off0[2];
uint32_t temp;
- uint64_t off8, val, mem_crb, word[2] = {0, 0};
+ uint64_t off8, val, word[2] = {0, 0};
+ void __iomem *mem_crb;
- /*
- * If not MN, go check for MS or invalid.
- */
+ if (size != 8)
+ return -EIO;
- if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
- mem_crb = NETXEN_CRB_QDR_NET;
- else {
- mem_crb = NETXEN_CRB_DDR_NET;
- if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
- return netxen_nic_pci_mem_read_direct(adapter,
- off, data, size);
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+ NETXEN_ADDR_QDR_NET_MAX_P3)) {
+ mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+ goto correct;
}
+ if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+ mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+ goto correct;
+ }
+
+ return -EIO;
+
+correct:
off8 = off & 0xfffffff8;
off0[0] = off & 0x7;
off0[1] = 0;
@@ -1749,17 +1801,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
*/
for (i = 0; i < loop; i++) {
- temp = off8 + (i << 3);
- NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
- temp = 0;
- NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
- temp = MIU_TA_CTL_ENABLE;
- NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
- temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
- NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
+ writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO);
+ writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI);
+ writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL);
+ writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
+ mem_crb + MIU_TEST_AGT_CTRL);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
+ temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -1774,8 +1823,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
start = off0[i] >> 2;
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
- temp = NXRD32(adapter,
- mem_crb + MIU_TEST_AGT_RDDATA(k));
+ temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
word[i] |= ((uint64_t)temp << (32 * k));
}
}
@@ -1812,20 +1860,43 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
return 0;
}
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
- u64 off, u32 data)
+void
+netxen_setup_hwops(struct netxen_adapter *adapter)
{
- NXWR32(adapter, off, data);
+ adapter->init_port = netxen_niu_xg_init_port;
+ adapter->stop_port = netxen_niu_disable_xg_port;
- return 0;
-}
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ adapter->crb_read = netxen_nic_hw_read_wx_128M,
+ adapter->crb_write = netxen_nic_hw_write_wx_128M,
+ adapter->pci_set_window = netxen_nic_pci_set_window_128M,
+ adapter->pci_mem_read = netxen_nic_pci_mem_read_128M,
+ adapter->pci_mem_write = netxen_nic_pci_mem_write_128M,
+ adapter->io_read = netxen_nic_io_read_128M,
+ adapter->io_write = netxen_nic_io_write_128M,
+
+ adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+ adapter->set_multi = netxen_p2_nic_set_multi;
+ adapter->set_mtu = netxen_nic_set_mtu_xgb;
+ adapter->set_promisc = netxen_p2_nic_set_promisc;
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
-{
- return NXRD32(adapter, off);
+ } else {
+ adapter->crb_read = netxen_nic_hw_read_wx_2M,
+ adapter->crb_write = netxen_nic_hw_write_wx_2M,
+ adapter->pci_set_window = netxen_nic_pci_set_window_2M,
+ adapter->pci_mem_read = netxen_nic_pci_mem_read_2M,
+ adapter->pci_mem_write = netxen_nic_pci_mem_write_2M,
+ adapter->io_read = netxen_nic_io_read_2M,
+ adapter->io_write = netxen_nic_io_write_2M,
+
+ adapter->set_mtu = nx_fw_cmd_set_mtu;
+ adapter->set_promisc = netxen_p3_nic_set_promisc;
+ adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+ adapter->set_multi = netxen_p3_nic_set_multi;
+
+ adapter->phy_read = nx_fw_cmd_query_phy;
+ adapter->phy_write = nx_fw_cmd_set_phy;
+ }
}
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -1833,13 +1904,11 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
int offset, board_type, magic, header_version;
struct pci_dev *pdev = adapter->pdev;
- offset = NETXEN_BRDCFG_START +
- offsetof(struct netxen_board_info, magic);
+ offset = NX_FW_MAGIC_OFFSET;
if (netxen_rom_fast_read(adapter, offset, &magic))
return -EIO;
- offset = NETXEN_BRDCFG_START +
- offsetof(struct netxen_board_info, header_version);
+ offset = NX_HDR_VERSION_OFFSET;
if (netxen_rom_fast_read(adapter, offset, &header_version))
return -EIO;
@@ -1851,8 +1920,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
return -EIO;
}
- offset = NETXEN_BRDCFG_START +
- offsetof(struct netxen_board_info, board_type);
+ offset = NX_BRDTYPE_OFFSET;
if (netxen_rom_fast_read(adapter, offset, &board_type))
return -EIO;
@@ -1993,62 +2061,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
}
}
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
-{
- u32 fw_major, fw_minor, fw_build;
- char brd_name[NETXEN_MAX_SHORT_NAME];
- char serial_num[32];
- int i, addr, val;
- int *ptr32;
- struct pci_dev *pdev = adapter->pdev;
-
- adapter->driver_mismatch = 0;
-
- ptr32 = (int *)&serial_num;
- addr = NETXEN_USER_START +
- offsetof(struct netxen_new_user_info, serial_num);
- for (i = 0; i < 8; i++) {
- if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
- dev_err(&pdev->dev, "error reading board info\n");
- adapter->driver_mismatch = 1;
- return;
- }
- ptr32[i] = cpu_to_le32(val);
- addr += sizeof(u32);
- }
-
- fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
- fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
- fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-
- adapter->fw_major = fw_major;
- adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
-
- if (adapter->portnum == 0) {
- get_brd_name_by_type(adapter->ahw.board_type, brd_name);
-
- printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
- brd_name, serial_num, adapter->ahw.revision_id);
- }
-
- if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
- adapter->driver_mismatch = 1;
- dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
- fw_major, fw_minor, fw_build);
- return;
- }
-
- dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
- fw_major, fw_minor, fw_build);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- i = NXRD32(adapter, NETXEN_SRE_MISC);
- adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
- dev_info(&pdev->dev, "firmware running in %s mode\n",
- adapter->ahw.cut_through ? "cut-through" : "legacy");
- }
-}
-
int
netxen_nic_wol_supported(struct netxen_adapter *adapter)
{
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index d4e83333978..3fd1dcb3583 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,19 +21,11 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#ifndef __NETXEN_NIC_HW_H_
#define __NETXEN_NIC_HW_H_
-#include "netxen_nic_hdr.h"
-
/* Hardware memory size of 128 meg */
#define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
@@ -63,10 +56,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
* Bit 31: soft_reset => 1:reset the MAC and the SERDES, 0:no-op
*/
-#define netxen_gb_enable_tx(config_word) \
- ((config_word) |= 1 << 0)
-#define netxen_gb_enable_rx(config_word) \
- ((config_word) |= 1 << 2)
#define netxen_gb_tx_flowctl(config_word) \
((config_word) |= 1 << 4)
#define netxen_gb_rx_flowctl(config_word) \
@@ -79,8 +68,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
((config_word) |= 1 << 18)
#define netxen_gb_rx_reset_mac(config_word) \
((config_word) |= 1 << 19)
-#define netxen_gb_soft_reset(config_word) \
- ((config_word) |= 1 << 31)
#define netxen_gb_unset_tx_flowctl(config_word) \
((config_word) &= ~(1 << 4))
@@ -242,7 +229,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
* Bits 14-15 : speed => 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd
*/
-#define netxen_get_phy_cablelen(config_word) (((config_word) >> 7) & 0x07)
#define netxen_get_phy_speed(config_word) (((config_word) >> 14) & 0x03)
#define netxen_set_phy_speed(config_word, val) \
@@ -252,85 +238,12 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
#define netxen_clear_phy_duplex(config_word) \
((config_word) &= ~(1 << 13))
-#define netxen_get_phy_jabber(config_word) \
- _netxen_crb_get_bit(config_word, 0)
-#define netxen_get_phy_polarity(config_word) \
- _netxen_crb_get_bit(config_word, 1)
-#define netxen_get_phy_recvpause(config_word) \
- _netxen_crb_get_bit(config_word, 2)
-#define netxen_get_phy_xmitpause(config_word) \
- _netxen_crb_get_bit(config_word, 3)
-#define netxen_get_phy_energydetect(config_word) \
- _netxen_crb_get_bit(config_word, 4)
-#define netxen_get_phy_downshift(config_word) \
- _netxen_crb_get_bit(config_word, 5)
-#define netxen_get_phy_crossover(config_word) \
- _netxen_crb_get_bit(config_word, 6)
#define netxen_get_phy_link(config_word) \
_netxen_crb_get_bit(config_word, 10)
-#define netxen_get_phy_resolved(config_word) \
- _netxen_crb_get_bit(config_word, 11)
-#define netxen_get_phy_pagercvd(config_word) \
- _netxen_crb_get_bit(config_word, 12)
#define netxen_get_phy_duplex(config_word) \
_netxen_crb_get_bit(config_word, 13)
/*
- * Interrupt Register definition
- * This definition applies to registers 18 and 19 (int enable and int status).
- * Bit 0 : jabber
- * Bit 1 : polarity_changed
- * Bit 4 : energy_detect
- * Bit 5 : downshift
- * Bit 6 : mdi_xover_changed
- * Bit 7 : fifo_over_underflow
- * Bit 8 : false_carrier
- * Bit 9 : symbol_error
- * Bit 10: link_status_changed
- * Bit 11: autoneg_completed
- * Bit 12: page_received
- * Bit 13: duplex_changed
- * Bit 14: speed_changed
- * Bit 15: autoneg_error
- */
-
-#define netxen_get_phy_int_jabber(config_word) \
- _netxen_crb_get_bit(config_word, 0)
-#define netxen_get_phy_int_polarity_changed(config_word) \
- _netxen_crb_get_bit(config_word, 1)
-#define netxen_get_phy_int_energy_detect(config_word) \
- _netxen_crb_get_bit(config_word, 4)
-#define netxen_get_phy_int_downshift(config_word) \
- _netxen_crb_get_bit(config_word, 5)
-#define netxen_get_phy_int_mdi_xover_changed(config_word) \
- _netxen_crb_get_bit(config_word, 6)
-#define netxen_get_phy_int_fifo_over_underflow(config_word) \
- _netxen_crb_get_bit(config_word, 7)
-#define netxen_get_phy_int_false_carrier(config_word) \
- _netxen_crb_get_bit(config_word, 8)
-#define netxen_get_phy_int_symbol_error(config_word) \
- _netxen_crb_get_bit(config_word, 9)
-#define netxen_get_phy_int_link_status_changed(config_word) \
- _netxen_crb_get_bit(config_word, 10)
-#define netxen_get_phy_int_autoneg_completed(config_word) \
- _netxen_crb_get_bit(config_word, 11)
-#define netxen_get_phy_int_page_received(config_word) \
- _netxen_crb_get_bit(config_word, 12)
-#define netxen_get_phy_int_duplex_changed(config_word) \
- _netxen_crb_get_bit(config_word, 13)
-#define netxen_get_phy_int_speed_changed(config_word) \
- _netxen_crb_get_bit(config_word, 14)
-#define netxen_get_phy_int_autoneg_error(config_word) \
- _netxen_crb_get_bit(config_word, 15)
-
-#define netxen_set_phy_int_link_status_changed(config_word) \
- ((config_word) |= 1 << 10)
-#define netxen_set_phy_int_autoneg_completed(config_word) \
- ((config_word) |= 1 << 11)
-#define netxen_set_phy_int_speed_changed(config_word) \
- ((config_word) |= 1 << 14)
-
-/*
* NIU Mode Register.
* Bit 0 : enable FibreChannel
* Bit 1 : enable 10/100/1000 Ethernet
@@ -345,33 +258,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
#define NETXEN_NIU_ALLMULTI_MODE 2
/*
- * NIU GB Drop CRC Register
- *
- * Bit 0 : drop_gb0 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 1 : drop_gb1 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 2 : drop_gb2 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 3 : drop_gb3 => 1:drop pkts with bad CRCs, 0:pass them on
- */
-
-#define netxen_set_gb_drop_gb0(config_word) \
- ((config_word) |= 1 << 0)
-#define netxen_set_gb_drop_gb1(config_word) \
- ((config_word) |= 1 << 1)
-#define netxen_set_gb_drop_gb2(config_word) \
- ((config_word) |= 1 << 2)
-#define netxen_set_gb_drop_gb3(config_word) \
- ((config_word) |= 1 << 3)
-
-#define netxen_clear_gb_drop_gb0(config_word) \
- ((config_word) &= ~(1 << 0))
-#define netxen_clear_gb_drop_gb1(config_word) \
- ((config_word) &= ~(1 << 1))
-#define netxen_clear_gb_drop_gb2(config_word) \
- ((config_word) &= ~(1 << 2))
-#define netxen_clear_gb_drop_gb3(config_word) \
- ((config_word) &= ~(1 << 3))
-
-/*
* NIU XG MAC Config Register
*
* Bit 0 : tx_enable => 1:enable frame xmit, 0:disable
@@ -387,22 +273,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
#define netxen_xg_soft_reset(config_word) \
((config_word) |= 1 << 4)
-/* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
- u32 mode);
-int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
- u32 mode);
-
-/* Generic enable for GbE ports. Will detect the speed of the link. */
-int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
-
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
-
-/* Disable a GbE interface */
-int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter);
-
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
-
typedef struct {
unsigned valid;
unsigned start_128M;
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 5d3343ef3d8..91c2bc61c8e 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,19 +21,12 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#include <linux/netdevice.h>
#include <linux/delay.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
struct crb_addr_pair {
u32 addr;
@@ -247,9 +241,14 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
rds_ring->skb_size =
NX_CT_DEFAULT_RX_BUF_LEN;
} else {
- rds_ring->dma_size = RX_DMA_MAP_LEN;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ rds_ring->dma_size =
+ NX_P3_RX_BUF_MAX_LEN;
+ else
+ rds_ring->dma_size =
+ NX_P2_RX_BUF_MAX_LEN;
rds_ring->skb_size =
- MAX_RX_BUFFER_LENGTH;
+ rds_ring->dma_size + NET_IP_ALIGN;
}
break;
@@ -261,14 +260,18 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
else
rds_ring->dma_size =
NX_P2_RX_JUMBO_BUF_MAX_LEN;
+
+ if (adapter->capabilities & NX_CAP0_HW_LRO)
+ rds_ring->dma_size += NX_LRO_BUFFER_EXTRA;
+
rds_ring->skb_size =
rds_ring->dma_size + NET_IP_ALIGN;
break;
case RCV_RING_LRO:
rds_ring->num_desc = adapter->num_lro_rxd;
- rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
- rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+ rds_ring->dma_size = NX_RX_LRO_BUFFER_LENGTH;
+ rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN;
break;
}
@@ -315,48 +318,6 @@ err_out:
return -ENOMEM;
}
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
-{
- adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
- adapter->set_multi = netxen_p2_nic_set_multi;
-
- switch (adapter->ahw.port_type) {
- case NETXEN_NIC_GBE:
- adapter->enable_phy_interrupts =
- netxen_niu_gbe_enable_phy_interrupts;
- adapter->disable_phy_interrupts =
- netxen_niu_gbe_disable_phy_interrupts;
- adapter->set_mtu = netxen_nic_set_mtu_gb;
- adapter->set_promisc = netxen_niu_set_promiscuous_mode;
- adapter->phy_read = netxen_niu_gbe_phy_read;
- adapter->phy_write = netxen_niu_gbe_phy_write;
- adapter->init_port = netxen_niu_gbe_init_port;
- adapter->stop_port = netxen_niu_disable_gbe_port;
- break;
-
- case NETXEN_NIC_XGBE:
- adapter->enable_phy_interrupts =
- netxen_niu_xgbe_enable_phy_interrupts;
- adapter->disable_phy_interrupts =
- netxen_niu_xgbe_disable_phy_interrupts;
- adapter->set_mtu = netxen_nic_set_mtu_xgb;
- adapter->init_port = netxen_niu_xg_init_port;
- adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
- adapter->stop_port = netxen_niu_disable_xg_port;
- break;
-
- default:
- break;
- }
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- adapter->set_mtu = nx_fw_cmd_set_mtu;
- adapter->set_promisc = netxen_p3_nic_set_promisc;
- adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
- adapter->set_multi = netxen_p3_nic_set_multi;
- }
-}
-
/*
* netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
* address to external PCI CRB address.
@@ -384,37 +345,7 @@ static u32 netxen_decode_crb_addr(u32 addr)
return (pci_base + offset);
}
-static long rom_max_timeout = 100;
-static long rom_lock_timeout = 10000;
-
-static int rom_lock(struct netxen_adapter *adapter)
-{
- int iter;
- u32 done = 0;
- int timeout = 0;
-
- while (!done) {
- /* acquire semaphore2 from PCI HW block */
- done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
- if (done == 1)
- break;
- if (timeout >= rom_lock_timeout)
- return -EIO;
-
- timeout++;
- /*
- * Yield CPU
- */
- if (!in_atomic())
- schedule();
- else {
- for (iter = 0; iter < 20; iter++)
- cpu_relax(); /*This a nop instr on i386 */
- }
- }
- NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
- return 0;
-}
+#define NETXEN_MAX_ROM_WAIT_USEC 100
static int netxen_wait_rom_done(struct netxen_adapter *adapter)
{
@@ -426,22 +357,16 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
while (done == 0) {
done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
done &= 2;
- timeout++;
- if (timeout >= rom_max_timeout) {
- printk("Timeout reached waiting for rom done");
+ if (++timeout >= NETXEN_MAX_ROM_WAIT_USEC) {
+ dev_err(&adapter->pdev->dev,
+ "Timeout reached waiting for rom done");
return -EIO;
}
+ udelay(1);
}
return 0;
}
-static void netxen_rom_unlock(struct netxen_adapter *adapter)
-{
- /* release semaphore2 */
- NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
-
-}
-
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
{
@@ -486,7 +411,7 @@ netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
{
int ret;
- ret = rom_lock(adapter);
+ ret = netxen_rom_lock(adapter);
if (ret < 0)
return ret;
@@ -500,7 +425,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
{
int ret;
- if (rom_lock(adapter) != 0)
+ if (netxen_rom_lock(adapter) != 0)
return -EIO;
ret = do_rom_fast_read(adapter, addr, valp);
@@ -521,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
u32 off;
/* resetall */
- rom_lock(adapter);
+ netxen_rom_lock(adapter);
NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
netxen_rom_unlock(adapter);
@@ -797,21 +722,28 @@ netxen_load_firmware(struct netxen_adapter *adapter)
flashaddr += 8;
}
} else {
- u32 data;
+ u64 data;
+ u32 hi, lo;
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
flashaddr = NETXEN_BOOTLD_START;
for (i = 0; i < size; i++) {
if (netxen_rom_fast_read(adapter,
- flashaddr, (int *)&data) != 0)
+ flashaddr, &lo) != 0)
+ return -EIO;
+ if (netxen_rom_fast_read(adapter,
+ flashaddr + 4, &hi) != 0)
return -EIO;
+ /* hi, lo are already in host endian byteorder */
+ data = (((u64)hi << 32) | lo);
+
if (adapter->pci_mem_write(adapter,
- flashaddr, &data, 4))
+ flashaddr, &data, 8))
return -EIO;
- flashaddr += 4;
+ flashaddr += 8;
}
}
msleep(1);
@@ -880,22 +812,10 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
return 0;
}
-void netxen_request_firmware(struct netxen_adapter *adapter)
+static int
+netxen_p3_has_mn(struct netxen_adapter *adapter)
{
u32 capability, flashed_ver;
- u8 fw_type;
- struct pci_dev *pdev = adapter->pdev;
- int rc = 0;
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- fw_type = NX_P2_MN_ROMIMAGE;
- goto request_fw;
- } else {
- fw_type = NX_P3_CT_ROMIMAGE;
- goto request_fw;
- }
-
-request_mn:
capability = 0;
netxen_rom_fast_read(adapter,
@@ -903,23 +823,35 @@ request_mn:
flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+
capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
- if (capability & NX_PEG_TUNE_MN_PRESENT) {
- fw_type = NX_P3_MN_ROMIMAGE;
- goto request_fw;
- }
+ if (capability & NX_PEG_TUNE_MN_PRESENT)
+ return 1;
}
+ return 0;
+}
- fw_type = NX_FLASH_ROMIMAGE;
- adapter->fw = NULL;
- goto done;
+void netxen_request_firmware(struct netxen_adapter *adapter)
+{
+ u8 fw_type;
+ struct pci_dev *pdev = adapter->pdev;
+ int rc = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ fw_type = NX_P2_MN_ROMIMAGE;
+ goto request_fw;
+ }
+
+ fw_type = netxen_p3_has_mn(adapter) ?
+ NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE;
request_fw:
rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
if (rc != 0) {
- if (fw_type == NX_P3_CT_ROMIMAGE) {
+ if (fw_type == NX_P3_MN_ROMIMAGE) {
msleep(1);
- goto request_mn;
+ fw_type = NX_P3_CT_ROMIMAGE;
+ goto request_fw;
}
fw_type = NX_FLASH_ROMIMAGE;
@@ -931,9 +863,10 @@ request_fw:
if (rc != 0) {
release_firmware(adapter->fw);
- if (fw_type == NX_P3_CT_ROMIMAGE) {
+ if (fw_type == NX_P3_MN_ROMIMAGE) {
msleep(1);
- goto request_mn;
+ fw_type = NX_P3_CT_ROMIMAGE;
+ goto request_fw;
}
fw_type = NX_FLASH_ROMIMAGE;
@@ -951,21 +884,23 @@ netxen_release_firmware(struct netxen_adapter *adapter)
{
if (adapter->fw)
release_firmware(adapter->fw);
+ adapter->fw = NULL;
}
-int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
+int netxen_init_dummy_dma(struct netxen_adapter *adapter)
{
- uint64_t addr;
- uint32_t hi;
- uint32_t lo;
+ u64 addr;
+ u32 hi, lo;
+
+ if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
- adapter->dummy_dma.addr =
- pci_alloc_consistent(adapter->pdev,
+ adapter->dummy_dma.addr = pci_alloc_consistent(adapter->pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
&adapter->dummy_dma.phys_addr);
if (adapter->dummy_dma.addr == NULL) {
- printk("%s: ERROR: Could not allocate dummy DMA memory\n",
- __func__);
+ dev_err(&adapter->pdev->dev,
+ "ERROR: Could not allocate dummy DMA memory\n");
return -ENOMEM;
}
@@ -976,29 +911,41 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- uint32_t temp = 0;
- NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
- }
-
return 0;
}
-void netxen_free_adapter_offload(struct netxen_adapter *adapter)
+/*
+ * NetXen DMA watchdog control:
+ *
+ * Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive
+ * Bit 1 : disable_request => 1 req disable dma watchdog
+ * Bit 2 : enable_request => 1 req enable dma watchdog
+ * Bit 3-31 : unused
+ */
+void netxen_free_dummy_dma(struct netxen_adapter *adapter)
{
int i = 100;
+ u32 ctrl;
+
+ if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return;
if (!adapter->dummy_dma.addr)
return;
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- do {
- if (dma_watchdog_shutdown_request(adapter) == 1)
- break;
+ ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL);
+ if ((ctrl & 0x1) != 0) {
+ NXWR32(adapter, NETXEN_DMA_WATCHDOG_CTRL, (ctrl | 0x2));
+
+ while ((ctrl & 0x1) != 0) {
+
msleep(50);
- if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+
+ ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL);
+
+ if (--i == 0)
break;
- } while (--i);
+ };
}
if (i) {
@@ -1007,10 +954,8 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
adapter->dummy_dma.addr,
adapter->dummy_dma.phys_addr);
adapter->dummy_dma.addr = NULL;
- } else {
- printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
- adapter->netdev->name);
- }
+ } else
+ dev_err(&adapter->pdev->dev, "dma_watchdog_shutdown failed\n");
}
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
@@ -1083,10 +1028,6 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
- if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
- adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
- }
-
return err;
}
@@ -1222,20 +1163,31 @@ no_skb:
static struct netxen_rx_buffer *
netxen_process_rcv(struct netxen_adapter *adapter,
- int ring, int index, int length, int cksum, int pkt_offset,
- struct nx_host_sds_ring *sds_ring)
+ struct nx_host_sds_ring *sds_ring,
+ int ring, u64 sts_data0)
{
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_rx_buffer *buffer;
struct sk_buff *skb;
- struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
+ struct nx_host_rds_ring *rds_ring;
+ int index, length, cksum, pkt_offset;
- if (unlikely(index > rds_ring->num_desc))
+ if (unlikely(ring >= adapter->max_rds_rings))
+ return NULL;
+
+ rds_ring = &recv_ctx->rds_rings[ring];
+
+ index = netxen_get_sts_refhandle(sts_data0);
+ if (unlikely(index >= rds_ring->num_desc))
return NULL;
buffer = &rds_ring->rx_buf_arr[index];
+ length = netxen_get_sts_totallength(sts_data0);
+ cksum = netxen_get_sts_status(sts_data0);
+ pkt_offset = netxen_get_sts_pkt_offset(sts_data0);
+
skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
if (!skb)
return buffer;
@@ -1249,11 +1201,88 @@ netxen_process_rcv(struct netxen_adapter *adapter,
if (pkt_offset)
skb_pull(skb, pkt_offset);
+ skb->truesize = skb->len + sizeof(struct sk_buff);
skb->protocol = eth_type_trans(skb, netdev);
napi_gro_receive(&sds_ring->napi, skb);
- adapter->stats.no_rcv++;
+ adapter->stats.rx_pkts++;
+ adapter->stats.rxbytes += length;
+
+ return buffer;
+}
+
+#define TCP_HDR_SIZE 20
+#define TCP_TS_OPTION_SIZE 12
+#define TCP_TS_HDR_SIZE (TCP_HDR_SIZE + TCP_TS_OPTION_SIZE)
+
+static struct netxen_rx_buffer *
+netxen_process_lro(struct netxen_adapter *adapter,
+ struct nx_host_sds_ring *sds_ring,
+ int ring, u64 sts_data0, u64 sts_data1)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct netxen_rx_buffer *buffer;
+ struct sk_buff *skb;
+ struct nx_host_rds_ring *rds_ring;
+ struct iphdr *iph;
+ struct tcphdr *th;
+ bool push, timestamp;
+ int l2_hdr_offset, l4_hdr_offset;
+ int index;
+ u16 lro_length, length, data_offset;
+ u32 seq_number;
+
+ if (unlikely(ring > adapter->max_rds_rings))
+ return NULL;
+
+ rds_ring = &recv_ctx->rds_rings[ring];
+
+ index = netxen_get_lro_sts_refhandle(sts_data0);
+ if (unlikely(index > rds_ring->num_desc))
+ return NULL;
+
+ buffer = &rds_ring->rx_buf_arr[index];
+
+ timestamp = netxen_get_lro_sts_timestamp(sts_data0);
+ lro_length = netxen_get_lro_sts_length(sts_data0);
+ l2_hdr_offset = netxen_get_lro_sts_l2_hdr_offset(sts_data0);
+ l4_hdr_offset = netxen_get_lro_sts_l4_hdr_offset(sts_data0);
+ push = netxen_get_lro_sts_push_flag(sts_data0);
+ seq_number = netxen_get_lro_sts_seq_number(sts_data1);
+
+ skb = netxen_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK);
+ if (!skb)
+ return buffer;
+
+ if (timestamp)
+ data_offset = l4_hdr_offset + TCP_TS_HDR_SIZE;
+ else
+ data_offset = l4_hdr_offset + TCP_HDR_SIZE;
+
+ skb_put(skb, lro_length + data_offset);
+
+ skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
+
+ skb_pull(skb, l2_hdr_offset);
+ skb->protocol = eth_type_trans(skb, netdev);
+
+ iph = (struct iphdr *)skb->data;
+ th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+
+ length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
+ iph->tot_len = htons(length);
+ iph->check = 0;
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+ th->psh = push;
+ th->seq = htonl(seq_number);
+
+ length = skb->len;
+
+ netif_receive_skb(skb);
+
+ adapter->stats.lro_pkts++;
adapter->stats.rxbytes += length;
return buffer;
@@ -1275,27 +1304,33 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
u32 consumer = sds_ring->consumer;
int count = 0;
- u64 sts_data;
- int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
+ u64 sts_data0, sts_data1;
+ int opcode, ring = 0, desc_cnt;
while (count < max) {
desc = &sds_ring->desc_head[consumer];
- sts_data = le64_to_cpu(desc->status_desc_data[0]);
+ sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
- if (!(sts_data & STATUS_OWNER_HOST))
+ if (!(sts_data0 & STATUS_OWNER_HOST))
break;
- desc_cnt = netxen_get_sts_desc_cnt(sts_data);
- ring = netxen_get_sts_type(sts_data);
-
- if (ring > RCV_RING_JUMBO)
- goto skip;
+ desc_cnt = netxen_get_sts_desc_cnt(sts_data0);
- opcode = netxen_get_sts_opcode(sts_data);
+ opcode = netxen_get_sts_opcode(sts_data0);
switch (opcode) {
case NETXEN_NIC_RXPKT_DESC:
case NETXEN_OLD_RXPKT_DESC:
+ case NETXEN_NIC_SYN_OFFLOAD:
+ ring = netxen_get_sts_type(sts_data0);
+ rxbuf = netxen_process_rcv(adapter, sds_ring,
+ ring, sts_data0);
+ break;
+ case NETXEN_NIC_LRO_DESC:
+ ring = netxen_get_lro_sts_type(sts_data0);
+ sts_data1 = le64_to_cpu(desc->status_desc_data[1]);
+ rxbuf = netxen_process_lro(adapter, sds_ring,
+ ring, sts_data0, sts_data1);
break;
case NETXEN_NIC_RESPONSE_DESC:
netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
@@ -1305,14 +1340,6 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
WARN_ON(desc_cnt > 1);
- index = netxen_get_sts_refhandle(sts_data);
- length = netxen_get_sts_totallength(sts_data);
- cksum = netxen_get_sts_status(sts_data);
- pkt_offset = netxen_get_sts_pkt_offset(sts_data);
-
- rxbuf = netxen_process_rcv(adapter, ring, index,
- length, cksum, pkt_offset, sds_ring);
-
if (rxbuf)
list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
@@ -1347,7 +1374,7 @@ skip:
if (count) {
sds_ring->consumer = consumer;
- NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
+ NXWRIO(adapter, sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -1402,8 +1429,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
__netif_tx_lock(tx_ring->txq, smp_processor_id());
- if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
+ if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) {
netif_wake_queue(netdev);
+ adapter->tx_timeo_cnt = 0;
+ }
__netif_tx_unlock(tx_ring->txq);
}
}
@@ -1465,10 +1494,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
if (count) {
rds_ring->producer = producer;
- NXWR32(adapter, rds_ring->crb_rcv_producer,
+ NXWRIO(adapter, rds_ring->crb_rcv_producer,
(producer-1) & (rds_ring->num_desc-1));
- if (adapter->fw_major < 4) {
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
/*
* Write a doorbell msg to tell phanmon of change in
* receive ring producer
@@ -1481,9 +1510,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
(rds_ring->num_desc - 1)));
netxen_set_msg_ctxid(msg, adapter->portnum);
netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
- writel(msg,
- DB_NORMALIZE(adapter,
+ read_lock(&adapter->adapter_lock);
+ writel(msg, DB_NORMALIZE(adapter,
NETXEN_RCV_PRODUCER_OFFSET));
+ read_unlock(&adapter->adapter_lock);
}
}
}
@@ -1525,7 +1555,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
if (count) {
rds_ring->producer = producer;
- NXWR32(adapter, rds_ring->crb_rcv_producer,
+ NXWRIO(adapter, rds_ring->crb_rcv_producer,
(producer - 1) & (rds_ring->num_desc - 1));
}
spin_unlock(&rds_ring->lock);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 28f270f5ac7..f7bdde111df 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
*/
#include <linux/vmalloc.h>
@@ -33,12 +28,12 @@
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
-#include "netxen_nic_phan_reg.h"
#include <linux/dma-mapping.h>
#include <linux/if_vlan.h>
#include <net/ip.h>
#include <linux/ipv6.h>
+#include <linux/inetdevice.h>
MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
MODULE_LICENSE("GPL");
@@ -63,18 +58,31 @@ static int __devinit netxen_nic_probe(struct pci_dev *pdev,
static void __devexit netxen_nic_remove(struct pci_dev *pdev);
static int netxen_nic_open(struct net_device *netdev);
static int netxen_nic_close(struct net_device *netdev);
-static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
+static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *,
+ struct net_device *);
static void netxen_tx_timeout(struct net_device *netdev);
static void netxen_tx_timeout_task(struct work_struct *work);
-static void netxen_watchdog(unsigned long);
+static void netxen_fw_poll_work(struct work_struct *work);
+static void netxen_schedule_work(struct netxen_adapter *adapter,
+ work_func_t func, int delay);
+static void netxen_cancel_fw_work(struct netxen_adapter *adapter);
static int netxen_nic_poll(struct napi_struct *napi, int budget);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void netxen_nic_poll_controller(struct net_device *netdev);
#endif
+
+static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
+static void netxen_remove_sysfs_entries(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);
+
static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data);
static irqreturn_t netxen_msix_intr(int irq, void *data);
+static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
@@ -94,8 +102,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
-static void netxen_watchdog(unsigned long);
-
static uint32_t crb_cmd_producer[4] = {
CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1,
CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3
@@ -105,7 +111,7 @@ void
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
struct nx_host_tx_ring *tx_ring)
{
- NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
+ NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
netif_stop_queue(adapter->netdev);
@@ -122,7 +128,7 @@ static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
struct nx_host_tx_ring *tx_ring)
{
- NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
+ NXWRIO(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
}
static uint32_t msi_tgt_status[8] = {
@@ -138,18 +144,17 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- NXWR32(adapter, sds_ring->crb_intr_mask, 0);
+ NXWRIO(adapter, sds_ring->crb_intr_mask, 0);
}
static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
+ NXWRIO(adapter, sds_ring->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter))
- adapter->pci_write_immediate(adapter,
- adapter->legacy_intr.tgt_mask_reg, 0xfbff);
+ NXWRIO(adapter, adapter->tgt_mask_reg, 0xfbff);
}
static int
@@ -179,7 +184,7 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
- return 1;
+ return -ENOMEM;
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
@@ -308,36 +313,6 @@ err_out:
return err;
}
-static void netxen_check_options(struct netxen_adapter *adapter)
-{
- if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
- adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
- else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
- adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
-
- adapter->msix_supported = 0;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- adapter->msix_supported = !!use_msi_x;
- adapter->rss_supported = !!use_msi_x;
- } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
- switch (adapter->ahw.board_type) {
- case NETXEN_BRDTYPE_P2_SB31_10G:
- case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
- adapter->msix_supported = !!use_msi_x;
- adapter->rss_supported = !!use_msi_x;
- break;
- default:
- break;
- }
- }
-
- adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
- adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
- adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
-
- return;
-}
-
static int
netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
{
@@ -537,10 +512,22 @@ netxen_setup_intr(struct netxen_adapter *adapter)
legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
else
legacy_intrp = &legacy_intr[0];
- adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
- adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
- adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
- adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+
+ adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+ adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+ legacy_intrp->tgt_status_reg);
+ adapter->tgt_mask_reg = netxen_get_ioaddr(adapter,
+ legacy_intrp->tgt_mask_reg);
+ adapter->pci_int_reg = netxen_get_ioaddr(adapter,
+ legacy_intrp->pci_int_reg);
+ adapter->isr_int_vec = netxen_get_ioaddr(adapter, ISR_INT_VECTOR);
+
+ if (adapter->ahw.revision_id >= NX_P3_B1)
+ adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+ ISR_INT_STATE_REG);
+ else
+ adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+ CRB_INT_VECTOR);
netxen_set_msix_bit(pdev, 0);
@@ -567,8 +554,8 @@ netxen_setup_intr(struct netxen_adapter *adapter)
if (use_msi && !pci_enable_msi(pdev)) {
adapter->flags |= NETXEN_NIC_MSI_ENABLED;
- adapter->msi_tgt_status =
- msi_tgt_status[adapter->ahw.pci_func];
+ adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+ msi_tgt_status[adapter->ahw.pci_func]);
dev_info(&pdev->dev, "using msi interrupts\n");
adapter->msix_entries[0].vector = pdev->irq;
return;
@@ -628,14 +615,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
mem_len = pci_resource_len(pdev, 0);
pci_len0 = 0;
- adapter->hw_write_wx = netxen_nic_hw_write_wx_128M;
- adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
- adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
- adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
- adapter->pci_set_window = netxen_nic_pci_set_window_128M;
- adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
- adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
-
/* 128 Meg of memory */
if (mem_len == NETXEN_PCI_128MB_SIZE) {
mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
@@ -648,14 +627,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
- adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
- adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
- adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
- adapter->pci_write_immediate =
- netxen_nic_pci_write_immediate_2M;
- adapter->pci_set_window = netxen_nic_pci_set_window_2M;
- adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
- adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
mem_ptr0 = pci_ioremap_bar(pdev, 0);
if (mem_ptr0 == NULL) {
@@ -667,9 +638,10 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
adapter->ahw.ddr_mn_window = 0;
adapter->ahw.qdr_sn_window = 0;
- adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
- (pci_func * 0x20);
- adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
+ adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE +
+ 0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20);
+ adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE +
+ 0x100000 + PCIX_SN_WINDOW;
if (pci_func < 4)
adapter->ahw.ms_win_crb += (pci_func * 0x20);
else
@@ -679,6 +651,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
return -EIO;
}
+ netxen_setup_hwops(adapter);
+
dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
adapter->ahw.pci_base0 = mem_ptr0;
@@ -717,20 +691,111 @@ err_out:
return err;
}
+static void
+netxen_check_options(struct netxen_adapter *adapter)
+{
+ u32 fw_major, fw_minor, fw_build;
+ char brd_name[NETXEN_MAX_SHORT_NAME];
+ char serial_num[32];
+ int i, offset, val;
+ int *ptr32;
+ struct pci_dev *pdev = adapter->pdev;
+
+ adapter->driver_mismatch = 0;
+
+ ptr32 = (int *)&serial_num;
+ offset = NX_FW_SERIAL_NUM_OFFSET;
+ for (i = 0; i < 8; i++) {
+ if (netxen_rom_fast_read(adapter, offset, &val) == -1) {
+ dev_err(&pdev->dev, "error reading board info\n");
+ adapter->driver_mismatch = 1;
+ return;
+ }
+ ptr32[i] = cpu_to_le32(val);
+ offset += sizeof(u32);
+ }
+
+ fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
+
+ adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
+
+ if (adapter->portnum == 0) {
+ get_brd_name_by_type(adapter->ahw.board_type, brd_name);
+
+ printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
+ brd_name, serial_num, adapter->ahw.revision_id);
+ }
+
+ if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
+ adapter->driver_mismatch = 1;
+ dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
+ fw_major, fw_minor, fw_build);
+ return;
+ }
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ i = NXRD32(adapter, NETXEN_SRE_MISC);
+ adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
+ }
+
+ dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n",
+ fw_major, fw_minor, fw_build,
+ adapter->ahw.cut_through ? "cut-through" : "legacy");
+
+ if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
+ adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+
+ adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
+
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+ adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
+ adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+ } else if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
+ adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
+ adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+ }
+
+ adapter->msix_supported = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ adapter->msix_supported = !!use_msi_x;
+ adapter->rss_supported = !!use_msi_x;
+ } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+ switch (adapter->ahw.board_type) {
+ case NETXEN_BRDTYPE_P2_SB31_10G:
+ case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+ adapter->msix_supported = !!use_msi_x;
+ adapter->rss_supported = !!use_msi_x;
+ break;
+ default:
+ break;
+ }
+ }
+
+ adapter->num_txd = MAX_CMD_DESCRIPTORS;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
+ adapter->max_rds_rings = 3;
+ } else {
+ adapter->num_lro_rxd = 0;
+ adapter->max_rds_rings = 2;
+ }
+}
+
static int
-netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
+netxen_start_firmware(struct netxen_adapter *adapter)
{
int val, err, first_boot;
struct pci_dev *pdev = adapter->pdev;
- int first_driver = 0;
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- first_driver = (adapter->portnum == 0);
- else
- first_driver = (adapter->ahw.pci_func == 0);
+ /* required for NX2031 dummy dma */
+ err = nx_set_dma_mask(adapter);
+ if (err)
+ return err;
- if (!first_driver)
+ if (!netxen_can_start_firmware(adapter))
goto wait_init;
first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
@@ -741,12 +806,13 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
return err;
}
- if (request_fw)
- netxen_request_firmware(adapter);
+ netxen_request_firmware(adapter);
err = netxen_need_fw_reset(adapter);
- if (err <= 0)
- return err;
+ if (err < 0)
+ goto err_out;
+ if (err == 0)
+ goto ready;
if (first_boot != 0x55555555) {
NXWR32(adapter, CRB_CMDPEG_STATE, 0);
@@ -755,10 +821,17 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
}
NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
+ NXWR32(adapter, NETXEN_PEG_HALT_STATUS1, 0);
+ NXWR32(adapter, NETXEN_PEG_HALT_STATUS2, 0);
+
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_set_port_mode(adapter);
- netxen_load_firmware(adapter);
+ err = netxen_load_firmware(adapter);
+ if (err)
+ goto err_out;
+
+ netxen_release_firmware(adapter);
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
@@ -770,9 +843,9 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
}
- err = netxen_initialize_adapter_offload(adapter);
+ err = netxen_init_dummy_dma(adapter);
if (err)
- return err;
+ goto err_out;
/*
* Tell the hardware our version number.
@@ -782,15 +855,28 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
| (_NETXEN_NIC_LINUX_SUBVERSION);
NXWR32(adapter, CRB_DRIVER_VERSION, val);
+ready:
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
+
wait_init:
/* Handshake with the card before we register the devices. */
err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
if (err) {
- netxen_free_adapter_offload(adapter);
- return err;
+ netxen_free_dummy_dma(adapter);
+ goto err_out;
}
- return 0;
+ nx_update_dma_mask(adapter);
+
+ netxen_check_options(adapter);
+
+ adapter->need_fw_reset = 0;
+
+ /* fall through and release firmware */
+
+err_out:
+ netxen_release_firmware(adapter);
+ return err;
}
static int
@@ -840,11 +926,28 @@ netxen_nic_free_irq(struct netxen_adapter *adapter)
}
}
+static void
+netxen_nic_init_coalesce_defaults(struct netxen_adapter *adapter)
+{
+ adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
+ adapter->coal.normal.data.rx_time_us =
+ NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
+ adapter->coal.normal.data.rx_packets =
+ NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
+ adapter->coal.normal.data.tx_time_us =
+ NETXEN_DEFAULT_INTR_COALESCE_TX_TIME_US;
+ adapter->coal.normal.data.tx_packets =
+ NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS;
+}
+
static int
netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
{
int err;
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return -EIO;
+
err = adapter->init_port(adapter, adapter->physical_port);
if (err) {
printk(KERN_ERR "%s: Failed to initialize port %d\n",
@@ -862,6 +965,12 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
if (adapter->max_sds_rings > 1)
netxen_config_rss(adapter, 1);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_config_intr_coalesce(adapter);
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+ netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);
+
netxen_napi_enable(adapter);
if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
@@ -869,14 +978,18 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
else
netxen_nic_set_link_parameters(adapter);
- mod_timer(&adapter->watchdog_timer, jiffies);
-
+ set_bit(__NX_DEV_UP, &adapter->state);
return 0;
}
static void
netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return;
+
+ clear_bit(__NX_DEV_UP, &adapter->state);
+
spin_lock(&adapter->tx_clean_lock);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@@ -887,12 +1000,12 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
+ adapter->set_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE);
+
netxen_napi_disable(adapter);
netxen_release_tx_buffers(adapter);
spin_unlock(&adapter->tx_clean_lock);
-
- del_timer_sync(&adapter->watchdog_timer);
}
@@ -905,6 +1018,9 @@ netxen_nic_attach(struct netxen_adapter *adapter)
struct nx_host_rds_ring *rds_ring;
struct nx_host_tx_ring *tx_ring;
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+ return 0;
+
err = netxen_init_firmware(adapter);
if (err)
return err;
@@ -913,11 +1029,6 @@ netxen_nic_attach(struct netxen_adapter *adapter)
if (err)
return err;
- if (adapter->fw_major < 4)
- adapter->max_rds_rings = 3;
- else
- adapter->max_rds_rings = 2;
-
err = netxen_alloc_sw_resources(adapter);
if (err) {
printk(KERN_ERR "%s: Error in setting sw resources\n",
@@ -925,8 +1036,6 @@ netxen_nic_attach(struct netxen_adapter *adapter)
return err;
}
- netxen_nic_clear_stats(adapter);
-
err = netxen_alloc_hw_resources(adapter);
if (err) {
printk(KERN_ERR "%s: Error in setting hw resources\n",
@@ -934,10 +1043,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
goto err_out_free_sw;
}
- if (adapter->fw_major < 4) {
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
tx_ring = adapter->tx_ring;
- tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
- tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
+ tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+ crb_cmd_producer[adapter->portnum]);
+ tx_ring->crb_cmd_consumer = netxen_get_ioaddr(adapter,
+ crb_cmd_consumer[adapter->portnum]);
tx_ring->producer = 0;
tx_ring->sw_consumer = 0;
@@ -958,6 +1069,11 @@ netxen_nic_attach(struct netxen_adapter *adapter)
goto err_out_free_rxbuf;
}
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_nic_init_coalesce_defaults(adapter);
+
+ netxen_create_sysfs_entries(adapter);
+
adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
return 0;
@@ -972,6 +1088,11 @@ err_out_free_sw:
static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return;
+
+ netxen_remove_sysfs_entries(adapter);
+
netxen_free_hw_resources(adapter);
netxen_release_rx_buffers(adapter);
netxen_nic_free_irq(adapter);
@@ -981,6 +1102,101 @@ netxen_nic_detach(struct netxen_adapter *adapter)
adapter->is_up = 0;
}
+int
+netxen_nic_reset_context(struct netxen_adapter *adapter)
+{
+ int err = 0;
+ struct net_device *netdev = adapter->netdev;
+
+ if (test_and_set_bit(__NX_RESETTING, &adapter->state))
+ return -EBUSY;
+
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ netxen_nic_down(adapter, netdev);
+
+ netxen_nic_detach(adapter);
+
+ if (netif_running(netdev)) {
+ err = netxen_nic_attach(adapter);
+ if (!err)
+ err = netxen_nic_up(adapter, netdev);
+
+ if (err)
+ goto done;
+ }
+
+ netif_device_attach(netdev);
+ }
+
+done:
+ clear_bit(__NX_RESETTING, &adapter->state);
+ return err;
+}
+
+static int
+netxen_setup_netdev(struct netxen_adapter *adapter,
+ struct net_device *netdev)
+{
+ int err = 0;
+ struct pci_dev *pdev = adapter->pdev;
+
+ adapter->rx_csum = 1;
+ adapter->mc_enabled = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ adapter->max_mc_count = 38;
+ else
+ adapter->max_mc_count = 16;
+
+ netdev->netdev_ops = &netxen_netdev_ops;
+ netdev->watchdog_timeo = 2*HZ;
+
+ netxen_nic_change_mtu(netdev, netdev->mtu);
+
+ SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
+
+ netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->features |= (NETIF_F_GRO);
+ netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+ netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+ }
+
+ if (adapter->pci_using_dac) {
+ netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
+ netdev->features |= (NETIF_F_HW_VLAN_TX);
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+ netdev->features |= NETIF_F_LRO;
+
+ netdev->irq = adapter->msix_entries[0].vector;
+
+ INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
+
+ if (netxen_read_mac_addr(adapter))
+ dev_warn(&pdev->dev, "failed to read mac addr\n");
+
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register net device\n");
+ return err;
+ }
+
+ return 0;
+}
+
static int __devinit
netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1018,9 +1234,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev = alloc_etherdev(sizeof(struct netxen_adapter));
if(!netdev) {
- printk(KERN_ERR"%s: Failed to allocate memory for the "
- "device block.Check system memory resource"
- " usage.\n", netxen_nic_driver_name);
+ dev_err(&pdev->dev, "failed to allocate net_device\n");
+ err = -ENOMEM;
goto err_out_free_res;
}
@@ -1034,10 +1249,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
revision_id = pdev->revision;
adapter->ahw.revision_id = revision_id;
- err = nx_set_dma_mask(adapter);
- if (err)
- goto err_out_free_netdev;
-
rwlock_init(&adapter->adapter_lock);
spin_lock_init(&adapter->tx_clean_lock);
INIT_LIST_HEAD(&adapter->mac_list);
@@ -1048,43 +1259,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
- adapter->rx_csum = 1;
- adapter->mc_enabled = 0;
- if (NX_IS_REVISION_P3(revision_id))
- adapter->max_mc_count = 38;
- else
- adapter->max_mc_count = 16;
-
- netdev->netdev_ops = &netxen_netdev_ops;
- netdev->watchdog_timeo = 2*HZ;
-
- netxen_nic_change_mtu(netdev, netdev->mtu);
- SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
-
- netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
- netdev->features |= (NETIF_F_GRO);
- netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
-
- if (NX_IS_REVISION_P3(revision_id)) {
- netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
- netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
- }
-
- if (adapter->pci_using_dac) {
- netdev->features |= NETIF_F_HIGHDMA;
- netdev->vlan_features |= NETIF_F_HIGHDMA;
- }
-
- if (netxen_nic_get_board_info(adapter) != 0) {
- printk("%s: Error getting board config info.\n",
- netxen_nic_driver_name);
- err = -EIO;
+ err = netxen_nic_get_board_info(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "Error getting board config info.\n");
goto err_out_iounmap;
}
- netxen_initialize_adapter_ops(adapter);
-
/* Mezz cards have PCI function 0,2,3 enabled */
switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -1096,53 +1277,32 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- err = netxen_start_firmware(adapter, 1);
+ err = netxen_start_firmware(adapter);
if (err)
goto err_out_iounmap;
- nx_update_dma_mask(adapter);
-
- netxen_nic_get_firmware_info(adapter);
-
/*
* See if the firmware gave us a virtual-physical port mapping.
*/
adapter->physical_port = adapter->portnum;
- if (adapter->fw_major < 4) {
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
i = NXRD32(adapter, CRB_V2P(adapter->portnum));
if (i != 0x55555555)
adapter->physical_port = i;
}
- netxen_check_options(adapter);
+ netxen_nic_clear_stats(adapter);
netxen_setup_intr(adapter);
- netdev->irq = adapter->msix_entries[0].vector;
-
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &netxen_watchdog;
- adapter->watchdog_timer.data = (unsigned long)adapter;
- INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
- INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
-
- err = netxen_read_mac_addr(adapter);
+ err = netxen_setup_netdev(adapter, netdev);
if (err)
- dev_warn(&pdev->dev, "failed to read mac addr\n");
-
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- if ((err = register_netdev(netdev))) {
- printk(KERN_ERR "%s: register_netdev failed port #%d"
- " aborting\n", netxen_nic_driver_name,
- adapter->portnum);
- err = -EIO;
goto err_out_disable_msi;
- }
pci_set_drvdata(pdev, adapter);
+ netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
@@ -1159,7 +1319,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_disable_msi:
netxen_teardown_intr(adapter);
- netxen_free_adapter_offload(adapter);
+ netxen_free_dummy_dma(adapter);
+
+ nx_decr_dev_ref_cnt(adapter);
err_out_iounmap:
netxen_cleanup_pci_map(adapter);
@@ -1187,17 +1349,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
netdev = adapter->netdev;
+ netxen_cancel_fw_work(adapter);
+
unregister_netdev(netdev);
- cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->tx_timeout_task);
- if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
- netxen_nic_detach(adapter);
- }
+ netxen_nic_detach(adapter);
+
+ nx_decr_dev_ref_cnt(adapter);
if (adapter->portnum == 0)
- netxen_free_adapter_offload(adapter);
+ netxen_free_dummy_dma(adapter);
+
+ clear_bit(__NX_RESETTING, &adapter->state);
netxen_teardown_intr(adapter);
@@ -1211,27 +1376,33 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
free_netdev(netdev);
}
-
-#ifdef CONFIG_PM
-static int
-netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __netxen_nic_shutdown(struct pci_dev *pdev)
{
-
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
+ int retval;
netif_device_detach(netdev);
+ netxen_cancel_fw_work(adapter);
+
if (netif_running(netdev))
netxen_nic_down(adapter, netdev);
- cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->tx_timeout_task);
- if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
- netxen_nic_detach(adapter);
+ netxen_nic_detach(adapter);
+
+ if (adapter->portnum == 0)
+ netxen_free_dummy_dma(adapter);
+
+ nx_decr_dev_ref_cnt(adapter);
- pci_save_state(pdev);
+ clear_bit(__NX_RESETTING, &adapter->state);
+
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
if (netxen_nic_wol_supported(adapter)) {
pci_enable_wake(pdev, PCI_D3cold, 1);
@@ -1239,10 +1410,27 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
}
pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
+static void netxen_nic_shutdown(struct pci_dev *pdev)
+{
+ if (__netxen_nic_shutdown(pdev))
+ return;
+}
+#ifdef CONFIG_PM
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ int retval;
+
+ retval = __netxen_nic_shutdown(pdev);
+ if (retval)
+ return retval;
+
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ return 0;
+}
static int
netxen_nic_resume(struct pci_dev *pdev)
@@ -1260,7 +1448,7 @@ netxen_nic_resume(struct pci_dev *pdev)
adapter->curr_window = 255;
- err = netxen_start_firmware(adapter, 0);
+ err = netxen_start_firmware(adapter);
if (err) {
dev_err(&pdev->dev, "failed to start firmware\n");
return err;
@@ -1269,16 +1457,24 @@ netxen_nic_resume(struct pci_dev *pdev)
if (netif_running(netdev)) {
err = netxen_nic_attach(adapter);
if (err)
- return err;
+ goto err_out;
err = netxen_nic_up(adapter, netdev);
if (err)
- return err;
+ goto err_out_detach;
netif_device_attach(netdev);
+
+ netxen_config_indev_addr(netdev, NETDEV_UP);
}
- return 0;
+ netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
+err_out_detach:
+ netxen_nic_detach(adapter);
+err_out:
+ nx_decr_dev_ref_cnt(adapter);
+ return err;
}
#endif
@@ -1290,11 +1486,9 @@ static int netxen_nic_open(struct net_device *netdev)
if (adapter->driver_mismatch)
return -EIO;
- if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
- err = netxen_nic_attach(adapter);
- if (err)
- return err;
- }
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
err = netxen_nic_up(adapter, netdev);
if (err)
@@ -1320,30 +1514,52 @@ static int netxen_nic_close(struct net_device *netdev)
return 0;
}
-static bool netxen_tso_check(struct net_device *netdev,
- struct cmd_desc_type0 *desc, struct sk_buff *skb)
+static void
+netxen_tso_check(struct net_device *netdev,
+ struct nx_host_tx_ring *tx_ring,
+ struct cmd_desc_type0 *first_desc,
+ struct sk_buff *skb)
{
- bool tso = false;
u8 opcode = TX_ETHER_PKT;
__be16 protocol = skb->protocol;
- u16 flags = 0;
+ u16 flags = 0, vid = 0;
+ u32 producer;
+ int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
+ struct cmd_desc_type0 *hwdesc;
+ struct vlan_ethhdr *vh;
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
- struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+
+ vh = (struct vlan_ethhdr *)skb->data;
protocol = vh->h_vlan_encapsulated_proto;
flags = FLAGS_VLAN_TAGGED;
+
+ } else if (vlan_tx_tag_present(skb)) {
+
+ flags = FLAGS_VLAN_OOB;
+ vid = vlan_tx_tag_get(skb);
+ netxen_set_tx_vlan_tci(first_desc, vid);
+ vlan_oob = 1;
}
if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
skb_shinfo(skb)->gso_size > 0) {
- desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
- desc->total_hdr_length =
- skb_transport_offset(skb) + tcp_hdrlen(skb);
+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+
+ first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ first_desc->total_hdr_length = hdr_len;
+ if (vlan_oob) {
+ first_desc->total_hdr_length += VLAN_HLEN;
+ first_desc->tcp_hdr_offset = VLAN_HLEN;
+ first_desc->ip_hdr_offset = VLAN_HLEN;
+ /* Only in case of TSO on vlan device */
+ flags |= FLAGS_VLAN_TAGGED;
+ }
opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
TX_TCP_LSO6 : TX_TCP_LSO;
- tso = true;
+ tso = 1;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4proto;
@@ -1364,55 +1580,133 @@ static bool netxen_tso_check(struct net_device *netdev,
opcode = TX_UDPV6_PKT;
}
}
- desc->tcp_hdr_offset = skb_transport_offset(skb);
- desc->ip_hdr_offset = skb_network_offset(skb);
- netxen_set_tx_flags_opcode(desc, flags, opcode);
- return tso;
+
+ first_desc->tcp_hdr_offset += skb_transport_offset(skb);
+ first_desc->ip_hdr_offset += skb_network_offset(skb);
+ netxen_set_tx_flags_opcode(first_desc, flags, opcode);
+
+ if (!tso)
+ return;
+
+ /* For LSO, we need to copy the MAC/IP/TCP headers into
+ * the descriptor ring
+ */
+ producer = tx_ring->producer;
+ copied = 0;
+ offset = 2;
+
+ if (vlan_oob) {
+ /* Create a TSO vlan header template for firmware */
+
+ hwdesc = &tx_ring->desc_head[producer];
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+ copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+ hdr_len + VLAN_HLEN);
+
+ vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
+ skb_copy_from_linear_data(skb, vh, 12);
+ vh->h_vlan_proto = htons(ETH_P_8021Q);
+ vh->h_vlan_TCI = htons(vid);
+ skb_copy_from_linear_data_offset(skb, 12,
+ (char *)vh + 16, copy_len - 16);
+
+ copied = copy_len - VLAN_HLEN;
+ offset = 0;
+
+ producer = get_next_index(producer, tx_ring->num_desc);
+ }
+
+ while (copied < hdr_len) {
+
+ copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+ (hdr_len - copied));
+
+ hwdesc = &tx_ring->desc_head[producer];
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+ skb_copy_from_linear_data_offset(skb, copied,
+ (char *)hwdesc + offset, copy_len);
+
+ copied += copy_len;
+ offset = 0;
+
+ producer = get_next_index(producer, tx_ring->num_desc);
+ }
+
+ tx_ring->producer = producer;
+ barrier();
}
-static void
-netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
- struct netxen_cmd_buffer *pbuf, int last)
+static int
+netxen_map_tx_skb(struct pci_dev *pdev,
+ struct sk_buff *skb, struct netxen_cmd_buffer *pbuf)
{
- int k;
- struct netxen_skb_frag *buffrag;
+ struct netxen_skb_frag *nf;
+ struct skb_frag_struct *frag;
+ int i, nr_frags;
+ dma_addr_t map;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ nf = &pbuf->frag_array[0];
- buffrag = &pbuf->frag_array[0];
- pci_unmap_single(pdev, buffrag->dma,
- buffrag->length, PCI_DMA_TODEVICE);
+ map = pci_map_single(pdev, skb->data,
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(pdev, map))
+ goto out_err;
- for (k = 1; k < last; k++) {
- buffrag = &pbuf->frag_array[k];
- pci_unmap_page(pdev, buffrag->dma,
- buffrag->length, PCI_DMA_TODEVICE);
+ nf->dma = map;
+ nf->length = skb_headlen(skb);
+
+ for (i = 0; i < nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ nf = &pbuf->frag_array[i+1];
+
+ map = pci_map_page(pdev, frag->page, frag->page_offset,
+ frag->size, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(pdev, map))
+ goto unwind;
+
+ nf->dma = map;
+ nf->length = frag->size;
}
+
+ return 0;
+
+unwind:
+ while (--i >= 0) {
+ nf = &pbuf->frag_array[i+1];
+ pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
+ }
+
+ nf = &pbuf->frag_array[0];
+ pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
+
+out_err:
+ return -ENOMEM;
}
static inline void
netxen_clear_cmddesc(u64 *desc)
{
- int i;
- for (i = 0; i < 8; i++)
- desc[i] = 0ULL;
+ desc[0] = 0ULL;
+ desc[2] = 0ULL;
}
-static int
+static netdev_tx_t
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
- unsigned int first_seg_len = skb->len - skb->data_len;
struct netxen_cmd_buffer *pbuf;
struct netxen_skb_frag *buffrag;
- struct cmd_desc_type0 *hwdesc;
- struct pci_dev *pdev = adapter->pdev;
- dma_addr_t temp_dma;
+ struct cmd_desc_type0 *hwdesc, *first_desc;
+ struct pci_dev *pdev;
int i, k;
u32 producer;
int frag_count, no_of_desc;
u32 num_txd = tx_ring->num_desc;
- bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
@@ -1425,121 +1719,60 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
producer = tx_ring->producer;
-
- hwdesc = &tx_ring->desc_head[producer];
- netxen_clear_cmddesc((u64 *)hwdesc);
pbuf = &tx_ring->cmd_buf_arr[producer];
- is_tso = netxen_tso_check(netdev, hwdesc, skb);
+ pdev = adapter->pdev;
+
+ if (netxen_map_tx_skb(pdev, skb, pbuf))
+ goto drop_packet;
pbuf->skb = skb;
pbuf->frag_count = frag_count;
- buffrag = &pbuf->frag_array[0];
- temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(pdev, temp_dma))
- goto drop_packet;
- buffrag->dma = temp_dma;
- buffrag->length = first_seg_len;
- netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
- netxen_set_tx_port(hwdesc, adapter->portnum);
+ first_desc = hwdesc = &tx_ring->desc_head[producer];
+ netxen_clear_cmddesc((u64 *)hwdesc);
+
+ netxen_set_tx_frags_len(first_desc, frag_count, skb->len);
+ netxen_set_tx_port(first_desc, adapter->portnum);
- hwdesc->buffer_length[0] = cpu_to_le16(first_seg_len);
- hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
+ for (i = 0; i < frag_count; i++) {
- for (i = 1, k = 1; i < frag_count; i++, k++) {
- struct skb_frag_struct *frag;
- int len, temp_len;
- unsigned long offset;
+ k = i % 4;
- /* move to next desc. if there is a need */
- if ((i & 0x3) == 0) {
- k = 0;
+ if ((k == 0) && (i > 0)) {
+ /* move to next desc.*/
producer = get_next_index(producer, num_txd);
hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
- pbuf = &tx_ring->cmd_buf_arr[producer];
- pbuf->skb = NULL;
- }
- frag = &skb_shinfo(skb)->frags[i - 1];
- len = frag->size;
- offset = frag->page_offset;
-
- temp_len = len;
- temp_dma = pci_map_page(pdev, frag->page, offset,
- len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(pdev, temp_dma)) {
- netxen_clean_tx_dma_mapping(pdev, pbuf, i);
- goto drop_packet;
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
}
- buffrag++;
- buffrag->dma = temp_dma;
- buffrag->length = temp_len;
+ buffrag = &pbuf->frag_array[i];
- hwdesc->buffer_length[k] = cpu_to_le16(temp_len);
+ hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length);
switch (k) {
case 0:
- hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
+ hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
break;
case 1:
- hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
+ hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma);
break;
case 2:
- hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
+ hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma);
break;
case 3:
- hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
+ hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma);
break;
}
- frag++;
}
- producer = get_next_index(producer, num_txd);
- /* For LSO, we need to copy the MAC/IP/TCP headers into
- * the descriptor ring
- */
- if (is_tso) {
- int hdr_len, first_hdr_len, more_hdr;
- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
- first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
- more_hdr = 1;
- } else {
- first_hdr_len = hdr_len;
- more_hdr = 0;
- }
- /* copy the MAC/IP/TCP headers to the cmd descriptor list */
- hwdesc = &tx_ring->desc_head[producer];
- pbuf = &tx_ring->cmd_buf_arr[producer];
- pbuf->skb = NULL;
-
- /* copy the first 64 bytes */
- memcpy(((void *)hwdesc) + 2,
- (void *)(skb->data), first_hdr_len);
- producer = get_next_index(producer, num_txd);
-
- if (more_hdr) {
- hwdesc = &tx_ring->desc_head[producer];
- pbuf = &tx_ring->cmd_buf_arr[producer];
- pbuf->skb = NULL;
- /* copy the next 64 bytes - should be enough except
- * for pathological case
- */
- skb_copy_from_linear_data_offset(skb, first_hdr_len,
- hwdesc,
- (hdr_len -
- first_hdr_len));
- producer = get_next_index(producer, num_txd);
- }
- }
+ tx_ring->producer = get_next_index(producer, num_txd);
- tx_ring->producer = producer;
- adapter->stats.txbytes += skb->len;
+ netxen_tso_check(netdev, tx_ring, first_desc, skb);
netxen_nic_update_cmd_producer(adapter, tx_ring);
+ adapter->stats.txbytes += skb->len;
adapter->stats.xmitcalled++;
return NETDEV_TX_OK;
@@ -1635,58 +1868,14 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
netxen_advert_link_change(adapter, linkup);
}
-static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
-
- netif_device_detach(netdev);
- netxen_nic_down(adapter, netdev);
- netxen_nic_detach(adapter);
-}
-
-static void netxen_watchdog(unsigned long v)
-{
- struct netxen_adapter *adapter = (struct netxen_adapter *)v;
-
- if (netxen_nic_check_temp(adapter))
- goto do_sched;
-
- if (!adapter->has_link_events) {
- netxen_nic_handle_phy_intr(adapter);
-
- if (adapter->link_changed)
- goto do_sched;
- }
-
- if (netif_running(adapter->netdev))
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-
- return;
-
-do_sched:
- schedule_work(&adapter->watchdog_task);
-}
-
-void netxen_watchdog_task(struct work_struct *work)
+static void netxen_tx_timeout(struct net_device *netdev)
{
- struct netxen_adapter *adapter =
- container_of(work, struct netxen_adapter, watchdog_task);
+ struct netxen_adapter *adapter = netdev_priv(netdev);
- if (adapter->temp == NX_TEMP_PANIC) {
- netxen_nic_thermal_shutdown(adapter);
+ if (test_bit(__NX_RESETTING, &adapter->state))
return;
- }
-
- if (adapter->link_changed)
- netxen_nic_set_link_parameters(adapter);
-
- if (netif_running(adapter->netdev))
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
-static void netxen_tx_timeout(struct net_device *netdev)
-{
- struct netxen_adapter *adapter = netdev_priv(netdev);
+ dev_err(&netdev->dev, "transmit timeout, resetting.\n");
schedule_work(&adapter->tx_timeout_task);
}
@@ -1698,15 +1887,37 @@ static void netxen_tx_timeout_task(struct work_struct *work)
if (!netif_running(adapter->netdev))
return;
- printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
- netxen_nic_driver_name, adapter->netdev->name);
+ if (test_and_set_bit(__NX_RESETTING, &adapter->state))
+ return;
- netxen_napi_disable(adapter);
+ if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS)
+ goto request_reset;
- adapter->netdev->trans_start = jiffies;
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ /* try to scrub interrupt */
+ netxen_napi_disable(adapter);
- netxen_napi_enable(adapter);
- netif_wake_queue(adapter->netdev);
+ adapter->netdev->trans_start = jiffies;
+
+ netxen_napi_enable(adapter);
+
+ netif_wake_queue(adapter->netdev);
+
+ goto done;
+
+ } else {
+ if (!netxen_nic_reset_context(adapter)) {
+ adapter->netdev->trans_start = jiffies;
+ goto done;
+ }
+
+ /* context reset failed, fall through for fw reset */
+ }
+
+request_reset:
+ adapter->need_fw_reset = 1;
+done:
+ clear_bit(__NX_RESETTING, &adapter->state);
}
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
@@ -1716,7 +1927,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
memset(stats, 0, sizeof(*stats));
- stats->rx_packets = adapter->stats.no_rcv;
+ stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes;
stats->tx_bytes = adapter->stats.txbytes;
@@ -1732,41 +1943,37 @@ static irqreturn_t netxen_intr(int irq, void *data)
struct netxen_adapter *adapter = sds_ring->adapter;
u32 status = 0;
- status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+ status = readl(adapter->isr_int_vec);
- if (!(status & adapter->legacy_intr.int_vec_bit))
+ if (!(status & adapter->int_vec_bit))
return IRQ_NONE;
- if (adapter->ahw.revision_id >= NX_P3_B1) {
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
/* check interrupt state machine, to be sure */
- status = adapter->pci_read_immediate(adapter,
- ISR_INT_STATE_REG);
+ status = readl(adapter->crb_int_state_reg);
if (!ISR_LEGACY_INT_TRIGGERED(status))
return IRQ_NONE;
} else {
unsigned long our_int = 0;
- our_int = NXRD32(adapter, CRB_INT_VECTOR);
+ our_int = readl(adapter->crb_int_state_reg);
/* not our interrupt */
if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
return IRQ_NONE;
/* claim interrupt */
- NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
- }
+ writel((our_int & 0xffffffff), adapter->crb_int_state_reg);
- /* clear interrupt */
- if (adapter->fw_major < 4)
+ /* clear interrupt */
netxen_nic_disable_int(sds_ring);
+ }
- adapter->pci_write_immediate(adapter,
- adapter->legacy_intr.tgt_status_reg,
- 0xffffffff);
+ writel(0xffffffff, adapter->tgt_status_reg);
/* read twice to ensure write is flushed */
- adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
- adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+ readl(adapter->isr_int_vec);
+ readl(adapter->isr_int_vec);
napi_schedule(&sds_ring->napi);
@@ -1779,8 +1986,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
struct netxen_adapter *adapter = sds_ring->adapter;
/* clear interrupt */
- adapter->pci_write_immediate(adapter,
- adapter->msi_tgt_status, 0xffffffff);
+ writel(0xffffffff, adapter->tgt_status_reg);
napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
@@ -1827,6 +2033,473 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
}
#endif
+static int
+nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+ int count;
+ if (netxen_api_lock(adapter))
+ return -EIO;
+
+ count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+ NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+ netxen_api_unlock(adapter);
+ return count;
+}
+
+static int
+nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+ int count;
+ if (netxen_api_lock(adapter))
+ return -EIO;
+
+ count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+ WARN_ON(count == 0);
+
+ NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+
+ if (count == 0)
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
+
+ netxen_api_unlock(adapter);
+ return count;
+}
+
+static void
+nx_dev_request_reset(struct netxen_adapter *adapter)
+{
+ u32 state;
+
+ if (netxen_api_lock(adapter))
+ return;
+
+ state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+ if (state != NX_DEV_INITALIZING)
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
+
+ netxen_api_unlock(adapter);
+}
+
+static int
+netxen_can_start_firmware(struct netxen_adapter *adapter)
+{
+ int count;
+ int can_start = 0;
+
+ if (netxen_api_lock(adapter))
+ return 0;
+
+ count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+ if ((count < 0) || (count >= NX_MAX_PCI_FUNC))
+ count = 0;
+
+ if (count == 0) {
+ can_start = 1;
+ NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_INITALIZING);
+ }
+
+ NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+ netxen_api_unlock(adapter);
+
+ return can_start;
+}
+
+static void
+netxen_schedule_work(struct netxen_adapter *adapter,
+ work_func_t func, int delay)
+{
+ INIT_DELAYED_WORK(&adapter->fw_work, func);
+ schedule_delayed_work(&adapter->fw_work, delay);
+}
+
+static void
+netxen_cancel_fw_work(struct netxen_adapter *adapter)
+{
+ while (test_and_set_bit(__NX_RESETTING, &adapter->state))
+ msleep(10);
+
+ cancel_delayed_work_sync(&adapter->fw_work);
+}
+
+static void
+netxen_attach_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 err = 0;
+
+ if (netif_running(netdev)) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ goto done;
+
+ err = netxen_nic_up(adapter, netdev);
+ if (err) {
+ netxen_nic_detach(adapter);
+ goto done;
+ }
+
+ netxen_config_indev_addr(netdev, NETDEV_UP);
+ }
+
+ netif_device_attach(netdev);
+
+done:
+ adapter->fw_fail_cnt = 0;
+ clear_bit(__NX_RESETTING, &adapter->state);
+ netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
+static void
+netxen_fwinit_work(struct work_struct *work)
+{
+ struct netxen_adapter *adapter = container_of(work,
+ struct netxen_adapter, fw_work.work);
+ int dev_state;
+
+ dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+ switch (dev_state) {
+ case NX_DEV_COLD:
+ case NX_DEV_READY:
+ if (!netxen_start_firmware(adapter)) {
+ netxen_schedule_work(adapter, netxen_attach_work, 0);
+ return;
+ }
+ break;
+
+ case NX_DEV_INITALIZING:
+ if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
+ netxen_schedule_work(adapter,
+ netxen_fwinit_work, 2 * FW_POLL_DELAY);
+ return;
+ }
+ break;
+
+ case NX_DEV_FAILED:
+ default:
+ break;
+ }
+
+ nx_incr_dev_ref_cnt(adapter);
+ clear_bit(__NX_RESETTING, &adapter->state);
+}
+
+static void
+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;
+ u32 status;
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ netxen_nic_down(adapter, netdev);
+
+ netxen_nic_detach(adapter);
+
+ status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+
+ ref_cnt = nx_decr_dev_ref_cnt(adapter);
+
+ if (status & NX_RCODE_FATAL_ERROR)
+ return;
+
+ if (adapter->temp == NX_TEMP_PANIC)
+ return;
+
+ delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
+
+ adapter->fw_wait_cnt = 0;
+ netxen_schedule_work(adapter, netxen_fwinit_work, delay);
+}
+
+static int
+netxen_check_health(struct netxen_adapter *adapter)
+{
+ u32 state, heartbit;
+ struct net_device *netdev = adapter->netdev;
+
+ if (netxen_nic_check_temp(adapter))
+ goto detach;
+
+ if (adapter->need_fw_reset) {
+ nx_dev_request_reset(adapter);
+ goto detach;
+ }
+
+ state = NXRD32(adapter, NX_CRB_DEV_STATE);
+ if (state == NX_DEV_NEED_RESET)
+ goto detach;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
+
+ heartbit = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+ if (heartbit != adapter->heartbit) {
+ adapter->heartbit = heartbit;
+ adapter->fw_fail_cnt = 0;
+ return 0;
+ }
+
+ if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
+ return 0;
+
+ clear_bit(__NX_FW_ATTACHED, &adapter->state);
+
+ dev_info(&netdev->dev, "firmware hang detected\n");
+
+detach:
+ if (!test_and_set_bit(__NX_RESETTING, &adapter->state))
+ netxen_schedule_work(adapter, netxen_detach_work, 0);
+ return 1;
+}
+
+static void
+netxen_fw_poll_work(struct work_struct *work)
+{
+ struct netxen_adapter *adapter = container_of(work,
+ struct netxen_adapter, fw_work.work);
+
+ if (test_bit(__NX_RESETTING, &adapter->state))
+ goto reschedule;
+
+ if (test_bit(__NX_DEV_UP, &adapter->state)) {
+ if (!adapter->has_link_events) {
+
+ netxen_nic_handle_phy_intr(adapter);
+
+ if (adapter->link_changed)
+ netxen_nic_set_link_parameters(adapter);
+ }
+ }
+
+ if (netxen_check_health(adapter))
+ return;
+
+reschedule:
+ netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
+static ssize_t
+netxen_store_bridged_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct net_device *net = to_net_dev(dev);
+ struct netxen_adapter *adapter = netdev_priv(net);
+ unsigned long new;
+ int ret = -EINVAL;
+
+ if (!(adapter->capabilities & NX_FW_CAPABILITY_BDG))
+ goto err_out;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ goto err_out;
+
+ if (strict_strtoul(buf, 2, &new))
+ goto err_out;
+
+ if (!netxen_config_bridged_mode(adapter, !!new))
+ ret = len;
+
+err_out:
+ return ret;
+}
+
+static ssize_t
+netxen_show_bridged_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *net = to_net_dev(dev);
+ struct netxen_adapter *adapter;
+ int bridged_mode = 0;
+
+ adapter = netdev_priv(net);
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
+ bridged_mode = !!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED);
+
+ return sprintf(buf, "%d\n", bridged_mode);
+}
+
+static struct device_attribute dev_attr_bridged_mode = {
+ .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
+ .show = netxen_show_bridged_mode,
+ .store = netxen_store_bridged_mode,
+};
+
+static void
+netxen_create_sysfs_entries(struct netxen_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct device *dev = &netdev->dev;
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
+ /* bridged_mode control */
+ if (device_create_file(dev, &dev_attr_bridged_mode)) {
+ dev_warn(&netdev->dev,
+ "failed to create bridged_mode sysfs entry\n");
+ }
+ }
+}
+
+static void
+netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct device *dev = &netdev->dev;
+
+ if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
+ device_remove_file(dev, &dev_attr_bridged_mode);
+}
+
+#ifdef CONFIG_INET
+
+#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)
+
+static int
+netxen_destip_supported(struct netxen_adapter *adapter)
+{
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
+
+ if (adapter->ahw.cut_through)
+ return 0;
+
+ return 1;
+}
+
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{
+ struct in_device *indev;
+ struct netxen_adapter *adapter = netdev_priv(dev);
+
+ if (!netxen_destip_supported(adapter))
+ return;
+
+ indev = in_dev_get(dev);
+ if (!indev)
+ return;
+
+ for_ifa(indev) {
+ switch (event) {
+ case NETDEV_UP:
+ netxen_config_ipaddr(adapter,
+ ifa->ifa_address, NX_IP_UP);
+ break;
+ case NETDEV_DOWN:
+ netxen_config_ipaddr(adapter,
+ ifa->ifa_address, NX_IP_DOWN);
+ break;
+ default:
+ break;
+ }
+ } endfor_ifa(indev);
+
+ in_dev_put(indev);
+ return;
+}
+
+static int netxen_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct netxen_adapter *adapter;
+ struct net_device *dev = (struct net_device *)ptr;
+
+recheck:
+ if (dev == NULL)
+ goto done;
+
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ dev = vlan_dev_real_dev(dev);
+ goto recheck;
+ }
+
+ if (!is_netxen_netdev(dev))
+ goto done;
+
+ adapter = netdev_priv(dev);
+
+ if (!adapter)
+ goto done;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ goto done;
+
+ netxen_config_indev_addr(dev, event);
+done:
+ return NOTIFY_DONE;
+}
+
+static int
+netxen_inetaddr_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct netxen_adapter *adapter;
+ struct net_device *dev;
+
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+ dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
+
+recheck:
+ if (dev == NULL || !netif_running(dev))
+ goto done;
+
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ dev = vlan_dev_real_dev(dev);
+ goto recheck;
+ }
+
+ if (!is_netxen_netdev(dev))
+ goto done;
+
+ adapter = netdev_priv(dev);
+
+ if (!adapter || !netxen_destip_supported(adapter))
+ goto done;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ goto done;
+
+ switch (event) {
+ case NETDEV_UP:
+ netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
+ break;
+ case NETDEV_DOWN:
+ netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN);
+ break;
+ default:
+ break;
+ }
+
+done:
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block netxen_netdev_cb = {
+ .notifier_call = netxen_netdev_event,
+};
+
+static struct notifier_block netxen_inetaddr_cb = {
+ .notifier_call = netxen_inetaddr_event,
+};
+#else
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{ }
+#endif
+
static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
.id_table = netxen_pci_tbl,
@@ -1834,16 +2507,20 @@ static struct pci_driver netxen_driver = {
.remove = __devexit_p(netxen_nic_remove),
#ifdef CONFIG_PM
.suspend = netxen_nic_suspend,
- .resume = netxen_nic_resume
+ .resume = netxen_nic_resume,
#endif
+ .shutdown = netxen_nic_shutdown
};
-/* Driver Registration on NetXen card */
-
static int __init netxen_init_module(void)
{
printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+#ifdef CONFIG_INET
+ register_netdevice_notifier(&netxen_netdev_cb);
+ register_inetaddr_notifier(&netxen_inetaddr_cb);
+#endif
+
return pci_register_driver(&netxen_driver);
}
@@ -1852,6 +2529,11 @@ module_init(netxen_init_module);
static void __exit netxen_exit_module(void)
{
pci_unregister_driver(&netxen_driver);
+
+#ifdef CONFIG_INET
+ unregister_inetaddr_notifier(&netxen_inetaddr_cb);
+ unregister_netdevice_notifier(&netxen_netdev_cb);
+#endif
}
module_exit(netxen_exit_module);
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
deleted file mode 100644
index 5941c79be72..00000000000
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright (C) 2003 - 2009 NetXen, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
- */
-
-#include "netxen_nic.h"
-
-#define NETXEN_GB_MAC_SOFT_RESET 0x80000000
-#define NETXEN_GB_MAC_RESET_PROT_BLK 0x000F0000
-#define NETXEN_GB_MAC_ENABLE_TX_RX 0x00000005
-#define NETXEN_GB_MAC_PAUSED_FRMS 0x00000020
-
-static long phy_lock_timeout = 100000000;
-
-static int phy_lock(struct netxen_adapter *adapter)
-{
- int i;
- int done = 0, timeout = 0;
-
- while (!done) {
- done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
- if (done == 1)
- break;
- if (timeout >= phy_lock_timeout) {
- return -1;
- }
- timeout++;
- if (!in_atomic())
- schedule();
- else {
- for (i = 0; i < 20; i++)
- cpu_relax();
- }
- }
-
- NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
- return 0;
-}
-
-static int phy_unlock(struct netxen_adapter *adapter)
-{
- adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
-
- return 0;
-}
-
-/*
- * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
- * mii management interface.
- *
- * Note: The MII management interface goes through port 0.
- * Individual phys are addressed as follows:
- * @param phy [15:8] phy id
- * @param reg [7:0] register number
- *
- * @returns 0 on success
- * -1 on error
- *
- */
-int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
- __u32 * readval)
-{
- long timeout = 0;
- long result = 0;
- long restore = 0;
- long phy = adapter->physical_port;
- __u32 address;
- __u32 command;
- __u32 status;
- __u32 mac_cfg0;
-
- if (phy_lock(adapter) != 0) {
- return -1;
- }
-
- /*
- * MII mgmt all goes through port 0 MAC interface,
- * so it cannot be in reset
- */
-
- mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
- if (netxen_gb_get_soft_reset(mac_cfg0)) {
- __u32 temp;
- temp = 0;
- netxen_gb_tx_reset_pb(temp);
- netxen_gb_rx_reset_pb(temp);
- netxen_gb_tx_reset_mac(temp);
- netxen_gb_rx_reset_mac(temp);
- if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
- return -EIO;
- restore = 1;
- }
-
- address = 0;
- netxen_gb_mii_mgmt_reg_addr(address, reg);
- netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
- return -EIO;
- command = 0; /* turn off any prior activity */
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
- return -EIO;
- /* send read command */
- netxen_gb_mii_mgmt_set_read_cycle(command);
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
- return -EIO;
-
- status = 0;
- do {
- status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
- timeout++;
- } while ((netxen_get_gb_mii_mgmt_busy(status)
- || netxen_get_gb_mii_mgmt_notvalid(status))
- && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
-
- if (timeout < NETXEN_NIU_PHY_WAITMAX) {
- *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
- result = 0;
- } else
- result = -1;
-
- if (restore)
- if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
- return -EIO;
- phy_unlock(adapter);
- return result;
-}
-
-/*
- * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
- * mii management interface.
- *
- * Note: The MII management interface goes through port 0.
- * Individual phys are addressed as follows:
- * @param phy [15:8] phy id
- * @param reg [7:0] register number
- *
- * @returns 0 on success
- * -1 on error
- *
- */
-int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
- __u32 val)
-{
- long timeout = 0;
- long result = 0;
- long restore = 0;
- long phy = adapter->physical_port;
- __u32 address;
- __u32 command;
- __u32 status;
- __u32 mac_cfg0;
-
- /*
- * MII mgmt all goes through port 0 MAC interface, so it
- * cannot be in reset
- */
-
- mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
- if (netxen_gb_get_soft_reset(mac_cfg0)) {
- __u32 temp;
- temp = 0;
- netxen_gb_tx_reset_pb(temp);
- netxen_gb_rx_reset_pb(temp);
- netxen_gb_tx_reset_mac(temp);
- netxen_gb_rx_reset_mac(temp);
-
- if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
- return -EIO;
- restore = 1;
- }
-
- command = 0; /* turn off any prior activity */
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
- return -EIO;
-
- address = 0;
- netxen_gb_mii_mgmt_reg_addr(address, reg);
- netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
- return -EIO;
-
- if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
- return -EIO;
-
- status = 0;
- do {
- status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
- timeout++;
- } while ((netxen_get_gb_mii_mgmt_busy(status))
- && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
-
- if (timeout < NETXEN_NIU_PHY_WAITMAX)
- result = 0;
- else
- result = -EIO;
-
- /* restore the state of port 0 MAC in case we tampered with it */
- if (restore)
- if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
- return -EIO;
-
- return result;
-}
-
-int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
-{
- NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f);
- return 0;
-}
-
-int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
-{
- int result = 0;
- __u32 enable = 0;
- netxen_set_phy_int_link_status_changed(enable);
- netxen_set_phy_int_autoneg_completed(enable);
- netxen_set_phy_int_speed_changed(enable);
-
- if (0 !=
- netxen_niu_gbe_phy_write(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
- enable))
- result = -EIO;
-
- return result;
-}
-
-int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
-{
- NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f);
- return 0;
-}
-
-int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
-{
- int result = 0;
- if (0 !=
- netxen_niu_gbe_phy_write(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
- result = -EIO;
-
- return result;
-}
-
-static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
-{
- int result = 0;
- if (0 !=
- netxen_niu_gbe_phy_write(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
- -EIO))
- result = -EIO;
-
- return result;
-}
-
-/*
- * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
- *
- */
-static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
- int port, long enable)
-{
- NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
- NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
- NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
- NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
-
- if (enable) {
- /*
- * Do NOT enable flow control until a suitable solution for
- * shutting down pause frames is found.
- */
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
- }
-
- if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR "ERROR enabling PHY interrupts\n");
- if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR "ERROR clearing PHY interrupts\n");
-}
-
-/*
- * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
- */
-static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
- int port, long enable)
-{
- NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
- NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
- NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
- NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
-
- if (enable) {
- /*
- * Do NOT enable flow control until a suitable solution for
- * shutting down pause frames is found.
- */
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
- }
-
- if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR "ERROR enabling PHY interrupts\n");
- if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR "ERROR clearing PHY interrupts\n");
-}
-
-int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
-{
- int result = 0;
- __u32 status;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- if (adapter->disable_phy_interrupts)
- adapter->disable_phy_interrupts(adapter);
- mdelay(2);
-
- if (0 == netxen_niu_gbe_phy_read(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) {
- if (netxen_get_phy_link(status)) {
- if (netxen_get_phy_speed(status) == 2) {
- netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
- } else if ((netxen_get_phy_speed(status) == 1)
- || (netxen_get_phy_speed(status) == 0)) {
- netxen_niu_gbe_set_mii_mode(adapter, port, 1);
- } else {
- result = -1;
- }
-
- } else {
- /*
- * We don't have link. Cable must be unconnected.
- * Enable phy interrupts so we take action when
- * plugged in.
- */
-
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- NETXEN_GB_MAC_SOFT_RESET);
- NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- NETXEN_GB_MAC_RESET_PROT_BLK |
- NETXEN_GB_MAC_ENABLE_TX_RX |
- NETXEN_GB_MAC_PAUSED_FRMS);
- if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR
- "ERROR clearing PHY interrupts\n");
- if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR
- "ERROR enabling PHY interrupts\n");
- if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR
- "ERROR clearing PHY interrupts\n");
- result = -1;
- }
- } else {
- result = -EIO;
- }
- return result;
-}
-
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
-{
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
- NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
- }
-
- return 0;
-}
-
-/* Disable a GbE interface */
-int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
-{
- __u32 mac_cfg0;
- u32 port = adapter->physical_port;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- if (port > NETXEN_NIU_MAX_GBE_PORTS)
- return -EINVAL;
- mac_cfg0 = 0;
- netxen_gb_soft_reset(mac_cfg0);
- if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0))
- return -EIO;
- return 0;
-}
-
-/* Disable an XG interface */
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
-{
- __u32 mac_cfg;
- u32 port = adapter->physical_port;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- if (port > NETXEN_NIU_MAX_XG_PORTS)
- return -EINVAL;
-
- mac_cfg = 0;
- if (NXWR32(adapter,
- NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
- return -EIO;
- return 0;
-}
-
-/* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
- u32 mode)
-{
- __u32 reg;
- u32 port = adapter->physical_port;
-
- if (port > NETXEN_NIU_MAX_GBE_PORTS)
- return -EINVAL;
-
- /* save previous contents */
- reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR);
- if (mode == NETXEN_NIU_PROMISC_MODE) {
- switch (port) {
- case 0:
- netxen_clear_gb_drop_gb0(reg);
- break;
- case 1:
- netxen_clear_gb_drop_gb1(reg);
- break;
- case 2:
- netxen_clear_gb_drop_gb2(reg);
- break;
- case 3:
- netxen_clear_gb_drop_gb3(reg);
- break;
- default:
- return -EIO;
- }
- } else {
- switch (port) {
- case 0:
- netxen_set_gb_drop_gb0(reg);
- break;
- case 1:
- netxen_set_gb_drop_gb1(reg);
- break;
- case 2:
- netxen_set_gb_drop_gb2(reg);
- break;
- case 3:
- netxen_set_gb_drop_gb3(reg);
- break;
- default:
- return -EIO;
- }
- }
- if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg))
- return -EIO;
- return 0;
-}
-
-int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
- u32 mode)
-{
- __u32 reg;
- u32 port = adapter->physical_port;
-
- if (port > NETXEN_NIU_MAX_XG_PORTS)
- return -EINVAL;
-
- reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
- if (mode == NETXEN_NIU_PROMISC_MODE)
- reg = (reg | 0x2000UL);
- else
- reg = (reg & ~0x2000UL);
-
- if (mode == NETXEN_NIU_ALLMULTI_MODE)
- reg = (reg | 0x1000UL);
- else
- reg = (reg & ~0x1000UL);
-
- NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
-
- return 0;
-}
-
-int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
-{
- u32 mac_hi, mac_lo;
- u32 reg_hi, reg_lo;
-
- u8 phy = adapter->physical_port;
- u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
- NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
-
- if (phy >= phy_count)
- return -EINVAL;
-
- mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
- mac_hi = addr[2] | ((u32)addr[3] << 8) |
- ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
-
- if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
- reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
- reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
- } else {
- reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
- reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
- }
-
- /* write twice to flush */
- if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
- return -EIO;
- if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
- return -EIO;
-
- return 0;
-}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
deleted file mode 100644
index b73a62ca74f..00000000000
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2003 - 2009 NetXen, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- * info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
- */
-
-#ifndef __NIC_PHAN_REG_H_
-#define __NIC_PHAN_REG_H_
-
-/*
- * CRB Registers or queue message done only at initialization time.
- */
-#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200)
-#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
-#define NIC_CRB_BASE_2 NETXEN_CAM_RAM(0x700)
-#define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X))
-
-#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
-#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
-#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
-#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
-#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10)
-#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14)
-#define NX_CDRP_CRB_OFFSET NETXEN_NIC_REG(0x18)
-#define NX_ARG1_CRB_OFFSET NETXEN_NIC_REG(0x1c)
-#define NX_ARG2_CRB_OFFSET NETXEN_NIC_REG(0x20)
-#define NX_ARG3_CRB_OFFSET NETXEN_NIC_REG(0x24)
-#define NX_SIGN_CRB_OFFSET NETXEN_NIC_REG(0x28)
-#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20)
-#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24)
-#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28)
-#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c)
-#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30)
-#define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34)
-#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38)
-#define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c)
-#define CRB_HOST_DUMMY_BUF_ADDR_LO NETXEN_NIC_REG(0x40)
-#define CRB_MMAP_ADDR_0 NETXEN_NIC_REG(0x44)
-#define CRB_MMAP_ADDR_1 NETXEN_NIC_REG(0x48)
-#define CRB_MMAP_ADDR_2 NETXEN_NIC_REG(0x4c)
-#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50)
-#define CRB_MMAP_SIZE_0 NETXEN_NIC_REG(0x54)
-#define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58)
-#define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c)
-#define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60)
-#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64)
-#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68)
-#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c)
-#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70)
-#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x74)
-#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x78)
-#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x7c)
-#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x80)
-#define CRB_RX_LRO_TIMER NETXEN_NIC_REG(0x84)
-#define CRB_RX_LRO_MID_TIMER NETXEN_NIC_REG(0x88)
-#define CRB_DMA_MAX_RCV_BUFS NETXEN_NIC_REG(0x8c)
-#define CRB_MAX_DMA_ENTRIES NETXEN_NIC_REG(0x90)
-#define CRB_XG_STATE NETXEN_NIC_REG(0x94) /* XG Link status */
-#define CRB_XG_STATE_P3 NETXEN_NIC_REG(0x98) /* XG PF Link status */
-#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0x9c)
-#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0)
-#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4)
-#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8)
-#define CRB_TX_STATE NETXEN_NIC_REG(0xac)
-#define CRB_TX_COUNT NETXEN_NIC_REG(0xb0)
-#define CRB_RX_STATE NETXEN_NIC_REG(0xb4)
-#define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8)
-#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc)
-#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
-#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4)
-#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
-#define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc)
-#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
-#define CRB_CTX_RESET NETXEN_NIC_REG(0xd8)
-#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc)
-#define CRB_HOST_STS_CONS NETXEN_NIC_REG(0xe0)
-#define CRB_PEG_CMD_PROD NETXEN_NIC_REG(0xe4)
-#define CRB_PF_LINK_SPEED_1 NETXEN_NIC_REG(0xe8)
-#define CRB_PF_LINK_SPEED_2 NETXEN_NIC_REG(0xec)
-#define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0)
-#define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4)
-#define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8)
-#define CRB_HOST_DUMMY_BUF NETXEN_NIC_REG(0xfc)
-
-#define CRB_RCVPEG_STATE NETXEN_NIC_REG(0x13c)
-#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac)
-#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0)
-#define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8)
-#define CRB_CMD_CONSUMER_OFFSET_2 NETXEN_NIC_REG(0x1bc)
-#define CRB_CMD_PRODUCER_OFFSET_3 NETXEN_NIC_REG(0x1d0)
-#define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4)
-#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4)
-
-#define CRB_V2P_0 NETXEN_NIC_REG(0x290)
-#define CRB_V2P_1 NETXEN_NIC_REG(0x294)
-#define CRB_V2P_2 NETXEN_NIC_REG(0x298)
-#define CRB_V2P_3 NETXEN_NIC_REG(0x29c)
-#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
-#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
-#define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8)
-#define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0)
-#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
-#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
-
-#define CRB_FW_CAPABILITIES_1 NETXEN_CAM_RAM(0x128)
-#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0)
-
-/*
- * capabilities register, can be used to selectively enable/disable features
- * for backward compability
- */
-#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
-#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
-#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270)
-#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
-
-#define INTR_SCHEME_PERPORT 0x1
-#define MSI_MODE_MULTIFUNC 0x1
-
-/* used for ethtool tests */
-#define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280)
-
-/*
- * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
- * which can be read by the Phantom host to get producer/consumer indexes from
- * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
- * registers will be used for the addresses of the ring's shared memory
- * on the Phantom.
- */
-
-#define nx_get_temp_val(x) ((x) >> 16)
-#define nx_get_temp_state(x) ((x) & 0xffff)
-#define nx_encode_temp(val, state) (((val) << 16) | (state))
-
-/*
- * CRB registers used by the receive peg logic.
- */
-
-struct netxen_recv_crb {
- u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
- u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
- u32 sw_int_mask[NUM_STS_DESC_RINGS];
-};
-
-/*
- * Temperature control.
- */
-enum {
- NX_TEMP_NORMAL = 0x1, /* Normal operating range */
- NX_TEMP_WARN, /* Sound alert, temperature getting high */
- NX_TEMP_PANIC /* Fatal error, hardware has shut down. */
-};
-
-#endif /* __NIC_PHAN_REG_H_ */