diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
index b48a881..4e29e29 100644
--- a/drivers/misc/xilinx_sdfec.c
+++ b/drivers/misc/xilinx_sdfec.c
@@ -201,6 +201,7 @@ struct xsdfec_clks {
  * @dev: pointer to device struct
  * @state: State of the SDFEC device
  * @config: Configuration of the SDFEC device
+ * @intr_enabled: indicates IRQ enabled
  * @state_updated: indicates State updated by interrupt handler
  * @stats_updated: indicates Stats updated by interrupt handler
  * @isr_err_count: Count of ISR errors
@@ -220,6 +221,7 @@ struct xsdfec_dev {
        struct device *dev;
        enum xsdfec_state state;
        struct xsdfec_config config;
+       bool intr_enabled;
        bool state_updated;
        bool stats_updated;
        atomic_t isr_err_count;
@@ -323,6 +325,28 @@ static int xsdfec_dev_release(struct inode *iptr, struct file *fptr)
        return 0;
 }

+static int xsdfec_get_status(struct xsdfec_dev *xsdfec, void __user *arg)
+{
+       struct xsdfec_status status;
+       int err;
+
+       status.fec_id = xsdfec->config.fec_id;
+       spin_lock_irq(&xsdfec->irq_lock);
+       status.state = xsdfec->state;
+       xsdfec->state_updated = false;
+       spin_unlock_irq(&xsdfec->irq_lock);
+       status.activity = (xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR) &
+                          XSDFEC_IS_ACTIVITY_SET);
+
+       err = copy_to_user(arg, &status, sizeof(status));
+       if (err) {
+               dev_err(xsdfec->dev, "%s failed for SDFEC%d", __func__,
+                       xsdfec->config.fec_id);
+               err = -EFAULT;
+       }
+       return err;
+}
+
 static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg)
 {
        int err;
@@ -908,6 +932,83 @@ static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec)
        return 0;
 }

