&ioc->scsi_lookup_lock);
 }
 
+/**
+ * _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using
+ *   Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle, unused in this function, for function type match
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+       u16 handle)
+{
+       Mpi26AtomicRequestDescriptor_t descriptor;
+       u32 *request = (u32 *)&descriptor;
+
+       descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
+       descriptor.MSIxIndex = _base_get_msix_index(ioc);
+       descriptor.SMID = cpu_to_le16(smid);
+
+       writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
+ * _base_put_smid_fast_path_atomic - send fast path request to firmware
+ * using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle, unused in this function, for function type match
+ * Return nothing
+ */
+static void
+_base_put_smid_fast_path_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+       u16 handle)
+{
+       Mpi26AtomicRequestDescriptor_t descriptor;
+       u32 *request = (u32 *)&descriptor;
+
+       descriptor.RequestFlags = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
+       descriptor.MSIxIndex = _base_get_msix_index(ioc);
+       descriptor.SMID = cpu_to_le16(smid);
+
+       writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
+ * _base_put_smid_hi_priority_atomic - send Task Management request to
+ * firmware using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+       u16 msix_task)
+{
+       Mpi26AtomicRequestDescriptor_t descriptor;
+       u32 *request = (u32 *)&descriptor;
+
+       descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
+       descriptor.MSIxIndex = msix_task;
+       descriptor.SMID = cpu_to_le16(smid);
+
+       writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
+ * _base_put_smid_default - Default, primarily used for config pages
+ * use Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_default_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+       Mpi26AtomicRequestDescriptor_t descriptor;
+       u32 *request = (u32 *)&descriptor;
+
+       descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+       descriptor.MSIxIndex = _base_get_msix_index(ioc);
+       descriptor.SMID = cpu_to_le16(smid);
+
+       writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
 /**
  * _base_display_OEMs_branding - Display branding string
  * @ioc: per adapter object
        if ((facts->IOCCapabilities &
              MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE) && (!reset_devices))
                ioc->rdpq_array_capable = 1;
+       if ((facts->IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ)
+           && ioc->is_aero_ioc)
+               ioc->atomic_desc_capable = 1;
        facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
        facts->IOCRequestFrameSize =
            le16_to_cpu(mpi_reply.IOCRequestFrameSize);
 
                break;
        }
-
-       ioc->put_smid_default = &_base_put_smid_default;
-       ioc->put_smid_fast_path = &_base_put_smid_fast_path;
-       ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
-       if (ioc->is_mcpu_endpoint)
-               ioc->put_smid_scsi_io = &_base_put_smid_mpi_ep_scsi_io;
-       else
-               ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
-
+       if (ioc->atomic_desc_capable) {
+               ioc->put_smid_default = &_base_put_smid_default_atomic;
+               ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic;
+               ioc->put_smid_fast_path =
+                               &_base_put_smid_fast_path_atomic;
+               ioc->put_smid_hi_priority =
+                               &_base_put_smid_hi_priority_atomic;
+       } else {
+               ioc->put_smid_default = &_base_put_smid_default;
+               ioc->put_smid_fast_path = &_base_put_smid_fast_path;
+               ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
+               if (ioc->is_mcpu_endpoint)
+                       ioc->put_smid_scsi_io =
+                               &_base_put_smid_mpi_ep_scsi_io;
+               else
+                       ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
+       }
        /*
         * These function pointers for other requests that don't
         * the require IEEE scatter gather elements.