Merge "[qca-nss-ecm] Conntrack cleans up DB when route event happens"
diff --git a/ecm_db.c b/ecm_db.c
index 1e677e9..9cf7765 100644
--- a/ecm_db.c
+++ b/ecm_db.c
@@ -83,6 +83,13 @@
#endif
/*
+ * Check the configured HZ value.
+ */
+#if HZ > 100000
+#error "Bad HZ value"
+#endif
+
+/*
* Global lists.
* All instances are inserted into global list - this allows easy iteration of all instances of a particular type.
* The list is doubly linked for fast removal. The list is in no particular order.
@@ -1036,6 +1043,46 @@
}
/*
+ * ecm_db_connection_elapsed_defunct_timer()
+ * Returns the elapsed time of defunct timer.
+ * If the timer is already expired and not removed from the database, the
+ * function returns a negative value. The caller MUST handle this return value.
+ */
+int ecm_db_connection_elapsed_defunct_timer(struct ecm_db_connection_instance *ci)
+{
+ long int expires_in;
+ int elapsed;
+
+ DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%p: magic failed", ci);
+
+ /*
+ * Do some sanity checks.
+ * If it is not in a timer group, which means already expired, or the
+ * connection has not been fully created yet. Just return 0.
+ */
+ spin_lock_bh(&ecm_db_lock);
+ if (ci->defunct_timer.group == ECM_DB_TIMER_GROUPS_MAX) {
+ spin_unlock_bh(&ecm_db_lock);
+ return -1;
+ }
+
+ /*
+ * Already expired, but not removed from the database completely.
+ */
+ expires_in = (long int)(ci->defunct_timer.timeout - ecm_db_time);
+ if (expires_in < 0) {
+ spin_unlock_bh(&ecm_db_lock);
+ return -1;
+ }
+
+ elapsed = ecm_db_timer_groups[ci->defunct_timer.group].time - expires_in;
+ spin_unlock_bh(&ecm_db_lock);
+
+ return elapsed;
+}
+EXPORT_SYMBOL(ecm_db_connection_elapsed_defunct_timer);
+
+/*
* ecm_db_connection_defunct_timer_reset()
* Set/change the timer group associated with a connection. Returns false if the connection has become defunct and the new group cannot be set for that reason.
*/
@@ -1079,14 +1126,31 @@
*/
void ecm_db_connection_make_defunct(struct ecm_db_connection_instance *ci)
{
+ struct ecm_front_end_connection_instance *feci;
+ ecm_front_end_acceleration_mode_t accel_mode;
+
DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%p: magic failed", ci);
if (ci->defunct) {
ci->defunct(ci->feci);
}
- if (ecm_db_timer_group_entry_remove(&ci->defunct_timer)) {
- ecm_db_connection_deref(ci);
+ feci = ecm_db_connection_front_end_get_and_ref(ci);
+ accel_mode = feci->accel_state_get(feci);
+ feci->deref(feci);
+
+ /*
+ * It is possible that the defunct process fails and re-try is in progress.
+ * In that case, the connection's defunct timer is reset to defunct re-try
+ * timeout value and the connection waits for the next defunct call. So, we
+ * should remove the timer from the timer group, if the re-acceleration for this
+ * connection is not possible which means "decel pending" or one of the
+ * "accel fail" modes. Otherwise, the timer will be removed and re-try will not happen.
+ */
+ if (ECM_FRONT_END_ACCELERATION_NOT_POSSIBLE(accel_mode)) {
+ if (ecm_db_timer_group_entry_remove(&ci->defunct_timer)) {
+ ecm_db_connection_deref(ci);
+ }
}
}
EXPORT_SYMBOL(ecm_db_connection_make_defunct);
@@ -12409,6 +12473,12 @@
ecm_db_timer_groups[ECM_DB_TIMER_GROUPS_CONNECTION_SIP_TIMEOUT].tg = ECM_DB_TIMER_GROUPS_CONNECTION_SIP_TIMEOUT;
/*
+ * Defunct re-try timeout (5 seconds)
+ */
+ ecm_db_timer_groups[ECM_DB_TIMER_GROUPS_CONNECTION_DEFUNCT_RETRY_TIMEOUT].time = ECM_DB_CONNECTION_DEFUNCT_RETRY_TIMEOUT;
+ ecm_db_timer_groups[ECM_DB_TIMER_GROUPS_CONNECTION_DEFUNCT_RETRY_TIMEOUT].tg = ECM_DB_TIMER_GROUPS_CONNECTION_DEFUNCT_RETRY_TIMEOUT;
+
+ /*
* Reset connection by protocol counters
*/
memset(ecm_db_connection_count_by_protocol, 0, sizeof(ecm_db_connection_count_by_protocol));
diff --git a/ecm_db.h b/ecm_db.h
index d74d86f..39c9e7e 100644
--- a/ecm_db.h
+++ b/ecm_db.h
@@ -38,6 +38,7 @@
void ecm_db_connection_data_totals_update_dropped(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets);
void ecm_db_connection_data_totals_update(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets);
+int ecm_db_connection_elapsed_defunct_timer(struct ecm_db_connection_instance *ci);
bool ecm_db_connection_defunct_timer_reset(struct ecm_db_connection_instance *ci, ecm_db_timer_group_t tg);
bool ecm_db_connection_defunct_timer_touch(struct ecm_db_connection_instance *ci);
void ecm_db_connection_make_defunct(struct ecm_db_connection_instance *ci);
diff --git a/ecm_db_types.h b/ecm_db_types.h
index 1ad4ff1..cbe3b69 100644
--- a/ecm_db_types.h
+++ b/ecm_db_types.h
@@ -105,6 +105,7 @@
#define ECM_DB_CONNECTION_SDP_TIMEOUT 120
#define ECM_DB_CONNECTION_SIP_TIMEOUT 28800
#define ECM_DB_CONNECTION_BITTORRENT_TIMEOUT 120
+#define ECM_DB_CONNECTION_DEFUNCT_RETRY_TIMEOUT 5
/*
* Timer groups.
@@ -135,6 +136,7 @@
ECM_DB_TIMER_GROUPS_CONNECTION_SIP_TIMEOUT, /* SIP timeout */
ECM_DB_TIMER_GROUPS_CONNECTION_IGMP_TIMEOUT, /* IGMP timeout */
ECM_DB_TIMER_GROUPS_CONNECTION_BITTORRENT_TIMEOUT, /* Bittorrent connections timeout */
+ ECM_DB_TIMER_GROUPS_CONNECTION_DEFUNCT_RETRY_TIMEOUT, /* Defunct retry timeout */
ECM_DB_TIMER_GROUPS_MAX /* Always the last one */
};
typedef enum ecm_db_timer_groups ecm_db_timer_group_t;
diff --git a/frontends/ecm_front_end_common.c b/frontends/ecm_front_end_common.c
index fe2e5e5..6ed9d4b 100644
--- a/frontends/ecm_front_end_common.c
+++ b/frontends/ecm_front_end_common.c
@@ -80,4 +80,38 @@
}
#endif
+/*
+ * ecm_front_end_destroy_failure_handle()
+ * Destroy request failure handler.
+ */
+void ecm_front_end_destroy_failure_handle(struct ecm_front_end_connection_instance *feci)
+{
+ spin_lock_bh(&feci->lock);
+ feci->stats.driver_fail_total++;
+ feci->stats.driver_fail++;
+ if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
+ /*
+ * Reached to the driver failure limit. ECM no longer allows
+ * re-trying deceleration.
+ */
+ feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
+ spin_unlock_bh(&feci->lock);
+ DEBUG_WARN("%p: Decel failed - driver fail limit\n", feci);
+ return;
+ }
+ /*
+ * Destroy request failed. The accelerated connection couldn't be destroyed
+ * in the acceleration engine. Revert back the accel_mode, unset the is_defunct
+ * flag just in case this request has come through the defunct process.
+ */
+ feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_ACCEL;
+ feci->is_defunct = false;
+ spin_unlock_bh(&feci->lock);
+
+ /*
+ * Reset the defunct timer to a smaller timeout value so that the connection will be
+ * tried to be defuncted again, when the timeout expires (its value is 5 seconds).
+ */
+ ecm_db_connection_defunct_timer_reset(feci->ci, ECM_DB_TIMER_GROUPS_CONNECTION_DEFUNCT_RETRY_TIMEOUT);
+}
diff --git a/frontends/include/ecm_front_end_common.h b/frontends/include/ecm_front_end_common.h
index 8a9ed93..ca3a35a 100644
--- a/frontends/include/ecm_front_end_common.h
+++ b/frontends/include/ecm_front_end_common.h
@@ -171,3 +171,4 @@
extern void ecm_front_end_bond_notifier_stop(int num);
extern int ecm_front_end_bond_notifier_init(struct dentry *dentry);
extern void ecm_front_end_bond_notifier_exit(void);
+extern void ecm_front_end_destroy_failure_handle(struct ecm_front_end_connection_instance *feci);
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
index a82cc02..b5d3d7a 100644
--- a/frontends/nss/ecm_nss_ipv4.c
+++ b/frontends/nss/ecm_nss_ipv4.c
@@ -1721,6 +1721,8 @@
struct ecm_classifier_rule_sync class_sync;
int flow_dir;
int return_dir;
+ unsigned long int delta_jiffies;
+ int elapsed;
/*
* Look up ecm connection with a view to synchronising the connection, classifier and data tracker.
@@ -1764,11 +1766,26 @@
#endif
if (!ci) {
DEBUG_TRACE("%p: NSS Sync: no connection\n", sync);
- goto sync_conntrack;
+ return;
}
+
DEBUG_TRACE("%p: Sync conn %p\n", sync, ci);
/*
+ * Get the elapsed time since the last sync and add this elapsed time
+ * to the conntrack's timeout while updating it. If the return value is
+ * a negative value which means the timer is not in a valid state, just
+ * return here and do not update the defunct timer and the conntrack.
+ */
+ elapsed = ecm_db_connection_elapsed_defunct_timer(ci);
+ if (elapsed < 0) {
+ ecm_db_connection_deref(ci);
+ return;
+ }
+ DEBUG_TRACE("%p: elapsed: %d\n", ci, elapsed);
+ delta_jiffies = elapsed * HZ;
+
+ /*
* Keep connection alive and updated
*/
if (!ecm_db_connection_defunct_timer_touch(ci)) {
@@ -2007,19 +2024,9 @@
/*
* Only update if this is not a fixed timeout
+ * delta_jiffies is the elapsed time since the last sync of this connection.
*/
if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
- unsigned long int delta_jiffies;
-
- /*
- * Convert ms ticks from the NSS to jiffies. We know that inc_ticks is small
- * and we expect HZ to be small too so we can multiply without worrying about
- * wrap-around problems. We add a rounding constant to ensure that the different
- * time bases don't cause truncation errors.
- */
- DEBUG_ASSERT(HZ <= 100000, "Bad HZ\n");
- delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC;
-
spin_lock_bh(&ct->lock);
ct->timeout.expires += delta_jiffies;
spin_unlock_bh(&ct->lock);
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
index f43ee59..d420317 100644
--- a/frontends/nss/ecm_nss_ipv6.c
+++ b/frontends/nss/ecm_nss_ipv6.c
@@ -1387,6 +1387,8 @@
struct ecm_classifier_rule_sync class_sync;
int flow_dir;
int return_dir;
+ unsigned long int delta_jiffies;
+ int elapsed;
ECM_NSS_IPV6_ADDR_TO_IP_ADDR(flow_ip, sync->flow_ip);
ECM_NSS_IPV6_ADDR_TO_IP_ADDR(return_ip, sync->return_ip);
@@ -1408,11 +1410,25 @@
ci = ecm_db_connection_find_and_ref(flow_ip, return_ip, sync->protocol, (int)sync->flow_ident, (int)sync->return_ident);
if (!ci) {
DEBUG_TRACE("%p: NSS Sync: no connection\n", sync);
- goto sync_conntrack;
+ return;
}
+
DEBUG_TRACE("%p: Sync conn %p\n", sync, ci);
/*
+ * Get the elapsed time since the last sync and add this elapsed time
+ * to the conntrack's timeout while updating it. If the return value is
+ * a negative value which means the timer is not in a valid state, just
+ * return here and do not update the defunct timer and the conntrack.
+ */
+ elapsed = ecm_db_connection_elapsed_defunct_timer(ci);
+ if (elapsed < 0) {
+ ecm_db_connection_deref(ci);
+ return;
+ }
+ delta_jiffies = elapsed * HZ;
+
+ /*
* Keep connection alive and updated
*/
if (!ecm_db_connection_defunct_timer_touch(ci)) {
@@ -1650,23 +1666,14 @@
/*
* Only update if this is not a fixed timeout
+ * delta_jiffies is the elapsed time since the last sync of this connection.
*/
if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
- unsigned long int delta_jiffies;
-
- /*
- * Convert ms ticks from the NSS to jiffies. We know that inc_ticks is small
- * and we expect HZ to be small too so we can multiply without worrying about
- * wrap-around problems. We add a rounding constant to ensure that the different
- * time bases don't cause truncation errors.
- */
- DEBUG_ASSERT(HZ <= 100000, "Bad HZ\n");
- delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC;
-
spin_lock_bh(&ct->lock);
ct->timeout.expires += delta_jiffies;
spin_unlock_bh(&ct->lock);
}
+
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
acct = nf_conn_acct_find(ct);
#else
diff --git a/frontends/nss/ecm_nss_non_ported_ipv4.c b/frontends/nss/ecm_nss_non_ported_ipv4.c
index 0586594..6e1eee0 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv4.c
@@ -74,6 +74,7 @@
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
+#include "ecm_front_end_common.h"
#include "ecm_tracker_datagram.h"
#include "ecm_tracker_udp.h"
#include "ecm_tracker_tcp.h"
@@ -1456,14 +1457,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", nnpci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/nss/ecm_nss_non_ported_ipv6.c b/frontends/nss/ecm_nss_non_ported_ipv6.c
index c5efaaf..3e91a62 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv6.c
@@ -75,6 +75,7 @@
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
+#include "ecm_front_end_common.h"
#include "ecm_tracker_datagram.h"
#include "ecm_tracker_udp.h"
#include "ecm_tracker_tcp.h"
@@ -1274,14 +1275,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", nnpci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c
index 71d87e9..44f24ee 100644
--- a/frontends/nss/ecm_nss_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
@@ -1487,14 +1487,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", npci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c
index 1bb31f0..08641cb 100644
--- a/frontends/nss/ecm_nss_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_ported_ipv6.c
@@ -1377,14 +1377,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", npci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c
index 03c7c4c..701c949 100644
--- a/frontends/sfe/ecm_sfe_ipv4.c
+++ b/frontends/sfe/ecm_sfe_ipv4.c
@@ -1533,12 +1533,11 @@
unsigned long int delta_jiffies;
/*
- * Convert ms ticks from the SFE to jiffies. We know that inc_ticks is small
+ * Convert ms ticks from the SFE to jiffies. We know that inc_ticks is small
* and we expect HZ to be small too so we can multiply without worrying about
* wrap-around problems. We add a rounding constant to ensure that the different
* time bases don't cause truncation errors.
*/
- DEBUG_ASSERT(HZ <= 100000, "Bad HZ\n");
delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC;
spin_lock_bh(&ct->lock);
diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c
index 96153a8..927bb89 100644
--- a/frontends/sfe/ecm_sfe_ipv6.c
+++ b/frontends/sfe/ecm_sfe_ipv6.c
@@ -1247,12 +1247,11 @@
unsigned long int delta_jiffies;
/*
- * Convert ms ticks from the SFE to jiffies. We know that inc_ticks is small
+ * Convert ms ticks from the SFE to jiffies. We know that inc_ticks is small
* and we expect HZ to be small too so we can multiply without worrying about
* wrap-around problems. We add a rounding constant to ensure that the different
* time bases don't cause truncation errors.
*/
- DEBUG_ASSERT(HZ <= 100000, "Bad HZ\n");
delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC;
spin_lock_bh(&ct->lock);
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv4.c b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
index 7008b7a..4160bd4 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
@@ -74,6 +74,7 @@
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
+#include "ecm_front_end_common.h"
#include "ecm_tracker_datagram.h"
#include "ecm_tracker_udp.h"
#include "ecm_tracker_tcp.h"
@@ -1354,14 +1355,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", nnpci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv6.c b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
index 89ab791..c0e082f 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
@@ -75,6 +75,7 @@
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
+#include "ecm_front_end_common.h"
#include "ecm_tracker_datagram.h"
#include "ecm_tracker_udp.h"
#include "ecm_tracker_tcp.h"
@@ -1245,14 +1246,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", nnpci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/sfe/ecm_sfe_ported_ipv4.c b/frontends/sfe/ecm_sfe_ported_ipv4.c
index 7356ed4..896747b 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv4.c
@@ -1395,14 +1395,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", npci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter
diff --git a/frontends/sfe/ecm_sfe_ported_ipv6.c b/frontends/sfe/ecm_sfe_ported_ipv6.c
index aab8267..ae9a9f8 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv6.c
@@ -1338,14 +1338,7 @@
/*
* TX failed
*/
- spin_lock_bh(&feci->lock);
- feci->stats.driver_fail_total++;
- feci->stats.driver_fail++;
- if (feci->stats.driver_fail >= feci->stats.driver_fail_limit) {
- DEBUG_WARN("%p: Decel failed - driver fail limit\n", npci);
- feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_FAIL_DRIVER;
- }
- spin_unlock_bh(&feci->lock);
+ ecm_front_end_destroy_failure_handle(feci);
/*
* Could not send the request, decrement the decel pending counter