}
 
 static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc,
-                          unsigned tail, struct mlx4_cqe *cqe)
+                          unsigned tail, struct mlx4_cqe *cqe, int is_eth)
 {
        struct mlx4_ib_proxy_sqp_hdr *hdr;
 
                                   DMA_FROM_DEVICE);
        hdr = (struct mlx4_ib_proxy_sqp_hdr *) (qp->sqp_proxy_rcv[tail].addr);
        wc->pkey_index  = be16_to_cpu(hdr->tun.pkey_index);
-       wc->slid        = be16_to_cpu(hdr->tun.slid_mac_47_32);
-       wc->sl          = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12);
        wc->src_qp      = be32_to_cpu(hdr->tun.flags_src_qp) & 0xFFFFFF;
        wc->wc_flags   |= (hdr->tun.g_ml_path & 0x80) ? (IB_WC_GRH) : 0;
        wc->dlid_path_bits = 0;
 
+       if (is_eth) {
+               wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid);
+               memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4);
+               memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2);
+               wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC);
+       } else {
+               wc->slid        = be16_to_cpu(hdr->tun.slid_mac_47_32);
+               wc->sl          = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12);
+       }
+
        return 0;
 }
 
        struct mlx4_srq *msrq = NULL;
        int is_send;
        int is_error;
+       int is_eth;
        u32 g_mlpath_rqpn;
        u16 wqe_ctr;
        unsigned tail = 0;
                        break;
                }
 
+               is_eth = (rdma_port_get_link_layer(wc->qp->device,
+                                                 (*cur_qp)->port) ==
+                         IB_LINK_LAYER_ETHERNET);
                if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) {
                        if ((*cur_qp)->mlx4_ib_qp_type &
                            (MLX4_IB_QPT_PROXY_SMI_OWNER |
                             MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI))
-                               return use_tunnel_data(*cur_qp, cq, wc, tail, cqe);
+                               return use_tunnel_data(*cur_qp, cq, wc, tail,
+                                                      cqe, is_eth);
                }
 
                wc->slid           = be16_to_cpu(cqe->rlid);
                wc->pkey_index     = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
                wc->wc_flags      |= mlx4_ib_ipoib_csum_ok(cqe->status,
                                        cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;
-               if (rdma_port_get_link_layer(wc->qp->device,
-                               (*cur_qp)->port) == IB_LINK_LAYER_ETHERNET)
+               if (is_eth) {
                        wc->sl  = be16_to_cpu(cqe->sl_vid) >> 13;
-               else
-                       wc->sl  = be16_to_cpu(cqe->sl_vid) >> 12;
-               if (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_VLAN_PRESENT_MASK) {
-                       wc->vlan_id = be16_to_cpu(cqe->sl_vid) &
-                               MLX4_CQE_VID_MASK;
+                       if (be32_to_cpu(cqe->vlan_my_qpn) &
+                                       MLX4_CQE_VLAN_PRESENT_MASK) {
+                               wc->vlan_id = be16_to_cpu(cqe->sl_vid) &
+                                       MLX4_CQE_VID_MASK;
+                       } else {
+                               wc->vlan_id = 0xffff;
+                       }
+                       memcpy(wc->smac, cqe->smac, ETH_ALEN);
+                       wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC);
                } else {
+                       wc->sl  = be16_to_cpu(cqe->sl_vid) >> 12;
                        wc->vlan_id = 0xffff;
                }
-               wc->wc_flags |= IB_WC_WITH_VLAN;
-               memcpy(wc->smac, cqe->smac, ETH_ALEN);
-               wc->wc_flags |= IB_WC_WITH_SMAC;
        }
 
        return 0;
 
 
        /* adjust tunnel data */
        tun_mad->hdr.pkey_index = cpu_to_be16(tun_pkey_ix);
