qp = ibdev->qp1_proxy[port - 1];
        if (qp) {
                int new_smac_index;
-               u64 old_smac = qp->pri.smac;
+               u64 old_smac;
                struct mlx4_update_qp_params update_params;
 
+               mutex_lock(&qp->mutex);
+               old_smac = qp->pri.smac;
                if (new_smac == old_smac)
                        goto unlock;
 
                        release_mac = new_smac;
                        goto unlock;
                }
-
+               /* if old port was zero, no mac was yet registered for this QP */
+               if (qp->pri.smac_port)
+                       release_mac = old_smac;
                qp->pri.smac = new_smac;
+               qp->pri.smac_port = port;
                qp->pri.smac_index = new_smac_index;
-
-               release_mac = old_smac;
        }
 
 unlock:
-       mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
        if (release_mac != MLX4_IB_INVALID_MAC)
                mlx4_unregister_mac(ibdev->dev, port, release_mac);
+       if (qp)
+               mutex_unlock(&qp->mutex);
+       mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
 }
 
 static void mlx4_ib_get_dev_addr(struct net_device *dev,
 
                                   MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp))
                        pr_warn("modify QP %06x to RESET failed.\n",
                               qp->mqp.qpn);
-               if (qp->pri.smac) {
+               if (qp->pri.smac || (!qp->pri.smac && qp->pri.smac_port)) {
                        mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac);
                        qp->pri.smac = 0;
+                       qp->pri.smac_port = 0;
                }
                if (qp->alt.smac) {
                        mlx4_unregister_mac(dev->dev, qp->alt.smac_port, qp->alt.smac);
                 * If one was already assigned, but the new mac differs,
                 * unregister the old one and register the new one.
                */
-               if (!smac_info->smac || smac_info->smac != smac) {
+               if ((!smac_info->smac && !smac_info->smac_port) ||
+                   smac_info->smac != smac) {
                        /* register candidate now, unreg if needed, after success */
                        smac_index = mlx4_register_mac(dev->dev, port, smac);
                        if (smac_index >= 0) {
        u64_mac = atomic64_read(&dev->iboe.mac[qp->port - 1]);
 
        context->pri_path.sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | ((qp->port - 1) << 6);
-       if (!qp->pri.smac) {
+       if (!qp->pri.smac && !qp->pri.smac_port) {
                smac_index = mlx4_register_mac(dev->dev, qp->port, u64_mac);
                if (smac_index >= 0) {
                        qp->pri.candidate_smac_index = smac_index;
                        if (qp->flags & MLX4_IB_QP_NETIF)
                                mlx4_ib_steer_qp_reg(dev, qp, 0);
                }
-               if (qp->pri.smac) {
+               if (qp->pri.smac || (!qp->pri.smac && qp->pri.smac_port)) {
                        mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac);
                        qp->pri.smac = 0;
+                       qp->pri.smac_port = 0;
                }
                if (qp->alt.smac) {
                        mlx4_unregister_mac(dev->dev, qp->alt.smac_port, qp->alt.smac);
        if (err && steer_qp)
                mlx4_ib_steer_qp_reg(dev, qp, 0);
        kfree(context);
-       if (qp->pri.candidate_smac) {
+       if (qp->pri.candidate_smac ||
+           (!qp->pri.candidate_smac && qp->pri.candidate_smac_port)) {
                if (err) {
                        mlx4_unregister_mac(dev->dev, qp->pri.candidate_smac_port, qp->pri.candidate_smac);
                } else {
-                       if (qp->pri.smac)
+                       if (qp->pri.smac || (!qp->pri.smac && qp->pri.smac_port))
                                mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac);
                        qp->pri.smac = qp->pri.candidate_smac;
                        qp->pri.smac_index = qp->pri.candidate_smac_index;