xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
13184b1efSMike Baucom /* SPDX-License-Identifier: BSD-3-Clause
2d9e70b1dSRandy Schacher  * Copyright(c) 2019-2023 Broadcom
33184b1efSMike Baucom  * All rights reserved.
43184b1efSMike Baucom  */
53184b1efSMike Baucom 
63184b1efSMike Baucom #include <rte_common.h>
73184b1efSMike Baucom #include <rte_cycles.h>
83184b1efSMike Baucom #include <rte_malloc.h>
93184b1efSMike Baucom #include <rte_log.h>
103184b1efSMike Baucom #include <rte_alarm.h>
113184b1efSMike Baucom #include "bnxt.h"
123184b1efSMike Baucom #include "bnxt_ulp.h"
130c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h"
14dd0191d5SShuanglin Wang #include "bnxt_ulp_tf.h"
153184b1efSMike Baucom #include "bnxt_tf_common.h"
163184b1efSMike Baucom #include "ulp_ha_mgr.h"
173184b1efSMike Baucom #include "ulp_flow_db.h"
183184b1efSMike Baucom 
193184b1efSMike Baucom /* Local only MACROs and defines that aren't exported */
203184b1efSMike Baucom #define ULP_HA_TIMER_THREAD	(1 << 0)
213184b1efSMike Baucom #define ULP_HA_TIMER_IS_RUNNING(info) (!!((info)->flags & ULP_HA_TIMER_THREAD))
223184b1efSMike Baucom #define ULP_HA_TIMER_SEC 1
233184b1efSMike Baucom #define ULP_HA_WAIT_TIME (MS_PER_S / 10)
243184b1efSMike Baucom #define ULP_HA_WAIT_TIMEOUT (MS_PER_S * 2)
253184b1efSMike Baucom 
263184b1efSMike Baucom #define ULP_HA_IF_TBL_DIR	TF_DIR_RX
273184b1efSMike Baucom #define ULP_HA_IF_TBL_TYPE	TF_IF_TBL_TYPE_PROF_PARIF_ERR_ACT_REC_PTR
283184b1efSMike Baucom 
29ba6fa50aSKishore Padmanabha static void ulp_ha_mgr_timer_cancel(struct bnxt_ulp_context *ulp_ctx);
30bf598786SKishore Padmanabha static int32_t ulp_ha_mgr_timer_start(void *arg);
313184b1efSMike Baucom static void ulp_ha_mgr_timer_cb(void *arg);
323184b1efSMike Baucom static int32_t ulp_ha_mgr_app_type_set(struct bnxt_ulp_context *ulp_ctx,
333184b1efSMike Baucom 				enum ulp_ha_mgr_app_type app_type);
343184b1efSMike Baucom static int32_t
353184b1efSMike Baucom ulp_ha_mgr_region_set(struct bnxt_ulp_context *ulp_ctx,
363184b1efSMike Baucom 		      enum ulp_ha_mgr_region region);
373184b1efSMike Baucom static int32_t
383184b1efSMike Baucom ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,
393184b1efSMike Baucom 		     enum ulp_ha_mgr_state state);
403184b1efSMike Baucom 
413184b1efSMike Baucom static int32_t
421993b267SShahaji Bhosle ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx, uint32_t *cnt);
431993b267SShahaji Bhosle 
441993b267SShahaji Bhosle static int32_t
456d160d77SRandy Schacher ulp_ha_mgr_state_set_v1(struct bnxt_ulp_context *ulp_ctx,
463184b1efSMike Baucom 			enum ulp_ha_mgr_state state)
473184b1efSMike Baucom {
483184b1efSMike Baucom 	struct tf_set_if_tbl_entry_parms set_parms = { 0 };
493184b1efSMike Baucom 	struct tf *tfp;
503184b1efSMike Baucom 	uint32_t val = 0;
513184b1efSMike Baucom 	int32_t rc = 0;
523184b1efSMike Baucom 
533184b1efSMike Baucom 	if (ulp_ctx == NULL) {
54dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms in state get.\n");
553184b1efSMike Baucom 		return -EINVAL;
563184b1efSMike Baucom 	}
57d9e70b1dSRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
583184b1efSMike Baucom 	if (tfp == NULL) {
59dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
603184b1efSMike Baucom 		return -EINVAL;
613184b1efSMike Baucom 	}
623184b1efSMike Baucom 
633184b1efSMike Baucom 	val = (uint32_t)state;
643184b1efSMike Baucom 
653184b1efSMike Baucom 	set_parms.dir = ULP_HA_IF_TBL_DIR;
663184b1efSMike Baucom 	set_parms.type = ULP_HA_IF_TBL_TYPE;
673184b1efSMike Baucom 	set_parms.data = (uint8_t *)&val;
683184b1efSMike Baucom 	set_parms.data_sz_in_bytes = sizeof(val);
69dd0191d5SShuanglin Wang 	set_parms.idx = bnxt_ulp_cntxt_ha_reg_state_get(ulp_ctx);
703184b1efSMike Baucom 
713184b1efSMike Baucom 	rc = tf_set_if_tbl_entry(tfp, &set_parms);
723184b1efSMike Baucom 	if (rc)
73dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to write the HA state\n");
743184b1efSMike Baucom 
753184b1efSMike Baucom 	return rc;
763184b1efSMike Baucom }
773184b1efSMike Baucom 
783184b1efSMike Baucom static int32_t
796d160d77SRandy Schacher ulp_ha_mgr_state_set_v2(struct bnxt_ulp_context *ulp_ctx,
806d160d77SRandy Schacher 			enum ulp_ha_mgr_state state)
816d160d77SRandy Schacher {
826d160d77SRandy Schacher 	struct tf_set_session_hotup_state_parms parms = { 0 };
836d160d77SRandy Schacher 	struct tf *tfp;
846d160d77SRandy Schacher 	int32_t rc = 0;
856d160d77SRandy Schacher 
866d160d77SRandy Schacher 	if (ulp_ctx == NULL) {
87dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms in state get.\n");
886d160d77SRandy Schacher 		return -EINVAL;
896d160d77SRandy Schacher 	}
906d160d77SRandy Schacher 
916d160d77SRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_SHARED_WC);
926d160d77SRandy Schacher 	if (tfp == NULL) {
93dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
946d160d77SRandy Schacher 		return -EINVAL;
956d160d77SRandy Schacher 	}
966d160d77SRandy Schacher 
976d160d77SRandy Schacher 	parms.state = (uint16_t)state;
986d160d77SRandy Schacher 	rc = tf_set_session_hotup_state(tfp, &parms);
996d160d77SRandy Schacher 	if (rc) {
100dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to write the HA state\n");
1016d160d77SRandy Schacher 		return rc;
1026d160d77SRandy Schacher 	}
1036d160d77SRandy Schacher 
1046d160d77SRandy Schacher 	return rc;
1056d160d77SRandy Schacher }
1066d160d77SRandy Schacher 
1076d160d77SRandy Schacher static int32_t
1086d160d77SRandy Schacher ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,
1096d160d77SRandy Schacher 		     enum ulp_ha_mgr_state state)
1106d160d77SRandy Schacher {
1116d160d77SRandy Schacher 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))
1126d160d77SRandy Schacher 		return ulp_ha_mgr_state_set_v2(ulp_ctx, state);
1136d160d77SRandy Schacher 	else
1146d160d77SRandy Schacher 		return ulp_ha_mgr_state_set_v1(ulp_ctx, state);
1156d160d77SRandy Schacher }
1166d160d77SRandy Schacher 
1176d160d77SRandy Schacher static int32_t
1186d160d77SRandy Schacher ulp_ha_mgr_tf_state_get(struct bnxt_ulp_context *ulp_ctx,
1196d160d77SRandy Schacher 			uint32_t *state,
1206d160d77SRandy Schacher 			uint32_t *cnt)
1216d160d77SRandy Schacher {
1226d160d77SRandy Schacher 	struct tf_get_session_hotup_state_parms parms = { 0 };
1236d160d77SRandy Schacher 	struct tf *tfp;
1246d160d77SRandy Schacher 	int32_t rc = 0;
1256d160d77SRandy Schacher 
1266d160d77SRandy Schacher 	if (ulp_ctx == NULL) {
127dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms in client num get.\n");
1286d160d77SRandy Schacher 		return -EINVAL;
1296d160d77SRandy Schacher 	}
1306d160d77SRandy Schacher 
1316d160d77SRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_SHARED_WC);
1326d160d77SRandy Schacher 	if (tfp == NULL) {
133dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
1346d160d77SRandy Schacher 		return -EINVAL;
1356d160d77SRandy Schacher 	}
1366d160d77SRandy Schacher 
1376d160d77SRandy Schacher 	rc = tf_get_session_hotup_state(tfp, &parms);
1386d160d77SRandy Schacher 	if (rc) {
139dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to read the HA state\n");
1406d160d77SRandy Schacher 		return rc;
1416d160d77SRandy Schacher 	}
1426d160d77SRandy Schacher 
1436d160d77SRandy Schacher 	if (state)
1446d160d77SRandy Schacher 		*state = parms.state;
1456d160d77SRandy Schacher 
1466d160d77SRandy Schacher 	if (cnt)
1476d160d77SRandy Schacher 		*cnt = parms.ref_cnt;
1486d160d77SRandy Schacher 
1496d160d77SRandy Schacher 	return rc;
1506d160d77SRandy Schacher }
1516d160d77SRandy Schacher 
1526d160d77SRandy Schacher static int32_t
1536d160d77SRandy Schacher ulp_ha_mgr_tf_client_num_get_v1(struct bnxt_ulp_context *ulp_ctx,
1541993b267SShahaji Bhosle 				uint32_t *cnt)
1551993b267SShahaji Bhosle {
1561993b267SShahaji Bhosle 	struct tf_get_if_tbl_entry_parms get_parms = { 0 };
1571993b267SShahaji Bhosle 	struct tf *tfp;
1581993b267SShahaji Bhosle 	uint32_t val = 0;
1591993b267SShahaji Bhosle 	int32_t rc = 0;
1601993b267SShahaji Bhosle 
1611993b267SShahaji Bhosle 	if (ulp_ctx == NULL || cnt == NULL) {
162dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms in client num get.\n");
1631993b267SShahaji Bhosle 		return -EINVAL;
1641993b267SShahaji Bhosle 	}
165d9e70b1dSRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
1661993b267SShahaji Bhosle 	if (tfp == NULL) {
167dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
1681993b267SShahaji Bhosle 		return -EINVAL;
1691993b267SShahaji Bhosle 	}
1701993b267SShahaji Bhosle 
1711993b267SShahaji Bhosle 	get_parms.dir = ULP_HA_IF_TBL_DIR;
1721993b267SShahaji Bhosle 	get_parms.type = ULP_HA_IF_TBL_TYPE;
173dd0191d5SShuanglin Wang 	get_parms.idx = bnxt_ulp_cntxt_ha_reg_cnt_get(ulp_ctx);
1741993b267SShahaji Bhosle 	get_parms.data = (uint8_t *)&val;
1751993b267SShahaji Bhosle 	get_parms.data_sz_in_bytes = sizeof(val);
1761993b267SShahaji Bhosle 
1771993b267SShahaji Bhosle 	rc = tf_get_if_tbl_entry(tfp, &get_parms);
1781993b267SShahaji Bhosle 	if (rc)
179dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to read the number of HA clients\n");
1801993b267SShahaji Bhosle 
1811993b267SShahaji Bhosle 	*cnt = val;
1821993b267SShahaji Bhosle 	return rc;
1831993b267SShahaji Bhosle }
1841993b267SShahaji Bhosle 
1851993b267SShahaji Bhosle static int32_t
1866d160d77SRandy Schacher ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx,
1876d160d77SRandy Schacher 			     uint32_t *cnt)
1886d160d77SRandy Schacher {
1896d160d77SRandy Schacher 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))
1906d160d77SRandy Schacher 		return ulp_ha_mgr_tf_state_get(ulp_ctx, NULL, cnt);
1916d160d77SRandy Schacher 	else
1926d160d77SRandy Schacher 		return ulp_ha_mgr_tf_client_num_get_v1(ulp_ctx, cnt);
1936d160d77SRandy Schacher }
1946d160d77SRandy Schacher 
1956d160d77SRandy Schacher static int32_t
1963184b1efSMike Baucom ulp_ha_mgr_region_set(struct bnxt_ulp_context *ulp_ctx,
1973184b1efSMike Baucom 		      enum ulp_ha_mgr_region region)
1983184b1efSMike Baucom {
1993184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
2003184b1efSMike Baucom 
2013184b1efSMike Baucom 	if (ulp_ctx == NULL) {
202dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid params in ha region get.\n");
2033184b1efSMike Baucom 		return -EINVAL;
2043184b1efSMike Baucom 	}
2053184b1efSMike Baucom 
2063184b1efSMike Baucom 	ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
2073184b1efSMike Baucom 	if (ha_info == NULL) {
208dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get ha info\n");
2093184b1efSMike Baucom 		return -EINVAL;
2103184b1efSMike Baucom 	}
2113184b1efSMike Baucom 	ha_info->region = region;
2123184b1efSMike Baucom 
2133184b1efSMike Baucom 	return 0;
2143184b1efSMike Baucom }
2153184b1efSMike Baucom 
2163184b1efSMike Baucom static int32_t
2173184b1efSMike Baucom ulp_ha_mgr_app_type_set(struct bnxt_ulp_context *ulp_ctx,
2183184b1efSMike Baucom 			enum ulp_ha_mgr_app_type app_type)
2193184b1efSMike Baucom {
2203184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
2213184b1efSMike Baucom 
2223184b1efSMike Baucom 	if (ulp_ctx == NULL) {
223dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid Parms.\n");
2243184b1efSMike Baucom 		return -EINVAL;
2253184b1efSMike Baucom 	}
2263184b1efSMike Baucom 
2273184b1efSMike Baucom 	ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
2283184b1efSMike Baucom 	if (ha_info == NULL) {
229dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the ha info.\n");
2303184b1efSMike Baucom 		return -EINVAL;
2313184b1efSMike Baucom 	}
2323184b1efSMike Baucom 	ha_info->app_type = app_type;
2333184b1efSMike Baucom 
2343184b1efSMike Baucom 	return 0;
2353184b1efSMike Baucom }
2363184b1efSMike Baucom 
2373184b1efSMike Baucom static void
238bf598786SKishore Padmanabha ulp_ha_mgr_timer_cb(void *arg)
2393184b1efSMike Baucom {
2403184b1efSMike Baucom 	struct tf_move_tcam_shared_entries_parms mparms = { 0 };
2411993b267SShahaji Bhosle 	struct tf_clear_tcam_shared_entries_parms cparms = { 0 };
2423184b1efSMike Baucom 	struct bnxt_ulp_context *ulp_ctx;
2433184b1efSMike Baucom 	enum ulp_ha_mgr_state curr_state;
2441993b267SShahaji Bhosle 	enum ulp_ha_mgr_app_type app_type;
2451993b267SShahaji Bhosle 	uint8_t myclient_cnt = 0;
2461993b267SShahaji Bhosle 	uint32_t client_cnt = 0;
2473184b1efSMike Baucom 	struct tf *tfp;
2483184b1efSMike Baucom 	int32_t rc;
2493184b1efSMike Baucom 
250bf598786SKishore Padmanabha 	ulp_ctx = bnxt_ulp_cntxt_entry_acquire(arg);
251d75b5512SKishore Padmanabha 	if (ulp_ctx == NULL) {
252bf598786SKishore Padmanabha 		ulp_ha_mgr_timer_start(arg);
253d75b5512SKishore Padmanabha 		return;
254d75b5512SKishore Padmanabha 	}
255d75b5512SKishore Padmanabha 
2561993b267SShahaji Bhosle 	myclient_cnt = bnxt_ulp_cntxt_num_shared_clients_get(ulp_ctx);
2571993b267SShahaji Bhosle 	if (myclient_cnt == 0) {
258dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR,
2591993b267SShahaji Bhosle 			     "PANIC Client Count is zero kill timer\n.");
2601993b267SShahaji Bhosle 		return;
2611993b267SShahaji Bhosle 	}
2621993b267SShahaji Bhosle 
263d9e70b1dSRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_SHARED_WC);
2641993b267SShahaji Bhosle 	if (tfp == NULL) {
265dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
2661993b267SShahaji Bhosle 		goto cb_restart;
2671993b267SShahaji Bhosle 	}
2681993b267SShahaji Bhosle 
2693184b1efSMike Baucom 	rc = ulp_ha_mgr_state_get(ulp_ctx, &curr_state);
2703184b1efSMike Baucom 	if (rc) {
2713184b1efSMike Baucom 		/*
272f63aa27dSKishore Padmanabha 		 * This shouldn't happen, if it does, reset the timer
2733184b1efSMike Baucom 		 * and try again next time.
2743184b1efSMike Baucom 		 */
275dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed(%d) to get state.\n",
2761993b267SShahaji Bhosle 			     rc);
2773184b1efSMike Baucom 		goto cb_restart;
2783184b1efSMike Baucom 	}
2791993b267SShahaji Bhosle 
2801993b267SShahaji Bhosle 	rc = ulp_ha_mgr_tf_client_num_get(ulp_ctx, &client_cnt);
2811993b267SShahaji Bhosle 	if (rc) {
282dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed(%d) to get cnt.\n",
2831993b267SShahaji Bhosle 			     rc);
2841993b267SShahaji Bhosle 		goto cb_restart;
2851993b267SShahaji Bhosle 	}
2861993b267SShahaji Bhosle 
2871993b267SShahaji Bhosle 	rc =  ulp_ha_mgr_app_type_get(ulp_ctx, &app_type);
2881993b267SShahaji Bhosle 	if (rc) {
289dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed(%d) to get type.\n",
2901993b267SShahaji Bhosle 			     rc);
2911993b267SShahaji Bhosle 		goto cb_restart;
2921993b267SShahaji Bhosle 	}
2931993b267SShahaji Bhosle 
2941993b267SShahaji Bhosle 	/* Handle the Cleanup if an app went away */
2951993b267SShahaji Bhosle 	if (client_cnt == myclient_cnt) {
2961993b267SShahaji Bhosle 		if (curr_state == ULP_HA_STATE_PRIM_SEC_RUN &&
2971993b267SShahaji Bhosle 		    app_type == ULP_HA_APP_TYPE_PRIM) {
2981993b267SShahaji Bhosle 		    /*
2991993b267SShahaji Bhosle 		     * The SECONDARY went away:
3001993b267SShahaji Bhosle 		     * 1. Set the state to PRIM_RUN
3011993b267SShahaji Bhosle 		     * 2. Clear the High region so our TCAM will hit.
3021993b267SShahaji Bhosle 		     */
3031993b267SShahaji Bhosle 			rc = ulp_ha_mgr_state_set(ulp_ctx,
3041993b267SShahaji Bhosle 						  ULP_HA_STATE_PRIM_RUN);
3051993b267SShahaji Bhosle 			if (rc) {
306dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
3071993b267SShahaji Bhosle 					     "On HA CB:Failed(%d) to set state\n",
3081993b267SShahaji Bhosle 					     rc);
3091993b267SShahaji Bhosle 				goto cb_restart;
3101993b267SShahaji Bhosle 			}
3111993b267SShahaji Bhosle 
3121993b267SShahaji Bhosle 			cparms.dir = TF_DIR_RX;
3131993b267SShahaji Bhosle 			cparms.tcam_tbl_type =
3141993b267SShahaji Bhosle 				TF_TCAM_TBL_TYPE_WC_TCAM_HIGH;
3151993b267SShahaji Bhosle 			rc = tf_clear_tcam_shared_entries(tfp, &cparms);
3161993b267SShahaji Bhosle 			if (rc) {
317dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
3181993b267SShahaji Bhosle 					     "On HA CB:Failed(%d) clear tcam\n",
3191993b267SShahaji Bhosle 					     rc);
3201993b267SShahaji Bhosle 				goto cb_restart;
3211993b267SShahaji Bhosle 			}
3221993b267SShahaji Bhosle 		} else if (curr_state == ULP_HA_STATE_PRIM_SEC_RUN &&
3231993b267SShahaji Bhosle 			    app_type == ULP_HA_APP_TYPE_SEC) {
3241993b267SShahaji Bhosle 			/*
3251993b267SShahaji Bhosle 			 * The PRIMARY went away:
3261993b267SShahaji Bhosle 			 * 1. Set the state to SEC_COPY
3271993b267SShahaji Bhosle 			 * 2. Clear the Low Region for the next copy
3281993b267SShahaji Bhosle 			 */
3291993b267SShahaji Bhosle 			rc = ulp_ha_mgr_state_set(ulp_ctx,
3301993b267SShahaji Bhosle 						  ULP_HA_STATE_SEC_TIMER_COPY);
3311993b267SShahaji Bhosle 			if (rc) {
332dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
3331993b267SShahaji Bhosle 					     "On HA CB:Failed(%d) to set state\n",
3341993b267SShahaji Bhosle 					     rc);
3351993b267SShahaji Bhosle 				goto cb_restart;
3361993b267SShahaji Bhosle 			}
3371993b267SShahaji Bhosle 			curr_state = ULP_HA_STATE_SEC_TIMER_COPY;
3381993b267SShahaji Bhosle 		}
3391993b267SShahaji Bhosle 	}
3401993b267SShahaji Bhosle 
3411993b267SShahaji Bhosle 	/* Only the Secondary has work to on SEC_TIMER_COPY */
3421993b267SShahaji Bhosle 	if (curr_state != ULP_HA_STATE_SEC_TIMER_COPY ||
3431993b267SShahaji Bhosle 	    app_type != ULP_HA_APP_TYPE_SEC)
3443184b1efSMike Baucom 		goto cb_restart;
3453184b1efSMike Baucom 
3463184b1efSMike Baucom 	/* Protect the flow database during the copy */
3473184b1efSMike Baucom 	if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
3483184b1efSMike Baucom 		/* Should not fail, if we do, restart timer and try again */
349dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n");
3503184b1efSMike Baucom 		goto cb_restart;
3513184b1efSMike Baucom 	}
3523184b1efSMike Baucom 	/* All paths after this point must release the fdb lock */
3533184b1efSMike Baucom 
3543184b1efSMike Baucom 	/* The Primary has issued a close and we are in the timer copy
3553184b1efSMike Baucom 	 * phase.  Become the new Primary, Set state to Primary Run and
3563184b1efSMike Baucom 	 * move WC entries to Low Region.
3573184b1efSMike Baucom 	 */
358dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(INFO, "On HA CB: Moving entries HI to LOW\n");
3591993b267SShahaji Bhosle 
3601993b267SShahaji Bhosle 	cparms.dir = TF_DIR_RX;
3611993b267SShahaji Bhosle 	cparms.tcam_tbl_type = TF_TCAM_TBL_TYPE_WC_TCAM_LOW;
3621993b267SShahaji Bhosle 	rc = tf_clear_tcam_shared_entries(tfp, &cparms);
3631993b267SShahaji Bhosle 	if (rc) {
364dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR,
3651993b267SShahaji Bhosle 			     "On HA CB:Failed(%d) clear tcam low\n",
3661993b267SShahaji Bhosle 			     rc);
3673184b1efSMike Baucom 		goto unlock;
3683184b1efSMike Baucom 	}
3693184b1efSMike Baucom 
3701993b267SShahaji Bhosle 	mparms.dir = TF_DIR_RX;
3711993b267SShahaji Bhosle 	mparms.tcam_tbl_type = TF_TCAM_TBL_TYPE_WC_TCAM_HIGH;
3723184b1efSMike Baucom 	rc = tf_move_tcam_shared_entries(tfp, &mparms);
3733184b1efSMike Baucom 	if (rc) {
374dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "On HA_CB: Failed to move entries\n");
3753184b1efSMike Baucom 		goto unlock;
3763184b1efSMike Baucom 	}
3773184b1efSMike Baucom 
3783184b1efSMike Baucom 	ulp_ha_mgr_region_set(ulp_ctx, ULP_HA_REGION_LOW);
3793184b1efSMike Baucom 	ulp_ha_mgr_app_type_set(ulp_ctx, ULP_HA_APP_TYPE_PRIM);
3803184b1efSMike Baucom 	ulp_ha_mgr_state_set(ulp_ctx, ULP_HA_STATE_PRIM_RUN);
381dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(INFO, "On HA CB: SEC[SEC_TIMER_COPY] => PRIM[PRIM_RUN]\n");
3823184b1efSMike Baucom unlock:
3833184b1efSMike Baucom 	bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
3843184b1efSMike Baucom cb_restart:
385d75b5512SKishore Padmanabha 	bnxt_ulp_cntxt_entry_release();
386bf598786SKishore Padmanabha 	ulp_ha_mgr_timer_start(arg);
3873184b1efSMike Baucom }
3883184b1efSMike Baucom 
3893184b1efSMike Baucom static int32_t
390bf598786SKishore Padmanabha ulp_ha_mgr_timer_start(void *arg)
3913184b1efSMike Baucom {
3923184b1efSMike Baucom 	rte_eal_alarm_set(US_PER_S * ULP_HA_TIMER_SEC,
393bf598786SKishore Padmanabha 			  ulp_ha_mgr_timer_cb, arg);
3943184b1efSMike Baucom 	return 0;
3953184b1efSMike Baucom }
3963184b1efSMike Baucom 
3973184b1efSMike Baucom static void
398ba6fa50aSKishore Padmanabha ulp_ha_mgr_timer_cancel(struct bnxt_ulp_context *ulp_ctx)
3993184b1efSMike Baucom {
400ba6fa50aSKishore Padmanabha 	rte_eal_alarm_cancel(ulp_ha_mgr_timer_cb, ulp_ctx->cfg_data);
4013184b1efSMike Baucom }
4023184b1efSMike Baucom 
4033184b1efSMike Baucom int32_t
4043184b1efSMike Baucom ulp_ha_mgr_init(struct bnxt_ulp_context *ulp_ctx)
4053184b1efSMike Baucom {
4063184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
4073184b1efSMike Baucom 	int32_t rc;
4083184b1efSMike Baucom 	ha_info = rte_zmalloc("ulp_ha_mgr_info", sizeof(*ha_info), 0);
4093184b1efSMike Baucom 	if (!ha_info)
4103184b1efSMike Baucom 		return -ENOMEM;
4113184b1efSMike Baucom 
4123184b1efSMike Baucom 	/* Add the HA info tbl to the ulp context. */
4133184b1efSMike Baucom 	bnxt_ulp_cntxt_ptr2_ha_info_set(ulp_ctx, ha_info);
4143184b1efSMike Baucom 
415*7d32c003SAriel Otilibili 	pthread_mutex_init(&ha_info->ha_lock, NULL);
416bf598786SKishore Padmanabha 	rc = ulp_ha_mgr_timer_start(ulp_ctx->cfg_data);
4171993b267SShahaji Bhosle 	if (rc) {
418dd0191d5SShuanglin Wang 		PMD_DRV_LOG_LINE(ERR, "Unable to start timer CB");
4191993b267SShahaji Bhosle 		goto cleanup;
4201993b267SShahaji Bhosle 	}
4213184b1efSMike Baucom 
4223184b1efSMike Baucom 	return 0;
4233184b1efSMike Baucom cleanup:
4243184b1efSMike Baucom 	if (ha_info != NULL)
4253184b1efSMike Baucom 		ulp_ha_mgr_deinit(ulp_ctx);
4263184b1efSMike Baucom 	return -ENOMEM;
4273184b1efSMike Baucom }
4283184b1efSMike Baucom 
4293184b1efSMike Baucom void
4303184b1efSMike Baucom ulp_ha_mgr_deinit(struct bnxt_ulp_context *ulp_ctx)
4313184b1efSMike Baucom {
4323184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
4333184b1efSMike Baucom 
434ba6fa50aSKishore Padmanabha 	ulp_ha_mgr_timer_cancel(ulp_ctx);
4351993b267SShahaji Bhosle 
4363184b1efSMike Baucom 	ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
4373184b1efSMike Baucom 	if (ha_info == NULL) {
438dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get HA Info for deinit.\n");
4393184b1efSMike Baucom 		return;
4403184b1efSMike Baucom 	}
4413184b1efSMike Baucom 
4423184b1efSMike Baucom 	pthread_mutex_destroy(&ha_info->ha_lock);
4433184b1efSMike Baucom 	rte_free(ha_info);
4443184b1efSMike Baucom 
4453184b1efSMike Baucom 	bnxt_ulp_cntxt_ptr2_ha_info_set(ulp_ctx, NULL);
4463184b1efSMike Baucom }
4473184b1efSMike Baucom 
4483184b1efSMike Baucom int32_t
4493184b1efSMike Baucom ulp_ha_mgr_app_type_get(struct bnxt_ulp_context *ulp_ctx,
4503184b1efSMike Baucom 			enum ulp_ha_mgr_app_type *app_type)
4513184b1efSMike Baucom {
4523184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
4533184b1efSMike Baucom 
4543184b1efSMike Baucom 	if (ulp_ctx == NULL || app_type == NULL) {
455dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid Parms.\n");
4563184b1efSMike Baucom 		return -EINVAL;
4573184b1efSMike Baucom 	}
4583184b1efSMike Baucom 
4593184b1efSMike Baucom 	ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
4603184b1efSMike Baucom 	if (ha_info == NULL) {
461dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the HA info.\n");
4623184b1efSMike Baucom 		return -EINVAL;
4633184b1efSMike Baucom 	}
4643184b1efSMike Baucom 	*app_type = ha_info->app_type;
4653184b1efSMike Baucom 
4663184b1efSMike Baucom 	return 0;
4673184b1efSMike Baucom }
4683184b1efSMike Baucom 
4696d160d77SRandy Schacher static int32_t
4706d160d77SRandy Schacher ulp_ha_mgr_state_get_v1(struct bnxt_ulp_context *ulp_ctx,
4713184b1efSMike Baucom 			enum ulp_ha_mgr_state *state)
4723184b1efSMike Baucom {
4733184b1efSMike Baucom 	struct tf_get_if_tbl_entry_parms get_parms = { 0 };
4743184b1efSMike Baucom 	struct tf *tfp;
4753184b1efSMike Baucom 	uint32_t val = 0;
4763184b1efSMike Baucom 	int32_t rc = 0;
4773184b1efSMike Baucom 
4783184b1efSMike Baucom 	if (ulp_ctx == NULL || state == NULL) {
479dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms in state get.\n");
4803184b1efSMike Baucom 		return -EINVAL;
4813184b1efSMike Baucom 	}
482d9e70b1dSRandy Schacher 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
4833184b1efSMike Baucom 	if (tfp == NULL) {
484dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the TFP.\n");
4853184b1efSMike Baucom 		return -EINVAL;
4863184b1efSMike Baucom 	}
4873184b1efSMike Baucom 
4883184b1efSMike Baucom 	get_parms.dir = ULP_HA_IF_TBL_DIR;
4893184b1efSMike Baucom 	get_parms.type = ULP_HA_IF_TBL_TYPE;
490dd0191d5SShuanglin Wang 	get_parms.idx = bnxt_ulp_cntxt_ha_reg_state_get(ulp_ctx);
4913184b1efSMike Baucom 	get_parms.data = (uint8_t *)&val;
4923184b1efSMike Baucom 	get_parms.data_sz_in_bytes = sizeof(val);
4933184b1efSMike Baucom 
4943184b1efSMike Baucom 	rc = tf_get_if_tbl_entry(tfp, &get_parms);
4953184b1efSMike Baucom 	if (rc)
496dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to read the HA state\n");
4973184b1efSMike Baucom 
4983184b1efSMike Baucom 	*state = val;
4993184b1efSMike Baucom 	return rc;
5003184b1efSMike Baucom }
5013184b1efSMike Baucom 
5023184b1efSMike Baucom int32_t
5036d160d77SRandy Schacher ulp_ha_mgr_state_get(struct bnxt_ulp_context *ulp_ctx,
5046d160d77SRandy Schacher 		     enum ulp_ha_mgr_state *state)
5056d160d77SRandy Schacher {
5066d160d77SRandy Schacher 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))
5076d160d77SRandy Schacher 		return ulp_ha_mgr_tf_state_get(ulp_ctx, state, NULL);
5086d160d77SRandy Schacher 	else
5096d160d77SRandy Schacher 		return ulp_ha_mgr_state_get_v1(ulp_ctx, state);
5106d160d77SRandy Schacher }
5116d160d77SRandy Schacher 
5126d160d77SRandy Schacher int32_t
5133184b1efSMike Baucom ulp_ha_mgr_open(struct bnxt_ulp_context *ulp_ctx)
5143184b1efSMike Baucom {
5153184b1efSMike Baucom 	enum ulp_ha_mgr_state curr_state;
5163184b1efSMike Baucom 	int32_t rc;
5173184b1efSMike Baucom 
5183184b1efSMike Baucom 	rc = ulp_ha_mgr_state_get(ulp_ctx, &curr_state);
5193184b1efSMike Baucom 	if (rc) {
520dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get HA state on Open (%d)\n", rc);
5213184b1efSMike Baucom 		return -EINVAL;
5223184b1efSMike Baucom 	}
5233184b1efSMike Baucom 
5243184b1efSMike Baucom 	/*
5253184b1efSMike Baucom 	 * An Open can only occur during the Init and Primary Run states. During
5263184b1efSMike Baucom 	 * Init, the system attempting to Open will become the only system
5273184b1efSMike Baucom 	 * running. During Primary Run, the system attempting to Open will
5283184b1efSMike Baucom 	 * become the secondary system temporarily, and should eventually be
5293184b1efSMike Baucom 	 * transitioned to the primary system.
5303184b1efSMike Baucom 	 */
5313184b1efSMike Baucom 	switch (curr_state) {
5323184b1efSMike Baucom 	case ULP_HA_STATE_INIT:
5333184b1efSMike Baucom 		/*
5343184b1efSMike Baucom 		 * No system is running, as we are the primary.  Since no other
5353184b1efSMike Baucom 		 * system is running, we start writing into the low region.  By
5363184b1efSMike Baucom 		 * writing into the low region, we save room for the secondary
5373184b1efSMike Baucom 		 * system to override our entries by using the high region.
5383184b1efSMike Baucom 		 */
5393184b1efSMike Baucom 		ulp_ha_mgr_app_type_set(ulp_ctx, ULP_HA_APP_TYPE_PRIM);
5403184b1efSMike Baucom 		ulp_ha_mgr_region_set(ulp_ctx, ULP_HA_REGION_LOW);
5413184b1efSMike Baucom 		rc = ulp_ha_mgr_state_set(ulp_ctx, ULP_HA_STATE_PRIM_RUN);
5423184b1efSMike Baucom 		if (rc) {
543dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "On Open: Failed to set PRIM_RUN.\n");
5443184b1efSMike Baucom 			return -EINVAL;
5453184b1efSMike Baucom 		}
5463184b1efSMike Baucom 
547dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Open: [INIT] => PRIM[PRIM_RUN]\n");
5483184b1efSMike Baucom 		break;
5493184b1efSMike Baucom 	case ULP_HA_STATE_PRIM_RUN:
5503184b1efSMike Baucom 		/*
5513184b1efSMike Baucom 		 * The secondary system is starting in order to take over.
5523184b1efSMike Baucom 		 * The current primary is expected to eventually close and pass
5533184b1efSMike Baucom 		 * full control to this system;however, until the primary closes
5543184b1efSMike Baucom 		 * both are operational.
5553184b1efSMike Baucom 		 */
5563184b1efSMike Baucom 		ulp_ha_mgr_app_type_set(ulp_ctx, ULP_HA_APP_TYPE_SEC);
5573184b1efSMike Baucom 		ulp_ha_mgr_region_set(ulp_ctx, ULP_HA_REGION_HI);
5583184b1efSMike Baucom 
5593184b1efSMike Baucom 		rc = ulp_ha_mgr_state_set(ulp_ctx, ULP_HA_STATE_PRIM_SEC_RUN);
5603184b1efSMike Baucom 		if (rc) {
561dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "On Open: Failed to set PRIM_SEC_RUN\n");
5623184b1efSMike Baucom 			return -EINVAL;
5633184b1efSMike Baucom 		}
564dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Open: [PRIM_RUN] => [PRIM_SEC_RUN]\n");
5653184b1efSMike Baucom 		break;
5663184b1efSMike Baucom 	default:
567dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "On Open: Unknown state 0x%x\n", curr_state);
5683184b1efSMike Baucom 		return -EINVAL;
5693184b1efSMike Baucom 	}
5703184b1efSMike Baucom 
5713184b1efSMike Baucom 	return 0;
5723184b1efSMike Baucom }
5733184b1efSMike Baucom 
5743184b1efSMike Baucom int32_t
5753184b1efSMike Baucom ulp_ha_mgr_close(struct bnxt_ulp_context *ulp_ctx)
5763184b1efSMike Baucom {
5773184b1efSMike Baucom 	enum ulp_ha_mgr_state curr_state, next_state, poll_state;
5783184b1efSMike Baucom 	enum ulp_ha_mgr_app_type app_type;
5793184b1efSMike Baucom 	int32_t timeout;
5803184b1efSMike Baucom 	int32_t rc;
5813184b1efSMike Baucom 
5821993b267SShahaji Bhosle 	curr_state = ULP_HA_STATE_INIT;
5831993b267SShahaji Bhosle 	app_type = ULP_HA_APP_TYPE_NONE;
5843184b1efSMike Baucom 	rc = ulp_ha_mgr_state_get(ulp_ctx, &curr_state);
5853184b1efSMike Baucom 	if (rc) {
586dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "On Close: Failed(%d) to get HA state\n", rc);
5873184b1efSMike Baucom 		return -EINVAL;
5883184b1efSMike Baucom 	}
5893184b1efSMike Baucom 
5903184b1efSMike Baucom 	rc = ulp_ha_mgr_app_type_get(ulp_ctx, &app_type);
5913184b1efSMike Baucom 	if (rc) {
592dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "On Close: Failed to get the app type.\n");
5933184b1efSMike Baucom 		return -EINVAL;
5943184b1efSMike Baucom 	}
5953184b1efSMike Baucom 
5963184b1efSMike Baucom 	if (curr_state == ULP_HA_STATE_PRIM_RUN &&
5973184b1efSMike Baucom 	    app_type == ULP_HA_APP_TYPE_PRIM) {
5983184b1efSMike Baucom 		/*
5993184b1efSMike Baucom 		 * Only the primary is running, so a close effectively moves the
6003184b1efSMike Baucom 		 * system back to INIT.
6013184b1efSMike Baucom 		 */
6023184b1efSMike Baucom 		next_state = ULP_HA_STATE_INIT;
6033184b1efSMike Baucom 		ulp_ha_mgr_state_set(ulp_ctx, next_state);
604dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Close: PRIM[PRIM_RUN] => [INIT]\n");
6053184b1efSMike Baucom 	} else if (curr_state == ULP_HA_STATE_PRIM_SEC_RUN &&
6063184b1efSMike Baucom 		  app_type == ULP_HA_APP_TYPE_PRIM) {
6073184b1efSMike Baucom 		/*
6083184b1efSMike Baucom 		 * While both are running, the primary received a close.
6093184b1efSMike Baucom 		 * Cleanup the flows, set the COPY state, and wait for the
6103184b1efSMike Baucom 		 * secondary to become the Primary.
6113184b1efSMike Baucom 		 */
612dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO,
6133184b1efSMike Baucom 			     "On Close: PRIM[PRIM_SEC_RUN] flushing flows.\n");
6143184b1efSMike Baucom 
6153184b1efSMike Baucom 		ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
6163184b1efSMike Baucom 		ulp_ha_mgr_state_set(ulp_ctx, ULP_HA_STATE_SEC_TIMER_COPY);
6173184b1efSMike Baucom 
6183184b1efSMike Baucom 		/*
6193184b1efSMike Baucom 		 * TODO: This needs to be bounded in case the other system does
6203184b1efSMike Baucom 		 * not move to PRIM_RUN.
6213184b1efSMike Baucom 		 */
622dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO,
6233184b1efSMike Baucom 			     "On Close: PRIM[PRIM_SEC_RUN] => [Copy], enter wait.\n");
6243184b1efSMike Baucom 		timeout = ULP_HA_WAIT_TIMEOUT;
6253184b1efSMike Baucom 		do {
6263184b1efSMike Baucom 			rte_delay_ms(ULP_HA_WAIT_TIME);
6273184b1efSMike Baucom 			rc = ulp_ha_mgr_state_get(ulp_ctx, &poll_state);
6283184b1efSMike Baucom 			if (rc) {
629dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
6303184b1efSMike Baucom 					     "Failed to get HA state on Close (%d)\n",
6313184b1efSMike Baucom 					     rc);
6323184b1efSMike Baucom 				goto cleanup;
6333184b1efSMike Baucom 			}
6343184b1efSMike Baucom 			timeout -= ULP_HA_WAIT_TIME;
635dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(INFO,
6363184b1efSMike Baucom 				     "On Close: Waiting %d ms for PRIM_RUN\n",
6373184b1efSMike Baucom 				     timeout);
6383184b1efSMike Baucom 		} while (poll_state != ULP_HA_STATE_PRIM_RUN && timeout > 0);
6393184b1efSMike Baucom 
6403184b1efSMike Baucom 		if (timeout <= 0) {
641dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "On Close: SEC[COPY] Timed out\n");
6423184b1efSMike Baucom 			goto cleanup;
6433184b1efSMike Baucom 		}
6443184b1efSMike Baucom 
645dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Close: PRIM[PRIM_SEC_RUN] => [COPY]\n");
6463184b1efSMike Baucom 	} else if (curr_state == ULP_HA_STATE_PRIM_SEC_RUN &&
6473184b1efSMike Baucom 		   app_type == ULP_HA_APP_TYPE_SEC) {
6483184b1efSMike Baucom 		/*
6493184b1efSMike Baucom 		 * While both are running, the secondary unexpectedly received a
6501993b267SShahaji Bhosle 		 * close.
6513184b1efSMike Baucom 		 */
6523184b1efSMike Baucom 		ulp_ha_mgr_state_set(ulp_ctx, ULP_HA_STATE_PRIM_RUN);
6533184b1efSMike Baucom 
654dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Close: SEC[PRIM_SEC_RUN] => [PRIM_RUN]\n");
6553184b1efSMike Baucom 	} else if (curr_state == ULP_HA_STATE_SEC_TIMER_COPY &&
6563184b1efSMike Baucom 		   app_type == ULP_HA_APP_TYPE_SEC) {
6573184b1efSMike Baucom 		/*
6583184b1efSMike Baucom 		 * While both were running and the Secondary went into copy,
6593184b1efSMike Baucom 		 * secondary received a close.  Wait until the former Primary
6603184b1efSMike Baucom 		 * clears the copy stage, close, and set to INIT.
6613184b1efSMike Baucom 		 */
662dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "On Close: SEC[COPY] wait for PRIM_RUN\n");
6633184b1efSMike Baucom 
6643184b1efSMike Baucom 		timeout = ULP_HA_WAIT_TIMEOUT;
6653184b1efSMike Baucom 		do {
6663184b1efSMike Baucom 			rte_delay_ms(ULP_HA_WAIT_TIME);
6673184b1efSMike Baucom 			rc = ulp_ha_mgr_state_get(ulp_ctx, &poll_state);
6683184b1efSMike Baucom 			if (rc) {
669dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
6703184b1efSMike Baucom 					     "Failed to get HA state on Close (%d)\n",
6713184b1efSMike Baucom 					     rc);
6723184b1efSMike Baucom 				goto cleanup;
6733184b1efSMike Baucom 			}
6743184b1efSMike Baucom 
6753184b1efSMike Baucom 			timeout -= ULP_HA_WAIT_TIME;
676dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(INFO,
6773184b1efSMike Baucom 				     "On Close: Waiting %d ms for PRIM_RUN\n",
6783184b1efSMike Baucom 				     timeout);
6793184b1efSMike Baucom 		} while (poll_state != ULP_HA_STATE_PRIM_RUN &&
6803184b1efSMike Baucom 			 timeout >= 0);
6813184b1efSMike Baucom 
6823184b1efSMike Baucom 		if (timeout <= 0) {
683dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR,
6843184b1efSMike Baucom 				     "On Close: SEC[COPY] Timed out\n");
6853184b1efSMike Baucom 			goto cleanup;
6863184b1efSMike Baucom 		}
6873184b1efSMike Baucom 
6883184b1efSMike Baucom 		next_state = ULP_HA_STATE_INIT;
6893184b1efSMike Baucom 		rc = ulp_ha_mgr_state_set(ulp_ctx, next_state);
6903184b1efSMike Baucom 		if (rc) {
691dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR,
6923184b1efSMike Baucom 				     "On Close: Failed to set state to INIT(%x)\n",
6933184b1efSMike Baucom 				     rc);
6943184b1efSMike Baucom 			goto cleanup;
6953184b1efSMike Baucom 		}
6963184b1efSMike Baucom 
697dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO,
6983184b1efSMike Baucom 			     "On Close: SEC[COPY] => [INIT] after %d ms\n",
6993184b1efSMike Baucom 			     ULP_HA_WAIT_TIMEOUT - timeout);
700dd0191d5SShuanglin Wang 	} else {
701dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "On Close: Invalid type/state %d/%d\n",
702dd0191d5SShuanglin Wang 			     curr_state, app_type);
7033184b1efSMike Baucom 	}
7046d160d77SRandy Schacher 	/* else do nothing just return*/
7056d160d77SRandy Schacher 
7063184b1efSMike Baucom cleanup:
7073184b1efSMike Baucom 	return rc;
7083184b1efSMike Baucom }
7093184b1efSMike Baucom 
7103184b1efSMike Baucom int32_t
7113184b1efSMike Baucom ulp_ha_mgr_region_get(struct bnxt_ulp_context *ulp_ctx,
7123184b1efSMike Baucom 		      enum ulp_ha_mgr_region *region)
7133184b1efSMike Baucom {
7143184b1efSMike Baucom 	struct bnxt_ulp_ha_mgr_info *ha_info;
7153184b1efSMike Baucom 
7163184b1efSMike Baucom 	if (ulp_ctx == NULL || region == NULL) {
717dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid params in ha region get.\n");
7183184b1efSMike Baucom 		return -EINVAL;
7193184b1efSMike Baucom 	}
7203184b1efSMike Baucom 
7213184b1efSMike Baucom 	ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
7223184b1efSMike Baucom 	if (ha_info == NULL) {
723dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get ha info\n");
7243184b1efSMike Baucom 		return -EINVAL;
7253184b1efSMike Baucom 	}
7263184b1efSMike Baucom 	*region = ha_info->region;
7273184b1efSMike Baucom 
7283184b1efSMike Baucom 	return 0;
7293184b1efSMike Baucom }
730