net/mlx4_core: Add basic support for TCP/IP offloads under tunneling
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / mellanox / mlx4 / fw.c
index 0d63daa2f422e082d85fd627a892c9fb5f5c1945..55c4ea7402586f8f2b3124f570ca6bd4246046bd 100644 (file)
@@ -134,7 +134,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
                [5] = "Time stamping support",
                [6] = "VST (control vlan insertion/stripping) support",
                [7] = "FSM (MAC anti-spoofing) support",
-               [8] = "Dynamic QP updates support"
+               [8] = "Dynamic QP updates support",
+               [9] = "TCP/IP offloads/flow-steering for VXLAN support"
        };
        int i;
 
@@ -159,8 +160,6 @@ int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
                return PTR_ERR(mailbox);
        inbox = mailbox->buf;
 
-       memset(inbox, 0, MOD_STAT_CFG_IN_SIZE);
-
        MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET);
        MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET);
 
@@ -177,6 +176,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
                                struct mlx4_cmd_mailbox *outbox,
                                struct mlx4_cmd_info *cmd)
 {
+       struct mlx4_priv *priv = mlx4_priv(dev);
        u8      field;
        u32     size;
        int     err = 0;
@@ -185,40 +185,48 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
 #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET                0x1
 #define QUERY_FUNC_CAP_PF_BHVR_OFFSET          0x4
 #define QUERY_FUNC_CAP_FMR_OFFSET              0x8
-#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET         0x10
-#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET         0x14
-#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET                0x18
-#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET                0x20
-#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET                0x24
-#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET                0x28
+#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP     0x10
+#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP     0x14
+#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP    0x18
+#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP    0x20
+#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP    0x24
+#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP    0x28
 #define QUERY_FUNC_CAP_MAX_EQ_OFFSET           0x2c
 #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET      0x30
 
+#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET         0x50
+#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET         0x54
+#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET                0x58
+#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET                0x60
+#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET                0x64
+#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET                0x68
+
 #define QUERY_FUNC_CAP_FMR_FLAG                        0x80
 #define QUERY_FUNC_CAP_FLAG_RDMA               0x40
 #define QUERY_FUNC_CAP_FLAG_ETH                        0x80
+#define QUERY_FUNC_CAP_FLAG_QUOTAS             0x10
 
 /* when opcode modifier = 1 */
 #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET                0x3
-#define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET       0x8
-#define QUERY_FUNC_CAP_ETH_PROPS_OFFSET                0xc
+#define QUERY_FUNC_CAP_FLAGS0_OFFSET           0x8
+#define QUERY_FUNC_CAP_FLAGS1_OFFSET           0xc
 
 #define QUERY_FUNC_CAP_QP0_TUNNEL              0x10
 #define QUERY_FUNC_CAP_QP0_PROXY               0x14
 #define QUERY_FUNC_CAP_QP1_TUNNEL              0x18
 #define QUERY_FUNC_CAP_QP1_PROXY               0x1c
+#define QUERY_FUNC_CAP_PHYS_PORT_ID            0x28
 
-#define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC     0x40
-#define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN    0x80
+#define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC                0x40
+#define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN       0x80
+#define QUERY_FUNC_CAP_FLAGS1_NIC_INFO                 0x10
 
-#define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80
+#define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80
 
        if (vhcr->op_modifier == 1) {
-               field = 0;
-               /* ensure force vlan and force mac bits are not set */
-               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
-               /* ensure that phy_wqe_gid bit is not set */
-               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
+               /* Set nic_info bit to mark new fields support */
+               field  = QUERY_FUNC_CAP_FLAGS1_NIC_INFO;
+               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET);
 
                field = vhcr->in_modifier; /* phys-port = logical-port */
                MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
@@ -236,9 +244,13 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
                size += 2;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY);
 
+               MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier],
+                        QUERY_FUNC_CAP_PHYS_PORT_ID);
+
        } else if (vhcr->op_modifier == 0) {
-               /* enable rdma and ethernet interfaces */
-               field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA);
+               /* enable rdma and ethernet interfaces, and new quota locations */
+               field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA |
+                        QUERY_FUNC_CAP_FLAG_QUOTAS);
                MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET);
 
                field = dev->caps.num_ports;
@@ -250,14 +262,20 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
                field = 0; /* protected FMR support not available as yet */
                MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET);
 
-               size = dev->caps.num_qps;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
+               size = dev->caps.num_qps;
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
 
-               size = dev->caps.num_srqs;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
+               size = dev->caps.num_srqs;
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
 
