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
52u32 rt_global_debug_component = COMP_ERR;
53EXPORT_SYMBOL(rt_global_debug_component);
54
55
56
57static 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
70static 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
78static 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
89struct 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}
167EXPORT_SYMBOL(alloc_rtllib);
168
169void 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}
183EXPORT_SYMBOL(free_rtllib);
184
185static int __init rtllib_init(void)
186{
187	return 0;
188}
189
190static void __exit rtllib_exit(void)
191{
192}
193
194module_init(rtllib_init);
195module_exit(rtllib_exit);
196
197MODULE_LICENSE("GPL");
198