diff --git a/platform/linux-keystone2/include/odp/plat/state.h b/platform/linux-keystone2/include/odp/plat/state.h
index 63428cb..0f8304a 100644
--- a/platform/linux-keystone2/include/odp/plat/state.h
+++ b/platform/linux-keystone2/include/odp/plat/state.h
@@ -25,6 +25,7 @@ struct odp_global_s {
 		nwal_Inst         handle;     /**< NWAL handle */
 		Pktlib_HeapHandle sa2pa_heap; /**< Internal SA->PA heap */
 		Pktlib_HeapHandle pa2sa_heap; /**< Internal PA->SA head */
+		nwalGlobCxtInfo_t info;       /**< NWAL global info */
 	} nwal;                 /**< Global NWAL state */
 	Qmss_MemRegion public_desc_memregion;
 };
@@ -35,6 +36,7 @@ struct odp_proc_s {
 		Pktlib_HeapHandle netcp_heap;            /**< internal default heap */
 		Pktlib_HeapHandle netcp_control_rx_heap; /**< rx control messages */
 		Pktlib_HeapHandle netcp_control_tx_heap; /**< tx control messages */
+		void *context_buffer; /**< NWAL internal process context */
 	} nwal;                         /**< Per process NWAL state */
 	Rm_ServiceHandle *rm_service;   /**< Resource Manager service handle */
 	void *descriptor_mem_base;
