diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 10 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 52 |
2 files changed, 25 insertions, 37 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 37589265297e..5f85ad686c98 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1248,7 +1248,6 @@ int netxen_process_cmd_ring(unsigned long data) | |||
1248 | struct pci_dev *pdev; | 1248 | struct pci_dev *pdev; |
1249 | struct netxen_skb_frag *frag; | 1249 | struct netxen_skb_frag *frag; |
1250 | u32 i; | 1250 | u32 i; |
1251 | struct sk_buff *skb = NULL; | ||
1252 | int done; | 1251 | int done; |
1253 | 1252 | ||
1254 | spin_lock(&adapter->tx_lock); | 1253 | spin_lock(&adapter->tx_lock); |
@@ -1278,9 +1277,8 @@ int netxen_process_cmd_ring(unsigned long data) | |||
1278 | while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { | 1277 | while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { |
1279 | buffer = &adapter->cmd_buf_arr[last_consumer]; | 1278 | buffer = &adapter->cmd_buf_arr[last_consumer]; |
1280 | pdev = adapter->pdev; | 1279 | pdev = adapter->pdev; |
1281 | frag = &buffer->frag_array[0]; | 1280 | if (buffer->skb) { |
1282 | skb = buffer->skb; | 1281 | frag = &buffer->frag_array[0]; |
1283 | if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { | ||
1284 | pci_unmap_single(pdev, frag->dma, frag->length, | 1282 | pci_unmap_single(pdev, frag->dma, frag->length, |
1285 | PCI_DMA_TODEVICE); | 1283 | PCI_DMA_TODEVICE); |
1286 | frag->dma = 0ULL; | 1284 | frag->dma = 0ULL; |
@@ -1293,8 +1291,8 @@ int netxen_process_cmd_ring(unsigned long data) | |||
1293 | } | 1291 | } |
1294 | 1292 | ||
1295 | adapter->stats.skbfreed++; | 1293 | adapter->stats.skbfreed++; |
1296 | dev_kfree_skb_any(skb); | 1294 | dev_kfree_skb_any(buffer->skb); |
1297 | skb = NULL; | 1295 | buffer->skb = NULL; |
1298 | } else if (adapter->proc_cmd_buf_counter == 1) { | 1296 | } else if (adapter->proc_cmd_buf_counter == 1) { |
1299 | adapter->stats.txnullskb++; | 1297 | adapter->stats.txnullskb++; |
1300 | } | 1298 | } |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2d75c710f62a..cec9e04f51ea 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -994,28 +994,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
994 | return NETDEV_TX_OK; | 994 | return NETDEV_TX_OK; |
995 | } | 995 | } |
996 | 996 | ||
997 | /* | ||
998 | * Everything is set up. Now, we just need to transmit it out. | ||
999 | * Note that we have to copy the contents of buffer over to | ||
1000 | * right place. Later on, this can be optimized out by de-coupling the | ||
1001 | * producer index from the buffer index. | ||
1002 | */ | ||
1003 | retry_getting_window: | ||
1004 | spin_lock_bh(&adapter->tx_lock); | ||
1005 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { | ||
1006 | spin_unlock_bh(&adapter->tx_lock); | ||
1007 | /* | ||
1008 | * Yield CPU | ||
1009 | */ | ||
1010 | if (!in_atomic()) | ||
1011 | schedule(); | ||
1012 | else { | ||
1013 | for (i = 0; i < 20; i++) | ||
1014 | cpu_relax(); /*This a nop instr on i386 */ | ||
1015 | } | ||
1016 | goto retry_getting_window; | ||
1017 | } | ||
1018 | local_producer = adapter->cmd_producer; | ||
1019 | /* There 4 fragments per descriptor */ | 997 | /* There 4 fragments per descriptor */ |
1020 | no_of_desc = (frag_count + 3) >> 2; | 998 | no_of_desc = (frag_count + 3) >> 2; |
1021 | if (netdev->features & NETIF_F_TSO) { | 999 | if (netdev->features & NETIF_F_TSO) { |
@@ -1029,16 +1007,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1029 | } | 1007 | } |
1030 | } | 1008 | } |
1031 | } | 1009 | } |
1010 | |||
1011 | spin_lock_bh(&adapter->tx_lock); | ||
1012 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { | ||
1013 | goto out_requeue; | ||
1014 | } | ||
1015 | local_producer = adapter->cmd_producer; | ||
1032 | k = adapter->cmd_producer; | 1016 | k = adapter->cmd_producer; |
1033 | max_tx_desc_count = adapter->max_tx_desc_count; | 1017 | max_tx_desc_count = adapter->max_tx_desc_count; |
1034 | last_cmd_consumer = adapter->last_cmd_consumer; | 1018 | last_cmd_consumer = adapter->last_cmd_consumer; |
1035 | if ((k + no_of_desc) >= | 1019 | if ((k + no_of_desc) >= |
1036 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : | 1020 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : |
1037 | last_cmd_consumer)) { | 1021 | last_cmd_consumer)) { |
1038 | netif_stop_queue(netdev); | 1022 | goto out_requeue; |
1039 | adapter->flags |= NETXEN_NETDEV_STATUS; | ||
1040 | spin_unlock_bh(&adapter->tx_lock); | ||
1041 | return NETDEV_TX_BUSY; | ||
1042 | } | 1023 | } |
1043 | k = get_index_range(k, max_tx_desc_count, no_of_desc); | 1024 | k = get_index_range(k, max_tx_desc_count, no_of_desc); |
1044 | adapter->cmd_producer = k; | 1025 | adapter->cmd_producer = k; |
@@ -1091,6 +1072,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1091 | adapter->max_tx_desc_count); | 1072 | adapter->max_tx_desc_count); |
1092 | hwdesc = &hw->cmd_desc_head[producer]; | 1073 | hwdesc = &hw->cmd_desc_head[producer]; |
1093 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1074 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
1075 | pbuf = &adapter->cmd_buf_arr[producer]; | ||
1076 | pbuf->skb = NULL; | ||
1094 | } | 1077 | } |
1095 | frag = &skb_shinfo(skb)->frags[i - 1]; | 1078 | frag = &skb_shinfo(skb)->frags[i - 1]; |
1096 | len = frag->size; | 1079 | len = frag->size; |
@@ -1146,6 +1129,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1146 | } | 1129 | } |
1147 | /* copy the MAC/IP/TCP headers to the cmd descriptor list */ | 1130 | /* copy the MAC/IP/TCP headers to the cmd descriptor list */ |
1148 | hwdesc = &hw->cmd_desc_head[producer]; | 1131 | hwdesc = &hw->cmd_desc_head[producer]; |
1132 | pbuf = &adapter->cmd_buf_arr[producer]; | ||
1133 | pbuf->skb = NULL; | ||
1149 | 1134 | ||
1150 | /* copy the first 64 bytes */ | 1135 | /* copy the first 64 bytes */ |
1151 | memcpy(((void *)hwdesc) + 2, | 1136 | memcpy(((void *)hwdesc) + 2, |
@@ -1154,6 +1139,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1154 | 1139 | ||
1155 | if (more_hdr) { | 1140 | if (more_hdr) { |
1156 | hwdesc = &hw->cmd_desc_head[producer]; | 1141 | hwdesc = &hw->cmd_desc_head[producer]; |
1142 | pbuf = &adapter->cmd_buf_arr[producer]; | ||
1143 | pbuf->skb = NULL; | ||
1157 | /* copy the next 64 bytes - should be enough except | 1144 | /* copy the next 64 bytes - should be enough except |
1158 | * for pathological case | 1145 | * for pathological case |
1159 | */ | 1146 | */ |
@@ -1187,14 +1174,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1187 | } | 1174 | } |
1188 | 1175 | ||
1189 | adapter->stats.xmitfinished++; | 1176 | adapter->stats.xmitfinished++; |
1190 | spin_unlock_bh(&adapter->tx_lock); | ||
1191 | |||
1192 | netdev->trans_start = jiffies; | 1177 | netdev->trans_start = jiffies; |
1193 | 1178 | ||
1194 | DPRINTK(INFO, "wrote CMD producer %x to phantom\n", producer); | 1179 | spin_unlock_bh(&adapter->tx_lock); |
1195 | |||
1196 | DPRINTK(INFO, "Done. Send\n"); | ||
1197 | return NETDEV_TX_OK; | 1180 | return NETDEV_TX_OK; |
1181 | |||
1182 | out_requeue: | ||
1183 | netif_stop_queue(netdev); | ||
1184 | adapter->flags |= NETXEN_NETDEV_STATUS; | ||
1185 | |||
1186 | spin_unlock_bh(&adapter->tx_lock); | ||
1187 | return NETDEV_TX_BUSY; | ||
1198 | } | 1188 | } |
1199 | 1189 | ||
1200 | static void netxen_watchdog(unsigned long v) | 1190 | static void netxen_watchdog(unsigned long v) |