Просмотр исходного кода

qcacmn: Handle overflow of management rx reorder list

Deliver the oldest management frames to upper layers if
the management rx reorder list grows beyond the maximum
configured size.

Change-Id: Id0199849e26804310dd502051b8e14f56f0df795
CRs-Fixed: 3051431
Edayilliam Jayadev 3 лет назад
Родитель
Сommit
f1527f6374

+ 20 - 10
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_rx_reo.c

@@ -570,21 +570,28 @@ mgmt_rx_reo_list_display(struct mgmt_rx_reo_list *reo_list,
  * mgmt_rx_reo_list_entry_get_release_reason() - Helper API to get the reason
  * for releasing the reorder list entry to upper layer.
  * reorder list.
+ * @reo_list: Pointer to reorder list
  * @entry: List entry
- * @ts_latest_aged_out_frame: Global time stamp of latest aged out frame
+ *
+ * This API expects the caller to acquire the spin lock protecting the reorder
+ * list.
  *
  * Return: Reason for releasing the frame.
  */
 static uint8_t
 mgmt_rx_reo_list_entry_get_release_reason(
-		struct mgmt_rx_reo_list_entry *entry,
-		struct mgmt_rx_reo_global_ts_info *ts_latest_aged_out_frame)
+		struct mgmt_rx_reo_list *reo_list,
+		struct mgmt_rx_reo_list_entry *entry)
 {
 	uint8_t release_reason = 0;
 
-	if (!entry || !ts_latest_aged_out_frame)
+	if (!reo_list || !entry)
 		return 0;
 
+	if (mgmt_rx_reo_list_max_size_exceeded(reo_list))
+		release_reason |=
+		   MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_LIST_MAX_SIZE_EXCEEDED;
+
 	if (!MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry))
 		release_reason |=
 			MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_ZERO_WAIT_COUNT;
@@ -593,9 +600,9 @@ mgmt_rx_reo_list_entry_get_release_reason(
 		release_reason |=
 				MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_AGED_OUT;
 
-	if (ts_latest_aged_out_frame->valid &&
+	if (reo_list->ts_latest_aged_out_frame.valid &&
 	    MGMT_RX_REO_LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(
-				ts_latest_aged_out_frame, entry))
+				&reo_list->ts_latest_aged_out_frame, entry))
 		release_reason |=
 		MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME;
 
@@ -633,7 +640,7 @@ mgmt_rx_reo_list_entry_send_up(struct mgmt_rx_reo_list *reo_list,
 	ts_last_delivered_frame = &reo_list->ts_last_delivered_frame;
 
 	release_reason = mgmt_rx_reo_list_entry_get_release_reason(
-				entry, &reo_list->ts_latest_aged_out_frame);
+					reo_list, entry);
 
 	qdf_assert_always(release_reason != 0);
 