diff --git a/platform/linux-keystone2/include/odp/plat/ti_mcsdk.h b/platform/linux-keystone2/include/odp/plat/ti_mcsdk.h
index b8e002a..d0bc5af 100644
--- a/platform/linux-keystone2/include/odp/plat/ti_mcsdk.h
+++ b/platform/linux-keystone2/include/odp/plat/ti_mcsdk.h
@@ -27,7 +27,6 @@ extern "C" {
 /** @internal McSDK initialization configuration */
 struct mcsdk_cfg_s {
 	int def_mem_size;            /**<  Bytes of CMA memory we have allocated */
-	int min_buf_headroom_size;   /**<  Minimal amount of headroom in a buffer */
 	int def_max_descriptors;     /**<  Number of descriptors in system  (must be power of 2), 2^14 max */
 	int def_tot_descriptors_for_us; /**<  Number of descriptors to create in our region (must be power of 2)*/
 	int def_heap_n_descriptors;  /**<  Number of descriptor plus buffers in default heap*/
@@ -40,17 +39,22 @@ struct mcsdk_cfg_s {
 
 Rm_ServiceHandle *rm_client_init(void);
 int mcsdk_global_init(void);
+int mcsdk_global_term(void);
 int mcsdk_local_init(int thread_id);
 int mcsdk_cppi_init(void);
 int mcsdk_qmss_init(int max_descriptors);
 int mcsdk_qmss_start(void);
+int mcsdk_qmss_exit(void);
 int mcsdk_cppi_start(void);
+int mcsdk_cppi_exit(void);
 int mcsdk_qmss_setup_memregion(uint32_t desc_num, uint32_t desc_size,
 		uint32_t *desc_mem_base);
+int mcsdk_qmss_remove_memregion(void);
 int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table);
 int mcsdk_nwal_start(Pktlib_HeapHandle pkt_heap,
 		     Pktlib_HeapHandle cmd_rx_heap,
 		     Pktlib_HeapHandle cmd_tx_heap);
+int mcsdk_delete_heap(Pktlib_HeapHandle heap);
 
 extern Pktlib_HeapIfTable  pktlib_if_table;
 extern hplib_virtualAddrInfo_T odp_vm_info;
diff --git a/platform/linux-keystone2/mcsdk/mcsdk_init.c b/platform/linux-keystone2/mcsdk/mcsdk_init.c
index 2c1407a..d7b5406 100644
--- a/platform/linux-keystone2/mcsdk/mcsdk_init.c
+++ b/platform/linux-keystone2/mcsdk/mcsdk_init.c
@@ -39,7 +39,6 @@ struct mcsdk_cfg_s default_mcsdk_cfg = {
 	.def_heap_buf_size = TUNE_NETAPI_DEFAULT_BUFFER_SIZE,
 	.def_heap_tailroom_size = 0,
 	.def_heap_extra_size = 0,
-	.min_buf_headroom_size = ODP_CACHE_LINE_SIZE,
 };
 
 /**
@@ -108,9 +107,7 @@ static uint8_t *cma_mem_alloc(uint32_t size)
 
 static void cma_mem_free(uint8_t *ptr ODP_UNUSED, uint32_t size ODP_UNUSED)
 {
-	/* Do Nothing. */
-	odp_pr_err("need to provide a free () for some reason!!\n");
-	return;
+	hplib_vmMemFree(ptr, size + odp_global->cfg.def_heap_extra_size, 0);
 }
 
 /********************************************************************
@@ -263,57 +260,42 @@ int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table)
 	count = 0;
 	bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr(
 			(uint32_t)nwal_entry->nwal_inst_mem);
-	if (NWAL_CONFIG_BUFSIZE_HANDLE < sizes[nwal_BUF_INDEX_INST]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CONFIG_BUFSIZE_HANDLE >= sizes[nwal_BUF_INDEX_INST],
+		   "Not enough space");
 	count++;
 
 	bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr(
 			(uint32_t)nwal_entry->nwal_handle_mem);
-	if (NWAL_CHAN_HANDLE_SIZE < sizes[nwal_BUF_INDEX_INT_HANDLES]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CHAN_HANDLE_SIZE >= sizes[nwal_BUF_INDEX_INT_HANDLES],
+		   "Not enough space");
 	count++;
 	bases[nwal_BUF_INDEX_PA_LLD_BUF0] = (uint32_t *)Osal_nwalLocToGlobAddr(
 			(uint32_t)pa_entry->pa_buf0);
-	if ((NWAL_CONFIG_BUFSIZE_PA_BUF0) < sizes[nwal_BUF_INDEX_PA_LLD_BUF0]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CONFIG_BUFSIZE_PA_BUF0 >=
+			sizes[nwal_BUF_INDEX_PA_LLD_BUF0],
+		   "Not enough space");
 	count++;
 
 	bases[nwal_BUF_INDEX_PA_LLD_BUF1] = (uint32_t *)Osal_nwalLocToGlobAddr(
 			(uint32_t)pa_entry->pa_buf1);
-	if ((NWAL_CONFIG_BUFSIZE_PA_BUF1) < sizes[nwal_BUF_INDEX_PA_LLD_BUF1]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CONFIG_BUFSIZE_PA_BUF1 >=
+			sizes[nwal_BUF_INDEX_PA_LLD_BUF1],
+		   "Not enough space");
 	count++;
 
 	bases[nwal_BUF_INDEX_PA_LLD_BUF2] = (uint32_t *)Osal_nwalLocToGlobAddr(
 			(uint32_t)pa_entry->pa_buf2);
-	if ((NWAL_CONFIG_BUFSIZE_PA_BUF2) < sizes[nwal_BUF_INDEX_PA_LLD_BUF2]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CONFIG_BUFSIZE_PA_BUF2 >=
+			sizes[nwal_BUF_INDEX_PA_LLD_BUF2],
+		   "Not enough space");
 	count++;
 #ifdef NETAPI_ENABLE_SECURITY
 	bases[nwal_BUF_INDEX_SA_LLD_HANDLE] =
 			(uint32_t *)Osal_nwalLocToGlobAddr(
 					(uint32_t)sa_entry->salld_handle);
-	if ((NWAL_CONFIG_BUFSIZE_SA_HANDLE)
-			< sizes[nwal_BUF_INDEX_SA_LLD_HANDLE]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT(NWAL_CONFIG_BUFSIZE_SA_HANDLE >=
+			sizes[nwal_BUF_INDEX_SA_LLD_HANDLE],
+		   "Not enough space");
 	count++;
 
 	bases[nwal_BUF_INDEX_SA_CONTEXT] = (uint32_t *)Osal_nwalLocToGlobAddr(
@@ -325,13 +307,10 @@ int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table)
 	bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] =
 			(uint32_t *)Osal_nwalLocToGlobAddr(
 					(uint32_t)sa_entry->salld_chan_handle);
-	if ((NWAL_CONFIG_BUFSIZE_SA_HANDLE_PER_CHAN
-			* TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS * 2)
-			< sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE]) {
-		/* Resize Memory */
-		while (1)
-			;
-	}
+	ODP_ASSERT((NWAL_CONFIG_BUFSIZE_SA_HANDLE_PER_CHAN
+			* TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS * 2) >=
+			sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE],
+		   "Not enough space");
 	count++;
 #else
 	bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = 0;