-               size = dev->caps.num_cqs;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
+               size = dev->caps.num_cqs;
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
 
                size = dev->caps.num_eqs;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
@@ -265,14 +283,19 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
                size = dev->caps.reserved_eqs;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
 
-               size = dev->caps.num_mpts;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
+               size = dev->caps.num_mpts;
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
 
-               size = dev->caps.num_mtts;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
+               size = dev->caps.num_mtts;
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
 
                size = dev->caps.num_mgms + dev->caps.num_amgms;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
+               MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
 
        } else
                err = -EINVAL;
@@ -287,7 +310,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
        u32                     *outbox;
        u8                      field, op_modifier;
        u32                     size;
-       int                     err = 0;
+       int                     err = 0, quotas = 0;
 
        op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */
 
@@ -311,6 +334,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
                        goto out;
                }
                func_cap->flags = field;
+               quotas = !!(func_cap->flags & QUERY_FUNC_CAP_FLAG_QUOTAS);
 
                MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
                func_cap->num_ports = field;
@@ -318,29 +342,50 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
                MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET);
                func_cap->pf_context_behaviour = size;
 
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
-               func_cap->qp_quota = size & 0xFFFFFF;
+               if (quotas) {
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
+                       func_cap->qp_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
+                       func_cap->srq_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
+                       func_cap->cq_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
+                       func_cap->mpt_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
+                       func_cap->mtt_quota = size & 0xFFFFFF;
 
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
-               func_cap->srq_quota = size & 0xFFFFFF;
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
+                       func_cap->mcg_quota = size & 0xFFFFFF;
 
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
-               func_cap->cq_quota = size & 0xFFFFFF;
+               } else {
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
+                       func_cap->qp_quota = size & 0xFFFFFF;
 
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
+                       func_cap->srq_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
+                       func_cap->cq_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
+                       func_cap->mpt_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
+                       func_cap->mtt_quota = size & 0xFFFFFF;
+
+                       MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
+                       func_cap->mcg_quota = size & 0xFFFFFF;
+               }
                MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
                func_cap->max_eq = size & 0xFFFFFF;
 
                MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
                func_cap->reserved_eq = size & 0xFFFFFF;
 
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
-               func_cap->mpt_quota = size & 0xFFFFFF;
-
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
-               func_cap->mtt_quota = size & 0xFFFFFF;
-
-               MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
-               func_cap->mcg_quota = size & 0xFFFFFF;
                goto out;
        }
 
@@ -350,22 +395,22 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
                goto out;
        }
 
+       MLX4_GET(func_cap->flags1, outbox, QUERY_FUNC_CAP_FLAGS1_OFFSET);
        if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_ETH) {
-               MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
-               if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) {
+               if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_OFFSET) {
                        mlx4_err(dev, "VLAN is enforced on this port\n");
                        err = -EPROTONOSUPPORT;
                        goto out;
                }
 
-               if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) {
+               if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_MAC) {
                        mlx4_err(dev, "Force mac is enabled on this port\n");
                        err = -EPROTONOSUPPORT;
                        goto out;
                }
        } else if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_IB) {
-               MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
-               if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) {
+               MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET);
+               if (field & QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID) {
                        mlx4_err(dev, "phy_wqe_gid is "
                                 "enforced on this ib port\n");
                        err = -EPROTONOSUPPORT;
@@ -392,6 +437,10 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
        MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_PROXY);
        func_cap->qp1_proxy_qpn = size & 0xFFFFFF;
 
+       if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_NIC_INFO)
+               MLX4_GET(func_cap->phys_port_id, outbox,
+                        QUERY_FUNC_CAP_PHYS_PORT_ID);
+
        /* All other resources are allocated by the master, but we still report
         * 'num' and 'reserved' capabilities as follows:
         * - num remains the maximum resource index
@@ -488,6 +537,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET         0x98
 #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET                0xa0
 #define QUERY_DEV_CAP_FW_REASSIGN_MAC          0x9d
+#define QUERY_DEV_CAP_VXLAN                    0x9e
 
        dev_cap->flags2 = 0;
        mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -652,7 +702,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                 QUERY_DEV_CAP_RSVD_LKEY_OFFSET);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC);
        if (field & 1<<6)
-               dev_cap->flags2 |= MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN;
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN;
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
+       if (field & 1<<3)
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS;
        MLX4_GET(dev_cap->max_icm_sz, outbox,
                 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
        if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS)
@@ -801,6 +854,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        field &= 0x7f;
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
 
+       /* For guests, disable vxlan tunneling */
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
+       field &= 0xf7;
+       MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN);
+
        /* For guests, report Blueflame disabled */
        MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET);
        field &= 0x7f;
