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