1/****************************************************************************** 2 3 Copyright(c) 2005 Intel Corporation. All rights reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2 of the GNU General Public License as 7 published by the Free Software Foundation. 8 9 This program is distributed in the hope that it will be useful, but WITHOUT 10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 more details. 13 14 You should have received a copy of the GNU General Public License along with 15 this program; if not, write to the Free Software Foundation, Inc., 59 16 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 The full GNU General Public License is included in this distribution in the 19 file called LICENSE. 20 21 Contact Information: 22 Intel Linux Wireless <ilw@linux.intel.com> 23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24 25******************************************************************************/ 26#include <linux/compiler.h> 27#include <linux/errno.h> 28#include <linux/if_arp.h> 29#include <linux/in6.h> 30#include <linux/in.h> 31#include <linux/ip.h> 32#include <linux/kernel.h> 33#include <linux/module.h> 34#include <linux/netdevice.h> 35#include <linux/proc_fs.h> 36#include <linux/skbuff.h> 37#include <linux/tcp.h> 38#include <linux/types.h> 39#include <linux/wireless.h> 40#include <linux/etherdevice.h> 41#include <asm/uaccess.h> 42 43#include "libipw.h" 44 45int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel) 46{ 47 int i; 48 49 /* Driver needs to initialize the geography map before using 50 * these helper functions */ 51 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 52 return 0; 53 54 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 55 for (i = 0; i < ieee->geo.bg_channels; i++) 56 /* NOTE: If G mode is currently supported but 57 * this is a B only channel, we don't see it 58 * as valid. */ 59 if ((ieee->geo.bg[i].channel == channel) && 60 !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) && 61 (!(ieee->mode & IEEE_G) || 62 !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY))) 63 return LIBIPW_24GHZ_BAND; 64 65 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 66 for (i = 0; i < ieee->geo.a_channels; i++) 67 if ((ieee->geo.a[i].channel == channel) && 68 !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID)) 69 return LIBIPW_52GHZ_BAND; 70 71 return 0; 72} 73 74int libipw_channel_to_index(struct libipw_device *ieee, u8 channel) 75{ 76 int i; 77 78 /* Driver needs to initialize the geography map before using 79 * these helper functions */ 80 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 81 return -1; 82 83 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 84 for (i = 0; i < ieee->geo.bg_channels; i++) 85 if (ieee->geo.bg[i].channel == channel) 86 return i; 87 88 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 89 for (i = 0; i < ieee->geo.a_channels; i++) 90 if (ieee->geo.a[i].channel == channel) 91 return i; 92 93 return -1; 94} 95 96u32 libipw_channel_to_freq(struct libipw_device * ieee, u8 channel) 97{ 98 const struct libipw_channel * ch; 99 100 /* Driver needs to initialize the geography map before using 101 * these helper functions */ 102 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 103 return 0; 104 105 ch = libipw_get_channel(ieee, channel); 106 if (!ch->channel) 107 return 0; 108 return ch->freq; 109} 110 111u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) 112{ 113 int i; 114 115 /* Driver needs to initialize the geography map before using 116 * these helper functions */ 117 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 118 return 0; 119 120 freq /= 100000; 121 122 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 123 for (i = 0; i < ieee->geo.bg_channels; i++) 124 if (ieee->geo.bg[i].freq == freq) 125 return ieee->geo.bg[i].channel; 126 127 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 128 for (i = 0; i < ieee->geo.a_channels; i++) 129 if (ieee->geo.a[i].freq == freq) 130 return ieee->geo.a[i].channel; 131 132 return 0; 133} 134 135void libipw_set_geo(struct libipw_device *ieee, 136 const struct libipw_geo *geo) 137{ 138 memcpy(ieee->geo.name, geo->name, 3); 139 ieee->geo.name[3] = '\0'; 140 ieee->geo.bg_channels = geo->bg_channels; 141 ieee->geo.a_channels = geo->a_channels; 142 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * 143 sizeof(struct libipw_channel)); 144 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * 145 sizeof(struct libipw_channel)); 146} 147 148const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 149{ 150 return &ieee->geo; 151} 152 153u8 libipw_get_channel_flags(struct libipw_device * ieee, u8 channel) 154{ 155 int index = libipw_channel_to_index(ieee, channel); 156 157 if (index == -1) 158 return LIBIPW_CH_INVALID; 159 160 if (channel <= LIBIPW_24GHZ_CHANNELS) 161 return ieee->geo.bg[index].flags; 162 163 return ieee->geo.a[index].flags; 164} 165 166static const struct libipw_channel bad_channel = { 167 .channel = 0, 168 .flags = LIBIPW_CH_INVALID, 169 .max_power = 0, 170}; 171 172const struct libipw_channel *libipw_get_channel(struct libipw_device 173 *ieee, u8 channel) 174{ 175 int index = libipw_channel_to_index(ieee, channel); 176 177 if (index == -1) 178 return &bad_channel; 179 180 if (channel <= LIBIPW_24GHZ_CHANNELS) 181 return &ieee->geo.bg[index]; 182 183 return &ieee->geo.a[index]; 184} 185 186EXPORT_SYMBOL(libipw_get_channel); 187EXPORT_SYMBOL(libipw_get_channel_flags); 188EXPORT_SYMBOL(libipw_is_valid_channel); 189EXPORT_SYMBOL(libipw_freq_to_channel); 190EXPORT_SYMBOL(libipw_channel_to_freq); 191EXPORT_SYMBOL(libipw_channel_to_index); 192EXPORT_SYMBOL(libipw_set_geo); 193EXPORT_SYMBOL(libipw_get_geo); 194