1 /* 2 * Wireless utility functions 3 * 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 */ 6 #include <net/wireless.h> 7 #include <asm/bitops.h> 8 #include "core.h" 9 10 struct ieee80211_rate * 11 ieee80211_get_response_rate(struct ieee80211_supported_band *sband, 12 u32 basic_rates, int bitrate) 13 { 14 struct ieee80211_rate *result = &sband->bitrates[0]; 15 int i; 16 17 for (i = 0; i < sband->n_bitrates; i++) { 18 if (!(basic_rates & BIT(i))) 19 continue; 20 if (sband->bitrates[i].bitrate > bitrate) 21 continue; 22 result = &sband->bitrates[i]; 23 } 24 25 return result; 26 } 27 EXPORT_SYMBOL(ieee80211_get_response_rate); 28 29 int ieee80211_channel_to_frequency(int chan) 30 { 31 if (chan < 14) 32 return 2407 + chan * 5; 33 34 if (chan == 14) 35 return 2484; 36 37 /* FIXME: 802.11j 17.3.8.3.2 */ 38 return (chan + 1000) * 5; 39 } 40 EXPORT_SYMBOL(ieee80211_channel_to_frequency); 41 42 int ieee80211_frequency_to_channel(int freq) 43 { 44 if (freq == 2484) 45 return 14; 46 47 if (freq < 2484) 48 return (freq - 2407) / 5; 49 50 /* FIXME: 802.11j 17.3.8.3.2 */ 51 return freq/5 - 1000; 52 } 53 EXPORT_SYMBOL(ieee80211_frequency_to_channel); 54 55 struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, 56 int freq) 57 { 58 enum ieee80211_band band; 59 struct ieee80211_supported_band *sband; 60 int i; 61 62 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 63 sband = wiphy->bands[band]; 64 65 if (!sband) 66 continue; 67 68 for (i = 0; i < sband->n_channels; i++) { 69 if (sband->channels[i].center_freq == freq) 70 return &sband->channels[i]; 71 } 72 } 73 74 return NULL; 75 } 76 EXPORT_SYMBOL(__ieee80211_get_channel); 77 78 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband, 79 enum ieee80211_band band) 80 { 81 int i, want; 82 83 switch (band) { 84 case IEEE80211_BAND_5GHZ: 85 want = 3; 86 for (i = 0; i < sband->n_bitrates; i++) { 87 if (sband->bitrates[i].bitrate == 60 || 88 sband->bitrates[i].bitrate == 120 || 89 sband->bitrates[i].bitrate == 240) { 90 sband->bitrates[i].flags |= 91 IEEE80211_RATE_MANDATORY_A; 92 want--; 93 } 94 } 95 WARN_ON(want); 96 break; 97 case IEEE80211_BAND_2GHZ: 98 want = 7; 99 for (i = 0; i < sband->n_bitrates; i++) { 100 if (sband->bitrates[i].bitrate == 10) { 101 sband->bitrates[i].flags |= 102 IEEE80211_RATE_MANDATORY_B | 103 IEEE80211_RATE_MANDATORY_G; 104 want--; 105 } 106 107 if (sband->bitrates[i].bitrate == 20 || 108 sband->bitrates[i].bitrate == 55 || 109 sband->bitrates[i].bitrate == 110 || 110 sband->bitrates[i].bitrate == 60 || 111 sband->bitrates[i].bitrate == 120 || 112 sband->bitrates[i].bitrate == 240) { 113 sband->bitrates[i].flags |= 114 IEEE80211_RATE_MANDATORY_G; 115 want--; 116 } 117 118 if (sband->bitrates[i].bitrate != 10 && 119 sband->bitrates[i].bitrate != 20 && 120 sband->bitrates[i].bitrate != 55 && 121 sband->bitrates[i].bitrate != 110) 122 sband->bitrates[i].flags |= 123 IEEE80211_RATE_ERP_G; 124 } 125 WARN_ON(want != 0 && want != 3 && want != 6); 126 break; 127 case IEEE80211_NUM_BANDS: 128 WARN_ON(1); 129 break; 130 } 131 } 132 133 void ieee80211_set_bitrate_flags(struct wiphy *wiphy) 134 { 135 enum ieee80211_band band; 136 137 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 138 if (wiphy->bands[band]) 139 set_mandatory_flags_band(wiphy->bands[band], band); 140 } 141