aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/main.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.c35
-rw-r--r--drivers/infiniband/hw/nes/nes.h4
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c8
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c95
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h10
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c78
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c37
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c15
-rw-r--r--drivers/net/mlx4/catas.c6
-rw-r--r--drivers/net/mlx4/en_main.c3
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mcg.c23
-rw-r--r--include/linux/mlx4/device.h10
-rw-r--r--include/linux/mlx4/driver.h6
20 files changed, 297 insertions, 60 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 4c85224aeaa7..c7a6213c6996 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -623,8 +623,9 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
623 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); 623 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
624 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 624 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
625 625
626 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, !!(mqp->flags & 626 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw,
627 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); 627 !!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
628 MLX4_PROTOCOL_IB);
628 if (err) 629 if (err)
629 return err; 630 return err;
630 631
@@ -635,7 +636,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
635 return 0; 636 return 0;
636 637
637err_add: 638err_add:
638 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw); 639 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
639 return err; 640 return err;
640} 641}
641 642
@@ -665,7 +666,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
665 struct mlx4_ib_gid_entry *ge; 666 struct mlx4_ib_gid_entry *ge;
666 667
667 err = mlx4_multicast_detach(mdev->dev, 668 err = mlx4_multicast_detach(mdev->dev,
668 &mqp->mqp, gid->raw); 669 &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
669 if (err) 670 if (err)
670 return err; 671 return err;
671 672
@@ -1005,7 +1006,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1005 if (mlx4_uar_alloc(dev, &ibdev->priv_uar)) 1006 if (mlx4_uar_alloc(dev, &ibdev->priv_uar))
1006 goto err_pd; 1007 goto err_pd;
1007 1008
1008 ibdev->uar_map = ioremap(ibdev->priv_uar.pfn << PAGE_SHIFT, PAGE_SIZE); 1009 ibdev->uar_map = ioremap((phys_addr_t) ibdev->priv_uar.pfn << PAGE_SHIFT,
1010 PAGE_SIZE);
1009 if (!ibdev->uar_map) 1011 if (!ibdev->uar_map)
1010 goto err_uar; 1012 goto err_uar;
1011 MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock); 1013 MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock);
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 0aa0110e4b6c..e4a08c2819e4 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -146,7 +146,7 @@ static void poll_catas(unsigned long dev_ptr)
146 146
147void mthca_start_catas_poll(struct mthca_dev *dev) 147void mthca_start_catas_poll(struct mthca_dev *dev)
148{ 148{
149 unsigned long addr; 149 phys_addr_t addr;
150 150
151 init_timer(&dev->catas_err.timer); 151 init_timer(&dev->catas_err.timer);
152 dev->catas_err.map = NULL; 152 dev->catas_err.map = NULL;
@@ -158,7 +158,8 @@ void mthca_start_catas_poll(struct mthca_dev *dev)
158 dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4); 158 dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4);
159 if (!dev->catas_err.map) { 159 if (!dev->catas_err.map) {
160 mthca_warn(dev, "couldn't map catastrophic error region " 160 mthca_warn(dev, "couldn't map catastrophic error region "
161 "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4); 161 "at 0x%llx/0x%x\n", (unsigned long long) addr,
162 dev->catas_err.size * 4);
162 return; 163 return;
163 } 164 }
164 165
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index f4ceecd9684b..7bfa2a164955 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -713,7 +713,7 @@ int mthca_RUN_FW(struct mthca_dev *dev, u8 *status)
713 713
714static void mthca_setup_cmd_doorbells(struct mthca_dev *dev, u64 base) 714static void mthca_setup_cmd_doorbells(struct mthca_dev *dev, u64 base)
715{ 715{
716 unsigned long addr; 716 phys_addr_t addr;
717 u16 max_off = 0; 717 u16 max_off = 0;
718 int i; 718 int i;
719 719
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 8e8c728aff88..76785c653c13 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -653,7 +653,7 @@ static int mthca_map_reg(struct mthca_dev *dev,
653 unsigned long offset, unsigned long size, 653 unsigned long offset, unsigned long size,
654 void __iomem **map) 654 void __iomem **map)
655{ 655{
656 unsigned long base = pci_resource_start(dev->pdev, 0); 656 phys_addr_t base = pci_resource_start(dev->pdev, 0);
657 657
658 *map = ioremap(base + offset, size); 658 *map = ioremap(base + offset, size);
659 if (!*map) 659 if (!*map)
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 5eee6665919a..8a40cd539ab1 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -790,7 +790,7 @@ static int mthca_setup_hca(struct mthca_dev *dev)
790 goto err_uar_table_free; 790 goto err_uar_table_free;
791 } 791 }
792 792
793 dev->kar = ioremap(dev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE); 793 dev->kar = ioremap((phys_addr_t) dev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
794 if (!dev->kar) { 794 if (!dev->kar) {
795 mthca_err(dev, "Couldn't map kernel access region, " 795 mthca_err(dev, "Couldn't map kernel access region, "
796 "aborting.\n"); 796 "aborting.\n");
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 065b20899876..44045c8846db 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -853,7 +853,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
853 853
854int mthca_init_mr_table(struct mthca_dev *dev) 854int mthca_init_mr_table(struct mthca_dev *dev)
855{ 855{
856 unsigned long addr; 856 phys_addr_t addr;
857 int mpts, mtts, err, i; 857 int mpts, mtts, err, i;
858 858
859 err = mthca_alloc_init(&dev->mr_table.mpt_alloc, 859 err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 0c9f0aa5d4ea..3b4ec3238ceb 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -144,6 +144,7 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
144 struct nes_device *nesdev; 144 struct nes_device *nesdev;
145 struct net_device *netdev; 145 struct net_device *netdev;
146 struct nes_vnic *nesvnic; 146 struct nes_vnic *nesvnic;
147 unsigned int is_bonded;
147 148
148 nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n", 149 nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n",
149 &ifa->ifa_address, &ifa->ifa_mask); 150 &ifa->ifa_address, &ifa->ifa_mask);
@@ -152,7 +153,8 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
152 nesdev, nesdev->netdev[0]->name); 153 nesdev, nesdev->netdev[0]->name);
153 netdev = nesdev->netdev[0]; 154 netdev = nesdev->netdev[0];
154 nesvnic = netdev_priv(netdev); 155 nesvnic = netdev_priv(netdev);
155 if (netdev == event_netdev) { 156 is_bonded = (netdev->master == event_netdev);
157 if ((netdev == event_netdev) || is_bonded) {
156 if (nesvnic->rdma_enabled == 0) { 158 if (nesvnic->rdma_enabled == 0) {
157 nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" 159 nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since"
158 " RDMA is not enabled.\n", 160 " RDMA is not enabled.\n",
@@ -169,7 +171,10 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
169 nes_manage_arp_cache(netdev, netdev->dev_addr, 171 nes_manage_arp_cache(netdev, netdev->dev_addr,
170 ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); 172 ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE);
171 nesvnic->local_ipaddr = 0; 173 nesvnic->local_ipaddr = 0;
172 return NOTIFY_OK; 174 if (is_bonded)
175 continue;
176 else
177 return NOTIFY_OK;
173 break; 178 break;
174 case NETDEV_UP: 179 case NETDEV_UP:
175 nes_debug(NES_DBG_NETDEV, "event:UP\n"); 180 nes_debug(NES_DBG_NETDEV, "event:UP\n");
@@ -178,15 +183,24 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
178 nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); 183 nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n");
179 return NOTIFY_OK; 184 return NOTIFY_OK;
180 } 185 }
186 /* fall through */
187 case NETDEV_CHANGEADDR:
181 /* Add the address to the IP table */ 188 /* Add the address to the IP table */
182 nesvnic->local_ipaddr = ifa->ifa_address; 189 if (netdev->master)
190 nesvnic->local_ipaddr =
191 ((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address;
192 else
193 nesvnic->local_ipaddr = ifa->ifa_address;
183 194
184 nes_write_indexed(nesdev, 195 nes_write_indexed(nesdev,
185 NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), 196 NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)),
186 ntohl(ifa->ifa_address)); 197 ntohl(nesvnic->local_ipaddr));
187 nes_manage_arp_cache(netdev, netdev->dev_addr, 198 nes_manage_arp_cache(netdev, netdev->dev_addr,
188 ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); 199 ntohl(nesvnic->local_ipaddr), NES_ARP_ADD);
189 return NOTIFY_OK; 200 if (is_bonded)
201 continue;
202 else
203 return NOTIFY_OK;
190 break; 204 break;
191 default: 205 default:
192 break; 206 break;
@@ -660,6 +674,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
660 } 674 }
661 nes_notifiers_registered++; 675 nes_notifiers_registered++;
662 676
677 INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status);
678
663 /* Initialize network devices */ 679 /* Initialize network devices */
664 if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) 680 if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL)
665 goto bail7; 681 goto bail7;
@@ -742,6 +758,7 @@ static void __devexit nes_remove(struct pci_dev *pcidev)
742 struct nes_device *nesdev = pci_get_drvdata(pcidev); 758 struct nes_device *nesdev = pci_get_drvdata(pcidev);
743 struct net_device *netdev; 759 struct net_device *netdev;
744 int netdev_index = 0; 760 int netdev_index = 0;
761 unsigned long flags;
745 762
746 if (nesdev->netdev_count) { 763 if (nesdev->netdev_count) {
747 netdev = nesdev->netdev[netdev_index]; 764 netdev = nesdev->netdev[netdev_index];
@@ -768,6 +785,14 @@ static void __devexit nes_remove(struct pci_dev *pcidev)
768 free_irq(pcidev->irq, nesdev); 785 free_irq(pcidev->irq, nesdev);
769 tasklet_kill(&nesdev->dpc_tasklet); 786 tasklet_kill(&nesdev->dpc_tasklet);
770 787
788 spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags);
789 if (nesdev->link_recheck) {
790 spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
791 cancel_delayed_work_sync(&nesdev->work);
792 } else {
793 spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
794 }
795
771 /* Deallocate the Adapter Structure */ 796 /* Deallocate the Adapter Structure */
772 nes_destroy_adapter(nesdev->nesadapter); 797 nes_destroy_adapter(nesdev->nesadapter);
773 798
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index b3d145e82b4c..6fe79876009e 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -268,6 +268,9 @@ struct nes_device {
268 u8 napi_isr_ran; 268 u8 napi_isr_ran;
269 u8 disable_rx_flow_control; 269 u8 disable_rx_flow_control;
270 u8 disable_tx_flow_control; 270 u8 disable_tx_flow_control;
271
272 struct delayed_work work;
273 u8 link_recheck;
271}; 274};
272 275
273 276
@@ -507,6 +510,7 @@ void nes_nic_ce_handler(struct nes_device *, struct nes_hw_nic_cq *);
507void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *); 510void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *);
508int nes_destroy_cqp(struct nes_device *); 511int nes_destroy_cqp(struct nes_device *);
509int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); 512int nes_nic_cm_xmit(struct sk_buff *, struct net_device *);
513void nes_recheck_link_status(struct work_struct *work);
510 514
511/* nes_nic.c */ 515/* nes_nic.c */
512struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); 516struct net_device *nes_netdev_init(struct nes_device *, void __iomem *);
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 25ad0f9944c0..009ec814d517 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1107,6 +1107,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
1107 struct flowi fl; 1107 struct flowi fl;
1108 struct neighbour *neigh; 1108 struct neighbour *neigh;
1109 int rc = arpindex; 1109 int rc = arpindex;
1110 struct net_device *netdev;
1110 struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; 1111 struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
1111 1112
1112 memset(&fl, 0, sizeof fl); 1113 memset(&fl, 0, sizeof fl);
@@ -1117,7 +1118,12 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
1117 return rc; 1118 return rc;
1118 } 1119 }
1119 1120
1120 neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev); 1121 if (nesvnic->netdev->master)
1122 netdev = nesvnic->netdev->master;
1123 else
1124 netdev = nesvnic->netdev;
1125
1126 neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev);
1121 if (neigh) { 1127 if (neigh) {
1122 if (neigh->nud_state & NUD_VALID) { 1128 if (neigh->nud_state & NUD_VALID) {
1123 nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" 1129 nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 1980a461c499..8b606fd64022 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -2608,6 +2608,13 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2608 netif_start_queue(nesvnic->netdev); 2608 netif_start_queue(nesvnic->netdev);
2609 nesvnic->linkup = 1; 2609 nesvnic->linkup = 1;
2610 netif_carrier_on(nesvnic->netdev); 2610 netif_carrier_on(nesvnic->netdev);
2611
2612 spin_lock(&nesvnic->port_ibevent_lock);
2613 if (nesdev->iw_status == 0) {
2614 nesdev->iw_status = 1;
2615 nes_port_ibevent(nesvnic);
2616 }
2617 spin_unlock(&nesvnic->port_ibevent_lock);
2611 } 2618 }
2612 } 2619 }
2613 } else { 2620 } else {
@@ -2633,9 +2640,23 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2633 netif_stop_queue(nesvnic->netdev); 2640 netif_stop_queue(nesvnic->netdev);
2634 nesvnic->linkup = 0; 2641 nesvnic->linkup = 0;
2635 netif_carrier_off(nesvnic->netdev); 2642 netif_carrier_off(nesvnic->netdev);
2643
2644 spin_lock(&nesvnic->port_ibevent_lock);
2645 if (nesdev->iw_status == 1) {
2646 nesdev->iw_status = 0;
2647 nes_port_ibevent(nesvnic);
2648 }
2649 spin_unlock(&nesvnic->port_ibevent_lock);
2636 } 2650 }
2637 } 2651 }
2638 } 2652 }
2653 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_SFP_D) {
2654 if (nesdev->link_recheck)
2655 cancel_delayed_work(&nesdev->work);
2656 nesdev->link_recheck = 1;
2657 schedule_delayed_work(&nesdev->work,
2658 NES_LINK_RECHECK_DELAY);
2659 }
2639 } 2660 }
2640 2661
2641 spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 2662 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
@@ -2643,6 +2664,80 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2643 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE; 2664 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE;
2644} 2665}
2645 2666
2667void nes_recheck_link_status(struct work_struct *work)
2668{
2669 unsigned long flags;
2670 struct nes_device *nesdev = container_of(work, struct nes_device, work.work);
2671 struct nes_adapter *nesadapter = nesdev->nesadapter;
2672 struct nes_vnic *nesvnic;
2673 u32 mac_index = nesdev->mac_index;
2674 u16 phy_data;
2675 u16 temp_phy_data;
2676
2677 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2678
2679 /* check link status */
2680 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
2681 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2682
2683 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
2684 nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2685 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
2686 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2687
2688 phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
2689
2690 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2691 __func__, phy_data,
2692 nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
2693
2694 if (phy_data & 0x0004) {
2695 nesadapter->mac_link_down[mac_index] = 0;
2696 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2697 if (nesvnic->linkup == 0) {
2698 printk(PFX "The Link is now up for port %s, netdev %p.\n",
2699 nesvnic->netdev->name, nesvnic->netdev);
2700 if (netif_queue_stopped(nesvnic->netdev))
2701 netif_start_queue(nesvnic->netdev);
2702 nesvnic->linkup = 1;
2703 netif_carrier_on(nesvnic->netdev);
2704
2705 spin_lock(&nesvnic->port_ibevent_lock);
2706 if (nesdev->iw_status == 0) {
2707 nesdev->iw_status = 1;
2708 nes_port_ibevent(nesvnic);
2709 }
2710 spin_unlock(&nesvnic->port_ibevent_lock);
2711 }
2712 }
2713
2714 } else {
2715 nesadapter->mac_link_down[mac_index] = 1;
2716 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2717 if (nesvnic->linkup == 1) {
2718 printk(PFX "The Link is now down for port %s, netdev %p.\n",
2719 nesvnic->netdev->name, nesvnic->netdev);
2720 if (!(netif_queue_stopped(nesvnic->netdev)))
2721 netif_stop_queue(nesvnic->netdev);
2722 nesvnic->linkup = 0;
2723 netif_carrier_off(nesvnic->netdev);
2724
2725 spin_lock(&nesvnic->port_ibevent_lock);
2726 if (nesdev->iw_status == 1) {
2727 nesdev->iw_status = 0;
2728 nes_port_ibevent(nesvnic);
2729 }
2730 spin_unlock(&nesvnic->port_ibevent_lock);
2731 }
2732 }
2733 }
2734 if (nesdev->link_recheck++ < NES_LINK_RECHECK_MAX)
2735 schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY);
2736 else
2737 nesdev->link_recheck = 0;
2738
2739 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2740}
2646 2741
2647 2742
2648static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) 2743static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 1204c3432b63..d2abe07133a5 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1193,6 +1193,8 @@ struct nes_listener {
1193 1193
1194struct nes_ib_device; 1194struct nes_ib_device;
1195 1195
1196#define NES_EVENT_DELAY msecs_to_jiffies(100)
1197
1196struct nes_vnic { 1198struct nes_vnic {
1197 struct nes_ib_device *nesibdev; 1199 struct nes_ib_device *nesibdev;
1198 u64 sq_full; 1200 u64 sq_full;
@@ -1247,6 +1249,10 @@ struct nes_vnic {
1247 u32 lro_max_aggr; 1249 u32 lro_max_aggr;
1248 struct net_lro_mgr lro_mgr; 1250 struct net_lro_mgr lro_mgr;
1249 struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; 1251 struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
1252 struct timer_list event_timer;
1253 enum ib_event_type delayed_event;
1254 enum ib_event_type last_dispatched_event;
1255 spinlock_t port_ibevent_lock;
1250}; 1256};
1251 1257
1252struct nes_ib_device { 1258struct nes_ib_device {
@@ -1348,6 +1354,10 @@ struct nes_terminate_hdr {
1348#define BAD_FRAME_OFFSET 64 1354#define BAD_FRAME_OFFSET 64
1349#define CQE_MAJOR_DRV 0x8000 1355#define CQE_MAJOR_DRV 0x8000
1350 1356
1357/* Used for link status recheck after interrupt processing */
1358#define NES_LINK_RECHECK_DELAY msecs_to_jiffies(50)
1359#define NES_LINK_RECHECK_MAX 60
1360
1351#define nes_vlan_rx vlan_hwaccel_receive_skb 1361#define nes_vlan_rx vlan_hwaccel_receive_skb
1352#define nes_netif_rx netif_receive_skb 1362#define nes_netif_rx netif_receive_skb
1353 1363
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 5a4c36484722..2c9c1933bbe3 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -144,6 +144,7 @@ static int nes_netdev_open(struct net_device *netdev)
144 u32 nic_active_bit; 144 u32 nic_active_bit;
145 u32 nic_active; 145 u32 nic_active;
146 struct list_head *list_pos, *list_temp; 146 struct list_head *list_pos, *list_temp;
147 unsigned long flags;
147 148
148 assert(nesdev != NULL); 149 assert(nesdev != NULL);
149 150
@@ -233,18 +234,36 @@ static int nes_netdev_open(struct net_device *netdev)
233 first_nesvnic = nesvnic; 234 first_nesvnic = nesvnic;
234 } 235 }
235 236
236 if (nesvnic->of_device_registered) {
237 nesdev->iw_status = 1;
238 nesdev->nesadapter->send_term_ok = 1;
239 nes_port_ibevent(nesvnic);
240 }
241
242 if (first_nesvnic->linkup) { 237 if (first_nesvnic->linkup) {
243 /* Enable network packets */ 238 /* Enable network packets */
244 nesvnic->linkup = 1; 239 nesvnic->linkup = 1;
245 netif_start_queue(netdev); 240 netif_start_queue(netdev);
246 netif_carrier_on(netdev); 241 netif_carrier_on(netdev);
247 } 242 }
243
244 spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags);
245 if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_SFP_D) {
246 if (nesdev->link_recheck)
247 cancel_delayed_work(&nesdev->work);
248 nesdev->link_recheck = 1;
249 schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY);
250 }
251 spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
252
253 spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags);
254 if (nesvnic->of_device_registered) {
255 nesdev->nesadapter->send_term_ok = 1;
256 if (nesvnic->linkup == 1) {
257 if (nesdev->iw_status == 0) {
258 nesdev->iw_status = 1;
259 nes_port_ibevent(nesvnic);
260 }
261 } else {
262 nesdev->iw_status = 0;
263 }
264 }
265 spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags);
266
248 napi_enable(&nesvnic->napi); 267 napi_enable(&nesvnic->napi);
249 nesvnic->netdev_open = 1; 268 nesvnic->netdev_open = 1;
250 269
@@ -263,6 +282,7 @@ static int nes_netdev_stop(struct net_device *netdev)
263 u32 nic_active; 282 u32 nic_active;
264 struct nes_vnic *first_nesvnic = NULL; 283 struct nes_vnic *first_nesvnic = NULL;
265 struct list_head *list_pos, *list_temp; 284 struct list_head *list_pos, *list_temp;
285 unsigned long flags;
266 286
267 nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", 287 nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
268 nesvnic, nesdev, netdev, netdev->name); 288 nesvnic, nesdev, netdev, netdev->name);
@@ -315,12 +335,17 @@ static int nes_netdev_stop(struct net_device *netdev)
315 nic_active &= nic_active_mask; 335 nic_active &= nic_active_mask;
316 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); 336 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
317 337
318 338 spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags);
319 if (nesvnic->of_device_registered) { 339 if (nesvnic->of_device_registered) {
320 nesdev->nesadapter->send_term_ok = 0; 340 nesdev->nesadapter->send_term_ok = 0;
321 nesdev->iw_status = 0; 341 nesdev->iw_status = 0;
322 nes_port_ibevent(nesvnic); 342 if (nesvnic->linkup == 1)
343 nes_port_ibevent(nesvnic);
323 } 344 }
345 del_timer_sync(&nesvnic->event_timer);
346 nesvnic->event_timer.function = NULL;
347 spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags);
348
324 nes_destroy_nic_qp(nesvnic); 349 nes_destroy_nic_qp(nesvnic);
325 350
326 nesvnic->netdev_open = 0; 351 nesvnic->netdev_open = 0;
@@ -1750,7 +1775,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1750 nesvnic->rdma_enabled = 0; 1775 nesvnic->rdma_enabled = 0;
1751 } 1776 }
1752 nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; 1777 nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id;
1778 init_timer(&nesvnic->event_timer);
1779 nesvnic->event_timer.function = NULL;
1753 spin_lock_init(&nesvnic->tx_lock); 1780 spin_lock_init(&nesvnic->tx_lock);
1781 spin_lock_init(&nesvnic->port_ibevent_lock);
1754 nesdev->netdev[nesdev->netdev_count] = netdev; 1782 nesdev->netdev[nesdev->netdev_count] = netdev;
1755 1783
1756 nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", 1784 nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n",
@@ -1763,8 +1791,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1763 (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || 1791 (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
1764 ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { 1792 ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
1765 u32 u32temp; 1793 u32 u32temp;
1766 u32 link_mask; 1794 u32 link_mask = 0;
1767 u32 link_val; 1795 u32 link_val = 0;
1796 u16 temp_phy_data;
1797 u16 phy_data = 0;
1798 unsigned long flags;
1768 1799
1769 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1800 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1770 (0x200 * (nesdev->mac_index & 1))); 1801 (0x200 * (nesdev->mac_index & 1)));
@@ -1786,6 +1817,23 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1786 link_val = 0x02020000; 1817 link_val = 0x02020000;
1787 } 1818 }
1788 break; 1819 break;
1820 case NES_PHY_TYPE_SFP_D:
1821 spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags);
1822 nes_read_10G_phy_reg(nesdev,
1823 nesdev->nesadapter->phy_index[nesdev->mac_index],
1824 1, 0x9003);
1825 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1826 nes_read_10G_phy_reg(nesdev,
1827 nesdev->nesadapter->phy_index[nesdev->mac_index],
1828 3, 0x0021);
1829 nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1830 nes_read_10G_phy_reg(nesdev,
1831 nesdev->nesadapter->phy_index[nesdev->mac_index],
1832 3, 0x0021);
1833 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1834 spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
1835 phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
1836 break;
1789 default: 1837 default:
1790 link_mask = 0x0f1f0000; 1838 link_mask = 0x0f1f0000;
1791 link_val = 0x0f0f0000; 1839 link_val = 0x0f0f0000;
@@ -1795,8 +1843,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1795 u32temp = nes_read_indexed(nesdev, 1843 u32temp = nes_read_indexed(nesdev,
1796 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1844 NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1797 (0x200 * (nesdev->mac_index & 1))); 1845 (0x200 * (nesdev->mac_index & 1)));
1798 if ((u32temp & link_mask) == link_val) 1846
1799 nesvnic->linkup = 1; 1847 if (phy_type == NES_PHY_TYPE_SFP_D) {
1848 if (phy_data & 0x0004)
1849 nesvnic->linkup = 1;
1850 } else {
1851 if ((u32temp & link_mask) == link_val)
1852 nesvnic->linkup = 1;
1853 }
1800 1854
1801 /* clear the MAC interrupt status, assumes direct logical to physical mapping */ 1855 /* clear the MAC interrupt status, assumes direct logical to physical mapping */
1802 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); 1856 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 99933e4e48ff..26d8018c0a7c 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -3936,6 +3936,30 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
3936 return nesibdev; 3936 return nesibdev;
3937} 3937}
3938 3938
3939
3940/**
3941 * nes_handle_delayed_event
3942 */
3943static void nes_handle_delayed_event(unsigned long data)
3944{
3945 struct nes_vnic *nesvnic = (void *) data;
3946
3947 if (nesvnic->delayed_event != nesvnic->last_dispatched_event) {
3948 struct ib_event event;
3949
3950 event.device = &nesvnic->nesibdev->ibdev;
3951 if (!event.device)
3952 goto stop_timer;
3953 event.event = nesvnic->delayed_event;
3954 event.element.port_num = nesvnic->logical_port + 1;
3955 ib_dispatch_event(&event);
3956 }
3957
3958stop_timer:
3959 nesvnic->event_timer.function = NULL;
3960}
3961
3962
3939void nes_port_ibevent(struct nes_vnic *nesvnic) 3963void nes_port_ibevent(struct nes_vnic *nesvnic)
3940{ 3964{
3941 struct nes_ib_device *nesibdev = nesvnic->nesibdev; 3965 struct nes_ib_device *nesibdev = nesvnic->nesibdev;
@@ -3944,7 +3968,18 @@ void nes_port_ibevent(struct nes_vnic *nesvnic)
3944 event.device = &nesibdev->ibdev; 3968 event.device = &nesibdev->ibdev;
3945 event.element.port_num = nesvnic->logical_port + 1; 3969 event.element.port_num = nesvnic->logical_port + 1;
3946 event.event = nesdev->iw_status ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR; 3970 event.event = nesdev->iw_status ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
3947 ib_dispatch_event(&event); 3971
3972 if (!nesvnic->event_timer.function) {
3973 ib_dispatch_event(&event);
3974 nesvnic->last_dispatched_event = event.event;
3975 nesvnic->event_timer.function = nes_handle_delayed_event;
3976 nesvnic->event_timer.data = (unsigned long) nesvnic;
3977 nesvnic->event_timer.expires = jiffies + NES_EVENT_DELAY;
3978 add_timer(&nesvnic->event_timer);
3979 } else {
3980 mod_timer(&nesvnic->event_timer, jiffies + NES_EVENT_DELAY);
3981 }
3982 nesvnic->delayed_event = event.event;
3948} 3983}
3949 3984
3950 3985
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 70ecb949683e..83664ed2804f 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1132,15 +1132,12 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
1132 1132
1133 spin_lock_irqsave(&target->lock, flags); 1133 spin_lock_irqsave(&target->lock, flags);
1134 iu = __srp_get_tx_iu(target, SRP_IU_CMD); 1134 iu = __srp_get_tx_iu(target, SRP_IU_CMD);
1135 if (iu) {
1136 req = list_first_entry(&target->free_reqs, struct srp_request,
1137 list);
1138 list_del(&req->list);
1139 }
1140 spin_unlock_irqrestore(&target->lock, flags);
1141
1142 if (!iu) 1135 if (!iu)
1143 goto err; 1136 goto err_unlock;
1137
1138 req = list_first_entry(&target->free_reqs, struct srp_request, list);
1139 list_del(&req->list);
1140 spin_unlock_irqrestore(&target->lock, flags);
1144 1141
1145 dev = target->srp_host->srp_dev->dev; 1142 dev = target->srp_host->srp_dev->dev;
1146 ib_dma_sync_single_for_cpu(dev, iu->dma, srp_max_iu_len, 1143 ib_dma_sync_single_for_cpu(dev, iu->dma, srp_max_iu_len,
@@ -1185,6 +1182,8 @@ err_iu:
1185 1182
1186 spin_lock_irqsave(&target->lock, flags); 1183 spin_lock_irqsave(&target->lock, flags);
1187 list_add(&req->list, &target->free_reqs); 1184 list_add(&req->list, &target->free_reqs);
1185
1186err_unlock:
1188 spin_unlock_irqrestore(&target->lock, flags); 1187 spin_unlock_irqrestore(&target->lock, flags);
1189 1188
1190err: 1189err:
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index 68aaa42d0ced..32f947154c33 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -113,7 +113,7 @@ static void catas_reset(struct work_struct *work)
113void mlx4_start_catas_poll(struct mlx4_dev *dev) 113void mlx4_start_catas_poll(struct mlx4_dev *dev)
114{ 114{
115 struct mlx4_priv *priv = mlx4_priv(dev); 115 struct mlx4_priv *priv = mlx4_priv(dev);
116 unsigned long addr; 116 phys_addr_t addr;
117 117
118 INIT_LIST_HEAD(&priv->catas_err.list); 118 INIT_LIST_HEAD(&priv->catas_err.list);
119 init_timer(&priv->catas_err.timer); 119 init_timer(&priv->catas_err.timer);
@@ -124,8 +124,8 @@ void mlx4_start_catas_poll(struct mlx4_dev *dev)
124 124
125 priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4); 125 priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4);
126 if (!priv->catas_err.map) { 126 if (!priv->catas_err.map) {
127 mlx4_warn(dev, "Failed to map internal error buffer at 0x%lx\n", 127 mlx4_warn(dev, "Failed to map internal error buffer at 0x%llx\n",
128 addr); 128 (unsigned long long) addr);
129 return; 129 return;
130 } 130 }
131 131
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index f6e0d40cd876..1ff6ca6466ed 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -202,7 +202,8 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
202 if (mlx4_uar_alloc(dev, &mdev->priv_uar)) 202 if (mlx4_uar_alloc(dev, &mdev->priv_uar))
203 goto err_pd; 203 goto err_pd;
204 204
205 mdev->uar_map = ioremap(mdev->priv_uar.pfn << PAGE_SHIFT, PAGE_SIZE); 205 mdev->uar_map = ioremap((phys_addr_t) mdev->priv_uar.pfn << PAGE_SHIFT,
206 PAGE_SIZE);
206 if (!mdev->uar_map) 207 if (!mdev->uar_map)
207 goto err_uar; 208 goto err_uar;
208 spin_lock_init(&mdev->uar_lock); 209 spin_lock_init(&mdev->uar_lock);
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 782f11d8fa71..4ffdc18fcb8a 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -829,7 +829,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
829 goto err_uar_table_free; 829 goto err_uar_table_free;
830 } 830 }
831 831
832 priv->kar = ioremap(priv->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE); 832 priv->kar = ioremap((phys_addr_t) priv->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
833 if (!priv->kar) { 833 if (!priv->kar) {
834 mlx4_err(dev, "Couldn't map kernel access region, " 834 mlx4_err(dev, "Couldn't map kernel access region, "
835 "aborting.\n"); 835 "aborting.\n");
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index c4f88b7ef7b6..79cf42db2ea9 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -95,7 +95,8 @@ static int mlx4_MGID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
95 * entry in hash chain and *mgm holds end of hash chain. 95 * entry in hash chain and *mgm holds end of hash chain.
96 */ 96 */
97static int find_mgm(struct mlx4_dev *dev, 97static int find_mgm(struct mlx4_dev *dev,
98 u8 *gid, struct mlx4_cmd_mailbox *mgm_mailbox, 98 u8 *gid, enum mlx4_protocol protocol,
99 struct mlx4_cmd_mailbox *mgm_mailbox,
99 u16 *hash, int *prev, int *index) 100 u16 *hash, int *prev, int *index)
100{ 101{
101 struct mlx4_cmd_mailbox *mailbox; 102 struct mlx4_cmd_mailbox *mailbox;
@@ -134,7 +135,8 @@ static int find_mgm(struct mlx4_dev *dev,
134 return err; 135 return err;
135 } 136 }
136 137
137 if (!memcmp(mgm->gid, gid, 16)) 138 if (!memcmp(mgm->gid, gid, 16) &&
139 be32_to_cpu(mgm->members_count) >> 30 == protocol)
138 return err; 140 return err;
139 141
140 *prev = *index; 142 *prev = *index;
@@ -146,7 +148,7 @@ static int find_mgm(struct mlx4_dev *dev,
146} 148}
147 149
148int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 150int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
149 int block_mcast_loopback) 151 int block_mcast_loopback, enum mlx4_protocol protocol)
150{ 152{
151 struct mlx4_priv *priv = mlx4_priv(dev); 153 struct mlx4_priv *priv = mlx4_priv(dev);
152 struct mlx4_cmd_mailbox *mailbox; 154 struct mlx4_cmd_mailbox *mailbox;
@@ -165,7 +167,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
165 167
166 mutex_lock(&priv->mcg_table.mutex); 168 mutex_lock(&priv->mcg_table.mutex);
167 169
168 err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 170 err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
169 if (err) 171 if (err)
170 goto out; 172 goto out;
171 173
@@ -187,7 +189,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
187 memcpy(mgm->gid, gid, 16); 189 memcpy(mgm->gid, gid, 16);
188 } 190 }
189 191
190 members_count = be32_to_cpu(mgm->members_count); 192 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
191 if (members_count == MLX4_QP_PER_MGM) { 193 if (members_count == MLX4_QP_PER_MGM) {
192 mlx4_err(dev, "MGM at index %x is full.\n", index); 194 mlx4_err(dev, "MGM at index %x is full.\n", index);
193 err = -ENOMEM; 195 err = -ENOMEM;
@@ -207,7 +209,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
207 else 209 else
208 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 210 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);
209 211
210 mgm->members_count = cpu_to_be32(members_count); 212 mgm->members_count = cpu_to_be32(members_count | (u32) protocol << 30);
211 213
212 err = mlx4_WRITE_MCG(dev, index, mailbox); 214 err = mlx4_WRITE_MCG(dev, index, mailbox);
213 if (err) 215 if (err)
@@ -242,7 +244,8 @@ out:
242} 244}
243EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 245EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
244 246
245int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) 247int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
248 enum mlx4_protocol protocol)
246{ 249{
247 struct mlx4_priv *priv = mlx4_priv(dev); 250 struct mlx4_priv *priv = mlx4_priv(dev);
248 struct mlx4_cmd_mailbox *mailbox; 251 struct mlx4_cmd_mailbox *mailbox;
@@ -260,7 +263,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
260 263
261 mutex_lock(&priv->mcg_table.mutex); 264 mutex_lock(&priv->mcg_table.mutex);
262 265
263 err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 266 err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
264 if (err) 267 if (err)
265 goto out; 268 goto out;
266 269
@@ -270,7 +273,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
270 goto out; 273 goto out;
271 } 274 }
272 275
273 members_count = be32_to_cpu(mgm->members_count); 276 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
274 for (loc = -1, i = 0; i < members_count; ++i) 277 for (loc = -1, i = 0; i < members_count; ++i)
275 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) 278 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
276 loc = i; 279 loc = i;
@@ -282,7 +285,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
282 } 285 }
283 286
284 287
285 mgm->members_count = cpu_to_be32(--members_count); 288 mgm->members_count = cpu_to_be32(--members_count | (u32) protocol << 30);
286 mgm->qp[loc] = mgm->qp[i - 1]; 289 mgm->qp[loc] = mgm->qp[i - 1];
287 mgm->qp[i - 1] = 0; 290 mgm->qp[i - 1] = 0;
288 291
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index a7b15bc7648e..049214642036 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -144,6 +144,11 @@ enum {
144 MLX4_STAT_RATE_OFFSET = 5 144 MLX4_STAT_RATE_OFFSET = 5
145}; 145};
146 146
147enum mlx4_protocol {
148 MLX4_PROTOCOL_IB,
149 MLX4_PROTOCOL_EN,
150};
151
147enum { 152enum {
148 MLX4_MTT_FLAG_PRESENT = 1 153 MLX4_MTT_FLAG_PRESENT = 1
149}; 154};
@@ -500,8 +505,9 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
500int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); 505int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
501 506
502int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 507int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
503 int block_mcast_loopback); 508 int block_mcast_loopback, enum mlx4_protocol protocol);
504int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 509int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
510 enum mlx4_protocol protocol);
505 511
506int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index); 512int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index);
507void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index); 513void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index);
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index f407cd4bfb34..e1eebf78caba 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -34,6 +34,7 @@
34#define MLX4_DRIVER_H 34#define MLX4_DRIVER_H
35 35
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/mlx4/device.h>
37 38
38struct mlx4_dev; 39struct mlx4_dev;
39 40
@@ -44,11 +45,6 @@ enum mlx4_dev_event {
44 MLX4_DEV_EVENT_PORT_REINIT, 45 MLX4_DEV_EVENT_PORT_REINIT,
45}; 46};
46 47
47enum mlx4_protocol {
48 MLX4_PROTOCOL_IB,
49 MLX4_PROTOCOL_EN,
50};
51
52struct mlx4_interface { 48struct mlx4_interface {
53 void * (*add) (struct mlx4_dev *dev); 49 void * (*add) (struct mlx4_dev *dev);
54 void (*remove)(struct mlx4_dev *dev, void *context); 50 void (*remove)(struct mlx4_dev *dev, void *context);