From 3d396eb17e9f8c5f59314078b45b88647591378d Mon Sep 17 00:00:00 2001 From: "Amit S. Kale" Date: Sat, 21 Oct 2006 15:33:03 -0400 Subject: Add NetXen 1G/10G ethernet driver. Signed-off-by: Amit S. Kale Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 910 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 910 insertions(+) create mode 100644 drivers/net/netxen/netxen_nic.h (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h new file mode 100644 index 00000000000..c7d76c14f7b --- /dev/null +++ b/drivers/net/netxen/netxen_nic.h @@ -0,0 +1,910 @@ +/* + * Copyright (C) 2003 - 2006 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, + * 3965 Freedom Circle, Fourth floor, + * Santa Clara, CA 95054 + */ + +#ifndef _NETXEN_NIC_H_ +#define _NETXEN_NIC_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "netxen_nic_hw.h" + +#define NETXEN_NIC_BUILD_NO "232" +#define _NETXEN_NIC_LINUX_MAJOR 2 +#define _NETXEN_NIC_LINUX_MINOR 3 +#define _NETXEN_NIC_LINUX_SUBVERSION 57 +#define NETXEN_NIC_LINUX_VERSIONID "2.3.57" +#define NETXEN_NIC_FW_VERSIONID "2.3.57" + +#define RCV_DESC_RINGSIZE \ + (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) +#define STATUS_DESC_RINGSIZE \ + (sizeof(struct status_desc)* adapter->max_rx_desc_count) +#define TX_RINGSIZE \ + (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) +#define RCV_BUFFSIZE \ + (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) +#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) + +#define NETXEN_NETDEV_STATUS 0x1 + +#define ADDR_IN_WINDOW1(off) \ + ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 + +/* + * normalize a 64MB crb address to 32MB PCI window + * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 + */ +#define NETXEN_CRB_NORMALIZE(adapter, reg) \ + ((adapter)->ahw.pci_base + (reg) \ + - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST) + +#define MAX_RX_BUFFER_LENGTH 2000 +#define MAX_RX_JUMBO_BUFFER_LENGTH 9046 +#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN) +#define RX_JUMBO_DMA_MAP_LEN \ + (MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN) +#define NETXEN_ROM_ROUNDUP 0x80000000ULL + +/* + * Maximum number of ring contexts + */ +#define MAX_RING_CTX 1 + +/* Opcodes to be used with the commands */ +enum { + TX_ETHER_PKT = 0x01, +/* The following opcodes are for IP checksum */ + TX_TCP_PKT, + TX_UDP_PKT, + TX_IP_PKT, + TX_TCP_LSO, + TX_IPSEC, + TX_IPSEC_CMD +}; + +/* The following opcodes are for internal consumption. */ +#define NETXEN_CONTROL_OP 0x10 +#define PEGNET_REQUEST 0x11 + +#define MAX_NUM_CARDS 4 + +#define MAX_BUFFERS_PER_CMD 32 + +/* + * Following are the states of the Phantom. Phantom will set them and + * Host will read to check if the fields are correct. + */ +#define PHAN_INITIALIZE_START 0xff00 +#define PHAN_INITIALIZE_FAILED 0xffff +#define PHAN_INITIALIZE_COMPLETE 0xff01 + +/* Host writes the following to notify that it has done the init-handshake */ +#define PHAN_INITIALIZE_ACK 0xf00f + +#define NUM_RCV_DESC_RINGS 2 /* No of Rcv Descriptor contexts */ + +/* descriptor types */ +#define RCV_DESC_NORMAL 0x01 +#define RCV_DESC_JUMBO 0x02 +#define RCV_DESC_NORMAL_CTXID 0 +#define RCV_DESC_JUMBO_CTXID 1 + +#define RCV_DESC_TYPE(ID) \ + ((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL) + +#define MAX_CMD_DESCRIPTORS 1024 +#define MAX_RCV_DESCRIPTORS 32768 +#define MAX_JUMBO_RCV_DESCRIPTORS 1024 +#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS +#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS +#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS +#define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS +#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS) +#define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8) + +#define MIN_TX_COUNT 4096 +#define MIN_RX_COUNT 4096 + +#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */ + +#define PHAN_PEG_RCV_INITIALIZED 0xff01 +#define PHAN_PEG_RCV_START_INITIALIZE 0xff00 + +#define get_next_index(index, length) \ + (((index) + 1) & ((length) - 1)) + +#define get_index_range(index,length,count) \ + (((index) + (count)) & ((length) - 1)) + +/* + * Following data structures describe the descriptors that will be used. + * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when + * we are doing LSO (above the 1500 size packet) only. + */ + +/* + * The size of reference handle been changed to 16 bits to pass the MSS fields + * for the LSO packet + */ + +#define FLAGS_CHECKSUM_ENABLED 0x01 +#define FLAGS_LSO_ENABLED 0x02 +#define FLAGS_IPSEC_SA_ADD 0x04 +#define FLAGS_IPSEC_SA_DELETE 0x08 +#define FLAGS_VLAN_TAGGED 0x10 + +#define CMD_DESC_TOTAL_LENGTH(cmd_desc) \ + ((cmd_desc)->length_tcp_hdr & 0x00FFFFFF) +#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc) \ + (((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF) +#define CMD_DESC_PORT(cmd_desc) ((cmd_desc)->port_ctxid & 0x0F) +#define CMD_DESC_CTX_ID(cmd_desc) (((cmd_desc)->port_ctxid >> 4) & 0x0F) + +#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var) \ + ((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF)) +#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var) \ + ((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000)) +#define CMD_DESC_PORT_WRT(cmd_desc, var) \ + ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) + +struct cmd_desc_type0 { + u64 netxen_next; /* for fragments handled by Phantom */ + union { + struct { + u32 addr_low_part2; + u32 addr_high_part2; + }; + u64 addr_buffer2; + }; + + /* Bit pattern: 0-23 total length, 24-32 tcp header offset */ + u32 length_tcp_hdr; + u8 ip_hdr_offset; /* For LSO only */ + u8 num_of_buffers; /* total number of segments */ + u8 flags; /* as defined above */ + u8 opcode; + + u16 reference_handle; /* changed to u16 to add mss */ + u16 mss; /* passed by NDIS_PACKET for LSO */ + /* Bit pattern 0-3 port, 0-3 ctx id */ + u8 port_ctxid; + u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */ + u16 conn_id; /* IPSec offoad only */ + + union { + struct { + u32 addr_low_part3; + u32 addr_high_part3; + }; + u64 addr_buffer3; + }; + + union { + struct { + u32 addr_low_part1; + u32 addr_high_part1; + }; + u64 addr_buffer1; + }; + + u16 buffer1_length; + u16 buffer2_length; + u16 buffer3_length; + u16 buffer4_length; + + union { + struct { + u32 addr_low_part4; + u32 addr_high_part4; + }; + u64 addr_buffer4; + }; + +} __attribute__ ((aligned(64))); + +/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */ +struct rcv_desc { + u16 reference_handle; + u16 reserved; + u32 buffer_length; /* allocated buffer length (usually 2K) */ + u64 addr_buffer; +}; + +/* opcode field in status_desc */ +#define RCV_NIC_PKT (0xA) +#define STATUS_NIC_PKT ((RCV_NIC_PKT) << 12) + +/* for status field in status_desc */ +#define STATUS_NEED_CKSUM (1) +#define STATUS_CKSUM_OK (2) + +/* owner bits of status_desc */ +#define STATUS_OWNER_HOST (0x1) +#define STATUS_OWNER_PHANTOM (0x2) + +#define NETXEN_PROT_IP (1) +#define NETXEN_PROT_UNKNOWN (0) + +/* Note: sizeof(status_desc) should always be a mutliple of 2 */ +#define STATUS_DESC_PORT(status_desc) \ + ((status_desc)->port_status_type_op & 0x0F) +#define STATUS_DESC_STATUS(status_desc) \ + (((status_desc)->port_status_type_op >> 4) & 0x0F) +#define STATUS_DESC_TYPE(status_desc) \ + (((status_desc)->port_status_type_op >> 8) & 0x0F) +#define STATUS_DESC_OPCODE(status_desc) \ + (((status_desc)->port_status_type_op >> 12) & 0x0F) + +struct status_desc { + /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */ + u16 port_status_type_op; + u16 total_length; /* NIC mode */ + u16 reference_handle; /* handle for the associated packet */ + /* Bit pattern: 0-1 owner, 2-5 protocol */ + u16 owner; /* Owner of the descriptor */ +} __attribute__ ((aligned(8))); + +enum { + NETXEN_RCV_PEG_0 = 0, + NETXEN_RCV_PEG_1 +}; +/* The version of the main data structure */ +#define NETXEN_BDINFO_VERSION 1 + +/* Magic number to let user know flash is programmed */ +#define NETXEN_BDINFO_MAGIC 0x12345678 + +/* Max number of Gig ports on a Phantom board */ +#define NETXEN_MAX_PORTS 4 + +typedef enum { + NETXEN_BRDTYPE_P1_BD = 0x0000, + NETXEN_BRDTYPE_P1_SB = 0x0001, + NETXEN_BRDTYPE_P1_SMAX = 0x0002, + NETXEN_BRDTYPE_P1_SOCK = 0x0003, + + NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008, + NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009, + NETXEN_BRDTYPE_P2_SB35_4G = 0x000a, + NETXEN_BRDTYPE_P2_SB31_10G = 0x000b, + NETXEN_BRDTYPE_P2_SB31_2G = 0x000c, + + NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d, + NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, + NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f +} netxen_brdtype_t; + +typedef enum { + NETXEN_BRDMFG_INVENTEC = 1 +} netxen_brdmfg; + +typedef enum { + MEM_ORG_128Mbx4 = 0x0, /* DDR1 only */ + MEM_ORG_128Mbx8 = 0x1, /* DDR1 only */ + MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */ + MEM_ORG_256Mbx4 = 0x3, + MEM_ORG_256Mbx8 = 0x4, + MEM_ORG_256Mbx16 = 0x5, + MEM_ORG_512Mbx4 = 0x6, + MEM_ORG_512Mbx8 = 0x7, + MEM_ORG_512Mbx16 = 0x8, + MEM_ORG_1Gbx4 = 0x9, + MEM_ORG_1Gbx8 = 0xa, + MEM_ORG_1Gbx16 = 0xb, + MEM_ORG_2Gbx4 = 0xc, + MEM_ORG_2Gbx8 = 0xd, + MEM_ORG_2Gbx16 = 0xe, + MEM_ORG_128Mbx32 = 0x10002, /* GDDR only */ + MEM_ORG_256Mbx32 = 0x10005 /* GDDR only */ +} netxen_mn_mem_org_t; + +typedef enum { + MEM_ORG_512Kx36 = 0x0, + MEM_ORG_1Mx36 = 0x1, + MEM_ORG_2Mx36 = 0x2 +} netxen_sn_mem_org_t; + +typedef enum { + MEM_DEPTH_4MB = 0x1, + MEM_DEPTH_8MB = 0x2, + MEM_DEPTH_16MB = 0x3, + MEM_DEPTH_32MB = 0x4, + MEM_DEPTH_64MB = 0x5, + MEM_DEPTH_128MB = 0x6, + MEM_DEPTH_256MB = 0x7, + MEM_DEPTH_512MB = 0x8, + MEM_DEPTH_1GB = 0x9, + MEM_DEPTH_2GB = 0xa, + MEM_DEPTH_4GB = 0xb, + MEM_DEPTH_8GB = 0xc, + MEM_DEPTH_16GB = 0xd, + MEM_DEPTH_32GB = 0xe +} netxen_mem_depth_t; + +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 */ +typedef enum { + CRBINIT_START = 0, /* Crbinit section */ + BRDCFG_START = 0x4000, /* board config */ + INITCODE_START = 0x6000, /* pegtune code */ + BOOTLD_START = 0x10000, /* bootld */ + IMAGE_START = 0x43000, /* compressed image */ + SECONDARY_START = 0x200000, /* backup images */ + PXE_START = 0x3E0000, /* user defined region */ + USER_START = 0x3E8000, /* User defined region for new boards */ + FIXED_START = 0x3F0000 /* backup of crbinit */ +} netxen_flash_map_t; + +#define USER_START_OLD PXE_START /* for backward compatibility */ + +#define FLASH_START (CRBINIT_START) +#define INIT_SECTOR (0) +#define PRIMARY_START (BOOTLD_START) +#define FLASH_CRBINIT_SIZE (0x4000) +#define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info)) +#define FLASH_USER_SIZE (sizeof(netxen_user_info)/sizeof(u32)) +#define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START) +#define NUM_PRIMARY_SECTORS (0x20) +#define NUM_CONFIG_SECTORS (1) +#define PFX "netxen: " + +/* Note: Make sure to not call this before adapter->port is valid */ +#if !defined(NETXEN_DEBUG) +#define DPRINTK(klevel, fmt, args...) do { \ + } while (0) +#else +#define DPRINTK(klevel, fmt, args...) do { \ + printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\ + (adapter != NULL && adapter->port != NULL && \ + adapter->port[0] != NULL && \ + adapter->port[0]->netdev != NULL) ? \ + adapter->port[0]->netdev->name : NULL, \ + ## args); } while(0) +#endif + +/* Number of status descriptors to handle per interrupt */ +#define MAX_STATUS_HANDLE (128) + +/* + * netxen_skb_frag{} is to contain mapping info for each SG list. This + * has to be freed when DMA is complete. This is part of netxen_tx_buffer{}. + */ +struct netxen_skb_frag { + u64 dma; + u32 length; +}; + +/* Following defines are for the state of the buffers */ +#define NETXEN_BUFFER_FREE 0 +#define NETXEN_BUFFER_BUSY 1 + +/* + * There will be one netxen_buffer per skb packet. These will be + * used to save the dma info for pci_unmap_page() + */ +struct netxen_cmd_buffer { + struct sk_buff *skb; + struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; + u32 total_length; + u32 mss; + u16 port; + u8 cmd; + u8 frag_count; + unsigned long time_stamp; + u32 state; + u32 no_of_descriptors; +}; + +/* In rx_buffer, we do not need multiple fragments as is a single buffer */ +struct netxen_rx_buffer { + struct sk_buff *skb; + u64 dma; + u16 ref_handle; + u16 state; +}; + +/* Board types */ +#define NETXEN_NIC_GBE 0x01 +#define NETXEN_NIC_XGBE 0x02 + +/* + * One hardware_context{} per adapter + * contains interrupt info as well shared hardware info. + */ +struct netxen_hardware_context { + struct pci_dev *pdev; + void __iomem *pci_base; /* base of mapped phantom memory */ + u8 revision_id; + u16 board_type; + u16 max_ports; + struct netxen_board_info boardcfg; + u32 xg_linkup; + /* Address of cmd ring in Phantom */ + struct cmd_desc_type0 *cmd_desc_head; + dma_addr_t cmd_desc_phys_addr; + struct netxen_adapter *adapter; +}; + +#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ +#define ETHERNET_FCS_SIZE 4 + +struct netxen_adapter_stats { + u64 ints; + u64 hostints; + u64 otherints; + u64 process_rcv; + u64 process_xmit; + u64 noxmitdone; + u64 xmitcsummed; + u64 post_called; + u64 posted; + u64 lastposted; + u64 goodskbposts; +}; + +/* + * Rcv Descriptor Context. One such per Rcv Descriptor. There may + * be one Rcv Descriptor for normal packets, one for jumbo and may be others. + */ +struct netxen_rcv_desc_ctx { + u32 flags; + u32 producer; + u32 rcv_pending; /* Num of bufs posted in phantom */ + u32 rcv_free; /* Num of bufs in free list */ + dma_addr_t phys_addr; + struct rcv_desc *desc_head; /* address of rx ring in Phantom */ + u32 max_rx_desc_count; + u32 dma_size; + u32 skb_size; + struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ + int begin_alloc; +}; + +/* + * Receive context. There is one such structure per instance of the + * receive processing. Any state information that is relevant to + * the receive, and is must be in this structure. The global data may be + * present elsewhere. + */ +struct netxen_recv_context { + struct netxen_rcv_desc_ctx rcv_desc[NUM_RCV_DESC_RINGS]; + u32 status_rx_producer; + u32 status_rx_consumer; + dma_addr_t rcv_status_desc_phys_addr; + struct status_desc *rcv_status_desc_head; +}; + +#define NETXEN_NIC_MSI_ENABLED 0x02 + +struct netxen_drvops; + +struct netxen_adapter { + struct netxen_hardware_context ahw; + int port_count; /* Number of configured ports */ + int active_ports; /* Number of open ports */ + struct netxen_port *port[NETXEN_MAX_PORTS]; /* ptr to each port */ + spinlock_t tx_lock; + spinlock_t lock; + struct work_struct watchdog_task; + struct work_struct tx_timeout_task; + struct timer_list watchdog_timer; + + u32 curr_window; + + u32 cmd_producer; + u32 cmd_consumer; + + u32 last_cmd_consumer; + u32 max_tx_desc_count; + u32 max_rx_desc_count; + u32 max_jumbo_rx_desc_count; + /* Num of instances active on cmd buffer ring */ + u32 proc_cmd_buf_counter; + + u32 num_threads, total_threads; /*Use to keep track of xmit threads */ + + u32 flags; + u32 irq; + int driver_mismatch; + + struct netxen_adapter_stats stats; + + struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ + + /* + * Receive instances. These can be either one per port, + * or one per peg, etc. + */ + struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; + + int is_up; + int work_done; + struct netxen_drvops *ops; +}; /* netxen_adapter structure */ + +/* Max number of xmit producer threads that can run simultaneously */ +#define MAX_XMIT_PRODUCERS 16 + +struct netxen_port_stats { + u64 rcvdbadskb; + u64 xmitcalled; + u64 xmitedframes; + u64 xmitfinished; + u64 badskblen; + u64 nocmddescriptor; + u64 polled; + u64 uphappy; + u64 updropped; + u64 uplcong; + u64 uphcong; + u64 upmcong; + u64 updunno; + u64 skbfreed; + u64 txdropped; + u64 txnullskb; + u64 csummed; + u64 no_rcv; + u64 rxbytes; + u64 txbytes; +}; + +struct netxen_port { + struct netxen_adapter *adapter; + + u16 portnum; /* GBE port number */ + u16 link_speed; + u16 link_duplex; + u16 link_autoneg; + + int flags; + + struct net_device *netdev; + struct pci_dev *pdev; + struct net_device_stats net_stats; + struct netxen_port_stats stats; +}; + +struct netxen_drvops { + int (*enable_phy_interrupts) (struct netxen_adapter *, int); + int (*disable_phy_interrupts) (struct netxen_adapter *, int); + void (*handle_phy_intr) (struct netxen_adapter *); + int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); + int (*set_mtu) (struct netxen_port *, int); + int (*set_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*unset_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *); + int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val); + int (*init_port) (struct netxen_adapter *, int); + void (*init_niu) (struct netxen_adapter *); + int (*stop_port) (struct netxen_adapter *, int); +}; + +extern char netxen_nic_driver_name[]; + +int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, + int port); +int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, + int port); +int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter, + int port); +int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter, + int port); +int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter, + int port); +int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter, + int port); +void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter); +void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter); +void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, + long enable); +void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, + long enable); +int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg, + __le32 * readval); +int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, + long reg, __le32 val); + +/* Functions available from netxen_nic_hw.c */ +int netxen_niu_xginit(struct netxen_adapter *); +int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu); +int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu); +void netxen_nic_init_niu_gb(struct netxen_adapter *adapter); +void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw); +void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); +int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); +void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); +void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value); + +int netxen_nic_get_board_info(struct netxen_adapter *adapter); +int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, + int len); +int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, + int len); +void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, + unsigned long off, int data); + +/* Functions from netxen_nic_init.c */ +void netxen_phantom_init(struct netxen_adapter *adapter); +void netxen_load_firmware(struct netxen_adapter *adapter); +int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); +int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); + +/* Functions from netxen_nic_isr.c */ +void netxen_nic_isr_other(struct netxen_adapter *adapter); +void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 port, + u32 link); +void netxen_handle_port_int(struct netxen_adapter *adapter, u32 port, + u32 enable); +void netxen_nic_stop_all_ports(struct netxen_adapter *adapter); +void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); +void netxen_initialize_adapter_hw(struct netxen_adapter *adapter); +void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); +int netxen_init_firmware(struct netxen_adapter *adapter); +void netxen_free_hw_resources(struct netxen_adapter *adapter); +void netxen_tso_check(struct netxen_adapter *adapter, + struct cmd_desc_type0 *desc, struct sk_buff *skb); +int netxen_nic_hw_resources(struct netxen_adapter *adapter); +void netxen_nic_clear_stats(struct netxen_adapter *adapter); +int +netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, + struct netxen_port *port); +int netxen_nic_rx_has_work(struct netxen_adapter *adapter); +int netxen_nic_tx_has_work(struct netxen_adapter *adapter); +void netxen_watchdog_task(unsigned long v); +void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, + u32 ringid); +void netxen_process_cmd_ring(unsigned long data); +u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); +void netxen_nic_set_multi(struct net_device *netdev); +int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); +int netxen_nic_set_mac(struct net_device *netdev, void *p); +struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); + +static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) +{ + /* + * ISR_INT_MASK: Can be read from window 0 or 1. + */ + writel(0x7ff, (void __iomem *)(adapter->ahw.pci_base + ISR_INT_MASK)); +} + +static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) +{ + u32 mask; + + switch (adapter->ahw.board_type) { + case NETXEN_NIC_GBE: + mask = 0x77b; + break; + case NETXEN_NIC_XGBE: + mask = 0x77f; + break; + default: + mask = 0x7ff; + break; + } + + writel(mask, (void __iomem *)(adapter->ahw.pci_base + ISR_INT_MASK)); + + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + mask = 0xbff; + writel(mask, (void __iomem *) + (adapter->ahw.pci_base + ISR_INT_TARGET_MASK)); + } +} + +int netxen_is_flash_supported(struct netxen_adapter *adapter); +int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); + +extern void netxen_change_ringparam(struct netxen_adapter *adapter); +extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, + int *valp); + +extern struct ethtool_ops netxen_nic_ethtool_ops; + +#endif /* __NETXEN_NIC_H_ */ -- cgit v1.2.3-70-g09d2 From 1494a81410d8c53fa6c800be1e22b6b6f64180e6 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 7 Nov 2006 05:12:16 -0500 Subject: [netdrvr] netxen: build fixes Most contributed and Signed-off-by: Andrew Morton with some from me as well. Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 1 - drivers/net/netxen/netxen_nic_hdr.h | 1 - drivers/net/netxen/netxen_nic_hw.c | 2 +- drivers/net/netxen/netxen_nic_main.c | 9 ++++++--- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index c7d76c14f7b..0458db45e70 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -30,7 +30,6 @@ #ifndef _NETXEN_NIC_H_ #define _NETXEN_NIC_H_ -#include #include #include #include diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 965cf625ba4..83bf28b372a 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c7d97054d05..9603c635b05 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -351,7 +351,7 @@ void netxen_tso_check(struct netxen_adapter *adapter, ((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)); desc->opcode = TX_TCP_LSO; - } else if (skb->ip_summed == CHECKSUM_HW) { + } else if (skb->ip_summed == CHECKSUM_COMPLETE) { if (skb->nh.iph->protocol == IPPROTO_TCP) { desc->opcode = TX_TCP_PKT; } else if (skb->nh.iph->protocol == IPPROTO_UDP) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index b54ea164e0e..145bf47f0a8 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -38,6 +38,9 @@ #include "netxen_nic_phan_reg.h" #include "netxen_nic_ioctl.h" +#include +#include + MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); @@ -66,7 +69,7 @@ static int netxen_nic_poll(struct net_device *dev, int *budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void netxen_nic_poll_controller(struct net_device *netdev); #endif -static irqreturn_t netxen_intr(int irq, void *data, struct pt_regs *regs); +static irqreturn_t netxen_intr(int irq, void *data); /* PCI Device ID Table */ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { @@ -969,7 +972,7 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) * @irq: interrupt number * data points to adapter stucture (which may be handling more than 1 port */ -irqreturn_t netxen_intr(int irq, void *data, struct pt_regs * regs) +irqreturn_t netxen_intr(int irq, void *data) { struct netxen_adapter *adapter; struct netxen_port *port; @@ -1049,7 +1052,7 @@ static void netxen_nic_poll_controller(struct net_device *netdev) struct netxen_port *port = netdev_priv(netdev); struct netxen_adapter *adapter = port->adapter; disable_irq(adapter->irq); - netxen_intr(adapter->irq, adapter, NULL); + netxen_intr(adapter->irq, adapter); enable_irq(adapter->irq); } #endif -- cgit v1.2.3-70-g09d2 From cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6 Mon Sep 17 00:00:00 2001 From: "Amit S. Kale" Date: Wed, 29 Nov 2006 09:00:10 -0800 Subject: [PATCH] NetXen: temp monitoring, newer firmware support, mm footprint reduction NetXen: 1G/10G Ethernet Driver updates - Temparature monitoring and device control - Memory footprint reduction - Driver changes to support newer version of firmware Signed-off-by: Amit S. Kale netxen_nic.h | 165 ++++++++++++++++++++++++++++++++-- netxen_nic_ethtool.c | 89 ++++++++++++------ netxen_nic_hdr.h | 71 +++++++++++++- netxen_nic_hw.c | 206 +++++++++++++++++++++++++++++-------------- netxen_nic_hw.h | 8 + netxen_nic_init.c | 239 +++++++++++++++++++++++++++++++++++++++++--------- netxen_nic_ioctl.h | 12 +- netxen_nic_isr.c | 54 +++++------ netxen_nic_main.c | 121 +++++++++++++++++-------- netxen_nic_niu.c | 172 +++++++++++++++++++++++++++-------- netxen_nic_phan_reg.h | 24 ++++- 11 files changed, 891 insertions(+), 270 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 165 +++++++++++++++++++-- drivers/net/netxen/netxen_nic_ethtool.c | 89 ++++++++---- drivers/net/netxen/netxen_nic_hdr.h | 71 ++++++++- drivers/net/netxen/netxen_nic_hw.c | 206 +++++++++++++++++--------- drivers/net/netxen/netxen_nic_hw.h | 8 +- drivers/net/netxen/netxen_nic_init.c | 239 ++++++++++++++++++++++++++----- drivers/net/netxen/netxen_nic_ioctl.h | 12 +- drivers/net/netxen/netxen_nic_isr.c | 54 ++++--- drivers/net/netxen/netxen_nic_main.c | 121 +++++++++++----- drivers/net/netxen/netxen_nic_niu.c | 172 +++++++++++++++++----- drivers/net/netxen/netxen_nic_phan_reg.h | 24 +++- 11 files changed, 891 insertions(+), 270 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 0458db45e70..1bee560d7d0 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,12 +63,12 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "232" +#define NETXEN_NIC_BUILD_NO "5" #define _NETXEN_NIC_LINUX_MAJOR 2 #define _NETXEN_NIC_LINUX_MINOR 3 -#define _NETXEN_NIC_LINUX_SUBVERSION 57 -#define NETXEN_NIC_LINUX_VERSIONID "2.3.57" -#define NETXEN_NIC_FW_VERSIONID "2.3.57" +#define _NETXEN_NIC_LINUX_SUBVERSION 59 +#define NETXEN_NIC_LINUX_VERSIONID "2.3.59" "-" NETXEN_NIC_BUILD_NO +#define NETXEN_NIC_FW_VERSIONID "2.3.59" #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) @@ -89,9 +89,24 @@ * normalize a 64MB crb address to 32MB PCI window * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 */ +#define NETXEN_CRB_NORMAL(reg) \ + (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST + #define NETXEN_CRB_NORMALIZE(adapter, reg) \ - ((adapter)->ahw.pci_base + (reg) \ - - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST) + pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg)) + +#define FIRST_PAGE_GROUP_START 0 +#define FIRST_PAGE_GROUP_END 0x400000 + +#define SECOND_PAGE_GROUP_START 0x4000000 +#define SECOND_PAGE_GROUP_END 0x66BC000 + +#define THIRD_PAGE_GROUP_START 0x70E4000 +#define THIRD_PAGE_GROUP_END 0x8000000 + +#define FIRST_PAGE_GROUP_SIZE FIRST_PAGE_GROUP_END - FIRST_PAGE_GROUP_START +#define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START +#define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START #define MAX_RX_BUFFER_LENGTH 2000 #define MAX_RX_JUMBO_BUFFER_LENGTH 9046 @@ -328,6 +343,7 @@ typedef enum { NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f } netxen_brdtype_t; +#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(netxen_brdinfo_t)) typedef enum { NETXEN_BRDMFG_INVENTEC = 1 @@ -615,15 +631,23 @@ struct netxen_rx_buffer { */ struct netxen_hardware_context { struct pci_dev *pdev; - void __iomem *pci_base; /* base of mapped phantom memory */ + void __iomem *pci_base0; + void __iomem *pci_base1; + void __iomem *pci_base2; + u8 revision_id; u16 board_type; u16 max_ports; struct netxen_board_info boardcfg; u32 xg_linkup; + u32 qg_linksup; /* Address of cmd ring in Phantom */ struct cmd_desc_type0 *cmd_desc_head; + char *pauseaddr; + struct pci_dev *cmd_desc_pdev; dma_addr_t cmd_desc_phys_addr; + dma_addr_t pause_physaddr; + struct pci_dev *pause_pdev; struct netxen_adapter *adapter; }; @@ -654,6 +678,7 @@ struct netxen_rcv_desc_ctx { u32 rcv_pending; /* Num of bufs posted in phantom */ u32 rcv_free; /* Num of bufs in free list */ dma_addr_t phys_addr; + struct pci_dev *phys_pdev; struct rcv_desc *desc_head; /* address of rx ring in Phantom */ u32 max_rx_desc_count; u32 dma_size; @@ -673,6 +698,7 @@ struct netxen_recv_context { u32 status_rx_producer; u32 status_rx_consumer; dma_addr_t rcv_status_desc_phys_addr; + struct pci_dev *rcv_status_desc_pdev; struct status_desc *rcv_status_desc_head; }; @@ -708,6 +734,7 @@ struct netxen_adapter { u32 flags; u32 irq; int driver_mismatch; + u32 temp; struct netxen_adapter_stats stats; @@ -766,6 +793,43 @@ struct netxen_port { struct netxen_port_stats stats; }; +#define PCI_OFFSET_FIRST_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base0 + (off)) +#define PCI_OFFSET_SECOND_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START) +#define PCI_OFFSET_THIRD_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START) + +static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter, + unsigned long off) +{ + if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) { + return (adapter->ahw.pci_base0 + off); + } else if ((off < SECOND_PAGE_GROUP_END) && + (off >= SECOND_PAGE_GROUP_START)) { + return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START); + } else if ((off < THIRD_PAGE_GROUP_END) && + (off >= THIRD_PAGE_GROUP_START)) { + return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START); + } + return NULL; +} + +static inline void __iomem *pci_base(struct netxen_adapter *adapter, + unsigned long off) +{ + if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) { + return adapter->ahw.pci_base0; + } else if ((off < SECOND_PAGE_GROUP_END) && + (off >= SECOND_PAGE_GROUP_START)) { + return adapter->ahw.pci_base1; + } else if ((off < THIRD_PAGE_GROUP_END) && + (off >= THIRD_PAGE_GROUP_START)) { + return adapter->ahw.pci_base2; + } + return NULL; +} + struct netxen_drvops { int (*enable_phy_interrupts) (struct netxen_adapter *, int); int (*disable_phy_interrupts) (struct netxen_adapter *, int); @@ -809,7 +873,6 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, long reg, __le32 val); /* Functions available from netxen_nic_hw.c */ -int netxen_niu_xginit(struct netxen_adapter *); int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu); int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu); void netxen_nic_init_niu_gb(struct netxen_adapter *adapter); @@ -828,10 +891,13 @@ void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); /* Functions from netxen_nic_init.c */ -void netxen_phantom_init(struct netxen_adapter *adapter); +void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); void netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); +int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); +int netxen_rom_se(struct netxen_adapter *adapter, int addr); +int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); /* Functions from netxen_nic_isr.c */ void netxen_nic_isr_other(struct netxen_adapter *adapter); @@ -842,6 +908,8 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 port, void netxen_nic_stop_all_ports(struct netxen_adapter *adapter); void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); void netxen_initialize_adapter_hw(struct netxen_adapter *adapter); +void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, + struct pci_dev **used_dev); void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); int netxen_init_firmware(struct netxen_adapter *adapter); void netxen_free_hw_resources(struct netxen_adapter *adapter); @@ -869,7 +937,10 @@ static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) /* * ISR_INT_MASK: Can be read from window 0 or 1. */ - writel(0x7ff, (void __iomem *)(adapter->ahw.pci_base + ISR_INT_MASK)); + writel(0x7ff, + (void __iomem + *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + } static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) @@ -888,13 +959,83 @@ static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) break; } - writel(mask, (void __iomem *)(adapter->ahw.pci_base + ISR_INT_MASK)); + writel(mask, + (void __iomem + *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { mask = 0xbff; writel(mask, (void __iomem *) - (adapter->ahw.pci_base + ISR_INT_TARGET_MASK)); + (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); + } +} + +/* + * NetXen Board information + */ + +#define NETXEN_MAX_SHORT_NAME 16 +typedef struct { + netxen_brdtype_t brdtype; /* type of board */ + long ports; /* max no of physical ports */ + char short_name[NETXEN_MAX_SHORT_NAME]; +} netxen_brdinfo_t; + +static const netxen_brdinfo_t netxen_boards[] = { + {NETXEN_BRDTYPE_P2_SB31_10G_CX4, 1, "XGb CX4"}, + {NETXEN_BRDTYPE_P2_SB31_10G_HMEZ, 1, "XGb HMEZ"}, + {NETXEN_BRDTYPE_P2_SB31_10G_IMEZ, 2, "XGb IMEZ"}, + {NETXEN_BRDTYPE_P2_SB31_10G, 1, "XGb XFP"}, + {NETXEN_BRDTYPE_P2_SB35_4G, 4, "Quad Gb"}, + {NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"}, +}; + +#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(netxen_brdinfo_t)) + +static inline void get_brd_ports_name_by_type(u32 type, int *ports, char *name) +{ + int i, found = 0; + for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { + if (netxen_boards[i].brdtype == type) { + *ports = netxen_boards[i].ports; + strcpy(name, netxen_boards[i].short_name); + found = 1; + break; + } + } + if (!found) { + *ports = 0; + name = "Unknown"; + } +} + +static inline void get_brd_port_by_type(u32 type, int *ports) +{ + int i, found = 0; + for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { + if (netxen_boards[i].brdtype == type) { + *ports = netxen_boards[i].ports; + found = 1; + break; + } + } + if (!found) + *ports = 0; +} + +static inline void get_brd_name_by_type(u32 type, char *name) +{ + int i, found = 0; + for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { + if (netxen_boards[i].brdtype == type) { + strcpy(name, netxen_boards[i].short_name); + found = 1; + break; + } + } + if (!found) + name = "Unknown"; } int netxen_is_flash_supported(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index caf6cc15b24..f3fc35cf8af 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -53,6 +53,9 @@ struct netxen_nic_stats { #define NETXEN_NIC_STAT(m) sizeof(((struct netxen_port *)0)->m), \ offsetof(struct netxen_port, m) +#define NETXEN_NIC_PORT_WINDOW 0x10000 +#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF + static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)}, {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)}, @@ -111,9 +114,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - uint32_t fw_major = 0; - uint32_t fw_minor = 0; - uint32_t fw_build = 0; + u32 fw_major = 0; + u32 fw_minor = 0; + u32 fw_build = 0; strncpy(drvinfo->driver, "netxen_nic", 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); @@ -136,6 +139,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; + struct netxen_board_info *boardinfo; + boardinfo = &adapter->ahw.boardcfg; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -144,16 +149,12 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full | - SUPPORTED_TP | - SUPPORTED_MII | SUPPORTED_Autoneg); + SUPPORTED_1000baseT_Full); ecmd->advertising = (ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full | - ADVERTISED_TP | - ADVERTISED_MII | ADVERTISED_Autoneg); + ADVERTISED_1000baseT_Full); ecmd->port = PORT_TP; @@ -162,16 +163,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->duplex = port->link_duplex; } else return -EIO; /* link absent */ - - ecmd->phy_address = port->portnum; - ecmd->transceiver = XCVR_EXTERNAL; - - /* get autoneg settings */ - ecmd->autoneg = port->link_autoneg; - return 0; - } - - if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { ecmd->supported = (SUPPORTED_TP | SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full); @@ -182,13 +174,47 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->speed = SPEED_10000; ecmd->duplex = DUPLEX_FULL; - ecmd->phy_address = port->portnum; - ecmd->transceiver = XCVR_EXTERNAL; ecmd->autoneg = AUTONEG_DISABLE; - return 0; + } else + return -EIO; + + ecmd->phy_address = port->portnum; + ecmd->transceiver = XCVR_EXTERNAL; + + switch ((netxen_brdtype_t) boardinfo->board_type) { + case NETXEN_BRDTYPE_P2_SB35_4G: + case NETXEN_BRDTYPE_P2_SB31_2G: + ecmd->supported |= SUPPORTED_Autoneg; + ecmd->advertising |= ADVERTISED_Autoneg; + case NETXEN_BRDTYPE_P2_SB31_10G_CX4: + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; + ecmd->port = PORT_TP; + ecmd->autoneg = (boardinfo->board_type == + NETXEN_BRDTYPE_P2_SB31_10G_CX4) ? + (AUTONEG_DISABLE) : (port->link_autoneg); + break; + case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: + case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: + ecmd->supported |= SUPPORTED_MII; + ecmd->advertising |= ADVERTISED_MII; + ecmd->port = PORT_FIBRE; + ecmd->autoneg = AUTONEG_DISABLE; + break; + case NETXEN_BRDTYPE_P2_SB31_10G: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_FIBRE; + ecmd->autoneg = AUTONEG_DISABLE; + break; + default: + printk("ERROR: Unsupported board model %d\n", + (netxen_brdtype_t) boardinfo->board_type); + return -EIO; + } - return -EIO; + return 0; } static int @@ -371,7 +397,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { /* GB: port specific registers */ if (mode == 0 && i >= 19) - window = port->portnum * 0x10000; + window = port->portnum * NETXEN_NIC_PORT_WINDOW; NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. reg[i - 3] + window, @@ -385,7 +411,8 @@ static void netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; - wol->wolopts = 0; /* options can be added depending upon the mode */ + /* options can be added depending upon the mode */ + wol->wolopts = 0; } static u32 netxen_nic_get_link(struct net_device *dev) @@ -531,9 +558,9 @@ static int netxen_nic_reg_test(struct net_device *dev) save = data_read; if (data_read) - data_written = data_read & 0xDEADBEEF; + data_written = data_read & NETXEN_NIC_INVALID_DATA; else - data_written = 0xDEADBEEF; + data_written = NETXEN_NIC_INVALID_DATA; netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(port-> portnum), @@ -559,9 +586,9 @@ static int netxen_nic_reg_test(struct net_device *dev) save = data_read; if (data_read) - data_written = data_read & 0xDEADBEEF; + data_written = data_read & NETXEN_NIC_INVALID_DATA; else - data_written = 0xDEADBEEF; + data_written = NETXEN_NIC_INVALID_DATA; netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(port-> portnum), @@ -587,9 +614,9 @@ static int netxen_nic_reg_test(struct net_device *dev) save = data_read; if (data_read) - data_written = data_read & 0xDEADBEEF; + data_written = data_read & NETXEN_NIC_INVALID_DATA; else - data_written = 0xDEADBEEF; + data_written = NETXEN_NIC_INVALID_DATA; netxen_nic_write_w0(adapter, NETXEN_NIU_GB_INTERFACE_STATUS(port-> portnum), diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 83bf28b372a..72c6ec4ee2a 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -6,12 +6,12 @@ * 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, @@ -397,6 +397,7 @@ enum { #define NETXEN_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004) #define NETXEN_ROMUSB_ROM_ADDRESS (ROMUSB_ROM + 0x0008) +#define NETXEN_ROMUSB_ROM_WDATA (ROMUSB_ROM + 0x000c) #define NETXEN_ROMUSB_ROM_ABYTE_CNT (ROMUSB_ROM + 0x0010) #define NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT (ROMUSB_ROM + 0x0014) #define NETXEN_ROMUSB_ROM_RDATA (ROMUSB_ROM + 0x0018) @@ -404,7 +405,29 @@ enum { /* Lock IDs for ROM lock */ #define ROM_LOCK_DRIVER 0x0d417340 -#define NETXEN_PCI_CRB_WINDOWSIZE 0x00100000 /* all are 1MB windows */ +/****************************************************************************** +* +* Definitions specific to M25P flash +* +******************************************************************************* +* Instructions +*/ +#define M25P_INSTR_WREN 0x06 +#define M25P_INSTR_WRDI 0x04 +#define M25P_INSTR_RDID 0x9f +#define M25P_INSTR_RDSR 0x05 +#define M25P_INSTR_WRSR 0x01 +#define M25P_INSTR_READ 0x03 +#define M25P_INSTR_FAST_READ 0x0b +#define M25P_INSTR_PP 0x02 +#define M25P_INSTR_SE 0xd8 +#define M25P_INSTR_BE 0xc7 +#define M25P_INSTR_DP 0xb9 +#define M25P_INSTR_RES 0xab + +/* all are 1MB windows */ + +#define NETXEN_PCI_CRB_WINDOWSIZE 0x00100000 #define NETXEN_PCI_CRB_WINDOW(A) \ (NETXEN_PCI_CRBSPACE + (A)*NETXEN_PCI_CRB_WINDOWSIZE) @@ -505,6 +528,12 @@ enum { #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) +#define NETXEN_NIU_FULL_LEVEL_XG (NETXEN_CRB_NIU + 0x00450) + +#define NETXEN_NIU_XG1_RESET (NETXEN_CRB_NIU + 0x0011c) +#define NETXEN_NIU_XG1_POWER_DOWN (NETXEN_CRB_NIU + 0x00120) +#define NETXEN_NIU_XG1_RESET_PLL (NETXEN_CRB_NIU + 0x00124) + #define NETXEN_MAC_ADDR_CNTL_REG (NETXEN_CRB_NIU + 0x1000) #define NETXEN_MULTICAST_ADDR_HI_0 (NETXEN_CRB_NIU + 0x1010) @@ -568,6 +597,29 @@ enum { #define NETXEN_NIU_XGE_REMOTE_ERROR_CNT (NETXEN_CRB_NIU + 0x70050) #define NETXEN_NIU_XGE_CONTROL_CHAR_CNT (NETXEN_CRB_NIU + 0x70054) #define NETXEN_NIU_XGE_PAUSE_FRAME_CNT (NETXEN_CRB_NIU + 0x70058) +#define NETXEN_NIU_XG1_CONFIG_0 (NETXEN_CRB_NIU + 0x80000) +#define NETXEN_NIU_XG1_CONFIG_1 (NETXEN_CRB_NIU + 0x80004) +#define NETXEN_NIU_XG1_IPG (NETXEN_CRB_NIU + 0x80008) +#define NETXEN_NIU_XG1_STATION_ADDR_0_HI (NETXEN_CRB_NIU + 0x8000c) +#define NETXEN_NIU_XG1_STATION_ADDR_0_1 (NETXEN_CRB_NIU + 0x80010) +#define NETXEN_NIU_XG1_STATION_ADDR_1_LO (NETXEN_CRB_NIU + 0x80014) +#define NETXEN_NIU_XG1_STATUS (NETXEN_CRB_NIU + 0x80018) +#define NETXEN_NIU_XG1_MAX_FRAME_SIZE (NETXEN_CRB_NIU + 0x8001c) +#define NETXEN_NIU_XG1_PAUSE_FRAME_VALUE (NETXEN_CRB_NIU + 0x80020) +#define NETXEN_NIU_XG1_TX_BYTE_CNT (NETXEN_CRB_NIU + 0x80024) +#define NETXEN_NIU_XG1_TX_FRAME_CNT (NETXEN_CRB_NIU + 0x80028) +#define NETXEN_NIU_XG1_RX_BYTE_CNT (NETXEN_CRB_NIU + 0x8002c) +#define NETXEN_NIU_XG1_RX_FRAME_CNT (NETXEN_CRB_NIU + 0x80030) +#define NETXEN_NIU_XG1_AGGR_ERROR_CNT (NETXEN_CRB_NIU + 0x80034) +#define NETXEN_NIU_XG1_MULTICAST_FRAME_CNT (NETXEN_CRB_NIU + 0x80038) +#define NETXEN_NIU_XG1_UNICAST_FRAME_CNT (NETXEN_CRB_NIU + 0x8003c) +#define NETXEN_NIU_XG1_CRC_ERROR_CNT (NETXEN_CRB_NIU + 0x80040) +#define NETXEN_NIU_XG1_OVERSIZE_FRAME_ERR (NETXEN_CRB_NIU + 0x80044) +#define NETXEN_NIU_XG1_UNDERSIZE_FRAME_ERR (NETXEN_CRB_NIU + 0x80048) +#define NETXEN_NIU_XG1_LOCAL_ERROR_CNT (NETXEN_CRB_NIU + 0x8004c) +#define NETXEN_NIU_XG1_REMOTE_ERROR_CNT (NETXEN_CRB_NIU + 0x80050) +#define NETXEN_NIU_XG1_CONTROL_CHAR_CNT (NETXEN_CRB_NIU + 0x80054) +#define NETXEN_NIU_XG1_PAUSE_FRAME_CNT (NETXEN_CRB_NIU + 0x80058) /* XG Link status */ #define XG_LINK_UP 0x10 @@ -580,8 +632,15 @@ enum { #define NETXEN_FW_VERSION_SUB (NETXEN_CAM_RAM(0x158)) #define NETXEN_ROM_LOCK_ID (NETXEN_CAM_RAM(0x100)) -#define PCIX_PS_OP_ADDR_LO (0x10000) /* Used for PS PCI Memory access */ -#define PCIX_PS_OP_ADDR_HI (0x10004) /* via CRB (PS side only) */ +#define NETXEN_PHY_LOCK_ID (NETXEN_CAM_RAM(0x120)) + +/* Lock IDs for PHY lock */ +#define PHY_LOCK_DRIVER 0x44524956 + +/* Used for PS PCI Memory access */ +#define PCIX_PS_OP_ADDR_LO (0x10000) +/* via CRB (PS side only) */ +#define PCIX_PS_OP_ADDR_HI (0x10004) #define PCIX_INT_VECTOR (0x10100) #define PCIX_INT_MASK (0x10104) @@ -609,6 +668,8 @@ enum { #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_TGT_SPLIT_CHICKEN (0x12080) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9603c635b05..99e647a5ae7 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -6,12 +6,12 @@ * 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, @@ -43,15 +43,26 @@ #define NETXEN_FLASH_BASE (BOOTLD_START) #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) #define NETXEN_MAX_MTU 8000 -#define NETXEN_MIN_MTU 64 +#define NETXEN_MIN_MTU 64 #define NETXEN_ETH_FCS_SIZE 4 #define NETXEN_ENET_HEADER_SIZE 14 -#define NETXEN_WINDOW_ONE 0x2000000 /* CRB Window: bit 25 of CRB address */ +#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) #define NETXEN_NIU_HDRSIZE (0x1 << 6) #define NETXEN_NIU_TLRSIZE (0x1 << 5) -unsigned long netxen_nic_pci_set_window(void __iomem * pci_base, +#define lower32(x) ((u32)((x) & 0xffffffff)) +#define upper32(x) \ + ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff)) + +#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL +#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL +#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL +#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL + +#define NETXEN_NIC_WINDOW_MARGIN 0x100000 + +unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, unsigned long long addr); void netxen_free_hw_resources(struct netxen_adapter *adapter); @@ -93,7 +104,9 @@ void netxen_nic_set_multi(struct net_device *netdev) port->portnum, NETXEN_NIU_PROMISC_MODE); } else { - if (adapter->ops->unset_promisc) + if (adapter->ops->unset_promisc && + adapter->ahw.boardcfg.board_type + != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) adapter->ops->unset_promisc(adapter, port->portnum, NETXEN_NIU_NON_PROMISC_MODE); @@ -161,26 +174,24 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) int netxen_nic_hw_resources(struct netxen_adapter *adapter) { struct netxen_hardware_context *hw = &adapter->ahw; - int i; u32 state = 0; void *addr; + void *pause_addr; int loops = 0, err = 0; int ctx, ring; u32 card_cmdring = 0; struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; - struct cmd_desc_type0 *pcmd; - DPRINTK(INFO, "pci_base: %lx\n", adapter->ahw.pci_base); DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE, - adapter->ahw.pci_base + NETXEN_PCI_CRBSPACE); + PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM, - adapter->ahw.pci_base + NETXEN_CRB_CAM); + pci_base_offset(adapter, NETXEN_CRB_CAM)); DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE, - adapter->ahw.pci_base + NETXEN_CAM_RAM_BASE); + pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1, - adapter->ahw.pci_base + NIC_CRB_BASE_PORT1); + pci_base_offset(adapter, NIC_CRB_BASE_PORT1)); /* Window 1 call */ card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING)); @@ -214,25 +225,34 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); - addr = pci_alloc_consistent(adapter->ahw.pdev, - sizeof(struct cmd_desc_type0) * - adapter->max_tx_desc_count, - &hw->cmd_desc_phys_addr); + addr = netxen_alloc(adapter->ahw.pdev, + sizeof(struct cmd_desc_type0) * + adapter->max_tx_desc_count, + &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev); + if (addr == NULL) { DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); - err = -ENOMEM; - return err; + return -ENOMEM; + } + + pause_addr = netxen_alloc(adapter->ahw.pdev, 512, + (dma_addr_t *) & hw->pause_physaddr, + &hw->pause_pdev); + if (pause_addr == NULL) { + DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n"); + return -ENOMEM; } - /* we need to prelink all of the cmd descriptors */ - pcmd = (struct cmd_desc_type0 *)addr; - for (i = 1; i < adapter->max_tx_desc_count; i++) { - pcmd->netxen_next = - (card_cmdring + i * sizeof(struct cmd_desc_type0)); - pcmd++; + hw->pauseaddr = (char *)pause_addr; + { + u64 *ptr = (u64 *) pause_addr; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1; + *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2; } - /* fill in last link (point to first) */ - pcmd->netxen_next = card_cmdring; hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; @@ -241,9 +261,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { rcv_desc = &recv_ctx->rcv_desc[ring]; - addr = pci_alloc_consistent(adapter->ahw.pdev, - RCV_DESC_RINGSIZE, - &rcv_desc->phys_addr); + addr = netxen_alloc(adapter->ahw.pdev, + RCV_DESC_RINGSIZE, + &rcv_desc->phys_addr, + &rcv_desc->phys_pdev); if (addr == NULL) { DPRINTK(ERR, "bad return from " "pci_alloc_consistent\n"); @@ -254,10 +275,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) rcv_desc->desc_head = (struct rcv_desc *)addr; } - addr = pci_alloc_consistent(adapter->ahw.pdev, - STATUS_DESC_RINGSIZE, - &recv_ctx-> - rcv_status_desc_phys_addr); + addr = netxen_alloc(adapter->ahw.pdev, + STATUS_DESC_RINGSIZE, + &recv_ctx-> + rcv_status_desc_phys_addr, + &recv_ctx->rcv_status_desc_pdev); if (addr == NULL) { DPRINTK(ERR, "bad return from" " pci_alloc_consistent\n"); @@ -273,19 +295,20 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n", ring, rcv_desc_crb->crb_globalrcv_ring); /* Window = 1 */ - writel(rcv_desc->phys_addr, + writel(lower32(rcv_desc->phys_addr), NETXEN_CRB_NORMALIZE(adapter, rcv_desc_crb-> crb_globalrcv_ring)); DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x" - " val 0x%x," + " val 0x%llx," " virt %p\n", ctx, rcv_desc_crb->crb_globalrcv_ring, - rcv_desc->phys_addr, rcv_desc->desc_head); + (unsigned long long)rcv_desc->phys_addr, + +rcv_desc->desc_head); } /* Window = 1 */ - writel(recv_ctx->rcv_status_desc_phys_addr, + writel(lower32(recv_ctx->rcv_status_desc_phys_addr), NETXEN_CRB_NORMALIZE(adapter, recv_crb_registers[ctx]. crb_rcvstatus_ring)); @@ -293,13 +316,19 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) " val 0x%x,virt%p\n", ctx, recv_crb_registers[ctx].crb_rcvstatus_ring, - recv_ctx->rcv_status_desc_phys_addr, + (unsigned long long)recv_ctx->rcv_status_desc_phys_addr, recv_ctx->rcv_status_desc_head); } /* Window = 1 */ - writel(hw->cmd_desc_phys_addr, - NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); + writel(lower32(hw->pause_physaddr), + NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO)); + writel(upper32(hw->pause_physaddr), + NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI)); + writel(lower32(hw->cmd_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); + writel(upper32(hw->cmd_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI)); return err; } @@ -310,13 +339,19 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) int ctx, ring; if (adapter->ahw.cmd_desc_head != NULL) { - pci_free_consistent(adapter->ahw.pdev, + pci_free_consistent(adapter->ahw.cmd_desc_pdev, sizeof(struct cmd_desc_type0) * adapter->max_tx_desc_count, adapter->ahw.cmd_desc_head, adapter->ahw.cmd_desc_phys_addr); adapter->ahw.cmd_desc_head = NULL; } + if (adapter->ahw.pauseaddr != NULL) { + pci_free_consistent(adapter->ahw.pause_pdev, 512, + adapter->ahw.pauseaddr, + adapter->ahw.pause_physaddr); + adapter->ahw.pauseaddr = NULL; + } for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { recv_ctx = &adapter->recv_ctx[ctx]; @@ -324,7 +359,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) rcv_desc = &recv_ctx->rcv_desc[ring]; if (rcv_desc->desc_head != NULL) { - pci_free_consistent(adapter->ahw.pdev, + pci_free_consistent(rcv_desc->phys_pdev, RCV_DESC_RINGSIZE, rcv_desc->desc_head, rcv_desc->phys_addr); @@ -333,7 +368,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) } if (recv_ctx->rcv_status_desc_head != NULL) { - pci_free_consistent(adapter->ahw.pdev, + pci_free_consistent(recv_ctx->rcv_status_desc_pdev, STATUS_DESC_RINGSIZE, recv_ctx->rcv_status_desc_head, recv_ctx-> @@ -360,10 +395,10 @@ void netxen_tso_check(struct netxen_adapter *adapter, return; } } + adapter->stats.xmitcsummed++; CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data); desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr); desc->ip_hdr_offset = skb->nh.raw - skb->data; - adapter->stats.xmitcsummed++; } int netxen_is_flash_supported(struct netxen_adapter *adapter) @@ -373,7 +408,7 @@ int netxen_is_flash_supported(struct netxen_adapter *adapter) /* if the flash size less than 4Mb, make huge war cry and die */ for (j = 1; j < 4; j++) { - addr = j * 0x100000; + addr = j * NETXEN_NIC_WINDOW_MARGIN; for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) { if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0 && netxen_rom_fast_read(adapter, (addr + locs[i]), @@ -458,7 +493,9 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) * register address is received by PCI. The direct region bypasses * the CRB bus. */ - offset = adapter->ahw.pci_base + NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW); + offset = + PCI_OFFSET_SECOND_RANGE(adapter, + NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); if (wndw & 0x1) wndw = NETXEN_WINDOW_ONE; @@ -497,8 +534,8 @@ void netxen_load_firmware(struct netxen_adapter *adapter) "loading flash image\n"); return; } - off = netxen_nic_pci_set_window(adapter->ahw.pci_base, memaddr); - addr = (adapter->ahw.pci_base + off); + off = netxen_nic_pci_set_window(adapter, memaddr); + addr = pci_base_offset(adapter, off); writel(data, addr); flashaddr += 4; memaddr += 4; @@ -521,14 +558,19 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, if (ADDR_IN_WINDOW1(off)) { addr = NETXEN_CRB_NORMALIZE(adapter, off); } else { /* Window 0 */ - addr = adapter->ahw.pci_base + off; + addr = pci_base_offset(adapter, off); netxen_nic_pci_change_crbwindow(adapter, 0); } DPRINTK(INFO, "writing to base %lx offset %llx addr %p" " data %llx len %d\n", - adapter->ahw.pci_base, off, addr, + pci_base(adapter, off), off, addr, *(unsigned long long *)data, len); + if (!addr) { + netxen_nic_pci_change_crbwindow(adapter, 1); + return 1; + } + switch (len) { case 1: writeb(*(u8 *) data, addr); @@ -566,12 +608,16 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ addr = NETXEN_CRB_NORMALIZE(adapter, off); } else { /* Window 0 */ - addr = adapter->ahw.pci_base + off; + addr = pci_base_offset(adapter, off); netxen_nic_pci_change_crbwindow(adapter, 0); } DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", - adapter->ahw.pci_base, off, addr); + pci_base(adapter, off), off, addr); + if (!addr) { + netxen_nic_pci_change_crbwindow(adapter, 1); + return 1; + } switch (len) { case 1: *(u8 *) data = readb(addr); @@ -604,7 +650,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", - adapter->ahw.pci_base, off, addr, val); + pci_base(adapter, off), off, addr); writel(val, addr); } @@ -629,7 +675,7 @@ void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) void __iomem *addr; netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(adapter->ahw.pci_base + index); + addr = (void __iomem *)(pci_base_offset(adapter, index)); writel(value, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } @@ -639,7 +685,7 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) { void __iomem *addr; - addr = (void __iomem *)(adapter->ahw.pci_base + index); + addr = (void __iomem *)(pci_base_offset(adapter, index)); netxen_nic_pci_change_crbwindow(adapter, 0); *value = readl(addr); @@ -649,7 +695,8 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) int netxen_pci_set_window_warning_count = 0; unsigned long -netxen_nic_pci_set_window(void __iomem * pci_base, unsigned long long addr) +netxen_nic_pci_set_window(struct netxen_adapter *adapter, + unsigned long long addr) { static int ddr_mn_window = -1; static int qdr_sn_window = -1; @@ -661,12 +708,15 @@ netxen_nic_pci_set_window(void __iomem * pci_base, unsigned long long addr) window = (addr >> 25) & 0x3ff; if (ddr_mn_window != window) { ddr_mn_window = window; - writel(window, pci_base + - NETXEN_PCIX_PH_REG(PCIX_MN_WINDOW)); + writel(window, PCI_OFFSET_SECOND_RANGE(adapter, + NETXEN_PCIX_PH_REG + (PCIX_MN_WINDOW))); /* MUST make sure window is set before we forge on... */ - readl(pci_base + NETXEN_PCIX_PH_REG(PCIX_MN_WINDOW)); + readl(PCI_OFFSET_SECOND_RANGE(adapter, + NETXEN_PCIX_PH_REG + (PCIX_MN_WINDOW))); } - addr -= (window * 0x2000000); + addr -= (window * NETXEN_WINDOW_ONE); addr += NETXEN_PCI_DDR_NET; } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { addr -= NETXEN_ADDR_OCM0; @@ -682,10 +732,14 @@ netxen_nic_pci_set_window(void __iomem * pci_base, unsigned long long addr) window = (addr >> 22) & 0x3f; if (qdr_sn_window != window) { qdr_sn_window = window; - writel((window << 22), pci_base + - NETXEN_PCIX_PH_REG(PCIX_SN_WINDOW)); + writel((window << 22), + PCI_OFFSET_SECOND_RANGE(adapter, + NETXEN_PCIX_PH_REG + (PCIX_SN_WINDOW))); /* MUST make sure window is set before we forge on... */ - readl(pci_base + NETXEN_PCIX_PH_REG(PCIX_SN_WINDOW)); + readl(PCI_OFFSET_SECOND_RANGE(adapter, + NETXEN_PCIX_PH_REG + (PCIX_SN_WINDOW))); } addr -= (window * 0x400000); addr += NETXEN_PCI_QDR_NET; @@ -811,7 +865,7 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); } else { netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(adapter->ahw.pci_base + off); + addr = (void __iomem *)(pci_base_offset(adapter, off)); writel(data, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } @@ -879,6 +933,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) u32 fw_major = 0; u32 fw_minor = 0; u32 fw_build = 0; + char brd_name[NETXEN_MAX_SHORT_NAME]; + struct netxen_new_user_info user_info; + int i, addr = USER_START; + u32 *ptr32; struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); if (board_info->magic != NETXEN_BDINFO_MAGIC) { @@ -894,6 +952,24 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) valid = 0; } if (valid) { + ptr32 = (u32 *) & user_info; + for (i = 0; + i < sizeof(struct netxen_new_user_info) / sizeof(u32); + i++) { + if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { + printk("%s: ERROR reading %s board userarea.\n", + netxen_nic_driver_name, + netxen_nic_driver_name); + return; + } + ptr32++; + addr += sizeof(u32); + } + get_brd_name_by_type(board_info->board_type, brd_name); + + printk("NetXen %s Board S/N %s Chip id 0x%x\n", + brd_name, user_info.serial_num, board_info->chip_id); + printk("NetXen %s Board #%d, Chip id 0x%x\n", board_info->board_type == 0x0b ? "XGB" : "GBE", board_info->board_num, board_info->chip_id); diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index fb1a0253863..201a636b7ab 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -82,9 +82,9 @@ struct netxen_adapter; #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) -#define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ - addr = (adapter->ahw.pci_base + X); \ - *(u32 *)Y = readl((void __iomem*) addr); +#define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ + addr = pci_base_offset(adapter, (X)); \ + *(u32 *)Y = readl(addr); struct netxen_port; void netxen_nic_set_link_parameters(struct netxen_port *port); @@ -472,6 +472,8 @@ int netxen_niu_xg_macaddr_set(struct netxen_port *port, /* 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 port); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index d122e51e43a..0dca029bc3e 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -51,11 +51,13 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \ NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20 +#define NETXEN_NIC_XDMA_RESET 0x8000ff + static inline void netxen_nic_locked_write_reg(struct netxen_adapter *adapter, unsigned long off, int *data) { - void __iomem *addr = (adapter->ahw.pci_base + off); + void __iomem *addr = pci_base_offset(adapter, off); writel(*data, addr); } @@ -141,6 +143,24 @@ int netxen_init_firmware(struct netxen_adapter *adapter) return err; } +#define NETXEN_ADDR_LIMIT 0xffffffffULL + +void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, + struct pci_dev **used_dev) +{ + void *addr; + + addr = pci_alloc_consistent(pdev, sz, ptr); + if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) { + *used_dev = pdev; + return addr; + } + pci_free_consistent(pdev, sz, addr, *ptr); + addr = pci_alloc_consistent(NULL, sz, ptr); + *used_dev = NULL; + return addr; +} + void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) { int ctxid, ring; @@ -177,23 +197,17 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) { + int ports = 0; + struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); + if (netxen_nic_get_board_info(adapter) != 0) printk("%s: Error getting board config info.\n", netxen_nic_driver_name); - - switch (adapter->ahw.board_type) { - case NETXEN_NIC_GBE: - adapter->ahw.max_ports = 4; - break; - - case NETXEN_NIC_XGBE: - adapter->ahw.max_ports = 1; - break; - - default: + get_brd_port_by_type(board_info->board_type, &ports); + if (ports == 0) printk(KERN_ERR "%s: Unknown board type\n", netxen_nic_driver_name); - } + adapter->ahw.max_ports = ports; } void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) @@ -225,6 +239,7 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; ops->macaddr_set = netxen_niu_xg_macaddr_set; ops->set_mtu = netxen_nic_set_mtu_xgb; + ops->init_port = netxen_niu_xg_init_port; ops->set_promisc = netxen_niu_xg_set_promiscuous_mode; ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode; ops->stop_port = netxen_niu_disable_xg_port; @@ -295,15 +310,6 @@ static inline int rom_lock(struct netxen_adapter *adapter) return 0; } -static inline void rom_unlock(struct netxen_adapter *adapter) -{ - u32 val; - - /* release semaphore2 */ - netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val); - -} - int netxen_wait_rom_done(struct netxen_adapter *adapter) { long timeout = 0; @@ -321,6 +327,81 @@ int netxen_wait_rom_done(struct netxen_adapter *adapter) return 0; } +static inline int netxen_rom_wren(struct netxen_adapter *adapter) +{ + /* Set write enable latch in ROM status register */ + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, + M25P_INSTR_WREN); + if (netxen_wait_rom_done(adapter)) { + return -1; + } + return 0; +} + +static inline unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter, + unsigned int addr) +{ + unsigned int data = 0xdeaddead; + data = netxen_nic_reg_read(adapter, addr); + return data; +} + +static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter) +{ + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, + M25P_INSTR_RDSR); + if (netxen_wait_rom_done(adapter)) { + return -1; + } + return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA); +} + +static inline void netxen_rom_unlock(struct netxen_adapter *adapter) +{ + u32 val; + + /* release semaphore2 */ + netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val); + +} + +int netxen_rom_wip_poll(struct netxen_adapter *adapter) +{ + long timeout = 0; + long wip = 1; + int val; + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); + while (wip != 0) { + val = netxen_do_rom_rdsr(adapter); + wip = val & 1; + timeout++; + if (timeout > rom_max_timeout) { + return -1; + } + } + return 0; +} + +static inline int do_rom_fast_write(struct netxen_adapter *adapter, + int addr, int data) +{ + if (netxen_rom_wren(adapter)) { + return -1; + } + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, + M25P_INSTR_PP); + if (netxen_wait_rom_done(adapter)) { + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); + return -1; + } + + return netxen_rom_wip_poll(adapter); +} + static inline int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { @@ -350,7 +431,43 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) return -EIO; ret = do_rom_fast_read(adapter, addr, valp); - rom_unlock(adapter); + netxen_rom_unlock(adapter); + return ret; +} + +int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) +{ + int ret = 0; + + if (rom_lock(adapter) != 0) { + return -1; + } + ret = do_rom_fast_write(adapter, addr, data); + netxen_rom_unlock(adapter); + return ret; +} +int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) +{ + netxen_rom_wren(adapter); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, + M25P_INSTR_SE); + if (netxen_wait_rom_done(adapter)) { + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); + return -1; + } + return netxen_rom_wip_poll(adapter); +} + +int netxen_rom_se(struct netxen_adapter *adapter, int addr) +{ + int ret = 0; + if (rom_lock(adapter) != 0) { + return -1; + } + ret = netxen_do_rom_se(adapter, addr); + netxen_rom_unlock(adapter); return ret; } @@ -372,7 +489,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* resetall */ status = netxen_nic_get_board_info(adapter); if (status) - printk("%s: pinit_from_rom: Error getting board info\n", + printk("%s: netxen_pinit_from_rom: Error getting board info\n", netxen_nic_driver_name); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, @@ -408,8 +525,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); if (buf == NULL) { - printk("%s: pinit_from_rom: Unable to calloc memory.\n", - netxen_nic_driver_name); + printk("%s: netxen_pinit_from_rom: Unable to calloc " + "memory.\n", netxen_nic_driver_name); return -ENOMEM; } for (i = 0; i < n; i++) { @@ -441,7 +558,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) if (off == NETXEN_ROMUSB_GLB_SW_RESET) { init_delay = 1; /* hold xdma in reset also */ - buf[i].data = 0x8000ff; + buf[i].data = NETXEN_NIC_XDMA_RESET; } if (ADDR_IN_WINDOW1(off)) { @@ -450,7 +567,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } else { netxen_nic_pci_change_crbwindow(adapter, 0); writel(buf[i].data, - adapter->ahw.pci_base + off); + pci_base_offset(adapter, off)); netxen_nic_pci_change_crbwindow(adapter, 1); } @@ -505,18 +622,15 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) return 0; } -void netxen_phantom_init(struct netxen_adapter *adapter) +void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) { u32 val = 0; int loops = 0; - netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, &val, 4); - writel(1, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); - - if (0 == val) { + if (!pegtune_val) { while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) { udelay(100); + schedule(); val = readl(NETXEN_CRB_NORMALIZE (adapter, CRB_CMDPEG_STATE)); @@ -536,7 +650,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) &(adapter->recv_ctx[ctx]); u32 consumer; struct status_desc *desc_head; - struct status_desc *desc; /* used to read status desc here */ + struct status_desc *desc; consumer = recv_ctx->status_rx_consumer; desc_head = recv_ctx->rcv_status_desc_head; @@ -549,6 +663,53 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) return 0; } +static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) +{ + int port_num; + struct netxen_port *port; + struct net_device *netdev; + uint32_t temp, temp_state, temp_val; + int rv = 0; + + temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE)); + + temp_state = nx_get_temp_state(temp); + temp_val = nx_get_temp_val(temp); + + if (temp_state == NX_TEMP_PANIC) { + printk(KERN_ALERT + "%s: Device temperature %d degrees C exceeds" + " maximum allowed. Hardware has been shut down.\n", + netxen_nic_driver_name, temp_val); + for (port_num = 0; port_num < adapter->ahw.max_ports; + port_num++) { + port = adapter->port[port_num]; + netdev = port->netdev; + + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + rv = 1; + } else if (temp_state == NX_TEMP_WARN) { + if (adapter->temp == NX_TEMP_NORMAL) { + printk(KERN_ALERT + "%s: Device temperature %d degrees C " + "exceeds operating range." + " Immediate action needed.\n", + netxen_nic_driver_name, temp_val); + } + } else { + if (adapter->temp == NX_TEMP_WARN) { + printk(KERN_INFO + "%s: Device temperature is now %d degrees C" + " in normal range.\n", netxen_nic_driver_name, + temp_val); + } + } + adapter->temp = temp_state; + return rv; +} + void netxen_watchdog_task(unsigned long v) { int port_num; @@ -556,6 +717,9 @@ void netxen_watchdog_task(unsigned long v) struct net_device *netdev; struct netxen_adapter *adapter = (struct netxen_adapter *)v; + if (netxen_nic_check_temp(adapter)) + return; + for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) { port = adapter->port[port_num]; netdev = port->netdev; @@ -570,8 +734,6 @@ void netxen_watchdog_task(unsigned long v) netif_wake_queue(netdev); } - netxen_nic_pci_change_crbwindow(adapter, 1); - if (adapter->ops->handle_phy_intr) adapter->ops->handle_phy_intr(adapter); mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); @@ -742,7 +904,6 @@ void netxen_process_cmd_ring(unsigned long data) * number as part of the descriptor. This way we will be able to get * the netdev which is associated with that device. */ - /* Window = 1 */ consumer = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); @@ -861,7 +1022,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) * We need to schedule the posting of buffers to the pegs. */ rcv_desc->begin_alloc = index; - DPRINTK(ERR, "unm_post_rx_buffers: " + DPRINTK(ERR, "netxen_post_rx_buffers: " " allocated only %d buffers\n", count); break; } diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h index 806818eb963..23e53adbf12 100644 --- a/drivers/net/netxen/netxen_nic_ioctl.h +++ b/drivers/net/netxen/netxen_nic_ioctl.h @@ -6,12 +6,12 @@ * 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, @@ -32,9 +32,11 @@ #include -#define NETXEN_CMD_START SIOCDEVPRIVATE -#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) -#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) +#define NETXEN_CMD_START SIOCDEVPRIVATE +#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) +#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) +#define NETXEN_NIC_NAME_LEN 16 +#define NETXEN_NIC_NAME_RSP "NETXEN" typedef enum { netxen_nic_cmd_none = 0, diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index f1c3e5af03a..ae180fee800 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -149,47 +149,41 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, void netxen_nic_isr_other(struct netxen_adapter *adapter) { - u32 enable, portno; - u32 i2qhi; - - /* - * bit 3 is for i2qInt, if high its enabled - * check for phy interrupts - * read vector and check for bit 45 for phy - * clear int by writing the same value into ISR_INT_VECTOR REG - */ - - DPRINTK(INFO, "I2Q is the source of INT \n"); + u32 portno; + u32 val, linkup, qg_linksup; /* verify the offset */ - i2qhi = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI)); - - DPRINTK(INFO, "isr NETXEN_I2Q_CLR_PCI_HI = 0x%x \n", i2qhi); + val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); + if (val == adapter->ahw.qg_linksup) + return; - if (i2qhi & 0x4000) { - for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { - DPRINTK(INFO, "External PHY interrupt ON PORT %d\n", - portno); + qg_linksup = adapter->ahw.qg_linksup; + adapter->ahw.qg_linksup = val; + DPRINTK(1, INFO, "%s: link update 0x%08x\n", netxen_nic_driver_name, + val); + for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { + linkup = val & 1; + if (linkup != (qg_linksup & 1)) { + printk(KERN_INFO "%s: PORT %d link %s\n", + netxen_nic_driver_name, portno, + ((linkup == 0) ? "down" : "up")); + netxen_indicate_link_status(adapter, portno, linkup); + if (linkup) + netxen_nic_set_link_parameters(adapter-> + port[portno]); - enable = 1; - netxen_handle_port_int(adapter, portno, enable); } + val = val >> 1; + qg_linksup = qg_linksup >> 1; + } - /* Clear the interrupt on I2Q */ - writel((u32) i2qhi, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI)); + adapter->stats.otherints++; - } } void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter) { - u32 val; - val = readl(NETXEN_CRB_NORMALIZE(adapter, ISR_INT_VECTOR)); - if (val & 0x4) { - adapter->stats.otherints++; - netxen_nic_isr_other(adapter); - } + netxen_nic_isr_other(adapter); } void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index ffd272c93a6..cd1336e899b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -31,6 +31,7 @@ * */ +#include #include "netxen_nic_hw.h" #include "netxen_nic.h" @@ -41,16 +42,19 @@ #include #include +#define PHAN_VENDOR_ID 0x4040 + MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); char netxen_nic_driver_name[] = "netxen"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " - NETXEN_NIC_LINUX_VERSIONID "-" NETXEN_NIC_BUILD_NO; + NETXEN_NIC_LINUX_VERSIONID; #define NETXEN_NETDEV_WEIGHT 120 #define NETXEN_ADAPTER_UP_MAGIC 777 +#define NETXEN_NIC_PEG_TUNE 0 /* Local functions to NetXen NIC driver */ static int __devinit netxen_nic_probe(struct pci_dev *pdev, @@ -101,7 +105,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *netdev = NULL; struct netxen_adapter *adapter = NULL; struct netxen_port *port = NULL; - u8 __iomem *mem_ptr = NULL; + u8 *mem_ptr0 = NULL; + u8 *mem_ptr1 = NULL; + u8 *mem_ptr2 = NULL; + unsigned long mem_base, mem_len; int pci_using_dac, i, err; int ring; @@ -111,6 +118,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u64 mac_addr[FLASH_NUM_PORTS + 1]; int valid_mac; + printk(KERN_INFO "%s \n", netxen_nic_driver_string); if ((err = pci_enable_device(pdev))) return err; if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { @@ -138,11 +146,26 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mem_len = pci_resource_len(pdev, 0); /* 128 Meg of memory */ - mem_ptr = ioremap(mem_base, NETXEN_PCI_MAPSIZE_BYTES); - if (mem_ptr == 0UL) { - printk(KERN_ERR "%s: Cannot ioremap adapter memory aborting." - ":%p\n", netxen_nic_driver_name, mem_ptr); + mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); + mem_ptr1 = + ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE); + mem_ptr2 = + ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); + + if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { + DPRINTK(1, ERR, + "Cannot remap adapter memory aborting.:" + "0 -> %p, 1 -> %p, 2 -> %p\n", + mem_ptr0, mem_ptr1, mem_ptr2); + err = -EIO; + if (mem_ptr0) + iounmap(mem_ptr0); + if (mem_ptr1) + iounmap(mem_ptr1); + if (mem_ptr2) + iounmap(mem_ptr2); + goto err_out_free_res; } @@ -221,9 +244,17 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } adapter->cmd_buf_arr = cmd_buf_arr; - adapter->ahw.pci_base = mem_ptr; + adapter->ahw.pci_base0 = mem_ptr0; + adapter->ahw.pci_base1 = mem_ptr1; + adapter->ahw.pci_base2 = mem_ptr2; spin_lock_init(&adapter->tx_lock); spin_lock_init(&adapter->lock); +#ifdef CONFIG_IA64 + netxen_pinit_from_rom(adapter, 0); + udelay(500); + netxen_load_firmware(adapter); +#endif + /* initialize the buffers in adapter */ netxen_initialize_adapter_sw(adapter); /* @@ -262,6 +293,20 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else valid_mac = 0; + /* + * Initialize all the CRB registers here. + */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); + + /* Unlock the HW, prompting the boot sequence */ + writel(1, + NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); + + /* Handshake with the card before we register the devices. */ + netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + /* initialize the all the ports */ for (i = 0; i < adapter->ahw.max_ports; i++) { @@ -351,15 +396,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->port[i] = port; } - /* - * Initialize all the CRB registers here. - */ - /* Window = 1 */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); - - netxen_phantom_init(adapter); /* * delay a while to ensure that the Pegs are up & running. * Otherwise, we might see some flaky behaviour. @@ -414,7 +450,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) kfree(adapter); err_out_iounmap: - iounmap(mem_ptr); + iounmap(mem_ptr0); + iounmap(mem_ptr1); + iounmap(mem_ptr2); + err_out_free_res: pci_release_regions(pdev); err_out_disable_pdev: @@ -460,7 +499,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) netxen_free_hw_resources(adapter); - iounmap(adapter->ahw.pci_base); + iounmap(adapter->ahw.pci_base0); + iounmap(adapter->ahw.pci_base1); + iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); pci_disable_device(pdev); @@ -496,7 +537,6 @@ static int netxen_nic_open(struct net_device *netdev) { struct netxen_port *port = netdev_priv(netdev); struct netxen_adapter *adapter = port->adapter; - struct netxen_rcv_desc_ctx *rcv_desc; int err = 0; int ctx, ring; @@ -527,11 +567,8 @@ static int netxen_nic_open(struct net_device *netdev) if (adapter->ops->init_niu) adapter->ops->init_niu(adapter); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { - for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { - rcv_desc = - &adapter->recv_ctx[ctx].rcv_desc[ring]; + for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) netxen_post_rx_buffers(adapter, ctx, ring); - } } adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; } @@ -579,10 +616,6 @@ static int netxen_nic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_stop_queue(netdev); - /* disable phy_ints */ - if (adapter->ops->disable_phy_interrupts) - adapter->ops->disable_phy_interrupts(adapter, port->portnum); - adapter->active_ports--; if (!adapter->active_ports) { @@ -690,13 +723,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) local_producer = adapter->cmd_producer; /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; - if (skb_shinfo(skb)->gso_size > 0) { - no_of_desc++; - if (((skb->nh.iph)->ihl * sizeof(u32)) + - ((skb->h.th)->doff * sizeof(u32)) + - sizeof(struct ethhdr) > - (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { + if (netdev->features & NETIF_F_TSO) { + if (skb_shinfo(skb)->gso_size > 0) { + no_of_desc++; + if (((skb->nh.iph)->ihl * sizeof(u32)) + + ((skb->h.th)->doff * sizeof(u32)) + + sizeof(struct ethhdr) > + (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { + no_of_desc++; + } } } k = adapter->cmd_producer; @@ -740,7 +776,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; - if (skb_shinfo(skb)->gso_size > 0) { + if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { pbuf->mss = skb_shinfo(skb)->gso_size; hwdesc->mss = skb_shinfo(skb)->gso_size; } else { @@ -934,9 +970,10 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) /* Window = 0 or 1 */ do { writel(0xffffffff, (void __iomem *) - (adapter->ahw.pci_base + ISR_INT_TARGET_STATUS)); + (PCI_OFFSET_SECOND_RANGE + (adapter, ISR_INT_TARGET_STATUS))); mask = readl((void __iomem *) - (adapter->ahw.pci_base + ISR_INT_VECTOR)); + pci_base_offset(adapter, ISR_INT_VECTOR)); } while (((mask & 0x80) != 0) && (++count < 32)); if ((mask & 0x80) != 0) printk("Could not disable interrupt completely\n"); @@ -1065,8 +1102,10 @@ static int netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { int err = 0; + unsigned long nr_bytes = 0; struct netxen_port *port = netdev_priv(netdev); struct netxen_adapter *adapter = port->adapter; + char dev_name[NETXEN_NIC_NAME_LEN]; DPRINTK(INFO, "doing ioctl for %s\n", netdev->name); switch (cmd) { @@ -1077,7 +1116,13 @@ netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case NETXEN_NIC_NAME: DPRINTK(INFO, "ioctl cmd for NetXen\n"); if (ifr->ifr_data) { - put_user(port->portnum, (u16 __user *) ifr->ifr_data); + sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, + port->portnum); + nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name, + NETXEN_NIC_NAME_LEN); + if (nr_bytes) + err = -EIO; + } break; @@ -1101,8 +1146,6 @@ static struct pci_driver netxen_driver = { static int __init netxen_init_module(void) { - printk(KERN_INFO "%s \n", netxen_nic_driver_string); - return pci_module_init(&netxen_driver); } diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 6e421c876fe..7950a04532e 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -6,12 +6,12 @@ * 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, @@ -32,19 +32,56 @@ */ #include "netxen_nic.h" -#include + +#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 inline int phy_lock(void) +{ + int i; + int done = 0, timeout = 0; + + while (!done) { + done = readl((void __iomem *)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(); + } + } + + writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER); + return 0; +} + +static inline int phy_unlock(void) +{ + readl((void __iomem *)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: + * 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 + * -1 on error * */ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, @@ -56,10 +93,17 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, __le32 address; __le32 command; __le32 status; - __le32 mii_cfg; __le32 mac_cfg0; - /* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */ + if (phy_lock() != 0) { + return -1; + } + + /* + * MII mgmt all goes through port 0 MAC interface, + * so it cannot be in reset + */ + if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; @@ -77,18 +121,6 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, restore = 1; } - /* reset MII management interface */ - mii_cfg = 0; - netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); - netxen_gb_mii_mgmt_reset(mii_cfg); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0), - &mii_cfg, 4)) - return -EIO; - netxen_gb_mii_mgmt_unset(mii_cfg); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0), - &mii_cfg, 4)) - return -EIO; - address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); @@ -130,7 +162,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; - + phy_unlock(); return result; } @@ -139,12 +171,12 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, * mii management interface. * * Note: The MII management interface goes through port 0. - * Individual phys are addressed as follows: + * 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 + * -1 on error * */ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, @@ -158,7 +190,11 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, __le32 status; __le32 mac_cfg0; - /* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */ + /* + * MII mgmt all goes through port 0 MAC interface, so it + * cannot be in reset + */ + if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; @@ -382,14 +418,23 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) } } else { - /* We don't have link. Cable must be unconnected. */ - /* Enable phy interrupts so we take action when plugged in */ + /* + * We don't have link. Cable must be unconnected. + * Enable phy interrupts so we take action when + * plugged in. + */ + netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0 - (port), 0x80000000); + (port), + NETXEN_GB_MAC_SOFT_RESET); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0 - (port), 0x0000f0025); + (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, port)) printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); @@ -407,10 +452,34 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) return result; } +int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) +{ + long reg = 0, ret = 0; + + if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XG1_CONFIG_0, 0x5); + /* XXX hack for Mez cards: both ports in promisc mode */ + netxen_nic_hw_read_wx(adapter, + NETXEN_NIU_XGE_CONFIG_1, ®, 4); + reg = (reg | 0x2000UL); + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XGE_CONFIG_1, reg); + reg = 0; + netxen_nic_hw_read_wx(adapter, + NETXEN_NIU_XG1_CONFIG_1, ®, 4); + reg = (reg | 0x2000UL); + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XG1_CONFIG_1, reg); + } + + return ret; +} + /* * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts * @param enable 0 means don't enable the port - * 1 means enable (or re-enable) the port + * 1 means enable (or re-enable) the port */ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int port, long enable) @@ -421,7 +490,10 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" " (device enable = %d)\n", (int)port, (int)enable); - /* The read of the PHY INT status will clear the pending interrupt status */ + /* + * The read of the PHY INT status will clear the pending + * interrupt status + */ if (netxen_niu_gbe_phy_read(adapter, port, NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, &int_src) != 0) @@ -540,20 +612,42 @@ int netxen_niu_macaddr_set(struct netxen_port *port, __le32 temp = 0; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; + unsigned char mac_addr[MAX_ADDR_LEN]; + int i; + + for (i = 0; i < 10; i++) { + memcpy(&temp, addr, 2); + temp <<= 16; + if (netxen_nic_hw_write_wx + (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &temp, 4)) + return -EIO; - memcpy(&temp, addr, 2); - temp <<= 16; - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), - &temp, 4)) - return -EIO; + temp = 0; - temp = 0; + memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); + if (netxen_nic_hw_write_wx + (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &temp, 4)) + return -2; - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), - &temp, 4)) - return -2; + netxen_niu_macaddr_get(adapter, phy, + (netxen_ethernet_macaddr_t *) mac_addr); + if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0)) + break; + } + if (i == 10) { + printk(KERN_ERR "%s: cannot set Mac addr for %s\n", + netxen_nic_driver_name, port->netdev->name); + printk(KERN_ERR "MAC address set: " + "%02x:%02x:%02x:%02x:%02x:%02x.\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + printk(KERN_ERR "MAC address get: " + "%02x:%02x:%02x:%02x:%02x:%02x.\n", + mac_addr[0], + mac_addr[1], + mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + } return 0; } diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 863645ed1cd..8181d436783 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -6,12 +6,12 @@ * 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, @@ -58,6 +58,9 @@ #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) + /* address of command descriptors in the host memory */ #define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x30) #define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x34) @@ -82,10 +85,18 @@ #define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x94) #define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x98) #define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x9c) +#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4) /* Register for communicating XG link status */ #define CRB_XG_STATE NETXEN_NIC_REG(0xa0) +/* Register for communicating card temperature */ +/* Upper 16 bits are temperature value. Lower 16 bits are the state */ +#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8) +#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)) + /* Debug registers for controlling NIC pkt gen agent */ #define CRB_AGENT_GO NETXEN_NIC_REG(0xb0) #define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0xb4) @@ -192,4 +203,13 @@ struct netxen_recv_crb recv_crb_registers[] = { extern struct netxen_recv_crb recv_crb_registers[]; #endif /* DEFINE_GLOBAL_RECEIVE_CRB */ +/* + * 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_ */ -- cgit v1.2.3-70-g09d2 From 71bd7877d470b4037c9ef0d060ac39228f0f6289 Mon Sep 17 00:00:00 2001 From: "Amit S. Kale" Date: Fri, 1 Dec 2006 05:36:22 -0800 Subject: [PATCH] NetXen: driver cleanup, removed unnecessary __iomem type casts Signed-off-by: Amit S. Kale netxen_nic.h | 38 ++++++++------------------------------ netxen_nic_ethtool.c | 5 ++--- netxen_nic_hw.c | 12 +++++------- netxen_nic_main.c | 8 +++----- 4 files changed, 18 insertions(+), 45 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 38 +++++++-------------------------- drivers/net/netxen/netxen_nic_ethtool.c | 5 ++--- drivers/net/netxen/netxen_nic_hw.c | 12 +++++------ drivers/net/netxen/netxen_nic_main.c | 8 +++---- 4 files changed, 18 insertions(+), 45 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 1bee560d7d0..d925053fe59 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -343,7 +343,6 @@ typedef enum { NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f } netxen_brdtype_t; -#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(netxen_brdinfo_t)) typedef enum { NETXEN_BRDMFG_INVENTEC = 1 @@ -937,9 +936,7 @@ static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) /* * ISR_INT_MASK: Can be read from window 0 or 1. */ - writel(0x7ff, - (void __iomem - *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); } @@ -959,14 +956,12 @@ static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) break; } - writel(mask, - (void __iomem - *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { mask = 0xbff; - writel(mask, (void __iomem *) - (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); + writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, + ISR_INT_TARGET_MASK)); } } @@ -975,13 +970,13 @@ static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) */ #define NETXEN_MAX_SHORT_NAME 16 -typedef struct { +struct netxen_brdinfo { netxen_brdtype_t brdtype; /* type of board */ long ports; /* max no of physical ports */ char short_name[NETXEN_MAX_SHORT_NAME]; -} netxen_brdinfo_t; +}; -static const netxen_brdinfo_t netxen_boards[] = { +static const struct netxen_brdinfo netxen_boards[] = { {NETXEN_BRDTYPE_P2_SB31_10G_CX4, 1, "XGb CX4"}, {NETXEN_BRDTYPE_P2_SB31_10G_HMEZ, 1, "XGb HMEZ"}, {NETXEN_BRDTYPE_P2_SB31_10G_IMEZ, 2, "XGb IMEZ"}, @@ -990,24 +985,7 @@ static const netxen_brdinfo_t netxen_boards[] = { {NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"}, }; -#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(netxen_brdinfo_t)) - -static inline void get_brd_ports_name_by_type(u32 type, int *ports, char *name) -{ - int i, found = 0; - for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { - if (netxen_boards[i].brdtype == type) { - *ports = netxen_boards[i].ports; - strcpy(name, netxen_boards[i].short_name); - found = 1; - break; - } - } - if (!found) { - *ports = 0; - name = "Unknown"; - } -} +#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(struct netxen_brdinfo)) static inline void get_brd_port_by_type(u32 type, int *ports) { diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index f3fc35cf8af..9a914aeba5b 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -139,8 +139,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - struct netxen_board_info *boardinfo; - boardinfo = &adapter->ahw.boardcfg; + struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -208,7 +207,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->autoneg = AUTONEG_DISABLE; break; default: - printk("ERROR: Unsupported board model %d\n", + printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); return -EIO; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 99e647a5ae7..105c24f0ad4 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -275,10 +275,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) rcv_desc->desc_head = (struct rcv_desc *)addr; } - addr = netxen_alloc(adapter->ahw.pdev, - STATUS_DESC_RINGSIZE, - &recv_ctx-> - rcv_status_desc_phys_addr, + addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, + &recv_ctx->rcv_status_desc_phys_addr, &recv_ctx->rcv_status_desc_pdev); if (addr == NULL) { DPRINTK(ERR, "bad return from" @@ -675,7 +673,7 @@ void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) void __iomem *addr; netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(pci_base_offset(adapter, index)); + addr = pci_base_offset(adapter, index); writel(value, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } @@ -685,7 +683,7 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) { void __iomem *addr; - addr = (void __iomem *)(pci_base_offset(adapter, index)); + addr = pci_base_offset(adapter, index); netxen_nic_pci_change_crbwindow(adapter, 0); *value = readl(addr); @@ -865,7 +863,7 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); } else { netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(pci_base_offset(adapter, off)); + addr = pci_base_offset(adapter, off); writel(data, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cd1336e899b..1cb662d5bd7 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -969,11 +969,9 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) netxen_nic_disable_int(adapter); /* Window = 0 or 1 */ do { - writel(0xffffffff, (void __iomem *) - (PCI_OFFSET_SECOND_RANGE - (adapter, ISR_INT_TARGET_STATUS))); - mask = readl((void __iomem *) - pci_base_offset(adapter, ISR_INT_VECTOR)); + writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, + ISR_INT_TARGET_STATUS)); + mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); } while (((mask & 0x80) != 0) && (++count < 32)); if ((mask & 0x80) != 0) printk("Could not disable interrupt completely\n"); -- cgit v1.2.3-70-g09d2 From 80922fbcb6f00127e91580e7565bb665947ac5d3 Mon Sep 17 00:00:00 2001 From: "Amit S. Kale" Date: Mon, 4 Dec 2006 09:18:00 -0800 Subject: [PATCH] NetXen: whitespace cleaup and more cleanup fixes Signed-off-by: Amit S. Kale netxen_nic.h | 56 ++++++++++++++++++++-------------------------- netxen_nic_ethtool.c | 53 +++++++++++++++++++++----------------------- netxen_nic_hdr.h | 6 ++--- netxen_nic_hw.c | 54 +++++++++++++++++++++------------------------ netxen_nic_hw.h | 10 ++++---- netxen_nic_init.c | 61 +++++++++++++++++++++++++-------------------------- netxen_nic_ioctl.h | 6 ++--- netxen_nic_isr.c | 48 +++++++++++++++++----------------------- netxen_nic_main.c | 54 +++++++++++++++++---------------------------- netxen_nic_niu.c | 10 ++++---- 10 files changed, 165 insertions(+), 193 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 56 ++++++++++++++---------------- drivers/net/netxen/netxen_nic_ethtool.c | 53 ++++++++++++++-------------- drivers/net/netxen/netxen_nic_hdr.h | 6 ++-- drivers/net/netxen/netxen_nic_hw.c | 54 ++++++++++++++--------------- drivers/net/netxen/netxen_nic_hw.h | 10 +++--- drivers/net/netxen/netxen_nic_init.c | 61 ++++++++++++++++----------------- drivers/net/netxen/netxen_nic_ioctl.h | 6 ++-- drivers/net/netxen/netxen_nic_isr.c | 48 ++++++++++++-------------- drivers/net/netxen/netxen_nic_main.c | 54 ++++++++++++----------------- drivers/net/netxen/netxen_nic_niu.c | 10 +++--- 10 files changed, 165 insertions(+), 193 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d925053fe59..d51f43709cb 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 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, @@ -89,8 +89,8 @@ * normalize a 64MB crb address to 32MB PCI window * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 */ -#define NETXEN_CRB_NORMAL(reg) \ - (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST +#define NETXEN_CRB_NORMAL(reg) \ + ((reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST) #define NETXEN_CRB_NORMALIZE(adapter, reg) \ pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg)) @@ -164,7 +164,7 @@ enum { #define MAX_CMD_DESCRIPTORS 1024 #define MAX_RCV_DESCRIPTORS 32768 -#define MAX_JUMBO_RCV_DESCRIPTORS 1024 +#define MAX_JUMBO_RCV_DESCRIPTORS 4096 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS @@ -559,7 +559,7 @@ typedef enum { #define PRIMARY_START (BOOTLD_START) #define FLASH_CRBINIT_SIZE (0x4000) #define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info)) -#define FLASH_USER_SIZE (sizeof(netxen_user_info)/sizeof(u32)) +#define FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32)) #define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START) #define NUM_PRIMARY_SECTORS (0x20) #define NUM_CONFIG_SECTORS (1) @@ -572,7 +572,7 @@ typedef enum { #else #define DPRINTK(klevel, fmt, args...) do { \ printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\ - (adapter != NULL && adapter->port != NULL && \ + (adapter != NULL && \ adapter->port[0] != NULL && \ adapter->port[0]->netdev != NULL) ? \ adapter->port[0]->netdev->name : NULL, \ @@ -703,8 +703,6 @@ struct netxen_recv_context { #define NETXEN_NIC_MSI_ENABLED 0x02 -struct netxen_drvops; - struct netxen_adapter { struct netxen_hardware_context ahw; int port_count; /* Number of configured ports */ @@ -746,8 +744,21 @@ struct netxen_adapter { struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; int is_up; - int work_done; - struct netxen_drvops *ops; + int (*enable_phy_interrupts) (struct netxen_adapter *, int); + int (*disable_phy_interrupts) (struct netxen_adapter *, int); + void (*handle_phy_intr) (struct netxen_adapter *); + int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); + int (*set_mtu) (struct netxen_port *, int); + int (*set_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*unset_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *); + int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val); + int (*init_port) (struct netxen_adapter *, int); + void (*init_niu) (struct netxen_adapter *); + int (*stop_port) (struct netxen_adapter *, int); + }; /* netxen_adapter structure */ /* Max number of xmit producer threads that can run simultaneously */ @@ -829,23 +840,6 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter, return NULL; } -struct netxen_drvops { - int (*enable_phy_interrupts) (struct netxen_adapter *, int); - int (*disable_phy_interrupts) (struct netxen_adapter *, int); - void (*handle_phy_intr) (struct netxen_adapter *); - int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); - int (*set_mtu) (struct netxen_port *, int); - int (*set_promisc) (struct netxen_adapter *, int, - netxen_niu_prom_mode_t); - int (*unset_promisc) (struct netxen_adapter *, int, - netxen_niu_prom_mode_t); - int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *); - int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val); - int (*init_port) (struct netxen_adapter *, int); - void (*init_niu) (struct netxen_adapter *); - int (*stop_port) (struct netxen_adapter *, int); -}; - extern char netxen_nic_driver_name[]; int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 9a914aeba5b..c7fcbf345db 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 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, @@ -118,7 +118,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) u32 fw_minor = 0; u32 fw_build = 0; - strncpy(drvinfo->driver, "netxen_nic", 32); + strncpy(drvinfo->driver, netxen_nic_driver_name, 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_MAJOR)); @@ -210,7 +210,6 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); return -EIO; - } return 0; @@ -226,18 +225,18 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { /* autonegotiation */ - if (adapter->ops->phy_write - && adapter->ops->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) ecmd->autoneg) != 0) + if (adapter->phy_write + && adapter->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, + (__le32) ecmd->autoneg) != 0) return -EIO; else port->link_autoneg = ecmd->autoneg; - if (adapter->ops->phy_read - && adapter->ops->phy_read(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) + if (adapter->phy_read + && adapter->phy_read(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) != 0) return -EIO; /* speed */ @@ -257,10 +256,10 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) netxen_clear_phy_duplex(status); if (ecmd->duplex == DUPLEX_FULL) netxen_set_phy_duplex(status); - if (adapter->ops->phy_write - && adapter->ops->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - *((int *)&status)) != 0) + if (adapter->phy_write + && adapter->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + *((int *)&status)) != 0) return -EIO; else { port->link_speed = ecmd->speed; @@ -422,10 +421,10 @@ static u32 netxen_nic_get_link(struct net_device *dev) /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { - if (adapter->ops->phy_read - && adapter->ops->phy_read(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) + if (adapter->phy_read + && adapter->phy_read(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) != 0) return -EIO; else return (netxen_get_phy_link(status)); @@ -526,10 +525,10 @@ netxen_nic_set_pauseparam(struct net_device *dev, *(u32 *) (&val)); /* set autoneg */ autoneg = pause->autoneg; - if (adapter->ops->phy_write - && adapter->ops->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) autoneg) != 0) + if (adapter->phy_write + && adapter->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, + (__le32) autoneg) != 0) return -EIO; else { port->link_autoneg = pause->autoneg; diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 72c6ec4ee2a..fe8b675f9e7 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 105c24f0ad4..7470852ab58 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, @@ -81,8 +81,8 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) DPRINTK(INFO, "valid ether addr\n"); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - if (adapter->ops->macaddr_set) - adapter->ops->macaddr_set(port, addr->sa_data); + if (adapter->macaddr_set) + adapter->macaddr_set(port, addr->sa_data); return 0; } @@ -99,17 +99,17 @@ void netxen_nic_set_multi(struct net_device *netdev) mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { - if (adapter->ops->set_promisc) - adapter->ops->set_promisc(adapter, - port->portnum, - NETXEN_NIU_PROMISC_MODE); + if (adapter->set_promisc) + adapter->set_promisc(adapter, + port->portnum, + NETXEN_NIU_PROMISC_MODE); } else { - if (adapter->ops->unset_promisc && + if (adapter->unset_promisc && adapter->ahw.boardcfg.board_type != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) - adapter->ops->unset_promisc(adapter, - port->portnum, - NETXEN_NIU_NON_PROMISC_MODE); + adapter->unset_promisc(adapter, + port->portnum, + NETXEN_NIU_NON_PROMISC_MODE); } if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03); @@ -160,8 +160,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) return -EINVAL; } - if (adapter->ops->set_mtu) - adapter->ops->set_mtu(port, mtu); + if (adapter->set_mtu) + adapter->set_mtu(port, mtu); netdev->mtu = mtu; return 0; @@ -184,14 +184,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; - DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE, + DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); - DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM, + DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, pci_base_offset(adapter, NETXEN_CRB_CAM)); - DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE, + DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); - DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1, - pci_base_offset(adapter, NIC_CRB_BASE_PORT1)); /* Window 1 call */ card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING)); @@ -648,7 +646,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", - pci_base(adapter, off), off, addr); + pci_base(adapter, off), off, addr, val); writel(val, addr); } @@ -660,7 +658,7 @@ int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", - adapter->ahw.pci_base, off, addr); + pci_base(adapter, off), off, addr); val = readl(addr); writel(val, addr); @@ -848,8 +846,8 @@ void netxen_nic_stop_all_ports(struct netxen_adapter *adapter) for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) { port = adapter->port[port_nr]; - if (adapter->ops->stop_port) - adapter->ops->stop_port(adapter, port->portnum); + if (adapter->stop_port) + adapter->stop_port(adapter, port->portnum); } } @@ -878,8 +876,8 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ - if (adapter->ops->phy_read - && adapter->ops-> + if (adapter->phy_read + && adapter-> phy_read(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status) == 0) { @@ -909,8 +907,8 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) port->link_duplex = -1; break; } - if (adapter->ops->phy_read - && adapter->ops-> + if (adapter->phy_read + && adapter-> phy_read(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, (__le32 *) & autoneg) != 0) diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 201a636b7ab..0685633a9c1 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, @@ -83,8 +83,8 @@ struct netxen_adapter; #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) #define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ - addr = pci_base_offset(adapter, (X)); \ - *(u32 *)Y = readl(addr); + addr = pci_base_offset(adapter, X); \ + *(u32 *)Y = readl((void __iomem*) addr); struct netxen_port; void netxen_nic_set_link_parameters(struct netxen_port *port); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 0dca029bc3e..deac1a3ae27 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 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, @@ -212,37 +212,36 @@ void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) { - struct netxen_drvops *ops = adapter->ops; switch (adapter->ahw.board_type) { case NETXEN_NIC_GBE: - ops->enable_phy_interrupts = + adapter->enable_phy_interrupts = netxen_niu_gbe_enable_phy_interrupts; - ops->disable_phy_interrupts = + adapter->disable_phy_interrupts = netxen_niu_gbe_disable_phy_interrupts; - ops->handle_phy_intr = netxen_nic_gbe_handle_phy_intr; - ops->macaddr_set = netxen_niu_macaddr_set; - ops->set_mtu = netxen_nic_set_mtu_gb; - ops->set_promisc = netxen_niu_set_promiscuous_mode; - ops->unset_promisc = netxen_niu_set_promiscuous_mode; - ops->phy_read = netxen_niu_gbe_phy_read; - ops->phy_write = netxen_niu_gbe_phy_write; - ops->init_port = netxen_niu_gbe_init_port; - ops->init_niu = netxen_nic_init_niu_gb; - ops->stop_port = netxen_niu_disable_gbe_port; + adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr; + adapter->macaddr_set = netxen_niu_macaddr_set; + adapter->set_mtu = netxen_nic_set_mtu_gb; + adapter->set_promisc = netxen_niu_set_promiscuous_mode; + adapter->unset_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->init_niu = netxen_nic_init_niu_gb; + adapter->stop_port = netxen_niu_disable_gbe_port; break; case NETXEN_NIC_XGBE: - ops->enable_phy_interrupts = + adapter->enable_phy_interrupts = netxen_niu_xgbe_enable_phy_interrupts; - ops->disable_phy_interrupts = + adapter->disable_phy_interrupts = netxen_niu_xgbe_disable_phy_interrupts; - ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; - ops->macaddr_set = netxen_niu_xg_macaddr_set; - ops->set_mtu = netxen_nic_set_mtu_xgb; - ops->init_port = netxen_niu_xg_init_port; - ops->set_promisc = netxen_niu_xg_set_promiscuous_mode; - ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode; - ops->stop_port = netxen_niu_disable_xg_port; + adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; + adapter->macaddr_set = netxen_niu_xg_macaddr_set; + 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->unset_promisc = netxen_niu_xg_set_promiscuous_mode; + adapter->stop_port = netxen_niu_disable_xg_port; break; default: @@ -383,8 +382,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter) return 0; } -static inline int do_rom_fast_write(struct netxen_adapter *adapter, - int addr, int data) +static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, + int data) { if (netxen_rom_wren(adapter)) { return -1; @@ -734,8 +733,8 @@ void netxen_watchdog_task(unsigned long v) netif_wake_queue(netdev); } - if (adapter->ops->handle_phy_intr) - adapter->ops->handle_phy_intr(adapter); + if (adapter->handle_phy_intr) + adapter->handle_phy_intr(adapter); mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); } diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h index 23e53adbf12..8eef139f250 100644 --- a/drivers/net/netxen/netxen_nic_ioctl.h +++ b/drivers/net/netxen/netxen_nic_ioctl.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index ae180fee800..0f6e7b8b65d 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, @@ -84,46 +84,41 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, struct netxen_port *port; /* This should clear the interrupt source */ - if (adapter->ops->phy_read) - adapter->ops->phy_read(adapter, portno, - NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, - &int_src); + if (adapter->phy_read) + adapter->phy_read(adapter, portno, + NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, + &int_src); if (int_src == 0) { DPRINTK(INFO, "No phy interrupts for port #%d\n", portno); return; } - if (adapter->ops->disable_phy_interrupts) - adapter->ops->disable_phy_interrupts(adapter, portno); + if (adapter->disable_phy_interrupts) + adapter->disable_phy_interrupts(adapter, portno); port = adapter->port[portno]; if (netxen_get_phy_int_jabber(int_src)) - DPRINTK(INFO, "NetXen: %s Jabber interrupt \n", - port->netdev->name); + DPRINTK(INFO, "Jabber interrupt \n"); if (netxen_get_phy_int_polarity_changed(int_src)) - DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n", - port->netdev->name); + DPRINTK(INFO, "POLARITY CHANGED int \n"); if (netxen_get_phy_int_energy_detect(int_src)) - DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n", - port->netdev->name); + DPRINTK(INFO, "ENERGY DETECT INT \n"); if (netxen_get_phy_int_downshift(int_src)) - DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n", - port->netdev->name); + DPRINTK(INFO, "DOWNSHIFT INT \n"); /* write it down later.. */ if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { __le32 status; - DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR" - " LINK STATUS CHANGED \n", port->netdev->name); + DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); - if (adapter->ops->phy_read - && adapter->ops->phy_read(adapter, portno, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) == 0) { + if (adapter->phy_read + && adapter->phy_read(adapter, portno, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) == 0) { if (netxen_get_phy_int_link_status_changed(int_src)) { if (netxen_get_phy_link(status)) { netxen_niu_gbe_init_port(adapter, @@ -143,8 +138,8 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, } } } - if (adapter->ops->enable_phy_interrupts) - adapter->ops->enable_phy_interrupts(adapter, portno); + if (adapter->enable_phy_interrupts) + adapter->enable_phy_interrupts(adapter, portno); } void netxen_nic_isr_other(struct netxen_adapter *adapter) @@ -159,8 +154,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter) qg_linksup = adapter->ahw.qg_linksup; adapter->ahw.qg_linksup = val; - DPRINTK(1, INFO, "%s: link update 0x%08x\n", netxen_nic_driver_name, - val); + DPRINTK(INFO, "link update 0x%08x\n", val); for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { linkup = val & 1; if (linkup != (qg_linksup & 1)) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 1cb662d5bd7..6dbdc8be394 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 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, @@ -233,16 +233,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } - adapter->ops = kzalloc(sizeof(struct netxen_drvops), GFP_KERNEL); - if (adapter->ops == NULL) { - printk(KERN_ERR - "%s: Could not allocate memory for adapter->ops:%d\n", - netxen_nic_driver_name, - (int)sizeof(struct netxen_adapter)); - err = -ENOMEM; - goto err_out_free_rx_buffer; - } - adapter->cmd_buf_arr = cmd_buf_arr; adapter->ahw.pci_base0 = mem_ptr0; adapter->ahw.pci_base1 = mem_ptr1; @@ -373,10 +363,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr[4], netdev->dev_addr[5]); } else { - if (adapter->ops->macaddr_set) - adapter->ops->macaddr_set(port, - netdev-> - dev_addr); + if (adapter->macaddr_set) + adapter->macaddr_set(port, + netdev->dev_addr); } } INIT_WORK(&adapter->tx_timeout_task, @@ -427,7 +416,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) free_netdev(port->netdev); } } - kfree(adapter->ops); err_out_free_rx_buffer: for (i = 0; i < MAX_RCV_CTX; ++i) { @@ -525,7 +513,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) } vfree(adapter->cmd_buf_arr); - kfree(adapter->ops); kfree(adapter); } @@ -557,15 +544,15 @@ static int netxen_nic_open(struct net_device *netdev) err); return err; } - if (adapter->ops->init_port - && adapter->ops->init_port(adapter, port->portnum) != 0) { + if (adapter->init_port + && adapter->init_port(adapter, port->portnum) != 0) { printk(KERN_ERR "%s: Failed to initialize port %d\n", netxen_nic_driver_name, port->portnum); netxen_free_hw_resources(adapter); return -EIO; } - if (adapter->ops->init_niu) - adapter->ops->init_niu(adapter); + if (adapter->init_niu) + adapter->init_niu(adapter); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) netxen_post_rx_buffers(adapter, ctx, ring); @@ -591,8 +578,8 @@ static int netxen_nic_open(struct net_device *netdev) /* Done here again so that even if phantom sw overwrote it, * we set it */ - if (adapter->ops->macaddr_set) - adapter->ops->macaddr_set(port, netdev->dev_addr); + if (adapter->macaddr_set) + adapter->macaddr_set(port, netdev->dev_addr); netxen_nic_set_link_parameters(port); netxen_nic_set_multi(netdev); @@ -1039,11 +1026,12 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) int done = 1; int ctx; int this_work_done; + int work_done = 0; DPRINTK(INFO, "polling for %d descriptors\n", *budget); port->stats.polled++; - adapter->work_done = 0; + work_done = 0; for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { /* * Fairness issue. This will give undue weight to the @@ -1060,20 +1048,20 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) this_work_done = netxen_process_rcv_ring(adapter, ctx, work_to_do / MAX_RCV_CTX); - adapter->work_done += this_work_done; + work_done += this_work_done; } - netdev->quota -= adapter->work_done; - *budget -= adapter->work_done; + netdev->quota -= work_done; + *budget -= work_done; - if (adapter->work_done >= work_to_do + if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0) done = 0; netxen_process_cmd_ring((unsigned long)adapter); DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", - adapter->work_done, work_to_do); + work_done, work_to_do); if (done) { netif_rx_complete(netdev); netxen_nic_enable_int(adapter); diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 7950a04532e..ff74f1e413d 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 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 @@ -16,10 +16,10 @@ * 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, @@ -399,8 +399,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) { int result = 0; __le32 status; - if (adapter->ops->disable_phy_interrupts) - adapter->ops->disable_phy_interrupts(adapter, port); + if (adapter->disable_phy_interrupts) + adapter->disable_phy_interrupts(adapter, port); mdelay(2); if (0 == -- cgit v1.2.3-70-g09d2 From ed25ffa16434724f5ed825aa48734c7f3aefa203 Mon Sep 17 00:00:00 2001 From: "Amit S. Kale" Date: Mon, 4 Dec 2006 09:23:25 -0800 Subject: [PATCH] NetXen: multiport firmware support, ioctl interface NetXen: 1G/10G Ethernet driver updates - Multiport and newer firmware support - ioctl interface for user level tools - Cast error fix for multiport Signed-off-by: Amit S. Kale netxen_nic.h | 281 +++++++++++++++++++++++++------- netxen_nic_ethtool.c | 12 - netxen_nic_hw.c | 429 +++++++++++++++++++++++++++++++++++++++++--------- netxen_nic_init.c | 301 ++++++++++++++++++++++++++++++----- netxen_nic_ioctl.h | 2 netxen_nic_isr.c | 3 netxen_nic_main.c | 260 ++++++++++++++++++------------ netxen_nic_niu.c | 22 +- netxen_nic_phan_reg.h | 228 ++++++++++++++++---------- 9 files changed, 1161 insertions(+), 377 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 281 +++++++++++++++----- drivers/net/netxen/netxen_nic_ethtool.c | 12 +- drivers/net/netxen/netxen_nic_hw.c | 429 +++++++++++++++++++++++++------ drivers/net/netxen/netxen_nic_init.c | 301 +++++++++++++++++++--- drivers/net/netxen/netxen_nic_ioctl.h | 2 +- drivers/net/netxen/netxen_nic_isr.c | 3 +- drivers/net/netxen/netxen_nic_main.c | 260 ++++++++++++------- drivers/net/netxen/netxen_nic_niu.c | 22 +- drivers/net/netxen/netxen_nic_phan_reg.h | 228 +++++++++------- 9 files changed, 1161 insertions(+), 377 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d51f43709cb..3151aaa7906 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,27 +63,49 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "5" -#define _NETXEN_NIC_LINUX_MAJOR 2 +#define NETXEN_NIC_BUILD_NO "1" +#define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 -#define _NETXEN_NIC_LINUX_SUBVERSION 59 -#define NETXEN_NIC_LINUX_VERSIONID "2.3.59" "-" NETXEN_NIC_BUILD_NO -#define NETXEN_NIC_FW_VERSIONID "2.3.59" +#define _NETXEN_NIC_LINUX_SUBVERSION 2 +#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO +#define NETXEN_NIC_FW_VERSIONID "3.3.2" #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) #define STATUS_DESC_RINGSIZE \ (sizeof(struct status_desc)* adapter->max_rx_desc_count) +#define LRO_DESC_RINGSIZE \ + (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count) #define TX_RINGSIZE \ (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) #define RCV_BUFFSIZE \ (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) -#define NETXEN_NETDEV_STATUS 0x1 +#define NETXEN_NETDEV_STATUS 0x1 +#define NETXEN_RCV_PRODUCER_OFFSET 0 +#define NETXEN_RCV_PEG_DB_ID 2 +#define NETXEN_HOST_DUMMY_DMA_SIZE 1024 #define ADDR_IN_WINDOW1(off) \ ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 +/* + * In netxen_nic_down(), we must wait for any pending callback requests into + * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be + * reenabled right after it is deleted in netxen_nic_down(). FLUSH_SCHEDULED_WORK() + * does this synchronization. + * + * Normally, schedule_work()/flush_scheduled_work() could have worked, but + * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off() + * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a + * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause + * linkwatch_event() to be executed which also attempts to acquire the rtnl + * lock thus causing a deadlock. + */ + +#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp) +#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq) +extern struct workqueue_struct *netxen_workq; /* * normalize a 64MB crb address to 32MB PCI window @@ -95,8 +117,14 @@ #define NETXEN_CRB_NORMALIZE(adapter, reg) \ pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg)) +#define DB_NORMALIZE(adapter, off) \ + (adapter->ahw.db_base + (off)) + +#define NX_P2_C0 0x24 +#define NX_P2_C1 0x25 + #define FIRST_PAGE_GROUP_START 0 -#define FIRST_PAGE_GROUP_END 0x400000 +#define FIRST_PAGE_GROUP_END 0x100000 #define SECOND_PAGE_GROUP_START 0x4000000 #define SECOND_PAGE_GROUP_END 0x66BC000 @@ -108,11 +136,13 @@ #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START -#define MAX_RX_BUFFER_LENGTH 2000 +#define MAX_RX_BUFFER_LENGTH 1760 #define MAX_RX_JUMBO_BUFFER_LENGTH 9046 -#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN) +#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) +#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) #define RX_JUMBO_DMA_MAP_LEN \ - (MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN) + (MAX_RX_JUMBO_BUFFER_LENGTH - 2) +#define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2) #define NETXEN_ROM_ROUNDUP 0x80000000ULL /* @@ -151,30 +181,38 @@ enum { /* Host writes the following to notify that it has done the init-handshake */ #define PHAN_INITIALIZE_ACK 0xf00f -#define NUM_RCV_DESC_RINGS 2 /* No of Rcv Descriptor contexts */ +#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */ /* descriptor types */ #define RCV_DESC_NORMAL 0x01 #define RCV_DESC_JUMBO 0x02 +#define RCV_DESC_LRO 0x04 #define RCV_DESC_NORMAL_CTXID 0 #define RCV_DESC_JUMBO_CTXID 1 +#define RCV_DESC_LRO_CTXID 2 #define RCV_DESC_TYPE(ID) \ - ((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL) + ((ID == RCV_DESC_JUMBO_CTXID) \ + ? RCV_DESC_JUMBO \ + : ((ID == RCV_DESC_LRO_CTXID) \ + ? RCV_DESC_LRO : \ + (RCV_DESC_NORMAL))) #define MAX_CMD_DESCRIPTORS 1024 #define MAX_RCV_DESCRIPTORS 32768 #define MAX_JUMBO_RCV_DESCRIPTORS 4096 +#define MAX_LRO_RCV_DESCRIPTORS 2048 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS #define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS -#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS) #define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8) - +#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \ + MAX_LRO_RCV_DESCRIPTORS) #define MIN_TX_COUNT 4096 #define MIN_RX_COUNT 4096 - +#define NETXEN_CTX_SIGNATURE 0xdee0 +#define NETXEN_RCV_PRODUCER(ringid) (ringid) #define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */ #define PHAN_PEG_RCV_INITIALIZED 0xff01 @@ -186,6 +224,67 @@ enum { #define get_index_range(index,length,count) \ (((index) + (count)) & ((length) - 1)) +#define MPORT_SINGLE_FUNCTION_MODE 0x1111 + +extern unsigned long long netxen_dma_mask; + +/* + * NetXen host-peg signal message structure + * + * Bit 0-1 : peg_id => 0x2 for tx and 01 for rx + * Bit 2 : priv_id => must be 1 + * Bit 3-17 : count => for doorbell + * Bit 18-27 : ctx_id => Context id + * Bit 28-31 : opcode + */ + +typedef u32 netxen_ctx_msg; + +#define _netxen_set_bits(config_word, start, bits, val) {\ + unsigned long long mask = (((1ULL << (bits)) - 1) << (start)); \ + unsigned long long value = (val); \ + (config_word) &= ~mask; \ + (config_word) |= (((value) << (start)) & mask); \ +} + +#define netxen_set_msg_peg_id(config_word, val) \ + _netxen_set_bits(config_word, 0, 2, val) +#define netxen_set_msg_privid(config_word) \ + set_bit(2, (unsigned long*)&config_word) +#define netxen_set_msg_count(config_word, val) \ + _netxen_set_bits(config_word, 3, 15, val) +#define netxen_set_msg_ctxid(config_word, val) \ + _netxen_set_bits(config_word, 18, 10, val) +#define netxen_set_msg_opcode(config_word, val) \ + _netxen_set_bits(config_word, 28, 4, val) + +struct netxen_rcv_context { + u32 rcv_ring_addr_lo; + u32 rcv_ring_addr_hi; + u32 rcv_ring_size; + u32 rsrvd; +}; + +struct netxen_ring_ctx { + + /* one command ring */ + u64 cmd_consumer_offset; + u32 cmd_ring_addr_lo; + u32 cmd_ring_addr_hi; + u32 cmd_ring_size; + u32 rsrvd; + + /* three receive rings */ + struct netxen_rcv_context rcv_ctx[3]; + + /* one status ring */ + u32 sts_ring_addr_lo; + u32 sts_ring_addr_hi; + u32 sts_ring_size; + + u32 ctx_id; +} __attribute__ ((aligned(64))); + /* * Following data structures describe the descriptors that will be used. * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when @@ -203,22 +302,32 @@ enum { #define FLAGS_IPSEC_SA_DELETE 0x08 #define FLAGS_VLAN_TAGGED 0x10 -#define CMD_DESC_TOTAL_LENGTH(cmd_desc) \ - ((cmd_desc)->length_tcp_hdr & 0x00FFFFFF) -#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc) \ - (((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF) -#define CMD_DESC_PORT(cmd_desc) ((cmd_desc)->port_ctxid & 0x0F) -#define CMD_DESC_CTX_ID(cmd_desc) (((cmd_desc)->port_ctxid >> 4) & 0x0F) +#define netxen_set_cmd_desc_port(cmd_desc, var) \ + ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) -#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var) \ - ((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF)) -#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var) \ - ((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000)) -#define CMD_DESC_PORT_WRT(cmd_desc, var) \ - ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) +#define netxen_set_cmd_desc_flags(cmd_desc, val) \ + _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val) +#define netxen_set_cmd_desc_opcode(cmd_desc, val) \ + _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val) + +#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ + _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val); +#define netxen_set_cmd_desc_totallength(cmd_desc, val) \ + _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val); + +#define netxen_get_cmd_desc_opcode(cmd_desc) \ + (((cmd_desc)->flags_opcode >> 7) & 0x003F) +#define netxen_get_cmd_desc_totallength(cmd_desc) \ + (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF) struct cmd_desc_type0 { - u64 netxen_next; /* for fragments handled by Phantom */ + 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 */ + u16 flags_opcode; + /* Bit pattern: 0-7 total number of segments, + 8-31 Total size of the packet */ + u32 num_of_buffers_total_length; union { struct { u32 addr_low_part2; @@ -227,13 +336,6 @@ struct cmd_desc_type0 { u64 addr_buffer2; }; - /* Bit pattern: 0-23 total length, 24-32 tcp header offset */ - u32 length_tcp_hdr; - u8 ip_hdr_offset; /* For LSO only */ - u8 num_of_buffers; /* total number of segments */ - u8 flags; /* as defined above */ - u8 opcode; - u16 reference_handle; /* changed to u16 to add mss */ u16 mss; /* passed by NDIS_PACKET for LSO */ /* Bit pattern 0-3 port, 0-3 ctx id */ @@ -248,7 +350,6 @@ struct cmd_desc_type0 { }; u64 addr_buffer3; }; - union { struct { u32 addr_low_part1; @@ -270,6 +371,8 @@ struct cmd_desc_type0 { u64 addr_buffer4; }; + u64 unused; + } __attribute__ ((aligned(64))); /* Note: sizeof(rcv_desc) should always be a mutliple of 2 */ @@ -296,22 +399,49 @@ struct rcv_desc { #define NETXEN_PROT_UNKNOWN (0) /* Note: sizeof(status_desc) should always be a mutliple of 2 */ -#define STATUS_DESC_PORT(status_desc) \ - ((status_desc)->port_status_type_op & 0x0F) -#define STATUS_DESC_STATUS(status_desc) \ - (((status_desc)->port_status_type_op >> 4) & 0x0F) -#define STATUS_DESC_TYPE(status_desc) \ - (((status_desc)->port_status_type_op >> 8) & 0x0F) -#define STATUS_DESC_OPCODE(status_desc) \ - (((status_desc)->port_status_type_op >> 12) & 0x0F) + +#define netxen_get_sts_desc_lro_cnt(status_desc) \ + ((status_desc)->lro & 0x7F) +#define netxen_get_sts_desc_lro_last_frag(status_desc) \ + (((status_desc)->lro & 0x80) >> 7) + +#define netxen_get_sts_port(status_desc) \ + ((status_desc)->status_desc_data & 0x0F) +#define netxen_get_sts_status(status_desc) \ + (((status_desc)->status_desc_data >> 4) & 0x0F) +#define netxen_get_sts_type(status_desc) \ + (((status_desc)->status_desc_data >> 8) & 0x0F) +#define netxen_get_sts_totallength(status_desc) \ + (((status_desc)->status_desc_data >> 12) & 0xFFFF) +#define netxen_get_sts_refhandle(status_desc) \ + (((status_desc)->status_desc_data >> 28) & 0xFFFF) +#define netxen_get_sts_prot(status_desc) \ + (((status_desc)->status_desc_data >> 44) & 0x0F) +#define netxen_get_sts_owner(status_desc) \ + (((status_desc)->status_desc_data >> 56) & 0x03) +#define netxen_get_sts_opcode(status_desc) \ + (((status_desc)->status_desc_data >> 58) & 0x03F) + +#define netxen_clear_sts_owner(status_desc) \ + ((status_desc)->status_desc_data &= \ + ~(((unsigned long long)3) << 56 )) +#define netxen_set_sts_owner(status_desc, val) \ + ((status_desc)->status_desc_data |= \ + (((unsigned long long)((val) & 0x3)) << 56 )) struct status_desc { - /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */ - u16 port_status_type_op; - u16 total_length; /* NIC mode */ - u16 reference_handle; /* handle for the associated packet */ - /* Bit pattern: 0-1 owner, 2-5 protocol */ - u16 owner; /* Owner of the descriptor */ + /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length + 28-43 reference_handle, 44-47 protocol, 48-52 unused + 53-55 desc_cnt, 56-57 owner, 58-63 opcode + */ + u64 status_desc_data; + u32 hash_value; + u8 hash_type; + u8 msg_type; + u8 unused; + /* Bit pattern: 0-6 lro_count indicates frag sequence, + 7 last_frag indicates last frag */ + u8 lro; } __attribute__ ((aligned(8))); enum { @@ -563,7 +693,8 @@ typedef enum { #define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START) #define NUM_PRIMARY_SECTORS (0x20) #define NUM_CONFIG_SECTORS (1) -#define PFX "netxen: " +#define PFX "NetXen: " +extern char netxen_nic_driver_name[]; /* Note: Make sure to not call this before adapter->port is valid */ #if !defined(NETXEN_DEBUG) @@ -609,7 +740,6 @@ struct netxen_cmd_buffer { u8 frag_count; unsigned long time_stamp; u32 state; - u32 no_of_descriptors; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -618,6 +748,9 @@ struct netxen_rx_buffer { u64 dma; u16 ref_handle; u16 state; + u32 lro_expected_frags; + u32 lro_current_frags; + u32 lro_length; }; /* Board types */ @@ -633,6 +766,8 @@ struct netxen_hardware_context { void __iomem *pci_base0; void __iomem *pci_base1; void __iomem *pci_base2; + void __iomem *db_base; + unsigned long db_len; u8 revision_id; u16 board_type; @@ -642,14 +777,13 @@ struct netxen_hardware_context { u32 qg_linksup; /* Address of cmd ring in Phantom */ struct cmd_desc_type0 *cmd_desc_head; - char *pauseaddr; struct pci_dev *cmd_desc_pdev; dma_addr_t cmd_desc_phys_addr; - dma_addr_t pause_physaddr; - struct pci_dev *pause_pdev; struct netxen_adapter *adapter; }; +#define RCV_RING_LRO RCV_DESC_LRO + #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ #define ETHERNET_FCS_SIZE 4 @@ -702,6 +836,13 @@ struct netxen_recv_context { }; #define NETXEN_NIC_MSI_ENABLED 0x02 +#define NETXEN_DMA_MASK 0xfffffffe +#define NETXEN_DB_MAPSIZE_BYTES 0x1000 + +struct netxen_dummy_dma { + void *addr; + dma_addr_t phys_addr; +}; struct netxen_adapter { struct netxen_hardware_context ahw; @@ -711,18 +852,19 @@ struct netxen_adapter { spinlock_t tx_lock; spinlock_t lock; struct work_struct watchdog_task; - struct work_struct tx_timeout_task; + struct work_struct tx_timeout_task[NETXEN_MAX_PORTS]; struct timer_list watchdog_timer; u32 curr_window; u32 cmd_producer; - u32 cmd_consumer; + u32 *cmd_consumer; u32 last_cmd_consumer; u32 max_tx_desc_count; u32 max_rx_desc_count; u32 max_jumbo_rx_desc_count; + u32 max_lro_rx_desc_count; /* Num of instances active on cmd buffer ring */ u32 proc_cmd_buf_counter; @@ -744,6 +886,13 @@ struct netxen_adapter { struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; int is_up; + int number; + struct netxen_dummy_dma dummy_dma; + + /* Context interface shared between card and host */ + struct netxen_ring_ctx *ctx_desc; + struct pci_dev *ctx_desc_pdev; + dma_addr_t ctx_desc_phys_addr; int (*enable_phy_interrupts) (struct netxen_adapter *, int); int (*disable_phy_interrupts) (struct netxen_adapter *, int); void (*handle_phy_intr) (struct netxen_adapter *); @@ -758,7 +907,6 @@ struct netxen_adapter { int (*init_port) (struct netxen_adapter *, int); void (*init_niu) (struct netxen_adapter *); int (*stop_port) (struct netxen_adapter *, int); - }; /* netxen_adapter structure */ /* Max number of xmit producer threads that can run simultaneously */ @@ -840,8 +988,6 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter, return NULL; } -extern char netxen_nic_driver_name[]; - int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, int port); int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, @@ -880,10 +1026,20 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); +int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len); +int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len); +int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size); +int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); /* Functions from netxen_nic_init.c */ +void netxen_free_adapter_offload(struct netxen_adapter *adapter); +int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); void netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); @@ -918,7 +1074,9 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter); void netxen_watchdog_task(unsigned long v); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); -void netxen_process_cmd_ring(unsigned long data); +void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx, + u32 ringid); +int netxen_process_cmd_ring(unsigned long data); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_nic_set_multi(struct net_device *netdev); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); @@ -1012,7 +1170,6 @@ static inline void get_brd_name_by_type(u32 type, char *name) int netxen_is_flash_supported(struct netxen_adapter *adapter); int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); - extern void netxen_change_ringparam(struct netxen_adapter *adapter); extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index c7fcbf345db..2ab4885cc95 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -459,20 +459,22 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - int i, j; + int i; ring->rx_pending = 0; + ring->rx_jumbo_pending = 0; for (i = 0; i < MAX_RCV_CTX; ++i) { - for (j = 0; j < NUM_RCV_DESC_RINGS; j++) - ring->rx_pending += - adapter->recv_ctx[i].rcv_desc[j].rcv_pending; + ring->rx_pending += adapter->recv_ctx[i]. + rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending; + ring->rx_jumbo_pending += adapter->recv_ctx[i]. + rcv_desc[RCV_DESC_JUMBO_CTXID].rcv_pending; } ring->rx_max_pending = adapter->max_rx_desc_count; ring->tx_max_pending = adapter->max_tx_desc_count; + ring->rx_jumbo_max_pending = adapter->max_jumbo_rx_desc_count; ring->rx_mini_max_pending = 0; ring->rx_mini_pending = 0; - ring->rx_jumbo_max_pending = 0; ring->rx_jumbo_pending = 0; } diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 7470852ab58..9147b6048df 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -42,7 +42,7 @@ #define NETXEN_FLASH_BASE (BOOTLD_START) #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) -#define NETXEN_MAX_MTU 8000 +#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE #define NETXEN_MIN_MTU 64 #define NETXEN_ETH_FCS_SIZE 4 #define NETXEN_ENET_HEADER_SIZE 14 @@ -176,11 +176,9 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) struct netxen_hardware_context *hw = &adapter->ahw; u32 state = 0; void *addr; - void *pause_addr; int loops = 0, err = 0; int ctx, ring; u32 card_cmdring = 0; - struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; @@ -224,33 +222,42 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); addr = netxen_alloc(adapter->ahw.pdev, - sizeof(struct cmd_desc_type0) * - adapter->max_tx_desc_count, - &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev); + sizeof(struct netxen_ring_ctx) + + sizeof(uint32_t), + (dma_addr_t *) & adapter->ctx_desc_phys_addr, + &adapter->ctx_desc_pdev); + printk("ctx_desc_phys_addr: 0x%llx\n", + (u64) adapter->ctx_desc_phys_addr); if (addr == NULL) { DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); - return -ENOMEM; + err = -ENOMEM; + return err; } + memset(addr, 0, sizeof(struct netxen_ring_ctx)); + adapter->ctx_desc = (struct netxen_ring_ctx *)addr; + adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr + + sizeof(struct netxen_ring_ctx); + adapter->cmd_consumer = (uint32_t *) (((char *)addr) + + sizeof(struct netxen_ring_ctx)); + + addr = pci_alloc_consistent(adapter->ahw.pdev, + sizeof(struct cmd_desc_type0) * + adapter->max_tx_desc_count, + (dma_addr_t *) & hw->cmd_desc_phys_addr); + printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr); - pause_addr = netxen_alloc(adapter->ahw.pdev, 512, - (dma_addr_t *) & hw->pause_physaddr, - &hw->pause_pdev); - if (pause_addr == NULL) { - DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n"); + if (addr == NULL) { + DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); + netxen_free_hw_resources(adapter); return -ENOMEM; } - hw->pauseaddr = (char *)pause_addr; - { - u64 *ptr = (u64 *) pause_addr; - *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; - *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; - *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR; - *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; - *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1; - *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2; - } + adapter->ctx_desc->cmd_ring_addr_lo = + hw->cmd_desc_phys_addr & 0xffffffffUL; + adapter->ctx_desc->cmd_ring_addr_hi = + ((u64) hw->cmd_desc_phys_addr >> 32); + adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count; hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; @@ -271,6 +278,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } rcv_desc->desc_head = (struct rcv_desc *)addr; + adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo = + rcv_desc->phys_addr & 0xffffffffUL; + adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi = + ((u64) rcv_desc->phys_addr >> 32); + adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = + rcv_desc->max_rx_desc_count; } addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, @@ -284,47 +297,21 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; - for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { - rcv_desc = &recv_ctx->rcv_desc[ring]; - rcv_desc_crb = - &recv_crb_registers[ctx].rcv_desc_crb[ring]; - DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n", - ring, rcv_desc_crb->crb_globalrcv_ring); - /* Window = 1 */ - writel(lower32(rcv_desc->phys_addr), - NETXEN_CRB_NORMALIZE(adapter, - rcv_desc_crb-> - crb_globalrcv_ring)); - DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x" - " val 0x%llx," - " virt %p\n", ctx, - rcv_desc_crb->crb_globalrcv_ring, - (unsigned long long)rcv_desc->phys_addr, - +rcv_desc->desc_head); - } + adapter->ctx_desc->sts_ring_addr_lo = + recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL; + adapter->ctx_desc->sts_ring_addr_hi = + ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32); + adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count; - /* Window = 1 */ - writel(lower32(recv_ctx->rcv_status_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, - recv_crb_registers[ctx]. - crb_rcvstatus_ring)); - DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x," - " val 0x%x,virt%p\n", - ctx, - recv_crb_registers[ctx].crb_rcvstatus_ring, - (unsigned long long)recv_ctx->rcv_status_desc_phys_addr, - recv_ctx->rcv_status_desc_head); } /* Window = 1 */ - writel(lower32(hw->pause_physaddr), - NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO)); - writel(upper32(hw->pause_physaddr), - NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI)); - - writel(lower32(hw->cmd_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); - writel(upper32(hw->cmd_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI)); + + writel(lower32(adapter->ctx_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO)); + writel(upper32(adapter->ctx_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI)); + writel(NETXEN_CTX_SIGNATURE, + NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG)); return err; } @@ -334,6 +321,15 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) struct netxen_rcv_desc_ctx *rcv_desc; int ctx, ring; + if (adapter->ctx_desc != NULL) { + pci_free_consistent(adapter->ctx_desc_pdev, + sizeof(struct netxen_ring_ctx) + + sizeof(uint32_t), + adapter->ctx_desc, + adapter->ctx_desc_phys_addr); + adapter->ctx_desc = NULL; + } + if (adapter->ahw.cmd_desc_head != NULL) { pci_free_consistent(adapter->ahw.cmd_desc_pdev, sizeof(struct cmd_desc_type0) * @@ -342,11 +338,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) adapter->ahw.cmd_desc_phys_addr); adapter->ahw.cmd_desc_head = NULL; } - if (adapter->ahw.pauseaddr != NULL) { - pci_free_consistent(adapter->ahw.pause_pdev, 512, - adapter->ahw.pauseaddr, - adapter->ahw.pause_physaddr); - adapter->ahw.pauseaddr = NULL; + /* Special handling: there are 2 ports on this board */ + if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { + adapter->ahw.max_ports = 2; } for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { @@ -381,19 +375,22 @@ void netxen_tso_check(struct netxen_adapter *adapter, desc->total_hdr_length = sizeof(struct ethhdr) + ((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)); - desc->opcode = TX_TCP_LSO; + netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); } else if (skb->ip_summed == CHECKSUM_COMPLETE) { if (skb->nh.iph->protocol == IPPROTO_TCP) { - desc->opcode = TX_TCP_PKT; + netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); } else if (skb->nh.iph->protocol == IPPROTO_UDP) { - desc->opcode = TX_UDP_PKT; + netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); } else { return; } } adapter->stats.xmitcsummed++; - CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data); - desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr); + desc->tcp_hdr_offset = skb->h.raw - skb->data; + netxen_set_cmd_desc_totallength(desc, + cpu_to_le32 + (netxen_get_cmd_desc_totallength + (desc))); desc->ip_hdr_offset = skb->nh.raw - skb->data; } @@ -871,7 +868,7 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) { struct netxen_adapter *adapter = port->adapter; __le32 status; - u16 autoneg; + __le32 autoneg; __le32 mode; netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); @@ -911,7 +908,7 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) && adapter-> phy_read(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32 *) & autoneg) != 0) + &autoneg) != 0) port->link_autoneg = autoneg; } else goto link_down; @@ -1006,3 +1003,291 @@ int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off) netxen_nic_hw_read_wx(adapter, off, &data, 4); return data; } + +int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len) +{ + void *addr; + u64 offset = off; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (ADDR_IN_WINDOW1(off)) { + addr = NETXEN_CRB_NORMALIZE(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + offset = NETXEN_CRB_NORMAL(off); + mem_page = offset & PAGE_MASK; + if (mem_page != ((offset + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += offset & (PAGE_SIZE - 1); + } + } else { + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + if (mem_page != ((off + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + netxen_nic_pci_change_crbwindow(adapter, 0); + } + switch (len) { + case 1: + writeb(*(u8 *) data, addr); + break; + case 2: + writew(*(u16 *) data, addr); + break; + case 4: + writel(*(u32 *) data, addr); + break; + case 8: + writeq(*(u64 *) data, addr); + break; + default: + DPRINTK(INFO, + "writing data %lx to offset %llx, num words=%d\n", + *(unsigned long *)data, off, (len >> 3)); + + netxen_nic_hw_block_write64((u64 __iomem *) data, addr, + (len >> 3)); + break; + } + + if (!ADDR_IN_WINDOW1(off)) + netxen_nic_pci_change_crbwindow(adapter, 1); + if (mem_ptr) + iounmap(mem_ptr); + return 0; +} + +int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len) +{ + void *addr; + u64 offset; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (ADDR_IN_WINDOW1(off)) { + addr = NETXEN_CRB_NORMALIZE(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + offset = NETXEN_CRB_NORMAL(off); + mem_page = offset & PAGE_MASK; + if (mem_page != ((offset + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + *(u8 *) data = 0; + return 1; + } + addr = mem_ptr; + addr += offset & (PAGE_SIZE - 1); + } + } else { + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + if (mem_page != ((off + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) + return 1; + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + netxen_nic_pci_change_crbwindow(adapter, 0); + } + switch (len) { + case 1: + *(u8 *) data = readb(addr); + break; + case 2: + *(u16 *) data = readw(addr); + break; + case 4: + *(u32 *) data = readl(addr); + break; + case 8: + *(u64 *) data = readq(addr); + break; + default: + netxen_nic_hw_block_read64((u64 __iomem *) data, addr, + (len >> 3)); + break; + } + if (!ADDR_IN_WINDOW1(off)) + netxen_nic_pci_change_crbwindow(adapter, 1); + if (mem_ptr) + iounmap(mem_ptr); + return 0; +} + +int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int size) +{ + void *addr; + int ret = 0; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (data == NULL || off > (128 * 1024 * 1024)) { + printk(KERN_ERR "%s: data: %p off:%llx\n", + netxen_nic_driver_name, data, off); + return 1; + } + off = netxen_nic_pci_set_window(adapter, off); + /* Corner case : Malicious user tried to break the driver by reading + last few bytes in ranges and tries to read further addresses. + */ + if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { + printk(KERN_ERR "%s: Invalid access to memory address range" + " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, + off + size); + return 1; + } + addr = pci_base_offset(adapter, off); + DPRINTK(INFO, "writing data %llx to offset %llx\n", + *(unsigned long long *)data, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + /* Map two pages whenever user tries to access addresses in two + consecutive pages. + */ + if (mem_page != ((off + size - 1) & PAGE_MASK)) + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + switch (size) { + case 1: + writeb(*(u8 *) data, addr); + break; + case 2: + writew(*(u16 *) data, addr); + break; + case 4: + writel(*(u32 *) data, addr); + break; + case 8: + writeq(*(u64 *) data, addr); + break; + default: + DPRINTK(INFO, + "writing data %lx to offset %llx, num words=%d\n", + *(unsigned long *)data, off, (size >> 3)); + + netxen_nic_hw_block_write64((u64 __iomem *) data, addr, + (size >> 3)); + break; + } + + if (mem_ptr) + iounmap(mem_ptr); + DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data); + + return ret; +} + +int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size) +{ + void *addr; + int ret = 0; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (data == NULL || off > (128 * 1024 * 1024)) { + printk(KERN_ERR "%s: data: %p off:%llx\n", + netxen_nic_driver_name, data, off); + return 1; + } + off = netxen_nic_pci_set_window(adapter, off); + /* Corner case : Malicious user tried to break the driver by reading + last few bytes in ranges and tries to read further addresses. + */ + if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { + printk(KERN_ERR "%s: Invalid access to memory address range" + " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, + off + size); + return 1; + } + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + /* Map two pages whenever user tries to access addresses in two + consecutive pages. + */ + if (mem_page != ((off + size - 1) & PAGE_MASK)) + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + *(u8 *) data = 0; + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + switch (size) { + case 1: + *(u8 *) data = readb(addr); + break; + case 2: + *(u16 *) data = readw(addr); + break; + case 4: + *(u32 *) data = readl(addr); + break; + case 8: + *(u64 *) data = readq(addr); + break; + default: + netxen_nic_hw_block_read64((u64 __iomem *) data, addr, + (size >> 3)); + break; + } + + if (mem_ptr) + iounmap(mem_ptr); + DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data); + + return ret; +} diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index deac1a3ae27..f78668030ec 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -137,6 +137,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter) return err; } /* Window 1 call */ + writel(MPORT_SINGLE_FUNCTION_MODE, + NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); writel(PHAN_INITIALIZE_ACK, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); @@ -184,15 +186,12 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) for (i = 0; i < num_rx_bufs; i++) { rx_buf->ref_handle = i; rx_buf->state = NETXEN_BUFFER_FREE; - DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:" "%p\n", ctxid, i, rx_buf); rx_buf++; } } } - DPRINTK(INFO, "initialized buffers for %s and %s\n", - "adapter->free_cmd_buf_list", "adapter->free_rxbuf"); } void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) @@ -621,6 +620,43 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) return 0; } +int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) +{ + uint64_t addr; + uint32_t hi; + uint32_t lo; + + adapter->dummy_dma.addr = + pci_alloc_consistent(adapter->ahw.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", + __FUNCTION__); + return -ENOMEM; + } + + addr = (uint64_t) adapter->dummy_dma.phys_addr; + hi = (addr >> 32) & 0xffffffff; + lo = addr & 0xffffffff; + + writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI)); + writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO)); + + return 0; +} + +void netxen_free_adapter_offload(struct netxen_adapter *adapter) +{ + if (adapter->dummy_dma.addr) { + pci_free_consistent(adapter->ahw.pdev, + NETXEN_HOST_DUMMY_DMA_SIZE, + adapter->dummy_dma.addr, + adapter->dummy_dma.phys_addr); + adapter->dummy_dma.addr = NULL; + } +} + void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) { u32 val = 0; @@ -655,7 +691,8 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) desc_head = recv_ctx->rcv_status_desc_head; desc = &desc_head[consumer]; - if (((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) + if (((le16_to_cpu(netxen_get_sts_owner(desc))) + & STATUS_OWNER_HOST)) return 1; } @@ -747,19 +784,19 @@ void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, struct status_desc *desc) { - struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)]; + struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)]; struct pci_dev *pdev = port->pdev; struct net_device *netdev = port->netdev; - int index = le16_to_cpu(desc->reference_handle); + int index = le16_to_cpu(netxen_get_sts_refhandle(desc)); struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); struct netxen_rx_buffer *buffer; struct sk_buff *skb; - u32 length = le16_to_cpu(desc->total_length); + u32 length = le16_to_cpu(netxen_get_sts_totallength(desc)); u32 desc_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int ret; - desc_ctx = STATUS_DESC_TYPE(desc); + desc_ctx = netxen_get_sts_type(desc); if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { printk("%s: %s Bad Rcv descriptor ring\n", netxen_nic_driver_name, netdev->name); @@ -767,20 +804,49 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, } rcv_desc = &recv_ctx->rcv_desc[desc_ctx]; + if (unlikely(index > rcv_desc->max_rx_desc_count)) { + DPRINTK(ERR, "Got a buffer index:%x Max is %x\n", + index, rcv_desc->max_rx_desc_count); + return; + } buffer = &rcv_desc->rx_buf_arr[index]; + if (desc_ctx == RCV_DESC_LRO_CTXID) { + buffer->lro_current_frags++; + if (netxen_get_sts_desc_lro_last_frag(desc)) { + buffer->lro_expected_frags = + netxen_get_sts_desc_lro_cnt(desc); + buffer->lro_length = length; + } + if (buffer->lro_current_frags != buffer->lro_expected_frags) { + if (buffer->lro_expected_frags != 0) { + printk("LRO: (refhandle:%x) recv frag." + "wait for last. flags: %x expected:%d" + "have:%d\n", index, + netxen_get_sts_desc_lro_last_frag(desc), + buffer->lro_expected_frags, + buffer->lro_current_frags); + } + return; + } + } pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); skb = (struct sk_buff *)buffer->skb; - if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) { + if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) { port->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; - } else - skb->ip_summed = CHECKSUM_NONE; + } skb->dev = netdev; - skb_put(skb, length); + if (desc_ctx == RCV_DESC_LRO_CTXID) { + /* True length was only available on the last pkt */ + skb_put(skb, buffer->lro_length); + } else { + skb_put(skb, length); + } + skb->protocol = eth_type_trans(skb, netdev); ret = netif_receive_skb(skb); @@ -826,6 +892,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, adapter->stats.post_called++; buffer->skb = NULL; buffer->state = NETXEN_BUFFER_FREE; + buffer->lro_current_frags = 0; + buffer->lro_expected_frags = 0; port->stats.no_rcv++; port->stats.rxbytes += length; @@ -838,6 +906,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) struct status_desc *desc_head = recv_ctx->rcv_status_desc_head; struct status_desc *desc; /* used to read status desc here */ u32 consumer = recv_ctx->status_rx_consumer; + u32 producer = 0; int count = 0, ring; DPRINTK(INFO, "procesing receive\n"); @@ -849,18 +918,22 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) */ while (count < max) { desc = &desc_head[consumer]; - if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) { - DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner); + if (! + (le16_to_cpu(netxen_get_sts_owner(desc)) & + STATUS_OWNER_HOST)) { + DPRINTK(ERR, "desc %p ownedby %x\n", desc, + netxen_get_sts_owner(desc)); break; } netxen_process_rcv(adapter, ctxid, desc); - desc->owner = STATUS_OWNER_PHANTOM; + netxen_clear_sts_owner(desc); + netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } if (count) { for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { - netxen_post_rx_buffers(adapter, ctxid, ring); + netxen_post_rx_buffers_nodb(adapter, ctxid, ring); } } @@ -868,6 +941,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) if (count) { adapter->stats.process_rcv++; recv_ctx->status_rx_consumer = consumer; + recv_ctx->status_rx_producer = producer; /* Window = 1 */ writel(consumer, @@ -880,12 +954,13 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) } /* Process Command status ring */ -void netxen_process_cmd_ring(unsigned long data) +int netxen_process_cmd_ring(unsigned long data) { u32 last_consumer; u32 consumer; struct netxen_adapter *adapter = (struct netxen_adapter *)data; - int count = 0; + int count1 = 0; + int count2 = 0; struct netxen_cmd_buffer *buffer; struct netxen_port *port; /* port #1 */ struct netxen_port *nport; @@ -894,6 +969,7 @@ void netxen_process_cmd_ring(unsigned long data) u32 i; struct sk_buff *skb = NULL; int p; + int done; spin_lock(&adapter->tx_lock); last_consumer = adapter->last_cmd_consumer; @@ -903,14 +979,13 @@ void netxen_process_cmd_ring(unsigned long data) * number as part of the descriptor. This way we will be able to get * the netdev which is associated with that device. */ - consumer = - readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); + consumer = *(adapter->cmd_consumer); if (last_consumer == consumer) { /* Ring is empty */ DPRINTK(INFO, "last_consumer %d == consumer %d\n", last_consumer, consumer); spin_unlock(&adapter->tx_lock); - return; + return 1; } adapter->proc_cmd_buf_counter++; @@ -921,7 +996,7 @@ void netxen_process_cmd_ring(unsigned long data) */ spin_unlock(&adapter->tx_lock); - while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) { + while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { buffer = &adapter->cmd_buf_arr[last_consumer]; port = adapter->port[buffer->port]; pdev = port->pdev; @@ -947,24 +1022,25 @@ void netxen_process_cmd_ring(unsigned long data) && netif_carrier_ok(port->netdev)) && ((jiffies - port->netdev->trans_start) > port->netdev->watchdog_timeo)) { - schedule_work(&port->adapter->tx_timeout_task); + SCHEDULE_WORK(port->adapter->tx_timeout_task + + port->portnum); } last_consumer = get_next_index(last_consumer, adapter->max_tx_desc_count); - count++; + count1++; } - adapter->stats.noxmitdone += count; + adapter->stats.noxmitdone += count1; - count = 0; + count2 = 0; spin_lock(&adapter->tx_lock); if ((--adapter->proc_cmd_buf_counter) == 0) { adapter->last_cmd_consumer = last_consumer; while ((adapter->last_cmd_consumer != consumer) - && (count < MAX_STATUS_HANDLE)) { + && (count2 < MAX_STATUS_HANDLE)) { buffer = &adapter->cmd_buf_arr[adapter->last_cmd_consumer]; - count++; + count2++; if (buffer->skb) break; else @@ -973,7 +1049,7 @@ void netxen_process_cmd_ring(unsigned long data) adapter->max_tx_desc_count); } } - if (count) { + if (count1 || count2) { for (p = 0; p < adapter->ahw.max_ports; p++) { nport = adapter->port[p]; if (netif_queue_stopped(nport->netdev) @@ -983,10 +1059,30 @@ void netxen_process_cmd_ring(unsigned long data) } } } + /* + * If everything is freed up to consumer then check if the ring is full + * If the ring is full then check if more needs to be freed and + * schedule the call back again. + * + * This happens when there are 2 CPUs. One could be freeing and the + * other filling it. If the ring is full when we get out of here and + * the card has already interrupted the host then the host can miss the + * interrupt. + * + * There is still a possible race condition and the host could miss an + * interrupt. The card has to take care of this. + */ + if (adapter->last_cmd_consumer == consumer && + (((adapter->cmd_producer + 1) % + adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) { + consumer = *(adapter->cmd_consumer); + } + done = (adapter->last_cmd_consumer == consumer); spin_unlock(&adapter->tx_lock); DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer, __FUNCTION__); + return (done); } /* @@ -998,17 +1094,16 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) struct sk_buff *skb; struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); struct netxen_rcv_desc_ctx *rcv_desc = NULL; - struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx]; - struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; - u32 producer; + uint producer; struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; int index = 0; + netxen_ctx_msg msg = 0; + dma_addr_t dma; adapter->stats.post_called++; rcv_desc = &recv_ctx->rcv_desc[ringid]; - rcv_desc_crb = &crbarea->rcv_desc_crb[ringid]; producer = rcv_desc->producer; index = rcv_desc->begin_alloc; @@ -1018,6 +1113,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) skb = dev_alloc_skb(rcv_desc->skb_size); if (unlikely(!skb)) { /* + * TODO * We need to schedule the posting of buffers to the pegs. */ rcv_desc->begin_alloc = index; @@ -1025,9 +1121,105 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) " allocated only %d buffers\n", count); break; } + + count++; /* now there should be no failure */ + pdesc = &rcv_desc->desc_head[producer]; + +#if defined(XGB_DEBUG) + *(unsigned long *)(skb->head) = 0xc0debabe; + if (skb_is_nonlinear(skb)) { + printk("Allocated SKB @%p is nonlinear\n"); + } +#endif + skb_reserve(skb, 2); + /* This will be setup when we receive the + * buffer after it has been filled FSL TBD TBD + * skb->dev = netdev; + */ + dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, + PCI_DMA_FROMDEVICE); + pdesc->addr_buffer = dma; + buffer->skb = skb; + buffer->state = NETXEN_BUFFER_BUSY; + buffer->dma = dma; + /* make a rcv descriptor */ + pdesc->reference_handle = buffer->ref_handle; + pdesc->buffer_length = rcv_desc->dma_size; + DPRINTK(INFO, "done writing descripter\n"); + producer = + get_next_index(producer, rcv_desc->max_rx_desc_count); + index = get_next_index(index, rcv_desc->max_rx_desc_count); + buffer = &rcv_desc->rx_buf_arr[index]; + } + /* if we did allocate buffers, then write the count to Phantom */ + if (count) { + rcv_desc->begin_alloc = index; + rcv_desc->rcv_pending += count; + adapter->stats.lastposted = count; + adapter->stats.posted += count; + rcv_desc->producer = producer; + if (rcv_desc->rcv_free >= 32) { + rcv_desc->rcv_free = 0; + /* Window = 1 */ + writel((producer - 1) & + (rcv_desc->max_rx_desc_count - 1), + NETXEN_CRB_NORMALIZE(adapter, + recv_crb_registers[0]. + rcv_desc_crb[ringid]. + crb_rcv_producer_offset)); + /* + * Write a doorbell msg to tell phanmon of change in + * receive ring producer + */ + netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID); + netxen_set_msg_privid(msg); + netxen_set_msg_count(msg, + ((producer - + 1) & (rcv_desc-> + max_rx_desc_count - 1))); + netxen_set_msg_ctxid(msg, 0); + netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); + writel(msg, + DB_NORMALIZE(adapter, + NETXEN_RCV_PRODUCER_OFFSET)); + } + } +} + +void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, + uint32_t ringid) +{ + struct pci_dev *pdev = adapter->ahw.pdev; + struct sk_buff *skb; + struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); + struct netxen_rcv_desc_ctx *rcv_desc = NULL; + u32 producer; + struct rcv_desc *pdesc; + struct netxen_rx_buffer *buffer; + int count = 0; + int index = 0; + + adapter->stats.post_called++; + rcv_desc = &recv_ctx->rcv_desc[ringid]; + + producer = rcv_desc->producer; + index = rcv_desc->begin_alloc; + buffer = &rcv_desc->rx_buf_arr[index]; + /* We can start writing rx descriptors into the phantom memory. */ + while (buffer->state == NETXEN_BUFFER_FREE) { + skb = dev_alloc_skb(rcv_desc->skb_size); + if (unlikely(!skb)) { + /* + * We need to schedule the posting of buffers to the pegs. + */ + rcv_desc->begin_alloc = index; + DPRINTK(ERR, "netxen_post_rx_buffers_nodb: " + " allocated only %d buffers\n", count); + break; + } count++; /* now there should be no failure */ pdesc = &rcv_desc->desc_head[producer]; - skb_reserve(skb, NET_IP_ALIGN); + skb_reserve(skb, 2); /* * This will be setup when we receive the * buffer after it has been filled @@ -1038,6 +1230,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) buffer->dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); + /* make a rcv descriptor */ pdesc->reference_handle = le16_to_cpu(buffer->ref_handle); pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size); @@ -1062,7 +1255,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) writel((producer - 1) & (rcv_desc->max_rx_desc_count - 1), NETXEN_CRB_NORMALIZE(adapter, - rcv_desc_crb-> + recv_crb_registers[0]. + rcv_desc_crb[ringid]. crb_rcv_producer_offset)); wmb(); } @@ -1195,8 +1389,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, switch (data.cmd) { case netxen_nic_cmd_pci_read: - if ((retval = netxen_nic_hw_read_wx(adapter, data.off, - &(data.u), data.size))) + if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off, + &(data.u), data.size))) goto error_out; if (copy_to_user ((void __user *)&(up_data->u), &(data.u), data.size)) { @@ -1209,8 +1403,35 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, break; case netxen_nic_cmd_pci_write: - data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u), - data.size); + if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off, + &(data.u), data.size))) + goto error_out; + data.rv = 0; + break; + + case netxen_nic_cmd_pci_mem_read: + if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u), + data.size)) { + DPRINTK(ERR, "Failed to read the data.\n"); + retval = -EFAULT; + goto error_out; + } + if (copy_to_user + ((void __user *)&(up_data->u), &(data.u), data.size)) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + data.rv = 0; + break; + + case netxen_nic_cmd_pci_mem_write: + if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off, + &(data.u), + data.size))) + goto error_out; + data.rv = 0; break; case netxen_nic_cmd_pci_config_read: @@ -1295,7 +1516,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, retval = -EOPNOTSUPP; goto error_out; } - put_user(data.rv, (u16 __user *) (&(up_data->rv))); + put_user(data.rv, (&(up_data->rv))); DPRINTK(INFO, "done ioctl for %p well.\n", adapter); error_out: diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h index 8eef139f250..1221fa52755 100644 --- a/drivers/net/netxen/netxen_nic_ioctl.h +++ b/drivers/net/netxen/netxen_nic_ioctl.h @@ -36,7 +36,7 @@ #define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) #define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) #define NETXEN_NIC_NAME_LEN 16 -#define NETXEN_NIC_NAME_RSP "NETXEN" +#define NETXEN_NIC_NAME_RSP "NETXEN-UNM" typedef enum { netxen_nic_cmd_none = 0, diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 0f6e7b8b65d..1b45f50fa6a 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -68,8 +68,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, u32 link) { - struct netxen_port *pport = adapter->port[portno]; - struct net_device *netdev = pport->netdev; + struct net_device *netdev = (adapter->port[portno])->netdev; if (link) netif_carrier_on(netdev); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6dbdc8be394..06c4778f520 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -32,6 +32,7 @@ */ #include +#include #include "netxen_nic_hw.h" #include "netxen_nic.h" @@ -48,14 +49,21 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); -char netxen_nic_driver_name[] = "netxen"; +char netxen_nic_driver_name[] = "netxen-nic"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " NETXEN_NIC_LINUX_VERSIONID; +struct netxen_adapter *g_adapter = NULL; + #define NETXEN_NETDEV_WEIGHT 120 #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 +u8 nx_p2_id = NX_P2_C0; + +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#define DMA_35BIT_MASK 0x00000007ffffffffULL + /* Local functions to NetXen NIC driver */ static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -87,6 +95,9 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); +struct workqueue_struct *netxen_workq; +static void netxen_watchdog(unsigned long); + /* * netxen_nic_probe() * @@ -105,20 +116,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *netdev = NULL; struct netxen_adapter *adapter = NULL; struct netxen_port *port = NULL; - u8 *mem_ptr0 = NULL; - u8 *mem_ptr1 = NULL; - u8 *mem_ptr2 = NULL; + void __iomem *mem_ptr0 = NULL; + void __iomem *mem_ptr1 = NULL; + void __iomem *mem_ptr2 = NULL; - unsigned long mem_base, mem_len; + u8 *db_ptr = NULL; + unsigned long mem_base, mem_len, db_base, db_len; int pci_using_dac, i, err; int ring; struct netxen_recv_context *recv_ctx = NULL; struct netxen_rcv_desc_ctx *rcv_desc = NULL; struct netxen_cmd_buffer *cmd_buf_arr = NULL; u64 mac_addr[FLASH_NUM_PORTS + 1]; - int valid_mac; + int valid_mac = 0; + static int netxen_cards_found = 0; printk(KERN_INFO "%s \n", netxen_nic_driver_string); + /* In current scheme, we use only PCI function 0 */ + if (PCI_FUNC(pdev->devfn) != 0) { + DPRINTK(ERR, "NetXen function %d will not be enabled.\n", + PCI_FUNC(pdev->devfn)); + return -ENODEV; + } if ((err = pci_enable_device(pdev))) return err; if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { @@ -130,10 +149,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_disable_pdev; pci_set_master(pdev); - if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) && - (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0)) + pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id); + if (nx_p2_id == NX_P2_C1 && + (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && + (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { pci_using_dac = 1; - else { + } else { if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) goto err_out_free_res; @@ -153,21 +174,34 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { - DPRINTK(1, ERR, + DPRINTK(ERR, "Cannot remap adapter memory aborting.:" "0 -> %p, 1 -> %p, 2 -> %p\n", mem_ptr0, mem_ptr1, mem_ptr2); err = -EIO; - if (mem_ptr0) - iounmap(mem_ptr0); - if (mem_ptr1) - iounmap(mem_ptr1); - if (mem_ptr2) - iounmap(mem_ptr2); - - goto err_out_free_res; + goto err_out_iounmap; + } + db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ + db_len = pci_resource_len(pdev, 4); + + if (db_len == 0) { + printk(KERN_ERR "%s: doorbell is disabled\n", + netxen_nic_driver_name); + err = -EIO; + goto err_out_iounmap; + } + DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base, + db_len); + + db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); + if (db_ptr == 0UL) { + printk(KERN_ERR "%s: Failed to allocate doorbell map.", + netxen_nic_driver_name); + err = -EIO; + goto err_out_iounmap; } + DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); /* * Allocate a adapter structure which will manage all the initialization @@ -183,17 +217,24 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_nic_driver_name, (int)sizeof(struct netxen_adapter)); err = -ENOMEM; - goto err_out_iounmap; + goto err_out_dbunmap; } + if (netxen_cards_found == 0) { + g_adapter = adapter; + } adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; + adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; pci_set_drvdata(pdev, adapter); cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); if (cmd_buf_arr == NULL) { + printk(KERN_ERR + "%s: Could not allocate cmd_buf_arr memory:%d\n", + netxen_nic_driver_name, (int)TX_RINGSIZE); err = -ENOMEM; goto err_out_free_adapter; } @@ -220,11 +261,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; break; + case RCV_RING_LRO: + rcv_desc->max_rx_desc_count = + adapter->max_lro_rx_desc_count; + rcv_desc->flags = RCV_DESC_LRO; + rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; + rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; + break; + } rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) vmalloc(RCV_BUFFSIZE); if (rcv_desc->rx_buf_arr == NULL) { + printk(KERN_ERR "%s: Could not allocate" + "rcv_desc->rx_buf_arr memory:%d\n", + netxen_nic_driver_name, + (int)RCV_BUFFSIZE); err = -ENOMEM; goto err_out_free_rx_buffer; } @@ -237,16 +290,17 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.pci_base0 = mem_ptr0; adapter->ahw.pci_base1 = mem_ptr1; adapter->ahw.pci_base2 = mem_ptr2; + adapter->ahw.db_base = db_ptr; + adapter->ahw.db_len = db_len; spin_lock_init(&adapter->tx_lock); spin_lock_init(&adapter->lock); + netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ #ifdef CONFIG_IA64 netxen_pinit_from_rom(adapter, 0); udelay(500); netxen_load_firmware(adapter); #endif - /* initialize the buffers in adapter */ - netxen_initialize_adapter_sw(adapter); /* * Set the CRB window to invalid. If any register in window 0 is * accessed it should set the window to 0 and then reset it to 1. @@ -268,7 +322,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (void (*)(void *))netxen_watchdog_task, adapter); adapter->ahw.pdev = pdev; adapter->proc_cmd_buf_counter = 0; - pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id); + adapter->ahw.revision_id = nx_p2_id; if (pci_enable_msi(pdev)) { adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; @@ -290,6 +344,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); + /* do this before waking up pegs so that we have valid dummy dma addr */ + err = netxen_initialize_adapter_offload(adapter); + if (err) { + goto err_out_free_dev; + } + /* Unlock the HW, prompting the boot sequence */ writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); @@ -298,6 +358,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); /* initialize the all the ports */ + adapter->active_ports = 0; for (i = 0; i < adapter->ahw.max_ports; i++) { netdev = alloc_etherdev(sizeof(struct netxen_port)); @@ -368,7 +429,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr); } } - INIT_WORK(&adapter->tx_timeout_task, + INIT_WORK(adapter->tx_timeout_task + i, (void (*)(void *))netxen_tx_timeout_task, netdev); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -381,7 +442,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_dev; } adapter->port_count++; - adapter->active_ports = 0; adapter->port[i] = port; } @@ -402,6 +462,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + adapter->number = netxen_cards_found; adapter->driver_mismatch = 0; return 0; @@ -417,6 +478,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } + netxen_free_adapter_offload(adapter); + err_out_free_rx_buffer: for (i = 0; i < MAX_RCV_CTX; ++i) { recv_ctx = &adapter->recv_ctx[i]; @@ -428,19 +491,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } } - vfree(cmd_buf_arr); - kfree(adapter->port); - err_out_free_adapter: pci_set_drvdata(pdev, NULL); kfree(adapter); + err_out_dbunmap: + if (db_ptr) + iounmap(db_ptr); + err_out_iounmap: - iounmap(mem_ptr0); - iounmap(mem_ptr1); - iounmap(mem_ptr2); + if (mem_ptr0) + iounmap(mem_ptr0); + if (mem_ptr1) + iounmap(mem_ptr1); + if (mem_ptr2) + iounmap(mem_ptr2); err_out_free_res: pci_release_regions(pdev); @@ -465,12 +532,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_nic_stop_all_ports(adapter); /* leave the hw in the same state as reboot */ - netxen_pinit_from_rom(adapter, 0); - udelay(500); netxen_load_firmware(adapter); - - if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) - netxen_nic_disable_int(adapter); + netxen_free_adapter_offload(adapter); udelay(500); /* Delay for a while to drain the DMA engines */ for (i = 0; i < adapter->port_count; i++) { @@ -487,6 +550,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) netxen_free_hw_resources(adapter); + iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); iounmap(adapter->ahw.pci_base1); iounmap(adapter->ahw.pci_base2); @@ -534,6 +598,8 @@ static int netxen_nic_open(struct net_device *netdev) return -EIO; } netxen_nic_flash_print(adapter); + if (adapter->init_niu) + adapter->init_niu(adapter); /* setup all the resources for the Phantom... */ /* this include the descriptors for rcv, tx, and status */ @@ -551,25 +617,24 @@ static int netxen_nic_open(struct net_device *netdev) netxen_free_hw_resources(adapter); return -EIO; } - if (adapter->init_niu) - adapter->init_niu(adapter); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) netxen_post_rx_buffers(adapter, ctx, ring); } - adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; - } - adapter->active_ports++; - if (adapter->active_ports == 1) { + adapter->irq = adapter->ahw.pdev->irq; err = request_irq(adapter->ahw.pdev->irq, &netxen_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); - adapter->active_ports--; + netxen_free_hw_resources(adapter); return err; } - adapter->irq = adapter->ahw.pdev->irq; + + adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; + } + adapter->active_ports++; + if (adapter->active_ports == 1) { if (!adapter->driver_mismatch) mod_timer(&adapter->watchdog_timer, jiffies); @@ -583,6 +648,9 @@ static int netxen_nic_open(struct net_device *netdev) netxen_nic_set_link_parameters(port); netxen_nic_set_multi(netdev); + if (adapter->set_mtu) + adapter->set_mtu(port, netdev->mtu); + if (!adapter->driver_mismatch) netif_start_queue(netdev); @@ -635,6 +703,7 @@ static int netxen_nic_close(struct net_device *netdev) } cmd_buff++; } + FLUSH_SCHEDULED_WORK(); del_timer_sync(&adapter->watchdog_timer); } @@ -655,7 +724,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct cmd_desc_type0 *hwdesc; int k; struct netxen_cmd_buffer *pbuf = NULL; - unsigned int tries = 0; static int dropped_packet = 0; int frag_count; u32 local_producer = 0; @@ -717,7 +785,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)) + sizeof(struct ethhdr) > - (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { + (sizeof(struct cmd_desc_type0) - 2)) { no_of_desc++; } } @@ -728,27 +796,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if ((k + no_of_desc) >= ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : last_cmd_consumer)) { + port->stats.nocmddescriptor++; + DPRINTK(ERR, "No command descriptors available," + " producer = %d, consumer = %d count=%llu," + " dropping packet\n", producer, + adapter->last_cmd_consumer, + port->stats.nocmddescriptor); + + netif_stop_queue(netdev); + port->flags |= NETXEN_NETDEV_STATUS; spin_unlock_bh(&adapter->tx_lock); - if (tries == 0) { - local_bh_disable(); - netxen_process_cmd_ring((unsigned long)adapter); - local_bh_enable(); - ++tries; - goto retry_getting_window; - } else { - port->stats.nocmddescriptor++; - DPRINTK(ERR, "No command descriptors available," - " producer = %d, consumer = %d count=%llu," - " dropping packet\n", producer, - adapter->last_cmd_consumer, - port->stats.nocmddescriptor); - - spin_lock_bh(&adapter->tx_lock); - netif_stop_queue(netdev); - port->flags |= NETXEN_NETDEV_STATUS; - spin_unlock_bh(&adapter->tx_lock); - return NETDEV_TX_BUSY; - } + return NETDEV_TX_BUSY; } k = get_index_range(k, max_tx_desc_count, no_of_desc); adapter->cmd_producer = k; @@ -770,7 +828,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->mss = 0; hwdesc->mss = 0; } - pbuf->no_of_descriptors = no_of_desc; pbuf->total_length = skb->len; pbuf->skb = skb; pbuf->cmd = TX_ETHER_PKT; @@ -780,11 +837,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); buffrag->length = first_seg_len; - CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len); - hwdesc->num_of_buffers = frag_count; - hwdesc->opcode = TX_ETHER_PKT; + netxen_set_cmd_desc_totallength(hwdesc, skb->len); + netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); + netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); - CMD_DESC_PORT_WRT(hwdesc, port->portnum); + netxen_set_cmd_desc_port(hwdesc, port->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -843,12 +900,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* For LSO, we need to copy the MAC/IP/TCP headers into * the descriptor ring */ - if (hw->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) { + if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer]) + == TX_TCP_LSO) { int hdr_len, first_hdr_len, more_hdr; hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length; - if (hdr_len > (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { - first_hdr_len = - sizeof(struct cmd_desc_type0) - NET_IP_ALIGN; + 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; @@ -858,7 +915,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) hwdesc = &hw->cmd_desc_head[producer]; /* copy the first 64 bytes */ - memcpy(((void *)hwdesc) + NET_IP_ALIGN, + memcpy(((void *)hwdesc) + 2, (void *)(skb->data), first_hdr_len); producer = get_next_index(producer, max_tx_desc_count); @@ -874,7 +931,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } spin_lock_bh(&adapter->tx_lock); port->stats.txbytes += - CMD_DESC_TOTAL_LENGTH(&hw->cmd_desc_head[saved_producer]); + netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); /* Code to update the adapter considering how many producer threads are currently working */ if ((--adapter->num_threads) == 0) { @@ -884,20 +941,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); wmb(); adapter->total_threads = 0; - } else { - u32 crb_producer = 0; - crb_producer = - readl(NETXEN_CRB_NORMALIZE - (adapter, CRB_CMD_PRODUCER_OFFSET)); - if (crb_producer == local_producer) { - crb_producer = get_index_range(crb_producer, - max_tx_desc_count, - no_of_desc); - writel(crb_producer, - NETXEN_CRB_NORMALIZE(adapter, - CRB_CMD_PRODUCER_OFFSET)); - wmb(); - } } port->stats.xmitfinished++; @@ -914,15 +957,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) static void netxen_watchdog(unsigned long v) { struct netxen_adapter *adapter = (struct netxen_adapter *)v; - schedule_work(&adapter->watchdog_task); + if (adapter != g_adapter) { + printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n", + __FUNCTION__, adapter, g_adapter); + return; + } + + SCHEDULE_WORK(&adapter->watchdog_task); } static void netxen_tx_timeout(struct net_device *netdev) { struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); - struct netxen_adapter *adapter = port->adapter; - schedule_work(&adapter->tx_timeout_task); + SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum); } static void netxen_tx_timeout_task(struct net_device *netdev) @@ -953,6 +1001,11 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { int count = 0; u32 mask; + mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); + if ((mask & 0x80) == 0) { + /* not our interrupt */ + return ret; + } netxen_nic_disable_int(adapter); /* Window = 0 or 1 */ do { @@ -1012,7 +1065,10 @@ irqreturn_t netxen_intr(int irq, void *data) netdev = port->netdev; /* process our status queue (for all 4 ports) */ - netxen_handle_int(adapter, netdev); + if (netif_running(netdev)) { + netxen_handle_int(adapter, netdev); + break; + } } return IRQ_HANDLED; @@ -1054,11 +1110,11 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) netdev->quota -= work_done; *budget -= work_done; - if (work_done >= work_to_do - && netxen_nic_rx_has_work(adapter) != 0) + if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0) done = 0; - netxen_process_cmd_ring((unsigned long)adapter); + if (netxen_process_cmd_ring((unsigned long)adapter) == 0) + done = 0; DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", work_done, work_to_do); @@ -1104,8 +1160,9 @@ netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) if (ifr->ifr_data) { sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, port->portnum); - nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name, - NETXEN_NIC_NAME_LEN); + nr_bytes = + copy_to_user((char __user *)ifr->ifr_data, dev_name, + NETXEN_NIC_NAME_LEN); if (nr_bytes) err = -EIO; @@ -1132,6 +1189,9 @@ static struct pci_driver netxen_driver = { static int __init netxen_init_module(void) { + if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0) + return -ENOMEM; + return pci_module_init(&netxen_driver); } @@ -1142,7 +1202,7 @@ static void __exit netxen_exit_module(void) /* * Wait for some time to allow the dma to drain, if any. */ - mdelay(5); + destroy_workqueue(netxen_workq); pci_unregister_driver(&netxen_driver); } diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index ff74f1e413d..4987dc765d9 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -40,13 +40,15 @@ static long phy_lock_timeout = 100000000; -static inline int phy_lock(void) +static inline int phy_lock(struct netxen_adapter *adapter) { int i; int done = 0, timeout = 0; while (!done) { - done = readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); + done = + readl(pci_base_offset + (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK))); if (done == 1) break; if (timeout >= phy_lock_timeout) { @@ -61,13 +63,15 @@ static inline int phy_lock(void) } } - writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER); + writel(PHY_LOCK_DRIVER, + NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID)); return 0; } -static inline int phy_unlock(void) +static inline int phy_unlock(struct netxen_adapter *adapter) { - readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); + readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK))); + return 0; } @@ -95,7 +99,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, __le32 status; __le32 mac_cfg0; - if (phy_lock() != 0) { + if (phy_lock(adapter) != 0) { return -1; } @@ -162,7 +166,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; - phy_unlock(); + phy_unlock(adapter); return result; } @@ -612,7 +616,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port, __le32 temp = 0; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; - unsigned char mac_addr[MAX_ADDR_LEN]; + unsigned char mac_addr[6]; int i; for (i = 0; i < 10; i++) { @@ -631,7 +635,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port, netxen_niu_macaddr_get(adapter, phy, (netxen_ethernet_macaddr_t *) mac_addr); - if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0)) + if (memcmp(mac_addr, addr, 6) == 0) break; } diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 8181d436783..7879f855af0 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -33,15 +33,74 @@ /* * 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)) -/* - * The following 2 are the base adresses for the CRB registers and their - * offsets will be added to get addresses for the index addresses. - */ -#define NIC_CRB_BASE_PORT1 NETXEN_CAM_RAM(0x200) -#define NIC_CRB_BASE_PORT2 NETXEN_CAM_RAM(0x250) +#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) /* C0 EPG BUG */ +#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) +#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x18) /* host add:cmd ring */ +#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x1c) +#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */ +#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) /* phantom init status */ +#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) /* interrupt coalescing */ +#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_AGENT_GO NETXEN_NIC_REG(0x98) /* NIC pkt gen agent */ +#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) /* Debug -performance */ +#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) /* LRO On/OFF */ +#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0) +#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */ +#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8) +#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_PEG_CMD_CONS NETXEN_NIC_REG(0xe8) +#define CRB_HOST_BUFFER_PROD 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 NETXEN_NIC_REG(X) (NIC_CRB_BASE_PORT1+(X)) +#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac) +#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) +#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4) /* * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address @@ -51,74 +110,20 @@ * on the Phantom. */ -#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00) -#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04) - -/* point to the indexes */ -#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) - -/* address of command descriptors in the host memory */ -#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x30) -#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x34) - -/* The following 4 CRB registers are for doing performance coal */ -#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x38) -#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x3c) -#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x40) -#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x44) - -/* Needed by the host to find out the state of Phantom's initialization */ -#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x4c) -#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50) -#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x54) - -/* Interrupt coalescing parameters */ -#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x80) -#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x84) -#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x88) -#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x8c) -#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x90) -#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x94) -#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x98) -#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x9c) -#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4) - -/* Register for communicating XG link status */ -#define CRB_XG_STATE NETXEN_NIC_REG(0xa0) - -/* Register for communicating card temperature */ -/* Upper 16 bits are temperature value. Lower 16 bits are the state */ -#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8) -#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)) - -/* Debug registers for controlling NIC pkt gen agent */ -#define CRB_AGENT_GO NETXEN_NIC_REG(0xb0) -#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0xb4) -#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xb8) -#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xbc) -#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xc0) - -/* Debug registers for observing NIC performance */ -#define CRB_TX_STATE NETXEN_NIC_REG(0xd0) -#define CRB_TX_COUNT NETXEN_NIC_REG(0xd4) -#define CRB_RX_STATE NETXEN_NIC_REG(0xd8) +#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 per Rcv Descriptor ring */ struct netxen_rcv_desc_crb { u32 crb_rcv_producer_offset __attribute__ ((aligned(512))); u32 crb_rcv_consumer_offset; u32 crb_globalrcv_ring; + u32 crb_rcv_ring_size; }; /* - * CRB registers used by the receive peg logic. One instance of these - * needs to be instantiated per instance of the receive peg. + * CRB registers used by the receive peg logic. */ struct netxen_recv_crb { @@ -127,6 +132,7 @@ struct netxen_recv_crb { u32 crb_rcv_status_producer; u32 crb_rcv_status_consumer; u32 crb_rcvpeg_state; + u32 crb_status_ring_size; }; #if defined(DEFINE_GLOBAL_RECV_CRB) @@ -139,30 +145,48 @@ struct netxen_recv_crb recv_crb_registers[] = { { { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x18), + NETXEN_NIC_REG(0x100), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x1c), + NETXEN_NIC_REG(0x104), /* crb_gloablrcv_ring: */ - NETXEN_NIC_REG(0x20), + NETXEN_NIC_REG(0x108), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x10c), + }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x100), + NETXEN_NIC_REG(0x110), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x104), + NETXEN_NIC_REG(0x114), /* crb_gloablrcv_ring: */ - NETXEN_NIC_REG(0x108), + NETXEN_NIC_REG(0x118), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x11c), + }, + /* LRO */ + { + /* crb_rcv_producer_offset: */ + NETXEN_NIC_REG(0x120), + /* crb_rcv_consumer_offset: */ + NETXEN_NIC_REG(0x124), + /* crb_gloablrcv_ring: */ + NETXEN_NIC_REG(0x128), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x12c), } }, /* crb_rcvstatus_ring: */ - NETXEN_NIC_REG(0x24), + NETXEN_NIC_REG(0x130), /* crb_rcv_status_producer: */ - NETXEN_NIC_REG(0x28), + NETXEN_NIC_REG(0x134), /* crb_rcv_status_consumer: */ - NETXEN_NIC_REG(0x2c), + NETXEN_NIC_REG(0x138), /* crb_rcvpeg_state: */ - NETXEN_NIC_REG(0x48), + NETXEN_NIC_REG(0x13c), + /* crb_status_ring_size */ + NETXEN_NIC_REG(0x140), }, /* @@ -173,34 +197,66 @@ struct netxen_recv_crb recv_crb_registers[] = { { { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x80), + NETXEN_NIC_REG(0x144), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x84), + NETXEN_NIC_REG(0x148), /* crb_globalrcv_ring: */ - NETXEN_NIC_REG(0x88), + NETXEN_NIC_REG(0x14c), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x150), + }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x10C), + NETXEN_NIC_REG(0x154), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x110), + NETXEN_NIC_REG(0x158), /* crb_globalrcv_ring: */ - NETXEN_NIC_REG(0x114), + NETXEN_NIC_REG(0x15c), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x160), + }, + /* LRO */ + { + /* crb_rcv_producer_offset: */ + NETXEN_NIC_REG(0x164), + /* crb_rcv_consumer_offset: */ + NETXEN_NIC_REG(0x168), + /* crb_globalrcv_ring: */ + NETXEN_NIC_REG(0x16c), + /* crb_rcv_ring_size */ + NETXEN_NIC_REG(0x170), } + }, /* crb_rcvstatus_ring: */ - NETXEN_NIC_REG(0x8c), + NETXEN_NIC_REG(0x174), /* crb_rcv_status_producer: */ - NETXEN_NIC_REG(0x90), + NETXEN_NIC_REG(0x178), /* crb_rcv_status_consumer: */ - NETXEN_NIC_REG(0x94), + NETXEN_NIC_REG(0x17c), /* crb_rcvpeg_state: */ - NETXEN_NIC_REG(0x98), + NETXEN_NIC_REG(0x180), + /* crb_status_ring_size */ + NETXEN_NIC_REG(0x184), + }, }; + +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)}, + {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, + {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} +}; + #else extern struct netxen_recv_crb recv_crb_registers[]; +extern u64 ctx_addr_sig_regs[][3]; +#define CRB_CTX_ADDR_REG_LO (ctx_addr_sig_regs[0][0]) +#define CRB_CTX_ADDR_REG_HI (ctx_addr_sig_regs[0][2]) +#define CRB_CTX_SIGNATURE_REG (ctx_addr_sig_regs[0][1]) #endif /* DEFINE_GLOBAL_RECEIVE_CRB */ /* -- cgit v1.2.3-70-g09d2 From 6d5aefb8eaa38e44b5b8cf60c812aceafc02d924 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 5 Dec 2006 19:36:26 +0000 Subject: WorkQueue: Fix up arch-specific work items where possible Fix up arch-specific work items where possible to use the new work_struct and delayed_work structs. Three places that enqueue bits of their stack and then return have been marked with #error as this is not permitted. Signed-Off-By: David Howells --- arch/arm/common/sharpsl_pm.c | 22 +++++++++++----------- arch/arm/mach-omap1/board-h3.c | 3 ++- arch/arm/mach-omap1/board-nokia770.c | 6 +++--- arch/arm/mach-omap1/leds-osk.c | 4 ++-- arch/arm/mach-omap2/board-h4.c | 3 ++- arch/arm/mach-pxa/akita-ioexp.c | 6 +++--- arch/ia64/hp/sim/simserial.c | 4 ++-- arch/ia64/kernel/mca.c | 8 ++++---- arch/ia64/kernel/smpboot.c | 12 +++++++----- arch/mips/kernel/kspd.c | 4 ++-- arch/powerpc/platforms/embedded6xx/ls_uart.c | 4 ++-- arch/powerpc/platforms/powermac/backlight.c | 12 ++++++------ arch/ppc/8260_io/fcc_enet.c | 21 +++++++++++++-------- arch/ppc/8xx_io/fec.c | 21 +++++++++++++-------- arch/s390/appldata/appldata_base.c | 6 +++--- arch/um/drivers/chan_kern.c | 2 +- arch/um/drivers/mconsole_kern.c | 4 ++-- arch/um/drivers/net_kern.c | 1 + arch/um/drivers/port_kern.c | 4 ++-- drivers/macintosh/rack-meter.c | 16 ++++++++++------ drivers/net/chelsio/cphy.h | 2 +- drivers/net/chelsio/my3126.c | 8 +++++--- drivers/net/netxen/netxen_nic.h | 3 ++- drivers/net/netxen/netxen_nic_init.c | 5 +++-- drivers/net/netxen/netxen_nic_main.c | 19 ++++++++++--------- drivers/net/smc91x.c | 15 +++++++++------ drivers/net/wireless/zd1211rw/zd_mac.c | 23 +++++++++++++---------- drivers/net/wireless/zd1211rw/zd_mac.h | 4 ++-- drivers/spi/pxa2xx_spi.c | 9 +++++---- drivers/usb/core/hub.c | 2 +- drivers/usb/misc/appledisplay.c | 11 ++++++----- drivers/video/pxafb.c | 7 ++++--- include/asm-arm/arch-omap/irda.h | 2 +- include/linux/netpoll.h | 2 +- 34 files changed, 154 insertions(+), 121 deletions(-) (limited to 'drivers/net/netxen/netxen_nic.h') diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 605dedf9679..b3599743093 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -60,16 +60,16 @@ static int sharpsl_ac_check(void); static int sharpsl_fatal_check(void); static int sharpsl_average_value(int ad); static void sharpsl_average_clear(void); -static void sharpsl_charge_toggle(void *private_); -static void sharpsl_battery_thread(void *private_); +static void sharpsl_charge_toggle(struct work_struct *private_); +static void sharpsl_battery_thread(struct work_struct *private_); /* * Variables */ struct sharpsl_pm_status sharpsl_pm; -DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); -DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); +DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); +DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); @@ -116,7 +116,7 @@ void sharpsl_battery_kick(void) EXPORT_SYMBOL(sharpsl_battery_kick); -static void sharpsl_battery_thread(void *private_) +static void sharpsl_battery_thread(struct work_struct *private_) { int voltage, percent, apm_status, i = 0; @@ -128,7 +128,7 @@ static void sharpsl_battery_thread(void *private_) /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); while(1) { voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); @@ -212,7 +212,7 @@ static void sharpsl_charge_off(void) sharpsl_pm_led(SHARPSL_LED_OFF); sharpsl_pm.charge_mode = CHRG_OFF; - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } static void sharpsl_charge_error(void) @@ -222,7 +222,7 @@ static void sharpsl_charge_error(void) sharpsl_pm.charge_mode = CHRG_ERROR; } -static void sharpsl_charge_toggle(void *private_) +static void sharpsl_charge_toggle(struct work_struct *private_) { dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); @@ -254,7 +254,7 @@ static void sharpsl_ac_timer(unsigned long data) else if (sharpsl_pm.charge_mode == CHRG_ON) sharpsl_charge_off(); - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } @@ -279,10 +279,10 @@ static void sharpsl_chrg_full_timer(unsigned long data) sharpsl_charge_off(); } else if (sharpsl_pm.full_count < 2) { dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else { sharpsl_charge_off(); sharpsl_pm.charge_mode = CHRG_DONE; diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index f225a083dee..9d2346fb68f 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -323,7 +323,8 @@ static int h3_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index dbc555d209f..cbe909bad79 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -74,7 +74,7 @@ static struct omap_kp_platform_data nokia770_kp_data = { .rows = 8, .cols = 8, .keymap = nokia770_keymap, - .keymapsize = ARRAY_SIZE(nokia770_keymap) + .keymapsize = ARRAY_SIZE(nokia770_keymap), .delay = 4, }; @@ -191,7 +191,7 @@ static void nokia770_audio_pwr_up(void) printk("HP connected\n"); } -static void codec_delayed_power_down(void *arg) +static void codec_delayed_power_down(struct work_struct *work) { down(&audio_pwr_sem); if (audio_pwr_state == -1) @@ -200,7 +200,7 @@ static void codec_delayed_power_down(void *arg) up(&audio_pwr_sem); } -static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); +static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); static void nokia770_audio_pwr_down(void) { diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index 3b29e59b0e6..0cbf1b0071f 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c @@ -35,7 +35,7 @@ static u8 hw_led_state; static u8 tps_leds_change; -static void tps_work(void *unused) +static void tps_work(struct work_struct *unused) { for (;;) { u8 leds; @@ -61,7 +61,7 @@ static void tps_work(void *unused) } } -static DECLARE_WORK(work, tps_work, NULL); +static DECLARE_WORK(work, tps_work); #ifdef CONFIG_OMAP_OSK_MISTRAL diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 26a95a642ad..3b1ad1d981a 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -206,7 +206,8 @@ static int h4_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c index 1b398742ab5..12d2fe0ceff 100644 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ b/arch/arm/mach-pxa/akita-ioexp.c @@ -36,11 +36,11 @@ I2C_CLIENT_INSMOD; static int max7310_write(struct i2c_client *client, int address, int data); static struct i2c_client max7310_template; -static void akita_ioexp_work(void *private_); +static void akita_ioexp_work(struct work_struct *private_); static struct device *akita_ioexp_device; static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT; -DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL); +DECLARE_WORK(akita_ioexp, akita_ioexp_work); /* @@ -158,7 +158,7 @@ void akita_reset_ioexp(struct device *dev, unsigned char bit) EXPORT_SYMBOL(akita_set_ioexp); EXPORT_SYMBOL(akita_reset_ioexp); -static void akita_ioexp_work(void *private_) +static void akita_ioexp_work(struct work_struct *private_) { if (akita_ioexp_device) max7310_set_ouputs(akita_ioexp_device, ioexp_output_value); diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index caab986af70..b62f0c4d2c7 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -209,7 +209,7 @@ static void do_serial_bh(void) } #endif -static void do_softint(void *private_) +static void do_softint(struct work_struct *private_) { printk(KERN_ERR "simserial: do_softint called\n"); } @@ -698,7 +698,7 @@ static int get_async_struct(int line, struct async_struct **ret_info) info->flags = sstate->flags; info->xmit_fifo_size = sstate->xmit_fifo_size; info->line = line; - INIT_WORK(&info->work, do_softint, info); + INIT_WORK(&info->work, do_softint); info->state = sstate; if (sstate->info) { kfree(info); diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 7cfa63a98cb..6bedd97570c 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -678,7 +678,7 @@ ia64_mca_cmc_vector_enable (void *dummy) * disable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_disable_keventd(void *unused) +ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0); } @@ -690,7 +690,7 @@ ia64_mca_cmc_vector_disable_keventd(void *unused) * enable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_enable_keventd(void *unused) +ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0); } @@ -1247,8 +1247,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = -1; } -static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL); -static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL); +static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); +static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd); /* * ia64_mca_cmc_int_handler diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index f7d7f566814..b21ddecea94 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -463,15 +463,17 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) } struct create_idle { + struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; void -do_fork_idle(void *_c_idle) +do_fork_idle(struct work_struct *work) { - struct create_idle *c_idle = _c_idle; + struct create_idle *c_idle = + container_of(work, struct create_idle, work); c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -482,10 +484,10 @@ do_boot_cpu (int sapicid, int cpu) { int timeout; struct create_idle c_idle = { + .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER(c_idle.done), }; - DECLARE_WORK(work, do_fork_idle, &c_idle); c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -497,9 +499,9 @@ do_boot_cpu (int sapicid, int cpu) * We can't use kernel_thread since we must avoid to reschedule the child. */ if (!keventd_up() || current_is_keventd()) - work.func(work.data); + c_idle.work.func(&c_idle.work); else { - schedule_work(&work); + schedule_work(&c_idle.work); wait_for_completion(&c_idle.done); } diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index f06a144c788..2c82412b9ef 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -319,7 +319,7 @@ static void sp_cleanup(void) static int channel_open = 0; /* the work handler */ -static void sp_work(void *data) +static void sp_work(struct work_struct *unused) { if (!channel_open) { if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { @@ -354,7 +354,7 @@ static void startwork(int vpe) return; } - INIT_WORK(&work, sp_work, NULL); + INIT_WORK(&work, sp_work); queue_work(workqueue, &work); } else queue_work(workqueue, &work); diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c index 31bcdae8482..0e837762cc5 100644 --- a/arch/powerpc/platforms/embedded6xx/ls_uart.c +++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c @@ -14,7 +14,7 @@ static unsigned long avr_clock; static struct work_struct wd_work; -static void wd_stop(void *unused) +static void wd_stop(struct work_struct *unused) { const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"; int i = 0, rescue = 8; @@ -122,7 +122,7 @@ static int __init ls_uarts_init(void) ls_uart_init(); - INIT_WORK(&wd_work, wd_stop, NULL); + INIT_WORK(&wd_work, wd_stop); schedule_work(&wd_work); return 0; diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index afa593a8544..c3a89414ddc 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -18,11 +18,11 @@ #define OLD_BACKLIGHT_MAX 15 -static void pmac_backlight_key_worker(void *data); -static void pmac_backlight_set_legacy_worker(void *data); +static void pmac_backlight_key_worker(struct work_struct *work); +static void pmac_backlight_set_legacy_worker(struct work_struct *work); -static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); -static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); +static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker); +static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker); /* Although these variables are used in interrupt context, it makes no sense to * protect them. No user is able to produce enough key events per second and @@ -94,7 +94,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) return level; } -static void pmac_backlight_key_worker(void *data) +static void pmac_backlight_key_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; @@ -166,7 +166,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) return error; } -static void pmac_backlight_set_legacy_worker(void *data) +static void pmac_backlight_set_legacy_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 2e1943e2781..709952c25f2 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -385,6 +385,7 @@ struct fcc_enet_private { phy_info_t *phy; struct work_struct phy_relink; struct work_struct phy_display_config; + struct net_device *dev; uint sequence_done; @@ -1391,10 +1392,11 @@ static phy_info_t *phy_info[] = { NULL }; -static void mii_display_status(void *data) +static void mii_display_status(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, phy_relink); + struct net_device *dev = fep->dev; uint s = fep->phy_status; if (!fep->link && !fep->old_link) { @@ -1428,10 +1430,12 @@ static void mii_display_status(void *data) printk(".\n"); } -static void mii_display_config(void *data) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, + phy_display_config); + struct net_device *dev = fep->dev; uint s = fep->phy_status; printk("%s: config: auto-negotiation ", dev->name); @@ -1758,8 +1762,9 @@ static int __init fec_enet_init(void) cep->phy_id_done = 0; cep->phy_addr = fip->fc_phyaddr; mii_queue(dev, mk_mii_read(MII_PHYSID1), mii_discover_phy); - INIT_WORK(&cep->phy_relink, mii_display_status, dev); - INIT_WORK(&cep->phy_display_config, mii_display_config, dev); + INIT_WORK(&cep->phy_relink, mii_display_status); + INIT_WORK(&cep->phy_display_config, mii_display_config); + cep->dev = dev; #endif /* CONFIG_USE_MDIO */ fip++; diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 2f9fa9e3d33..e6c28fb423b 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -173,6 +173,7 @@ struct fec_enet_private { uint phy_speed; phy_info_t *phy; struct work_struct phy_task; + struct net_device *dev; uint sequence_done; @@ -1263,10 +1264,11 @@ static void mii_display_status(struct net_device *dev) printk(".\n"); } -static void mii_display_config(void *priv) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1295,10 +1297,11 @@ static void mii_display_config(void *priv) fep->sequence_done = 1; } -static void mii_relink(void *priv) +static void mii_relink(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1325,7 +1328,8 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_relink, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_relink); schedule_work(&fep->phy_task); } @@ -1333,7 +1337,8 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_display_config); schedule_work(&fep->phy_task); } diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index af1e8fc7d98..67d5cf9cba8 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -92,8 +92,8 @@ static int appldata_timer_active; * Work queue */ static struct workqueue_struct *appldata_wq; -static void appldata_work_fn(void *data); -static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); +static void appldata_work_fn(struct work_struct *work); +static DECLARE_WORK(appldata_work, appldata_work_fn); /* @@ -125,7 +125,7 @@ static void appldata_timer_function(unsigned long data) * * call data gathering function for each (active) module */ -static void appldata_work_fn(void *data) +static void appldata_work_fn(struct work_struct *work) { struct list_head *lh; struct appldata_ops *ops; diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3576b3cc505..7d4190e5565 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -638,7 +638,7 @@ int chan_out_fd(struct list_head *chans) return -1; } -void chan_interrupt(struct list_head *chans, struct work_struct *task, +void chan_interrupt(struct list_head *chans, struct delayed_work *task, struct tty_struct *tty, int irq) { struct list_head *ele, *next; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 7b172160fe0..96f0189327a 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -56,7 +56,7 @@ static struct notifier_block reboot_notifier = { static LIST_HEAD(mc_requests); -static void mc_work_proc(void *unused) +static void mc_work_proc(struct work_struct *unused) { struct mconsole_entry *req; unsigned long flags; @@ -72,7 +72,7 @@ static void mc_work_proc(void *unused) } } -static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); +static DECLARE_WORK(mconsole_work, mc_work_proc); static irqreturn_t mconsole_interrupt(int irq, void *dev_id) { diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index ec9eb8bd943..286bc0b3207 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -99,6 +99,7 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id) * same device, since it tests for (dev->flags & IFF_UP). So * there's no harm in delaying the device shutdown. */ schedule_work(&close_work); +#error this is not permitted - close_work will go out of scope goto out; } reactivate_fd(lp->fd, UM_ETH_IRQ); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index ce9f3733f73..6dfe632f1c1 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -132,7 +132,7 @@ static int port_accept(struct port_list *port) DECLARE_MUTEX(ports_sem); struct list_head ports = LIST_HEAD_INIT(ports); -void port_work_proc(void *unused) +void port_work_proc(struct work_struct *unused) { struct port_list *port; struct list_head *ele; @@ -150,7 +150,7 @@ void port_work_proc(void *unused) local_irq_restore(flags); } -DECLARE_WORK(port_work, port_work_proc, NULL); +DECLARE_WORK(port_work, port_work_proc); static irqreturn_t port_interrupt(int irq, void *data) { diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index f1b6f563673..5ed41fe84e5 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -48,7 +48,8 @@ struct rackmeter_dma { } ____cacheline_aligned; struct rackmeter_cpu { - struct work_struct sniffer; + struct delayed_work sniffer; + struct rackmeter *rm; cputime64_t prev_wall; cputime64_t prev_idle; int zero; @@ -208,11 +209,12 @@ static void rackmeter_setup_dbdma(struct rackmeter *rm) rackmeter_do_pause(rm, 0); } -static void rackmeter_do_timer(void *data) +static void rackmeter_do_timer(struct work_struct *work) { - struct rackmeter *rm = data; + struct rackmeter_cpu *rcpu = + container_of(work, struct rackmeter_cpu, sniffer.work); + struct rackmeter *rm = rcpu->rm; unsigned int cpu = smp_processor_id(); - struct rackmeter_cpu *rcpu = &rm->cpu[cpu]; cputime64_t cur_jiffies, total_idle_ticks; unsigned int total_ticks, idle_ticks; int i, offset, load, cumm, pause; @@ -263,8 +265,10 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) * on those machines yet */ - INIT_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer, rm); - INIT_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer, rm); + rm->cpu[0].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer); + rm->cpu[1].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer); for_each_online_cpu(cpu) { struct rackmeter_cpu *rcpu; diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h index 60901f25014..cf914349988 100644 --- a/drivers/net/chelsio/cphy.h +++ b/drivers/net/chelsio/cphy.h @@ -91,7 +91,7 @@ struct cphy { int state; /* Link status state machine */ adapter_t *adapter; /* associated adapter */ - struct work_struct phy_update; + struct delayed_work phy_update; u16 bmsr; int count; diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c index 0b90014d5b3..c7731b6f9de 100644 --- a/drivers/net/chelsio/my3126.c +++ b/drivers/net/chelsio/my3126.c @@ -93,9 +93,11 @@ static int my3126_interrupt_handler(struct cphy *cphy) return cphy_cause_link_change; } -static void my3216_poll(void *arg) +static void my3216_poll(struct work_struct *work) { - my3126_interrupt_handler(arg); + struct cphy *cphy = container_of(work, struct cphy, phy_update.work); + + my3126_interrupt_handler(cphy); } static int my3126_set_loopback(struct cphy *cphy, int on) @@ -171,7 +173,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter, if (cphy) cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); - INIT_WORK(&cphy->phy_update, my3216_poll, cphy); + INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); cphy->bmsr = 0; return (cphy); diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d925053fe59..9c588af8ab7 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -714,6 +714,7 @@ struct netxen_adapter { spinlock_t lock; struct work_struct watchdog_task; struct work_struct tx_timeout_task; + struct net_device *netdev; struct timer_list watchdog_timer; u32 curr_window; @@ -921,7 +922,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, struct netxen_port *port); int netxen_nic_rx_has_work(struct netxen_adapter *adapter); int netxen_nic_tx_has_work(struct netxen_adapter *adapter); -void netxen_watchdog_task(unsigned long v); +void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); void netxen_process_cmd_ring(unsigned long data); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 0dca029bc3e..eae18236aef 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -710,12 +710,13 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) return rv; } -void netxen_watchdog_task(unsigned long v) +void netxen_watchdog_task(struct work_struct *work) { int port_num; struct netxen_port *port; struct net_device *netdev; - struct netxen_adapter *adapter = (struct netxen_adapter *)v; + struct netxen_adapter *adapter = + container_of(work, struct netxen_adapter, watchdog_task); if (netxen_nic_check_temp(adapter)) return; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 1cb662d5bd7..df0bb36a1cf 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -64,7 +64,7 @@ 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 void netxen_tx_timeout(struct net_device *netdev); -static void netxen_tx_timeout_task(struct net_device *netdev); +static void netxen_tx_timeout_task(struct work_struct *work); static void netxen_watchdog(unsigned long); static int netxen_handle_int(struct netxen_adapter *, struct net_device *); static int netxen_nic_ioctl(struct net_device *netdev, @@ -274,8 +274,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.xg_linkup = 0; adapter->watchdog_timer.function = &netxen_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; - INIT_WORK(&adapter->watchdog_task, - (void (*)(void *))netxen_watchdog_task, adapter); + INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); adapter->ahw.pdev = pdev; adapter->proc_cmd_buf_counter = 0; pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id); @@ -379,8 +378,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_addr); } } - INIT_WORK(&adapter->tx_timeout_task, - (void (*)(void *))netxen_tx_timeout_task, netdev); + adapter->netdev = netdev; + INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -938,18 +937,20 @@ static void netxen_tx_timeout(struct net_device *netdev) schedule_work(&adapter->tx_timeout_task); } -static void netxen_tx_timeout_task(struct net_device *netdev) +static void netxen_tx_timeout_task(struct work_struct *work) { - struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); + struct netxen_adapter *adapter = + container_of(work, struct netxen_adapter, tx_timeout_task); + struct net_device *netdev = adapter->netdev; unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, netdev->name); - spin_lock_irqsave(&port->adapter->lock, flags); + spin_lock_irqsave(&adapter->lock, flags); netxen_nic_close(netdev); netxen_nic_open(netdev); - spin_unlock_irqrestore(&port->adapter->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); netdev->trans_start = jiffies; netif_wake_queue(netdev); } diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 95b6478f55c..e62a9586fb9 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -210,6 +210,7 @@ struct smc_local { /* work queue */ struct work_struct phy_configure; + struct net_device *dev; int work_pending; spinlock_t lock; @@ -1114,10 +1115,11 @@ static void smc_phy_check_media(struct net_device *dev, int init) * of autonegotiation.) If the RPC ANEG bit is cleared, the selection * is controlled by the RPC SPEED and RPC DPLX bits. */ -static void smc_phy_configure(void *data) +static void smc_phy_configure(struct work_struct *work) { - struct net_device *dev = data; - struct smc_local *lp = netdev_priv(dev); + struct smc_local *lp = + container_of(work, struct smc_local, phy_configure); + struct net_device *dev = lp->dev; void __iomem *ioaddr = lp->base; int phyaddr = lp->mii.phy_id; int my_phy_caps; /* My PHY capabilities */ @@ -1592,7 +1594,7 @@ smc_open(struct net_device *dev) /* Configure the PHY, initialize the link state */ if (lp->phy_type != 0) - smc_phy_configure(dev); + smc_phy_configure(&lp->phy_configure); else { spin_lock_irq(&lp->lock); smc_10bt_check_media(dev, 1); @@ -1972,7 +1974,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) #endif tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); - INIT_WORK(&lp->phy_configure, smc_phy_configure, dev); + INIT_WORK(&lp->phy_configure, smc_phy_configure); + lp->dev = dev; lp->mii.phy_id_mask = 0x1f; lp->mii.reg_num_mask = 0x1f; lp->mii.force_media = 0; @@ -2322,7 +2325,7 @@ static int smc_drv_resume(struct platform_device *dev) smc_reset(ndev); smc_enable(ndev); if (lp->phy_type != 0) - smc_phy_configure(ndev); + smc_phy_configure(&lp->phy_configure); netif_device_attach(ndev); } } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 44f3cfd4cc1..f1573a9c233 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -32,8 +32,8 @@ static void ieee_init(struct ieee80211_device *ieee); static void softmac_init(struct ieee80211softmac_device *sm); -static void set_rts_cts_work(void *d); -static void set_basic_rates_work(void *d); +static void set_rts_cts_work(struct work_struct *work); +static void set_basic_rates_work(struct work_struct *work); static void housekeeping_init(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac); @@ -48,8 +48,8 @@ int zd_mac_init(struct zd_mac *mac, memset(mac, 0, sizeof(*mac)); spin_lock_init(&mac->lock); mac->netdev = netdev; - INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac); - INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac); + INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); + INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); @@ -366,9 +366,10 @@ static void try_enable_tx(struct zd_mac *mac) spin_unlock_irqrestore(&mac->lock, flags); } -static void set_rts_cts_work(void *d) +static void set_rts_cts_work(struct work_struct *work) { - struct zd_mac *mac = d; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_rts_cts_work.work); unsigned long flags; u8 rts_rate; unsigned int short_preamble; @@ -387,9 +388,10 @@ static void set_rts_cts_work(void *d) try_enable_tx(mac); } -static void set_basic_rates_work(void *d) +static void set_basic_rates_work(struct work_struct *work) { - struct zd_mac *mac = d; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_basic_rates_work.work); unsigned long flags; u16 basic_rates; @@ -467,12 +469,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) if (need_set_rts_cts && !mac->updating_rts_rate) { mac->updating_rts_rate = 1; netif_stop_queue(mac->netdev); - queue_work(zd_workqueue, &mac->set_rts_cts_work); + queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); } if (need_set_rates && !mac->updating_basic_rates) { mac->updating_basic_rates = 1; netif_stop_queue(mac->netdev); - queue_work(zd_workqueue, &mac->set_basic_rates_work); + queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, + 0); } spin_unlock_irqrestore(&mac->lock, flags); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 08d6b8c08e7..d4e8b870409 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -133,8 +133,8 @@ struct zd_mac { struct iw_statistics iw_stats; struct housekeeping housekeeping; - struct work_struct set_rts_cts_work; - struct work_struct set_basic_rates_work; + struct delayed_work set_rts_cts_work; + struct delayed_work set_basic_rates_work; unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 72025df5561..494d9b85648 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -148,7 +148,7 @@ struct chip_data { void (*cs_control)(u32 command); }; -static void pump_messages(void *data); +static void pump_messages(struct work_struct *work); static int flush(struct driver_data *drv_data) { @@ -884,9 +884,10 @@ static void pump_transfers(unsigned long data) } } -static void pump_messages(void *data) +static void pump_messages(struct work_struct *work) { - struct driver_data *drv_data = data; + struct driver_data *drv_data = + container_of(work, struct driver_data, pump_messages); unsigned long flags; /* Lock queue and check for queue work */ @@ -1098,7 +1099,7 @@ static int init_queue(struct driver_data *drv_data) tasklet_init(&drv_data->pump_transfers, pump_transfers, (unsigned long)drv_data); - INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); + INIT_WORK(&drv_data->pump_messages, pump_messages); drv_data->workqueue = create_singlethread_workqueue( drv_data->master->cdev.dev->bus_id); if (drv_data->workqueue == NULL) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 39186db1015..9be41ed1f9a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -68,7 +68,7 @@ struct usb_hub { unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; - struct work_struct leds; + struct delayed_work leds; }; diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index ba30ca6a14a..02cbb7fff24 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -76,7 +76,7 @@ struct appledisplay { char *urbdata; /* interrupt URB data buffer */ char *msgdata; /* control message data buffer */ - struct work_struct work; + struct delayed_work work; int button_pressed; spinlock_t lock; }; @@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb) case ACD_BTN_BRIGHT_UP: case ACD_BTN_BRIGHT_DOWN: pdata->button_pressed = 1; - queue_work(wq, &pdata->work); + queue_delayed_work(wq, &pdata->work, 0); break; case ACD_BTN_NONE: default: @@ -184,9 +184,10 @@ static struct backlight_properties appledisplay_bl_data = { .max_brightness = 0xFF }; -static void appledisplay_work(void *private) +static void appledisplay_work(struct work_struct *work) { - struct appledisplay *pdata = private; + struct appledisplay *pdata = + container_of(work, struct appledisplay, work.work); int retval; up(&pdata->bd->sem); @@ -238,7 +239,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->udev = udev; spin_lock_init(&pdata->lock); - INIT_WORK(&pdata->work, appledisplay_work, pdata); + INIT_DELAYED_WORK(&pdata->work, appledisplay_work); /* Allocate buffer for control messages */ pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 8a8ae55a740..38eb0b69c2d 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -964,9 +964,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) * Our LCD controller task (which is called when we blank or unblank) * via keventd. */ -static void pxafb_task(void *dummy) +static void pxafb_task(struct work_struct *work) { - struct pxafb_info *fbi = dummy; + struct pxafb_info *fbi = + container_of(work, struct pxafb_info, task); u_int state = xchg(&fbi->task_state, -1); set_ctrlr_state(fbi, state); @@ -1159,7 +1160,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) } init_waitqueue_head(&fbi->ctrlr_wait); - INIT_WORK(&fbi->task, pxafb_task, fbi); + INIT_WORK(&fbi->task, pxafb_task); init_MUTEX(&fbi->ctrlr_sem); return fbi; diff --git a/include/asm-arm/arch-omap/irda.h b/include/asm-arm/arch-omap/irda.h index 805ae3575e4..345a649ec83 100644 --- a/include/asm-arm/arch-omap/irda.h +++ b/include/asm-arm/arch-omap/irda.h @@ -24,7 +24,7 @@ struct omap_irda_config { /* Very specific to the needs of some platforms (h3,h4) * having calls which can sleep in irda_set_speed. */ - struct work_struct gpio_expa; + struct delayed_work gpio_expa; int rx_channel; int tx_channel; unsigned long dest_start; diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 2cc9867b162..29930b71a9a 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -32,7 +32,7 @@ struct netpoll_info { struct netpoll *rx_np; /* netpoll that registered an rx_hook */ struct sk_buff_head arp_tx; /* list of arp requests to reply to */ struct sk_buff_head txq; - struct work_struct tx_work; + struct delayed_work tx_work; }; void netpoll_poll(struct netpoll *np); -- cgit v1.2.3-70-g09d2