Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*******************************************************************************
  3
  4  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
  5
  6  Portions of this file are based on the WEP enablement code provided by the
  7  Host AP project hostap-drivers v0.1.3
  8  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  9  <j@w1.fi>
 10  Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
 11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 12
 13  Contact Information:
 14  Intel Linux Wireless <ilw@linux.intel.com>
 15  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 16
 17*******************************************************************************/
 18
 19#include <linux/compiler.h>
 20#include <linux/errno.h>
 21#include <linux/if_arp.h>
 22#include <linux/in6.h>
 23#include <linux/in.h>
 24#include <linux/ip.h>
 25#include <linux/kernel.h>
 26#include <linux/module.h>
 27#include <linux/netdevice.h>
 28#include <linux/proc_fs.h>
 29#include <linux/skbuff.h>
 30#include <linux/slab.h>
 31#include <linux/tcp.h>
 32#include <linux/types.h>
 33#include <linux/wireless.h>
 34#include <linux/etherdevice.h>
 35#include <linux/uaccess.h>
 36#include <net/net_namespace.h>
 37#include <net/arp.h>
 38
 39#include "libipw.h"
 40
 41#define DRV_DESCRIPTION "802.11 data/management/control stack"
 42#define DRV_NAME        "libipw"
 43#define DRV_PROCNAME	"ieee80211"
 44#define DRV_VERSION	LIBIPW_VERSION
 45#define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 46
 47MODULE_VERSION(DRV_VERSION);
 48MODULE_DESCRIPTION(DRV_DESCRIPTION);
 49MODULE_AUTHOR(DRV_COPYRIGHT);
 50MODULE_LICENSE("GPL");
 51
 52static struct cfg80211_ops libipw_config_ops = { };
 53static void *libipw_wiphy_privid = &libipw_wiphy_privid;
 54
 55static int libipw_networks_allocate(struct libipw_device *ieee)
 56{
 57	int i, j;
 58
 59	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
 60		ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
 61					    GFP_KERNEL);
 62		if (!ieee->networks[i]) {
 63			LIBIPW_ERROR("Out of memory allocating beacons\n");
 64			for (j = 0; j < i; j++)
 65				kfree(ieee->networks[j]);
 66			return -ENOMEM;
 67		}
 68	}
 69
 70	return 0;
 71}
 72
 73static inline void libipw_networks_free(struct libipw_device *ieee)
 74{
 75	int i;
 76
 77	for (i = 0; i < MAX_NETWORK_COUNT; i++)
 78		kfree(ieee->networks[i]);
 79}
 80
 81void libipw_networks_age(struct libipw_device *ieee,
 82                            unsigned long age_secs)
 83{
 84	struct libipw_network *network = NULL;
 85	unsigned long flags;
 86	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
 87
 88	spin_lock_irqsave(&ieee->lock, flags);
 89	list_for_each_entry(network, &ieee->network_list, list) {
 90		network->last_scanned -= age_jiffies;
 91	}
 92	spin_unlock_irqrestore(&ieee->lock, flags);
 93}
 94EXPORT_SYMBOL(libipw_networks_age);
 95
 96static void libipw_networks_initialize(struct libipw_device *ieee)
 97{
 98	int i;
 99
100	INIT_LIST_HEAD(&ieee->network_free_list);
101	INIT_LIST_HEAD(&ieee->network_list);
102	for (i = 0; i < MAX_NETWORK_COUNT; i++)
103		list_add_tail(&ieee->networks[i]->list,
104			      &ieee->network_free_list);
105}
106
 
 
 
 
 
 
 
 
 
