diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 465 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 80 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 109 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 95 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 279 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 125 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 357 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 802 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 550 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_phan_reg.h | 178 |
11 files changed, 1388 insertions, 1654 deletions
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile index cf01a9130c9..a70b682f616 100644 --- a/drivers/net/netxen/Makefile +++ b/drivers/net/netxen/Makefile @@ -31,4 +31,4 @@ 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..449d3511628 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,12 +53,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 41 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.41" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -143,18 +144,13 @@ #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 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 @@ -200,13 +196,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,8 +228,6 @@ #define MPORT_SINGLE_FUNCTION_MODE 0x1111 #define MPORT_MULTI_FUNCTION_MODE 0x2222 -#include "netxen_nic_phan_reg.h" - /* * NetXen host-peg signal message structure * @@ -302,6 +303,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 +321,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 */ + + __le64 addr_buffer2; - __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; + __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; + __le16 vlan_TCI; + __le16 reserved; + __le32 reserved2; } __attribute__ ((aligned(64))); @@ -380,9 +360,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 +398,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 +459,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 +469,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 +502,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 @@ -726,7 +569,8 @@ struct netxen_adapter_stats { u64 rxdropped; u64 txdropped; u64 csummed; - u64 no_rcv; + u64 rx_pkts; + u64 lro_pkts; u64 rxbytes; u64 txbytes; }; @@ -840,7 +684,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 +737,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 +935,9 @@ typedef struct { #define NX_MAC_EVENT 0x1 +#define NX_IP_UP 2 +#define NX_IP_DOWN 3 + /* * Driver --> Firmware */ @@ -1104,7 +964,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 +992,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 +1085,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)) @@ -1281,14 +1162,12 @@ struct netxen_adapter { 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 *); @@ -1315,37 +1194,16 @@ struct netxen_adapter { nx_nic_intr_coalesce_t coal; - u32 fw_major; + 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); @@ -1359,6 +1217,30 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); #define NXWR32(adapter, off, val) \ (adapter->hw_write_wx(adapter, off, 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); @@ -1398,8 +1280,9 @@ 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); @@ -1440,14 +1323,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 +1343,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 +1396,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(); diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 9f8ae4719e2..0f42ab99836 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -30,45 +30,9 @@ #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) { @@ -416,6 +380,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,7 +649,7 @@ 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]; } @@ -675,7 +677,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) } - if (adapter->fw_major >= 4) { + if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; @@ -705,7 +707,7 @@ 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)) { nx_fw_cmd_destroy_rx_ctx(adapter); nx_fw_cmd_destroy_tx_ctx(adapter); } else { diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index e16ea46c24b..3886135006e 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -37,7 +37,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 +56,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)}, }; @@ -490,28 +490,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,6 +941,28 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } +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; +} + struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, @@ -893,6 +973,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 +990,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..92f5970c9aa 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -723,9 +723,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 +899,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,7 +943,7 @@ 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 ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index b9123d445c9..db510cee809 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -30,7 +30,6 @@ #include "netxen_nic.h" #include "netxen_nic_hw.h" -#include "netxen_nic_phan_reg.h" #include <net/ip.h> @@ -87,7 +86,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 +319,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 +386,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) { @@ -643,7 +749,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 +765,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 +872,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 +918,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 +1005,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,33 +1044,6 @@ 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. */ @@ -1833,13 +2016,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 +2032,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; @@ -1998,30 +2178,28 @@ 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 i, offset, 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); + offset = NX_FW_SERIAL_NUM_OFFSET; for (i = 0; i < 8; i++) { - if (netxen_rom_fast_read(adapter, addr, &val) == -1) { + 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); - addr += sizeof(u32); + 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_major = fw_major; adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build); if (adapter->portnum == 0) { @@ -2047,6 +2225,11 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) dev_info(&pdev->dev, "firmware running in %s mode\n", 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; } int diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index d4e83333978..98e4b95788b 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -31,8 +31,6 @@ #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 +61,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 +73,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 +234,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 +243,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 +263,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 +278,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..8d4aa6f74bf 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -32,7 +32,6 @@ #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 +246,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; @@ -267,8 +271,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) 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; } @@ -317,43 +321,24 @@ err_out: 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; + adapter->init_port = netxen_niu_xg_init_port; + adapter->stop_port = netxen_niu_disable_xg_port; - case NETXEN_NIC_XGBE: - adapter->enable_phy_interrupts = - netxen_niu_xgbe_enable_phy_interrupts; - adapter->disable_phy_interrupts = - netxen_niu_xgbe_disable_phy_interrupts; + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + 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->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_promisc = netxen_p2_nic_set_promisc; + } else { 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; + + if (adapter->ahw.port_type == NETXEN_NIC_GBE) { + adapter->phy_read = nx_fw_cmd_query_phy; + adapter->phy_write = nx_fw_cmd_set_phy; + } } } @@ -384,37 +369,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 +381,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 +435,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 +449,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 +470,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); @@ -880,22 +829,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 +840,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; +} + +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 = NX_FLASH_ROMIMAGE; - adapter->fw = NULL; - goto done; + 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 +880,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; @@ -953,19 +903,20 @@ netxen_release_firmware(struct netxen_adapter *adapter) release_firmware(adapter->fw); } -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 +927,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 +970,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 +1044,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 +1179,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; @@ -1253,7 +1221,84 @@ netxen_process_rcv(struct netxen_adapter *adapter, 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) + + ((unsigned long)skb->data - (unsigned long)skb->head)); + + 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 +1320,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 +1356,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]); @@ -1468,7 +1511,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, NXWR32(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 diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 28f270f5ac7..f824a392bf5 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -33,12 +33,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,14 +63,19 @@ 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_reset_task(struct work_struct *work); static void netxen_watchdog(unsigned long); 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 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); @@ -94,8 +99,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 @@ -179,7 +182,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,12 +311,16 @@ err_out: return err; } -static void netxen_check_options(struct netxen_adapter *adapter) +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; + 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)) { @@ -331,11 +338,15 @@ static void netxen_check_options(struct netxen_adapter *adapter) } } - adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST; - adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS; - adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS; + adapter->num_txd = MAX_CMD_DESCRIPTORS; - return; + 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 @@ -745,8 +756,10 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) netxen_request_firmware(adapter); err = netxen_need_fw_reset(adapter); - if (err <= 0) + if (err < 0) return err; + if (err == 0) + goto wait_init; if (first_boot != 0x55555555) { NXWR32(adapter, CRB_CMDPEG_STATE, 0); @@ -770,7 +783,7 @@ 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; @@ -786,10 +799,14 @@ 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); + netxen_free_dummy_dma(adapter); return err; } + nx_update_dma_mask(adapter); + + netxen_nic_get_firmware_info(adapter); + return 0; } @@ -840,6 +857,20 @@ 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) { @@ -862,6 +893,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) @@ -887,6 +924,8 @@ 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); @@ -905,6 +944,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 +955,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", @@ -934,7 +971,7 @@ 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]; @@ -958,6 +995,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 +1014,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 +1028,98 @@ 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 (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { + + if (netif_running(netdev)) + netxen_nic_down(adapter, netdev); + + netxen_nic_detach(adapter); + + err = netxen_nic_attach(adapter); + if (err) + goto done; + + if (netif_running(netdev)) + err = netxen_nic_up(adapter, netdev); + } +done: + 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; + + err = netxen_napi_add(adapter, netdev); + if (err) + return err; + + 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_reset_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 +1157,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; } @@ -1048,38 +1186,10 @@ 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; } @@ -1100,15 +1210,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 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; @@ -1118,28 +1224,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 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); @@ -1159,7 +1246,7 @@ 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); err_out_iounmap: netxen_cleanup_pci_map(adapter); @@ -1192,12 +1279,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) 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_adapter_offload(adapter); + netxen_free_dummy_dma(adapter); netxen_teardown_intr(adapter); @@ -1211,14 +1296,11 @@ 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); @@ -1228,10 +1310,14 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) 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); - pci_save_state(pdev); + retval = pci_save_state(pdev); + if (retval) + return retval; if (netxen_nic_wol_supported(adapter)) { pci_enable_wake(pdev, PCI_D3cold, 1); @@ -1239,10 +1325,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) @@ -1290,11 +1393,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 +1421,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 +1487,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]; + 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 +1626,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); + tx_ring->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 = 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; @@ -1687,10 +1827,12 @@ void netxen_watchdog_task(struct work_struct *work) 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); } -static void netxen_tx_timeout_task(struct work_struct *work) +static void netxen_reset_task(struct work_struct *work) { struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, tx_timeout_task); @@ -1698,9 +1840,6 @@ 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); - netxen_napi_disable(adapter); adapter->netdev->trans_start = jiffies; @@ -1716,7 +1855,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; @@ -1758,7 +1897,7 @@ static irqreturn_t netxen_intr(int irq, void *data) } /* clear interrupt */ - if (adapter->fw_major < 4) + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) netxen_nic_disable_int(sds_ring); adapter->pci_write_immediate(adapter, @@ -1827,6 +1966,202 @@ static void netxen_nic_poll_controller(struct net_device *netdev) } #endif +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); +} + +static void netxen_watchdog(unsigned long); + +#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 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; + struct in_device *indev; + +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 || !netxen_destip_supported(adapter)) + goto done; + + if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) + goto done; + + indev = in_dev_get(dev); + if (!indev) + goto done; + + 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); +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, +}; +#endif + static struct pci_driver netxen_driver = { .name = netxen_nic_driver_name, .id_table = netxen_pci_tbl, @@ -1834,16 +2169,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 +2191,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_ */ |