Эх сурвалжийг харах

qcacmn: Fix FFT bin values for pack mode 0

While copying FFT bins from the target, Spectral Host driver reads
one DWORD (32-bits) at a time and extracts FFT bins out of those DWORDs.
This extraction uses standard bit shift and mask operations as below.

    #define QDF_GET_BITS(_val, _index, _num_bits) \
                    (((_val) >> (_index)) & ((1 << (_num_bits)) - 1))

For a chipset that uses pack mode 0 i.e., packs 1 FFT bin per DWORD,
_num_bits in the above operation will be 32. So, we try to left shift the
integer constant '1' by 32. If the integer constant is represented by
32-bit integer, we could have issues in the result of shift operation.
As per C standard, the result of shifting an operand by a count greater
than or equal to width (in bits) of the operand is undefined.
This is because some platforms could optimize the shift operation by
masking the shift count to 5 bits. That means, the shift actually
performed is 32 & 31, which is 0.

Fix this by using 64-bit integer constant '1' in the above operation.

Change-Id: Ic7fe4de7917f3069d78a2ff29d86009cbf381e3f
CRs-Fixed: 3125158
Shiva Krishna Pittala 3 жил өмнө
parent
commit
0878b6eaf9

+ 10 - 1
target_if/spectral/target_if_spectral_phyerr.c

@@ -2222,7 +2222,16 @@ target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral,
 	for (dword_idx = 0; dword_idx < num_dwords; dword_idx++) {
 		dword = *dword_ptr++; /* Read a DWORD */
 		for (idx = 0; idx < num_bins_per_dword; idx++) {
-			fft_bin_val = (uint16_t)QDF_GET_BITS(
+			/**
+			 * If we use QDF_GET_BITS, when hw_fft_bin_width_bits is
+			 * 32, on certain platforms, we could end up doing a
+			 * 32-bit left shift operation on 32-bit constant
+			 * integer '1'. As per C standard, result of shifting an
+			 * operand by a count greater than or equal to width
+			 * (in bits) of the operand is undefined.
+			 * If we use QDF_GET_BITS_64, we can avoid that.
+			 */
+			fft_bin_val = (uint16_t)QDF_GET_BITS64(
 					dword,
 					idx * hw_fft_bin_width_bits,
 					hw_fft_bin_width_bits);