Author: hselasky
Date: Thu Oct  2 10:46:12 2014
New Revision: 272407
URL: https://svnweb.freebsd.org/changeset/base/272407

Log:
  MFC r272027:
  
  Hardware driver update from Mellanox Technologies, including:
   - improved performance
   - better stability
   - new features
   - bugfixes
  
  Supported HCAs:
   - ConnectX-2
   - ConnectX-3
   - ConnectX-3 Pro
  
  NOTE:
    - TSO feature needs r271946, which is not yet merged.
  
  Sponsored by: Mellanox Technologies
  Approved by:  re, glebius

Added:
  stable/10/sys/ofed/drivers/net/mlx4/mlx4_stats.h
     - copied unchanged from r272027, 
head/sys/ofed/drivers/net/mlx4/mlx4_stats.h
  stable/10/sys/ofed/drivers/net/mlx4/utils.c
     - copied unchanged from r272027, head/sys/ofed/drivers/net/mlx4/utils.c
  stable/10/sys/ofed/drivers/net/mlx4/utils.h
     - copied unchanged from r272027, head/sys/ofed/drivers/net/mlx4/utils.h
Modified:
  stable/10/contrib/ofed/libibverbs/examples/asyncwatch.c
  stable/10/contrib/ofed/libibverbs/examples/device_list.c
  stable/10/contrib/ofed/libibverbs/examples/devinfo.c
  stable/10/contrib/ofed/libmlx4/src/mlx4-abi.h
  stable/10/sys/conf/files
  stable/10/sys/modules/mlx4/Makefile
  stable/10/sys/modules/mlxen/Makefile
  stable/10/sys/ofed/drivers/infiniband/hw/mlx4/mad.c
  stable/10/sys/ofed/drivers/infiniband/hw/mlx4/main.c
  stable/10/sys/ofed/drivers/infiniband/hw/mlx4/qp.c
  stable/10/sys/ofed/drivers/net/mlx4/alloc.c
  stable/10/sys/ofed/drivers/net/mlx4/catas.c
  stable/10/sys/ofed/drivers/net/mlx4/cmd.c
  stable/10/sys/ofed/drivers/net/mlx4/cq.c
  stable/10/sys/ofed/drivers/net/mlx4/en_cq.c
  stable/10/sys/ofed/drivers/net/mlx4/en_ethtool.c
  stable/10/sys/ofed/drivers/net/mlx4/en_main.c
  stable/10/sys/ofed/drivers/net/mlx4/en_netdev.c
  stable/10/sys/ofed/drivers/net/mlx4/en_port.c
  stable/10/sys/ofed/drivers/net/mlx4/en_port.h
  stable/10/sys/ofed/drivers/net/mlx4/en_resources.c
  stable/10/sys/ofed/drivers/net/mlx4/en_rx.c
  stable/10/sys/ofed/drivers/net/mlx4/en_selftest.c
  stable/10/sys/ofed/drivers/net/mlx4/en_tx.c
  stable/10/sys/ofed/drivers/net/mlx4/eq.c
  stable/10/sys/ofed/drivers/net/mlx4/fw.c
  stable/10/sys/ofed/drivers/net/mlx4/fw.h
  stable/10/sys/ofed/drivers/net/mlx4/icm.c
  stable/10/sys/ofed/drivers/net/mlx4/icm.h
  stable/10/sys/ofed/drivers/net/mlx4/intf.c
  stable/10/sys/ofed/drivers/net/mlx4/main.c
  stable/10/sys/ofed/drivers/net/mlx4/mcg.c
  stable/10/sys/ofed/drivers/net/mlx4/mlx4.h
  stable/10/sys/ofed/drivers/net/mlx4/mlx4_en.h
  stable/10/sys/ofed/drivers/net/mlx4/mr.c
  stable/10/sys/ofed/drivers/net/mlx4/pd.c
  stable/10/sys/ofed/drivers/net/mlx4/port.c
  stable/10/sys/ofed/drivers/net/mlx4/profile.c
  stable/10/sys/ofed/drivers/net/mlx4/qp.c
  stable/10/sys/ofed/drivers/net/mlx4/reset.c
  stable/10/sys/ofed/drivers/net/mlx4/resource_tracker.c
  stable/10/sys/ofed/drivers/net/mlx4/sense.c
  stable/10/sys/ofed/drivers/net/mlx4/srq.c
  stable/10/sys/ofed/drivers/net/mlx4/sys_tune.c
  stable/10/sys/ofed/include/linux/mlx4/cmd.h
  stable/10/sys/ofed/include/linux/mlx4/cq.h
  stable/10/sys/ofed/include/linux/mlx4/device.h
  stable/10/sys/ofed/include/linux/mlx4/driver.h
  stable/10/sys/ofed/include/linux/mlx4/qp.h
  stable/10/sys/ofed/include/linux/mlx4/srq.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/contrib/ofed/libibverbs/examples/asyncwatch.c
==============================================================================
--- stable/10/contrib/ofed/libibverbs/examples/asyncwatch.c     Thu Oct  2 
10:39:07 2014        (r272406)
+++ stable/10/contrib/ofed/libibverbs/examples/asyncwatch.c     Thu Oct  2 
10:46:12 2014        (r272407)
@@ -35,8 +35,6 @@
 #endif /* HAVE_CONFIG_H */
 
 #include <stdio.h>
-#include <endian.h>
-#include <byteswap.h>
 
 #include <infiniband/verbs.h>
 

Modified: stable/10/contrib/ofed/libibverbs/examples/device_list.c
==============================================================================
--- stable/10/contrib/ofed/libibverbs/examples/device_list.c    Thu Oct  2 
10:39:07 2014        (r272406)
+++ stable/10/contrib/ofed/libibverbs/examples/device_list.c    Thu Oct  2 
10:46:12 2014        (r272407)
@@ -36,9 +36,6 @@
 
 #include <stdio.h>
 
-#include <endian.h>
-#include <byteswap.h>
-
 #include <infiniband/verbs.h>
 #include <infiniband/arch.h>
 

Modified: stable/10/contrib/ofed/libibverbs/examples/devinfo.c
==============================================================================
--- stable/10/contrib/ofed/libibverbs/examples/devinfo.c        Thu Oct  2 
10:39:07 2014        (r272406)
+++ stable/10/contrib/ofed/libibverbs/examples/devinfo.c        Thu Oct  2 
10:46:12 2014        (r272407)
@@ -41,8 +41,6 @@
 #include <string.h>
 #include <getopt.h>
 #include <netinet/in.h>
-#include <endian.h>
-#include <byteswap.h>
 
 #include <infiniband/verbs.h>
 #include <infiniband/driver.h>

