xref: /linux/net/wireless/util.c (revision 8fa5723aa7e053d498336b48448b292fc2e0458b)
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 int ieee80211_channel_to_frequency(int chan)
11 {
12 	if (chan < 14)
13 		return 2407 + chan * 5;
14 
15 	if (chan == 14)
16 		return 2484;
17 
18 	/* FIXME: 802.11j 17.3.8.3.2 */
19 	return (chan + 1000) * 5;
20 }
21 EXPORT_SYMBOL(ieee80211_channel_to_frequency);
22 
23 int ieee80211_frequency_to_channel(int freq)
24 {
25 	if (freq == 2484)
26 		return 14;
27 
28 	if (freq < 2484)
29 		return (freq - 2407) / 5;
30 
31 	/* FIXME: 802.11j 17.3.8.3.2 */
32 	return freq/5 - 1000;
33 }
34 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
35 
36 struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
37 						  int freq)
38 {
39 	enum ieee80211_band band;
40 	struct ieee80211_supported_band *sband;
41 	int i;
42 
43 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
44 		sband = wiphy->bands[band];
45 
46 		if (!sband)
47 			continue;
48 
49 		for (i = 0; i < sband->n_channels; i++) {
50 			if (sband->channels[i].center_freq == freq)
51 				return &sband->channels[i];
52 		}
53 	}
54 
55 	return NULL;
56 }
57 EXPORT_SYMBOL(__ieee80211_get_channel);
58 
59 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
60 				     enum ieee80211_band band)
61 {
62 	int i, want;
63 
64 	switch (band) {
65 	case IEEE80211_BAND_5GHZ:
66 		want = 3;
67 		for (i = 0; i < sband->n_bitrates; i++) {
68 			if (sband->bitrates[i].bitrate == 60 ||
69 			    sband->bitrates[i].bitrate == 120 ||
70 			    sband->bitrates[i].bitrate == 240) {
71 				sband->bitrates[i].flags |=
72 					IEEE80211_RATE_MANDATORY_A;
73 				want--;
74 			}
75 		}
76 		WARN_ON(want);
77 		break;
78 	case IEEE80211_BAND_2GHZ:
79 		want = 7;
80 		for (i = 0; i < sband->n_bitrates; i++) {
81 			if (sband->bitrates[i].bitrate == 10) {
82 				sband->bitrates[i].flags |=
83 					IEEE80211_RATE_MANDATORY_B |
84 					IEEE80211_RATE_MANDATORY_G;
85 				want--;
86 			}
87 
88 			if (sband->bitrates[i].bitrate == 20 ||
89 			    sband->bitrates[i].bitrate == 55 ||
90 			    sband->bitrates[i].bitrate == 110 ||
91 			    sband->bitrates[i].bitrate == 60 ||
92 			    sband->bitrates[i].bitrate == 120 ||
93 			    sband->bitrates[i].bitrate == 240) {
94 				sband->bitrates[i].flags |=
95 					IEEE80211_RATE_MANDATORY_G;
96 				want--;
97 			}
98 
99 			if (sband->bitrates[i].bitrate != 10 &&
100 			    sband->bitrates[i].bitrate != 20 &&
101 			    sband->bitrates[i].bitrate != 55 &&
102 			    sband->bitrates[i].bitrate != 110)
103 				sband->bitrates[i].flags |=
104 					IEEE80211_RATE_ERP_G;
105 		}
106 		WARN_ON(want != 0 && want != 3 && want != 6);
107 		break;
108 	case IEEE80211_NUM_BANDS:
109 		WARN_ON(1);
110 		break;
111 	}
112 }
113 
114 void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
115 {
116 	enum ieee80211_band band;
117 
118 	for (band = 0; band < IEEE80211_NUM_BANDS; band++)
119 		if (wiphy->bands[band])
120 			set_mandatory_flags_band(wiphy->bands[band], band);
121 }
122