return ice_vsi_setup(pf, pi, ICE_VSI_SWITCHDEV_CTRL, ICE_INVAL_VFID);
 }
 
+/**
+ * ice_eswitch_napi_del - remove NAPI handle for all port representors
+ * @pf: pointer to PF structure
+ */
+static void ice_eswitch_napi_del(struct ice_pf *pf)
+{
+       int i;
+
+       ice_for_each_vf(pf, i)
+               netif_napi_del(&pf->vf[i].repr->q_vector->napi);
+}
+
 /**
  * ice_eswitch_napi_enable - enable NAPI for all port representors
  * @pf: pointer to PF structure
        pf->switchdev.is_running = true;
        return 0;
 }
+
+/**
+ * ice_eswitch_start_all_tx_queues - start Tx queues of all port representors
+ * @pf: pointer to PF structure
+ */
+static void ice_eswitch_start_all_tx_queues(struct ice_pf *pf)
+{
+       struct ice_repr *repr;
+       int i;
+
+       if (test_bit(ICE_DOWN, pf->state))
+               return;
+
+       ice_for_each_vf(pf, i) {
+               repr = pf->vf[i].repr;
+               if (repr)
+                       ice_repr_start_tx_queues(repr);
+       }
+}
+
+/**
+ * ice_eswitch_stop_all_tx_queues - stop Tx queues of all port representors
+ * @pf: pointer to PF structure
+ */
+void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf)
+{
+       struct ice_repr *repr;
+       int i;
+
+       if (test_bit(ICE_DOWN, pf->state))
+               return;
+
+       ice_for_each_vf(pf, i) {
+               repr = pf->vf[i].repr;
+               if (repr)
+                       ice_repr_stop_tx_queues(repr);
+       }
+}
+
+/**
+ * ice_eswitch_rebuild - rebuild eswitch
+ * @pf: pointer to PF structure
+ */
+int ice_eswitch_rebuild(struct ice_pf *pf)
+{
+       struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi;
+       int status;
+
+       ice_eswitch_napi_disable(pf);
+       ice_eswitch_napi_del(pf);
+
+       status = ice_eswitch_setup_env(pf);
+       if (status)
+               return status;
+
+       status = ice_eswitch_setup_reprs(pf);
+       if (status)
+               return status;
+
+       ice_eswitch_remap_rings_to_vectors(pf);
+
+       status = ice_vsi_open(ctrl_vsi);
+       if (status)
+               return status;
+
+       ice_eswitch_napi_enable(pf);
+       ice_eswitch_set_rxdid(ctrl_vsi, ICE_RXDID_FLEX_NIC_2);
+       ice_eswitch_start_all_tx_queues(pf);
+
+       return 0;
+}
 
 #ifdef CONFIG_ICE_SWITCHDEV
 void ice_eswitch_release(struct ice_pf *pf);
 int ice_eswitch_configure(struct ice_pf *pf);
+int ice_eswitch_rebuild(struct ice_pf *pf);
 
 int ice_eswitch_mode_get(struct devlink *devlink, u16 *mode);
 int
 bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf);
 
 void ice_eswitch_update_repr(struct ice_vsi *vsi);
+
+void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf);
 #else /* CONFIG_ICE_SWITCHDEV */
 static inline void ice_eswitch_release(struct ice_pf *pf) { }
 
+static inline void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf) { }
+
 static inline void ice_eswitch_update_repr(struct ice_vsi *vsi) { }
 
 static inline int ice_eswitch_configure(struct ice_pf *pf)
        return -EOPNOTSUPP;
 }
 
+static inline int ice_eswitch_rebuild(struct ice_pf *pf)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int ice_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 {
        return DEVLINK_ESWITCH_MODE_LEGACY;
 
  */
 #define CREATE_TRACE_POINTS
 #include "ice_trace.h"
+#include "ice_eswitch.h"
 
 #define DRV_SUMMARY    "Intel(R) Ethernet Connection E800 Series Linux Driver"
 static const char ice_driver_string[] = DRV_SUMMARY;
        /* Caller of this function is expected to set the
         * vsi->state ICE_DOWN bit
         */
-       if (vsi->netdev) {
+       if (vsi->netdev && vsi->type == ICE_VSI_PF) {
                netif_carrier_off(vsi->netdev);
                netif_tx_disable(vsi->netdev);
+       } else if (vsi->type == ICE_VSI_SWITCHDEV_CTRL) {
+               ice_eswitch_stop_all_tx_queues(vsi->back);
        }
 
        ice_vsi_dis_irq(vsi);
                goto err_vsi_rebuild;
        }
 
+       err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
+       if (err) {
+               dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
+               goto err_vsi_rebuild;
+       }
+
        /* If Flow Director is active */
        if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) {
                err = ice_vsi_rebuild_by_type(pf, ICE_VSI_CTRL);
 
        }
 }
 
+/**
+ * ice_repr_start_tx_queues - start Tx queues of port representor
+ * @repr: pointer to repr structure
+ */
+void ice_repr_start_tx_queues(struct ice_repr *repr)
+{
+       netif_carrier_on(repr->netdev);
+       netif_tx_start_all_queues(repr->netdev);
+}
+
+/**
+ * ice_repr_stop_tx_queues - stop Tx queues of port representor
+ * @repr: pointer to repr structure
+ */
+void ice_repr_stop_tx_queues(struct ice_repr *repr)
+{
+       netif_carrier_off(repr->netdev);
+       netif_tx_stop_all_queues(repr->netdev);
+}
+
 /**
  * ice_repr_set_traffic_vsi - set traffic VSI for port representor
  * @repr: repr on with VSI will be set
 
 int ice_repr_add_for_all_vfs(struct ice_pf *pf);
 void ice_repr_rem_from_all_vfs(struct ice_pf *pf);
 
+void ice_repr_start_tx_queues(struct ice_repr *repr);
+void ice_repr_stop_tx_queues(struct ice_repr *repr);
+
 void ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi);
 
 struct ice_repr *ice_netdev_to_repr(struct net_device *netdev);
 
                ice_vf_post_vsi_rebuild(vf);
        }
 
+       if (ice_is_eswitch_mode_switchdev(pf))
+               if (ice_eswitch_rebuild(pf))
+                       dev_warn(dev, "eswitch rebuild failed\n");
+
        ice_flush(hw);
        clear_bit(ICE_VF_DIS, pf->state);