Modified: stable/10/contrib/ofed/libmlx4/src/mlx4-abi.h
==============================================================================
--- stable/10/contrib/ofed/libmlx4/src/mlx4-abi.h       Thu Oct  2 10:39:07 
2014        (r272406)
+++ stable/10/contrib/ofed/libmlx4/src/mlx4-abi.h       Thu Oct  2 10:46:12 
2014        (r272407)
@@ -36,7 +36,7 @@
 #include <infiniband/kern-abi.h>
 
 #define MLX4_UVERBS_MIN_ABI_VERSION    2
-#define MLX4_UVERBS_MAX_ABI_VERSION    3
+#define MLX4_UVERBS_MAX_ABI_VERSION    4
 
 struct mlx4_alloc_ucontext_resp {
        struct ibv_get_context_resp     ibv_resp;

Modified: stable/10/sys/conf/files
==============================================================================
--- stable/10/sys/conf/files    Thu Oct  2 10:39:07 2014        (r272406)
+++ stable/10/sys/conf/files    Thu Oct  2 10:46:12 2014        (r272407)
@@ -3745,7 +3745,7 @@ ofed/drivers/net/mlx4/sys_tune.c          option
 ofed/drivers/net/mlx4/en_cq.c                  optional mlxen          \
        no-depend obj-prefix "mlx4_"                                    \
        compile-with "${OFED_C_NOIMP} -I$S/ofed/drivers/net/mlx4/"
-ofed/drivers/net/mlx4/en_frag.c                        optional mlxen          
\
+ofed/drivers/net/mlx4/utils.c                  optional mlxen          \
        no-depend obj-prefix "mlx4_"                                    \
        compile-with "${OFED_C_NOIMP} -I$S/ofed/drivers/net/mlx4/"
 ofed/drivers/net/mlx4/en_main.c                        optional mlxen          
\

Modified: stable/10/sys/modules/mlx4/Makefile
==============================================================================
--- stable/10/sys/modules/mlx4/Makefile Thu Oct  2 10:39:07 2014        
(r272406)
+++ stable/10/sys/modules/mlx4/Makefile Thu Oct  2 10:46:12 2014        
(r272407)
@@ -5,7 +5,7 @@
 
 .PATH:  ${.CURDIR}/../../ofed/include/linux
 KMOD    = mlx4
-SRCS    = device_if.h bus_if.h pci_if.h vnode_if.h
+SRCS    = device_if.h bus_if.h pci_if.h vnode_if.h opt_inet.h opt_inet6.h
 SRCS+= alloc.c catas.c cmd.c cq.c eq.c fw.c icm.c intf.c main.c mcg.c mr.c 
linux_compat.c linux_radix.c        linux_idr.c
 SRCS+= pd.c port.c profile.c qp.c reset.c sense.c srq.c resource_tracker.c 
sys_tune.c
 

Modified: stable/10/sys/modules/mlxen/Makefile
==============================================================================
--- stable/10/sys/modules/mlxen/Makefile        Thu Oct  2 10:39:07 2014        
(r272406)
+++ stable/10/sys/modules/mlxen/Makefile        Thu Oct  2 10:46:12 2014        
(r272407)
@@ -5,8 +5,8 @@
 
 KMOD    = mlxen
 SRCS    = device_if.h bus_if.h pci_if.h vnode_if.h
-SRCS   += en_cq.c en_frag.c en_main.c en_netdev.c en_port.c en_resources.c
-SRCS   += en_rx.c en_tx.c
+SRCS   += en_cq.c en_main.c en_netdev.c en_port.c en_resources.c
+SRCS   += en_rx.c en_tx.c utils.c
 SRCS   += opt_inet.h opt_inet6.h
 CFLAGS+= -I${.CURDIR}/../../ofed/drivers/net/mlx4
 CFLAGS+= -I${.CURDIR}/../../ofed/include/

Modified: stable/10/sys/ofed/drivers/infiniband/hw/mlx4/mad.c
==============================================================================
--- stable/10/sys/ofed/drivers/infiniband/hw/mlx4/mad.c Thu Oct  2 10:39:07 
2014        (r272406)
+++ stable/10/sys/ofed/drivers/infiniband/hw/mlx4/mad.c Thu Oct  2 10:46:12 
2014        (r272407)
@@ -1081,7 +1081,7 @@ static void handle_lid_change_event(stru
 
        if (mlx4_is_master(dev->dev) && !dev->sriov.is_going_down)
                mlx4_gen_slaves_port_mgt_ev(dev->dev, port_num,
-                                           MLX4_EQ_PORT_INFO_LID_CHANGE_MASK);
+                                           MLX4_EQ_PORT_INFO_LID_CHANGE_MASK, 
0, 0);
 }
 
 static void handle_client_rereg_event(struct mlx4_ib_dev *dev, u8 port_num)
@@ -1093,7 +1093,7 @@ static void handle_client_rereg_event(st
                if (!dev->sriov.is_going_down) {
                        mlx4_ib_mcg_port_cleanup(&dev->sriov.demux[port_num - 
1], 0);
                        mlx4_gen_slaves_port_mgt_ev(dev->dev, port_num,
-                                                   
MLX4_EQ_PORT_INFO_CLIENT_REREG_MASK);
+                                                   
MLX4_EQ_PORT_INFO_CLIENT_REREG_MASK, 0, 0);
                }
        }
        mlx4_ib_dispatch_event(dev, port_num, IB_EVENT_CLIENT_REREGISTER);
@@ -1191,7 +1191,7 @@ void handle_port_mgmt_change_event(struc
                        /*if master, notify all slaves*/
                        if (mlx4_is_master(dev->dev))
                                mlx4_gen_slaves_port_mgt_ev(dev->dev, port,
-                                                           
MLX4_EQ_PORT_INFO_GID_PFX_CHANGE_MASK);
+                                                           
MLX4_EQ_PORT_INFO_GID_PFX_CHANGE_MASK, 0, 0);
                }
 
                if (changed_attr & MLX4_EQ_PORT_INFO_CLIENT_REREG_MASK)

Modified: stable/10/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- stable/10/sys/ofed/drivers/infiniband/hw/mlx4/main.c        Thu Oct  2 
10:39:07 2014        (r272406)
+++ stable/10/sys/ofed/drivers/infiniband/hw/mlx4/main.c        Thu Oct  2 
10:46:12 2014        (r272407)
@@ -1005,7 +1005,7 @@ static int flow_spec_to_net_rule(struct 
        case IB_FLOW_IB_UC:
                spec_l2->id = MLX4_NET_TRANS_RULE_ID_IB;
                if(flow_spec->l2_id.ib_uc.qpn) {
-                       spec_l2->ib.r_u_qpn = 
cpu_to_be32(flow_spec->l2_id.ib_uc.qpn);
+                       spec_l2->ib.l3_qpn = 
cpu_to_be32(flow_spec->l2_id.ib_uc.qpn);
                        spec_l2->ib.qpn_msk = cpu_to_be32(0xffffff);
                     }
                break;
@@ -2013,7 +2013,7 @@ static void *mlx4_ib_add(struct mlx4_dev
        for (i = 0; i < ibdev->num_ports; ++i) {
                if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
                                                IB_LINK_LAYER_ETHERNET) {
-                       err = mlx4_counter_alloc(ibdev->dev, 
&ibdev->counters[i]);
+                       err = mlx4_counter_alloc(ibdev->dev, i + 1, 
&ibdev->counters[i]);
                        if (err)
                                ibdev->counters[i] = -1;
                } else
@@ -2112,7 +2112,7 @@ err_steer_qp_release:
 err_counter:
        for (; i; --i)
                if (ibdev->counters[i - 1] != -1)
-                       mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]);
+                       mlx4_counter_free(ibdev->dev, i, ibdev->counters[i - 
1]);
 
 err_map:
        iounmap(ibdev->priv_uar.map);
