diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 95 |
1 files changed, 22 insertions, 73 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 95955204ef5..dc4d593217c 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -317,7 +317,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
317 | 317 | ||
318 | adapter->ahw.pdev = pdev; | 318 | adapter->ahw.pdev = pdev; |
319 | adapter->ahw.pci_func = pci_func_id; | 319 | adapter->ahw.pci_func = pci_func_id; |
320 | spin_lock_init(&adapter->tx_lock); | ||
321 | 320 | ||
322 | /* remap phys address */ | 321 | /* remap phys address */ |
323 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 322 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
@@ -533,7 +532,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
533 | adapter->watchdog_timer.data = (unsigned long)adapter; | 532 | adapter->watchdog_timer.data = (unsigned long)adapter; |
534 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 533 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); |
535 | adapter->ahw.pdev = pdev; | 534 | adapter->ahw.pdev = pdev; |
536 | adapter->proc_cmd_buf_counter = 0; | ||
537 | adapter->ahw.revision_id = pdev->revision; | 535 | adapter->ahw.revision_id = pdev->revision; |
538 | 536 | ||
539 | /* make sure Window == 1 */ | 537 | /* make sure Window == 1 */ |
@@ -952,41 +950,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
952 | struct netxen_skb_frag *buffrag; | 950 | struct netxen_skb_frag *buffrag; |
953 | unsigned int i; | 951 | unsigned int i; |
954 | 952 | ||
955 | u32 producer = 0; | 953 | u32 producer, consumer; |
956 | u32 saved_producer = 0; | 954 | u32 saved_producer = 0; |
957 | struct cmd_desc_type0 *hwdesc; | 955 | struct cmd_desc_type0 *hwdesc; |
958 | int k; | 956 | int k; |
959 | struct netxen_cmd_buffer *pbuf = NULL; | 957 | struct netxen_cmd_buffer *pbuf = NULL; |
960 | static int dropped_packet = 0; | ||
961 | int frag_count; | 958 | int frag_count; |
962 | u32 local_producer = 0; | ||
963 | u32 max_tx_desc_count = 0; | ||
964 | u32 last_cmd_consumer = 0; | ||
965 | int no_of_desc; | 959 | int no_of_desc; |
960 | u32 num_txd = adapter->max_tx_desc_count; | ||
966 | 961 | ||
967 | adapter->stats.xmitcalled++; | ||
968 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 962 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
969 | 963 | ||
970 | if (unlikely(skb->len <= 0)) { | ||
971 | dev_kfree_skb_any(skb); | ||
972 | adapter->stats.badskblen++; | ||
973 | return NETDEV_TX_OK; | ||
974 | } | ||
975 | |||
976 | if (frag_count > MAX_BUFFERS_PER_CMD) { | ||
977 | printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) " | ||
978 | "too large, can handle only %d frags\n", | ||
979 | netxen_nic_driver_name, netdev->name, | ||
980 | frag_count, MAX_BUFFERS_PER_CMD); | ||
981 | adapter->stats.txdropped++; | ||
982 | if ((++dropped_packet & 0xff) == 0xff) | ||
983 | printk("%s: %s droppped packets = %d\n", | ||
984 | netxen_nic_driver_name, netdev->name, | ||
985 | dropped_packet); | ||
986 | |||
987 | return NETDEV_TX_OK; | ||
988 | } | ||
989 | |||
990 | /* There 4 fragments per descriptor */ | 964 | /* There 4 fragments per descriptor */ |
991 | no_of_desc = (frag_count + 3) >> 2; | 965 | no_of_desc = (frag_count + 3) >> 2; |
992 | if (netdev->features & NETIF_F_TSO) { | 966 | if (netdev->features & NETIF_F_TSO) { |
@@ -1001,27 +975,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1001 | } | 975 | } |
1002 | } | 976 | } |
1003 | 977 | ||
1004 | spin_lock_bh(&adapter->tx_lock); | 978 | producer = adapter->cmd_producer; |
1005 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { | 979 | smp_mb(); |
1006 | goto out_requeue; | 980 | consumer = adapter->last_cmd_consumer; |
981 | if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { | ||
982 | netif_stop_queue(netdev); | ||
983 | smp_mb(); | ||
984 | return NETDEV_TX_BUSY; | ||
1007 | } | 985 | } |
1008 | local_producer = adapter->cmd_producer; | ||
1009 | k = adapter->cmd_producer; | ||
1010 | max_tx_desc_count = adapter->max_tx_desc_count; | ||
1011 | last_cmd_consumer = adapter->last_cmd_consumer; | ||
1012 | if ((k + no_of_desc) >= | ||
1013 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : | ||
1014 | last_cmd_consumer)) { | ||
1015 | goto out_requeue; | ||
1016 | } | ||
1017 | k = get_index_range(k, max_tx_desc_count, no_of_desc); | ||
1018 | adapter->cmd_producer = k; | ||
1019 | adapter->total_threads++; | ||
1020 | adapter->num_threads++; | ||
1021 | 986 | ||
1022 | spin_unlock_bh(&adapter->tx_lock); | ||
1023 | /* Copy the descriptors into the hardware */ | 987 | /* Copy the descriptors into the hardware */ |
1024 | producer = local_producer; | ||
1025 | saved_producer = producer; | 988 | saved_producer = producer; |
1026 | hwdesc = &hw->cmd_desc_head[producer]; | 989 | hwdesc = &hw->cmd_desc_head[producer]; |
1027 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 990 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
@@ -1061,8 +1024,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1061 | /* move to next desc. if there is a need */ | 1024 | /* move to next desc. if there is a need */ |
1062 | if ((i & 0x3) == 0) { | 1025 | if ((i & 0x3) == 0) { |
1063 | k = 0; | 1026 | k = 0; |
1064 | producer = get_next_index(producer, | 1027 | producer = get_next_index(producer, num_txd); |
1065 | adapter->max_tx_desc_count); | ||
1066 | hwdesc = &hw->cmd_desc_head[producer]; | 1028 | hwdesc = &hw->cmd_desc_head[producer]; |
1067 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1029 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
1068 | pbuf = &adapter->cmd_buf_arr[producer]; | 1030 | pbuf = &adapter->cmd_buf_arr[producer]; |
@@ -1080,7 +1042,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1080 | buffrag->dma = temp_dma; | 1042 | buffrag->dma = temp_dma; |
1081 | buffrag->length = temp_len; | 1043 | buffrag->length = temp_len; |
1082 | 1044 | ||
1083 | DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k); | ||
1084 | switch (k) { | 1045 | switch (k) { |
1085 | case 0: | 1046 | case 0: |
1086 | hwdesc->buffer1_length = cpu_to_le16(temp_len); | 1047 | hwdesc->buffer1_length = cpu_to_le16(temp_len); |
@@ -1101,7 +1062,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1101 | } | 1062 | } |
1102 | frag++; | 1063 | frag++; |
1103 | } | 1064 | } |
1104 | producer = get_next_index(producer, adapter->max_tx_desc_count); | 1065 | producer = get_next_index(producer, num_txd); |
1105 | 1066 | ||
1106 | /* might change opcode to TX_TCP_LSO */ | 1067 | /* might change opcode to TX_TCP_LSO */ |
1107 | netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); | 1068 | netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); |
@@ -1128,7 +1089,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1128 | /* copy the first 64 bytes */ | 1089 | /* copy the first 64 bytes */ |
1129 | memcpy(((void *)hwdesc) + 2, | 1090 | memcpy(((void *)hwdesc) + 2, |
1130 | (void *)(skb->data), first_hdr_len); | 1091 | (void *)(skb->data), first_hdr_len); |
1131 | producer = get_next_index(producer, max_tx_desc_count); | 1092 | producer = get_next_index(producer, num_txd); |
1132 | 1093 | ||
1133 | if (more_hdr) { | 1094 | if (more_hdr) { |
1134 | hwdesc = &hw->cmd_desc_head[producer]; | 1095 | hwdesc = &hw->cmd_desc_head[producer]; |
@@ -1141,35 +1102,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1141 | hwdesc, | 1102 | hwdesc, |
1142 | (hdr_len - | 1103 | (hdr_len - |
1143 | first_hdr_len)); | 1104 | first_hdr_len)); |
1144 | producer = get_next_index(producer, max_tx_desc_count); | 1105 | producer = get_next_index(producer, num_txd); |
1145 | } | 1106 | } |
1146 | } | 1107 | } |
1147 | 1108 | ||
1148 | spin_lock_bh(&adapter->tx_lock); | 1109 | adapter->cmd_producer = producer; |
1149 | adapter->stats.txbytes += skb->len; | 1110 | adapter->stats.txbytes += skb->len; |
1150 | 1111 | ||
1151 | /* Code to update the adapter considering how many producer threads | 1112 | netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); |
1152 | are currently working */ | ||
1153 | if ((--adapter->num_threads) == 0) { | ||
1154 | /* This is the last thread */ | ||
1155 | u32 crb_producer = adapter->cmd_producer; | ||
1156 | netxen_nic_update_cmd_producer(adapter, crb_producer); | ||
1157 | wmb(); | ||
1158 | adapter->total_threads = 0; | ||
1159 | } | ||
1160 | 1113 | ||
1161 | adapter->stats.xmitfinished++; | 1114 | adapter->stats.xmitcalled++; |
1162 | netdev->trans_start = jiffies; | 1115 | netdev->trans_start = jiffies; |
1163 | 1116 | ||
1164 | spin_unlock_bh(&adapter->tx_lock); | ||
1165 | return NETDEV_TX_OK; | 1117 | return NETDEV_TX_OK; |
1166 | |||
1167 | out_requeue: | ||
1168 | netif_stop_queue(netdev); | ||
1169 | adapter->flags |= NETXEN_NETDEV_STATUS; | ||
1170 | |||
1171 | spin_unlock_bh(&adapter->tx_lock); | ||
1172 | return NETDEV_TX_BUSY; | ||
1173 | } | 1118 | } |
1174 | 1119 | ||
1175 | static void netxen_watchdog(unsigned long v) | 1120 | static void netxen_watchdog(unsigned long v) |
@@ -1194,9 +1139,13 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1194 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1139 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1195 | netxen_nic_driver_name, adapter->netdev->name); | 1140 | netxen_nic_driver_name, adapter->netdev->name); |
1196 | 1141 | ||
1197 | netxen_nic_close(adapter->netdev); | 1142 | netxen_nic_disable_int(adapter); |
1198 | netxen_nic_open(adapter->netdev); | 1143 | napi_disable(&adapter->napi); |
1144 | |||
1199 | adapter->netdev->trans_start = jiffies; | 1145 | adapter->netdev->trans_start = jiffies; |
1146 | |||
1147 | napi_enable(&adapter->napi); | ||
1148 | netxen_nic_enable_int(adapter); | ||
1200 | netif_wake_queue(adapter->netdev); | 1149 | netif_wake_queue(adapter->netdev); |
1201 | } | 1150 | } |
1202 | 1151 | ||