+static int xsdfec_start(struct xsdfec_dev *xsdfec)
+{
+       u32 regread;
+
+       regread = xsdfec_regread(xsdfec, XSDFEC_FEC_CODE_ADDR);
+       regread &= 0x1;
+       if (regread != xsdfec->config.code) {
+               dev_err(xsdfec->dev,
+                       "%s SDFEC HW code does not match driver code, reg %d, code %d",
+                       __func__, regread, xsdfec->config.code);
+               return -EINVAL;
+       }
+
+       /* Set AXIS enable */
+       xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR,
+                       XSDFEC_AXIS_ENABLE_MASK);
+       /* Done */
+       xsdfec->state = XSDFEC_STARTED;
+       return 0;
+}
+
+static int xsdfec_stop(struct xsdfec_dev *xsdfec)
+{
+       u32 regread;
+
+       if (xsdfec->state != XSDFEC_STARTED)
+               dev_err(xsdfec->dev, "Device not started correctly");
+       /* Disable AXIS_ENABLE Input interfaces only */
+       regread = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR);
+       regread &= (~XSDFEC_AXIS_IN_ENABLE_MASK);
+       xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR, regread);
+       /* Stop */
+       xsdfec->state = XSDFEC_STOPPED;
+       return 0;
+}
+
+static int xsdfec_clear_stats(struct xsdfec_dev *xsdfec)
+{
+       atomic_set(&xsdfec->isr_err_count, 0);
+       atomic_set(&xsdfec->uecc_count, 0);
+       atomic_set(&xsdfec->cecc_count, 0);
+
+       return 0;
+}
+
+static int xsdfec_get_stats(struct xsdfec_dev *xsdfec, void __user *arg)
+{
+       int err;
+       struct xsdfec_stats user_stats;
+
+       spin_lock_irq(&xsdfec->irq_lock);
+       user_stats.isr_err_count = atomic_read(&xsdfec->isr_err_count);
+       user_stats.cecc_count = atomic_read(&xsdfec->cecc_count);
+       user_stats.uecc_count = atomic_read(&xsdfec->uecc_count);
+       xsdfec->stats_updated = false;
+       spin_unlock_irq(&xsdfec->irq_lock);
+
+       err = copy_to_user(arg, &user_stats, sizeof(user_stats));
+       if (err) {
+               dev_err(xsdfec->dev, "%s failed for SDFEC%d", __func__,
+                       xsdfec->config.fec_id);
+               err = -EFAULT;
+       }
+
+       return err;
+}
+
+static int xsdfec_set_default_config(struct xsdfec_dev *xsdfec)
+{
+       /* Ensure registers are aligned with core configuration */
+       xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code);
+       xsdfec_cfg_axi_streams(xsdfec);
+       update_config_from_hw(xsdfec);
+
+       return 0;
+}
+
 static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
                             unsigned long data)
 {
@@ -919,6 +1020,15 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
        if (!xsdfec)
                return rval;

+       /* In failed state allow only reset and get status IOCTLs */
+       if (xsdfec->state == XSDFEC_NEEDS_RESET &&
+           (cmd != XSDFEC_SET_DEFAULT_CONFIG && cmd != XSDFEC_GET_STATUS &&
+            cmd != XSDFEC_GET_STATS && cmd != XSDFEC_CLEAR_STATS)) {
+               dev_err(xsdfec->dev, "SDFEC%d in failed state. Reset Required",
+                       xsdfec->config.fec_id);
+               return -EPERM;
+       }
+
        if (_IOC_TYPE(cmd) != XSDFEC_MAGIC) {
                dev_err(xsdfec->dev, "Not a xilinx sdfec ioctl");
                return -ENOTTY;
@@ -946,9 +1056,27 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
        }

        switch (cmd) {
+       case XSDFEC_START_DEV:
+               rval = xsdfec_start(xsdfec);
+               break;
+       case XSDFEC_STOP_DEV:
+               rval = xsdfec_stop(xsdfec);
+               break;
+       case XSDFEC_CLEAR_STATS:
+               rval = xsdfec_clear_stats(xsdfec);
+               break;
+       case XSDFEC_GET_STATS:
+               rval = xsdfec_get_stats(xsdfec, arg);
+               break;
+       case XSDFEC_GET_STATUS:
+               rval = xsdfec_get_status(xsdfec, arg);
+               break;
        case XSDFEC_GET_CONFIG:
                rval = xsdfec_get_config(xsdfec, arg);
                break;
+       case XSDFEC_SET_DEFAULT_CONFIG:
+               rval = xsdfec_set_default_config(xsdfec);
+               break;
        case XSDFEC_SET_IRQ:
                rval = xsdfec_set_irq(xsdfec, arg);
                break;
diff --git a/include/uapi/misc/xilinx_sdfec.h b/include/uapi/misc/xilinx_sdfec.h
index 8dfada9..df47995 100644
--- a/include/uapi/misc/xilinx_sdfec.h
+++ b/include/uapi/misc/xilinx_sdfec.h
@@ -235,6 +235,21 @@ struct xsdfec_config {
 };

 /**
+ * struct xsdfec_stats - Stats retrived by ioctl XSDFEC_GET_STATS. Used
+ *                      to buffer atomic_t variables from struct
+ *                      xsdfec_dev. Counts are accumulated until
+ *                      the user clears them.
+ * @isr_err_count: Count of ISR errors
+ * @cecc_count: Count of Correctable ECC errors (SBE)
+ * @uecc_count: Count of Uncorrectable ECC errors (MBE)
+ */
+struct xsdfec_stats {
+       u32 isr_err_count;
+       u32 cecc_count;
+       u32 uecc_count;
+};
+
+/**
  * struct xsdfec_ldpc_param_table_sizes - Used to store sizes of SD-FEC table
  *                                       entries for an individual LPDC code
  *                                       parameter.
@@ -274,6 +289,32 @@ xsdfec_calculate_shared_ldpc_table_entry_size(struct xsdfec_ldpc_params *ldpc,
  */
 #define XSDFEC_MAGIC 'f'
 /**
+ * DOC: XSDFEC_START_DEV
+ *
+ * @Description
+ *
+ * ioctl to start SD-FEC core
+ *
+ * This fails if the XSDFEC_SET_ORDER ioctl has not been previously called
+ */
+#define XSDFEC_START_DEV _IO(XSDFEC_MAGIC, 0)
+/**
+ * DOC: XSDFEC_STOP_DEV
+ *
+ * @Description
+ *
+ * ioctl to stop the SD-FEC core
+ */
+#define XSDFEC_STOP_DEV _IO(XSDFEC_MAGIC, 1)
+/**
+ * DOC: XSDFEC_GET_STATUS
+ *
+ * @Description
+ *
+ * ioctl that returns status of SD-FEC core
+ */
+#define XSDFEC_GET_STATUS _IOR(XSDFEC_MAGIC, 2, struct xsdfec_status *)
+/**
  * DOC: XSDFEC_SET_IRQ
  * @Parameters
  *
@@ -392,4 +433,38 @@ xsdfec_calculate_shared_ldpc_table_entry_size(struct xsdfec_ldpc_params *ldpc,
  * ioctl that determines if SD-FEC is processing data
  */
 #define XSDFEC_IS_ACTIVE _IOR(XSDFEC_MAGIC, 10, bool *)
+/**
+ * DOC: XSDFEC_CLEAR_STATS
+ *
+ * @Description
+ *
+ * ioctl that clears error stats collected during interrupts
+ */
+#define XSDFEC_CLEAR_STATS _IO(XSDFEC_MAGIC, 11)
+/**
+ * DOC: XSDFEC_GET_STATS
+ * @Parameters
+ *
+ * @struct xsdfec_stats *
+ *     Pointer to the &struct xsdfec_stats that will contain the updated stats
+ *     values
+ *
+ * @Description
+ *
+ * ioctl that returns SD-FEC core stats
+ *
+ * This can only be used when the driver is in the XSDFEC_STOPPED state
+ */
+#define XSDFEC_GET_STATS _IOR(XSDFEC_MAGIC, 12, struct xsdfec_stats *)
+/**
+ * DOC: XSDFEC_SET_DEFAULT_CONFIG
+ *
+ * @Description
+ *
+ * ioctl that returns SD-FEC core to default config, use after a reset
+ *
+ * This can only be used when the driver is in the XSDFEC_STOPPED state
+ */
+#define XSDFEC_SET_DEFAULT_CONFIG _IO(XSDFEC_MAGIC, 13)
+
 #endif /* __XILINX_SDFEC_H__ */