@@ -2200,7 +2200,7 @@ static void mlx4_ib_remove(struct mlx4_d
        iounmap(ibdev->priv_uar.map);
        for (p = 0; p < ibdev->num_ports; ++p)
                if (ibdev->counters[p] != -1)
-                       mlx4_counter_free(ibdev->dev, ibdev->counters[p]);
+                       mlx4_counter_free(ibdev->dev, p + 1, 
ibdev->counters[p]);
        mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
                mlx4_CLOSE_PORT(dev, p);
 

Modified: stable/10/sys/ofed/drivers/infiniband/hw/mlx4/qp.c
==============================================================================
--- stable/10/sys/ofed/drivers/infiniband/hw/mlx4/qp.c  Thu Oct  2 10:39:07 
2014        (r272406)
+++ stable/10/sys/ofed/drivers/infiniband/hw/mlx4/qp.c  Thu Oct  2 10:46:12 
2014        (r272407)
@@ -2679,10 +2679,10 @@ static int mlx4_wq_overflow(struct mlx4_
 
 static __be32 convert_access(int acc)
 {
-       return (acc & IB_ACCESS_REMOTE_ATOMIC ? 
cpu_to_be32(MLX4_WQE_FMR_PERM_ATOMIC)       : 0) |
-              (acc & IB_ACCESS_REMOTE_WRITE  ? 
cpu_to_be32(MLX4_WQE_FMR_PERM_REMOTE_WRITE) : 0) |
-              (acc & IB_ACCESS_REMOTE_READ   ? 
cpu_to_be32(MLX4_WQE_FMR_PERM_REMOTE_READ)  : 0) |
-              (acc & IB_ACCESS_LOCAL_WRITE   ? 
cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_WRITE)  : 0) |
+       return (acc & IB_ACCESS_REMOTE_ATOMIC ? 
cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_ATOMIC)          : 0) |
+              (acc & IB_ACCESS_REMOTE_WRITE  ? 
cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_WRITE)    : 0) |
+              (acc & IB_ACCESS_REMOTE_READ   ? 
cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_READ)     : 0) |
+              (acc & IB_ACCESS_LOCAL_WRITE   ? 
cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_WRITE)              : 0) |
                cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_READ);
 }
 
