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