]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/net/qlge/qlge_main.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6.git] / drivers / net / qlge / qlge_main.c
index 4a075484e151d01e76157c6877faf6cc94dfab18..707b391afa02e434fb33ac180ac661d358fb7438 100644 (file)
@@ -69,9 +69,9 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 #define MSIX_IRQ 0
 #define MSI_IRQ 1
 #define LEG_IRQ 2
-static int irq_type = MSIX_IRQ;
-module_param(irq_type, int, MSIX_IRQ);
-MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
+static int qlge_irq_type = MSIX_IRQ;
+module_param(qlge_irq_type, int, MSIX_IRQ);
+MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
 
 static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
        {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
@@ -1661,6 +1661,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
        if (unlikely(!skb)) {
                QPRINTK(qdev, RX_STATUS, DEBUG,
                        "No skb available, drop packet.\n");
+               rx_ring->rx_dropped++;
                return;
        }
 
@@ -1669,6 +1670,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
                QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
                                        ib_mac_rsp->flags2);
                dev_kfree_skb_any(skb);
+               rx_ring->rx_errors++;
                return;
        }
 
@@ -1677,6 +1679,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
         */
        if (skb->len > ndev->mtu + ETH_HLEN) {
                dev_kfree_skb_any(skb);
+               rx_ring->rx_dropped++;
                return;
        }
 
@@ -1697,6 +1700,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
                        IB_MAC_IOCB_RSP_M_REG ? "Registered" : "",
                        (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
                        IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
+               rx_ring->rx_multicast++;
        }
        if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) {
                QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n");
@@ -1728,8 +1732,8 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
                }
        }
 
-       ndev->stats.rx_packets++;
-       ndev->stats.rx_bytes += skb->len;
+       rx_ring->rx_packets++;
+       rx_ring->rx_bytes += skb->len;
        skb_record_rx_queue(skb, rx_ring->cq_id);
        if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
                if (qdev->vlgrp &&
@@ -1753,7 +1757,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
 static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
                                   struct ob_mac_iocb_rsp *mac_rsp)
 {
-       struct net_device *ndev = qdev->ndev;
        struct tx_ring *tx_ring;
        struct tx_ring_desc *tx_ring_desc;
 
@@ -1761,8 +1764,8 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
        tx_ring = &qdev->tx_ring[mac_rsp->txq_idx];
        tx_ring_desc = &tx_ring->q[mac_rsp->tid];
        ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt);
-       ndev->stats.tx_bytes += (tx_ring_desc->skb)->len;
-       ndev->stats.tx_packets++;
+       tx_ring->tx_bytes += (tx_ring_desc->skb)->len;
+       tx_ring->tx_packets++;
        dev_kfree_skb(tx_ring_desc->skb);
        tx_ring_desc->skb = NULL;
 
@@ -2205,6 +2208,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
                        __func__, tx_ring_idx);
                netif_stop_subqueue(ndev, tx_ring->wq_id);
                atomic_inc(&tx_ring->queue_stopped);
+               tx_ring->tx_errors++;
                return NETDEV_TX_BUSY;
        }
        tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
@@ -2239,6 +2243,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
                        NETDEV_TX_OK) {
                QPRINTK(qdev, TX_QUEUED, ERR,
                                "Could not map the segments.\n");
+               tx_ring->tx_errors++;
                return NETDEV_TX_BUSY;
        }
        QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr);
@@ -2342,8 +2347,8 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev,
            pci_alloc_consistent(qdev->pdev, tx_ring->wq_size,
                                 &tx_ring->wq_base_dma);
 