107struct net_device *alloc_libipw(int sizeof_priv, int monitor)
108{
109	struct libipw_device *ieee;
110	struct net_device *dev;
111	int err;
112
113	LIBIPW_DEBUG_INFO("Initializing...\n");
114
115	dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
116	if (!dev)
117		goto failed;
118
119	ieee = netdev_priv(dev);
120
121	ieee->dev = dev;
122
123	if (!monitor) {
124		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
125		if (!ieee->wdev.wiphy) {
126			LIBIPW_ERROR("Unable to allocate wiphy.\n");
127			goto failed_free_netdev;
128		}
129
130		ieee->dev->ieee80211_ptr = &ieee->wdev;
131		ieee->wdev.iftype = NL80211_IFTYPE_STATION;
132
133		/* Fill-out wiphy structure bits we know...  Not enough info
134		   here to call set_wiphy_dev or set MAC address or channel info
135		   -- have to do that in ->ndo_init... */
136		ieee->wdev.wiphy->privid = libipw_wiphy_privid;
137
138		ieee->wdev.wiphy->max_scan_ssids = 1;
139		ieee->wdev.wiphy->max_scan_ie_len = 0;
140		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
141						| BIT(NL80211_IFTYPE_ADHOC);
142	}
143
144	err = libipw_networks_allocate(ieee);
145	if (err) {
146		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
147		goto failed_free_wiphy;
148	}
149	libipw_networks_initialize(ieee);
150
151	/* Default fragmentation threshold is maximum payload size */
152	ieee->fts = DEFAULT_FTS;
153	ieee->rts = DEFAULT_FTS;
154	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
155	ieee->open_wep = 1;
156
157	/* Default to enabling full open WEP with host based encrypt/decrypt */
158	ieee->host_encrypt = 1;
159	ieee->host_decrypt = 1;
160	ieee->host_mc_decrypt = 1;
161
162	/* Host fragmentation in Open mode. Default is enabled.
163	 * Note: host fragmentation is always enabled if host encryption
164	 * is enabled. For cards can do hardware encryption, they must do
165	 * hardware fragmentation as well. So we don't need a variable
166	 * like host_enc_frag. */
167	ieee->host_open_frag = 1;
168	ieee->ieee802_1x = 1;	/* Default to supporting 802.1x */
169
170	spin_lock_init(&ieee->lock);
171
172	lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
173
174	ieee->wpa_enabled = 0;
175	ieee->drop_unencrypted = 0;
176	ieee->privacy_invoked = 0;
177
178	return dev;
179
180failed_free_wiphy:
181	if (!monitor)
182		wiphy_free(ieee->wdev.wiphy);
183failed_free_netdev:
184	free_netdev(dev);
185failed:
186	return NULL;
187}
188EXPORT_SYMBOL(alloc_libipw);
189
190void free_libipw(struct net_device *dev, int monitor)
191{
192	struct libipw_device *ieee = netdev_priv(dev);
193
194	lib80211_crypt_info_free(&ieee->crypt_info);
195
196	libipw_networks_free(ieee);
197
198	/* free cfg80211 resources */
199	if (!monitor)
200		wiphy_free(ieee->wdev.wiphy);
201
202	free_netdev(dev);
203}
204EXPORT_SYMBOL(free_libipw);
205
206#ifdef CONFIG_LIBIPW_DEBUG
207
208static int debug = 0;
209u32 libipw_debug_level = 0;
210EXPORT_SYMBOL_GPL(libipw_debug_level);
211static struct proc_dir_entry *libipw_proc = NULL;
212
213static int debug_level_proc_show(struct seq_file *m, void *v)
214{
215	seq_printf(m, "0x%08X\n", libipw_debug_level);
216	return 0;
217}
218
219static int debug_level_proc_open(struct inode *inode, struct file *file)
220{
221	return single_open(file, debug_level_proc_show, NULL);
222}
223
224static ssize_t debug_level_proc_write(struct file *file,
225		const char __user *buffer, size_t count, loff_t *pos)
226{
227	char buf[] = "0x00000000\n";
228	size_t len = min(sizeof(buf) - 1, count);
229	unsigned long val;
230
231	if (copy_from_user(buf, buffer, len))
232		return count;
233	buf[len] = 0;
234	if (sscanf(buf, "%li", &val) != 1)
235		printk(KERN_INFO DRV_NAME
236		       ": %s is not in hex or decimal form.\n", buf);
237	else
238		libipw_debug_level = val;
239
240	return strnlen(buf, len);
241}
242
243static const struct proc_ops debug_level_proc_ops = {
244	.proc_open	= debug_level_proc_open,
245	.proc_read	= seq_read,
246	.proc_lseek	= seq_lseek,
247	.proc_release	= single_release,
248	.proc_write	= debug_level_proc_write,
 
249};
250#endif				/* CONFIG_LIBIPW_DEBUG */
251
252static int __init libipw_init(void)
253{
254#ifdef CONFIG_LIBIPW_DEBUG
255	struct proc_dir_entry *e;
256
257	libipw_debug_level = debug;
258	libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
259	if (libipw_proc == NULL) {
260		LIBIPW_ERROR("Unable to create " DRV_PROCNAME
261				" proc directory\n");
262		return -EIO;
263	}
264	e = proc_create("debug_level", 0644, libipw_proc,
265			&debug_level_proc_ops);
266	if (!e) {
267		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
268		libipw_proc = NULL;
269		return -EIO;
270	}
271#endif				/* CONFIG_LIBIPW_DEBUG */
272
273	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
274	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
275
276	return 0;
277}
278
279static void __exit libipw_exit(void)
280{
281#ifdef CONFIG_LIBIPW_DEBUG
282	if (libipw_proc) {
283		remove_proc_entry("debug_level", libipw_proc);
284		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
285		libipw_proc = NULL;
286	}
287#endif				/* CONFIG_LIBIPW_DEBUG */
288}
289
290#ifdef CONFIG_LIBIPW_DEBUG
291#include <linux/moduleparam.h>
292module_param(debug, int, 0444);
293MODULE_PARM_DESC(debug, "debug output mask");
294#endif				/* CONFIG_LIBIPW_DEBUG */
295
296module_exit(libipw_exit);
297module_init(libipw_init);
v4.6
 
  1/*******************************************************************************
  2
  3  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
  4
  5  Portions of this file are based on the WEP enablement code provided by the
  6  Host AP project hostap-drivers v0.1.3
  7  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  8  <j@w1.fi>
  9  Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
 10
 11  This program is free software; you can redistribute it and/or modify it
 12  under the terms of version 2 of the GNU General Public License as
 13  published by the Free Software Foundation.
 14
 15  This program is distributed in the hope that it will be useful, but WITHOUT
 16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 17  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 18  more details.
 19
 20  You should have received a copy of the GNU General Public License along with
 21  this program; if not, write to the Free Software Foundation, Inc., 59
 22  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 23
 24  The full GNU General Public License is included in this distribution in the
 25  file called LICENSE.
 26
 27  Contact Information:
 28  Intel Linux Wireless <ilw@linux.intel.com>
 29  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 30
 31*******************************************************************************/
 32
 33#include <linux/compiler.h>
 34#include <linux/errno.h>
 35#include <linux/if_arp.h>
 36#include <linux/in6.h>
 37#include <linux/in.h>
 38#include <linux/ip.h>
 39#include <linux/kernel.h>
 40#include <linux/module.h>
 41#include <linux/netdevice.h>
 42#include <linux/proc_fs.h>
 43#include <linux/skbuff.h>
 44#include <linux/slab.h>
 45#include <linux/tcp.h>
 46#include <linux/types.h>
 47#include <linux/wireless.h>
 48#include <linux/etherdevice.h>
 49#include <asm/uaccess.h>
 50#include <net/net_namespace.h>
 51#include <net/arp.h>
 52
 53#include "libipw.h"
 54
 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
 56#define DRV_NAME        "libipw"
 57#define DRV_PROCNAME	"ieee80211"
 58#define DRV_VERSION	LIBIPW_VERSION
 59#define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 60
 61MODULE_VERSION(DRV_VERSION);
 62MODULE_DESCRIPTION(DRV_DESCRIPTION);
 63MODULE_AUTHOR(DRV_COPYRIGHT);
 64MODULE_LICENSE("GPL");
 65
 66static struct cfg80211_ops libipw_config_ops = { };
 67static void *libipw_wiphy_privid = &libipw_wiphy_privid;
 68
 69static int libipw_networks_allocate(struct libipw_device *ieee)
 70{
 71	int i, j;
 72
 73	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
 74		ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
 75					    GFP_KERNEL);
 76		if (!ieee->networks[i]) {
 77			LIBIPW_ERROR("Out of memory allocating beacons\n");
 78			for (j = 0; j < i; j++)
 79				kfree(ieee->networks[j]);
 80			return -ENOMEM;
 81		}
 82	}
 83
 84	return 0;
 85}
 86
 87static inline void libipw_networks_free(struct libipw_device *ieee)
 88{
 89	int i;
 90
 91	for (i = 0; i < MAX_NETWORK_COUNT; i++)
 92		kfree(ieee->networks[i]);
 93}
 94
 95void libipw_networks_age(struct libipw_device *ieee,
 96                            unsigned long age_secs)
 97{
 98	struct libipw_network *network = NULL;
 99	unsigned long flags;
100	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
101
102	spin_lock_irqsave(&ieee->lock, flags);
103	list_for_each_entry(network, &ieee->network_list, list) {
104		network->last_scanned -= age_jiffies;
105	}
106	spin_unlock_irqrestore(&ieee->lock, flags);
107}
108EXPORT_SYMBOL(libipw_networks_age);
109
110static void libipw_networks_initialize(struct libipw_device *ieee)
111{
112	int i;
113
114	INIT_LIST_HEAD(&ieee->network_free_list);
115	INIT_LIST_HEAD(&ieee->network_list);
116	for (i = 0; i < MAX_NETWORK_COUNT; i++)
117		list_add_tail(&ieee->networks[i]->list,
118			      &ieee->network_free_list);
119}
120
121int libipw_change_mtu(struct net_device *dev, int new_mtu)
122{
123	if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
124		return -EINVAL;
125	dev->mtu = new_mtu;
126	return 0;
127}
128EXPORT_SYMBOL(libipw_change_mtu);
129
130struct net_device *alloc_libipw(int sizeof_priv, int monitor)
131{
132	struct libipw_device *ieee;
133	struct net_device *dev;
134	int err;
135
136	LIBIPW_DEBUG_INFO("Initializing...\n");
137
138	dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
139	if (!dev)
140		goto failed;
141
142	ieee = netdev_priv(dev);
143
144	ieee->dev = dev;
145
146	if (!monitor) {
147		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
148		if (!ieee->wdev.wiphy) {
149			LIBIPW_ERROR("Unable to allocate wiphy.\n");
150			goto failed_free_netdev;
151		}
152
153		ieee->dev->ieee80211_ptr = &ieee->wdev;
154		ieee->wdev.iftype = NL80211_IFTYPE_STATION;
155
156		/* Fill-out wiphy structure bits we know...  Not enough info
157		   here to call set_wiphy_dev or set MAC address or channel info
158		   -- have to do that in ->ndo_init... */
159		ieee->wdev.wiphy->privid = libipw_wiphy_privid;
160
161		ieee->wdev.wiphy->max_scan_ssids = 1;
162		ieee->wdev.wiphy->max_scan_ie_len = 0;
163		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
164						| BIT(NL80211_IFTYPE_ADHOC);
165	}
166
167	err = libipw_networks_allocate(ieee);
168	if (err) {
169		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
170		goto failed_free_wiphy;
171	}
172	libipw_networks_initialize(ieee);
173
174	/* Default fragmentation threshold is maximum payload size */
175	ieee->fts = DEFAULT_FTS;
176	ieee->rts = DEFAULT_FTS;
177	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
178	ieee->open_wep = 1;
179
180	/* Default to enabling full open WEP with host based encrypt/decrypt */
181	ieee->host_encrypt = 1;
182	ieee->host_decrypt = 1;
183	ieee->host_mc_decrypt = 1;
184
185	/* Host fragmentation in Open mode. Default is enabled.
186	 * Note: host fragmentation is always enabled if host encryption
187	 * is enabled. For cards can do hardware encryption, they must do
188	 * hardware fragmentation as well. So we don't need a variable
189	 * like host_enc_frag. */
190	ieee->host_open_frag = 1;
191	ieee->ieee802_1x = 1;	/* Default to supporting 802.1x */
192
193	spin_lock_init(&ieee->lock);
194
195	lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
196
197	ieee->wpa_enabled = 0;
198	ieee->drop_unencrypted = 0;
199	ieee->privacy_invoked = 0;
200
201	return dev;
202
203failed_free_wiphy:
204	if (!monitor)
205		wiphy_free(ieee->wdev.wiphy);
206failed_free_netdev:
207	free_netdev(dev);
208failed:
209	return NULL;
210}
211EXPORT_SYMBOL(alloc_libipw);
212
213void free_libipw(struct net_device *dev, int monitor)
214{
215	struct libipw_device *ieee = netdev_priv(dev);
216
217	lib80211_crypt_info_free(&ieee->crypt_info);
218
219	libipw_networks_free(ieee);
220
221	/* free cfg80211 resources */
222	if (!monitor)
223		wiphy_free(ieee->wdev.wiphy);
224
225	free_netdev(dev);
226}
227EXPORT_SYMBOL(free_libipw);
228
229#ifdef CONFIG_LIBIPW_DEBUG
230
231static int debug = 0;
232u32 libipw_debug_level = 0;
233EXPORT_SYMBOL_GPL(libipw_debug_level);
234static struct proc_dir_entry *libipw_proc = NULL;
235
236static int debug_level_proc_show(struct seq_file *m, void *v)
237{
238	seq_printf(m, "0x%08X\n", libipw_debug_level);
239	return 0;
240}
241
242static int debug_level_proc_open(struct inode *inode, struct file *file)
243{
244	return single_open(file, debug_level_proc_show, NULL);
245}
246
247static ssize_t debug_level_proc_write(struct file *file,
248		const char __user *buffer, size_t count, loff_t *pos)
249{
250	char buf[] = "0x00000000\n";
251	size_t len = min(sizeof(buf) - 1, count);
252	unsigned long val;
253
254	if (copy_from_user(buf, buffer, len))
255		return count;
256	buf[len] = 0;
257	if (sscanf(buf, "%li", &val) != 1)
258		printk(KERN_INFO DRV_NAME
259		       ": %s is not in hex or decimal form.\n", buf);
260	else
261		libipw_debug_level = val;
262
263	return strnlen(buf, len);
264}
265
266static const struct file_operations debug_level_proc_fops = {
267	.owner		= THIS_MODULE,
268	.open		= debug_level_proc_open,
269	.read		= seq_read,
270	.llseek		= seq_lseek,
271	.release	= single_release,
272	.write		= debug_level_proc_write,
273};
274#endif				/* CONFIG_LIBIPW_DEBUG */
275
276static int __init libipw_init(void)
277{
278#ifdef CONFIG_LIBIPW_DEBUG
279	struct proc_dir_entry *e;
280
281	libipw_debug_level = debug;
282	libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
283	if (libipw_proc == NULL) {
284		LIBIPW_ERROR("Unable to create " DRV_PROCNAME
285				" proc directory\n");
286		return -EIO;
287	}
288	e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
289			&debug_level_proc_fops);
290	if (!e) {
291		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
292		libipw_proc = NULL;
293		return -EIO;
294	}
295#endif				/* CONFIG_LIBIPW_DEBUG */
296
297	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
298	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
299
300	return 0;
301}
302
303static void __exit libipw_exit(void)
304{
305#ifdef CONFIG_LIBIPW_DEBUG
306	if (libipw_proc) {
307		remove_proc_entry("debug_level", libipw_proc);
308		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
309		libipw_proc = NULL;
310	}
311#endif				/* CONFIG_LIBIPW_DEBUG */
312}
313
314#ifdef CONFIG_LIBIPW_DEBUG
315#include <linux/moduleparam.h>
316module_param(debug, int, 0444);
317MODULE_PARM_DESC(debug, "debug output mask");
318#endif				/* CONFIG_LIBIPW_DEBUG */
319
320module_exit(libipw_exit);
321module_init(libipw_init);