+
+int
+mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable)
+{
+ struct mlx5_vdpa_virtq *virtq = &priv->virtqs[index];
+ int ret;
+
+ DRV_LOG(INFO, "Update virtq %d status %sable -> %sable.", index,
+ virtq->enable ? "en" : "dis", enable ? "en" : "dis");
+ if (virtq->enable == !!enable)
+ return 0;
+ if (!priv->configured) {
+ virtq->enable = !!enable;
+ return 0;
+ }
+ if (enable) {
+ /* Configuration might have been updated - reconfigure virtq. */
+ if (virtq->virtq) {
+ ret = mlx5_vdpa_virtq_stop(priv, index);
+ if (ret)
+ DRV_LOG(WARNING, "Failed to stop virtq %d.",
+ index);
+ mlx5_vdpa_virtq_unset(virtq);
+ }
+ ret = mlx5_vdpa_virtq_setup(priv, index);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to setup virtq %d.", index);
+ return ret;
+ /* The only case virtq can stay invalid. */
+ }
+ }
+ virtq->enable = !!enable;
+ if (is_virtq_recvq(virtq->index, priv->nr_virtqs)) {
+ /* Need to add received virtq to the RQT table of the TIRs. */
+ ret = mlx5_vdpa_steer_update(priv);
+ if (ret) {
+ virtq->enable = !enable;
+ return ret;
+ }
+ }
+ return 0;
+}