qcacmn: Add APIs to get IE by EID and Ext ID

Add wlan utility APIs to get IE pointer from within IE buffer by
EID or Ext ID.

Change-Id: I26492078cec73b5877f3fc346a91223a045f31aa
CRs-Fixed: 2103529
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index 9a37679..ca690a8 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -91,6 +91,7 @@
 #define WLAN_CHAN_170_FREQ      (5852)
 
 #define WLAN_MAC_EID_VENDOR     221
+#define WLAN_MAC_EID_EXT        255
 
 /**
  * enum wlan_umac_comp_id - UMAC component id
diff --git a/umac/cmn_services/utils/inc/wlan_utility.h b/umac/cmn_services/utils/inc/wlan_utility.h
index c604ee5..35e32ee 100644
--- a/umac/cmn_services/utils/inc/wlan_utility.h
+++ b/umac/cmn_services/utils/inc/wlan_utility.h
@@ -63,6 +63,19 @@
 uint8_t wlan_freq_to_chan(uint32_t freq);
 
 /**
+ * wlan_get_ie_ptr_from_eid() - Find out ie from eid
+ * @eid: element id
+ * @ie: source ie address
+ * @ie_len: source ie length
+ *
+ * Return: vendor ie address - success
+ *         NULL - failure
+ */
+const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid,
+					const uint8_t *ie,
+					int ie_len);
+
+/**
  * wlan_get_vendor_ie_ptr_from_oui() - Find out vendor ie
  * @oui: oui buffer
  * @oui_size: oui size
@@ -74,8 +87,27 @@
  * Return: vendor ie address - success
  *         NULL - failure
  */
-uint8_t *wlan_get_vendor_ie_ptr_from_oui(uint8_t *oui,
-	uint8_t oui_size, uint8_t *ie, uint16_t ie_len);
+const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui,
+					       uint8_t oui_size,
+					       const uint8_t *ie,
+					       uint16_t ie_len);
+
+/**
+ * wlan_get_ext_ie_ptr_from_ext_id() - Find out ext ie
+ * @oui: oui buffer
+ * @oui_size: oui size
+ * @ie: source ie address
+ * @ie_len: source ie length
+ *
+ * This function find out ext ie from ext id (passed oui)
+ *
+ * Return: vendor ie address - success
+ *         NULL - failure
+ */
+const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui,
+					       uint8_t oui_size,
+					       const uint8_t *ie,
+					       uint16_t ie_len);
 
 /**
  * wlan_is_emulation_platform() - check if platform is emulation based
diff --git a/umac/cmn_services/utils/src/wlan_utility.c b/umac/cmn_services/utils/src/wlan_utility.c
index a2a17f7..7a76d46 100644
--- a/umac/cmn_services/utils/src/wlan_utility.c
+++ b/umac/cmn_services/utils/src/wlan_utility.c
@@ -72,21 +72,37 @@
 	return chan;
 }
 
-uint8_t *wlan_get_vendor_ie_ptr_from_oui(uint8_t *oui,
-	uint8_t oui_size, uint8_t *ie, uint16_t ie_len)
+static const uint8_t *wlan_get_ie_ptr_from_eid_n_oui(uint8_t eid,
+						     const uint8_t *oui,
+						     uint8_t oui_size,
+						     const uint8_t *ie,
+						     uint16_t ie_len)
 {
 	int32_t left = ie_len;
-	uint8_t *ptr = ie;
+	const uint8_t *ptr = ie;
 	uint8_t elem_id, elem_len;
 
 	while (left >= 2) {
 		elem_id  = ptr[0];
 		elem_len = ptr[1];
 		left -= 2;
+
 		if (elem_len > left)
 			return NULL;
-		if (WLAN_MAC_EID_VENDOR == elem_id) {
-			if (memcmp(&ptr[2], oui, oui_size) == 0)
+
+		if (eid == elem_id) {
+			/* if oui is not provide eid match is enough */
+			if (!oui)
+				return ptr;
+
+			/*
+			 * if oui is provided and oui_size is more than left
+			 * bytes, then we cannot have match
+			 */
+			if (oui_size > left)
+				return NULL;
+
+			if (qdf_mem_cmp(&ptr[2], oui, oui_size) == 0)
 				return ptr;
 		}
 
