]> err.no Git - linux-2.6/blobdiff - drivers/infiniband/hw/nes/nes_nic.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / infiniband / hw / nes / nes_nic.c
index b6cc265aa9a41eee602f45d43522ad377bf829e7..01cd0effc492b0712e880ac016117d082a295ae6 100644 (file)
@@ -92,15 +92,6 @@ static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
                | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 static int debug = -1;
 
-
-static int nes_netdev_open(struct net_device *);
-static int nes_netdev_stop(struct net_device *);
-static int nes_netdev_start_xmit(struct sk_buff *, struct net_device *);
-static struct net_device_stats *nes_netdev_get_stats(struct net_device *);
-static void nes_netdev_tx_timeout(struct net_device *);
-static int nes_netdev_set_mac_address(struct net_device *, void *);
-static int nes_netdev_change_mtu(struct net_device *, int);
-
 /**
  * nes_netdev_poll
  */
@@ -148,14 +139,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 +217,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 +251,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 +265,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));
@@ -777,7 +793,7 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
 
        memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
        printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n",
-                  __FUNCTION__, netdev->addr_len,
+                  __func__, netdev->addr_len,
                   mac_addr->sa_data[0], mac_addr->sa_data[1],
                   mac_addr->sa_data[2], mac_addr->sa_data[3],
                   mac_addr->sa_data[4], mac_addr->sa_data[5]);
@@ -807,7 +823,7 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
 /**
  * nes_netdev_set_multicast_list
  */
-void nes_netdev_set_multicast_list(struct net_device *netdev)
+static void nes_netdev_set_multicast_list(struct net_device *netdev)
 {
        struct nes_vnic *nesvnic = netdev_priv(netdev);
        struct nes_device *nesdev = nesvnic->nesdev;
@@ -859,7 +875,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) {
@@ -908,7 +923,7 @@ static int nes_netdev_change_mtu(struct     net_device *netdev,     int     new_mtu)
                return -EINVAL;
 
        netdev->mtu     = new_mtu;
-       nesvnic->max_frame_size = new_mtu+ETH_HLEN;
+       nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;
 
        if (netdev->mtu > 1500) {
                jumbomode=1;
@@ -923,28 +938,6 @@ static int nes_netdev_change_mtu(struct    net_device *netdev,     int     new_mtu)
        return ret;
 }
 
-
-/**
- * nes_netdev_exit - destroy network device
- */
-void nes_netdev_exit(struct nes_vnic *nesvnic)
-{
-       struct net_device *netdev = nesvnic->netdev;
-       struct nes_ib_device *nesibdev = nesvnic->nesibdev;
-
-       nes_debug(NES_DBG_SHUTDOWN, "\n");
-
-       // destroy the ibdevice if RDMA enabled
-       if ((nesvnic->rdma_enabled)&&(nesvnic->of_device_registered)) {
-               nes_destroy_ofa_device( nesibdev );
-               nesvnic->of_device_registered = 0;
-               nesvnic->nesibdev = NULL;
-       }
-       unregister_netdev(netdev);
-       nes_debug(NES_DBG_SHUTDOWN, "\n");
-}
-
-
 #define NES_ETHTOOL_STAT_COUNT 55
 static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = {
        "Link Change Interrupts",
@@ -1470,10 +1463,15 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
 {
        struct nes_vnic *nesvnic = netdev_priv(netdev);
        struct nes_device *nesdev = nesvnic->nesdev;
+       struct nes_adapter *nesadapter = nesdev->nesadapter;
        u32 u32temp;
+       unsigned long flags;
 
+       spin_lock_irqsave(&nesadapter->phy_lock, flags);
        nesvnic->vlan_grp = grp;
 
+       nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
+
        /* Enable/Disable VLAN Stripping */
        u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
        if (grp)
@@ -1482,6 +1480,7 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
                u32temp |= 0x02000000;
 
        nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp);
+       spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
 }
 
 
@@ -1540,7 +1539,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
        nesvnic->msg_enable = netif_msg_init(debug, default_msg);
        nesvnic->netdev_index = nesdev->netdev_count;
        nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count;
-       nesvnic->max_frame_size = netdev->mtu+netdev->hard_header_len;
+       nesvnic->max_frame_size = netdev->mtu + netdev->hard_header_len + VLAN_HLEN;
 
        curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)];
        nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid;
@@ -1610,7 +1609,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 +1647,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;