@@ -339,10 +318,7 @@ int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table)
 	bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = 0;
 	count = count+3;
 #endif
-	if (count != nwal_N_BUFS) {
-		while (1)
-			;
-	}
+	ODP_ASSERT(count == nwal_N_BUFS, "count == nwal_N_BUFS");
 
 	nwal_getLocContextBufferReq(nwal_size_info.nProc, &local_ctx_size);
 	nwal_loc_ctx_mem = malloc(local_ctx_size);
@@ -350,6 +326,7 @@ int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table)
 		odp_pr_err("Couldn't allocate NWAL local contex\n");
 		return -1;
 	}
+	odp_proc.nwal.context_buffer = nwal_loc_ctx_mem;
 	nwal_ret = nwal_createProc(bases[nwal_BUF_INDEX_INST],
 				   nwal_loc_ctx_mem,
 				   &base_addr_cfg);
@@ -366,8 +343,14 @@ int mcsdk_nwal_init(int region2use, Pktlib_HeapIfTable *p_table)
 		odp_pr_err("nwal_create Failed %d\n", nwal_ret);
 		return -1;
 	}
-
 	odp_pr_dbg("Global and Local Network initialization Successful\n");
+
+	nwal_ret = nwal_getGlobCxtInfo(odp_global->nwal.handle,
+				       &odp_global->nwal.info);
+	if (nwal_ret != nwal_OK) {
+		odp_pr_err("Couldn't get global NWAL info: %d\n", nwal_ret);
+		return -1;
+	}
 	return 1;
 }
 
@@ -388,7 +371,7 @@ int mcsdk_nwal_start(Pktlib_HeapHandle pkt_heap, Pktlib_HeapHandle cmd_rx_heap,
 	 * Update the Start of Packet Offset for the default flows created
 	 * by NWAL
 	 */
-	nwal_local_cfg.rxSopPktOffset = odp_global->cfg.min_buf_headroom_size;
+	nwal_local_cfg.rxSopPktOffset = 0;
 	nwal_local_cfg.rxPktTailRoomSz = odp_global->cfg.def_heap_tailroom_size;
 
 	/* Call back registration for the core */
@@ -665,6 +648,67 @@ int mcsdk_global_init(void)
 	return 0;
 }
 
