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-2019, Broadcom.
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
18 * of the license of that module. An independent module is a module which is
19 * not 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 667243 2016-10-26 11:37:48Z $
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 // 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 // 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
59 return a summary. Currently implemented as a simple average but could easily
60 evolve into more cpomplex alogrithms.
61 */
62 cca_congest_channel_req_t *
cca_per_chan_summary(cca_congest_channel_req_t * input,cca_congest_channel_req_t * avg,bool percent)63 cca_per_chan_summary(cca_congest_channel_req_t *input,
64 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
90 if (percent) {
91 avg->secs[0].duration = totals.duration / avg->num_secs;
92 avg->secs[0].congest_ibss = totals.congest_ibss * 0x64 / totals.duration;
93 avg->secs[0].congest_obss = totals.congest_obss * 0x64 / totals.duration;
94 avg->secs[0].interference = totals.interference * 0x64 / 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
cca_info(uint8 * bitmap,int num_bits,int * left,int * bit_pos)105 static void 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
spec_to_chan(chanspec_t chspec)116 static uint8 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_BW_LE20(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
153 readings. For the moment, do not overwrite input array.
154 */
cca_analyze(cca_congest_channel_req_t * input[],int num_chans,uint flags,chanspec_t * answer)155 int cca_analyze(cca_congest_channel_req_t *input[], int num_chans, uint flags,
156 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 }
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 }
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 }
205 cca_info(bitmap, num_chans, &left, &i);
206 if (!left) {
207 ret_val = CCA_ERRNO_BAND;
208 goto f_exit;
209 }
210
211 /* Filter for Duration */
212 if (!(flags & CCA_FLAG_IGNORE_DURATION)) {
213 for (i = 0; i < num_chans; i++) {
214 if (input[i]->secs[0].duration < CCA_THRESH_MILLI) {
215 clrbit(bitmap, i);
216 }
217 }
218 }
219 cca_info(bitmap, num_chans, &left, &i);
220 if (!left) {
221 ret_val = CCA_ERRNO_DURATION;
222 goto f_exit;
223 }
224
225 /* Filter for 1 6 11 on 2.4 Band */
226 if (flags & CCA_FLAGS_PREFER_1_6_11) {
227 int tmp_channel = spec_to_chan(input[i]->chanspec);
228 int is2g = CHSPEC_IS2G(input[i]->chanspec);
229 for (i = 0; i < num_chans; i++) {
230 if (is2g && tmp_channel != 1 && tmp_channel != 0x6 &&
231 tmp_channel != 0xB) {
232 clrbit(bitmap, i);
233 }
234 }
235 }
236 cca_info(bitmap, num_chans, &left, &i);
237 if (!left) {
238 ret_val = CCA_ERRNO_PREF_CHAN;
239 goto f_exit;
240 }
241
242 /* Toss high interference interference */
243 if (!(flags & CCA_FLAG_IGNORE_INTERFER)) {
244 for (i = 0; i < num_chans; i++) {
245 if (input[i]->secs[0].interference > CCA_THRESH_INTERFERE) {
246 clrbit(bitmap, i);
247 }
248 }
249 cca_info(bitmap, num_chans, &left, &i);
250 if (!left) {
251 ret_val = CCA_ERRNO_INTERFER;
252 goto f_exit;
253 }
254 }
255
256 /* Now find lowest obss */
257 winner = 0;
258 for (i = 0; i < num_chans; i++) {
259 if (isset(bitmap, i) && input[i]->secs[0].congest_obss < min_obss) {
260 winner = i;
261 min_obss = input[i]->secs[0].congest_obss;
262 }
263 }
264 *answer = input[winner]->chanspec;
265 f_exit:
266 free(bitmap); /* free the allocated memory for bitmap */
267 return ret_val;
268 }
269 #endif /* !BCMDRIVER */
270
271 /* offset of cntmember by sizeof(uint32) from the first cnt variable, txframe.
272 */
273 #define IDX_IN_WL_CNT_VER_6_T(cntmember) \
274 ((OFFSETOF(wl_cnt_ver_6_t, cntmember) - \
275 OFFSETOF(wl_cnt_ver_6_t, txframe)) / \
276 sizeof(uint32))
277
278 #define IDX_IN_WL_CNT_VER_11_T(cntmember) \
279 ((OFFSETOF(wl_cnt_ver_11_t, cntmember) - \
280 OFFSETOF(wl_cnt_ver_11_t, txframe)) / \
281 sizeof(uint32))
282
283 /* Exclude version and length fields */
284 #define NUM_OF_CNT_IN_WL_CNT_VER_6_T \
285 ((sizeof(wl_cnt_ver_6_t) - 2 * sizeof(uint16)) / sizeof(uint32))
286 /* Exclude macstat cnt variables. wl_cnt_ver_6_t only has 62 macstat cnt
287 * variables. */
288 #define NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T \
289 (NUM_OF_CNT_IN_WL_CNT_VER_6_T - (WL_CNT_MCST_VAR_NUM - 2))
290
291 /* Exclude version and length fields */
292 #define NUM_OF_CNT_IN_WL_CNT_VER_11_T \
293 ((sizeof(wl_cnt_ver_11_t) - 2 * sizeof(uint16)) / sizeof(uint32))
294 /* Exclude 64 macstat cnt variables. */
295 #define NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T \
296 ((sizeof(wl_cnt_wlc_t)) / sizeof(uint32))
297
298 /* Index conversion table from wl_cnt_ver_6_t to wl_cnt_wlc_t */
299 static const uint8 wlcntver6t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T] = {
300 IDX_IN_WL_CNT_VER_6_T(txframe),
301 IDX_IN_WL_CNT_VER_6_T(txbyte),
302 IDX_IN_WL_CNT_VER_6_T(txretrans),
303 IDX_IN_WL_CNT_VER_6_T(txerror),
304 IDX_IN_WL_CNT_VER_6_T(txctl),
305 IDX_IN_WL_CNT_VER_6_T(txprshort),
306 IDX_IN_WL_CNT_VER_6_T(txserr),
307 IDX_IN_WL_CNT_VER_6_T(txnobuf),
308 IDX_IN_WL_CNT_VER_6_T(txnoassoc),
309 IDX_IN_WL_CNT_VER_6_T(txrunt),
310 IDX_IN_WL_CNT_VER_6_T(txchit),
311 IDX_IN_WL_CNT_VER_6_T(txcmiss),
312 IDX_IN_WL_CNT_VER_6_T(txuflo),
313 IDX_IN_WL_CNT_VER_6_T(txphyerr),
314 IDX_IN_WL_CNT_VER_6_T(txphycrs),
315 IDX_IN_WL_CNT_VER_6_T(rxframe),
316 IDX_IN_WL_CNT_VER_6_T(rxbyte),
317 IDX_IN_WL_CNT_VER_6_T(rxerror),
318 IDX_IN_WL_CNT_VER_6_T(rxctl),
319 IDX_IN_WL_CNT_VER_6_T(rxnobuf),
320 IDX_IN_WL_CNT_VER_6_T(rxnondata),
321 IDX_IN_WL_CNT_VER_6_T(rxbadds),
322 IDX_IN_WL_CNT_VER_6_T(rxbadcm),
323 IDX_IN_WL_CNT_VER_6_T(rxfragerr),
324 IDX_IN_WL_CNT_VER_6_T(rxrunt),
325 IDX_IN_WL_CNT_VER_6_T(rxgiant),
326 IDX_IN_WL_CNT_VER_6_T(rxnoscb),
327 IDX_IN_WL_CNT_VER_6_T(rxbadproto),
328 IDX_IN_WL_CNT_VER_6_T(rxbadsrcmac),
329 IDX_IN_WL_CNT_VER_6_T(rxbadda),
330 IDX_IN_WL_CNT_VER_6_T(rxfilter),
331 IDX_IN_WL_CNT_VER_6_T(rxoflo),
332 IDX_IN_WL_CNT_VER_6_T(rxuflo),
333 IDX_IN_WL_CNT_VER_6_T(rxuflo) + 1,
334 IDX_IN_WL_CNT_VER_6_T(rxuflo) + 2,
335 IDX_IN_WL_CNT_VER_6_T(rxuflo) + 3,
336 IDX_IN_WL_CNT_VER_6_T(rxuflo) + 4,
337 IDX_IN_WL_CNT_VER_6_T(rxuflo) + 5,
338 IDX_IN_WL_CNT_VER_6_T(d11cnt_txrts_off),
339 IDX_IN_WL_CNT_VER_6_T(d11cnt_rxcrc_off),
340 IDX_IN_WL_CNT_VER_6_T(d11cnt_txnocts_off),
341 IDX_IN_WL_CNT_VER_6_T(dmade),
342 IDX_IN_WL_CNT_VER_6_T(dmada),
343 IDX_IN_WL_CNT_VER_6_T(dmape),
344 IDX_IN_WL_CNT_VER_6_T(reset),
345 IDX_IN_WL_CNT_VER_6_T(tbtt),
346 IDX_IN_WL_CNT_VER_6_T(txdmawar),
347 IDX_IN_WL_CNT_VER_6_T(pkt_callback_reg_fail),
348 IDX_IN_WL_CNT_VER_6_T(txfrag),
349 IDX_IN_WL_CNT_VER_6_T(txmulti),
350 IDX_IN_WL_CNT_VER_6_T(txfail),
351 IDX_IN_WL_CNT_VER_6_T(txretry),
352 IDX_IN_WL_CNT_VER_6_T(txretrie),
353 IDX_IN_WL_CNT_VER_6_T(rxdup),
354 IDX_IN_WL_CNT_VER_6_T(txrts),
355 IDX_IN_WL_CNT_VER_6_T(txnocts),
356 IDX_IN_WL_CNT_VER_6_T(txnoack),
357 IDX_IN_WL_CNT_VER_6_T(rxfrag),
358 IDX_IN_WL_CNT_VER_6_T(rxmulti),
359 IDX_IN_WL_CNT_VER_6_T(rxcrc),
360 IDX_IN_WL_CNT_VER_6_T(txfrmsnt),
361 IDX_IN_WL_CNT_VER_6_T(rxundec),
362 IDX_IN_WL_CNT_VER_6_T(tkipmicfaill),
363 IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr),
364 IDX_IN_WL_CNT_VER_6_T(tkipreplay),
365 IDX_IN_WL_CNT_VER_6_T(ccmpfmterr),
366 IDX_IN_WL_CNT_VER_6_T(ccmpreplay),
367 IDX_IN_WL_CNT_VER_6_T(ccmpundec),
368 IDX_IN_WL_CNT_VER_6_T(fourwayfail),
369 IDX_IN_WL_CNT_VER_6_T(wepundec),
370 IDX_IN_WL_CNT_VER_6_T(wepicverr),
371 IDX_IN_WL_CNT_VER_6_T(decsuccess),
372 IDX_IN_WL_CNT_VER_6_T(tkipicverr),
373 IDX_IN_WL_CNT_VER_6_T(wepexcluded),
374 IDX_IN_WL_CNT_VER_6_T(txchanrej),
375 IDX_IN_WL_CNT_VER_6_T(psmwds),
376 IDX_IN_WL_CNT_VER_6_T(phywatchdog),
377 IDX_IN_WL_CNT_VER_6_T(prq_entries_handled),
378 IDX_IN_WL_CNT_VER_6_T(prq_undirected_entries),
379 IDX_IN_WL_CNT_VER_6_T(prq_bad_entries),
380 IDX_IN_WL_CNT_VER_6_T(atim_suppress_count),
381 IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready),
382 IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready_done),
383 IDX_IN_WL_CNT_VER_6_T(late_tbtt_dpc),
384 IDX_IN_WL_CNT_VER_6_T(rx1mbps),
385 IDX_IN_WL_CNT_VER_6_T(rx2mbps),
386 IDX_IN_WL_CNT_VER_6_T(rx5mbps5),
387 IDX_IN_WL_CNT_VER_6_T(rx6mbps),
388 IDX_IN_WL_CNT_VER_6_T(rx9mbps),
389 IDX_IN_WL_CNT_VER_6_T(rx11mbps),
390 IDX_IN_WL_CNT_VER_6_T(rx12mbps),
391 IDX_IN_WL_CNT_VER_6_T(rx18mbps),
392 IDX_IN_WL_CNT_VER_6_T(rx24mbps),
393 IDX_IN_WL_CNT_VER_6_T(rx36mbps),
394 IDX_IN_WL_CNT_VER_6_T(rx48mbps),
395 IDX_IN_WL_CNT_VER_6_T(rx54mbps),
396 IDX_IN_WL_CNT_VER_6_T(rx108mbps),
397 IDX_IN_WL_CNT_VER_6_T(rx162mbps),
398 IDX_IN_WL_CNT_VER_6_T(rx216mbps),
399 IDX_IN_WL_CNT_VER_6_T(rx270mbps),
400 IDX_IN_WL_CNT_VER_6_T(rx324mbps),
401 IDX_IN_WL_CNT_VER_6_T(rx378mbps),
402 IDX_IN_WL_CNT_VER_6_T(rx432mbps),
403 IDX_IN_WL_CNT_VER_6_T(rx486mbps),
404 IDX_IN_WL_CNT_VER_6_T(rx540mbps),
405 IDX_IN_WL_CNT_VER_6_T(rfdisable),
406 IDX_IN_WL_CNT_VER_6_T(txexptime),
407 IDX_IN_WL_CNT_VER_6_T(txmpdu_sgi),
408 IDX_IN_WL_CNT_VER_6_T(rxmpdu_sgi),
409 IDX_IN_WL_CNT_VER_6_T(txmpdu_stbc),
410 IDX_IN_WL_CNT_VER_6_T(rxmpdu_stbc),
411 IDX_IN_WL_CNT_VER_6_T(rxundec_mcst),
412 IDX_IN_WL_CNT_VER_6_T(tkipmicfaill_mcst),
413 IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr_mcst),
414 IDX_IN_WL_CNT_VER_6_T(tkipreplay_mcst),
415 IDX_IN_WL_CNT_VER_6_T(ccmpfmterr_mcst),
416 IDX_IN_WL_CNT_VER_6_T(ccmpreplay_mcst),
417 IDX_IN_WL_CNT_VER_6_T(ccmpundec_mcst),
418 IDX_IN_WL_CNT_VER_6_T(fourwayfail_mcst),
419 IDX_IN_WL_CNT_VER_6_T(wepundec_mcst),
420 IDX_IN_WL_CNT_VER_6_T(wepicverr_mcst),
421 IDX_IN_WL_CNT_VER_6_T(decsuccess_mcst),
422 IDX_IN_WL_CNT_VER_6_T(tkipicverr_mcst),
423 IDX_IN_WL_CNT_VER_6_T(wepexcluded_mcst)};
424
425 #define INVALID_IDX ((uint8)(-1))
426
427 /* Index conversion table from wl_cnt_ver_11_t to wl_cnt_wlc_t */
428 static const uint8 wlcntver11t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T] = {
429 IDX_IN_WL_CNT_VER_11_T(txframe),
430 IDX_IN_WL_CNT_VER_11_T(txbyte),
431 IDX_IN_WL_CNT_VER_11_T(txretrans),
432 IDX_IN_WL_CNT_VER_11_T(txerror),
433 IDX_IN_WL_CNT_VER_11_T(txctl),
434 IDX_IN_WL_CNT_VER_11_T(txprshort),
435 IDX_IN_WL_CNT_VER_11_T(txserr),
436 IDX_IN_WL_CNT_VER_11_T(txnobuf),
437 IDX_IN_WL_CNT_VER_11_T(txnoassoc),
438 IDX_IN_WL_CNT_VER_11_T(txrunt),
439 IDX_IN_WL_CNT_VER_11_T(txchit),
440 IDX_IN_WL_CNT_VER_11_T(txcmiss),
441 IDX_IN_WL_CNT_VER_11_T(txuflo),
442 IDX_IN_WL_CNT_VER_11_T(txphyerr),
443 IDX_IN_WL_CNT_VER_11_T(txphycrs),
444 IDX_IN_WL_CNT_VER_11_T(rxframe),
445 IDX_IN_WL_CNT_VER_11_T(rxbyte),
446 IDX_IN_WL_CNT_VER_11_T(rxerror),
447 IDX_IN_WL_CNT_VER_11_T(rxctl),
448 IDX_IN_WL_CNT_VER_11_T(rxnobuf),
449 IDX_IN_WL_CNT_VER_11_T(rxnondata),
450 IDX_IN_WL_CNT_VER_11_T(rxbadds),
451 IDX_IN_WL_CNT_VER_11_T(rxbadcm),
452 IDX_IN_WL_CNT_VER_11_T(rxfragerr),
453 IDX_IN_WL_CNT_VER_11_T(rxrunt),
454 IDX_IN_WL_CNT_VER_11_T(rxgiant),
455 IDX_IN_WL_CNT_VER_11_T(rxnoscb),
456 IDX_IN_WL_CNT_VER_11_T(rxbadproto),
457 IDX_IN_WL_CNT_VER_11_T(rxbadsrcmac),
458 IDX_IN_WL_CNT_VER_11_T(rxbadda),
459 IDX_IN_WL_CNT_VER_11_T(rxfilter),
460 IDX_IN_WL_CNT_VER_11_T(rxoflo),
461 IDX_IN_WL_CNT_VER_11_T(rxuflo),
462 IDX_IN_WL_CNT_VER_11_T(rxuflo) + 1,
463 IDX_IN_WL_CNT_VER_11_T(rxuflo) + 2,
464 IDX_IN_WL_CNT_VER_11_T(rxuflo) + 3,
465 IDX_IN_WL_CNT_VER_11_T(rxuflo) + 4,
466 IDX_IN_WL_CNT_VER_11_T(rxuflo) + 5,
467 IDX_IN_WL_CNT_VER_11_T(d11cnt_txrts_off),
468 IDX_IN_WL_CNT_VER_11_T(d11cnt_rxcrc_off),
469 IDX_IN_WL_CNT_VER_11_T(d11cnt_txnocts_off),
470 IDX_IN_WL_CNT_VER_11_T(dmade),
471 IDX_IN_WL_CNT_VER_11_T(dmada),
472 IDX_IN_WL_CNT_VER_11_T(dmape),
473 IDX_IN_WL_CNT_VER_11_T(reset),
474 IDX_IN_WL_CNT_VER_11_T(tbtt),
475 IDX_IN_WL_CNT_VER_11_T(txdmawar),
476 IDX_IN_WL_CNT_VER_11_T(pkt_callback_reg_fail),
477 IDX_IN_WL_CNT_VER_11_T(txfrag),
478 IDX_IN_WL_CNT_VER_11_T(txmulti),
479 IDX_IN_WL_CNT_VER_11_T(txfail),
480 IDX_IN_WL_CNT_VER_11_T(txretry),
481 IDX_IN_WL_CNT_VER_11_T(txretrie),
482 IDX_IN_WL_CNT_VER_11_T(rxdup),
483 IDX_IN_WL_CNT_VER_11_T(txrts),
484 IDX_IN_WL_CNT_VER_11_T(txnocts),
485 IDX_IN_WL_CNT_VER_11_T(txnoack),
486 IDX_IN_WL_CNT_VER_11_T(rxfrag),
487 IDX_IN_WL_CNT_VER_11_T(rxmulti),
488 IDX_IN_WL_CNT_VER_11_T(rxcrc),
489 IDX_IN_WL_CNT_VER_11_T(txfrmsnt),
490 IDX_IN_WL_CNT_VER_11_T(rxundec),
491 IDX_IN_WL_CNT_VER_11_T(tkipmicfaill),
492 IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr),
493 IDX_IN_WL_CNT_VER_11_T(tkipreplay),
494 IDX_IN_WL_CNT_VER_11_T(ccmpfmterr),
495 IDX_IN_WL_CNT_VER_11_T(ccmpreplay),
496 IDX_IN_WL_CNT_VER_11_T(ccmpundec),
497 IDX_IN_WL_CNT_VER_11_T(fourwayfail),
498 IDX_IN_WL_CNT_VER_11_T(wepundec),
499 IDX_IN_WL_CNT_VER_11_T(wepicverr),
500 IDX_IN_WL_CNT_VER_11_T(decsuccess),
501 IDX_IN_WL_CNT_VER_11_T(tkipicverr),
502 IDX_IN_WL_CNT_VER_11_T(wepexcluded),
503 IDX_IN_WL_CNT_VER_11_T(txchanrej),
504 IDX_IN_WL_CNT_VER_11_T(psmwds),
505 IDX_IN_WL_CNT_VER_11_T(phywatchdog),
506 IDX_IN_WL_CNT_VER_11_T(prq_entries_handled),
507 IDX_IN_WL_CNT_VER_11_T(prq_undirected_entries),
508 IDX_IN_WL_CNT_VER_11_T(prq_bad_entries),
509 IDX_IN_WL_CNT_VER_11_T(atim_suppress_count),
510 IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready),
511 IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready_done),
512 IDX_IN_WL_CNT_VER_11_T(late_tbtt_dpc),
513 IDX_IN_WL_CNT_VER_11_T(rx1mbps),
514 IDX_IN_WL_CNT_VER_11_T(rx2mbps),
515 IDX_IN_WL_CNT_VER_11_T(rx5mbps5),
516 IDX_IN_WL_CNT_VER_11_T(rx6mbps),
517 IDX_IN_WL_CNT_VER_11_T(rx9mbps),
518 IDX_IN_WL_CNT_VER_11_T(rx11mbps),
519 IDX_IN_WL_CNT_VER_11_T(rx12mbps),
520 IDX_IN_WL_CNT_VER_11_T(rx18mbps),
521 IDX_IN_WL_CNT_VER_11_T(rx24mbps),
522 IDX_IN_WL_CNT_VER_11_T(rx36mbps),
523 IDX_IN_WL_CNT_VER_11_T(rx48mbps),
524 IDX_IN_WL_CNT_VER_11_T(rx54mbps),
525 IDX_IN_WL_CNT_VER_11_T(rx108mbps),
526 IDX_IN_WL_CNT_VER_11_T(rx162mbps),
527 IDX_IN_WL_CNT_VER_11_T(rx216mbps),
528 IDX_IN_WL_CNT_VER_11_T(rx270mbps),
529 IDX_IN_WL_CNT_VER_11_T(rx324mbps),
530 IDX_IN_WL_CNT_VER_11_T(rx378mbps),
531 IDX_IN_WL_CNT_VER_11_T(rx432mbps),
532 IDX_IN_WL_CNT_VER_11_T(rx486mbps),
533 IDX_IN_WL_CNT_VER_11_T(rx540mbps),
534 IDX_IN_WL_CNT_VER_11_T(rfdisable),
535 IDX_IN_WL_CNT_VER_11_T(txexptime),
536 IDX_IN_WL_CNT_VER_11_T(txmpdu_sgi),
537 IDX_IN_WL_CNT_VER_11_T(rxmpdu_sgi),
538 IDX_IN_WL_CNT_VER_11_T(txmpdu_stbc),
539 IDX_IN_WL_CNT_VER_11_T(rxmpdu_stbc),
540 IDX_IN_WL_CNT_VER_11_T(rxundec_mcst),
541 IDX_IN_WL_CNT_VER_11_T(tkipmicfaill_mcst),
542 IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr_mcst),
543 IDX_IN_WL_CNT_VER_11_T(tkipreplay_mcst),
544 IDX_IN_WL_CNT_VER_11_T(ccmpfmterr_mcst),
545 IDX_IN_WL_CNT_VER_11_T(ccmpreplay_mcst),
546 IDX_IN_WL_CNT_VER_11_T(ccmpundec_mcst),
547 IDX_IN_WL_CNT_VER_11_T(fourwayfail_mcst),
548 IDX_IN_WL_CNT_VER_11_T(wepundec_mcst),
549 IDX_IN_WL_CNT_VER_11_T(wepicverr_mcst),
550 IDX_IN_WL_CNT_VER_11_T(decsuccess_mcst),
551 IDX_IN_WL_CNT_VER_11_T(tkipicverr_mcst),
552 IDX_IN_WL_CNT_VER_11_T(wepexcluded_mcst),
553 IDX_IN_WL_CNT_VER_11_T(dma_hang),
554 IDX_IN_WL_CNT_VER_11_T(reinit),
555 IDX_IN_WL_CNT_VER_11_T(pstatxucast),
556 IDX_IN_WL_CNT_VER_11_T(pstatxnoassoc),
557 IDX_IN_WL_CNT_VER_11_T(pstarxucast),
558 IDX_IN_WL_CNT_VER_11_T(pstarxbcmc),
559 IDX_IN_WL_CNT_VER_11_T(pstatxbcmc),
560 IDX_IN_WL_CNT_VER_11_T(cso_passthrough),
561 IDX_IN_WL_CNT_VER_11_T(cso_normal),
562 IDX_IN_WL_CNT_VER_11_T(chained),
563 IDX_IN_WL_CNT_VER_11_T(chainedsz1),
564 IDX_IN_WL_CNT_VER_11_T(unchained),
565 IDX_IN_WL_CNT_VER_11_T(maxchainsz),
566 IDX_IN_WL_CNT_VER_11_T(currchainsz),
567 IDX_IN_WL_CNT_VER_11_T(pciereset),
568 IDX_IN_WL_CNT_VER_11_T(cfgrestore),
569 IDX_IN_WL_CNT_VER_11_T(reinitreason),
570 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 1,
571 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 2,
572 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 3,
573 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 4,
574 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 5,
575 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 6,
576 IDX_IN_WL_CNT_VER_11_T(reinitreason) + 7,
577 IDX_IN_WL_CNT_VER_11_T(rxrtry),
578 IDX_IN_WL_CNT_VER_11_T(rxmpdu_mu),
579 IDX_IN_WL_CNT_VER_11_T(txbar),
580 IDX_IN_WL_CNT_VER_11_T(rxbar),
581 IDX_IN_WL_CNT_VER_11_T(txpspoll),
582 IDX_IN_WL_CNT_VER_11_T(rxpspoll),
583 IDX_IN_WL_CNT_VER_11_T(txnull),
584 IDX_IN_WL_CNT_VER_11_T(rxnull),
585 IDX_IN_WL_CNT_VER_11_T(txqosnull),
586 IDX_IN_WL_CNT_VER_11_T(rxqosnull),
587 IDX_IN_WL_CNT_VER_11_T(txassocreq),
588 IDX_IN_WL_CNT_VER_11_T(rxassocreq),
589 IDX_IN_WL_CNT_VER_11_T(txreassocreq),
590 IDX_IN_WL_CNT_VER_11_T(rxreassocreq),
591 IDX_IN_WL_CNT_VER_11_T(txdisassoc),
592 IDX_IN_WL_CNT_VER_11_T(rxdisassoc),
593 IDX_IN_WL_CNT_VER_11_T(txassocrsp),
594 IDX_IN_WL_CNT_VER_11_T(rxassocrsp),
595 IDX_IN_WL_CNT_VER_11_T(txreassocrsp),
596 IDX_IN_WL_CNT_VER_11_T(rxreassocrsp),
597 IDX_IN_WL_CNT_VER_11_T(txauth),
598 IDX_IN_WL_CNT_VER_11_T(rxauth),
599 IDX_IN_WL_CNT_VER_11_T(txdeauth),
600 IDX_IN_WL_CNT_VER_11_T(rxdeauth),
601 IDX_IN_WL_CNT_VER_11_T(txprobereq),
602 IDX_IN_WL_CNT_VER_11_T(rxprobereq),
603 IDX_IN_WL_CNT_VER_11_T(txprobersp),
604 IDX_IN_WL_CNT_VER_11_T(rxprobersp),
605 IDX_IN_WL_CNT_VER_11_T(txaction),
606 IDX_IN_WL_CNT_VER_11_T(rxaction),
607 IDX_IN_WL_CNT_VER_11_T(ampdu_wds),
608 IDX_IN_WL_CNT_VER_11_T(txlost),
609 IDX_IN_WL_CNT_VER_11_T(txdatamcast),
610 IDX_IN_WL_CNT_VER_11_T(txdatabcast),
611 INVALID_IDX,
612 IDX_IN_WL_CNT_VER_11_T(rxback),
613 IDX_IN_WL_CNT_VER_11_T(txback),
614 INVALID_IDX,
615 INVALID_IDX,
616 INVALID_IDX,
617 INVALID_IDX,
618 IDX_IN_WL_CNT_VER_11_T(txbcast),
619 IDX_IN_WL_CNT_VER_11_T(txdropped),
620 IDX_IN_WL_CNT_VER_11_T(rxbcast),
621 IDX_IN_WL_CNT_VER_11_T(rxdropped)};
622
623 /* Index conversion table from wl_cnt_ver_11_t to
624 * either wl_cnt_ge40mcst_v1_t or wl_cnt_lt40mcst_v1_t
625 */
626 static const uint8 wlcntver11t_to_wlcntXX40mcstv1t[WL_CNT_MCST_VAR_NUM] = {
627 IDX_IN_WL_CNT_VER_11_T(txallfrm),
628 IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
629 IDX_IN_WL_CNT_VER_11_T(txctsfrm),
630 IDX_IN_WL_CNT_VER_11_T(txackfrm),
631 IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
632 IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
633 IDX_IN_WL_CNT_VER_11_T(txfunfl),
634 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
635 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
636 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
637 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
638 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
639 IDX_IN_WL_CNT_VER_11_T(txfbw),
640 IDX_IN_WL_CNT_VER_11_T(txmpdu),
641 IDX_IN_WL_CNT_VER_11_T(txtplunfl),
642 IDX_IN_WL_CNT_VER_11_T(txphyerror),
643 IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
644 IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
645 IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
646 IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
647 IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
648 IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
649 IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
650 IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
651 IDX_IN_WL_CNT_VER_11_T(rxstrt),
652 IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
653 IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
654 IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
655 IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
656 IDX_IN_WL_CNT_VER_11_T(rxctsucast),
657 IDX_IN_WL_CNT_VER_11_T(rxackucast),
658 IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
659 IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
660 IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
661 IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
662 IDX_IN_WL_CNT_VER_11_T(rxctsocast),
663 IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
664 IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
665 IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
666 IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
667 IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
668 IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
669 IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
670 IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
671 IDX_IN_WL_CNT_VER_11_T(rxnodelim),
672 IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
673 IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
674 IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
675 IDX_IN_WL_CNT_VER_11_T(txsfovfl),
676 IDX_IN_WL_CNT_VER_11_T(pmqovfl),
677 IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
678 IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
679 IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
680 IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
681 IDX_IN_WL_CNT_VER_11_T(prs_timeout),
682 IDX_IN_WL_CNT_VER_11_T(rxnack),
683 IDX_IN_WL_CNT_VER_11_T(frmscons),
684 IDX_IN_WL_CNT_VER_11_T(txnack),
685 IDX_IN_WL_CNT_VER_11_T(rxback),
686 IDX_IN_WL_CNT_VER_11_T(txback),
687 IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
688 IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
689 IDX_IN_WL_CNT_VER_11_T(rxtoolate),
690 IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)};
691
692 /* For mcst offsets that were not used. (2 Pads) */
693 #define INVALID_MCST_IDX ((uint8)(-1))
694 /* Index conversion table from wl_cnt_ver_11_t to wl_cnt_v_le10_mcst_t */
695 static const uint8 wlcntver11t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
696 IDX_IN_WL_CNT_VER_11_T(txallfrm),
697 IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
698 IDX_IN_WL_CNT_VER_11_T(txctsfrm),
699 IDX_IN_WL_CNT_VER_11_T(txackfrm),
700 IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
701 IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
702 IDX_IN_WL_CNT_VER_11_T(txfunfl),
703 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
704 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
705 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
706 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
707 IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
708 IDX_IN_WL_CNT_VER_11_T(txfbw),
709 INVALID_MCST_IDX,
710 IDX_IN_WL_CNT_VER_11_T(txtplunfl),
711 IDX_IN_WL_CNT_VER_11_T(txphyerror),
712 IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
713 IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
714 IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
715 IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
716 IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
717 IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
718 IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
719 IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
720 IDX_IN_WL_CNT_VER_11_T(rxstrt),
721 IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
722 IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
723 IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
724 IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
725 IDX_IN_WL_CNT_VER_11_T(rxctsucast),
726 IDX_IN_WL_CNT_VER_11_T(rxackucast),
727 IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
728 IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
729 IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
730 IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
731 IDX_IN_WL_CNT_VER_11_T(rxctsocast),
732 IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
733 IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
734 IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
735 IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
736 IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
737 IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
738 IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
739 IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
740 INVALID_MCST_IDX,
741 IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
742 IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
743 IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
744 IDX_IN_WL_CNT_VER_11_T(txsfovfl),
745 IDX_IN_WL_CNT_VER_11_T(pmqovfl),
746 IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
747 IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
748 IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
749 IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
750 IDX_IN_WL_CNT_VER_11_T(prs_timeout),
751 IDX_IN_WL_CNT_VER_11_T(rxnack),
752 IDX_IN_WL_CNT_VER_11_T(frmscons),
753 IDX_IN_WL_CNT_VER_11_T(txnack),
754 IDX_IN_WL_CNT_VER_11_T(rxback),
755 IDX_IN_WL_CNT_VER_11_T(txback),
756 IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
757 IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
758 IDX_IN_WL_CNT_VER_11_T(rxtoolate),
759 IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)};
760
761 /* Index conversion table from wl_cnt_ver_6_t to wl_cnt_v_le10_mcst_t */
762 static const uint8 wlcntver6t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
763 IDX_IN_WL_CNT_VER_6_T(txallfrm),
764 IDX_IN_WL_CNT_VER_6_T(txrtsfrm),
765 IDX_IN_WL_CNT_VER_6_T(txctsfrm),
766 IDX_IN_WL_CNT_VER_6_T(txackfrm),
767 IDX_IN_WL_CNT_VER_6_T(txdnlfrm),
768 IDX_IN_WL_CNT_VER_6_T(txbcnfrm),
769 IDX_IN_WL_CNT_VER_6_T(txfunfl),
770 IDX_IN_WL_CNT_VER_6_T(txfunfl) + 1,
771 IDX_IN_WL_CNT_VER_6_T(txfunfl) + 2,
772 IDX_IN_WL_CNT_VER_6_T(txfunfl) + 3,
773 IDX_IN_WL_CNT_VER_6_T(txfunfl) + 4,
774 IDX_IN_WL_CNT_VER_6_T(txfunfl) + 5,
775 IDX_IN_WL_CNT_VER_6_T(txfbw),
776 INVALID_MCST_IDX,
777 IDX_IN_WL_CNT_VER_6_T(txtplunfl),
778 IDX_IN_WL_CNT_VER_6_T(txphyerror),
779 IDX_IN_WL_CNT_VER_6_T(pktengrxducast),
780 IDX_IN_WL_CNT_VER_6_T(pktengrxdmcast),
781 IDX_IN_WL_CNT_VER_6_T(rxfrmtoolong),
782 IDX_IN_WL_CNT_VER_6_T(rxfrmtooshrt),
783 IDX_IN_WL_CNT_VER_6_T(rxinvmachdr),
784 IDX_IN_WL_CNT_VER_6_T(rxbadfcs),
785 IDX_IN_WL_CNT_VER_6_T(rxbadplcp),
786 IDX_IN_WL_CNT_VER_6_T(rxcrsglitch),
787 IDX_IN_WL_CNT_VER_6_T(rxstrt),
788 IDX_IN_WL_CNT_VER_6_T(rxdfrmucastmbss),
789 IDX_IN_WL_CNT_VER_6_T(rxmfrmucastmbss),
790 IDX_IN_WL_CNT_VER_6_T(rxcfrmucast),
791 IDX_IN_WL_CNT_VER_6_T(rxrtsucast),
792 IDX_IN_WL_CNT_VER_6_T(rxctsucast),
793 IDX_IN_WL_CNT_VER_6_T(rxackucast),
794 IDX_IN_WL_CNT_VER_6_T(rxdfrmocast),
795 IDX_IN_WL_CNT_VER_6_T(rxmfrmocast),
796 IDX_IN_WL_CNT_VER_6_T(rxcfrmocast),
797 IDX_IN_WL_CNT_VER_6_T(rxrtsocast),
798 IDX_IN_WL_CNT_VER_6_T(rxctsocast),
799 IDX_IN_WL_CNT_VER_6_T(rxdfrmmcast),
800 IDX_IN_WL_CNT_VER_6_T(rxmfrmmcast),
801 IDX_IN_WL_CNT_VER_6_T(rxcfrmmcast),
802 IDX_IN_WL_CNT_VER_6_T(rxbeaconmbss),
803 IDX_IN_WL_CNT_VER_6_T(rxdfrmucastobss),
804 IDX_IN_WL_CNT_VER_6_T(rxbeaconobss),
805 IDX_IN_WL_CNT_VER_6_T(rxrsptmout),
806 IDX_IN_WL_CNT_VER_6_T(bcntxcancl),
807 INVALID_MCST_IDX,
808 IDX_IN_WL_CNT_VER_6_T(rxf0ovfl),
809 IDX_IN_WL_CNT_VER_6_T(rxf1ovfl),
810 IDX_IN_WL_CNT_VER_6_T(rxf2ovfl),
811 IDX_IN_WL_CNT_VER_6_T(txsfovfl),
812 IDX_IN_WL_CNT_VER_6_T(pmqovfl),
813 IDX_IN_WL_CNT_VER_6_T(rxcgprqfrm),
814 IDX_IN_WL_CNT_VER_6_T(rxcgprsqovfl),
815 IDX_IN_WL_CNT_VER_6_T(txcgprsfail),
816 IDX_IN_WL_CNT_VER_6_T(txcgprssuc),
817 IDX_IN_WL_CNT_VER_6_T(prs_timeout),
818 IDX_IN_WL_CNT_VER_6_T(rxnack),
819 IDX_IN_WL_CNT_VER_6_T(frmscons),
820 IDX_IN_WL_CNT_VER_6_T(txnack),
821 IDX_IN_WL_CNT_VER_6_T(rxback),
822 IDX_IN_WL_CNT_VER_6_T(txback),
823 IDX_IN_WL_CNT_VER_6_T(bphy_rxcrsglitch),
824 IDX_IN_WL_CNT_VER_6_T(rxdrop20s),
825 IDX_IN_WL_CNT_VER_6_T(rxtoolate),
826 IDX_IN_WL_CNT_VER_6_T(bphy_badplcp)};
827
828 /* copy wlc layer counters from old type cntbuf to wl_cnt_wlc_t type. */
wl_copy_wlccnt(uint16 cntver,uint32 * dst,uint32 * src,uint8 src_max_idx)829 static int wl_copy_wlccnt(uint16 cntver, uint32 *dst, uint32 *src,
830 uint8 src_max_idx)
831 {
832 uint i;
833 if (dst == NULL || src == NULL) {
834 return BCME_ERROR;
835 }
836
837 /* Init wlccnt with invalid value. Unchanged value will not be printed out
838 */
839 for (i = 0; i < (sizeof(wl_cnt_wlc_t) / sizeof(uint32)); i++) {
840 dst[i] = INVALID_CNT_VAL;
841 }
842
843 if (cntver == WL_CNT_VERSION_6) {
844 for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T; i++) {
845 if (wlcntver6t_to_wlcntwlct[i] >= src_max_idx) {
846 /* src buffer does not have counters from here */
847 break;
848 }
849 dst[i] = src[wlcntver6t_to_wlcntwlct[i]];
850 }
851 } else {
852 for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T; i++) {
853 if (wlcntver11t_to_wlcntwlct[i] >= src_max_idx) {
854 if (wlcntver11t_to_wlcntwlct[i] == INVALID_IDX) {
855 continue;
856 } else {
857 /* src buffer does not have counters from here */
858 break;
859 }
860 }
861 dst[i] = src[wlcntver11t_to_wlcntwlct[i]];
862 }
863 }
864 return BCME_OK;
865 }
866
867 /* copy macstat counters from old type cntbuf to wl_cnt_v_le10_mcst_t type. */
wl_copy_macstat_upto_ver10(uint16 cntver,uint32 * dst,uint32 * src)868 static int wl_copy_macstat_upto_ver10(uint16 cntver, uint32 *dst, uint32 *src)
869 {
870 uint i;
871
872 if (dst == NULL || src == NULL) {
873 return BCME_ERROR;
874 }
875
876 if (cntver == WL_CNT_VERSION_6) {
877 for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
878 if (wlcntver6t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
879 /* This mcst counter does not exist in wl_cnt_ver_6_t */
880 dst[i] = INVALID_CNT_VAL;
881 } else {
882 dst[i] = src[wlcntver6t_to_wlcntvle10mcstt[i]];
883 }
884 }
885 } else {
886 for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
887 if (wlcntver11t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
888 /* This mcst counter does not exist in wl_cnt_ver_11_t */
889 dst[i] = INVALID_CNT_VAL;
890 } else {
891 dst[i] = src[wlcntver11t_to_wlcntvle10mcstt[i]];
892 }
893 }
894 }
895 return BCME_OK;
896 }
897
wl_copy_macstat_ver11(uint32 * dst,uint32 * src)898 static int wl_copy_macstat_ver11(uint32 *dst, uint32 *src)
899 {
900 uint i;
901
902 if (dst == NULL || src == NULL) {
903 return BCME_ERROR;
904 }
905
906 for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
907 dst[i] = src[wlcntver11t_to_wlcntXX40mcstv1t[i]];
908 }
909 return BCME_OK;
910 }
911
912 /**
913 * Translate non-xtlv 'wl counters' IOVar buffer received by old driver/FW to
914 * xtlv format. Parameters: cntbuf: pointer to non-xtlv 'wl counters' IOVar
915 * buffer received by old driver/FW. Newly translated xtlv format is written to
916 * this pointer. buflen: length of the "cntbuf" without any padding. corerev:
917 * chip core revision of the driver/FW.
918 */
wl_cntbuf_to_xtlv_format(void * ctx,void * cntbuf,int buflen,uint32 corerev)919 int wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen,
920 uint32 corerev)
921 {
922 wl_cnt_wlc_t *wlccnt = NULL;
923 uint32 *macstat = NULL;
924 xtlv_desc_t xtlv_desc[3];
925 uint16 mcst_xtlv_id;
926 int res = BCME_OK;
927 wl_cnt_info_t *cntinfo = cntbuf;
928 uint8 *xtlvbuf_p = cntinfo->data;
929 uint16 ver = cntinfo->version;
930 uint16 xtlvbuflen = (uint16)buflen;
931 uint16 src_max_idx;
932 #ifdef BCMDRIVER
933 osl_t *osh = ctx;
934 #else
935 BCM_REFERENCE(ctx);
936 #endif // endif
937
938 if (ver >= WL_CNT_VERSION_XTLV) {
939 /* Already in xtlv format. */
940 goto exit;
941 }
942
943 #ifdef BCMDRIVER
944 wlccnt = MALLOC(osh, sizeof(*wlccnt));
945 macstat = MALLOC(osh, WL_CNT_MCST_STRUCT_SZ);
946 #else
947 wlccnt = (wl_cnt_wlc_t *)malloc(sizeof(*wlccnt));
948 macstat = (uint32 *)malloc(WL_CNT_MCST_STRUCT_SZ);
949 #endif // endif
950 if (!wlccnt || !macstat) {
951 printf("%s: malloc fail!\n", __FUNCTION__);
952 res = BCME_NOMEM;
953 goto exit;
954 }
955
956 /* Check if the max idx in the struct exceeds the boundary of uint8 */
957 if (NUM_OF_CNT_IN_WL_CNT_VER_6_T > ((uint8)(-1) + 1) ||
958 NUM_OF_CNT_IN_WL_CNT_VER_11_T > ((uint8)(-1) + 1)) {
959 printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
960 " to be of uint16 instead of uint8\n");
961 res = BCME_ERROR;
962 goto exit;
963 }
964
965 /* Exclude version and length fields in either wlc_cnt_ver_6_t or
966 * wlc_cnt_ver_11_t */
967 src_max_idx =
968 (cntinfo->datalen - OFFSETOF(wl_cnt_info_t, data)) / sizeof(uint32);
969 if (src_max_idx > (uint8)(-1)) {
970 printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
971 " to be of uint16 instead of uint8\n"
972 "Try updating wl utility to the latest.\n");
973 src_max_idx = (uint8)(-1);
974 }
975
976 /* Copy wlc layer counters to wl_cnt_wlc_t */
977 res = wl_copy_wlccnt(ver, (uint32 *)wlccnt, (uint32 *)cntinfo->data,
978 (uint8)src_max_idx);
979 if (res != BCME_OK) {
980 printf("wl_copy_wlccnt fail!\n");
981 goto exit;
982 }
983
984 /* Copy macstat counters to wl_cnt_wlc_t */
985 if (ver == WL_CNT_VERSION_11) {
986 res = wl_copy_macstat_ver11(macstat, (uint32 *)cntinfo->data);
987 if (res != BCME_OK) {
988 printf("wl_copy_macstat_ver11 fail!\n");
989 goto exit;
990 }
991 if (corerev >= 0x28) {
992 mcst_xtlv_id = WL_CNT_XTLV_GE40_UCODE_V1;
993 } else {
994 mcst_xtlv_id = WL_CNT_XTLV_LT40_UCODE_V1;
995 }
996 } else {
997 res = wl_copy_macstat_upto_ver10(ver, macstat, (uint32 *)cntinfo->data);
998 if (res != BCME_OK) {
999 printf("wl_copy_macstat_upto_ver10 fail!\n");
1000 goto exit;
1001 }
1002 mcst_xtlv_id = WL_CNT_XTLV_CNTV_LE10_UCODE;
1003 }
1004
1005 xtlv_desc[0].type = WL_CNT_XTLV_WLC;
1006 xtlv_desc[0].len = sizeof(*wlccnt);
1007 xtlv_desc[0].ptr = wlccnt;
1008
1009 xtlv_desc[1].type = mcst_xtlv_id;
1010 xtlv_desc[1].len = WL_CNT_MCST_STRUCT_SZ;
1011 xtlv_desc[1].ptr = macstat;
1012
1013 xtlv_desc[0x2].type = 0;
1014 xtlv_desc[0x2].len = 0;
1015 xtlv_desc[0x2].ptr = NULL;
1016
1017 memset(cntbuf, 0, buflen);
1018
1019 res = bcm_pack_xtlv_buf_from_mem(&xtlvbuf_p, &xtlvbuflen, xtlv_desc,
1020 BCM_XTLV_OPTION_ALIGN32);
1021 cntinfo->datalen = (buflen - xtlvbuflen);
1022 exit:
1023 #ifdef BCMDRIVER
1024 if (wlccnt) {
1025 MFREE(osh, wlccnt, sizeof(*wlccnt));
1026 }
1027 if (macstat) {
1028 MFREE(osh, macstat, WL_CNT_MCST_STRUCT_SZ);
1029 }
1030 #else
1031 if (wlccnt) {
1032 free(wlccnt);
1033 }
1034 if (macstat) {
1035 free(macstat);
1036 }
1037 #endif // endif
1038 return res;
1039 }
1040