diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 575 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 710 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 168 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 251 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 2196 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 60 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 806 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_isr.c | 220 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 1169 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 114 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_phan_reg.h | 31 |
12 files changed, 4551 insertions, 1751 deletions
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile index a07cdc6f7384..8e7c4c910d2a 100644 --- a/drivers/net/netxen/Makefile +++ b/drivers/net/netxen/Makefile | |||
@@ -32,4 +32,4 @@ | |||
32 | obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o | 32 | obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o |
33 | 33 | ||
34 | netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \ | 34 | netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \ |
35 | netxen_nic_isr.o netxen_nic_ethtool.o netxen_nic_niu.o | 35 | netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ctx.o |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index da4c4fb97064..8e736614407d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | #include <linux/mm.h> | 55 | #include <linux/mm.h> |
56 | #include <linux/mman.h> | 56 | #include <linux/mman.h> |
57 | #include <linux/vmalloc.h> | ||
57 | 58 | ||
58 | #include <asm/system.h> | 59 | #include <asm/system.h> |
59 | #include <asm/io.h> | 60 | #include <asm/io.h> |
@@ -63,10 +64,12 @@ | |||
63 | 64 | ||
64 | #include "netxen_nic_hw.h" | 65 | #include "netxen_nic_hw.h" |
65 | 66 | ||
66 | #define _NETXEN_NIC_LINUX_MAJOR 3 | 67 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
67 | #define _NETXEN_NIC_LINUX_MINOR 4 | 68 | #define _NETXEN_NIC_LINUX_MINOR 0 |
68 | #define _NETXEN_NIC_LINUX_SUBVERSION 18 | 69 | #define _NETXEN_NIC_LINUX_SUBVERSION 0 |
69 | #define NETXEN_NIC_LINUX_VERSIONID "3.4.18" | 70 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.0" |
71 | |||
72 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c)) | ||
70 | 73 | ||
71 | #define NETXEN_NUM_FLASH_SECTORS (64) | 74 | #define NETXEN_NUM_FLASH_SECTORS (64) |
72 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) | 75 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) |
@@ -84,7 +87,7 @@ | |||
84 | #define TX_RINGSIZE \ | 87 | #define TX_RINGSIZE \ |
85 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) | 88 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) |
86 | #define RCV_BUFFSIZE \ | 89 | #define RCV_BUFFSIZE \ |
87 | (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) | 90 | (sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count) |
88 | #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) | 91 | #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) |
89 | 92 | ||
90 | #define NETXEN_NETDEV_STATUS 0x1 | 93 | #define NETXEN_NETDEV_STATUS 0x1 |
@@ -111,6 +114,13 @@ | |||
111 | 114 | ||
112 | #define NX_P2_C0 0x24 | 115 | #define NX_P2_C0 0x24 |
113 | #define NX_P2_C1 0x25 | 116 | #define NX_P2_C1 0x25 |
117 | #define NX_P3_A0 0x30 | ||
118 | #define NX_P3_A2 0x30 | ||
119 | #define NX_P3_B0 0x40 | ||
120 | #define NX_P3_B1 0x41 | ||
121 | |||
122 | #define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1) | ||
123 | #define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0) | ||
114 | 124 | ||
115 | #define FIRST_PAGE_GROUP_START 0 | 125 | #define FIRST_PAGE_GROUP_START 0 |
116 | #define FIRST_PAGE_GROUP_END 0x100000 | 126 | #define FIRST_PAGE_GROUP_END 0x100000 |
@@ -125,6 +135,16 @@ | |||
125 | #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START | 135 | #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START |
126 | #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START | 136 | #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START |
127 | 137 | ||
138 | #define P2_MAX_MTU (8000) | ||
139 | #define P3_MAX_MTU (9600) | ||
140 | #define NX_ETHERMTU 1500 | ||
141 | #define NX_MAX_ETHERHDR 32 /* This contains some padding */ | ||
142 | |||
143 | #define NX_RX_NORMAL_BUF_MAX_LEN (NX_MAX_ETHERHDR + NX_ETHERMTU) | ||
144 | #define NX_P2_RX_JUMBO_BUF_MAX_LEN (NX_MAX_ETHERHDR + P2_MAX_MTU) | ||
145 | #define NX_P3_RX_JUMBO_BUF_MAX_LEN (NX_MAX_ETHERHDR + P3_MAX_MTU) | ||
146 | #define NX_CT_DEFAULT_RX_BUF_LEN 2048 | ||
147 | |||
128 | #define MAX_RX_BUFFER_LENGTH 1760 | 148 | #define MAX_RX_BUFFER_LENGTH 1760 |
129 | #define MAX_RX_JUMBO_BUFFER_LENGTH 8062 | 149 | #define MAX_RX_JUMBO_BUFFER_LENGTH 8062 |
130 | #define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) | 150 | #define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) |
@@ -132,7 +152,6 @@ | |||
132 | #define RX_JUMBO_DMA_MAP_LEN \ | 152 | #define RX_JUMBO_DMA_MAP_LEN \ |
133 | (MAX_RX_JUMBO_BUFFER_LENGTH - 2) | 153 | (MAX_RX_JUMBO_BUFFER_LENGTH - 2) |
134 | #define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2) | 154 | #define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2) |
135 | #define NETXEN_ROM_ROUNDUP 0x80000000ULL | ||
136 | 155 | ||
137 | /* | 156 | /* |
138 | * Maximum number of ring contexts | 157 | * Maximum number of ring contexts |
@@ -140,16 +159,16 @@ | |||
140 | #define MAX_RING_CTX 1 | 159 | #define MAX_RING_CTX 1 |
141 | 160 | ||
142 | /* Opcodes to be used with the commands */ | 161 | /* Opcodes to be used with the commands */ |
143 | enum { | 162 | #define TX_ETHER_PKT 0x01 |
144 | TX_ETHER_PKT = 0x01, | 163 | #define TX_TCP_PKT 0x02 |
145 | /* The following opcodes are for IP checksum */ | 164 | #define TX_UDP_PKT 0x03 |
146 | TX_TCP_PKT, | 165 | #define TX_IP_PKT 0x04 |
147 | TX_UDP_PKT, | 166 | #define TX_TCP_LSO 0x05 |
148 | TX_IP_PKT, | 167 | #define TX_TCP_LSO6 0x06 |
149 | TX_TCP_LSO, | 168 | #define TX_IPSEC 0x07 |
150 | TX_IPSEC, | 169 | #define TX_IPSEC_CMD 0x0a |
151 | TX_IPSEC_CMD | 170 | #define TX_TCPV6_PKT 0x0b |
152 | }; | 171 | #define TX_UDPV6_PKT 0x0c |
153 | 172 | ||
154 | /* The following opcodes are for internal consumption. */ | 173 | /* The following opcodes are for internal consumption. */ |
155 | #define NETXEN_CONTROL_OP 0x10 | 174 | #define NETXEN_CONTROL_OP 0x10 |
@@ -191,6 +210,7 @@ enum { | |||
191 | #define MAX_RCV_DESCRIPTORS 16384 | 210 | #define MAX_RCV_DESCRIPTORS 16384 |
192 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) | 211 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) |
193 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) | 212 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) |
213 | #define MAX_RCV_DESCRIPTORS_10G 8192 | ||
194 | #define MAX_JUMBO_RCV_DESCRIPTORS 1024 | 214 | #define MAX_JUMBO_RCV_DESCRIPTORS 1024 |
195 | #define MAX_LRO_RCV_DESCRIPTORS 64 | 215 | #define MAX_LRO_RCV_DESCRIPTORS 64 |
196 | #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS | 216 | #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS |
@@ -219,8 +239,6 @@ enum { | |||
219 | #define MPORT_MULTI_FUNCTION_MODE 0x2222 | 239 | #define MPORT_MULTI_FUNCTION_MODE 0x2222 |
220 | 240 | ||
221 | #include "netxen_nic_phan_reg.h" | 241 | #include "netxen_nic_phan_reg.h" |
222 | extern unsigned long long netxen_dma_mask; | ||
223 | extern unsigned long last_schedule_time; | ||
224 | 242 | ||
225 | /* | 243 | /* |
226 | * NetXen host-peg signal message structure | 244 | * NetXen host-peg signal message structure |
@@ -289,7 +307,7 @@ struct netxen_ring_ctx { | |||
289 | #define netxen_set_cmd_desc_port(cmd_desc, var) \ | 307 | #define netxen_set_cmd_desc_port(cmd_desc, var) \ |
290 | ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) | 308 | ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) |
291 | #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ | 309 | #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ |
292 | ((cmd_desc)->port_ctxid |= ((var) & 0xF0)) | 310 | ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0)) |
293 | 311 | ||
294 | #define netxen_set_cmd_desc_flags(cmd_desc, val) \ | 312 | #define netxen_set_cmd_desc_flags(cmd_desc, val) \ |
295 | (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ | 313 | (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ |
@@ -377,8 +395,8 @@ struct rcv_desc { | |||
377 | }; | 395 | }; |
378 | 396 | ||
379 | /* opcode field in status_desc */ | 397 | /* opcode field in status_desc */ |
380 | #define RCV_NIC_PKT (0xA) | 398 | #define NETXEN_NIC_RXPKT_DESC 0x04 |
381 | #define STATUS_NIC_PKT ((RCV_NIC_PKT) << 12) | 399 | #define NETXEN_OLD_RXPKT_DESC 0x3f |
382 | 400 | ||
383 | /* for status field in status_desc */ | 401 | /* for status field in status_desc */ |
384 | #define STATUS_NEED_CKSUM (1) | 402 | #define STATUS_NEED_CKSUM (1) |
@@ -410,6 +428,8 @@ struct rcv_desc { | |||
410 | (((sts_data) >> 28) & 0xFFFF) | 428 | (((sts_data) >> 28) & 0xFFFF) |
411 | #define netxen_get_sts_prot(sts_data) \ | 429 | #define netxen_get_sts_prot(sts_data) \ |
412 | (((sts_data) >> 44) & 0x0F) | 430 | (((sts_data) >> 44) & 0x0F) |
431 | #define netxen_get_sts_pkt_offset(sts_data) \ | ||
432 | (((sts_data) >> 48) & 0x1F) | ||
413 | #define netxen_get_sts_opcode(sts_data) \ | 433 | #define netxen_get_sts_opcode(sts_data) \ |
414 | (((sts_data) >> 58) & 0x03F) | 434 | (((sts_data) >> 58) & 0x03F) |
415 | 435 | ||
@@ -424,17 +444,30 @@ struct rcv_desc { | |||
424 | 444 | ||
425 | struct status_desc { | 445 | struct status_desc { |
426 | /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length | 446 | /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length |
427 | 28-43 reference_handle, 44-47 protocol, 48-52 unused | 447 | 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset |
428 | 53-55 desc_cnt, 56-57 owner, 58-63 opcode | 448 | 53-55 desc_cnt, 56-57 owner, 58-63 opcode |
429 | */ | 449 | */ |
430 | __le64 status_desc_data; | 450 | __le64 status_desc_data; |
431 | __le32 hash_value; | 451 | union { |
432 | u8 hash_type; | 452 | struct { |
433 | u8 msg_type; | 453 | __le32 hash_value; |
434 | u8 unused; | 454 | u8 hash_type; |
435 | /* Bit pattern: 0-6 lro_count indicates frag sequence, | 455 | u8 msg_type; |
436 | 7 last_frag indicates last frag */ | 456 | u8 unused; |
437 | u8 lro; | 457 | union { |
458 | /* Bit pattern: 0-6 lro_count indicates frag | ||
459 | * sequence, 7 last_frag indicates last frag | ||
460 | */ | ||
461 | u8 lro; | ||
462 | |||
463 | /* chained buffers */ | ||
464 | u8 nr_frags; | ||
465 | }; | ||
466 | }; | ||
467 | struct { | ||
468 | __le16 frag_handles[4]; | ||
469 | }; | ||
470 | }; | ||
438 | } __attribute__ ((aligned(16))); | 471 | } __attribute__ ((aligned(16))); |
439 | 472 | ||
440 | enum { | 473 | enum { |
@@ -464,7 +497,20 @@ typedef enum { | |||
464 | 497 | ||
465 | NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d, | 498 | NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d, |
466 | NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, | 499 | NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, |
467 | NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f | 500 | NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f, |
501 | |||
502 | NETXEN_BRDTYPE_P3_REF_QG = 0x0021, | ||
503 | NETXEN_BRDTYPE_P3_HMEZ = 0x0022, | ||
504 | NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023, | ||
505 | NETXEN_BRDTYPE_P3_4_GB = 0x0024, | ||
506 | NETXEN_BRDTYPE_P3_IMEZ = 0x0025, | ||
507 | NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026, | ||
508 | NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027, | ||
509 | NETXEN_BRDTYPE_P3_XG_LOM = 0x0028, | ||
510 | NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029, | ||
511 | NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031, | ||
512 | NETXEN_BRDTYPE_P3_10G_XFP = 0x0032 | ||
513 | |||
468 | } netxen_brdtype_t; | 514 | } netxen_brdtype_t; |
469 | 515 | ||
470 | typedef enum { | 516 | typedef enum { |
@@ -747,6 +793,7 @@ struct netxen_cmd_buffer { | |||
747 | 793 | ||
748 | /* In rx_buffer, we do not need multiple fragments as is a single buffer */ | 794 | /* In rx_buffer, we do not need multiple fragments as is a single buffer */ |
749 | struct netxen_rx_buffer { | 795 | struct netxen_rx_buffer { |
796 | struct list_head list; | ||
750 | struct sk_buff *skb; | 797 | struct sk_buff *skb; |
751 | u64 dma; | 798 | u64 dma; |
752 | u16 ref_handle; | 799 | u16 ref_handle; |
@@ -765,7 +812,6 @@ struct netxen_rx_buffer { | |||
765 | * contains interrupt info as well shared hardware info. | 812 | * contains interrupt info as well shared hardware info. |
766 | */ | 813 | */ |
767 | struct netxen_hardware_context { | 814 | struct netxen_hardware_context { |
768 | struct pci_dev *pdev; | ||
769 | void __iomem *pci_base0; | 815 | void __iomem *pci_base0; |
770 | void __iomem *pci_base1; | 816 | void __iomem *pci_base1; |
771 | void __iomem *pci_base2; | 817 | void __iomem *pci_base2; |
@@ -773,15 +819,20 @@ struct netxen_hardware_context { | |||
773 | unsigned long first_page_group_start; | 819 | unsigned long first_page_group_start; |
774 | void __iomem *db_base; | 820 | void __iomem *db_base; |
775 | unsigned long db_len; | 821 | unsigned long db_len; |
822 | unsigned long pci_len0; | ||
823 | |||
824 | u8 cut_through; | ||
825 | int qdr_sn_window; | ||
826 | int ddr_mn_window; | ||
827 | unsigned long mn_win_crb; | ||
828 | unsigned long ms_win_crb; | ||
776 | 829 | ||
777 | u8 revision_id; | 830 | u8 revision_id; |
778 | u16 board_type; | 831 | u16 board_type; |
779 | struct netxen_board_info boardcfg; | 832 | struct netxen_board_info boardcfg; |
780 | u32 xg_linkup; | 833 | u32 linkup; |
781 | u32 qg_linksup; | ||
782 | /* Address of cmd ring in Phantom */ | 834 | /* Address of cmd ring in Phantom */ |
783 | struct cmd_desc_type0 *cmd_desc_head; | 835 | struct cmd_desc_type0 *cmd_desc_head; |
784 | struct pci_dev *cmd_desc_pdev; | ||
785 | dma_addr_t cmd_desc_phys_addr; | 836 | dma_addr_t cmd_desc_phys_addr; |
786 | struct netxen_adapter *adapter; | 837 | struct netxen_adapter *adapter; |
787 | int pci_func; | 838 | int pci_func; |
@@ -813,17 +864,17 @@ struct netxen_adapter_stats { | |||
813 | * Rcv Descriptor Context. One such per Rcv Descriptor. There may | 864 | * Rcv Descriptor Context. One such per Rcv Descriptor. There may |
814 | * be one Rcv Descriptor for normal packets, one for jumbo and may be others. | 865 | * be one Rcv Descriptor for normal packets, one for jumbo and may be others. |
815 | */ | 866 | */ |
816 | struct netxen_rcv_desc_ctx { | 867 | struct nx_host_rds_ring { |
817 | u32 flags; | 868 | u32 flags; |
818 | u32 producer; | 869 | u32 producer; |
819 | u32 rcv_pending; /* Num of bufs posted in phantom */ | ||
820 | dma_addr_t phys_addr; | 870 | dma_addr_t phys_addr; |
821 | struct pci_dev *phys_pdev; | 871 | u32 crb_rcv_producer; /* reg offset */ |
822 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ | 872 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ |
823 | u32 max_rx_desc_count; | 873 | u32 max_rx_desc_count; |
824 | u32 dma_size; | 874 | u32 dma_size; |
825 | u32 skb_size; | 875 | u32 skb_size; |
826 | struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ | 876 | struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ |
877 | struct list_head free_list; | ||
827 | int begin_alloc; | 878 | int begin_alloc; |
828 | }; | 879 | }; |
829 | 880 | ||
@@ -834,17 +885,319 @@ struct netxen_rcv_desc_ctx { | |||
834 | * present elsewhere. | 885 | * present elsewhere. |
835 | */ | 886 | */ |
836 | struct netxen_recv_context { | 887 | struct netxen_recv_context { |
837 | struct netxen_rcv_desc_ctx rcv_desc[NUM_RCV_DESC_RINGS]; | 888 | u32 state; |
838 | u32 status_rx_producer; | 889 | u16 context_id; |
890 | u16 virt_port; | ||
891 | |||
892 | struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS]; | ||
839 | u32 status_rx_consumer; | 893 | u32 status_rx_consumer; |
894 | u32 crb_sts_consumer; /* reg offset */ | ||
840 | dma_addr_t rcv_status_desc_phys_addr; | 895 | dma_addr_t rcv_status_desc_phys_addr; |
841 | struct pci_dev *rcv_status_desc_pdev; | ||
842 | struct status_desc *rcv_status_desc_head; | 896 | struct status_desc *rcv_status_desc_head; |
843 | }; | 897 | }; |
844 | 898 | ||
845 | #define NETXEN_NIC_MSI_ENABLED 0x02 | 899 | /* New HW context creation */ |
846 | #define NETXEN_DMA_MASK 0xfffffffe | 900 | |
847 | #define NETXEN_DB_MAPSIZE_BYTES 0x1000 | 901 | #define NX_OS_CRB_RETRY_COUNT 4000 |
902 | #define NX_CDRP_SIGNATURE_MAKE(pcifn, version) \ | ||
903 | (((pcifn) & 0xff) | (((version) & 0xff) << 8) | (0xcafe << 16)) | ||
904 | |||
905 | #define NX_CDRP_CLEAR 0x00000000 | ||
906 | #define NX_CDRP_CMD_BIT 0x80000000 | ||
907 | |||
908 | /* | ||
909 | * All responses must have the NX_CDRP_CMD_BIT cleared | ||
910 | * in the crb NX_CDRP_CRB_OFFSET. | ||
911 | */ | ||
912 | #define NX_CDRP_FORM_RSP(rsp) (rsp) | ||
913 | #define NX_CDRP_IS_RSP(rsp) (((rsp) & NX_CDRP_CMD_BIT) == 0) | ||
914 | |||
915 | #define NX_CDRP_RSP_OK 0x00000001 | ||
916 | #define NX_CDRP_RSP_FAIL 0x00000002 | ||
917 | #define NX_CDRP_RSP_TIMEOUT 0x00000003 | ||
918 | |||
919 | /* | ||
920 | * All commands must have the NX_CDRP_CMD_BIT set in | ||
921 | * the crb NX_CDRP_CRB_OFFSET. | ||
922 | */ | ||
923 | #define NX_CDRP_FORM_CMD(cmd) (NX_CDRP_CMD_BIT | (cmd)) | ||
924 | #define NX_CDRP_IS_CMD(cmd) (((cmd) & NX_CDRP_CMD_BIT) != 0) | ||
925 | |||
926 | #define NX_CDRP_CMD_SUBMIT_CAPABILITIES 0x00000001 | ||
927 | #define NX_CDRP_CMD_READ_MAX_RDS_PER_CTX 0x00000002 | ||
928 | #define NX_CDRP_CMD_READ_MAX_SDS_PER_CTX 0x00000003 | ||
929 | #define NX_CDRP_CMD_READ_MAX_RULES_PER_CTX 0x00000004 | ||
930 | #define NX_CDRP_CMD_READ_MAX_RX_CTX 0x00000005 | ||
931 | #define NX_CDRP_CMD_READ_MAX_TX_CTX 0x00000006 | ||
932 | #define NX_CDRP_CMD_CREATE_RX_CTX 0x00000007 | ||
933 | #define NX_CDRP_CMD_DESTROY_RX_CTX 0x00000008 | ||
934 | #define NX_CDRP_CMD_CREATE_TX_CTX 0x00000009 | ||
935 | #define NX_CDRP_CMD_DESTROY_TX_CTX 0x0000000a | ||
936 | #define NX_CDRP_CMD_SETUP_STATISTICS 0x0000000e | ||
937 | #define NX_CDRP_CMD_GET_STATISTICS 0x0000000f | ||
938 | #define NX_CDRP_CMD_DELETE_STATISTICS 0x00000010 | ||
939 | #define NX_CDRP_CMD_SET_MTU 0x00000012 | ||
940 | #define NX_CDRP_CMD_MAX 0x00000013 | ||
941 | |||
942 | #define NX_RCODE_SUCCESS 0 | ||
943 | #define NX_RCODE_NO_HOST_MEM 1 | ||
944 | #define NX_RCODE_NO_HOST_RESOURCE 2 | ||
945 | #define NX_RCODE_NO_CARD_CRB 3 | ||
946 | #define NX_RCODE_NO_CARD_MEM 4 | ||
947 | #define NX_RCODE_NO_CARD_RESOURCE 5 | ||
948 | #define NX_RCODE_INVALID_ARGS 6 | ||
949 | #define NX_RCODE_INVALID_ACTION 7 | ||
950 | #define NX_RCODE_INVALID_STATE 8 | ||
951 | #define NX_RCODE_NOT_SUPPORTED 9 | ||
952 | #define NX_RCODE_NOT_PERMITTED 10 | ||
953 | #define NX_RCODE_NOT_READY 11 | ||
954 | #define NX_RCODE_DOES_NOT_EXIST 12 | ||
955 | #define NX_RCODE_ALREADY_EXISTS 13 | ||
956 | #define NX_RCODE_BAD_SIGNATURE 14 | ||
957 | #define NX_RCODE_CMD_NOT_IMPL 15 | ||
958 | #define NX_RCODE_CMD_INVALID 16 | ||
959 | #define NX_RCODE_TIMEOUT 17 | ||
960 | #define NX_RCODE_CMD_FAILED 18 | ||
961 | #define NX_RCODE_MAX_EXCEEDED 19 | ||
962 | #define NX_RCODE_MAX 20 | ||
963 | |||
964 | #define NX_DESTROY_CTX_RESET 0 | ||
965 | #define NX_DESTROY_CTX_D3_RESET 1 | ||
966 | #define NX_DESTROY_CTX_MAX 2 | ||
967 | |||
968 | /* | ||
969 | * Capabilities | ||
970 | */ | ||
971 | #define NX_CAP_BIT(class, bit) (1 << bit) | ||
972 | #define NX_CAP0_LEGACY_CONTEXT NX_CAP_BIT(0, 0) | ||
973 | #define NX_CAP0_MULTI_CONTEXT NX_CAP_BIT(0, 1) | ||
974 | #define NX_CAP0_LEGACY_MN NX_CAP_BIT(0, 2) | ||
975 | #define NX_CAP0_LEGACY_MS NX_CAP_BIT(0, 3) | ||
976 | #define NX_CAP0_CUT_THROUGH NX_CAP_BIT(0, 4) | ||
977 | #define NX_CAP0_LRO NX_CAP_BIT(0, 5) | ||
978 | #define NX_CAP0_LSO NX_CAP_BIT(0, 6) | ||
979 | #define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7) | ||
980 | #define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8) | ||
981 | |||
982 | /* | ||
983 | * Context state | ||
984 | */ | ||
985 | #define NX_HOST_CTX_STATE_FREED 0 | ||
986 | #define NX_HOST_CTX_STATE_ALLOCATED 1 | ||
987 | #define NX_HOST_CTX_STATE_ACTIVE 2 | ||
988 | #define NX_HOST_CTX_STATE_DISABLED 3 | ||
989 | #define NX_HOST_CTX_STATE_QUIESCED 4 | ||
990 | #define NX_HOST_CTX_STATE_MAX 5 | ||
991 | |||
992 | /* | ||
993 | * Rx context | ||
994 | */ | ||
995 | |||
996 | typedef struct { | ||
997 | u64 host_phys_addr; /* Ring base addr */ | ||
998 | u32 ring_size; /* Ring entries */ | ||
999 | u16 msi_index; | ||
1000 | u16 rsvd; /* Padding */ | ||
1001 | } nx_hostrq_sds_ring_t; | ||
1002 | |||
1003 | typedef struct { | ||
1004 | u64 host_phys_addr; /* Ring base addr */ | ||
1005 | u64 buff_size; /* Packet buffer size */ | ||
1006 | u32 ring_size; /* Ring entries */ | ||
1007 | u32 ring_kind; /* Class of ring */ | ||
1008 | } nx_hostrq_rds_ring_t; | ||
1009 | |||
1010 | typedef struct { | ||
1011 | u64 host_rsp_dma_addr; /* Response dma'd here */ | ||
1012 | u32 capabilities[4]; /* Flag bit vector */ | ||
1013 | u32 host_int_crb_mode; /* Interrupt crb usage */ | ||
1014 | u32 host_rds_crb_mode; /* RDS crb usage */ | ||
1015 | /* These ring offsets are relative to data[0] below */ | ||
1016 | u32 rds_ring_offset; /* Offset to RDS config */ | ||
1017 | u32 sds_ring_offset; /* Offset to SDS config */ | ||
1018 | u16 num_rds_rings; /* Count of RDS rings */ | ||
1019 | u16 num_sds_rings; /* Count of SDS rings */ | ||
1020 | u16 rsvd1; /* Padding */ | ||
1021 | u16 rsvd2; /* Padding */ | ||
1022 | u8 reserved[128]; /* reserve space for future expansion*/ | ||
1023 | /* MUST BE 64-bit aligned. | ||
1024 | The following is packed: | ||
1025 | - N hostrq_rds_rings | ||
1026 | - N hostrq_sds_rings */ | ||
1027 | char data[0]; | ||
1028 | } nx_hostrq_rx_ctx_t; | ||
1029 | |||
1030 | typedef struct { | ||
1031 | u32 host_producer_crb; /* Crb to use */ | ||
1032 | u32 rsvd1; /* Padding */ | ||
1033 | } nx_cardrsp_rds_ring_t; | ||
1034 | |||
1035 | typedef struct { | ||
1036 | u32 host_consumer_crb; /* Crb to use */ | ||
1037 | u32 interrupt_crb; /* Crb to use */ | ||
1038 | } nx_cardrsp_sds_ring_t; | ||
1039 | |||
1040 | typedef struct { | ||
1041 | /* These ring offsets are relative to data[0] below */ | ||
1042 | u32 rds_ring_offset; /* Offset to RDS config */ | ||
1043 | u32 sds_ring_offset; /* Offset to SDS config */ | ||
1044 | u32 host_ctx_state; /* Starting State */ | ||
1045 | u32 num_fn_per_port; /* How many PCI fn share the port */ | ||
1046 | u16 num_rds_rings; /* Count of RDS rings */ | ||
1047 | u16 num_sds_rings; /* Count of SDS rings */ | ||
1048 | u16 context_id; /* Handle for context */ | ||
1049 | u8 phys_port; /* Physical id of port */ | ||
1050 | u8 virt_port; /* Virtual/Logical id of port */ | ||
1051 | u8 reserved[128]; /* save space for future expansion */ | ||
1052 | /* MUST BE 64-bit aligned. | ||
1053 | The following is packed: | ||
1054 | - N cardrsp_rds_rings | ||
1055 | - N cardrs_sds_rings */ | ||
1056 | char data[0]; | ||
1057 | } nx_cardrsp_rx_ctx_t; | ||
1058 | |||
1059 | #define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings) \ | ||
1060 | (sizeof(HOSTRQ_RX) + \ | ||
1061 | (rds_rings)*(sizeof(nx_hostrq_rds_ring_t)) + \ | ||
1062 | (sds_rings)*(sizeof(nx_hostrq_sds_ring_t))) | ||
1063 | |||
1064 | #define SIZEOF_CARDRSP_RX(CARDRSP_RX, rds_rings, sds_rings) \ | ||
1065 | (sizeof(CARDRSP_RX) + \ | ||
1066 | (rds_rings)*(sizeof(nx_cardrsp_rds_ring_t)) + \ | ||
1067 | (sds_rings)*(sizeof(nx_cardrsp_sds_ring_t))) | ||
1068 | |||
1069 | /* | ||
1070 | * Tx context | ||
1071 | */ | ||
1072 | |||
1073 | typedef struct { | ||
1074 | u64 host_phys_addr; /* Ring base addr */ | ||
1075 | u32 ring_size; /* Ring entries */ | ||
1076 | u32 rsvd; /* Padding */ | ||
1077 | } nx_hostrq_cds_ring_t; | ||
1078 | |||
1079 | typedef struct { | ||
1080 | u64 host_rsp_dma_addr; /* Response dma'd here */ | ||
1081 | u64 cmd_cons_dma_addr; /* */ | ||
1082 | u64 dummy_dma_addr; /* */ | ||
1083 | u32 capabilities[4]; /* Flag bit vector */ | ||
1084 | u32 host_int_crb_mode; /* Interrupt crb usage */ | ||
1085 | u32 rsvd1; /* Padding */ | ||
1086 | u16 rsvd2; /* Padding */ | ||
1087 | u16 interrupt_ctl; | ||
1088 | u16 msi_index; | ||
1089 | u16 rsvd3; /* Padding */ | ||
1090 | nx_hostrq_cds_ring_t cds_ring; /* Desc of cds ring */ | ||
1091 | u8 reserved[128]; /* future expansion */ | ||
1092 | } nx_hostrq_tx_ctx_t; | ||
1093 | |||
1094 | typedef struct { | ||
1095 | u32 host_producer_crb; /* Crb to use */ | ||
1096 | u32 interrupt_crb; /* Crb to use */ | ||
1097 | } nx_cardrsp_cds_ring_t; | ||
1098 | |||
1099 | typedef struct { | ||
1100 | u32 host_ctx_state; /* Starting state */ | ||
1101 | u16 context_id; /* Handle for context */ | ||
1102 | u8 phys_port; /* Physical id of port */ | ||
1103 | u8 virt_port; /* Virtual/Logical id of port */ | ||
1104 | nx_cardrsp_cds_ring_t cds_ring; /* Card cds settings */ | ||
1105 | u8 reserved[128]; /* future expansion */ | ||
1106 | } nx_cardrsp_tx_ctx_t; | ||
1107 | |||
1108 | #define SIZEOF_HOSTRQ_TX(HOSTRQ_TX) (sizeof(HOSTRQ_TX)) | ||
1109 | #define SIZEOF_CARDRSP_TX(CARDRSP_TX) (sizeof(CARDRSP_TX)) | ||
1110 | |||
1111 | /* CRB */ | ||
1112 | |||
1113 | #define NX_HOST_RDS_CRB_MODE_UNIQUE 0 | ||
1114 | #define NX_HOST_RDS_CRB_MODE_SHARED 1 | ||
1115 | #define NX_HOST_RDS_CRB_MODE_CUSTOM 2 | ||
1116 | #define NX_HOST_RDS_CRB_MODE_MAX 3 | ||
1117 | |||
1118 | #define NX_HOST_INT_CRB_MODE_UNIQUE 0 | ||
1119 | #define NX_HOST_INT_CRB_MODE_SHARED 1 | ||
1120 | #define NX_HOST_INT_CRB_MODE_NORX 2 | ||
1121 | #define NX_HOST_INT_CRB_MODE_NOTX 3 | ||
1122 | #define NX_HOST_INT_CRB_MODE_NORXTX 4 | ||
1123 | |||
1124 | |||
1125 | /* MAC */ | ||
1126 | |||
1127 | #define MC_COUNT_P2 16 | ||
1128 | #define MC_COUNT_P3 38 | ||
1129 | |||
1130 | #define NETXEN_MAC_NOOP 0 | ||
1131 | #define NETXEN_MAC_ADD 1 | ||
1132 | #define NETXEN_MAC_DEL 2 | ||
1133 | |||
1134 | typedef struct nx_mac_list_s { | ||
1135 | struct nx_mac_list_s *next; | ||
1136 | uint8_t mac_addr[MAX_ADDR_LEN]; | ||
1137 | } nx_mac_list_t; | ||
1138 | |||
1139 | /* | ||
1140 | * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is | ||
1141 | * adjusted based on configured MTU. | ||
1142 | */ | ||
1143 | #define NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US 3 | ||
1144 | #define NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS 256 | ||
1145 | #define NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS 64 | ||
1146 | #define NETXEN_DEFAULT_INTR_COALESCE_TX_TIME_US 4 | ||
1147 | |||
1148 | #define NETXEN_NIC_INTR_DEFAULT 0x04 | ||
1149 | |||
1150 | typedef union { | ||
1151 | struct { | ||
1152 | uint16_t rx_packets; | ||
1153 | uint16_t rx_time_us; | ||
1154 | uint16_t tx_packets; | ||
1155 | uint16_t tx_time_us; | ||
1156 | } data; | ||
1157 | uint64_t word; | ||
1158 | } nx_nic_intr_coalesce_data_t; | ||
1159 | |||
1160 | typedef struct { | ||
1161 | uint16_t stats_time_us; | ||
1162 | uint16_t rate_sample_time; | ||
1163 | uint16_t flags; | ||
1164 | uint16_t rsvd_1; | ||
1165 | uint32_t low_threshold; | ||
1166 | uint32_t high_threshold; | ||
1167 | nx_nic_intr_coalesce_data_t normal; | ||
1168 | nx_nic_intr_coalesce_data_t low; | ||
1169 | nx_nic_intr_coalesce_data_t high; | ||
1170 | nx_nic_intr_coalesce_data_t irq; | ||
1171 | } nx_nic_intr_coalesce_t; | ||
1172 | |||
1173 | typedef struct { | ||
1174 | u64 qhdr; | ||
1175 | u64 req_hdr; | ||
1176 | u64 words[6]; | ||
1177 | } nx_nic_req_t; | ||
1178 | |||
1179 | typedef struct { | ||
1180 | u8 op; | ||
1181 | u8 tag; | ||
1182 | u8 mac_addr[6]; | ||
1183 | } nx_mac_req_t; | ||
1184 | |||
1185 | #define MAX_PENDING_DESC_BLOCK_SIZE 64 | ||
1186 | |||
1187 | #define NETXEN_NIC_MSI_ENABLED 0x02 | ||
1188 | #define NETXEN_NIC_MSIX_ENABLED 0x04 | ||
1189 | #define NETXEN_IS_MSI_FAMILY(adapter) \ | ||
1190 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) | ||
1191 | |||
1192 | #define MSIX_ENTRIES_PER_ADAPTER 8 | ||
1193 | #define NETXEN_MSIX_TBL_SPACE 8192 | ||
1194 | #define NETXEN_PCI_REG_MSIX_TBL 0x44 | ||
1195 | |||
1196 | #define NETXEN_DB_MAPSIZE_BYTES 0x1000 | ||
1197 | |||
1198 | #define NETXEN_NETDEV_WEIGHT 120 | ||
1199 | #define NETXEN_ADAPTER_UP_MAGIC 777 | ||
1200 | #define NETXEN_NIC_PEG_TUNE 0 | ||
848 | 1201 | ||
849 | struct netxen_dummy_dma { | 1202 | struct netxen_dummy_dma { |
850 | void *addr; | 1203 | void *addr; |
@@ -854,46 +1207,65 @@ struct netxen_dummy_dma { | |||
854 | struct netxen_adapter { | 1207 | struct netxen_adapter { |
855 | struct netxen_hardware_context ahw; | 1208 | struct netxen_hardware_context ahw; |
856 | 1209 | ||
857 | struct netxen_adapter *master; | ||
858 | struct net_device *netdev; | 1210 | struct net_device *netdev; |
859 | struct pci_dev *pdev; | 1211 | struct pci_dev *pdev; |
1212 | int pci_using_dac; | ||
860 | struct napi_struct napi; | 1213 | struct napi_struct napi; |
861 | struct net_device_stats net_stats; | 1214 | struct net_device_stats net_stats; |
862 | unsigned char mac_addr[ETH_ALEN]; | ||
863 | int mtu; | 1215 | int mtu; |
864 | int portnum; | 1216 | int portnum; |
865 | u8 physical_port; | 1217 | u8 physical_port; |
1218 | u16 tx_context_id; | ||
1219 | |||
1220 | uint8_t mc_enabled; | ||
1221 | uint8_t max_mc_count; | ||
1222 | nx_mac_list_t *mac_list; | ||
1223 | |||
1224 | struct netxen_legacy_intr_set legacy_intr; | ||
1225 | u32 crb_intr_mask; | ||
866 | 1226 | ||
867 | struct work_struct watchdog_task; | 1227 | struct work_struct watchdog_task; |
868 | struct timer_list watchdog_timer; | 1228 | struct timer_list watchdog_timer; |
869 | struct work_struct tx_timeout_task; | 1229 | struct work_struct tx_timeout_task; |
870 | 1230 | ||
871 | u32 curr_window; | 1231 | u32 curr_window; |
1232 | u32 crb_win; | ||
1233 | rwlock_t adapter_lock; | ||
1234 | |||
1235 | uint64_t dma_mask; | ||
872 | 1236 | ||
873 | u32 cmd_producer; | 1237 | u32 cmd_producer; |
874 | __le32 *cmd_consumer; | 1238 | __le32 *cmd_consumer; |
875 | u32 last_cmd_consumer; | 1239 | u32 last_cmd_consumer; |
1240 | u32 crb_addr_cmd_producer; | ||
1241 | u32 crb_addr_cmd_consumer; | ||
876 | 1242 | ||
877 | u32 max_tx_desc_count; | 1243 | u32 max_tx_desc_count; |
878 | u32 max_rx_desc_count; | 1244 | u32 max_rx_desc_count; |
879 | u32 max_jumbo_rx_desc_count; | 1245 | u32 max_jumbo_rx_desc_count; |
880 | u32 max_lro_rx_desc_count; | 1246 | u32 max_lro_rx_desc_count; |
881 | 1247 | ||
1248 | int max_rds_rings; | ||
1249 | |||
882 | u32 flags; | 1250 | u32 flags; |
883 | u32 irq; | 1251 | u32 irq; |
884 | int driver_mismatch; | 1252 | int driver_mismatch; |
885 | u32 temp; | 1253 | u32 temp; |
886 | 1254 | ||
1255 | u32 fw_major; | ||
1256 | |||
1257 | u8 msix_supported; | ||
1258 | u8 max_possible_rss_rings; | ||
1259 | struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER]; | ||
1260 | |||
887 | struct netxen_adapter_stats stats; | 1261 | struct netxen_adapter_stats stats; |
888 | 1262 | ||
889 | u16 portno; | ||
890 | u16 link_speed; | 1263 | u16 link_speed; |
891 | u16 link_duplex; | 1264 | u16 link_duplex; |
892 | u16 state; | 1265 | u16 state; |
893 | u16 link_autoneg; | 1266 | u16 link_autoneg; |
894 | int rx_csum; | 1267 | int rx_csum; |
895 | int status; | 1268 | int status; |
896 | spinlock_t stats_lock; | ||
897 | 1269 | ||
898 | struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ | 1270 | struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ |
899 | 1271 | ||
@@ -905,25 +1277,33 @@ struct netxen_adapter { | |||
905 | 1277 | ||
906 | int is_up; | 1278 | int is_up; |
907 | struct netxen_dummy_dma dummy_dma; | 1279 | struct netxen_dummy_dma dummy_dma; |
1280 | nx_nic_intr_coalesce_t coal; | ||
908 | 1281 | ||
909 | /* Context interface shared between card and host */ | 1282 | /* Context interface shared between card and host */ |
910 | struct netxen_ring_ctx *ctx_desc; | 1283 | struct netxen_ring_ctx *ctx_desc; |
911 | struct pci_dev *ctx_desc_pdev; | ||
912 | dma_addr_t ctx_desc_phys_addr; | 1284 | dma_addr_t ctx_desc_phys_addr; |
913 | int intr_scheme; | 1285 | int intr_scheme; |
914 | int msi_mode; | 1286 | int msi_mode; |
915 | int (*enable_phy_interrupts) (struct netxen_adapter *); | 1287 | int (*enable_phy_interrupts) (struct netxen_adapter *); |
916 | int (*disable_phy_interrupts) (struct netxen_adapter *); | 1288 | int (*disable_phy_interrupts) (struct netxen_adapter *); |
917 | void (*handle_phy_intr) (struct netxen_adapter *); | ||
918 | int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); | 1289 | int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); |
919 | int (*set_mtu) (struct netxen_adapter *, int); | 1290 | int (*set_mtu) (struct netxen_adapter *, int); |
920 | int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t); | 1291 | int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t); |
921 | int (*unset_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t); | ||
922 | int (*phy_read) (struct netxen_adapter *, long reg, u32 *); | 1292 | int (*phy_read) (struct netxen_adapter *, long reg, u32 *); |
923 | int (*phy_write) (struct netxen_adapter *, long reg, u32 val); | 1293 | int (*phy_write) (struct netxen_adapter *, long reg, u32 val); |
924 | int (*init_port) (struct netxen_adapter *, int); | 1294 | int (*init_port) (struct netxen_adapter *, int); |
925 | void (*init_niu) (struct netxen_adapter *); | ||
926 | int (*stop_port) (struct netxen_adapter *); | 1295 | int (*stop_port) (struct netxen_adapter *); |
1296 | |||
1297 | int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int); | ||
1298 | int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int); | ||
1299 | int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); | ||
1300 | int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); | ||
1301 | int (*pci_write_immediate)(struct netxen_adapter *, u64, u32); | ||
1302 | u32 (*pci_read_immediate)(struct netxen_adapter *, u64); | ||
1303 | void (*pci_write_normalize)(struct netxen_adapter *, u64, u32); | ||
1304 | u32 (*pci_read_normalize)(struct netxen_adapter *, u64); | ||
1305 | unsigned long (*pci_set_window)(struct netxen_adapter *, | ||
1306 | unsigned long long); | ||
927 | }; /* netxen_adapter structure */ | 1307 | }; /* netxen_adapter structure */ |
928 | 1308 | ||
929 | /* | 1309 | /* |
@@ -988,8 +1368,6 @@ int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter); | |||
988 | int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter); | 1368 | int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter); |
989 | int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter); | 1369 | int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter); |
990 | int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter); | 1370 | int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter); |
991 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter); | ||
992 | void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter); | ||
993 | int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | 1371 | int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, |
994 | __u32 * readval); | 1372 | __u32 * readval); |
995 | int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, | 1373 | int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, |
@@ -998,27 +1376,61 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, | |||
998 | /* Functions available from netxen_nic_hw.c */ | 1376 | /* Functions available from netxen_nic_hw.c */ |
999 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); | 1377 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); |
1000 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); | 1378 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); |
1001 | void netxen_nic_init_niu_gb(struct netxen_adapter *adapter); | ||
1002 | void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw); | ||
1003 | void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); | 1379 | void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); |
1004 | int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); | 1380 | int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); |
1005 | void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); | 1381 | void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); |
1006 | void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value); | 1382 | void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value); |
1383 | void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value); | ||
1384 | void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value); | ||
1007 | 1385 | ||
1008 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); | 1386 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); |
1009 | int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, | 1387 | |
1010 | int len); | 1388 | int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, |
1011 | int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | 1389 | ulong off, void *data, int len); |
1012 | int len); | 1390 | int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, |
1391 | ulong off, void *data, int len); | ||
1392 | int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, | ||
1393 | u64 off, void *data, int size); | ||
1394 | int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, | ||
1395 | u64 off, void *data, int size); | ||
1396 | int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter, | ||
1397 | u64 off, u32 data); | ||
1398 | u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off); | ||
1399 | void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter, | ||
1400 | u64 off, u32 data); | ||
1401 | u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off); | ||
1402 | unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, | ||
1403 | unsigned long long addr); | ||
1404 | void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, | ||
1405 | u32 wndw); | ||
1406 | |||
1407 | int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, | ||
1408 | ulong off, void *data, int len); | ||
1409 | int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, | ||
1410 | ulong off, void *data, int len); | ||
1411 | int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, | ||
1412 | u64 off, void *data, int size); | ||
1413 | int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, | ||
1414 | u64 off, void *data, int size); | ||
1013 | void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, | 1415 | void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, |
1014 | unsigned long off, int data); | 1416 | unsigned long off, int data); |
1417 | int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, | ||
1418 | u64 off, u32 data); | ||
1419 | u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off); | ||
1420 | void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter, | ||
1421 | u64 off, u32 data); | ||
1422 | u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off); | ||
1423 | unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | ||
1424 | unsigned long long addr); | ||
1015 | 1425 | ||
1016 | /* Functions from netxen_nic_init.c */ | 1426 | /* Functions from netxen_nic_init.c */ |
1017 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); | 1427 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); |
1018 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1428 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1019 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1429 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1430 | int netxen_receive_peg_ready(struct netxen_adapter *adapter); | ||
1020 | int netxen_load_firmware(struct netxen_adapter *adapter); | 1431 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1021 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1432 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
1433 | |||
1022 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1434 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
1023 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | 1435 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, |
1024 | u8 *bytes, size_t size); | 1436 | u8 *bytes, size_t size); |
@@ -1032,33 +1444,43 @@ void netxen_halt_pegs(struct netxen_adapter *adapter); | |||
1032 | 1444 | ||
1033 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); | 1445 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); |
1034 | 1446 | ||
1035 | /* Functions from netxen_nic_isr.c */ | 1447 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter); |
1036 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); | 1448 | void netxen_free_sw_resources(struct netxen_adapter *adapter); |
1037 | void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, | 1449 | |
1038 | struct pci_dev **used_dev); | 1450 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter); |
1451 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
1452 | |||
1453 | void netxen_release_rx_buffers(struct netxen_adapter *adapter); | ||
1454 | void netxen_release_tx_buffers(struct netxen_adapter *adapter); | ||
1455 | |||
1039 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); | 1456 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); |
1040 | int netxen_init_firmware(struct netxen_adapter *adapter); | 1457 | int netxen_init_firmware(struct netxen_adapter *adapter); |
1041 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
1042 | void netxen_tso_check(struct netxen_adapter *adapter, | 1458 | void netxen_tso_check(struct netxen_adapter *adapter, |
1043 | struct cmd_desc_type0 *desc, struct sk_buff *skb); | 1459 | struct cmd_desc_type0 *desc, struct sk_buff *skb); |
1044 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); | ||
1045 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); | 1460 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); |
1046 | void netxen_watchdog_task(struct work_struct *work); | 1461 | void netxen_watchdog_task(struct work_struct *work); |
1047 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, | 1462 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, |
1048 | u32 ringid); | 1463 | u32 ringid); |
1049 | int netxen_process_cmd_ring(struct netxen_adapter *adapter); | 1464 | int netxen_process_cmd_ring(struct netxen_adapter *adapter); |
1050 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); | 1465 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); |
1051 | void netxen_nic_set_multi(struct net_device *netdev); | 1466 | void netxen_p2_nic_set_multi(struct net_device *netdev); |
1467 | void netxen_p3_nic_set_multi(struct net_device *netdev); | ||
1468 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter); | ||
1469 | |||
1470 | u32 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu); | ||
1052 | int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); | 1471 | int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); |
1472 | |||
1053 | int netxen_nic_set_mac(struct net_device *netdev, void *p); | 1473 | int netxen_nic_set_mac(struct net_device *netdev, void *p); |
1054 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); | 1474 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); |
1055 | 1475 | ||
1476 | void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | ||
1477 | uint32_t crb_producer); | ||
1056 | 1478 | ||
1057 | /* | 1479 | /* |
1058 | * NetXen Board information | 1480 | * NetXen Board information |
1059 | */ | 1481 | */ |
1060 | 1482 | ||
1061 | #define NETXEN_MAX_SHORT_NAME 16 | 1483 | #define NETXEN_MAX_SHORT_NAME 32 |
1062 | struct netxen_brdinfo { | 1484 | struct netxen_brdinfo { |
1063 | netxen_brdtype_t brdtype; /* type of board */ | 1485 | netxen_brdtype_t brdtype; /* type of board */ |
1064 | long ports; /* max no of physical ports */ | 1486 | long ports; /* max no of physical ports */ |
@@ -1072,6 +1494,17 @@ static const struct netxen_brdinfo netxen_boards[] = { | |||
1072 | {NETXEN_BRDTYPE_P2_SB31_10G, 1, "XGb XFP"}, | 1494 | {NETXEN_BRDTYPE_P2_SB31_10G, 1, "XGb XFP"}, |
1073 | {NETXEN_BRDTYPE_P2_SB35_4G, 4, "Quad Gb"}, | 1495 | {NETXEN_BRDTYPE_P2_SB35_4G, 4, "Quad Gb"}, |
1074 | {NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"}, | 1496 | {NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"}, |
1497 | {NETXEN_BRDTYPE_P3_REF_QG, 4, "Reference Quad Gig "}, | ||
1498 | {NETXEN_BRDTYPE_P3_HMEZ, 2, "Dual XGb HMEZ"}, | ||
1499 | {NETXEN_BRDTYPE_P3_10G_CX4_LP, 2, "Dual XGb CX4 LP"}, | ||
1500 | {NETXEN_BRDTYPE_P3_4_GB, 4, "Quad Gig LP"}, | ||
1501 | {NETXEN_BRDTYPE_P3_IMEZ, 2, "Dual XGb IMEZ"}, | ||
1502 | {NETXEN_BRDTYPE_P3_10G_SFP_PLUS, 2, "Dual XGb SFP+ LP"}, | ||
1503 | {NETXEN_BRDTYPE_P3_10000_BASE_T, 1, "XGB 10G BaseT LP"}, | ||
1504 | {NETXEN_BRDTYPE_P3_XG_LOM, 2, "Dual XGb LOM"}, | ||
1505 | {NETXEN_BRDTYPE_P3_4_GB_MM, 4, "Quad GB - March Madness"}, | ||
1506 | {NETXEN_BRDTYPE_P3_10G_CX4, 2, "Reference Dual CX4 Option"}, | ||
1507 | {NETXEN_BRDTYPE_P3_10G_XFP, 1, "Reference Single XFP Option"} | ||
1075 | }; | 1508 | }; |
1076 | 1509 | ||
1077 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards) | 1510 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards) |
@@ -1097,7 +1530,7 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter) | |||
1097 | u32 ctrl; | 1530 | u32 ctrl; |
1098 | 1531 | ||
1099 | /* check if already inactive */ | 1532 | /* check if already inactive */ |
1100 | if (netxen_nic_hw_read_wx(adapter, | 1533 | if (adapter->hw_read_wx(adapter, |
1101 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | 1534 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) |
1102 | printk(KERN_ERR "failed to read dma watchdog status\n"); | 1535 | printk(KERN_ERR "failed to read dma watchdog status\n"); |
1103 | 1536 | ||
@@ -1117,7 +1550,7 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter) | |||
1117 | { | 1550 | { |
1118 | u32 ctrl; | 1551 | u32 ctrl; |
1119 | 1552 | ||
1120 | if (netxen_nic_hw_read_wx(adapter, | 1553 | if (adapter->hw_read_wx(adapter, |
1121 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | 1554 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) |
1122 | printk(KERN_ERR "failed to read dma watchdog status\n"); | 1555 | printk(KERN_ERR "failed to read dma watchdog status\n"); |
1123 | 1556 | ||
@@ -1129,7 +1562,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) | |||
1129 | { | 1562 | { |
1130 | u32 ctrl; | 1563 | u32 ctrl; |
1131 | 1564 | ||
1132 | if (netxen_nic_hw_read_wx(adapter, | 1565 | if (adapter->hw_read_wx(adapter, |
1133 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | 1566 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) |
1134 | printk(KERN_ERR "failed to read dma watchdog status\n"); | 1567 | printk(KERN_ERR "failed to read dma watchdog status\n"); |
1135 | 1568 | ||
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c new file mode 100644 index 000000000000..64babc59e699 --- /dev/null +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -0,0 +1,710 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003 - 2008 NetXen, Inc. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
18 | * MA 02111-1307, USA. | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution | ||
21 | * in the file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * info@netxen.com | ||
25 | * NetXen, | ||
26 | * 3965 Freedom Circle, Fourth floor, | ||
27 | * Santa Clara, CA 95054 | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #include "netxen_nic_hw.h" | ||
32 | #include "netxen_nic.h" | ||
33 | #include "netxen_nic_phan_reg.h" | ||
34 | |||
35 | #define NXHAL_VERSION 1 | ||
36 | |||
37 | static int | ||
38 | netxen_api_lock(struct netxen_adapter *adapter) | ||
39 | { | ||
40 | u32 done = 0, timeout = 0; | ||
41 | |||
42 | for (;;) { | ||
43 | /* Acquire PCIE HW semaphore5 */ | ||
44 | netxen_nic_read_w0(adapter, | ||
45 | NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done); | ||
46 | |||
47 | if (done == 1) | ||
48 | break; | ||
49 | |||
50 | if (++timeout >= NX_OS_CRB_RETRY_COUNT) { | ||
51 | printk(KERN_ERR "%s: lock timeout.\n", __func__); | ||
52 | return -1; | ||
53 | } | ||
54 | |||
55 | msleep(1); | ||
56 | } | ||
57 | |||
58 | #if 0 | ||
59 | netxen_nic_write_w1(adapter, | ||
60 | NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER); | ||
61 | #endif | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int | ||
66 | netxen_api_unlock(struct netxen_adapter *adapter) | ||
67 | { | ||
68 | u32 val; | ||
69 | |||
70 | /* Release PCIE HW semaphore5 */ | ||
71 | netxen_nic_read_w0(adapter, | ||
72 | NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static u32 | ||
77 | netxen_poll_rsp(struct netxen_adapter *adapter) | ||
78 | { | ||
79 | u32 raw_rsp, rsp = NX_CDRP_RSP_OK; | ||
80 | int timeout = 0; | ||
81 | |||
82 | do { | ||
83 | /* give atleast 1ms for firmware to respond */ | ||
84 | msleep(1); | ||
85 | |||
86 | if (++timeout > NX_OS_CRB_RETRY_COUNT) | ||
87 | return NX_CDRP_RSP_TIMEOUT; | ||
88 | |||
89 | netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, | ||
90 | &raw_rsp); | ||
91 | |||
92 | rsp = le32_to_cpu(raw_rsp); | ||
93 | } while (!NX_CDRP_IS_RSP(rsp)); | ||
94 | |||
95 | return rsp; | ||
96 | } | ||
97 | |||
98 | static u32 | ||
99 | netxen_issue_cmd(struct netxen_adapter *adapter, | ||
100 | u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) | ||
101 | { | ||
102 | u32 rsp; | ||
103 | u32 signature = 0; | ||
104 | u32 rcode = NX_RCODE_SUCCESS; | ||
105 | |||
106 | signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); | ||
107 | |||
108 | /* Acquire semaphore before accessing CRB */ | ||
109 | if (netxen_api_lock(adapter)) | ||
110 | return NX_RCODE_TIMEOUT; | ||
111 | |||
112 | netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, | ||
113 | cpu_to_le32(signature)); | ||
114 | |||
115 | netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, | ||
116 | cpu_to_le32(arg1)); | ||
117 | |||
118 | netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, | ||
119 | cpu_to_le32(arg2)); | ||
120 | |||
121 | netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, | ||
122 | cpu_to_le32(arg3)); | ||
123 | |||
124 | netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET, | ||
125 | cpu_to_le32(NX_CDRP_FORM_CMD(cmd))); | ||
126 | |||
127 | rsp = netxen_poll_rsp(adapter); | ||
128 | |||
129 | if (rsp == NX_CDRP_RSP_TIMEOUT) { | ||
130 | printk(KERN_ERR "%s: card response timeout.\n", | ||
131 | netxen_nic_driver_name); | ||
132 | |||
133 | rcode = NX_RCODE_TIMEOUT; | ||
134 | } else if (rsp == NX_CDRP_RSP_FAIL) { | ||
135 | netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode); | ||
136 | rcode = le32_to_cpu(rcode); | ||
137 | |||
138 | printk(KERN_ERR "%s: failed card response code:0x%x\n", | ||
139 | netxen_nic_driver_name, rcode); | ||
140 | } | ||
141 | |||
142 | /* Release semaphore */ | ||
143 | netxen_api_unlock(adapter); | ||
144 | |||
145 | return rcode; | ||
146 | } | ||
147 | |||
148 | u32 | ||
149 | nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu) | ||
150 | { | ||
151 | u32 rcode = NX_RCODE_SUCCESS; | ||
152 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0]; | ||
153 | |||
154 | if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) | ||
155 | rcode = netxen_issue_cmd(adapter, | ||
156 | adapter->ahw.pci_func, | ||
157 | NXHAL_VERSION, | ||
158 | recv_ctx->context_id, | ||
159 | mtu, | ||
160 | 0, | ||
161 | NX_CDRP_CMD_SET_MTU); | ||
162 | |||
163 | return rcode; | ||
164 | } | ||
165 | |||
166 | static int | ||
167 | nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) | ||
168 | { | ||
169 | void *addr; | ||
170 | nx_hostrq_rx_ctx_t *prq; | ||
171 | nx_cardrsp_rx_ctx_t *prsp; | ||
172 | nx_hostrq_rds_ring_t *prq_rds; | ||
173 | nx_hostrq_sds_ring_t *prq_sds; | ||
174 | nx_cardrsp_rds_ring_t *prsp_rds; | ||
175 | nx_cardrsp_sds_ring_t *prsp_sds; | ||
176 | struct nx_host_rds_ring *rds_ring; | ||
177 | |||
178 | dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; | ||
179 | u64 phys_addr; | ||
180 | |||
181 | int i, nrds_rings, nsds_rings; | ||
182 | size_t rq_size, rsp_size; | ||
183 | u32 cap, reg; | ||
184 | |||
185 | int err; | ||
186 | |||
187 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0]; | ||
188 | |||
189 | /* only one sds ring for now */ | ||
190 | nrds_rings = adapter->max_rds_rings; | ||
191 | nsds_rings = 1; | ||
192 | |||
193 | rq_size = | ||
194 | SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings); | ||
195 | rsp_size = | ||
196 | SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings); | ||
197 | |||
198 | addr = pci_alloc_consistent(adapter->pdev, | ||
199 | rq_size, &hostrq_phys_addr); | ||
200 | if (addr == NULL) | ||
201 | return -ENOMEM; | ||
202 | prq = (nx_hostrq_rx_ctx_t *)addr; | ||
203 | |||
204 | addr = pci_alloc_consistent(adapter->pdev, | ||
205 | rsp_size, &cardrsp_phys_addr); | ||
206 | if (addr == NULL) { | ||
207 | err = -ENOMEM; | ||
208 | goto out_free_rq; | ||
209 | } | ||
210 | prsp = (nx_cardrsp_rx_ctx_t *)addr; | ||
211 | |||
212 | prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); | ||
213 | |||
214 | cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); | ||
215 | cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); | ||
216 | |||
217 | prq->capabilities[0] = cpu_to_le32(cap); | ||
218 | prq->host_int_crb_mode = | ||
219 | cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); | ||
220 | prq->host_rds_crb_mode = | ||
221 | cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE); | ||
222 | |||
223 | prq->num_rds_rings = cpu_to_le16(nrds_rings); | ||
224 | prq->num_sds_rings = cpu_to_le16(nsds_rings); | ||
225 | prq->rds_ring_offset = 0; | ||
226 | prq->sds_ring_offset = prq->rds_ring_offset + | ||
227 | (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); | ||
228 | |||
229 | prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset); | ||
230 | |||
231 | for (i = 0; i < nrds_rings; i++) { | ||
232 | |||
233 | rds_ring = &recv_ctx->rds_rings[i]; | ||
234 | |||
235 | prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr); | ||
236 | prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count); | ||
237 | prq_rds[i].ring_kind = cpu_to_le32(i); | ||
238 | prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); | ||
239 | } | ||
240 | |||
241 | prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset); | ||
242 | |||
243 | prq_sds[0].host_phys_addr = | ||
244 | cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); | ||
245 | prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count); | ||
246 | /* only one msix vector for now */ | ||
247 | prq_sds[0].msi_index = cpu_to_le32(0); | ||
248 | |||
249 | /* now byteswap offsets */ | ||
250 | prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset); | ||
251 | prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset); | ||
252 | |||
253 | phys_addr = hostrq_phys_addr; | ||
254 | err = netxen_issue_cmd(adapter, | ||
255 | adapter->ahw.pci_func, | ||
256 | NXHAL_VERSION, | ||
257 | (u32)(phys_addr >> 32), | ||
258 | (u32)(phys_addr & 0xffffffff), | ||
259 | rq_size, | ||
260 | NX_CDRP_CMD_CREATE_RX_CTX); | ||
261 | if (err) { | ||
262 | printk(KERN_WARNING | ||
263 | "Failed to create rx ctx in firmware%d\n", err); | ||
264 | goto out_free_rsp; | ||
265 | } | ||
266 | |||
267 | |||
268 | prsp_rds = ((nx_cardrsp_rds_ring_t *) | ||
269 | &prsp->data[prsp->rds_ring_offset]); | ||
270 | |||
271 | for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) { | ||
272 | rds_ring = &recv_ctx->rds_rings[i]; | ||
273 | |||
274 | reg = le32_to_cpu(prsp_rds[i].host_producer_crb); | ||
275 | rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200); | ||
276 | } | ||
277 | |||
278 | prsp_sds = ((nx_cardrsp_sds_ring_t *) | ||
279 | &prsp->data[prsp->sds_ring_offset]); | ||
280 | reg = le32_to_cpu(prsp_sds[0].host_consumer_crb); | ||
281 | recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200); | ||
282 | |||
283 | reg = le32_to_cpu(prsp_sds[0].interrupt_crb); | ||
284 | adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200); | ||
285 | |||
286 | recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); | ||
287 | recv_ctx->context_id = le16_to_cpu(prsp->context_id); | ||
288 | recv_ctx->virt_port = le16_to_cpu(prsp->virt_port); | ||
289 | |||
290 | out_free_rsp: | ||
291 | pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); | ||
292 | out_free_rq: | ||
293 | pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr); | ||
294 | return err; | ||
295 | } | ||
296 | |||
297 | static void | ||
298 | nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) | ||
299 | { | ||
300 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0]; | ||
301 | |||
302 | if (netxen_issue_cmd(adapter, | ||
303 | adapter->ahw.pci_func, | ||
304 | NXHAL_VERSION, | ||
305 | recv_ctx->context_id, | ||
306 | NX_DESTROY_CTX_RESET, | ||
307 | 0, | ||
308 | NX_CDRP_CMD_DESTROY_RX_CTX)) { | ||
309 | |||
310 | printk(KERN_WARNING | ||
311 | "%s: Failed to destroy rx ctx in firmware\n", | ||
312 | netxen_nic_driver_name); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) | ||
318 | { | ||
319 | nx_hostrq_tx_ctx_t *prq; | ||
320 | nx_hostrq_cds_ring_t *prq_cds; | ||
321 | nx_cardrsp_tx_ctx_t *prsp; | ||
322 | void *rq_addr, *rsp_addr; | ||
323 | size_t rq_size, rsp_size; | ||
324 | u32 temp; | ||
325 | int err = 0; | ||
326 | u64 offset, phys_addr; | ||
327 | dma_addr_t rq_phys_addr, rsp_phys_addr; | ||
328 | |||
329 | rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); | ||
330 | rq_addr = pci_alloc_consistent(adapter->pdev, | ||
331 | rq_size, &rq_phys_addr); | ||
332 | if (!rq_addr) | ||
333 | return -ENOMEM; | ||
334 | |||
335 | rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t); | ||
336 | rsp_addr = pci_alloc_consistent(adapter->pdev, | ||
337 | rsp_size, &rsp_phys_addr); | ||
338 | if (!rsp_addr) { | ||
339 | err = -ENOMEM; | ||
340 | goto out_free_rq; | ||
341 | } | ||
342 | |||
343 | memset(rq_addr, 0, rq_size); | ||
344 | prq = (nx_hostrq_tx_ctx_t *)rq_addr; | ||
345 | |||
346 | memset(rsp_addr, 0, rsp_size); | ||
347 | prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr; | ||
348 | |||
349 | prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); | ||
350 | |||
351 | temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO); | ||
352 | prq->capabilities[0] = cpu_to_le32(temp); | ||
353 | |||
354 | prq->host_int_crb_mode = | ||
355 | cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); | ||
356 | |||
357 | prq->interrupt_ctl = 0; | ||
358 | prq->msi_index = 0; | ||
359 | |||
360 | prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr); | ||
361 | |||
362 | offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx); | ||
363 | prq->cmd_cons_dma_addr = cpu_to_le64(offset); | ||
364 | |||
365 | prq_cds = &prq->cds_ring; | ||
366 | |||
367 | prq_cds->host_phys_addr = | ||
368 | cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); | ||
369 | |||
370 | prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count); | ||
371 | |||
372 | phys_addr = rq_phys_addr; | ||
373 | err = netxen_issue_cmd(adapter, | ||
374 | adapter->ahw.pci_func, | ||
375 | NXHAL_VERSION, | ||
376 | (u32)(phys_addr >> 32), | ||
377 | ((u32)phys_addr & 0xffffffff), | ||
378 | rq_size, | ||
379 | NX_CDRP_CMD_CREATE_TX_CTX); | ||
380 | |||
381 | if (err == NX_RCODE_SUCCESS) { | ||
382 | temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); | ||
383 | adapter->crb_addr_cmd_producer = | ||
384 | NETXEN_NIC_REG(temp - 0x200); | ||
385 | #if 0 | ||
386 | adapter->tx_state = | ||
387 | le32_to_cpu(prsp->host_ctx_state); | ||
388 | #endif | ||
389 | adapter->tx_context_id = | ||
390 | le16_to_cpu(prsp->context_id); | ||
391 | } else { | ||
392 | printk(KERN_WARNING | ||
393 | "Failed to create tx ctx in firmware%d\n", err); | ||
394 | err = -EIO; | ||
395 | } | ||
396 | |||
397 | pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr); | ||
398 | |||
399 | out_free_rq: | ||
400 | pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr); | ||
401 | |||
402 | return err; | ||
403 | } | ||
404 | |||
405 | static void | ||
406 | nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) | ||
407 | { | ||
408 | if (netxen_issue_cmd(adapter, | ||
409 | adapter->ahw.pci_func, | ||
410 | NXHAL_VERSION, | ||
411 | adapter->tx_context_id, | ||
412 | NX_DESTROY_CTX_RESET, | ||
413 | 0, | ||
414 | NX_CDRP_CMD_DESTROY_TX_CTX)) { | ||
415 | |||
416 | printk(KERN_WARNING | ||
417 | "%s: Failed to destroy tx ctx in firmware\n", | ||
418 | netxen_nic_driver_name); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static u64 ctx_addr_sig_regs[][3] = { | ||
423 | {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, | ||
424 | {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, | ||
425 | {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, | ||
426 | {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} | ||
427 | }; | ||
428 | |||
429 | #define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) | ||
430 | #define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) | ||
431 | #define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) | ||
432 | |||
433 | #define lower32(x) ((u32)((x) & 0xffffffff)) | ||
434 | #define upper32(x) ((u32)(((u64)(x) >> 32) & 0xffffffff)) | ||
435 | |||
436 | static struct netxen_recv_crb recv_crb_registers[] = { | ||
437 | /* Instance 0 */ | ||
438 | { | ||
439 | /* crb_rcv_producer: */ | ||
440 | { | ||
441 | NETXEN_NIC_REG(0x100), | ||
442 | /* Jumbo frames */ | ||
443 | NETXEN_NIC_REG(0x110), | ||
444 | /* LRO */ | ||
445 | NETXEN_NIC_REG(0x120) | ||
446 | }, | ||
447 | /* crb_sts_consumer: */ | ||
448 | NETXEN_NIC_REG(0x138), | ||
449 | }, | ||
450 | /* Instance 1 */ | ||
451 | { | ||
452 | /* crb_rcv_producer: */ | ||
453 | { | ||
454 | NETXEN_NIC_REG(0x144), | ||
455 | /* Jumbo frames */ | ||
456 | NETXEN_NIC_REG(0x154), | ||
457 | /* LRO */ | ||
458 | NETXEN_NIC_REG(0x164) | ||
459 | }, | ||
460 | /* crb_sts_consumer: */ | ||
461 | NETXEN_NIC_REG(0x17c), | ||
462 | }, | ||
463 | /* Instance 2 */ | ||
464 | { | ||
465 | /* crb_rcv_producer: */ | ||
466 | { | ||
467 | NETXEN_NIC_REG(0x1d8), | ||
468 | /* Jumbo frames */ | ||
469 | NETXEN_NIC_REG(0x1f8), | ||
470 | /* LRO */ | ||
471 | NETXEN_NIC_REG(0x208) | ||
472 | }, | ||
473 | /* crb_sts_consumer: */ | ||
474 | NETXEN_NIC_REG(0x220), | ||
475 | }, | ||
476 | /* Instance 3 */ | ||
477 | { | ||
478 | /* crb_rcv_producer: */ | ||
479 | { | ||
480 | NETXEN_NIC_REG(0x22c), | ||
481 | /* Jumbo frames */ | ||
482 | NETXEN_NIC_REG(0x23c), | ||
483 | /* LRO */ | ||
484 | NETXEN_NIC_REG(0x24c) | ||
485 | }, | ||
486 | /* crb_sts_consumer: */ | ||
487 | NETXEN_NIC_REG(0x264), | ||
488 | }, | ||
489 | }; | ||
490 | |||
491 | static int | ||
492 | netxen_init_old_ctx(struct netxen_adapter *adapter) | ||
493 | { | ||
494 | struct netxen_recv_context *recv_ctx; | ||
495 | struct nx_host_rds_ring *rds_ring; | ||
496 | int ctx, ring; | ||
497 | int func_id = adapter->portnum; | ||
498 | |||
499 | adapter->ctx_desc->cmd_ring_addr = | ||
500 | cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); | ||
501 | adapter->ctx_desc->cmd_ring_size = | ||
502 | cpu_to_le32(adapter->max_tx_desc_count); | ||
503 | |||
504 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
505 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
506 | |||
507 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
508 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
509 | |||
510 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = | ||
511 | cpu_to_le64(rds_ring->phys_addr); | ||
512 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = | ||
513 | cpu_to_le32(rds_ring->max_rx_desc_count); | ||
514 | } | ||
515 | adapter->ctx_desc->sts_ring_addr = | ||
516 | cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); | ||
517 | adapter->ctx_desc->sts_ring_size = | ||
518 | cpu_to_le32(adapter->max_rx_desc_count); | ||
519 | } | ||
520 | |||
521 | adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id), | ||
522 | lower32(adapter->ctx_desc_phys_addr)); | ||
523 | adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id), | ||
524 | upper32(adapter->ctx_desc_phys_addr)); | ||
525 | adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id), | ||
526 | NETXEN_CTX_SIGNATURE | func_id); | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static uint32_t sw_int_mask[4] = { | ||
531 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
532 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
533 | }; | ||
534 | |||
535 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | ||
536 | { | ||
537 | struct netxen_hardware_context *hw = &adapter->ahw; | ||
538 | u32 state = 0; | ||
539 | void *addr; | ||
540 | int err = 0; | ||
541 | int ctx, ring; | ||
542 | struct netxen_recv_context *recv_ctx; | ||
543 | struct nx_host_rds_ring *rds_ring; | ||
544 | |||
545 | err = netxen_receive_peg_ready(adapter); | ||
546 | if (err) { | ||
547 | printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n", | ||
548 | state); | ||
549 | return err; | ||
550 | } | ||
551 | |||
552 | addr = pci_alloc_consistent(adapter->pdev, | ||
553 | sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), | ||
554 | &adapter->ctx_desc_phys_addr); | ||
555 | |||
556 | if (addr == NULL) { | ||
557 | DPRINTK(ERR, "failed to allocate hw context\n"); | ||
558 | return -ENOMEM; | ||
559 | } | ||
560 | memset(addr, 0, sizeof(struct netxen_ring_ctx)); | ||
561 | adapter->ctx_desc = (struct netxen_ring_ctx *)addr; | ||
562 | adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); | ||
563 | adapter->ctx_desc->cmd_consumer_offset = | ||
564 | cpu_to_le64(adapter->ctx_desc_phys_addr + | ||
565 | sizeof(struct netxen_ring_ctx)); | ||
566 | adapter->cmd_consumer = | ||
567 | (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); | ||
568 | |||
569 | /* cmd desc ring */ | ||
570 | addr = pci_alloc_consistent(adapter->pdev, | ||
571 | sizeof(struct cmd_desc_type0) * | ||
572 | adapter->max_tx_desc_count, | ||
573 | &hw->cmd_desc_phys_addr); | ||
574 | |||
575 | if (addr == NULL) { | ||
576 | printk(KERN_ERR "%s failed to allocate tx desc ring\n", | ||
577 | netxen_nic_driver_name); | ||
578 | return -ENOMEM; | ||
579 | } | ||
580 | |||
581 | hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; | ||
582 | |||
583 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
584 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
585 | |||
586 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
587 | /* rx desc ring */ | ||
588 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
589 | addr = pci_alloc_consistent(adapter->pdev, | ||
590 | RCV_DESC_RINGSIZE, | ||
591 | &rds_ring->phys_addr); | ||
592 | if (addr == NULL) { | ||
593 | printk(KERN_ERR "%s failed to allocate rx " | ||
594 | "desc ring[%d]\n", | ||
595 | netxen_nic_driver_name, ring); | ||
596 | err = -ENOMEM; | ||
597 | goto err_out_free; | ||
598 | } | ||
599 | rds_ring->desc_head = (struct rcv_desc *)addr; | ||
600 | |||
601 | if (adapter->fw_major < 4) | ||
602 | rds_ring->crb_rcv_producer = | ||
603 | recv_crb_registers[adapter->portnum]. | ||
604 | crb_rcv_producer[ring]; | ||
605 | } | ||
606 | |||
607 | /* status desc ring */ | ||
608 | addr = pci_alloc_consistent(adapter->pdev, | ||
609 | STATUS_DESC_RINGSIZE, | ||
610 | &recv_ctx->rcv_status_desc_phys_addr); | ||
611 | if (addr == NULL) { | ||
612 | printk(KERN_ERR "%s failed to allocate sts desc ring\n", | ||
613 | netxen_nic_driver_name); | ||
614 | err = -ENOMEM; | ||
615 | goto err_out_free; | ||
616 | } | ||
617 | recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; | ||
618 | |||
619 | if (adapter->fw_major < 4) | ||
620 | recv_ctx->crb_sts_consumer = | ||
621 | recv_crb_registers[adapter->portnum]. | ||
622 | crb_sts_consumer; | ||
623 | } | ||
624 | |||
625 | if (adapter->fw_major >= 4) { | ||
626 | adapter->intr_scheme = INTR_SCHEME_PERPORT; | ||
627 | adapter->msi_mode = MSI_MODE_MULTIFUNC; | ||
628 | |||
629 | err = nx_fw_cmd_create_rx_ctx(adapter); | ||
630 | if (err) | ||
631 | goto err_out_free; | ||
632 | err = nx_fw_cmd_create_tx_ctx(adapter); | ||
633 | if (err) | ||
634 | goto err_out_free; | ||
635 | } else { | ||
636 | |||
637 | adapter->intr_scheme = adapter->pci_read_normalize(adapter, | ||
638 | CRB_NIC_CAPABILITIES_FW); | ||
639 | adapter->msi_mode = adapter->pci_read_normalize(adapter, | ||
640 | CRB_NIC_MSI_MODE_FW); | ||
641 | adapter->crb_intr_mask = sw_int_mask[adapter->portnum]; | ||
642 | |||
643 | err = netxen_init_old_ctx(adapter); | ||
644 | if (err) { | ||
645 | netxen_free_hw_resources(adapter); | ||
646 | return err; | ||
647 | } | ||
648 | |||
649 | } | ||
650 | |||
651 | return 0; | ||
652 | |||
653 | err_out_free: | ||
654 | netxen_free_hw_resources(adapter); | ||
655 | return err; | ||
656 | } | ||
657 | |||
658 | void netxen_free_hw_resources(struct netxen_adapter *adapter) | ||
659 | { | ||
660 | struct netxen_recv_context *recv_ctx; | ||
661 | struct nx_host_rds_ring *rds_ring; | ||
662 | int ctx, ring; | ||
663 | |||
664 | if (adapter->fw_major >= 4) { | ||
665 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
666 | nx_fw_cmd_destroy_rx_ctx(adapter); | ||
667 | } | ||
668 | |||
669 | if (adapter->ctx_desc != NULL) { | ||
670 | pci_free_consistent(adapter->pdev, | ||
671 | sizeof(struct netxen_ring_ctx) + | ||
672 | sizeof(uint32_t), | ||
673 | adapter->ctx_desc, | ||
674 | adapter->ctx_desc_phys_addr); | ||
675 | adapter->ctx_desc = NULL; | ||
676 | } | ||
677 | |||
678 | if (adapter->ahw.cmd_desc_head != NULL) { | ||
679 | pci_free_consistent(adapter->pdev, | ||
680 | sizeof(struct cmd_desc_type0) * | ||
681 | adapter->max_tx_desc_count, | ||
682 | adapter->ahw.cmd_desc_head, | ||
683 | adapter->ahw.cmd_desc_phys_addr); | ||
684 | adapter->ahw.cmd_desc_head = NULL; | ||
685 | } | ||
686 | |||
687 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
688 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
689 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
690 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
691 | |||
692 | if (rds_ring->desc_head != NULL) { | ||
693 | pci_free_consistent(adapter->pdev, | ||
694 | RCV_DESC_RINGSIZE, | ||
695 | rds_ring->desc_head, | ||
696 | rds_ring->phys_addr); | ||
697 | rds_ring->desc_head = NULL; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | if (recv_ctx->rcv_status_desc_head != NULL) { | ||
702 | pci_free_consistent(adapter->pdev, | ||
703 | STATUS_DESC_RINGSIZE, | ||
704 | recv_ctx->rcv_status_desc_head, | ||
705 | recv_ctx->rcv_status_desc_phys_addr); | ||
706 | recv_ctx->rcv_status_desc_head = NULL; | ||
707 | } | ||
708 | } | ||
709 | } | ||
710 | |||
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 723487bf200c..48ee06b6f4e9 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -93,17 +93,21 @@ static void | |||
93 | netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | 93 | netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) |
94 | { | 94 | { |
95 | struct netxen_adapter *adapter = netdev_priv(dev); | 95 | struct netxen_adapter *adapter = netdev_priv(dev); |
96 | unsigned long flags; | ||
96 | u32 fw_major = 0; | 97 | u32 fw_major = 0; |
97 | u32 fw_minor = 0; | 98 | u32 fw_minor = 0; |
98 | u32 fw_build = 0; | 99 | u32 fw_build = 0; |
99 | 100 | ||
100 | strncpy(drvinfo->driver, netxen_nic_driver_name, 32); | 101 | strncpy(drvinfo->driver, netxen_nic_driver_name, 32); |
101 | strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); | 102 | strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); |
102 | fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, | 103 | write_lock_irqsave(&adapter->adapter_lock, flags); |
103 | NETXEN_FW_VERSION_MAJOR)); | 104 | fw_major = adapter->pci_read_normalize(adapter, |
104 | fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, | 105 | NETXEN_FW_VERSION_MAJOR); |
105 | NETXEN_FW_VERSION_MINOR)); | 106 | fw_minor = adapter->pci_read_normalize(adapter, |
106 | fw_build = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); | 107 | NETXEN_FW_VERSION_MINOR); |
108 | fw_build = adapter->pci_read_normalize(adapter, | ||
109 | NETXEN_FW_VERSION_SUB); | ||
110 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
107 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); | 111 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); |
108 | 112 | ||
109 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 113 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); |
@@ -159,9 +163,16 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
159 | switch ((netxen_brdtype_t) boardinfo->board_type) { | 163 | switch ((netxen_brdtype_t) boardinfo->board_type) { |
160 | case NETXEN_BRDTYPE_P2_SB35_4G: | 164 | case NETXEN_BRDTYPE_P2_SB35_4G: |
161 | case NETXEN_BRDTYPE_P2_SB31_2G: | 165 | case NETXEN_BRDTYPE_P2_SB31_2G: |
166 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
167 | case NETXEN_BRDTYPE_P3_4_GB: | ||
168 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
169 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
170 | |||
162 | ecmd->supported |= SUPPORTED_Autoneg; | 171 | ecmd->supported |= SUPPORTED_Autoneg; |
163 | ecmd->advertising |= ADVERTISED_Autoneg; | 172 | ecmd->advertising |= ADVERTISED_Autoneg; |
164 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | 173 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: |
174 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
175 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
165 | ecmd->supported |= SUPPORTED_TP; | 176 | ecmd->supported |= SUPPORTED_TP; |
166 | ecmd->advertising |= ADVERTISED_TP; | 177 | ecmd->advertising |= ADVERTISED_TP; |
167 | ecmd->port = PORT_TP; | 178 | ecmd->port = PORT_TP; |
@@ -171,12 +182,17 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
171 | break; | 182 | break; |
172 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | 183 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: |
173 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 184 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
185 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
186 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
187 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
174 | ecmd->supported |= SUPPORTED_MII; | 188 | ecmd->supported |= SUPPORTED_MII; |
175 | ecmd->advertising |= ADVERTISED_MII; | 189 | ecmd->advertising |= ADVERTISED_MII; |
176 | ecmd->port = PORT_FIBRE; | 190 | ecmd->port = PORT_FIBRE; |
177 | ecmd->autoneg = AUTONEG_DISABLE; | 191 | ecmd->autoneg = AUTONEG_DISABLE; |
178 | break; | 192 | break; |
179 | case NETXEN_BRDTYPE_P2_SB31_10G: | 193 | case NETXEN_BRDTYPE_P2_SB31_10G: |
194 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
195 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
180 | ecmd->supported |= SUPPORTED_FIBRE; | 196 | ecmd->supported |= SUPPORTED_FIBRE; |
181 | ecmd->advertising |= ADVERTISED_FIBRE; | 197 | ecmd->advertising |= ADVERTISED_FIBRE; |
182 | ecmd->port = PORT_FIBRE; | 198 | ecmd->port = PORT_FIBRE; |
@@ -349,19 +365,18 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | |||
349 | { | 365 | { |
350 | struct netxen_adapter *adapter = netdev_priv(dev); | 366 | struct netxen_adapter *adapter = netdev_priv(dev); |
351 | __u32 mode, *regs_buff = p; | 367 | __u32 mode, *regs_buff = p; |
352 | void __iomem *addr; | ||
353 | int i, window; | 368 | int i, window; |
354 | 369 | ||
355 | memset(p, 0, NETXEN_NIC_REGS_LEN); | 370 | memset(p, 0, NETXEN_NIC_REGS_LEN); |
356 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | | 371 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | |
357 | (adapter->pdev)->device; | 372 | (adapter->pdev)->device; |
358 | /* which mode */ | 373 | /* which mode */ |
359 | NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, ®s_buff[0]); | 374 | adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, ®s_buff[0], 4); |
360 | mode = regs_buff[0]; | 375 | mode = regs_buff[0]; |
361 | 376 | ||
362 | /* Common registers to all the modes */ | 377 | /* Common registers to all the modes */ |
363 | NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, | 378 | adapter->hw_read_wx(adapter, |
364 | ®s_buff[2]); | 379 | NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, ®s_buff[2], 4); |
365 | /* GB/XGB Mode */ | 380 | /* GB/XGB Mode */ |
366 | mode = (mode / 2) - 1; | 381 | mode = (mode / 2) - 1; |
367 | window = 0; | 382 | window = 0; |
@@ -372,9 +387,9 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | |||
372 | window = adapter->physical_port * | 387 | window = adapter->physical_port * |
373 | NETXEN_NIC_PORT_WINDOW; | 388 | NETXEN_NIC_PORT_WINDOW; |
374 | 389 | ||
375 | NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. | 390 | adapter->hw_read_wx(adapter, |
376 | reg[i - 3] + window, | 391 | niu_registers[mode].reg[i - 3] + window, |
377 | ®s_buff[i]); | 392 | ®s_buff[i], 4); |
378 | } | 393 | } |
379 | 394 | ||
380 | } | 395 | } |
@@ -398,7 +413,7 @@ static u32 netxen_nic_test_link(struct net_device *dev) | |||
398 | return !val; | 413 | return !val; |
399 | } | 414 | } |
400 | } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { | 415 | } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { |
401 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | 416 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); |
402 | return (val == XG_LINK_UP) ? 0 : 1; | 417 | return (val == XG_LINK_UP) ? 0 : 1; |
403 | } | 418 | } |
404 | return -EIO; | 419 | return -EIO; |
@@ -427,6 +442,7 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
427 | return 0; | 442 | return 0; |
428 | } | 443 | } |
429 | 444 | ||
445 | #if 0 | ||
430 | static int | 446 | static int |
431 | netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | 447 | netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, |
432 | u8 * bytes) | 448 | u8 * bytes) |
@@ -447,7 +463,6 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
447 | } | 463 | } |
448 | printk(KERN_INFO "%s: flash unlocked. \n", | 464 | printk(KERN_INFO "%s: flash unlocked. \n", |
449 | netxen_nic_driver_name); | 465 | netxen_nic_driver_name); |
450 | last_schedule_time = jiffies; | ||
451 | ret = netxen_flash_erase_secondary(adapter); | 466 | ret = netxen_flash_erase_secondary(adapter); |
452 | if (ret != FLASH_SUCCESS) { | 467 | if (ret != FLASH_SUCCESS) { |
453 | printk(KERN_ERR "%s: Flash erase failed.\n", | 468 | printk(KERN_ERR "%s: Flash erase failed.\n", |
@@ -497,6 +512,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
497 | 512 | ||
498 | return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len); | 513 | return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len); |
499 | } | 514 | } |
515 | #endif /* 0 */ | ||
500 | 516 | ||
501 | static void | 517 | static void |
502 | netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) | 518 | netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) |
@@ -508,9 +524,9 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) | |||
508 | ring->rx_jumbo_pending = 0; | 524 | ring->rx_jumbo_pending = 0; |
509 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 525 | for (i = 0; i < MAX_RCV_CTX; ++i) { |
510 | ring->rx_pending += adapter->recv_ctx[i]. | 526 | ring->rx_pending += adapter->recv_ctx[i]. |
511 | rcv_desc[RCV_DESC_NORMAL_CTXID].max_rx_desc_count; | 527 | rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count; |
512 | ring->rx_jumbo_pending += adapter->recv_ctx[i]. | 528 | ring->rx_jumbo_pending += adapter->recv_ctx[i]. |
513 | rcv_desc[RCV_DESC_JUMBO_CTXID].max_rx_desc_count; | 529 | rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count; |
514 | } | 530 | } |
515 | ring->tx_pending = adapter->max_tx_desc_count; | 531 | ring->tx_pending = adapter->max_tx_desc_count; |
516 | 532 | ||
@@ -655,7 +671,7 @@ static int netxen_nic_reg_test(struct net_device *dev) | |||
655 | data_written = (u32)0xa5a5a5a5; | 671 | data_written = (u32)0xa5a5a5a5; |
656 | 672 | ||
657 | netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); | 673 | netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); |
658 | data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST)); | 674 | data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST); |
659 | if (data_written != data_read) | 675 | if (data_written != data_read) |
660 | return 1; | 676 | return 1; |
661 | 677 | ||
@@ -736,6 +752,117 @@ static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data) | |||
736 | return 0; | 752 | return 0; |
737 | } | 753 | } |
738 | 754 | ||
755 | static u32 netxen_nic_get_tso(struct net_device *dev) | ||
756 | { | ||
757 | struct netxen_adapter *adapter = netdev_priv(dev); | ||
758 | |||
759 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
760 | return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0; | ||
761 | |||
762 | return (dev->features & NETIF_F_TSO) != 0; | ||
763 | } | ||
764 | |||
765 | static int netxen_nic_set_tso(struct net_device *dev, u32 data) | ||
766 | { | ||
767 | if (data) { | ||
768 | struct netxen_adapter *adapter = netdev_priv(dev); | ||
769 | |||
770 | dev->features |= NETIF_F_TSO; | ||
771 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
772 | dev->features |= NETIF_F_TSO6; | ||
773 | } else | ||
774 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
775 | |||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * Set the coalescing parameters. Currently only normal is supported. | ||
781 | * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the | ||
782 | * firmware coalescing to default. | ||
783 | */ | ||
784 | static int netxen_set_intr_coalesce(struct net_device *netdev, | ||
785 | struct ethtool_coalesce *ethcoal) | ||
786 | { | ||
787 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
788 | |||
789 | if (!NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
790 | return -EINVAL; | ||
791 | |||
792 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
793 | return -EINVAL; | ||
794 | |||
795 | /* | ||
796 | * Return Error if unsupported values or | ||
797 | * unsupported parameters are set. | ||
798 | */ | ||
799 | if (ethcoal->rx_coalesce_usecs > 0xffff || | ||
800 | ethcoal->rx_max_coalesced_frames > 0xffff || | ||
801 | ethcoal->tx_coalesce_usecs > 0xffff || | ||
802 | ethcoal->tx_max_coalesced_frames > 0xffff || | ||
803 | ethcoal->rx_coalesce_usecs_irq || | ||
804 | ethcoal->rx_max_coalesced_frames_irq || | ||
805 | ethcoal->tx_coalesce_usecs_irq || | ||
806 | ethcoal->tx_max_coalesced_frames_irq || | ||
807 | ethcoal->stats_block_coalesce_usecs || | ||
808 | ethcoal->use_adaptive_rx_coalesce || | ||
809 | ethcoal->use_adaptive_tx_coalesce || | ||
810 | ethcoal->pkt_rate_low || | ||
811 | ethcoal->rx_coalesce_usecs_low || | ||
812 | ethcoal->rx_max_coalesced_frames_low || | ||
813 | ethcoal->tx_coalesce_usecs_low || | ||
814 | ethcoal->tx_max_coalesced_frames_low || | ||
815 | ethcoal->pkt_rate_high || | ||
816 | ethcoal->rx_coalesce_usecs_high || | ||
817 | ethcoal->rx_max_coalesced_frames_high || | ||
818 | ethcoal->tx_coalesce_usecs_high || | ||
819 | ethcoal->tx_max_coalesced_frames_high) | ||
820 | return -EINVAL; | ||
821 | |||
822 | if (!ethcoal->rx_coalesce_usecs || | ||
823 | !ethcoal->rx_max_coalesced_frames) { | ||
824 | adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT; | ||
825 | adapter->coal.normal.data.rx_time_us = | ||
826 | NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US; | ||
827 | adapter->coal.normal.data.rx_packets = | ||
828 | NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS; | ||
829 | } else { | ||
830 | adapter->coal.flags = 0; | ||
831 | adapter->coal.normal.data.rx_time_us = | ||
832 | ethcoal->rx_coalesce_usecs; | ||
833 | adapter->coal.normal.data.rx_packets = | ||
834 | ethcoal->rx_max_coalesced_frames; | ||
835 | } | ||
836 | adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs; | ||
837 | adapter->coal.normal.data.tx_packets = | ||
838 | ethcoal->tx_max_coalesced_frames; | ||
839 | |||
840 | netxen_config_intr_coalesce(adapter); | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static int netxen_get_intr_coalesce(struct net_device *netdev, | ||
846 | struct ethtool_coalesce *ethcoal) | ||
847 | { | ||
848 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
849 | |||
850 | if (!NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
851 | return -EINVAL; | ||
852 | |||
853 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
854 | return -EINVAL; | ||
855 | |||
856 | ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us; | ||
857 | ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us; | ||
858 | ethcoal->rx_max_coalesced_frames = | ||
859 | adapter->coal.normal.data.rx_packets; | ||
860 | ethcoal->tx_max_coalesced_frames = | ||
861 | adapter->coal.normal.data.tx_packets; | ||
862 | |||
863 | return 0; | ||
864 | } | ||
865 | |||
739 | struct ethtool_ops netxen_nic_ethtool_ops = { | 866 | struct ethtool_ops netxen_nic_ethtool_ops = { |
740 | .get_settings = netxen_nic_get_settings, | 867 | .get_settings = netxen_nic_get_settings, |
741 | .set_settings = netxen_nic_set_settings, | 868 | .set_settings = netxen_nic_set_settings, |
@@ -745,17 +872,22 @@ struct ethtool_ops netxen_nic_ethtool_ops = { | |||
745 | .get_link = ethtool_op_get_link, | 872 | .get_link = ethtool_op_get_link, |
746 | .get_eeprom_len = netxen_nic_get_eeprom_len, | 873 | .get_eeprom_len = netxen_nic_get_eeprom_len, |
747 | .get_eeprom = netxen_nic_get_eeprom, | 874 | .get_eeprom = netxen_nic_get_eeprom, |
875 | #if 0 | ||
748 | .set_eeprom = netxen_nic_set_eeprom, | 876 | .set_eeprom = netxen_nic_set_eeprom, |
877 | #endif | ||
749 | .get_ringparam = netxen_nic_get_ringparam, | 878 | .get_ringparam = netxen_nic_get_ringparam, |
750 | .get_pauseparam = netxen_nic_get_pauseparam, | 879 | .get_pauseparam = netxen_nic_get_pauseparam, |
751 | .set_pauseparam = netxen_nic_set_pauseparam, | 880 | .set_pauseparam = netxen_nic_set_pauseparam, |
752 | .set_tx_csum = ethtool_op_set_tx_csum, | 881 | .set_tx_csum = ethtool_op_set_tx_csum, |
753 | .set_sg = ethtool_op_set_sg, | 882 | .set_sg = ethtool_op_set_sg, |
754 | .set_tso = ethtool_op_set_tso, | 883 | .get_tso = netxen_nic_get_tso, |
884 | .set_tso = netxen_nic_set_tso, | ||
755 | .self_test = netxen_nic_diag_test, | 885 | .self_test = netxen_nic_diag_test, |
756 | .get_strings = netxen_nic_get_strings, | 886 | .get_strings = netxen_nic_get_strings, |
757 | .get_ethtool_stats = netxen_nic_get_ethtool_stats, | 887 | .get_ethtool_stats = netxen_nic_get_ethtool_stats, |
758 | .get_sset_count = netxen_get_sset_count, | 888 | .get_sset_count = netxen_get_sset_count, |
759 | .get_rx_csum = netxen_nic_get_rx_csum, | 889 | .get_rx_csum = netxen_nic_get_rx_csum, |
760 | .set_rx_csum = netxen_nic_set_rx_csum, | 890 | .set_rx_csum = netxen_nic_set_rx_csum, |
891 | .get_coalesce = netxen_get_intr_coalesce, | ||
892 | .set_coalesce = netxen_set_intr_coalesce, | ||
761 | }; | 893 | }; |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 24d027e29c45..3ce13e451aac 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -126,7 +126,8 @@ enum { | |||
126 | NETXEN_HW_PEGR0_CRB_AGT_ADR, | 126 | NETXEN_HW_PEGR0_CRB_AGT_ADR, |
127 | NETXEN_HW_PEGR1_CRB_AGT_ADR, | 127 | NETXEN_HW_PEGR1_CRB_AGT_ADR, |
128 | NETXEN_HW_PEGR2_CRB_AGT_ADR, | 128 | NETXEN_HW_PEGR2_CRB_AGT_ADR, |
129 | NETXEN_HW_PEGR3_CRB_AGT_ADR | 129 | NETXEN_HW_PEGR3_CRB_AGT_ADR, |
130 | NETXEN_HW_PEGN4_CRB_AGT_ADR | ||
130 | }; | 131 | }; |
131 | 132 | ||
132 | /* Hub 5 */ | 133 | /* Hub 5 */ |
@@ -316,6 +317,8 @@ enum { | |||
316 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN2_CRB_AGT_ADR) | 317 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN2_CRB_AGT_ADR) |
317 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGN3 \ | 318 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGN3 \ |
318 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN3_CRB_AGT_ADR) | 319 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN3_CRB_AGT_ADR) |
320 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGN4 \ | ||
321 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN4_CRB_AGT_ADR) | ||
319 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGNC \ | 322 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGNC \ |
320 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGNC_CRB_AGT_ADR) | 323 | ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGNC_CRB_AGT_ADR) |
321 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGR0 \ | 324 | #define NETXEN_HW_CRB_HUB_AGT_ADR_PGR0 \ |
@@ -435,6 +438,7 @@ enum { | |||
435 | #define NETXEN_CRB_ROMUSB \ | 438 | #define NETXEN_CRB_ROMUSB \ |
436 | NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB) | 439 | NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB) |
437 | #define NETXEN_CRB_I2Q NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q) | 440 | #define NETXEN_CRB_I2Q NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q) |
441 | #define NETXEN_CRB_SMB NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SMB) | ||
438 | #define NETXEN_CRB_MAX NETXEN_PCI_CRB_WINDOW(64) | 442 | #define NETXEN_CRB_MAX NETXEN_PCI_CRB_WINDOW(64) |
439 | 443 | ||
440 | #define NETXEN_CRB_PCIX_HOST NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PH) | 444 | #define NETXEN_CRB_PCIX_HOST NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PH) |
@@ -446,6 +450,7 @@ enum { | |||
446 | #define NETXEN_CRB_PEG_NET_D NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND) | 450 | #define NETXEN_CRB_PEG_NET_D NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND) |
447 | #define NETXEN_CRB_PEG_NET_I NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI) | 451 | #define NETXEN_CRB_PEG_NET_I NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI) |
448 | #define NETXEN_CRB_DDR_NET NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN) | 452 | #define NETXEN_CRB_DDR_NET NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN) |
453 | #define NETXEN_CRB_QDR_NET NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SN) | ||
449 | 454 | ||
450 | #define NETXEN_CRB_PCIX_MD NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PS) | 455 | #define NETXEN_CRB_PCIX_MD NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PS) |
451 | #define NETXEN_CRB_PCIE NETXEN_CRB_PCIX_MD | 456 | #define NETXEN_CRB_PCIE NETXEN_CRB_PCIX_MD |
@@ -461,11 +466,20 @@ enum { | |||
461 | #define ISR_INT_TARGET_MASK_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2)) | 466 | #define ISR_INT_TARGET_MASK_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2)) |
462 | #define ISR_INT_TARGET_STATUS_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3)) | 467 | #define ISR_INT_TARGET_STATUS_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3)) |
463 | #define ISR_INT_TARGET_MASK_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3)) | 468 | #define ISR_INT_TARGET_MASK_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3)) |
469 | #define ISR_INT_TARGET_STATUS_F4 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F4)) | ||
470 | #define ISR_INT_TARGET_MASK_F4 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F4)) | ||
471 | #define ISR_INT_TARGET_STATUS_F5 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F5)) | ||
472 | #define ISR_INT_TARGET_MASK_F5 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F5)) | ||
473 | #define ISR_INT_TARGET_STATUS_F6 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F6)) | ||
474 | #define ISR_INT_TARGET_MASK_F6 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F6)) | ||
475 | #define ISR_INT_TARGET_STATUS_F7 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F7)) | ||
476 | #define ISR_INT_TARGET_MASK_F7 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F7)) | ||
464 | 477 | ||
465 | #define NETXEN_PCI_MAPSIZE 128 | 478 | #define NETXEN_PCI_MAPSIZE 128 |
466 | #define NETXEN_PCI_DDR_NET (0x00000000UL) | 479 | #define NETXEN_PCI_DDR_NET (0x00000000UL) |
467 | #define NETXEN_PCI_QDR_NET (0x04000000UL) | 480 | #define NETXEN_PCI_QDR_NET (0x04000000UL) |
468 | #define NETXEN_PCI_DIRECT_CRB (0x04400000UL) | 481 | #define NETXEN_PCI_DIRECT_CRB (0x04400000UL) |
482 | #define NETXEN_PCI_CAMQM (0x04800000UL) | ||
469 | #define NETXEN_PCI_CAMQM_MAX (0x04ffffffUL) | 483 | #define NETXEN_PCI_CAMQM_MAX (0x04ffffffUL) |
470 | #define NETXEN_PCI_OCM0 (0x05000000UL) | 484 | #define NETXEN_PCI_OCM0 (0x05000000UL) |
471 | #define NETXEN_PCI_OCM0_MAX (0x050fffffUL) | 485 | #define NETXEN_PCI_OCM0_MAX (0x050fffffUL) |
@@ -474,6 +488,13 @@ enum { | |||
474 | #define NETXEN_PCI_CRBSPACE (0x06000000UL) | 488 | #define NETXEN_PCI_CRBSPACE (0x06000000UL) |
475 | #define NETXEN_PCI_128MB_SIZE (0x08000000UL) | 489 | #define NETXEN_PCI_128MB_SIZE (0x08000000UL) |
476 | #define NETXEN_PCI_32MB_SIZE (0x02000000UL) | 490 | #define NETXEN_PCI_32MB_SIZE (0x02000000UL) |
491 | #define NETXEN_PCI_2MB_SIZE (0x00200000UL) | ||
492 | |||
493 | #define NETXEN_PCI_MN_2M (0) | ||
494 | #define NETXEN_PCI_MS_2M (0x80000) | ||
495 | #define NETXEN_PCI_OCM0_2M (0x000c0000UL) | ||
496 | #define NETXEN_PCI_CAMQM_2M_BASE (0x000ff800UL) | ||
497 | #define NETXEN_PCI_CAMQM_2M_END (0x04800800UL) | ||
477 | 498 | ||
478 | #define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM) | 499 | #define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM) |
479 | 500 | ||
@@ -484,7 +505,14 @@ enum { | |||
484 | #define NETXEN_ADDR_OCM1 (0x0000000200400000ULL) | 505 | #define NETXEN_ADDR_OCM1 (0x0000000200400000ULL) |
485 | #define NETXEN_ADDR_OCM1_MAX (0x00000002004fffffULL) | 506 | #define NETXEN_ADDR_OCM1_MAX (0x00000002004fffffULL) |
486 | #define NETXEN_ADDR_QDR_NET (0x0000000300000000ULL) | 507 | #define NETXEN_ADDR_QDR_NET (0x0000000300000000ULL) |
487 | #define NETXEN_ADDR_QDR_NET_MAX (0x00000003003fffffULL) | 508 | #define NETXEN_ADDR_QDR_NET_MAX_P2 (0x00000003003fffffULL) |
509 | #define NETXEN_ADDR_QDR_NET_MAX_P3 (0x0000000303ffffffULL) | ||
510 | |||
511 | /* | ||
512 | * Register offsets for MN | ||
513 | */ | ||
514 | #define NETXEN_MIU_CONTROL (0x000) | ||
515 | #define NETXEN_MIU_MN_CONTROL (NETXEN_CRB_DDR_NET+NETXEN_MIU_CONTROL) | ||
488 | 516 | ||
489 | /* 200ms delay in each loop */ | 517 | /* 200ms delay in each loop */ |
490 | #define NETXEN_NIU_PHY_WAITLEN 200000 | 518 | #define NETXEN_NIU_PHY_WAITLEN 200000 |
@@ -550,6 +578,9 @@ enum { | |||
550 | #define NETXEN_MULTICAST_ADDR_HI_2 (NETXEN_CRB_NIU + 0x1018) | 578 | #define NETXEN_MULTICAST_ADDR_HI_2 (NETXEN_CRB_NIU + 0x1018) |
551 | #define NETXEN_MULTICAST_ADDR_HI_3 (NETXEN_CRB_NIU + 0x101c) | 579 | #define NETXEN_MULTICAST_ADDR_HI_3 (NETXEN_CRB_NIU + 0x101c) |
552 | 580 | ||
581 | #define NETXEN_UNICAST_ADDR_BASE (NETXEN_CRB_NIU + 0x1080) | ||
582 | #define NETXEN_MULTICAST_ADDR_BASE (NETXEN_CRB_NIU + 0x1100) | ||
583 | |||
553 | #define NETXEN_NIU_GB_MAC_CONFIG_0(I) \ | 584 | #define NETXEN_NIU_GB_MAC_CONFIG_0(I) \ |
554 | (NETXEN_CRB_NIU + 0x30000 + (I)*0x10000) | 585 | (NETXEN_CRB_NIU + 0x30000 + (I)*0x10000) |
555 | #define NETXEN_NIU_GB_MAC_CONFIG_1(I) \ | 586 | #define NETXEN_NIU_GB_MAC_CONFIG_1(I) \ |
@@ -630,16 +661,76 @@ enum { | |||
630 | #define NETXEN_NIU_XG1_CONTROL_CHAR_CNT (NETXEN_CRB_NIU + 0x80054) | 661 | #define NETXEN_NIU_XG1_CONTROL_CHAR_CNT (NETXEN_CRB_NIU + 0x80054) |
631 | #define NETXEN_NIU_XG1_PAUSE_FRAME_CNT (NETXEN_CRB_NIU + 0x80058) | 662 | #define NETXEN_NIU_XG1_PAUSE_FRAME_CNT (NETXEN_CRB_NIU + 0x80058) |
632 | 663 | ||
664 | /* P3 802.3ap */ | ||
665 | #define NETXEN_NIU_AP_MAC_CONFIG_0(I) (NETXEN_CRB_NIU+0xa0000+(I)*0x10000) | ||
666 | #define NETXEN_NIU_AP_MAC_CONFIG_1(I) (NETXEN_CRB_NIU+0xa0004+(I)*0x10000) | ||
667 | #define NETXEN_NIU_AP_MAC_IPG_IFG(I) (NETXEN_CRB_NIU+0xa0008+(I)*0x10000) | ||
668 | #define NETXEN_NIU_AP_HALF_DUPLEX_CTRL(I) (NETXEN_CRB_NIU+0xa000c+(I)*0x10000) | ||
669 | #define NETXEN_NIU_AP_MAX_FRAME_SIZE(I) (NETXEN_CRB_NIU+0xa0010+(I)*0x10000) | ||
670 | #define NETXEN_NIU_AP_TEST_REG(I) (NETXEN_CRB_NIU+0xa001c+(I)*0x10000) | ||
671 | #define NETXEN_NIU_AP_MII_MGMT_CONFIG(I) (NETXEN_CRB_NIU+0xa0020+(I)*0x10000) | ||
672 | #define NETXEN_NIU_AP_MII_MGMT_COMMAND(I) (NETXEN_CRB_NIU+0xa0024+(I)*0x10000) | ||
673 | #define NETXEN_NIU_AP_MII_MGMT_ADDR(I) (NETXEN_CRB_NIU+0xa0028+(I)*0x10000) | ||
674 | #define NETXEN_NIU_AP_MII_MGMT_CTRL(I) (NETXEN_CRB_NIU+0xa002c+(I)*0x10000) | ||
675 | #define NETXEN_NIU_AP_MII_MGMT_STATUS(I) (NETXEN_CRB_NIU+0xa0030+(I)*0x10000) | ||
676 | #define NETXEN_NIU_AP_MII_MGMT_INDICATE(I) (NETXEN_CRB_NIU+0xa0034+(I)*0x10000) | ||
677 | #define NETXEN_NIU_AP_INTERFACE_CTRL(I) (NETXEN_CRB_NIU+0xa0038+(I)*0x10000) | ||
678 | #define NETXEN_NIU_AP_INTERFACE_STATUS(I) (NETXEN_CRB_NIU+0xa003c+(I)*0x10000) | ||
679 | #define NETXEN_NIU_AP_STATION_ADDR_0(I) (NETXEN_CRB_NIU+0xa0040+(I)*0x10000) | ||
680 | #define NETXEN_NIU_AP_STATION_ADDR_1(I) (NETXEN_CRB_NIU+0xa0044+(I)*0x10000) | ||
681 | |||
682 | /* | ||
683 | * Register offsets for MN | ||
684 | */ | ||
685 | #define MIU_CONTROL (0x000) | ||
686 | #define MIU_TEST_AGT_CTRL (0x090) | ||
687 | #define MIU_TEST_AGT_ADDR_LO (0x094) | ||
688 | #define MIU_TEST_AGT_ADDR_HI (0x098) | ||
689 | #define MIU_TEST_AGT_WRDATA_LO (0x0a0) | ||
690 | #define MIU_TEST_AGT_WRDATA_HI (0x0a4) | ||
691 | #define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i))) | ||
692 | #define MIU_TEST_AGT_RDDATA_LO (0x0a8) | ||
693 | #define MIU_TEST_AGT_RDDATA_HI (0x0ac) | ||
694 | #define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i))) | ||
695 | #define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 | ||
696 | #define MIU_TEST_AGT_UPPER_ADDR(off) (0) | ||
697 | |||
698 | /* MIU_TEST_AGT_CTRL flags. work for SIU as well */ | ||
699 | #define MIU_TA_CTL_START 1 | ||
700 | #define MIU_TA_CTL_ENABLE 2 | ||
701 | #define MIU_TA_CTL_WRITE 4 | ||
702 | #define MIU_TA_CTL_BUSY 8 | ||
703 | |||
704 | #define SIU_TEST_AGT_CTRL (0x060) | ||
705 | #define SIU_TEST_AGT_ADDR_LO (0x064) | ||
706 | #define SIU_TEST_AGT_ADDR_HI (0x078) | ||
707 | #define SIU_TEST_AGT_WRDATA_LO (0x068) | ||
708 | #define SIU_TEST_AGT_WRDATA_HI (0x06c) | ||
709 | #define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i))) | ||
710 | #define SIU_TEST_AGT_RDDATA_LO (0x070) | ||
711 | #define SIU_TEST_AGT_RDDATA_HI (0x074) | ||
712 | #define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i))) | ||
713 | |||
714 | #define SIU_TEST_AGT_ADDR_MASK 0x3ffff8 | ||
715 | #define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22) | ||
716 | |||
633 | /* XG Link status */ | 717 | /* XG Link status */ |
634 | #define XG_LINK_UP 0x10 | 718 | #define XG_LINK_UP 0x10 |
635 | #define XG_LINK_DOWN 0x20 | 719 | #define XG_LINK_DOWN 0x20 |
636 | 720 | ||
721 | #define XG_LINK_UP_P3 0x01 | ||
722 | #define XG_LINK_DOWN_P3 0x02 | ||
723 | #define XG_LINK_STATE_P3_MASK 0xf | ||
724 | #define XG_LINK_STATE_P3(pcifn,val) \ | ||
725 | (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK) | ||
726 | |||
637 | #define NETXEN_CAM_RAM_BASE (NETXEN_CRB_CAM + 0x02000) | 727 | #define NETXEN_CAM_RAM_BASE (NETXEN_CRB_CAM + 0x02000) |
638 | #define NETXEN_CAM_RAM(reg) (NETXEN_CAM_RAM_BASE + (reg)) | 728 | #define NETXEN_CAM_RAM(reg) (NETXEN_CAM_RAM_BASE + (reg)) |
639 | #define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150)) | 729 | #define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150)) |
640 | #define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154)) | 730 | #define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154)) |
641 | #define NETXEN_FW_VERSION_SUB (NETXEN_CAM_RAM(0x158)) | 731 | #define NETXEN_FW_VERSION_SUB (NETXEN_CAM_RAM(0x158)) |
642 | #define NETXEN_ROM_LOCK_ID (NETXEN_CAM_RAM(0x100)) | 732 | #define NETXEN_ROM_LOCK_ID (NETXEN_CAM_RAM(0x100)) |
733 | #define NETXEN_CRB_WIN_LOCK_ID (NETXEN_CAM_RAM(0x124)) | ||
643 | 734 | ||
644 | #define NETXEN_PHY_LOCK_ID (NETXEN_CAM_RAM(0x120)) | 735 | #define NETXEN_PHY_LOCK_ID (NETXEN_CAM_RAM(0x120)) |
645 | 736 | ||
@@ -654,30 +745,71 @@ enum { | |||
654 | #define PCIX_INT_VECTOR (0x10100) | 745 | #define PCIX_INT_VECTOR (0x10100) |
655 | #define PCIX_INT_MASK (0x10104) | 746 | #define PCIX_INT_MASK (0x10104) |
656 | 747 | ||
657 | #define PCIX_MN_WINDOW_F0 (0x10200) | ||
658 | #define PCIX_MN_WINDOW(_f) (PCIX_MN_WINDOW_F0 + (0x20 * (_f))) | ||
659 | #define PCIX_MS_WINDOW (0x10204) | ||
660 | #define PCIX_SN_WINDOW_F0 (0x10208) | ||
661 | #define PCIX_SN_WINDOW(_f) (PCIX_SN_WINDOW_F0 + (0x20 * (_f))) | ||
662 | #define PCIX_CRB_WINDOW (0x10210) | 748 | #define PCIX_CRB_WINDOW (0x10210) |
663 | #define PCIX_CRB_WINDOW_F0 (0x10210) | 749 | #define PCIX_CRB_WINDOW_F0 (0x10210) |
664 | #define PCIX_CRB_WINDOW_F1 (0x10230) | 750 | #define PCIX_CRB_WINDOW_F1 (0x10230) |
665 | #define PCIX_CRB_WINDOW_F2 (0x10250) | 751 | #define PCIX_CRB_WINDOW_F2 (0x10250) |
666 | #define PCIX_CRB_WINDOW_F3 (0x10270) | 752 | #define PCIX_CRB_WINDOW_F3 (0x10270) |
753 | #define PCIX_CRB_WINDOW_F4 (0x102ac) | ||
754 | #define PCIX_CRB_WINDOW_F5 (0x102bc) | ||
755 | #define PCIX_CRB_WINDOW_F6 (0x102cc) | ||
756 | #define PCIX_CRB_WINDOW_F7 (0x102dc) | ||
757 | #define PCIE_CRB_WINDOW_REG(func) (((func) < 4) ? \ | ||
758 | (PCIX_CRB_WINDOW_F0 + (0x20 * (func))) :\ | ||
759 | (PCIX_CRB_WINDOW_F4 + (0x10 * ((func)-4)))) | ||
760 | |||
761 | #define PCIX_MN_WINDOW (0x10200) | ||
762 | #define PCIX_MN_WINDOW_F0 (0x10200) | ||
763 | #define PCIX_MN_WINDOW_F1 (0x10220) | ||
764 | #define PCIX_MN_WINDOW_F2 (0x10240) | ||
765 | #define PCIX_MN_WINDOW_F3 (0x10260) | ||
766 | #define PCIX_MN_WINDOW_F4 (0x102a0) | ||
767 | #define PCIX_MN_WINDOW_F5 (0x102b0) | ||
768 | #define PCIX_MN_WINDOW_F6 (0x102c0) | ||
769 | #define PCIX_MN_WINDOW_F7 (0x102d0) | ||
770 | #define PCIE_MN_WINDOW_REG(func) (((func) < 4) ? \ | ||
771 | (PCIX_MN_WINDOW_F0 + (0x20 * (func))) :\ | ||
772 | (PCIX_MN_WINDOW_F4 + (0x10 * ((func)-4)))) | ||
773 | |||
774 | #define PCIX_SN_WINDOW (0x10208) | ||
775 | #define PCIX_SN_WINDOW_F0 (0x10208) | ||
776 | #define PCIX_SN_WINDOW_F1 (0x10228) | ||
777 | #define PCIX_SN_WINDOW_F2 (0x10248) | ||
778 | #define PCIX_SN_WINDOW_F3 (0x10268) | ||
779 | #define PCIX_SN_WINDOW_F4 (0x102a8) | ||
780 | #define PCIX_SN_WINDOW_F5 (0x102b8) | ||
781 | #define PCIX_SN_WINDOW_F6 (0x102c8) | ||
782 | #define PCIX_SN_WINDOW_F7 (0x102d8) | ||
783 | #define PCIE_SN_WINDOW_REG(func) (((func) < 4) ? \ | ||
784 | (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\ | ||
785 | (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4)))) | ||
667 | 786 | ||
668 | #define PCIX_TARGET_STATUS (0x10118) | 787 | #define PCIX_TARGET_STATUS (0x10118) |
788 | #define PCIX_TARGET_STATUS_F1 (0x10160) | ||
789 | #define PCIX_TARGET_STATUS_F2 (0x10164) | ||
790 | #define PCIX_TARGET_STATUS_F3 (0x10168) | ||
791 | #define PCIX_TARGET_STATUS_F4 (0x10360) | ||
792 | #define PCIX_TARGET_STATUS_F5 (0x10364) | ||
793 | #define PCIX_TARGET_STATUS_F6 (0x10368) | ||
794 | #define PCIX_TARGET_STATUS_F7 (0x1036c) | ||
795 | |||
669 | #define PCIX_TARGET_MASK (0x10128) | 796 | #define PCIX_TARGET_MASK (0x10128) |
670 | #define PCIX_TARGET_STATUS_F1 (0x10160) | 797 | #define PCIX_TARGET_MASK_F1 (0x10170) |
671 | #define PCIX_TARGET_MASK_F1 (0x10170) | 798 | #define PCIX_TARGET_MASK_F2 (0x10174) |
672 | #define PCIX_TARGET_STATUS_F2 (0x10164) | 799 | #define PCIX_TARGET_MASK_F3 (0x10178) |
673 | #define PCIX_TARGET_MASK_F2 (0x10174) | 800 | #define PCIX_TARGET_MASK_F4 (0x10370) |
674 | #define PCIX_TARGET_STATUS_F3 (0x10168) | 801 | #define PCIX_TARGET_MASK_F5 (0x10374) |
675 | #define PCIX_TARGET_MASK_F3 (0x10178) | 802 | #define PCIX_TARGET_MASK_F6 (0x10378) |
803 | #define PCIX_TARGET_MASK_F7 (0x1037c) | ||
676 | 804 | ||
677 | #define PCIX_MSI_F0 (0x13000) | 805 | #define PCIX_MSI_F0 (0x13000) |
678 | #define PCIX_MSI_F1 (0x13004) | 806 | #define PCIX_MSI_F1 (0x13004) |
679 | #define PCIX_MSI_F2 (0x13008) | 807 | #define PCIX_MSI_F2 (0x13008) |
680 | #define PCIX_MSI_F3 (0x1300c) | 808 | #define PCIX_MSI_F3 (0x1300c) |
809 | #define PCIX_MSI_F4 (0x13010) | ||
810 | #define PCIX_MSI_F5 (0x13014) | ||
811 | #define PCIX_MSI_F6 (0x13018) | ||
812 | #define PCIX_MSI_F7 (0x1301c) | ||
681 | #define PCIX_MSI_F(i) (0x13000+((i)*4)) | 813 | #define PCIX_MSI_F(i) (0x13000+((i)*4)) |
682 | 814 | ||
683 | #define PCIX_PS_MEM_SPACE (0x90000) | 815 | #define PCIX_PS_MEM_SPACE (0x90000) |
@@ -695,11 +827,102 @@ enum { | |||
695 | #define PCIE_SEM2_UNLOCK (0x1c014) /* Flash unlock */ | 827 | #define PCIE_SEM2_UNLOCK (0x1c014) /* Flash unlock */ |
696 | #define PCIE_SEM3_LOCK (0x1c018) /* Phy lock */ | 828 | #define PCIE_SEM3_LOCK (0x1c018) /* Phy lock */ |
697 | #define PCIE_SEM3_UNLOCK (0x1c01c) /* Phy unlock */ | 829 | #define PCIE_SEM3_UNLOCK (0x1c01c) /* Phy unlock */ |
698 | 830 | #define PCIE_SEM5_LOCK (0x1c028) /* API lock */ | |
831 | #define PCIE_SEM5_UNLOCK (0x1c02c) /* API unlock */ | ||
832 | #define PCIE_SEM6_LOCK (0x1c030) /* sw lock */ | ||
833 | #define PCIE_SEM6_UNLOCK (0x1c034) /* sw unlock */ | ||
834 | #define PCIE_SEM7_LOCK (0x1c038) /* crb win lock */ | ||
835 | #define PCIE_SEM7_UNLOCK (0x1c03c) /* crbwin unlock*/ | ||
836 | |||
837 | #define PCIE_SETUP_FUNCTION (0x12040) | ||
838 | #define PCIE_SETUP_FUNCTION2 (0x12048) | ||
699 | #define PCIE_TGT_SPLIT_CHICKEN (0x12080) | 839 | #define PCIE_TGT_SPLIT_CHICKEN (0x12080) |
840 | #define PCIE_CHICKEN3 (0x120c8) | ||
700 | 841 | ||
701 | #define PCIE_MAX_MASTER_SPLIT (0x14048) | 842 | #define PCIE_MAX_MASTER_SPLIT (0x14048) |
702 | 843 | ||
844 | #define NETXEN_PORT_MODE_NONE 0 | ||
845 | #define NETXEN_PORT_MODE_XG 1 | ||
846 | #define NETXEN_PORT_MODE_GB 2 | ||
847 | #define NETXEN_PORT_MODE_802_3_AP 3 | ||
848 | #define NETXEN_PORT_MODE_AUTO_NEG 4 | ||
849 | #define NETXEN_PORT_MODE_AUTO_NEG_1G 5 | ||
850 | #define NETXEN_PORT_MODE_AUTO_NEG_XG 6 | ||
851 | #define NETXEN_PORT_MODE_ADDR (NETXEN_CAM_RAM(0x24)) | ||
852 | #define NETXEN_WOL_PORT_MODE (NETXEN_CAM_RAM(0x198)) | ||
853 | |||
703 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) | 854 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) |
704 | 855 | ||
856 | #define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) | ||
857 | |||
858 | /* | ||
859 | * PCI Interrupt Vector Values. | ||
860 | */ | ||
861 | #define PCIX_INT_VECTOR_BIT_F0 0x0080 | ||
862 | #define PCIX_INT_VECTOR_BIT_F1 0x0100 | ||
863 | #define PCIX_INT_VECTOR_BIT_F2 0x0200 | ||
864 | #define PCIX_INT_VECTOR_BIT_F3 0x0400 | ||
865 | #define PCIX_INT_VECTOR_BIT_F4 0x0800 | ||
866 | #define PCIX_INT_VECTOR_BIT_F5 0x1000 | ||
867 | #define PCIX_INT_VECTOR_BIT_F6 0x2000 | ||
868 | #define PCIX_INT_VECTOR_BIT_F7 0x4000 | ||
869 | |||
870 | struct netxen_legacy_intr_set { | ||
871 | uint32_t int_vec_bit; | ||
872 | uint32_t tgt_status_reg; | ||
873 | uint32_t tgt_mask_reg; | ||
874 | uint32_t pci_int_reg; | ||
875 | }; | ||
876 | |||
877 | #define NX_LEGACY_INTR_CONFIG \ | ||
878 | { \ | ||
879 | { \ | ||
880 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F0, \ | ||
881 | .tgt_status_reg = ISR_INT_TARGET_STATUS, \ | ||
882 | .tgt_mask_reg = ISR_INT_TARGET_MASK, \ | ||
883 | .pci_int_reg = ISR_MSI_INT_TRIGGER(0) }, \ | ||
884 | \ | ||
885 | { \ | ||
886 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F1, \ | ||
887 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F1, \ | ||
888 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F1, \ | ||
889 | .pci_int_reg = ISR_MSI_INT_TRIGGER(1) }, \ | ||
890 | \ | ||
891 | { \ | ||
892 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F2, \ | ||
893 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F2, \ | ||
894 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F2, \ | ||
895 | .pci_int_reg = ISR_MSI_INT_TRIGGER(2) }, \ | ||
896 | \ | ||
897 | { \ | ||
898 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F3, \ | ||
899 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F3, \ | ||
900 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F3, \ | ||
901 | .pci_int_reg = ISR_MSI_INT_TRIGGER(3) }, \ | ||
902 | \ | ||
903 | { \ | ||
904 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F4, \ | ||
905 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F4, \ | ||
906 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F4, \ | ||
907 | .pci_int_reg = ISR_MSI_INT_TRIGGER(4) }, \ | ||
908 | \ | ||
909 | { \ | ||
910 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F5, \ | ||
911 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F5, \ | ||
912 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F5, \ | ||
913 | .pci_int_reg = ISR_MSI_INT_TRIGGER(5) }, \ | ||
914 | \ | ||
915 | { \ | ||
916 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F6, \ | ||
917 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F6, \ | ||
918 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F6, \ | ||
919 | .pci_int_reg = ISR_MSI_INT_TRIGGER(6) }, \ | ||
920 | \ | ||
921 | { \ | ||
922 | .int_vec_bit = PCIX_INT_VECTOR_BIT_F7, \ | ||
923 | .tgt_status_reg = ISR_INT_TARGET_STATUS_F7, \ | ||
924 | .tgt_mask_reg = ISR_INT_TARGET_MASK_F7, \ | ||
925 | .pci_int_reg = ISR_MSI_INT_TRIGGER(7) }, \ | ||
926 | } | ||
927 | |||
705 | #endif /* __NETXEN_NIC_HDR_H_ */ | 928 | #endif /* __NETXEN_NIC_HDR_H_ */ |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c43d06b8de9b..96a3bc6426e2 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -38,242 +38,262 @@ | |||
38 | 38 | ||
39 | #include <net/ip.h> | 39 | #include <net/ip.h> |
40 | 40 | ||
41 | struct netxen_recv_crb recv_crb_registers[] = { | 41 | #define MASK(n) ((1ULL<<(n))-1) |
42 | /* | 42 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) |
43 | * Instance 0. | 43 | #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) |
44 | */ | 44 | #define MS_WIN(addr) (addr & 0x0ffc0000) |
45 | { | 45 | |
46 | /* rcv_desc_crb: */ | 46 | #define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) |
47 | { | 47 | |
48 | { | 48 | #define CRB_BLK(off) ((off >> 20) & 0x3f) |
49 | /* crb_rcv_producer_offset: */ | 49 | #define CRB_SUBBLK(off) ((off >> 16) & 0xf) |
50 | NETXEN_NIC_REG(0x100), | 50 | #define CRB_WINDOW_2M (0x130060) |
51 | /* crb_rcv_consumer_offset: */ | 51 | #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) |
52 | NETXEN_NIC_REG(0x104), | 52 | #define CRB_INDIRECT_2M (0x1e0000UL) |
53 | /* crb_gloablrcv_ring: */ | 53 | |
54 | NETXEN_NIC_REG(0x108), | 54 | #define CRB_WIN_LOCK_TIMEOUT 100000000 |
55 | /* crb_rcv_ring_size */ | 55 | static crb_128M_2M_block_map_t crb_128M_2M_map[64] = { |
56 | NETXEN_NIC_REG(0x10c), | 56 | {{{0, 0, 0, 0} } }, /* 0: PCI */ |
57 | 57 | {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ | |
58 | }, | 58 | {1, 0x0110000, 0x0120000, 0x130000}, |
59 | /* Jumbo frames */ | 59 | {1, 0x0120000, 0x0122000, 0x124000}, |
60 | { | 60 | {1, 0x0130000, 0x0132000, 0x126000}, |
61 | /* crb_rcv_producer_offset: */ | 61 | {1, 0x0140000, 0x0142000, 0x128000}, |
62 | NETXEN_NIC_REG(0x110), | 62 | {1, 0x0150000, 0x0152000, 0x12a000}, |
63 | /* crb_rcv_consumer_offset: */ | 63 | {1, 0x0160000, 0x0170000, 0x110000}, |
64 | NETXEN_NIC_REG(0x114), | 64 | {1, 0x0170000, 0x0172000, 0x12e000}, |
65 | /* crb_gloablrcv_ring: */ | 65 | {0, 0x0000000, 0x0000000, 0x000000}, |
66 | NETXEN_NIC_REG(0x118), | 66 | {0, 0x0000000, 0x0000000, 0x000000}, |
67 | /* crb_rcv_ring_size */ | 67 | {0, 0x0000000, 0x0000000, 0x000000}, |
68 | NETXEN_NIC_REG(0x11c), | 68 | {0, 0x0000000, 0x0000000, 0x000000}, |
69 | }, | 69 | {0, 0x0000000, 0x0000000, 0x000000}, |
70 | /* LRO */ | 70 | {0, 0x0000000, 0x0000000, 0x000000}, |
71 | { | 71 | {1, 0x01e0000, 0x01e0800, 0x122000}, |
72 | /* crb_rcv_producer_offset: */ | 72 | {0, 0x0000000, 0x0000000, 0x000000} } }, |
73 | NETXEN_NIC_REG(0x120), | 73 | {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */ |
74 | /* crb_rcv_consumer_offset: */ | 74 | {{{0, 0, 0, 0} } }, /* 3: */ |
75 | NETXEN_NIC_REG(0x124), | 75 | {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */ |
76 | /* crb_gloablrcv_ring: */ | 76 | {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE */ |
77 | NETXEN_NIC_REG(0x128), | 77 | {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU */ |
78 | /* crb_rcv_ring_size */ | 78 | {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM */ |
79 | NETXEN_NIC_REG(0x12c), | 79 | {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */ |
80 | } | 80 | {0, 0x0000000, 0x0000000, 0x000000}, |
81 | }, | 81 | {0, 0x0000000, 0x0000000, 0x000000}, |
82 | /* crb_rcvstatus_ring: */ | 82 | {0, 0x0000000, 0x0000000, 0x000000}, |
83 | NETXEN_NIC_REG(0x130), | 83 | {0, 0x0000000, 0x0000000, 0x000000}, |
84 | /* crb_rcv_status_producer: */ | 84 | {0, 0x0000000, 0x0000000, 0x000000}, |
85 | NETXEN_NIC_REG(0x134), | 85 | {0, 0x0000000, 0x0000000, 0x000000}, |
86 | /* crb_rcv_status_consumer: */ | 86 | {0, 0x0000000, 0x0000000, 0x000000}, |
87 | NETXEN_NIC_REG(0x138), | 87 | {0, 0x0000000, 0x0000000, 0x000000}, |
88 | /* crb_rcvpeg_state: */ | 88 | {0, 0x0000000, 0x0000000, 0x000000}, |
89 | NETXEN_NIC_REG(0x13c), | 89 | {0, 0x0000000, 0x0000000, 0x000000}, |
90 | /* crb_status_ring_size */ | 90 | {0, 0x0000000, 0x0000000, 0x000000}, |
91 | NETXEN_NIC_REG(0x140), | 91 | {0, 0x0000000, 0x0000000, 0x000000}, |
92 | 92 | {0, 0x0000000, 0x0000000, 0x000000}, | |
93 | }, | 93 | {0, 0x0000000, 0x0000000, 0x000000}, |
94 | /* | 94 | {1, 0x08f0000, 0x08f2000, 0x172000} } }, |
95 | * Instance 1, | 95 | {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1*/ |
96 | */ | 96 | {0, 0x0000000, 0x0000000, 0x000000}, |
97 | { | 97 | {0, 0x0000000, 0x0000000, 0x000000}, |
98 | /* rcv_desc_crb: */ | 98 | {0, 0x0000000, 0x0000000, 0x000000}, |
99 | { | 99 | {0, 0x0000000, 0x0000000, 0x000000}, |
100 | { | 100 | {0, 0x0000000, 0x0000000, 0x000000}, |
101 | /* crb_rcv_producer_offset: */ | 101 | {0, 0x0000000, 0x0000000, 0x000000}, |
102 | NETXEN_NIC_REG(0x144), | 102 | {0, 0x0000000, 0x0000000, 0x000000}, |
103 | /* crb_rcv_consumer_offset: */ | 103 | {0, 0x0000000, 0x0000000, 0x000000}, |
104 | NETXEN_NIC_REG(0x148), | 104 | {0, 0x0000000, 0x0000000, 0x000000}, |
105 | /* crb_globalrcv_ring: */ | 105 | {0, 0x0000000, 0x0000000, 0x000000}, |
106 | NETXEN_NIC_REG(0x14c), | 106 | {0, 0x0000000, 0x0000000, 0x000000}, |
107 | /* crb_rcv_ring_size */ | 107 | {0, 0x0000000, 0x0000000, 0x000000}, |
108 | NETXEN_NIC_REG(0x150), | 108 | {0, 0x0000000, 0x0000000, 0x000000}, |
109 | 109 | {0, 0x0000000, 0x0000000, 0x000000}, | |
110 | }, | 110 | {1, 0x09f0000, 0x09f2000, 0x176000} } }, |
111 | /* Jumbo frames */ | 111 | {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2*/ |
112 | { | 112 | {0, 0x0000000, 0x0000000, 0x000000}, |
113 | /* crb_rcv_producer_offset: */ | 113 | {0, 0x0000000, 0x0000000, 0x000000}, |
114 | NETXEN_NIC_REG(0x154), | 114 | {0, 0x0000000, 0x0000000, 0x000000}, |
115 | /* crb_rcv_consumer_offset: */ | 115 | {0, 0x0000000, 0x0000000, 0x000000}, |
116 | NETXEN_NIC_REG(0x158), | 116 | {0, 0x0000000, 0x0000000, 0x000000}, |
117 | /* crb_globalrcv_ring: */ | 117 | {0, 0x0000000, 0x0000000, 0x000000}, |
118 | NETXEN_NIC_REG(0x15c), | 118 | {0, 0x0000000, 0x0000000, 0x000000}, |
119 | /* crb_rcv_ring_size */ | 119 | {0, 0x0000000, 0x0000000, 0x000000}, |
120 | NETXEN_NIC_REG(0x160), | 120 | {0, 0x0000000, 0x0000000, 0x000000}, |
121 | }, | 121 | {0, 0x0000000, 0x0000000, 0x000000}, |
122 | /* LRO */ | 122 | {0, 0x0000000, 0x0000000, 0x000000}, |
123 | { | 123 | {0, 0x0000000, 0x0000000, 0x000000}, |
124 | /* crb_rcv_producer_offset: */ | 124 | {0, 0x0000000, 0x0000000, 0x000000}, |
125 | NETXEN_NIC_REG(0x164), | 125 | {0, 0x0000000, 0x0000000, 0x000000}, |
126 | /* crb_rcv_consumer_offset: */ | 126 | {1, 0x0af0000, 0x0af2000, 0x17a000} } }, |
127 | NETXEN_NIC_REG(0x168), | 127 | {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3*/ |
128 | /* crb_globalrcv_ring: */ | 128 | {0, 0x0000000, 0x0000000, 0x000000}, |
129 | NETXEN_NIC_REG(0x16c), | 129 | {0, 0x0000000, 0x0000000, 0x000000}, |
130 | /* crb_rcv_ring_size */ | 130 | {0, 0x0000000, 0x0000000, 0x000000}, |
131 | NETXEN_NIC_REG(0x170), | 131 | {0, 0x0000000, 0x0000000, 0x000000}, |
132 | } | 132 | {0, 0x0000000, 0x0000000, 0x000000}, |
133 | 133 | {0, 0x0000000, 0x0000000, 0x000000}, | |
134 | }, | 134 | {0, 0x0000000, 0x0000000, 0x000000}, |
135 | /* crb_rcvstatus_ring: */ | 135 | {0, 0x0000000, 0x0000000, 0x000000}, |
136 | NETXEN_NIC_REG(0x174), | 136 | {0, 0x0000000, 0x0000000, 0x000000}, |
137 | /* crb_rcv_status_producer: */ | 137 | {0, 0x0000000, 0x0000000, 0x000000}, |
138 | NETXEN_NIC_REG(0x178), | 138 | {0, 0x0000000, 0x0000000, 0x000000}, |
139 | /* crb_rcv_status_consumer: */ | 139 | {0, 0x0000000, 0x0000000, 0x000000}, |
140 | NETXEN_NIC_REG(0x17c), | 140 | {0, 0x0000000, 0x0000000, 0x000000}, |
141 | /* crb_rcvpeg_state: */ | 141 | {0, 0x0000000, 0x0000000, 0x000000}, |
142 | NETXEN_NIC_REG(0x180), | 142 | {1, 0x0bf0000, 0x0bf2000, 0x17e000} } }, |
143 | /* crb_status_ring_size */ | 143 | {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */ |
144 | NETXEN_NIC_REG(0x184), | 144 | {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */ |
145 | }, | 145 | {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */ |
146 | /* | 146 | {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */ |
147 | * Instance 2, | 147 | {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */ |
148 | */ | 148 | {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */ |
149 | { | 149 | {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */ |
150 | { | 150 | {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */ |
151 | { | 151 | {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */ |
152 | /* crb_rcv_producer_offset: */ | 152 | {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */ |
153 | NETXEN_NIC_REG(0x1d8), | 153 | {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */ |
154 | /* crb_rcv_consumer_offset: */ | 154 | {{{0, 0, 0, 0} } }, /* 23: */ |
155 | NETXEN_NIC_REG(0x1dc), | 155 | {{{0, 0, 0, 0} } }, /* 24: */ |
156 | /* crb_gloablrcv_ring: */ | 156 | {{{0, 0, 0, 0} } }, /* 25: */ |
157 | NETXEN_NIC_REG(0x1f0), | 157 | {{{0, 0, 0, 0} } }, /* 26: */ |
158 | /* crb_rcv_ring_size */ | 158 | {{{0, 0, 0, 0} } }, /* 27: */ |
159 | NETXEN_NIC_REG(0x1f4), | 159 | {{{0, 0, 0, 0} } }, /* 28: */ |
160 | }, | 160 | {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */ |
161 | /* Jumbo frames */ | 161 | {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */ |
162 | { | 162 | {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */ |
163 | /* crb_rcv_producer_offset: */ | 163 | {{{0} } }, /* 32: PCI */ |
164 | NETXEN_NIC_REG(0x1f8), | 164 | {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */ |
165 | /* crb_rcv_consumer_offset: */ | 165 | {1, 0x2110000, 0x2120000, 0x130000}, |
166 | NETXEN_NIC_REG(0x1fc), | 166 | {1, 0x2120000, 0x2122000, 0x124000}, |
167 | /* crb_gloablrcv_ring: */ | 167 | {1, 0x2130000, 0x2132000, 0x126000}, |
168 | NETXEN_NIC_REG(0x200), | 168 | {1, 0x2140000, 0x2142000, 0x128000}, |
169 | /* crb_rcv_ring_size */ | 169 | {1, 0x2150000, 0x2152000, 0x12a000}, |
170 | NETXEN_NIC_REG(0x204), | 170 | {1, 0x2160000, 0x2170000, 0x110000}, |
171 | }, | 171 | {1, 0x2170000, 0x2172000, 0x12e000}, |
172 | /* LRO */ | 172 | {0, 0x0000000, 0x0000000, 0x000000}, |
173 | { | 173 | {0, 0x0000000, 0x0000000, 0x000000}, |
174 | /* crb_rcv_producer_offset: */ | 174 | {0, 0x0000000, 0x0000000, 0x000000}, |
175 | NETXEN_NIC_REG(0x208), | 175 | {0, 0x0000000, 0x0000000, 0x000000}, |
176 | /* crb_rcv_consumer_offset: */ | 176 | {0, 0x0000000, 0x0000000, 0x000000}, |
177 | NETXEN_NIC_REG(0x20c), | 177 | {0, 0x0000000, 0x0000000, 0x000000}, |
178 | /* crb_gloablrcv_ring: */ | 178 | {0, 0x0000000, 0x0000000, 0x000000}, |
179 | NETXEN_NIC_REG(0x210), | 179 | {0, 0x0000000, 0x0000000, 0x000000} } }, |
180 | /* crb_rcv_ring_size */ | 180 | {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */ |
181 | NETXEN_NIC_REG(0x214), | 181 | {{{0} } }, /* 35: */ |
182 | } | 182 | {{{0} } }, /* 36: */ |
183 | }, | 183 | {{{0} } }, /* 37: */ |
184 | /* crb_rcvstatus_ring: */ | 184 | {{{0} } }, /* 38: */ |
185 | NETXEN_NIC_REG(0x218), | 185 | {{{0} } }, /* 39: */ |
186 | /* crb_rcv_status_producer: */ | 186 | {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */ |
187 | NETXEN_NIC_REG(0x21c), | 187 | {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */ |
188 | /* crb_rcv_status_consumer: */ | 188 | {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */ |
189 | NETXEN_NIC_REG(0x220), | 189 | {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */ |
190 | /* crb_rcvpeg_state: */ | 190 | {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */ |
191 | NETXEN_NIC_REG(0x224), | 191 | {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */ |
192 | /* crb_status_ring_size */ | 192 | {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */ |
193 | NETXEN_NIC_REG(0x228), | 193 | {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */ |
194 | }, | 194 | {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */ |
195 | /* | 195 | {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */ |
196 | * Instance 3, | 196 | {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */ |
197 | */ | 197 | {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */ |
198 | { | 198 | {{{0} } }, /* 52: */ |
199 | { | 199 | {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */ |
200 | { | 200 | {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */ |
201 | /* crb_rcv_producer_offset: */ | 201 | {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */ |
202 | NETXEN_NIC_REG(0x22c), | 202 | {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */ |
203 | /* crb_rcv_consumer_offset: */ | 203 | {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */ |
204 | NETXEN_NIC_REG(0x230), | 204 | {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */ |
205 | /* crb_gloablrcv_ring: */ | 205 | {{{0} } }, /* 59: I2C0 */ |
206 | NETXEN_NIC_REG(0x234), | 206 | {{{0} } }, /* 60: I2C1 */ |
207 | /* crb_rcv_ring_size */ | 207 | {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */ |
208 | NETXEN_NIC_REG(0x238), | 208 | {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */ |
209 | }, | 209 | {{{1, 0x3f00000, 0x3f01000, 0x168000} } } /* 63: P2NR0 */ |
210 | /* Jumbo frames */ | ||
211 | { | ||
212 | /* crb_rcv_producer_offset: */ | ||
213 | NETXEN_NIC_REG(0x23c), | ||
214 | /* crb_rcv_consumer_offset: */ | ||
215 | NETXEN_NIC_REG(0x240), | ||
216 | /* crb_gloablrcv_ring: */ | ||
217 | NETXEN_NIC_REG(0x244), | ||
218 | /* crb_rcv_ring_size */ | ||
219 | NETXEN_NIC_REG(0x248), | ||
220 | }, | ||
221 | /* LRO */ | ||
222 | { | ||
223 | /* crb_rcv_producer_offset: */ | ||
224 | NETXEN_NIC_REG(0x24c), | ||
225 | /* crb_rcv_consumer_offset: */ | ||
226 | NETXEN_NIC_REG(0x250), | ||
227 | /* crb_gloablrcv_ring: */ | ||
228 | NETXEN_NIC_REG(0x254), | ||
229 | /* crb_rcv_ring_size */ | ||
230 | NETXEN_NIC_REG(0x258), | ||
231 | } | ||
232 | }, | ||
233 | /* crb_rcvstatus_ring: */ | ||
234 | NETXEN_NIC_REG(0x25c), | ||
235 | /* crb_rcv_status_producer: */ | ||
236 | NETXEN_NIC_REG(0x260), | ||
237 | /* crb_rcv_status_consumer: */ | ||
238 | NETXEN_NIC_REG(0x264), | ||
239 | /* crb_rcvpeg_state: */ | ||
240 | NETXEN_NIC_REG(0x268), | ||
241 | /* crb_status_ring_size */ | ||
242 | NETXEN_NIC_REG(0x26c), | ||
243 | }, | ||
244 | }; | 210 | }; |
245 | 211 | ||
246 | static u64 ctx_addr_sig_regs[][3] = { | 212 | /* |
247 | {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, | 213 | * top 12 bits of crb internal address (hub, agent) |
248 | {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, | 214 | */ |
249 | {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, | 215 | static unsigned crb_hub_agt[64] = |
250 | {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} | 216 | { |
217 | 0, | ||
218 | NETXEN_HW_CRB_HUB_AGT_ADR_PS, | ||
219 | NETXEN_HW_CRB_HUB_AGT_ADR_MN, | ||
220 | NETXEN_HW_CRB_HUB_AGT_ADR_MS, | ||
221 | 0, | ||
222 | NETXEN_HW_CRB_HUB_AGT_ADR_SRE, | ||
223 | NETXEN_HW_CRB_HUB_AGT_ADR_NIU, | ||
224 | NETXEN_HW_CRB_HUB_AGT_ADR_QMN, | ||
225 | NETXEN_HW_CRB_HUB_AGT_ADR_SQN0, | ||
226 | NETXEN_HW_CRB_HUB_AGT_ADR_SQN1, | ||
227 | NETXEN_HW_CRB_HUB_AGT_ADR_SQN2, | ||
228 | NETXEN_HW_CRB_HUB_AGT_ADR_SQN3, | ||
229 | NETXEN_HW_CRB_HUB_AGT_ADR_I2Q, | ||
230 | NETXEN_HW_CRB_HUB_AGT_ADR_TIMR, | ||
231 | NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB, | ||
232 | NETXEN_HW_CRB_HUB_AGT_ADR_PGN4, | ||
233 | NETXEN_HW_CRB_HUB_AGT_ADR_XDMA, | ||
234 | NETXEN_HW_CRB_HUB_AGT_ADR_PGN0, | ||
235 | NETXEN_HW_CRB_HUB_AGT_ADR_PGN1, | ||
236 | NETXEN_HW_CRB_HUB_AGT_ADR_PGN2, | ||
237 | NETXEN_HW_CRB_HUB_AGT_ADR_PGN3, | ||
238 | NETXEN_HW_CRB_HUB_AGT_ADR_PGND, | ||
239 | NETXEN_HW_CRB_HUB_AGT_ADR_PGNI, | ||
240 | NETXEN_HW_CRB_HUB_AGT_ADR_PGS0, | ||
241 | NETXEN_HW_CRB_HUB_AGT_ADR_PGS1, | ||
242 | NETXEN_HW_CRB_HUB_AGT_ADR_PGS2, | ||
243 | NETXEN_HW_CRB_HUB_AGT_ADR_PGS3, | ||
244 | 0, | ||
245 | NETXEN_HW_CRB_HUB_AGT_ADR_PGSI, | ||
246 | NETXEN_HW_CRB_HUB_AGT_ADR_SN, | ||
247 | 0, | ||
248 | NETXEN_HW_CRB_HUB_AGT_ADR_EG, | ||
249 | 0, | ||
250 | NETXEN_HW_CRB_HUB_AGT_ADR_PS, | ||
251 | NETXEN_HW_CRB_HUB_AGT_ADR_CAM, | ||
252 | 0, | ||
253 | 0, | ||
254 | 0, | ||
255 | 0, | ||
256 | 0, | ||
257 | NETXEN_HW_CRB_HUB_AGT_ADR_TIMR, | ||
258 | 0, | ||
259 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1, | ||
260 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2, | ||
261 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3, | ||
262 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4, | ||
263 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5, | ||
264 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6, | ||
265 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7, | ||
266 | NETXEN_HW_CRB_HUB_AGT_ADR_XDMA, | ||
267 | NETXEN_HW_CRB_HUB_AGT_ADR_I2Q, | ||
268 | NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB, | ||
269 | 0, | ||
270 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0, | ||
271 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8, | ||
272 | NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9, | ||
273 | NETXEN_HW_CRB_HUB_AGT_ADR_OCM0, | ||
274 | 0, | ||
275 | NETXEN_HW_CRB_HUB_AGT_ADR_SMB, | ||
276 | NETXEN_HW_CRB_HUB_AGT_ADR_I2C0, | ||
277 | NETXEN_HW_CRB_HUB_AGT_ADR_I2C1, | ||
278 | 0, | ||
279 | NETXEN_HW_CRB_HUB_AGT_ADR_PGNC, | ||
280 | 0, | ||
251 | }; | 281 | }; |
252 | #define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) | ||
253 | #define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) | ||
254 | #define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) | ||
255 | |||
256 | 282 | ||
257 | /* PCI Windowing for DDR regions. */ | 283 | /* PCI Windowing for DDR regions. */ |
258 | 284 | ||
259 | #define ADDR_IN_RANGE(addr, low, high) \ | 285 | #define ADDR_IN_RANGE(addr, low, high) \ |
260 | (((addr) <= (high)) && ((addr) >= (low))) | 286 | (((addr) <= (high)) && ((addr) >= (low))) |
261 | 287 | ||
262 | #define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START) | ||
263 | #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) | ||
264 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE | 288 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE |
265 | #define NETXEN_MIN_MTU 64 | 289 | #define NETXEN_MIN_MTU 64 |
266 | #define NETXEN_ETH_FCS_SIZE 4 | 290 | #define NETXEN_ETH_FCS_SIZE 4 |
267 | #define NETXEN_ENET_HEADER_SIZE 14 | 291 | #define NETXEN_ENET_HEADER_SIZE 14 |
268 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ | 292 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ |
269 | #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) | 293 | #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) |
270 | #define NETXEN_NIU_HDRSIZE (0x1 << 6) | 294 | #define NETXEN_NIU_HDRSIZE (0x1 << 6) |
271 | #define NETXEN_NIU_TLRSIZE (0x1 << 5) | 295 | #define NETXEN_NIU_TLRSIZE (0x1 << 5) |
272 | 296 | ||
273 | #define lower32(x) ((u32)((x) & 0xffffffff)) | ||
274 | #define upper32(x) \ | ||
275 | ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff)) | ||
276 | |||
277 | #define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL | 297 | #define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL |
278 | #define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL | 298 | #define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL |
279 | #define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL | 299 | #define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL |
@@ -281,10 +301,6 @@ static u64 ctx_addr_sig_regs[][3] = { | |||
281 | 301 | ||
282 | #define NETXEN_NIC_WINDOW_MARGIN 0x100000 | 302 | #define NETXEN_NIC_WINDOW_MARGIN 0x100000 |
283 | 303 | ||
284 | static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, | ||
285 | unsigned long long addr); | ||
286 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
287 | |||
288 | int netxen_nic_set_mac(struct net_device *netdev, void *p) | 304 | int netxen_nic_set_mac(struct net_device *netdev, void *p) |
289 | { | 305 | { |
290 | struct netxen_adapter *adapter = netdev_priv(netdev); | 306 | struct netxen_adapter *adapter = netdev_priv(netdev); |
@@ -296,266 +312,370 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) | |||
296 | if (!is_valid_ether_addr(addr->sa_data)) | 312 | if (!is_valid_ether_addr(addr->sa_data)) |
297 | return -EADDRNOTAVAIL; | 313 | return -EADDRNOTAVAIL; |
298 | 314 | ||
299 | DPRINTK(INFO, "valid ether addr\n"); | ||
300 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 315 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
301 | 316 | ||
302 | if (adapter->macaddr_set) | 317 | /* For P3, MAC addr is not set in NIU */ |
303 | adapter->macaddr_set(adapter, addr->sa_data); | 318 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
319 | if (adapter->macaddr_set) | ||
320 | adapter->macaddr_set(adapter, addr->sa_data); | ||
304 | 321 | ||
305 | return 0; | 322 | return 0; |
306 | } | 323 | } |
307 | 324 | ||
308 | /* | 325 | #define NETXEN_UNICAST_ADDR(port, index) \ |
309 | * netxen_nic_set_multi - Multicast | 326 | (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8)) |
310 | */ | 327 | #define NETXEN_MCAST_ADDR(port, index) \ |
311 | void netxen_nic_set_multi(struct net_device *netdev) | 328 | (NETXEN_MULTICAST_ADDR_BASE+(port*0x80)+(index*8)) |
329 | #define MAC_HI(addr) \ | ||
330 | ((addr[2] << 16) | (addr[1] << 8) | (addr[0])) | ||
331 | #define MAC_LO(addr) \ | ||
332 | ((addr[5] << 16) | (addr[4] << 8) | (addr[3])) | ||
333 | |||
334 | static int | ||
335 | netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) | ||
336 | { | ||
337 | u32 val = 0; | ||
338 | u16 port = adapter->physical_port; | ||
339 | u8 *addr = adapter->netdev->dev_addr; | ||
340 | |||
341 | if (adapter->mc_enabled) | ||
342 | return 0; | ||
343 | |||
344 | adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); | ||
345 | val |= (1UL << (28+port)); | ||
346 | adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); | ||
347 | |||
348 | /* add broadcast addr to filter */ | ||
349 | val = 0xffffff; | ||
350 | netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); | ||
351 | netxen_crb_writelit_adapter(adapter, | ||
352 | NETXEN_UNICAST_ADDR(port, 0)+4, val); | ||
353 | |||
354 | /* add station addr to filter */ | ||
355 | val = MAC_HI(addr); | ||
356 | netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val); | ||
357 | val = MAC_LO(addr); | ||
358 | netxen_crb_writelit_adapter(adapter, | ||
359 | NETXEN_UNICAST_ADDR(port, 1)+4, val); | ||
360 | |||
361 | adapter->mc_enabled = 1; | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static int | ||
366 | netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) | ||
367 | { | ||
368 | u32 val = 0; | ||
369 | u16 port = adapter->physical_port; | ||
370 | u8 *addr = adapter->netdev->dev_addr; | ||
371 | |||
372 | if (!adapter->mc_enabled) | ||
373 | return 0; | ||
374 | |||
375 | adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); | ||
376 | val &= ~(1UL << (28+port)); | ||
377 | adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); | ||
378 | |||
379 | val = MAC_HI(addr); | ||
380 | netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); | ||
381 | val = MAC_LO(addr); | ||
382 | netxen_crb_writelit_adapter(adapter, | ||
383 | NETXEN_UNICAST_ADDR(port, 0)+4, val); | ||
384 | |||
385 | netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0); | ||
386 | netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0); | ||
387 | |||
388 | adapter->mc_enabled = 0; | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int | ||
393 | netxen_nic_set_mcast_addr(struct netxen_adapter *adapter, | ||
394 | int index, u8 *addr) | ||
395 | { | ||
396 | u32 hi = 0, lo = 0; | ||
397 | u16 port = adapter->physical_port; | ||
398 | |||
399 | lo = MAC_LO(addr); | ||
400 | hi = MAC_HI(addr); | ||
401 | |||
402 | netxen_crb_writelit_adapter(adapter, | ||
403 | NETXEN_MCAST_ADDR(port, index), hi); | ||
404 | netxen_crb_writelit_adapter(adapter, | ||
405 | NETXEN_MCAST_ADDR(port, index)+4, lo); | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | void netxen_p2_nic_set_multi(struct net_device *netdev) | ||
312 | { | 411 | { |
313 | struct netxen_adapter *adapter = netdev_priv(netdev); | 412 | struct netxen_adapter *adapter = netdev_priv(netdev); |
314 | struct dev_mc_list *mc_ptr; | 413 | struct dev_mc_list *mc_ptr; |
414 | u8 null_addr[6]; | ||
415 | int index = 0; | ||
416 | |||
417 | memset(null_addr, 0, 6); | ||
315 | 418 | ||
316 | mc_ptr = netdev->mc_list; | ||
317 | if (netdev->flags & IFF_PROMISC) { | 419 | if (netdev->flags & IFF_PROMISC) { |
318 | if (adapter->set_promisc) | 420 | |
319 | adapter->set_promisc(adapter, | 421 | adapter->set_promisc(adapter, |
320 | NETXEN_NIU_PROMISC_MODE); | 422 | NETXEN_NIU_PROMISC_MODE); |
321 | } else { | 423 | |
322 | if (adapter->unset_promisc) | 424 | /* Full promiscuous mode */ |
323 | adapter->unset_promisc(adapter, | 425 | netxen_nic_disable_mcast_filter(adapter); |
324 | NETXEN_NIU_NON_PROMISC_MODE); | 426 | |
427 | return; | ||
428 | } | ||
429 | |||
430 | if (netdev->mc_count == 0) { | ||
431 | adapter->set_promisc(adapter, | ||
432 | NETXEN_NIU_NON_PROMISC_MODE); | ||
433 | netxen_nic_disable_mcast_filter(adapter); | ||
434 | return; | ||
325 | } | 435 | } |
436 | |||
437 | adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE); | ||
438 | if (netdev->flags & IFF_ALLMULTI || | ||
439 | netdev->mc_count > adapter->max_mc_count) { | ||
440 | netxen_nic_disable_mcast_filter(adapter); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | netxen_nic_enable_mcast_filter(adapter); | ||
445 | |||
446 | for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++) | ||
447 | netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr); | ||
448 | |||
449 | if (index != netdev->mc_count) | ||
450 | printk(KERN_WARNING "%s: %s multicast address count mismatch\n", | ||
451 | netxen_nic_driver_name, netdev->name); | ||
452 | |||
453 | /* Clear out remaining addresses */ | ||
454 | for (; index < adapter->max_mc_count; index++) | ||
455 | netxen_nic_set_mcast_addr(adapter, index, null_addr); | ||
326 | } | 456 | } |
327 | 457 | ||
328 | /* | 458 | static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, |
329 | * netxen_nic_change_mtu - Change the Maximum Transfer Unit | 459 | u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list) |
330 | * @returns 0 on success, negative on failure | ||
331 | */ | ||
332 | int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | ||
333 | { | 460 | { |
334 | struct netxen_adapter *adapter = netdev_priv(netdev); | 461 | nx_mac_list_t *cur, *prev; |
335 | int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; | 462 | |
463 | /* if in del_list, move it to adapter->mac_list */ | ||
464 | for (cur = *del_list, prev = NULL; cur;) { | ||
465 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { | ||
466 | if (prev == NULL) | ||
467 | *del_list = cur->next; | ||
468 | else | ||
469 | prev->next = cur->next; | ||
470 | cur->next = adapter->mac_list; | ||
471 | adapter->mac_list = cur; | ||
472 | return 0; | ||
473 | } | ||
474 | prev = cur; | ||
475 | cur = cur->next; | ||
476 | } | ||
477 | |||
478 | /* make sure to add each mac address only once */ | ||
479 | for (cur = adapter->mac_list; cur; cur = cur->next) { | ||
480 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) | ||
481 | return 0; | ||
482 | } | ||
483 | /* not in del_list, create new entry and add to add_list */ | ||
484 | cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL); | ||
485 | if (cur == NULL) { | ||
486 | printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may" | ||
487 | "not work properly from now.\n", __func__); | ||
488 | return -1; | ||
489 | } | ||
336 | 490 | ||
337 | if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { | 491 | memcpy(cur->mac_addr, addr, ETH_ALEN); |
338 | printk(KERN_ERR "%s: %s %d is not supported.\n", | 492 | cur->next = *add_list; |
339 | netxen_nic_driver_name, netdev->name, mtu); | 493 | *add_list = cur; |
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int | ||
498 | netxen_send_cmd_descs(struct netxen_adapter *adapter, | ||
499 | struct cmd_desc_type0 *cmd_desc_arr, int nr_elements) | ||
500 | { | ||
501 | uint32_t i, producer; | ||
502 | struct netxen_cmd_buffer *pbuf; | ||
503 | struct cmd_desc_type0 *cmd_desc; | ||
504 | |||
505 | if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) { | ||
506 | printk(KERN_WARNING "%s: Too many command descriptors in a " | ||
507 | "request\n", __func__); | ||
340 | return -EINVAL; | 508 | return -EINVAL; |
341 | } | 509 | } |
342 | 510 | ||
343 | if (adapter->set_mtu) | 511 | i = 0; |
344 | adapter->set_mtu(adapter, mtu); | 512 | |
345 | netdev->mtu = mtu; | 513 | producer = adapter->cmd_producer; |
514 | do { | ||
515 | cmd_desc = &cmd_desc_arr[i]; | ||
516 | |||
517 | pbuf = &adapter->cmd_buf_arr[producer]; | ||
518 | pbuf->mss = 0; | ||
519 | pbuf->total_length = 0; | ||
520 | pbuf->skb = NULL; | ||
521 | pbuf->cmd = 0; | ||
522 | pbuf->frag_count = 0; | ||
523 | pbuf->port = 0; | ||
524 | |||
525 | /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ | ||
526 | memcpy(&adapter->ahw.cmd_desc_head[producer], | ||
527 | &cmd_desc_arr[i], sizeof(struct cmd_desc_type0)); | ||
528 | |||
529 | producer = get_next_index(producer, | ||
530 | adapter->max_tx_desc_count); | ||
531 | i++; | ||
532 | |||
533 | } while (i != nr_elements); | ||
534 | |||
535 | adapter->cmd_producer = producer; | ||
536 | |||
537 | /* write producer index to start the xmit */ | ||
538 | |||
539 | netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); | ||
346 | 540 | ||
347 | return 0; | 541 | return 0; |
348 | } | 542 | } |
349 | 543 | ||
350 | /* | 544 | #define NIC_REQUEST 0x14 |
351 | * check if the firmware has been downloaded and ready to run and | 545 | #define NETXEN_MAC_EVENT 0x1 |
352 | * setup the address for the descriptors in the adapter | 546 | |
353 | */ | 547 | static int nx_p3_sre_macaddr_change(struct net_device *dev, |
354 | int netxen_nic_hw_resources(struct netxen_adapter *adapter) | 548 | u8 *addr, unsigned op) |
355 | { | 549 | { |
356 | struct netxen_hardware_context *hw = &adapter->ahw; | 550 | struct netxen_adapter *adapter = (struct netxen_adapter *)dev->priv; |
357 | u32 state = 0; | 551 | nx_nic_req_t req; |
358 | void *addr; | 552 | nx_mac_req_t mac_req; |
359 | int loops = 0, err = 0; | 553 | int rv; |
360 | int ctx, ring; | 554 | |
361 | struct netxen_recv_context *recv_ctx; | 555 | memset(&req, 0, sizeof(nx_nic_req_t)); |
362 | struct netxen_rcv_desc_ctx *rcv_desc; | 556 | req.qhdr |= (NIC_REQUEST << 23); |
363 | int func_id = adapter->portnum; | 557 | req.req_hdr |= NETXEN_MAC_EVENT; |
364 | 558 | req.req_hdr |= ((u64)adapter->portnum << 16); | |
365 | DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, | 559 | mac_req.op = op; |
366 | PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); | 560 | memcpy(&mac_req.mac_addr, addr, 6); |
367 | DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, | 561 | req.words[0] = cpu_to_le64(*(u64 *)&mac_req); |
368 | pci_base_offset(adapter, NETXEN_CRB_CAM)); | 562 | |
369 | DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, | 563 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
370 | pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); | 564 | if (rv != 0) { |
371 | 565 | printk(KERN_ERR "ERROR. Could not send mac update\n"); | |
372 | 566 | return rv; | |
373 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
374 | DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); | ||
375 | loops = 0; | ||
376 | state = 0; | ||
377 | /* Window 1 call */ | ||
378 | state = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
379 | recv_crb_registers[ctx]. | ||
380 | crb_rcvpeg_state)); | ||
381 | while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { | ||
382 | msleep(1); | ||
383 | /* Window 1 call */ | ||
384 | state = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
385 | recv_crb_registers | ||
386 | [ctx]. | ||
387 | crb_rcvpeg_state)); | ||
388 | loops++; | ||
389 | } | ||
390 | if (loops >= 20) { | ||
391 | printk(KERN_ERR "Rcv Peg initialization not complete:" | ||
392 | "%x.\n", state); | ||
393 | err = -EIO; | ||
394 | return err; | ||
395 | } | ||
396 | } | 567 | } |
397 | adapter->intr_scheme = readl( | ||
398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); | ||
399 | adapter->msi_mode = readl( | ||
400 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); | ||
401 | |||
402 | addr = netxen_alloc(adapter->ahw.pdev, | ||
403 | sizeof(struct netxen_ring_ctx) + | ||
404 | sizeof(uint32_t), | ||
405 | (dma_addr_t *) & adapter->ctx_desc_phys_addr, | ||
406 | &adapter->ctx_desc_pdev); | ||
407 | |||
408 | if (addr == NULL) { | ||
409 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); | ||
410 | err = -ENOMEM; | ||
411 | return err; | ||
412 | } | ||
413 | memset(addr, 0, sizeof(struct netxen_ring_ctx)); | ||
414 | adapter->ctx_desc = (struct netxen_ring_ctx *)addr; | ||
415 | adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); | ||
416 | adapter->ctx_desc->cmd_consumer_offset = | ||
417 | cpu_to_le64(adapter->ctx_desc_phys_addr + | ||
418 | sizeof(struct netxen_ring_ctx)); | ||
419 | adapter->cmd_consumer = (__le32 *) (((char *)addr) + | ||
420 | sizeof(struct netxen_ring_ctx)); | ||
421 | |||
422 | addr = netxen_alloc(adapter->ahw.pdev, | ||
423 | sizeof(struct cmd_desc_type0) * | ||
424 | adapter->max_tx_desc_count, | ||
425 | (dma_addr_t *) & hw->cmd_desc_phys_addr, | ||
426 | &adapter->ahw.cmd_desc_pdev); | ||
427 | |||
428 | if (addr == NULL) { | ||
429 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); | ||
430 | netxen_free_hw_resources(adapter); | ||
431 | return -ENOMEM; | ||
432 | } | ||
433 | |||
434 | adapter->ctx_desc->cmd_ring_addr = | ||
435 | cpu_to_le64(hw->cmd_desc_phys_addr); | ||
436 | adapter->ctx_desc->cmd_ring_size = | ||
437 | cpu_to_le32(adapter->max_tx_desc_count); | ||
438 | |||
439 | hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; | ||
440 | |||
441 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
442 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
443 | |||
444 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
445 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
446 | addr = netxen_alloc(adapter->ahw.pdev, | ||
447 | RCV_DESC_RINGSIZE, | ||
448 | &rcv_desc->phys_addr, | ||
449 | &rcv_desc->phys_pdev); | ||
450 | if (addr == NULL) { | ||
451 | DPRINTK(ERR, "bad return from " | ||
452 | "pci_alloc_consistent\n"); | ||
453 | netxen_free_hw_resources(adapter); | ||
454 | err = -ENOMEM; | ||
455 | return err; | ||
456 | } | ||
457 | rcv_desc->desc_head = (struct rcv_desc *)addr; | ||
458 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = | ||
459 | cpu_to_le64(rcv_desc->phys_addr); | ||
460 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = | ||
461 | cpu_to_le32(rcv_desc->max_rx_desc_count); | ||
462 | } | ||
463 | 568 | ||
464 | addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, | 569 | return 0; |
465 | &recv_ctx->rcv_status_desc_phys_addr, | ||
466 | &recv_ctx->rcv_status_desc_pdev); | ||
467 | if (addr == NULL) { | ||
468 | DPRINTK(ERR, "bad return from" | ||
469 | " pci_alloc_consistent\n"); | ||
470 | netxen_free_hw_resources(adapter); | ||
471 | err = -ENOMEM; | ||
472 | return err; | ||
473 | } | ||
474 | recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; | ||
475 | adapter->ctx_desc->sts_ring_addr = | ||
476 | cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); | ||
477 | adapter->ctx_desc->sts_ring_size = | ||
478 | cpu_to_le32(adapter->max_rx_desc_count); | ||
479 | |||
480 | } | ||
481 | /* Window = 1 */ | ||
482 | |||
483 | writel(lower32(adapter->ctx_desc_phys_addr), | ||
484 | NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO(func_id))); | ||
485 | writel(upper32(adapter->ctx_desc_phys_addr), | ||
486 | NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id))); | ||
487 | writel(NETXEN_CTX_SIGNATURE | func_id, | ||
488 | NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id))); | ||
489 | return err; | ||
490 | } | 570 | } |
491 | 571 | ||
492 | void netxen_free_hw_resources(struct netxen_adapter *adapter) | 572 | void netxen_p3_nic_set_multi(struct net_device *netdev) |
493 | { | 573 | { |
494 | struct netxen_recv_context *recv_ctx; | 574 | struct netxen_adapter *adapter = netdev_priv(netdev); |
495 | struct netxen_rcv_desc_ctx *rcv_desc; | 575 | nx_mac_list_t *cur, *next, *del_list, *add_list = NULL; |
496 | int ctx, ring; | 576 | struct dev_mc_list *mc_ptr; |
497 | 577 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | |
498 | if (adapter->ctx_desc != NULL) { | 578 | |
499 | pci_free_consistent(adapter->ctx_desc_pdev, | 579 | adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE); |
500 | sizeof(struct netxen_ring_ctx) + | ||
501 | sizeof(uint32_t), | ||
502 | adapter->ctx_desc, | ||
503 | adapter->ctx_desc_phys_addr); | ||
504 | adapter->ctx_desc = NULL; | ||
505 | } | ||
506 | |||
507 | if (adapter->ahw.cmd_desc_head != NULL) { | ||
508 | pci_free_consistent(adapter->ahw.cmd_desc_pdev, | ||
509 | sizeof(struct cmd_desc_type0) * | ||
510 | adapter->max_tx_desc_count, | ||
511 | adapter->ahw.cmd_desc_head, | ||
512 | adapter->ahw.cmd_desc_phys_addr); | ||
513 | adapter->ahw.cmd_desc_head = NULL; | ||
514 | } | ||
515 | |||
516 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
517 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
518 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
519 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
520 | |||
521 | if (rcv_desc->desc_head != NULL) { | ||
522 | pci_free_consistent(rcv_desc->phys_pdev, | ||
523 | RCV_DESC_RINGSIZE, | ||
524 | rcv_desc->desc_head, | ||
525 | rcv_desc->phys_addr); | ||
526 | rcv_desc->desc_head = NULL; | ||
527 | } | ||
528 | } | ||
529 | 580 | ||
530 | if (recv_ctx->rcv_status_desc_head != NULL) { | 581 | /* |
531 | pci_free_consistent(recv_ctx->rcv_status_desc_pdev, | 582 | * Programming mac addresses will automaticly enabling L2 filtering. |
532 | STATUS_DESC_RINGSIZE, | 583 | * HW will replace timestamp with L2 conid when L2 filtering is |
533 | recv_ctx->rcv_status_desc_head, | 584 | * enabled. This causes problem for LSA. Do not enabling L2 filtering |
534 | recv_ctx-> | 585 | * until that problem is fixed. |
535 | rcv_status_desc_phys_addr); | 586 | */ |
536 | recv_ctx->rcv_status_desc_head = NULL; | 587 | if ((netdev->flags & IFF_PROMISC) || |
588 | (netdev->mc_count > adapter->max_mc_count)) | ||
589 | return; | ||
590 | |||
591 | del_list = adapter->mac_list; | ||
592 | adapter->mac_list = NULL; | ||
593 | |||
594 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); | ||
595 | if (netdev->mc_count > 0) { | ||
596 | nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list); | ||
597 | for (mc_ptr = netdev->mc_list; mc_ptr; | ||
598 | mc_ptr = mc_ptr->next) { | ||
599 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, | ||
600 | &add_list, &del_list); | ||
537 | } | 601 | } |
538 | } | 602 | } |
603 | for (cur = del_list; cur;) { | ||
604 | nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); | ||
605 | next = cur->next; | ||
606 | kfree(cur); | ||
607 | cur = next; | ||
608 | } | ||
609 | for (cur = add_list; cur;) { | ||
610 | nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD); | ||
611 | next = cur->next; | ||
612 | cur->next = adapter->mac_list; | ||
613 | adapter->mac_list = cur; | ||
614 | cur = next; | ||
615 | } | ||
539 | } | 616 | } |
540 | 617 | ||
541 | void netxen_tso_check(struct netxen_adapter *adapter, | 618 | #define NETXEN_CONFIG_INTR_COALESCE 3 |
542 | struct cmd_desc_type0 *desc, struct sk_buff *skb) | 619 | |
620 | /* | ||
621 | * Send the interrupt coalescing parameter set by ethtool to the card. | ||
622 | */ | ||
623 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter) | ||
543 | { | 624 | { |
544 | if (desc->mss) { | 625 | nx_nic_req_t req; |
545 | desc->total_hdr_length = (sizeof(struct ethhdr) + | 626 | int rv; |
546 | ip_hdrlen(skb) + tcp_hdrlen(skb)); | 627 | |
547 | netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); | 628 | memset(&req, 0, sizeof(nx_nic_req_t)); |
548 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 629 | |
549 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) { | 630 | req.qhdr |= (NIC_REQUEST << 23); |
550 | netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); | 631 | req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; |
551 | } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) { | 632 | req.req_hdr |= ((u64)adapter->portnum << 16); |
552 | netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); | 633 | |
553 | } else { | 634 | memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); |
554 | return; | 635 | |
555 | } | 636 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
637 | if (rv != 0) { | ||
638 | printk(KERN_ERR "ERROR. Could not send " | ||
639 | "interrupt coalescing parameters\n"); | ||
556 | } | 640 | } |
557 | desc->tcp_hdr_offset = skb_transport_offset(skb); | 641 | |
558 | desc->ip_hdr_offset = skb_network_offset(skb); | 642 | return rv; |
643 | } | ||
644 | |||
645 | /* | ||
646 | * netxen_nic_change_mtu - Change the Maximum Transfer Unit | ||
647 | * @returns 0 on success, negative on failure | ||
648 | */ | ||
649 | |||
650 | #define MTU_FUDGE_FACTOR 100 | ||
651 | |||
652 | int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | ||
653 | { | ||
654 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
655 | int max_mtu; | ||
656 | |||
657 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
658 | max_mtu = P3_MAX_MTU; | ||
659 | else | ||
660 | max_mtu = P2_MAX_MTU; | ||
661 | |||
662 | if (mtu > max_mtu) { | ||
663 | printk(KERN_ERR "%s: mtu > %d bytes unsupported\n", | ||
664 | netdev->name, max_mtu); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
668 | if (adapter->set_mtu) | ||
669 | adapter->set_mtu(adapter, mtu); | ||
670 | netdev->mtu = mtu; | ||
671 | |||
672 | mtu += MTU_FUDGE_FACTOR; | ||
673 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
674 | nx_fw_cmd_set_mtu(adapter, mtu); | ||
675 | else if (adapter->set_mtu) | ||
676 | adapter->set_mtu(adapter, mtu); | ||
677 | |||
678 | return 0; | ||
559 | } | 679 | } |
560 | 680 | ||
561 | int netxen_is_flash_supported(struct netxen_adapter *adapter) | 681 | int netxen_is_flash_supported(struct netxen_adapter *adapter) |
@@ -632,41 +752,49 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]) | |||
632 | return 0; | 752 | return 0; |
633 | } | 753 | } |
634 | 754 | ||
755 | #define CRB_WIN_LOCK_TIMEOUT 100000000 | ||
756 | |||
757 | static int crb_win_lock(struct netxen_adapter *adapter) | ||
758 | { | ||
759 | int done = 0, timeout = 0; | ||
760 | |||
761 | while (!done) { | ||
762 | /* acquire semaphore3 from PCI HW block */ | ||
763 | adapter->hw_read_wx(adapter, | ||
764 | NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4); | ||
765 | if (done == 1) | ||
766 | break; | ||
767 | if (timeout >= CRB_WIN_LOCK_TIMEOUT) | ||
768 | return -1; | ||
769 | timeout++; | ||
770 | udelay(1); | ||
771 | } | ||
772 | netxen_crb_writelit_adapter(adapter, | ||
773 | NETXEN_CRB_WIN_LOCK_ID, adapter->portnum); | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static void crb_win_unlock(struct netxen_adapter *adapter) | ||
778 | { | ||
779 | int val; | ||
780 | |||
781 | adapter->hw_read_wx(adapter, | ||
782 | NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4); | ||
783 | } | ||
784 | |||
635 | /* | 785 | /* |
636 | * Changes the CRB window to the specified window. | 786 | * Changes the CRB window to the specified window. |
637 | */ | 787 | */ |
638 | void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | 788 | void |
789 | netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw) | ||
639 | { | 790 | { |
640 | void __iomem *offset; | 791 | void __iomem *offset; |
641 | u32 tmp; | 792 | u32 tmp; |
642 | int count = 0; | 793 | int count = 0; |
794 | uint8_t func = adapter->ahw.pci_func; | ||
643 | 795 | ||
644 | if (adapter->curr_window == wndw) | 796 | if (adapter->curr_window == wndw) |
645 | return; | 797 | return; |
646 | switch(adapter->ahw.pci_func) { | ||
647 | case 0: | ||
648 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
649 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); | ||
650 | break; | ||
651 | case 1: | ||
652 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
653 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F1)); | ||
654 | break; | ||
655 | case 2: | ||
656 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
657 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F2)); | ||
658 | break; | ||
659 | case 3: | ||
660 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
661 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3)); | ||
662 | break; | ||
663 | default: | ||
664 | printk(KERN_INFO "Changing the window for PCI function " | ||
665 | "%d\n", adapter->ahw.pci_func); | ||
666 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
667 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); | ||
668 | break; | ||
669 | } | ||
670 | /* | 798 | /* |
671 | * Move the CRB window. | 799 | * Move the CRB window. |
672 | * We need to write to the "direct access" region of PCI | 800 | * We need to write to the "direct access" region of PCI |
@@ -675,6 +803,8 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | |||
675 | * register address is received by PCI. The direct region bypasses | 803 | * register address is received by PCI. The direct region bypasses |
676 | * the CRB bus. | 804 | * the CRB bus. |
677 | */ | 805 | */ |
806 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
807 | NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); | ||
678 | 808 | ||
679 | if (wndw & 0x1) | 809 | if (wndw & 0x1) |
680 | wndw = NETXEN_WINDOW_ONE; | 810 | wndw = NETXEN_WINDOW_ONE; |
@@ -685,7 +815,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | |||
685 | while ((tmp = readl(offset)) != wndw) { | 815 | while ((tmp = readl(offset)) != wndw) { |
686 | printk(KERN_WARNING "%s: %s WARNING: CRB window value not " | 816 | printk(KERN_WARNING "%s: %s WARNING: CRB window value not " |
687 | "registered properly: 0x%08x.\n", | 817 | "registered properly: 0x%08x.\n", |
688 | netxen_nic_driver_name, __FUNCTION__, tmp); | 818 | netxen_nic_driver_name, __func__, tmp); |
689 | mdelay(1); | 819 | mdelay(1); |
690 | if (count >= 10) | 820 | if (count >= 10) |
691 | break; | 821 | break; |
@@ -698,51 +828,119 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | |||
698 | adapter->curr_window = 0; | 828 | adapter->curr_window = 0; |
699 | } | 829 | } |
700 | 830 | ||
831 | /* | ||
832 | * Return -1 if off is not valid, | ||
833 | * 1 if window access is needed. 'off' is set to offset from | ||
834 | * CRB space in 128M pci map | ||
835 | * 0 if no window access is needed. 'off' is set to 2M addr | ||
836 | * In: 'off' is offset from base in 128M pci map | ||
837 | */ | ||
838 | static int | ||
839 | netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, | ||
840 | ulong *off, int len) | ||
841 | { | ||
842 | unsigned long end = *off + len; | ||
843 | crb_128M_2M_sub_block_map_t *m; | ||
844 | |||
845 | |||
846 | if (*off >= NETXEN_CRB_MAX) | ||
847 | return -1; | ||
848 | |||
849 | if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) { | ||
850 | *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE + | ||
851 | (ulong)adapter->ahw.pci_base0; | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | if (*off < NETXEN_PCI_CRBSPACE) | ||
856 | return -1; | ||
857 | |||
858 | *off -= NETXEN_PCI_CRBSPACE; | ||
859 | end = *off + len; | ||
860 | |||
861 | /* | ||
862 | * Try direct map | ||
863 | */ | ||
864 | m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; | ||
865 | |||
866 | if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) { | ||
867 | *off = *off + m->start_2M - m->start_128M + | ||
868 | (ulong)adapter->ahw.pci_base0; | ||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | * Not in direct map, use crb window | ||
874 | */ | ||
875 | return 1; | ||
876 | } | ||
877 | |||
878 | /* | ||
879 | * In: 'off' is offset from CRB space in 128M pci map | ||
880 | * Out: 'off' is 2M pci map addr | ||
881 | * side effect: lock crb window | ||
882 | */ | ||
883 | static void | ||
884 | netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) | ||
885 | { | ||
886 | u32 win_read; | ||
887 | |||
888 | adapter->crb_win = CRB_HI(*off); | ||
889 | writel(adapter->crb_win, (void *)(CRB_WINDOW_2M + | ||
890 | adapter->ahw.pci_base0)); | ||
891 | /* | ||
892 | * Read back value to make sure write has gone through before trying | ||
893 | * to use it. | ||
894 | */ | ||
895 | win_read = readl((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0)); | ||
896 | if (win_read != adapter->crb_win) { | ||
897 | printk(KERN_ERR "%s: Written crbwin (0x%x) != " | ||
898 | "Read crbwin (0x%x), off=0x%lx\n", | ||
899 | __func__, adapter->crb_win, win_read, *off); | ||
900 | } | ||
901 | *off = (*off & MASK(16)) + CRB_INDIRECT_2M + | ||
902 | (ulong)adapter->ahw.pci_base0; | ||
903 | } | ||
904 | |||
701 | int netxen_load_firmware(struct netxen_adapter *adapter) | 905 | int netxen_load_firmware(struct netxen_adapter *adapter) |
702 | { | 906 | { |
703 | int i; | 907 | int i; |
704 | u32 data, size = 0; | 908 | u32 data, size = 0; |
705 | u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE; | 909 | u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START; |
706 | u64 off; | ||
707 | void __iomem *addr; | ||
708 | 910 | ||
709 | size = NETXEN_FIRMWARE_LEN; | 911 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; |
710 | writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | 912 | |
913 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
914 | adapter->pci_write_normalize(adapter, | ||
915 | NETXEN_ROMUSB_GLB_CAS_RST, 1); | ||
711 | 916 | ||
712 | for (i = 0; i < size; i++) { | 917 | for (i = 0; i < size; i++) { |
713 | int retries = 10; | ||
714 | if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) | 918 | if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) |
715 | return -EIO; | 919 | return -EIO; |
716 | 920 | ||
717 | off = netxen_nic_pci_set_window(adapter, memaddr); | 921 | adapter->pci_mem_write(adapter, memaddr, &data, 4); |
718 | addr = pci_base_offset(adapter, off); | ||
719 | writel(data, addr); | ||
720 | do { | ||
721 | if (readl(addr) == data) | ||
722 | break; | ||
723 | msleep(100); | ||
724 | writel(data, addr); | ||
725 | } while (--retries); | ||
726 | if (!retries) { | ||
727 | printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n", | ||
728 | netxen_nic_driver_name, memaddr); | ||
729 | return -EIO; | ||
730 | } | ||
731 | flashaddr += 4; | 922 | flashaddr += 4; |
732 | memaddr += 4; | 923 | memaddr += 4; |
924 | cond_resched(); | ||
925 | } | ||
926 | msleep(1); | ||
927 | |||
928 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
929 | adapter->pci_write_normalize(adapter, | ||
930 | NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | ||
931 | else { | ||
932 | adapter->pci_write_normalize(adapter, | ||
933 | NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | ||
934 | adapter->pci_write_normalize(adapter, | ||
935 | NETXEN_ROMUSB_GLB_CAS_RST, 0); | ||
733 | } | 936 | } |
734 | udelay(100); | ||
735 | /* make sure Casper is powered on */ | ||
736 | writel(0x3fff, | ||
737 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); | ||
738 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | ||
739 | 937 | ||
740 | return 0; | 938 | return 0; |
741 | } | 939 | } |
742 | 940 | ||
743 | int | 941 | int |
744 | netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | 942 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, |
745 | int len) | 943 | ulong off, void *data, int len) |
746 | { | 944 | { |
747 | void __iomem *addr; | 945 | void __iomem *addr; |
748 | 946 | ||
@@ -750,7 +948,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | |||
750 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 948 | addr = NETXEN_CRB_NORMALIZE(adapter, off); |
751 | } else { /* Window 0 */ | 949 | } else { /* Window 0 */ |
752 | addr = pci_base_offset(adapter, off); | 950 | addr = pci_base_offset(adapter, off); |
753 | netxen_nic_pci_change_crbwindow(adapter, 0); | 951 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); |
754 | } | 952 | } |
755 | 953 | ||
756 | DPRINTK(INFO, "writing to base %lx offset %llx addr %p" | 954 | DPRINTK(INFO, "writing to base %lx offset %llx addr %p" |
@@ -758,7 +956,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | |||
758 | pci_base(adapter, off), off, addr, | 956 | pci_base(adapter, off), off, addr, |
759 | *(unsigned long long *)data, len); | 957 | *(unsigned long long *)data, len); |
760 | if (!addr) { | 958 | if (!addr) { |
761 | netxen_nic_pci_change_crbwindow(adapter, 1); | 959 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); |
762 | return 1; | 960 | return 1; |
763 | } | 961 | } |
764 | 962 | ||
@@ -785,14 +983,14 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | |||
785 | break; | 983 | break; |
786 | } | 984 | } |
787 | if (!ADDR_IN_WINDOW1(off)) | 985 | if (!ADDR_IN_WINDOW1(off)) |
788 | netxen_nic_pci_change_crbwindow(adapter, 1); | 986 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); |
789 | 987 | ||
790 | return 0; | 988 | return 0; |
791 | } | 989 | } |
792 | 990 | ||
793 | int | 991 | int |
794 | netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, | 992 | netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, |
795 | int len) | 993 | ulong off, void *data, int len) |
796 | { | 994 | { |
797 | void __iomem *addr; | 995 | void __iomem *addr; |
798 | 996 | ||
@@ -800,13 +998,13 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, | |||
800 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 998 | addr = NETXEN_CRB_NORMALIZE(adapter, off); |
801 | } else { /* Window 0 */ | 999 | } else { /* Window 0 */ |
802 | addr = pci_base_offset(adapter, off); | 1000 | addr = pci_base_offset(adapter, off); |
803 | netxen_nic_pci_change_crbwindow(adapter, 0); | 1001 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); |
804 | } | 1002 | } |
805 | 1003 | ||
806 | DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", | 1004 | DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", |
807 | pci_base(adapter, off), off, addr); | 1005 | pci_base(adapter, off), off, addr); |
808 | if (!addr) { | 1006 | if (!addr) { |
809 | netxen_nic_pci_change_crbwindow(adapter, 1); | 1007 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); |
810 | return 1; | 1008 | return 1; |
811 | } | 1009 | } |
812 | switch (len) { | 1010 | switch (len) { |
@@ -830,81 +1028,195 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, | |||
830 | DPRINTK(INFO, "read %lx\n", *(unsigned long *)data); | 1028 | DPRINTK(INFO, "read %lx\n", *(unsigned long *)data); |
831 | 1029 | ||
832 | if (!ADDR_IN_WINDOW1(off)) | 1030 | if (!ADDR_IN_WINDOW1(off)) |
833 | netxen_nic_pci_change_crbwindow(adapter, 1); | 1031 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); |
834 | 1032 | ||
835 | return 0; | 1033 | return 0; |
836 | } | 1034 | } |
837 | 1035 | ||
838 | void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) | 1036 | int |
839 | { /* Only for window 1 */ | 1037 | netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, |
840 | void __iomem *addr; | 1038 | ulong off, void *data, int len) |
1039 | { | ||
1040 | unsigned long flags = 0; | ||
1041 | int rv; | ||
1042 | |||
1043 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); | ||
1044 | |||
1045 | if (rv == -1) { | ||
1046 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", | ||
1047 | __func__, off); | ||
1048 | dump_stack(); | ||
1049 | return -1; | ||
1050 | } | ||
1051 | |||
1052 | if (rv == 1) { | ||
1053 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1054 | crb_win_lock(adapter); | ||
1055 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | ||
1056 | } | ||
841 | 1057 | ||
842 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 1058 | DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n", |
843 | DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", | 1059 | *(unsigned long *)data, off, len); |
844 | pci_base(adapter, off), off, addr, val); | ||
845 | writel(val, addr); | ||
846 | 1060 | ||
1061 | switch (len) { | ||
1062 | case 1: | ||
1063 | writeb(*(uint8_t *)data, (void *)off); | ||
1064 | break; | ||
1065 | case 2: | ||
1066 | writew(*(uint16_t *)data, (void *)off); | ||
1067 | break; | ||
1068 | case 4: | ||
1069 | writel(*(uint32_t *)data, (void *)off); | ||
1070 | break; | ||
1071 | case 8: | ||
1072 | writeq(*(uint64_t *)data, (void *)off); | ||
1073 | break; | ||
1074 | default: | ||
1075 | DPRINTK(1, INFO, | ||
1076 | "writing data %lx to offset %llx, num words=%d\n", | ||
1077 | *(unsigned long *)data, off, (len>>3)); | ||
1078 | break; | ||
1079 | } | ||
1080 | if (rv == 1) { | ||
1081 | crb_win_unlock(adapter); | ||
1082 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1083 | } | ||
1084 | |||
1085 | return 0; | ||
847 | } | 1086 | } |
848 | 1087 | ||
849 | int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) | 1088 | int |
850 | { /* Only for window 1 */ | 1089 | netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, |
851 | void __iomem *addr; | 1090 | ulong off, void *data, int len) |
852 | int val; | 1091 | { |
1092 | unsigned long flags = 0; | ||
1093 | int rv; | ||
853 | 1094 | ||
854 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 1095 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); |
855 | DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", | 1096 | |
856 | pci_base(adapter, off), off, addr); | 1097 | if (rv == -1) { |
857 | val = readl(addr); | 1098 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", |
858 | writel(val, addr); | 1099 | __func__, off); |
1100 | dump_stack(); | ||
1101 | return -1; | ||
1102 | } | ||
1103 | |||
1104 | if (rv == 1) { | ||
1105 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1106 | crb_win_lock(adapter); | ||
1107 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | ||
1108 | } | ||
1109 | |||
1110 | DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len); | ||
1111 | |||
1112 | switch (len) { | ||
1113 | case 1: | ||
1114 | *(uint8_t *)data = readb((void *)off); | ||
1115 | break; | ||
1116 | case 2: | ||
1117 | *(uint16_t *)data = readw((void *)off); | ||
1118 | break; | ||
1119 | case 4: | ||
1120 | *(uint32_t *)data = readl((void *)off); | ||
1121 | break; | ||
1122 | case 8: | ||
1123 | *(uint64_t *)data = readq((void *)off); | ||
1124 | break; | ||
1125 | default: | ||
1126 | break; | ||
1127 | } | ||
859 | 1128 | ||
1129 | DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data); | ||
1130 | |||
1131 | if (rv == 1) { | ||
1132 | crb_win_unlock(adapter); | ||
1133 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1134 | } | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) | ||
1140 | { | ||
1141 | adapter->hw_write_wx(adapter, off, &val, 4); | ||
1142 | } | ||
1143 | |||
1144 | int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) | ||
1145 | { | ||
1146 | int val; | ||
1147 | adapter->hw_read_wx(adapter, off, &val, 4); | ||
860 | return val; | 1148 | return val; |
861 | } | 1149 | } |
862 | 1150 | ||
863 | /* Change the window to 0, write and change back to window 1. */ | 1151 | /* Change the window to 0, write and change back to window 1. */ |
864 | void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) | 1152 | void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) |
865 | { | 1153 | { |
866 | void __iomem *addr; | 1154 | adapter->hw_write_wx(adapter, index, &value, 4); |
867 | |||
868 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
869 | addr = pci_base_offset(adapter, index); | ||
870 | writel(value, addr); | ||
871 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
872 | } | 1155 | } |
873 | 1156 | ||
874 | /* Change the window to 0, read and change back to window 1. */ | 1157 | /* Change the window to 0, read and change back to window 1. */ |
875 | void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) | 1158 | void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value) |
876 | { | 1159 | { |
877 | void __iomem *addr; | 1160 | adapter->hw_read_wx(adapter, index, value, 4); |
1161 | } | ||
878 | 1162 | ||
879 | addr = pci_base_offset(adapter, index); | 1163 | void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value) |
1164 | { | ||
1165 | adapter->hw_write_wx(adapter, index, &value, 4); | ||
1166 | } | ||
1167 | |||
1168 | void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value) | ||
1169 | { | ||
1170 | adapter->hw_read_wx(adapter, index, value, 4); | ||
1171 | } | ||
1172 | |||
1173 | /* | ||
1174 | * check memory access boundary. | ||
1175 | * used by test agent. support ddr access only for now | ||
1176 | */ | ||
1177 | static unsigned long | ||
1178 | netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter, | ||
1179 | unsigned long long addr, int size) | ||
1180 | { | ||
1181 | if (!ADDR_IN_RANGE(addr, | ||
1182 | NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) || | ||
1183 | !ADDR_IN_RANGE(addr+size-1, | ||
1184 | NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) || | ||
1185 | ((size != 1) && (size != 2) && (size != 4) && (size != 8))) { | ||
1186 | return 0; | ||
1187 | } | ||
880 | 1188 | ||
881 | netxen_nic_pci_change_crbwindow(adapter, 0); | 1189 | return 1; |
882 | *value = readl(addr); | ||
883 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
884 | } | 1190 | } |
885 | 1191 | ||
886 | static int netxen_pci_set_window_warning_count; | 1192 | static int netxen_pci_set_window_warning_count; |
887 | 1193 | ||
888 | static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, | 1194 | unsigned long |
889 | unsigned long long addr) | 1195 | netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, |
1196 | unsigned long long addr) | ||
890 | { | 1197 | { |
891 | static int ddr_mn_window = -1; | 1198 | void __iomem *offset; |
892 | static int qdr_sn_window = -1; | ||
893 | int window; | 1199 | int window; |
1200 | unsigned long long qdr_max; | ||
1201 | uint8_t func = adapter->ahw.pci_func; | ||
1202 | |||
1203 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
1204 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2; | ||
1205 | } else { | ||
1206 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3; | ||
1207 | } | ||
894 | 1208 | ||
895 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1209 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
896 | /* DDR network side */ | 1210 | /* DDR network side */ |
897 | addr -= NETXEN_ADDR_DDR_NET; | 1211 | addr -= NETXEN_ADDR_DDR_NET; |
898 | window = (addr >> 25) & 0x3ff; | 1212 | window = (addr >> 25) & 0x3ff; |
899 | if (ddr_mn_window != window) { | 1213 | if (adapter->ahw.ddr_mn_window != window) { |
900 | ddr_mn_window = window; | 1214 | adapter->ahw.ddr_mn_window = window; |
901 | writel(window, PCI_OFFSET_SECOND_RANGE(adapter, | 1215 | offset = PCI_OFFSET_SECOND_RANGE(adapter, |
902 | NETXEN_PCIX_PH_REG | 1216 | NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func))); |
903 | (PCIX_MN_WINDOW(adapter->ahw.pci_func)))); | 1217 | writel(window, offset); |
904 | /* MUST make sure window is set before we forge on... */ | 1218 | /* MUST make sure window is set before we forge on... */ |
905 | readl(PCI_OFFSET_SECOND_RANGE(adapter, | 1219 | readl(offset); |
906 | NETXEN_PCIX_PH_REG | ||
907 | (PCIX_MN_WINDOW(adapter->ahw.pci_func)))); | ||
908 | } | 1220 | } |
909 | addr -= (window * NETXEN_WINDOW_ONE); | 1221 | addr -= (window * NETXEN_WINDOW_ONE); |
910 | addr += NETXEN_PCI_DDR_NET; | 1222 | addr += NETXEN_PCI_DDR_NET; |
@@ -914,22 +1226,17 @@ static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, | |||
914 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | 1226 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { |
915 | addr -= NETXEN_ADDR_OCM1; | 1227 | addr -= NETXEN_ADDR_OCM1; |
916 | addr += NETXEN_PCI_OCM1; | 1228 | addr += NETXEN_PCI_OCM1; |
917 | } else | 1229 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) { |
918 | if (ADDR_IN_RANGE | ||
919 | (addr, NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX)) { | ||
920 | /* QDR network side */ | 1230 | /* QDR network side */ |
921 | addr -= NETXEN_ADDR_QDR_NET; | 1231 | addr -= NETXEN_ADDR_QDR_NET; |
922 | window = (addr >> 22) & 0x3f; | 1232 | window = (addr >> 22) & 0x3f; |
923 | if (qdr_sn_window != window) { | 1233 | if (adapter->ahw.qdr_sn_window != window) { |
924 | qdr_sn_window = window; | 1234 | adapter->ahw.qdr_sn_window = window; |
925 | writel((window << 22), | 1235 | offset = PCI_OFFSET_SECOND_RANGE(adapter, |
926 | PCI_OFFSET_SECOND_RANGE(adapter, | 1236 | NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func))); |
927 | NETXEN_PCIX_PH_REG | 1237 | writel((window << 22), offset); |
928 | (PCIX_SN_WINDOW(adapter->ahw.pci_func)))); | ||
929 | /* MUST make sure window is set before we forge on... */ | 1238 | /* MUST make sure window is set before we forge on... */ |
930 | readl(PCI_OFFSET_SECOND_RANGE(adapter, | 1239 | readl(offset); |
931 | NETXEN_PCIX_PH_REG | ||
932 | (PCIX_SN_WINDOW(adapter->ahw.pci_func)))); | ||
933 | } | 1240 | } |
934 | addr -= (window * 0x400000); | 1241 | addr -= (window * 0x400000); |
935 | addr += NETXEN_PCI_QDR_NET; | 1242 | addr += NETXEN_PCI_QDR_NET; |
@@ -943,11 +1250,711 @@ static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, | |||
943 | printk("%s: Warning:netxen_nic_pci_set_window()" | 1250 | printk("%s: Warning:netxen_nic_pci_set_window()" |
944 | " Unknown address range!\n", | 1251 | " Unknown address range!\n", |
945 | netxen_nic_driver_name); | 1252 | netxen_nic_driver_name); |
1253 | addr = -1UL; | ||
1254 | } | ||
1255 | return addr; | ||
1256 | } | ||
1257 | |||
1258 | /* | ||
1259 | * Note : only 32-bit writes! | ||
1260 | */ | ||
1261 | int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter, | ||
1262 | u64 off, u32 data) | ||
1263 | { | ||
1264 | writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off))); | ||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off) | ||
1269 | { | ||
1270 | return readl((void __iomem *)(pci_base_offset(adapter, off))); | ||
1271 | } | ||
1272 | |||
1273 | void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter, | ||
1274 | u64 off, u32 data) | ||
1275 | { | ||
1276 | writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); | ||
1277 | } | ||
1278 | |||
1279 | u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off) | ||
1280 | { | ||
1281 | return readl(NETXEN_CRB_NORMALIZE(adapter, off)); | ||
1282 | } | ||
1283 | |||
1284 | unsigned long | ||
1285 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | ||
1286 | unsigned long long addr) | ||
1287 | { | ||
1288 | int window; | ||
1289 | u32 win_read; | ||
1290 | |||
1291 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | ||
1292 | /* DDR network side */ | ||
1293 | window = MN_WIN(addr); | ||
1294 | adapter->ahw.ddr_mn_window = window; | ||
1295 | adapter->hw_write_wx(adapter, | ||
1296 | adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, | ||
1297 | &window, 4); | ||
1298 | adapter->hw_read_wx(adapter, | ||
1299 | adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, | ||
1300 | &win_read, 4); | ||
1301 | if ((win_read << 17) != window) { | ||
1302 | printk(KERN_INFO "Written MNwin (0x%x) != " | ||
1303 | "Read MNwin (0x%x)\n", window, win_read); | ||
1304 | } | ||
1305 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET; | ||
1306 | } else if (ADDR_IN_RANGE(addr, | ||
1307 | NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1308 | if ((addr & 0x00ff800) == 0xff800) { | ||
1309 | printk("%s: QM access not handled.\n", __func__); | ||
1310 | addr = -1UL; | ||
1311 | } | ||
1312 | |||
1313 | window = OCM_WIN(addr); | ||
1314 | adapter->ahw.ddr_mn_window = window; | ||
1315 | adapter->hw_write_wx(adapter, | ||
1316 | adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, | ||
1317 | &window, 4); | ||
1318 | adapter->hw_read_wx(adapter, | ||
1319 | adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, | ||
1320 | &win_read, 4); | ||
1321 | if ((win_read >> 7) != window) { | ||
1322 | printk(KERN_INFO "%s: Written OCMwin (0x%x) != " | ||
1323 | "Read OCMwin (0x%x)\n", | ||
1324 | __func__, window, win_read); | ||
1325 | } | ||
1326 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M; | ||
1327 | |||
1328 | } else if (ADDR_IN_RANGE(addr, | ||
1329 | NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { | ||
1330 | /* QDR network side */ | ||
1331 | window = MS_WIN(addr); | ||
1332 | adapter->ahw.qdr_sn_window = window; | ||
1333 | adapter->hw_write_wx(adapter, | ||
1334 | adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, | ||
1335 | &window, 4); | ||
1336 | adapter->hw_read_wx(adapter, | ||
1337 | adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, | ||
1338 | &win_read, 4); | ||
1339 | if (win_read != window) { | ||
1340 | printk(KERN_INFO "%s: Written MSwin (0x%x) != " | ||
1341 | "Read MSwin (0x%x)\n", | ||
1342 | __func__, window, win_read); | ||
1343 | } | ||
1344 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET; | ||
946 | 1345 | ||
1346 | } else { | ||
1347 | /* | ||
1348 | * peg gdb frequently accesses memory that doesn't exist, | ||
1349 | * this limits the chit chat so debugging isn't slowed down. | ||
1350 | */ | ||
1351 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
1352 | || (netxen_pci_set_window_warning_count%64 == 0)) { | ||
1353 | printk("%s: Warning:%s Unknown address range!\n", | ||
1354 | __func__, netxen_nic_driver_name); | ||
1355 | } | ||
1356 | addr = -1UL; | ||
947 | } | 1357 | } |
948 | return addr; | 1358 | return addr; |
949 | } | 1359 | } |
950 | 1360 | ||
1361 | static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter, | ||
1362 | unsigned long long addr) | ||
1363 | { | ||
1364 | int window; | ||
1365 | unsigned long long qdr_max; | ||
1366 | |||
1367 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
1368 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2; | ||
1369 | else | ||
1370 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3; | ||
1371 | |||
1372 | if (ADDR_IN_RANGE(addr, | ||
1373 | NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | ||
1374 | /* DDR network side */ | ||
1375 | BUG(); /* MN access can not come here */ | ||
1376 | } else if (ADDR_IN_RANGE(addr, | ||
1377 | NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1378 | return 1; | ||
1379 | } else if (ADDR_IN_RANGE(addr, | ||
1380 | NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
1381 | return 1; | ||
1382 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) { | ||
1383 | /* QDR network side */ | ||
1384 | window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f; | ||
1385 | if (adapter->ahw.qdr_sn_window == window) | ||
1386 | return 1; | ||
1387 | } | ||
1388 | |||
1389 | return 0; | ||
1390 | } | ||
1391 | |||
1392 | static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter, | ||
1393 | u64 off, void *data, int size) | ||
1394 | { | ||
1395 | unsigned long flags; | ||
1396 | void *addr; | ||
1397 | int ret = 0; | ||
1398 | u64 start; | ||
1399 | uint8_t *mem_ptr = NULL; | ||
1400 | unsigned long mem_base; | ||
1401 | unsigned long mem_page; | ||
1402 | |||
1403 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1404 | |||
1405 | /* | ||
1406 | * If attempting to access unknown address or straddle hw windows, | ||
1407 | * do not access. | ||
1408 | */ | ||
1409 | start = adapter->pci_set_window(adapter, off); | ||
1410 | if ((start == -1UL) || | ||
1411 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { | ||
1412 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1413 | printk(KERN_ERR "%s out of bound pci memory access. " | ||
1414 | "offset is 0x%llx\n", netxen_nic_driver_name, off); | ||
1415 | return -1; | ||
1416 | } | ||
1417 | |||
1418 | addr = (void *)(pci_base_offset(adapter, start)); | ||
1419 | if (!addr) { | ||
1420 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1421 | mem_base = pci_resource_start(adapter->pdev, 0); | ||
1422 | mem_page = start & PAGE_MASK; | ||
1423 | /* Map two pages whenever user tries to access addresses in two | ||
1424 | consecutive pages. | ||
1425 | */ | ||
1426 | if (mem_page != ((start + size - 1) & PAGE_MASK)) | ||
1427 | mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); | ||
1428 | else | ||
1429 | mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); | ||
1430 | if (mem_ptr == 0UL) { | ||
1431 | *(uint8_t *)data = 0; | ||
1432 | return -1; | ||
1433 | } | ||
1434 | addr = mem_ptr; | ||
1435 | addr += start & (PAGE_SIZE - 1); | ||
1436 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1437 | } | ||
1438 | |||
1439 | switch (size) { | ||
1440 | case 1: | ||
1441 | *(uint8_t *)data = readb(addr); | ||
1442 | break; | ||
1443 | case 2: | ||
1444 | *(uint16_t *)data = readw(addr); | ||
1445 | break; | ||
1446 | case 4: | ||
1447 | *(uint32_t *)data = readl(addr); | ||
1448 | break; | ||
1449 | case 8: | ||
1450 | *(uint64_t *)data = readq(addr); | ||
1451 | break; | ||
1452 | default: | ||
1453 | ret = -1; | ||
1454 | break; | ||
1455 | } | ||
1456 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1457 | DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data); | ||
1458 | |||
1459 | if (mem_ptr) | ||
1460 | iounmap(mem_ptr); | ||
1461 | return ret; | ||
1462 | } | ||
1463 | |||
1464 | static int | ||
1465 | netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off, | ||
1466 | void *data, int size) | ||
1467 | { | ||
1468 | unsigned long flags; | ||
1469 | void *addr; | ||
1470 | int ret = 0; | ||
1471 | u64 start; | ||
1472 | uint8_t *mem_ptr = NULL; | ||
1473 | unsigned long mem_base; | ||
1474 | unsigned long mem_page; | ||
1475 | |||
1476 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1477 | |||
1478 | /* | ||
1479 | * If attempting to access unknown address or straddle hw windows, | ||
1480 | * do not access. | ||
1481 | */ | ||
1482 | start = adapter->pci_set_window(adapter, off); | ||
1483 | if ((start == -1UL) || | ||
1484 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { | ||
1485 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1486 | printk(KERN_ERR "%s out of bound pci memory access. " | ||
1487 | "offset is 0x%llx\n", netxen_nic_driver_name, off); | ||
1488 | return -1; | ||
1489 | } | ||
1490 | |||
1491 | addr = (void *)(pci_base_offset(adapter, start)); | ||
1492 | if (!addr) { | ||
1493 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1494 | mem_base = pci_resource_start(adapter->pdev, 0); | ||
1495 | mem_page = start & PAGE_MASK; | ||
1496 | /* Map two pages whenever user tries to access addresses in two | ||
1497 | * consecutive pages. | ||
1498 | */ | ||
1499 | if (mem_page != ((start + size - 1) & PAGE_MASK)) | ||
1500 | mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2); | ||
1501 | else | ||
1502 | mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); | ||
1503 | if (mem_ptr == 0UL) | ||
1504 | return -1; | ||
1505 | addr = mem_ptr; | ||
1506 | addr += start & (PAGE_SIZE - 1); | ||
1507 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1508 | } | ||
1509 | |||
1510 | switch (size) { | ||
1511 | case 1: | ||
1512 | writeb(*(uint8_t *)data, addr); | ||
1513 | break; | ||
1514 | case 2: | ||
1515 | writew(*(uint16_t *)data, addr); | ||
1516 | break; | ||
1517 | case 4: | ||
1518 | writel(*(uint32_t *)data, addr); | ||
1519 | break; | ||
1520 | case 8: | ||
1521 | writeq(*(uint64_t *)data, addr); | ||
1522 | break; | ||
1523 | default: | ||
1524 | ret = -1; | ||
1525 | break; | ||
1526 | } | ||
1527 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1528 | DPRINTK(1, INFO, "writing data %llx to offset %llx\n", | ||
1529 | *(unsigned long long *)data, start); | ||
1530 | if (mem_ptr) | ||
1531 | iounmap(mem_ptr); | ||
1532 | return ret; | ||
1533 | } | ||
1534 | |||
1535 | #define MAX_CTL_CHECK 1000 | ||
1536 | |||
1537 | int | ||
1538 | netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, | ||
1539 | u64 off, void *data, int size) | ||
1540 | { | ||
1541 | unsigned long flags, mem_crb; | ||
1542 | int i, j, ret = 0, loop, sz[2], off0; | ||
1543 | uint32_t temp; | ||
1544 | uint64_t off8, tmpw, word[2] = {0, 0}; | ||
1545 | |||
1546 | /* | ||
1547 | * If not MN, go check for MS or invalid. | ||
1548 | */ | ||
1549 | if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0) | ||
1550 | return netxen_nic_pci_mem_write_direct(adapter, | ||
1551 | off, data, size); | ||
1552 | |||
1553 | off8 = off & 0xfffffff8; | ||
1554 | off0 = off & 0x7; | ||
1555 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1556 | sz[1] = size - sz[0]; | ||
1557 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1558 | mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | ||
1559 | |||
1560 | if ((size != 8) || (off0 != 0)) { | ||
1561 | for (i = 0; i < loop; i++) { | ||
1562 | if (adapter->pci_mem_read(adapter, | ||
1563 | off8 + (i << 3), &word[i], 8)) | ||
1564 | return -1; | ||
1565 | } | ||
1566 | } | ||
1567 | |||
1568 | switch (size) { | ||
1569 | case 1: | ||
1570 | tmpw = *((uint8_t *)data); | ||
1571 | break; | ||
1572 | case 2: | ||
1573 | tmpw = *((uint16_t *)data); | ||
1574 | break; | ||
1575 | case 4: | ||
1576 | tmpw = *((uint32_t *)data); | ||
1577 | break; | ||
1578 | case 8: | ||
1579 | default: | ||
1580 | tmpw = *((uint64_t *)data); | ||
1581 | break; | ||
1582 | } | ||
1583 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1584 | word[0] |= tmpw << (off0 * 8); | ||
1585 | |||
1586 | if (loop == 2) { | ||
1587 | word[1] &= ~(~0ULL << (sz[1] * 8)); | ||
1588 | word[1] |= tmpw >> (sz[0] * 8); | ||
1589 | } | ||
1590 | |||
1591 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1592 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1593 | |||
1594 | for (i = 0; i < loop; i++) { | ||
1595 | writel((uint32_t)(off8 + (i << 3)), | ||
1596 | (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1597 | writel(0, | ||
1598 | (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1599 | writel(word[i] & 0xffffffff, | ||
1600 | (void *)(mem_crb+MIU_TEST_AGT_WRDATA_LO)); | ||
1601 | writel((word[i] >> 32) & 0xffffffff, | ||
1602 | (void *)(mem_crb+MIU_TEST_AGT_WRDATA_HI)); | ||
1603 | writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1604 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1605 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1606 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1607 | |||
1608 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1609 | temp = readl( | ||
1610 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1611 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1612 | break; | ||
1613 | } | ||
1614 | |||
1615 | if (j >= MAX_CTL_CHECK) { | ||
1616 | printk("%s: %s Fail to write through agent\n", | ||
1617 | __func__, netxen_nic_driver_name); | ||
1618 | ret = -1; | ||
1619 | break; | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | ||
1624 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1625 | return ret; | ||
1626 | } | ||
1627 | |||
1628 | int | ||
1629 | netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, | ||
1630 | u64 off, void *data, int size) | ||
1631 | { | ||
1632 | unsigned long flags, mem_crb; | ||
1633 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | ||
1634 | uint32_t temp; | ||
1635 | uint64_t off8, val, word[2] = {0, 0}; | ||
1636 | |||
1637 | |||
1638 | /* | ||
1639 | * If not MN, go check for MS or invalid. | ||
1640 | */ | ||
1641 | if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0) | ||
1642 | return netxen_nic_pci_mem_read_direct(adapter, off, data, size); | ||
1643 | |||
1644 | off8 = off & 0xfffffff8; | ||
1645 | off0[0] = off & 0x7; | ||
1646 | off0[1] = 0; | ||
1647 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1648 | sz[1] = size - sz[0]; | ||
1649 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1650 | mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | ||
1651 | |||
1652 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1653 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1654 | |||
1655 | for (i = 0; i < loop; i++) { | ||
1656 | writel((uint32_t)(off8 + (i << 3)), | ||
1657 | (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1658 | writel(0, | ||
1659 | (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1660 | writel(MIU_TA_CTL_ENABLE, | ||
1661 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1662 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE, | ||
1663 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1664 | |||
1665 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1666 | temp = readl( | ||
1667 | (void *)(mem_crb+MIU_TEST_AGT_CTRL)); | ||
1668 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1669 | break; | ||
1670 | } | ||
1671 | |||
1672 | if (j >= MAX_CTL_CHECK) { | ||
1673 | printk(KERN_ERR "%s: %s Fail to read through agent\n", | ||
1674 | __func__, netxen_nic_driver_name); | ||
1675 | break; | ||
1676 | } | ||
1677 | |||
1678 | start = off0[i] >> 2; | ||
1679 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1680 | for (k = start; k <= end; k++) { | ||
1681 | word[i] |= ((uint64_t) readl( | ||
1682 | (void *)(mem_crb + | ||
1683 | MIU_TEST_AGT_RDDATA(k))) << (32*k)); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | ||
1688 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1689 | |||
1690 | if (j >= MAX_CTL_CHECK) | ||
1691 | return -1; | ||
1692 | |||
1693 | if (sz[0] == 8) { | ||
1694 | val = word[0]; | ||
1695 | } else { | ||
1696 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | ||
1697 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | ||
1698 | } | ||
1699 | |||
1700 | switch (size) { | ||
1701 | case 1: | ||
1702 | *(uint8_t *)data = val; | ||
1703 | break; | ||
1704 | case 2: | ||
1705 | *(uint16_t *)data = val; | ||
1706 | break; | ||
1707 | case 4: | ||
1708 | *(uint32_t *)data = val; | ||
1709 | break; | ||
1710 | case 8: | ||
1711 | *(uint64_t *)data = val; | ||
1712 | break; | ||
1713 | } | ||
1714 | DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data); | ||
1715 | return 0; | ||
1716 | } | ||
1717 | |||
1718 | int | ||
1719 | netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, | ||
1720 | u64 off, void *data, int size) | ||
1721 | { | ||
1722 | int i, j, ret = 0, loop, sz[2], off0; | ||
1723 | uint32_t temp; | ||
1724 | uint64_t off8, mem_crb, tmpw, word[2] = {0, 0}; | ||
1725 | |||
1726 | /* | ||
1727 | * If not MN, go check for MS or invalid. | ||
1728 | */ | ||
1729 | if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3) | ||
1730 | mem_crb = NETXEN_CRB_QDR_NET; | ||
1731 | else { | ||
1732 | mem_crb = NETXEN_CRB_DDR_NET; | ||
1733 | if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0) | ||
1734 | return netxen_nic_pci_mem_write_direct(adapter, | ||
1735 | off, data, size); | ||
1736 | } | ||
1737 | |||
1738 | off8 = off & 0xfffffff8; | ||
1739 | off0 = off & 0x7; | ||
1740 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1741 | sz[1] = size - sz[0]; | ||
1742 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1743 | |||
1744 | if ((size != 8) || (off0 != 0)) { | ||
1745 | for (i = 0; i < loop; i++) { | ||
1746 | if (adapter->pci_mem_read(adapter, off8 + (i << 3), | ||
1747 | &word[i], 8)) | ||
1748 | return -1; | ||
1749 | } | ||
1750 | } | ||
1751 | |||
1752 | switch (size) { | ||
1753 | case 1: | ||
1754 | tmpw = *((uint8_t *)data); | ||
1755 | break; | ||
1756 | case 2: | ||
1757 | tmpw = *((uint16_t *)data); | ||
1758 | break; | ||
1759 | case 4: | ||
1760 | tmpw = *((uint32_t *)data); | ||
1761 | break; | ||
1762 | case 8: | ||
1763 | default: | ||
1764 | tmpw = *((uint64_t *)data); | ||
1765 | break; | ||
1766 | } | ||
1767 | |||
1768 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1769 | word[0] |= tmpw << (off0 * 8); | ||
1770 | |||
1771 | if (loop == 2) { | ||
1772 | word[1] &= ~(~0ULL << (sz[1] * 8)); | ||
1773 | word[1] |= tmpw >> (sz[0] * 8); | ||
1774 | } | ||
1775 | |||
1776 | /* | ||
1777 | * don't lock here - write_wx gets the lock if each time | ||
1778 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1779 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1780 | */ | ||
1781 | |||
1782 | for (i = 0; i < loop; i++) { | ||
1783 | temp = off8 + (i << 3); | ||
1784 | adapter->hw_write_wx(adapter, | ||
1785 | mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4); | ||
1786 | temp = 0; | ||
1787 | adapter->hw_write_wx(adapter, | ||
1788 | mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4); | ||
1789 | temp = word[i] & 0xffffffff; | ||
1790 | adapter->hw_write_wx(adapter, | ||
1791 | mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4); | ||
1792 | temp = (word[i] >> 32) & 0xffffffff; | ||
1793 | adapter->hw_write_wx(adapter, | ||
1794 | mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4); | ||
1795 | temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1796 | adapter->hw_write_wx(adapter, | ||
1797 | mem_crb+MIU_TEST_AGT_CTRL, &temp, 4); | ||
1798 | temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1799 | adapter->hw_write_wx(adapter, | ||
1800 | mem_crb+MIU_TEST_AGT_CTRL, &temp, 4); | ||
1801 | |||
1802 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1803 | adapter->hw_read_wx(adapter, | ||
1804 | mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); | ||
1805 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1806 | break; | ||
1807 | } | ||
1808 | |||
1809 | if (j >= MAX_CTL_CHECK) { | ||
1810 | printk(KERN_ERR "%s: Fail to write through agent\n", | ||
1811 | netxen_nic_driver_name); | ||
1812 | ret = -1; | ||
1813 | break; | ||
1814 | } | ||
1815 | } | ||
1816 | |||
1817 | /* | ||
1818 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | ||
1819 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1820 | */ | ||
1821 | return ret; | ||
1822 | } | ||
1823 | |||
1824 | int | ||
1825 | netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, | ||
1826 | u64 off, void *data, int size) | ||
1827 | { | ||
1828 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | ||
1829 | uint32_t temp; | ||
1830 | uint64_t off8, val, mem_crb, word[2] = {0, 0}; | ||
1831 | |||
1832 | /* | ||
1833 | * If not MN, go check for MS or invalid. | ||
1834 | */ | ||
1835 | |||
1836 | if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3) | ||
1837 | mem_crb = NETXEN_CRB_QDR_NET; | ||
1838 | else { | ||
1839 | mem_crb = NETXEN_CRB_DDR_NET; | ||
1840 | if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0) | ||
1841 | return netxen_nic_pci_mem_read_direct(adapter, | ||
1842 | off, data, size); | ||
1843 | } | ||
1844 | |||
1845 | off8 = off & 0xfffffff8; | ||
1846 | off0[0] = off & 0x7; | ||
1847 | off0[1] = 0; | ||
1848 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1849 | sz[1] = size - sz[0]; | ||
1850 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1851 | |||
1852 | /* | ||
1853 | * don't lock here - write_wx gets the lock if each time | ||
1854 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1855 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1856 | */ | ||
1857 | |||
1858 | for (i = 0; i < loop; i++) { | ||
1859 | temp = off8 + (i << 3); | ||
1860 | adapter->hw_write_wx(adapter, | ||
1861 | mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4); | ||
1862 | temp = 0; | ||
1863 | adapter->hw_write_wx(adapter, | ||
1864 | mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4); | ||
1865 | temp = MIU_TA_CTL_ENABLE; | ||
1866 | adapter->hw_write_wx(adapter, | ||
1867 | mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); | ||
1868 | temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE; | ||
1869 | adapter->hw_write_wx(adapter, | ||
1870 | mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); | ||
1871 | |||
1872 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1873 | adapter->hw_read_wx(adapter, | ||
1874 | mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); | ||
1875 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1876 | break; | ||
1877 | } | ||
1878 | |||
1879 | if (j >= MAX_CTL_CHECK) { | ||
1880 | printk(KERN_ERR "%s: Fail to read through agent\n", | ||
1881 | netxen_nic_driver_name); | ||
1882 | break; | ||
1883 | } | ||
1884 | |||
1885 | start = off0[i] >> 2; | ||
1886 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1887 | for (k = start; k <= end; k++) { | ||
1888 | adapter->hw_read_wx(adapter, | ||
1889 | mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4); | ||
1890 | word[i] |= ((uint64_t)temp << (32 * k)); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | /* | ||
1895 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | ||
1896 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1897 | */ | ||
1898 | |||
1899 | if (j >= MAX_CTL_CHECK) | ||
1900 | return -1; | ||
1901 | |||
1902 | if (sz[0] == 8) { | ||
1903 | val = word[0]; | ||
1904 | } else { | ||
1905 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | ||
1906 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | ||
1907 | } | ||
1908 | |||
1909 | switch (size) { | ||
1910 | case 1: | ||
1911 | *(uint8_t *)data = val; | ||
1912 | break; | ||
1913 | case 2: | ||
1914 | *(uint16_t *)data = val; | ||
1915 | break; | ||
1916 | case 4: | ||
1917 | *(uint32_t *)data = val; | ||
1918 | break; | ||
1919 | case 8: | ||
1920 | *(uint64_t *)data = val; | ||
1921 | break; | ||
1922 | } | ||
1923 | DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data); | ||
1924 | return 0; | ||
1925 | } | ||
1926 | |||
1927 | /* | ||
1928 | * Note : only 32-bit writes! | ||
1929 | */ | ||
1930 | int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, | ||
1931 | u64 off, u32 data) | ||
1932 | { | ||
1933 | adapter->hw_write_wx(adapter, off, &data, 4); | ||
1934 | |||
1935 | return 0; | ||
1936 | } | ||
1937 | |||
1938 | u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off) | ||
1939 | { | ||
1940 | u32 temp; | ||
1941 | adapter->hw_read_wx(adapter, off, &temp, 4); | ||
1942 | return temp; | ||
1943 | } | ||
1944 | |||
1945 | void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter, | ||
1946 | u64 off, u32 data) | ||
1947 | { | ||
1948 | adapter->hw_write_wx(adapter, off, &data, 4); | ||
1949 | } | ||
1950 | |||
1951 | u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off) | ||
1952 | { | ||
1953 | u32 temp; | ||
1954 | adapter->hw_read_wx(adapter, off, &temp, 4); | ||
1955 | return temp; | ||
1956 | } | ||
1957 | |||
951 | #if 0 | 1958 | #if 0 |
952 | int | 1959 | int |
953 | netxen_nic_erase_pxe(struct netxen_adapter *adapter) | 1960 | netxen_nic_erase_pxe(struct netxen_adapter *adapter) |
@@ -1003,12 +2010,25 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) | |||
1003 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 2010 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
1004 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | 2011 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: |
1005 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | 2012 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: |
2013 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
2014 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
2015 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
2016 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
2017 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
2018 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
2019 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
2020 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
2021 | |||
1006 | adapter->ahw.board_type = NETXEN_NIC_XGBE; | 2022 | adapter->ahw.board_type = NETXEN_NIC_XGBE; |
1007 | break; | 2023 | break; |
1008 | case NETXEN_BRDTYPE_P1_BD: | 2024 | case NETXEN_BRDTYPE_P1_BD: |
1009 | case NETXEN_BRDTYPE_P1_SB: | 2025 | case NETXEN_BRDTYPE_P1_SB: |
1010 | case NETXEN_BRDTYPE_P1_SMAX: | 2026 | case NETXEN_BRDTYPE_P1_SMAX: |
1011 | case NETXEN_BRDTYPE_P1_SOCK: | 2027 | case NETXEN_BRDTYPE_P1_SOCK: |
2028 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
2029 | case NETXEN_BRDTYPE_P3_4_GB: | ||
2030 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
2031 | |||
1012 | adapter->ahw.board_type = NETXEN_NIC_GBE; | 2032 | adapter->ahw.board_type = NETXEN_NIC_GBE; |
1013 | break; | 2033 | break; |
1014 | default: | 2034 | default: |
@@ -1042,25 +2062,11 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) | |||
1042 | return 0; | 2062 | return 0; |
1043 | } | 2063 | } |
1044 | 2064 | ||
1045 | void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) | ||
1046 | { | ||
1047 | netxen_niu_gbe_init_port(adapter, adapter->physical_port); | ||
1048 | } | ||
1049 | |||
1050 | void | 2065 | void |
1051 | netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, | 2066 | netxen_crb_writelit_adapter(struct netxen_adapter *adapter, |
1052 | int data) | 2067 | unsigned long off, int data) |
1053 | { | 2068 | { |
1054 | void __iomem *addr; | 2069 | adapter->hw_write_wx(adapter, off, &data, 4); |
1055 | |||
1056 | if (ADDR_IN_WINDOW1(off)) { | ||
1057 | writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); | ||
1058 | } else { | ||
1059 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
1060 | addr = pci_base_offset(adapter, off); | ||
1061 | writel(data, addr); | ||
1062 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
1063 | } | ||
1064 | } | 2070 | } |
1065 | 2071 | ||
1066 | void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | 2072 | void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) |
@@ -1147,12 +2153,11 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
1147 | addr += sizeof(u32); | 2153 | addr += sizeof(u32); |
1148 | } | 2154 | } |
1149 | 2155 | ||
1150 | fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, | 2156 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4); |
1151 | NETXEN_FW_VERSION_MAJOR)); | 2157 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4); |
1152 | fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, | 2158 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4); |
1153 | NETXEN_FW_VERSION_MINOR)); | 2159 | |
1154 | fw_build = | 2160 | adapter->fw_major = fw_major; |
1155 | readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); | ||
1156 | 2161 | ||
1157 | if (adapter->portnum == 0) { | 2162 | if (adapter->portnum == 0) { |
1158 | get_brd_name_by_type(board_info->board_type, brd_name); | 2163 | get_brd_name_by_type(board_info->board_type, brd_name); |
@@ -1163,28 +2168,13 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
1163 | fw_minor, fw_build); | 2168 | fw_minor, fw_build); |
1164 | } | 2169 | } |
1165 | 2170 | ||
1166 | if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { | 2171 | if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) < |
1167 | adapter->driver_mismatch = 1; | 2172 | NETXEN_VERSION_CODE(3, 4, 216)) { |
1168 | } | ||
1169 | if (fw_minor != _NETXEN_NIC_LINUX_MINOR && | ||
1170 | fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { | ||
1171 | adapter->driver_mismatch = 1; | 2173 | adapter->driver_mismatch = 1; |
1172 | } | 2174 | printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n", |
1173 | if (adapter->driver_mismatch) { | 2175 | netxen_nic_driver_name, |
1174 | printk(KERN_ERR "%s: driver and firmware version mismatch\n", | 2176 | fw_major, fw_minor, fw_build); |
1175 | adapter->netdev->name); | ||
1176 | return; | 2177 | return; |
1177 | } | 2178 | } |
1178 | |||
1179 | switch (adapter->ahw.board_type) { | ||
1180 | case NETXEN_NIC_GBE: | ||
1181 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", | ||
1182 | adapter->netdev->name); | ||
1183 | break; | ||
1184 | case NETXEN_NIC_XGBE: | ||
1185 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", | ||
1186 | adapter->netdev->name); | ||
1187 | break; | ||
1188 | } | ||
1189 | } | 2179 | } |
1190 | 2180 | ||
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index a3ea1dd98c41..b8e0030f03d7 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h | |||
@@ -82,19 +82,9 @@ struct netxen_adapter; | |||
82 | 82 | ||
83 | #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) | 83 | #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) |
84 | 84 | ||
85 | #define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ | ||
86 | addr = pci_base_offset(adapter, X); \ | ||
87 | *(u32 *)Y = readl((void __iomem*) addr); | ||
88 | |||
89 | struct netxen_port; | 85 | struct netxen_port; |
90 | void netxen_nic_set_link_parameters(struct netxen_adapter *adapter); | 86 | void netxen_nic_set_link_parameters(struct netxen_adapter *adapter); |
91 | void netxen_nic_flash_print(struct netxen_adapter *adapter); | 87 | void netxen_nic_flash_print(struct netxen_adapter *adapter); |
92 | int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, | ||
93 | void *data, int len); | ||
94 | void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, | ||
95 | unsigned long off, int data); | ||
96 | int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, | ||
97 | void *data, int len); | ||
98 | 88 | ||
99 | typedef u8 netxen_ethernet_macaddr_t[6]; | 89 | typedef u8 netxen_ethernet_macaddr_t[6]; |
100 | 90 | ||
@@ -432,7 +422,8 @@ typedef enum { | |||
432 | /* Promiscous mode options (GbE mode only) */ | 422 | /* Promiscous mode options (GbE mode only) */ |
433 | typedef enum { | 423 | typedef enum { |
434 | NETXEN_NIU_PROMISC_MODE = 0, | 424 | NETXEN_NIU_PROMISC_MODE = 0, |
435 | NETXEN_NIU_NON_PROMISC_MODE | 425 | NETXEN_NIU_NON_PROMISC_MODE, |
426 | NETXEN_NIU_ALLMULTI_MODE | ||
436 | } netxen_niu_prom_mode_t; | 427 | } netxen_niu_prom_mode_t; |
437 | 428 | ||
438 | /* | 429 | /* |
@@ -478,42 +469,6 @@ typedef enum { | |||
478 | #define netxen_xg_soft_reset(config_word) \ | 469 | #define netxen_xg_soft_reset(config_word) \ |
479 | ((config_word) |= 1 << 4) | 470 | ((config_word) |= 1 << 4) |
480 | 471 | ||
481 | /* | ||
482 | * MAC Control Register | ||
483 | * | ||
484 | * Bit 0-1 : id_pool0 | ||
485 | * Bit 2 : enable_xtnd0 | ||
486 | * Bit 4-5 : id_pool1 | ||
487 | * Bit 6 : enable_xtnd1 | ||
488 | * Bit 8-9 : id_pool2 | ||
489 | * Bit 10 : enable_xtnd2 | ||
490 | * Bit 12-13 : id_pool3 | ||
491 | * Bit 14 : enable_xtnd3 | ||
492 | * Bit 24-25 : mode_select | ||
493 | * Bit 28-31 : enable_pool | ||
494 | */ | ||
495 | |||
496 | #define netxen_nic_mcr_set_id_pool0(config, val) \ | ||
497 | ((config) |= ((val) &0x03)) | ||
498 | #define netxen_nic_mcr_set_enable_xtnd0(config) \ | ||
499 | ((config) |= 1 << 3) | ||
500 | #define netxen_nic_mcr_set_id_pool1(config, val) \ | ||
501 | ((config) |= (((val) & 0x03) << 4)) | ||
502 | #define netxen_nic_mcr_set_enable_xtnd1(config) \ | ||
503 | ((config) |= 1 << 6) | ||
504 | #define netxen_nic_mcr_set_id_pool2(config, val) \ | ||
505 | ((config) |= (((val) & 0x03) << 8)) | ||
506 | #define netxen_nic_mcr_set_enable_xtnd2(config) \ | ||
507 | ((config) |= 1 << 10) | ||
508 | #define netxen_nic_mcr_set_id_pool3(config, val) \ | ||
509 | ((config) |= (((val) & 0x03) << 12)) | ||
510 | #define netxen_nic_mcr_set_enable_xtnd3(config) \ | ||
511 | ((config) |= 1 << 14) | ||
512 | #define netxen_nic_mcr_set_mode_select(config, val) \ | ||
513 | ((config) |= (((val) & 0x03) << 24)) | ||
514 | #define netxen_nic_mcr_set_enable_pool(config, val) \ | ||
515 | ((config) |= (((val) & 0x0f) << 28)) | ||
516 | |||
517 | /* Set promiscuous mode for a GbE interface */ | 472 | /* Set promiscuous mode for a GbE interface */ |
518 | int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | 473 | int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, |
519 | netxen_niu_prom_mode_t mode); | 474 | netxen_niu_prom_mode_t mode); |
@@ -538,4 +493,15 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter); | |||
538 | 493 | ||
539 | int netxen_niu_disable_xg_port(struct netxen_adapter *adapter); | 494 | int netxen_niu_disable_xg_port(struct netxen_adapter *adapter); |
540 | 495 | ||
496 | typedef struct { | ||
497 | unsigned valid; | ||
498 | unsigned start_128M; | ||
499 | unsigned end_128M; | ||
500 | unsigned start_2M; | ||
501 | } crb_128M_2M_sub_block_map_t; | ||
502 | |||
503 | typedef struct { | ||
504 | crb_128M_2M_sub_block_map_t sub_block[16]; | ||
505 | } crb_128M_2M_block_map_t; | ||
506 | |||
541 | #endif /* __NETXEN_NIC_HW_H_ */ | 507 | #endif /* __NETXEN_NIC_HW_H_ */ |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 70d1b22ced22..01ab31b34a85 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -42,8 +42,6 @@ struct crb_addr_pair { | |||
42 | u32 data; | 42 | u32 data; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | unsigned long last_schedule_time; | ||
46 | |||
47 | #define NETXEN_MAX_CRB_XFORM 60 | 45 | #define NETXEN_MAX_CRB_XFORM 60 |
48 | static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | 46 | static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; |
49 | #define NETXEN_ADDR_ERROR (0xffffffff) | 47 | #define NETXEN_ADDR_ERROR (0xffffffff) |
@@ -117,6 +115,8 @@ static void crb_addr_transform_setup(void) | |||
117 | crb_addr_transform(C2C1); | 115 | crb_addr_transform(C2C1); |
118 | crb_addr_transform(C2C0); | 116 | crb_addr_transform(C2C0); |
119 | crb_addr_transform(SMB); | 117 | crb_addr_transform(SMB); |
118 | crb_addr_transform(OCM0); | ||
119 | crb_addr_transform(I2C0); | ||
120 | } | 120 | } |
121 | 121 | ||
122 | int netxen_init_firmware(struct netxen_adapter *adapter) | 122 | int netxen_init_firmware(struct netxen_adapter *adapter) |
@@ -124,15 +124,15 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
124 | u32 state = 0, loops = 0, err = 0; | 124 | u32 state = 0, loops = 0, err = 0; |
125 | 125 | ||
126 | /* Window 1 call */ | 126 | /* Window 1 call */ |
127 | state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 127 | state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); |
128 | 128 | ||
129 | if (state == PHAN_INITIALIZE_ACK) | 129 | if (state == PHAN_INITIALIZE_ACK) |
130 | return 0; | 130 | return 0; |
131 | 131 | ||
132 | while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) { | 132 | while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) { |
133 | udelay(100); | 133 | msleep(1); |
134 | /* Window 1 call */ | 134 | /* Window 1 call */ |
135 | state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 135 | state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); |
136 | 136 | ||
137 | loops++; | 137 | loops++; |
138 | } | 138 | } |
@@ -143,64 +143,193 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
143 | return err; | 143 | return err; |
144 | } | 144 | } |
145 | /* Window 1 call */ | 145 | /* Window 1 call */ |
146 | writel(INTR_SCHEME_PERPORT, | 146 | adapter->pci_write_normalize(adapter, |
147 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); | 147 | CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); |
148 | writel(MSI_MODE_MULTIFUNC, | 148 | adapter->pci_write_normalize(adapter, |
149 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST)); | 149 | CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); |
150 | writel(MPORT_MULTI_FUNCTION_MODE, | 150 | adapter->pci_write_normalize(adapter, |
151 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); | 151 | CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); |
152 | writel(PHAN_INITIALIZE_ACK, | 152 | adapter->pci_write_normalize(adapter, |
153 | NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 153 | CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); |
154 | 154 | ||
155 | return err; | 155 | return err; |
156 | } | 156 | } |
157 | 157 | ||
158 | #define NETXEN_ADDR_LIMIT 0xffffffffULL | 158 | void netxen_release_rx_buffers(struct netxen_adapter *adapter) |
159 | { | ||
160 | struct netxen_recv_context *recv_ctx; | ||
161 | struct nx_host_rds_ring *rds_ring; | ||
162 | struct netxen_rx_buffer *rx_buf; | ||
163 | int i, ctxid, ring; | ||
164 | |||
165 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | ||
166 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
167 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
168 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
169 | for (i = 0; i < rds_ring->max_rx_desc_count; ++i) { | ||
170 | rx_buf = &(rds_ring->rx_buf_arr[i]); | ||
171 | if (rx_buf->state == NETXEN_BUFFER_FREE) | ||
172 | continue; | ||
173 | pci_unmap_single(adapter->pdev, | ||
174 | rx_buf->dma, | ||
175 | rds_ring->dma_size, | ||
176 | PCI_DMA_FROMDEVICE); | ||
177 | if (rx_buf->skb != NULL) | ||
178 | dev_kfree_skb_any(rx_buf->skb); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | } | ||
159 | 183 | ||
160 | void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, | 184 | void netxen_release_tx_buffers(struct netxen_adapter *adapter) |
161 | struct pci_dev **used_dev) | ||
162 | { | 185 | { |
163 | void *addr; | 186 | struct netxen_cmd_buffer *cmd_buf; |
187 | struct netxen_skb_frag *buffrag; | ||
188 | int i, j; | ||
189 | |||
190 | cmd_buf = adapter->cmd_buf_arr; | ||
191 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | ||
192 | buffrag = cmd_buf->frag_array; | ||
193 | if (buffrag->dma) { | ||
194 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
195 | buffrag->length, PCI_DMA_TODEVICE); | ||
196 | buffrag->dma = 0ULL; | ||
197 | } | ||
198 | for (j = 0; j < cmd_buf->frag_count; j++) { | ||
199 | buffrag++; | ||
200 | if (buffrag->dma) { | ||
201 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
202 | buffrag->length, | ||
203 | PCI_DMA_TODEVICE); | ||
204 | buffrag->dma = 0ULL; | ||
205 | } | ||
206 | } | ||
207 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
208 | if (cmd_buf->skb) { | ||
209 | dev_kfree_skb_any(cmd_buf->skb); | ||
210 | cmd_buf->skb = NULL; | ||
211 | } | ||
212 | cmd_buf++; | ||
213 | } | ||
214 | } | ||
164 | 215 | ||
165 | addr = pci_alloc_consistent(pdev, sz, ptr); | 216 | void netxen_free_sw_resources(struct netxen_adapter *adapter) |
166 | if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) { | 217 | { |
167 | *used_dev = pdev; | 218 | struct netxen_recv_context *recv_ctx; |
168 | return addr; | 219 | struct nx_host_rds_ring *rds_ring; |
220 | int ctx, ring; | ||
221 | |||
222 | for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) { | ||
223 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
224 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
225 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
226 | if (rds_ring->rx_buf_arr) { | ||
227 | vfree(rds_ring->rx_buf_arr); | ||
228 | rds_ring->rx_buf_arr = NULL; | ||
229 | } | ||
230 | } | ||
169 | } | 231 | } |
170 | pci_free_consistent(pdev, sz, addr, *ptr); | 232 | if (adapter->cmd_buf_arr) |
171 | addr = pci_alloc_consistent(NULL, sz, ptr); | 233 | vfree(adapter->cmd_buf_arr); |
172 | *used_dev = NULL; | 234 | return; |
173 | return addr; | ||
174 | } | 235 | } |
175 | 236 | ||
176 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | 237 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) |
177 | { | 238 | { |
178 | int ctxid, ring; | 239 | struct netxen_recv_context *recv_ctx; |
179 | u32 i; | 240 | struct nx_host_rds_ring *rds_ring; |
180 | u32 num_rx_bufs = 0; | 241 | struct netxen_rx_buffer *rx_buf; |
181 | struct netxen_rcv_desc_ctx *rcv_desc; | 242 | int ctx, ring, i, num_rx_bufs; |
182 | 243 | ||
183 | DPRINTK(INFO, "initializing some queues: %p\n", adapter); | 244 | struct netxen_cmd_buffer *cmd_buf_arr; |
184 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | 245 | struct net_device *netdev = adapter->netdev; |
185 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 246 | |
186 | struct netxen_rx_buffer *rx_buf; | 247 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); |
187 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; | 248 | if (cmd_buf_arr == NULL) { |
188 | rcv_desc->begin_alloc = 0; | 249 | printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n", |
189 | rx_buf = rcv_desc->rx_buf_arr; | 250 | netdev->name); |
190 | num_rx_bufs = rcv_desc->max_rx_desc_count; | 251 | return -ENOMEM; |
252 | } | ||
253 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
254 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
255 | |||
256 | for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) { | ||
257 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
258 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
259 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
260 | switch (RCV_DESC_TYPE(ring)) { | ||
261 | case RCV_DESC_NORMAL: | ||
262 | rds_ring->max_rx_desc_count = | ||
263 | adapter->max_rx_desc_count; | ||
264 | rds_ring->flags = RCV_DESC_NORMAL; | ||
265 | if (adapter->ahw.cut_through) { | ||
266 | rds_ring->dma_size = | ||
267 | NX_CT_DEFAULT_RX_BUF_LEN; | ||
268 | rds_ring->skb_size = | ||
269 | NX_CT_DEFAULT_RX_BUF_LEN; | ||
270 | } else { | ||
271 | rds_ring->dma_size = RX_DMA_MAP_LEN; | ||
272 | rds_ring->skb_size = | ||
273 | MAX_RX_BUFFER_LENGTH; | ||
274 | } | ||
275 | break; | ||
276 | |||
277 | case RCV_DESC_JUMBO: | ||
278 | rds_ring->max_rx_desc_count = | ||
279 | adapter->max_jumbo_rx_desc_count; | ||
280 | rds_ring->flags = RCV_DESC_JUMBO; | ||
281 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
282 | rds_ring->dma_size = | ||
283 | NX_P3_RX_JUMBO_BUF_MAX_LEN; | ||
284 | else | ||
285 | rds_ring->dma_size = | ||
286 | NX_P2_RX_JUMBO_BUF_MAX_LEN; | ||
287 | rds_ring->skb_size = | ||
288 | rds_ring->dma_size + NET_IP_ALIGN; | ||
289 | break; | ||
290 | |||
291 | case RCV_RING_LRO: | ||
292 | rds_ring->max_rx_desc_count = | ||
293 | adapter->max_lro_rx_desc_count; | ||
294 | rds_ring->flags = RCV_DESC_LRO; | ||
295 | rds_ring->dma_size = RX_LRO_DMA_MAP_LEN; | ||
296 | rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
297 | break; | ||
298 | |||
299 | } | ||
300 | rds_ring->rx_buf_arr = (struct netxen_rx_buffer *) | ||
301 | vmalloc(RCV_BUFFSIZE); | ||
302 | if (rds_ring->rx_buf_arr == NULL) { | ||
303 | printk(KERN_ERR "%s: Failed to allocate " | ||
304 | "rx buffer ring %d\n", | ||
305 | netdev->name, ring); | ||
306 | /* free whatever was already allocated */ | ||
307 | goto err_out; | ||
308 | } | ||
309 | memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
310 | INIT_LIST_HEAD(&rds_ring->free_list); | ||
311 | rds_ring->begin_alloc = 0; | ||
191 | /* | 312 | /* |
192 | * Now go through all of them, set reference handles | 313 | * Now go through all of them, set reference handles |
193 | * and put them in the queues. | 314 | * and put them in the queues. |
194 | */ | 315 | */ |
316 | num_rx_bufs = rds_ring->max_rx_desc_count; | ||
317 | rx_buf = rds_ring->rx_buf_arr; | ||
195 | for (i = 0; i < num_rx_bufs; i++) { | 318 | for (i = 0; i < num_rx_bufs; i++) { |
319 | list_add_tail(&rx_buf->list, | ||
320 | &rds_ring->free_list); | ||
196 | rx_buf->ref_handle = i; | 321 | rx_buf->ref_handle = i; |
197 | rx_buf->state = NETXEN_BUFFER_FREE; | 322 | rx_buf->state = NETXEN_BUFFER_FREE; |
198 | DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:" | ||
199 | "%p\n", ctxid, i, rx_buf); | ||
200 | rx_buf++; | 323 | rx_buf++; |
201 | } | 324 | } |
202 | } | 325 | } |
203 | } | 326 | } |
327 | |||
328 | return 0; | ||
329 | |||
330 | err_out: | ||
331 | netxen_free_sw_resources(adapter); | ||
332 | return -ENOMEM; | ||
204 | } | 333 | } |
205 | 334 | ||
206 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | 335 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) |
@@ -211,14 +340,12 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | |||
211 | netxen_niu_gbe_enable_phy_interrupts; | 340 | netxen_niu_gbe_enable_phy_interrupts; |
212 | adapter->disable_phy_interrupts = | 341 | adapter->disable_phy_interrupts = |
213 | netxen_niu_gbe_disable_phy_interrupts; | 342 | netxen_niu_gbe_disable_phy_interrupts; |
214 | adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr; | ||
215 | adapter->macaddr_set = netxen_niu_macaddr_set; | 343 | adapter->macaddr_set = netxen_niu_macaddr_set; |
216 | adapter->set_mtu = netxen_nic_set_mtu_gb; | 344 | adapter->set_mtu = netxen_nic_set_mtu_gb; |
217 | adapter->set_promisc = netxen_niu_set_promiscuous_mode; | 345 | adapter->set_promisc = netxen_niu_set_promiscuous_mode; |
218 | adapter->unset_promisc = netxen_niu_set_promiscuous_mode; | ||
219 | adapter->phy_read = netxen_niu_gbe_phy_read; | 346 | adapter->phy_read = netxen_niu_gbe_phy_read; |
220 | adapter->phy_write = netxen_niu_gbe_phy_write; | 347 | adapter->phy_write = netxen_niu_gbe_phy_write; |
221 | adapter->init_niu = netxen_nic_init_niu_gb; | 348 | adapter->init_port = netxen_niu_gbe_init_port; |
222 | adapter->stop_port = netxen_niu_disable_gbe_port; | 349 | adapter->stop_port = netxen_niu_disable_gbe_port; |
223 | break; | 350 | break; |
224 | 351 | ||
@@ -227,12 +354,10 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | |||
227 | netxen_niu_xgbe_enable_phy_interrupts; | 354 | netxen_niu_xgbe_enable_phy_interrupts; |
228 | adapter->disable_phy_interrupts = | 355 | adapter->disable_phy_interrupts = |
229 | netxen_niu_xgbe_disable_phy_interrupts; | 356 | netxen_niu_xgbe_disable_phy_interrupts; |
230 | adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; | ||
231 | adapter->macaddr_set = netxen_niu_xg_macaddr_set; | 357 | adapter->macaddr_set = netxen_niu_xg_macaddr_set; |
232 | adapter->set_mtu = netxen_nic_set_mtu_xgb; | 358 | adapter->set_mtu = netxen_nic_set_mtu_xgb; |
233 | adapter->init_port = netxen_niu_xg_init_port; | 359 | adapter->init_port = netxen_niu_xg_init_port; |
234 | adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode; | 360 | adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode; |
235 | adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode; | ||
236 | adapter->stop_port = netxen_niu_disable_xg_port; | 361 | adapter->stop_port = netxen_niu_disable_xg_port; |
237 | break; | 362 | break; |
238 | 363 | ||
@@ -270,7 +395,9 @@ static u32 netxen_decode_crb_addr(u32 addr) | |||
270 | 395 | ||
271 | static long rom_max_timeout = 100; | 396 | static long rom_max_timeout = 100; |
272 | static long rom_lock_timeout = 10000; | 397 | static long rom_lock_timeout = 10000; |
398 | #if 0 | ||
273 | static long rom_write_timeout = 700; | 399 | static long rom_write_timeout = 700; |
400 | #endif | ||
274 | 401 | ||
275 | static int rom_lock(struct netxen_adapter *adapter) | 402 | static int rom_lock(struct netxen_adapter *adapter) |
276 | { | 403 | { |
@@ -319,6 +446,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) | |||
319 | return 0; | 446 | return 0; |
320 | } | 447 | } |
321 | 448 | ||
449 | #if 0 | ||
322 | static int netxen_rom_wren(struct netxen_adapter *adapter) | 450 | static int netxen_rom_wren(struct netxen_adapter *adapter) |
323 | { | 451 | { |
324 | /* Set write enable latch in ROM status register */ | 452 | /* Set write enable latch in ROM status register */ |
@@ -348,6 +476,7 @@ static int netxen_do_rom_rdsr(struct netxen_adapter *adapter) | |||
348 | } | 476 | } |
349 | return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA); | 477 | return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA); |
350 | } | 478 | } |
479 | #endif | ||
351 | 480 | ||
352 | static void netxen_rom_unlock(struct netxen_adapter *adapter) | 481 | static void netxen_rom_unlock(struct netxen_adapter *adapter) |
353 | { | 482 | { |
@@ -358,6 +487,7 @@ static void netxen_rom_unlock(struct netxen_adapter *adapter) | |||
358 | 487 | ||
359 | } | 488 | } |
360 | 489 | ||
490 | #if 0 | ||
361 | static int netxen_rom_wip_poll(struct netxen_adapter *adapter) | 491 | static int netxen_rom_wip_poll(struct netxen_adapter *adapter) |
362 | { | 492 | { |
363 | long timeout = 0; | 493 | long timeout = 0; |
@@ -393,6 +523,7 @@ static int do_rom_fast_write(struct netxen_adapter *adapter, int addr, | |||
393 | 523 | ||
394 | return netxen_rom_wip_poll(adapter); | 524 | return netxen_rom_wip_poll(adapter); |
395 | } | 525 | } |
526 | #endif | ||
396 | 527 | ||
397 | static int do_rom_fast_read(struct netxen_adapter *adapter, | 528 | static int do_rom_fast_read(struct netxen_adapter *adapter, |
398 | int addr, int *valp) | 529 | int addr, int *valp) |
@@ -475,7 +606,6 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) | |||
475 | netxen_rom_unlock(adapter); | 606 | netxen_rom_unlock(adapter); |
476 | return ret; | 607 | return ret; |
477 | } | 608 | } |
478 | #endif /* 0 */ | ||
479 | 609 | ||
480 | static int do_rom_fast_write_words(struct netxen_adapter *adapter, | 610 | static int do_rom_fast_write_words(struct netxen_adapter *adapter, |
481 | int addr, u8 *bytes, size_t size) | 611 | int addr, u8 *bytes, size_t size) |
@@ -740,28 +870,25 @@ int netxen_flash_unlock(struct netxen_adapter *adapter) | |||
740 | 870 | ||
741 | return ret; | 871 | return ret; |
742 | } | 872 | } |
873 | #endif /* 0 */ | ||
743 | 874 | ||
744 | #define NETXEN_BOARDTYPE 0x4008 | 875 | #define NETXEN_BOARDTYPE 0x4008 |
745 | #define NETXEN_BOARDNUM 0x400c | 876 | #define NETXEN_BOARDNUM 0x400c |
746 | #define NETXEN_CHIPNUM 0x4010 | 877 | #define NETXEN_CHIPNUM 0x4010 |
747 | #define NETXEN_ROMBUS_RESET 0xFFFFFFFF | ||
748 | #define NETXEN_ROM_FIRST_BARRIER 0x800000000ULL | ||
749 | #define NETXEN_ROM_FOUND_INIT 0x400 | ||
750 | 878 | ||
751 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 879 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) |
752 | { | 880 | { |
753 | int addr, val; | 881 | int addr, val; |
754 | int n, i; | 882 | int i, init_delay = 0; |
755 | int init_delay = 0; | ||
756 | struct crb_addr_pair *buf; | 883 | struct crb_addr_pair *buf; |
884 | unsigned offset, n; | ||
757 | u32 off; | 885 | u32 off; |
758 | 886 | ||
759 | /* resetall */ | 887 | /* resetall */ |
760 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 888 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, |
761 | NETXEN_ROMBUS_RESET); | 889 | 0xffffffff); |
762 | 890 | ||
763 | if (verbose) { | 891 | if (verbose) { |
764 | int val; | ||
765 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) | 892 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) |
766 | printk("P2 ROM board type: 0x%08x\n", val); | 893 | printk("P2 ROM board type: 0x%08x\n", val); |
767 | else | 894 | else |
@@ -776,117 +903,141 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
776 | printk("Could not read chip number\n"); | 903 | printk("Could not read chip number\n"); |
777 | } | 904 | } |
778 | 905 | ||
779 | if (netxen_rom_fast_read(adapter, 0, &n) == 0 | 906 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
780 | && (n & NETXEN_ROM_FIRST_BARRIER)) { | 907 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
781 | n &= ~NETXEN_ROM_ROUNDUP; | 908 | (n != 0xcafecafeUL) || |
782 | if (n < NETXEN_ROM_FOUND_INIT) { | 909 | netxen_rom_fast_read(adapter, 4, &n) != 0) { |
783 | if (verbose) | 910 | printk(KERN_ERR "%s: ERROR Reading crb_init area: " |
784 | printk("%s: %d CRB init values found" | 911 | "n: %08x\n", netxen_nic_driver_name, n); |
785 | " in ROM.\n", netxen_nic_driver_name, n); | ||
786 | } else { | ||
787 | printk("%s:n=0x%x Error! NetXen card flash not" | ||
788 | " initialized.\n", __FUNCTION__, n); | ||
789 | return -EIO; | 912 | return -EIO; |
790 | } | 913 | } |
791 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); | 914 | offset = n & 0xffffU; |
792 | if (buf == NULL) { | 915 | n = (n >> 16) & 0xffffU; |
793 | printk("%s: netxen_pinit_from_rom: Unable to calloc " | 916 | } else { |
794 | "memory.\n", netxen_nic_driver_name); | 917 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
795 | return -ENOMEM; | 918 | !(n & 0x80000000)) { |
796 | } | 919 | printk(KERN_ERR "%s: ERROR Reading crb_init area: " |
797 | for (i = 0; i < n; i++) { | 920 | "n: %08x\n", netxen_nic_driver_name, n); |
798 | if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0 | 921 | return -EIO; |
799 | || netxen_rom_fast_read(adapter, 8 * i + 8, | ||
800 | &addr) != 0) | ||
801 | return -EIO; | ||
802 | |||
803 | buf[i].addr = addr; | ||
804 | buf[i].data = val; | ||
805 | |||
806 | if (verbose) | ||
807 | printk("%s: PCI: 0x%08x == 0x%08x\n", | ||
808 | netxen_nic_driver_name, (unsigned int) | ||
809 | netxen_decode_crb_addr(addr), val); | ||
810 | } | 922 | } |
811 | for (i = 0; i < n; i++) { | 923 | offset = 1; |
924 | n &= ~0x80000000; | ||
925 | } | ||
926 | |||
927 | if (n < 1024) { | ||
928 | if (verbose) | ||
929 | printk(KERN_DEBUG "%s: %d CRB init values found" | ||
930 | " in ROM.\n", netxen_nic_driver_name, n); | ||
931 | } else { | ||
932 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" | ||
933 | " initialized.\n", __func__, n); | ||
934 | return -EIO; | ||
935 | } | ||
936 | |||
937 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); | ||
938 | if (buf == NULL) { | ||
939 | printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n", | ||
940 | netxen_nic_driver_name); | ||
941 | return -ENOMEM; | ||
942 | } | ||
943 | for (i = 0; i < n; i++) { | ||
944 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || | ||
945 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) | ||
946 | return -EIO; | ||
947 | |||
948 | buf[i].addr = addr; | ||
949 | buf[i].data = val; | ||
812 | 950 | ||
813 | off = netxen_decode_crb_addr(buf[i].addr); | 951 | if (verbose) |
814 | if (off == NETXEN_ADDR_ERROR) { | 952 | printk(KERN_DEBUG "%s: PCI: 0x%08x == 0x%08x\n", |
815 | printk(KERN_ERR"CRB init value out of range %x\n", | 953 | netxen_nic_driver_name, |
954 | (u32)netxen_decode_crb_addr(addr), val); | ||
955 | } | ||
956 | for (i = 0; i < n; i++) { | ||
957 | |||
958 | off = netxen_decode_crb_addr(buf[i].addr); | ||
959 | if (off == NETXEN_ADDR_ERROR) { | ||
960 | printk(KERN_ERR"CRB init value out of range %x\n", | ||
816 | buf[i].addr); | 961 | buf[i].addr); |
962 | continue; | ||
963 | } | ||
964 | off += NETXEN_PCI_CRBSPACE; | ||
965 | /* skipping cold reboot MAGIC */ | ||
966 | if (off == NETXEN_CAM_RAM(0x1fc)) | ||
967 | continue; | ||
968 | |||
969 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
970 | /* do not reset PCI */ | ||
971 | if (off == (ROMUSB_GLB + 0xbc)) | ||
817 | continue; | 972 | continue; |
818 | } | 973 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) |
819 | off += NETXEN_PCI_CRBSPACE; | 974 | buf[i].data = 0x1020; |
820 | /* skipping cold reboot MAGIC */ | 975 | /* skip the function enable register */ |
821 | if (off == NETXEN_CAM_RAM(0x1fc)) | 976 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) |
977 | continue; | ||
978 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2)) | ||
822 | continue; | 979 | continue; |
980 | if ((off & 0x0ff00000) == NETXEN_CRB_SMB) | ||
981 | continue; | ||
982 | } | ||
823 | 983 | ||
824 | /* After writing this register, HW needs time for CRB */ | 984 | if (off == NETXEN_ADDR_ERROR) { |
825 | /* to quiet down (else crb_window returns 0xffffffff) */ | 985 | printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n", |
826 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { | 986 | netxen_nic_driver_name, buf[i].addr); |
827 | init_delay = 1; | 987 | continue; |
988 | } | ||
989 | |||
990 | /* After writing this register, HW needs time for CRB */ | ||
991 | /* to quiet down (else crb_window returns 0xffffffff) */ | ||
992 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { | ||
993 | init_delay = 1; | ||
994 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
828 | /* hold xdma in reset also */ | 995 | /* hold xdma in reset also */ |
829 | buf[i].data = NETXEN_NIC_XDMA_RESET; | 996 | buf[i].data = NETXEN_NIC_XDMA_RESET; |
830 | } | 997 | } |
998 | } | ||
831 | 999 | ||
832 | if (ADDR_IN_WINDOW1(off)) { | 1000 | adapter->hw_write_wx(adapter, off, &buf[i].data, 4); |
833 | writel(buf[i].data, | ||
834 | NETXEN_CRB_NORMALIZE(adapter, off)); | ||
835 | } else { | ||
836 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
837 | writel(buf[i].data, | ||
838 | pci_base_offset(adapter, off)); | ||
839 | 1001 | ||
840 | netxen_nic_pci_change_crbwindow(adapter, 1); | 1002 | if (init_delay == 1) { |
841 | } | 1003 | msleep(1000); |
842 | if (init_delay == 1) { | 1004 | init_delay = 0; |
843 | msleep(1000); | ||
844 | init_delay = 0; | ||
845 | } | ||
846 | msleep(1); | ||
847 | } | 1005 | } |
848 | kfree(buf); | 1006 | msleep(1); |
1007 | } | ||
1008 | kfree(buf); | ||
849 | 1009 | ||
850 | /* disable_peg_cache_all */ | 1010 | /* disable_peg_cache_all */ |
851 | 1011 | ||
852 | /* unreset_net_cache */ | 1012 | /* unreset_net_cache */ |
853 | netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val, | 1013 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
854 | 4); | 1014 | adapter->hw_read_wx(adapter, |
855 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 1015 | NETXEN_ROMUSB_GLB_SW_RESET, &val, 4); |
856 | (val & 0xffffff0f)); | ||
857 | /* p2dn replyCount */ | ||
858 | netxen_crb_writelit_adapter(adapter, | ||
859 | NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); | ||
860 | /* disable_peg_cache 0 */ | ||
861 | netxen_crb_writelit_adapter(adapter, | 1016 | netxen_crb_writelit_adapter(adapter, |
862 | NETXEN_CRB_PEG_NET_D + 0x4c, 8); | 1017 | NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); |
863 | /* disable_peg_cache 1 */ | ||
864 | netxen_crb_writelit_adapter(adapter, | ||
865 | NETXEN_CRB_PEG_NET_I + 0x4c, 8); | ||
866 | |||
867 | /* peg_clr_all */ | ||
868 | |||
869 | /* peg_clr 0 */ | ||
870 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, | ||
871 | 0); | ||
872 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, | ||
873 | 0); | ||
874 | /* peg_clr 1 */ | ||
875 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, | ||
876 | 0); | ||
877 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, | ||
878 | 0); | ||
879 | /* peg_clr 2 */ | ||
880 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, | ||
881 | 0); | ||
882 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, | ||
883 | 0); | ||
884 | /* peg_clr 3 */ | ||
885 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, | ||
886 | 0); | ||
887 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, | ||
888 | 0); | ||
889 | } | 1018 | } |
1019 | |||
1020 | /* p2dn replyCount */ | ||
1021 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); | ||
1022 | /* disable_peg_cache 0 */ | ||
1023 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8); | ||
1024 | /* disable_peg_cache 1 */ | ||
1025 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8); | ||
1026 | |||
1027 | /* peg_clr_all */ | ||
1028 | |||
1029 | /* peg_clr 0 */ | ||
1030 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0); | ||
1031 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0); | ||
1032 | /* peg_clr 1 */ | ||
1033 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0); | ||
1034 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0); | ||
1035 | /* peg_clr 2 */ | ||
1036 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0); | ||
1037 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0); | ||
1038 | /* peg_clr 3 */ | ||
1039 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0); | ||
1040 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0); | ||
890 | return 0; | 1041 | return 0; |
891 | } | 1042 | } |
892 | 1043 | ||
@@ -897,12 +1048,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
897 | uint32_t lo; | 1048 | uint32_t lo; |
898 | 1049 | ||
899 | adapter->dummy_dma.addr = | 1050 | adapter->dummy_dma.addr = |
900 | pci_alloc_consistent(adapter->ahw.pdev, | 1051 | pci_alloc_consistent(adapter->pdev, |
901 | NETXEN_HOST_DUMMY_DMA_SIZE, | 1052 | NETXEN_HOST_DUMMY_DMA_SIZE, |
902 | &adapter->dummy_dma.phys_addr); | 1053 | &adapter->dummy_dma.phys_addr); |
903 | if (adapter->dummy_dma.addr == NULL) { | 1054 | if (adapter->dummy_dma.addr == NULL) { |
904 | printk("%s: ERROR: Could not allocate dummy DMA memory\n", | 1055 | printk("%s: ERROR: Could not allocate dummy DMA memory\n", |
905 | __FUNCTION__); | 1056 | __func__); |
906 | return -ENOMEM; | 1057 | return -ENOMEM; |
907 | } | 1058 | } |
908 | 1059 | ||
@@ -910,8 +1061,13 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
910 | hi = (addr >> 32) & 0xffffffff; | 1061 | hi = (addr >> 32) & 0xffffffff; |
911 | lo = addr & 0xffffffff; | 1062 | lo = addr & 0xffffffff; |
912 | 1063 | ||
913 | writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI)); | 1064 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); |
914 | writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO)); | 1065 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); |
1066 | |||
1067 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
1068 | uint32_t temp = 0; | ||
1069 | adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4); | ||
1070 | } | ||
915 | 1071 | ||
916 | return 0; | 1072 | return 0; |
917 | } | 1073 | } |
@@ -931,7 +1087,7 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) | |||
931 | } while (--i); | 1087 | } while (--i); |
932 | 1088 | ||
933 | if (i) { | 1089 | if (i) { |
934 | pci_free_consistent(adapter->ahw.pdev, | 1090 | pci_free_consistent(adapter->pdev, |
935 | NETXEN_HOST_DUMMY_DMA_SIZE, | 1091 | NETXEN_HOST_DUMMY_DMA_SIZE, |
936 | adapter->dummy_dma.addr, | 1092 | adapter->dummy_dma.addr, |
937 | adapter->dummy_dma.phys_addr); | 1093 | adapter->dummy_dma.phys_addr); |
@@ -946,22 +1102,24 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) | |||
946 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | 1102 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) |
947 | { | 1103 | { |
948 | u32 val = 0; | 1104 | u32 val = 0; |
949 | int retries = 30; | 1105 | int retries = 60; |
950 | 1106 | ||
951 | if (!pegtune_val) { | 1107 | if (!pegtune_val) { |
952 | do { | 1108 | do { |
953 | val = readl(NETXEN_CRB_NORMALIZE | 1109 | val = adapter->pci_read_normalize(adapter, |
954 | (adapter, CRB_CMDPEG_STATE)); | 1110 | CRB_CMDPEG_STATE); |
955 | pegtune_val = readl(NETXEN_CRB_NORMALIZE | ||
956 | (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
957 | 1111 | ||
958 | if (val == PHAN_INITIALIZE_COMPLETE || | 1112 | if (val == PHAN_INITIALIZE_COMPLETE || |
959 | val == PHAN_INITIALIZE_ACK) | 1113 | val == PHAN_INITIALIZE_ACK) |
960 | return 0; | 1114 | return 0; |
961 | 1115 | ||
962 | msleep(1000); | 1116 | msleep(500); |
1117 | |||
963 | } while (--retries); | 1118 | } while (--retries); |
1119 | |||
964 | if (!retries) { | 1120 | if (!retries) { |
1121 | pegtune_val = adapter->pci_read_normalize(adapter, | ||
1122 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE); | ||
965 | printk(KERN_WARNING "netxen_phantom_init: init failed, " | 1123 | printk(KERN_WARNING "netxen_phantom_init: init failed, " |
966 | "pegtune_val=%x\n", pegtune_val); | 1124 | "pegtune_val=%x\n", pegtune_val); |
967 | return -1; | 1125 | return -1; |
@@ -971,58 +1129,61 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | |||
971 | return 0; | 1129 | return 0; |
972 | } | 1130 | } |
973 | 1131 | ||
974 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | 1132 | int netxen_receive_peg_ready(struct netxen_adapter *adapter) |
975 | { | 1133 | { |
976 | struct net_device *netdev = adapter->netdev; | 1134 | u32 val = 0; |
977 | uint32_t temp, temp_state, temp_val; | 1135 | int retries = 2000; |
978 | int rv = 0; | 1136 | |
979 | 1137 | do { | |
980 | temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE)); | 1138 | val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE); |
981 | 1139 | ||
982 | temp_state = nx_get_temp_state(temp); | 1140 | if (val == PHAN_PEG_RCV_INITIALIZED) |
983 | temp_val = nx_get_temp_val(temp); | 1141 | return 0; |
984 | 1142 | ||
985 | if (temp_state == NX_TEMP_PANIC) { | 1143 | msleep(10); |
986 | printk(KERN_ALERT | 1144 | |
987 | "%s: Device temperature %d degrees C exceeds" | 1145 | } while (--retries); |
988 | " maximum allowed. Hardware has been shut down.\n", | 1146 | |
989 | netxen_nic_driver_name, temp_val); | 1147 | if (!retries) { |
990 | 1148 | printk(KERN_ERR "Receive Peg initialization not " | |
991 | netif_carrier_off(netdev); | 1149 | "complete, state: 0x%x.\n", val); |
992 | netif_stop_queue(netdev); | 1150 | return -EIO; |
993 | rv = 1; | ||
994 | } else if (temp_state == NX_TEMP_WARN) { | ||
995 | if (adapter->temp == NX_TEMP_NORMAL) { | ||
996 | printk(KERN_ALERT | ||
997 | "%s: Device temperature %d degrees C " | ||
998 | "exceeds operating range." | ||
999 | " Immediate action needed.\n", | ||
1000 | netxen_nic_driver_name, temp_val); | ||
1001 | } | ||
1002 | } else { | ||
1003 | if (adapter->temp == NX_TEMP_WARN) { | ||
1004 | printk(KERN_INFO | ||
1005 | "%s: Device temperature is now %d degrees C" | ||
1006 | " in normal range.\n", netxen_nic_driver_name, | ||
1007 | temp_val); | ||
1008 | } | ||
1009 | } | 1151 | } |
1010 | adapter->temp = temp_state; | 1152 | |
1011 | return rv; | 1153 | return 0; |
1012 | } | 1154 | } |
1013 | 1155 | ||
1014 | void netxen_watchdog_task(struct work_struct *work) | 1156 | static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter, |
1157 | struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum) | ||
1015 | { | 1158 | { |
1016 | struct netxen_adapter *adapter = | 1159 | struct netxen_rx_buffer *buffer; |
1017 | container_of(work, struct netxen_adapter, watchdog_task); | 1160 | struct sk_buff *skb; |
1018 | 1161 | ||
1019 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1162 | buffer = &rds_ring->rx_buf_arr[index]; |
1020 | return; | 1163 | |
1164 | pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size, | ||
1165 | PCI_DMA_FROMDEVICE); | ||
1021 | 1166 | ||
1022 | if (adapter->handle_phy_intr) | 1167 | skb = buffer->skb; |
1023 | adapter->handle_phy_intr(adapter); | 1168 | if (!skb) |
1169 | goto no_skb; | ||
1024 | 1170 | ||
1025 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 1171 | if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) { |
1172 | adapter->stats.csummed++; | ||
1173 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1174 | } else | ||
1175 | skb->ip_summed = CHECKSUM_NONE; | ||
1176 | |||
1177 | skb->dev = adapter->netdev; | ||
1178 | |||
1179 | buffer->skb = NULL; | ||
1180 | |||
1181 | no_skb: | ||
1182 | buffer->state = NETXEN_BUFFER_FREE; | ||
1183 | buffer->lro_current_frags = 0; | ||
1184 | buffer->lro_expected_frags = 0; | ||
1185 | list_add_tail(&buffer->list, &rds_ring->free_list); | ||
1186 | return skb; | ||
1026 | } | 1187 | } |
1027 | 1188 | ||
1028 | /* | 1189 | /* |
@@ -1031,9 +1192,8 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1031 | * invoke the routine to send more rx buffers to the Phantom... | 1192 | * invoke the routine to send more rx buffers to the Phantom... |
1032 | */ | 1193 | */ |
1033 | static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | 1194 | static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, |
1034 | struct status_desc *desc) | 1195 | struct status_desc *desc, struct status_desc *frag_desc) |
1035 | { | 1196 | { |
1036 | struct pci_dev *pdev = adapter->pdev; | ||
1037 | struct net_device *netdev = adapter->netdev; | 1197 | struct net_device *netdev = adapter->netdev; |
1038 | u64 sts_data = le64_to_cpu(desc->status_desc_data); | 1198 | u64 sts_data = le64_to_cpu(desc->status_desc_data); |
1039 | int index = netxen_get_sts_refhandle(sts_data); | 1199 | int index = netxen_get_sts_refhandle(sts_data); |
@@ -1042,8 +1202,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1042 | struct sk_buff *skb; | 1202 | struct sk_buff *skb; |
1043 | u32 length = netxen_get_sts_totallength(sts_data); | 1203 | u32 length = netxen_get_sts_totallength(sts_data); |
1044 | u32 desc_ctx; | 1204 | u32 desc_ctx; |
1045 | struct netxen_rcv_desc_ctx *rcv_desc; | 1205 | u16 pkt_offset = 0, cksum; |
1046 | int ret; | 1206 | struct nx_host_rds_ring *rds_ring; |
1047 | 1207 | ||
1048 | desc_ctx = netxen_get_sts_type(sts_data); | 1208 | desc_ctx = netxen_get_sts_type(sts_data); |
1049 | if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { | 1209 | if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { |
@@ -1052,13 +1212,13 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1052 | return; | 1212 | return; |
1053 | } | 1213 | } |
1054 | 1214 | ||
1055 | rcv_desc = &recv_ctx->rcv_desc[desc_ctx]; | 1215 | rds_ring = &recv_ctx->rds_rings[desc_ctx]; |
1056 | if (unlikely(index > rcv_desc->max_rx_desc_count)) { | 1216 | if (unlikely(index > rds_ring->max_rx_desc_count)) { |
1057 | DPRINTK(ERR, "Got a buffer index:%x Max is %x\n", | 1217 | DPRINTK(ERR, "Got a buffer index:%x Max is %x\n", |
1058 | index, rcv_desc->max_rx_desc_count); | 1218 | index, rds_ring->max_rx_desc_count); |
1059 | return; | 1219 | return; |
1060 | } | 1220 | } |
1061 | buffer = &rcv_desc->rx_buf_arr[index]; | 1221 | buffer = &rds_ring->rx_buf_arr[index]; |
1062 | if (desc_ctx == RCV_DESC_LRO_CTXID) { | 1222 | if (desc_ctx == RCV_DESC_LRO_CTXID) { |
1063 | buffer->lro_current_frags++; | 1223 | buffer->lro_current_frags++; |
1064 | if (netxen_get_sts_desc_lro_last_frag(desc)) { | 1224 | if (netxen_get_sts_desc_lro_last_frag(desc)) { |
@@ -1079,43 +1239,52 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1079 | } | 1239 | } |
1080 | } | 1240 | } |
1081 | 1241 | ||
1082 | pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size, | 1242 | cksum = netxen_get_sts_status(sts_data); |
1083 | PCI_DMA_FROMDEVICE); | ||
1084 | 1243 | ||
1085 | skb = (struct sk_buff *)buffer->skb; | 1244 | skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum); |
1086 | 1245 | if (!skb) | |
1087 | if (likely(adapter->rx_csum && | 1246 | return; |
1088 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { | ||
1089 | adapter->stats.csummed++; | ||
1090 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1091 | } else | ||
1092 | skb->ip_summed = CHECKSUM_NONE; | ||
1093 | 1247 | ||
1094 | skb->dev = netdev; | ||
1095 | if (desc_ctx == RCV_DESC_LRO_CTXID) { | 1248 | if (desc_ctx == RCV_DESC_LRO_CTXID) { |
1096 | /* True length was only available on the last pkt */ | 1249 | /* True length was only available on the last pkt */ |
1097 | skb_put(skb, buffer->lro_length); | 1250 | skb_put(skb, buffer->lro_length); |
1098 | } else { | 1251 | } else { |
1099 | skb_put(skb, length); | 1252 | if (length > rds_ring->skb_size) |
1253 | skb_put(skb, rds_ring->skb_size); | ||
1254 | else | ||
1255 | skb_put(skb, length); | ||
1256 | |||
1257 | pkt_offset = netxen_get_sts_pkt_offset(sts_data); | ||
1258 | if (pkt_offset) | ||
1259 | skb_pull(skb, pkt_offset); | ||
1100 | } | 1260 | } |
1101 | 1261 | ||
1102 | skb->protocol = eth_type_trans(skb, netdev); | 1262 | skb->protocol = eth_type_trans(skb, netdev); |
1103 | 1263 | ||
1104 | ret = netif_receive_skb(skb); | ||
1105 | netdev->last_rx = jiffies; | ||
1106 | |||
1107 | rcv_desc->rcv_pending--; | ||
1108 | |||
1109 | /* | 1264 | /* |
1110 | * We just consumed one buffer so post a buffer. | 1265 | * rx buffer chaining is disabled, walk and free |
1266 | * any spurious rx buffer chain. | ||
1111 | */ | 1267 | */ |
1112 | buffer->skb = NULL; | 1268 | if (frag_desc) { |
1113 | buffer->state = NETXEN_BUFFER_FREE; | 1269 | u16 i, nr_frags = desc->nr_frags; |
1114 | buffer->lro_current_frags = 0; | 1270 | |
1115 | buffer->lro_expected_frags = 0; | 1271 | dev_kfree_skb_any(skb); |
1272 | for (i = 0; i < nr_frags; i++) { | ||
1273 | index = frag_desc->frag_handles[i]; | ||
1274 | skb = netxen_process_rxbuf(adapter, | ||
1275 | rds_ring, index, cksum); | ||
1276 | if (skb) | ||
1277 | dev_kfree_skb_any(skb); | ||
1278 | } | ||
1279 | adapter->stats.rxdropped++; | ||
1280 | } else { | ||
1116 | 1281 | ||
1117 | adapter->stats.no_rcv++; | 1282 | netif_receive_skb(skb); |
1118 | adapter->stats.rxbytes += length; | 1283 | netdev->last_rx = jiffies; |
1284 | |||
1285 | adapter->stats.no_rcv++; | ||
1286 | adapter->stats.rxbytes += length; | ||
1287 | } | ||
1119 | } | 1288 | } |
1120 | 1289 | ||
1121 | /* Process Receive status ring */ | 1290 | /* Process Receive status ring */ |
@@ -1123,10 +1292,11 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1123 | { | 1292 | { |
1124 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); | 1293 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); |
1125 | struct status_desc *desc_head = recv_ctx->rcv_status_desc_head; | 1294 | struct status_desc *desc_head = recv_ctx->rcv_status_desc_head; |
1126 | struct status_desc *desc; /* used to read status desc here */ | 1295 | struct status_desc *desc, *frag_desc; |
1127 | u32 consumer = recv_ctx->status_rx_consumer; | 1296 | u32 consumer = recv_ctx->status_rx_consumer; |
1128 | u32 producer = 0; | ||
1129 | int count = 0, ring; | 1297 | int count = 0, ring; |
1298 | u64 sts_data; | ||
1299 | u16 opcode; | ||
1130 | 1300 | ||
1131 | while (count < max) { | 1301 | while (count < max) { |
1132 | desc = &desc_head[consumer]; | 1302 | desc = &desc_head[consumer]; |
@@ -1135,24 +1305,38 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1135 | netxen_get_sts_owner(desc)); | 1305 | netxen_get_sts_owner(desc)); |
1136 | break; | 1306 | break; |
1137 | } | 1307 | } |
1138 | netxen_process_rcv(adapter, ctxid, desc); | 1308 | |
1309 | sts_data = le64_to_cpu(desc->status_desc_data); | ||
1310 | opcode = netxen_get_sts_opcode(sts_data); | ||
1311 | frag_desc = NULL; | ||
1312 | if (opcode == NETXEN_NIC_RXPKT_DESC) { | ||
1313 | if (desc->nr_frags) { | ||
1314 | consumer = get_next_index(consumer, | ||
1315 | adapter->max_rx_desc_count); | ||
1316 | frag_desc = &desc_head[consumer]; | ||
1317 | netxen_set_sts_owner(frag_desc, | ||
1318 | STATUS_OWNER_PHANTOM); | ||
1319 | } | ||
1320 | } | ||
1321 | |||
1322 | netxen_process_rcv(adapter, ctxid, desc, frag_desc); | ||
1323 | |||
1139 | netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); | 1324 | netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); |
1140 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); | 1325 | |
1326 | consumer = get_next_index(consumer, | ||
1327 | adapter->max_rx_desc_count); | ||
1141 | count++; | 1328 | count++; |
1142 | } | 1329 | } |
1143 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) | 1330 | for (ring = 0; ring < adapter->max_rds_rings; ring++) |
1144 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); | 1331 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); |
1145 | 1332 | ||
1146 | /* update the consumer index in phantom */ | 1333 | /* update the consumer index in phantom */ |
1147 | if (count) { | 1334 | if (count) { |
1148 | recv_ctx->status_rx_consumer = consumer; | 1335 | recv_ctx->status_rx_consumer = consumer; |
1149 | recv_ctx->status_rx_producer = producer; | ||
1150 | 1336 | ||
1151 | /* Window = 1 */ | 1337 | /* Window = 1 */ |
1152 | writel(consumer, | 1338 | adapter->pci_write_normalize(adapter, |
1153 | NETXEN_CRB_NORMALIZE(adapter, | 1339 | recv_ctx->crb_sts_consumer, consumer); |
1154 | recv_crb_registers[adapter->portnum]. | ||
1155 | crb_rcv_status_consumer)); | ||
1156 | } | 1340 | } |
1157 | 1341 | ||
1158 | return count; | 1342 | return count; |
@@ -1231,10 +1415,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1231 | */ | 1415 | */ |
1232 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | 1416 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) |
1233 | { | 1417 | { |
1234 | struct pci_dev *pdev = adapter->ahw.pdev; | 1418 | struct pci_dev *pdev = adapter->pdev; |
1235 | struct sk_buff *skb; | 1419 | struct sk_buff *skb; |
1236 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); | 1420 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); |
1237 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | 1421 | struct nx_host_rds_ring *rds_ring = NULL; |
1238 | uint producer; | 1422 | uint producer; |
1239 | struct rcv_desc *pdesc; | 1423 | struct rcv_desc *pdesc; |
1240 | struct netxen_rx_buffer *buffer; | 1424 | struct netxen_rx_buffer *buffer; |
@@ -1242,41 +1426,36 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
1242 | int index = 0; | 1426 | int index = 0; |
1243 | netxen_ctx_msg msg = 0; | 1427 | netxen_ctx_msg msg = 0; |
1244 | dma_addr_t dma; | 1428 | dma_addr_t dma; |
1429 | struct list_head *head; | ||
1245 | 1430 | ||
1246 | rcv_desc = &recv_ctx->rcv_desc[ringid]; | 1431 | rds_ring = &recv_ctx->rds_rings[ringid]; |
1432 | |||
1433 | producer = rds_ring->producer; | ||
1434 | index = rds_ring->begin_alloc; | ||
1435 | head = &rds_ring->free_list; | ||
1247 | 1436 | ||
1248 | producer = rcv_desc->producer; | ||
1249 | index = rcv_desc->begin_alloc; | ||
1250 | buffer = &rcv_desc->rx_buf_arr[index]; | ||
1251 | /* We can start writing rx descriptors into the phantom memory. */ | 1437 | /* We can start writing rx descriptors into the phantom memory. */ |
1252 | while (buffer->state == NETXEN_BUFFER_FREE) { | 1438 | while (!list_empty(head)) { |
1253 | skb = dev_alloc_skb(rcv_desc->skb_size); | 1439 | |
1440 | skb = dev_alloc_skb(rds_ring->skb_size); | ||
1254 | if (unlikely(!skb)) { | 1441 | if (unlikely(!skb)) { |
1255 | /* | 1442 | rds_ring->begin_alloc = index; |
1256 | * TODO | ||
1257 | * We need to schedule the posting of buffers to the pegs. | ||
1258 | */ | ||
1259 | rcv_desc->begin_alloc = index; | ||
1260 | DPRINTK(ERR, "netxen_post_rx_buffers: " | ||
1261 | " allocated only %d buffers\n", count); | ||
1262 | break; | 1443 | break; |
1263 | } | 1444 | } |
1264 | 1445 | ||
1446 | buffer = list_entry(head->next, struct netxen_rx_buffer, list); | ||
1447 | list_del(&buffer->list); | ||
1448 | |||
1265 | count++; /* now there should be no failure */ | 1449 | count++; /* now there should be no failure */ |
1266 | pdesc = &rcv_desc->desc_head[producer]; | 1450 | pdesc = &rds_ring->desc_head[producer]; |
1267 | 1451 | ||
1268 | #if defined(XGB_DEBUG) | 1452 | if (!adapter->ahw.cut_through) |
1269 | *(unsigned long *)(skb->head) = 0xc0debabe; | 1453 | skb_reserve(skb, 2); |
1270 | if (skb_is_nonlinear(skb)) { | ||
1271 | printk("Allocated SKB @%p is nonlinear\n"); | ||
1272 | } | ||
1273 | #endif | ||
1274 | skb_reserve(skb, 2); | ||
1275 | /* This will be setup when we receive the | 1454 | /* This will be setup when we receive the |
1276 | * buffer after it has been filled FSL TBD TBD | 1455 | * buffer after it has been filled FSL TBD TBD |
1277 | * skb->dev = netdev; | 1456 | * skb->dev = netdev; |
1278 | */ | 1457 | */ |
1279 | dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, | 1458 | dma = pci_map_single(pdev, skb->data, rds_ring->dma_size, |
1280 | PCI_DMA_FROMDEVICE); | 1459 | PCI_DMA_FROMDEVICE); |
1281 | pdesc->addr_buffer = cpu_to_le64(dma); | 1460 | pdesc->addr_buffer = cpu_to_le64(dma); |
1282 | buffer->skb = skb; | 1461 | buffer->skb = skb; |
@@ -1284,112 +1463,101 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
1284 | buffer->dma = dma; | 1463 | buffer->dma = dma; |
1285 | /* make a rcv descriptor */ | 1464 | /* make a rcv descriptor */ |
1286 | pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); | 1465 | pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); |
1287 | pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); | 1466 | pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); |
1288 | DPRINTK(INFO, "done writing descripter\n"); | 1467 | DPRINTK(INFO, "done writing descripter\n"); |
1289 | producer = | 1468 | producer = |
1290 | get_next_index(producer, rcv_desc->max_rx_desc_count); | 1469 | get_next_index(producer, rds_ring->max_rx_desc_count); |
1291 | index = get_next_index(index, rcv_desc->max_rx_desc_count); | 1470 | index = get_next_index(index, rds_ring->max_rx_desc_count); |
1292 | buffer = &rcv_desc->rx_buf_arr[index]; | ||
1293 | } | 1471 | } |
1294 | /* if we did allocate buffers, then write the count to Phantom */ | 1472 | /* if we did allocate buffers, then write the count to Phantom */ |
1295 | if (count) { | 1473 | if (count) { |
1296 | rcv_desc->begin_alloc = index; | 1474 | rds_ring->begin_alloc = index; |
1297 | rcv_desc->rcv_pending += count; | 1475 | rds_ring->producer = producer; |
1298 | rcv_desc->producer = producer; | ||
1299 | /* Window = 1 */ | 1476 | /* Window = 1 */ |
1300 | writel((producer - 1) & | 1477 | adapter->pci_write_normalize(adapter, |
1301 | (rcv_desc->max_rx_desc_count - 1), | 1478 | rds_ring->crb_rcv_producer, |
1302 | NETXEN_CRB_NORMALIZE(adapter, | 1479 | (producer-1) & (rds_ring->max_rx_desc_count-1)); |
1303 | recv_crb_registers[ | 1480 | |
1304 | adapter->portnum]. | 1481 | if (adapter->fw_major < 4) { |
1305 | rcv_desc_crb[ringid]. | ||
1306 | crb_rcv_producer_offset)); | ||
1307 | /* | 1482 | /* |
1308 | * Write a doorbell msg to tell phanmon of change in | 1483 | * Write a doorbell msg to tell phanmon of change in |
1309 | * receive ring producer | 1484 | * receive ring producer |
1485 | * Only for firmware version < 4.0.0 | ||
1310 | */ | 1486 | */ |
1311 | netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID); | 1487 | netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID); |
1312 | netxen_set_msg_privid(msg); | 1488 | netxen_set_msg_privid(msg); |
1313 | netxen_set_msg_count(msg, | 1489 | netxen_set_msg_count(msg, |
1314 | ((producer - | 1490 | ((producer - |
1315 | 1) & (rcv_desc-> | 1491 | 1) & (rds_ring-> |
1316 | max_rx_desc_count - 1))); | 1492 | max_rx_desc_count - 1))); |
1317 | netxen_set_msg_ctxid(msg, adapter->portnum); | 1493 | netxen_set_msg_ctxid(msg, adapter->portnum); |
1318 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); | 1494 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); |
1319 | writel(msg, | 1495 | writel(msg, |
1320 | DB_NORMALIZE(adapter, | 1496 | DB_NORMALIZE(adapter, |
1321 | NETXEN_RCV_PRODUCER_OFFSET)); | 1497 | NETXEN_RCV_PRODUCER_OFFSET)); |
1498 | } | ||
1322 | } | 1499 | } |
1323 | } | 1500 | } |
1324 | 1501 | ||
1325 | static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | 1502 | static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, |
1326 | uint32_t ctx, uint32_t ringid) | 1503 | uint32_t ctx, uint32_t ringid) |
1327 | { | 1504 | { |
1328 | struct pci_dev *pdev = adapter->ahw.pdev; | 1505 | struct pci_dev *pdev = adapter->pdev; |
1329 | struct sk_buff *skb; | 1506 | struct sk_buff *skb; |
1330 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); | 1507 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); |
1331 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | 1508 | struct nx_host_rds_ring *rds_ring = NULL; |
1332 | u32 producer; | 1509 | u32 producer; |
1333 | struct rcv_desc *pdesc; | 1510 | struct rcv_desc *pdesc; |
1334 | struct netxen_rx_buffer *buffer; | 1511 | struct netxen_rx_buffer *buffer; |
1335 | int count = 0; | 1512 | int count = 0; |
1336 | int index = 0; | 1513 | int index = 0; |
1514 | struct list_head *head; | ||
1337 | 1515 | ||
1338 | rcv_desc = &recv_ctx->rcv_desc[ringid]; | 1516 | rds_ring = &recv_ctx->rds_rings[ringid]; |
1339 | 1517 | ||
1340 | producer = rcv_desc->producer; | 1518 | producer = rds_ring->producer; |
1341 | index = rcv_desc->begin_alloc; | 1519 | index = rds_ring->begin_alloc; |
1342 | buffer = &rcv_desc->rx_buf_arr[index]; | 1520 | head = &rds_ring->free_list; |
1343 | /* We can start writing rx descriptors into the phantom memory. */ | 1521 | /* We can start writing rx descriptors into the phantom memory. */ |
1344 | while (buffer->state == NETXEN_BUFFER_FREE) { | 1522 | while (!list_empty(head)) { |
1345 | skb = dev_alloc_skb(rcv_desc->skb_size); | 1523 | |
1524 | skb = dev_alloc_skb(rds_ring->skb_size); | ||
1346 | if (unlikely(!skb)) { | 1525 | if (unlikely(!skb)) { |
1347 | /* | 1526 | rds_ring->begin_alloc = index; |
1348 | * We need to schedule the posting of buffers to the pegs. | ||
1349 | */ | ||
1350 | rcv_desc->begin_alloc = index; | ||
1351 | DPRINTK(ERR, "netxen_post_rx_buffers_nodb: " | ||
1352 | " allocated only %d buffers\n", count); | ||
1353 | break; | 1527 | break; |
1354 | } | 1528 | } |
1529 | |||
1530 | buffer = list_entry(head->next, struct netxen_rx_buffer, list); | ||
1531 | list_del(&buffer->list); | ||
1532 | |||
1355 | count++; /* now there should be no failure */ | 1533 | count++; /* now there should be no failure */ |
1356 | pdesc = &rcv_desc->desc_head[producer]; | 1534 | pdesc = &rds_ring->desc_head[producer]; |
1357 | skb_reserve(skb, 2); | 1535 | if (!adapter->ahw.cut_through) |
1358 | /* | 1536 | skb_reserve(skb, 2); |
1359 | * This will be setup when we receive the | ||
1360 | * buffer after it has been filled | ||
1361 | * skb->dev = netdev; | ||
1362 | */ | ||
1363 | buffer->skb = skb; | 1537 | buffer->skb = skb; |
1364 | buffer->state = NETXEN_BUFFER_BUSY; | 1538 | buffer->state = NETXEN_BUFFER_BUSY; |
1365 | buffer->dma = pci_map_single(pdev, skb->data, | 1539 | buffer->dma = pci_map_single(pdev, skb->data, |
1366 | rcv_desc->dma_size, | 1540 | rds_ring->dma_size, |
1367 | PCI_DMA_FROMDEVICE); | 1541 | PCI_DMA_FROMDEVICE); |
1368 | 1542 | ||
1369 | /* make a rcv descriptor */ | 1543 | /* make a rcv descriptor */ |
1370 | pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); | 1544 | pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); |
1371 | pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); | 1545 | pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); |
1372 | pdesc->addr_buffer = cpu_to_le64(buffer->dma); | 1546 | pdesc->addr_buffer = cpu_to_le64(buffer->dma); |
1373 | DPRINTK(INFO, "done writing descripter\n"); | ||
1374 | producer = | 1547 | producer = |
1375 | get_next_index(producer, rcv_desc->max_rx_desc_count); | 1548 | get_next_index(producer, rds_ring->max_rx_desc_count); |
1376 | index = get_next_index(index, rcv_desc->max_rx_desc_count); | 1549 | index = get_next_index(index, rds_ring->max_rx_desc_count); |
1377 | buffer = &rcv_desc->rx_buf_arr[index]; | 1550 | buffer = &rds_ring->rx_buf_arr[index]; |
1378 | } | 1551 | } |
1379 | 1552 | ||
1380 | /* if we did allocate buffers, then write the count to Phantom */ | 1553 | /* if we did allocate buffers, then write the count to Phantom */ |
1381 | if (count) { | 1554 | if (count) { |
1382 | rcv_desc->begin_alloc = index; | 1555 | rds_ring->begin_alloc = index; |
1383 | rcv_desc->rcv_pending += count; | 1556 | rds_ring->producer = producer; |
1384 | rcv_desc->producer = producer; | ||
1385 | /* Window = 1 */ | 1557 | /* Window = 1 */ |
1386 | writel((producer - 1) & | 1558 | adapter->pci_write_normalize(adapter, |
1387 | (rcv_desc->max_rx_desc_count - 1), | 1559 | rds_ring->crb_rcv_producer, |
1388 | NETXEN_CRB_NORMALIZE(adapter, | 1560 | (producer-1) & (rds_ring->max_rx_desc_count-1)); |
1389 | recv_crb_registers[ | ||
1390 | adapter->portnum]. | ||
1391 | rcv_desc_crb[ringid]. | ||
1392 | crb_rcv_producer_offset)); | ||
1393 | wmb(); | 1561 | wmb(); |
1394 | } | 1562 | } |
1395 | } | 1563 | } |
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c deleted file mode 100644 index 96cec41f9019..000000000000 --- a/drivers/net/netxen/netxen_nic_isr.c +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003 - 2006 NetXen, Inc. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
18 | * MA 02111-1307, USA. | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution | ||
21 | * in the file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * info@netxen.com | ||
25 | * NetXen, | ||
26 | * 3965 Freedom Circle, Fourth floor, | ||
27 | * Santa Clara, CA 95054 | ||
28 | */ | ||
29 | |||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/delay.h> | ||
32 | |||
33 | #include "netxen_nic.h" | ||
34 | #include "netxen_nic_hw.h" | ||
35 | #include "netxen_nic_phan_reg.h" | ||
36 | |||
37 | /* | ||
38 | * netxen_nic_get_stats - Get System Network Statistics | ||
39 | * @netdev: network interface device structure | ||
40 | */ | ||
41 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | ||
42 | { | ||
43 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
44 | struct net_device_stats *stats = &adapter->net_stats; | ||
45 | |||
46 | memset(stats, 0, sizeof(*stats)); | ||
47 | |||
48 | /* total packets received */ | ||
49 | stats->rx_packets = adapter->stats.no_rcv; | ||
50 | /* total packets transmitted */ | ||
51 | stats->tx_packets = adapter->stats.xmitedframes + | ||
52 | adapter->stats.xmitfinished; | ||
53 | /* total bytes received */ | ||
54 | stats->rx_bytes = adapter->stats.rxbytes; | ||
55 | /* total bytes transmitted */ | ||
56 | stats->tx_bytes = adapter->stats.txbytes; | ||
57 | /* bad packets received */ | ||
58 | stats->rx_errors = adapter->stats.rcvdbadskb; | ||
59 | /* packet transmit problems */ | ||
60 | stats->tx_errors = adapter->stats.nocmddescriptor; | ||
61 | /* no space in linux buffers */ | ||
62 | stats->rx_dropped = adapter->stats.rxdropped; | ||
63 | /* no space available in linux */ | ||
64 | stats->tx_dropped = adapter->stats.txdropped; | ||
65 | |||
66 | return stats; | ||
67 | } | ||
68 | |||
69 | static void netxen_indicate_link_status(struct netxen_adapter *adapter, | ||
70 | u32 link) | ||
71 | { | ||
72 | struct net_device *netdev = adapter->netdev; | ||
73 | |||
74 | if (link) | ||
75 | netif_carrier_on(netdev); | ||
76 | else | ||
77 | netif_carrier_off(netdev); | ||
78 | } | ||
79 | |||
80 | #if 0 | ||
81 | void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) | ||
82 | { | ||
83 | __u32 int_src; | ||
84 | |||
85 | /* This should clear the interrupt source */ | ||
86 | if (adapter->phy_read) | ||
87 | adapter->phy_read(adapter, | ||
88 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, | ||
89 | &int_src); | ||
90 | if (int_src == 0) { | ||
91 | DPRINTK(INFO, "No phy interrupts for port #%d\n", portno); | ||
92 | return; | ||
93 | } | ||
94 | if (adapter->disable_phy_interrupts) | ||
95 | adapter->disable_phy_interrupts(adapter); | ||
96 | |||
97 | if (netxen_get_phy_int_jabber(int_src)) | ||
98 | DPRINTK(INFO, "Jabber interrupt \n"); | ||
99 | |||
100 | if (netxen_get_phy_int_polarity_changed(int_src)) | ||
101 | DPRINTK(INFO, "POLARITY CHANGED int \n"); | ||
102 | |||
103 | if (netxen_get_phy_int_energy_detect(int_src)) | ||
104 | DPRINTK(INFO, "ENERGY DETECT INT \n"); | ||
105 | |||
106 | if (netxen_get_phy_int_downshift(int_src)) | ||
107 | DPRINTK(INFO, "DOWNSHIFT INT \n"); | ||
108 | /* write it down later.. */ | ||
109 | if ((netxen_get_phy_int_speed_changed(int_src)) | ||
110 | || (netxen_get_phy_int_link_status_changed(int_src))) { | ||
111 | __u32 status; | ||
112 | |||
113 | DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); | ||
114 | |||
115 | if (adapter->phy_read | ||
116 | && adapter->phy_read(adapter, | ||
117 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | ||
118 | &status) == 0) { | ||
119 | if (netxen_get_phy_int_link_status_changed(int_src)) { | ||
120 | if (netxen_get_phy_link(status)) { | ||
121 | printk(KERN_INFO "%s: %s Link UP\n", | ||
122 | netxen_nic_driver_name, | ||
123 | adapter->netdev->name); | ||
124 | |||
125 | } else { | ||
126 | printk(KERN_INFO "%s: %s Link DOWN\n", | ||
127 | netxen_nic_driver_name, | ||
128 | adapter->netdev->name); | ||
129 | } | ||
130 | netxen_indicate_link_status(adapter, | ||
131 | netxen_get_phy_link | ||
132 | (status)); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | if (adapter->enable_phy_interrupts) | ||
137 | adapter->enable_phy_interrupts(adapter); | ||
138 | } | ||
139 | #endif /* 0 */ | ||
140 | |||
141 | static void netxen_nic_isr_other(struct netxen_adapter *adapter) | ||
142 | { | ||
143 | int portno = adapter->portnum; | ||
144 | u32 val, linkup, qg_linksup; | ||
145 | |||
146 | /* verify the offset */ | ||
147 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | ||
148 | val = val >> adapter->physical_port; | ||
149 | if (val == adapter->ahw.qg_linksup) | ||
150 | return; | ||
151 | |||
152 | qg_linksup = adapter->ahw.qg_linksup; | ||
153 | adapter->ahw.qg_linksup = val; | ||
154 | DPRINTK(INFO, "link update 0x%08x\n", val); | ||
155 | |||
156 | linkup = val & 1; | ||
157 | |||
158 | if (linkup != (qg_linksup & 1)) { | ||
159 | printk(KERN_INFO "%s: %s PORT %d link %s\n", | ||
160 | adapter->netdev->name, | ||
161 | netxen_nic_driver_name, portno, | ||
162 | ((linkup == 0) ? "down" : "up")); | ||
163 | netxen_indicate_link_status(adapter, linkup); | ||
164 | if (linkup) | ||
165 | netxen_nic_set_link_parameters(adapter); | ||
166 | |||
167 | } | ||
168 | } | ||
169 | |||
170 | void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter) | ||
171 | { | ||
172 | netxen_nic_isr_other(adapter); | ||
173 | } | ||
174 | |||
175 | #if 0 | ||
176 | int netxen_nic_link_ok(struct netxen_adapter *adapter) | ||
177 | { | ||
178 | switch (adapter->ahw.board_type) { | ||
179 | case NETXEN_NIC_GBE: | ||
180 | return ((adapter->ahw.qg_linksup) & 1); | ||
181 | |||
182 | case NETXEN_NIC_XGBE: | ||
183 | return ((adapter->ahw.xg_linkup) & 1); | ||
184 | |||
185 | default: | ||
186 | printk(KERN_ERR"%s: Function: %s, Unknown board type\n", | ||
187 | netxen_nic_driver_name, __FUNCTION__); | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | #endif /* 0 */ | ||
194 | |||
195 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | ||
196 | { | ||
197 | struct net_device *netdev = adapter->netdev; | ||
198 | u32 val; | ||
199 | |||
200 | /* WINDOW = 1 */ | ||
201 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | ||
202 | val >>= (adapter->physical_port * 8); | ||
203 | val &= 0xff; | ||
204 | |||
205 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { | ||
206 | printk(KERN_INFO "%s: %s NIC Link is down\n", | ||
207 | netxen_nic_driver_name, netdev->name); | ||
208 | adapter->ahw.xg_linkup = 0; | ||
209 | if (netif_running(netdev)) { | ||
210 | netif_carrier_off(netdev); | ||
211 | netif_stop_queue(netdev); | ||
212 | } | ||
213 | } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { | ||
214 | printk(KERN_INFO "%s: %s NIC Link is up\n", | ||
215 | netxen_nic_driver_name, netdev->name); | ||
216 | adapter->ahw.xg_linkup = 1; | ||
217 | netif_carrier_on(netdev); | ||
218 | netif_wake_queue(netdev); | ||
219 | } | ||
220 | } | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 63cd67b931e7..91d209a8f6cb 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -49,13 +49,18 @@ char netxen_nic_driver_name[] = "netxen_nic"; | |||
49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " | 49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " |
50 | NETXEN_NIC_LINUX_VERSIONID; | 50 | NETXEN_NIC_LINUX_VERSIONID; |
51 | 51 | ||
52 | #define NETXEN_NETDEV_WEIGHT 120 | 52 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; |
53 | #define NETXEN_ADAPTER_UP_MAGIC 777 | 53 | |
54 | #define NETXEN_NIC_PEG_TUNE 0 | 54 | /* Default to restricted 1G auto-neg mode */ |
55 | static int wol_port_mode = 5; | ||
56 | |||
57 | static int use_msi = 1; | ||
58 | |||
59 | static int use_msi_x = 1; | ||
55 | 60 | ||
56 | /* Local functions to NetXen NIC driver */ | 61 | /* Local functions to NetXen NIC driver */ |
57 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 62 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
58 | const struct pci_device_id *ent); | 63 | const struct pci_device_id *ent); |
59 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 64 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
60 | static int netxen_nic_open(struct net_device *netdev); | 65 | static int netxen_nic_open(struct net_device *netdev); |
61 | static int netxen_nic_close(struct net_device *netdev); | 66 | static int netxen_nic_close(struct net_device *netdev); |
@@ -83,6 +88,7 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | |||
83 | ENTRY(0x0005), | 88 | ENTRY(0x0005), |
84 | ENTRY(0x0024), | 89 | ENTRY(0x0024), |
85 | ENTRY(0x0025), | 90 | ENTRY(0x0025), |
91 | ENTRY(0x0100), | ||
86 | {0,} | 92 | {0,} |
87 | }; | 93 | }; |
88 | 94 | ||
@@ -108,95 +114,61 @@ static struct workqueue_struct *netxen_workq; | |||
108 | 114 | ||
109 | static void netxen_watchdog(unsigned long); | 115 | static void netxen_watchdog(unsigned long); |
110 | 116 | ||
111 | static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 117 | static uint32_t crb_cmd_producer[4] = { |
112 | uint32_t crb_producer) | 118 | CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1, |
119 | CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3 | ||
120 | }; | ||
121 | |||
122 | void | ||
123 | netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | ||
124 | uint32_t crb_producer) | ||
113 | { | 125 | { |
114 | switch (adapter->portnum) { | 126 | adapter->pci_write_normalize(adapter, |
115 | case 0: | 127 | adapter->crb_addr_cmd_producer, crb_producer); |
116 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
117 | (adapter, CRB_CMD_PRODUCER_OFFSET)); | ||
118 | return; | ||
119 | case 1: | ||
120 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
121 | (adapter, CRB_CMD_PRODUCER_OFFSET_1)); | ||
122 | return; | ||
123 | case 2: | ||
124 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
125 | (adapter, CRB_CMD_PRODUCER_OFFSET_2)); | ||
126 | return; | ||
127 | case 3: | ||
128 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
129 | (adapter, CRB_CMD_PRODUCER_OFFSET_3)); | ||
130 | return; | ||
131 | default: | ||
132 | printk(KERN_WARNING "We tried to update " | ||
133 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
134 | "PCI function id %d\n", | ||
135 | adapter->portnum); | ||
136 | return; | ||
137 | } | ||
138 | } | 128 | } |
139 | 129 | ||
140 | static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | 130 | static uint32_t crb_cmd_consumer[4] = { |
141 | u32 crb_consumer) | 131 | CRB_CMD_CONSUMER_OFFSET, CRB_CMD_CONSUMER_OFFSET_1, |
132 | CRB_CMD_CONSUMER_OFFSET_2, CRB_CMD_CONSUMER_OFFSET_3 | ||
133 | }; | ||
134 | |||
135 | static inline void | ||
136 | netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | ||
137 | u32 crb_consumer) | ||
142 | { | 138 | { |
143 | switch (adapter->portnum) { | 139 | adapter->pci_write_normalize(adapter, |
144 | case 0: | 140 | adapter->crb_addr_cmd_consumer, crb_consumer); |
145 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
146 | (adapter, CRB_CMD_CONSUMER_OFFSET)); | ||
147 | return; | ||
148 | case 1: | ||
149 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
150 | (adapter, CRB_CMD_CONSUMER_OFFSET_1)); | ||
151 | return; | ||
152 | case 2: | ||
153 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
154 | (adapter, CRB_CMD_CONSUMER_OFFSET_2)); | ||
155 | return; | ||
156 | case 3: | ||
157 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
158 | (adapter, CRB_CMD_CONSUMER_OFFSET_3)); | ||
159 | return; | ||
160 | default: | ||
161 | printk(KERN_WARNING "We tried to update " | ||
162 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
163 | "PCI function id %d\n", | ||
164 | adapter->portnum); | ||
165 | return; | ||
166 | } | ||
167 | } | 141 | } |
168 | 142 | ||
169 | #define ADAPTER_LIST_SIZE 12 | 143 | static uint32_t msi_tgt_status[8] = { |
170 | |||
171 | static uint32_t msi_tgt_status[4] = { | ||
172 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | 144 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, |
173 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | 145 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, |
146 | ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, | ||
147 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | ||
174 | }; | 148 | }; |
175 | 149 | ||
176 | static uint32_t sw_int_mask[4] = { | 150 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; |
177 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
178 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
179 | }; | ||
180 | 151 | ||
181 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 152 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
182 | { | 153 | { |
183 | u32 mask = 0x7ff; | 154 | u32 mask = 0x7ff; |
184 | int retries = 32; | 155 | int retries = 32; |
185 | int port = adapter->portnum; | ||
186 | int pci_fn = adapter->ahw.pci_func; | 156 | int pci_fn = adapter->ahw.pci_func; |
187 | 157 | ||
188 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) | 158 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) |
189 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | 159 | adapter->pci_write_normalize(adapter, |
160 | adapter->crb_intr_mask, 0); | ||
190 | 161 | ||
191 | if (adapter->intr_scheme != -1 && | 162 | if (adapter->intr_scheme != -1 && |
192 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 163 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
193 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 164 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
194 | 165 | ||
195 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 166 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
196 | do { | 167 | do { |
197 | writel(0xffffffff, | 168 | adapter->pci_write_immediate(adapter, |
198 | PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)); | 169 | ISR_INT_TARGET_STATUS, 0xffffffff); |
199 | mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); | 170 | mask = adapter->pci_read_immediate(adapter, |
171 | ISR_INT_VECTOR); | ||
200 | if (!(mask & 0x80)) | 172 | if (!(mask & 0x80)) |
201 | break; | 173 | break; |
202 | udelay(10); | 174 | udelay(10); |
@@ -208,8 +180,8 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
208 | } | 180 | } |
209 | } else { | 181 | } else { |
210 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { | 182 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { |
211 | writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, | 183 | adapter->pci_write_immediate(adapter, |
212 | msi_tgt_status[pci_fn])); | 184 | msi_tgt_status[pci_fn], 0xffffffff); |
213 | } | 185 | } |
214 | } | 186 | } |
215 | } | 187 | } |
@@ -217,7 +189,6 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
217 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) | 189 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) |
218 | { | 190 | { |
219 | u32 mask; | 191 | u32 mask; |
220 | int port = adapter->portnum; | ||
221 | 192 | ||
222 | DPRINTK(1, INFO, "Entered ISR Enable \n"); | 193 | DPRINTK(1, INFO, "Entered ISR Enable \n"); |
223 | 194 | ||
@@ -235,24 +206,299 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
235 | break; | 206 | break; |
236 | } | 207 | } |
237 | 208 | ||
238 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 209 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
239 | } | 210 | } |
240 | 211 | ||
241 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | 212 | adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); |
242 | 213 | ||
243 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 214 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
244 | mask = 0xbff; | 215 | mask = 0xbff; |
245 | if (adapter->intr_scheme != -1 && | 216 | if (adapter->intr_scheme != -1 && |
246 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | 217 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { |
247 | writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 218 | adapter->pci_write_normalize(adapter, |
219 | CRB_INT_VECTOR, 0); | ||
248 | } | 220 | } |
249 | writel(mask, | 221 | adapter->pci_write_immediate(adapter, |
250 | PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)); | 222 | ISR_INT_TARGET_MASK, mask); |
251 | } | 223 | } |
252 | 224 | ||
253 | DPRINTK(1, INFO, "Done with enable Int\n"); | 225 | DPRINTK(1, INFO, "Done with enable Int\n"); |
254 | } | 226 | } |
255 | 227 | ||
228 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | ||
229 | { | ||
230 | struct pci_dev *pdev = adapter->pdev; | ||
231 | int err; | ||
232 | uint64_t mask; | ||
233 | |||
234 | #ifdef CONFIG_IA64 | ||
235 | adapter->dma_mask = DMA_32BIT_MASK; | ||
236 | #else | ||
237 | if (revision_id >= NX_P3_B0) { | ||
238 | /* should go to DMA_64BIT_MASK */ | ||
239 | adapter->dma_mask = DMA_39BIT_MASK; | ||
240 | mask = DMA_39BIT_MASK; | ||
241 | } else if (revision_id == NX_P3_A2) { | ||
242 | adapter->dma_mask = DMA_39BIT_MASK; | ||
243 | mask = DMA_39BIT_MASK; | ||
244 | } else if (revision_id == NX_P2_C1) { | ||
245 | adapter->dma_mask = DMA_35BIT_MASK; | ||
246 | mask = DMA_35BIT_MASK; | ||
247 | } else { | ||
248 | adapter->dma_mask = DMA_32BIT_MASK; | ||
249 | mask = DMA_32BIT_MASK; | ||
250 | goto set_32_bit_mask; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
255 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
256 | * come off this pool. | ||
257 | */ | ||
258 | if (pci_set_dma_mask(pdev, mask) == 0 && | ||
259 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) { | ||
260 | adapter->pci_using_dac = 1; | ||
261 | return 0; | ||
262 | } | ||
263 | #endif /* CONFIG_IA64 */ | ||
264 | |||
265 | set_32_bit_mask: | ||
266 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
267 | if (!err) | ||
268 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
269 | if (err) { | ||
270 | DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err); | ||
271 | return err; | ||
272 | } | ||
273 | |||
274 | adapter->pci_using_dac = 0; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static void netxen_check_options(struct netxen_adapter *adapter) | ||
279 | { | ||
280 | switch (adapter->ahw.boardcfg.board_type) { | ||
281 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
282 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
283 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
284 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
285 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
286 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
287 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
288 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
289 | adapter->msix_supported = !!use_msi_x; | ||
290 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
291 | break; | ||
292 | |||
293 | case NETXEN_BRDTYPE_P2_SB31_10G: | ||
294 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
295 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | ||
296 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
297 | adapter->msix_supported = 0; | ||
298 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
299 | break; | ||
300 | |||
301 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
302 | case NETXEN_BRDTYPE_P3_4_GB: | ||
303 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
304 | case NETXEN_BRDTYPE_P2_SB35_4G: | ||
305 | case NETXEN_BRDTYPE_P2_SB31_2G: | ||
306 | adapter->msix_supported = 0; | ||
307 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
308 | break; | ||
309 | |||
310 | default: | ||
311 | adapter->msix_supported = 0; | ||
312 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
313 | |||
314 | printk(KERN_WARNING "Unknown board type(0x%x)\n", | ||
315 | adapter->ahw.boardcfg.board_type); | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
320 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
321 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
322 | |||
323 | adapter->max_possible_rss_rings = 1; | ||
324 | return; | ||
325 | } | ||
326 | |||
327 | static int | ||
328 | netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | ||
329 | { | ||
330 | int ret = 0; | ||
331 | |||
332 | if (first_boot == 0x55555555) { | ||
333 | /* This is the first boot after power up */ | ||
334 | |||
335 | /* PCI bus master workaround */ | ||
336 | adapter->hw_read_wx(adapter, | ||
337 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
338 | if (!(first_boot & 0x4)) { | ||
339 | first_boot |= 0x4; | ||
340 | adapter->hw_write_wx(adapter, | ||
341 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
342 | adapter->hw_read_wx(adapter, | ||
343 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
344 | } | ||
345 | |||
346 | /* This is the first boot after power up */ | ||
347 | adapter->hw_read_wx(adapter, | ||
348 | NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4); | ||
349 | if (first_boot != 0x80000f) { | ||
350 | /* clear the register for future unloads/loads */ | ||
351 | adapter->pci_write_normalize(adapter, | ||
352 | NETXEN_CAM_RAM(0x1fc), 0); | ||
353 | ret = -1; | ||
354 | } | ||
355 | |||
356 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
357 | /* Start P2 boot loader */ | ||
358 | adapter->pci_write_normalize(adapter, | ||
359 | NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
360 | adapter->pci_write_normalize(adapter, | ||
361 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
362 | } | ||
363 | } | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | static void netxen_set_port_mode(struct netxen_adapter *adapter) | ||
368 | { | ||
369 | u32 val, data; | ||
370 | |||
371 | val = adapter->ahw.boardcfg.board_type; | ||
372 | if ((val == NETXEN_BRDTYPE_P3_HMEZ) || | ||
373 | (val == NETXEN_BRDTYPE_P3_XG_LOM)) { | ||
374 | if (port_mode == NETXEN_PORT_MODE_802_3_AP) { | ||
375 | data = NETXEN_PORT_MODE_802_3_AP; | ||
376 | adapter->hw_write_wx(adapter, | ||
377 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
378 | } else if (port_mode == NETXEN_PORT_MODE_XG) { | ||
379 | data = NETXEN_PORT_MODE_XG; | ||
380 | adapter->hw_write_wx(adapter, | ||
381 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
382 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { | ||
383 | data = NETXEN_PORT_MODE_AUTO_NEG_1G; | ||
384 | adapter->hw_write_wx(adapter, | ||
385 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
386 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { | ||
387 | data = NETXEN_PORT_MODE_AUTO_NEG_XG; | ||
388 | adapter->hw_write_wx(adapter, | ||
389 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
390 | } else { | ||
391 | data = NETXEN_PORT_MODE_AUTO_NEG; | ||
392 | adapter->hw_write_wx(adapter, | ||
393 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
394 | } | ||
395 | |||
396 | if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && | ||
397 | (wol_port_mode != NETXEN_PORT_MODE_XG) && | ||
398 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) && | ||
399 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) { | ||
400 | wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
401 | } | ||
402 | adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, | ||
403 | &wol_port_mode, 4); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | #define PCI_CAP_ID_GEN 0x10 | ||
408 | |||
409 | static void netxen_pcie_strap_init(struct netxen_adapter *adapter) | ||
410 | { | ||
411 | u32 pdevfuncsave; | ||
412 | u32 c8c9value = 0; | ||
413 | u32 chicken = 0; | ||
414 | u32 control = 0; | ||
415 | int i, pos; | ||
416 | struct pci_dev *pdev; | ||
417 | |||
418 | pdev = pci_get_device(0x1166, 0x0140, NULL); | ||
419 | if (pdev) { | ||
420 | pci_dev_put(pdev); | ||
421 | adapter->hw_read_wx(adapter, | ||
422 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
423 | chicken |= 0x4000; | ||
424 | adapter->hw_write_wx(adapter, | ||
425 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
426 | } | ||
427 | |||
428 | pdev = adapter->pdev; | ||
429 | |||
430 | adapter->hw_read_wx(adapter, | ||
431 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
432 | /* clear chicken3.25:24 */ | ||
433 | chicken &= 0xFCFFFFFF; | ||
434 | /* | ||
435 | * if gen1 and B0, set F1020 - if gen 2, do nothing | ||
436 | * if gen2 set to F1000 | ||
437 | */ | ||
438 | pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); | ||
439 | if (pos == 0xC0) { | ||
440 | pci_read_config_dword(pdev, pos + 0x10, &control); | ||
441 | if ((control & 0x000F0000) != 0x00020000) { | ||
442 | /* set chicken3.24 if gen1 */ | ||
443 | chicken |= 0x01000000; | ||
444 | } | ||
445 | printk(KERN_INFO "%s Gen2 strapping detected\n", | ||
446 | netxen_nic_driver_name); | ||
447 | c8c9value = 0xF1000; | ||
448 | } else { | ||
449 | /* set chicken3.24 if gen1 */ | ||
450 | chicken |= 0x01000000; | ||
451 | printk(KERN_INFO "%s Gen1 strapping detected\n", | ||
452 | netxen_nic_driver_name); | ||
453 | if (adapter->ahw.revision_id == NX_P3_B0) | ||
454 | c8c9value = 0xF1020; | ||
455 | else | ||
456 | c8c9value = 0; | ||
457 | |||
458 | } | ||
459 | adapter->hw_write_wx(adapter, | ||
460 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
461 | |||
462 | if (!c8c9value) | ||
463 | return; | ||
464 | |||
465 | pdevfuncsave = pdev->devfn; | ||
466 | if (pdevfuncsave & 0x07) | ||
467 | return; | ||
468 | |||
469 | for (i = 0; i < 8; i++) { | ||
470 | pci_read_config_dword(pdev, pos + 8, &control); | ||
471 | pci_read_config_dword(pdev, pos + 8, &control); | ||
472 | pci_write_config_dword(pdev, pos + 8, c8c9value); | ||
473 | pdev->devfn++; | ||
474 | } | ||
475 | pdev->devfn = pdevfuncsave; | ||
476 | } | ||
477 | |||
478 | static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) | ||
479 | { | ||
480 | u32 control; | ||
481 | int pos; | ||
482 | |||
483 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
484 | if (pos) { | ||
485 | pci_read_config_dword(pdev, pos, &control); | ||
486 | if (enable) | ||
487 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
488 | else | ||
489 | control = 0; | ||
490 | pci_write_config_dword(pdev, pos, control); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | static void netxen_init_msix_entries(struct netxen_adapter *adapter) | ||
495 | { | ||
496 | int i; | ||
497 | |||
498 | for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++) | ||
499 | adapter->msix_entries[i].entry = i; | ||
500 | } | ||
501 | |||
256 | /* | 502 | /* |
257 | * netxen_nic_probe() | 503 | * netxen_nic_probe() |
258 | * | 504 | * |
@@ -278,28 +524,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
278 | 524 | ||
279 | 525 | ||
280 | u8 __iomem *db_ptr = NULL; | 526 | u8 __iomem *db_ptr = NULL; |
281 | unsigned long mem_base, mem_len, db_base, db_len; | 527 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; |
282 | int pci_using_dac, i = 0, err; | 528 | int i = 0, err; |
283 | int ring; | 529 | int first_driver, first_boot; |
284 | struct netxen_recv_context *recv_ctx = NULL; | ||
285 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | ||
286 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | ||
287 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; | 530 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; |
288 | int valid_mac = 0; | ||
289 | u32 val; | 531 | u32 val; |
290 | int pci_func_id = PCI_FUNC(pdev->devfn); | 532 | int pci_func_id = PCI_FUNC(pdev->devfn); |
291 | DECLARE_MAC_BUF(mac); | 533 | DECLARE_MAC_BUF(mac); |
534 | struct netxen_legacy_intr_set *legacy_intrp; | ||
535 | uint8_t revision_id; | ||
292 | 536 | ||
293 | if (pci_func_id == 0) | 537 | if (pci_func_id == 0) |
294 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 538 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
295 | 539 | ||
296 | if (pdev->class != 0x020000) { | 540 | if (pdev->class != 0x020000) { |
297 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | 541 | printk(KERN_DEBUG "NetXen function %d, class %x will not " |
298 | "be enabled.\n",pci_func_id, pdev->class); | 542 | "be enabled.\n",pci_func_id, pdev->class); |
299 | return -ENODEV; | 543 | return -ENODEV; |
300 | } | 544 | } |
545 | |||
301 | if ((err = pci_enable_device(pdev))) | 546 | if ((err = pci_enable_device(pdev))) |
302 | return err; | 547 | return err; |
548 | |||
303 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 549 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
304 | err = -ENODEV; | 550 | err = -ENODEV; |
305 | goto err_out_disable_pdev; | 551 | goto err_out_disable_pdev; |
@@ -309,18 +555,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
309 | goto err_out_disable_pdev; | 555 | goto err_out_disable_pdev; |
310 | 556 | ||
311 | pci_set_master(pdev); | 557 | pci_set_master(pdev); |
312 | if (pdev->revision == NX_P2_C1 && | ||
313 | (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && | ||
314 | (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { | ||
315 | pci_using_dac = 1; | ||
316 | } else { | ||
317 | if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || | ||
318 | (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) | ||
319 | goto err_out_free_res; | ||
320 | |||
321 | pci_using_dac = 0; | ||
322 | } | ||
323 | |||
324 | 558 | ||
325 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 559 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
326 | if(!netdev) { | 560 | if(!netdev) { |
@@ -333,13 +567,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
333 | SET_NETDEV_DEV(netdev, &pdev->dev); | 567 | SET_NETDEV_DEV(netdev, &pdev->dev); |
334 | 568 | ||
335 | adapter = netdev->priv; | 569 | adapter = netdev->priv; |
336 | 570 | adapter->netdev = netdev; | |
337 | adapter->ahw.pdev = pdev; | 571 | adapter->pdev = pdev; |
338 | adapter->ahw.pci_func = pci_func_id; | 572 | adapter->ahw.pci_func = pci_func_id; |
339 | 573 | ||
574 | revision_id = pdev->revision; | ||
575 | adapter->ahw.revision_id = revision_id; | ||
576 | |||
577 | err = nx_set_dma_mask(adapter, revision_id); | ||
578 | if (err) | ||
579 | goto err_out_free_netdev; | ||
580 | |||
581 | rwlock_init(&adapter->adapter_lock); | ||
582 | adapter->ahw.qdr_sn_window = -1; | ||
583 | adapter->ahw.ddr_mn_window = -1; | ||
584 | |||
340 | /* remap phys address */ | 585 | /* remap phys address */ |
341 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 586 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
342 | mem_len = pci_resource_len(pdev, 0); | 587 | mem_len = pci_resource_len(pdev, 0); |
588 | pci_len0 = 0; | ||
589 | |||
590 | adapter->hw_write_wx = netxen_nic_hw_write_wx_128M; | ||
591 | adapter->hw_read_wx = netxen_nic_hw_read_wx_128M; | ||
592 | adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M; | ||
593 | adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M; | ||
594 | adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M; | ||
595 | adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M; | ||
596 | adapter->pci_set_window = netxen_nic_pci_set_window_128M; | ||
597 | adapter->pci_mem_read = netxen_nic_pci_mem_read_128M; | ||
598 | adapter->pci_mem_write = netxen_nic_pci_mem_write_128M; | ||
343 | 599 | ||
344 | /* 128 Meg of memory */ | 600 | /* 128 Meg of memory */ |
345 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 601 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
@@ -356,27 +612,48 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
356 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 612 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); |
357 | first_page_group_start = 0; | 613 | first_page_group_start = 0; |
358 | first_page_group_end = 0; | 614 | first_page_group_end = 0; |
615 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { | ||
616 | adapter->hw_write_wx = netxen_nic_hw_write_wx_2M; | ||
617 | adapter->hw_read_wx = netxen_nic_hw_read_wx_2M; | ||
618 | adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M; | ||
619 | adapter->pci_write_immediate = | ||
620 | netxen_nic_pci_write_immediate_2M; | ||
621 | adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M; | ||
622 | adapter->pci_write_normalize = | ||
623 | netxen_nic_pci_write_normalize_2M; | ||
624 | adapter->pci_set_window = netxen_nic_pci_set_window_2M; | ||
625 | adapter->pci_mem_read = netxen_nic_pci_mem_read_2M; | ||
626 | adapter->pci_mem_write = netxen_nic_pci_mem_write_2M; | ||
627 | |||
628 | mem_ptr0 = ioremap(mem_base, mem_len); | ||
629 | pci_len0 = mem_len; | ||
630 | first_page_group_start = 0; | ||
631 | first_page_group_end = 0; | ||
632 | |||
633 | adapter->ahw.ddr_mn_window = 0; | ||
634 | adapter->ahw.qdr_sn_window = 0; | ||
635 | |||
636 | adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW + | ||
637 | (pci_func_id * 0x20); | ||
638 | adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW; | ||
639 | if (pci_func_id < 4) | ||
640 | adapter->ahw.ms_win_crb += (pci_func_id * 0x20); | ||
641 | else | ||
642 | adapter->ahw.ms_win_crb += | ||
643 | 0xA0 + ((pci_func_id - 4) * 0x10); | ||
359 | } else { | 644 | } else { |
360 | err = -EIO; | 645 | err = -EIO; |
361 | goto err_out_free_netdev; | 646 | goto err_out_free_netdev; |
362 | } | 647 | } |
363 | 648 | ||
364 | if ((!mem_ptr0 && mem_len == NETXEN_PCI_128MB_SIZE) || | 649 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
365 | !mem_ptr1 || !mem_ptr2) { | ||
366 | DPRINTK(ERR, | ||
367 | "Cannot remap adapter memory aborting.:" | ||
368 | "0 -> %p, 1 -> %p, 2 -> %p\n", | ||
369 | mem_ptr0, mem_ptr1, mem_ptr2); | ||
370 | 650 | ||
371 | err = -EIO; | ||
372 | goto err_out_iounmap; | ||
373 | } | ||
374 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ | 651 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ |
375 | db_len = pci_resource_len(pdev, 4); | 652 | db_len = pci_resource_len(pdev, 4); |
376 | 653 | ||
377 | if (db_len == 0) { | 654 | if (db_len == 0) { |
378 | printk(KERN_ERR "%s: doorbell is disabled\n", | 655 | printk(KERN_ERR "%s: doorbell is disabled\n", |
379 | netxen_nic_driver_name); | 656 | netxen_nic_driver_name); |
380 | err = -EIO; | 657 | err = -EIO; |
381 | goto err_out_iounmap; | 658 | goto err_out_iounmap; |
382 | } | 659 | } |
@@ -386,13 +663,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
386 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); | 663 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); |
387 | if (!db_ptr) { | 664 | if (!db_ptr) { |
388 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", | 665 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", |
389 | netxen_nic_driver_name); | 666 | netxen_nic_driver_name); |
390 | err = -EIO; | 667 | err = -EIO; |
391 | goto err_out_iounmap; | 668 | goto err_out_iounmap; |
392 | } | 669 | } |
393 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); | 670 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); |
394 | 671 | ||
395 | adapter->ahw.pci_base0 = mem_ptr0; | 672 | adapter->ahw.pci_base0 = mem_ptr0; |
673 | adapter->ahw.pci_len0 = pci_len0; | ||
396 | adapter->ahw.first_page_group_start = first_page_group_start; | 674 | adapter->ahw.first_page_group_start = first_page_group_start; |
397 | adapter->ahw.first_page_group_end = first_page_group_end; | 675 | adapter->ahw.first_page_group_end = first_page_group_end; |
398 | adapter->ahw.pci_base1 = mem_ptr1; | 676 | adapter->ahw.pci_base1 = mem_ptr1; |
@@ -400,11 +678,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
400 | adapter->ahw.db_base = db_ptr; | 678 | adapter->ahw.db_base = db_ptr; |
401 | adapter->ahw.db_len = db_len; | 679 | adapter->ahw.db_len = db_len; |
402 | 680 | ||
403 | adapter->netdev = netdev; | ||
404 | adapter->pdev = pdev; | ||
405 | |||
406 | netif_napi_add(netdev, &adapter->napi, | 681 | netif_napi_add(netdev, &adapter->napi, |
407 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); | 682 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); |
683 | |||
684 | if (revision_id >= NX_P3_B0) | ||
685 | legacy_intrp = &legacy_intr[pci_func_id]; | ||
686 | else | ||
687 | legacy_intrp = &legacy_intr[0]; | ||
688 | |||
689 | adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit; | ||
690 | adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg; | ||
691 | adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg; | ||
692 | adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg; | ||
408 | 693 | ||
409 | /* this will be read from FW later */ | 694 | /* this will be read from FW later */ |
410 | adapter->intr_scheme = -1; | 695 | adapter->intr_scheme = -1; |
@@ -414,12 +699,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
414 | adapter->portnum = pci_func_id; | 699 | adapter->portnum = pci_func_id; |
415 | adapter->status &= ~NETXEN_NETDEV_STATUS; | 700 | adapter->status &= ~NETXEN_NETDEV_STATUS; |
416 | adapter->rx_csum = 1; | 701 | adapter->rx_csum = 1; |
702 | adapter->mc_enabled = 0; | ||
703 | if (NX_IS_REVISION_P3(revision_id)) { | ||
704 | adapter->max_mc_count = 38; | ||
705 | adapter->max_rds_rings = 2; | ||
706 | } else { | ||
707 | adapter->max_mc_count = 16; | ||
708 | adapter->max_rds_rings = 3; | ||
709 | } | ||
417 | 710 | ||
418 | netdev->open = netxen_nic_open; | 711 | netdev->open = netxen_nic_open; |
419 | netdev->stop = netxen_nic_close; | 712 | netdev->stop = netxen_nic_close; |
420 | netdev->hard_start_xmit = netxen_nic_xmit_frame; | 713 | netdev->hard_start_xmit = netxen_nic_xmit_frame; |
421 | netdev->get_stats = netxen_nic_get_stats; | 714 | netdev->get_stats = netxen_nic_get_stats; |
422 | netdev->set_multicast_list = netxen_nic_set_multi; | 715 | if (NX_IS_REVISION_P3(revision_id)) |
716 | netdev->set_multicast_list = netxen_p3_nic_set_multi; | ||
717 | else | ||
718 | netdev->set_multicast_list = netxen_p2_nic_set_multi; | ||
423 | netdev->set_mac_address = netxen_nic_set_mac; | 719 | netdev->set_mac_address = netxen_nic_set_mac; |
424 | netdev->change_mtu = netxen_nic_change_mtu; | 720 | netdev->change_mtu = netxen_nic_change_mtu; |
425 | netdev->tx_timeout = netxen_tx_timeout; | 721 | netdev->tx_timeout = netxen_tx_timeout; |
@@ -435,18 +731,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
435 | netdev->features = NETIF_F_SG; | 731 | netdev->features = NETIF_F_SG; |
436 | netdev->features |= NETIF_F_IP_CSUM; | 732 | netdev->features |= NETIF_F_IP_CSUM; |
437 | netdev->features |= NETIF_F_TSO; | 733 | netdev->features |= NETIF_F_TSO; |
734 | if (NX_IS_REVISION_P3(revision_id)) { | ||
735 | netdev->features |= NETIF_F_IPV6_CSUM; | ||
736 | netdev->features |= NETIF_F_TSO6; | ||
737 | } | ||
438 | 738 | ||
439 | if (pci_using_dac) | 739 | if (adapter->pci_using_dac) |
440 | netdev->features |= NETIF_F_HIGHDMA; | 740 | netdev->features |= NETIF_F_HIGHDMA; |
441 | 741 | ||
442 | if (pci_enable_msi(pdev)) | ||
443 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | ||
444 | else | ||
445 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
446 | |||
447 | netdev->irq = pdev->irq; | ||
448 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
449 | |||
450 | /* | 742 | /* |
451 | * Set the CRB window to invalid. If any register in window 0 is | 743 | * Set the CRB window to invalid. If any register in window 0 is |
452 | * accessed it should set the window to 0 and then reset it to 1. | 744 | * accessed it should set the window to 0 and then reset it to 1. |
@@ -455,87 +747,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
455 | 747 | ||
456 | if (netxen_nic_get_board_info(adapter) != 0) { | 748 | if (netxen_nic_get_board_info(adapter) != 0) { |
457 | printk("%s: Error getting board config info.\n", | 749 | printk("%s: Error getting board config info.\n", |
458 | netxen_nic_driver_name); | 750 | netxen_nic_driver_name); |
459 | err = -EIO; | 751 | err = -EIO; |
460 | goto err_out_iounmap; | 752 | goto err_out_iounmap; |
461 | } | 753 | } |
462 | 754 | ||
463 | /* | ||
464 | * Adapter in our case is quad port so initialize it before | ||
465 | * initializing the ports | ||
466 | */ | ||
467 | |||
468 | netxen_initialize_adapter_ops(adapter); | 755 | netxen_initialize_adapter_ops(adapter); |
469 | 756 | ||
470 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
471 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | ||
472 | (adapter->ahw.boardcfg.board_type == | ||
473 | NETXEN_BRDTYPE_P2_SB31_2G)) | ||
474 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
475 | else | ||
476 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | ||
477 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
478 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
479 | |||
480 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | ||
481 | if (cmd_buf_arr == NULL) { | ||
482 | printk(KERN_ERR | ||
483 | "%s: Could not allocate cmd_buf_arr memory:%d\n", | ||
484 | netxen_nic_driver_name, (int)TX_RINGSIZE); | ||
485 | err = -ENOMEM; | ||
486 | goto err_out_free_adapter; | ||
487 | } | ||
488 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
489 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
490 | |||
491 | for (i = 0; i < MAX_RCV_CTX; ++i) { | ||
492 | recv_ctx = &adapter->recv_ctx[i]; | ||
493 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
494 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
495 | switch (RCV_DESC_TYPE(ring)) { | ||
496 | case RCV_DESC_NORMAL: | ||
497 | rcv_desc->max_rx_desc_count = | ||
498 | adapter->max_rx_desc_count; | ||
499 | rcv_desc->flags = RCV_DESC_NORMAL; | ||
500 | rcv_desc->dma_size = RX_DMA_MAP_LEN; | ||
501 | rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH; | ||
502 | break; | ||
503 | |||
504 | case RCV_DESC_JUMBO: | ||
505 | rcv_desc->max_rx_desc_count = | ||
506 | adapter->max_jumbo_rx_desc_count; | ||
507 | rcv_desc->flags = RCV_DESC_JUMBO; | ||
508 | rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN; | ||
509 | rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; | ||
510 | break; | ||
511 | |||
512 | case RCV_RING_LRO: | ||
513 | rcv_desc->max_rx_desc_count = | ||
514 | adapter->max_lro_rx_desc_count; | ||
515 | rcv_desc->flags = RCV_DESC_LRO; | ||
516 | rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; | ||
517 | rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
518 | break; | ||
519 | |||
520 | } | ||
521 | rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) | ||
522 | vmalloc(RCV_BUFFSIZE); | ||
523 | |||
524 | if (rcv_desc->rx_buf_arr == NULL) { | ||
525 | printk(KERN_ERR "%s: Could not allocate " | ||
526 | "rcv_desc->rx_buf_arr memory:%d\n", | ||
527 | netxen_nic_driver_name, | ||
528 | (int)RCV_BUFFSIZE); | ||
529 | err = -ENOMEM; | ||
530 | goto err_out_free_rx_buffer; | ||
531 | } | ||
532 | memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
533 | } | ||
534 | |||
535 | } | ||
536 | |||
537 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | ||
538 | |||
539 | /* Mezz cards have PCI function 0,2,3 enabled */ | 757 | /* Mezz cards have PCI function 0,2,3 enabled */ |
540 | switch (adapter->ahw.boardcfg.board_type) { | 758 | switch (adapter->ahw.boardcfg.board_type) { |
541 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 759 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
@@ -547,90 +765,71 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
547 | break; | 765 | break; |
548 | } | 766 | } |
549 | 767 | ||
550 | init_timer(&adapter->watchdog_timer); | 768 | /* |
551 | adapter->ahw.xg_linkup = 0; | 769 | * This call will setup various max rx/tx counts. |
552 | adapter->watchdog_timer.function = &netxen_watchdog; | 770 | * It must be done before any buffer/ring allocations. |
553 | adapter->watchdog_timer.data = (unsigned long)adapter; | 771 | */ |
554 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 772 | netxen_check_options(adapter); |
555 | adapter->ahw.pdev = pdev; | ||
556 | adapter->ahw.revision_id = pdev->revision; | ||
557 | |||
558 | /* make sure Window == 1 */ | ||
559 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
560 | 773 | ||
774 | first_driver = 0; | ||
775 | if (NX_IS_REVISION_P3(revision_id)) { | ||
776 | if (adapter->ahw.pci_func == 0) | ||
777 | first_driver = 1; | ||
778 | } else { | ||
779 | if (adapter->portnum == 0) | ||
780 | first_driver = 1; | ||
781 | } | ||
782 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; | ||
783 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; | ||
561 | netxen_nic_update_cmd_producer(adapter, 0); | 784 | netxen_nic_update_cmd_producer(adapter, 0); |
562 | netxen_nic_update_cmd_consumer(adapter, 0); | 785 | netxen_nic_update_cmd_consumer(adapter, 0); |
563 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); | ||
564 | 786 | ||
565 | if (netxen_is_flash_supported(adapter) == 0 && | 787 | if (first_driver) { |
566 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 788 | first_boot = adapter->pci_read_normalize(adapter, |
567 | valid_mac = 1; | 789 | NETXEN_CAM_RAM(0x1fc)); |
568 | else | ||
569 | valid_mac = 0; | ||
570 | |||
571 | if (valid_mac) { | ||
572 | unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
573 | netdev->dev_addr[0] = *(p + 5); | ||
574 | netdev->dev_addr[1] = *(p + 4); | ||
575 | netdev->dev_addr[2] = *(p + 3); | ||
576 | netdev->dev_addr[3] = *(p + 2); | ||
577 | netdev->dev_addr[4] = *(p + 1); | ||
578 | netdev->dev_addr[5] = *(p + 0); | ||
579 | 790 | ||
580 | memcpy(netdev->perm_addr, netdev->dev_addr, | 791 | err = netxen_check_hw_init(adapter, first_boot); |
581 | netdev->addr_len); | 792 | if (err) { |
582 | if (!is_valid_ether_addr(netdev->perm_addr)) { | 793 | printk(KERN_ERR "%s: error in init HW init sequence\n", |
583 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | 794 | netxen_nic_driver_name); |
584 | netxen_nic_driver_name, | 795 | goto err_out_iounmap; |
585 | print_mac(mac, netdev->dev_addr)); | ||
586 | } else { | ||
587 | if (adapter->macaddr_set) | ||
588 | adapter->macaddr_set(adapter, | ||
589 | netdev->dev_addr); | ||
590 | } | 796 | } |
591 | } | ||
592 | 797 | ||
593 | if (adapter->portnum == 0) { | 798 | if (NX_IS_REVISION_P3(revision_id)) |
594 | err = netxen_initialize_adapter_offload(adapter); | 799 | netxen_set_port_mode(adapter); |
595 | if (err) | 800 | |
596 | goto err_out_free_rx_buffer; | 801 | if (first_boot != 0x55555555) { |
597 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | 802 | adapter->pci_write_normalize(adapter, |
598 | NETXEN_CAM_RAM(0x1fc))); | 803 | CRB_CMDPEG_STATE, 0); |
599 | if (val == 0x55555555) { | ||
600 | /* This is the first boot after power up */ | ||
601 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
602 | if (!(val & 0x4)) { | ||
603 | val |= 0x4; | ||
604 | netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); | ||
605 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
606 | if (!(val & 0x4)) | ||
607 | printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", | ||
608 | netxen_nic_driver_name); | ||
609 | } | ||
610 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
611 | NETXEN_ROMUSB_GLB_SW_RESET)); | ||
612 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | ||
613 | if (val != 0x80000f) { | ||
614 | /* clear the register for future unloads/loads */ | ||
615 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
616 | NETXEN_CAM_RAM(0x1fc))); | ||
617 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | ||
618 | err = -ENODEV; | ||
619 | goto err_out_free_dev; | ||
620 | } | ||
621 | } else { | ||
622 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
623 | CRB_CMDPEG_STATE)); | ||
624 | netxen_pinit_from_rom(adapter, 0); | 804 | netxen_pinit_from_rom(adapter, 0); |
625 | msleep(1); | 805 | msleep(1); |
626 | netxen_load_firmware(adapter); | 806 | netxen_load_firmware(adapter); |
627 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
628 | } | 807 | } |
629 | 808 | ||
630 | /* clear the register for future unloads/loads */ | 809 | if (NX_IS_REVISION_P3(revision_id)) |
631 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | 810 | netxen_pcie_strap_init(adapter); |
632 | dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n", | 811 | |
633 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | 812 | if (NX_IS_REVISION_P2(revision_id)) { |
813 | |||
814 | /* Initialize multicast addr pool owners */ | ||
815 | val = 0x7654; | ||
816 | if (adapter->ahw.board_type == NETXEN_NIC_XGBE) | ||
817 | val |= 0x0f000000; | ||
818 | netxen_crb_writelit_adapter(adapter, | ||
819 | NETXEN_MAC_ADDR_CNTL_REG, val); | ||
820 | |||
821 | } | ||
822 | |||
823 | if ((first_boot == 0x55555555) && | ||
824 | (NX_IS_REVISION_P2(revision_id))) { | ||
825 | /* Unlock the HW, prompting the boot sequence */ | ||
826 | adapter->pci_write_normalize(adapter, | ||
827 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
828 | } | ||
829 | |||
830 | err = netxen_initialize_adapter_offload(adapter); | ||
831 | if (err) | ||
832 | goto err_out_iounmap; | ||
634 | 833 | ||
635 | /* | 834 | /* |
636 | * Tell the hardware our version number. | 835 | * Tell the hardware our version number. |
@@ -638,24 +837,101 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
638 | i = (_NETXEN_NIC_LINUX_MAJOR << 16) | 837 | i = (_NETXEN_NIC_LINUX_MAJOR << 16) |
639 | | ((_NETXEN_NIC_LINUX_MINOR << 8)) | 838 | | ((_NETXEN_NIC_LINUX_MINOR << 8)) |
640 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 839 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
641 | writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION)); | 840 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); |
642 | 841 | ||
643 | /* Unlock the HW, prompting the boot sequence */ | ||
644 | writel(1, | ||
645 | NETXEN_CRB_NORMALIZE(adapter, | ||
646 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
647 | /* Handshake with the card before we register the devices. */ | 842 | /* Handshake with the card before we register the devices. */ |
648 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 843 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
844 | |||
845 | } /* first_driver */ | ||
846 | |||
847 | netxen_nic_flash_print(adapter); | ||
848 | |||
849 | if (NX_IS_REVISION_P3(revision_id)) { | ||
850 | adapter->hw_read_wx(adapter, | ||
851 | NETXEN_MIU_MN_CONTROL, &val, 4); | ||
852 | adapter->ahw.cut_through = (val & 0x4) ? 1 : 0; | ||
853 | dev_info(&pdev->dev, "firmware running in %s mode\n", | ||
854 | adapter->ahw.cut_through ? "cut through" : "legacy"); | ||
649 | } | 855 | } |
650 | 856 | ||
651 | /* | 857 | /* |
652 | * See if the firmware gave us a virtual-physical port mapping. | 858 | * See if the firmware gave us a virtual-physical port mapping. |
653 | */ | 859 | */ |
654 | adapter->physical_port = adapter->portnum; | 860 | adapter->physical_port = adapter->portnum; |
655 | i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); | 861 | i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum)); |
656 | if (i != 0x55555555) | 862 | if (i != 0x55555555) |
657 | adapter->physical_port = i; | 863 | adapter->physical_port = i; |
658 | 864 | ||
865 | adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); | ||
866 | |||
867 | netxen_set_msix_bit(pdev, 0); | ||
868 | |||
869 | if (NX_IS_REVISION_P3(revision_id)) { | ||
870 | if ((mem_len != NETXEN_PCI_128MB_SIZE) && | ||
871 | mem_len != NETXEN_PCI_2MB_SIZE) | ||
872 | adapter->msix_supported = 0; | ||
873 | } | ||
874 | |||
875 | if (adapter->msix_supported) { | ||
876 | |||
877 | netxen_init_msix_entries(adapter); | ||
878 | |||
879 | if (pci_enable_msix(pdev, adapter->msix_entries, | ||
880 | MSIX_ENTRIES_PER_ADAPTER)) | ||
881 | goto request_msi; | ||
882 | |||
883 | adapter->flags |= NETXEN_NIC_MSIX_ENABLED; | ||
884 | netxen_set_msix_bit(pdev, 1); | ||
885 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | ||
886 | |||
887 | } else { | ||
888 | request_msi: | ||
889 | if (use_msi && !pci_enable_msi(pdev)) { | ||
890 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
891 | dev_info(&pdev->dev, "using msi interrupts\n"); | ||
892 | } else | ||
893 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
894 | } | ||
895 | |||
896 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
897 | netdev->irq = adapter->msix_entries[0].vector; | ||
898 | else | ||
899 | netdev->irq = pdev->irq; | ||
900 | |||
901 | err = netxen_receive_peg_ready(adapter); | ||
902 | if (err) | ||
903 | goto err_out_disable_msi; | ||
904 | |||
905 | init_timer(&adapter->watchdog_timer); | ||
906 | adapter->ahw.linkup = 0; | ||
907 | adapter->watchdog_timer.function = &netxen_watchdog; | ||
908 | adapter->watchdog_timer.data = (unsigned long)adapter; | ||
909 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | ||
910 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
911 | |||
912 | if (netxen_is_flash_supported(adapter) == 0 && | ||
913 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { | ||
914 | unsigned char *p; | ||
915 | |||
916 | p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
917 | netdev->dev_addr[0] = *(p + 5); | ||
918 | netdev->dev_addr[1] = *(p + 4); | ||
919 | netdev->dev_addr[2] = *(p + 3); | ||
920 | netdev->dev_addr[3] = *(p + 2); | ||
921 | netdev->dev_addr[4] = *(p + 1); | ||
922 | netdev->dev_addr[5] = *(p + 0); | ||
923 | |||
924 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
925 | netdev->addr_len); | ||
926 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
927 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | ||
928 | netxen_nic_driver_name, | ||
929 | print_mac(mac, netdev->dev_addr)); | ||
930 | } else { | ||
931 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
932 | } | ||
933 | } | ||
934 | |||
659 | netif_carrier_off(netdev); | 935 | netif_carrier_off(netdev); |
660 | netif_stop_queue(netdev); | 936 | netif_stop_queue(netdev); |
661 | 937 | ||
@@ -664,41 +940,37 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
664 | " aborting\n", netxen_nic_driver_name, | 940 | " aborting\n", netxen_nic_driver_name, |
665 | adapter->portnum); | 941 | adapter->portnum); |
666 | err = -EIO; | 942 | err = -EIO; |
667 | goto err_out_free_dev; | 943 | goto err_out_disable_msi; |
668 | } | 944 | } |
669 | 945 | ||
670 | netxen_nic_flash_print(adapter); | ||
671 | pci_set_drvdata(pdev, adapter); | 946 | pci_set_drvdata(pdev, adapter); |
672 | 947 | ||
673 | return 0; | 948 | switch (adapter->ahw.board_type) { |
674 | 949 | case NETXEN_NIC_GBE: | |
675 | err_out_free_dev: | 950 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", |
676 | if (adapter->portnum == 0) | 951 | adapter->netdev->name); |
677 | netxen_free_adapter_offload(adapter); | 952 | break; |
678 | 953 | case NETXEN_NIC_XGBE: | |
679 | err_out_free_rx_buffer: | 954 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", |
680 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 955 | adapter->netdev->name); |
681 | recv_ctx = &adapter->recv_ctx[i]; | 956 | break; |
682 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
683 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
684 | if (rcv_desc->rx_buf_arr != NULL) { | ||
685 | vfree(rcv_desc->rx_buf_arr); | ||
686 | rcv_desc->rx_buf_arr = NULL; | ||
687 | } | ||
688 | } | ||
689 | } | 957 | } |
690 | vfree(cmd_buf_arr); | ||
691 | 958 | ||
692 | err_out_free_adapter: | 959 | return 0; |
960 | |||
961 | err_out_disable_msi: | ||
962 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
963 | pci_disable_msix(pdev); | ||
693 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 964 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
694 | pci_disable_msi(pdev); | 965 | pci_disable_msi(pdev); |
695 | 966 | ||
696 | pci_set_drvdata(pdev, NULL); | 967 | if (first_driver) |
968 | netxen_free_adapter_offload(adapter); | ||
697 | 969 | ||
970 | err_out_iounmap: | ||
698 | if (db_ptr) | 971 | if (db_ptr) |
699 | iounmap(db_ptr); | 972 | iounmap(db_ptr); |
700 | 973 | ||
701 | err_out_iounmap: | ||
702 | if (mem_ptr0) | 974 | if (mem_ptr0) |
703 | iounmap(mem_ptr0); | 975 | iounmap(mem_ptr0); |
704 | if (mem_ptr1) | 976 | if (mem_ptr1) |
@@ -713,6 +985,7 @@ err_out_free_res: | |||
713 | pci_release_regions(pdev); | 985 | pci_release_regions(pdev); |
714 | 986 | ||
715 | err_out_disable_pdev: | 987 | err_out_disable_pdev: |
988 | pci_set_drvdata(pdev, NULL); | ||
716 | pci_disable_device(pdev); | 989 | pci_disable_device(pdev); |
717 | return err; | 990 | return err; |
718 | } | 991 | } |
@@ -721,11 +994,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
721 | { | 994 | { |
722 | struct netxen_adapter *adapter; | 995 | struct netxen_adapter *adapter; |
723 | struct net_device *netdev; | 996 | struct net_device *netdev; |
724 | struct netxen_rx_buffer *buffer; | ||
725 | struct netxen_recv_context *recv_ctx; | ||
726 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
727 | int i, ctxid, ring; | ||
728 | static int init_firmware_done = 0; | ||
729 | 997 | ||
730 | adapter = pci_get_drvdata(pdev); | 998 | adapter = pci_get_drvdata(pdev); |
731 | if (adapter == NULL) | 999 | if (adapter == NULL) |
@@ -736,36 +1004,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
736 | unregister_netdev(netdev); | 1004 | unregister_netdev(netdev); |
737 | 1005 | ||
738 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1006 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
739 | init_firmware_done++; | ||
740 | netxen_free_hw_resources(adapter); | 1007 | netxen_free_hw_resources(adapter); |
1008 | netxen_free_sw_resources(adapter); | ||
741 | } | 1009 | } |
742 | 1010 | ||
743 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | ||
744 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
745 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
746 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
747 | for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) { | ||
748 | buffer = &(rcv_desc->rx_buf_arr[i]); | ||
749 | if (buffer->state == NETXEN_BUFFER_FREE) | ||
750 | continue; | ||
751 | pci_unmap_single(pdev, buffer->dma, | ||
752 | rcv_desc->dma_size, | ||
753 | PCI_DMA_FROMDEVICE); | ||
754 | if (buffer->skb != NULL) | ||
755 | dev_kfree_skb_any(buffer->skb); | ||
756 | } | ||
757 | vfree(rcv_desc->rx_buf_arr); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | vfree(adapter->cmd_buf_arr); | ||
762 | |||
763 | if (adapter->portnum == 0) | 1011 | if (adapter->portnum == 0) |
764 | netxen_free_adapter_offload(adapter); | 1012 | netxen_free_adapter_offload(adapter); |
765 | 1013 | ||
766 | if (adapter->irq) | 1014 | if (adapter->irq) |
767 | free_irq(adapter->irq, adapter); | 1015 | free_irq(adapter->irq, adapter); |
768 | 1016 | ||
1017 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
1018 | pci_disable_msix(pdev); | ||
769 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 1019 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
770 | pci_disable_msi(pdev); | 1020 | pci_disable_msi(pdev); |
771 | 1021 | ||
@@ -803,51 +1053,69 @@ static int netxen_nic_open(struct net_device *netdev) | |||
803 | return -EIO; | 1053 | return -EIO; |
804 | } | 1054 | } |
805 | 1055 | ||
806 | /* setup all the resources for the Phantom... */ | 1056 | err = netxen_alloc_sw_resources(adapter); |
807 | /* this include the descriptors for rcv, tx, and status */ | ||
808 | netxen_nic_clear_stats(adapter); | ||
809 | err = netxen_nic_hw_resources(adapter); | ||
810 | if (err) { | 1057 | if (err) { |
811 | printk(KERN_ERR "Error in setting hw resources:%d\n", | 1058 | printk(KERN_ERR "%s: Error in setting sw resources\n", |
812 | err); | 1059 | netdev->name); |
813 | return err; | 1060 | return err; |
814 | } | 1061 | } |
1062 | |||
1063 | netxen_nic_clear_stats(adapter); | ||
1064 | |||
1065 | err = netxen_alloc_hw_resources(adapter); | ||
1066 | if (err) { | ||
1067 | printk(KERN_ERR "%s: Error in setting hw resources\n", | ||
1068 | netdev->name); | ||
1069 | goto err_out_free_sw; | ||
1070 | } | ||
1071 | |||
1072 | if (adapter->fw_major < 4) { | ||
1073 | adapter->crb_addr_cmd_producer = | ||
1074 | crb_cmd_producer[adapter->portnum]; | ||
1075 | adapter->crb_addr_cmd_consumer = | ||
1076 | crb_cmd_consumer[adapter->portnum]; | ||
1077 | } | ||
1078 | |||
1079 | netxen_nic_update_cmd_producer(adapter, 0); | ||
1080 | netxen_nic_update_cmd_consumer(adapter, 0); | ||
1081 | |||
815 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1082 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
816 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) | 1083 | for (ring = 0; ring < adapter->max_rds_rings; ring++) |
817 | netxen_post_rx_buffers(adapter, ctx, ring); | 1084 | netxen_post_rx_buffers(adapter, ctx, ring); |
818 | } | 1085 | } |
819 | adapter->irq = adapter->ahw.pdev->irq; | 1086 | if (NETXEN_IS_MSI_FAMILY(adapter)) |
820 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
821 | handler = netxen_msi_intr; | 1087 | handler = netxen_msi_intr; |
822 | else { | 1088 | else { |
823 | flags |= IRQF_SHARED; | 1089 | flags |= IRQF_SHARED; |
824 | handler = netxen_intr; | 1090 | handler = netxen_intr; |
825 | } | 1091 | } |
1092 | adapter->irq = netdev->irq; | ||
826 | err = request_irq(adapter->irq, handler, | 1093 | err = request_irq(adapter->irq, handler, |
827 | flags, netdev->name, adapter); | 1094 | flags, netdev->name, adapter); |
828 | if (err) { | 1095 | if (err) { |
829 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 1096 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
830 | netxen_free_hw_resources(adapter); | 1097 | goto err_out_free_hw; |
831 | return err; | ||
832 | } | 1098 | } |
833 | 1099 | ||
834 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 1100 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
835 | } | 1101 | } |
1102 | |||
836 | /* Done here again so that even if phantom sw overwrote it, | 1103 | /* Done here again so that even if phantom sw overwrote it, |
837 | * we set it */ | 1104 | * we set it */ |
838 | if (adapter->init_port | 1105 | err = adapter->init_port(adapter, adapter->physical_port); |
839 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 1106 | if (err) { |
840 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 1107 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
841 | netxen_nic_driver_name, adapter->portnum); | 1108 | netxen_nic_driver_name, adapter->portnum); |
842 | return -EIO; | 1109 | goto err_out_free_irq; |
843 | } | 1110 | } |
844 | if (adapter->macaddr_set) | 1111 | adapter->macaddr_set(adapter, netdev->dev_addr); |
845 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
846 | 1112 | ||
847 | netxen_nic_set_link_parameters(adapter); | 1113 | netxen_nic_set_link_parameters(adapter); |
848 | 1114 | ||
849 | netxen_nic_set_multi(netdev); | 1115 | netdev->set_multicast_list(netdev); |
850 | if (adapter->set_mtu) | 1116 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
1117 | nx_fw_cmd_set_mtu(adapter, netdev->mtu); | ||
1118 | else | ||
851 | adapter->set_mtu(adapter, netdev->mtu); | 1119 | adapter->set_mtu(adapter, netdev->mtu); |
852 | 1120 | ||
853 | mod_timer(&adapter->watchdog_timer, jiffies); | 1121 | mod_timer(&adapter->watchdog_timer, jiffies); |
@@ -858,6 +1126,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
858 | netif_start_queue(netdev); | 1126 | netif_start_queue(netdev); |
859 | 1127 | ||
860 | return 0; | 1128 | return 0; |
1129 | |||
1130 | err_out_free_irq: | ||
1131 | free_irq(adapter->irq, adapter); | ||
1132 | err_out_free_hw: | ||
1133 | netxen_free_hw_resources(adapter); | ||
1134 | err_out_free_sw: | ||
1135 | netxen_free_sw_resources(adapter); | ||
1136 | return err; | ||
861 | } | 1137 | } |
862 | 1138 | ||
863 | /* | 1139 | /* |
@@ -866,9 +1142,6 @@ static int netxen_nic_open(struct net_device *netdev) | |||
866 | static int netxen_nic_close(struct net_device *netdev) | 1142 | static int netxen_nic_close(struct net_device *netdev) |
867 | { | 1143 | { |
868 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1144 | struct netxen_adapter *adapter = netdev_priv(netdev); |
869 | int i, j; | ||
870 | struct netxen_cmd_buffer *cmd_buff; | ||
871 | struct netxen_skb_frag *buffrag; | ||
872 | 1145 | ||
873 | netif_carrier_off(netdev); | 1146 | netif_carrier_off(netdev); |
874 | netif_stop_queue(netdev); | 1147 | netif_stop_queue(netdev); |
@@ -879,30 +1152,8 @@ static int netxen_nic_close(struct net_device *netdev) | |||
879 | 1152 | ||
880 | netxen_nic_disable_int(adapter); | 1153 | netxen_nic_disable_int(adapter); |
881 | 1154 | ||
882 | cmd_buff = adapter->cmd_buf_arr; | 1155 | netxen_release_tx_buffers(adapter); |
883 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 1156 | |
884 | buffrag = cmd_buff->frag_array; | ||
885 | if (buffrag->dma) { | ||
886 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
887 | buffrag->length, PCI_DMA_TODEVICE); | ||
888 | buffrag->dma = 0ULL; | ||
889 | } | ||
890 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
891 | buffrag++; | ||
892 | if (buffrag->dma) { | ||
893 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
894 | buffrag->length, | ||
895 | PCI_DMA_TODEVICE); | ||
896 | buffrag->dma = 0ULL; | ||
897 | } | ||
898 | } | ||
899 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
900 | if (cmd_buff->skb) { | ||
901 | dev_kfree_skb_any(cmd_buff->skb); | ||
902 | cmd_buff->skb = NULL; | ||
903 | } | ||
904 | cmd_buff++; | ||
905 | } | ||
906 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1157 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
907 | FLUSH_SCHEDULED_WORK(); | 1158 | FLUSH_SCHEDULED_WORK(); |
908 | del_timer_sync(&adapter->watchdog_timer); | 1159 | del_timer_sync(&adapter->watchdog_timer); |
@@ -911,6 +1162,31 @@ static int netxen_nic_close(struct net_device *netdev) | |||
911 | return 0; | 1162 | return 0; |
912 | } | 1163 | } |
913 | 1164 | ||
1165 | void netxen_tso_check(struct netxen_adapter *adapter, | ||
1166 | struct cmd_desc_type0 *desc, struct sk_buff *skb) | ||
1167 | { | ||
1168 | if (desc->mss) { | ||
1169 | desc->total_hdr_length = (sizeof(struct ethhdr) + | ||
1170 | ip_hdrlen(skb) + tcp_hdrlen(skb)); | ||
1171 | |||
1172 | if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) && | ||
1173 | (skb->protocol == htons(ETH_P_IPV6))) | ||
1174 | netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6); | ||
1175 | else | ||
1176 | netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); | ||
1177 | |||
1178 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1179 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | ||
1180 | netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); | ||
1181 | else if (ip_hdr(skb)->protocol == IPPROTO_UDP) | ||
1182 | netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); | ||
1183 | else | ||
1184 | return; | ||
1185 | } | ||
1186 | desc->tcp_hdr_offset = skb_transport_offset(skb); | ||
1187 | desc->ip_hdr_offset = skb_network_offset(skb); | ||
1188 | } | ||
1189 | |||
914 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 1190 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
915 | { | 1191 | { |
916 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1192 | struct netxen_adapter *adapter = netdev_priv(netdev); |
@@ -932,7 +1208,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
932 | 1208 | ||
933 | /* There 4 fragments per descriptor */ | 1209 | /* There 4 fragments per descriptor */ |
934 | no_of_desc = (frag_count + 3) >> 2; | 1210 | no_of_desc = (frag_count + 3) >> 2; |
935 | if (netdev->features & NETIF_F_TSO) { | 1211 | if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { |
936 | if (skb_shinfo(skb)->gso_size > 0) { | 1212 | if (skb_shinfo(skb)->gso_size > 0) { |
937 | 1213 | ||
938 | no_of_desc++; | 1214 | no_of_desc++; |
@@ -959,7 +1235,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
959 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1235 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
960 | /* Take skb->data itself */ | 1236 | /* Take skb->data itself */ |
961 | pbuf = &adapter->cmd_buf_arr[producer]; | 1237 | pbuf = &adapter->cmd_buf_arr[producer]; |
962 | if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { | 1238 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1239 | skb_shinfo(skb)->gso_size > 0) { | ||
963 | pbuf->mss = skb_shinfo(skb)->gso_size; | 1240 | pbuf->mss = skb_shinfo(skb)->gso_size; |
964 | hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); | 1241 | hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); |
965 | } else { | 1242 | } else { |
@@ -1086,6 +1363,89 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1086 | return NETDEV_TX_OK; | 1363 | return NETDEV_TX_OK; |
1087 | } | 1364 | } |
1088 | 1365 | ||
1366 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | ||
1367 | { | ||
1368 | struct net_device *netdev = adapter->netdev; | ||
1369 | uint32_t temp, temp_state, temp_val; | ||
1370 | int rv = 0; | ||
1371 | |||
1372 | temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE); | ||
1373 | |||
1374 | temp_state = nx_get_temp_state(temp); | ||
1375 | temp_val = nx_get_temp_val(temp); | ||
1376 | |||
1377 | if (temp_state == NX_TEMP_PANIC) { | ||
1378 | printk(KERN_ALERT | ||
1379 | "%s: Device temperature %d degrees C exceeds" | ||
1380 | " maximum allowed. Hardware has been shut down.\n", | ||
1381 | netxen_nic_driver_name, temp_val); | ||
1382 | |||
1383 | netif_carrier_off(netdev); | ||
1384 | netif_stop_queue(netdev); | ||
1385 | rv = 1; | ||
1386 | } else if (temp_state == NX_TEMP_WARN) { | ||
1387 | if (adapter->temp == NX_TEMP_NORMAL) { | ||
1388 | printk(KERN_ALERT | ||
1389 | "%s: Device temperature %d degrees C " | ||
1390 | "exceeds operating range." | ||
1391 | " Immediate action needed.\n", | ||
1392 | netxen_nic_driver_name, temp_val); | ||
1393 | } | ||
1394 | } else { | ||
1395 | if (adapter->temp == NX_TEMP_WARN) { | ||
1396 | printk(KERN_INFO | ||
1397 | "%s: Device temperature is now %d degrees C" | ||
1398 | " in normal range.\n", netxen_nic_driver_name, | ||
1399 | temp_val); | ||
1400 | } | ||
1401 | } | ||
1402 | adapter->temp = temp_state; | ||
1403 | return rv; | ||
1404 | } | ||
1405 | |||
1406 | static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | ||
1407 | { | ||
1408 | struct net_device *netdev = adapter->netdev; | ||
1409 | u32 val, port, linkup; | ||
1410 | |||
1411 | port = adapter->physical_port; | ||
1412 | |||
1413 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | ||
1414 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); | ||
1415 | linkup = (val >> port) & 1; | ||
1416 | } else { | ||
1417 | if (adapter->fw_major < 4) { | ||
1418 | val = adapter->pci_read_normalize(adapter, | ||
1419 | CRB_XG_STATE); | ||
1420 | val = (val >> port*8) & 0xff; | ||
1421 | linkup = (val == XG_LINK_UP); | ||
1422 | } else { | ||
1423 | val = adapter->pci_read_normalize(adapter, | ||
1424 | CRB_XG_STATE_P3); | ||
1425 | val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); | ||
1426 | linkup = (val == XG_LINK_UP_P3); | ||
1427 | } | ||
1428 | } | ||
1429 | |||
1430 | if (adapter->ahw.linkup && !linkup) { | ||
1431 | printk(KERN_INFO "%s: %s NIC Link is down\n", | ||
1432 | netxen_nic_driver_name, netdev->name); | ||
1433 | adapter->ahw.linkup = 0; | ||
1434 | if (netif_running(netdev)) { | ||
1435 | netif_carrier_off(netdev); | ||
1436 | netif_stop_queue(netdev); | ||
1437 | } | ||
1438 | } else if (!adapter->ahw.linkup && linkup) { | ||
1439 | printk(KERN_INFO "%s: %s NIC Link is up\n", | ||
1440 | netxen_nic_driver_name, netdev->name); | ||
1441 | adapter->ahw.linkup = 1; | ||
1442 | if (netif_running(netdev)) { | ||
1443 | netif_carrier_on(netdev); | ||
1444 | netif_wake_queue(netdev); | ||
1445 | } | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1089 | static void netxen_watchdog(unsigned long v) | 1449 | static void netxen_watchdog(unsigned long v) |
1090 | { | 1450 | { |
1091 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 1451 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; |
@@ -1093,6 +1453,19 @@ static void netxen_watchdog(unsigned long v) | |||
1093 | SCHEDULE_WORK(&adapter->watchdog_task); | 1453 | SCHEDULE_WORK(&adapter->watchdog_task); |
1094 | } | 1454 | } |
1095 | 1455 | ||
1456 | void netxen_watchdog_task(struct work_struct *work) | ||
1457 | { | ||
1458 | struct netxen_adapter *adapter = | ||
1459 | container_of(work, struct netxen_adapter, watchdog_task); | ||
1460 | |||
1461 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | ||
1462 | return; | ||
1463 | |||
1464 | netxen_nic_handle_phy_intr(adapter); | ||
1465 | |||
1466 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | ||
1467 | } | ||
1468 | |||
1096 | static void netxen_tx_timeout(struct net_device *netdev) | 1469 | static void netxen_tx_timeout(struct net_device *netdev) |
1097 | { | 1470 | { |
1098 | struct netxen_adapter *adapter = (struct netxen_adapter *) | 1471 | struct netxen_adapter *adapter = (struct netxen_adapter *) |
@@ -1118,6 +1491,38 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1118 | netif_wake_queue(adapter->netdev); | 1491 | netif_wake_queue(adapter->netdev); |
1119 | } | 1492 | } |
1120 | 1493 | ||
1494 | /* | ||
1495 | * netxen_nic_get_stats - Get System Network Statistics | ||
1496 | * @netdev: network interface device structure | ||
1497 | */ | ||
1498 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | ||
1499 | { | ||
1500 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
1501 | struct net_device_stats *stats = &adapter->net_stats; | ||
1502 | |||
1503 | memset(stats, 0, sizeof(*stats)); | ||
1504 | |||
1505 | /* total packets received */ | ||
1506 | stats->rx_packets = adapter->stats.no_rcv; | ||
1507 | /* total packets transmitted */ | ||
1508 | stats->tx_packets = adapter->stats.xmitedframes + | ||
1509 | adapter->stats.xmitfinished; | ||
1510 | /* total bytes received */ | ||
1511 | stats->rx_bytes = adapter->stats.rxbytes; | ||
1512 | /* total bytes transmitted */ | ||
1513 | stats->tx_bytes = adapter->stats.txbytes; | ||
1514 | /* bad packets received */ | ||
1515 | stats->rx_errors = adapter->stats.rcvdbadskb; | ||
1516 | /* packet transmit problems */ | ||
1517 | stats->tx_errors = adapter->stats.nocmddescriptor; | ||
1518 | /* no space in linux buffers */ | ||
1519 | stats->rx_dropped = adapter->stats.rxdropped; | ||
1520 | /* no space available in linux */ | ||
1521 | stats->tx_dropped = adapter->stats.txdropped; | ||
1522 | |||
1523 | return stats; | ||
1524 | } | ||
1525 | |||
1121 | static inline void | 1526 | static inline void |
1122 | netxen_handle_int(struct netxen_adapter *adapter) | 1527 | netxen_handle_int(struct netxen_adapter *adapter) |
1123 | { | 1528 | { |
@@ -1125,20 +1530,20 @@ netxen_handle_int(struct netxen_adapter *adapter) | |||
1125 | napi_schedule(&adapter->napi); | 1530 | napi_schedule(&adapter->napi); |
1126 | } | 1531 | } |
1127 | 1532 | ||
1128 | irqreturn_t netxen_intr(int irq, void *data) | 1533 | static irqreturn_t netxen_intr(int irq, void *data) |
1129 | { | 1534 | { |
1130 | struct netxen_adapter *adapter = data; | 1535 | struct netxen_adapter *adapter = data; |
1131 | u32 our_int = 0; | 1536 | u32 our_int = 0; |
1132 | 1537 | ||
1133 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1538 | our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); |
1134 | /* not our interrupt */ | 1539 | /* not our interrupt */ |
1135 | if ((our_int & (0x80 << adapter->portnum)) == 0) | 1540 | if ((our_int & (0x80 << adapter->portnum)) == 0) |
1136 | return IRQ_NONE; | 1541 | return IRQ_NONE; |
1137 | 1542 | ||
1138 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { | 1543 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { |
1139 | /* claim interrupt */ | 1544 | /* claim interrupt */ |
1140 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), | 1545 | adapter->pci_write_normalize(adapter, CRB_INT_VECTOR, |
1141 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1546 | our_int & ~((u32)(0x80 << adapter->portnum))); |
1142 | } | 1547 | } |
1143 | 1548 | ||
1144 | netxen_handle_int(adapter); | 1549 | netxen_handle_int(adapter); |
@@ -1146,7 +1551,7 @@ irqreturn_t netxen_intr(int irq, void *data) | |||
1146 | return IRQ_HANDLED; | 1551 | return IRQ_HANDLED; |
1147 | } | 1552 | } |
1148 | 1553 | ||
1149 | irqreturn_t netxen_msi_intr(int irq, void *data) | 1554 | static irqreturn_t netxen_msi_intr(int irq, void *data) |
1150 | { | 1555 | { |
1151 | struct netxen_adapter *adapter = data; | 1556 | struct netxen_adapter *adapter = data; |
1152 | 1557 | ||
@@ -1220,10 +1625,6 @@ module_init(netxen_init_module); | |||
1220 | 1625 | ||
1221 | static void __exit netxen_exit_module(void) | 1626 | static void __exit netxen_exit_module(void) |
1222 | { | 1627 | { |
1223 | /* | ||
1224 | * Wait for some time to allow the dma to drain, if any. | ||
1225 | */ | ||
1226 | msleep(100); | ||
1227 | pci_unregister_driver(&netxen_driver); | 1628 | pci_unregister_driver(&netxen_driver); |
1228 | destroy_workqueue(netxen_workq); | 1629 | destroy_workqueue(netxen_workq); |
1229 | } | 1630 | } |
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index a3bc7cc67a6f..4cb8f4a1cf4b 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -46,9 +46,8 @@ static int phy_lock(struct netxen_adapter *adapter) | |||
46 | int done = 0, timeout = 0; | 46 | int done = 0, timeout = 0; |
47 | 47 | ||
48 | while (!done) { | 48 | while (!done) { |
49 | done = | 49 | done = netxen_nic_reg_read(adapter, |
50 | readl(pci_base_offset | 50 | NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); |
51 | (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK))); | ||
52 | if (done == 1) | 51 | if (done == 1) |
53 | break; | 52 | break; |
54 | if (timeout >= phy_lock_timeout) { | 53 | if (timeout >= phy_lock_timeout) { |
@@ -63,14 +62,14 @@ static int phy_lock(struct netxen_adapter *adapter) | |||
63 | } | 62 | } |
64 | } | 63 | } |
65 | 64 | ||
66 | writel(PHY_LOCK_DRIVER, | 65 | netxen_crb_writelit_adapter(adapter, |
67 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID)); | 66 | NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER); |
68 | return 0; | 67 | return 0; |
69 | } | 68 | } |
70 | 69 | ||
71 | static int phy_unlock(struct netxen_adapter *adapter) | 70 | static int phy_unlock(struct netxen_adapter *adapter) |
72 | { | 71 | { |
73 | readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK))); | 72 | adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); |
74 | 73 | ||
75 | return 0; | 74 | return 0; |
76 | } | 75 | } |
@@ -109,7 +108,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
109 | * so it cannot be in reset | 108 | * so it cannot be in reset |
110 | */ | 109 | */ |
111 | 110 | ||
112 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), | 111 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
113 | &mac_cfg0, 4)) | 112 | &mac_cfg0, 4)) |
114 | return -EIO; | 113 | return -EIO; |
115 | if (netxen_gb_get_soft_reset(mac_cfg0)) { | 114 | if (netxen_gb_get_soft_reset(mac_cfg0)) { |
@@ -119,7 +118,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
119 | netxen_gb_rx_reset_pb(temp); | 118 | netxen_gb_rx_reset_pb(temp); |
120 | netxen_gb_tx_reset_mac(temp); | 119 | netxen_gb_tx_reset_mac(temp); |
121 | netxen_gb_rx_reset_mac(temp); | 120 | netxen_gb_rx_reset_mac(temp); |
122 | if (netxen_nic_hw_write_wx(adapter, | 121 | if (adapter->hw_write_wx(adapter, |
123 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | 122 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
124 | &temp, 4)) | 123 | &temp, 4)) |
125 | return -EIO; | 124 | return -EIO; |
@@ -129,22 +128,22 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
129 | address = 0; | 128 | address = 0; |
130 | netxen_gb_mii_mgmt_reg_addr(address, reg); | 129 | netxen_gb_mii_mgmt_reg_addr(address, reg); |
131 | netxen_gb_mii_mgmt_phy_addr(address, phy); | 130 | netxen_gb_mii_mgmt_phy_addr(address, phy); |
132 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), | 131 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), |
133 | &address, 4)) | 132 | &address, 4)) |
134 | return -EIO; | 133 | return -EIO; |
135 | command = 0; /* turn off any prior activity */ | 134 | command = 0; /* turn off any prior activity */ |
136 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), | 135 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
137 | &command, 4)) | 136 | &command, 4)) |
138 | return -EIO; | 137 | return -EIO; |
139 | /* send read command */ | 138 | /* send read command */ |
140 | netxen_gb_mii_mgmt_set_read_cycle(command); | 139 | netxen_gb_mii_mgmt_set_read_cycle(command); |
141 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), | 140 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
142 | &command, 4)) | 141 | &command, 4)) |
143 | return -EIO; | 142 | return -EIO; |
144 | 143 | ||
145 | status = 0; | 144 | status = 0; |
146 | do { | 145 | do { |
147 | if (netxen_nic_hw_read_wx(adapter, | 146 | if (adapter->hw_read_wx(adapter, |
148 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), | 147 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), |
149 | &status, 4)) | 148 | &status, 4)) |
150 | return -EIO; | 149 | return -EIO; |
@@ -154,7 +153,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
154 | && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); | 153 | && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); |
155 | 154 | ||
156 | if (timeout < NETXEN_NIU_PHY_WAITMAX) { | 155 | if (timeout < NETXEN_NIU_PHY_WAITMAX) { |
157 | if (netxen_nic_hw_read_wx(adapter, | 156 | if (adapter->hw_read_wx(adapter, |
158 | NETXEN_NIU_GB_MII_MGMT_STATUS(0), | 157 | NETXEN_NIU_GB_MII_MGMT_STATUS(0), |
159 | readval, 4)) | 158 | readval, 4)) |
160 | return -EIO; | 159 | return -EIO; |
@@ -163,7 +162,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
163 | result = -1; | 162 | result = -1; |
164 | 163 | ||
165 | if (restore) | 164 | if (restore) |
166 | if (netxen_nic_hw_write_wx(adapter, | 165 | if (adapter->hw_write_wx(adapter, |
167 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | 166 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
168 | &mac_cfg0, 4)) | 167 | &mac_cfg0, 4)) |
169 | return -EIO; | 168 | return -EIO; |
@@ -201,7 +200,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, | |||
201 | * cannot be in reset | 200 | * cannot be in reset |
202 | */ | 201 | */ |
203 | 202 | ||
204 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), | 203 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
205 | &mac_cfg0, 4)) | 204 | &mac_cfg0, 4)) |
206 | return -EIO; | 205 | return -EIO; |
207 | if (netxen_gb_get_soft_reset(mac_cfg0)) { | 206 | if (netxen_gb_get_soft_reset(mac_cfg0)) { |
@@ -212,7 +211,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, | |||
212 | netxen_gb_tx_reset_mac(temp); | 211 | netxen_gb_tx_reset_mac(temp); |
213 | netxen_gb_rx_reset_mac(temp); | 212 | netxen_gb_rx_reset_mac(temp); |
214 | 213 | ||
215 | if (netxen_nic_hw_write_wx(adapter, | 214 | if (adapter->hw_write_wx(adapter, |
216 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | 215 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
217 | &temp, 4)) | 216 | &temp, 4)) |
218 | return -EIO; | 217 | return -EIO; |
@@ -220,24 +219,24 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, | |||
220 | } | 219 | } |
221 | 220 | ||
222 | command = 0; /* turn off any prior activity */ | 221 | command = 0; /* turn off any prior activity */ |
223 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), | 222 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
224 | &command, 4)) | 223 | &command, 4)) |
225 | return -EIO; | 224 | return -EIO; |
226 | 225 | ||
227 | address = 0; | 226 | address = 0; |
228 | netxen_gb_mii_mgmt_reg_addr(address, reg); | 227 | netxen_gb_mii_mgmt_reg_addr(address, reg); |
229 | netxen_gb_mii_mgmt_phy_addr(address, phy); | 228 | netxen_gb_mii_mgmt_phy_addr(address, phy); |
230 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), | 229 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), |
231 | &address, 4)) | 230 | &address, 4)) |
232 | return -EIO; | 231 | return -EIO; |
233 | 232 | ||
234 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), | 233 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), |
235 | &val, 4)) | 234 | &val, 4)) |
236 | return -EIO; | 235 | return -EIO; |
237 | 236 | ||
238 | status = 0; | 237 | status = 0; |
239 | do { | 238 | do { |
240 | if (netxen_nic_hw_read_wx(adapter, | 239 | if (adapter->hw_read_wx(adapter, |
241 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), | 240 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), |
242 | &status, 4)) | 241 | &status, 4)) |
243 | return -EIO; | 242 | return -EIO; |
@@ -252,7 +251,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, | |||
252 | 251 | ||
253 | /* restore the state of port 0 MAC in case we tampered with it */ | 252 | /* restore the state of port 0 MAC in case we tampered with it */ |
254 | if (restore) | 253 | if (restore) |
255 | if (netxen_nic_hw_write_wx(adapter, | 254 | if (adapter->hw_write_wx(adapter, |
256 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | 255 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
257 | &mac_cfg0, 4)) | 256 | &mac_cfg0, 4)) |
258 | return -EIO; | 257 | return -EIO; |
@@ -401,14 +400,16 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
401 | { | 400 | { |
402 | int result = 0; | 401 | int result = 0; |
403 | __u32 status; | 402 | __u32 status; |
403 | |||
404 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
405 | return 0; | ||
406 | |||
404 | if (adapter->disable_phy_interrupts) | 407 | if (adapter->disable_phy_interrupts) |
405 | adapter->disable_phy_interrupts(adapter); | 408 | adapter->disable_phy_interrupts(adapter); |
406 | mdelay(2); | 409 | mdelay(2); |
407 | 410 | ||
408 | if (0 == | 411 | if (0 == netxen_niu_gbe_phy_read(adapter, |
409 | netxen_niu_gbe_phy_read(adapter, | 412 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) { |
410 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | ||
411 | &status)) { | ||
412 | if (netxen_get_phy_link(status)) { | 413 | if (netxen_get_phy_link(status)) { |
413 | if (netxen_get_phy_speed(status) == 2) { | 414 | if (netxen_get_phy_speed(status) == 2) { |
414 | netxen_niu_gbe_set_gmii_mode(adapter, port, 1); | 415 | netxen_niu_gbe_set_gmii_mode(adapter, port, 1); |
@@ -456,12 +457,12 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
456 | 457 | ||
457 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | 458 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
458 | { | 459 | { |
459 | u32 portnum = adapter->physical_port; | 460 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
460 | 461 | netxen_crb_writelit_adapter(adapter, | |
461 | netxen_crb_writelit_adapter(adapter, | 462 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); |
462 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); | 463 | netxen_crb_writelit_adapter(adapter, |
463 | netxen_crb_writelit_adapter(adapter, | 464 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5); |
464 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); | 465 | } |
465 | 466 | ||
466 | return 0; | 467 | return 0; |
467 | } | 468 | } |
@@ -581,10 +582,10 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, | |||
581 | if ((phy < 0) || (phy > 3)) | 582 | if ((phy < 0) || (phy > 3)) |
582 | return -EINVAL; | 583 | return -EINVAL; |
583 | 584 | ||
584 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), | 585 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), |
585 | &stationhigh, 4)) | 586 | &stationhigh, 4)) |
586 | return -EIO; | 587 | return -EIO; |
587 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), | 588 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), |
588 | &stationlow, 4)) | 589 | &stationlow, 4)) |
589 | return -EIO; | 590 | return -EIO; |
590 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); | 591 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); |
@@ -613,14 +614,14 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, | |||
613 | temp[0] = temp[1] = 0; | 614 | temp[0] = temp[1] = 0; |
614 | memcpy(temp + 2, addr, 2); | 615 | memcpy(temp + 2, addr, 2); |
615 | val = le32_to_cpu(*(__le32 *)temp); | 616 | val = le32_to_cpu(*(__le32 *)temp); |
616 | if (netxen_nic_hw_write_wx | 617 | if (adapter->hw_write_wx(adapter, |
617 | (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) | 618 | NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) |
618 | return -EIO; | 619 | return -EIO; |
619 | 620 | ||
620 | memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); | 621 | memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); |
621 | val = le32_to_cpu(*(__le32 *)temp); | 622 | val = le32_to_cpu(*(__le32 *)temp); |
622 | if (netxen_nic_hw_write_wx | 623 | if (adapter->hw_write_wx(adapter, |
623 | (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) | 624 | NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) |
624 | return -2; | 625 | return -2; |
625 | 626 | ||
626 | netxen_niu_macaddr_get(adapter, | 627 | netxen_niu_macaddr_get(adapter, |
@@ -654,7 +655,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
654 | 655 | ||
655 | mac_cfg0 = 0; | 656 | mac_cfg0 = 0; |
656 | netxen_gb_soft_reset(mac_cfg0); | 657 | netxen_gb_soft_reset(mac_cfg0); |
657 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | 658 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
658 | &mac_cfg0, 4)) | 659 | &mac_cfg0, 4)) |
659 | return -EIO; | 660 | return -EIO; |
660 | mac_cfg0 = 0; | 661 | mac_cfg0 = 0; |
@@ -666,7 +667,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
666 | netxen_gb_tx_reset_mac(mac_cfg0); | 667 | netxen_gb_tx_reset_mac(mac_cfg0); |
667 | netxen_gb_rx_reset_mac(mac_cfg0); | 668 | netxen_gb_rx_reset_mac(mac_cfg0); |
668 | 669 | ||
669 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | 670 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
670 | &mac_cfg0, 4)) | 671 | &mac_cfg0, 4)) |
671 | return -EIO; | 672 | return -EIO; |
672 | mac_cfg1 = 0; | 673 | mac_cfg1 = 0; |
@@ -679,7 +680,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
679 | 680 | ||
680 | if (mode == NETXEN_NIU_10_100_MB) { | 681 | if (mode == NETXEN_NIU_10_100_MB) { |
681 | netxen_gb_set_intfmode(mac_cfg1, 1); | 682 | netxen_gb_set_intfmode(mac_cfg1, 1); |
682 | if (netxen_nic_hw_write_wx(adapter, | 683 | if (adapter->hw_write_wx(adapter, |
683 | NETXEN_NIU_GB_MAC_CONFIG_1(port), | 684 | NETXEN_NIU_GB_MAC_CONFIG_1(port), |
684 | &mac_cfg1, 4)) | 685 | &mac_cfg1, 4)) |
685 | return -EIO; | 686 | return -EIO; |
@@ -692,7 +693,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
692 | 693 | ||
693 | } else if (mode == NETXEN_NIU_1000_MB) { | 694 | } else if (mode == NETXEN_NIU_1000_MB) { |
694 | netxen_gb_set_intfmode(mac_cfg1, 2); | 695 | netxen_gb_set_intfmode(mac_cfg1, 2); |
695 | if (netxen_nic_hw_write_wx(adapter, | 696 | if (adapter->hw_write_wx(adapter, |
696 | NETXEN_NIU_GB_MAC_CONFIG_1(port), | 697 | NETXEN_NIU_GB_MAC_CONFIG_1(port), |
697 | &mac_cfg1, 4)) | 698 | &mac_cfg1, 4)) |
698 | return -EIO; | 699 | return -EIO; |
@@ -704,7 +705,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
704 | } | 705 | } |
705 | mii_cfg = 0; | 706 | mii_cfg = 0; |
706 | netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); | 707 | netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); |
707 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), | 708 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), |
708 | &mii_cfg, 4)) | 709 | &mii_cfg, 4)) |
709 | return -EIO; | 710 | return -EIO; |
710 | mac_cfg0 = 0; | 711 | mac_cfg0 = 0; |
@@ -713,7 +714,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
713 | netxen_gb_unset_rx_flowctl(mac_cfg0); | 714 | netxen_gb_unset_rx_flowctl(mac_cfg0); |
714 | netxen_gb_unset_tx_flowctl(mac_cfg0); | 715 | netxen_gb_unset_tx_flowctl(mac_cfg0); |
715 | 716 | ||
716 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | 717 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
717 | &mac_cfg0, 4)) | 718 | &mac_cfg0, 4)) |
718 | return -EIO; | 719 | return -EIO; |
719 | return 0; | 720 | return 0; |
@@ -730,7 +731,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) | |||
730 | return -EINVAL; | 731 | return -EINVAL; |
731 | mac_cfg0 = 0; | 732 | mac_cfg0 = 0; |
732 | netxen_gb_soft_reset(mac_cfg0); | 733 | netxen_gb_soft_reset(mac_cfg0); |
733 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | 734 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
734 | &mac_cfg0, 4)) | 735 | &mac_cfg0, 4)) |
735 | return -EIO; | 736 | return -EIO; |
736 | return 0; | 737 | return 0; |
@@ -746,7 +747,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) | |||
746 | return -EINVAL; | 747 | return -EINVAL; |
747 | 748 | ||
748 | mac_cfg = 0; | 749 | mac_cfg = 0; |
749 | if (netxen_nic_hw_write_wx(adapter, | 750 | if (adapter->hw_write_wx(adapter, |
750 | NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) | 751 | NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) |
751 | return -EIO; | 752 | return -EIO; |
752 | return 0; | 753 | return 0; |
@@ -763,7 +764,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
763 | return -EINVAL; | 764 | return -EINVAL; |
764 | 765 | ||
765 | /* save previous contents */ | 766 | /* save previous contents */ |
766 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, | 767 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, |
767 | ®, 4)) | 768 | ®, 4)) |
768 | return -EIO; | 769 | return -EIO; |
769 | if (mode == NETXEN_NIU_PROMISC_MODE) { | 770 | if (mode == NETXEN_NIU_PROMISC_MODE) { |
@@ -801,7 +802,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
801 | return -EIO; | 802 | return -EIO; |
802 | } | 803 | } |
803 | } | 804 | } |
804 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, | 805 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, |
805 | ®, 4)) | 806 | ®, 4)) |
806 | return -EIO; | 807 | return -EIO; |
807 | return 0; | 808 | return 0; |
@@ -826,13 +827,13 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, | |||
826 | case 0: | 827 | case 0: |
827 | memcpy(temp + 2, addr, 2); | 828 | memcpy(temp + 2, addr, 2); |
828 | val = le32_to_cpu(*(__le32 *)temp); | 829 | val = le32_to_cpu(*(__le32 *)temp); |
829 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, | 830 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, |
830 | &val, 4)) | 831 | &val, 4)) |
831 | return -EIO; | 832 | return -EIO; |
832 | 833 | ||
833 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | 834 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); |
834 | val = le32_to_cpu(*(__le32 *)temp); | 835 | val = le32_to_cpu(*(__le32 *)temp); |
835 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, | 836 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, |
836 | &val, 4)) | 837 | &val, 4)) |
837 | return -EIO; | 838 | return -EIO; |
838 | break; | 839 | break; |
@@ -840,13 +841,13 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, | |||
840 | case 1: | 841 | case 1: |
841 | memcpy(temp + 2, addr, 2); | 842 | memcpy(temp + 2, addr, 2); |
842 | val = le32_to_cpu(*(__le32 *)temp); | 843 | val = le32_to_cpu(*(__le32 *)temp); |
843 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, | 844 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, |
844 | &val, 4)) | 845 | &val, 4)) |
845 | return -EIO; | 846 | return -EIO; |
846 | 847 | ||
847 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | 848 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); |
848 | val = le32_to_cpu(*(__le32 *)temp); | 849 | val = le32_to_cpu(*(__le32 *)temp); |
849 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, | 850 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, |
850 | &val, 4)) | 851 | &val, 4)) |
851 | return -EIO; | 852 | return -EIO; |
852 | break; | 853 | break; |
@@ -877,10 +878,10 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, | |||
877 | if (phy != 0) | 878 | if (phy != 0) |
878 | return -EINVAL; | 879 | return -EINVAL; |
879 | 880 | ||
880 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, | 881 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, |
881 | &stationhigh, 4)) | 882 | &stationhigh, 4)) |
882 | return -EIO; | 883 | return -EIO; |
883 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, | 884 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, |
884 | &stationlow, 4)) | 885 | &stationlow, 4)) |
885 | return -EIO; | 886 | return -EIO; |
886 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); | 887 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); |
@@ -901,7 +902,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
901 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 902 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
902 | return -EINVAL; | 903 | return -EINVAL; |
903 | 904 | ||
904 | if (netxen_nic_hw_read_wx(adapter, | 905 | if (adapter->hw_read_wx(adapter, |
905 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) | 906 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) |
906 | return -EIO; | 907 | return -EIO; |
907 | if (mode == NETXEN_NIU_PROMISC_MODE) | 908 | if (mode == NETXEN_NIU_PROMISC_MODE) |
@@ -909,6 +910,11 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
909 | else | 910 | else |
910 | reg = (reg & ~0x2000UL); | 911 | reg = (reg & ~0x2000UL); |
911 | 912 | ||
913 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | ||
914 | reg = (reg | 0x1000UL); | ||
915 | else | ||
916 | reg = (reg & ~0x1000UL); | ||
917 | |||
912 | netxen_crb_writelit_adapter(adapter, | 918 | netxen_crb_writelit_adapter(adapter, |
913 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | 919 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); |
914 | 920 | ||
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index a566b50f36f5..3bfa51b62a4f 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h | |||
@@ -42,8 +42,11 @@ | |||
42 | #define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c) | 42 | #define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c) |
43 | #define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */ | 43 | #define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */ |
44 | #define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) | 44 | #define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) |
45 | #define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x18) /* host add:cmd ring */ | 45 | #define NX_CDRP_CRB_OFFSET NETXEN_NIC_REG(0x18) |
46 | #define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x1c) | 46 | #define NX_ARG1_CRB_OFFSET NETXEN_NIC_REG(0x1c) |
47 | #define NX_ARG2_CRB_OFFSET NETXEN_NIC_REG(0x20) | ||
48 | #define NX_ARG3_CRB_OFFSET NETXEN_NIC_REG(0x24) | ||
49 | #define NX_SIGN_CRB_OFFSET NETXEN_NIC_REG(0x28) | ||
47 | #define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */ | 50 | #define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */ |
48 | #define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24) | 51 | #define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24) |
49 | #define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28) | 52 | #define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28) |
@@ -73,8 +76,8 @@ | |||
73 | #define CRB_RX_LRO_MID_TIMER NETXEN_NIC_REG(0x88) | 76 | #define CRB_RX_LRO_MID_TIMER NETXEN_NIC_REG(0x88) |
74 | #define CRB_DMA_MAX_RCV_BUFS NETXEN_NIC_REG(0x8c) | 77 | #define CRB_DMA_MAX_RCV_BUFS NETXEN_NIC_REG(0x8c) |
75 | #define CRB_MAX_DMA_ENTRIES NETXEN_NIC_REG(0x90) | 78 | #define CRB_MAX_DMA_ENTRIES NETXEN_NIC_REG(0x90) |
76 | #define CRB_XG_STATE NETXEN_NIC_REG(0x94) /* XG Link status */ | 79 | #define CRB_XG_STATE NETXEN_NIC_REG(0x94) /* XG Link status */ |
77 | #define CRB_AGENT_GO NETXEN_NIC_REG(0x98) /* NIC pkt gen agent */ | 80 | #define CRB_XG_STATE_P3 NETXEN_NIC_REG(0x98) /* XG PF Link status */ |
78 | #define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0x9c) | 81 | #define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0x9c) |
79 | #define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0) | 82 | #define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0) |
80 | #define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4) | 83 | #define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4) |
@@ -97,7 +100,9 @@ | |||
97 | #define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0) | 100 | #define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0) |
98 | #define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4) | 101 | #define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4) |
99 | #define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8) | 102 | #define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8) |
103 | #define CRB_HOST_DUMMY_BUF NETXEN_NIC_REG(0xfc) | ||
100 | 104 | ||
105 | #define CRB_RCVPEG_STATE NETXEN_NIC_REG(0x13c) | ||
101 | #define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac) | 106 | #define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac) |
102 | #define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) | 107 | #define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) |
103 | #define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8) | 108 | #define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8) |
@@ -147,29 +152,15 @@ | |||
147 | #define nx_get_temp_state(x) ((x) & 0xffff) | 152 | #define nx_get_temp_state(x) ((x) & 0xffff) |
148 | #define nx_encode_temp(val, state) (((val) << 16) | (state)) | 153 | #define nx_encode_temp(val, state) (((val) << 16) | (state)) |
149 | 154 | ||
150 | /* CRB registers per Rcv Descriptor ring */ | ||
151 | struct netxen_rcv_desc_crb { | ||
152 | u32 crb_rcv_producer_offset __attribute__ ((aligned(512))); | ||
153 | u32 crb_rcv_consumer_offset; | ||
154 | u32 crb_globalrcv_ring; | ||
155 | u32 crb_rcv_ring_size; | ||
156 | }; | ||
157 | |||
158 | /* | 155 | /* |
159 | * CRB registers used by the receive peg logic. | 156 | * CRB registers used by the receive peg logic. |
160 | */ | 157 | */ |
161 | 158 | ||
162 | struct netxen_recv_crb { | 159 | struct netxen_recv_crb { |
163 | struct netxen_rcv_desc_crb rcv_desc_crb[NUM_RCV_DESC_RINGS]; | 160 | u32 crb_rcv_producer[NUM_RCV_DESC_RINGS]; |
164 | u32 crb_rcvstatus_ring; | 161 | u32 crb_sts_consumer; |
165 | u32 crb_rcv_status_producer; | ||
166 | u32 crb_rcv_status_consumer; | ||
167 | u32 crb_rcvpeg_state; | ||
168 | u32 crb_status_ring_size; | ||
169 | }; | 162 | }; |
170 | 163 | ||
171 | extern struct netxen_recv_crb recv_crb_registers[]; | ||
172 | |||
173 | /* | 164 | /* |
174 | * Temperature control. | 165 | * Temperature control. |
175 | */ | 166 | */ |