Преглед на файлове

qcacmn: Add big-endian Host support for MLO global shared memory

MLO global shared memory arena accesses from the Host side will not go
through any implicit endian-ness conversions. Hence, convert the DWORDS
to the Host CPU order before using them.

Change-Id: If24edc7c6ef59fc82352d081b01a4baaaff65e02
CRs-Fixed: 3406980
Shiva Krishna Pittala преди 2 години
родител
ревизия
8f0c611fec
променени са 1 файла, в които са добавени 35 реда и са изтрити 5 реда
  1. 35 5
      target_if/init_deinit/src/mlo_global_h_shmem_arena.c

+ 35 - 5
target_if/init_deinit/src/mlo_global_h_shmem_arena.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -42,6 +42,24 @@ static struct wlan_host_mlo_glb_h_shmem_arena_ctx
 	(qdf_offsetof(typeof(*(ptlv)), field_name) < (tlv_len) ? \
 		true : false)
 
+#ifdef BIG_ENDIAN_HOST
+static inline void
+convert_dwords_to_host_order(uint32_t *pwords, size_t num_words)
+{
+	size_t word = 0;
+
+	for (; word < num_words; word++) {
+		*pwords = qdf_le32_to_cpu(*pwords);
+		++pwords;
+	}
+}
+#else
+static inline void
+convert_dwords_to_host_order(uint32_t *pwords, size_t num_words)
+{
+}
+#endif
+
 /**
  * get_field_value_in_tlv() - Get the value of a given field in a given TLV
  * @ptlv: Pointer to start of the TLV
@@ -52,8 +70,15 @@ static struct wlan_host_mlo_glb_h_shmem_arena_ctx
  * structure is less than the TLV length, else 0.
  */
 #define get_field_value_in_tlv(ptlv, field_name, tlv_len) \
-	(qdf_offsetof(typeof(*(ptlv)), field_name) < (tlv_len) ? \
-		(ptlv)->field_name : 0)
+	(qdf_offsetof(typeof(*(ptlv)), field_name) >= (tlv_len) ? 0 : \
+	 ({ \
+	   typeof((ptlv)->field_name) _field_ = (ptlv)->field_name; \
+	   qdf_assert(!(sizeof(_field_) & 0x3)); \
+	   convert_dwords_to_host_order((uint32_t *)&_field_, \
+					sizeof(_field_) >> 2); \
+	   _field_; \
+	  }) \
+	)
 
 /**
  * get_field_pointer_in_tlv() - Get the address of a given field in a given TLV
@@ -84,13 +109,18 @@ process_tlv_header(const uint8_t *data, size_t remaining_len,
 		   uint32_t expected_tag, uint32_t *tlv_len,
 		   uint32_t *tlv_tag)
 {
+	uint32_t tlv_header;
+
 	if (remaining_len < MLO_SHMEM_TLV_HDR_SIZE) {
 		target_if_err("Not enough space(%zu) to read TLV header(%u)",
 			      remaining_len, (uint32_t)MLO_SHMEM_TLV_HDR_SIZE);
 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
 	}
 
-	*tlv_len = MLO_SHMEMTLV_GET_TLVLEN(MLO_SHMEMTLV_GET_HDR(data));
+	tlv_header = MLO_SHMEMTLV_GET_HDR(data);
+	tlv_header = qdf_le32_to_cpu(tlv_header);
+
+	*tlv_len = MLO_SHMEMTLV_GET_TLVLEN(tlv_header);
 	*tlv_len += MLO_SHMEM_TLV_HDR_SIZE;
 	if (remaining_len < *tlv_len) {
 		target_if_err("Not enough space(%zu) to read TLV payload(%u)",
@@ -98,7 +128,7 @@ process_tlv_header(const uint8_t *data, size_t remaining_len,
 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
 	}
 
-	*tlv_tag = MLO_SHMEMTLV_GET_TLVTAG(MLO_SHMEMTLV_GET_HDR(data));
+	*tlv_tag = MLO_SHMEMTLV_GET_TLVTAG(tlv_header);
 	if (*tlv_tag != expected_tag) {
 		target_if_err("Unexpected TLV tag: %u is seen. Expected: %u",
 			      *tlv_tag,