@@ -2709,10 +2709,12 @@ static void set_fmr_seg(struct mlx4_wqe_
 
 static void set_local_inv_seg(struct mlx4_wqe_local_inval_seg *iseg, u32 rkey)
 {
-       iseg->flags     = 0;
-       iseg->mem_key   = cpu_to_be32(rkey);
-       iseg->guest_id  = 0;
-       iseg->pa        = 0;
+       iseg->mem_key = cpu_to_be32(rkey);
+
+       iseg->reserved1    = 0;
+       iseg->reserved2    = 0;
+       iseg->reserved3[0] = 0;
+       iseg->reserved3[1] = 0;
 }
 
 static __always_inline void set_raddr_seg(struct mlx4_wqe_raddr_seg *rseg,

Modified: stable/10/sys/ofed/drivers/net/mlx4/alloc.c
==============================================================================
--- stable/10/sys/ofed/drivers/net/mlx4/alloc.c Thu Oct  2 10:39:07 2014        
(r272406)
+++ stable/10/sys/ofed/drivers/net/mlx4/alloc.c Thu Oct  2 10:46:12 2014        
(r272407)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
- * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2007, 2008, 2014 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -34,7 +34,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
-#include <linux/bitops.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
 
@@ -70,9 +70,9 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap
        return obj;
 }
 
-void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
+void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj, int use_rr)
 {
-       mlx4_bitmap_free_range(bitmap, obj, 1);
+       mlx4_bitmap_free_range(bitmap, obj, 1, use_rr);
 }
 
 static unsigned long find_aligned_range(unsigned long *bitmap,
@@ -148,11 +148,17 @@ u32 mlx4_bitmap_avail(struct mlx4_bitmap
        return bitmap->avail;
 }
 
-void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
+void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt,
+                           int use_rr)
 {
        obj &= bitmap->max + bitmap->reserved_top - 1;
 
        spin_lock(&bitmap->lock);
+       if (!use_rr) {
+               bitmap->last = min(bitmap->last, obj);
+               bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+                               & bitmap->mask;
+       }
        bitmap_clear(bitmap->table, obj, cnt);
        bitmap->avail += cnt;
        spin_unlock(&bitmap->lock);

Modified: stable/10/sys/ofed/drivers/net/mlx4/catas.c
==============================================================================
--- stable/10/sys/ofed/drivers/net/mlx4/catas.c Thu Oct  2 10:39:07 2014        
(r272406)
+++ stable/10/sys/ofed/drivers/net/mlx4/catas.c Thu Oct  2 10:46:12 2014        
(r272407)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
- * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2007, 2008, 2014 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -34,10 +34,11 @@
 #include <linux/workqueue.h>
 #include <linux/module.h>
 
-#include "mlx4.h"
+#include <asm/byteorder.h>
 
-#define MLX4_CATAS_POLL_INTERVAL        (5 * HZ)
+#include "mlx4.h"
 
+#define        MLX4_CATAS_POLL_INTERVAL        (5 * HZ)
 
 static DEFINE_SPINLOCK(catas_lock);
 
@@ -156,11 +157,13 @@ void mlx4_stop_catas_poll(struct mlx4_de
 
        del_timer_sync(&priv->catas_err.timer);
 
-       if (priv->catas_err.map)
+       if (priv->catas_err.map) {
                iounmap(priv->catas_err.map);
+               priv->catas_err.map = NULL;
+       }
 
        spin_lock_irq(&catas_lock);
-       list_del(&priv->catas_err.list);
+       list_del_init(&priv->catas_err.list);
        spin_unlock_irq(&catas_lock);
 }
 

Modified: stable/10/sys/ofed/drivers/net/mlx4/cmd.c
==============================================================================
--- stable/10/sys/ofed/drivers/net/mlx4/cmd.c   Thu Oct  2 10:39:07 2014        
(r272406)
+++ stable/10/sys/ofed/drivers/net/mlx4/cmd.c   Thu Oct  2 10:46:12 2014        
(r272407)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights 
reserved.
+ * Copyright (c) 2005, 2006, 2007, 2008, 2014 Mellanox Technologies. All 
rights reserved.
  * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -34,14 +34,17 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/mlx4/device.h>
 #include <linux/semaphore.h>
 #include <rdma/ib_smi.h>
 
 #include <asm/io.h>
+#include <linux/ktime.h>
 
 #include "mlx4.h"
 #include "fw.h"
@@ -110,6 +113,14 @@ enum {
        GO_BIT_TIMEOUT_MSECS    = 10000
 };
 
+enum mlx4_vlan_transition {
+       MLX4_VLAN_TRANSITION_VST_VST = 0,
+       MLX4_VLAN_TRANSITION_VST_VGT = 1,
+       MLX4_VLAN_TRANSITION_VGT_VST = 2,
+       MLX4_VLAN_TRANSITION_VGT_VGT = 3,
+};
+
+
 struct mlx4_cmd_context {
        struct completion       done;
        int                     result;
@@ -152,6 +163,131 @@ static int mlx4_status_to_errno(u8 statu
        return trans_table[status];
 }
 
+static const char *cmd_to_str(u16 cmd)
+{
+       switch (cmd) {
+       case MLX4_CMD_SYS_EN:           return "SYS_EN";
+       case MLX4_CMD_SYS_DIS:          return "SYS_DIS";
+       case MLX4_CMD_MAP_FA:           return "MAP_FA";
+       case MLX4_CMD_UNMAP_FA:         return "UNMAP_FA";
+       case MLX4_CMD_RUN_FW:           return "RUN_FW";
+       case MLX4_CMD_MOD_STAT_CFG:     return "MOD_STAT_CFG";
+       case MLX4_CMD_QUERY_DEV_CAP:    return "QUERY_DEV_CAP";
+       case MLX4_CMD_QUERY_FW:         return "QUERY_FW";
+       case MLX4_CMD_ENABLE_LAM:       return "ENABLE_LAM";
+       case MLX4_CMD_DISABLE_LAM:      return "DISABLE_LAM";
+       case MLX4_CMD_QUERY_DDR:        return "QUERY_DDR";
+       case MLX4_CMD_QUERY_ADAPTER:    return "QUERY_ADAPTER";
+       case MLX4_CMD_INIT_HCA:         return "INIT_HCA";
+       case MLX4_CMD_CLOSE_HCA:        return "CLOSE_HCA";
+       case MLX4_CMD_INIT_PORT:        return "INIT_PORT";
+       case MLX4_CMD_CLOSE_PORT:       return "CLOSE_PORT";
+       case MLX4_CMD_QUERY_HCA:        return "QUERY_HCA";
+       case MLX4_CMD_QUERY_PORT:       return "QUERY_PORT";
+       case MLX4_CMD_SENSE_PORT:       return "SENSE_PORT";
+       case MLX4_CMD_HW_HEALTH_CHECK:  return "HW_HEALTH_CHECK";
+       case MLX4_CMD_SET_PORT:         return "SET_PORT";
+       case MLX4_CMD_SET_NODE:         return "SET_NODE";
+       case MLX4_CMD_QUERY_FUNC:       return "QUERY_FUNC";
+       case MLX4_CMD_MAP_ICM:          return "MAP_ICM";
+       case MLX4_CMD_UNMAP_ICM:        return "UNMAP_ICM";
+       case MLX4_CMD_MAP_ICM_AUX:      return "MAP_ICM_AUX";
+       case MLX4_CMD_UNMAP_ICM_AUX:    return "UNMAP_ICM_AUX";
+       case MLX4_CMD_SET_ICM_SIZE:     return "SET_ICM_SIZE";
+               /*master notify fw on finish for slave's flr*/
+       case MLX4_CMD_INFORM_FLR_DONE:  return "INFORM_FLR_DONE";
+       case MLX4_CMD_GET_OP_REQ:       return "GET_OP_REQ";
+
+               /* TPT commands */
+       case MLX4_CMD_SW2HW_MPT:        return "SW2HW_MPT";
+       case MLX4_CMD_QUERY_MPT:        return "QUERY_MPT";
+       case MLX4_CMD_HW2SW_MPT:        return "HW2SW_MPT";
+       case MLX4_CMD_READ_MTT:         return "READ_MTT";
+       case MLX4_CMD_WRITE_MTT:        return "WRITE_MTT";
+       case MLX4_CMD_SYNC_TPT:         return "SYNC_TPT";
+
+               /* EQ commands */
+       case MLX4_CMD_MAP_EQ:           return "MAP_EQ";
+       case MLX4_CMD_SW2HW_EQ:         return "SW2HW_EQ";
+       case MLX4_CMD_HW2SW_EQ:         return "HW2SW_EQ";
+       case MLX4_CMD_QUERY_EQ:         return "QUERY_EQ";
+
+               /* CQ commands */
+       case MLX4_CMD_SW2HW_CQ:         return "SW2HW_CQ";
+       case MLX4_CMD_HW2SW_CQ:         return "HW2SW_CQ";
+       case MLX4_CMD_QUERY_CQ:         return "QUERY_CQ:";
+       case MLX4_CMD_MODIFY_CQ:        return "MODIFY_CQ:";
+
+               /* SRQ commands */
+       case MLX4_CMD_SW2HW_SRQ:        return "SW2HW_SRQ";
+       case MLX4_CMD_HW2SW_SRQ:        return "HW2SW_SRQ";
+       case MLX4_CMD_QUERY_SRQ:        return "QUERY_SRQ";
+       case MLX4_CMD_ARM_SRQ:          return "ARM_SRQ";
+
+               /* QP/EE commands */
+       case MLX4_CMD_RST2INIT_QP:      return "RST2INIT_QP";
+       case MLX4_CMD_INIT2RTR_QP:      return "INIT2RTR_QP";
+       case MLX4_CMD_RTR2RTS_QP:       return "RTR2RTS_QP";
+       case MLX4_CMD_RTS2RTS_QP:       return "RTS2RTS_QP";
+       case MLX4_CMD_SQERR2RTS_QP:     return "SQERR2RTS_QP";
+       case MLX4_CMD_2ERR_QP:          return "2ERR_QP";
+       case MLX4_CMD_RTS2SQD_QP:       return "RTS2SQD_QP";
+       case MLX4_CMD_SQD2SQD_QP:       return "SQD2SQD_QP";
+       case MLX4_CMD_SQD2RTS_QP:       return "SQD2RTS_QP";
+       case MLX4_CMD_2RST_QP:          return "2RST_QP";
+       case MLX4_CMD_QUERY_QP:         return "QUERY_QP";
+       case MLX4_CMD_INIT2INIT_QP:     return "INIT2INIT_QP";
+       case MLX4_CMD_SUSPEND_QP:       return "SUSPEND_QP";
+       case MLX4_CMD_UNSUSPEND_QP:     return "UNSUSPEND_QP";
+               /* special QP and management commands */
+       case MLX4_CMD_CONF_SPECIAL_QP:  return "CONF_SPECIAL_QP";
+       case MLX4_CMD_MAD_IFC:          return "MAD_IFC";
+
+               /* multicast commands */
+       case MLX4_CMD_READ_MCG:         return "READ_MCG";
+       case MLX4_CMD_WRITE_MCG:        return "WRITE_MCG";
+       case MLX4_CMD_MGID_HASH:        return "MGID_HASH";
+
+               /* miscellaneous commands */
+       case MLX4_CMD_DIAG_RPRT:        return "DIAG_RPRT";
+       case MLX4_CMD_NOP:              return "NOP";
+       case MLX4_CMD_ACCESS_MEM:       return "ACCESS_MEM";
+       case MLX4_CMD_SET_VEP:          return "SET_VEP";
+
+               /* Ethernet specific commands */
+       case MLX4_CMD_SET_VLAN_FLTR:    return "SET_VLAN_FLTR";
+       case MLX4_CMD_SET_MCAST_FLTR:   return "SET_MCAST_FLTR";
+       case MLX4_CMD_DUMP_ETH_STATS:   return "DUMP_ETH_STATS";
+
+               /* Communication channel commands */
+       case MLX4_CMD_ARM_COMM_CHANNEL: return "ARM_COMM_CHANNEL";
+       case MLX4_CMD_GEN_EQE:          return "GEN_EQE";
+
+               /* virtual commands */
+       case MLX4_CMD_ALLOC_RES:        return "ALLOC_RES";
+       case MLX4_CMD_FREE_RES:         return "FREE_RES";
+       case MLX4_CMD_MCAST_ATTACH:     return "MCAST_ATTACH";
+       case MLX4_CMD_UCAST_ATTACH:     return "UCAST_ATTACH";
+       case MLX4_CMD_PROMISC:          return "PROMISC";
+       case MLX4_CMD_QUERY_FUNC_CAP:   return "QUERY_FUNC_CAP";
+       case MLX4_CMD_QP_ATTACH:        return "QP_ATTACH";
+
+               /* debug commands */
+       case MLX4_CMD_QUERY_DEBUG_MSG:  return "QUERY_DEBUG_MSG";
+       case MLX4_CMD_SET_DEBUG_MSG:    return "SET_DEBUG_MSG";
+
+               /* statistics commands */
+       case MLX4_CMD_QUERY_IF_STAT:    return "QUERY_IF_STAT";
+       case MLX4_CMD_SET_IF_STAT:      return "SET_IF_STAT";
+
+               /* register/delete flow steering network rules */
+       case MLX4_QP_FLOW_STEERING_ATTACH:      return 
"QP_FLOW_STEERING_ATTACH";
+       case MLX4_QP_FLOW_STEERING_DETACH:      return 
"QP_FLOW_STEERING_DETACH";
+       case MLX4_FLOW_STEERING_IB_UC_QP_RANGE: return 
"FLOW_STEERING_IB_UC_QP_RANGE";
+       default: return "OTHER";
+       }
+}
+
 static u8 mlx4_errno_to_status(int errno)
 {
        switch (errno) {
@@ -244,6 +380,17 @@ static int mlx4_comm_cmd_wait(struct mlx
 
        down(&cmd->event_sem);
 
+       end = msecs_to_jiffies(timeout) + jiffies;
+       while (comm_pending(dev) && time_before(jiffies, end))
+               cond_resched();
+       if (comm_pending(dev)) {
+               mlx4_warn(dev, "mlx4_comm_cmd_wait: Comm channel "
+                         "is not idle. My toggle is %d (op: 0x%x)\n",
+                         mlx4_priv(dev)->cmd.comm_toggle, op);
+               up(&cmd->event_sem);
+               return -EAGAIN;
+       }
+
        spin_lock(&cmd->context_lock);
        BUG_ON(cmd->free_head < 0);
        context = &cmd->context[cmd->free_head];
@@ -255,12 +402,8 @@ static int mlx4_comm_cmd_wait(struct mlx
 
        mlx4_comm_cmd_post(dev, op, param);
 
-       if (!wait_for_completion_timeout(&context->done,
-                                        msecs_to_jiffies(timeout))) {
-               mlx4_warn(dev, "communication channel command 0x%x timed 
out\n", op);
-               err = -EBUSY;
-               goto out;
-       }
+       /* In slave, wait unconditionally for completion */
+       wait_for_completion(&context->done);
 
        err = context->result;
        if (err && context->fw_status != CMD_STAT_MULTI_FUNC_REQ) {
@@ -309,14 +452,29 @@ static int cmd_pending(struct mlx4_dev *
                 !!(status & swab32(1 << HCR_T_BIT)));
 }
 
-static int mlx4_cmd_post(struct mlx4_dev *dev, u64 in_param, u64 out_param,
-                        u32 in_modifier, u8 op_modifier, u16 op, u16 token,
-                        int event)
+static int get_status(struct mlx4_dev *dev, u32 *status, int *go_bit,
+                     int *t_bit)
+{
+       if (pci_channel_offline(dev->pdev))
+               return -EIO;
+
+       *status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET);
+       *t_bit = !!(*status & swab32(1 << HCR_T_BIT));
+       *go_bit = !!(*status & swab32(1 << HCR_GO_BIT));
+
+       return 0;
+}
+
+static int mlx4_cmd_post(struct mlx4_dev *dev, struct timespec *ts1,
+                        u64 in_param, u64 out_param, u32 in_modifier,
+                        u8 op_modifier, u16 op, u16 token, int event)
 {
        struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd;
        u32 __iomem *hcr = cmd->hcr;
        int ret = -EAGAIN;
        unsigned long end;
+       int err, go_bit = 0, t_bit = 0;
+       u32 status = 0;
 
        mutex_lock(&cmd->hcr_mutex);
 
@@ -363,6 +521,9 @@ static int mlx4_cmd_post(struct mlx4_dev
        __raw_writel((__force u32) cpu_to_be32(out_param & 0xfffffffful), hcr + 
4);
        __raw_writel((__force u32) cpu_to_be32(token << 16),              hcr + 
5);
 
+       if (ts1)
+               ktime_get_ts(ts1);
+
        /* __raw_writel may not order writes. */
        wmb();
 
@@ -383,6 +544,15 @@ static int mlx4_cmd_post(struct mlx4_dev
        ret = 0;
 
 out:
+       if (ret) {
+               err = get_status(dev, &status, &go_bit, &t_bit);
+               mlx4_warn(dev, "Could not post command %s (0x%x): ret=%d, "
+                         "in_param=0x%llx, in_mod=0x%x, op_mod=0x%x, "
+                         "get_status err=%d, status_reg=0x%x, go_bit=%d, "
+                         "t_bit=%d, toggle=0x%x\n", cmd_to_str(op), op, ret,
+                         (unsigned long long) in_param, in_modifier, 
op_modifier, err, status,
+                         go_bit, t_bit, cmd->toggle);
+       }
        mutex_unlock(&cmd->hcr_mutex);
        return ret;
 }
@@ -439,7 +609,7 @@ static int mlx4_slave_cmd(struct mlx4_de
                        ret = mlx4_status_to_errno(vhcr->status);
                } else
                        mlx4_err(dev, "failed execution of VHCR_POST command"
-                                "opcode 0x%x\n", op);
+                                "opcode %s (0x%x)\n", cmd_to_str(op), op);
        }
 
        mutex_unlock(&priv->cmd.slave_cmd_mutex);
@@ -467,7 +637,7 @@ static int mlx4_cmd_poll(struct mlx4_dev
                goto out;
        }
 
-       err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0,
+       err = mlx4_cmd_post(dev, NULL, in_param, out_param ? *out_param : 0,
                            in_modifier, op_modifier, op, CMD_POLL_TOKEN, 0);
        if (err)
                goto out;
@@ -487,7 +657,8 @@ static int mlx4_cmd_poll(struct mlx4_dev
        }
 
        if (cmd_pending(dev)) {
-               mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n", 
op);
+               mlx4_warn(dev, "command %s (0x%x) timed out (go bit not 
cleared)\n",
+                         cmd_to_str(op), op);
                err = -ETIMEDOUT;
                goto out;
        }
@@ -502,8 +673,8 @@ static int mlx4_cmd_poll(struct mlx4_dev
                           __raw_readl(hcr + HCR_STATUS_OFFSET)) >> 24;
        err = mlx4_status_to_errno(stat);
        if (err)
-               mlx4_err(dev, "command 0x%x failed: fw status = 0x%x\n",
-                        op, stat);
+               mlx4_err(dev, "command %s (0x%x) failed: fw status = 0x%x\n",
+                        cmd_to_str(op), op, stat);
 
 out:
        up(&priv->cmd.poll_sem);
@@ -527,19 +698,6 @@ void mlx4_cmd_event(struct mlx4_dev *dev
        complete(&context->done);
 }
 
-static int get_status(struct mlx4_dev *dev, u32 *status, int *go_bit,
-                     int *t_bit)
-{
-       if (pci_channel_offline(dev->pdev))
-               return -EIO;
-
-       *status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET);
-       *t_bit = !!(*status & swab32(1 << HCR_T_BIT));
-       *go_bit = !!(*status & swab32(1 << HCR_GO_BIT));
-
-       return 0;
-}
-
 static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
                         int out_is_imm, u32 in_modifier, u8 op_modifier,
                         u16 op, unsigned long timeout)
@@ -549,6 +707,12 @@ static int mlx4_cmd_wait(struct mlx4_dev
        int err = 0;
        int go_bit = 0, t_bit = 0, stat_err;
        u32 status = 0;
+       struct timespec ts1, ts2;
+       ktime_t t1, t2, delta;
+       s64 ds;
+
+       if (out_is_imm && !out_param)
+               return -EINVAL;
 
        down(&cmd->event_sem);
 
@@ -561,29 +725,38 @@ static int mlx4_cmd_wait(struct mlx4_dev
 
        init_completion(&context->done);
 
-       err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0,
+       err = mlx4_cmd_post(dev, &ts1, in_param, out_param ? *out_param : 0,
                            in_modifier, op_modifier, op, context->token, 1);
-       if (err) {
-               mlx4_warn(dev, "command 0x%x could not be posted (%d)\n",
-                         op, err);
+       if (err)
                goto out;
-       }
 
        if (!wait_for_completion_timeout(&context->done,
                                         msecs_to_jiffies(timeout))) {
                stat_err = get_status(dev, &status, &go_bit, &t_bit);
-               mlx4_warn(dev, "command 0x%x timed out: "
-                         "get_status err=%d, status=0x%x, go_bit=%d, "
-                         "t_bit=%d, toggle=0x%x\n", op, stat_err, status,
-                         go_bit, t_bit, mlx4_priv(dev)->cmd.toggle);
+               mlx4_warn(dev, "command %s (0x%x) timed out: in_param=0x%llx, "
+                         "in_mod=0x%x, op_mod=0x%x, get_status err=%d, "
+                         "status_reg=0x%x, go_bit=%d, t_bit=%d, toggle=0x%x\n"
+                         , cmd_to_str(op), op, (unsigned long long) in_param, 
in_modifier,
+                         op_modifier, stat_err, status, go_bit, t_bit,
+                         mlx4_priv(dev)->cmd.toggle);
                err = -EBUSY;
                goto out;
        }
+       if (mlx4_debug_level & MLX4_DEBUG_MASK_CMD_TIME) {
+               ktime_get_ts(&ts2);
+               t1 = timespec_to_ktime(ts1);
+               t2 = timespec_to_ktime(ts2);
+               delta = ktime_sub(t2, t1);
+               ds = ktime_to_ns(delta);
+               pr_info("mlx4: fw exec time for %s is %lld nsec\n", 
cmd_to_str(op), (long long) ds);
+       }
 
        err = context->result;
        if (err) {
-               mlx4_err(dev, "command 0x%x failed: fw status = 0x%x\n",
-                        op, context->fw_status);
+               mlx4_err(dev, "command %s (0x%x) failed: in_param=0x%llx, "
+                        "in_mod=0x%x, op_mod=0x%x, fw status = 0x%x\n",
+                        cmd_to_str(op), op, (unsigned long long) in_param, 
in_modifier,
+                        op_modifier, context->fw_status);
                goto out;
        }
 
@@ -640,7 +813,7 @@ static int mlx4_ACCESS_MEM(struct mlx4_d
            (slave & ~0x7f) | (size & 0xff)) {
                mlx4_err(dev, "Bad access mem params - slave_addr:0x%llx "
                              "master_addr:0x%llx slave_id:%d size:%d\n",
-                             (long long)slave_addr, (long long)master_addr, 
slave, size);
+                             (unsigned long long) slave_addr, (unsigned long 
long) master_addr, slave, size);
                return -EINVAL;
        }
 
@@ -813,6 +986,24 @@ static int mlx4_MAD_IFC_wrapper(struct m
                                    vhcr->op, MLX4_CMD_TIME_CLASS_C, 
MLX4_CMD_NATIVE);
 }
 
+static int MLX4_CMD_DIAG_RPRT_wrapper(struct mlx4_dev *dev, int slave,
+                    struct mlx4_vhcr *vhcr,
+                    struct mlx4_cmd_mailbox *inbox,
+                    struct mlx4_cmd_mailbox *outbox,
+                    struct mlx4_cmd_info *cmd)
+{
+       return -EPERM;
+}
+
+static int MLX4_CMD_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
+                    struct mlx4_vhcr *vhcr,
+                    struct mlx4_cmd_mailbox *inbox,
+                    struct mlx4_cmd_mailbox *outbox,
+                    struct mlx4_cmd_info *cmd)
+{
+       return -EPERM;
+}
+
 int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave,
                     struct mlx4_vhcr *vhcr,
                     struct mlx4_cmd_mailbox *inbox,
@@ -950,6 +1141,16 @@ static struct mlx4_cmd_info cmd_info[] =
                .wrapper = NULL
        },
        {
+               .opcode = MLX4_CMD_DIAG_RPRT,
+               .has_inbox = false,
+               .has_outbox = false,
+               .out_is_imm = false,
+               .encode_slave_id = false,
+               .skip_err_print = true,
+               .verify = NULL,
+               .wrapper = MLX4_CMD_DIAG_RPRT_wrapper
+       },
+       {
                .opcode = MLX4_CMD_NOP,
                .has_inbox = false,
                .has_outbox = false,
@@ -1247,6 +1448,16 @@ static struct mlx4_cmd_info cmd_info[] =
                .wrapper = mlx4_GEN_QP_wrapper
        },
        {
+               .opcode = MLX4_CMD_UPDATE_QP,
+               .has_inbox = false,
+               .has_outbox = false,
+               .out_is_imm = false,
+               .encode_slave_id = false,
+               .skip_err_print = true,
+               .verify = NULL,
+               .wrapper = MLX4_CMD_UPDATE_QP_wrapper
+       },
+       {
                .opcode = MLX4_CMD_CONF_SPECIAL_QP,
                .has_inbox = false,
                .has_outbox = false,
@@ -1348,6 +1559,17 @@ static struct mlx4_cmd_info cmd_info[] =
                .verify = NULL,
                .wrapper = mlx4_QP_FLOW_STEERING_DETACH_wrapper
        },
