libipw_module.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*******************************************************************************
  2. Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
  3. Portions of this file are based on the WEP enablement code provided by the
  4. Host AP project hostap-drivers v0.1.3
  5. Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  6. <j@w1.fi>
  7. Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
  8. This program is free software; you can redistribute it and/or modify it
  9. under the terms of version 2 of the GNU General Public License as
  10. published by the Free Software Foundation.
  11. This program is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. more details.
  15. You should have received a copy of the GNU General Public License along with
  16. this program; if not, write to the Free Software Foundation, Inc., 59
  17. Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. The full GNU General Public License is included in this distribution in the
  19. file called LICENSE.
  20. Contact Information:
  21. Intel Linux Wireless <ilw@linux.intel.com>
  22. Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  23. *******************************************************************************/
  24. #include <linux/compiler.h>
  25. #include <linux/errno.h>
  26. #include <linux/if_arp.h>
  27. #include <linux/in6.h>
  28. #include <linux/in.h>
  29. #include <linux/ip.h>
  30. #include <linux/kernel.h>
  31. #include <linux/module.h>
  32. #include <linux/netdevice.h>
  33. #include <linux/proc_fs.h>
  34. #include <linux/skbuff.h>
  35. #include <linux/slab.h>
  36. #include <linux/tcp.h>
  37. #include <linux/types.h>
  38. #include <linux/wireless.h>
  39. #include <linux/etherdevice.h>
  40. #include <asm/uaccess.h>
  41. #include <net/net_namespace.h>
  42. #include <net/arp.h>
  43. #include "libipw.h"
  44. #define DRV_DESCRIPTION "802.11 data/management/control stack"
  45. #define DRV_NAME "ieee80211"
  46. #define DRV_VERSION LIBIPW_VERSION
  47. #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
  48. MODULE_VERSION(DRV_VERSION);
  49. MODULE_DESCRIPTION(DRV_DESCRIPTION);
  50. MODULE_AUTHOR(DRV_COPYRIGHT);
  51. MODULE_LICENSE("GPL");
  52. static int libipw_networks_allocate(struct libipw_device *ieee)
  53. {
  54. if (ieee->networks)
  55. return 0;
  56. ieee->networks =
  57. kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
  58. GFP_KERNEL);
  59. if (!ieee->networks) {
  60. printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
  61. ieee->dev->name);
  62. return -ENOMEM;
  63. }
  64. return 0;
  65. }
  66. void libipw_network_reset(struct libipw_network *network)
  67. {
  68. if (!network)
  69. return;
  70. if (network->ibss_dfs) {
  71. kfree(network->ibss_dfs);
  72. network->ibss_dfs = NULL;
  73. }
  74. }
  75. static inline void libipw_networks_free(struct libipw_device *ieee)
  76. {
  77. int i;
  78. if (!ieee->networks)
  79. return;
  80. for (i = 0; i < MAX_NETWORK_COUNT; i++)
  81. if (ieee->networks[i].ibss_dfs)
  82. kfree(ieee->networks[i].ibss_dfs);
  83. kfree(ieee->networks);
  84. ieee->networks = NULL;
  85. }
  86. void libipw_networks_age(struct libipw_device *ieee,
  87. unsigned long age_secs)
  88. {
  89. struct libipw_network *network = NULL;
  90. unsigned long flags;
  91. unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
  92. spin_lock_irqsave(&ieee->lock, flags);
  93. list_for_each_entry(network, &ieee->network_list, list) {
  94. network->last_scanned -= age_jiffies;
  95. }
  96. spin_unlock_irqrestore(&ieee->lock, flags);
  97. }
  98. EXPORT_SYMBOL(libipw_networks_age);
  99. static void libipw_networks_initialize(struct libipw_device *ieee)
  100. {
  101. int i;
  102. INIT_LIST_HEAD(&ieee->network_free_list);
  103. INIT_LIST_HEAD(&ieee->network_list);
  104. for (i = 0; i < MAX_NETWORK_COUNT; i++)
  105. list_add_tail(&ieee->networks[i].list,
  106. &ieee->network_free_list);
  107. }
  108. int libipw_change_mtu(struct net_device *dev, int new_mtu)
  109. {
  110. if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
  111. return -EINVAL;
  112. dev->mtu = new_mtu;
  113. return 0;
  114. }
  115. EXPORT_SYMBOL(libipw_change_mtu);
  116. struct net_device *alloc_ieee80211(int sizeof_priv)
  117. {
  118. struct libipw_device *ieee;
  119. struct net_device *dev;
  120. int err;
  121. LIBIPW_DEBUG_INFO("Initializing...\n");
  122. dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
  123. if (!dev) {
  124. LIBIPW_ERROR("Unable to allocate network device.\n");
  125. goto failed;
  126. }
  127. ieee = netdev_priv(dev);
  128. ieee->dev = dev;
  129. err = libipw_networks_allocate(ieee);
  130. if (err) {
  131. LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
  132. goto failed_free_netdev;
  133. }
  134. libipw_networks_initialize(ieee);
  135. /* Default fragmentation threshold is maximum payload size */
  136. ieee->fts = DEFAULT_FTS;
  137. ieee->rts = DEFAULT_FTS;
  138. ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
  139. ieee->open_wep = 1;
  140. /* Default to enabling full open WEP with host based encrypt/decrypt */
  141. ieee->host_encrypt = 1;
  142. ieee->host_decrypt = 1;
  143. ieee->host_mc_decrypt = 1;
  144. /* Host fragementation in Open mode. Default is enabled.
  145. * Note: host fragmentation is always enabled if host encryption
  146. * is enabled. For cards can do hardware encryption, they must do
  147. * hardware fragmentation as well. So we don't need a variable
  148. * like host_enc_frag. */
  149. ieee->host_open_frag = 1;
  150. ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
  151. spin_lock_init(&ieee->lock);
  152. lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
  153. ieee->wpa_enabled = 0;
  154. ieee->drop_unencrypted = 0;
  155. ieee->privacy_invoked = 0;
  156. return dev;
  157. failed_free_netdev:
  158. free_netdev(dev);
  159. failed:
  160. return NULL;
  161. }
  162. void free_ieee80211(struct net_device *dev)
  163. {
  164. struct libipw_device *ieee = netdev_priv(dev);
  165. lib80211_crypt_info_free(&ieee->crypt_info);
  166. libipw_networks_free(ieee);
  167. free_netdev(dev);
  168. }
  169. #ifdef CONFIG_LIBIPW_DEBUG
  170. static int debug = 0;
  171. u32 libipw_debug_level = 0;
  172. EXPORT_SYMBOL_GPL(libipw_debug_level);
  173. static struct proc_dir_entry *libipw_proc = NULL;
  174. static int show_debug_level(char *page, char **start, off_t offset,
  175. int count, int *eof, void *data)
  176. {
  177. return snprintf(page, count, "0x%08X\n", libipw_debug_level);
  178. }
  179. static int store_debug_level(struct file *file, const char __user * buffer,
  180. unsigned long count, void *data)
  181. {
  182. char buf[] = "0x00000000\n";
  183. unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
  184. unsigned long val;
  185. if (copy_from_user(buf, buffer, len))
  186. return count;
  187. buf[len] = 0;
  188. if (sscanf(buf, "%li", &val) != 1)
  189. printk(KERN_INFO DRV_NAME
  190. ": %s is not in hex or decimal form.\n", buf);
  191. else
  192. libipw_debug_level = val;
  193. return strnlen(buf, len);
  194. }
  195. #endif /* CONFIG_LIBIPW_DEBUG */
  196. static int __init libipw_init(void)
  197. {
  198. #ifdef CONFIG_LIBIPW_DEBUG
  199. struct proc_dir_entry *e;
  200. libipw_debug_level = debug;
  201. libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
  202. if (libipw_proc == NULL) {
  203. LIBIPW_ERROR("Unable to create " DRV_NAME
  204. " proc directory\n");
  205. return -EIO;
  206. }
  207. e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
  208. libipw_proc);
  209. if (!e) {
  210. remove_proc_entry(DRV_NAME, init_net.proc_net);
  211. libipw_proc = NULL;
  212. return -EIO;
  213. }
  214. e->read_proc = show_debug_level;
  215. e->write_proc = store_debug_level;
  216. e->data = NULL;
  217. #endif /* CONFIG_LIBIPW_DEBUG */
  218. printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
  219. printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
  220. return 0;
  221. }
  222. static void __exit libipw_exit(void)
  223. {
  224. #ifdef CONFIG_LIBIPW_DEBUG
  225. if (libipw_proc) {
  226. remove_proc_entry("debug_level", libipw_proc);
  227. remove_proc_entry(DRV_NAME, init_net.proc_net);
  228. libipw_proc = NULL;
  229. }
  230. #endif /* CONFIG_LIBIPW_DEBUG */
  231. }
  232. #ifdef CONFIG_LIBIPW_DEBUG
  233. #include <linux/moduleparam.h>
  234. module_param(debug, int, 0444);
  235. MODULE_PARM_DESC(debug, "debug output mask");
  236. #endif /* CONFIG_LIBIPW_DEBUG */
  237. module_exit(libipw_exit);
  238. module_init(libipw_init);
  239. EXPORT_SYMBOL(alloc_ieee80211);
  240. EXPORT_SYMBOL(free_ieee80211);