Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libipw_geo.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright(c) 2005 Intel Corporation. All rights reserved.
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of version 2 of the GNU General Public License as
7  published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  more details.
13 
14  You should have received a copy of the GNU General Public License along with
15  this program; if not, write to the Free Software Foundation, Inc., 59
16  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18  The full GNU General Public License is included in this distribution in the
19  file called LICENSE.
20 
21  Contact Information:
22  Intel Linux Wireless <[email protected]>
23  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 
25 ******************************************************************************/
26 #include <linux/compiler.h>
27 #include <linux/errno.h>
28 #include <linux/if_arp.h>
29 #include <linux/in6.h>
30 #include <linux/in.h>
31 #include <linux/ip.h>
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/netdevice.h>
35 #include <linux/proc_fs.h>
36 #include <linux/skbuff.h>
37 #include <linux/tcp.h>
38 #include <linux/types.h>
39 #include <linux/wireless.h>
40 #include <linux/etherdevice.h>
41 #include <asm/uaccess.h>
42 
43 #include "libipw.h"
44 
46 {
47  int i;
48 
49  /* Driver needs to initialize the geography map before using
50  * these helper functions */
51  if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
52  return 0;
53 
54  if (ieee->freq_band & LIBIPW_24GHZ_BAND)
55  for (i = 0; i < ieee->geo.bg_channels; i++)
56  /* NOTE: If G mode is currently supported but
57  * this is a B only channel, we don't see it
58  * as valid. */
59  if ((ieee->geo.bg[i].channel == channel) &&
60  !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) &&
61  (!(ieee->mode & IEEE_G) ||
62  !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY)))
63  return LIBIPW_24GHZ_BAND;
64 
65  if (ieee->freq_band & LIBIPW_52GHZ_BAND)
66  for (i = 0; i < ieee->geo.a_channels; i++)
67  if ((ieee->geo.a[i].channel == channel) &&
68  !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID))
69  return LIBIPW_52GHZ_BAND;
70 
71  return 0;
72 }
73 
75 {
76  int i;
77 
78  /* Driver needs to initialize the geography map before using
79  * these helper functions */
80  if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
81  return -1;
82 
83  if (ieee->freq_band & LIBIPW_24GHZ_BAND)
84  for (i = 0; i < ieee->geo.bg_channels; i++)
85  if (ieee->geo.bg[i].channel == channel)
86  return i;
87 
88  if (ieee->freq_band & LIBIPW_52GHZ_BAND)
89  for (i = 0; i < ieee->geo.a_channels; i++)
90  if (ieee->geo.a[i].channel == channel)
91  return i;
92 
93  return -1;
94 }
95 
97 {
98  const struct libipw_channel * ch;
99 
100  /* Driver needs to initialize the geography map before using
101  * these helper functions */
102  if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
103  return 0;
104 
105  ch = libipw_get_channel(ieee, channel);
106  if (!ch->channel)
107  return 0;
108  return ch->freq;
109 }
110 
112 {
113  int i;
114 
115  /* Driver needs to initialize the geography map before using
116  * these helper functions */
117  if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
118  return 0;
119 
120  freq /= 100000;
121 
122  if (ieee->freq_band & LIBIPW_24GHZ_BAND)
123  for (i = 0; i < ieee->geo.bg_channels; i++)
124  if (ieee->geo.bg[i].freq == freq)
125  return ieee->geo.bg[i].channel;
126 
127  if (ieee->freq_band & LIBIPW_52GHZ_BAND)
128  for (i = 0; i < ieee->geo.a_channels; i++)
129  if (ieee->geo.a[i].freq == freq)
130  return ieee->geo.a[i].channel;
131 
132  return 0;
133 }
134 
135 int libipw_set_geo(struct libipw_device *ieee,
136  const struct libipw_geo *geo)
137 {
138  memcpy(ieee->geo.name, geo->name, 3);
139  ieee->geo.name[3] = '\0';
140  ieee->geo.bg_channels = geo->bg_channels;
141  ieee->geo.a_channels = geo->a_channels;
142  memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
143  sizeof(struct libipw_channel));
144  memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
145  sizeof(struct libipw_channel));
146  return 0;
147 }
148 
149 const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee)
150 {
151  return &ieee->geo;
152 }
153 
155 {
156  int index = libipw_channel_to_index(ieee, channel);
157 
158  if (index == -1)
159  return LIBIPW_CH_INVALID;
160 
161  if (channel <= LIBIPW_24GHZ_CHANNELS)
162  return ieee->geo.bg[index].flags;
163 
164  return ieee->geo.a[index].flags;
165 }
166 
167 static const struct libipw_channel bad_channel = {
168  .channel = 0,
169  .flags = LIBIPW_CH_INVALID,
170  .max_power = 0,
171 };
172 
174  *ieee, u8 channel)
175 {
176  int index = libipw_channel_to_index(ieee, channel);
177 
178  if (index == -1)
179  return &bad_channel;
180 
181  if (channel <= LIBIPW_24GHZ_CHANNELS)
182  return &ieee->geo.bg[index];
183 
184  return &ieee->geo.a[index];
185 }
186