+       /* wol commands */
+       {
+               .opcode = MLX4_CMD_MOD_STAT_CFG,
+               .has_inbox = false,
+               .has_outbox = false,
+               .out_is_imm = false,
+               .encode_slave_id = false,
+               .skip_err_print = true,
+               .verify = NULL,
+               .wrapper = mlx4_MOD_STAT_CFG_wrapper
+       },
 };
 
 static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
@@ -1401,8 +1623,8 @@ static int mlx4_master_process_vhcr(stru
                }
        }
        if (!cmd) {
-               mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n",
-                        vhcr->op, slave);
+               mlx4_err(dev, "unparavirt command: %s (0x%x) accepted from 
slave:%d\n",
+                        cmd_to_str(vhcr->op), vhcr->op, slave);
                vhcr_cmd->status = CMD_STAT_BAD_PARAM;
                goto out_status;
        }
@@ -1420,8 +1642,8 @@ static int mlx4_master_process_vhcr(stru
                if (mlx4_ACCESS_MEM(dev, inbox->dma, slave,
                                    vhcr->in_param,
                                    MLX4_MAILBOX_SIZE, 1)) {
-                       mlx4_err(dev, "%s: Failed reading inbox (cmd:0x%x)\n",
-                                __func__, cmd->opcode);
+                       mlx4_err(dev, "%s: Failed reading inbox for cmd %s 
(0x%x)\n",
+                                __func__, cmd_to_str(cmd->opcode), 
cmd->opcode);
                        vhcr_cmd->status = CMD_STAT_INTERNAL_ERR;
                        goto out_status;
                }
@@ -1429,9 +1651,9 @@ static int mlx4_master_process_vhcr(stru
 
        /* Apply permission and bound checks if applicable */
        if (cmd->verify && cmd->verify(dev, slave, vhcr, inbox)) {
-               mlx4_warn(dev, "Command:0x%x from slave: %d failed protection "
-                         "checks for resource_id:%d\n", vhcr->op, slave,
-                         vhcr->in_modifier);
+               mlx4_warn(dev, "Command %s (0x%x) from slave: %d failed 
protection "
+                         "checks for resource_id: %d\n", cmd_to_str(vhcr->op),
+                         vhcr->op, slave, vhcr->in_modifier);
                vhcr_cmd->status = CMD_STAT_BAD_OP;
                goto out_status;
        }
@@ -1470,9 +1692,13 @@ static int mlx4_master_process_vhcr(stru
        }
 
        if (err) {
-               mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with"
-                         " error:%d, status %d\n",
-                         vhcr->op, slave, vhcr->errno, err);
+               if (!cmd->skip_err_print)
+                       mlx4_warn(dev, "vhcr command %s (0x%x) slave:%d "
+                                 "in_param 0x%llx in_mod=0x%x, op_mod=0x%x "
+                                 "failed with error:%d, status %d\n",
+                                 cmd_to_str(vhcr->op), vhcr->op, slave,
+                                 (unsigned long long) vhcr->in_param, 
vhcr->in_modifier,
+                                 vhcr->op_modifier, vhcr->errno, err);
                vhcr_cmd->status = mlx4_errno_to_status(err);
                goto out_status;
        }
@@ -1487,7 +1713,7 @@ static int mlx4_master_process_vhcr(stru
                        /* If we failed to write back the outbox after the
                         *command was successfully executed, we must fail this
                         * slave, as it is now in undefined state */
-                       mlx4_err(dev, "%s:Failed writing outbox\n", __func__);
+                       mlx4_err(dev, "%s: Failed writing outbox\n", __func__);
                        goto out;
                }
        }
