1 // SPDX-License-Identifier: GPL-2.0-only 2 /****************************************************************************** 3 4 Copyright(c) 2005 Intel Corporation. All rights reserved. 5 6 7 Contact Information: 8 Intel Linux Wireless <ilw@linux.intel.com> 9 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 10 11 ******************************************************************************/ 12 #include <linux/compiler.h> 13 #include <linux/errno.h> 14 #include <linux/if_arp.h> 15 #include <linux/in6.h> 16 #include <linux/in.h> 17 #include <linux/ip.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/netdevice.h> 21 #include <linux/proc_fs.h> 22 #include <linux/skbuff.h> 23 #include <linux/tcp.h> 24 #include <linux/types.h> 25 #include <linux/wireless.h> 26 #include <linux/etherdevice.h> 27 #include <linux/uaccess.h> 28 29 #include "libipw.h" 30 31 int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel) 32 { 33 int i; 34 35 /* Driver needs to initialize the geography map before using 36 * these helper functions */ 37 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 38 return 0; 39 40 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 41 for (i = 0; i < ieee->geo.bg_channels; i++) 42 /* NOTE: If G mode is currently supported but 43 * this is a B only channel, we don't see it 44 * as valid. */ 45 if ((ieee->geo.bg[i].channel == channel) && 46 !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) && 47 (!(ieee->mode & IEEE_G) || 48 !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY))) 49 return LIBIPW_24GHZ_BAND; 50 51 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 52 for (i = 0; i < ieee->geo.a_channels; i++) 53 if ((ieee->geo.a[i].channel == channel) && 54 !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID)) 55 return LIBIPW_52GHZ_BAND; 56 57 return 0; 58 } 59 60 int libipw_channel_to_index(struct libipw_device *ieee, u8 channel) 61 { 62 int i; 63 64 /* Driver needs to initialize the geography map before using 65 * these helper functions */ 66 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 67 return -1; 68 69 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 70 for (i = 0; i < ieee->geo.bg_channels; i++) 71 if (ieee->geo.bg[i].channel == channel) 72 return i; 73 74 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 75 for (i = 0; i < ieee->geo.a_channels; i++) 76 if (ieee->geo.a[i].channel == channel) 77 return i; 78 79 return -1; 80 } 81 82 u32 libipw_channel_to_freq(struct libipw_device * ieee, u8 channel) 83 { 84 const struct libipw_channel * ch; 85 86 /* Driver needs to initialize the geography map before using 87 * these helper functions */ 88 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 89 return 0; 90 91 ch = libipw_get_channel(ieee, channel); 92 if (!ch->channel) 93 return 0; 94 return ch->freq; 95 } 96 97 u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) 98 { 99 int i; 100 101 /* Driver needs to initialize the geography map before using 102 * these helper functions */ 103 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) 104 return 0; 105 106 freq /= 100000; 107 108 if (ieee->freq_band & LIBIPW_24GHZ_BAND) 109 for (i = 0; i < ieee->geo.bg_channels; i++) 110 if (ieee->geo.bg[i].freq == freq) 111 return ieee->geo.bg[i].channel; 112 113 if (ieee->freq_band & LIBIPW_52GHZ_BAND) 114 for (i = 0; i < ieee->geo.a_channels; i++) 115 if (ieee->geo.a[i].freq == freq) 116 return ieee->geo.a[i].channel; 117 118 return 0; 119 } 120 121 void libipw_set_geo(struct libipw_device *ieee, 122 const struct libipw_geo *geo) 123 { 124 memcpy(ieee->geo.name, geo->name, 3); 125 ieee->geo.name[3] = '\0'; 126 ieee->geo.bg_channels = geo->bg_channels; 127 ieee->geo.a_channels = geo->a_channels; 128 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * 129 sizeof(struct libipw_channel)); 130 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * 131 sizeof(struct libipw_channel)); 132 } 133 134 const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 135 { 136 return &ieee->geo; 137 } 138 139 u8 libipw_get_channel_flags(struct libipw_device * ieee, u8 channel) 140 { 141 int index = libipw_channel_to_index(ieee, channel); 142 143 if (index == -1) 144 return LIBIPW_CH_INVALID; 145 146 if (channel <= LIBIPW_24GHZ_CHANNELS) 147 return ieee->geo.bg[index].flags; 148 149 return ieee->geo.a[index].flags; 150 } 151 152 static const struct libipw_channel bad_channel = { 153 .channel = 0, 154 .flags = LIBIPW_CH_INVALID, 155 .max_power = 0, 156 }; 157 158 const struct libipw_channel *libipw_get_channel(struct libipw_device 159 *ieee, u8 channel) 160 { 161 int index = libipw_channel_to_index(ieee, channel); 162 163 if (index == -1) 164 return &bad_channel; 165 166 if (channel <= LIBIPW_24GHZ_CHANNELS) 167 return &ieee->geo.bg[index]; 168 169 return &ieee->geo.a[index]; 170 } 171 172 EXPORT_SYMBOL(libipw_get_channel); 173 EXPORT_SYMBOL(libipw_get_channel_flags); 174 EXPORT_SYMBOL(libipw_is_valid_channel); 175 EXPORT_SYMBOL(libipw_freq_to_channel); 176 EXPORT_SYMBOL(libipw_channel_to_freq); 177 EXPORT_SYMBOL(libipw_channel_to_index); 178 EXPORT_SYMBOL(libipw_set_geo); 179 EXPORT_SYMBOL(libipw_get_geo); 180