@@ -97,6 +113,31 @@
 	return NULL;
 }
 
+const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid,
+					const uint8_t *ie,
+					int ie_len)
+{
+	return wlan_get_ie_ptr_from_eid_n_oui(eid, NULL, 0, ie, ie_len);
+}
+
+const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui,
+					       uint8_t oui_size,
+					       const uint8_t *ie,
+					       uint16_t ie_len)
+{
+	return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_VENDOR,
+					      oui, oui_size, ie, ie_len);
+}
+
+const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui,
+					       uint8_t oui_size,
+					       const uint8_t *ie,
+					       uint16_t ie_len)
+{
+	return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_EXT,
+					      oui, oui_size, ie, ie_len);
+}
+
 bool wlan_is_emulation_platform(uint32_t phy_version)
 {
 	if ((phy_version == 0xABC0) || (phy_version == 0xABC1) ||
diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
index 924c384..f353f62 100644
--- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
+++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
@@ -121,7 +121,7 @@
  *
  * Return: pointer to p2p ie
  */
-static uint8_t *p2p_get_p2pie_ptr(uint8_t *ie, uint16_t ie_len)
+static const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len)
 {
 	return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI,
 			P2P_OUI_SIZE, ie, ie_len);
@@ -137,12 +137,12 @@
  *
  * Return: pointer to p2p ie
  */
-static uint8_t *p2p_get_p2pie_from_probe_rsp(
+static const uint8_t *p2p_get_p2pie_from_probe_rsp(
 	struct tx_action_context *tx_ctx)
 {
-	uint8_t *ie;
-	uint8_t *p2p_ie;
-	uint8_t *tmp_p2p_ie;
+	const uint8_t *ie;
+	const uint8_t *p2p_ie;
+	const uint8_t *tmp_p2p_ie;
 	uint16_t ie_len;
 
 	ie = tx_ctx->buf + PROBE_RSP_IE_OFFSET;
@@ -176,10 +176,10 @@
  *
  * Return: pointer to noa attr
  */
-static uint8_t *p2p_get_presence_noa_attr(uint8_t *pies, int length)
+static const uint8_t *p2p_get_presence_noa_attr(const uint8_t *pies, int length)
 {
 	int left = length;
-	uint8_t *ptr = pies;
+	const uint8_t *ptr = pies;
 	uint8_t elem_id;
 	uint16_t elem_len;
 
@@ -387,7 +387,7 @@
  * Return: noa stream length
  */
 static uint16_t p2p_update_noa_stream(struct tx_action_context *tx_ctx,
-	uint8_t *p2p_ie, uint8_t *noa_attr, uint32_t *total_len,
+	uint8_t *p2p_ie, const uint8_t *noa_attr, uint32_t *total_len,
 	uint8_t *noa_stream)
 {
 	uint16_t noa_len;
@@ -1231,24 +1231,24 @@
 	uint8_t noa_len = 0;
 	uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE];
 	uint8_t orig_len = 0;
-	uint8_t *ie;
+	const uint8_t *ie;
 	uint8_t ie_len;
 	uint8_t *p2p_ie = NULL;
-	uint8_t *presence_noa_attr = NULL;
+	const uint8_t *presence_noa_attr = NULL;
 	uint32_t nbytes_copy;
 	uint32_t buf_len = tx_ctx->buf_len;
 	struct p2p_frame_info *frame_info;
 
 	frame_info = &(tx_ctx->frame_info);
 	if (frame_info->sub_type == P2P_MGMT_PROBE_RSP) {
-		p2p_ie = p2p_get_p2pie_from_probe_rsp(tx_ctx);
+		p2p_ie = (uint8_t *)p2p_get_p2pie_from_probe_rsp(tx_ctx);
 	} else if (frame_info->action_type ==
 			P2P_ACTION_PRESENCE_RSP) {
 		ie = tx_ctx->buf +
 			P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
 		ie_len = tx_ctx->buf_len -
 			P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
-		p2p_ie = p2p_get_p2pie_ptr(ie, ie_len);
+		p2p_ie = (uint8_t *)p2p_get_p2pie_ptr(ie, ie_len);
 		if (p2p_ie) {
 			/* extract the presence of NoA attribute inside
 			 * P2P IE */