[qca-nss-ecm]: deliver network device event to front end

Sometimes front end want to respond to network device event by itself.
So a new callback 'regeneration_needed' is added to front end. This
function will be triggered when generation of connection changed after
network device event.

Change-Id: I163f50508fe70d48f5dd6983cc070d3e10ef242a
Signed-off-by: Xiaoping Fan <xfan@codeaurora.org>
diff --git a/ecm_db.c b/ecm_db.c
index 3f10ae2..b7604e2 100644
--- a/ecm_db.c
+++ b/ecm_db.c
@@ -1982,6 +1982,27 @@
 EXPORT_SYMBOL(ecm_db_regeneration_needed);
 
 /*
+ * ecm_db_connection_regenerate()
+ *	Re-generate a specific connection
+ */
+void ecm_db_connection_regenerate(struct ecm_db_connection_instance *ci)
+{
+	struct ecm_front_end_connection_instance *feci;
+
+	DEBUG_TRACE("Regenerate connection: %p\n", ci);
+
+	DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%p: magic failed", ci);
+
+	/*
+	 * Notify front end to regenerate a connection.
+	 */
+	feci = ecm_db_connection_front_end_get_and_ref(ci);
+	feci->regenerate(feci, ci);
+	feci->deref(feci);
+}
+EXPORT_SYMBOL(ecm_db_connection_regenerate);
+
+/*
  * ecm_db_connection_direction_get()
  *	Return direction of the connection.
  *
@@ -5986,7 +6007,7 @@
 		struct ecm_db_connection_instance *cin;
 
 		DEBUG_TRACE("%p: Re-generate: %d\n", ci, ca_type);
-		ecm_db_connection_regeneration_needed(ci);
+		ecm_db_connection_regenerate(ci);
 
 		cin = ecm_db_connection_by_classifier_type_assignment_get_and_ref_next(ci, ca_type);
 		ecm_db_connection_by_classifier_type_assignment_deref(ci, ca_type);
diff --git a/ecm_db.h b/ecm_db.h
index 182b393..186d4e0 100644
--- a/ecm_db.h
+++ b/ecm_db.h
@@ -79,6 +79,7 @@
 bool ecm_db_connection_regeneration_required_peek(struct ecm_db_connection_instance *ci);
 void ecm_db_connection_regeneration_needed(struct ecm_db_connection_instance *ci);
 void ecm_db_regeneration_needed(void);
+void ecm_db_connection_regenerate(struct ecm_db_connection_instance *ci);
 #ifdef ECM_DB_CTA_TRACK_ENABLE
 void ecm_db_connection_regenerate_by_assignment_type(ecm_classifier_type_t ca_type);
 void ecm_db_connection_make_defunct_by_assignment_type(ecm_classifier_type_t ca_type);
diff --git a/ecm_interface.c b/ecm_interface.c
index 5df7e6e..07e04fb 100644
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -3198,37 +3198,6 @@
 #endif
 
 /*
- * ecm_interface_regenerate_connection()
- *	Re-generate a specific connection
- */
-void ecm_interface_regenerate_connection(struct ecm_db_connection_instance *ci)
-{
-	struct ecm_front_end_connection_instance *feci;
-
-	DEBUG_TRACE("Regenerate connection: %p\n", ci);
-
-	/*
-	 * Flag the connection as needing re-generation.
-	 * Re-generation occurs when we next see traffic OR an acceleration engine sync for this connection.
-	 * Refer to front end protocol specific process() functions.
-	 */
-	ecm_db_connection_regeneration_needed(ci);
-
-	/*
-	 * If the connection is accelerated then force deceleration.
-	 * Under normal circumstances deceleration would occur on the next sync received,
-	 * however, there is a situation where a sync may not occur if, say, a cable has been pulled.
-	 * The acceleration engine would see no further traffic to trigger sending a sync and so
-	 * re-generation would not occur.
-	 * The connection would stall and no-regeneration would happen leaving the connection in bad state.
-	 * NOTE: We can just call decelerate() upon the front end - if its not accelerated this will have no effect.
-	 */
-	feci = ecm_db_connection_front_end_get_and_ref(ci);
-	feci->decelerate(feci);
-	feci->deref(feci);
-}
-
-/*
  * ecm_interface_regenerate_connections()
  *	Cause regeneration of all connections that are using the specified interface.
  */
@@ -3272,7 +3241,7 @@
 		cin = ecm_db_connection_iface_from_get_and_ref_next(ci_from);
 
 		DEBUG_TRACE("%p: Regenerate: %p", ii, ci_from);
-		ecm_db_connection_regeneration_needed(ci_from);
+		ecm_db_connection_regenerate(ci_from);
 		ecm_db_connection_deref(ci_from);
 		ci_from = cin;
 	}
