Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtllib_module.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  Copyright(c) 2004 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
9  Copyright (c) 2002-2003, Jouni Malinen <[email protected]>
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  James P. Ketrenos <[email protected]>
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/pci.h>
43 #include <linux/proc_fs.h>
44 #include <linux/skbuff.h>
45 #include <linux/slab.h>
46 #include <linux/tcp.h>
47 #include <linux/types.h>
48 #include <linux/wireless.h>
49 #include <linux/etherdevice.h>
50 #include <linux/uaccess.h>
51 #include <net/arp.h>
52 
53 #include "rtllib.h"
54 
55 
58 
59 
60 void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data)
61 {
62  ptimer->function = fun;
63  ptimer->data = data;
64  init_timer(ptimer);
65 }
66 
67 static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
68 {
69  if (ieee->networks)
70  return 0;
71 
72  ieee->networks = kzalloc(
73  MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
74  GFP_KERNEL);
75  if (!ieee->networks) {
76  printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
77  ieee->dev->name);
78  return -ENOMEM;
79  }
80 
81  return 0;
82 }
83 
84 static inline void rtllib_networks_free(struct rtllib_device *ieee)
85 {
86  if (!ieee->networks)
87  return;
88  kfree(ieee->networks);
89  ieee->networks = NULL;
90 }
91 
92 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
93 {
94  int i;
95 
96  INIT_LIST_HEAD(&ieee->network_free_list);
97  INIT_LIST_HEAD(&ieee->network_list);
98  for (i = 0; i < MAX_NETWORK_COUNT; i++)
99  list_add_tail(&ieee->networks[i].list,
100  &ieee->network_free_list);
101 }
102 
103 struct net_device *alloc_rtllib(int sizeof_priv)
104 {
105  struct rtllib_device *ieee = NULL;
106  struct net_device *dev;
107  int i, err;
108 
109  RTLLIB_DEBUG_INFO("Initializing...\n");
110 
111  dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
112  if (!dev) {
113  RTLLIB_ERROR("Unable to network device.\n");
114  goto failed;
115  }
116  ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
117  memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
118  ieee->dev = dev;
119 
120  err = rtllib_networks_allocate(ieee);
121  if (err) {
122  RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
123  err);
124  goto failed;
125  }
126  rtllib_networks_initialize(ieee);
127 
128 
129  /* Default fragmentation threshold is maximum payload size */
130  ieee->fts = DEFAULT_FTS;
132  ieee->open_wep = 1;
133 
134  /* Default to enabling full open WEP with host based encrypt/decrypt */
135  ieee->host_encrypt = 1;
136  ieee->host_decrypt = 1;
137  ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
138 
140 
141  spin_lock_init(&ieee->lock);
143  spin_lock_init(&ieee->bw_spinlock);
145  atomic_set(&(ieee->atm_chnlop), 0);
146  atomic_set(&(ieee->atm_swbw), 0);
147 
148  /* SAM FIXME */
149  lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
150 
151  ieee->bHalfNMode = false;
152  ieee->wpa_enabled = 0;
153  ieee->tkip_countermeasures = 0;
154  ieee->drop_unencrypted = 0;
155  ieee->privacy_invoked = 0;
156  ieee->ieee802_1x = 1;
157  ieee->raw_tx = 0;
158  ieee->hwsec_active = 0;
159 
160  memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
161  rtllib_softmac_init(ieee);
162 
163  ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
164  if (ieee->pHTInfo == NULL) {
165  RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
166  return NULL;
167  }
169  HTInitializeHTInfo(ieee);
170  TSInitialize(ieee);
171  for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
172  INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
173 
174  for (i = 0; i < 17; i++) {
175  ieee->last_rxseq_num[i] = -1;
176  ieee->last_rxfrag_num[i] = -1;
177  ieee->last_packet_time[i] = 0;
178  }
179 
180  return dev;
181 
182  failed:
183  if (dev)
184  free_netdev(dev);
185  return NULL;
186 }
188 
190 {
191  struct rtllib_device *ieee = (struct rtllib_device *)
192  netdev_priv_rsl(dev);
193 
194  kfree(ieee->pHTInfo);
195  ieee->pHTInfo = NULL;
196  rtllib_softmac_free(ieee);
197 
199 
200  rtllib_networks_free(ieee);
201  free_netdev(dev);
202 }
204 
206 static int debug = \
207  RTLLIB_DL_ERR
208  ;
209 static struct proc_dir_entry *rtllib_proc;
210 
211 static int show_debug_level(char *page, char **start, off_t offset,
212  int count, int *eof, void *data)
213 {
214  return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
215 }
216 
217 static int store_debug_level(struct file *file, const char __user *buffer,
218  unsigned long count, void *data)
219 {
220  char buf[] = "0x00000000";
221  unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
222  char *p = (char *)buf;
223  unsigned long val;
224 
225  if (copy_from_user(buf, buffer, len))
226  return count;
227  buf[len] = 0;
228  if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
229  p++;
230  if (p[0] == 'x' || p[0] == 'X')
231  p++;
232  val = simple_strtoul(p, &p, 16);
233  } else
234  val = simple_strtoul(p, &p, 10);
235  if (p == buf)
237  ": %s is not in hex or decimal form.\n", buf);
238  else
239  rtllib_debug_level = val;
240 
241  return strnlen(buf, count);
242 }
243 
245 {
246  struct proc_dir_entry *e;
247 
248  rtllib_debug_level = debug;
249  rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
250  if (rtllib_proc == NULL) {
251  RTLLIB_ERROR("Unable to create " DRV_NAME
252  " proc directory\n");
253  return -EIO;
254  }
255  e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
256  rtllib_proc);
257  if (!e) {
259  rtllib_proc = NULL;
260  return -EIO;
261  }
262  e->read_proc = show_debug_level;
263  e->write_proc = store_debug_level;
264  e->data = NULL;
265 
266  return 0;
267 }
268 
269 void __exit rtllib_exit(void)
270 {
271  if (rtllib_proc) {
272  remove_proc_entry("debug_level", rtllib_proc);
274  rtllib_proc = NULL;
275  }
276 }
277 
280 
281 MODULE_LICENSE("GPL");