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