ソースを参照

qcacld-3.0: Add changes for auth in send mgmt path

Add changes to support authentication in send mgmt path.
With these changes, supplicant/upper layer can send authentication
frame for station mode.

Change-Id: I6807f49acc9284e69c6362e07a583ff26f15edca
CRs-Fixed: 2029357
Padma, Santhosh Kumar 7 年 前
コミット
22c462c648

+ 23 - 0
core/hdd/src/wlan_hdd_p2p.c

@@ -226,6 +226,9 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	QDF_STATUS status;
 	struct net_device *dev = wdev->netdev;
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	uint8_t type;
+	uint8_t sub_type;
+	QDF_STATUS qdf_status;
 
 	ENTER();
 
@@ -239,6 +242,26 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		return -EINVAL;
 	}
 
+	type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
+	sub_type = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
+
+	/* When frame to be transmitted is auth mgmt, then trigger
+	 * sme_send_mgmt_tx to send auth frame without need for policy manager.
+	 * Where as wlan_cfg80211_mgmt_tx requires roc and requires approval
+	 * from policy manager.
+	 */
+	if ((adapter->device_mode == QDF_STA_MODE) &&
+	    (type == SIR_MAC_MGMT_FRAME &&
+	    sub_type == SIR_MAC_MGMT_AUTH)) {
+		qdf_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(adapter),
+					      adapter->session_id, buf, len);
+
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			return 0;
+		else
+			return -EINVAL;
+	}
+
 	status = wlan_cfg80211_mgmt_tx(adapter->hdd_vdev, chan,
 			offchan, wait, buf, len, no_cck,
 			dont_wait_for_ack, cookie);

+ 1 - 0
core/mac/inc/wni_api.h

@@ -247,6 +247,7 @@ enum eWniMsgTypes {
 	eWNI_SME_BT_ACTIVITY_INFO_IND,
 	eWNI_SME_SET_HE_BSS_COLOR,
 	eWNI_SME_TRIGGER_SAE,
+	eWNI_SME_SEND_MGMT_FRAME_TX,
 	eWNI_SME_MSG_TYPES_END
 };
 

+ 14 - 0
core/mac/src/include/sir_params.h

@@ -202,6 +202,20 @@ typedef struct sSirMbMsgP2p {
 	uint32_t data[1];
 } tSirMbMsgP2p, *tpSirMbMsgP2p;
 
+/**
+ * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM
+ * @type: Message type
+ * @msg_len: Message length
+ * @session_id: session id
+ * @data: Pointer to data tobe transmitted
+ */
+struct sir_mgmt_msg {
+	uint16_t type;
+	uint16_t msg_len;
+	uint8_t session_id;
+	uint8_t *data;
+};
+
 /* ******************************************* *
 *                                             *
 *         SIRIUS MESSAGE TYPES                *

+ 5 - 0
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1477,6 +1477,11 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
 		/* These messages are from HDD.No need to respond to HDD */
 		lim_process_normal_hdd_msg(mac_ctx, msg, false);
 		break;
+	case eWNI_SME_SEND_MGMT_FRAME_TX:
+		lim_send_mgmt_frame_tx(mac_ctx, msg);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
 	case eWNI_SME_MON_INIT_SESSION:
 		lim_mon_init_session(mac_ctx, msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);

+ 82 - 0
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -4827,3 +4827,85 @@ error_addba_rsp:
 	cds_packet_free((void *)pkt_ptr);
 	return qdf_status;
 }
