aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2x00/libipw_module.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ipw2x00/libipw_module.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ipw2x00/libipw_module.c')
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index eb2b60834c17..2fa55867bd8b 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -62,18 +62,22 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
62MODULE_AUTHOR(DRV_COPYRIGHT); 62MODULE_AUTHOR(DRV_COPYRIGHT);
63MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
64 64
65struct cfg80211_ops libipw_config_ops = { };
66void *libipw_wiphy_privid = &libipw_wiphy_privid;
67
65static int libipw_networks_allocate(struct libipw_device *ieee) 68static int libipw_networks_allocate(struct libipw_device *ieee)
66{ 69{
67 if (ieee->networks) 70 int i, j;
68 return 0; 71
69 72 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
70 ieee->networks = 73 ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
71 kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), 74 GFP_KERNEL);
72 GFP_KERNEL); 75 if (!ieee->networks[i]) {
73 if (!ieee->networks) { 76 LIBIPW_ERROR("Out of memory allocating beacons\n");
74 printk(KERN_WARNING "%s: Out of memory allocating beacons\n", 77 for (j = 0; j < i; j++)
75 ieee->dev->name); 78 kfree(ieee->networks[j]);
76 return -ENOMEM; 79 return -ENOMEM;
80 }
77 } 81 }
78 82
79 return 0; 83 return 0;
@@ -94,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
94{ 98{
95 int i; 99 int i;
96 100
97 if (!ieee->networks) 101 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
98 return; 102 if (ieee->networks[i]->ibss_dfs)
99 103 kfree(ieee->networks[i]->ibss_dfs);
100 for (i = 0; i < MAX_NETWORK_COUNT; i++) 104 kfree(ieee->networks[i]);
101 if (ieee->networks[i].ibss_dfs) 105 }
102 kfree(ieee->networks[i].ibss_dfs);
103
104 kfree(ieee->networks);
105 ieee->networks = NULL;
106} 106}
107 107
108void libipw_networks_age(struct libipw_device *ieee, 108void libipw_networks_age(struct libipw_device *ieee,
@@ -127,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
127 INIT_LIST_HEAD(&ieee->network_free_list); 127 INIT_LIST_HEAD(&ieee->network_free_list);
128 INIT_LIST_HEAD(&ieee->network_list); 128 INIT_LIST_HEAD(&ieee->network_list);
129 for (i = 0; i < MAX_NETWORK_COUNT; i++) 129 for (i = 0; i < MAX_NETWORK_COUNT; i++)
130 list_add_tail(&ieee->networks[i].list, 130 list_add_tail(&ieee->networks[i]->list,
131 &ieee->network_free_list); 131 &ieee->network_free_list);
132} 132}
133 133
@@ -140,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
140} 140}
141EXPORT_SYMBOL(libipw_change_mtu); 141EXPORT_SYMBOL(libipw_change_mtu);
142 142
143struct net_device *alloc_ieee80211(int sizeof_priv) 143struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
144{ 144{
145 struct libipw_device *ieee; 145 struct libipw_device *ieee;
146 struct net_device *dev; 146 struct net_device *dev;
@@ -157,10 +157,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
157 157
158 ieee->dev = dev; 158 ieee->dev = dev;
159 159
160 if (!monitor) {
161 ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
162 if (!ieee->wdev.wiphy) {
163 LIBIPW_ERROR("Unable to allocate wiphy.\n");
164 goto failed_free_netdev;
165 }
166
167 ieee->dev->ieee80211_ptr = &ieee->wdev;
168 ieee->wdev.iftype = NL80211_IFTYPE_STATION;
169
170 /* Fill-out wiphy structure bits we know... Not enough info
171 here to call set_wiphy_dev or set MAC address or channel info
172 -- have to do that in ->ndo_init... */
173 ieee->wdev.wiphy->privid = libipw_wiphy_privid;
174
175 ieee->wdev.wiphy->max_scan_ssids = 1;
176 ieee->wdev.wiphy->max_scan_ie_len = 0;
177 ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
178 | BIT(NL80211_IFTYPE_ADHOC);
179 }
180
160 err = libipw_networks_allocate(ieee); 181 err = libipw_networks_allocate(ieee);
161 if (err) { 182 if (err) {
162 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); 183 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
163 goto failed_free_netdev; 184 goto failed_free_wiphy;
164 } 185 }
165 libipw_networks_initialize(ieee); 186 libipw_networks_initialize(ieee);
166 187
@@ -175,7 +196,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
175 ieee->host_decrypt = 1; 196 ieee->host_decrypt = 1;
176 ieee->host_mc_decrypt = 1; 197 ieee->host_mc_decrypt = 1;
177 198
178 /* Host fragementation in Open mode. Default is enabled. 199 /* Host fragmentation in Open mode. Default is enabled.
179 * Note: host fragmentation is always enabled if host encryption 200 * Note: host fragmentation is always enabled if host encryption
180 * is enabled. For cards can do hardware encryption, they must do 201 * is enabled. For cards can do hardware encryption, they must do
181 * hardware fragmentation as well. So we don't need a variable 202 * hardware fragmentation as well. So we don't need a variable
@@ -193,19 +214,27 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
193 214
194 return dev; 215 return dev;
195 216
217failed_free_wiphy:
218 if (!monitor)
219 wiphy_free(ieee->wdev.wiphy);
196failed_free_netdev: 220failed_free_netdev:
197 free_netdev(dev); 221 free_netdev(dev);
198failed: 222failed:
199 return NULL; 223 return NULL;
200} 224}
201 225
202void free_ieee80211(struct net_device *dev) 226void free_ieee80211(struct net_device *dev, int monitor)
203{ 227{
204 struct libipw_device *ieee = netdev_priv(dev); 228 struct libipw_device *ieee = netdev_priv(dev);
205 229
206 lib80211_crypt_info_free(&ieee->crypt_info); 230 lib80211_crypt_info_free(&ieee->crypt_info);
207 231
208 libipw_networks_free(ieee); 232 libipw_networks_free(ieee);
233
234 /* free cfg80211 resources */
235 if (!monitor)
236 wiphy_free(ieee->wdev.wiphy);
237
209 free_netdev(dev); 238 free_netdev(dev);
210} 239}
211 240
@@ -216,17 +245,22 @@ u32 libipw_debug_level = 0;
216EXPORT_SYMBOL_GPL(libipw_debug_level); 245EXPORT_SYMBOL_GPL(libipw_debug_level);
217static struct proc_dir_entry *libipw_proc = NULL; 246static struct proc_dir_entry *libipw_proc = NULL;
218 247
219static int show_debug_level(char *page, char **start, off_t offset, 248static int debug_level_proc_show(struct seq_file *m, void *v)
220 int count, int *eof, void *data)
221{ 249{
222 return snprintf(page, count, "0x%08X\n", libipw_debug_level); 250 seq_printf(m, "0x%08X\n", libipw_debug_level);
251 return 0;
223} 252}
224 253
225static int store_debug_level(struct file *file, const char __user * buffer, 254static int debug_level_proc_open(struct inode *inode, struct file *file)
226 unsigned long count, void *data) 255{
256 return single_open(file, debug_level_proc_show, NULL);
257}
258
259static ssize_t debug_level_proc_write(struct file *file,
260 const char __user *buffer, size_t count, loff_t *pos)
227{ 261{
228 char buf[] = "0x00000000\n"; 262 char buf[] = "0x00000000\n";
229 unsigned long len = min((unsigned long)sizeof(buf) - 1, count); 263 size_t len = min(sizeof(buf) - 1, count);
230 unsigned long val; 264 unsigned long val;
231 265
232 if (copy_from_user(buf, buffer, len)) 266 if (copy_from_user(buf, buffer, len))
@@ -240,6 +274,15 @@ static int store_debug_level(struct file *file, const char __user * buffer,
240 274
241 return strnlen(buf, len); 275 return strnlen(buf, len);
242} 276}
277
278static const struct file_operations debug_level_proc_fops = {
279 .owner = THIS_MODULE,
280 .open = debug_level_proc_open,
281 .read = seq_read,
282 .llseek = seq_lseek,
283 .release = single_release,
284 .write = debug_level_proc_write,
285};
243#endif /* CONFIG_LIBIPW_DEBUG */ 286#endif /* CONFIG_LIBIPW_DEBUG */
244 287
245static int __init libipw_init(void) 288static int __init libipw_init(void)
@@ -254,16 +297,13 @@ static int __init libipw_init(void)
254 " proc directory\n"); 297 " proc directory\n");
255 return -EIO; 298 return -EIO;
256 } 299 }
257 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, 300 e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
258 libipw_proc); 301 &debug_level_proc_fops);
259 if (!e) { 302 if (!e) {
260 remove_proc_entry(DRV_NAME, init_net.proc_net); 303 remove_proc_entry(DRV_NAME, init_net.proc_net);
261 libipw_proc = NULL; 304 libipw_proc = NULL;
262 return -EIO; 305 return -EIO;
263 } 306 }
264 e->read_proc = show_debug_level;
265 e->write_proc = store_debug_level;
266 e->data = NULL;
267#endif /* CONFIG_LIBIPW_DEBUG */ 307#endif /* CONFIG_LIBIPW_DEBUG */
268 308
269 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); 309 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");