summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig/ifieee80211.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-01-28 19:15:52 +0000
committersam <sam@FreeBSD.org>2009-01-28 19:15:52 +0000
commitdd3fa012e1ae14320b6296cb11bd6be3bbd7435c (patch)
tree9848838492fd75fa597ee4c75e3bf3099d4a85fb /sbin/ifconfig/ifieee80211.c
parent7dcaa08f7f90f0b3c1ed4ee1f46114ebc5ce3888 (diff)
downloadFreeBSD-src-dd3fa012e1ae14320b6296cb11bd6be3bbd7435c.zip
FreeBSD-src-dd3fa012e1ae14320b6296cb11bd6be3bbd7435c.tar.gz
Fix 1/2 and 1/4 width channel handling:
o only include 1/2 and 1/4 width channels when they are specified in the regulatory database description; previously we treated them as if they were part of the band and blindly added them for 11a/g o check the channel list returned in the devcaps to identify whether a device supports 1/2 or 1/4 width channels on a band; this might be better brought out as a capability bit to avoid filling the channel list w/ 1/2 and 1/4 width channels but then cards that only support these channels in a range of frequencies could not be described (though right now we don't check frequency range only band)
Diffstat (limited to 'sbin/ifconfig/ifieee80211.c')
-rw-r--r--sbin/ifconfig/ifieee80211.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index fa97675..c0f756c 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -1789,6 +1789,19 @@ chanlookup(const struct ieee80211_channel chans[], int nchans,
return NULL;
}
+static int
+chanfind(const struct ieee80211_channel chans[], int nchans, int flags)
+{
+ int i;
+
+ for (i = 0; i < nchans; i++) {
+ const struct ieee80211_channel *c = &chans[i];
+ if ((c->ic_flags & flags) == flags)
+ return 1;
+ }
+ return 0;
+}
+
static void
regdomain_addchans(struct ieee80211req_chaninfo *ci,
const netband_head *bands,
@@ -1799,9 +1812,15 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
const struct netband *nb;
const struct freqband *b;
struct ieee80211_channel *c, *prev;
- int freq, channelSep;
+ int freq, channelSep, hasHalfChans, hasQuarterChans;
channelSep = (chanFlags & IEEE80211_CHAN_2GHZ) ? 0 : 40;
+ hasHalfChans = chanfind(avail->ic_chans, avail->ic_nchans,
+ IEEE80211_CHAN_HALF |
+ (chanFlags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
+ hasQuarterChans = chanfind(avail->ic_chans, avail->ic_nchans,
+ IEEE80211_CHAN_QUARTER |
+ (chanFlags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
LIST_FOREACH(nb, bands, next) {
b = nb->band;
if (verbose)
@@ -1812,28 +1831,31 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
uint32_t flags = nb->flags | b->flags;
/* check if device can operate on this frequency */
- if (chanlookup(avail->ic_chans, avail->ic_nchans, freq, chanFlags) == NULL) {
+ /*
+ * XXX GSM frequency mapping is handled in the kernel
+ * so we cannot find them in the calibration table;
+ * just construct the list and the kernel will reject
+ * if it's wrong.
+ */
+ if (chanlookup(avail->ic_chans, avail->ic_nchans, freq, chanFlags) == NULL &&
+ (flags & IEEE80211_CHAN_GSM) == 0) {
if (verbose)
printf("%u: skip, flags 0x%x not available\n", freq, chanFlags);
continue;
}
- /*
- * NB: don't enforce 1/2 and 1/4 rate channels being
- * specified in the device's calibration list for
- * 900MHz cards because most are not self-identifying.
- */
- if ((flags & IEEE80211_CHAN_HALF) &&
- ((chanFlags & IEEE80211_CHAN_HALF) == 0 &&
- (flags & IEEE80211_CHAN_GSM) == 0)) {
+ if ((flags & IEEE80211_CHAN_HALF) && !hasHalfChans) {
if (verbose)
- printf("%u: skip, device does not support half-rate channels\n", freq);
+ printf("%u: skip, device does not "
+ "support half-rate channel\n",
+ freq);
continue;
}
if ((flags & IEEE80211_CHAN_QUARTER) &&
- ((chanFlags & IEEE80211_CHAN_QUARTER) == 0 &&
- (flags & IEEE80211_CHAN_GSM) == 0)) {
+ !hasQuarterChans) {
if (verbose)
- printf("%u: skip, device does not support quarter-rate channels\n", freq);
+ printf("%u: skip, device does not "
+ "support quarter-rate channel\n",
+ freq);
continue;
}
if ((flags & IEEE80211_CHAN_HT20) &&
@@ -1932,26 +1954,12 @@ regdomain_makechannels(
if (!LIST_EMPTY(&rd->bands_11b))
regdomain_addchans(ci, &rd->bands_11b, reg,
IEEE80211_CHAN_B, &dc->dc_chaninfo);
- if (!LIST_EMPTY(&rd->bands_11g)) {
+ if (!LIST_EMPTY(&rd->bands_11g))
regdomain_addchans(ci, &rd->bands_11g, reg,
IEEE80211_CHAN_G, &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11g, reg,
- IEEE80211_CHAN_G | IEEE80211_CHAN_HALF,
- &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11g, reg,
- IEEE80211_CHAN_G | IEEE80211_CHAN_QUARTER,
- &dc->dc_chaninfo);
- }
- if (!LIST_EMPTY(&rd->bands_11a)) {
+ if (!LIST_EMPTY(&rd->bands_11a))
regdomain_addchans(ci, &rd->bands_11a, reg,
IEEE80211_CHAN_A, &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11a, reg,
- IEEE80211_CHAN_A | IEEE80211_CHAN_HALF,
- &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11a, reg,
- IEEE80211_CHAN_A | IEEE80211_CHAN_QUARTER,
- &dc->dc_chaninfo);
- }
if (!LIST_EMPTY(&rd->bands_11na)) {
regdomain_addchans(ci, &rd->bands_11na, reg,
IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,
OpenPOWER on IntegriCloud