linux/drivers/net/wireless/intel/ipw2x00/libipw_geo.c
<<
>>
Prefs
   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);
 180