diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 27 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 8 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 12 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 201 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_isr.c | 19 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 265 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_phan_reg.h | 3 |
8 files changed, 137 insertions, 400 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2bc5eaae141f..7f20a03623a0 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -85,7 +85,7 @@ | |||
85 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) | 85 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) |
86 | #define RCV_BUFFSIZE \ | 86 | #define RCV_BUFFSIZE \ |
87 | (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) | 87 | (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) |
88 | #define find_diff_among(a,b,range) ((a)<=(b)?((b)-(a)):((b)+(range)-(a))) | 88 | #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) |
89 | 89 | ||
90 | #define NETXEN_NETDEV_STATUS 0x1 | 90 | #define NETXEN_NETDEV_STATUS 0x1 |
91 | #define NETXEN_RCV_PRODUCER_OFFSET 0 | 91 | #define NETXEN_RCV_PRODUCER_OFFSET 0 |
@@ -204,7 +204,7 @@ enum { | |||
204 | ? RCV_DESC_LRO : \ | 204 | ? RCV_DESC_LRO : \ |
205 | (RCV_DESC_NORMAL))) | 205 | (RCV_DESC_NORMAL))) |
206 | 206 | ||
207 | #define MAX_CMD_DESCRIPTORS 1024 | 207 | #define MAX_CMD_DESCRIPTORS 4096 |
208 | #define MAX_RCV_DESCRIPTORS 16384 | 208 | #define MAX_RCV_DESCRIPTORS 16384 |
209 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) | 209 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) |
210 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) | 210 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) |
@@ -818,15 +818,8 @@ struct netxen_adapter_stats { | |||
818 | u64 badskblen; | 818 | u64 badskblen; |
819 | u64 nocmddescriptor; | 819 | u64 nocmddescriptor; |
820 | u64 polled; | 820 | u64 polled; |
821 | u64 uphappy; | 821 | u64 rxdropped; |
822 | u64 updropped; | ||
823 | u64 uplcong; | ||
824 | u64 uphcong; | ||
825 | u64 upmcong; | ||
826 | u64 updunno; | ||
827 | u64 skbfreed; | ||
828 | u64 txdropped; | 822 | u64 txdropped; |
829 | u64 txnullskb; | ||
830 | u64 csummed; | 823 | u64 csummed; |
831 | u64 no_rcv; | 824 | u64 no_rcv; |
832 | u64 rxbytes; | 825 | u64 rxbytes; |
@@ -842,7 +835,6 @@ struct netxen_rcv_desc_ctx { | |||
842 | u32 flags; | 835 | u32 flags; |
843 | u32 producer; | 836 | u32 producer; |
844 | u32 rcv_pending; /* Num of bufs posted in phantom */ | 837 | u32 rcv_pending; /* Num of bufs posted in phantom */ |
845 | u32 rcv_free; /* Num of bufs in free list */ | ||
846 | dma_addr_t phys_addr; | 838 | dma_addr_t phys_addr; |
847 | struct pci_dev *phys_pdev; | 839 | struct pci_dev *phys_pdev; |
848 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ | 840 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ |
@@ -889,8 +881,6 @@ struct netxen_adapter { | |||
889 | int mtu; | 881 | int mtu; |
890 | int portnum; | 882 | int portnum; |
891 | 883 | ||
892 | spinlock_t tx_lock; | ||
893 | spinlock_t lock; | ||
894 | struct work_struct watchdog_task; | 884 | struct work_struct watchdog_task; |
895 | struct timer_list watchdog_timer; | 885 | struct timer_list watchdog_timer; |
896 | struct work_struct tx_timeout_task; | 886 | struct work_struct tx_timeout_task; |
@@ -899,16 +889,12 @@ struct netxen_adapter { | |||
899 | 889 | ||
900 | u32 cmd_producer; | 890 | u32 cmd_producer; |
901 | __le32 *cmd_consumer; | 891 | __le32 *cmd_consumer; |
902 | |||
903 | u32 last_cmd_consumer; | 892 | u32 last_cmd_consumer; |
893 | |||
904 | u32 max_tx_desc_count; | 894 | u32 max_tx_desc_count; |
905 | u32 max_rx_desc_count; | 895 | u32 max_rx_desc_count; |
906 | u32 max_jumbo_rx_desc_count; | 896 | u32 max_jumbo_rx_desc_count; |
907 | u32 max_lro_rx_desc_count; | 897 | u32 max_lro_rx_desc_count; |
908 | /* Num of instances active on cmd buffer ring */ | ||
909 | u32 proc_cmd_buf_counter; | ||
910 | |||
911 | u32 num_threads, total_threads; /*Use to keep track of xmit threads */ | ||
912 | 898 | ||
913 | u32 flags; | 899 | u32 flags; |
914 | u32 irq; | 900 | u32 irq; |
@@ -942,6 +928,7 @@ struct netxen_adapter { | |||
942 | struct pci_dev *ctx_desc_pdev; | 928 | struct pci_dev *ctx_desc_pdev; |
943 | dma_addr_t ctx_desc_phys_addr; | 929 | dma_addr_t ctx_desc_phys_addr; |
944 | int intr_scheme; | 930 | int intr_scheme; |
931 | int msi_mode; | ||
945 | int (*enable_phy_interrupts) (struct netxen_adapter *); | 932 | int (*enable_phy_interrupts) (struct netxen_adapter *); |
946 | int (*disable_phy_interrupts) (struct netxen_adapter *); | 933 | int (*disable_phy_interrupts) (struct netxen_adapter *); |
947 | void (*handle_phy_intr) (struct netxen_adapter *); | 934 | void (*handle_phy_intr) (struct netxen_adapter *); |
@@ -1075,12 +1062,10 @@ void netxen_tso_check(struct netxen_adapter *adapter, | |||
1075 | struct cmd_desc_type0 *desc, struct sk_buff *skb); | 1062 | struct cmd_desc_type0 *desc, struct sk_buff *skb); |
1076 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); | 1063 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); |
1077 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); | 1064 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); |
1078 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter); | ||
1079 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter); | ||
1080 | void netxen_watchdog_task(struct work_struct *work); | 1065 | void netxen_watchdog_task(struct work_struct *work); |
1081 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, | 1066 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, |
1082 | u32 ringid); | 1067 | u32 ringid); |
1083 | int netxen_process_cmd_ring(unsigned long data); | 1068 | int netxen_process_cmd_ring(struct netxen_adapter *adapter); |
1084 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); | 1069 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); |
1085 | void netxen_nic_set_multi(struct net_device *netdev); | 1070 | void netxen_nic_set_multi(struct net_device *netdev); |
1086 | int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); | 1071 | int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 7a876f4b8db2..6e98d830eefb 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -64,15 +64,7 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { | |||
64 | {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, | 64 | {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, |
65 | {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, | 65 | {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, |
66 | {"polled", NETXEN_NIC_STAT(stats.polled)}, | 66 | {"polled", NETXEN_NIC_STAT(stats.polled)}, |
67 | {"uphappy", NETXEN_NIC_STAT(stats.uphappy)}, | ||
68 | {"updropped", NETXEN_NIC_STAT(stats.updropped)}, | ||
69 | {"uplcong", NETXEN_NIC_STAT(stats.uplcong)}, | ||
70 | {"uphcong", NETXEN_NIC_STAT(stats.uphcong)}, | ||
71 | {"upmcong", NETXEN_NIC_STAT(stats.upmcong)}, | ||
72 | {"updunno", NETXEN_NIC_STAT(stats.updunno)}, | ||
73 | {"skb_freed", NETXEN_NIC_STAT(stats.skbfreed)}, | ||
74 | {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, | 67 | {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, |
75 | {"tx_null_skb", NETXEN_NIC_STAT(stats.txnullskb)}, | ||
76 | {"csummed", NETXEN_NIC_STAT(stats.csummed)}, | 68 | {"csummed", NETXEN_NIC_STAT(stats.csummed)}, |
77 | {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, | 69 | {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, |
78 | {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, | 70 | {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index d72f8f8fcb50..160f605e58db 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -456,6 +456,12 @@ enum { | |||
456 | #define ISR_INT_MASK_SLOW (NETXEN_PCIX_PS_REG(PCIX_INT_MASK)) | 456 | #define ISR_INT_MASK_SLOW (NETXEN_PCIX_PS_REG(PCIX_INT_MASK)) |
457 | #define ISR_INT_TARGET_STATUS (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS)) | 457 | #define ISR_INT_TARGET_STATUS (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS)) |
458 | #define ISR_INT_TARGET_MASK (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK)) | 458 | #define ISR_INT_TARGET_MASK (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK)) |
459 | #define ISR_INT_TARGET_STATUS_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F1)) | ||
460 | #define ISR_INT_TARGET_MASK_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F1)) | ||
461 | #define ISR_INT_TARGET_STATUS_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F2)) | ||
462 | #define ISR_INT_TARGET_MASK_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2)) | ||
463 | #define ISR_INT_TARGET_STATUS_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3)) | ||
464 | #define ISR_INT_TARGET_MASK_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3)) | ||
459 | 465 | ||
460 | #define NETXEN_PCI_MAPSIZE 128 | 466 | #define NETXEN_PCI_MAPSIZE 128 |
461 | #define NETXEN_PCI_DDR_NET (0x00000000UL) | 467 | #define NETXEN_PCI_DDR_NET (0x00000000UL) |
@@ -662,6 +668,12 @@ enum { | |||
662 | 668 | ||
663 | #define PCIX_TARGET_STATUS (0x10118) | 669 | #define PCIX_TARGET_STATUS (0x10118) |
664 | #define PCIX_TARGET_MASK (0x10128) | 670 | #define PCIX_TARGET_MASK (0x10128) |
671 | #define PCIX_TARGET_STATUS_F1 (0x10160) | ||
672 | #define PCIX_TARGET_MASK_F1 (0x10170) | ||
673 | #define PCIX_TARGET_STATUS_F2 (0x10164) | ||
674 | #define PCIX_TARGET_MASK_F2 (0x10174) | ||
675 | #define PCIX_TARGET_STATUS_F3 (0x10168) | ||
676 | #define PCIX_TARGET_MASK_F3 (0x10178) | ||
665 | 677 | ||
666 | #define PCIX_MSI_F0 (0x13000) | 678 | #define PCIX_MSI_F0 (0x13000) |
667 | #define PCIX_MSI_F1 (0x13004) | 679 | #define PCIX_MSI_F1 (0x13004) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 01355701bf8e..05748ca6f216 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -398,6 +398,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); | 398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); |
399 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, | 399 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, |
400 | adapter->intr_scheme); | 400 | adapter->intr_scheme); |
401 | adapter->msi_mode = readl( | ||
402 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); | ||
401 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); | 403 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); |
402 | 404 | ||
403 | addr = netxen_alloc(adapter->ahw.pdev, | 405 | addr = netxen_alloc(adapter->ahw.pdev, |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 9e38bcb3fba9..45fa33e0cb90 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -145,6 +145,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
145 | /* Window 1 call */ | 145 | /* Window 1 call */ |
146 | writel(INTR_SCHEME_PERPORT, | 146 | writel(INTR_SCHEME_PERPORT, |
147 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); | 147 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); |
148 | writel(MSI_MODE_MULTIFUNC, | ||
149 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST)); | ||
148 | writel(MPORT_MULTI_FUNCTION_MODE, | 150 | writel(MPORT_MULTI_FUNCTION_MODE, |
149 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); | 151 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); |
150 | writel(PHAN_INITIALIZE_ACK, | 152 | writel(PHAN_INITIALIZE_ACK, |
@@ -183,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | |||
183 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 185 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { |
184 | struct netxen_rx_buffer *rx_buf; | 186 | struct netxen_rx_buffer *rx_buf; |
185 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; | 187 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; |
186 | rcv_desc->rcv_free = rcv_desc->max_rx_desc_count; | ||
187 | rcv_desc->begin_alloc = 0; | 188 | rcv_desc->begin_alloc = 0; |
188 | rx_buf = rcv_desc->rx_buf_arr; | 189 | rx_buf = rcv_desc->rx_buf_arr; |
189 | num_rx_bufs = rcv_desc->max_rx_desc_count; | 190 | num_rx_bufs = rcv_desc->max_rx_desc_count; |
@@ -974,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | |||
974 | return 0; | 975 | return 0; |
975 | } | 976 | } |
976 | 977 | ||
977 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter) | ||
978 | { | ||
979 | int ctx; | ||
980 | |||
981 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
982 | struct netxen_recv_context *recv_ctx = | ||
983 | &(adapter->recv_ctx[ctx]); | ||
984 | u32 consumer; | ||
985 | struct status_desc *desc_head; | ||
986 | struct status_desc *desc; | ||
987 | |||
988 | consumer = recv_ctx->status_rx_consumer; | ||
989 | desc_head = recv_ctx->rcv_status_desc_head; | ||
990 | desc = &desc_head[consumer]; | ||
991 | |||
992 | if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) | ||
993 | return 1; | ||
994 | } | ||
995 | |||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | 978 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) |
1000 | { | 979 | { |
1001 | struct net_device *netdev = adapter->netdev; | 980 | struct net_device *netdev = adapter->netdev; |
@@ -1038,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1038 | 1017 | ||
1039 | void netxen_watchdog_task(struct work_struct *work) | 1018 | void netxen_watchdog_task(struct work_struct *work) |
1040 | { | 1019 | { |
1041 | struct net_device *netdev; | ||
1042 | struct netxen_adapter *adapter = | 1020 | struct netxen_adapter *adapter = |
1043 | container_of(work, struct netxen_adapter, watchdog_task); | 1021 | container_of(work, struct netxen_adapter, watchdog_task); |
1044 | 1022 | ||
@@ -1048,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1048 | if (adapter->handle_phy_intr) | 1026 | if (adapter->handle_phy_intr) |
1049 | adapter->handle_phy_intr(adapter); | 1027 | adapter->handle_phy_intr(adapter); |
1050 | 1028 | ||
1051 | netdev = adapter->netdev; | ||
1052 | if ((netif_running(netdev)) && !netif_carrier_ok(netdev) && | ||
1053 | netxen_nic_link_ok(adapter) ) { | ||
1054 | printk(KERN_INFO "%s %s (port %d), Link is up\n", | ||
1055 | netxen_nic_driver_name, netdev->name, adapter->portnum); | ||
1056 | netif_carrier_on(netdev); | ||
1057 | netif_wake_queue(netdev); | ||
1058 | } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) { | ||
1059 | printk(KERN_ERR "%s %s Link is Down\n", | ||
1060 | netxen_nic_driver_name, netdev->name); | ||
1061 | netif_carrier_off(netdev); | ||
1062 | netif_stop_queue(netdev); | ||
1063 | } | ||
1064 | |||
1065 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 1029 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); |
1066 | } | 1030 | } |
1067 | 1031 | ||
@@ -1125,7 +1089,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1125 | skb = (struct sk_buff *)buffer->skb; | 1089 | skb = (struct sk_buff *)buffer->skb; |
1126 | 1090 | ||
1127 | if (likely(adapter->rx_csum && | 1091 | if (likely(adapter->rx_csum && |
1128 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { | 1092 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { |
1129 | adapter->stats.csummed++; | 1093 | adapter->stats.csummed++; |
1130 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1094 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1131 | } else | 1095 | } else |
@@ -1142,40 +1106,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1142 | skb->protocol = eth_type_trans(skb, netdev); | 1106 | skb->protocol = eth_type_trans(skb, netdev); |
1143 | 1107 | ||
1144 | ret = netif_receive_skb(skb); | 1108 | ret = netif_receive_skb(skb); |
1145 | |||
1146 | /* | ||
1147 | * RH: Do we need these stats on a regular basis. Can we get it from | ||
1148 | * Linux stats. | ||
1149 | */ | ||
1150 | switch (ret) { | ||
1151 | case NET_RX_SUCCESS: | ||
1152 | adapter->stats.uphappy++; | ||
1153 | break; | ||
1154 | |||
1155 | case NET_RX_CN_LOW: | ||
1156 | adapter->stats.uplcong++; | ||
1157 | break; | ||
1158 | |||
1159 | case NET_RX_CN_MOD: | ||
1160 | adapter->stats.upmcong++; | ||
1161 | break; | ||
1162 | |||
1163 | case NET_RX_CN_HIGH: | ||
1164 | adapter->stats.uphcong++; | ||
1165 | break; | ||
1166 | |||
1167 | case NET_RX_DROP: | ||
1168 | adapter->stats.updropped++; | ||
1169 | break; | ||
1170 | |||
1171 | default: | ||
1172 | adapter->stats.updunno++; | ||
1173 | break; | ||
1174 | } | ||
1175 | |||
1176 | netdev->last_rx = jiffies; | 1109 | netdev->last_rx = jiffies; |
1177 | 1110 | ||
1178 | rcv_desc->rcv_free++; | ||
1179 | rcv_desc->rcv_pending--; | 1111 | rcv_desc->rcv_pending--; |
1180 | 1112 | ||
1181 | /* | 1113 | /* |
@@ -1200,13 +1132,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1200 | u32 producer = 0; | 1132 | u32 producer = 0; |
1201 | int count = 0, ring; | 1133 | int count = 0, ring; |
1202 | 1134 | ||
1203 | DPRINTK(INFO, "procesing receive\n"); | ||
1204 | /* | ||
1205 | * we assume in this case that there is only one port and that is | ||
1206 | * port #1...changes need to be done in firmware to indicate port | ||
1207 | * number as part of the descriptor. This way we will be able to get | ||
1208 | * the netdev which is associated with that device. | ||
1209 | */ | ||
1210 | while (count < max) { | 1135 | while (count < max) { |
1211 | desc = &desc_head[consumer]; | 1136 | desc = &desc_head[consumer]; |
1212 | if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { | 1137 | if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { |
@@ -1219,11 +1144,8 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1219 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); | 1144 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); |
1220 | count++; | 1145 | count++; |
1221 | } | 1146 | } |
1222 | if (count) { | 1147 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) |
1223 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 1148 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); |
1224 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); | ||
1225 | } | ||
1226 | } | ||
1227 | 1149 | ||
1228 | /* update the consumer index in phantom */ | 1150 | /* update the consumer index in phantom */ |
1229 | if (count) { | 1151 | if (count) { |
@@ -1233,108 +1155,60 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1233 | /* Window = 1 */ | 1155 | /* Window = 1 */ |
1234 | writel(consumer, | 1156 | writel(consumer, |
1235 | NETXEN_CRB_NORMALIZE(adapter, | 1157 | NETXEN_CRB_NORMALIZE(adapter, |
1236 | recv_crb_registers[adapter->portnum]. | 1158 | recv_crb_registers[adapter->portnum]. |
1237 | crb_rcv_status_consumer)); | 1159 | crb_rcv_status_consumer)); |
1238 | wmb(); | ||
1239 | } | 1160 | } |
1240 | 1161 | ||
1241 | return count; | 1162 | return count; |
1242 | } | 1163 | } |
1243 | 1164 | ||
1244 | /* Process Command status ring */ | 1165 | /* Process Command status ring */ |
1245 | int netxen_process_cmd_ring(unsigned long data) | 1166 | int netxen_process_cmd_ring(struct netxen_adapter *adapter) |
1246 | { | 1167 | { |
1247 | u32 last_consumer; | 1168 | u32 last_consumer, consumer; |
1248 | u32 consumer; | 1169 | int count = 0, i; |
1249 | struct netxen_adapter *adapter = (struct netxen_adapter *)data; | ||
1250 | int count1 = 0; | ||
1251 | int count2 = 0; | ||
1252 | struct netxen_cmd_buffer *buffer; | 1170 | struct netxen_cmd_buffer *buffer; |
1253 | struct pci_dev *pdev; | 1171 | struct pci_dev *pdev = adapter->pdev; |
1172 | struct net_device *netdev = adapter->netdev; | ||
1254 | struct netxen_skb_frag *frag; | 1173 | struct netxen_skb_frag *frag; |
1255 | u32 i; | 1174 | int done = 0; |
1256 | int done; | ||
1257 | 1175 | ||
1258 | spin_lock(&adapter->tx_lock); | ||
1259 | last_consumer = adapter->last_cmd_consumer; | 1176 | last_consumer = adapter->last_cmd_consumer; |
1260 | DPRINTK(INFO, "procesing xmit complete\n"); | ||
1261 | /* we assume in this case that there is only one port and that is | ||
1262 | * port #1...changes need to be done in firmware to indicate port | ||
1263 | * number as part of the descriptor. This way we will be able to get | ||
1264 | * the netdev which is associated with that device. | ||
1265 | */ | ||
1266 | |||
1267 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); | 1177 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); |
1268 | if (last_consumer == consumer) { /* Ring is empty */ | ||
1269 | DPRINTK(INFO, "last_consumer %d == consumer %d\n", | ||
1270 | last_consumer, consumer); | ||
1271 | spin_unlock(&adapter->tx_lock); | ||
1272 | return 1; | ||
1273 | } | ||
1274 | |||
1275 | adapter->proc_cmd_buf_counter++; | ||
1276 | /* | ||
1277 | * Not needed - does not seem to be used anywhere. | ||
1278 | * adapter->cmd_consumer = consumer; | ||
1279 | */ | ||
1280 | spin_unlock(&adapter->tx_lock); | ||
1281 | 1178 | ||
1282 | while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { | 1179 | while (last_consumer != consumer) { |
1283 | buffer = &adapter->cmd_buf_arr[last_consumer]; | 1180 | buffer = &adapter->cmd_buf_arr[last_consumer]; |
1284 | pdev = adapter->pdev; | ||
1285 | if (buffer->skb) { | 1181 | if (buffer->skb) { |
1286 | frag = &buffer->frag_array[0]; | 1182 | frag = &buffer->frag_array[0]; |
1287 | pci_unmap_single(pdev, frag->dma, frag->length, | 1183 | pci_unmap_single(pdev, frag->dma, frag->length, |
1288 | PCI_DMA_TODEVICE); | 1184 | PCI_DMA_TODEVICE); |
1289 | frag->dma = 0ULL; | 1185 | frag->dma = 0ULL; |
1290 | for (i = 1; i < buffer->frag_count; i++) { | 1186 | for (i = 1; i < buffer->frag_count; i++) { |
1291 | DPRINTK(INFO, "getting fragment no %d\n", i); | ||
1292 | frag++; /* Get the next frag */ | 1187 | frag++; /* Get the next frag */ |
1293 | pci_unmap_page(pdev, frag->dma, frag->length, | 1188 | pci_unmap_page(pdev, frag->dma, frag->length, |
1294 | PCI_DMA_TODEVICE); | 1189 | PCI_DMA_TODEVICE); |
1295 | frag->dma = 0ULL; | 1190 | frag->dma = 0ULL; |
1296 | } | 1191 | } |
1297 | 1192 | ||
1298 | adapter->stats.skbfreed++; | 1193 | adapter->stats.xmitfinished++; |
1299 | dev_kfree_skb_any(buffer->skb); | 1194 | dev_kfree_skb_any(buffer->skb); |
1300 | buffer->skb = NULL; | 1195 | buffer->skb = NULL; |
1301 | } else if (adapter->proc_cmd_buf_counter == 1) { | ||
1302 | adapter->stats.txnullskb++; | ||
1303 | } | ||
1304 | if (unlikely(netif_queue_stopped(adapter->netdev) | ||
1305 | && netif_carrier_ok(adapter->netdev)) | ||
1306 | && ((jiffies - adapter->netdev->trans_start) > | ||
1307 | adapter->netdev->watchdog_timeo)) { | ||
1308 | SCHEDULE_WORK(&adapter->tx_timeout_task); | ||
1309 | } | 1196 | } |
1310 | 1197 | ||
1311 | last_consumer = get_next_index(last_consumer, | 1198 | last_consumer = get_next_index(last_consumer, |
1312 | adapter->max_tx_desc_count); | 1199 | adapter->max_tx_desc_count); |
1313 | count1++; | 1200 | if (++count >= MAX_STATUS_HANDLE) |
1201 | break; | ||
1314 | } | 1202 | } |
1315 | 1203 | ||
1316 | count2 = 0; | 1204 | if (count) { |
1317 | spin_lock(&adapter->tx_lock); | ||
1318 | if ((--adapter->proc_cmd_buf_counter) == 0) { | ||
1319 | adapter->last_cmd_consumer = last_consumer; | 1205 | adapter->last_cmd_consumer = last_consumer; |
1320 | while ((adapter->last_cmd_consumer != consumer) | 1206 | smp_mb(); |
1321 | && (count2 < MAX_STATUS_HANDLE)) { | 1207 | if (netif_queue_stopped(netdev) && netif_running(netdev)) { |
1322 | buffer = | 1208 | netif_tx_lock(netdev); |
1323 | &adapter->cmd_buf_arr[adapter->last_cmd_consumer]; | 1209 | netif_wake_queue(netdev); |
1324 | count2++; | 1210 | smp_mb(); |
1325 | if (buffer->skb) | 1211 | netif_tx_unlock(netdev); |
1326 | break; | ||
1327 | else | ||
1328 | adapter->last_cmd_consumer = | ||
1329 | get_next_index(adapter->last_cmd_consumer, | ||
1330 | adapter->max_tx_desc_count); | ||
1331 | } | ||
1332 | } | ||
1333 | if (count1 || count2) { | ||
1334 | if (netif_queue_stopped(adapter->netdev) | ||
1335 | && (adapter->flags & NETXEN_NETDEV_STATUS)) { | ||
1336 | netif_wake_queue(adapter->netdev); | ||
1337 | adapter->flags &= ~NETXEN_NETDEV_STATUS; | ||
1338 | } | 1212 | } |
1339 | } | 1213 | } |
1340 | /* | 1214 | /* |
@@ -1350,16 +1224,9 @@ int netxen_process_cmd_ring(unsigned long data) | |||
1350 | * There is still a possible race condition and the host could miss an | 1224 | * There is still a possible race condition and the host could miss an |
1351 | * interrupt. The card has to take care of this. | 1225 | * interrupt. The card has to take care of this. |
1352 | */ | 1226 | */ |
1353 | if (adapter->last_cmd_consumer == consumer && | 1227 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); |
1354 | (((adapter->cmd_producer + 1) % | 1228 | done = (last_consumer == consumer); |
1355 | adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) { | ||
1356 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); | ||
1357 | } | ||
1358 | done = (adapter->last_cmd_consumer == consumer); | ||
1359 | 1229 | ||
1360 | spin_unlock(&adapter->tx_lock); | ||
1361 | DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer, | ||
1362 | __FUNCTION__); | ||
1363 | return (done); | 1230 | return (done); |
1364 | } | 1231 | } |
1365 | 1232 | ||
@@ -1433,8 +1300,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
1433 | rcv_desc->begin_alloc = index; | 1300 | rcv_desc->begin_alloc = index; |
1434 | rcv_desc->rcv_pending += count; | 1301 | rcv_desc->rcv_pending += count; |
1435 | rcv_desc->producer = producer; | 1302 | rcv_desc->producer = producer; |
1436 | if (rcv_desc->rcv_free >= 32) { | ||
1437 | rcv_desc->rcv_free = 0; | ||
1438 | /* Window = 1 */ | 1303 | /* Window = 1 */ |
1439 | writel((producer - 1) & | 1304 | writel((producer - 1) & |
1440 | (rcv_desc->max_rx_desc_count - 1), | 1305 | (rcv_desc->max_rx_desc_count - 1), |
@@ -1458,8 +1323,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
1458 | writel(msg, | 1323 | writel(msg, |
1459 | DB_NORMALIZE(adapter, | 1324 | DB_NORMALIZE(adapter, |
1460 | NETXEN_RCV_PRODUCER_OFFSET)); | 1325 | NETXEN_RCV_PRODUCER_OFFSET)); |
1461 | wmb(); | ||
1462 | } | ||
1463 | } | 1326 | } |
1464 | } | 1327 | } |
1465 | 1328 | ||
@@ -1523,8 +1386,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | |||
1523 | rcv_desc->begin_alloc = index; | 1386 | rcv_desc->begin_alloc = index; |
1524 | rcv_desc->rcv_pending += count; | 1387 | rcv_desc->rcv_pending += count; |
1525 | rcv_desc->producer = producer; | 1388 | rcv_desc->producer = producer; |
1526 | if (rcv_desc->rcv_free >= 32) { | ||
1527 | rcv_desc->rcv_free = 0; | ||
1528 | /* Window = 1 */ | 1389 | /* Window = 1 */ |
1529 | writel((producer - 1) & | 1390 | writel((producer - 1) & |
1530 | (rcv_desc->max_rx_desc_count - 1), | 1391 | (rcv_desc->max_rx_desc_count - 1), |
@@ -1534,21 +1395,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | |||
1534 | rcv_desc_crb[ringid]. | 1395 | rcv_desc_crb[ringid]. |
1535 | crb_rcv_producer_offset)); | 1396 | crb_rcv_producer_offset)); |
1536 | wmb(); | 1397 | wmb(); |
1537 | } | ||
1538 | } | 1398 | } |
1539 | } | 1399 | } |
1540 | 1400 | ||
1541 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter) | ||
1542 | { | ||
1543 | if (find_diff_among(adapter->last_cmd_consumer, | ||
1544 | adapter->cmd_producer, | ||
1545 | adapter->max_tx_desc_count) > 0) | ||
1546 | return 1; | ||
1547 | |||
1548 | return 0; | ||
1549 | } | ||
1550 | |||
1551 | |||
1552 | void netxen_nic_clear_stats(struct netxen_adapter *adapter) | 1401 | void netxen_nic_clear_stats(struct netxen_adapter *adapter) |
1553 | { | 1402 | { |
1554 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | 1403 | memset(&adapter->stats, 0, sizeof(adapter->stats)); |
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 48a404aa66ce..c81313b717bd 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c | |||
@@ -59,7 +59,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | |||
59 | /* packet transmit problems */ | 59 | /* packet transmit problems */ |
60 | stats->tx_errors = adapter->stats.nocmddescriptor; | 60 | stats->tx_errors = adapter->stats.nocmddescriptor; |
61 | /* no space in linux buffers */ | 61 | /* no space in linux buffers */ |
62 | stats->rx_dropped = adapter->stats.updropped; | 62 | stats->rx_dropped = adapter->stats.rxdropped; |
63 | /* no space available in linux */ | 63 | /* no space available in linux */ |
64 | stats->tx_dropped = adapter->stats.txdropped; | 64 | stats->tx_dropped = adapter->stats.txdropped; |
65 | 65 | ||
@@ -193,14 +193,14 @@ int netxen_nic_link_ok(struct netxen_adapter *adapter) | |||
193 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | 193 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) |
194 | { | 194 | { |
195 | struct net_device *netdev = adapter->netdev; | 195 | struct net_device *netdev = adapter->netdev; |
196 | u32 val, val1; | 196 | u32 val; |
197 | 197 | ||
198 | /* WINDOW = 1 */ | 198 | /* WINDOW = 1 */ |
199 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | 199 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); |
200 | val >>= (physical_port[adapter->portnum] * 8); | 200 | val >>= (physical_port[adapter->portnum] * 8); |
201 | val1 = val & 0xff; | 201 | val &= 0xff; |
202 | 202 | ||
203 | if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) { | 203 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { |
204 | printk(KERN_INFO "%s: %s NIC Link is down\n", | 204 | printk(KERN_INFO "%s: %s NIC Link is down\n", |
205 | netxen_nic_driver_name, netdev->name); | 205 | netxen_nic_driver_name, netdev->name); |
206 | adapter->ahw.xg_linkup = 0; | 206 | adapter->ahw.xg_linkup = 0; |
@@ -208,16 +208,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
208 | netif_carrier_off(netdev); | 208 | netif_carrier_off(netdev); |
209 | netif_stop_queue(netdev); | 209 | netif_stop_queue(netdev); |
210 | } | 210 | } |
211 | /* read twice to clear sticky bits */ | 211 | } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { |
212 | /* WINDOW = 0 */ | ||
213 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); | ||
214 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); | ||
215 | |||
216 | if ((val & 0xffb) != 0xffb) { | ||
217 | printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n", | ||
218 | netxen_nic_driver_name, val1); | ||
219 | } | ||
220 | } else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) { | ||
221 | printk(KERN_INFO "%s: %s NIC Link is up\n", | 212 | printk(KERN_INFO "%s: %s NIC Link is up\n", |
222 | netxen_nic_driver_name, netdev->name); | 213 | netxen_nic_driver_name, netdev->name); |
223 | adapter->ahw.xg_linkup = 1; | 214 | adapter->ahw.xg_linkup = 1; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9737eae5ef11..a8fb439a4d03 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -63,12 +63,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); | |||
63 | static void netxen_tx_timeout(struct net_device *netdev); | 63 | static void netxen_tx_timeout(struct net_device *netdev); |
64 | static void netxen_tx_timeout_task(struct work_struct *work); | 64 | static void netxen_tx_timeout_task(struct work_struct *work); |
65 | static void netxen_watchdog(unsigned long); | 65 | static void netxen_watchdog(unsigned long); |
66 | static int netxen_handle_int(struct netxen_adapter *, struct net_device *); | ||
67 | static int netxen_nic_poll(struct napi_struct *napi, int budget); | 66 | static int netxen_nic_poll(struct napi_struct *napi, int budget); |
68 | #ifdef CONFIG_NET_POLL_CONTROLLER | 67 | #ifdef CONFIG_NET_POLL_CONTROLLER |
69 | static void netxen_nic_poll_controller(struct net_device *netdev); | 68 | static void netxen_nic_poll_controller(struct net_device *netdev); |
70 | #endif | 69 | #endif |
71 | static irqreturn_t netxen_intr(int irq, void *data); | 70 | static irqreturn_t netxen_intr(int irq, void *data); |
71 | static irqreturn_t netxen_msi_intr(int irq, void *data); | ||
72 | 72 | ||
73 | int physical_port[] = {0, 1, 2, 3}; | 73 | int physical_port[] = {0, 1, 2, 3}; |
74 | 74 | ||
@@ -149,33 +149,30 @@ static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | |||
149 | 149 | ||
150 | #define ADAPTER_LIST_SIZE 12 | 150 | #define ADAPTER_LIST_SIZE 12 |
151 | 151 | ||
152 | static uint32_t msi_tgt_status[4] = { | ||
153 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | ||
154 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | ||
155 | }; | ||
156 | |||
157 | static uint32_t sw_int_mask[4] = { | ||
158 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
159 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
160 | }; | ||
161 | |||
152 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 162 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
153 | { | 163 | { |
154 | uint32_t mask = 0x7ff; | 164 | u32 mask = 0x7ff; |
155 | int retries = 32; | 165 | int retries = 32; |
166 | int port = adapter->portnum; | ||
167 | int pci_fn = adapter->ahw.pci_func; | ||
156 | 168 | ||
157 | DPRINTK(1, INFO, "Entered ISR Disable \n"); | 169 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) |
158 | 170 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | |
159 | switch (adapter->portnum) { | ||
160 | case 0: | ||
161 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
162 | break; | ||
163 | case 1: | ||
164 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
165 | break; | ||
166 | case 2: | ||
167 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); | ||
168 | break; | ||
169 | case 3: | ||
170 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); | ||
171 | break; | ||
172 | } | ||
173 | 171 | ||
174 | if (adapter->intr_scheme != -1 && | 172 | if (adapter->intr_scheme != -1 && |
175 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 173 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
176 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 174 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); |
177 | 175 | ||
178 | /* Window = 0 or 1 */ | ||
179 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 176 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
180 | do { | 177 | do { |
181 | writel(0xffffffff, | 178 | writel(0xffffffff, |
@@ -190,14 +187,18 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
190 | printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", | 187 | printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", |
191 | netxen_nic_driver_name); | 188 | netxen_nic_driver_name); |
192 | } | 189 | } |
190 | } else { | ||
191 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { | ||
192 | writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, | ||
193 | msi_tgt_status[pci_fn])); | ||
194 | } | ||
193 | } | 195 | } |
194 | |||
195 | DPRINTK(1, INFO, "Done with Disable Int\n"); | ||
196 | } | 196 | } |
197 | 197 | ||
198 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) | 198 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) |
199 | { | 199 | { |
200 | u32 mask; | 200 | u32 mask; |
201 | int port = adapter->portnum; | ||
201 | 202 | ||
202 | DPRINTK(1, INFO, "Entered ISR Enable \n"); | 203 | DPRINTK(1, INFO, "Entered ISR Enable \n"); |
203 | 204 | ||
@@ -218,20 +219,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
218 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 219 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); |
219 | } | 220 | } |
220 | 221 | ||
221 | switch (adapter->portnum) { | 222 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); |
222 | case 0: | ||
223 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
224 | break; | ||
225 | case 1: | ||
226 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
227 | break; | ||
228 | case 2: | ||
229 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); | ||
230 | break; | ||
231 | case 3: | ||
232 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); | ||
233 | break; | ||
234 | } | ||
235 | 223 | ||
236 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 224 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
237 | mask = 0xbff; | 225 | mask = 0xbff; |
@@ -328,7 +316,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
328 | 316 | ||
329 | adapter->ahw.pdev = pdev; | 317 | adapter->ahw.pdev = pdev; |
330 | adapter->ahw.pci_func = pci_func_id; | 318 | adapter->ahw.pci_func = pci_func_id; |
331 | spin_lock_init(&adapter->tx_lock); | ||
332 | 319 | ||
333 | /* remap phys address */ | 320 | /* remap phys address */ |
334 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 321 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
@@ -401,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
401 | 388 | ||
402 | /* this will be read from FW later */ | 389 | /* this will be read from FW later */ |
403 | adapter->intr_scheme = -1; | 390 | adapter->intr_scheme = -1; |
391 | adapter->msi_mode = -1; | ||
404 | 392 | ||
405 | /* This will be reset for mezz cards */ | 393 | /* This will be reset for mezz cards */ |
406 | adapter->portnum = pci_func_id; | 394 | adapter->portnum = pci_func_id; |
@@ -415,7 +403,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
415 | netdev->set_mac_address = netxen_nic_set_mac; | 403 | netdev->set_mac_address = netxen_nic_set_mac; |
416 | netdev->change_mtu = netxen_nic_change_mtu; | 404 | netdev->change_mtu = netxen_nic_change_mtu; |
417 | netdev->tx_timeout = netxen_tx_timeout; | 405 | netdev->tx_timeout = netxen_tx_timeout; |
418 | netdev->watchdog_timeo = HZ; | 406 | netdev->watchdog_timeo = 2*HZ; |
419 | 407 | ||
420 | netxen_nic_change_mtu(netdev, netdev->mtu); | 408 | netxen_nic_change_mtu(netdev, netdev->mtu); |
421 | 409 | ||
@@ -543,7 +531,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
543 | adapter->watchdog_timer.data = (unsigned long)adapter; | 531 | adapter->watchdog_timer.data = (unsigned long)adapter; |
544 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 532 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); |
545 | adapter->ahw.pdev = pdev; | 533 | adapter->ahw.pdev = pdev; |
546 | adapter->proc_cmd_buf_counter = 0; | ||
547 | adapter->ahw.revision_id = pdev->revision; | 534 | adapter->ahw.revision_id = pdev->revision; |
548 | 535 | ||
549 | /* make sure Window == 1 */ | 536 | /* make sure Window == 1 */ |
@@ -833,6 +820,8 @@ static int netxen_nic_open(struct net_device *netdev) | |||
833 | struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; | 820 | struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; |
834 | int err = 0; | 821 | int err = 0; |
835 | int ctx, ring; | 822 | int ctx, ring; |
823 | irq_handler_t handler; | ||
824 | unsigned long flags = IRQF_SAMPLE_RANDOM; | ||
836 | 825 | ||
837 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { | 826 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { |
838 | err = netxen_init_firmware(adapter); | 827 | err = netxen_init_firmware(adapter); |
@@ -856,9 +845,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
856 | netxen_post_rx_buffers(adapter, ctx, ring); | 845 | netxen_post_rx_buffers(adapter, ctx, ring); |
857 | } | 846 | } |
858 | adapter->irq = adapter->ahw.pdev->irq; | 847 | adapter->irq = adapter->ahw.pdev->irq; |
859 | err = request_irq(adapter->ahw.pdev->irq, netxen_intr, | 848 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
860 | IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name, | 849 | handler = netxen_msi_intr; |
861 | adapter); | 850 | else { |
851 | flags |= IRQF_SHARED; | ||
852 | handler = netxen_intr; | ||
853 | } | ||
854 | err = request_irq(adapter->irq, handler, | ||
855 | flags, netdev->name, adapter); | ||
862 | if (err) { | 856 | if (err) { |
863 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 857 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
864 | netxen_free_hw_resources(adapter); | 858 | netxen_free_hw_resources(adapter); |
@@ -867,21 +861,12 @@ static int netxen_nic_open(struct net_device *netdev) | |||
867 | 861 | ||
868 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 862 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
869 | } | 863 | } |
870 | if (!adapter->driver_mismatch) | ||
871 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
872 | |||
873 | napi_enable(&adapter->napi); | ||
874 | |||
875 | netxen_nic_enable_int(adapter); | ||
876 | |||
877 | /* Done here again so that even if phantom sw overwrote it, | 864 | /* Done here again so that even if phantom sw overwrote it, |
878 | * we set it */ | 865 | * we set it */ |
879 | if (adapter->init_port | 866 | if (adapter->init_port |
880 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 867 | && adapter->init_port(adapter, adapter->portnum) != 0) { |
881 | del_timer_sync(&adapter->watchdog_timer); | ||
882 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 868 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
883 | netxen_nic_driver_name, adapter->portnum); | 869 | netxen_nic_driver_name, adapter->portnum); |
884 | napi_disable(&adapter->napi); | ||
885 | return -EIO; | 870 | return -EIO; |
886 | } | 871 | } |
887 | if (adapter->macaddr_set) | 872 | if (adapter->macaddr_set) |
@@ -894,6 +879,12 @@ static int netxen_nic_open(struct net_device *netdev) | |||
894 | adapter->set_mtu(adapter, netdev->mtu); | 879 | adapter->set_mtu(adapter, netdev->mtu); |
895 | 880 | ||
896 | if (!adapter->driver_mismatch) | 881 | if (!adapter->driver_mismatch) |
882 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
883 | |||
884 | napi_enable(&adapter->napi); | ||
885 | netxen_nic_enable_int(adapter); | ||
886 | |||
887 | if (!adapter->driver_mismatch) | ||
897 | netif_start_queue(netdev); | 888 | netif_start_queue(netdev); |
898 | 889 | ||
899 | return 0; | 890 | return 0; |
@@ -958,41 +949,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
958 | struct netxen_skb_frag *buffrag; | 949 | struct netxen_skb_frag *buffrag; |
959 | unsigned int i; | 950 | unsigned int i; |
960 | 951 | ||
961 | u32 producer = 0; | 952 | u32 producer, consumer; |
962 | u32 saved_producer = 0; | 953 | u32 saved_producer = 0; |
963 | struct cmd_desc_type0 *hwdesc; | 954 | struct cmd_desc_type0 *hwdesc; |
964 | int k; | 955 | int k; |
965 | struct netxen_cmd_buffer *pbuf = NULL; | 956 | struct netxen_cmd_buffer *pbuf = NULL; |
966 | static int dropped_packet = 0; | ||
967 | int frag_count; | 957 | int frag_count; |
968 | u32 local_producer = 0; | ||
969 | u32 max_tx_desc_count = 0; | ||
970 | u32 last_cmd_consumer = 0; | ||
971 | int no_of_desc; | 958 | int no_of_desc; |
959 | u32 num_txd = adapter->max_tx_desc_count; | ||
972 | 960 | ||
973 | adapter->stats.xmitcalled++; | ||
974 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 961 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
975 | 962 | ||
976 | if (unlikely(skb->len <= 0)) { | ||
977 | dev_kfree_skb_any(skb); | ||
978 | adapter->stats.badskblen++; | ||
979 | return NETDEV_TX_OK; | ||
980 | } | ||
981 | |||
982 | if (frag_count > MAX_BUFFERS_PER_CMD) { | ||
983 | printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) " | ||
984 | "too large, can handle only %d frags\n", | ||
985 | netxen_nic_driver_name, netdev->name, | ||
986 | frag_count, MAX_BUFFERS_PER_CMD); | ||
987 | adapter->stats.txdropped++; | ||
988 | if ((++dropped_packet & 0xff) == 0xff) | ||
989 | printk("%s: %s droppped packets = %d\n", | ||
990 | netxen_nic_driver_name, netdev->name, | ||
991 | dropped_packet); | ||
992 | |||
993 | return NETDEV_TX_OK; | ||
994 | } | ||
995 | |||
996 | /* There 4 fragments per descriptor */ | 963 | /* There 4 fragments per descriptor */ |
997 | no_of_desc = (frag_count + 3) >> 2; | 964 | no_of_desc = (frag_count + 3) >> 2; |
998 | if (netdev->features & NETIF_F_TSO) { | 965 | if (netdev->features & NETIF_F_TSO) { |
@@ -1007,27 +974,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1007 | } | 974 | } |
1008 | } | 975 | } |
1009 | 976 | ||
1010 | spin_lock_bh(&adapter->tx_lock); | 977 | producer = adapter->cmd_producer; |
1011 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { | 978 | smp_mb(); |
1012 | goto out_requeue; | 979 | consumer = adapter->last_cmd_consumer; |
1013 | } | 980 | if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { |
1014 | local_producer = adapter->cmd_producer; | 981 | netif_stop_queue(netdev); |
1015 | k = adapter->cmd_producer; | 982 | smp_mb(); |
1016 | max_tx_desc_count = adapter->max_tx_desc_count; | 983 | return NETDEV_TX_BUSY; |
1017 | last_cmd_consumer = adapter->last_cmd_consumer; | ||
1018 | if ((k + no_of_desc) >= | ||
1019 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : | ||
1020 | last_cmd_consumer)) { | ||
1021 | goto out_requeue; | ||
1022 | } | 984 | } |
1023 | k = get_index_range(k, max_tx_desc_count, no_of_desc); | ||
1024 | adapter->cmd_producer = k; | ||
1025 | adapter->total_threads++; | ||
1026 | adapter->num_threads++; | ||
1027 | 985 | ||
1028 | spin_unlock_bh(&adapter->tx_lock); | ||
1029 | /* Copy the descriptors into the hardware */ | 986 | /* Copy the descriptors into the hardware */ |
1030 | producer = local_producer; | ||
1031 | saved_producer = producer; | 987 | saved_producer = producer; |
1032 | hwdesc = &hw->cmd_desc_head[producer]; | 988 | hwdesc = &hw->cmd_desc_head[producer]; |
1033 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 989 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
@@ -1067,8 +1023,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1067 | /* move to next desc. if there is a need */ | 1023 | /* move to next desc. if there is a need */ |
1068 | if ((i & 0x3) == 0) { | 1024 | if ((i & 0x3) == 0) { |
1069 | k = 0; | 1025 | k = 0; |
1070 | producer = get_next_index(producer, | 1026 | producer = get_next_index(producer, num_txd); |
1071 | adapter->max_tx_desc_count); | ||
1072 | hwdesc = &hw->cmd_desc_head[producer]; | 1027 | hwdesc = &hw->cmd_desc_head[producer]; |
1073 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1028 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
1074 | pbuf = &adapter->cmd_buf_arr[producer]; | 1029 | pbuf = &adapter->cmd_buf_arr[producer]; |
@@ -1086,7 +1041,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1086 | buffrag->dma = temp_dma; | 1041 | buffrag->dma = temp_dma; |
1087 | buffrag->length = temp_len; | 1042 | buffrag->length = temp_len; |
1088 | 1043 | ||
1089 | DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k); | ||
1090 | switch (k) { | 1044 | switch (k) { |
1091 | case 0: | 1045 | case 0: |
1092 | hwdesc->buffer1_length = cpu_to_le16(temp_len); | 1046 | hwdesc->buffer1_length = cpu_to_le16(temp_len); |
@@ -1107,7 +1061,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1107 | } | 1061 | } |
1108 | frag++; | 1062 | frag++; |
1109 | } | 1063 | } |
1110 | producer = get_next_index(producer, adapter->max_tx_desc_count); | 1064 | producer = get_next_index(producer, num_txd); |
1111 | 1065 | ||
1112 | /* might change opcode to TX_TCP_LSO */ | 1066 | /* might change opcode to TX_TCP_LSO */ |
1113 | netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); | 1067 | netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); |
@@ -1134,7 +1088,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1134 | /* copy the first 64 bytes */ | 1088 | /* copy the first 64 bytes */ |
1135 | memcpy(((void *)hwdesc) + 2, | 1089 | memcpy(((void *)hwdesc) + 2, |
1136 | (void *)(skb->data), first_hdr_len); | 1090 | (void *)(skb->data), first_hdr_len); |
1137 | producer = get_next_index(producer, max_tx_desc_count); | 1091 | producer = get_next_index(producer, num_txd); |
1138 | 1092 | ||
1139 | if (more_hdr) { | 1093 | if (more_hdr) { |
1140 | hwdesc = &hw->cmd_desc_head[producer]; | 1094 | hwdesc = &hw->cmd_desc_head[producer]; |
@@ -1147,35 +1101,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1147 | hwdesc, | 1101 | hwdesc, |
1148 | (hdr_len - | 1102 | (hdr_len - |
1149 | first_hdr_len)); | 1103 | first_hdr_len)); |
1150 | producer = get_next_index(producer, max_tx_desc_count); | 1104 | producer = get_next_index(producer, num_txd); |
1151 | } | 1105 | } |
1152 | } | 1106 | } |
1153 | 1107 | ||
1154 | spin_lock_bh(&adapter->tx_lock); | 1108 | adapter->cmd_producer = producer; |
1155 | adapter->stats.txbytes += skb->len; | 1109 | adapter->stats.txbytes += skb->len; |
1156 | 1110 | ||
1157 | /* Code to update the adapter considering how many producer threads | 1111 | netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); |
1158 | are currently working */ | ||
1159 | if ((--adapter->num_threads) == 0) { | ||
1160 | /* This is the last thread */ | ||
1161 | u32 crb_producer = adapter->cmd_producer; | ||
1162 | netxen_nic_update_cmd_producer(adapter, crb_producer); | ||
1163 | wmb(); | ||
1164 | adapter->total_threads = 0; | ||
1165 | } | ||
1166 | 1112 | ||
1167 | adapter->stats.xmitfinished++; | 1113 | adapter->stats.xmitcalled++; |
1168 | netdev->trans_start = jiffies; | 1114 | netdev->trans_start = jiffies; |
1169 | 1115 | ||
1170 | spin_unlock_bh(&adapter->tx_lock); | ||
1171 | return NETDEV_TX_OK; | 1116 | return NETDEV_TX_OK; |
1172 | |||
1173 | out_requeue: | ||
1174 | netif_stop_queue(netdev); | ||
1175 | adapter->flags |= NETXEN_NETDEV_STATUS; | ||
1176 | |||
1177 | spin_unlock_bh(&adapter->tx_lock); | ||
1178 | return NETDEV_TX_BUSY; | ||
1179 | } | 1117 | } |
1180 | 1118 | ||
1181 | static void netxen_watchdog(unsigned long v) | 1119 | static void netxen_watchdog(unsigned long v) |
@@ -1200,87 +1138,60 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1200 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1138 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1201 | netxen_nic_driver_name, adapter->netdev->name); | 1139 | netxen_nic_driver_name, adapter->netdev->name); |
1202 | 1140 | ||
1203 | netxen_nic_close(adapter->netdev); | 1141 | netxen_nic_disable_int(adapter); |
1204 | netxen_nic_open(adapter->netdev); | 1142 | napi_disable(&adapter->napi); |
1143 | |||
1205 | adapter->netdev->trans_start = jiffies; | 1144 | adapter->netdev->trans_start = jiffies; |
1145 | |||
1146 | napi_enable(&adapter->napi); | ||
1147 | netxen_nic_enable_int(adapter); | ||
1206 | netif_wake_queue(adapter->netdev); | 1148 | netif_wake_queue(adapter->netdev); |
1207 | } | 1149 | } |
1208 | 1150 | ||
1209 | static int | 1151 | static inline void |
1210 | netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | 1152 | netxen_handle_int(struct netxen_adapter *adapter) |
1211 | { | 1153 | { |
1212 | u32 ret = 0; | ||
1213 | |||
1214 | DPRINTK(INFO, "Entered handle ISR\n"); | ||
1215 | adapter->stats.ints++; | ||
1216 | |||
1217 | netxen_nic_disable_int(adapter); | 1154 | netxen_nic_disable_int(adapter); |
1218 | 1155 | napi_schedule(&adapter->napi); | |
1219 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { | ||
1220 | if (netif_rx_schedule_prep(netdev, &adapter->napi)) { | ||
1221 | /* | ||
1222 | * Interrupts are already disabled. | ||
1223 | */ | ||
1224 | __netif_rx_schedule(netdev, &adapter->napi); | ||
1225 | } else { | ||
1226 | static unsigned int intcount = 0; | ||
1227 | if ((++intcount & 0xfff) == 0xfff) | ||
1228 | DPRINTK(KERN_ERR | ||
1229 | "%s: %s interrupt %d while in poll\n", | ||
1230 | netxen_nic_driver_name, netdev->name, | ||
1231 | intcount); | ||
1232 | } | ||
1233 | ret = 1; | ||
1234 | } | ||
1235 | |||
1236 | if (ret == 0) { | ||
1237 | netxen_nic_enable_int(adapter); | ||
1238 | } | ||
1239 | |||
1240 | return ret; | ||
1241 | } | 1156 | } |
1242 | 1157 | ||
1243 | /* | ||
1244 | * netxen_intr - Interrupt Handler | ||
1245 | * @irq: interrupt number | ||
1246 | * data points to adapter stucture (which may be handling more than 1 port | ||
1247 | */ | ||
1248 | irqreturn_t netxen_intr(int irq, void *data) | 1158 | irqreturn_t netxen_intr(int irq, void *data) |
1249 | { | 1159 | { |
1250 | struct netxen_adapter *adapter = data; | 1160 | struct netxen_adapter *adapter = data; |
1251 | struct net_device *netdev = adapter->netdev; | ||
1252 | u32 our_int = 0; | 1161 | u32 our_int = 0; |
1253 | 1162 | ||
1254 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1163 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
1255 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1164 | /* not our interrupt */ |
1256 | /* not our interrupt */ | 1165 | if ((our_int & (0x80 << adapter->portnum)) == 0) |
1257 | if ((our_int & (0x80 << adapter->portnum)) == 0) | 1166 | return IRQ_NONE; |
1258 | return IRQ_NONE; | ||
1259 | } | ||
1260 | 1167 | ||
1261 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { | 1168 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { |
1262 | /* claim interrupt */ | 1169 | /* claim interrupt */ |
1263 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1170 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), |
1264 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), | ||
1265 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1171 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
1266 | } | ||
1267 | } | 1172 | } |
1268 | 1173 | ||
1269 | if (netif_running(netdev)) | 1174 | netxen_handle_int(adapter); |
1270 | netxen_handle_int(adapter, netdev); | ||
1271 | 1175 | ||
1272 | return IRQ_HANDLED; | 1176 | return IRQ_HANDLED; |
1273 | } | 1177 | } |
1274 | 1178 | ||
1179 | irqreturn_t netxen_msi_intr(int irq, void *data) | ||
1180 | { | ||
1181 | struct netxen_adapter *adapter = data; | ||
1182 | |||
1183 | netxen_handle_int(adapter); | ||
1184 | return IRQ_HANDLED; | ||
1185 | } | ||
1186 | |||
1275 | static int netxen_nic_poll(struct napi_struct *napi, int budget) | 1187 | static int netxen_nic_poll(struct napi_struct *napi, int budget) |
1276 | { | 1188 | { |
1277 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); | 1189 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); |
1278 | struct net_device *netdev = adapter->netdev; | 1190 | int tx_complete; |
1279 | int done = 1; | ||
1280 | int ctx; | 1191 | int ctx; |
1281 | int work_done; | 1192 | int work_done; |
1282 | 1193 | ||
1283 | DPRINTK(INFO, "polling for %d descriptors\n", *budget); | 1194 | tx_complete = netxen_process_cmd_ring(adapter); |
1284 | 1195 | ||
1285 | work_done = 0; | 1196 | work_done = 0; |
1286 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1197 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
@@ -1300,16 +1211,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1300 | budget / MAX_RCV_CTX); | 1211 | budget / MAX_RCV_CTX); |
1301 | } | 1212 | } |
1302 | 1213 | ||
1303 | if (work_done >= budget) | 1214 | if ((work_done < budget) && tx_complete) { |
1304 | done = 0; | 1215 | netif_rx_complete(adapter->netdev, &adapter->napi); |
1305 | |||
1306 | if (netxen_process_cmd_ring((unsigned long)adapter) == 0) | ||
1307 | done = 0; | ||
1308 | |||
1309 | DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", | ||
1310 | work_done, work_to_do); | ||
1311 | if (done) { | ||
1312 | netif_rx_complete(netdev, napi); | ||
1313 | netxen_nic_enable_int(adapter); | 1216 | netxen_nic_enable_int(adapter); |
1314 | } | 1217 | } |
1315 | 1218 | ||
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index ffa3b7215ce8..a566b50f36f5 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h | |||
@@ -126,8 +126,11 @@ | |||
126 | */ | 126 | */ |
127 | #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) | 127 | #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) |
128 | #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) | 128 | #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) |
129 | #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) | ||
130 | #define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) | ||
129 | 131 | ||
130 | #define INTR_SCHEME_PERPORT 0x1 | 132 | #define INTR_SCHEME_PERPORT 0x1 |
133 | #define MSI_MODE_MULTIFUNC 0x1 | ||
131 | 134 | ||
132 | /* used for ethtool tests */ | 135 | /* used for ethtool tests */ |
133 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) | 136 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) |