bcmwifi.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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-2010, 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. * $Id: bcmwifi.c,v 1.18.24.2.4.1 2009/09/25 00:32:01 Exp $
  26. */
  27. #include <typedefs.h>
  28. #ifdef BCMDRIVER
  29. #include <osl.h>
  30. #include <bcmutils.h>
  31. #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
  32. #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
  33. #else
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <ctype.h>
  37. #endif
  38. #include <bcmwifi.h>
  39. #if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
  40. #include <bcmstdlib.h>
  41. #endif
  42. char *
  43. wf_chspec_ntoa(chanspec_t chspec, char *buf)
  44. {
  45. const char *band, *bw, *sb;
  46. uint channel;
  47. band = "";
  48. bw = "";
  49. sb = "";
  50. channel = CHSPEC_CHANNEL(chspec);
  51. if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) ||
  52. (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL))
  53. band = (CHSPEC_IS2G(chspec)) ? "b" : "a";
  54. if (CHSPEC_IS40(chspec)) {
  55. if (CHSPEC_SB_UPPER(chspec)) {
  56. sb = "u";
  57. channel += CH_10MHZ_APART;
  58. } else {
  59. sb = "l";
  60. channel -= CH_10MHZ_APART;
  61. }
  62. } else if (CHSPEC_IS10(chspec)) {
  63. bw = "n";
  64. }
  65. snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb);
  66. return (buf);
  67. }
  68. chanspec_t
  69. wf_chspec_aton(char *a)
  70. {
  71. char *endp = NULL;
  72. uint channel, band, bw, ctl_sb;
  73. char c;
  74. channel = strtoul(a, &endp, 10);
  75. if (endp == a)
  76. return 0;
  77. if (channel > MAXCHANNEL)
  78. return 0;
  79. band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
  80. bw = WL_CHANSPEC_BW_20;
  81. ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
  82. a = endp;
  83. c = tolower(a[0]);
  84. if (c == '\0')
  85. goto done;
  86. if (c == 'a' || c == 'b') {
  87. band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;
  88. a++;
  89. c = tolower(a[0]);
  90. if (c == '\0')
  91. goto done;
  92. }
  93. if (c == 'n') {
  94. bw = WL_CHANSPEC_BW_10;
  95. } else if (c == 'l') {
  96. bw = WL_CHANSPEC_BW_40;
  97. ctl_sb = WL_CHANSPEC_CTL_SB_LOWER;
  98. if (channel <= (MAXCHANNEL - CH_20MHZ_APART))
  99. channel += CH_10MHZ_APART;
  100. else
  101. return 0;
  102. } else if (c == 'u') {
  103. bw = WL_CHANSPEC_BW_40;
  104. ctl_sb = WL_CHANSPEC_CTL_SB_UPPER;
  105. if (channel > CH_20MHZ_APART)
  106. channel -= CH_10MHZ_APART;
  107. else
  108. return 0;
  109. } else {
  110. return 0;
  111. }
  112. done:
  113. return (channel | band | bw | ctl_sb);
  114. }
  115. int
  116. wf_mhz2channel(uint freq, uint start_factor)
  117. {
  118. int ch = -1;
  119. uint base;
  120. int offset;
  121. if (start_factor == 0) {
  122. if (freq >= 2400 && freq <= 2500)
  123. start_factor = WF_CHAN_FACTOR_2_4_G;
  124. else if (freq >= 5000 && freq <= 6000)
  125. start_factor = WF_CHAN_FACTOR_5_G;
  126. }
  127. if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
  128. return 14;
  129. base = start_factor / 2;
  130. if ((freq < base) || (freq > base + 1000))
  131. return -1;
  132. offset = freq - base;
  133. ch = offset / 5;
  134. if (offset != (ch * 5))
  135. return -1;
  136. if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
  137. return -1;
  138. return ch;
  139. }
  140. int
  141. wf_channel2mhz(uint ch, uint start_factor)
  142. {
  143. int freq;
  144. if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
  145. (ch <= 200))
  146. freq = -1;
  147. if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14))
  148. freq = 2484;
  149. else
  150. freq = ch * 5 + start_factor / 2;
  151. return freq;
  152. }