summaryrefslogtreecommitdiffstats
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.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 98737ef..71daa3d 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -107,9 +107,14 @@ static uint32_t crb_cmd_producer[4] = {
void
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
- struct nx_host_tx_ring *tx_ring, u32 producer)
+ struct nx_host_tx_ring *tx_ring)
{
- NXWR32(adapter, tx_ring->crb_cmd_producer, producer);
+ NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
+
+ if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
+ netif_stop_queue(adapter->netdev);
+ smp_mb();
+ }
}
static uint32_t crb_cmd_consumer[4] = {
@@ -119,9 +124,9 @@ static uint32_t crb_cmd_consumer[4] = {
static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
- struct nx_host_tx_ring *tx_ring, u32 consumer)
+ struct nx_host_tx_ring *tx_ring)
{
- NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer);
+ NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
}
static uint32_t msi_tgt_status[8] = {
@@ -900,8 +905,11 @@ netxen_nic_attach(struct netxen_adapter *adapter)
tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
- netxen_nic_update_cmd_producer(adapter, tx_ring, 0);
- netxen_nic_update_cmd_consumer(adapter, tx_ring, 0);
+ tx_ring->producer = 0;
+ tx_ring->sw_consumer = 0;
+
+ netxen_nic_update_cmd_producer(adapter, tx_ring);
+ netxen_nic_update_cmd_consumer(adapter, tx_ring);
}
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -1362,7 +1370,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
dma_addr_t temp_dma;
int i, k;
- u32 producer, consumer;
+ u32 producer;
int frag_count, no_of_desc;
u32 num_txd = tx_ring->num_desc;
bool is_tso = false;
@@ -1372,15 +1380,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2;
- producer = tx_ring->producer;
- smp_mb();
- consumer = tx_ring->sw_consumer;
- if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
+ if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) {
netif_stop_queue(netdev);
- smp_mb();
return NETDEV_TX_BUSY;
}
+ producer = tx_ring->producer;
+
hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
pbuf = &tx_ring->cmd_buf_arr[producer];
@@ -1493,7 +1499,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_ring->producer = producer;
adapter->stats.txbytes += skb->len;
- netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
+ netxen_nic_update_cmd_producer(adapter, tx_ring);
adapter->stats.xmitcalled++;
OpenPOWER on IntegriCloud