1 /*
2  * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef __UTILSAPI_H
21 #define __UTILSAPI_H
22 
23 #include "qdf_types.h"
24 #include <sir_common.h>
25 #include "ani_global.h"
26 #include "sys_wrapper.h"
27 #include "wlan_vdev_mlme_main.h"
28 #include "wlan_vdev_mlme_api.h"
29 
30 /**
31  * sir_swap_u16()
32  *
33  * FUNCTION:
34  * This function is called to swap two U8s of an uint16_t value
35  *
36  * LOGIC:
37  *
38  * ASSUMPTIONS:
39  * None.
40  *
41  * NOTE:
42  *
43  * @param  val    uint16_t value to be uint8_t swapped
44  * @return        Swapped uint16_t value
45  */
46 
sir_swap_u16(uint16_t val)47 static inline uint16_t sir_swap_u16(uint16_t val)
48 {
49 	return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8);
50 } /*** end sir_swap_u16() ***/
51 
52 /**
53  * sir_swap_u16if_needed()
54  *
55  * FUNCTION:
56  * This function is called to swap two U8s of an uint16_t value depending
57  * on endianness of the target processor/compiler the software is
58  * running on
59  *
60  * LOGIC:
61  *
62  * ASSUMPTIONS:
63  * None.
64  *
65  * NOTE:
66  *
67  * @param  val    uint16_t value to be uint8_t swapped
68  * @return        Swapped uint16_t value
69  */
70 
sir_swap_u16if_needed(uint16_t val)71 static inline uint16_t sir_swap_u16if_needed(uint16_t val)
72 {
73 #ifndef ANI_LITTLE_BYTE_ENDIAN
74 	return sir_swap_u16(val);
75 #else
76 	return val;
77 #endif
78 } /*** end sir_swap_u16if_needed() ***/
79 
80 /**
81  * sir_swap_u32()
82  *
83  * FUNCTION:
84  * This function is called to swap four U8s of an uint32_t value
85  *
86  * LOGIC:
87  *
88  * ASSUMPTIONS:
89  * None.
90  *
91  * NOTE:
92  *
93  * @param  val    uint32_t value to be uint8_t swapped
94  * @return        Swapped uint32_t value
95  */
96 
sir_swap_u32(uint32_t val)97 static inline uint32_t sir_swap_u32(uint32_t val)
98 {
99 	return (val << 24) |
100 		(val >> 24) |
101 		((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8);
102 } /*** end sir_swap_u32() ***/
103 
104 /**
105  * sir_swap_u32if_needed()
106  *
107  * FUNCTION:
108  * This function is called to swap U8s of an uint32_t value depending
109  * on endianness of the target processor/compiler the software is
110  * running on
111  *
112  * LOGIC:
113  *
114  * ASSUMPTIONS:
115  * None.
116  *
117  * NOTE:
118  *
119  * @param  val    uint32_t value to be uint8_t swapped
120  * @return        Swapped uint32_t value
121  */
122 
sir_swap_u32if_needed(uint32_t val)123 static inline uint32_t sir_swap_u32if_needed(uint32_t val)
124 {
125 #ifndef ANI_LITTLE_BYTE_ENDIAN
126 	return sir_swap_u32(val);
127 #else
128 	return val;
129 #endif
130 } /*** end sir_swap_u32if_needed() ***/
131 
132 /**
133  * sir_swap_u32_buf
134  *
135  * FUNCTION:
136  * It swaps N dwords into the same buffer
137  *
138  * LOGIC:
139  *
140  * ASSUMPTIONS:
141  * None.
142  *
143  * NOTE:
144  *
145  * @param  ptr address of uint32_t array
146  * @return void
147  *
148  */
149 
150 /**
151  * sir_read_u32_n
152  *
153  * FUNCTION:
154  * It reads a 32 bit number from the byte array in network byte order
155  * i.e. the least significant byte first
156  *
157  * LOGIC:
158  *
159  * ASSUMPTIONS:
160  * None.
161  *
162  * NOTE:
163  *
164  * @param  ptr address of  byte array
165  * @return 32 bit value
166  */
167 
sir_read_u32_n(uint8_t * ptr)168 static inline uint32_t sir_read_u32_n(uint8_t *ptr)
169 {
170 	return (*(ptr) << 24) |
171 		(*(ptr + 1) << 16) | (*(ptr + 2) << 8) | (*(ptr + 3));
172 }
173 
174 /**
175  * sir_read_u16
176  *
177  * FUNCTION:
178  * It reads a 16 bit number from the byte array in NON-network byte order
179  * i.e. the least significant byte first
180  *
181  * LOGIC:
182  *
183  * ASSUMPTIONS:
184  * None.
185  *
186  * NOTE:
187  *
188  * @param  ptr address of  byte array
189  * @return 16 bit value
190  */
191 
sir_read_u16(uint8_t * ptr)192 static inline uint16_t sir_read_u16(uint8_t *ptr)
193 {
194 	return (*ptr) | (*(ptr + 1) << 8);
195 }
196 
197 /**
198  * sir_read_u32
199  *
200  * FUNCTION:
201  * It reads a 32 bit number from the byte array in NON-network byte order
202  * i.e. the least significant byte first
203  *
204  * LOGIC:
205  *
206  * ASSUMPTIONS:
207  * None.
208  *
209  * NOTE:
210  *
211  * @param  ptr address of  byte array
212  * @return 32 bit value
213  */
214 
sir_read_u32(uint8_t * ptr)215 static inline uint32_t sir_read_u32(uint8_t *ptr)
216 {
217 	return (*(ptr)) |
218 		(*(ptr + 1) << 8) | (*(ptr + 2) << 16) | (*(ptr + 3) << 24);
219 }
220 
221 /* / Copy a MAC address from 'from' to 'to' */
sir_copy_mac_addr(uint8_t to[],uint8_t from[])222 static inline void sir_copy_mac_addr(uint8_t to[], uint8_t from[])
223 {
224 #if defined(_X86_)
225 	uint32_t align = (0x3 & ((uint32_t) to | (uint32_t) from));
226 
227 	if (align == 0) {
228 		*((uint16_t *) &(to[4])) = *((uint16_t *) &(from[4]));
229 		*((uint32_t *) to) = *((uint32_t *) from);
230 	} else if (align == 2) {
231 		*((uint16_t *) &to[4]) = *((uint16_t *) &from[4]);
232 		*((uint16_t *) &to[2]) = *((uint16_t *) &from[2]);
233 		*((uint16_t *) &to[0]) = *((uint16_t *) &from[0]);
234 	} else {
235 		to[5] = from[5];
236 		to[4] = from[4];
237 		to[3] = from[3];
238 		to[2] = from[2];
239 		to[1] = from[1];
240 		to[0] = from[0];
241 	}
242 #else
243 	to[0] = from[0];
244 	to[1] = from[1];
245 	to[2] = from[2];
246 	to[3] = from[3];
247 	to[4] = from[4];
248 	to[5] = from[5];
249 #endif
250 }
251 
sir_compare_mac_addr(uint8_t addr1[],uint8_t addr2[])252 static inline uint8_t sir_compare_mac_addr(uint8_t addr1[], uint8_t addr2[])
253 {
254 #if defined(_X86_)
255 	uint32_t align = (0x3 & ((uint32_t) addr1 | (uint32_t) addr2));
256 
257 	if (align == 0) {
258 		return (*((uint16_t *) &(addr1[4])) ==
259 			 *((uint16_t *) &(addr2[4])))
260 			&& (*((uint32_t *) addr1) == *((uint32_t *) addr2));
261 	} else if (align == 2) {
262 		return (*((uint16_t *) &addr1[4]) ==
263 			 *((uint16_t *) &addr2[4]))
264 			&& (*((uint16_t *) &addr1[2]) ==
265 			    *((uint16_t *) &addr2[2]))
266 			&& (*((uint16_t *) &addr1[0]) ==
267 			    *((uint16_t *) &addr2[0]));
268 	} else {
269 		return (addr1[5] == addr2[5]) &&
270 			(addr1[4] == addr2[4]) &&
271 			(addr1[3] == addr2[3]) &&
272 			(addr1[2] == addr2[2]) &&
273 			(addr1[1] == addr2[1]) && (addr1[0] == addr2[0]);
274 	}
275 #else
276 	return (addr1[0] == addr2[0]) &&
277 		(addr1[1] == addr2[1]) &&
278 		(addr1[2] == addr2[2]) &&
279 		(addr1[3] == addr2[3]) &&
280 		(addr1[4] == addr2[4]) && (addr1[5] == addr2[5]);
281 #endif
282 }
283 
284 /*
285  * converts uint16_t CW value to 4 bit value to be inserted in IE
286  */
convert_cw(uint16_t cw)287 static inline uint8_t convert_cw(uint16_t cw)
288 {
289 	uint8_t val = 0;
290 
291 	while (cw > 0) {
292 		val++;
293 		cw >>= 1;
294 	}
295 	if (val > 15)
296 		return 0xF;
297 	return val;
298 }
299 
300 /* The user priority to AC mapping is such:
301  *   UP(1, 2) ---> AC_BK(1)
302  *   UP(0, 3) ---> AC_BE(0)
303  *   UP(4, 5) ---> AC_VI(2)
304  *   UP(6, 7) ---> AC_VO(3)
305  */
306 #define WLAN_UP_TO_AC_MAP            0x33220110
307 #define upToAc(up)                ((WLAN_UP_TO_AC_MAP >> ((up) << 2)) & 0x03)
308 
309 #endif /* __UTILSAPI_H */
310