1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <linux/compiler.h>
34
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/version.h>
50#include <linux/wireless.h>
51#include <linux/etherdevice.h>
52#include <asm/uaccess.h>
53#include <net/arp.h>
54#include <net/net_namespace.h>
55
56#include "ieee80211.h"
57
58MODULE_DESCRIPTION("802.11 data/management/control stack");
59MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
60MODULE_LICENSE("GPL");
61
62#define DRV_NAME "ieee80211"
63
64static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
65{
66 if (ieee->networks)
67 return 0;
68
69 ieee->networks = kmalloc(
70 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL);
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
74 ieee->dev->name);
75 return -ENOMEM;
76 }
77
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
80
81 return 0;
82}
83
84static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
85{
86 if (!ieee->networks)
87 return;
88 kfree(ieee->networks);
89 ieee->networks = NULL;
90}
91
92static inline void ieee80211_networks_initialize(struct ieee80211_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, &ieee->network_free_list);
100}
101
102
103struct net_device *alloc_ieee80211(int sizeof_priv)
104{
105 struct ieee80211_device *ieee;
106 struct net_device *dev;
107 int i,err;
108
109 IEEE80211_DEBUG_INFO("Initializing...\n");
110
111 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
112 if (!dev) {
113 IEEE80211_ERROR("Unable to network device.\n");
114 goto failed;
115 }
116 ieee = netdev_priv(dev);
117
118 ieee->dev = dev;
119
120 err = ieee80211_networks_allocate(ieee);
121 if (err) {
122 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
123 err);
124 goto failed;
125 }
126 ieee80211_networks_initialize(ieee);
127
128
129 ieee->fts = DEFAULT_FTS;
130 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
131 ieee->open_wep = 1;
132
133
134 ieee->host_encrypt = 1;
135 ieee->host_decrypt = 1;
136 ieee->ieee802_1x = 1;
137
138 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
139 init_timer(&ieee->crypt_deinit_timer);
140 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
141 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
142
143 spin_lock_init(&ieee->lock);
144 spin_lock_init(&ieee->wpax_suitlist_lock);
145
146 ieee->wpax_type_set = 0;
147 ieee->wpa_enabled = 0;
148 ieee->tkip_countermeasures = 0;
149 ieee->drop_unencrypted = 0;
150 ieee->privacy_invoked = 0;
151 ieee->ieee802_1x = 1;
152 ieee->raw_tx = 0;
153
154 ieee80211_softmac_init(ieee);
155
156 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
157 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
158
159 for (i = 0; i < 17; i++) {
160 ieee->last_rxseq_num[i] = -1;
161 ieee->last_rxfrag_num[i] = -1;
162 ieee->last_packet_time[i] = 0;
163 }
164
165 ieee80211_tkip_null();
166 ieee80211_wep_null();
167 ieee80211_ccmp_null();
168 return dev;
169
170 failed:
171 if (dev)
172 free_netdev(dev);
173 return NULL;
174}
175
176
177void free_ieee80211(struct net_device *dev)
178{
179 struct ieee80211_device *ieee = netdev_priv(dev);
180
181 int i;
182 struct list_head *p, *q;
183
184
185 ieee80211_softmac_free(ieee);
186 del_timer_sync(&ieee->crypt_deinit_timer);
187 ieee80211_crypt_deinit_entries(ieee, 1);
188
189 for (i = 0; i < WEP_KEYS; i++) {
190 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
191 if (crypt) {
192 if (crypt->ops)
193 crypt->ops->deinit(crypt->priv);
194 kfree(crypt);
195 ieee->crypt[i] = NULL;
196 }
197 }
198
199 ieee80211_networks_free(ieee);
200
201 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
202 list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
203 kfree(list_entry(p, struct ieee_ibss_seq, list));
204 list_del(p);
205 }
206 }
207
208
209 free_netdev(dev);
210}
211