aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c70
1 files changed, 25 insertions, 45 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 454226f7baa8..263b55e36c7a 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -732,11 +732,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
- if (adapter->stop_port)
- adapter->stop_port(adapter);
-
- netxen_nic_disable_int(adapter);
-
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
init_firmware_done++;
netxen_free_hw_resources(adapter);
@@ -919,6 +914,9 @@ static int netxen_nic_close(struct net_device *netdev)
netif_stop_queue(netdev);
napi_disable(&adapter->napi);
+ if (adapter->stop_port)
+ adapter->stop_port(adapter);
+
netxen_nic_disable_int(adapter);
cmd_buff = adapter->cmd_buf_arr;
@@ -996,28 +994,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- /*
- * Everything is set up. Now, we just need to transmit it out.
- * Note that we have to copy the contents of buffer over to
- * right place. Later on, this can be optimized out by de-coupling the
- * producer index from the buffer index.
- */
- retry_getting_window:
- spin_lock_bh(&adapter->tx_lock);
- if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
- spin_unlock_bh(&adapter->tx_lock);
- /*
- * Yield CPU
- */
- if (!in_atomic())
- schedule();
- else {
- for (i = 0; i < 20; i++)
- cpu_relax(); /*This a nop instr on i386 */
- }
- goto retry_getting_window;
- }
- local_producer = adapter->cmd_producer;
/* There 4 fragments per descriptor */
no_of_desc = (frag_count + 3) >> 2;
if (netdev->features & NETIF_F_TSO) {
@@ -1031,16 +1007,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
}
+
+ spin_lock_bh(&adapter->tx_lock);
+ if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
+ goto out_requeue;
+ }
+ local_producer = adapter->cmd_producer;
k = adapter->cmd_producer;
max_tx_desc_count = adapter->max_tx_desc_count;
last_cmd_consumer = adapter->last_cmd_consumer;
if ((k + no_of_desc) >=
((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
last_cmd_consumer)) {
- netif_stop_queue(netdev);
- adapter->flags |= NETXEN_NETDEV_STATUS;
- spin_unlock_bh(&adapter->tx_lock);
- return NETDEV_TX_BUSY;
+ goto out_requeue;
}
k = get_index_range(k, max_tx_desc_count, no_of_desc);
adapter->cmd_producer = k;
@@ -1093,6 +1072,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
adapter->max_tx_desc_count);
hwdesc = &hw->cmd_desc_head[producer];
memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+ pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf->skb = NULL;
}
frag = &skb_shinfo(skb)->frags[i - 1];
len = frag->size;
@@ -1148,6 +1129,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
/* copy the MAC/IP/TCP headers to the cmd descriptor list */
hwdesc = &hw->cmd_desc_head[producer];
+ pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf->skb = NULL;
/* copy the first 64 bytes */
memcpy(((void *)hwdesc) + 2,
@@ -1156,6 +1139,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (more_hdr) {
hwdesc = &hw->cmd_desc_head[producer];
+ pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf->skb = NULL;
/* copy the next 64 bytes - should be enough except
* for pathological case
*/
@@ -1167,16 +1152,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
- i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
-
- hw->cmd_desc_head[saved_producer].flags_opcode =
- cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode);
- hw->cmd_desc_head[saved_producer].num_of_buffers_total_length =
- cpu_to_le32(hw->cmd_desc_head[saved_producer].
- num_of_buffers_total_length);
-
spin_lock_bh(&adapter->tx_lock);
- adapter->stats.txbytes += i;
+ adapter->stats.txbytes += skb->len;
/* Code to update the adapter considering how many producer threads
are currently working */
@@ -1189,14 +1166,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
adapter->stats.xmitfinished++;
- spin_unlock_bh(&adapter->tx_lock);
-
netdev->trans_start = jiffies;
- DPRINTK(INFO, "wrote CMD producer %x to phantom\n", producer);
-
- DPRINTK(INFO, "Done. Send\n");
+ spin_unlock_bh(&adapter->tx_lock);
return NETDEV_TX_OK;
+
+out_requeue:
+ netif_stop_queue(netdev);
+ adapter->flags |= NETXEN_NETDEV_STATUS;
+
+ spin_unlock_bh(&adapter->tx_lock);
+ return NETDEV_TX_BUSY;
}
static void netxen_watchdog(unsigned long v)