]> err.no Git - linux-2.6/blobdiff - drivers/net/cxgb3/sge.c
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6] / drivers / net / cxgb3 / sge.c
index 9ca8c66abd16193fddea7d0a5118ba2db2175505..796eb305cdc3ccb7348492818a128c7e69105006 100644 (file)
@@ -538,6 +538,31 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
        return p;
 }
 
+/**
+ *     t3_reset_qset - reset a sge qset
+ *     @q: the queue set
+ *
+ *     Reset the qset structure.
+ *     the NAPI structure is preserved in the event of
+ *     the qset's reincarnation, for example during EEH recovery.
+ */
+static void t3_reset_qset(struct sge_qset *q)
+{
+       if (q->adap &&
+           !(q->adap->flags & NAPI_INIT)) {
+               memset(q, 0, sizeof(*q));
+               return;
+       }
+
+       q->adap = NULL;
+       memset(&q->rspq, 0, sizeof(q->rspq));
+       memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
+       memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
+       q->txq_stopped = 0;
+       memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
+}
+
+
 /**
  *     free_qset - free the resources of an SGE queue set
  *     @adapter: the adapter owning the queue set
@@ -557,9 +582,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
 
        for (i = 0; i < SGE_RXQ_PER_SET; ++i)
                if (q->fl[i].desc) {
-                       spin_lock(&adapter->sge.reg_lock);
+                       spin_lock_irq(&adapter->sge.reg_lock);
                        t3_sge_disable_fl(adapter, q->fl[i].cntxt_id);
-                       spin_unlock(&adapter->sge.reg_lock);
+                       spin_unlock_irq(&adapter->sge.reg_lock);
                        free_rx_bufs(pdev, &q->fl[i]);
                        kfree(q->fl[i].sdesc);
                        dma_free_coherent(&pdev->dev,
@@ -570,9 +595,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
 
        for (i = 0; i < SGE_TXQ_PER_SET; ++i)
                if (q->txq[i].desc) {
-                       spin_lock(&adapter->sge.reg_lock);
+                       spin_lock_irq(&adapter->sge.reg_lock);
                        t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0);
-                       spin_unlock(&adapter->sge.reg_lock);
+                       spin_unlock_irq(&adapter->sge.reg_lock);
                        if (q->txq[i].sdesc) {
                                free_tx_desc(adapter, &q->txq[i],
                                             q->txq[i].in_use);
@@ -586,15 +611,15 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
                }
 
        if (q->rspq.desc) {
-               spin_lock(&adapter->sge.reg_lock);
+               spin_lock_irq(&adapter->sge.reg_lock);
                t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id);
-               spin_unlock(&adapter->sge.reg_lock);
+               spin_unlock_irq(&adapter->sge.reg_lock);
                dma_free_coherent(&pdev->dev,
                                  q->rspq.size * sizeof(struct rsp_desc),
                                  q->rspq.desc, q->rspq.phys_addr);
        }
 
-       memset(q, 0, sizeof(*q));
+       t3_reset_qset(q);
 }
 
 /**
@@ -1059,6 +1084,14 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
                         htonl(V_WR_TID(q->token)));
 }
 
+static inline void t3_stop_queue(struct net_device *dev, struct sge_qset *qs,
+                                struct sge_txq *q)
+{
+       netif_stop_queue(dev);
+       set_bit(TXQ_ETH, &qs->txq_stopped);
+       q->stops++;
+}
+
 /**
  *     eth_xmit - add a packet to the Ethernet Tx queue
  *     @skb: the packet
@@ -1090,30 +1123,23 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
        ndesc = calc_tx_descs(skb);
 
        if (unlikely(credits < ndesc)) {
-               if (!netif_queue_stopped(dev)) {
-                       netif_stop_queue(dev);
-                       set_bit(TXQ_ETH, &qs->txq_stopped);
-                       q->stops++;
-                       dev_err(&adap->pdev->dev,
-                               "%s: Tx ring %u full while queue awake!\n",
-                               dev->name, q->cntxt_id & 7);
-               }
+               t3_stop_queue(dev, qs, q);
+               dev_err(&adap->pdev->dev,
+                       "%s: Tx ring %u full while queue awake!\n",
+                       dev->name, q->cntxt_id & 7);
                spin_unlock(&q->lock);
                return NETDEV_TX_BUSY;
        }
 
        q->in_use += ndesc;
        if (unlikely(credits - ndesc < q->stop_thres)) {
-               q->stops++;
-               netif_stop_queue(dev);
-               set_bit(TXQ_ETH, &qs->txq_stopped);
-#if !USE_GTS
+               t3_stop_queue(dev, qs, q);
+
                if (should_restart_tx(q) &&
                    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
                        q->restarts++;
                        netif_wake_queue(dev);
                }
-#endif
        }
 
        gen = q->gen;
@@ -1364,7 +1390,7 @@ static void restart_ctrlq(unsigned long data)
  */
 int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
 {
-       int ret; 
+       int ret;
        local_bh_disable();
        ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
        local_bh_enable();
@@ -2666,7 +2692,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
                (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
                MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
 
-       spin_lock(&adapter->sge.reg_lock);
+       spin_lock_irq(&adapter->sge.reg_lock);
 
        /* FL threshold comparison uses < */
        ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx,
@@ -2710,7 +2736,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
                        goto err_unlock;
        }
 
-       spin_unlock(&adapter->sge.reg_lock);
+       spin_unlock_irq(&adapter->sge.reg_lock);
 
        q->adap = adapter;
        q->netdev = dev;
@@ -2727,7 +2753,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
        return 0;
 
       err_unlock:
-       spin_unlock(&adapter->sge.reg_lock);
+       spin_unlock_irq(&adapter->sge.reg_lock);
       err:
        t3_free_qset(adapter, q);
        return ret;