Bladeren bron

qcacld-3.0: Fix to send the deauthentication frame from HDD

qcacld-2.0 to qcacld-3.0 propagation

Currently, On sending disassoc from HDD lim will process
disassoc and clear's session of station and thus leading to
drop deauth in lim since context is already cleared. Hence
deauth frame is not sent from SoftAP although deauth command
is executed on hostapd_cli.
Fix will ensure to send disassoc command through new API
and doesn't clear's session and the same is cleared after
sending deauth.

Change-Id: I912a91f1df4001bb2d4f1f0d6031cc102d1bbd65
CRs-Fixed: 981121
Kondabattini, Ganesh 8 jaren geleden
bovenliggende
commit
3f2d02cd32

+ 4 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -12608,7 +12608,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
 				goto fn_end;
 
 			qdf_event_reset(&hapd_state->qdf_event);
-			hdd_softap_sta_disassoc(pAdapter, pDelStaParams);
+			sme_send_disassoc_req_frame(WLAN_HDD_GET_HAL_CTX
+					(pAdapter), pAdapter->sessionId,
+					(uint8_t *)&pDelStaParams->peerMacAddr,
+					pDelStaParams->reason_code, 0);
 			qdf_status = hdd_softap_sta_deauth(pAdapter,
 							   pDelStaParams);
 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {

+ 20 - 0
core/mac/inc/sir_api.h

@@ -6432,4 +6432,24 @@ struct sir_mac_pwr_dbg_cmd {
 	uint32_t args[MAX_POWER_DBG_ARGS_SUPPORTED];
 };
 
+/**
+ * struct sme_send_disassoc_frm_req - send disassoc request frame
+ * @msg_type: message type
+ * @length: length of message
+ * @session_id: session id
+ * @trans_id: transaction id
+ * @peer_mac: peer mac address
+ * @reason: reason for disassoc
+ * @wait_for_ack: wait for acknowledgment
+ **/
+ struct sme_send_disassoc_frm_req {
+	uint16_t msg_type;
+	uint16_t length;
+	uint8_t session_id;
+	uint16_t trans_id;
+	uint8_t peer_mac[6];
+	uint16_t reason;
+	uint8_t wait_for_ack;
+ };
+
 #endif /* __SIR_API_H */

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

@@ -261,6 +261,7 @@ enum eWniMsgTypes {
 	eWNI_SME_NDP_PEER_DEPARTED_IND,
 	eWNI_SME_NDP_END_IND,
 	eWNI_SME_REGISTER_P2P_ACK_CB,
+	eWNI_SME_SEND_DISASSOC_FRAME,
 	eWNI_SME_MSG_TYPES_END
 };
 

+ 4 - 1
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1364,7 +1364,10 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
 		/* These messages are from HDD. Need to respond to HDD */
 		lim_process_normal_hdd_msg(mac_ctx, msg, true);
 		break;
-
+	case eWNI_SME_SEND_DISASSOC_FRAME:
+		/* Need to response to hdd */
+		lim_process_normal_hdd_msg(mac_ctx, msg, true);
+		break;
 	case eWNI_SME_SCAN_ABORT_IND:
 		req_msg = msg->bodyptr;
 		if (req_msg) {

+ 69 - 1
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -90,6 +90,8 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal, uint32_t *);
 static void __lim_process_sme_deauth_req(tpAniSirGlobal, uint32_t *);
 static void __lim_process_sme_set_context_req(tpAniSirGlobal, uint32_t *);
 static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg);
+static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
+				uint32_t *msg_buf);
 static void lim_process_sme_channel_change_request(tpAniSirGlobal pMac,
 						   uint32_t *pMsg);
 static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg);
@@ -120,7 +122,6 @@ extern void pe_register_callbacks_with_wma(tpAniSirGlobal pMac,
 static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
 						uint32_t *msg);
 
