VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
                        strlen(enic->pp.name) + 1, enic->pp.name);
 
-               vic_provinfo_add_tlv(vp,
-                       VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
-                       ETH_ALEN, mac);
+               if (!is_zero_ether_addr(enic->pp.mac_addr))
+                       vic_provinfo_add_tlv(vp,
+                               VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
+                               ETH_ALEN, enic->pp.mac_addr);
+               else
+                       vic_provinfo_add_tlv(vp,
+                               VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
+                               ETH_ALEN, mac);
 
                if (enic->pp.set & ENIC_SET_INSTANCE) {
                        sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
                vic_provinfo_free(vp);
                if (err)
                        return err;
+
+               enic->pp.set |= ENIC_SET_APPLIED;
                break;
 
        case PORT_REQUEST_DISASSOCIATE:
+               enic->pp.set &= ~ENIC_SET_APPLIED;
                break;
 
        default:
                return -EINVAL;
        }
 
-       enic->pp.set |= ENIC_SET_APPLIED;
        return 0;
 }
 
        struct nlattr *port[])
 {
        struct enic *enic = netdev_priv(netdev);
+       struct enic_port_profile new_pp;
+       int err = 0;
 
-       memset(&enic->pp, 0, sizeof(enic->pp));
+       memset(&new_pp, 0, sizeof(new_pp));
 
        if (port[IFLA_PORT_REQUEST]) {
-               enic->pp.set |= ENIC_SET_REQUEST;
-               enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+               new_pp.set |= ENIC_SET_REQUEST;
+               new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
        }
 
        if (port[IFLA_PORT_PROFILE]) {
-               enic->pp.set |= ENIC_SET_NAME;
-               memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+               new_pp.set |= ENIC_SET_NAME;
+               memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]),
                        PORT_PROFILE_MAX);
        }
 
        if (port[IFLA_PORT_INSTANCE_UUID]) {
-               enic->pp.set |= ENIC_SET_INSTANCE;
-               memcpy(enic->pp.instance_uuid,
+               new_pp.set |= ENIC_SET_INSTANCE;
+               memcpy(new_pp.instance_uuid,
                        nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
        }
 
        if (port[IFLA_PORT_HOST_UUID]) {
-               enic->pp.set |= ENIC_SET_HOST;
-               memcpy(enic->pp.host_uuid,
+               new_pp.set |= ENIC_SET_HOST;
+               memcpy(new_pp.host_uuid,
                        nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
        }
 
        if (vf != PORT_SELF_VF)
                return -EOPNOTSUPP;
 
-       if (!(enic->pp.set & ENIC_SET_REQUEST))
+       if (!(new_pp.set & ENIC_SET_REQUEST))
                return -EOPNOTSUPP;
 
-       if (enic->pp.request == PORT_REQUEST_ASSOCIATE) {
-
-               /* If the interface mac addr hasn't been assigned,
-                * assign a random mac addr before setting port-
-                * profile.
-                */
+       if (new_pp.request == PORT_REQUEST_ASSOCIATE) {
+               /* Special case handling */
+               if (!is_zero_ether_addr(enic->pp.vf_mac))
+                       memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN);
 
                if (is_zero_ether_addr(netdev->dev_addr))
                        random_ether_addr(netdev->dev_addr);
+       } else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) {
+               if (!is_zero_ether_addr(enic->pp.mac_addr))
+                       enic_dev_del_addr(enic, enic->pp.mac_addr);
        }
 
-       return enic_set_port_profile(enic, netdev->dev_addr);
+       memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
+
+       err = enic_set_port_profile(enic, netdev->dev_addr);
+       if (err)
+               goto set_port_profile_cleanup;
+
+       if (!is_zero_ether_addr(enic->pp.mac_addr))
+               enic_dev_add_addr(enic, enic->pp.mac_addr);
+
+set_port_profile_cleanup:
+       memset(enic->pp.vf_mac, 0, ETH_ALEN);
+
+       if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
+               memset(netdev->dev_addr, 0, ETH_ALEN);
+               memset(enic->pp.mac_addr, 0, ETH_ALEN);
+       }
+
+       return err;
 }
 
 static int enic_get_vf_port(struct net_device *netdev, int vf,
        for (i = 0; i < enic->rq_count; i++)
                vnic_rq_enable(&enic->rq[i]);
 
-       enic_dev_add_station_addr(enic);
+       if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
+               enic_dev_add_addr(enic, enic->pp.mac_addr);
+       else
+               enic_dev_add_station_addr(enic);
        enic_set_rx_mode(netdev);
 
        netif_wake_queue(netdev);
 
        netif_carrier_off(netdev);
        netif_tx_disable(netdev);
-       enic_dev_del_station_addr(enic);
+       if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
+               enic_dev_del_addr(enic, enic->pp.mac_addr);
+       else
+               enic_dev_del_station_addr(enic);
 
        for (i = 0; i < enic->wq_count; i++) {
                err = vnic_wq_disable(&enic->wq[i]);