@@ -3283,7 +3252,7 @@
 		cin = ecm_db_connection_iface_to_get_and_ref_next(ci_to);
 
 		DEBUG_TRACE("%p: Regenerate: %p", ii, ci_to);
-		ecm_db_connection_regeneration_needed(ci_to);
+		ecm_db_connection_regenerate(ci_to);
 		ecm_db_connection_deref(ci_to);
 		ci_to = cin;
 	}
@@ -3297,7 +3266,7 @@
 		cin = ecm_db_connection_iface_nat_from_get_and_ref_next(ci_from_nat);
 
 		DEBUG_TRACE("%p: Regenerate: %p", ii, ci_from_nat);
-		ecm_db_connection_regeneration_needed(ci_from_nat);
+		ecm_db_connection_regenerate(ci_from_nat);
 		ecm_db_connection_deref(ci_from_nat);
 		ci_from_nat = cin;
 	}
@@ -3308,7 +3277,7 @@
 		cin = ecm_db_connection_iface_nat_to_get_and_ref_next(ci_to_nat);
 
 		DEBUG_TRACE("%p: Regenerate: %p", ii, ci_to_nat);
-		ecm_db_connection_regeneration_needed(ci_to_nat);
+		ecm_db_connection_regenerate(ci_to_nat);
 		ecm_db_connection_deref(ci_to_nat);
 		ci_to_nat = cin;
 	}
@@ -3328,7 +3297,7 @@
 		 */
 		if (ecm_db_multicast_connection_to_interfaces_set_check(ci_mcast)
 				&& ecm_db_connection_regeneration_required_peek(ci_mcast)) {
-			ecm_db_connection_regeneration_needed(ci_mcast);
+			ecm_db_connection_regenerate(ci_mcast);
 		}
 
 		cin = ecm_db_connection_get_and_ref_next(ci_mcast);
diff --git a/frontends/include/ecm_front_end_types.h b/frontends/include/ecm_front_end_types.h
index dbd109e..04e8261 100644
--- a/frontends/include/ecm_front_end_types.h
+++ b/frontends/include/ecm_front_end_types.h
@@ -74,6 +74,7 @@
 											 */
 #endif
 typedef int32_t (*ecm_front_end_connection_ae_interface_number_by_dev_get_method_t)(struct net_device *dev);
+typedef void (*ecm_front_end_connection_regenerate_method_t)(struct ecm_front_end_connection_instance *feci, struct ecm_db_connection_instance *ci);
 
 /*
  * Acceleration limiting modes.
@@ -115,6 +116,8 @@
 	ecm_front_end_connection_accel_ceased_method_t accel_ceased;		/* Acceleration has stopped */
 	ecm_front_end_connection_ae_interface_number_by_dev_get_method_t ae_interface_number_by_dev_get;
 										/* Get the acceleration engine interface number from the dev instance */
+	ecm_front_end_connection_regenerate_method_t regenerate;
+										/* regenerate a connection */
 #ifdef ECM_STATE_OUTPUT_ENABLE
 	ecm_front_end_connection_state_get_callback_t state_get;		/* Obtain state for this object */
 #endif
diff --git a/frontends/nss/ecm_nss_common.h b/frontends/nss/ecm_nss_common.h
index 714076d..81d0eec 100644
--- a/frontends/nss/ecm_nss_common.h
+++ b/frontends/nss/ecm_nss_common.h
@@ -63,3 +63,16 @@
 	return nss_cmn_get_interface_number_by_dev(dev);
 }
 
+/*
+ * ecm_nss_common_connection_regenerate()
+ *	Re-generate a specific connection in NSS front end
+ */
+static inline void ecm_nss_common_connection_regenerate(struct ecm_front_end_connection_instance *feci, struct ecm_db_connection_instance *ci)
+{
+	/*
+	 * Flag the connection as needing re-generation.
+	 * Re-generation occurs when we next see traffic OR an acceleration engine sync for this connection.
+	 * Refer to front end protocol specific process() functions.
+	 */
+	ecm_db_connection_regeneration_needed(ci);
+}
diff --git a/frontends/nss/ecm_nss_multicast_ipv4.c b/frontends/nss/ecm_nss_multicast_ipv4.c
index d4e81c5..ea49b0f 100644
--- a/frontends/nss/ecm_nss_multicast_ipv4.c
+++ b/frontends/nss/ecm_nss_multicast_ipv4.c
@@ -2144,6 +2144,7 @@
 	feci->state_get = ecm_nss_multicast_ipv4_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	return nmci;
 }
diff --git a/frontends/nss/ecm_nss_multicast_ipv6.c b/frontends/nss/ecm_nss_multicast_ipv6.c
index bf75146..f4fb6d5 100644
--- a/frontends/nss/ecm_nss_multicast_ipv6.c
+++ b/frontends/nss/ecm_nss_multicast_ipv6.c
@@ -2082,6 +2082,7 @@
 	feci->state_get = ecm_nss_multicast_ipv6_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	return nmci;
 }
