فهرست منبع

qcacmn: Prevent out of order delivery of mgmt frames

Keep track of the global time stamp of the last
management frame delivered to the upper layer.
Drop all the frames older than the last delivered
frame.

CRs-Fixed: 3049671
Change-Id: Ibe0cc239f7af38da63ea8c405b3f89fc9473ea57
Edayilliam Jayadev 3 سال پیش
والد
کامیت
d9667ef801

+ 34 - 2
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_rx_reo.c

@@ -623,10 +623,15 @@ mgmt_rx_reo_list_entry_send_up(struct mgmt_rx_reo_list *reo_list,
 	QDF_STATUS status;
 	uint8_t link_id;
 	struct wlan_objmgr_pdev *pdev;
+	uint32_t entry_global_ts;
+	struct mgmt_rx_reo_global_ts_info *ts_last_delivered_frame;
 
 	qdf_assert_always(reo_list);
 	qdf_assert_always(entry);
 
+	entry_global_ts = mgmt_rx_reo_get_global_ts(entry->rx_params);
+	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);
 
@@ -640,6 +645,32 @@ mgmt_rx_reo_list_entry_send_up(struct mgmt_rx_reo_list *reo_list,
 
 	link_id = mgmt_rx_reo_get_link_id(entry->rx_params);
 
+	/**
+	 * Last delivered frame global time stamp is invalid means that
+	 * current frame is the first frame to be delivered to the upper layer
+	 * from the reorder list. Blindly update the last delivered frame global
+	 * time stamp to the current frame's global time stamp and set the valid
+	 * to true.
+	 * If the last delivered frame global time stamp is valid and
+	 * current frame's global time stamp is >= last delivered frame global
+	 * time stamp, deliver the current frame to upper layer and update the
+	 * last delivered frame global time stamp.
+	 */
+	if (!ts_last_delivered_frame->valid ||
+	    mgmt_rx_reo_compare_global_timestamps_gte(
+		    entry_global_ts, ts_last_delivered_frame->global_ts)) {
+		/* TODO Process current management frame here */
+
+		ts_last_delivered_frame->global_ts = entry_global_ts;
+		ts_last_delivered_frame->valid = true;
+	} else {
+		/**
+		 * We need to replicate all the cleanup activities which the
+		 * upper layer would have done.
+		 */
+		qdf_nbuf_free(entry->nbuf);
+	}
+
 	free_mgmt_rx_event_params(entry->rx_params);
 
 	pdev = wlan_get_pdev_from_mlo_link_id(link_id);
@@ -1111,6 +1142,9 @@ mgmt_rx_reo_list_init(struct mgmt_rx_reo_list *reo_list)
 		return status;
 	}
 
+	reo_list->ts_last_delivered_frame.valid = false;
+	reo_list->ts_latest_aged_out_frame.valid = false;
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -1343,8 +1377,6 @@ mgmt_rx_reo_init_context(void)
 		return status;
 	}
 
-	reo_context->ts_last_delivered_frame.valid = false;
-
 	qdf_spinlock_create(&reo_context->reo_algo_entry_lock);
 
 	return QDF_STATUS_SUCCESS;

+ 3 - 3
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_rx_reo_i.h

@@ -146,6 +146,8 @@ struct mgmt_rx_reo_global_ts_info {
  * @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
  * has the largest global time stamp value.
+ * @ts_last_delivered_frame: Stores the global time stamp for the last frame
+ * delivered to the upper layer
  */
 struct mgmt_rx_reo_list {
 	qdf_list_t list;
@@ -153,6 +155,7 @@ struct mgmt_rx_reo_list {
 	uint32_t max_list_size;
 	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;
 };
 
 /*
@@ -191,15 +194,12 @@ struct mgmt_rx_reo_list_entry {
  * management rx-reordering. Reordering is done across all the psocs.
  * So there should be only one instance of this structure defined.
  * @reo_list: Linked list used for reordering
- * @ts_last_delivered_frame: Stores the global time stamp for the last frame
- * delivered to the upper layer
  * @num_mlo_links: Number of MLO links on the system
  * @reo_algo_entry_lock: Spin lock to protect reo algorithm entry critical
  * section execution
  */
 struct mgmt_rx_reo_context {
 	struct mgmt_rx_reo_list reo_list;
-	struct mgmt_rx_reo_global_ts_info ts_last_delivered_frame;
 	uint8_t num_mlo_links;
 	qdf_spinlock_t reo_algo_entry_lock;
 };