[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 <amitkale@netxen.com> 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 <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
80922fbcb6
commit
ed25ffa164
@@ -63,27 +63,49 @@
|
|||||||
|
|
||||||
#include "netxen_nic_hw.h"
|
#include "netxen_nic_hw.h"
|
||||||
|
|
||||||
#define NETXEN_NIC_BUILD_NO "5"
|
#define NETXEN_NIC_BUILD_NO "1"
|
||||||
#define _NETXEN_NIC_LINUX_MAJOR 2
|
#define _NETXEN_NIC_LINUX_MAJOR 3
|
||||||
#define _NETXEN_NIC_LINUX_MINOR 3
|
#define _NETXEN_NIC_LINUX_MINOR 3
|
||||||
#define _NETXEN_NIC_LINUX_SUBVERSION 59
|
#define _NETXEN_NIC_LINUX_SUBVERSION 2
|
||||||
#define NETXEN_NIC_LINUX_VERSIONID "2.3.59" "-" NETXEN_NIC_BUILD_NO
|
#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO
|
||||||
#define NETXEN_NIC_FW_VERSIONID "2.3.59"
|
#define NETXEN_NIC_FW_VERSIONID "3.3.2"
|
||||||
|
|
||||||
#define RCV_DESC_RINGSIZE \
|
#define RCV_DESC_RINGSIZE \
|
||||||
(sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
|
(sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
|
||||||
#define STATUS_DESC_RINGSIZE \
|
#define STATUS_DESC_RINGSIZE \
|
||||||
(sizeof(struct status_desc)* adapter->max_rx_desc_count)
|
(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 \
|
#define TX_RINGSIZE \
|
||||||
(sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
|
(sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
|
||||||
#define RCV_BUFFSIZE \
|
#define RCV_BUFFSIZE \
|
||||||
(sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
|
(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 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) \
|
#define ADDR_IN_WINDOW1(off) \
|
||||||
((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
|
((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
|
* normalize a 64MB crb address to 32MB PCI window
|
||||||
@@ -95,8 +117,14 @@
|
|||||||
#define NETXEN_CRB_NORMALIZE(adapter, reg) \
|
#define NETXEN_CRB_NORMALIZE(adapter, reg) \
|
||||||
pci_base_offset(adapter, NETXEN_CRB_NORMAL(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_START 0
|
||||||
#define FIRST_PAGE_GROUP_END 0x400000
|
#define FIRST_PAGE_GROUP_END 0x100000
|
||||||
|
|
||||||
#define SECOND_PAGE_GROUP_START 0x4000000
|
#define SECOND_PAGE_GROUP_START 0x4000000
|
||||||
#define SECOND_PAGE_GROUP_END 0x66BC000
|
#define SECOND_PAGE_GROUP_END 0x66BC000
|
||||||
@@ -108,11 +136,13 @@
|
|||||||
#define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_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 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 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 \
|
#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
|
#define NETXEN_ROM_ROUNDUP 0x80000000ULL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -151,30 +181,38 @@ enum {
|
|||||||
/* Host writes the following to notify that it has done the init-handshake */
|
/* Host writes the following to notify that it has done the init-handshake */
|
||||||
#define PHAN_INITIALIZE_ACK 0xf00f
|
#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 */
|
/* descriptor types */
|
||||||
#define RCV_DESC_NORMAL 0x01
|
#define RCV_DESC_NORMAL 0x01
|
||||||
#define RCV_DESC_JUMBO 0x02
|
#define RCV_DESC_JUMBO 0x02
|
||||||
|
#define RCV_DESC_LRO 0x04
|
||||||
#define RCV_DESC_NORMAL_CTXID 0
|
#define RCV_DESC_NORMAL_CTXID 0
|
||||||
#define RCV_DESC_JUMBO_CTXID 1
|
#define RCV_DESC_JUMBO_CTXID 1
|
||||||
|
#define RCV_DESC_LRO_CTXID 2
|
||||||
|
|
||||||
#define RCV_DESC_TYPE(ID) \
|
#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_CMD_DESCRIPTORS 1024
|
||||||
#define MAX_RCV_DESCRIPTORS 32768
|
#define MAX_RCV_DESCRIPTORS 32768
|
||||||
#define MAX_JUMBO_RCV_DESCRIPTORS 4096
|
#define MAX_JUMBO_RCV_DESCRIPTORS 4096
|
||||||
|
#define MAX_LRO_RCV_DESCRIPTORS 2048
|
||||||
#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
|
#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
|
||||||
#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
|
#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
|
||||||
#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
|
#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
|
||||||
#define MAX_RCVSTATUS_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 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_TX_COUNT 4096
|
||||||
#define MIN_RX_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 MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
|
||||||
|
|
||||||
#define PHAN_PEG_RCV_INITIALIZED 0xff01
|
#define PHAN_PEG_RCV_INITIALIZED 0xff01
|
||||||
@@ -186,6 +224,67 @@ enum {
|
|||||||
#define get_index_range(index,length,count) \
|
#define get_index_range(index,length,count) \
|
||||||
(((index) + (count)) & ((length) - 1))
|
(((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.
|
* Following data structures describe the descriptors that will be used.
|
||||||
* Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
|
* 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_IPSEC_SA_DELETE 0x08
|
||||||
#define FLAGS_VLAN_TAGGED 0x10
|
#define FLAGS_VLAN_TAGGED 0x10
|
||||||
|
|
||||||
#define CMD_DESC_TOTAL_LENGTH(cmd_desc) \
|
#define netxen_set_cmd_desc_port(cmd_desc, var) \
|
||||||
((cmd_desc)->length_tcp_hdr & 0x00FFFFFF)
|
((cmd_desc)->port_ctxid |= ((var) & 0x0F))
|
||||||
#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) \
|
#define netxen_set_cmd_desc_flags(cmd_desc, val) \
|
||||||
((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF))
|
_netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val)
|
||||||
#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var) \
|
#define netxen_set_cmd_desc_opcode(cmd_desc, val) \
|
||||||
((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000))
|
_netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val)
|
||||||
#define CMD_DESC_PORT_WRT(cmd_desc, var) \
|
|
||||||
((cmd_desc)->port_ctxid |= ((var) & 0x0F))
|
#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 {
|
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 {
|
union {
|
||||||
struct {
|
struct {
|
||||||
u32 addr_low_part2;
|
u32 addr_low_part2;
|
||||||
@@ -227,13 +336,6 @@ struct cmd_desc_type0 {
|
|||||||
u64 addr_buffer2;
|
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 reference_handle; /* changed to u16 to add mss */
|
||||||
u16 mss; /* passed by NDIS_PACKET for LSO */
|
u16 mss; /* passed by NDIS_PACKET for LSO */
|
||||||
/* Bit pattern 0-3 port, 0-3 ctx id */
|
/* Bit pattern 0-3 port, 0-3 ctx id */
|
||||||
@@ -248,7 +350,6 @@ struct cmd_desc_type0 {
|
|||||||
};
|
};
|
||||||
u64 addr_buffer3;
|
u64 addr_buffer3;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
u32 addr_low_part1;
|
u32 addr_low_part1;
|
||||||
@@ -270,6 +371,8 @@ struct cmd_desc_type0 {
|
|||||||
u64 addr_buffer4;
|
u64 addr_buffer4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u64 unused;
|
||||||
|
|
||||||
} __attribute__ ((aligned(64)));
|
} __attribute__ ((aligned(64)));
|
||||||
|
|
||||||
/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
|
/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
|
||||||
@@ -296,22 +399,49 @@ struct rcv_desc {
|
|||||||
#define NETXEN_PROT_UNKNOWN (0)
|
#define NETXEN_PROT_UNKNOWN (0)
|
||||||
|
|
||||||
/* Note: sizeof(status_desc) should always be a mutliple of 2 */
|
/* 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 netxen_get_sts_desc_lro_cnt(status_desc) \
|
||||||
#define STATUS_DESC_STATUS(status_desc) \
|
((status_desc)->lro & 0x7F)
|
||||||
(((status_desc)->port_status_type_op >> 4) & 0x0F)
|
#define netxen_get_sts_desc_lro_last_frag(status_desc) \
|
||||||
#define STATUS_DESC_TYPE(status_desc) \
|
(((status_desc)->lro & 0x80) >> 7)
|
||||||
(((status_desc)->port_status_type_op >> 8) & 0x0F)
|
|
||||||
#define STATUS_DESC_OPCODE(status_desc) \
|
#define netxen_get_sts_port(status_desc) \
|
||||||
(((status_desc)->port_status_type_op >> 12) & 0x0F)
|
((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 {
|
struct status_desc {
|
||||||
/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */
|
/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
|
||||||
u16 port_status_type_op;
|
28-43 reference_handle, 44-47 protocol, 48-52 unused
|
||||||
u16 total_length; /* NIC mode */
|
53-55 desc_cnt, 56-57 owner, 58-63 opcode
|
||||||
u16 reference_handle; /* handle for the associated packet */
|
*/
|
||||||
/* Bit pattern: 0-1 owner, 2-5 protocol */
|
u64 status_desc_data;
|
||||||
u16 owner; /* Owner of the descriptor */
|
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)));
|
} __attribute__ ((aligned(8)));
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -563,7 +693,8 @@ typedef enum {
|
|||||||
#define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START)
|
#define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START)
|
||||||
#define NUM_PRIMARY_SECTORS (0x20)
|
#define NUM_PRIMARY_SECTORS (0x20)
|
||||||
#define NUM_CONFIG_SECTORS (1)
|
#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 */
|
/* Note: Make sure to not call this before adapter->port is valid */
|
||||||
#if !defined(NETXEN_DEBUG)
|
#if !defined(NETXEN_DEBUG)
|
||||||
@@ -609,7 +740,6 @@ struct netxen_cmd_buffer {
|
|||||||
u8 frag_count;
|
u8 frag_count;
|
||||||
unsigned long time_stamp;
|
unsigned long time_stamp;
|
||||||
u32 state;
|
u32 state;
|
||||||
u32 no_of_descriptors;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* In rx_buffer, we do not need multiple fragments as is a single buffer */
|
/* In rx_buffer, we do not need multiple fragments as is a single buffer */
|
||||||
@@ -618,6 +748,9 @@ struct netxen_rx_buffer {
|
|||||||
u64 dma;
|
u64 dma;
|
||||||
u16 ref_handle;
|
u16 ref_handle;
|
||||||
u16 state;
|
u16 state;
|
||||||
|
u32 lro_expected_frags;
|
||||||
|
u32 lro_current_frags;
|
||||||
|
u32 lro_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Board types */
|
/* Board types */
|
||||||
@@ -633,6 +766,8 @@ struct netxen_hardware_context {
|
|||||||
void __iomem *pci_base0;
|
void __iomem *pci_base0;
|
||||||
void __iomem *pci_base1;
|
void __iomem *pci_base1;
|
||||||
void __iomem *pci_base2;
|
void __iomem *pci_base2;
|
||||||
|
void __iomem *db_base;
|
||||||
|
unsigned long db_len;
|
||||||
|
|
||||||
u8 revision_id;
|
u8 revision_id;
|
||||||
u16 board_type;
|
u16 board_type;
|
||||||
@@ -642,14 +777,13 @@ struct netxen_hardware_context {
|
|||||||
u32 qg_linksup;
|
u32 qg_linksup;
|
||||||
/* Address of cmd ring in Phantom */
|
/* Address of cmd ring in Phantom */
|
||||||
struct cmd_desc_type0 *cmd_desc_head;
|
struct cmd_desc_type0 *cmd_desc_head;
|
||||||
char *pauseaddr;
|
|
||||||
struct pci_dev *cmd_desc_pdev;
|
struct pci_dev *cmd_desc_pdev;
|
||||||
dma_addr_t cmd_desc_phys_addr;
|
dma_addr_t cmd_desc_phys_addr;
|
||||||
dma_addr_t pause_physaddr;
|
|
||||||
struct pci_dev *pause_pdev;
|
|
||||||
struct netxen_adapter *adapter;
|
struct netxen_adapter *adapter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RCV_RING_LRO RCV_DESC_LRO
|
||||||
|
|
||||||
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
|
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
|
||||||
#define ETHERNET_FCS_SIZE 4
|
#define ETHERNET_FCS_SIZE 4
|
||||||
|
|
||||||
@@ -702,6 +836,13 @@ struct netxen_recv_context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define NETXEN_NIC_MSI_ENABLED 0x02
|
#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_adapter {
|
||||||
struct netxen_hardware_context ahw;
|
struct netxen_hardware_context ahw;
|
||||||
@@ -711,18 +852,19 @@ struct netxen_adapter {
|
|||||||
spinlock_t tx_lock;
|
spinlock_t tx_lock;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct work_struct watchdog_task;
|
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;
|
struct timer_list watchdog_timer;
|
||||||
|
|
||||||
u32 curr_window;
|
u32 curr_window;
|
||||||
|
|
||||||
u32 cmd_producer;
|
u32 cmd_producer;
|
||||||
u32 cmd_consumer;
|
u32 *cmd_consumer;
|
||||||
|
|
||||||
u32 last_cmd_consumer;
|
u32 last_cmd_consumer;
|
||||||
u32 max_tx_desc_count;
|
u32 max_tx_desc_count;
|
||||||
u32 max_rx_desc_count;
|
u32 max_rx_desc_count;
|
||||||
u32 max_jumbo_rx_desc_count;
|
u32 max_jumbo_rx_desc_count;
|
||||||
|
u32 max_lro_rx_desc_count;
|
||||||
/* Num of instances active on cmd buffer ring */
|
/* Num of instances active on cmd buffer ring */
|
||||||
u32 proc_cmd_buf_counter;
|
u32 proc_cmd_buf_counter;
|
||||||
|
|
||||||
@@ -744,6 +886,13 @@ struct netxen_adapter {
|
|||||||
struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
|
struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
|
||||||
|
|
||||||
int is_up;
|
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 (*enable_phy_interrupts) (struct netxen_adapter *, int);
|
||||||
int (*disable_phy_interrupts) (struct netxen_adapter *, int);
|
int (*disable_phy_interrupts) (struct netxen_adapter *, int);
|
||||||
void (*handle_phy_intr) (struct netxen_adapter *);
|
void (*handle_phy_intr) (struct netxen_adapter *);
|
||||||
@@ -758,7 +907,6 @@ struct netxen_adapter {
|
|||||||
int (*init_port) (struct netxen_adapter *, int);
|
int (*init_port) (struct netxen_adapter *, int);
|
||||||
void (*init_niu) (struct netxen_adapter *);
|
void (*init_niu) (struct netxen_adapter *);
|
||||||
int (*stop_port) (struct netxen_adapter *, int);
|
int (*stop_port) (struct netxen_adapter *, int);
|
||||||
|
|
||||||
}; /* netxen_adapter structure */
|
}; /* netxen_adapter structure */
|
||||||
|
|
||||||
/* Max number of xmit producer threads that can run simultaneously */
|
/* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char netxen_nic_driver_name[];
|
|
||||||
|
|
||||||
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter,
|
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter,
|
||||||
int port);
|
int port);
|
||||||
int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
|
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 len);
|
||||||
int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
|
int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
|
||||||
int len);
|
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,
|
void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
|
||||||
unsigned long off, int data);
|
unsigned long off, int data);
|
||||||
|
|
||||||
/* Functions from netxen_nic_init.c */
|
/* 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_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
|
||||||
void netxen_load_firmware(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_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_watchdog_task(unsigned long v);
|
||||||
void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
|
void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
|
||||||
u32 ringid);
|
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);
|
u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
|
||||||
void netxen_nic_set_multi(struct net_device *netdev);
|
void netxen_nic_set_multi(struct net_device *netdev);
|
||||||
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
|
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_is_flash_supported(struct netxen_adapter *adapter);
|
||||||
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
|
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
|
||||||
|
|
||||||
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
|
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
|
||||||
extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
|
extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
|
||||||
int *valp);
|
int *valp);
|
||||||
|
@@ -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_port *port = netdev_priv(dev);
|
||||||
struct netxen_adapter *adapter = port->adapter;
|
struct netxen_adapter *adapter = port->adapter;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
ring->rx_pending = 0;
|
ring->rx_pending = 0;
|
||||||
|
ring->rx_jumbo_pending = 0;
|
||||||
for (i = 0; i < MAX_RCV_CTX; ++i) {
|
for (i = 0; i < MAX_RCV_CTX; ++i) {
|
||||||
for (j = 0; j < NUM_RCV_DESC_RINGS; j++)
|
ring->rx_pending += adapter->recv_ctx[i].
|
||||||
ring->rx_pending +=
|
rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending;
|
||||||
adapter->recv_ctx[i].rcv_desc[j].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->rx_max_pending = adapter->max_rx_desc_count;
|
||||||
ring->tx_max_pending = adapter->max_tx_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_max_pending = 0;
|
||||||
ring->rx_mini_pending = 0;
|
ring->rx_mini_pending = 0;
|
||||||
ring->rx_jumbo_max_pending = 0;
|
|
||||||
ring->rx_jumbo_pending = 0;
|
ring->rx_jumbo_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#define NETXEN_FLASH_BASE (BOOTLD_START)
|
#define NETXEN_FLASH_BASE (BOOTLD_START)
|
||||||
#define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE)
|
#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_MIN_MTU 64
|
||||||
#define NETXEN_ETH_FCS_SIZE 4
|
#define NETXEN_ETH_FCS_SIZE 4
|
||||||
#define NETXEN_ENET_HEADER_SIZE 14
|
#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;
|
struct netxen_hardware_context *hw = &adapter->ahw;
|
||||||
u32 state = 0;
|
u32 state = 0;
|
||||||
void *addr;
|
void *addr;
|
||||||
void *pause_addr;
|
|
||||||
int loops = 0, err = 0;
|
int loops = 0, err = 0;
|
||||||
int ctx, ring;
|
int ctx, ring;
|
||||||
u32 card_cmdring = 0;
|
u32 card_cmdring = 0;
|
||||||
struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
|
|
||||||
struct netxen_recv_context *recv_ctx;
|
struct netxen_recv_context *recv_ctx;
|
||||||
struct netxen_rcv_desc_ctx *rcv_desc;
|
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");
|
DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
|
||||||
|
|
||||||
addr = netxen_alloc(adapter->ahw.pdev,
|
addr = netxen_alloc(adapter->ahw.pdev,
|
||||||
sizeof(struct cmd_desc_type0) *
|
sizeof(struct netxen_ring_ctx) +
|
||||||
adapter->max_tx_desc_count,
|
sizeof(uint32_t),
|
||||||
&hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev);
|
(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");
|
||||||
|
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);
|
||||||
|
|
||||||
if (addr == NULL) {
|
if (addr == NULL) {
|
||||||
DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
|
DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
|
||||||
|
netxen_free_hw_resources(adapter);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
pause_addr = netxen_alloc(adapter->ahw.pdev, 512,
|
adapter->ctx_desc->cmd_ring_addr_lo =
|
||||||
(dma_addr_t *) & hw->pause_physaddr,
|
hw->cmd_desc_phys_addr & 0xffffffffUL;
|
||||||
&hw->pause_pdev);
|
adapter->ctx_desc->cmd_ring_addr_hi =
|
||||||
if (pause_addr == NULL) {
|
((u64) hw->cmd_desc_phys_addr >> 32);
|
||||||
DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n");
|
adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
|
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
|
||||||
|
|
||||||
@@ -271,6 +278,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
rcv_desc->desc_head = (struct rcv_desc *)addr;
|
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,
|
addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
|
||||||
@@ -284,47 +297,21 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
|
recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
|
||||||
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
|
adapter->ctx_desc->sts_ring_addr_lo =
|
||||||
rcv_desc = &recv_ctx->rcv_desc[ring];
|
recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL;
|
||||||
rcv_desc_crb =
|
adapter->ctx_desc->sts_ring_addr_hi =
|
||||||
&recv_crb_registers[ctx].rcv_desc_crb[ring];
|
((u64) recv_ctx->rcv_status_desc_phys_addr >> 32);
|
||||||
DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
|
adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
/* 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),
|
writel(lower32(adapter->ctx_desc_phys_addr),
|
||||||
NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
|
NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO));
|
||||||
writel(upper32(hw->cmd_desc_phys_addr),
|
writel(upper32(adapter->ctx_desc_phys_addr),
|
||||||
NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI));
|
NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI));
|
||||||
|
writel(NETXEN_CTX_SIGNATURE,
|
||||||
|
NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +321,15 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
|
|||||||
struct netxen_rcv_desc_ctx *rcv_desc;
|
struct netxen_rcv_desc_ctx *rcv_desc;
|
||||||
int ctx, ring;
|
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) {
|
if (adapter->ahw.cmd_desc_head != NULL) {
|
||||||
pci_free_consistent(adapter->ahw.cmd_desc_pdev,
|
pci_free_consistent(adapter->ahw.cmd_desc_pdev,
|
||||||
sizeof(struct cmd_desc_type0) *
|
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_phys_addr);
|
||||||
adapter->ahw.cmd_desc_head = NULL;
|
adapter->ahw.cmd_desc_head = NULL;
|
||||||
}
|
}
|
||||||
if (adapter->ahw.pauseaddr != NULL) {
|
/* Special handling: there are 2 ports on this board */
|
||||||
pci_free_consistent(adapter->ahw.pause_pdev, 512,
|
if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
|
||||||
adapter->ahw.pauseaddr,
|
adapter->ahw.max_ports = 2;
|
||||||
adapter->ahw.pause_physaddr);
|
|
||||||
adapter->ahw.pauseaddr = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
|
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) +
|
desc->total_hdr_length = sizeof(struct ethhdr) +
|
||||||
((skb->nh.iph)->ihl * sizeof(u32)) +
|
((skb->nh.iph)->ihl * sizeof(u32)) +
|
||||||
((skb->h.th)->doff * 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) {
|
} else if (skb->ip_summed == CHECKSUM_COMPLETE) {
|
||||||
if (skb->nh.iph->protocol == IPPROTO_TCP) {
|
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) {
|
} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
|
||||||
desc->opcode = TX_UDP_PKT;
|
netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adapter->stats.xmitcsummed++;
|
adapter->stats.xmitcsummed++;
|
||||||
CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
|
desc->tcp_hdr_offset = skb->h.raw - skb->data;
|
||||||
desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
|
netxen_set_cmd_desc_totallength(desc,
|
||||||
|
cpu_to_le32
|
||||||
|
(netxen_get_cmd_desc_totallength
|
||||||
|
(desc)));
|
||||||
desc->ip_hdr_offset = skb->nh.raw - skb->data;
|
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;
|
struct netxen_adapter *adapter = port->adapter;
|
||||||
__le32 status;
|
__le32 status;
|
||||||
u16 autoneg;
|
__le32 autoneg;
|
||||||
__le32 mode;
|
__le32 mode;
|
||||||
|
|
||||||
netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &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->
|
&& adapter->
|
||||||
phy_read(adapter, port->portnum,
|
phy_read(adapter, port->portnum,
|
||||||
NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
|
NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
|
||||||
(__le32 *) & autoneg) != 0)
|
&autoneg) != 0)
|
||||||
port->link_autoneg = autoneg;
|
port->link_autoneg = autoneg;
|
||||||
} else
|
} else
|
||||||
goto link_down;
|
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);
|
netxen_nic_hw_read_wx(adapter, off, &data, 4);
|
||||||
return data;
|
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;
|
||||||
|
}
|
||||||
|
@@ -137,6 +137,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* Window 1 call */
|
/* Window 1 call */
|
||||||
|
writel(MPORT_SINGLE_FUNCTION_MODE,
|
||||||
|
NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
|
||||||
writel(PHAN_INITIALIZE_ACK,
|
writel(PHAN_INITIALIZE_ACK,
|
||||||
NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
|
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++) {
|
for (i = 0; i < num_rx_bufs; i++) {
|
||||||
rx_buf->ref_handle = i;
|
rx_buf->ref_handle = i;
|
||||||
rx_buf->state = NETXEN_BUFFER_FREE;
|
rx_buf->state = NETXEN_BUFFER_FREE;
|
||||||
|
|
||||||
DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
|
DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
|
||||||
"%p\n", ctxid, i, rx_buf);
|
"%p\n", ctxid, i, rx_buf);
|
||||||
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)
|
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;
|
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)
|
void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
|
||||||
{
|
{
|
||||||
u32 val = 0;
|
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_head = recv_ctx->rcv_status_desc_head;
|
||||||
desc = &desc_head[consumer];
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,19 +784,19 @@ void
|
|||||||
netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
|
netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
|
||||||
struct status_desc *desc)
|
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 pci_dev *pdev = port->pdev;
|
||||||
struct net_device *netdev = port->netdev;
|
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_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
|
||||||
struct netxen_rx_buffer *buffer;
|
struct netxen_rx_buffer *buffer;
|
||||||
struct sk_buff *skb;
|
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;
|
u32 desc_ctx;
|
||||||
struct netxen_rcv_desc_ctx *rcv_desc;
|
struct netxen_rcv_desc_ctx *rcv_desc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
desc_ctx = STATUS_DESC_TYPE(desc);
|
desc_ctx = netxen_get_sts_type(desc);
|
||||||
if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
|
if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
|
||||||
printk("%s: %s Bad Rcv descriptor ring\n",
|
printk("%s: %s Bad Rcv descriptor ring\n",
|
||||||
netxen_nic_driver_name, netdev->name);
|
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];
|
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];
|
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_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
skb = (struct sk_buff *)buffer->skb;
|
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++;
|
port->stats.csummed++;
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
} else
|
}
|
||||||
skb->ip_summed = CHECKSUM_NONE;
|
|
||||||
skb->dev = netdev;
|
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);
|
skb->protocol = eth_type_trans(skb, netdev);
|
||||||
|
|
||||||
ret = netif_receive_skb(skb);
|
ret = netif_receive_skb(skb);
|
||||||
@@ -826,6 +892,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
|
|||||||
adapter->stats.post_called++;
|
adapter->stats.post_called++;
|
||||||
buffer->skb = NULL;
|
buffer->skb = NULL;
|
||||||
buffer->state = NETXEN_BUFFER_FREE;
|
buffer->state = NETXEN_BUFFER_FREE;
|
||||||
|
buffer->lro_current_frags = 0;
|
||||||
|
buffer->lro_expected_frags = 0;
|
||||||
|
|
||||||
port->stats.no_rcv++;
|
port->stats.no_rcv++;
|
||||||
port->stats.rxbytes += length;
|
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_head = recv_ctx->rcv_status_desc_head;
|
||||||
struct status_desc *desc; /* used to read status desc here */
|
struct status_desc *desc; /* used to read status desc here */
|
||||||
u32 consumer = recv_ctx->status_rx_consumer;
|
u32 consumer = recv_ctx->status_rx_consumer;
|
||||||
|
u32 producer = 0;
|
||||||
int count = 0, ring;
|
int count = 0, ring;
|
||||||
|
|
||||||
DPRINTK(INFO, "procesing receive\n");
|
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) {
|
while (count < max) {
|
||||||
desc = &desc_head[consumer];
|
desc = &desc_head[consumer];
|
||||||
if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) {
|
if (!
|
||||||
DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
|
(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;
|
break;
|
||||||
}
|
}
|
||||||
netxen_process_rcv(adapter, ctxid, desc);
|
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);
|
consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (count) {
|
if (count) {
|
||||||
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
|
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) {
|
if (count) {
|
||||||
adapter->stats.process_rcv++;
|
adapter->stats.process_rcv++;
|
||||||
recv_ctx->status_rx_consumer = consumer;
|
recv_ctx->status_rx_consumer = consumer;
|
||||||
|
recv_ctx->status_rx_producer = producer;
|
||||||
|
|
||||||
/* Window = 1 */
|
/* Window = 1 */
|
||||||
writel(consumer,
|
writel(consumer,
|
||||||
@@ -880,12 +954,13 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process Command status ring */
|
/* Process Command status ring */
|
||||||
void netxen_process_cmd_ring(unsigned long data)
|
int netxen_process_cmd_ring(unsigned long data)
|
||||||
{
|
{
|
||||||
u32 last_consumer;
|
u32 last_consumer;
|
||||||
u32 consumer;
|
u32 consumer;
|
||||||
struct netxen_adapter *adapter = (struct netxen_adapter *)data;
|
struct netxen_adapter *adapter = (struct netxen_adapter *)data;
|
||||||
int count = 0;
|
int count1 = 0;
|
||||||
|
int count2 = 0;
|
||||||
struct netxen_cmd_buffer *buffer;
|
struct netxen_cmd_buffer *buffer;
|
||||||
struct netxen_port *port; /* port #1 */
|
struct netxen_port *port; /* port #1 */
|
||||||
struct netxen_port *nport;
|
struct netxen_port *nport;
|
||||||
@@ -894,6 +969,7 @@ void netxen_process_cmd_ring(unsigned long data)
|
|||||||
u32 i;
|
u32 i;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
int p;
|
int p;
|
||||||
|
int done;
|
||||||
|
|
||||||
spin_lock(&adapter->tx_lock);
|
spin_lock(&adapter->tx_lock);
|
||||||
last_consumer = adapter->last_cmd_consumer;
|
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
|
* number as part of the descriptor. This way we will be able to get
|
||||||
* the netdev which is associated with that device.
|
* 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 */
|
if (last_consumer == consumer) { /* Ring is empty */
|
||||||
DPRINTK(INFO, "last_consumer %d == consumer %d\n",
|
DPRINTK(INFO, "last_consumer %d == consumer %d\n",
|
||||||
last_consumer, consumer);
|
last_consumer, consumer);
|
||||||
spin_unlock(&adapter->tx_lock);
|
spin_unlock(&adapter->tx_lock);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter->proc_cmd_buf_counter++;
|
adapter->proc_cmd_buf_counter++;
|
||||||
@@ -921,7 +996,7 @@ void netxen_process_cmd_ring(unsigned long data)
|
|||||||
*/
|
*/
|
||||||
spin_unlock(&adapter->tx_lock);
|
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];
|
buffer = &adapter->cmd_buf_arr[last_consumer];
|
||||||
port = adapter->port[buffer->port];
|
port = adapter->port[buffer->port];
|
||||||
pdev = port->pdev;
|
pdev = port->pdev;
|
||||||
@@ -947,24 +1022,25 @@ void netxen_process_cmd_ring(unsigned long data)
|
|||||||
&& netif_carrier_ok(port->netdev))
|
&& netif_carrier_ok(port->netdev))
|
||||||
&& ((jiffies - port->netdev->trans_start) >
|
&& ((jiffies - port->netdev->trans_start) >
|
||||||
port->netdev->watchdog_timeo)) {
|
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,
|
last_consumer = get_next_index(last_consumer,
|
||||||
adapter->max_tx_desc_count);
|
adapter->max_tx_desc_count);
|
||||||
count++;
|
count1++;
|
||||||
}
|
}
|
||||||
adapter->stats.noxmitdone += count;
|
adapter->stats.noxmitdone += count1;
|
||||||
|
|
||||||
count = 0;
|
count2 = 0;
|
||||||
spin_lock(&adapter->tx_lock);
|
spin_lock(&adapter->tx_lock);
|
||||||
if ((--adapter->proc_cmd_buf_counter) == 0) {
|
if ((--adapter->proc_cmd_buf_counter) == 0) {
|
||||||
adapter->last_cmd_consumer = last_consumer;
|
adapter->last_cmd_consumer = last_consumer;
|
||||||
while ((adapter->last_cmd_consumer != consumer)
|
while ((adapter->last_cmd_consumer != consumer)
|
||||||
&& (count < MAX_STATUS_HANDLE)) {
|
&& (count2 < MAX_STATUS_HANDLE)) {
|
||||||
buffer =
|
buffer =
|
||||||
&adapter->cmd_buf_arr[adapter->last_cmd_consumer];
|
&adapter->cmd_buf_arr[adapter->last_cmd_consumer];
|
||||||
count++;
|
count2++;
|
||||||
if (buffer->skb)
|
if (buffer->skb)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
@@ -973,7 +1049,7 @@ void netxen_process_cmd_ring(unsigned long data)
|
|||||||
adapter->max_tx_desc_count);
|
adapter->max_tx_desc_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count) {
|
if (count1 || count2) {
|
||||||
for (p = 0; p < adapter->ahw.max_ports; p++) {
|
for (p = 0; p < adapter->ahw.max_ports; p++) {
|
||||||
nport = adapter->port[p];
|
nport = adapter->port[p];
|
||||||
if (netif_queue_stopped(nport->netdev)
|
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);
|
spin_unlock(&adapter->tx_lock);
|
||||||
DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
|
DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
|
return (done);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -998,8 +1094,105 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
|
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
|
||||||
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
|
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
|
||||||
struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx];
|
uint producer;
|
||||||
struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
|
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];
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
/*
|
||||||
|
* TODO
|
||||||
|
* We need to schedule the posting of buffers to the pegs.
|
||||||
|
*/
|
||||||
|
rcv_desc->begin_alloc = index;
|
||||||
|
DPRINTK(ERR, "netxen_post_rx_buffers: "
|
||||||
|
" 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;
|
u32 producer;
|
||||||
struct rcv_desc *pdesc;
|
struct rcv_desc *pdesc;
|
||||||
struct netxen_rx_buffer *buffer;
|
struct netxen_rx_buffer *buffer;
|
||||||
@@ -1008,7 +1201,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
|
|||||||
|
|
||||||
adapter->stats.post_called++;
|
adapter->stats.post_called++;
|
||||||
rcv_desc = &recv_ctx->rcv_desc[ringid];
|
rcv_desc = &recv_ctx->rcv_desc[ringid];
|
||||||
rcv_desc_crb = &crbarea->rcv_desc_crb[ringid];
|
|
||||||
|
|
||||||
producer = rcv_desc->producer;
|
producer = rcv_desc->producer;
|
||||||
index = rcv_desc->begin_alloc;
|
index = rcv_desc->begin_alloc;
|
||||||
@@ -1021,13 +1213,13 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
|
|||||||
* We need to schedule the posting of buffers to the pegs.
|
* We need to schedule the posting of buffers to the pegs.
|
||||||
*/
|
*/
|
||||||
rcv_desc->begin_alloc = index;
|
rcv_desc->begin_alloc = index;
|
||||||
DPRINTK(ERR, "netxen_post_rx_buffers: "
|
DPRINTK(ERR, "netxen_post_rx_buffers_nodb: "
|
||||||
" allocated only %d buffers\n", count);
|
" allocated only %d buffers\n", count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count++; /* now there should be no failure */
|
count++; /* now there should be no failure */
|
||||||
pdesc = &rcv_desc->desc_head[producer];
|
pdesc = &rcv_desc->desc_head[producer];
|
||||||
skb_reserve(skb, NET_IP_ALIGN);
|
skb_reserve(skb, 2);
|
||||||
/*
|
/*
|
||||||
* This will be setup when we receive the
|
* This will be setup when we receive the
|
||||||
* buffer after it has been filled
|
* 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,
|
buffer->dma = pci_map_single(pdev, skb->data,
|
||||||
rcv_desc->dma_size,
|
rcv_desc->dma_size,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
/* make a rcv descriptor */
|
/* make a rcv descriptor */
|
||||||
pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
|
pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
|
||||||
pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
|
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) &
|
writel((producer - 1) &
|
||||||
(rcv_desc->max_rx_desc_count - 1),
|
(rcv_desc->max_rx_desc_count - 1),
|
||||||
NETXEN_CRB_NORMALIZE(adapter,
|
NETXEN_CRB_NORMALIZE(adapter,
|
||||||
rcv_desc_crb->
|
recv_crb_registers[0].
|
||||||
|
rcv_desc_crb[ringid].
|
||||||
crb_rcv_producer_offset));
|
crb_rcv_producer_offset));
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
@@ -1195,8 +1389,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
|
|||||||
|
|
||||||
switch (data.cmd) {
|
switch (data.cmd) {
|
||||||
case netxen_nic_cmd_pci_read:
|
case netxen_nic_cmd_pci_read:
|
||||||
if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
|
if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off,
|
||||||
&(data.u), data.size)))
|
&(data.u), data.size)))
|
||||||
goto error_out;
|
goto error_out;
|
||||||
if (copy_to_user
|
if (copy_to_user
|
||||||
((void __user *)&(up_data->u), &(data.u), data.size)) {
|
((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;
|
break;
|
||||||
|
|
||||||
case netxen_nic_cmd_pci_write:
|
case netxen_nic_cmd_pci_write:
|
||||||
data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
|
if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off,
|
||||||
data.size);
|
&(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;
|
break;
|
||||||
|
|
||||||
case netxen_nic_cmd_pci_config_read:
|
case netxen_nic_cmd_pci_config_read:
|
||||||
@@ -1295,7 +1516,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
|
|||||||
retval = -EOPNOTSUPP;
|
retval = -EOPNOTSUPP;
|
||||||
goto error_out;
|
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);
|
DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
|
||||||
|
|
||||||
error_out:
|
error_out:
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1)
|
#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1)
|
||||||
#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2)
|
#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2)
|
||||||
#define NETXEN_NIC_NAME_LEN 16
|
#define NETXEN_NIC_NAME_LEN 16
|
||||||
#define NETXEN_NIC_NAME_RSP "NETXEN"
|
#define NETXEN_NIC_NAME_RSP "NETXEN-UNM"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
netxen_nic_cmd_none = 0,
|
netxen_nic_cmd_none = 0,
|
||||||
|
@@ -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,
|
void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
|
||||||
u32 link)
|
u32 link)
|
||||||
{
|
{
|
||||||
struct netxen_port *pport = adapter->port[portno];
|
struct net_device *netdev = (adapter->port[portno])->netdev;
|
||||||
struct net_device *netdev = pport->netdev;
|
|
||||||
|
|
||||||
if (link)
|
if (link)
|
||||||
netif_carrier_on(netdev);
|
netif_carrier_on(netdev);
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/highmem.h>
|
||||||
#include "netxen_nic_hw.h"
|
#include "netxen_nic_hw.h"
|
||||||
|
|
||||||
#include "netxen_nic.h"
|
#include "netxen_nic.h"
|
||||||
@@ -48,14 +49,21 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
|
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 "
|
static char netxen_nic_driver_string[] = "NetXen Network Driver version "
|
||||||
NETXEN_NIC_LINUX_VERSIONID;
|
NETXEN_NIC_LINUX_VERSIONID;
|
||||||
|
|
||||||
|
struct netxen_adapter *g_adapter = NULL;
|
||||||
|
|
||||||
#define NETXEN_NETDEV_WEIGHT 120
|
#define NETXEN_NETDEV_WEIGHT 120
|
||||||
#define NETXEN_ADAPTER_UP_MAGIC 777
|
#define NETXEN_ADAPTER_UP_MAGIC 777
|
||||||
#define NETXEN_NIC_PEG_TUNE 0
|
#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 */
|
/* Local functions to NetXen NIC driver */
|
||||||
static int __devinit netxen_nic_probe(struct pci_dev *pdev,
|
static int __devinit netxen_nic_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent);
|
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);
|
MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
|
||||||
|
|
||||||
|
struct workqueue_struct *netxen_workq;
|
||||||
|
static void netxen_watchdog(unsigned long);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* netxen_nic_probe()
|
* 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 net_device *netdev = NULL;
|
||||||
struct netxen_adapter *adapter = NULL;
|
struct netxen_adapter *adapter = NULL;
|
||||||
struct netxen_port *port = NULL;
|
struct netxen_port *port = NULL;
|
||||||
u8 *mem_ptr0 = NULL;
|
void __iomem *mem_ptr0 = NULL;
|
||||||
u8 *mem_ptr1 = NULL;
|
void __iomem *mem_ptr1 = NULL;
|
||||||
u8 *mem_ptr2 = 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 pci_using_dac, i, err;
|
||||||
int ring;
|
int ring;
|
||||||
struct netxen_recv_context *recv_ctx = NULL;
|
struct netxen_recv_context *recv_ctx = NULL;
|
||||||
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
|
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
|
||||||
struct netxen_cmd_buffer *cmd_buf_arr = NULL;
|
struct netxen_cmd_buffer *cmd_buf_arr = NULL;
|
||||||
u64 mac_addr[FLASH_NUM_PORTS + 1];
|
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);
|
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)))
|
if ((err = pci_enable_device(pdev)))
|
||||||
return err;
|
return err;
|
||||||
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
|
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;
|
goto err_out_disable_pdev;
|
||||||
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) &&
|
pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id);
|
||||||
(pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0))
|
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;
|
pci_using_dac = 1;
|
||||||
else {
|
} else {
|
||||||
if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
|
if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
|
||||||
(err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
|
(err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
|
||||||
goto err_out_free_res;
|
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);
|
ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
|
||||||
|
|
||||||
if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
|
if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
|
||||||
DPRINTK(1, ERR,
|
DPRINTK(ERR,
|
||||||
"Cannot remap adapter memory aborting.:"
|
"Cannot remap adapter memory aborting.:"
|
||||||
"0 -> %p, 1 -> %p, 2 -> %p\n",
|
"0 -> %p, 1 -> %p, 2 -> %p\n",
|
||||||
mem_ptr0, mem_ptr1, mem_ptr2);
|
mem_ptr0, mem_ptr1, mem_ptr2);
|
||||||
|
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
if (mem_ptr0)
|
goto err_out_iounmap;
|
||||||
iounmap(mem_ptr0);
|
|
||||||
if (mem_ptr1)
|
|
||||||
iounmap(mem_ptr1);
|
|
||||||
if (mem_ptr2)
|
|
||||||
iounmap(mem_ptr2);
|
|
||||||
|
|
||||||
goto err_out_free_res;
|
|
||||||
}
|
}
|
||||||
|
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
|
* 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,
|
netxen_nic_driver_name,
|
||||||
(int)sizeof(struct netxen_adapter));
|
(int)sizeof(struct netxen_adapter));
|
||||||
err = -ENOMEM;
|
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_tx_desc_count = MAX_CMD_DESCRIPTORS;
|
||||||
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
|
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
|
||||||
adapter->max_jumbo_rx_desc_count = MAX_JUMBO_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);
|
pci_set_drvdata(pdev, adapter);
|
||||||
|
|
||||||
cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
|
cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
|
||||||
if (cmd_buf_arr == NULL) {
|
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;
|
err = -ENOMEM;
|
||||||
goto err_out_free_adapter;
|
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;
|
rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH;
|
||||||
break;
|
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 *)
|
rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
|
||||||
vmalloc(RCV_BUFFSIZE);
|
vmalloc(RCV_BUFFSIZE);
|
||||||
|
|
||||||
if (rcv_desc->rx_buf_arr == NULL) {
|
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;
|
err = -ENOMEM;
|
||||||
goto err_out_free_rx_buffer;
|
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_base0 = mem_ptr0;
|
||||||
adapter->ahw.pci_base1 = mem_ptr1;
|
adapter->ahw.pci_base1 = mem_ptr1;
|
||||||
adapter->ahw.pci_base2 = mem_ptr2;
|
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->tx_lock);
|
||||||
spin_lock_init(&adapter->lock);
|
spin_lock_init(&adapter->lock);
|
||||||
|
netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */
|
||||||
#ifdef CONFIG_IA64
|
#ifdef CONFIG_IA64
|
||||||
netxen_pinit_from_rom(adapter, 0);
|
netxen_pinit_from_rom(adapter, 0);
|
||||||
udelay(500);
|
udelay(500);
|
||||||
netxen_load_firmware(adapter);
|
netxen_load_firmware(adapter);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* initialize the buffers in adapter */
|
|
||||||
netxen_initialize_adapter_sw(adapter);
|
|
||||||
/*
|
/*
|
||||||
* Set the CRB window to invalid. If any register in window 0 is
|
* 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.
|
* 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);
|
(void (*)(void *))netxen_watchdog_task, adapter);
|
||||||
adapter->ahw.pdev = pdev;
|
adapter->ahw.pdev = pdev;
|
||||||
adapter->proc_cmd_buf_counter = 0;
|
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)) {
|
if (pci_enable_msi(pdev)) {
|
||||||
adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
|
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_CMD_CONSUMER_OFFSET));
|
||||||
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
|
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 */
|
/* Unlock the HW, prompting the boot sequence */
|
||||||
writel(1,
|
writel(1,
|
||||||
NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
|
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);
|
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
|
||||||
|
|
||||||
/* initialize the all the ports */
|
/* initialize the all the ports */
|
||||||
|
adapter->active_ports = 0;
|
||||||
|
|
||||||
for (i = 0; i < adapter->ahw.max_ports; i++) {
|
for (i = 0; i < adapter->ahw.max_ports; i++) {
|
||||||
netdev = alloc_etherdev(sizeof(struct netxen_port));
|
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);
|
netdev->dev_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INIT_WORK(&adapter->tx_timeout_task,
|
INIT_WORK(adapter->tx_timeout_task + i,
|
||||||
(void (*)(void *))netxen_tx_timeout_task, netdev);
|
(void (*)(void *))netxen_tx_timeout_task, netdev);
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
netif_stop_queue(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;
|
goto err_out_free_dev;
|
||||||
}
|
}
|
||||||
adapter->port_count++;
|
adapter->port_count++;
|
||||||
adapter->active_ports = 0;
|
|
||||||
adapter->port[i] = port;
|
adapter->port[i] = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,6 +462,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adapter->number = netxen_cards_found;
|
||||||
adapter->driver_mismatch = 0;
|
adapter->driver_mismatch = 0;
|
||||||
|
|
||||||
return 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:
|
err_out_free_rx_buffer:
|
||||||
for (i = 0; i < MAX_RCV_CTX; ++i) {
|
for (i = 0; i < MAX_RCV_CTX; ++i) {
|
||||||
recv_ctx = &adapter->recv_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);
|
vfree(cmd_buf_arr);
|
||||||
|
|
||||||
kfree(adapter->port);
|
|
||||||
|
|
||||||
err_out_free_adapter:
|
err_out_free_adapter:
|
||||||
pci_set_drvdata(pdev, NULL);
|
pci_set_drvdata(pdev, NULL);
|
||||||
kfree(adapter);
|
kfree(adapter);
|
||||||
|
|
||||||
|
err_out_dbunmap:
|
||||||
|
if (db_ptr)
|
||||||
|
iounmap(db_ptr);
|
||||||
|
|
||||||
err_out_iounmap:
|
err_out_iounmap:
|
||||||
iounmap(mem_ptr0);
|
if (mem_ptr0)
|
||||||
iounmap(mem_ptr1);
|
iounmap(mem_ptr0);
|
||||||
iounmap(mem_ptr2);
|
if (mem_ptr1)
|
||||||
|
iounmap(mem_ptr1);
|
||||||
|
if (mem_ptr2)
|
||||||
|
iounmap(mem_ptr2);
|
||||||
|
|
||||||
err_out_free_res:
|
err_out_free_res:
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
@@ -465,12 +532,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
netxen_nic_stop_all_ports(adapter);
|
netxen_nic_stop_all_ports(adapter);
|
||||||
/* leave the hw in the same state as reboot */
|
/* leave the hw in the same state as reboot */
|
||||||
netxen_pinit_from_rom(adapter, 0);
|
|
||||||
udelay(500);
|
|
||||||
netxen_load_firmware(adapter);
|
netxen_load_firmware(adapter);
|
||||||
|
netxen_free_adapter_offload(adapter);
|
||||||
if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
|
|
||||||
netxen_nic_disable_int(adapter);
|
|
||||||
|
|
||||||
udelay(500); /* Delay for a while to drain the DMA engines */
|
udelay(500); /* Delay for a while to drain the DMA engines */
|
||||||
for (i = 0; i < adapter->port_count; i++) {
|
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)
|
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
|
||||||
netxen_free_hw_resources(adapter);
|
netxen_free_hw_resources(adapter);
|
||||||
|
|
||||||
|
iounmap(adapter->ahw.db_base);
|
||||||
iounmap(adapter->ahw.pci_base0);
|
iounmap(adapter->ahw.pci_base0);
|
||||||
iounmap(adapter->ahw.pci_base1);
|
iounmap(adapter->ahw.pci_base1);
|
||||||
iounmap(adapter->ahw.pci_base2);
|
iounmap(adapter->ahw.pci_base2);
|
||||||
@@ -534,6 +598,8 @@ static int netxen_nic_open(struct net_device *netdev)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
netxen_nic_flash_print(adapter);
|
netxen_nic_flash_print(adapter);
|
||||||
|
if (adapter->init_niu)
|
||||||
|
adapter->init_niu(adapter);
|
||||||
|
|
||||||
/* setup all the resources for the Phantom... */
|
/* setup all the resources for the Phantom... */
|
||||||
/* this include the descriptors for rcv, tx, and status */
|
/* 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);
|
netxen_free_hw_resources(adapter);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (adapter->init_niu)
|
|
||||||
adapter->init_niu(adapter);
|
|
||||||
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
|
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
|
||||||
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
|
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
|
||||||
netxen_post_rx_buffers(adapter, ctx, ring);
|
netxen_post_rx_buffers(adapter, ctx, ring);
|
||||||
}
|
}
|
||||||
adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
|
adapter->irq = adapter->ahw.pdev->irq;
|
||||||
}
|
|
||||||
adapter->active_ports++;
|
|
||||||
if (adapter->active_ports == 1) {
|
|
||||||
err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
|
err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
|
||||||
SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
|
SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
|
||||||
adapter);
|
adapter);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "request_irq failed with: %d\n", err);
|
printk(KERN_ERR "request_irq failed with: %d\n", err);
|
||||||
adapter->active_ports--;
|
netxen_free_hw_resources(adapter);
|
||||||
return err;
|
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)
|
if (!adapter->driver_mismatch)
|
||||||
mod_timer(&adapter->watchdog_timer, jiffies);
|
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_link_parameters(port);
|
||||||
|
|
||||||
netxen_nic_set_multi(netdev);
|
netxen_nic_set_multi(netdev);
|
||||||
|
if (adapter->set_mtu)
|
||||||
|
adapter->set_mtu(port, netdev->mtu);
|
||||||
|
|
||||||
if (!adapter->driver_mismatch)
|
if (!adapter->driver_mismatch)
|
||||||
netif_start_queue(netdev);
|
netif_start_queue(netdev);
|
||||||
|
|
||||||
@@ -635,6 +703,7 @@ static int netxen_nic_close(struct net_device *netdev)
|
|||||||
}
|
}
|
||||||
cmd_buff++;
|
cmd_buff++;
|
||||||
}
|
}
|
||||||
|
FLUSH_SCHEDULED_WORK();
|
||||||
del_timer_sync(&adapter->watchdog_timer);
|
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;
|
struct cmd_desc_type0 *hwdesc;
|
||||||
int k;
|
int k;
|
||||||
struct netxen_cmd_buffer *pbuf = NULL;
|
struct netxen_cmd_buffer *pbuf = NULL;
|
||||||
unsigned int tries = 0;
|
|
||||||
static int dropped_packet = 0;
|
static int dropped_packet = 0;
|
||||||
int frag_count;
|
int frag_count;
|
||||||
u32 local_producer = 0;
|
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)) +
|
if (((skb->nh.iph)->ihl * sizeof(u32)) +
|
||||||
((skb->h.th)->doff * sizeof(u32)) +
|
((skb->h.th)->doff * sizeof(u32)) +
|
||||||
sizeof(struct ethhdr) >
|
sizeof(struct ethhdr) >
|
||||||
(sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
|
(sizeof(struct cmd_desc_type0) - 2)) {
|
||||||
no_of_desc++;
|
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) >=
|
if ((k + no_of_desc) >=
|
||||||
((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
|
((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
|
||||||
last_cmd_consumer)) {
|
last_cmd_consumer)) {
|
||||||
spin_unlock_bh(&adapter->tx_lock);
|
port->stats.nocmddescriptor++;
|
||||||
if (tries == 0) {
|
DPRINTK(ERR, "No command descriptors available,"
|
||||||
local_bh_disable();
|
" producer = %d, consumer = %d count=%llu,"
|
||||||
netxen_process_cmd_ring((unsigned long)adapter);
|
" dropping packet\n", producer,
|
||||||
local_bh_enable();
|
adapter->last_cmd_consumer,
|
||||||
++tries;
|
port->stats.nocmddescriptor);
|
||||||
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);
|
||||||
netif_stop_queue(netdev);
|
port->flags |= NETXEN_NETDEV_STATUS;
|
||||||
port->flags |= NETXEN_NETDEV_STATUS;
|
spin_unlock_bh(&adapter->tx_lock);
|
||||||
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);
|
k = get_index_range(k, max_tx_desc_count, no_of_desc);
|
||||||
adapter->cmd_producer = k;
|
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;
|
pbuf->mss = 0;
|
||||||
hwdesc->mss = 0;
|
hwdesc->mss = 0;
|
||||||
}
|
}
|
||||||
pbuf->no_of_descriptors = no_of_desc;
|
|
||||||
pbuf->total_length = skb->len;
|
pbuf->total_length = skb->len;
|
||||||
pbuf->skb = skb;
|
pbuf->skb = skb;
|
||||||
pbuf->cmd = TX_ETHER_PKT;
|
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,
|
buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len,
|
||||||
PCI_DMA_TODEVICE);
|
PCI_DMA_TODEVICE);
|
||||||
buffrag->length = first_seg_len;
|
buffrag->length = first_seg_len;
|
||||||
CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len);
|
netxen_set_cmd_desc_totallength(hwdesc, skb->len);
|
||||||
hwdesc->num_of_buffers = frag_count;
|
netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
|
||||||
hwdesc->opcode = TX_ETHER_PKT;
|
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->buffer1_length = cpu_to_le16(first_seg_len);
|
||||||
hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
|
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
|
/* For LSO, we need to copy the MAC/IP/TCP headers into
|
||||||
* the descriptor ring
|
* 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;
|
int hdr_len, first_hdr_len, more_hdr;
|
||||||
hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
|
hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
|
||||||
if (hdr_len > (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
|
if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
|
||||||
first_hdr_len =
|
first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
|
||||||
sizeof(struct cmd_desc_type0) - NET_IP_ALIGN;
|
|
||||||
more_hdr = 1;
|
more_hdr = 1;
|
||||||
} else {
|
} else {
|
||||||
first_hdr_len = hdr_len;
|
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];
|
hwdesc = &hw->cmd_desc_head[producer];
|
||||||
|
|
||||||
/* copy the first 64 bytes */
|
/* copy the first 64 bytes */
|
||||||
memcpy(((void *)hwdesc) + NET_IP_ALIGN,
|
memcpy(((void *)hwdesc) + 2,
|
||||||
(void *)(skb->data), first_hdr_len);
|
(void *)(skb->data), first_hdr_len);
|
||||||
producer = get_next_index(producer, max_tx_desc_count);
|
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);
|
spin_lock_bh(&adapter->tx_lock);
|
||||||
port->stats.txbytes +=
|
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
|
/* Code to update the adapter considering how many producer threads
|
||||||
are currently working */
|
are currently working */
|
||||||
if ((--adapter->num_threads) == 0) {
|
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));
|
NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
|
||||||
wmb();
|
wmb();
|
||||||
adapter->total_threads = 0;
|
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++;
|
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)
|
static void netxen_watchdog(unsigned long v)
|
||||||
{
|
{
|
||||||
struct netxen_adapter *adapter = (struct netxen_adapter *)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)
|
static void netxen_tx_timeout(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
struct netxen_port *port = (struct netxen_port *)netdev_priv(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)
|
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)) {
|
if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
u32 mask;
|
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);
|
netxen_nic_disable_int(adapter);
|
||||||
/* Window = 0 or 1 */
|
/* Window = 0 or 1 */
|
||||||
do {
|
do {
|
||||||
@@ -1012,7 +1065,10 @@ irqreturn_t netxen_intr(int irq, void *data)
|
|||||||
netdev = port->netdev;
|
netdev = port->netdev;
|
||||||
|
|
||||||
/* process our status queue (for all 4 ports) */
|
/* 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;
|
return IRQ_HANDLED;
|
||||||
@@ -1054,11 +1110,11 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
|
|||||||
netdev->quota -= work_done;
|
netdev->quota -= work_done;
|
||||||
*budget -= work_done;
|
*budget -= work_done;
|
||||||
|
|
||||||
if (work_done >= work_to_do
|
if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0)
|
||||||
&& netxen_nic_rx_has_work(adapter) != 0)
|
|
||||||
done = 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",
|
DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
|
||||||
work_done, work_to_do);
|
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) {
|
if (ifr->ifr_data) {
|
||||||
sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP,
|
sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP,
|
||||||
port->portnum);
|
port->portnum);
|
||||||
nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name,
|
nr_bytes =
|
||||||
NETXEN_NIC_NAME_LEN);
|
copy_to_user((char __user *)ifr->ifr_data, dev_name,
|
||||||
|
NETXEN_NIC_NAME_LEN);
|
||||||
if (nr_bytes)
|
if (nr_bytes)
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
|
|
||||||
@@ -1132,6 +1189,9 @@ static struct pci_driver netxen_driver = {
|
|||||||
|
|
||||||
static int __init netxen_init_module(void)
|
static int __init netxen_init_module(void)
|
||||||
{
|
{
|
||||||
|
if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
return pci_module_init(&netxen_driver);
|
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.
|
* Wait for some time to allow the dma to drain, if any.
|
||||||
*/
|
*/
|
||||||
mdelay(5);
|
destroy_workqueue(netxen_workq);
|
||||||
pci_unregister_driver(&netxen_driver);
|
pci_unregister_driver(&netxen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,13 +40,15 @@
|
|||||||
|
|
||||||
static long phy_lock_timeout = 100000000;
|
static long phy_lock_timeout = 100000000;
|
||||||
|
|
||||||
static inline int phy_lock(void)
|
static inline int phy_lock(struct netxen_adapter *adapter)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int done = 0, timeout = 0;
|
int done = 0, timeout = 0;
|
||||||
|
|
||||||
while (!done) {
|
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)
|
if (done == 1)
|
||||||
break;
|
break;
|
||||||
if (timeout >= phy_lock_timeout) {
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +99,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
|
|||||||
__le32 status;
|
__le32 status;
|
||||||
__le32 mac_cfg0;
|
__le32 mac_cfg0;
|
||||||
|
|
||||||
if (phy_lock() != 0) {
|
if (phy_lock(adapter) != 0) {
|
||||||
return -1;
|
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),
|
NETXEN_NIU_GB_MAC_CONFIG_0(0),
|
||||||
&mac_cfg0, 4))
|
&mac_cfg0, 4))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
phy_unlock();
|
phy_unlock(adapter);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +616,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
|
|||||||
__le32 temp = 0;
|
__le32 temp = 0;
|
||||||
struct netxen_adapter *adapter = port->adapter;
|
struct netxen_adapter *adapter = port->adapter;
|
||||||
int phy = port->portnum;
|
int phy = port->portnum;
|
||||||
unsigned char mac_addr[MAX_ADDR_LEN];
|
unsigned char mac_addr[6];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 10; 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_niu_macaddr_get(adapter, phy,
|
||||||
(netxen_ethernet_macaddr_t *) mac_addr);
|
(netxen_ethernet_macaddr_t *) mac_addr);
|
||||||
if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0))
|
if (memcmp(mac_addr, addr, 6) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,15 +33,74 @@
|
|||||||
/*
|
/*
|
||||||
* CRB Registers or queue message done only at initialization time.
|
* CRB Registers or queue message done only at initialization time.
|
||||||
*/
|
*/
|
||||||
|
#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200)
|
||||||
|
#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
|
||||||
|
|
||||||
/*
|
#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
|
||||||
* The following 2 are the base adresses for the CRB registers and their
|
#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
|
||||||
* offsets will be added to get addresses for the index addresses.
|
#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
|
||||||
*/
|
#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
|
||||||
#define NIC_CRB_BASE_PORT1 NETXEN_CAM_RAM(0x200)
|
#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */
|
||||||
#define NIC_CRB_BASE_PORT2 NETXEN_CAM_RAM(0x250)
|
#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
|
* CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
|
||||||
@@ -51,74 +110,20 @@
|
|||||||
* on the Phantom.
|
* on the Phantom.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
|
#define nx_get_temp_val(x) ((x) >> 16)
|
||||||
#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
|
#define nx_get_temp_state(x) ((x) & 0xffff)
|
||||||
|
#define nx_encode_temp(val, state) (((val) << 16) | (state))
|
||||||
/* 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)
|
|
||||||
|
|
||||||
/* CRB registers per Rcv Descriptor ring */
|
/* CRB registers per Rcv Descriptor ring */
|
||||||
struct netxen_rcv_desc_crb {
|
struct netxen_rcv_desc_crb {
|
||||||
u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
|
u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
|
||||||
u32 crb_rcv_consumer_offset;
|
u32 crb_rcv_consumer_offset;
|
||||||
u32 crb_globalrcv_ring;
|
u32 crb_globalrcv_ring;
|
||||||
|
u32 crb_rcv_ring_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CRB registers used by the receive peg logic. One instance of these
|
* CRB registers used by the receive peg logic.
|
||||||
* needs to be instantiated per instance of the receive peg.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct netxen_recv_crb {
|
struct netxen_recv_crb {
|
||||||
@@ -127,6 +132,7 @@ struct netxen_recv_crb {
|
|||||||
u32 crb_rcv_status_producer;
|
u32 crb_rcv_status_producer;
|
||||||
u32 crb_rcv_status_consumer;
|
u32 crb_rcv_status_consumer;
|
||||||
u32 crb_rcvpeg_state;
|
u32 crb_rcvpeg_state;
|
||||||
|
u32 crb_status_ring_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEFINE_GLOBAL_RECV_CRB)
|
#if defined(DEFINE_GLOBAL_RECV_CRB)
|
||||||
@@ -137,15 +143,6 @@ struct netxen_recv_crb recv_crb_registers[] = {
|
|||||||
{
|
{
|
||||||
/* rcv_desc_crb: */
|
/* rcv_desc_crb: */
|
||||||
{
|
{
|
||||||
{
|
|
||||||
/* crb_rcv_producer_offset: */
|
|
||||||
NETXEN_NIC_REG(0x18),
|
|
||||||
/* crb_rcv_consumer_offset: */
|
|
||||||
NETXEN_NIC_REG(0x1c),
|
|
||||||
/* crb_gloablrcv_ring: */
|
|
||||||
NETXEN_NIC_REG(0x20),
|
|
||||||
},
|
|
||||||
/* Jumbo frames */
|
|
||||||
{
|
{
|
||||||
/* crb_rcv_producer_offset: */
|
/* crb_rcv_producer_offset: */
|
||||||
NETXEN_NIC_REG(0x100),
|
NETXEN_NIC_REG(0x100),
|
||||||
@@ -153,16 +150,43 @@ struct netxen_recv_crb recv_crb_registers[] = {
|
|||||||
NETXEN_NIC_REG(0x104),
|
NETXEN_NIC_REG(0x104),
|
||||||
/* crb_gloablrcv_ring: */
|
/* crb_gloablrcv_ring: */
|
||||||
NETXEN_NIC_REG(0x108),
|
NETXEN_NIC_REG(0x108),
|
||||||
|
/* crb_rcv_ring_size */
|
||||||
|
NETXEN_NIC_REG(0x10c),
|
||||||
|
|
||||||
|
},
|
||||||
|
/* Jumbo frames */
|
||||||
|
{
|
||||||
|
/* crb_rcv_producer_offset: */
|
||||||
|
NETXEN_NIC_REG(0x110),
|
||||||
|
/* crb_rcv_consumer_offset: */
|
||||||
|
NETXEN_NIC_REG(0x114),
|
||||||
|
/* crb_gloablrcv_ring: */
|
||||||
|
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: */
|
/* crb_rcvstatus_ring: */
|
||||||
NETXEN_NIC_REG(0x24),
|
NETXEN_NIC_REG(0x130),
|
||||||
/* crb_rcv_status_producer: */
|
/* crb_rcv_status_producer: */
|
||||||
NETXEN_NIC_REG(0x28),
|
NETXEN_NIC_REG(0x134),
|
||||||
/* crb_rcv_status_consumer: */
|
/* crb_rcv_status_consumer: */
|
||||||
NETXEN_NIC_REG(0x2c),
|
NETXEN_NIC_REG(0x138),
|
||||||
/* crb_rcvpeg_state: */
|
/* 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: */
|
/* crb_rcv_producer_offset: */
|
||||||
NETXEN_NIC_REG(0x80),
|
NETXEN_NIC_REG(0x144),
|
||||||
/* crb_rcv_consumer_offset: */
|
/* crb_rcv_consumer_offset: */
|
||||||
NETXEN_NIC_REG(0x84),
|
NETXEN_NIC_REG(0x148),
|
||||||
/* crb_globalrcv_ring: */
|
/* crb_globalrcv_ring: */
|
||||||
NETXEN_NIC_REG(0x88),
|
NETXEN_NIC_REG(0x14c),
|
||||||
|
/* crb_rcv_ring_size */
|
||||||
|
NETXEN_NIC_REG(0x150),
|
||||||
|
|
||||||
},
|
},
|
||||||
/* Jumbo frames */
|
/* Jumbo frames */
|
||||||
{
|
{
|
||||||
/* crb_rcv_producer_offset: */
|
/* crb_rcv_producer_offset: */
|
||||||
NETXEN_NIC_REG(0x10C),
|
NETXEN_NIC_REG(0x154),
|
||||||
/* crb_rcv_consumer_offset: */
|
/* crb_rcv_consumer_offset: */
|
||||||
NETXEN_NIC_REG(0x110),
|
NETXEN_NIC_REG(0x158),
|
||||||
/* crb_globalrcv_ring: */
|
/* 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: */
|
/* crb_rcvstatus_ring: */
|
||||||
NETXEN_NIC_REG(0x8c),
|
NETXEN_NIC_REG(0x174),
|
||||||
/* crb_rcv_status_producer: */
|
/* crb_rcv_status_producer: */
|
||||||
NETXEN_NIC_REG(0x90),
|
NETXEN_NIC_REG(0x178),
|
||||||
/* crb_rcv_status_consumer: */
|
/* crb_rcv_status_consumer: */
|
||||||
NETXEN_NIC_REG(0x94),
|
NETXEN_NIC_REG(0x17c),
|
||||||
/* crb_rcvpeg_state: */
|
/* 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
|
#else
|
||||||
extern struct netxen_recv_crb recv_crb_registers[];
|
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 */
|
#endif /* DEFINE_GLOBAL_RECEIVE_CRB */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user