util.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Wireless utility functions
  3. *
  4. * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
  5. */
  6. #include <linux/bitops.h>
  7. #include <net/cfg80211.h>
  8. #include "core.h"
  9. struct ieee80211_rate *
  10. ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
  11. u32 basic_rates, int bitrate)
  12. {
  13. struct ieee80211_rate *result = &sband->bitrates[0];
  14. int i;
  15. for (i = 0; i < sband->n_bitrates; i++) {
  16. if (!(basic_rates & BIT(i)))
  17. continue;
  18. if (sband->bitrates[i].bitrate > bitrate)
  19. continue;
  20. result = &sband->bitrates[i];
  21. }
  22. return result;
  23. }
  24. EXPORT_SYMBOL(ieee80211_get_response_rate);
  25. int ieee80211_channel_to_frequency(int chan)
  26. {
  27. if (chan < 14)
  28. return 2407 + chan * 5;
  29. if (chan == 14)
  30. return 2484;
  31. /* FIXME: 802.11j 17.3.8.3.2 */
  32. return (chan + 1000) * 5;
  33. }
  34. EXPORT_SYMBOL(ieee80211_channel_to_frequency);
  35. int ieee80211_frequency_to_channel(int freq)
  36. {
  37. if (freq == 2484)
  38. return 14;
  39. if (freq < 2484)
  40. return (freq - 2407) / 5;
  41. /* FIXME: 802.11j 17.3.8.3.2 */
  42. return freq/5 - 1000;
  43. }
  44. EXPORT_SYMBOL(ieee80211_frequency_to_channel);
  45. struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
  46. int freq)
  47. {
  48. enum ieee80211_band band;
  49. struct ieee80211_supported_band *sband;
  50. int i;
  51. for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
  52. sband = wiphy->bands[band];
  53. if (!sband)
  54. continue;
  55. for (i = 0; i < sband->n_channels; i++) {
  56. if (sband->channels[i].center_freq == freq)
  57. return &sband->channels[i];
  58. }
  59. }
  60. return NULL;
  61. }
  62. EXPORT_SYMBOL(__ieee80211_get_channel);
  63. static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
  64. enum ieee80211_band band)
  65. {
  66. int i, want;
  67. switch (band) {
  68. case IEEE80211_BAND_5GHZ:
  69. want = 3;
  70. for (i = 0; i < sband->n_bitrates; i++) {
  71. if (sband->bitrates[i].bitrate == 60 ||
  72. sband->bitrates[i].bitrate == 120 ||
  73. sband->bitrates[i].bitrate == 240) {
  74. sband->bitrates[i].flags |=
  75. IEEE80211_RATE_MANDATORY_A;
  76. want--;
  77. }
  78. }
  79. WARN_ON(want);
  80. break;
  81. case IEEE80211_BAND_2GHZ:
  82. want = 7;
  83. for (i = 0; i < sband->n_bitrates; i++) {
  84. if (sband->bitrates[i].bitrate == 10) {
  85. sband->bitrates[i].flags |=
  86. IEEE80211_RATE_MANDATORY_B |
  87. IEEE80211_RATE_MANDATORY_G;
  88. want--;
  89. }
  90. if (sband->bitrates[i].bitrate == 20 ||
  91. sband->bitrates[i].bitrate == 55 ||
  92. sband->bitrates[i].bitrate == 110 ||
  93. sband->bitrates[i].bitrate == 60 ||
  94. sband->bitrates[i].bitrate == 120 ||
  95. sband->bitrates[i].bitrate == 240) {
  96. sband->bitrates[i].flags |=
  97. IEEE80211_RATE_MANDATORY_G;
  98. want--;
  99. }
  100. if (sband->bitrates[i].bitrate != 10 &&
  101. sband->bitrates[i].bitrate != 20 &&
  102. sband->bitrates[i].bitrate != 55 &&
  103. sband->bitrates[i].bitrate != 110)
  104. sband->bitrates[i].flags |=
  105. IEEE80211_RATE_ERP_G;
  106. }
  107. WARN_ON(want != 0 && want != 3 && want != 6);
  108. break;
  109. case IEEE80211_NUM_BANDS:
  110. WARN_ON(1);
  111. break;
  112. }
  113. }
  114. void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
  115. {
  116. enum ieee80211_band band;
  117. for (band = 0; band < IEEE80211_NUM_BANDS; band++)
  118. if (wiphy->bands[band])
  119. set_mandatory_flags_band(wiphy->bands[band], band);
  120. }
  121. int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
  122. const u8 *mac_addr)
  123. {
  124. if (key_idx > 5)
  125. return -EINVAL;
  126. /*
  127. * Disallow pairwise keys with non-zero index unless it's WEP
  128. * (because current deployments use pairwise WEP keys with
  129. * non-zero indizes but 802.11i clearly specifies to use zero)
  130. */
  131. if (mac_addr && key_idx &&
  132. params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
  133. params->cipher != WLAN_CIPHER_SUITE_WEP104)
  134. return -EINVAL;
  135. /* TODO: add definitions for the lengths to linux/ieee80211.h */
  136. switch (params->cipher) {
  137. case WLAN_CIPHER_SUITE_WEP40:
  138. if (params->key_len != 5)
  139. return -EINVAL;
  140. break;
  141. case WLAN_CIPHER_SUITE_TKIP:
  142. if (params->key_len != 32)
  143. return -EINVAL;
  144. break;
  145. case WLAN_CIPHER_SUITE_CCMP:
  146. if (params->key_len != 16)
  147. return -EINVAL;
  148. break;
  149. case WLAN_CIPHER_SUITE_WEP104:
  150. if (params->key_len != 13)
  151. return -EINVAL;
  152. break;
  153. case WLAN_CIPHER_SUITE_AES_CMAC:
  154. if (params->key_len != 16)
  155. return -EINVAL;
  156. break;
  157. default:
  158. return -EINVAL;
  159. }
  160. return 0;
  161. }