102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos/****************************************************************************** 202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos Copyright(c) 2005 Intel Corporation. All rights reserved. 402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos This program is free software; you can redistribute it and/or modify it 602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos under the terms of version 2 of the GNU General Public License as 702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos published by the Free Software Foundation. 802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos This program is distributed in the hope that it will be useful, but WITHOUT 1002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos more details. 1302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 1402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos You should have received a copy of the GNU General Public License along with 1502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos this program; if not, write to the Free Software Foundation, Inc., 59 1602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 1802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos The full GNU General Public License is included in this distribution in the 1902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos file called LICENSE. 2002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 2102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos Contact Information: 22c1eb2c82e5ccc9b691f737c3150e746c9af3ffabReinette Chatre Intel Linux Wireless <ilw@linux.intel.com> 2302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 2402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 2502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos******************************************************************************/ 2602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/compiler.h> 2702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/errno.h> 2802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/if_arp.h> 2902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/in6.h> 3002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/in.h> 3102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/ip.h> 3202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/kernel.h> 3302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/module.h> 3402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/netdevice.h> 3502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/proc_fs.h> 3602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/skbuff.h> 3702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/tcp.h> 3802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/types.h> 3902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/wireless.h> 4002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <linux/etherdevice.h> 4102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos#include <asm/uaccess.h> 4202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 43b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville#include "libipw.h" 4402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 45b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleint libipw_is_valid_channel(struct libipw_device *ieee, u8 channel) 4602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos{ 4702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos int i; 4802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 4902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos /* Driver needs to initialize the geography map before using 5002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos * these helper functions */ 5107981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 5207981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev return 0; 5302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 54b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_24GHZ_BAND) 5502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.bg_channels; i++) 5602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos /* NOTE: If G mode is currently supported but 5702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos * this is a B only channel, we don't see it 5802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos * as valid. */ 5902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos if ((ieee->geo.bg[i].channel == channel) && 60b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) && 6102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos (!(ieee->mode & IEEE_G) || 62b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY))) 63b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville return LIBIPW_24GHZ_BAND; 6402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 65b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_52GHZ_BAND) 6602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.a_channels; i++) 67d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi if ((ieee->geo.a[i].channel == channel) && 68b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID)) 69b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville return LIBIPW_52GHZ_BAND; 7002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 7102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return 0; 7202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos} 7302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 74b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleint libipw_channel_to_index(struct libipw_device *ieee, u8 channel) 7502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos{ 7602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos int i; 7702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 7802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos /* Driver needs to initialize the geography map before using 7902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos * these helper functions */ 8007981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 8107981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev return -1; 8202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 83b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_24GHZ_BAND) 8402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.bg_channels; i++) 8502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos if (ieee->geo.bg[i].channel == channel) 8602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return i; 8702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 88b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_52GHZ_BAND) 8902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.a_channels; i++) 9002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos if (ieee->geo.a[i].channel == channel) 9102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return i; 9202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 9302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return -1; 9402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos} 9502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 96b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleu32 libipw_channel_to_freq(struct libipw_device * ieee, u8 channel) 97f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger{ 98b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville const struct libipw_channel * ch; 99f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger 100f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger /* Driver needs to initialize the geography map before using 101f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger * these helper functions */ 102f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 103f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger return 0; 104f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger 105b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville ch = libipw_get_channel(ieee, channel); 106f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger if (!ch->channel) 107f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger return 0; 108f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger return ch->freq; 109f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger} 110f5cdf30618cf855c2043e5c0c131ebb120929864Larry Finger 111b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleu8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) 11202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos{ 11302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos int i; 11402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 11502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos /* Driver needs to initialize the geography map before using 11602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos * these helper functions */ 11707981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 11807981aa43f6aec32b875f360755ed3d14f9d5139Pete Zaitcev return 0; 11902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 12002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos freq /= 100000; 12102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 122b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_24GHZ_BAND) 12302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.bg_channels; i++) 12402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos if (ieee->geo.bg[i].freq == freq) 12502cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return ieee->geo.bg[i].channel; 12602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 127b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (ieee->freq_band & LIBIPW_52GHZ_BAND) 12802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos for (i = 0; i < ieee->geo.a_channels; i++) 12902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos if (ieee->geo.a[i].freq == freq) 13002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return ieee->geo.a[i].channel; 13102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 13202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return 0; 13302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos} 13402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 135b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleint libipw_set_geo(struct libipw_device *ieee, 136b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville const struct libipw_geo *geo) 13702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos{ 13802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos memcpy(ieee->geo.name, geo->name, 3); 13902cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos ieee->geo.name[3] = '\0'; 14002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos ieee->geo.bg_channels = geo->bg_channels; 14102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos ieee->geo.a_channels = geo->a_channels; 14202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * 143b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville sizeof(struct libipw_channel)); 14402cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * 145b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville sizeof(struct libipw_channel)); 14602cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return 0; 14702cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos} 14802cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 149b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleconst struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 15002cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos{ 15102cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos return &ieee->geo; 15202cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos} 15302cda6ae01814f58422c45259fb48136fbd7bcc1James Ketrenos 154b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleu8 libipw_get_channel_flags(struct libipw_device * ieee, u8 channel) 155d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi{ 156b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville int index = libipw_channel_to_index(ieee, channel); 157d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 158d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi if (index == -1) 159b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville return LIBIPW_CH_INVALID; 160d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 161b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (channel <= LIBIPW_24GHZ_CHANNELS) 162d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi return ieee->geo.bg[index].flags; 163d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 164d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi return ieee->geo.a[index].flags; 165d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi} 166d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 167b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvillestatic const struct libipw_channel bad_channel = { 168d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi .channel = 0, 169b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville .flags = LIBIPW_CH_INVALID, 170d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi .max_power = 0, 171d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi}; 172d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 173b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linvilleconst struct libipw_channel *libipw_get_channel(struct libipw_device 174d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi *ieee, u8 channel) 175d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi{ 176b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville int index = libipw_channel_to_index(ieee, channel); 177d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 178d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi if (index == -1) 179d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi return &bad_channel; 180d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 181b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. Linville if (channel <= LIBIPW_24GHZ_CHANNELS) 182d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi return &ieee->geo.bg[index]; 183d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 184d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi return &ieee->geo.a[index]; 185d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi} 186d128f6c176bff9c4929476e13132804321a6d5c5Zhu Yi 187b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_get_channel); 188b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_get_channel_flags); 189b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_is_valid_channel); 190b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_freq_to_channel); 191b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_channel_to_freq); 192b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_channel_to_index); 193b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_set_geo); 194b0a4e7d8a291de63f35b04464de9ab4a83d38a7cJohn W. LinvilleEXPORT_SYMBOL(libipw_get_geo); 195