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)
This commit is contained in:
parent
bb5d3b71d3
commit
d6bf86af1e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187841
@ -1789,6 +1789,19 @@ chanlookup(const struct ieee80211_channel chans[], int nchans,
|
|||||||
return NULL;
|
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
|
static void
|
||||||
regdomain_addchans(struct ieee80211req_chaninfo *ci,
|
regdomain_addchans(struct ieee80211req_chaninfo *ci,
|
||||||
const netband_head *bands,
|
const netband_head *bands,
|
||||||
@ -1799,9 +1812,15 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
|
|||||||
const struct netband *nb;
|
const struct netband *nb;
|
||||||
const struct freqband *b;
|
const struct freqband *b;
|
||||||
struct ieee80211_channel *c, *prev;
|
struct ieee80211_channel *c, *prev;
|
||||||
int freq, channelSep;
|
int freq, channelSep, hasHalfChans, hasQuarterChans;
|
||||||
|
|
||||||
channelSep = (chanFlags & IEEE80211_CHAN_2GHZ) ? 0 : 40;
|
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) {
|
LIST_FOREACH(nb, bands, next) {
|
||||||
b = nb->band;
|
b = nb->band;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@ -1812,28 +1831,31 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
|
|||||||
uint32_t flags = nb->flags | b->flags;
|
uint32_t flags = nb->flags | b->flags;
|
||||||
|
|
||||||
/* check if device can operate on this frequency */
|
/* 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)
|
if (verbose)
|
||||||
printf("%u: skip, flags 0x%x not available\n", freq, chanFlags);
|
printf("%u: skip, flags 0x%x not available\n", freq, chanFlags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
if ((flags & IEEE80211_CHAN_HALF) && !hasHalfChans) {
|
||||||
* 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 (verbose)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if ((flags & IEEE80211_CHAN_QUARTER) &&
|
if ((flags & IEEE80211_CHAN_QUARTER) &&
|
||||||
((chanFlags & IEEE80211_CHAN_QUARTER) == 0 &&
|
!hasQuarterChans) {
|
||||||
(flags & IEEE80211_CHAN_GSM) == 0)) {
|
|
||||||
if (verbose)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if ((flags & IEEE80211_CHAN_HT20) &&
|
if ((flags & IEEE80211_CHAN_HT20) &&
|
||||||
@ -1932,26 +1954,12 @@ regdomain_makechannels(
|
|||||||
if (!LIST_EMPTY(&rd->bands_11b))
|
if (!LIST_EMPTY(&rd->bands_11b))
|
||||||
regdomain_addchans(ci, &rd->bands_11b, reg,
|
regdomain_addchans(ci, &rd->bands_11b, reg,
|
||||||
IEEE80211_CHAN_B, &dc->dc_chaninfo);
|
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,
|
regdomain_addchans(ci, &rd->bands_11g, reg,
|
||||||
IEEE80211_CHAN_G, &dc->dc_chaninfo);
|
IEEE80211_CHAN_G, &dc->dc_chaninfo);
|
||||||
regdomain_addchans(ci, &rd->bands_11g, reg,
|
if (!LIST_EMPTY(&rd->bands_11a))
|
||||||
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)) {
|
|
||||||
regdomain_addchans(ci, &rd->bands_11a, reg,
|
regdomain_addchans(ci, &rd->bands_11a, reg,
|
||||||
IEEE80211_CHAN_A, &dc->dc_chaninfo);
|
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)) {
|
if (!LIST_EMPTY(&rd->bands_11na)) {
|
||||||
regdomain_addchans(ci, &rd->bands_11na, reg,
|
regdomain_addchans(ci, &rd->bands_11na, reg,
|
||||||
IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,
|
IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,
|
||||||
|
Loading…
Reference in New Issue
Block a user