netxen: remove low level tx lock
[deliverable/linux.git] / drivers / net / netxen / netxen_nic_main.c
index 95955204ef59d5db45207bdee40524717ad42230..dc4d593217c9667c63337683b5c7252d157f3265 100644 (file)
@@ -317,7 +317,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        adapter->ahw.pdev = pdev;
        adapter->ahw.pci_func  = pci_func_id;
-       spin_lock_init(&adapter->tx_lock);
 
        /* remap phys address */
        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)
        adapter->watchdog_timer.data = (unsigned long)adapter;
        INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
        adapter->ahw.pdev = pdev;
-       adapter->proc_cmd_buf_counter = 0;
        adapter->ahw.revision_id = pdev->revision;
 
        /* make sure Window == 1 */
@@ -952,41 +950,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        struct netxen_skb_frag *buffrag;
        unsigned int i;
 
-       u32 producer = 0;
+       u32 producer, consumer;
        u32 saved_producer = 0;
        struct cmd_desc_type0 *hwdesc;
        int k;
        struct netxen_cmd_buffer *pbuf = NULL;
-       static int dropped_packet = 0;
        int frag_count;
-       u32 local_producer = 0;
-       u32 max_tx_desc_count = 0;
-       u32 last_cmd_consumer = 0;
        int no_of_desc;
+       u32 num_txd = adapter->max_tx_desc_count;
 
-       adapter->stats.xmitcalled++;
        frag_count = skb_shinfo(skb)->nr_frags + 1;
 
-       if (unlikely(skb->len <= 0)) {
-               dev_kfree_skb_any(skb);
-               adapter->stats.badskblen++;
-               return NETDEV_TX_OK;
-       }
-
-       if (frag_count > MAX_BUFFERS_PER_CMD) {
-               printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) "
-                      "too large, can handle only %d frags\n",
-                      netxen_nic_driver_name, netdev->name,
-                      frag_count, MAX_BUFFERS_PER_CMD);
-               adapter->stats.txdropped++;
-               if ((++dropped_packet & 0xff) == 0xff)
-                       printk("%s: %s droppped packets = %d\n",
-                              netxen_nic_driver_name, netdev->name,
-                              dropped_packet);
-
-               return NETDEV_TX_OK;
-       }
-
        /* There 4 fragments per descriptor */
        no_of_desc = (frag_count + 3) >> 2;
        if (netdev->features & NETIF_F_TSO) {
@@ -1001,27 +975,16 @@ 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;
+       producer = adapter->cmd_producer;
+       smp_mb();
+       consumer = adapter->last_cmd_consumer;
+       if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
+               netif_stop_queue(netdev);
+               smp_mb();
+               return NETDEV_TX_BUSY;
        }
-       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)) {
-               goto out_requeue;
-       }
-       k = get_index_range(k, max_tx_desc_count, no_of_desc);
-       adapter->cmd_producer = k;
-       adapter->total_threads++;
-       adapter->num_threads++;
 
-       spin_unlock_bh(&adapter->tx_lock);
        /* Copy the descriptors into the hardware    */
-       producer = local_producer;
        saved_producer = producer;
        hwdesc = &hw->cmd_desc_head[producer];
        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)
                /* move to next desc. if there is a need */
                if ((i & 0x3) == 0) {
                        k = 0;
-                       producer = get_next_index(producer,
-                                                 adapter->max_tx_desc_count);
+                       producer = get_next_index(producer, num_txd);
                        hwdesc = &hw->cmd_desc_head[producer];
                        memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
                        pbuf = &adapter->cmd_buf_arr[producer];
@@ -1080,7 +1042,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                buffrag->dma = temp_dma;
                buffrag->length = temp_len;
 
-               DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k);
                switch (k) {
                case 0:
                        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)
                }
                frag++;
        }
-       producer = get_next_index(producer, adapter->max_tx_desc_count);
+       producer = get_next_index(producer, num_txd);
 
        /* might change opcode to TX_TCP_LSO */
        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)
                /* copy the first 64 bytes */
                memcpy(((void *)hwdesc) + 2,
                       (void *)(skb->data), first_hdr_len);
-               producer = get_next_index(producer, max_tx_desc_count);
+               producer = get_next_index(producer, num_txd);
 
                if (more_hdr) {
                        hwdesc = &hw->cmd_desc_head[producer];
@@ -1141,35 +1102,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                                                         hwdesc,
                                                         (hdr_len -
                                                          first_hdr_len));
-                       producer = get_next_index(producer, max_tx_desc_count);
+                       producer = get_next_index(producer, num_txd);
                }
        }
 
-       spin_lock_bh(&adapter->tx_lock);
+       adapter->cmd_producer = producer;
        adapter->stats.txbytes += skb->len;
 
-       /* Code to update the adapter considering how many producer threads
-          are currently working */
-       if ((--adapter->num_threads) == 0) {
-               /* This is the last thread */
-               u32 crb_producer = adapter->cmd_producer;
-               netxen_nic_update_cmd_producer(adapter, crb_producer);
-               wmb();
-               adapter->total_threads = 0;
-       }
+       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
 
-       adapter->stats.xmitfinished++;
+       adapter->stats.xmitcalled++;
        netdev->trans_start = jiffies;
 
-       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)
@@ -1194,9 +1139,13 @@ static void netxen_tx_timeout_task(struct work_struct *work)
        printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
               netxen_nic_driver_name, adapter->netdev->name);
 
-       netxen_nic_close(adapter->netdev);
-       netxen_nic_open(adapter->netdev);
+       netxen_nic_disable_int(adapter);
+       napi_disable(&adapter->napi);
+
        adapter->netdev->trans_start = jiffies;
+
+       napi_enable(&adapter->napi);
+       netxen_nic_enable_int(adapter);
        netif_wake_queue(adapter->netdev);
 }
 
This page took 0.028435 seconds and 5 git commands to generate.