xref: /openbmc/linux/net/wireless/util.c (revision b04b4f78)
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