-       tun_mad->hdr.sl_vid = cpu_to_be16(((u16)(wc->sl)) << 12);
-       tun_mad->hdr.slid_mac_47_32 = cpu_to_be16(wc->slid);
        tun_mad->hdr.flags_src_qp = cpu_to_be32(wc->src_qp & 0xFFFFFF);
        tun_mad->hdr.g_ml_path = (grh && (wc->wc_flags & IB_WC_GRH)) ? 0x80 : 0;
 
+       if (is_eth) {
+               u16 vlan = 0;
+               if (mlx4_get_slave_default_vlan(dev->dev, port, slave, &vlan,
+                                               NULL)) {
+                       /* VST mode */
+                       if (vlan != wc->vlan_id)
+                               /* Packet vlan is not the VST-assigned vlan.
+                                * Drop the packet.
+                                */
+                               goto out;
+                        else
+                               /* Remove the vlan tag before forwarding
+                                * the packet to the VF.
+                                */
+                               vlan = 0xffff;
+               } else {
+                       vlan = wc->vlan_id;
+               }
+
+               tun_mad->hdr.sl_vid = cpu_to_be16(vlan);
+               memcpy((char *)&tun_mad->hdr.mac_31_0, &(wc->smac[0]), 4);
+               memcpy((char *)&tun_mad->hdr.slid_mac_47_32, &(wc->smac[4]), 2);
+       } else {
+               tun_mad->hdr.sl_vid = cpu_to_be16(((u16)(wc->sl)) << 12);
+               tun_mad->hdr.slid_mac_47_32 = cpu_to_be16(wc->slid);
+       }
+
        ib_dma_sync_single_for_device(&dev->ib_dev,
                                      tun_qp->tx_ring[tun_tx_ix].buf.map,
                                      sizeof (struct mlx4_rcv_tunnel_mad),
 
 
 int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
-                        enum ib_qp_type dest_qpt, u16 pkey_index, u32 remote_qpn,
-                        u32 qkey, struct ib_ah_attr *attr, struct ib_mad *mad)
+                        enum ib_qp_type dest_qpt, u16 pkey_index,
+                        u32 remote_qpn, u32 qkey, struct ib_ah_attr *attr,
+                        u8 *s_mac, struct ib_mad *mad)
 {
        struct ib_sge list;
        struct ib_send_wr wr, *bad_wr;
        wr.num_sge = 1;
        wr.opcode = IB_WR_SEND;
        wr.send_flags = IB_SEND_SIGNALED;
+       if (s_mac)
+               memcpy(to_mah(ah)->av.eth.s_mac, s_mac, 6);
+
 
        ret = ib_post_send(send_qp, &wr, &bad_wr);
 out:
        if (ah_attr.ah_flags & IB_AH_GRH)
                fill_in_real_sgid_index(dev, slave, ctx->port, &ah_attr);
 
+       memcpy(ah_attr.dmac, tunnel->hdr.mac, 6);
+       ah_attr.vlan_id = be16_to_cpu(tunnel->hdr.vlan);
+       /* if slave have default vlan use it */
+       mlx4_get_slave_default_vlan(dev->dev, ctx->port, slave,
+                                   &ah_attr.vlan_id, &ah_attr.sl);
+
        mlx4_ib_send_to_wire(dev, slave, ctx->port,
                             is_proxy_qp0(dev, wc->src_qp, slave) ?
                             IB_QPT_SMI : IB_QPT_GSI,
                             be16_to_cpu(tunnel->hdr.pkey_index),
                             be32_to_cpu(tunnel->hdr.remote_qpn),
                             be32_to_cpu(tunnel->hdr.qkey),
-                            &ah_attr, &tunnel->mad);
+                            &ah_attr, wc->smac, &tunnel->mad);
 }
 
 static int mlx4_ib_alloc_pv_bufs(struct mlx4_ib_demux_pv_ctx *ctx,
 
        }
        mlx4_ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr);
        spin_unlock(&dev->sm_lock);
