Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=11e0704b7ec3abfeaee7e3a56f11c82024d1ae01
Commit:     11e0704b7ec3abfeaee7e3a56f11c82024d1ae01
Parent:     c7482b81c8b524193d736488c149adbe27a7eb7f
Author:     Glenn Streiff <[EMAIL PROTECTED]>
AuthorDate: Fri Feb 15 11:41:27 2008 -0600
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Fri Feb 15 15:05:05 2008 -0800

    RDMA/nes: Fix MAC interrupt erroneously masked on ifdown
    
    Only mask out MAC interrupt if necessary and re-enable on ifup.  There
    could be multiple netdevs going through the same MAC.  MAC interrupts
    should not be masked off until the last netdev is downed.
    
    Signed-off-by: Chien Tung <[EMAIL PROTECTED]>
    Signed-off-by: Glenn Streiff <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/nes/nes_nic.c |   52 ++++++++++++++++++++++++-----------
 1 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/drivers/infiniband/hw/nes/nes_nic.c 
b/drivers/infiniband/hw/nes/nes_nic.c
index b6cc265..67827ad 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -148,14 +148,15 @@ static int nes_netdev_open(struct net_device *netdev)
        struct nes_device *nesdev = nesvnic->nesdev;
        int ret;
        int i;
-       struct nes_vnic *first_nesvnic;
+       struct nes_vnic *first_nesvnic = NULL;
        u32 nic_active_bit;
        u32 nic_active;
+       struct list_head *list_pos, *list_temp;
 
        assert(nesdev != NULL);
 
-       first_nesvnic = 
list_entry(nesdev->nesadapter->nesvnic_list[nesdev->mac_index].next,
-                       struct nes_vnic, list);
+       if (nesvnic->netdev_open == 1)
+               return 0;
 
        if (netif_msg_ifup(nesvnic))
                printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name);
@@ -225,7 +226,18 @@ static int nes_netdev_open(struct net_device *netdev)
        nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
                        nesvnic->nic_cq.cq_number);
        nes_read32(nesdev->regs+NES_CQE_ALLOC);
-
+       list_for_each_safe(list_pos, list_temp, 
&nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
+               first_nesvnic = container_of(list_pos, struct nes_vnic, list);
+               if (first_nesvnic->netdev_open == 1)
+                       break;
+       }
+       if (first_nesvnic->netdev_open == 0) {
+               nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
+               nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * 
nesdev->mac_index),
+                               ~(NES_MAC_INT_LINK_STAT_CHG | 
NES_MAC_INT_XGMII_EXT |
+                               NES_MAC_INT_TX_UNDERFLOW | 
NES_MAC_INT_TX_ERROR));
+               first_nesvnic = nesvnic;
+       }
        if (first_nesvnic->linkup) {
                /* Enable network packets */
                nesvnic->linkup = 1;
@@ -248,6 +260,8 @@ static int nes_netdev_stop(struct net_device *netdev)
        struct nes_device *nesdev = nesvnic->nesdev;
        u32 nic_active_mask;
        u32 nic_active;
+       struct nes_vnic *first_nesvnic = NULL;
+       struct list_head *list_pos, *list_temp;
 
        nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
                        nesvnic, nesdev, netdev, netdev->name);
@@ -260,9 +274,20 @@ static int nes_netdev_stop(struct net_device *netdev)
        /* Disable network packets */
        napi_disable(&nesvnic->napi);
        netif_stop_queue(netdev);
-       if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == 
nesdev->mac_index)) {
-               nes_write_indexed(nesdev,
-                               NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 
0xffffffff);
+       list_for_each_safe(list_pos, list_temp, 
&nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
+               first_nesvnic = container_of(list_pos, struct nes_vnic, list);
+               if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != 
nesvnic))
+                       break;
+       }
+
+       if (first_nesvnic->netdev_open == 0)
+               nes_write_indexed(nesdev, 
NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
+       else if ((first_nesvnic != nesvnic) &&
+                (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != 
PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
+               nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * 
nesdev->mac_index), 0xffffffff);
+               nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + 
(0x200 * first_nesvnic->nesdev->mac_index),
+                               ~(NES_MAC_INT_LINK_STAT_CHG | 
NES_MAC_INT_XGMII_EXT |
+                               NES_MAC_INT_TX_UNDERFLOW | 
NES_MAC_INT_TX_ERROR));
        }
 
        nic_active_mask = ~((u32)(1 << nesvnic->nic_index));
@@ -859,7 +884,6 @@ void nes_netdev_set_multicast_list(struct net_device 
*netdev)
                for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
                        while (multicast_addr && nesvnic->mcrq_mcast_filter && 
((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) 
== 0))
                                multicast_addr = multicast_addr->next;
-
                        if (mc_nic_index < 0)
                                mc_nic_index = nesvnic->nic_index;
                        if (multicast_addr) {
@@ -1610,7 +1634,7 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
        list_add_tail(&nesvnic->list, 
&nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
 
        if ((nesdev->netdev_count == 0) &&
-                       (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) 
{
+           (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
                nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using 
register index 0x%04X\n",
                                
NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
                u32temp = nes_read_indexed(nesdev, 
NES_IDX_PHY_PCS_CONTROL_STATUS0 +
@@ -1648,18 +1672,14 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
                                nesvnic->linkup = 1;
                        }
                }
-               nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
                /* clear the MAC interrupt status, assumes direct logical to 
physical mapping */
-               u32temp = nes_read_indexed(nesdev, 
NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port));
+               u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + 
(0x200 * nesdev->mac_index));
                nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", 
u32temp);
-               nes_write_indexed(nesdev, 
NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port), u32temp);
+               nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * 
nesdev->mac_index), u32temp);
 
-               if (nesdev->nesadapter->phy_type[nesvnic->logical_port] != 
NES_PHY_TYPE_IRIS)
+               if (nesdev->nesadapter->phy_type[nesdev->mac_index] != 
NES_PHY_TYPE_IRIS)
                        nes_init_phy(nesdev);
 
-               nes_write_indexed(nesdev, 
NES_IDX_MAC_INT_MASK+(0x200*nesvnic->logical_port),
-                               ~(NES_MAC_INT_LINK_STAT_CHG | 
NES_MAC_INT_XGMII_EXT |
-                               NES_MAC_INT_TX_UNDERFLOW | 
NES_MAC_INT_TX_ERROR));
        }
 
        return netdev;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to