diff --git a/frontends/nss/ecm_nss_non_ported_ipv4.c b/frontends/nss/ecm_nss_non_ported_ipv4.c
index fddc46c..ef79e3d 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv4.c
@@ -1700,6 +1700,7 @@
 	feci->state_get = ecm_nss_non_ported_ipv4_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	return nnpci;
 }
diff --git a/frontends/nss/ecm_nss_non_ported_ipv6.c b/frontends/nss/ecm_nss_non_ported_ipv6.c
index fbb62f7..5ead02a 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv6.c
@@ -1593,6 +1593,7 @@
 	feci->state_get = ecm_nss_non_ported_ipv6_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	return nnpci;
 }
diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c
index 2bfc5c0..c8cd25a 100644
--- a/frontends/nss/ecm_nss_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
@@ -1709,6 +1709,7 @@
 	feci->state_get = ecm_nss_ported_ipv4_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	if (protocol == IPPROTO_TCP) {
 		npci->ported_accelerated_count_index = ECM_NSS_PORTED_IPV4_PROTO_TCP;
diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c
index 1ee42dd..bd73968 100644
--- a/frontends/nss/ecm_nss_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_ported_ipv6.c
@@ -1654,6 +1654,7 @@
 	feci->state_get = ecm_nss_ported_ipv6_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_nss_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_nss_common_connection_regenerate;
 
 	if (protocol == IPPROTO_TCP) {
 		npci->ported_accelerated_count_index = ECM_NSS_PORTED_IPV6_PROTO_TCP;
diff --git a/frontends/sfe/ecm_sfe_common.h b/frontends/sfe/ecm_sfe_common.h
index aeaafa9..c06dd2c 100644
--- a/frontends/sfe/ecm_sfe_common.h
+++ b/frontends/sfe/ecm_sfe_common.h
@@ -67,3 +67,27 @@
 	return dev->ifindex;
 }
 
+/*
+ * ecm_sfe_common_connection_regenerate()
+ *	Re-generate a specific connection in SFE front end
+ */
+static inline void ecm_sfe_common_connection_regenerate(struct ecm_front_end_connection_instance *feci, struct ecm_db_connection_instance *ci)
+{
+	/*
+	 * Flag the connection as needing re-generation.
+	 * Re-generation occurs when we next see traffic OR an acceleration engine sync for this connection.
+	 * Refer to front end protocol specific process() functions.
+	 */
+	ecm_db_connection_regeneration_needed(ci);
+
+	/*
+	 * If the connection is accelerated then force deceleration.
+	 * Under normal circumstances deceleration would occur on the next sync received,
+	 * however, there is a situation where a sync may not occur if, say, a cable has been pulled.
+	 * The acceleration engine would see no further traffic to trigger sending a sync and so
+	 * re-generation would not occur.
+	 * The connection would stall and no-regeneration would happen leaving the connection in bad state.
+	 * NOTE: We can just call decelerate() upon the front end - if its not accelerated this will have no effect.
+	 */
+	feci->decelerate(feci);
+}
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv4.c b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
index b6e9b82..83d52b5 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
@@ -1719,6 +1719,7 @@
 	feci->state_get = ecm_sfe_non_ported_ipv4_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_sfe_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_sfe_common_connection_regenerate;
 
 	return nnpci;
 }
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv6.c b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
index eda097e..d0380ee 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
@@ -1612,6 +1612,7 @@
 	feci->state_get = ecm_sfe_non_ported_ipv6_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_sfe_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_sfe_common_connection_regenerate;
 
 	return nnpci;
 }
diff --git a/frontends/sfe/ecm_sfe_ported_ipv4.c b/frontends/sfe/ecm_sfe_ported_ipv4.c
index 4c26bee..7bde29c 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv4.c
@@ -1729,6 +1729,7 @@
 	feci->state_get = ecm_sfe_ported_ipv4_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_sfe_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_sfe_common_connection_regenerate;
 
 	if (protocol == IPPROTO_TCP) {
 		npci->ported_accelerated_count_index = ECM_SFE_PORTED_IPV4_PROTO_TCP;
diff --git a/frontends/sfe/ecm_sfe_ported_ipv6.c b/frontends/sfe/ecm_sfe_ported_ipv6.c
index cb5dae9..3c51777 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv6.c
@@ -1674,6 +1674,7 @@
 	feci->state_get = ecm_sfe_ported_ipv6_connection_state_get;
 #endif
 	feci->ae_interface_number_by_dev_get = ecm_sfe_common_get_interface_number_by_dev;
+	feci->regenerate = ecm_sfe_common_connection_regenerate;
 
 	if (protocol == IPPROTO_TCP) {
 		npci->ported_accelerated_count_index = ECM_SFE_PORTED_IPV6_PROTO_TCP;