Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ieee80211_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/config.h>
35 #include <linux/errno.h>
36 #include <linux/if_arp.h>
37 #include <linux/in6.h>
38 #include <linux/in.h>
39 #include <linux/ip.h>
40 #include <linux/kernel.h>
41 #include <linux/module.h>
42 #include <linux/netdevice.h>
43 #include <linux/pci.h>
44 #include <linux/proc_fs.h>
45 #include <linux/skbuff.h>
46 #include <linux/slab.h>
47 #include <linux/tcp.h>
48 #include <linux/types.h>
49 #include <linux/wireless.h>
50 #include <linux/etherdevice.h>
51 #include <asm/uaccess.h>
52 #include <net/arp.h>
53 
54 #include "ieee80211.h"
55 
56 MODULE_DESCRIPTION("802.11 data/management/control stack");
57 MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <[email protected]>");
58 MODULE_LICENSE("GPL");
59 
60 #define DRV_NAME "ieee80211"
61 
62 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
63 {
64  if (ieee->networks)
65  return 0;
66 
67  ieee->networks = kcalloc(
68  MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
69  GFP_KERNEL);
70  if (!ieee->networks) {
71  printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
72  ieee->dev->name);
73  return -ENOMEM;
74  }
75 
76  return 0;
77 }
78 
79 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
80 {
81  if (!ieee->networks)
82  return;
83  kfree(ieee->networks);
84  ieee->networks = NULL;
85 }
86 
87 static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
88 {
89  int i;
90 
91  INIT_LIST_HEAD(&ieee->network_free_list);
92  INIT_LIST_HEAD(&ieee->network_list);
93  for (i = 0; i < MAX_NETWORK_COUNT; i++)
94  list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
95 }
96 
97 
98 struct net_device *alloc_ieee80211(int sizeof_priv)
99 {
100  struct ieee80211_device *ieee;
101  struct net_device *dev;
102  int i,err;
103 
104  IEEE80211_DEBUG_INFO("Initializing...\n");
105 
106  dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
107  if (!dev) {
108  IEEE80211_ERROR("Unable to network device.\n");
109  goto failed;
110  }
111 
112  ieee = netdev_priv(dev);
113  memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
114  ieee->dev = dev;
115 
116  err = ieee80211_networks_allocate(ieee);
117  if (err) {
118  IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
119  err);
120  goto failed;
121  }
122  ieee80211_networks_initialize(ieee);
123 
124 
125  /* Default fragmentation threshold is maximum payload size */
126  ieee->fts = DEFAULT_FTS;
128  ieee->open_wep = 1;
129 
130  /* Default to enabling full open WEP with host based encrypt/decrypt */
131  ieee->host_encrypt = 1;
132  ieee->host_decrypt = 1;
133  ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
134 
135  INIT_LIST_HEAD(&ieee->crypt_deinit_list);
137  ieee->crypt_deinit_timer.data = (unsigned long)ieee;
139 
140  spin_lock_init(&ieee->lock);
142  spin_lock_init(&ieee->bw_spinlock);
144  //added by WB
145  atomic_set(&(ieee->atm_chnlop), 0);
146  atomic_set(&(ieee->atm_swbw), 0);
147 
148  ieee->wpax_type_set = 0;
149  ieee->wpa_enabled = 0;
150  ieee->tkip_countermeasures = 0;
151  ieee->drop_unencrypted = 0;
152  ieee->privacy_invoked = 0;
153  ieee->ieee802_1x = 1;
154  ieee->raw_tx = 0;
155  //ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
156  ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
157 
159 
160  ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
161  if (ieee->pHTInfo == NULL)
162  {
163  IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
164  goto failed;
165  }
167  HTInitializeHTInfo(ieee); //may move to other place.
168  TSInitialize(ieee);
169 
170  for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
171  INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
172 
173  for (i = 0; i < 17; i++) {
174  ieee->last_rxseq_num[i] = -1;
175  ieee->last_rxfrag_num[i] = -1;
176  ieee->last_packet_time[i] = 0;
177  }
178 
179 //These function were added to load crypte module autoly
183 
184  return dev;
185 
186  failed:
187  if (dev)
188  free_netdev(dev);
189 
190  return NULL;
191 }
192 
193 
195 {
196  struct ieee80211_device *ieee = netdev_priv(dev);
197  int i;
198  //struct list_head *p, *q;
199 // del_timer_sync(&ieee->SwBwTimer);
200  kfree(ieee->pHTInfo);
201  ieee->pHTInfo = NULL;
202  RemoveAllTS(ieee);
206 
207  for (i = 0; i < WEP_KEYS; i++) {
208  struct ieee80211_crypt_data *crypt = ieee->crypt[i];
209  if (crypt) {
210  if (crypt->ops)
211  crypt->ops->deinit(crypt->priv);
212  kfree(crypt);
213  ieee->crypt[i] = NULL;
214  }
215  }
216 
217  ieee80211_networks_free(ieee);
218  free_netdev(dev);
219 }
220 
221 #ifdef CONFIG_IEEE80211_DEBUG
222 
224 static int debug = \
225  // IEEE80211_DL_INFO |
226  // IEEE80211_DL_WX |
227  // IEEE80211_DL_SCAN |
228  // IEEE80211_DL_STATE |
229  // IEEE80211_DL_MGMT |
230  // IEEE80211_DL_FRAG |
231  // IEEE80211_DL_EAP |
232  // IEEE80211_DL_DROP |
233  // IEEE80211_DL_TX |
234  // IEEE80211_DL_RX |
235  //IEEE80211_DL_QOS |
236  // IEEE80211_DL_HT |
237  // IEEE80211_DL_TS |
238 // IEEE80211_DL_BA |
239  // IEEE80211_DL_REORDER|
240 // IEEE80211_DL_TRACE |
241  //IEEE80211_DL_DATA |
242  IEEE80211_DL_ERR //awayls open this flags to show error out
243  ;
245 
246 static int show_debug_level(char *page, char **start, off_t offset,
247  int count, int *eof, void *data)
248 {
249  return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
250 }
251 
252 static int store_debug_level(struct file *file, const char *buffer,
253  unsigned long count, void *data)
254 {
255  char buf[] = "0x00000000";
256  unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
257  char *p = (char *)buf;
258  unsigned long val;
259 
260  if (copy_from_user(buf, buffer, len))
261  return count;
262  buf[len] = 0;
263  if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
264  p++;
265  if (p[0] == 'x' || p[0] == 'X')
266  p++;
267  val = simple_strtoul(p, &p, 16);
268  } else
269  val = simple_strtoul(p, &p, 10);
270  if (p == buf)
272  ": %s is not in hex or decimal form.\n", buf);
273  else
274  ieee80211_debug_level = val;
275 
276  return strnlen(buf, count);
277 }
278 
280 {
281  struct proc_dir_entry *e;
282 
283  ieee80211_debug_level = debug;
284 
285  ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
286  if (ieee80211_proc == NULL) {
287  IEEE80211_ERROR("Unable to create " DRV_NAME
288  " proc directory\n");
289  return -EIO;
290  }
291  e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
292  ieee80211_proc);
293  if (!e) {
295  ieee80211_proc = NULL;
296  return -EIO;
297  }
298  e->read_proc = show_debug_level;
299  e->write_proc = store_debug_level;
300  e->data = NULL;
301 
302  return 0;
303 }
304 
306 {
307  if (ieee80211_proc) {
308  remove_proc_entry("debug_level", ieee80211_proc);
310  ieee80211_proc = NULL;
311  }
312 }
313 
314 #include <linux/moduleparam.h>
315 module_param(debug, int, 0444);
316 MODULE_PARM_DESC(debug, "debug output mask");
317 #endif