123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /*
- * Wireless utility functions
- *
- * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
- */
- #include <linux/bitops.h>
- #include <net/cfg80211.h>
- #include "core.h"
- struct ieee80211_rate *
- ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
- u32 basic_rates, int bitrate)
- {
- struct ieee80211_rate *result = &sband->bitrates[0];
- int i;
- for (i = 0; i < sband->n_bitrates; i++) {
- if (!(basic_rates & BIT(i)))
- continue;
- if (sband->bitrates[i].bitrate > bitrate)
- continue;
- result = &sband->bitrates[i];
- }
- return result;
- }
- EXPORT_SYMBOL(ieee80211_get_response_rate);
- int ieee80211_channel_to_frequency(int chan)
- {
- if (chan < 14)
- return 2407 + chan * 5;
- if (chan == 14)
- return 2484;
- /* FIXME: 802.11j 17.3.8.3.2 */
- return (chan + 1000) * 5;
- }
- EXPORT_SYMBOL(ieee80211_channel_to_frequency);
- int ieee80211_frequency_to_channel(int freq)
- {
- if (freq == 2484)
- return 14;
- if (freq < 2484)
- return (freq - 2407) / 5;
- /* FIXME: 802.11j 17.3.8.3.2 */
- return freq/5 - 1000;
- }
- EXPORT_SYMBOL(ieee80211_frequency_to_channel);
- struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
- int freq)
- {
- enum ieee80211_band band;
- struct ieee80211_supported_band *sband;
- int i;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
- sband = wiphy->bands[band];
- if (!sband)
- continue;
- for (i = 0; i < sband->n_channels; i++) {
- if (sband->channels[i].center_freq == freq)
- return &sband->channels[i];
- }
- }
- return NULL;
- }
- EXPORT_SYMBOL(__ieee80211_get_channel);
- static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
- enum ieee80211_band band)
- {
- int i, want;
- switch (band) {
- case IEEE80211_BAND_5GHZ:
- want = 3;
- for (i = 0; i < sband->n_bitrates; i++) {
- if (sband->bitrates[i].bitrate == 60 ||
- sband->bitrates[i].bitrate == 120 ||
- sband->bitrates[i].bitrate == 240) {
- sband->bitrates[i].flags |=
- IEEE80211_RATE_MANDATORY_A;
- want--;
- }
- }
- WARN_ON(want);
- break;
- case IEEE80211_BAND_2GHZ:
- want = 7;
- for (i = 0; i < sband->n_bitrates; i++) {
- if (sband->bitrates[i].bitrate == 10) {
- sband->bitrates[i].flags |=
- IEEE80211_RATE_MANDATORY_B |
- IEEE80211_RATE_MANDATORY_G;
- want--;
- }
- if (sband->bitrates[i].bitrate == 20 ||
- sband->bitrates[i].bitrate == 55 ||
- sband->bitrates[i].bitrate == 110 ||
- sband->bitrates[i].bitrate == 60 ||
- sband->bitrates[i].bitrate == 120 ||
- sband->bitrates[i].bitrate == 240) {
- sband->bitrates[i].flags |=
- IEEE80211_RATE_MANDATORY_G;
- want--;
- }
- if (sband->bitrates[i].bitrate != 10 &&
- sband->bitrates[i].bitrate != 20 &&
- sband->bitrates[i].bitrate != 55 &&
- sband->bitrates[i].bitrate != 110)
- sband->bitrates[i].flags |=
- IEEE80211_RATE_ERP_G;
- }
- WARN_ON(want != 0 && want != 3 && want != 6);
- break;
- case IEEE80211_NUM_BANDS:
- WARN_ON(1);
- break;
- }
- }
- void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
- {
- enum ieee80211_band band;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
- if (wiphy->bands[band])
- set_mandatory_flags_band(wiphy->bands[band], band);
- }
- int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
- const u8 *mac_addr)
- {
- if (key_idx > 5)
- return -EINVAL;
- /*
- * Disallow pairwise keys with non-zero index unless it's WEP
- * (because current deployments use pairwise WEP keys with
- * non-zero indizes but 802.11i clearly specifies to use zero)
- */
- if (mac_addr && key_idx &&
- params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
- params->cipher != WLAN_CIPHER_SUITE_WEP104)
- return -EINVAL;
- /* TODO: add definitions for the lengths to linux/ieee80211.h */
- switch (params->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- if (params->key_len != 5)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- if (params->key_len != 32)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- if (params->key_len != 16)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- if (params->key_len != 13)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- if (params->key_len != 16)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
|