118056f34SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
218056f34SGreg Kroah-Hartman /*
3a959dec1SDerek Robson  * Copyright(c) 2004 Intel Corporation. All rights reserved.
4a959dec1SDerek Robson  *
5a959dec1SDerek Robson  * Portions of this file are based on the WEP enablement code provided by the
6a959dec1SDerek Robson  * Host AP project hostap-drivers v0.1.3
7a959dec1SDerek Robson  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8a959dec1SDerek Robson  * <jkmaline@cc.hut.fi>
9a959dec1SDerek Robson  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10a959dec1SDerek Robson  *
11a959dec1SDerek Robson  * Contact Information:
12a959dec1SDerek Robson  * James P. Ketrenos <ipw2100-admin@linux.intel.com>
13a959dec1SDerek Robson  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
1418056f34SGreg Kroah-Hartman  */
1594a79942SLarry Finger 
1694a79942SLarry Finger #include <linux/compiler.h>
1794a79942SLarry Finger #include <linux/errno.h>
1894a79942SLarry Finger #include <linux/if_arp.h>
1994a79942SLarry Finger #include <linux/in6.h>
2094a79942SLarry Finger #include <linux/in.h>
2194a79942SLarry Finger #include <linux/ip.h>
2294a79942SLarry Finger #include <linux/kernel.h>
2394a79942SLarry Finger #include <linux/module.h>
2494a79942SLarry Finger #include <linux/netdevice.h>
2594a79942SLarry Finger #include <linux/pci.h>
2694a79942SLarry Finger #include <linux/proc_fs.h>
2794a79942SLarry Finger #include <linux/skbuff.h>
2894a79942SLarry Finger #include <linux/slab.h>
2994a79942SLarry Finger #include <linux/tcp.h>
3094a79942SLarry Finger #include <linux/types.h>
3194a79942SLarry Finger #include <linux/wireless.h>
3294a79942SLarry Finger #include <linux/etherdevice.h>
338567829aSLarry Finger #include <linux/uaccess.h>
3494a79942SLarry Finger #include <net/arp.h>
3594a79942SLarry Finger #include "rtllib.h"
3694a79942SLarry Finger 
37d37e0208SSean MacLennan u32 rt_global_debug_component = COMP_ERR;
38d37e0208SSean MacLennan EXPORT_SYMBOL(rt_global_debug_component);
39d37e0208SSean MacLennan 
rtllib_networks_allocate(struct rtllib_device * ieee)4094a79942SLarry Finger static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
4194a79942SLarry Finger {
4294a79942SLarry Finger 	if (ieee->networks)
4394a79942SLarry Finger 		return 0;
4494a79942SLarry Finger 
45749f3c05SShraddha Barke 	ieee->networks = kcalloc(MAX_NETWORK_COUNT,
46749f3c05SShraddha Barke 				 sizeof(struct rtllib_network), GFP_KERNEL);
47b6b0012cSQuentin Lambert 	if (!ieee->networks)
4894a79942SLarry Finger 		return -ENOMEM;
4994a79942SLarry Finger 
5094a79942SLarry Finger 	return 0;
5194a79942SLarry Finger }
5294a79942SLarry Finger 
rtllib_networks_free(struct rtllib_device * ieee)5394a79942SLarry Finger static inline void rtllib_networks_free(struct rtllib_device *ieee)
5494a79942SLarry Finger {
5594a79942SLarry Finger 	if (!ieee->networks)
5694a79942SLarry Finger 		return;
5794a79942SLarry Finger 	kfree(ieee->networks);
5894a79942SLarry Finger 	ieee->networks = NULL;
5994a79942SLarry Finger }
6094a79942SLarry Finger 
rtllib_networks_initialize(struct rtllib_device * ieee)6194a79942SLarry Finger static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
6294a79942SLarry Finger {
6394a79942SLarry Finger 	int i;
6494a79942SLarry Finger 
6594a79942SLarry Finger 	INIT_LIST_HEAD(&ieee->network_free_list);
6694a79942SLarry Finger 	INIT_LIST_HEAD(&ieee->network_list);
6794a79942SLarry Finger 	for (i = 0; i < MAX_NETWORK_COUNT; i++)
688567829aSLarry Finger 		list_add_tail(&ieee->networks[i].list,
698567829aSLarry Finger 			      &ieee->network_free_list);
7094a79942SLarry Finger }
7194a79942SLarry Finger 
alloc_rtllib(int sizeof_priv)7294a79942SLarry Finger struct net_device *alloc_rtllib(int sizeof_priv)
7394a79942SLarry Finger {
7494a79942SLarry Finger 	struct rtllib_device *ieee = NULL;
7594a79942SLarry Finger 	struct net_device *dev;
7694a79942SLarry Finger 	int i, err;
7794a79942SLarry Finger 
78def16d2eSMateusz Kulikowski 	pr_debug("rtllib: Initializing...\n");
7994a79942SLarry Finger 
8094a79942SLarry Finger 	dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
8194a79942SLarry Finger 	if (!dev) {
82f0dddb1dSMateusz Kulikowski 		pr_err("Unable to allocate net_device.\n");
8349d74d70SHimangi Saraogi 		return NULL;
8494a79942SLarry Finger 	}
8594a79942SLarry Finger 	ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
8694a79942SLarry Finger 	ieee->dev = dev;
8794a79942SLarry Finger 
8894a79942SLarry Finger 	err = rtllib_networks_allocate(ieee);
8994a79942SLarry Finger 	if (err) {
90f0dddb1dSMateusz Kulikowski 		pr_err("Unable to allocate beacon storage: %d\n", err);
91e730cd57SYang Yingliang 		goto free_netdev;
9294a79942SLarry Finger 	}
9394a79942SLarry Finger 	rtllib_networks_initialize(ieee);
9494a79942SLarry Finger 
9594a79942SLarry Finger 	/* Default fragmentation threshold is maximum payload size */
9694a79942SLarry Finger 	ieee->fts = DEFAULT_FTS;
9794a79942SLarry Finger 	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
9894a79942SLarry Finger 	ieee->open_wep = 1;
9994a79942SLarry Finger 
10094a79942SLarry Finger 	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
10194a79942SLarry Finger 
10294a79942SLarry Finger 	ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
10394a79942SLarry Finger 
10494a79942SLarry Finger 	spin_lock_init(&ieee->lock);
10594a79942SLarry Finger 	spin_lock_init(&ieee->wpax_suitlist_lock);
10694a79942SLarry Finger 	spin_lock_init(&ieee->reorder_spinlock);
107f369953dSAaron Lawrence 	atomic_set(&ieee->atm_swbw, 0);
10894a79942SLarry Finger 
1093b148be0SSean MacLennan 	/* SAM FIXME */
1103b148be0SSean MacLennan 	lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
1113b148be0SSean MacLennan 
11294a79942SLarry Finger 	ieee->wpa_enabled = 0;
11394a79942SLarry Finger 	ieee->tkip_countermeasures = 0;
11494a79942SLarry Finger 	ieee->drop_unencrypted = 0;
11594a79942SLarry Finger 	ieee->privacy_invoked = 0;
11694a79942SLarry Finger 	ieee->ieee802_1x = 1;
11794a79942SLarry Finger 	ieee->raw_tx = 0;
11894a79942SLarry Finger 	ieee->hwsec_active = 0;
11994a79942SLarry Finger 
1205ea04480SLarry Finger 	memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
121e730cd57SYang Yingliang 	err = rtllib_softmac_init(ieee);
122e730cd57SYang Yingliang 	if (err)
123e730cd57SYang Yingliang 		goto free_crypt_info;
12494a79942SLarry Finger 
125*ccdbe14bSPhilipp Hortmann 	ieee->ht_info = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
126*ccdbe14bSPhilipp Hortmann 	if (!ieee->ht_info)
127e730cd57SYang Yingliang 		goto free_softmac;
128b6b0012cSQuentin Lambert 
12994a79942SLarry Finger 	HTUpdateDefaultSetting(ieee);
13094a79942SLarry Finger 	HTInitializeHTInfo(ieee);
13194a79942SLarry Finger 	TSInitialize(ieee);
13294a79942SLarry Finger 	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
13394a79942SLarry Finger 		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
13494a79942SLarry Finger 
13594a79942SLarry Finger 	for (i = 0; i < 17; i++) {
13694a79942SLarry Finger 		ieee->last_rxseq_num[i] = -1;
13794a79942SLarry Finger 		ieee->last_rxfrag_num[i] = -1;
13894a79942SLarry Finger 		ieee->last_packet_time[i] = 0;
13994a79942SLarry Finger 	}
14094a79942SLarry Finger 
14194a79942SLarry Finger 	return dev;
14294a79942SLarry Finger 
143e730cd57SYang Yingliang free_softmac:
144e730cd57SYang Yingliang 	rtllib_softmac_free(ieee);
145e730cd57SYang Yingliang free_crypt_info:
146e730cd57SYang Yingliang 	lib80211_crypt_info_free(&ieee->crypt_info);
147e730cd57SYang Yingliang 	rtllib_networks_free(ieee);
148e730cd57SYang Yingliang free_netdev:
14994a79942SLarry Finger 	free_netdev(dev);
150e730cd57SYang Yingliang 
15194a79942SLarry Finger 	return NULL;
15294a79942SLarry Finger }
1533b28499cSSean MacLennan EXPORT_SYMBOL(alloc_rtllib);
15494a79942SLarry Finger 
free_rtllib(struct net_device * dev)15594a79942SLarry Finger void free_rtllib(struct net_device *dev)
15694a79942SLarry Finger {
1578567829aSLarry Finger 	struct rtllib_device *ieee = (struct rtllib_device *)
1588567829aSLarry Finger 				      netdev_priv_rsl(dev);
159d7613e53SLarry Finger 
160*ccdbe14bSPhilipp Hortmann 	kfree(ieee->ht_info);
16194a79942SLarry Finger 	rtllib_softmac_free(ieee);
1620ddcf5fdSSean MacLennan 
1633b148be0SSean MacLennan 	lib80211_crypt_info_free(&ieee->crypt_info);
16494a79942SLarry Finger 
16594a79942SLarry Finger 	rtllib_networks_free(ieee);
16694a79942SLarry Finger 	free_netdev(dev);
16794a79942SLarry Finger }
1683b28499cSSean MacLennan EXPORT_SYMBOL(free_rtllib);
16994a79942SLarry Finger 
rtllib_init(void)170cf8ab8cfSRashika Kheria static int __init rtllib_init(void)
17194a79942SLarry Finger {
17294a79942SLarry Finger 	return 0;
17394a79942SLarry Finger }
17494a79942SLarry Finger 
rtllib_exit(void)175cf8ab8cfSRashika Kheria static void __exit rtllib_exit(void)
17694a79942SLarry Finger {
17794a79942SLarry Finger }
178d37e0208SSean MacLennan 
179d37e0208SSean MacLennan module_init(rtllib_init);
180d37e0208SSean MacLennan module_exit(rtllib_exit);
181d37e0208SSean MacLennan 
182d37e0208SSean MacLennan MODULE_LICENSE("GPL");
183