Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /******************************************************************************
0003 
0004   Copyright(c) 2005 Intel Corporation. All rights reserved.
0005 
0006 
0007   Contact Information:
0008   Intel Linux Wireless <ilw@linux.intel.com>
0009   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0010 
0011 ******************************************************************************/
0012 #include <linux/compiler.h>
0013 #include <linux/errno.h>
0014 #include <linux/if_arp.h>
0015 #include <linux/in6.h>
0016 #include <linux/in.h>
0017 #include <linux/ip.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/netdevice.h>
0021 #include <linux/proc_fs.h>
0022 #include <linux/skbuff.h>
0023 #include <linux/tcp.h>
0024 #include <linux/types.h>
0025 #include <linux/wireless.h>
0026 #include <linux/etherdevice.h>
0027 #include <linux/uaccess.h>
0028 
0029 #include "libipw.h"
0030 
0031 int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel)
0032 {
0033     int i;
0034 
0035     /* Driver needs to initialize the geography map before using
0036      * these helper functions */
0037     if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
0038         return 0;
0039 
0040     if (ieee->freq_band & LIBIPW_24GHZ_BAND)
0041         for (i = 0; i < ieee->geo.bg_channels; i++)
0042             /* NOTE: If G mode is currently supported but
0043              * this is a B only channel, we don't see it
0044              * as valid. */
0045             if ((ieee->geo.bg[i].channel == channel) &&
0046                 !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) &&
0047                 (!(ieee->mode & IEEE_G) ||
0048                  !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY)))
0049                 return LIBIPW_24GHZ_BAND;
0050 
0051     if (ieee->freq_band & LIBIPW_52GHZ_BAND)
0052         for (i = 0; i < ieee->geo.a_channels; i++)
0053             if ((ieee->geo.a[i].channel == channel) &&
0054                 !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID))
0055                 return LIBIPW_52GHZ_BAND;
0056 
0057     return 0;
0058 }
0059 
0060 int libipw_channel_to_index(struct libipw_device *ieee, u8 channel)
0061 {
0062     int i;
0063 
0064     /* Driver needs to initialize the geography map before using
0065      * these helper functions */
0066     if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
0067         return -1;
0068 
0069     if (ieee->freq_band & LIBIPW_24GHZ_BAND)
0070         for (i = 0; i < ieee->geo.bg_channels; i++)
0071             if (ieee->geo.bg[i].channel == channel)
0072                 return i;
0073 
0074     if (ieee->freq_band & LIBIPW_52GHZ_BAND)
0075         for (i = 0; i < ieee->geo.a_channels; i++)
0076             if (ieee->geo.a[i].channel == channel)
0077                 return i;
0078 
0079     return -1;
0080 }
0081 
0082 u32 libipw_channel_to_freq(struct libipw_device * ieee, u8 channel)
0083 {
0084     const struct libipw_channel * ch;
0085 
0086     /* Driver needs to initialize the geography map before using
0087      * these helper functions */
0088     if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
0089         return 0;
0090 
0091     ch = libipw_get_channel(ieee, channel);
0092     if (!ch->channel)
0093         return 0;
0094     return ch->freq;
0095 }
0096 
0097 u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq)
0098 {
0099     int i;
0100 
0101     /* Driver needs to initialize the geography map before using
0102      * these helper functions */
0103     if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
0104         return 0;
0105 
0106     freq /= 100000;
0107 
0108     if (ieee->freq_band & LIBIPW_24GHZ_BAND)
0109         for (i = 0; i < ieee->geo.bg_channels; i++)
0110             if (ieee->geo.bg[i].freq == freq)
0111                 return ieee->geo.bg[i].channel;
0112 
0113     if (ieee->freq_band & LIBIPW_52GHZ_BAND)
0114         for (i = 0; i < ieee->geo.a_channels; i++)
0115             if (ieee->geo.a[i].freq == freq)
0116                 return ieee->geo.a[i].channel;
0117 
0118     return 0;
0119 }
0120 
0121 void libipw_set_geo(struct libipw_device *ieee,
0122               const struct libipw_geo *geo)
0123 {
0124     memcpy(ieee->geo.name, geo->name, 3);
0125     ieee->geo.name[3] = '\0';
0126     ieee->geo.bg_channels = geo->bg_channels;
0127     ieee->geo.a_channels = geo->a_channels;
0128     memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
0129            sizeof(struct libipw_channel));
0130     memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
0131            sizeof(struct libipw_channel));
0132 }
0133 
0134 const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee)
0135 {
0136     return &ieee->geo;
0137 }
0138 
0139 u8 libipw_get_channel_flags(struct libipw_device * ieee, u8 channel)
0140 {
0141     int index = libipw_channel_to_index(ieee, channel);
0142 
0143     if (index == -1)
0144         return LIBIPW_CH_INVALID;
0145 
0146     if (channel <= LIBIPW_24GHZ_CHANNELS)
0147         return ieee->geo.bg[index].flags;
0148 
0149     return ieee->geo.a[index].flags;
0150 }
0151 
0152 static const struct libipw_channel bad_channel = {
0153     .channel = 0,
0154     .flags = LIBIPW_CH_INVALID,
0155     .max_power = 0,
0156 };
0157 
0158 const struct libipw_channel *libipw_get_channel(struct libipw_device
0159                               *ieee, u8 channel)
0160 {
0161     int index = libipw_channel_to_index(ieee, channel);
0162 
0163     if (index == -1)
0164         return &bad_channel;
0165 
0166     if (channel <= LIBIPW_24GHZ_CHANNELS)
0167         return &ieee->geo.bg[index];
0168 
0169     return &ieee->geo.a[index];
0170 }
0171 
0172 EXPORT_SYMBOL(libipw_get_channel);
0173 EXPORT_SYMBOL(libipw_get_channel_flags);
0174 EXPORT_SYMBOL(libipw_is_valid_channel);
0175 EXPORT_SYMBOL(libipw_freq_to_channel);
0176 EXPORT_SYMBOL(libipw_channel_to_freq);
0177 EXPORT_SYMBOL(libipw_channel_to_index);
0178 EXPORT_SYMBOL(libipw_set_geo);
0179 EXPORT_SYMBOL(libipw_get_geo);