+int mcsdk_delete_heap(Pktlib_HeapHandle heap)
+{
+	int32_t err_code = 0, ret;
+
+	ret = Pktlib_deleteHeap(heap, &err_code);
+
+	if (ret < 0) {
+		odp_pr_err("Pktlib_deleteHeap failed ret: %d, err: %d",
+			   ret, err_code);
+		return -1;
+	}
+
+	return 0;
+}
+
+int mcsdk_global_term(void)
+{
+	nwal_RetValue nwal_ret;
+	hplib_RetValue hplib_ret;
+
+	nwal_ret = nwal_delete(odp_global->nwal.handle);
+	if (nwal_ret != nwal_OK) {
+		odp_pr_err("nwal_delete_failed: %d", nwal_ret);
+		return -1;
+	}
+
+	/* close heaps */
+	mcsdk_delete_heap(odp_proc.nwal.netcp_heap);
+	mcsdk_delete_heap(odp_proc.nwal.netcp_control_rx_heap);
+	mcsdk_delete_heap(odp_proc.nwal.netcp_control_tx_heap);
+	mcsdk_delete_heap(odp_global->nwal.pa2sa_heap);
+	mcsdk_delete_heap(odp_global->nwal.sa2pa_heap);
+
+	free(odp_proc.nwal.context_buffer);
+	odp_proc.nwal.context_buffer = NULL;
+
+	/**
+	 * @todo: NWAL doesn't close CPPI handles so Cppi_exit fails. NWAL
+	 * should be fixed.
+	 *
+	 * mcsdk_cppi_exit();
+	 */
+	mcsdk_qmss_remove_memregion();
+	mcsdk_qmss_exit();
+
+	hplib_ret = hplib_resetMallocArea(0);
+	if (hplib_ret != hplib_OK)
+		odp_pr_err("hplib_resetMallocArea() failed for pool 0: %d\n",
+			   hplib_ret);
+	hplib_ret = hplib_resetMallocArea(1);
+	if (hplib_ret != hplib_OK)
+		odp_pr_err("hplib_resetMallocArea() failed for pool 1: %d\n",
+			   hplib_ret);
+	hplib_vmTeardown();
+	hplib_shmDelete();
+	if (hplib_ret != hplib_OK)
+		odp_pr_err("hplib_shmDelete() failed: %d\n", hplib_ret);
+
+	return 0;
+}
+
 int mcsdk_local_init(int thread_id)
 {
 	int ret;
diff --git a/platform/linux-keystone2/mcsdk/mcsdk_navig.c b/platform/linux-keystone2/mcsdk/mcsdk_navig.c
index c3009b7..146068c 100644
--- a/platform/linux-keystone2/mcsdk/mcsdk_navig.c
+++ b/platform/linux-keystone2/mcsdk/mcsdk_navig.c
@@ -94,6 +94,17 @@ int mcsdk_cppi_init(void)
 	return 1;
 }
 
+int mcsdk_cppi_exit(void)
+{
+	Cppi_Result result;
+	result = Cppi_exit();
+	if (result != CPPI_SOK) {
+		odp_pr_err("Cppi_exit failed with error code %d\n", result);
+		return -1;
+	}
+	return 1;
+}
+
 /*****************************************************************************
  * FUNCTION PURPOSE: Global Initialization of Queue Manager. Once Per System
  *****************************************************************************
@@ -202,6 +213,17 @@ int mcsdk_qmss_init(int max_descriptors)
 	return 1;
 }
 
+int mcsdk_qmss_exit(void)
+{
+	Qmss_Result result;
+	result = Qmss_exit();
+	if (result != QMSS_SOK) {
+		odp_pr_err("Qmss_exit failed with error code %d\n", result);
+		return -1;
+	}
+	return 1;
+}
+
 /********************************************************************
  * FUNCTION PURPOSE:  Internal NETAPI function to start QM
  ********************************************************************
@@ -267,3 +289,16 @@ int mcsdk_qmss_setup_memregion(uint32_t desc_num, uint32_t desc_size,
 
 	return 1;
 }
+
+int mcsdk_qmss_remove_memregion(void)
+{
+	Qmss_Result result;
+	result = Qmss_removeMemoryRegion(odp_global->public_desc_memregion,
+					 QMSS_PARAM_NOT_SPECIFIED);
+	if (result != QMSS_SOK) {
+		odp_pr_err("Qmss_removeMemoryRegion failed with error code %d\n",
+			   result);
+		return -1;
+	}
+	return 1;
+}
diff --git a/platform/linux-keystone2/odp_init.c b/platform/linux-keystone2/odp_init.c
index 1fde2ce..86df7fe 100644
--- a/platform/linux-keystone2/odp_init.c
+++ b/platform/linux-keystone2/odp_init.c
@@ -81,7 +81,7 @@ int odp_init_global(odp_init_t *params ODP_UNUSED,
 
 int odp_term_global(void)
 {
-	ODP_UNIMPLEMENTED();
+	mcsdk_global_term();
 	return 0;
 }
 
@@ -116,6 +116,5 @@ int odp_init_local(void)
 
 int odp_term_local(void)
 {
-	ODP_UNIMPLEMENTED();
-	return 0;
+	return (odp_thread_term_local() > 0) ? 1 : 0;
 }
