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 <linux/uaccess.h> 42 43 #include "libipw.h" 44 45 int 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 74 int 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 96 u32 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 111 u8 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 135 void 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 148 const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 149 { 150 return &ieee->geo; 151 } 152 153 u8 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 166 static const struct libipw_channel bad_channel = { 167 .channel = 0, 168 .flags = LIBIPW_CH_INVALID, 169 .max_power = 0, 170 }; 171 172 const 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 186 EXPORT_SYMBOL(libipw_get_channel); 187 EXPORT_SYMBOL(libipw_get_channel_flags); 188 EXPORT_SYMBOL(libipw_is_valid_channel); 189 EXPORT_SYMBOL(libipw_freq_to_channel); 190 EXPORT_SYMBOL(libipw_channel_to_freq); 191 EXPORT_SYMBOL(libipw_channel_to_index); 192 EXPORT_SYMBOL(libipw_set_geo); 193 EXPORT_SYMBOL(libipw_get_geo); 194