Переглянути джерело

qcacld-3.0: Log SAE authentication frames as part of roam logs

SAE authentication logging events are sent from host
driver during connection as well as during roaming.
But the other roaming frame related stats are printed
as part of the WMI_ROAM_STATS_EVENTID handling.
Since this roam stats event is received after preauth
frame related logs are queued to userspace, the order
of the logs are not correct.

Cache the SAE preauth logs in mlme and print them
upon receiving ROAM stats event. Read the firmware
service capability to decide if new caching needs
to be used or legacy behavior needs to be followed

Change-Id: I76381b9deef222f1481325974e2b5d9730eb2b67
CRs-Fixed: 3154147
Pragaspathi Thilagaraj 3 роки тому
батько
коміт
2bbd4b2892

+ 51 - 2
components/cmn_services/logging/inc/wlan_connectivity_logging.h

@@ -24,9 +24,8 @@
 #ifndef _WLAN_CONNECTIVITY_LOGGING_H_
 #define _WLAN_CONNECTIVITY_LOGGING_H_
 
-#include <wlan_cm_api.h>
-#include "wlan_cm_roam_api.h"
 #include "wlan_logging_sock_svc.h"
+#include "wlan_cm_roam_public_struct.h"
 
 #define WLAN_MAX_LOGGING_FREQ 90
 
@@ -400,6 +399,56 @@ struct wlan_connectivity_log_buf_data {
 #define logging_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, ## params)
 #define logging_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, ## params)
 
+#if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) && \
+		defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wlan_print_cached_sae_auth_logs() - Enqueue SAE authentication frame logs
+ * @bssid:  BSSID
+ * @vdev_id: Vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id);
+
+/**
+ * wlan_is_log_record_present_for_bssid() - Check if there is existing log
+ * record for the given bssid
+ * @bssid: BSSID
+ * @vdev_id: vdev id
+ *
+ * Return: true if record is present else false
+ */
+bool wlan_is_log_record_present_for_bssid(struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id);
+
+/**
+ * wlan_clear_sae_auth_logs_cache() - Clear the cached auth related logs
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void wlan_clear_sae_auth_logs_cache(uint8_t vdev_id);
+#else
+static inline
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+bool wlan_is_log_record_present_for_bssid(struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline
+void wlan_clear_sae_auth_logs_cache(uint8_t vdev_id)
+{}
+#endif
+
 #ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
 /**
  * wlan_connectivity_logging_start()  - Initialize the connectivity/roaming

+ 244 - 4
components/cmn_services/logging/src/wlan_connectivity_logging.c

@@ -20,10 +20,9 @@
  *
  * Implementation for the connectivity and roam logging api.
  */
-
-#include "wlan_mlme_api.h"
-#include "wlan_mlme_main.h"
 #include "wlan_connectivity_logging.h"
+#include "wlan_cm_api.h"
+#include "wlan_mlme_main.h"
 
 static struct wlan_connectivity_log_buf_data global_cl;
 