@@ -1516,6 +1742,75 @@ out:
        return ret;
 }
 
+static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv,
+                                           int slave, int port)
+{
+       struct mlx4_vport_oper_state *vp_oper;
+       struct mlx4_vport_state *vp_admin;
+       struct mlx4_vf_immed_vlan_work *work;
+       int err;
+       int admin_vlan_ix = NO_INDX;
+
+       vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
+       vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
+
+       if (vp_oper->state.default_vlan == vp_admin->default_vlan &&
+           vp_oper->state.default_qos == vp_admin->default_qos)
+               return 0;
+
+       work = kzalloc(sizeof(*work), GFP_KERNEL);
+       if (!work)
+               return -ENOMEM;
+
+       if (vp_oper->state.default_vlan != vp_admin->default_vlan) {
+               if (MLX4_VGT != vp_admin->default_vlan) {
+                       err = __mlx4_register_vlan(&priv->dev, port,
+                                                  vp_admin->default_vlan,
+                                                  &admin_vlan_ix);
+                       if (err) {
+                               mlx4_warn((&priv->dev),
+                                         "No vlan resources slave %d, port 
%d\n",
+                                         slave, port);
+                               return err;
+                       }
+               } else {
+                       admin_vlan_ix = NO_INDX;
+               }
+               work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN;
+               mlx4_dbg((&(priv->dev)),
+                        "alloc vlan %d idx  %d slave %d port %d\n",
+                        (int)(vp_admin->default_vlan),
+                        admin_vlan_ix, slave, port);
+       }
+
+       /* save original vlan ix and vlan id */
+       work->orig_vlan_id = vp_oper->state.default_vlan;
+       work->orig_vlan_ix = vp_oper->vlan_idx;
+
+       /* handle new qos */
+       if (vp_oper->state.default_qos != vp_admin->default_qos)
+               work->flags |= MLX4_VF_IMMED_VLAN_FLAG_QOS;
+
+       if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN)
+               vp_oper->vlan_idx = admin_vlan_ix;
+
+       vp_oper->state.default_vlan = vp_admin->default_vlan;
+       vp_oper->state.default_qos = vp_admin->default_qos;
+
+       /* iterate over QPs owned by this slave, using UPDATE_QP */
+       work->port = port;
+       work->slave = slave;
+       work->qos = vp_oper->state.default_qos;
+       work->vlan_id = vp_oper->state.default_vlan;
+       work->vlan_ix = vp_oper->vlan_idx;
+       work->priv = priv;
+       INIT_WORK(&work->work, mlx4_vf_immed_vlan_work_handler);
+       queue_work(priv->mfunc.master.comm_wq, &work->work);
+
+       return 0;
+}
+
+
 static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
 {
        int port, err;
@@ -1527,7 +1822,7 @@ static int mlx4_master_activate_admin_st
                vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
                vp_oper->state = *vp_admin;
                if (MLX4_VGT != vp_admin->default_vlan) {
-                       err = mlx4_register_vlan(&priv->dev, port,
+                       err = __mlx4_register_vlan(&priv->dev, port,
                                                 vp_admin->default_vlan, 
&(vp_oper->vlan_idx));
                        if (err) {
                                vp_oper->vlan_idx = NO_INDX;
@@ -1548,12 +1843,12 @@ static int mlx4_master_activate_admin_st
                                err = vp_oper->mac_idx;
                                vp_oper->mac_idx = NO_INDX;
                                mlx4_warn((&priv->dev),
-                                         "No mac resorces slave %d, port %d\n",
+                                         "No mac resources slave %d, port 
%d\n",
                                          slave, port);
                                return err;
                        }
                        mlx4_dbg((&(priv->dev)), "alloc mac %llx idx  %d slave 
%d port %d\n",
-                                (long long)vp_oper->state.mac, 
vp_oper->mac_idx, slave, port);
+                                (unsigned long long) vp_oper->state.mac, 
vp_oper->mac_idx, slave, port);
                }
        }
        return 0;
