180 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************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-649710 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 using36 * 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 but43 * this is a B only channel, we don't see it44 * 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 using65 * 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 using87 * 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 using102 * 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_device159 *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);180