+
+/**
+ * lim_tx_mgmt_frame() - Transmits Auth mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @mb_msg: Received message info
+ * @msg_len: Received message length
+ * @packet: Packet to be transmitted
+ * @frame: Received frame
+ *
+ * Return: None
+ */
+static void lim_tx_mgmt_frame(tpAniSirGlobal mac_ctx,
+	struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
+	void *packet, uint8_t *frame)
+{
+	tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+	QDF_STATUS qdf_status;
+	uint8_t sme_session_id = 0;
+	tpPESession session;
+	uint16_t auth_ack_status;
+	enum rateid min_rid = RATEID_DEFAULT;
+
+	sme_session_id = mb_msg->session_id;
+	session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+	if (session == NULL) {
+		pe_err("session not found for given sme session");
+		return;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 session->peSessionId, fc->subType));
+
+	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+	min_rid = lim_get_min_session_txrate(session);
+
+	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
+					 (uint16_t)msg_len,
+					 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+					 7, lim_tx_complete, frame,
+					 lim_auth_tx_complete_cnf,
+					 0, sme_session_id, false, 0, min_rid);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		session->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("*** Could not send Auth frame, retCode=%X ***",
+			qdf_status);
+		mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
+		auth_ack_status = SENT_FAIL;
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
+				session, auth_ack_status, eSIR_FAILURE);
+		/* Pkt will be freed up by the callback */
+	}
+}
+
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+		struct scheduler_msg *msg)
+{
+	struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
+	uint32_t msg_len;
+	tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+	uint8_t sme_session_id;
+	QDF_STATUS qdf_status;
+	uint8_t *frame;
+	void *packet;
+
+	msg_len = mb_msg->msg_len - sizeof(*mb_msg);
+	pe_debug("sending fc->type: %d fc->subType: %d",
+		fc->type, fc->subType);
+
+	sme_session_id = mb_msg->session_id;
+
+	qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
+				 (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("call to bufAlloc failed for AUTH frame");
+		return;
+	}
+
+	qdf_mem_copy(frame, mb_msg->data, msg_len);
+
+	lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+}

+ 11 - 0
core/mac/src/pe/lim/lim_types.h

@@ -1024,4 +1024,15 @@ void lim_process_auth_failure_timeout(tpAniSirGlobal mac_ctx);
  */
 void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx,
 				       uint32_t msg_type);
+
+/**
+ * lim_send_mgmt_frame_tx() - Sends mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @msg: Received message info
+ *
+ * Return: None
+ */
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+		struct scheduler_msg *msg);
+
 #endif /* __LIM_TYPES_H */

+ 1 - 0
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -402,6 +402,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND);
 		CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
 		CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE);
+		CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX);
 		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
 	default:
 		return (uint8_t *) "UNKNOWN";

+ 12 - 0
core/sme/inc/sme_api.h

@@ -1925,6 +1925,7 @@ void sme_free_join_rsp_fils_params(struct csr_roam_info *roam_info)
 {}
 
 #endif
+
 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
 /**
  * sme_set_he_bss_color() - Sets the HE BSS color
@@ -2027,4 +2028,15 @@ int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
  */
 void sme_enable_roaming_on_connected_sta(tHalHandle hal);
 
+/**
+ * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len);
 #endif /* #if !defined( __SME_API_H ) */

+ 2 - 1
core/sme/inc/sme_trace.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -141,6 +141,7 @@ enum {
 #endif
 	TRACE_CODE_SME_RX_HDD_PREF_NET_LIST,
 	TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+	TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX,
 	/*
 	 * New trace commands to be added before this comment not at the end
 	 * Trace codes for SME commands

+ 55 - 0
core/sme/src/common/sme_api.c

@@ -5512,6 +5512,61 @@ QDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
 	return status;
 }
 
+/**
+ * sme_prepare_mgmt_tx() - Prepares mgmt frame
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sir_mgmt_msg *msg;
+	uint16_t msg_len;
+	struct scheduler_msg sch_msg = {0};
+
+	sme_debug("prepares auth frame");
+
+	msg_len = sizeof(*msg) + len;
+	msg = qdf_mem_malloc(msg_len);
+	if (msg == NULL) {
+		status = QDF_STATUS_E_NOMEM;
+	} else {
+		msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
+		msg->msg_len = msg_len;
+		msg->session_id = session_id;
+		msg->data = (uint8_t *)msg + sizeof(*msg);
+		qdf_mem_copy(msg->data, buf, len);
+
+		sch_msg.type = eWNI_SME_SEND_MGMT_FRAME_TX;
+		sch_msg.bodyptr = msg;
+		status = scheduler_post_msg(QDF_MODULE_ID_PE, &sch_msg);
+	}
+	return status;
+}
+
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0));
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
 /**
  * sme_configure_ext_wow() - configure Extr WoW