Browse Source

qcacld-3.0: Fix handling of QOS action frame

QOS action frame is not handled and thus HDD's dscp mapping
are not updated.

Update the HDD's dscp mapping properly once hdd receive
QOS action frame.

Change-Id: I04ba9882767918cfb0c551791783f2b7eac998d5
CRs-Fixed: 2325729
Abhishek Singh 6 years ago
parent
commit
ee5c9a3851
1 changed files with 43 additions and 17 deletions
  1. 43 17
      core/hdd/src/wlan_hdd_p2p.c

+ 43 - 17
core/hdd/src/wlan_hdd_p2p.c

@@ -903,9 +903,30 @@ int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 	return ret;
 }
 
+/**
+ * hdd_is_qos_action_frame() - check if frame is QOS action frame
+ * @pb_frames: frame pointer
+ * @frame_len: frame length
+ *
+ * Return: true if it is QOS action frame else false.
+ */
+static inline bool
+hdd_is_qos_action_frame(uint8_t *pb_frames, uint32_t frame_len)
+{
+	if (frame_len <= WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1) {
+		hdd_debug("Not a QOS frame len: %d", frame_len);
+		return false;
+	}
+
+	return ((pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] ==
+		 WLAN_HDD_QOS_ACTION_FRAME) &&
+		(pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
+		 WLAN_HDD_QOS_MAP_CONFIGURE));
+}
+
 void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
-			     uint32_t nFrameLength,
-			     uint8_t *pbFrames,
+			     uint32_t frm_len,
+			     uint8_t *pb_frames,
 			     uint8_t frameType, uint32_t rxChan, int8_t rxRssi)
 {
 	uint16_t freq;
@@ -914,7 +935,7 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
 	struct hdd_context *hdd_ctx;
 
 	hdd_debug("Frame Type = %d Frame Length = %d",
-		frameType, nFrameLength);
+		frameType, frm_len);
 
 	if (NULL == adapter) {
 		hdd_err("adapter is NULL");
@@ -922,27 +943,27 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
 	}
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
-	if (0 == nFrameLength) {
+	if (!frm_len) {
 		hdd_err("Frame Length is Invalid ZERO");
 		return;
 	}
 
-	if (NULL == pbFrames) {
+	if (!pb_frames) {
 		hdd_err("pbFrames is NULL");
 		return;
 	}
 
-	type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
-	subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
+	type = WLAN_HDD_GET_TYPE_FRM_FC(pb_frames[0]);
+	subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pb_frames[0]);
 
 	/* Get adapter from Destination mac address of the frame */
 	if ((type == SIR_MAC_MGMT_FRAME) &&
 	    (subType != SIR_MAC_MGMT_PROBE_REQ) &&
 	    !qdf_is_macaddr_broadcast(
-	     (struct qdf_mac_addr *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET])) {
+	     (struct qdf_mac_addr *)&pb_frames[WLAN_HDD_80211_FRM_DA_OFFSET])) {
 		adapter =
 			hdd_get_adapter_by_macaddr(hdd_ctx,
-						   &pbFrames
+						   &pb_frames
 						   [WLAN_HDD_80211_FRM_DA_OFFSET]);
 		if (NULL == adapter) {
 			/*
@@ -952,17 +973,17 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
 			 */
 			hdd_err("adapter for action frame is NULL Macaddr = "
 				  MAC_ADDRESS_STR,
-				  MAC_ADDR_ARRAY(&pbFrames
+				  MAC_ADDR_ARRAY(&pb_frames
 						 [WLAN_HDD_80211_FRM_DA_OFFSET]));
 			hdd_debug("Frame Type = %d Frame Length = %d subType = %d",
-				frameType, nFrameLength, subType);
+				frameType, frm_len, subType);
 			/*
 			 * We will receive broadcast management frames
 			 * in OCB mode
 			 */
 			adapter = hdd_get_adapter(hdd_ctx, QDF_OCB_MODE);
 			if (NULL == adapter || !qdf_is_macaddr_broadcast(
-				(struct qdf_mac_addr *)&pbFrames
+				(struct qdf_mac_addr *)&pb_frames
 				[WLAN_HDD_80211_FRM_DA_OFFSET])) {
 				/*
 				 * Under assumtion that we don't
@@ -994,23 +1015,28 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
 		freq = ieee80211_channel_to_frequency(rxChan,
 						      NL80211_BAND_5GHZ);
 
+	if (hdd_is_qos_action_frame(pb_frames, frm_len))
+		sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
+					      adapter->dscp_to_up_map,
+					      adapter->session_id);
+
 	/* Indicate Frame Over Normal Interface */
 	hdd_debug("Indicate Frame over NL80211 sessionid : %d, idx :%d",
 		   adapter->session_id, adapter->dev->ifindex);
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
 	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
-		 freq, rxRssi * 100, pbFrames,
-			 nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED);
+		 freq, rxRssi * 100, pb_frames,
+			 frm_len, NL80211_RXMGMT_FLAG_ANSWERED);
 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
 	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
-			freq, rxRssi * 100, pbFrames,
-			 nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED,
+			freq, rxRssi * 100, pb_frames,
+			 frm_len, NL80211_RXMGMT_FLAG_ANSWERED,
 			 GFP_ATOMIC);
 #else
 	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, freq,
 			rxRssi * 100,
-			pbFrames, nFrameLength, GFP_ATOMIC);
+			pb_frames, frm_len, GFP_ATOMIC);
 #endif /* LINUX_VERSION_CODE */
 }