aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2x00/libipw_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ipw2x00/libipw_module.c')
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c124
1 files changed, 80 insertions, 44 deletions
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 8ce6e961c5da..a0e9f6aed7da 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -25,7 +25,7 @@
25 file called LICENSE. 25 file called LICENSE.
26 26
27 Contact Information: 27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com> 28 Intel Linux Wireless <ilw@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 30
31*******************************************************************************/ 31*******************************************************************************/
@@ -50,11 +50,11 @@
50#include <net/net_namespace.h> 50#include <net/net_namespace.h>
51#include <net/arp.h> 51#include <net/arp.h>
52 52
53#include "ieee80211.h" 53#include "libipw.h"
54 54
55#define DRV_DESCRIPTION "802.11 data/management/control stack" 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
56#define DRV_NAME "ieee80211" 56#define DRV_NAME "ieee80211"
57#define DRV_VERSION IEEE80211_VERSION 57#define DRV_VERSION LIBIPW_VERSION
58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" 58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
59 59
60MODULE_VERSION(DRV_VERSION); 60MODULE_VERSION(DRV_VERSION);
@@ -62,13 +62,16 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
62MODULE_AUTHOR(DRV_COPYRIGHT); 62MODULE_AUTHOR(DRV_COPYRIGHT);
63MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
64 64
65static int ieee80211_networks_allocate(struct ieee80211_device *ieee) 65struct cfg80211_ops libipw_config_ops = { };
66void *libipw_wiphy_privid = &libipw_wiphy_privid;
67
68static int libipw_networks_allocate(struct libipw_device *ieee)
66{ 69{
67 if (ieee->networks) 70 if (ieee->networks)
68 return 0; 71 return 0;
69 72
70 ieee->networks = 73 ieee->networks =
71 kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), 74 kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
72 GFP_KERNEL); 75 GFP_KERNEL);
73 if (!ieee->networks) { 76 if (!ieee->networks) {
74 printk(KERN_WARNING "%s: Out of memory allocating beacons\n", 77 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
@@ -79,7 +82,7 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
79 return 0; 82 return 0;
80} 83}
81 84
82void ieee80211_network_reset(struct ieee80211_network *network) 85void libipw_network_reset(struct libipw_network *network)
83{ 86{
84 if (!network) 87 if (!network)
85 return; 88 return;
@@ -90,7 +93,7 @@ void ieee80211_network_reset(struct ieee80211_network *network)
90 } 93 }
91} 94}
92 95
93static inline void ieee80211_networks_free(struct ieee80211_device *ieee) 96static inline void libipw_networks_free(struct libipw_device *ieee)
94{ 97{
95 int i; 98 int i;
96 99
@@ -105,10 +108,10 @@ static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
105 ieee->networks = NULL; 108 ieee->networks = NULL;
106} 109}
107 110
108void ieee80211_networks_age(struct ieee80211_device *ieee, 111void libipw_networks_age(struct libipw_device *ieee,
109 unsigned long age_secs) 112 unsigned long age_secs)
110{ 113{
111 struct ieee80211_network *network = NULL; 114 struct libipw_network *network = NULL;
112 unsigned long flags; 115 unsigned long flags;
113 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); 116 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
114 117
@@ -118,9 +121,9 @@ void ieee80211_networks_age(struct ieee80211_device *ieee,
118 } 121 }
119 spin_unlock_irqrestore(&ieee->lock, flags); 122 spin_unlock_irqrestore(&ieee->lock, flags);
120} 123}
121EXPORT_SYMBOL(ieee80211_networks_age); 124EXPORT_SYMBOL(libipw_networks_age);
122 125
123static void ieee80211_networks_initialize(struct ieee80211_device *ieee) 126static void libipw_networks_initialize(struct libipw_device *ieee)
124{ 127{
125 int i; 128 int i;
126 129
@@ -131,38 +134,59 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
131 &ieee->network_free_list); 134 &ieee->network_free_list);
132} 135}
133 136
134int ieee80211_change_mtu(struct net_device *dev, int new_mtu) 137int libipw_change_mtu(struct net_device *dev, int new_mtu)
135{ 138{
136 if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN)) 139 if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
137 return -EINVAL; 140 return -EINVAL;
138 dev->mtu = new_mtu; 141 dev->mtu = new_mtu;
139 return 0; 142 return 0;
140} 143}
141EXPORT_SYMBOL(ieee80211_change_mtu); 144EXPORT_SYMBOL(libipw_change_mtu);
142 145
143struct net_device *alloc_ieee80211(int sizeof_priv) 146struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
144{ 147{
145 struct ieee80211_device *ieee; 148 struct libipw_device *ieee;
146 struct net_device *dev; 149 struct net_device *dev;
147 int err; 150 int err;
148 151
149 IEEE80211_DEBUG_INFO("Initializing...\n"); 152 LIBIPW_DEBUG_INFO("Initializing...\n");
150 153
151 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); 154 dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
152 if (!dev) { 155 if (!dev) {
153 IEEE80211_ERROR("Unable to allocate network device.\n"); 156 LIBIPW_ERROR("Unable to allocate network device.\n");
154 goto failed; 157 goto failed;
155 } 158 }
156 ieee = netdev_priv(dev); 159 ieee = netdev_priv(dev);
157 160
158 ieee->dev = dev; 161 ieee->dev = dev;
159 162
160 err = ieee80211_networks_allocate(ieee); 163 if (!monitor) {
164 ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
165 if (!ieee->wdev.wiphy) {
166 LIBIPW_ERROR("Unable to allocate wiphy.\n");
167 goto failed_free_netdev;
168 }
169
170 ieee->dev->ieee80211_ptr = &ieee->wdev;
171 ieee->wdev.iftype = NL80211_IFTYPE_STATION;
172
173 /* Fill-out wiphy structure bits we know... Not enough info
174 here to call set_wiphy_dev or set MAC address or channel info
175 -- have to do that in ->ndo_init... */
176 ieee->wdev.wiphy->privid = libipw_wiphy_privid;
177
178 ieee->wdev.wiphy->max_scan_ssids = 1;
179 ieee->wdev.wiphy->max_scan_ie_len = 0;
180 ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
181 | BIT(NL80211_IFTYPE_ADHOC);
182 }
183
184 err = libipw_networks_allocate(ieee);
161 if (err) { 185 if (err) {
162 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err); 186 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
163 goto failed_free_netdev; 187 goto failed_free_wiphy;
164 } 188 }
165 ieee80211_networks_initialize(ieee); 189 libipw_networks_initialize(ieee);
166 190
167 /* Default fragmentation threshold is maximum payload size */ 191 /* Default fragmentation threshold is maximum payload size */
168 ieee->fts = DEFAULT_FTS; 192 ieee->fts = DEFAULT_FTS;
@@ -193,33 +217,45 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
193 217
194 return dev; 218 return dev;
195 219
220failed_free_wiphy:
221 if (!monitor)
222 wiphy_free(ieee->wdev.wiphy);
196failed_free_netdev: 223failed_free_netdev:
197 free_netdev(dev); 224 free_netdev(dev);
198failed: 225failed:
199 return NULL; 226 return NULL;
200} 227}
201 228
202void free_ieee80211(struct net_device *dev) 229void free_ieee80211(struct net_device *dev, int monitor)
203{ 230{
204 struct ieee80211_device *ieee = netdev_priv(dev); 231 struct libipw_device *ieee = netdev_priv(dev);
205 232
206 lib80211_crypt_info_free(&ieee->crypt_info); 233 lib80211_crypt_info_free(&ieee->crypt_info);
207 234
208 ieee80211_networks_free(ieee); 235 libipw_networks_free(ieee);
236
237 /* free cfg80211 resources */
238 if (!monitor) {
239 wiphy_unregister(ieee->wdev.wiphy);
240 kfree(ieee->a_band.channels);
241 kfree(ieee->bg_band.channels);
242 wiphy_free(ieee->wdev.wiphy);
243 }
244
209 free_netdev(dev); 245 free_netdev(dev);
210} 246}
211 247
212#ifdef CONFIG_LIBIPW_DEBUG 248#ifdef CONFIG_LIBIPW_DEBUG
213 249
214static int debug = 0; 250static int debug = 0;
215u32 ieee80211_debug_level = 0; 251u32 libipw_debug_level = 0;
216EXPORT_SYMBOL_GPL(ieee80211_debug_level); 252EXPORT_SYMBOL_GPL(libipw_debug_level);
217static struct proc_dir_entry *ieee80211_proc = NULL; 253static struct proc_dir_entry *libipw_proc = NULL;
218 254
219static int show_debug_level(char *page, char **start, off_t offset, 255static int show_debug_level(char *page, char **start, off_t offset,
220 int count, int *eof, void *data) 256 int count, int *eof, void *data)
221{ 257{
222 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level); 258 return snprintf(page, count, "0x%08X\n", libipw_debug_level);
223} 259}
224 260
225static int store_debug_level(struct file *file, const char __user * buffer, 261static int store_debug_level(struct file *file, const char __user * buffer,
@@ -236,29 +272,29 @@ static int store_debug_level(struct file *file, const char __user * buffer,
236 printk(KERN_INFO DRV_NAME 272 printk(KERN_INFO DRV_NAME
237 ": %s is not in hex or decimal form.\n", buf); 273 ": %s is not in hex or decimal form.\n", buf);
238 else 274 else
239 ieee80211_debug_level = val; 275 libipw_debug_level = val;
240 276
241 return strnlen(buf, len); 277 return strnlen(buf, len);
242} 278}
243#endif /* CONFIG_LIBIPW_DEBUG */ 279#endif /* CONFIG_LIBIPW_DEBUG */
244 280
245static int __init ieee80211_init(void) 281static int __init libipw_init(void)
246{ 282{
247#ifdef CONFIG_LIBIPW_DEBUG 283#ifdef CONFIG_LIBIPW_DEBUG
248 struct proc_dir_entry *e; 284 struct proc_dir_entry *e;
249 285
250 ieee80211_debug_level = debug; 286 libipw_debug_level = debug;
251 ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 287 libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
252 if (ieee80211_proc == NULL) { 288 if (libipw_proc == NULL) {
253 IEEE80211_ERROR("Unable to create " DRV_NAME 289 LIBIPW_ERROR("Unable to create " DRV_NAME
254 " proc directory\n"); 290 " proc directory\n");
255 return -EIO; 291 return -EIO;
256 } 292 }
257 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, 293 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
258 ieee80211_proc); 294 libipw_proc);
259 if (!e) { 295 if (!e) {
260 remove_proc_entry(DRV_NAME, init_net.proc_net); 296 remove_proc_entry(DRV_NAME, init_net.proc_net);
261 ieee80211_proc = NULL; 297 libipw_proc = NULL;
262 return -EIO; 298 return -EIO;
263 } 299 }
264 e->read_proc = show_debug_level; 300 e->read_proc = show_debug_level;
@@ -272,13 +308,13 @@ static int __init ieee80211_init(void)
272 return 0; 308 return 0;
273} 309}
274 310
275static void __exit ieee80211_exit(void) 311static void __exit libipw_exit(void)
276{ 312{
277#ifdef CONFIG_LIBIPW_DEBUG 313#ifdef CONFIG_LIBIPW_DEBUG
278 if (ieee80211_proc) { 314 if (libipw_proc) {
279 remove_proc_entry("debug_level", ieee80211_proc); 315 remove_proc_entry("debug_level", libipw_proc);
280 remove_proc_entry(DRV_NAME, init_net.proc_net); 316 remove_proc_entry(DRV_NAME, init_net.proc_net);
281 ieee80211_proc = NULL; 317 libipw_proc = NULL;
282 } 318 }
283#endif /* CONFIG_LIBIPW_DEBUG */ 319#endif /* CONFIG_LIBIPW_DEBUG */
284} 320}
@@ -289,8 +325,8 @@ module_param(debug, int, 0444);
289MODULE_PARM_DESC(debug, "debug output mask"); 325MODULE_PARM_DESC(debug, "debug output mask");
290#endif /* CONFIG_LIBIPW_DEBUG */ 326#endif /* CONFIG_LIBIPW_DEBUG */
291 327
292module_exit(ieee80211_exit); 328module_exit(libipw_exit);
293module_init(ieee80211_init); 329module_init(libipw_init);
294 330
295EXPORT_SYMBOL(alloc_ieee80211); 331EXPORT_SYMBOL(alloc_ieee80211);
296EXPORT_SYMBOL(free_ieee80211); 332EXPORT_SYMBOL(free_ieee80211);