Browse Source

qcacmn: Fix for HMT SOD insmod crash

In the case of MCC due to low power mode atomic operation in
accessing the bank is resulting the crash.
Fix crash by using spinlock for WIN and mutex for MCC.

Change-Id: I5bb49cbed32e41ad88bfaeb24496adb180e37551
Sai Rupesh Chevuru 3 years ago
parent
commit
deb7bbf8de
2 changed files with 22 additions and 6 deletions
  1. 4 0
      dp/wifi3.0/be/dp_be.h
  2. 18 6
      dp/wifi3.0/be/dp_be_tx.c

+ 4 - 0
dp/wifi3.0/be/dp_be.h

@@ -187,7 +187,11 @@ struct dp_tx_bank_profile {
 struct dp_soc_be {
 struct dp_soc_be {
 	struct dp_soc soc;
 	struct dp_soc soc;
 	uint8_t num_bank_profiles;
 	uint8_t num_bank_profiles;
+#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
+	qdf_mutex_t tx_bank_lock;
+#else
 	qdf_spinlock_t tx_bank_lock;
 	qdf_spinlock_t tx_bank_lock;
+#endif
 	struct dp_tx_bank_profile *bank_profiles;
 	struct dp_tx_bank_profile *bank_profiles;
 	struct dp_spt_page_desc *page_desc_base;
 	struct dp_spt_page_desc *page_desc_base;
 	uint32_t cc_cmem_base;
 	uint32_t cc_cmem_base;

+ 18 - 6
dp/wifi3.0/be/dp_be_tx.c

@@ -26,6 +26,18 @@
 #include <hal_be_api.h>
 #include <hal_be_api.h>
 #include <hal_be_tx.h>
 #include <hal_be_tx.h>
 
 
+#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
+#define DP_TX_BANK_LOCK_CREATE(lock) qdf_mutex_create(lock)
+#define DP_TX_BANK_LOCK_DESTROY(lock) qdf_mutex_destroy(lock)
+#define DP_TX_BANK_LOCK_ACQUIRE(lock) qdf_mutex_acquire(lock)
+#define DP_TX_BANK_LOCK_RELEASE(lock) qdf_mutex_release(lock)
+#else
+#define DP_TX_BANK_LOCK_CREATE(lock) qdf_spinlock_create(lock)
+#define DP_TX_BANK_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
+#define DP_TX_BANK_LOCK_ACQUIRE(lock) qdf_spin_lock_bh(lock)
+#define DP_TX_BANK_LOCK_RELEASE(lock) qdf_spin_unlock_bh(lock)
+#endif
+
 extern uint8_t sec_type_map[MAX_CDP_SEC_TYPE];
 extern uint8_t sec_type_map[MAX_CDP_SEC_TYPE];
 
 
 #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
 #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
@@ -286,7 +298,7 @@ QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *be_soc)
 		return QDF_STATUS_E_NOMEM;
 		return QDF_STATUS_E_NOMEM;
 	}
 	}
 
 
-	qdf_spinlock_create(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_CREATE(&be_soc->tx_bank_lock);
 
 
 	for (i = 0; i < num_tcl_banks; i++) {
 	for (i = 0; i < num_tcl_banks; i++) {
 		be_soc->bank_profiles[i].is_configured = false;
 		be_soc->bank_profiles[i].is_configured = false;
@@ -299,7 +311,7 @@ QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *be_soc)
 void dp_tx_deinit_bank_profiles(struct dp_soc_be *be_soc)
 void dp_tx_deinit_bank_profiles(struct dp_soc_be *be_soc)
 {
 {
 	qdf_mem_free(be_soc->bank_profiles);
 	qdf_mem_free(be_soc->bank_profiles);
-	qdf_spinlock_destroy(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_DESTROY(&be_soc->tx_bank_lock);
 }
 }
 
 
 static
 static
@@ -364,7 +376,7 @@ int dp_tx_get_bank_profile(struct dp_soc_be *be_soc,
 	/* convert vdev params into hal_tx_bank_config */
 	/* convert vdev params into hal_tx_bank_config */
 	dp_tx_get_vdev_bank_config(be_vdev, &vdev_config);
 	dp_tx_get_vdev_bank_config(be_vdev, &vdev_config);
 
 
-	qdf_spin_lock_bh(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_ACQUIRE(&be_soc->tx_bank_lock);
 	/* go over all banks and find a matching/unconfigured/unsed bank */
 	/* go over all banks and find a matching/unconfigured/unsed bank */
 	for (i = 0; i < be_soc->num_bank_profiles; i++) {
 	for (i = 0; i < be_soc->num_bank_profiles; i++) {
 		if (be_soc->bank_profiles[i].is_configured &&
 		if (be_soc->bank_profiles[i].is_configured &&
@@ -410,7 +422,7 @@ configure_and_return:
 				      bank_id);
 				      bank_id);
 inc_ref_and_return:
 inc_ref_and_return:
 	qdf_atomic_inc(&be_soc->bank_profiles[bank_id].ref_count);
 	qdf_atomic_inc(&be_soc->bank_profiles[bank_id].ref_count);
-	qdf_spin_unlock_bh(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_RELEASE(&be_soc->tx_bank_lock);
 
 
 	dp_info("found %s slot at index %d, input:0x%x match:0x%x ref_count %u",
 	dp_info("found %s slot at index %d, input:0x%x match:0x%x ref_count %u",
 		temp_str, bank_id, vdev_config.val,
 		temp_str, bank_id, vdev_config.val,
@@ -436,9 +448,9 @@ inc_ref_and_return:
 void dp_tx_put_bank_profile(struct dp_soc_be *be_soc,
 void dp_tx_put_bank_profile(struct dp_soc_be *be_soc,
 			    struct dp_vdev_be *be_vdev)
 			    struct dp_vdev_be *be_vdev)
 {
 {
-	qdf_spin_lock_bh(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_ACQUIRE(&be_soc->tx_bank_lock);
 	qdf_atomic_dec(&be_soc->bank_profiles[be_vdev->bank_id].ref_count);
 	qdf_atomic_dec(&be_soc->bank_profiles[be_vdev->bank_id].ref_count);
-	qdf_spin_unlock_bh(&be_soc->tx_bank_lock);
+	DP_TX_BANK_LOCK_RELEASE(&be_soc->tx_bank_lock);
 }
 }
 
 
 void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,
 void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,