xref: /OK3568_Linux_fs/external/rkwifibt/drivers/infineon/bcm_app_utils.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Misc utility routines used by kernel or app-level.
3  * Contents are wifi-specific, used by any kernel or app-level
4  * software that might want wifi things as it grows.
5  *
6  * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
7  *
8  * Copyright (C) 1999-2017, Broadcom Corporation
9  *
10  *      Unless you and Broadcom execute a separate written software license
11  * agreement governing use of this software, this software is licensed to you
12  * under the terms of the GNU General Public License version 2 (the "GPL"),
13  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
14  * following added to such license:
15  *
16  *      As a special exception, the copyright holders of this software give you
17  * permission to link this software with independent modules, and to copy and
18  * distribute the resulting executable under terms of your choice, provided that
19  * you also meet, for each linked independent module, the terms and conditions of
20  * the license of that module.  An independent module is a module which is not
21  * derived from this software.  The special exception does not apply to any
22  * modifications of the software.
23  *
24  *      Notwithstanding the above, under no circumstances may you combine this
25  * software in any way with any other Broadcom software provided under a license
26  * other than the GPL, without Broadcom's express prior written consent.
27  *
28  *
29  * <<Broadcom-WL-IPTag/Open:>>
30  *
31  * $Id: bcm_app_utils.c 667243 2016-10-26 11:37:48Z $
32  */
33 
34 #include <typedefs.h>
35 
36 #ifdef BCMDRIVER
37 #include <osl.h>
38 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
39 #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
40 #else /* BCMDRIVER */
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 #ifndef ASSERT
46 #define ASSERT(exp)
47 #endif // endif
48 #endif /* BCMDRIVER */
49 #include <bcmwifi_channels.h>
50 
51 #if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
52 #include <bcmstdlib.h>	/* For wl/exe/GNUmakefile.brcm_wlu and GNUmakefile.wlm_dll */
53 #endif // endif
54 
55 #include <bcmutils.h>
56 #include <wlioctl.h>
57 #include <wlioctl_utils.h>
58 
59 #ifndef BCMDRIVER
60 /*	Take an array of measurments representing a single channel over time and return
61 	a summary. Currently implemented as a simple average but could easily evolve
62 	into more cpomplex alogrithms.
63 */
64 cca_congest_channel_req_t *
cca_per_chan_summary(cca_congest_channel_req_t * input,cca_congest_channel_req_t * avg,bool percent)65 cca_per_chan_summary(cca_congest_channel_req_t *input, cca_congest_channel_req_t *avg, bool percent)
66 {
67 	int sec;
68 	cca_congest_t totals;
69 
70 	totals.duration  = 0;
71 	totals.congest_ibss  = 0;
72 	totals.congest_obss  = 0;
73 	totals.interference  = 0;
74 	avg->num_secs = 0;
75 
76 	for (sec = 0; sec < input->num_secs; sec++) {
77 		if (input->secs[sec].duration) {
78 			totals.duration += input->secs[sec].duration;
79 			totals.congest_ibss += input->secs[sec].congest_ibss;
80 			totals.congest_obss += input->secs[sec].congest_obss;
81 			totals.interference += input->secs[sec].interference;
82 			avg->num_secs++;
83 		}
84 	}
85 	avg->chanspec = input->chanspec;
86 
87 	if (!avg->num_secs || !totals.duration)
88 		return (avg);
89 
90 	if (percent) {
91 		avg->secs[0].duration = totals.duration / avg->num_secs;
92 		avg->secs[0].congest_ibss = totals.congest_ibss * 100/totals.duration;
93 		avg->secs[0].congest_obss = totals.congest_obss * 100/totals.duration;
94 		avg->secs[0].interference = totals.interference * 100/totals.duration;
95 	} else {
96 		avg->secs[0].duration = totals.duration / avg->num_secs;
97 		avg->secs[0].congest_ibss = totals.congest_ibss / avg->num_secs;
98 		avg->secs[0].congest_obss = totals.congest_obss / avg->num_secs;
99 		avg->secs[0].interference = totals.interference / avg->num_secs;
100 	}
101 
102 	return (avg);
103 }
104 
105 static void
cca_info(uint8 * bitmap,int num_bits,int * left,int * bit_pos)106 cca_info(uint8 *bitmap, int num_bits, int *left, int *bit_pos)
107 {
108 	int i;
109 	for (*left = 0, i = 0; i < num_bits; i++) {
110 		if (isset(bitmap, i)) {
111 			(*left)++;
112 			*bit_pos = i;
113 		}
114 	}
115 }
116 
117 static uint8
spec_to_chan(chanspec_t chspec)118 spec_to_chan(chanspec_t chspec)
119 {
120 	uint8 center_ch, edge, primary, sb;
121 
122 	center_ch = CHSPEC_CHANNEL(chspec);
123 
124 	if (CHSPEC_BW_LE20(chspec)) {
125 		return center_ch;
126 	} else {
127 		/* the lower edge of the wide channel is half the bw from
128 		 * the center channel.
129 		 */
130 		if (CHSPEC_IS40(chspec)) {
131 			edge = center_ch - CH_20MHZ_APART;
132 		} else {
133 			/* must be 80MHz (until we support more) */
134 			ASSERT(CHSPEC_IS80(chspec));
135 			edge = center_ch - CH_40MHZ_APART;
136 		}
137 
138 		/* find the channel number of the lowest 20MHz primary channel */
139 		primary = edge + CH_10MHZ_APART;
140 
141 		/* select the actual subband */
142 		sb = (chspec & WL_CHANSPEC_CTL_SB_MASK) >> WL_CHANSPEC_CTL_SB_SHIFT;
143 		primary = primary + sb * CH_20MHZ_APART;
144 
145 		return primary;
146 	}
147 }
148 
149 /*
150 	Take an array of measumrements representing summaries of different channels.
151 	Return a recomended channel.
152 	Interference is evil, get rid of that first.
153 	Then hunt for lowest Other bss traffic.
154 	Don't forget that channels with low duration times may not have accurate readings.
155 	For the moment, do not overwrite input array.
156 */
157 int
cca_analyze(cca_congest_channel_req_t * input[],int num_chans,uint flags,chanspec_t * answer)158 cca_analyze(cca_congest_channel_req_t *input[], int num_chans, uint flags, chanspec_t *answer)
159 {
160 	uint8 *bitmap = NULL;	/* 38 Max channels needs 5 bytes  = 40 */
161 	int i, left, winner, ret_val = 0;
162 	uint32 min_obss = 1 << 30;
163 	uint bitmap_sz;
164 
165 	bitmap_sz = CEIL(num_chans, NBBY);
166 	bitmap = (uint8 *)malloc(bitmap_sz);
167 	if (bitmap == NULL) {
168 		printf("unable to allocate memory\n");
169 		return BCME_NOMEM;
170 	}
171 
172 	memset(bitmap, 0, bitmap_sz);
173 	/* Initially, all channels are up for consideration */
174 	for (i = 0; i < num_chans; i++) {
175 		if (input[i]->chanspec)
176 			setbit(bitmap, i);
177 	}
178 	cca_info(bitmap, num_chans, &left, &i);
179 	if (!left) {
180 		ret_val = CCA_ERRNO_TOO_FEW;
181 		goto f_exit;
182 	}
183 
184 	/* Filter for 2.4 GHz Band */
185 	if (flags & CCA_FLAG_2G_ONLY) {
186 		for (i = 0; i < num_chans; i++) {
187 			if (!CHSPEC_IS2G(input[i]->chanspec))
188 				clrbit(bitmap, i);
189 		}
190 	}
191 	cca_info(bitmap, num_chans, &left, &i);
192 	if (!left) {
193 		ret_val = CCA_ERRNO_BAND;
194 		goto f_exit;
195 	}
196 
197 	/* Filter for 5 GHz Band */
198 	if (flags & CCA_FLAG_5G_ONLY) {
199 		for (i = 0; i < num_chans; i++) {
200 			if (!CHSPEC_IS5G(input[i]->chanspec))
201 				clrbit(bitmap, i);
202 		}
203 	}
204 	cca_info(bitmap, num_chans, &left, &i);
205 	if (!left) {
206 		ret_val = CCA_ERRNO_BAND;
207 		goto f_exit;
208 	}
209 
210 	/* Filter for Duration */
211 	if (!(flags & CCA_FLAG_IGNORE_DURATION)) {
212 		for (i = 0; i < num_chans; i++) {
213 			if (input[i]->secs[0].duration < CCA_THRESH_MILLI)
214 				clrbit(bitmap, i);
215 		}
216 	}
217 	cca_info(bitmap, num_chans, &left, &i);
218 	if (!left) {
219 		ret_val = CCA_ERRNO_DURATION;
220 		goto f_exit;
221 	}
222 
223 	/* Filter for 1 6 11 on 2.4 Band */
224 	if (flags &  CCA_FLAGS_PREFER_1_6_11) {
225 		int tmp_channel = spec_to_chan(input[i]->chanspec);
226 		int is2g = CHSPEC_IS2G(input[i]->chanspec);
227 		for (i = 0; i < num_chans; i++) {
228 			if (is2g && tmp_channel != 1 && tmp_channel != 6 && tmp_channel != 11)
229 				clrbit(bitmap, i);
230 		}
231 	}
232 	cca_info(bitmap, num_chans, &left, &i);
233 	if (!left) {
234 		ret_val = CCA_ERRNO_PREF_CHAN;
235 		goto f_exit;
236 	}
237 
238 	/* Toss high interference interference */
239 	if (!(flags & CCA_FLAG_IGNORE_INTERFER)) {
240 		for (i = 0; i < num_chans; i++) {
241 			if (input[i]->secs[0].interference > CCA_THRESH_INTERFERE)
242 				clrbit(bitmap, i);
243 		}
244 		cca_info(bitmap, num_chans, &left, &i);
245 		if (!left) {
246 			ret_val = CCA_ERRNO_INTERFER;
247 			goto f_exit;
248 		}
249 	}
250 
251 	/* Now find lowest obss */
252 	winner = 0;
253 	for (i = 0; i < num_chans; i++) {
254 		if (isset(bitmap, i) && input[i]->secs[0].congest_obss < min_obss) {
255 			winner = i;
256 			min_obss = input[i]->secs[0].congest_obss;
257 		}
258 	}
259 	*answer = input[winner]->chanspec;
260 	f_exit:
261 	free(bitmap);	/* free the allocated memory for bitmap */
262 	return ret_val;
263 }
264 #endif /* !BCMDRIVER */
265 
266 /* offset of cntmember by sizeof(uint32) from the first cnt variable, txframe. */
267 #define IDX_IN_WL_CNT_VER_6_T(cntmember)		\
268 	((OFFSETOF(wl_cnt_ver_6_t, cntmember) - OFFSETOF(wl_cnt_ver_6_t, txframe)) / sizeof(uint32))
269 
270 #define IDX_IN_WL_CNT_VER_11_T(cntmember)		\
271 	((OFFSETOF(wl_cnt_ver_11_t, cntmember) - OFFSETOF(wl_cnt_ver_11_t, txframe))	\
272 	/ sizeof(uint32))
273 
274 /* Exclude version and length fields */
275 #define NUM_OF_CNT_IN_WL_CNT_VER_6_T	\
276 	((sizeof(wl_cnt_ver_6_t) - 2 * sizeof(uint16)) / sizeof(uint32))
277 /* Exclude macstat cnt variables. wl_cnt_ver_6_t only has 62 macstat cnt variables. */
278 #define NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T			\
279 	(NUM_OF_CNT_IN_WL_CNT_VER_6_T - (WL_CNT_MCST_VAR_NUM - 2))
280 
281 /* Exclude version and length fields */
282 #define NUM_OF_CNT_IN_WL_CNT_VER_11_T	\
283 	((sizeof(wl_cnt_ver_11_t) - 2 * sizeof(uint16)) / sizeof(uint32))
284 /* Exclude 64 macstat cnt variables. */
285 #define NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T	\
286 	((sizeof(wl_cnt_wlc_t)) / sizeof(uint32))
287 
288 /* Index conversion table from wl_cnt_ver_6_t to wl_cnt_wlc_t */
289 static const uint8 wlcntver6t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T] = {
290 	IDX_IN_WL_CNT_VER_6_T(txframe),
291 	IDX_IN_WL_CNT_VER_6_T(txbyte),
292 	IDX_IN_WL_CNT_VER_6_T(txretrans),
293 	IDX_IN_WL_CNT_VER_6_T(txerror),
294 	IDX_IN_WL_CNT_VER_6_T(txctl),
295 	IDX_IN_WL_CNT_VER_6_T(txprshort),
296 	IDX_IN_WL_CNT_VER_6_T(txserr),
297 	IDX_IN_WL_CNT_VER_6_T(txnobuf),
298 	IDX_IN_WL_CNT_VER_6_T(txnoassoc),
299 	IDX_IN_WL_CNT_VER_6_T(txrunt),
300 	IDX_IN_WL_CNT_VER_6_T(txchit),
301 	IDX_IN_WL_CNT_VER_6_T(txcmiss),
302 	IDX_IN_WL_CNT_VER_6_T(txuflo),
303 	IDX_IN_WL_CNT_VER_6_T(txphyerr),
304 	IDX_IN_WL_CNT_VER_6_T(txphycrs),
305 	IDX_IN_WL_CNT_VER_6_T(rxframe),
306 	IDX_IN_WL_CNT_VER_6_T(rxbyte),
307 	IDX_IN_WL_CNT_VER_6_T(rxerror),
308 	IDX_IN_WL_CNT_VER_6_T(rxctl),
309 	IDX_IN_WL_CNT_VER_6_T(rxnobuf),
310 	IDX_IN_WL_CNT_VER_6_T(rxnondata),
311 	IDX_IN_WL_CNT_VER_6_T(rxbadds),
312 	IDX_IN_WL_CNT_VER_6_T(rxbadcm),
313 	IDX_IN_WL_CNT_VER_6_T(rxfragerr),
314 	IDX_IN_WL_CNT_VER_6_T(rxrunt),
315 	IDX_IN_WL_CNT_VER_6_T(rxgiant),
316 	IDX_IN_WL_CNT_VER_6_T(rxnoscb),
317 	IDX_IN_WL_CNT_VER_6_T(rxbadproto),
318 	IDX_IN_WL_CNT_VER_6_T(rxbadsrcmac),
319 	IDX_IN_WL_CNT_VER_6_T(rxbadda),
320 	IDX_IN_WL_CNT_VER_6_T(rxfilter),
321 	IDX_IN_WL_CNT_VER_6_T(rxoflo),
322 	IDX_IN_WL_CNT_VER_6_T(rxuflo),
323 	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 1,
324 	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 2,
325 	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 3,
326 	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 4,
327 	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 5,
328 	IDX_IN_WL_CNT_VER_6_T(d11cnt_txrts_off),
329 	IDX_IN_WL_CNT_VER_6_T(d11cnt_rxcrc_off),
330 	IDX_IN_WL_CNT_VER_6_T(d11cnt_txnocts_off),
331 	IDX_IN_WL_CNT_VER_6_T(dmade),
332 	IDX_IN_WL_CNT_VER_6_T(dmada),
333 	IDX_IN_WL_CNT_VER_6_T(dmape),
334 	IDX_IN_WL_CNT_VER_6_T(reset),
335 	IDX_IN_WL_CNT_VER_6_T(tbtt),
336 	IDX_IN_WL_CNT_VER_6_T(txdmawar),
337 	IDX_IN_WL_CNT_VER_6_T(pkt_callback_reg_fail),
338 	IDX_IN_WL_CNT_VER_6_T(txfrag),
339 	IDX_IN_WL_CNT_VER_6_T(txmulti),
340 	IDX_IN_WL_CNT_VER_6_T(txfail),
341 	IDX_IN_WL_CNT_VER_6_T(txretry),
342 	IDX_IN_WL_CNT_VER_6_T(txretrie),
343 	IDX_IN_WL_CNT_VER_6_T(rxdup),
344 	IDX_IN_WL_CNT_VER_6_T(txrts),
345 	IDX_IN_WL_CNT_VER_6_T(txnocts),
346 	IDX_IN_WL_CNT_VER_6_T(txnoack),
347 	IDX_IN_WL_CNT_VER_6_T(rxfrag),
348 	IDX_IN_WL_CNT_VER_6_T(rxmulti),
349 	IDX_IN_WL_CNT_VER_6_T(rxcrc),
350 	IDX_IN_WL_CNT_VER_6_T(txfrmsnt),
351 	IDX_IN_WL_CNT_VER_6_T(rxundec),
352 	IDX_IN_WL_CNT_VER_6_T(tkipmicfaill),
353 	IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr),
354 	IDX_IN_WL_CNT_VER_6_T(tkipreplay),
355 	IDX_IN_WL_CNT_VER_6_T(ccmpfmterr),
356 	IDX_IN_WL_CNT_VER_6_T(ccmpreplay),
357 	IDX_IN_WL_CNT_VER_6_T(ccmpundec),
358 	IDX_IN_WL_CNT_VER_6_T(fourwayfail),
359 	IDX_IN_WL_CNT_VER_6_T(wepundec),
360 	IDX_IN_WL_CNT_VER_6_T(wepicverr),
361 	IDX_IN_WL_CNT_VER_6_T(decsuccess),
362 	IDX_IN_WL_CNT_VER_6_T(tkipicverr),
363 	IDX_IN_WL_CNT_VER_6_T(wepexcluded),
364 	IDX_IN_WL_CNT_VER_6_T(txchanrej),
365 	IDX_IN_WL_CNT_VER_6_T(psmwds),
366 	IDX_IN_WL_CNT_VER_6_T(phywatchdog),
367 	IDX_IN_WL_CNT_VER_6_T(prq_entries_handled),
368 	IDX_IN_WL_CNT_VER_6_T(prq_undirected_entries),
369 	IDX_IN_WL_CNT_VER_6_T(prq_bad_entries),
370 	IDX_IN_WL_CNT_VER_6_T(atim_suppress_count),
371 	IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready),
372 	IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready_done),
373 	IDX_IN_WL_CNT_VER_6_T(late_tbtt_dpc),
374 	IDX_IN_WL_CNT_VER_6_T(rx1mbps),
375 	IDX_IN_WL_CNT_VER_6_T(rx2mbps),
376 	IDX_IN_WL_CNT_VER_6_T(rx5mbps5),
377 	IDX_IN_WL_CNT_VER_6_T(rx6mbps),
378 	IDX_IN_WL_CNT_VER_6_T(rx9mbps),
379 	IDX_IN_WL_CNT_VER_6_T(rx11mbps),
380 	IDX_IN_WL_CNT_VER_6_T(rx12mbps),
381 	IDX_IN_WL_CNT_VER_6_T(rx18mbps),
382 	IDX_IN_WL_CNT_VER_6_T(rx24mbps),
383 	IDX_IN_WL_CNT_VER_6_T(rx36mbps),
384 	IDX_IN_WL_CNT_VER_6_T(rx48mbps),
385 	IDX_IN_WL_CNT_VER_6_T(rx54mbps),
386 	IDX_IN_WL_CNT_VER_6_T(rx108mbps),
387 	IDX_IN_WL_CNT_VER_6_T(rx162mbps),
388 	IDX_IN_WL_CNT_VER_6_T(rx216mbps),
389 	IDX_IN_WL_CNT_VER_6_T(rx270mbps),
390 	IDX_IN_WL_CNT_VER_6_T(rx324mbps),
391 	IDX_IN_WL_CNT_VER_6_T(rx378mbps),
392 	IDX_IN_WL_CNT_VER_6_T(rx432mbps),
393 	IDX_IN_WL_CNT_VER_6_T(rx486mbps),
394 	IDX_IN_WL_CNT_VER_6_T(rx540mbps),
395 	IDX_IN_WL_CNT_VER_6_T(rfdisable),
396 	IDX_IN_WL_CNT_VER_6_T(txexptime),
397 	IDX_IN_WL_CNT_VER_6_T(txmpdu_sgi),
398 	IDX_IN_WL_CNT_VER_6_T(rxmpdu_sgi),
399 	IDX_IN_WL_CNT_VER_6_T(txmpdu_stbc),
400 	IDX_IN_WL_CNT_VER_6_T(rxmpdu_stbc),
401 	IDX_IN_WL_CNT_VER_6_T(rxundec_mcst),
402 	IDX_IN_WL_CNT_VER_6_T(tkipmicfaill_mcst),
403 	IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr_mcst),
404 	IDX_IN_WL_CNT_VER_6_T(tkipreplay_mcst),
405 	IDX_IN_WL_CNT_VER_6_T(ccmpfmterr_mcst),
406 	IDX_IN_WL_CNT_VER_6_T(ccmpreplay_mcst),
407 	IDX_IN_WL_CNT_VER_6_T(ccmpundec_mcst),
408 	IDX_IN_WL_CNT_VER_6_T(fourwayfail_mcst),
409 	IDX_IN_WL_CNT_VER_6_T(wepundec_mcst),
410 	IDX_IN_WL_CNT_VER_6_T(wepicverr_mcst),
411 	IDX_IN_WL_CNT_VER_6_T(decsuccess_mcst),
412 	IDX_IN_WL_CNT_VER_6_T(tkipicverr_mcst),
413 	IDX_IN_WL_CNT_VER_6_T(wepexcluded_mcst)
414 };
415 
416 #define INVALID_IDX ((uint8)(-1))
417 
418 /* Index conversion table from wl_cnt_ver_11_t to wl_cnt_wlc_t */
419 static const uint8 wlcntver11t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T] = {
420 	IDX_IN_WL_CNT_VER_11_T(txframe),
421 	IDX_IN_WL_CNT_VER_11_T(txbyte),
422 	IDX_IN_WL_CNT_VER_11_T(txretrans),
423 	IDX_IN_WL_CNT_VER_11_T(txerror),
424 	IDX_IN_WL_CNT_VER_11_T(txctl),
425 	IDX_IN_WL_CNT_VER_11_T(txprshort),
426 	IDX_IN_WL_CNT_VER_11_T(txserr),
427 	IDX_IN_WL_CNT_VER_11_T(txnobuf),
428 	IDX_IN_WL_CNT_VER_11_T(txnoassoc),
429 	IDX_IN_WL_CNT_VER_11_T(txrunt),
430 	IDX_IN_WL_CNT_VER_11_T(txchit),
431 	IDX_IN_WL_CNT_VER_11_T(txcmiss),
432 	IDX_IN_WL_CNT_VER_11_T(txuflo),
433 	IDX_IN_WL_CNT_VER_11_T(txphyerr),
434 	IDX_IN_WL_CNT_VER_11_T(txphycrs),
435 	IDX_IN_WL_CNT_VER_11_T(rxframe),
436 	IDX_IN_WL_CNT_VER_11_T(rxbyte),
437 	IDX_IN_WL_CNT_VER_11_T(rxerror),
438 	IDX_IN_WL_CNT_VER_11_T(rxctl),
439 	IDX_IN_WL_CNT_VER_11_T(rxnobuf),
440 	IDX_IN_WL_CNT_VER_11_T(rxnondata),
441 	IDX_IN_WL_CNT_VER_11_T(rxbadds),
442 	IDX_IN_WL_CNT_VER_11_T(rxbadcm),
443 	IDX_IN_WL_CNT_VER_11_T(rxfragerr),
444 	IDX_IN_WL_CNT_VER_11_T(rxrunt),
445 	IDX_IN_WL_CNT_VER_11_T(rxgiant),
446 	IDX_IN_WL_CNT_VER_11_T(rxnoscb),
447 	IDX_IN_WL_CNT_VER_11_T(rxbadproto),
448 	IDX_IN_WL_CNT_VER_11_T(rxbadsrcmac),
449 	IDX_IN_WL_CNT_VER_11_T(rxbadda),
450 	IDX_IN_WL_CNT_VER_11_T(rxfilter),
451 	IDX_IN_WL_CNT_VER_11_T(rxoflo),
452 	IDX_IN_WL_CNT_VER_11_T(rxuflo),
453 	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 1,
454 	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 2,
455 	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 3,
456 	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 4,
457 	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 5,
458 	IDX_IN_WL_CNT_VER_11_T(d11cnt_txrts_off),
459 	IDX_IN_WL_CNT_VER_11_T(d11cnt_rxcrc_off),
460 	IDX_IN_WL_CNT_VER_11_T(d11cnt_txnocts_off),
461 	IDX_IN_WL_CNT_VER_11_T(dmade),
462 	IDX_IN_WL_CNT_VER_11_T(dmada),
463 	IDX_IN_WL_CNT_VER_11_T(dmape),
464 	IDX_IN_WL_CNT_VER_11_T(reset),
465 	IDX_IN_WL_CNT_VER_11_T(tbtt),
466 	IDX_IN_WL_CNT_VER_11_T(txdmawar),
467 	IDX_IN_WL_CNT_VER_11_T(pkt_callback_reg_fail),
468 	IDX_IN_WL_CNT_VER_11_T(txfrag),
469 	IDX_IN_WL_CNT_VER_11_T(txmulti),
470 	IDX_IN_WL_CNT_VER_11_T(txfail),
471 	IDX_IN_WL_CNT_VER_11_T(txretry),
472 	IDX_IN_WL_CNT_VER_11_T(txretrie),
473 	IDX_IN_WL_CNT_VER_11_T(rxdup),
474 	IDX_IN_WL_CNT_VER_11_T(txrts),
475 	IDX_IN_WL_CNT_VER_11_T(txnocts),
476 	IDX_IN_WL_CNT_VER_11_T(txnoack),
477 	IDX_IN_WL_CNT_VER_11_T(rxfrag),
478 	IDX_IN_WL_CNT_VER_11_T(rxmulti),
479 	IDX_IN_WL_CNT_VER_11_T(rxcrc),
480 	IDX_IN_WL_CNT_VER_11_T(txfrmsnt),
481 	IDX_IN_WL_CNT_VER_11_T(rxundec),
482 	IDX_IN_WL_CNT_VER_11_T(tkipmicfaill),
483 	IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr),
484 	IDX_IN_WL_CNT_VER_11_T(tkipreplay),
485 	IDX_IN_WL_CNT_VER_11_T(ccmpfmterr),
486 	IDX_IN_WL_CNT_VER_11_T(ccmpreplay),
487 	IDX_IN_WL_CNT_VER_11_T(ccmpundec),
488 	IDX_IN_WL_CNT_VER_11_T(fourwayfail),
489 	IDX_IN_WL_CNT_VER_11_T(wepundec),
490 	IDX_IN_WL_CNT_VER_11_T(wepicverr),
491 	IDX_IN_WL_CNT_VER_11_T(decsuccess),
492 	IDX_IN_WL_CNT_VER_11_T(tkipicverr),
493 	IDX_IN_WL_CNT_VER_11_T(wepexcluded),
494 	IDX_IN_WL_CNT_VER_11_T(txchanrej),
495 	IDX_IN_WL_CNT_VER_11_T(psmwds),
496 	IDX_IN_WL_CNT_VER_11_T(phywatchdog),
497 	IDX_IN_WL_CNT_VER_11_T(prq_entries_handled),
498 	IDX_IN_WL_CNT_VER_11_T(prq_undirected_entries),
499 	IDX_IN_WL_CNT_VER_11_T(prq_bad_entries),
500 	IDX_IN_WL_CNT_VER_11_T(atim_suppress_count),
501 	IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready),
502 	IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready_done),
503 	IDX_IN_WL_CNT_VER_11_T(late_tbtt_dpc),
504 	IDX_IN_WL_CNT_VER_11_T(rx1mbps),
505 	IDX_IN_WL_CNT_VER_11_T(rx2mbps),
506 	IDX_IN_WL_CNT_VER_11_T(rx5mbps5),
507 	IDX_IN_WL_CNT_VER_11_T(rx6mbps),
508 	IDX_IN_WL_CNT_VER_11_T(rx9mbps),
509 	IDX_IN_WL_CNT_VER_11_T(rx11mbps),
510 	IDX_IN_WL_CNT_VER_11_T(rx12mbps),
511 	IDX_IN_WL_CNT_VER_11_T(rx18mbps),
512 	IDX_IN_WL_CNT_VER_11_T(rx24mbps),
513 	IDX_IN_WL_CNT_VER_11_T(rx36mbps),
514 	IDX_IN_WL_CNT_VER_11_T(rx48mbps),
515 	IDX_IN_WL_CNT_VER_11_T(rx54mbps),
516 	IDX_IN_WL_CNT_VER_11_T(rx108mbps),
517 	IDX_IN_WL_CNT_VER_11_T(rx162mbps),
518 	IDX_IN_WL_CNT_VER_11_T(rx216mbps),
519 	IDX_IN_WL_CNT_VER_11_T(rx270mbps),
520 	IDX_IN_WL_CNT_VER_11_T(rx324mbps),
521 	IDX_IN_WL_CNT_VER_11_T(rx378mbps),
522 	IDX_IN_WL_CNT_VER_11_T(rx432mbps),
523 	IDX_IN_WL_CNT_VER_11_T(rx486mbps),
524 	IDX_IN_WL_CNT_VER_11_T(rx540mbps),
525 	IDX_IN_WL_CNT_VER_11_T(rfdisable),
526 	IDX_IN_WL_CNT_VER_11_T(txexptime),
527 	IDX_IN_WL_CNT_VER_11_T(txmpdu_sgi),
528 	IDX_IN_WL_CNT_VER_11_T(rxmpdu_sgi),
529 	IDX_IN_WL_CNT_VER_11_T(txmpdu_stbc),
530 	IDX_IN_WL_CNT_VER_11_T(rxmpdu_stbc),
531 	IDX_IN_WL_CNT_VER_11_T(rxundec_mcst),
532 	IDX_IN_WL_CNT_VER_11_T(tkipmicfaill_mcst),
533 	IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr_mcst),
534 	IDX_IN_WL_CNT_VER_11_T(tkipreplay_mcst),
535 	IDX_IN_WL_CNT_VER_11_T(ccmpfmterr_mcst),
536 	IDX_IN_WL_CNT_VER_11_T(ccmpreplay_mcst),
537 	IDX_IN_WL_CNT_VER_11_T(ccmpundec_mcst),
538 	IDX_IN_WL_CNT_VER_11_T(fourwayfail_mcst),
539 	IDX_IN_WL_CNT_VER_11_T(wepundec_mcst),
540 	IDX_IN_WL_CNT_VER_11_T(wepicverr_mcst),
541 	IDX_IN_WL_CNT_VER_11_T(decsuccess_mcst),
542 	IDX_IN_WL_CNT_VER_11_T(tkipicverr_mcst),
543 	IDX_IN_WL_CNT_VER_11_T(wepexcluded_mcst),
544 	IDX_IN_WL_CNT_VER_11_T(dma_hang),
545 	IDX_IN_WL_CNT_VER_11_T(reinit),
546 	IDX_IN_WL_CNT_VER_11_T(pstatxucast),
547 	IDX_IN_WL_CNT_VER_11_T(pstatxnoassoc),
548 	IDX_IN_WL_CNT_VER_11_T(pstarxucast),
549 	IDX_IN_WL_CNT_VER_11_T(pstarxbcmc),
550 	IDX_IN_WL_CNT_VER_11_T(pstatxbcmc),
551 	IDX_IN_WL_CNT_VER_11_T(cso_passthrough),
552 	IDX_IN_WL_CNT_VER_11_T(cso_normal),
553 	IDX_IN_WL_CNT_VER_11_T(chained),
554 	IDX_IN_WL_CNT_VER_11_T(chainedsz1),
555 	IDX_IN_WL_CNT_VER_11_T(unchained),
556 	IDX_IN_WL_CNT_VER_11_T(maxchainsz),
557 	IDX_IN_WL_CNT_VER_11_T(currchainsz),
558 	IDX_IN_WL_CNT_VER_11_T(pciereset),
559 	IDX_IN_WL_CNT_VER_11_T(cfgrestore),
560 	IDX_IN_WL_CNT_VER_11_T(reinitreason),
561 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 1,
562 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 2,
563 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 3,
564 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 4,
565 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 5,
566 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 6,
567 	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 7,
568 	IDX_IN_WL_CNT_VER_11_T(rxrtry),
569 	IDX_IN_WL_CNT_VER_11_T(rxmpdu_mu),
570 	IDX_IN_WL_CNT_VER_11_T(txbar),
571 	IDX_IN_WL_CNT_VER_11_T(rxbar),
572 	IDX_IN_WL_CNT_VER_11_T(txpspoll),
573 	IDX_IN_WL_CNT_VER_11_T(rxpspoll),
574 	IDX_IN_WL_CNT_VER_11_T(txnull),
575 	IDX_IN_WL_CNT_VER_11_T(rxnull),
576 	IDX_IN_WL_CNT_VER_11_T(txqosnull),
577 	IDX_IN_WL_CNT_VER_11_T(rxqosnull),
578 	IDX_IN_WL_CNT_VER_11_T(txassocreq),
579 	IDX_IN_WL_CNT_VER_11_T(rxassocreq),
580 	IDX_IN_WL_CNT_VER_11_T(txreassocreq),
581 	IDX_IN_WL_CNT_VER_11_T(rxreassocreq),
582 	IDX_IN_WL_CNT_VER_11_T(txdisassoc),
583 	IDX_IN_WL_CNT_VER_11_T(rxdisassoc),
584 	IDX_IN_WL_CNT_VER_11_T(txassocrsp),
585 	IDX_IN_WL_CNT_VER_11_T(rxassocrsp),
586 	IDX_IN_WL_CNT_VER_11_T(txreassocrsp),
587 	IDX_IN_WL_CNT_VER_11_T(rxreassocrsp),
588 	IDX_IN_WL_CNT_VER_11_T(txauth),
589 	IDX_IN_WL_CNT_VER_11_T(rxauth),
590 	IDX_IN_WL_CNT_VER_11_T(txdeauth),
591 	IDX_IN_WL_CNT_VER_11_T(rxdeauth),
592 	IDX_IN_WL_CNT_VER_11_T(txprobereq),
593 	IDX_IN_WL_CNT_VER_11_T(rxprobereq),
594 	IDX_IN_WL_CNT_VER_11_T(txprobersp),
595 	IDX_IN_WL_CNT_VER_11_T(rxprobersp),
596 	IDX_IN_WL_CNT_VER_11_T(txaction),
597 	IDX_IN_WL_CNT_VER_11_T(rxaction),
598 	IDX_IN_WL_CNT_VER_11_T(ampdu_wds),
599 	IDX_IN_WL_CNT_VER_11_T(txlost),
600 	IDX_IN_WL_CNT_VER_11_T(txdatamcast),
601 	IDX_IN_WL_CNT_VER_11_T(txdatabcast),
602 	INVALID_IDX,
603 	IDX_IN_WL_CNT_VER_11_T(rxback),
604 	IDX_IN_WL_CNT_VER_11_T(txback),
605 	INVALID_IDX,
606 	INVALID_IDX,
607 	INVALID_IDX,
608 	INVALID_IDX,
609 	IDX_IN_WL_CNT_VER_11_T(txbcast),
610 	IDX_IN_WL_CNT_VER_11_T(txdropped),
611 	IDX_IN_WL_CNT_VER_11_T(rxbcast),
612 	IDX_IN_WL_CNT_VER_11_T(rxdropped)
613 };
614 
615 /* Index conversion table from wl_cnt_ver_11_t to
616  * either wl_cnt_ge40mcst_v1_t or wl_cnt_lt40mcst_v1_t
617  */
618 static const uint8 wlcntver11t_to_wlcntXX40mcstv1t[WL_CNT_MCST_VAR_NUM] = {
619 	IDX_IN_WL_CNT_VER_11_T(txallfrm),
620 	IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
621 	IDX_IN_WL_CNT_VER_11_T(txctsfrm),
622 	IDX_IN_WL_CNT_VER_11_T(txackfrm),
623 	IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
624 	IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
625 	IDX_IN_WL_CNT_VER_11_T(txfunfl),
626 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
627 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
628 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
629 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
630 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
631 	IDX_IN_WL_CNT_VER_11_T(txfbw),
632 	IDX_IN_WL_CNT_VER_11_T(txmpdu),
633 	IDX_IN_WL_CNT_VER_11_T(txtplunfl),
634 	IDX_IN_WL_CNT_VER_11_T(txphyerror),
635 	IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
636 	IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
637 	IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
638 	IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
639 	IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
640 	IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
641 	IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
642 	IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
643 	IDX_IN_WL_CNT_VER_11_T(rxstrt),
644 	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
645 	IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
646 	IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
647 	IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
648 	IDX_IN_WL_CNT_VER_11_T(rxctsucast),
649 	IDX_IN_WL_CNT_VER_11_T(rxackucast),
650 	IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
651 	IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
652 	IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
653 	IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
654 	IDX_IN_WL_CNT_VER_11_T(rxctsocast),
655 	IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
656 	IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
657 	IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
658 	IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
659 	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
660 	IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
661 	IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
662 	IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
663 	IDX_IN_WL_CNT_VER_11_T(rxnodelim),
664 	IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
665 	IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
666 	IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
667 	IDX_IN_WL_CNT_VER_11_T(txsfovfl),
668 	IDX_IN_WL_CNT_VER_11_T(pmqovfl),
669 	IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
670 	IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
671 	IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
672 	IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
673 	IDX_IN_WL_CNT_VER_11_T(prs_timeout),
674 	IDX_IN_WL_CNT_VER_11_T(rxnack),
675 	IDX_IN_WL_CNT_VER_11_T(frmscons),
676 	IDX_IN_WL_CNT_VER_11_T(txnack),
677 	IDX_IN_WL_CNT_VER_11_T(rxback),
678 	IDX_IN_WL_CNT_VER_11_T(txback),
679 	IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
680 	IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
681 	IDX_IN_WL_CNT_VER_11_T(rxtoolate),
682 	IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)
683 };
684 
685 /* For mcst offsets that were not used. (2 Pads) */
686 #define INVALID_MCST_IDX ((uint8)(-1))
687 /* Index conversion table from wl_cnt_ver_11_t to wl_cnt_v_le10_mcst_t */
688 static const uint8 wlcntver11t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
689 	IDX_IN_WL_CNT_VER_11_T(txallfrm),
690 	IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
691 	IDX_IN_WL_CNT_VER_11_T(txctsfrm),
692 	IDX_IN_WL_CNT_VER_11_T(txackfrm),
693 	IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
694 	IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
695 	IDX_IN_WL_CNT_VER_11_T(txfunfl),
696 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
697 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
698 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
699 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
700 	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
701 	IDX_IN_WL_CNT_VER_11_T(txfbw),
702 	INVALID_MCST_IDX,
703 	IDX_IN_WL_CNT_VER_11_T(txtplunfl),
704 	IDX_IN_WL_CNT_VER_11_T(txphyerror),
705 	IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
706 	IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
707 	IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
708 	IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
709 	IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
710 	IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
711 	IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
712 	IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
713 	IDX_IN_WL_CNT_VER_11_T(rxstrt),
714 	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
715 	IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
716 	IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
717 	IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
718 	IDX_IN_WL_CNT_VER_11_T(rxctsucast),
719 	IDX_IN_WL_CNT_VER_11_T(rxackucast),
720 	IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
721 	IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
722 	IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
723 	IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
724 	IDX_IN_WL_CNT_VER_11_T(rxctsocast),
725 	IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
726 	IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
727 	IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
728 	IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
729 	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
730 	IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
731 	IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
732 	IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
733 	INVALID_MCST_IDX,
734 	IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
735 	IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
736 	IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
737 	IDX_IN_WL_CNT_VER_11_T(txsfovfl),
738 	IDX_IN_WL_CNT_VER_11_T(pmqovfl),
739 	IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
740 	IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
741 	IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
742 	IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
743 	IDX_IN_WL_CNT_VER_11_T(prs_timeout),
744 	IDX_IN_WL_CNT_VER_11_T(rxnack),
745 	IDX_IN_WL_CNT_VER_11_T(frmscons),
746 	IDX_IN_WL_CNT_VER_11_T(txnack),
747 	IDX_IN_WL_CNT_VER_11_T(rxback),
748 	IDX_IN_WL_CNT_VER_11_T(txback),
749 	IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
750 	IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
751 	IDX_IN_WL_CNT_VER_11_T(rxtoolate),
752 	IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)
753 };
754 
755 /* Index conversion table from wl_cnt_ver_6_t to wl_cnt_v_le10_mcst_t */
756 static const uint8 wlcntver6t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
757 	IDX_IN_WL_CNT_VER_6_T(txallfrm),
758 	IDX_IN_WL_CNT_VER_6_T(txrtsfrm),
759 	IDX_IN_WL_CNT_VER_6_T(txctsfrm),
760 	IDX_IN_WL_CNT_VER_6_T(txackfrm),
761 	IDX_IN_WL_CNT_VER_6_T(txdnlfrm),
762 	IDX_IN_WL_CNT_VER_6_T(txbcnfrm),
763 	IDX_IN_WL_CNT_VER_6_T(txfunfl),
764 	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 1,
765 	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 2,
766 	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 3,
767 	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 4,
768 	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 5,
769 	IDX_IN_WL_CNT_VER_6_T(txfbw),
770 	INVALID_MCST_IDX,
771 	IDX_IN_WL_CNT_VER_6_T(txtplunfl),
772 	IDX_IN_WL_CNT_VER_6_T(txphyerror),
773 	IDX_IN_WL_CNT_VER_6_T(pktengrxducast),
774 	IDX_IN_WL_CNT_VER_6_T(pktengrxdmcast),
775 	IDX_IN_WL_CNT_VER_6_T(rxfrmtoolong),
776 	IDX_IN_WL_CNT_VER_6_T(rxfrmtooshrt),
777 	IDX_IN_WL_CNT_VER_6_T(rxinvmachdr),
778 	IDX_IN_WL_CNT_VER_6_T(rxbadfcs),
779 	IDX_IN_WL_CNT_VER_6_T(rxbadplcp),
780 	IDX_IN_WL_CNT_VER_6_T(rxcrsglitch),
781 	IDX_IN_WL_CNT_VER_6_T(rxstrt),
782 	IDX_IN_WL_CNT_VER_6_T(rxdfrmucastmbss),
783 	IDX_IN_WL_CNT_VER_6_T(rxmfrmucastmbss),
784 	IDX_IN_WL_CNT_VER_6_T(rxcfrmucast),
785 	IDX_IN_WL_CNT_VER_6_T(rxrtsucast),
786 	IDX_IN_WL_CNT_VER_6_T(rxctsucast),
787 	IDX_IN_WL_CNT_VER_6_T(rxackucast),
788 	IDX_IN_WL_CNT_VER_6_T(rxdfrmocast),
789 	IDX_IN_WL_CNT_VER_6_T(rxmfrmocast),
790 	IDX_IN_WL_CNT_VER_6_T(rxcfrmocast),
791 	IDX_IN_WL_CNT_VER_6_T(rxrtsocast),
792 	IDX_IN_WL_CNT_VER_6_T(rxctsocast),
793 	IDX_IN_WL_CNT_VER_6_T(rxdfrmmcast),
794 	IDX_IN_WL_CNT_VER_6_T(rxmfrmmcast),
795 	IDX_IN_WL_CNT_VER_6_T(rxcfrmmcast),
796 	IDX_IN_WL_CNT_VER_6_T(rxbeaconmbss),
797 	IDX_IN_WL_CNT_VER_6_T(rxdfrmucastobss),
798 	IDX_IN_WL_CNT_VER_6_T(rxbeaconobss),
799 	IDX_IN_WL_CNT_VER_6_T(rxrsptmout),
800 	IDX_IN_WL_CNT_VER_6_T(bcntxcancl),
801 	INVALID_MCST_IDX,
802 	IDX_IN_WL_CNT_VER_6_T(rxf0ovfl),
803 	IDX_IN_WL_CNT_VER_6_T(rxf1ovfl),
804 	IDX_IN_WL_CNT_VER_6_T(rxf2ovfl),
805 	IDX_IN_WL_CNT_VER_6_T(txsfovfl),
806 	IDX_IN_WL_CNT_VER_6_T(pmqovfl),
807 	IDX_IN_WL_CNT_VER_6_T(rxcgprqfrm),
808 	IDX_IN_WL_CNT_VER_6_T(rxcgprsqovfl),
809 	IDX_IN_WL_CNT_VER_6_T(txcgprsfail),
810 	IDX_IN_WL_CNT_VER_6_T(txcgprssuc),
811 	IDX_IN_WL_CNT_VER_6_T(prs_timeout),
812 	IDX_IN_WL_CNT_VER_6_T(rxnack),
813 	IDX_IN_WL_CNT_VER_6_T(frmscons),
814 	IDX_IN_WL_CNT_VER_6_T(txnack),
815 	IDX_IN_WL_CNT_VER_6_T(rxback),
816 	IDX_IN_WL_CNT_VER_6_T(txback),
817 	IDX_IN_WL_CNT_VER_6_T(bphy_rxcrsglitch),
818 	IDX_IN_WL_CNT_VER_6_T(rxdrop20s),
819 	IDX_IN_WL_CNT_VER_6_T(rxtoolate),
820 	IDX_IN_WL_CNT_VER_6_T(bphy_badplcp)
821 };
822 
823 /* copy wlc layer counters from old type cntbuf to wl_cnt_wlc_t type. */
824 static int
wl_copy_wlccnt(uint16 cntver,uint32 * dst,uint32 * src,uint8 src_max_idx)825 wl_copy_wlccnt(uint16 cntver, uint32 *dst, uint32 *src, uint8 src_max_idx)
826 {
827 	uint i;
828 	if (dst == NULL || src == NULL) {
829 		return BCME_ERROR;
830 	}
831 
832 	/* Init wlccnt with invalid value. Unchanged value will not be printed out */
833 	for (i = 0; i < (sizeof(wl_cnt_wlc_t) / sizeof(uint32)); i++) {
834 		dst[i] = INVALID_CNT_VAL;
835 	}
836 
837 	if (cntver == WL_CNT_VERSION_6) {
838 		for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T; i++) {
839 			if (wlcntver6t_to_wlcntwlct[i] >= src_max_idx) {
840 				/* src buffer does not have counters from here */
841 				break;
842 			}
843 			dst[i] = src[wlcntver6t_to_wlcntwlct[i]];
844 		}
845 	} else {
846 		for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T; i++) {
847 			if (wlcntver11t_to_wlcntwlct[i] >= src_max_idx) {
848 				if (wlcntver11t_to_wlcntwlct[i] == INVALID_IDX) {
849 					continue;
850 				}
851 				else {
852 					/* src buffer does not have counters from here */
853 					break;
854 				}
855 			}
856 			dst[i] = src[wlcntver11t_to_wlcntwlct[i]];
857 		}
858 	}
859 	return BCME_OK;
860 }
861 
862 /* copy macstat counters from old type cntbuf to wl_cnt_v_le10_mcst_t type. */
863 static int
wl_copy_macstat_upto_ver10(uint16 cntver,uint32 * dst,uint32 * src)864 wl_copy_macstat_upto_ver10(uint16 cntver, uint32 *dst, uint32 *src)
865 {
866 	uint i;
867 
868 	if (dst == NULL || src == NULL) {
869 		return BCME_ERROR;
870 	}
871 
872 	if (cntver == WL_CNT_VERSION_6) {
873 		for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
874 			if (wlcntver6t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
875 				/* This mcst counter does not exist in wl_cnt_ver_6_t */
876 				dst[i] = INVALID_CNT_VAL;
877 			} else {
878 				dst[i] = src[wlcntver6t_to_wlcntvle10mcstt[i]];
879 			}
880 		}
881 	} else {
882 		for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
883 			if (wlcntver11t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
884 				/* This mcst counter does not exist in wl_cnt_ver_11_t */
885 				dst[i] = INVALID_CNT_VAL;
886 			} else {
887 				dst[i] = src[wlcntver11t_to_wlcntvle10mcstt[i]];
888 			}
889 		}
890 	}
891 	return BCME_OK;
892 }
893 
894 static int
wl_copy_macstat_ver11(uint32 * dst,uint32 * src)895 wl_copy_macstat_ver11(uint32 *dst, uint32 *src)
896 {
897 	uint i;
898 
899 	if (dst == NULL || src == NULL) {
900 		return BCME_ERROR;
901 	}
902 
903 	for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
904 		dst[i] = src[wlcntver11t_to_wlcntXX40mcstv1t[i]];
905 	}
906 	return BCME_OK;
907 }
908 
909 /**
910  * Translate non-xtlv 'wl counters' IOVar buffer received by old driver/FW to xtlv format.
911  * Parameters:
912  *	cntbuf: pointer to non-xtlv 'wl counters' IOVar buffer received by old driver/FW.
913  *		Newly translated xtlv format is written to this pointer.
914  *	buflen: length of the "cntbuf" without any padding.
915  *	corerev: chip core revision of the driver/FW.
916  */
917 int
wl_cntbuf_to_xtlv_format(void * ctx,void * cntbuf,int buflen,uint32 corerev)918 wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen, uint32 corerev)
919 {
920 	wl_cnt_wlc_t *wlccnt = NULL;
921 	uint32 *macstat = NULL;
922 	xtlv_desc_t xtlv_desc[3];
923 	uint16 mcst_xtlv_id;
924 	int res = BCME_OK;
925 	wl_cnt_info_t *cntinfo = cntbuf;
926 	uint8 *xtlvbuf_p = cntinfo->data;
927 	uint16 ver = cntinfo->version;
928 	uint16 xtlvbuflen = (uint16)buflen;
929 	uint16 src_max_idx;
930 #ifdef BCMDRIVER
931 	osl_t *osh = ctx;
932 #else
933 	BCM_REFERENCE(ctx);
934 #endif // endif
935 
936 	if (ver >= WL_CNT_VERSION_XTLV) {
937 		/* Already in xtlv format. */
938 		goto exit;
939 	}
940 
941 #ifdef BCMDRIVER
942 	wlccnt = MALLOC(osh, sizeof(*wlccnt));
943 	macstat = MALLOC(osh, WL_CNT_MCST_STRUCT_SZ);
944 #else
945 	wlccnt = (wl_cnt_wlc_t *)malloc(sizeof(*wlccnt));
946 	macstat = (uint32 *)malloc(WL_CNT_MCST_STRUCT_SZ);
947 #endif // endif
948 	if (!wlccnt || !macstat) {
949 		printf("%s: malloc fail!\n", __FUNCTION__);
950 		res = BCME_NOMEM;
951 		goto exit;
952 	}
953 
954 	/* Check if the max idx in the struct exceeds the boundary of uint8 */
955 	if (NUM_OF_CNT_IN_WL_CNT_VER_6_T > ((uint8)(-1) + 1) ||
956 		NUM_OF_CNT_IN_WL_CNT_VER_11_T > ((uint8)(-1) + 1)) {
957 		printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
958 			" to be of uint16 instead of uint8\n");
959 		res = BCME_ERROR;
960 		goto exit;
961 	}
962 
963 	/* Exclude version and length fields in either wlc_cnt_ver_6_t or wlc_cnt_ver_11_t */
964 	src_max_idx = (cntinfo->datalen - OFFSETOF(wl_cnt_info_t, data)) / sizeof(uint32);
965 	if (src_max_idx > (uint8)(-1)) {
966 		printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
967 			" to be of uint16 instead of uint8\n"
968 			"Try updating wl utility to the latest.\n");
969 		src_max_idx = (uint8)(-1);
970 	}
971 
972 	/* Copy wlc layer counters to wl_cnt_wlc_t */
973 	res = wl_copy_wlccnt(ver, (uint32 *)wlccnt, (uint32 *)cntinfo->data, (uint8)src_max_idx);
974 	if (res != BCME_OK) {
975 		printf("wl_copy_wlccnt fail!\n");
976 		goto exit;
977 	}
978 
979 	/* Copy macstat counters to wl_cnt_wlc_t */
980 	if (ver == WL_CNT_VERSION_11) {
981 		res = wl_copy_macstat_ver11(macstat, (uint32 *)cntinfo->data);
982 		if (res != BCME_OK) {
983 			printf("wl_copy_macstat_ver11 fail!\n");
984 			goto exit;
985 		}
986 		if (corerev >= 40) {
987 			mcst_xtlv_id = WL_CNT_XTLV_GE40_UCODE_V1;
988 		} else {
989 			mcst_xtlv_id = WL_CNT_XTLV_LT40_UCODE_V1;
990 		}
991 	} else {
992 		res = wl_copy_macstat_upto_ver10(ver, macstat, (uint32 *)cntinfo->data);
993 		if (res != BCME_OK) {
994 			printf("wl_copy_macstat_upto_ver10 fail!\n");
995 			goto exit;
996 		}
997 		mcst_xtlv_id = WL_CNT_XTLV_CNTV_LE10_UCODE;
998 	}
999 
1000 	xtlv_desc[0].type = WL_CNT_XTLV_WLC;
1001 	xtlv_desc[0].len = sizeof(*wlccnt);
1002 	xtlv_desc[0].ptr = wlccnt;
1003 
1004 	xtlv_desc[1].type = mcst_xtlv_id;
1005 	xtlv_desc[1].len = WL_CNT_MCST_STRUCT_SZ;
1006 	xtlv_desc[1].ptr = macstat;
1007 
1008 	xtlv_desc[2].type = 0;
1009 	xtlv_desc[2].len = 0;
1010 	xtlv_desc[2].ptr = NULL;
1011 
1012 	memset(cntbuf, 0, buflen);
1013 
1014 	res = bcm_pack_xtlv_buf_from_mem(&xtlvbuf_p, &xtlvbuflen,
1015 		xtlv_desc, BCM_XTLV_OPTION_ALIGN32);
1016 	cntinfo->datalen = (buflen - xtlvbuflen);
1017 exit:
1018 #ifdef BCMDRIVER
1019 	if (wlccnt) {
1020 		MFREE(osh, wlccnt, sizeof(*wlccnt));
1021 	}
1022 	if (macstat) {
1023 		MFREE(osh, macstat, WL_CNT_MCST_STRUCT_SZ);
1024 	}
1025 #else
1026 	if (wlccnt) {
1027 		free(wlccnt);
1028 	}
1029 	if (macstat) {
1030 		free(macstat);
1031 	}
1032 #endif // endif
1033 	return res;
1034 }
1035