diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index f12e344..79c8eaa 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -39,5 +39,6 @@ sources = files('roc_dev.c',
 		'roc_npc_parse.c',
 		'roc_npc_utils.c',
 		'roc_platform.c',
+		'roc_sso.c',
 		'roc_utils.c')
 includes += include_directories('../../bus/pci')
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index 8dc8eed..b7fc3b7 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -88,6 +88,9 @@
 /* NIX */
 #include "roc_nix.h"
 
+/* SSO */
+#include "roc_sso.h"
+
 /* Utils */
 #include "roc_utils.h"
 
diff --git a/drivers/common/cnxk/roc_idev.c b/drivers/common/cnxk/roc_idev.c
index a92ac6a..63cc040 100644
--- a/drivers/common/cnxk/roc_idev.c
+++ b/drivers/common/cnxk/roc_idev.c
@@ -29,6 +29,7 @@ idev_get_cfg(void)
 void
 idev_set_defaults(struct idev_cfg *idev)
 {
+	idev->sso_pf_func = 0;
 	idev->npa = NULL;
 	idev->npa_pf_func = 0;
 	idev->max_pools = 128;
@@ -39,6 +40,32 @@ idev_set_defaults(struct idev_cfg *idev)
 }
 
 uint16_t
+idev_sso_pffunc_get(void)
+{
+	struct idev_cfg *idev;
+	uint16_t sso_pf_func;
+
+	idev = idev_get_cfg();
+	sso_pf_func = 0;
+	if (idev != NULL)
+		sso_pf_func = __atomic_load_n(&idev->sso_pf_func,
+					      __ATOMIC_ACQUIRE);
+
+	return sso_pf_func;
+}
+
+void
+idev_sso_pffunc_set(uint16_t sso_pf_func)
+{
+	struct idev_cfg *idev;
+
+	idev = idev_get_cfg();
+	if (idev != NULL)
+		__atomic_store_n(&idev->sso_pf_func, sso_pf_func,
+				 __ATOMIC_RELEASE);
+}
+
+uint16_t
 idev_npa_pffunc_get(void)
 {
 	struct idev_cfg *idev;
diff --git a/drivers/common/cnxk/roc_idev_priv.h b/drivers/common/cnxk/roc_idev_priv.h
index 36cdb33..ff10a90 100644
--- a/drivers/common/cnxk/roc_idev_priv.h
+++ b/drivers/common/cnxk/roc_idev_priv.h
@@ -8,6 +8,7 @@
 /* Intra device related functions */
 struct npa_lf;
 struct idev_cfg {
+	uint16_t sso_pf_func;
 	uint16_t npa_pf_func;
 	struct npa_lf *npa;
 	uint16_t npa_refcnt;
@@ -28,6 +29,10 @@ uint32_t idev_npa_maxpools_get(void);
 void idev_npa_maxpools_set(uint32_t max_pools);
 uint16_t idev_npa_lf_active(struct dev *dev);
 
+/* idev sso */
+void idev_sso_pffunc_set(uint16_t sso_pf_func);
+uint16_t idev_sso_pffunc_get(void);
+
 /* idev lmt */
 uint16_t idev_lmt_pffunc_get(void);
 
diff --git a/drivers/common/cnxk/roc_nix.c b/drivers/common/cnxk/roc_nix.c
index d6b288f..23d508b 100644
--- a/drivers/common/cnxk/roc_nix.c
+++ b/drivers/common/cnxk/roc_nix.c
@@ -143,6 +143,7 @@ roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, uint32_t nb_txq,
 	req->rss_sz = nix->reta_sz;
 	req->rss_grps = ROC_NIX_RSS_GRPS;
 	req->npa_func = idev_npa_pffunc_get();
+	req->sso_func = idev_sso_pffunc_get();
 	req->rx_cfg = rx_cfg;
 
 	if (!roc_nix->rss_tag_as_xor)
diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index 35c8fb1..17822f6 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -58,4 +58,5 @@ RTE_LOG_REGISTER(cnxk_logtype_mbox, pmd.cnxk.mbox, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npa, pmd.mempool.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_nix, pmd.net.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npc, pmd.net.cnxk.flow, NOTICE);
+RTE_LOG_REGISTER(cnxk_logtype_sso, pmd.event.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_tm, pmd.net.cnxk.tm, NOTICE);
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index ab9f9cb..13636e4 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -137,6 +137,7 @@ extern int cnxk_logtype_mbox;
 extern int cnxk_logtype_npa;
 extern int cnxk_logtype_nix;
 extern int cnxk_logtype_npc;
+extern int cnxk_logtype_sso;
 extern int cnxk_logtype_tm;
 
 #define plt_err(fmt, args...)                                                  \
@@ -158,6 +159,7 @@ extern int cnxk_logtype_tm;
 #define plt_npa_dbg(fmt, ...)	plt_dbg(npa, fmt, ##__VA_ARGS__)
 #define plt_nix_dbg(fmt, ...)	plt_dbg(nix, fmt, ##__VA_ARGS__)
 #define plt_npc_dbg(fmt, ...)	plt_dbg(npc, fmt, ##__VA_ARGS__)
+#define plt_sso_dbg(fmt, ...)	plt_dbg(sso, fmt, ##__VA_ARGS__)
 #define plt_tm_dbg(fmt, ...)	plt_dbg(tm, fmt, ##__VA_ARGS__)
 
 #ifdef __cplusplus
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
index 2dcd9e7..dd9d87a 100644
--- a/drivers/common/cnxk/roc_priv.h
+++ b/drivers/common/cnxk/roc_priv.h
@@ -26,4 +26,7 @@
 /* NPC */
 #include "roc_npc_priv.h"
 
+/* SSO */
+#include "roc_sso_priv.h"
+
 #endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_sso.c b/drivers/common/cnxk/roc_sso.c
new file mode 100644
index 0000000..6875b08
--- /dev/null
+++ b/drivers/common/cnxk/roc_sso.c
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+/* Private functions. */
+static int
+sso_lf_alloc(struct roc_sso *roc_sso, enum sso_lf_type lf_type, uint16_t nb_lf,
+	     void **rsp)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
+	int rc = -ENOSPC;
+
+	switch (lf_type) {
+	case SSO_LF_TYPE_HWS: {
+		struct ssow_lf_alloc_req *req;
+
+		req = mbox_alloc_msg_ssow_lf_alloc(dev->mbox);
+		if (req == NULL)
+			return rc;
+		req->hws = nb_lf;
+	} break;
+	case SSO_LF_TYPE_HWGRP: {
+		struct sso_lf_alloc_req *req;
+
+		req = mbox_alloc_msg_sso_lf_alloc(dev->mbox);
+		if (req == NULL)
+			return rc;
+		req->hwgrps = nb_lf;
+	} break;
+	default:
+		break;
+	}
+
+	rc = mbox_process_msg(dev->mbox, rsp);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static int
+sso_lf_free(struct roc_sso *roc_sso, enum sso_lf_type lf_type, uint16_t nb_lf)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
+	int rc = -ENOSPC;
+
+	switch (lf_type) {
+	case SSO_LF_TYPE_HWS: {
+		struct ssow_lf_free_req *req;
+
+		req = mbox_alloc_msg_ssow_lf_free(dev->mbox);
+		if (req == NULL)
+			return rc;
+		req->hws = nb_lf;
+	} break;
+	case SSO_LF_TYPE_HWGRP: {
+		struct sso_lf_free_req *req;
+
+		req = mbox_alloc_msg_sso_lf_free(dev->mbox);
+		if (req == NULL)
+			return rc;
+		req->hwgrps = nb_lf;
+	} break;
+	default:
+		break;
+	}
+
+	rc = mbox_process(dev->mbox);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static int
+sso_rsrc_attach(struct roc_sso *roc_sso, enum sso_lf_type lf_type,
+		uint16_t nb_lf)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
+	struct rsrc_attach_req *req;
+	int rc = -ENOSPC;
+
+	req = mbox_alloc_msg_attach_resources(dev->mbox);
+	if (req == NULL)
+		return rc;
+	switch (lf_type) {
+	case SSO_LF_TYPE_HWS:
+		req->ssow = nb_lf;
+		break;
+	case SSO_LF_TYPE_HWGRP:
+		req->sso = nb_lf;
+		break;
+	default:
+		return SSO_ERR_PARAM;
+	}
+
+	req->modify = true;
+	if (mbox_process(dev->mbox) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int
+sso_rsrc_detach(struct roc_sso *roc_sso, enum sso_lf_type lf_type)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
+	struct rsrc_detach_req *req;
+	int rc = -ENOSPC;
+
+	req = mbox_alloc_msg_detach_resources(dev->mbox);
+	if (req == NULL)
+		return rc;
+	switch (lf_type) {
+	case SSO_LF_TYPE_HWS:
+		req->ssow = true;
+		break;
+	case SSO_LF_TYPE_HWGRP:
+		req->sso = true;
+		break;
+	default:
+		return SSO_ERR_PARAM;
+	}
+
+	req->partial = true;
+	if (mbox_process(dev->mbox) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int
+sso_rsrc_get(struct roc_sso *roc_sso)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
+	struct free_rsrcs_rsp *rsrc_cnt;
+	int rc;
+
+	mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
+	rc = mbox_process_msg(dev->mbox, (void **)&rsrc_cnt);
+	if (rc < 0) {
+		plt_err("Failed to get free resource count\n");
+		return rc;
+	}
+
+	roc_sso->max_hwgrp = rsrc_cnt->sso;
+	roc_sso->max_hws = rsrc_cnt->ssow;
+
+	return 0;
+}
+
+int
+roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
+{
+	struct sso_lf_alloc_rsp *rsp_hwgrp;
+	int rc;
+
+	if (roc_sso->max_hwgrp < nb_hwgrp)
+		return -ENOENT;
+	if (roc_sso->max_hws < nb_hws)
+		return -ENOENT;
+
+	rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
+	if (rc < 0) {
+		plt_err("Unable to attach SSO HWS LFs");
+		return rc;
+	}
+
+	rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp);
+	if (rc < 0) {
+		plt_err("Unable to attach SSO HWGRP LFs");
+		goto hwgrp_atch_fail;
+	}
+
+	rc = sso_lf_alloc(roc_sso, SSO_LF_TYPE_HWS, nb_hws, NULL);
+	if (rc < 0) {
+		plt_err("Unable to alloc SSO HWS LFs");
+		goto hws_alloc_fail;
+	}
+
+	rc = sso_lf_alloc(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp,
+			  (void **)&rsp_hwgrp);
+	if (rc < 0) {
+		plt_err("Unable to alloc SSO HWGRP Lfs");
+		goto hwgrp_alloc_fail;
+	}
+
+	roc_sso->xaq_buf_size = rsp_hwgrp->xaq_buf_size;
+	roc_sso->xae_waes = rsp_hwgrp->xaq_wq_entries;
+	roc_sso->iue = rsp_hwgrp->in_unit_entries;
+
+	roc_sso->nb_hwgrp = nb_hwgrp;
+	roc_sso->nb_hws = nb_hws;
+
+	return 0;
+hwgrp_alloc_fail:
+	sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
+hws_alloc_fail:
+	sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
+hwgrp_atch_fail:
+	sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
+	return rc;
+}
+
+void
+roc_sso_rsrc_fini(struct roc_sso *roc_sso)
+{
+	if (!roc_sso->nb_hws && !roc_sso->nb_hwgrp)
+		return;
+
+	sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, roc_sso->nb_hws);
+	sso_lf_free(roc_sso, SSO_LF_TYPE_HWGRP, roc_sso->nb_hwgrp);
+
+	sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
+	sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
+
+	roc_sso->nb_hwgrp = 0;
+	roc_sso->nb_hws = 0;
+}
+
+int
+roc_sso_dev_init(struct roc_sso *roc_sso)
+{
+	struct plt_pci_device *pci_dev;
+	struct sso *sso;
+	int rc;
+
+	if (roc_sso == NULL || roc_sso->pci_dev == NULL)
+		return SSO_ERR_PARAM;
+
+	PLT_STATIC_ASSERT(sizeof(struct sso) <= ROC_SSO_MEM_SZ);
+	sso = roc_sso_to_sso_priv(roc_sso);
+	memset(sso, 0, sizeof(*sso));
+	pci_dev = roc_sso->pci_dev;
+
+	rc = dev_init(&sso->dev, pci_dev);
+	if (rc < 0) {
+		plt_err("Failed to init roc device");
+		goto fail;
+	}
+
+	rc = sso_rsrc_get(roc_sso);
+	if (rc < 0) {
+		plt_err("Failed to get SSO resources");
+		goto rsrc_fail;
+	}
+	rc = -ENOMEM;
+
+	idev_sso_pffunc_set(sso->dev.pf_func);
+	sso->pci_dev = pci_dev;
+	sso->dev.drv_inited = true;
+	roc_sso->lmt_base = sso->dev.lmt_base;
+
+	return 0;
+rsrc_fail:
+	rc |= dev_fini(&sso->dev, pci_dev);
+fail:
+	return rc;
+}
+
+int
+roc_sso_dev_fini(struct roc_sso *roc_sso)
+{
+	struct sso *sso;
+
+	sso = roc_sso_to_sso_priv(roc_sso);
+	sso->dev.drv_inited = false;
+
+	return dev_fini(&sso->dev, sso->pci_dev);
+}
diff --git a/drivers/common/cnxk/roc_sso.h b/drivers/common/cnxk/roc_sso.h
new file mode 100644
index 0000000..4f37f14
--- /dev/null
+++ b/drivers/common/cnxk/roc_sso.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_SSO_H_
+#define _ROC_SSO_H_
+
+struct roc_sso {
+	struct plt_pci_device *pci_dev;
+	/* Public data. */
+	uint16_t max_hwgrp;
+	uint16_t max_hws;
+	uint16_t nb_hwgrp;
+	uint8_t nb_hws;
+	uintptr_t lmt_base;
+	/* HW Const. */
+	uint32_t xae_waes;
+	uint32_t xaq_buf_size;
+	uint32_t iue;
+	/* Private data. */
+#define ROC_SSO_MEM_SZ (16 * 1024)
+	uint8_t reserved[ROC_SSO_MEM_SZ] __plt_cache_aligned;
+} __plt_cache_aligned;
+
+/* SSO device initialization */
+int __roc_api roc_sso_dev_init(struct roc_sso *roc_sso);
+int __roc_api roc_sso_dev_fini(struct roc_sso *roc_sso);
+
+/* SSO device configuration */
+int __roc_api roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws,
+				uint16_t nb_hwgrp);
+void __roc_api roc_sso_rsrc_fini(struct roc_sso *roc_sso);
+
+#endif /* _ROC_SSOW_H_ */
diff --git a/drivers/common/cnxk/roc_sso_priv.h b/drivers/common/cnxk/roc_sso_priv.h
new file mode 100644
index 0000000..1ab3f5b
--- /dev/null
+++ b/drivers/common/cnxk/roc_sso_priv.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_SSO_PRIV_H_
+#define _ROC_SSO_PRIV_H_
+
+struct sso_rsrc {
+	uint16_t rsrc_id;
+	uint64_t base;
+};
+
+struct sso {
+	struct plt_pci_device *pci_dev;
+	struct dev dev;
+} __plt_cache_aligned;
+
+enum sso_err_status {
+	SSO_ERR_PARAM = -4096,
+};
+
+enum sso_lf_type {
+	SSO_LF_TYPE_HWS,
+	SSO_LF_TYPE_HWGRP,
+};
+
+static inline struct sso *
+roc_sso_to_sso_priv(struct roc_sso *roc_sso)
+{
+	return (struct sso *)&roc_sso->reserved[0];
+}
+
+#endif /* _ROC_SSO_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_utils.c b/drivers/common/cnxk/roc_utils.c
index 236b4ae..542252f 100644
--- a/drivers/common/cnxk/roc_utils.c
+++ b/drivers/common/cnxk/roc_utils.c
@@ -15,6 +15,7 @@ roc_error_msg_get(int errorcode)
 	case NIX_ERR_PARAM:
 	case NPA_ERR_PARAM:
 	case NPC_ERR_PARAM:
+	case SSO_ERR_PARAM:
 	case UTIL_ERR_PARAM:
 		err_msg = "Invalid parameter";
 		break;
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index ed82b56..054c6bd 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -6,6 +6,7 @@ INTERNAL {
 	cnxk_logtype_nix;
 	cnxk_logtype_npa;
 	cnxk_logtype_npc;
+	cnxk_logtype_sso;
 	cnxk_logtype_tm;
 	roc_clk_freq_get;
 	roc_error_msg_get;
@@ -172,6 +173,10 @@ INTERNAL {
 	roc_npc_profile_name_get;
 	roc_plt_init;
 	roc_plt_init_cb_register;
+	roc_sso_dev_fini;
+	roc_sso_dev_init;
+	roc_sso_rsrc_fini;
+	roc_sso_rsrc_init;
 
 	local: *;
 };