-
 /**
  * lim_process_set_hw_mode() - Send set HW mode command to WMA
  * @mac: Globacl MAC pointer
@@ -4762,6 +4763,69 @@ static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal mac_ctx,
 		lim_log(mac_ctx, LOGE, FL("sme_req->callback is null"));
 }
 
+/**
+ *__lim_process_send_disassoc_frame: function processes disassoc frame
+ * @mac_ctx: pointer to mac context
+ * @msg_buf: message buffer
+ *
+ * function processes disassoc request received from SME
+ *
+ * return: none
+ */
+static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
+					uint32_t *msg_buf)
+{
+	struct sme_send_disassoc_frm_req sme_send_disassoc_frame_req;
+	tSirRetStatus status;
+	tpPESession session_entry = NULL;
+	uint8_t sme_session_id;
+	uint16_t sme_trans_id;
+
+	if (msg_buf == NULL) {
+		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+		return;
+	}
+
+	lim_get_session_info(mac_ctx, (uint8_t *)msg_buf, &sme_session_id,
+			&sme_trans_id);
+
+	status = lim_send_disassoc_frm_req_ser_des(mac_ctx,
+				&sme_send_disassoc_frame_req,
+				(uint8_t *)msg_buf);
+
+	if ((eSIR_FAILURE == status) ||
+		(lim_is_group_addr(sme_send_disassoc_frame_req.peer_mac) &&
+		!lim_is_addr_bc(sme_send_disassoc_frame_req.peer_mac))) {
+		PELOGE(lim_log(mac_ctx, LOGE,
+			FL("received invalid SME_DISASSOC_REQ message"));)
+		return;
+	}
+
+	session_entry = pe_find_session_by_sme_session_id(
+				mac_ctx, sme_session_id);
+	if (session_entry == NULL) {
+		lim_log(mac_ctx, LOGE,
+			FL("session does not exist for given bssId "MAC_ADDRESS_STR),
+			MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac));
+		return;
+	}
+
+	lim_log(mac_ctx, LOG1,
+			FL("msg_type->%d len->%d sess_id->%d trans_id->%d mac->"MAC_ADDRESS_STR" reason->%d wait_for_ack->%d"),
+			sme_send_disassoc_frame_req.msg_type,
+			sme_send_disassoc_frame_req.length,
+			sme_send_disassoc_frame_req.session_id,
+			sme_send_disassoc_frame_req.trans_id,
+			MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac),
+			sme_send_disassoc_frame_req.reason,
+			sme_send_disassoc_frame_req.wait_for_ack);
+
+	lim_send_disassoc_mgmt_frame(mac_ctx,
+		sme_send_disassoc_frame_req.reason,
+		sme_send_disassoc_frame_req.peer_mac,
+		session_entry, sme_send_disassoc_frame_req.wait_for_ack);
+}
+
 /**
  * lim_set_pdev_ht_ie() - sends the set HT IE req to FW
  * @mac_ctx: Pointer to Global MAC structure
@@ -5031,6 +5095,10 @@ bool lim_process_sme_req_messages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
 		__lim_process_sme_deauth_req(pMac, pMsgBuf);
 		break;
 
+	case eWNI_SME_SEND_DISASSOC_FRAME:
+		__lim_process_send_disassoc_frame(pMac, pMsgBuf);
+		break;
+
 	case eWNI_SME_SETCONTEXT_REQ:
 		__lim_process_sme_set_context_req(pMac, pMsgBuf);
 		break;

+ 76 - 1
core/mac/src/pe/lim/lim_ser_des_utils.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015,2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -43,6 +43,7 @@
 #include "lim_utils.h"
 #include "lim_ser_des_utils.h"
 
+
 /**---------------------------------------------------------------
    \fn     lim_get_session_info
    \brief  This function returns the sessionId and transactionId
@@ -76,3 +77,77 @@ lim_get_session_info(tpAniSirGlobal pMac, uint8_t *pBuf, uint8_t *sessionId,
 
 	return;
 }
+
+/**
+ * lim_send_disassoc_frm_req_ser_des - called on receiving SME_DISASSOC_REQ
+ * @mac_ctx: pointer to mac context
+ * @disassoc_frm_req: pointer to structure sme_send_disassoc_frm_req
+ *
+ * function send's disassoc frame request on receiving SME_DISASSOC_REQ
+ *
+ * return: eSIR_SUCCESS:Success Error value: Failure
+ */
+tSirRetStatus lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx,
+			struct sme_send_disassoc_frm_req *disassoc_frm_req,
+			uint8_t *buf)
+{
+	A_INT16 len = 0;
+
+	if (!disassoc_frm_req || !buf)
+		return eSIR_FAILURE;
+
+	disassoc_frm_req->msg_type = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+
+	len = disassoc_frm_req->length = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+
+	PELOG1(lim_log(mac_ctx, LOG1,
+		FL("SME_DISASSOC_REQ length %d bytes is:"), len);)
+		PELOG1(sirDumpBuf(mac_ctx, SIR_LIM_MODULE_ID, LOG1, buf, len);)
+
+	if (len < (A_INT16) sizeof(A_UINT32))
+		return eSIR_FAILURE;
+
+	/* skip message header */
+	len -= sizeof(A_UINT32);
+	if (len < 0)
+		return eSIR_FAILURE;
+
+	/* Extract sessionID */
+	disassoc_frm_req->session_id = *buf;
+	buf += sizeof(A_UINT8);
+	len -= sizeof(A_UINT8);
+	if (len < 0)
+		return eSIR_FAILURE;
+
+	/* Extract transactionid */
+	disassoc_frm_req->trans_id = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+	len -= sizeof(A_UINT16);
+
+	if (len < 0)
+		return eSIR_FAILURE;
+
+	/* Extract peerMacAddr */
+	qdf_mem_copy(disassoc_frm_req->peer_mac, buf, sizeof(tSirMacAddr));
+	buf += sizeof(tSirMacAddr);
+	len  -= sizeof(tSirMacAddr);
+
+	if (len < 0)
+		return eSIR_FAILURE;
+
+	/* Extract reasonCode */
+	disassoc_frm_req->reason = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+	len  -= sizeof(A_UINT16);
+
+	if (len < 0)
+		return eSIR_FAILURE;
+
+	disassoc_frm_req->wait_for_ack = *buf;
+	buf += sizeof(A_UINT8);
+	len -= sizeof(A_UINT8);
+
+	return eSIR_SUCCESS;
+}