-       return mlx4_ib_send_to_wire(dev, mlx4_master_func_num(dev->dev), ctx->port,
-                                   IB_QPT_GSI, 0, 1, IB_QP1_QKEY, &ah_attr, mad);
+       return mlx4_ib_send_to_wire(dev, mlx4_master_func_num(dev->dev),
+                                   ctx->port, IB_QPT_GSI, 0, 1, IB_QP1_QKEY,
+                                   &ah_attr, NULL, mad);
 }
 
 static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx,
 
 int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
                          enum ib_qp_type qpt, struct ib_wc *wc,
                          struct ib_grh *grh, struct ib_mad *mad);
+
 int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
                         enum ib_qp_type dest_qpt, u16 pkey_index, u32 remote_qpn,
-                        u32 qkey, struct ib_ah_attr *attr, struct ib_mad *mad);
+                        u32 qkey, struct ib_ah_attr *attr, u8 *s_mac,
+                        struct ib_mad *mad);
+
 __be64 mlx4_ib_get_new_demux_tid(struct mlx4_ib_demux_ctx *ctx);
 
 int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave,
 
        }
 
        if (is_eth) {
-               u8 smac[6];
+               u8 *smac;
                struct in6_addr in6;
 
                u16 pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13;
                memcpy(&ctrl->srcrb_flags16[0], ah->av.eth.mac, 2);
                memcpy(&ctrl->imm, ah->av.eth.mac + 2, 4);
                memcpy(&in6, sgid.raw, sizeof(in6));
-               rdma_get_ll_mac(&in6, smac);
+
+               if (!mlx4_is_mfunc(to_mdev(ib_dev)->dev))
+                       smac = to_mdev(sqp->qp.ibqp.device)->
+                               iboe.netdevs[sqp->qp.port - 1]->dev_addr;
+               else    /* use the src mac of the tunnel */
+                       smac = ah->av.eth.s_mac;
                memcpy(sqp->ud_header.eth.smac_h, smac, 6);
                if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6))
                        mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);
        hdr.remote_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
        hdr.pkey_index = cpu_to_be16(wr->wr.ud.pkey_index);
        hdr.qkey = cpu_to_be32(wr->wr.ud.remote_qkey);
+       memcpy(hdr.mac, ah->av.eth.mac, 6);
+       hdr.vlan = ah->av.eth.vlan;
 
        spc = MLX4_INLINE_ALIGN -
                ((unsigned long) (inl + 1) & (MLX4_INLINE_ALIGN - 1));
 
 }
 EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
 
+ /* mlx4_get_slave_default_vlan -
+ * return true if VST ( default vlan)
+ * if VST, will return vlan & qos (if not NULL)
+ */
+bool mlx4_get_slave_default_vlan(struct mlx4_dev *dev, int port, int slave,
+                                u16 *vlan, u8 *qos)
+{
+       struct mlx4_vport_oper_state *vp_oper;
+       struct mlx4_priv *priv;
+
+       priv = mlx4_priv(dev);
+       vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
+
+       if (MLX4_VGT != vp_oper->state.default_vlan) {
+               if (vlan)
+                       *vlan = vp_oper->state.default_vlan;
+               if (qos)
+                       *qos = vp_oper->state.default_qos;
+               return true;
+       }
+       return false;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_slave_default_vlan);
+
 int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
 
 int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting);
 int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf);
 int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state);
+/*
+ * mlx4_get_slave_default_vlan -
+ * return true if VST ( default vlan)
+ * if VST, will return vlan & qos (if not NULL)
+ */
+bool mlx4_get_slave_default_vlan(struct mlx4_dev *dev, int port, int slave,
+                                u16 *vlan, u8 *qos);
 
 #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8)
 
 
        u8              hop_limit;
        __be32          sl_tclass_flowlabel;
        u8              dgid[16];
-       u32             reserved4[2];
+       u8              s_mac[6];
+       u8              reserved4[2];
        __be16          vlan;
        u8              mac[ETH_ALEN];
 };