@@ -1599,6 +1894,7 @@ static void mlx4_master_do_cmd(struct ml
        if (cmd == MLX4_COMM_CMD_RESET) {
                mlx4_warn(dev, "Received reset from slave:%d\n", slave);
                slave_state[slave].active = false;
+               slave_state[slave].old_vlan_api = false;
                mlx4_master_deactivate_admin_state(priv, slave);
                for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) {
                                slave_state[slave].event_eq[i].eqn = -1;
@@ -1619,7 +1915,7 @@ static void mlx4_master_do_cmd(struct ml
        /*command from slave in the middle of FLR*/
        if (cmd != MLX4_COMM_CMD_RESET &&
            MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) {
-               mlx4_warn(dev, "slave:%d is Trying to run cmd(0x%x) "
+               mlx4_warn(dev, "slave:%d is Trying to run cmd (0x%x) "
                          "in the middle of FLR\n", slave, cmd);
                return;
        }
@@ -1630,7 +1926,6 @@ static void mlx4_master_do_cmd(struct ml
                        goto reset_slave;
                slave_state[slave].vhcr_dma = ((u64) param) << 48;
                priv->mfunc.master.slave_state[slave].cookie = 0;
-               mutex_init(&priv->mfunc.master.gen_eqe_mutex[slave]);
                break;
        case MLX4_COMM_CMD_VHCR1:
                if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR0)
@@ -1658,7 +1953,7 @@ static void mlx4_master_do_cmd(struct ml
 
                mutex_lock(&priv->cmd.slave_cmd_mutex);
                if (mlx4_master_process_vhcr(dev, slave, NULL)) {
-                       mlx4_err(dev, "Failed processing vhcr for slave:%d,"
+                       mlx4_err(dev, "Failed processing vhcr for slave: %d,"
                                 " resetting slave.\n", slave);
                        mutex_unlock(&priv->cmd.slave_cmd_mutex);
                        goto reset_slave;
@@ -1666,7 +1961,7 @@ static void mlx4_master_do_cmd(struct ml
                mutex_unlock(&priv->cmd.slave_cmd_mutex);
                break;
        default:
-               mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave);
+               mlx4_warn(dev, "Bad comm cmd: %d from slave: %d\n", cmd, slave);
                goto reset_slave;
        }
        spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags);
@@ -1676,8 +1971,8 @@ static void mlx4_master_do_cmd(struct ml
                is_going_down = 1;
        spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
        if (is_going_down) {
-               mlx4_warn(dev, "Slave is going down aborting command(%d)"
-                         " executing from slave:%d\n",
+               mlx4_warn(dev, "Slave is going down aborting command (%d)"
+                         " executing from slave: %d\n",
                          cmd, slave);
                return;
        }
@@ -1696,8 +1991,6 @@ reset_slave:
        spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
        /*with slave in the middle of flr, no need to clean resources again.*/
 inform_slave_state:
-       memset(&slave_state[slave].event_eq, 0,
-              sizeof(struct mlx4_slave_event_eq_info));
        __raw_writel((__force u32) cpu_to_be32(reply),
                     &priv->mfunc.comm[slave].slave_read);
        wmb();
@@ -1751,7 +2044,10 @@ void mlx4_master_comm_channel(struct wor
                                                   comm_cmd >> 16 & 0xff,
                                                   comm_cmd & 0xffff, toggle);
                                ++served;
-                       }
+                       } else
+                               mlx4_err(dev, "slave %d out of sync."
+                                 " read toggle %d, write toggle %d.\n", slave, 
slt,
+                                 toggle);
                }
        }
 
@@ -1759,6 +2055,19 @@ void mlx4_master_comm_channel(struct wor
                mlx4_warn(dev, "Got command event with bitmask from %d slaves"
                          " but %d were served\n",
                          reported, served);
+}
+/* master command processing */
+void mlx4_master_arm_comm_channel(struct work_struct *work)
+{
+       struct mlx4_mfunc_master_ctx *master =
+               container_of(work,
+                            struct mlx4_mfunc_master_ctx,
+                            arm_comm_work);
+       struct mlx4_mfunc *mfunc =
+               container_of(master, struct mlx4_mfunc, master);
+       struct mlx4_priv *priv =
+               container_of(mfunc, struct mlx4_priv, mfunc);
+       struct mlx4_dev *dev = &priv->dev;
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to