libipw_geo.c (4774B)
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 31int 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 60int 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 82u32 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 97u8 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 121void 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 134const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 135{ 136 return &ieee->geo; 137} 138 139u8 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 152static const struct libipw_channel bad_channel = { 153 .channel = 0, 154 .flags = LIBIPW_CH_INVALID, 155 .max_power = 0, 156}; 157 158const 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 172EXPORT_SYMBOL(libipw_get_channel); 173EXPORT_SYMBOL(libipw_get_channel_flags); 174EXPORT_SYMBOL(libipw_is_valid_channel); 175EXPORT_SYMBOL(libipw_freq_to_channel); 176EXPORT_SYMBOL(libipw_channel_to_freq); 177EXPORT_SYMBOL(libipw_channel_to_index); 178EXPORT_SYMBOL(libipw_set_geo); 179EXPORT_SYMBOL(libipw_get_geo);