bcm_app_utils.c 34 KB

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