This message contains the patch to add routine ieee80211_init_geo to the kernel, and a new flag
definition for the IEEE80211 codes. Note: I know that my mailer has messed up the white space by
converting all the tabs to spaces. The original files are OK. Larry
=====================================================================================
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index d5926bf..8a5dc0f 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -965,6 +965,7 @@ #define IEEE80211_52GHZ_CHANNELS (IEEE80
enum {
IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+ IEEE80211_CH_80211H_RULES = (1 << 1),
IEEE80211_CH_B_ONLY = (1 << 2),
IEEE80211_CH_NO_IBSS = (1 << 3),
IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
@@ -973,10 +974,10 @@ enum {
};
struct ieee80211_channel {
- u32 freq;
+ u32 freq; /* in MHz */
u8 channel;
u8 flags;
- u8 max_power;
+ u8 max_power; /* in dBm */
};
struct ieee80211_geo {
@@ -1260,6 +1261,9 @@ extern const struct ieee80211_geo *ieee8
extern int ieee80211_set_geo(struct ieee80211_device *ieee,
const struct ieee80211_geo *geo);
+extern int ieee80211_init_geo(struct ieee80211_device *ieee,
+ char * country, u8 outdoor);
+
extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
u8 channel);
extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
index 192243a..2e4806b 100644
--- a/net/ieee80211/ieee80211_geo.c
+++ b/net/ieee80211/ieee80211_geo.c
@@ -41,6 +41,7 @@ #include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
+#include <linux/delay.h>
#include <net/ieee80211.h>
@@ -133,6 +134,136 @@ int ieee80211_set_geo(struct ieee80211_d
return 0;
}
+static char ieee80211_country[10];
+static uint ieee80211_outdoor;
+static struct proc_dir_entry *ieee80211_geo_proc;
+static uint ieee80211_data_back;
+struct ieee80211_geo *geo;
+static uint bytes_xfer;
+
+static int show_geo_country(char *page, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ return snprintf(page, count, "%s %d\n", ieee80211_country,
ieee80211_outdoor);
+}
+
+static int store_geo_data(struct file *file, const char __user * buffer,
+ unsigned long count, void *data)
+{
+ unsigned long len = min((unsigned long)sizeof(struct ieee80211_geo) ,
count);
+ int i;
+
+ if (copy_from_user((geo + bytes_xfer), buffer, len)) {
+ IEEE80211_ERROR( "Error return from copy_from_user.\n");
+ return -EFAULT;
+ }
+ bytes_xfer += len;
+ if (bytes_xfer == sizeof(struct ieee80211_geo)) {
+ IEEE80211_DEBUG_INFO( "All data has been received.\n");
+ if (!geo->bg_channels && !geo->a_channels) { /* if no channels
specified - error */
+ IEEE80211_DEBUG_INFO( "No bg or a/h channels
specified.\n");
+ return count;
+ }
+ if (geo->bg_channels > IEEE80211_24GHZ_CHANNELS) { /* too many
bg channels */
+ IEEE80211_DEBUG_INFO( "Too many bg channels
specified.\n");
+ return count;
+ }
+ if (geo->a_channels > IEEE80211_52GHZ_CHANNELS) { /* too many a
channels */
+ IEEE80211_DEBUG_INFO( "Too many a/h channels
specified.\n");
+ return count;
+ }
+ for (i=0; i<geo->a_channels; i++) {
+ if (geo->a[i].channel < IEEE80211_52GHZ_MIN_CHANNEL ||
+ geo->a[i].channel > IEEE80211_52GHZ_MAX_CHANNEL)
+ return count; /* here if channel out of
range */
+ }
+ for (i=0; i<geo->bg_channels; i++) {
+ if (geo->bg[i].channel < IEEE80211_24GHZ_MIN_CHANNEL ||
+ geo->bg[i].channel > IEEE80211_24GHZ_MAX_CHANNEL)
+ return count; /* here if channel out of
range */
+ }
+ IEEE80211_DEBUG_INFO( "Data passed sanity checks.\n"); /* data
seems to be correct */
+ ieee80211_data_back = 0;
+ }
+ return count;
+}
+
+int ieee80211_init_geo(struct ieee80211_device *ieee,
+ char *country, u8 outdoor)
+{
+ int ret;
+ struct proc_dir_entry *e1, *e2;
+
+ static const struct ieee80211_geo ieee80211_geos[] = {
+ { /* Default parameters to be returned if daemon not running or other
error */
+ "---",
+ .a_channels = 0,
+ .bg_channels = 11,
+ .bg = {{.freq = 2412, .channel = 1, .max_power = 20},
+ {.freq = 2417, .channel = 2, .max_power = 20},
+ {.freq = 2422, .channel = 3, .max_power = 20},
+ {.freq = 2427, .channel = 4, .max_power = 20},
+ {.freq = 2432, .channel = 5, .max_power = 20},
+ {.freq = 2437, .channel = 6, .max_power = 20},
+ {.freq = 2442, .channel = 7, .max_power = 20},
+ {.freq = 2447, .channel = 8, .max_power = 20},
+ {.freq = 2452, .channel = 9, .max_power = 20},
+ {.freq = 2457, .channel = 10, .max_power = 20},
+ {.freq = 2462, .channel = 11, .max_power = 20}
+ },
+ },
+ };
+
+ IEEE80211_DEBUG_INFO( "Country Code: %s, Outdoor: %d\n", country,
outdoor);
+ memcpy(ieee80211_country, country, strlen(country));
+ ieee80211_outdoor = outdoor;
+ ieee80211_geo_proc = proc_mkdir("ieee80211_geo", proc_net);
+ (void)ieee80211_set_geo( ieee, ieee80211_geos); /* load default data in
case of error */
+ if (ieee80211_geo_proc == NULL) {
+ IEEE80211_ERROR( "Unable to create ieee80211_geo"
+ " proc directory - default geo data loaded\n");
+ return -EIO;
+ }
+ geo = kzalloc(sizeof(struct ieee80211_geo), GFP_KERNEL);
+ if (!geo) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+ e1 = create_proc_entry("geo_country", S_IFREG | S_IRUSR | S_IWUSR,
+ ieee80211_geo_proc);
+ e1->read_proc = show_geo_country;
+ e2 = create_proc_entry("geo_data", S_IWUSR | S_IWGRP | S_IWOTH,
+ ieee80211_geo_proc);
+ ieee80211_data_back = 1;
+ bytes_xfer = 0;
+ e2->write_proc = store_geo_data;
+
+ if (!e1 || !e2 ) {
+ IEEE80211_ERROR( "Unable to create files in ieee80211_geo"
+ " - default data loaded.\n");
+ ret = -EIO;
+ goto free_geo;
+ }
+ for (ret=0; ret<1000; ret++) {
+ if (!ieee80211_data_back)
+ break;
+ udelay(1000);
+ }
+ if (ret == 1000) {
+ ret = -EIO;
+ IEEE80211_DEBUG_INFO( "ieee80211_geo daemon not running - default
data loaded.\n");
+ goto free_geo; /* daemon not running */
+ }
+ ret = ieee80211_set_geo( ieee, geo);
+free_geo:
+ kfree(geo);
+cleanup:
+ remove_proc_entry("geo_country", ieee80211_geo_proc);
+ remove_proc_entry("geo_data", ieee80211_geo_proc);
+ remove_proc_entry("ieee80211_geo", proc_net);
+ return ret;
+}
+
const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
{
return &ieee->geo;
@@ -177,4 +308,5 @@ EXPORT_SYMBOL(ieee80211_is_valid_channel
EXPORT_SYMBOL(ieee80211_freq_to_channel);
EXPORT_SYMBOL(ieee80211_channel_to_index);
EXPORT_SYMBOL(ieee80211_set_geo);
+EXPORT_SYMBOL(ieee80211_init_geo);
EXPORT_SYMBOL(ieee80211_get_geo);
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html