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
8   <jkmaline@cc.hut.fi>
9   Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.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   The full GNU General Public License is included in this distribution in the
21   file called LICENSE.
22 
23   Contact Information:
24   James P. Ketrenos <ipw2100-admin@linux.intel.com>
25   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 
27 *******************************************************************************/
28 
29 #include <linux/compiler.h>
30 #include <linux/errno.h>
31 #include <linux/if_arp.h>
32 #include <linux/in6.h>
33 #include <linux/in.h>
34 #include <linux/ip.h>
35 #include <linux/kernel.h>
36 #include <linux/module.h>
37 #include <linux/netdevice.h>
38 #include <linux/pci.h>
39 #include <linux/proc_fs.h>
40 #include <linux/skbuff.h>
41 #include <linux/slab.h>
42 #include <linux/tcp.h>
43 #include <linux/types.h>
44 #include <linux/wireless.h>
45 #include <linux/etherdevice.h>
46 #include <linux/uaccess.h>
47 #include <net/arp.h>
48 
49 #include "rtllib.h"
50 
51 
52 u32 rt_global_debug_component = COMP_ERR;
53 EXPORT_SYMBOL(rt_global_debug_component);
54 
55 
56 
57 static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
58 {
59 	if (ieee->networks)
60 		return 0;
61 
62 	ieee->networks = kcalloc(MAX_NETWORK_COUNT,
63 				 sizeof(struct rtllib_network), GFP_KERNEL);
64 	if (!ieee->networks)
65 		return -ENOMEM;
66 
67 	return 0;
68 }
69 
70 static inline void rtllib_networks_free(struct rtllib_device *ieee)
71 {
72 	if (!ieee->networks)
73 		return;
74 	kfree(ieee->networks);
75 	ieee->networks = NULL;
76 }
77 
78 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
79 {
80 	int i;
81 
82 	INIT_LIST_HEAD(&ieee->network_free_list);
83 	INIT_LIST_HEAD(&ieee->network_list);
84 	for (i = 0; i < MAX_NETWORK_COUNT; i++)
85 		list_add_tail(&ieee->networks[i].list,
86 			      &ieee->network_free_list);
87 }
88 
89 struct net_device *alloc_rtllib(int sizeof_priv)
90 {
91 	struct rtllib_device *ieee = NULL;
92 	struct net_device *dev;
93 	int i, err;
94 
95 	pr_debug("rtllib: Initializing...\n");
96 
97 	dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
98 	if (!dev) {
99 		pr_err("Unable to allocate net_device.\n");
100 		return NULL;
101 	}
102 	ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
103 	memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
104 	ieee->dev = dev;
105 
106 	err = rtllib_networks_allocate(ieee);
107 	if (err) {
108 		pr_err("Unable to allocate beacon storage: %d\n", err);
109 		goto failed;
110 	}
111 	rtllib_networks_initialize(ieee);
112 
113 
114 	/* Default fragmentation threshold is maximum payload size */
115 	ieee->fts = DEFAULT_FTS;
116 	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
117 	ieee->open_wep = 1;
118 
119 	/* Default to enabling full open WEP with host based encrypt/decrypt */
120 	ieee->host_encrypt = 1;
121 	ieee->host_decrypt = 1;
122 	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
123 
124 	ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
125 
126 	spin_lock_init(&ieee->lock);
127 	spin_lock_init(&ieee->wpax_suitlist_lock);
128 	spin_lock_init(&ieee->reorder_spinlock);
129 	atomic_set(&(ieee->atm_swbw), 0);
130 
131 	/* SAM FIXME */
132 	lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
133 
134 	ieee->wpa_enabled = 0;
135 	ieee->tkip_countermeasures = 0;
136 	ieee->drop_unencrypted = 0;
137 	ieee->privacy_invoked = 0;
138 	ieee->ieee802_1x = 1;
139 	ieee->raw_tx = 0;
140 	ieee->hwsec_active = 0;
141 
142 	memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
143 	rtllib_softmac_init(ieee);
144 
145 	ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
146 	if (ieee->pHTInfo == NULL)
147 		return NULL;
148 
149 	HTUpdateDefaultSetting(ieee);
150 	HTInitializeHTInfo(ieee);
151 	TSInitialize(ieee);
152 	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
153 		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
154 
155 	for (i = 0; i < 17; i++) {
156 		ieee->last_rxseq_num[i] = -1;
157 		ieee->last_rxfrag_num[i] = -1;
158 		ieee->last_packet_time[i] = 0;
159 	}
160 
161 	return dev;
162 
163  failed:
164 	free_netdev(dev);
165 	return NULL;
166 }
167 EXPORT_SYMBOL(alloc_rtllib);
168 
169 void free_rtllib(struct net_device *dev)
170 {
171 	struct rtllib_device *ieee = (struct rtllib_device *)
172 				      netdev_priv_rsl(dev);
173 
174 	kfree(ieee->pHTInfo);
175 	ieee->pHTInfo = NULL;
176 	rtllib_softmac_free(ieee);
177 
178 	lib80211_crypt_info_free(&ieee->crypt_info);
179 
180 	rtllib_networks_free(ieee);
181 	free_netdev(dev);
182 }
183 EXPORT_SYMBOL(free_rtllib);
184 
185 static int __init rtllib_init(void)
186 {
187 	return 0;
188 }
189 
190 static void __exit rtllib_exit(void)
191 {
192 }
193 
194 module_init(rtllib_init);
195 module_exit(rtllib_exit);
196 
197 MODULE_LICENSE("GPL");
198