+ 5 - 1
core/mac/src/pe/lim/lim_ser_des_utils.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015,2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -95,4 +95,8 @@ static inline uint32_t lim_get_u32(uint8_t *ptr)
 #endif
 }
 
+tSirRetStatus lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx,
+		struct sme_send_disassoc_frm_req *disassoc_frm_req,
+		uint8_t *buf);
+
 #endif /* __LIM_SERDES_UTILS_H */

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

@@ -1161,4 +1161,7 @@ QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
 					  uint8_t default_idx);
 QDF_STATUS sme_register_p2p_ack_ind_callback(tHalHandle hal,
 		sir_p2p_ack_ind_callback callback);
+void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id, uint8_t
+				*peer_mac, uint16_t reason, uint8_t
+				wait_for_ack);
 #endif /* #if !defined( __SME_API_H ) */

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

@@ -15822,6 +15822,72 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id)
 	return qdf_status;
 }
 
+/**
+ * sme_send_disassoc_req_frame - send disassoc req
+ * @hal: handler to hal
+ * @session_id: session id
+ * @peer_mac: peer mac address
+ * @reason: reason for disassociation
+ * wait_for_ack: wait for acknowledgment
+ *
+ * function to send disassoc request to lim
+ *
+ * return: none
+ */
+void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id,
+		uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack)
+{
+	struct sme_send_disassoc_frm_req *msg;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	A_UINT8  *buf;
+	A_UINT16 tmp;
+
+	msg = qdf_mem_malloc(sizeof(struct sme_send_disassoc_frm_req));
+
+	if (NULL == msg)
+		qdf_status = QDF_STATUS_E_FAILURE;
+	else
+		qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		return;
+
+	qdf_mem_set(msg, sizeof(struct sme_send_disassoc_frm_req), 0);
+	msg->msg_type = (uint16_t) eWNI_SME_SEND_DISASSOC_FRAME;
+
+	msg->length = (uint16_t) sizeof(struct sme_send_disassoc_frm_req);
+
+	buf = &msg->session_id;
+
+	/* session id */
+	*buf = (A_UINT8) session_id;
+	buf += sizeof(A_UINT8);
+
+	/* transaction id */
+	*buf = 0;
+	*(buf + 1) = 0;
+	buf += sizeof(A_UINT16);
+
+	/* Set the peer MAC address before sending the message to LIM */
+	qdf_mem_copy(buf, peer_mac, QDF_MAC_ADDR_SIZE);
+
+	buf += QDF_MAC_ADDR_SIZE;
+
+	/* reasoncode */
+	tmp = (uint16_t) reason;
+	qdf_mem_copy(buf, &tmp, sizeof(uint16_t));
+	buf += sizeof(uint16_t);
+
+	*buf =  wait_for_ack;
+	buf += sizeof(uint8_t);
+
+	qdf_status = cds_send_mb_message_to_mac(msg);
+
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("cds_send_mb_message Failed"));
+}
+
 /**
  * sme_get_bpf_offload_capabilities() - Get length for BPF offload
  * @hal: Global HAL handle