@@ -87,6 +86,220 @@ void wlan_connectivity_logging_stop(void)
 	qdf_spinlock_destroy(&global_cl.write_ptr_lock);
 }
 
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
+	defined(WLAN_FEATURE_CONNECTIVITY_LOGGING)
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id)
+{
+	uint8_t i, j;
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(global_cl.psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		logging_err_rl("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Get the index of matching bssid and queue all the records for
+	 * that bssid
+	 */
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		if (!mlme_priv->auth_log[i][0].ktime_us)
+			continue;
+
+		if (qdf_is_macaddr_equal(bssid,
+					 &mlme_priv->auth_log[i][0].bssid))
+			break;
+	}
+
+	/*
+	 * No matching bssid found in cached log records.
+	 * So return from here.
+	 */
+	if (i >= MAX_ROAM_CANDIDATE_AP) {
+		logging_debug("No cached SAE auth logs");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
+		if (!mlme_priv->auth_log[i][j].ktime_us)
+			continue;
+
+		wlan_connectivity_log_enqueue(&mlme_priv->auth_log[i][j]);
+		qdf_mem_zero(&mlme_priv->auth_log[i][j],
+			     sizeof(mlme_priv->auth_log[i][j]));
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool wlan_is_log_record_present_for_bssid(struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id)
+{
+	struct wlan_log_record *record;
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	int i;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(global_cl.psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return false;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		logging_err_rl("vdev legacy private object is NULL");
+		return false;
+	}
+
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		record = &mlme_priv->auth_log[i][0];
+		if (!record->ktime_us)
+			continue;
+
+		if (qdf_is_macaddr_equal(bssid, &record->bssid)) {
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+			return true;
+		}
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return false;
+}
+
+/**
+ * wlan_add_sae_log_record_to_available_slot() - Add a new log record into the
+ * cache for the queue.
+ * @mlme_priv: Mlme private object
+ * @rec: Log record pointer
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+wlan_add_sae_log_record_to_available_slot(struct mlme_legacy_priv *mlme_priv,
+					  struct wlan_log_record *rec)
+{
+	uint8_t i, j;
+	bool is_entry_exist =
+		wlan_is_log_record_present_for_bssid(&rec->bssid, rec->vdev_id);
+
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		if (is_entry_exist && mlme_priv->auth_log[i][0].ktime_us &&
+		    qdf_is_macaddr_equal(&rec->bssid,
+					 &mlme_priv->auth_log[i][0].bssid)) {
+			/*
+			 * Frames for given bssid already exists
+			 * store the new frame in corresponding array
+			 * in empty slot
+			 */
+			for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
+				if (mlme_priv->auth_log[i][j].ktime_us)
+					continue;
+
+				mlme_priv->auth_log[i][j] = *rec;
+				break;
+			}
+
+		} else if (!is_entry_exist &&
+			   !mlme_priv->auth_log[i][0].ktime_us) {
+			/*
+			 * For given record, there is no existing bssid
+			 * so add the entry at first available slot
+			 */
+			mlme_priv->auth_log[i][0] = *rec;
+			break;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+wlan_add_sae_log_record_to_available_slot(struct mlme_legacy_priv *mlme_priv,
+					  struct wlan_log_record *rec)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static QDF_STATUS
+wlan_add_sae_auth_log_record(struct wlan_objmgr_vdev *vdev,
+			     struct wlan_log_record *rec)
+{
+	struct mlme_legacy_priv *mlme_priv;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		logging_err_rl("vdev legacy private object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_add_sae_log_record_to_available_slot(mlme_priv, rec);
+}
+
+void wlan_clear_sae_auth_logs_cache(uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(global_cl.psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		logging_err_rl("vdev legacy private object is NULL");
+		return;
+	}
+
+	qdf_mem_zero(mlme_priv->auth_log, sizeof(mlme_priv->auth_log));
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+static void
+wlan_cache_connectivity_log(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			    struct wlan_log_record *rec)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!psoc) {
+		logging_err_rl("PSOC is NULL");
+		return;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return;
+	}
+
+	wlan_add_sae_auth_log_record(vdev, rec);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+#define WLAN_SAE_AUTH_ALGO_NUMBER 3
 void
 wlan_connectivity_mgmt_event(struct wlan_frame_hdr *mac_hdr,
 			     uint8_t vdev_id, uint16_t status_code,
@@ -96,6 +309,9 @@ wlan_connectivity_mgmt_event(struct wlan_frame_hdr *mac_hdr,
 			     uint8_t auth_seq, enum wlan_main_tag tag)
 {
 	struct wlan_log_record *new_rec;
+	struct wlan_objmgr_vdev *vdev;
+	bool is_initial_connection = false;
+	bool is_auth_frame_caching_required = false;
 
 	new_rec = qdf_mem_malloc(sizeof(*new_rec));
 	if (!new_rec)
@@ -119,8 +335,32 @@ wlan_connectivity_mgmt_event(struct wlan_frame_hdr *mac_hdr,
 	new_rec->pkt_info.is_retry_frame =
 		(mac_hdr->i_fc[1] & IEEE80211_FC1_RETRY);
 
-	wlan_connectivity_log_enqueue(new_rec);
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(global_cl.psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (vdev) {
+		is_initial_connection = wlan_cm_is_vdev_connecting(vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+	} else {
+		logging_debug("Unable to find vdev:%d", vdev_id);
+		goto err;
+	}
 
+	if (global_cl.psoc)
+		is_auth_frame_caching_required =
+			wlan_psoc_nif_fw_ext2_cap_get(
+				global_cl.psoc,
+				WLAN_ROAM_STATS_FRAME_INFO_PER_CANDIDATE);
+
+	if (global_cl.psoc && !is_initial_connection &&
+	    (new_rec->log_subtype == WLAN_AUTH_REQ ||
+	     new_rec->log_subtype == WLAN_AUTH_RESP) &&
+	    auth_algo == WLAN_SAE_AUTH_ALGO_NUMBER &&
+	    is_auth_frame_caching_required) {
+		wlan_cache_connectivity_log(global_cl.psoc, vdev_id, new_rec);
+	} else {
+		wlan_connectivity_log_enqueue(new_rec);
+	}
+err:
 	qdf_mem_free(new_rec);
 }
 

+ 6 - 1
components/mlme/core/inc/wlan_mlme_main.h

@@ -30,8 +30,8 @@
 #include <wlan_cmn.h>
 #include <wlan_objmgr_vdev_obj.h>
 #include <wlan_objmgr_peer_obj.h>
-#include "wlan_cm_roam_public_struct.h"
 #include "wlan_wfa_config_public_struct.h"
+#include "wlan_connectivity_logging.h"
 
 #define MAC_MAX_ADD_IE_LENGTH       2048
 
@@ -410,6 +410,8 @@ struct wait_for_key_timer {
  * @vdev_stop_type: vdev stop type request
  * @roam_off_state: Roam offload state
  * @cm_roam: Roaming configuration
+ * @auth_log: Cached log records for SAE authentication frame
+ * related information.
  * @bigtk_vdev_support: BIGTK feature support for this vdev (SAP)
  * @sae_auth_retry: SAE auth retry information
  * @roam_reason_better_ap: roam due to better AP found
@@ -449,6 +451,9 @@ struct mlme_legacy_priv {
 	uint32_t vdev_stop_type;
 	struct wlan_mlme_roam mlme_roam;
 	struct wlan_cm_roam cm_roam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	struct wlan_log_record auth_log[MAX_ROAM_CANDIDATE_AP][WLAN_ROAM_MAX_CACHED_AUTH_FRAMES];
+#endif
 	bool bigtk_vdev_support;
 	struct sae_auth_retry sae_retry;
 	bool roam_reason_better_ap;

+ 7 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -6045,9 +6045,11 @@ cm_roam_mgmt_frame_event(struct roam_frame_info *frame_data,
 	log_record->timestamp_us = qdf_get_time_of_the_day_us();
 	log_record->ktime_us = qdf_ktime_to_us(qdf_ktime_get());
 	log_record->fw_timestamp_us = (uint64_t)frame_data->timestamp * 1000;
+	log_record->bssid = frame_data->bssid;
 	log_record->vdev_id = vdev_id;
 
 	log_record->pkt_info.seq_num = frame_data->seq_num;
+	log_record->pkt_info.auth_algo = frame_data->auth_algo;
 	log_record->pkt_info.rssi = (-1) * frame_data->rssi;
 	log_record->pkt_info.tx_status = frame_data->tx_status;
 	log_record->pkt_info.frame_status_code = frame_data->status_code;
@@ -6062,6 +6064,11 @@ cm_roam_mgmt_frame_event(struct roam_frame_info *frame_data,
 					(-1) * scan_data->ap[i].rssi;
 				log_record->bssid = scan_data->ap[i].bssid;
 				break;
+			} else if (qdf_is_macaddr_equal(&log_record->bssid,
+							&scan_data->ap[i].bssid)) {
+				log_record->pkt_info.rssi =
+					(-1) * scan_data->ap[i].rssi;
+				break;
 			}
 		}
 	}

+ 8 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -31,6 +31,8 @@
 #include "wlan_cm_public_struct.h"
 #include "wmi_unified.h"
 
+#define WLAN_ROAM_MAX_CACHED_AUTH_FRAMES            8
+
 #define ROAM_SCAN_OFFLOAD_START                     1
 #define ROAM_SCAN_OFFLOAD_STOP                      2
 #define ROAM_SCAN_OFFLOAD_RESTART                   3
@@ -1908,12 +1910,16 @@ enum roam_rt_stats_type {
  * struct roam_frame_info  - Structure to hold the mgmt frame/eapol frame
  * related info exchanged during roaming.
  * @present:     Flag to indicate if roam frame info TLV is present
+ * @bssid:       BSSID of the candidate AP or roamed AP to which the
+ * frame exchange happened
  * @timestamp:   Fw timestamp at which the frame was Tx/Rx'ed
  * @type:        Frame Type
  * @subtype:     Frame subtype
  * @is_rsp:      True if frame is response frame else false
  * @seq_num:     Frame sequence number from the 802.11 header
  * @status_code: Status code from 802.11 spec, section 9.4.1.9
+ * @auth_algo: Authentication algorithm as defined in 802.11 spec,
+ * 9.4.1.1 Authentication Algorithm Number field
  * @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
  * applicable only for tx frames
  * @rssi: Frame rssi
@@ -1921,12 +1927,14 @@ enum roam_rt_stats_type {
  */
 struct roam_frame_info {
 	bool present;
+	struct qdf_mac_addr bssid;
 	uint32_t timestamp;
 	uint8_t type;
 	uint8_t subtype;
 	uint8_t is_rsp;
 	enum qdf_dp_tx_rx_status tx_status;
 	uint16_t seq_num;
+	uint8_t auth_algo;
 	uint16_t status_code;
 	int32_t rssi;
 	uint16_t retry_count;

+ 11 - 1
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -34,7 +34,7 @@
 #include "wlan_dlm_api.h"
 #include <../../core/src/wlan_cm_roam_i.h>
 #include "wlan_reg_ucfg_api.h"
-
+#include "wlan_connectivity_logging.h"
 
 /* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */
 #define BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15
@@ -3054,6 +3054,7 @@ cm_get_frame_subtype_str(enum mgmt_subtype frame_subtype)
 	return "Invalid frm";
 }
 
+#define WLAN_SAE_AUTH_ALGO 3
 static void
 cm_roam_print_frame_info(struct roam_frame_stats *frame_data,
 			 struct wmi_roam_scan_data *scan_data, uint8_t vdev_id)
@@ -3067,6 +3068,14 @@ cm_roam_print_frame_info(struct roam_frame_stats *frame_data,
 
 	for (i = 0; i < frame_data->num_frame; i++) {
 		frame_info = &frame_data->frame_info[i];
+		if (frame_info->auth_algo == WLAN_SAE_AUTH_ALGO &&
+		    wlan_is_log_record_present_for_bssid(&frame_info->bssid,
+							 vdev_id)) {
+			wlan_print_cached_sae_auth_logs(&frame_info->bssid,
+							vdev_id);
+			continue;
+		}
+
 		qdf_mem_zero(time, TIME_STRING_LEN);
 		mlme_get_converted_timestamp(frame_info->timestamp, time);
 
@@ -3293,6 +3302,7 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 		}
 	}
 
+	wlan_clear_sae_auth_logs_cache(stats_info->vdev_id);
 err:
 	if (stats_info->roam_msg_info)
 		qdf_mem_free(stats_info->roam_msg_info);

+ 26 - 5
components/wmi/src/wmi_unified_roam_tlv.c

@@ -1993,7 +1993,13 @@ wmi_get_converted_tx_status(
 	return QDF_TX_RX_STATUS_INVALID;
 }
 
-#define WLAN_FC0_SUBTYPE_SHIFT         4
+#define WLAN_FC0_SUBTYPE_SHIFT              4
+#define WLAN_FRAME_INFO_TYPE_OFFSET         0
+#define WLAN_FRAME_INFO_SUBTYPE_OFFSET      2
+#define WLAN_FRAME_INFO_RESP_OFFSET         6
+#define WLAN_FRAME_INFO_AUTH_ALG_OFFSET     7
+#define WLAN_FRAME_INFO_SEQ_NUM_OFFSET      16
+
 /**
  * extract_roam_frame_info_tlv() - Extract the frame exchanges during roaming
  * info from the WMI_ROAM_STATS_EVENTID
@@ -2032,9 +2038,13 @@ extract_roam_frame_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 	dst_buf = dst->frame_info;
 	for (i = 0; i < num_frames; i++) {
 		dst_buf->timestamp = src_data->timestamp;
-		dst_buf->type = WMI_GET_BITS(src_data->frame_info, 0, 2);
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid,
+					   dst_buf->bssid.bytes);
+		dst_buf->type = WMI_GET_BITS(src_data->frame_info,
+					     WLAN_FRAME_INFO_TYPE_OFFSET, 2);
 
-		subtype = WMI_GET_BITS(src_data->frame_info, 2, 4);
+		subtype = WMI_GET_BITS(src_data->frame_info,
+				       WLAN_FRAME_INFO_SUBTYPE_OFFSET, 4);
 		if (dst_buf->type == WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT) {
 			dst_buf->type = ROAM_FRAME_INFO_FRAME_TYPE_EXT;
 			dst_buf->subtype =
@@ -2043,12 +2053,23 @@ extract_roam_frame_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 			dst_buf->subtype = subtype << WLAN_FC0_SUBTYPE_SHIFT;
 		}
 
-		dst_buf->is_rsp = WMI_GET_BITS(src_data->frame_info, 6, 1);
+		dst_buf->is_rsp = WMI_GET_BITS(src_data->frame_info,
+					       WLAN_FRAME_INFO_RESP_OFFSET, 1);
 		dst_buf->is_rsp &=
 			(dst_buf->type != WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT &&
 			 dst_buf->subtype == MGMT_SUBTYPE_AUTH);
-		dst_buf->seq_num = WMI_GET_BITS(src_data->frame_info, 7, 16);
+
+		dst_buf->seq_num = WMI_GET_BITS(src_data->frame_info,
+						WLAN_FRAME_INFO_SEQ_NUM_OFFSET,
+						16);
 		dst_buf->status_code = src_data->status_code;
+		if (dst_buf->type != WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT &&
+		    dst_buf->subtype == MGMT_SUBTYPE_AUTH)
+			dst_buf->auth_algo =
+				WMI_GET_BITS(src_data->frame_info,
+					     WLAN_FRAME_INFO_AUTH_ALG_OFFSET,
+					     4);
+
 		if (!dst_buf->is_rsp)
 			dst_buf->tx_status = wmi_get_converted_tx_status(
 							src_data->status_code);