@@ -924,7 +982,6 @@ int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt)
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
-       memset(mailbox->buf, 0, MLX4_MAILBOX_SIZE);
        pages = mailbox->buf;
 
        for (mlx4_icm_first(icm, &iter);
@@ -1227,6 +1284,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
 #define INIT_HCA_IN_SIZE                0x200
 #define INIT_HCA_VERSION_OFFSET                 0x000
 #define         INIT_HCA_VERSION                2
+#define INIT_HCA_VXLAN_OFFSET           0x0c
 #define INIT_HCA_CACHELINE_SZ_OFFSET    0x0e
 #define INIT_HCA_FLAGS_OFFSET           0x014
 #define INIT_HCA_QPC_OFFSET             0x020
@@ -1273,8 +1331,6 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
                return PTR_ERR(mailbox);
        inbox = mailbox->buf;
 
-       memset(inbox, 0, INIT_HCA_IN_SIZE);
-
        *((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION;
 
        *((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) =
@@ -1387,6 +1443,12 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
        MLX4_PUT(inbox, param->uar_page_sz,     INIT_HCA_UAR_PAGE_SZ_OFFSET);
        MLX4_PUT(inbox, param->log_uar_sz,      INIT_HCA_LOG_UAR_SZ_OFFSET);
 
+       /* set parser VXLAN attributes */
+       if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) {
+               u8 parser_params = 0;
+               MLX4_PUT(inbox, parser_params,  INIT_HCA_VXLAN_OFFSET);
+       }
+
        err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000,
                       MLX4_CMD_NATIVE);
 
@@ -1573,8 +1635,6 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
                        return PTR_ERR(mailbox);
                inbox = mailbox->buf;
 
-               memset(inbox, 0, INIT_PORT_IN_SIZE);
-
                flags = 0;
                flags |= (dev->caps.vl_cap[port] & 0xf) << INIT_PORT_VL_SHIFT;
                flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
@@ -1677,6 +1737,43 @@ int mlx4_NOP(struct mlx4_dev *dev)
        return mlx4_cmd(dev, 0, 0x1f, 0, MLX4_CMD_NOP, 100, MLX4_CMD_NATIVE);
 }
 
+int mlx4_get_phys_port_id(struct mlx4_dev *dev)
+{
+       u8 port;
+       u32 *outbox;
+       struct mlx4_cmd_mailbox *mailbox;
+       u32 in_mod;
+       u32 guid_hi, guid_lo;
+       int err, ret = 0;
+#define MOD_STAT_CFG_PORT_OFFSET 8
+#define MOD_STAT_CFG_GUID_H     0X14
+#define MOD_STAT_CFG_GUID_L     0X1c
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       outbox = mailbox->buf;
+
+       for (port = 1; port <= dev->caps.num_ports; port++) {
+               in_mod = port << MOD_STAT_CFG_PORT_OFFSET;
+               err = mlx4_cmd_box(dev, 0, mailbox->dma, in_mod, 0x2,
+                                  MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A,
+                                  MLX4_CMD_NATIVE);
+               if (err) {
+                       mlx4_err(dev, "Fail to get port %d uplink guid\n",
+                                port);
+                       ret = err;
+               } else {
+                       MLX4_GET(guid_hi, outbox, MOD_STAT_CFG_GUID_H);
+                       MLX4_GET(guid_lo, outbox, MOD_STAT_CFG_GUID_L);
+                       dev->caps.phys_port_id[port] = (u64)guid_lo |
+                                                      (u64)guid_hi << 32;
+               }
+       }
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return ret;
+}
+
 #define MLX4_WOL_SETUP_MODE (5 << 28)
 int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port)
 {
@@ -1713,7 +1810,6 @@ void mlx4_opreq_action(struct work_struct *work)
        u32 *outbox;
        u32 modifier;
        u16 token;
-       u16 type_m;
        u16 type;
        int err;
        u32 num_qps;
@@ -1739,14 +1835,13 @@ void mlx4_opreq_action(struct work_struct *work)
                                   MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A,
                                   MLX4_CMD_NATIVE);
                if (err) {
-                       mlx4_err(dev, "Failed to retreive required operation: %d\n",
+                       mlx4_err(dev, "Failed to retrieve required operation: %d\n",
                                 err);
                        return;
                }
                MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET);
                MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET);
                MLX4_GET(type, outbox, GET_OP_REQ_TYPE_OFFSET);
-               type_m = type >> 12;
                type &= 0xfff;
 
                switch (type) {