@@ -704,7 +711,8 @@ mgmt_rx_reo_list_is_ready_to_send_up_entry(struct mgmt_rx_reo_list *reo_list,
 	if (!reo_list || !entry)
 		return false;
 
-	return !MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(
+	return mgmt_rx_reo_list_max_size_exceeded(reo_list) ||
+	       !MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(
 	       entry) || MGMT_RX_REO_LIST_ENTRY_IS_AGED_OUT(entry) ||
 	       (reo_list->ts_latest_aged_out_frame.valid &&
 		MGMT_RX_REO_LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(
@@ -791,7 +799,7 @@ mgmt_rx_reo_list_ageout_timer_handler(void *arg)
 
 	qdf_list_for_each(&reo_list->list, cur_entry, node) {
 		if (cur_ts - cur_entry->insertion_ts >=
-		    MGMT_RX_REO_LIST_TIMEOUT) {
+		    reo_list->list_entry_timeout_us) {
 			uint32_t cur_entry_global_ts;
 			struct mgmt_rx_reo_global_ts_info *ts_ageout;
 
@@ -1130,7 +1138,9 @@ mgmt_rx_reo_list_init(struct mgmt_rx_reo_list *reo_list)
 {
 	QDF_STATUS status;
 
-	reo_list->max_list_size = MGMT_RX_REO_MAX_LIST_SIZE;
+	reo_list->max_list_size = MGMT_RX_REO_LIST_MAX_SIZE;
+	reo_list->list_entry_timeout_us = MGMT_RX_REO_LIST_TIMEOUT_US;
+
 	qdf_list_create(&reo_list->list, reo_list->max_list_size);
 	qdf_spinlock_create(&reo_list->list_lock);
 

+ 23 - 2
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_rx_reo_i.h

@@ -32,10 +32,11 @@
 #include <wlan_objmgr_pdev_obj.h>
 #include <wlan_objmgr_psoc_obj.h>
 
-#define MGMT_RX_REO_MAX_LIST_SIZE        (100)
-#define MGMT_RX_REO_LIST_TIMEOUT         (10 * USEC_PER_MSEC)
+#define MGMT_RX_REO_LIST_MAX_SIZE        (100)
+#define MGMT_RX_REO_LIST_TIMEOUT_US      (10 * USEC_PER_MSEC)
 #define MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS  (BIT(0))
 #define MGMT_RX_REO_STATUS_AGED_OUT                       (BIT(1))
+
 /**
  * TODO: Dummy macro for Maximum MLO links on the system
  * This is added only as a place holder for the time being.
@@ -47,6 +48,7 @@
 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_ZERO_WAIT_COUNT           (BIT(0))
 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_AGED_OUT                  (BIT(1))
 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME (BIT(2))
+#define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_LIST_MAX_SIZE_EXCEEDED    (BIT(3))
 
 #define MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry)   \
 	((entry)->status & MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS)
@@ -142,6 +144,8 @@ struct mgmt_rx_reo_global_ts_info {
  * @list: List used for reordering
  * @list_lock: Lock to protect the list
  * @max_list_size: Maximum size of the reorder list
+ * @list_entry_timeout_us: Time out value(microsecond) for the reorder list
+ * entries
  * @ageout_timer: Periodic timer to age-out the list entries
  * @ts_latest_aged_out_frame: Stores the global time stamp for the latest aged
  * out frame. Latest aged out frame is the aged out frame in reorder list which
@@ -153,6 +157,7 @@ struct mgmt_rx_reo_list {
 	qdf_list_t list;
 	qdf_spinlock_t list_lock;
 	uint32_t max_list_size;
+	uint32_t list_entry_timeout_us;
 	qdf_timer_t ageout_timer;
 	struct mgmt_rx_reo_global_ts_info ts_latest_aged_out_frame;
 	struct mgmt_rx_reo_global_ts_info ts_last_delivered_frame;
@@ -336,5 +341,21 @@ QDF_STATUS
 wlan_mgmt_rx_reo_algo_entry(struct wlan_objmgr_pdev *pdev,
 			    struct mgmt_rx_reo_frame_descriptor *desc,
 			    bool *is_queued);
+
+/**
+ * mgmt_rx_reo_list_max_size_exceeded() - Helper API to check whether
+ * list has exceeded the maximum configured size
+ * @reo_list: Pointer to reorder list
+ *
+ * This API expects the caller to acquire the spin lock protecting the reorder
+ * list.
+ *
+ * Return: true if reorder list has exceeded the max size
+ */
+static inline bool
+mgmt_rx_reo_list_max_size_exceeded(struct mgmt_rx_reo_list *reo_list)
+{
+	return (qdf_list_size(&reo_list->list) > reo_list->max_list_size);
+}
 #endif /* WLAN_MGMT_RX_REO_SUPPORT */
 #endif /* _WLAN_MGMT_TXRX_RX_REO_I_H */

+ 1 - 1
umac/cmn_services/mgmt_txrx/dispatcher/inc/cfg_mgmt_rx_reo.h

@@ -15,7 +15,7 @@
  */
 
 /**
- *  DOC: cfg_mgmt_txrx.h
+ *  DOC: cfg_mgmt_rx_reo.h
  *  This file contains cfg definitions of mgmt rx reo sub-component
  */