-       if ((tx_ring->wq_base == NULL)
-               || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
+       if ((tx_ring->wq_base == NULL) ||
+           tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
                QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
                return -ENOMEM;
        }
@@ -2865,7 +2870,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
        int i, err;
 
        /* Get the MSIX vectors. */
-       if (irq_type == MSIX_IRQ) {
+       if (qlge_irq_type == MSIX_IRQ) {
                /* Try to alloc space for the msix struct,
                 * if it fails then go to MSI/legacy.
                 */
@@ -2873,7 +2878,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
                                            sizeof(struct msix_entry),
                                            GFP_KERNEL);
                if (!qdev->msi_x_entry) {
-                       irq_type = MSI_IRQ;
+                       qlge_irq_type = MSI_IRQ;
                        goto msi;
                }
 
@@ -2896,7 +2901,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
                        QPRINTK(qdev, IFUP, WARNING,
                                "MSI-X Enable failed, trying MSI.\n");
                        qdev->intr_count = 1;
-                       irq_type = MSI_IRQ;
+                       qlge_irq_type = MSI_IRQ;
                } else if (err == 0) {
                        set_bit(QL_MSIX_ENABLED, &qdev->flags);
                        QPRINTK(qdev, IFUP, INFO,
@@ -2907,7 +2912,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
        }
 msi:
        qdev->intr_count = 1;
-       if (irq_type == MSI_IRQ) {
+       if (qlge_irq_type == MSI_IRQ) {
                if (!pci_enable_msi(qdev->pdev)) {
                        set_bit(QL_MSI_ENABLED, &qdev->flags);
                        QPRINTK(qdev, IFUP, INFO,
@@ -2915,7 +2920,7 @@ msi:
                        return;
                }
        }
-       irq_type = LEG_IRQ;
+       qlge_irq_type = LEG_IRQ;
        QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
 }
 
@@ -3509,9 +3514,6 @@ int ql_wol(struct ql_adapter *qdev)
        }
 
        if (qdev->wol) {
-               /* Reroute all packets to Management Interface */
-               ql_write32(qdev, MGMT_RCV_CFG, (MGMT_RCV_CFG_RM |
-                       (MGMT_RCV_CFG_RM << 16)));
                wol |= MB_WOL_MODE_ON;
                status = ql_mb_wol_mode(qdev, wol);
                QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
@@ -3712,6 +3714,10 @@ static int qlge_open(struct net_device *ndev)
        int err = 0;
        struct ql_adapter *qdev = netdev_priv(ndev);
 
+       err = ql_adapter_reset(qdev);
+       if (err)
+               return err;
+
        err = ql_configure_rings(qdev);
        if (err)
                return err;
@@ -3817,6 +3823,37 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
 static struct net_device_stats *qlge_get_stats(struct net_device
                                               *ndev)
 {
+       struct ql_adapter *qdev = netdev_priv(ndev);
+       struct rx_ring *rx_ring = &qdev->rx_ring[0];
+       struct tx_ring *tx_ring = &qdev->tx_ring[0];
+       unsigned long pkts, mcast, dropped, errors, bytes;
+       int i;
+
+       /* Get RX stats. */
+       pkts = mcast = dropped = errors = bytes = 0;
+       for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
+                       pkts += rx_ring->rx_packets;
+                       bytes += rx_ring->rx_bytes;
+                       dropped += rx_ring->rx_dropped;
+                       errors += rx_ring->rx_errors;
+                       mcast += rx_ring->rx_multicast;
+       }
+       ndev->stats.rx_packets = pkts;
+       ndev->stats.rx_bytes = bytes;
+       ndev->stats.rx_dropped = dropped;
+       ndev->stats.rx_errors = errors;
+       ndev->stats.multicast = mcast;
+
+       /* Get TX stats. */
+       pkts = errors = bytes = 0;
+       for (i = 0; i < qdev->tx_ring_count; i++, tx_ring++) {
+                       pkts += tx_ring->tx_packets;
+                       bytes += tx_ring->tx_bytes;
+                       errors += tx_ring->tx_errors;
+       }
+       ndev->stats.tx_packets = pkts;
+       ndev->stats.tx_bytes = bytes;
+       ndev->stats.tx_errors = errors;
        return &ndev->stats;
 }
 
@@ -3914,9 +3951,6 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
        struct sockaddr *addr = p;
        int status;
 
-       if (netif_running(ndev))
-               return -EBUSY;
-
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
        memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
@@ -4109,6 +4143,8 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                goto err_out;
        }
 
+       /* Set PCIe reset type for EEH to fundamental. */
+       pdev->needs_freset = 1;
        pci_save_state(pdev);
        qdev->reg_base =
            ioremap_nocache(pci_resource_start(pdev, 1),