summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-05-08 10:31:22 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-05-08 10:31:22 +0000
commit21e2e4c106cd36089f6bc9847f96b62533ebf644 (patch)
tree5f7a28a0f913a45bbb9c90062985175e44213034
parent8a48a077f7cabd2cc3f98a48cadf302e3f041188 (diff)
downloadFreeBSD-src-21e2e4c106cd36089f6bc9847f96b62533ebf644.zip
FreeBSD-src-21e2e4c106cd36089f6bc9847f96b62533ebf644.tar.gz
Hook HT channel setup.
-rw-r--r--sys/dev/iwn/if_iwn.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 6c954e6..3ce065c 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -154,9 +154,7 @@ static void iwn4965_print_power_group(struct iwn_softc *, int);
static void iwn5000_read_eeprom(struct iwn_softc *);
static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
static void iwn_read_eeprom_band(struct iwn_softc *, int);
-#if 0 /* HT */
static void iwn_read_eeprom_ht40(struct iwn_softc *, int);
-#endif
static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
struct ieee80211_channel *);
@@ -1696,7 +1694,7 @@ iwn4965_read_eeprom(struct iwn_softc *sc)
iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
/* Read the list of authorized channels (20MHz ones only). */
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 7; i++) {
addr = iwn4965_regulatory_bands[i];
iwn_read_eeprom_channels(sc, i, addr);
}
@@ -1783,7 +1781,7 @@ iwn5000_read_eeprom(struct iwn_softc *sc)
sc->eeprom_domain, 4);
/* Read the list of authorized channels (20MHz ones only). */
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 7; i++) {
if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
addr = base + iwn6000_regulatory_bands[i];
else
@@ -1889,18 +1887,15 @@ iwn_read_eeprom_band(struct iwn_softc *sc, int n)
"add chan %d flags 0x%x maxpwr %d\n", chan,
channels[i].flags, channels[i].maxpwr);
-#if 0 /* HT */
- /* XXX no constraints on using HT20 */
- /* add HT20, HT40 added separately */
- c = &ic->ic_channels[ic->ic_nchans++];
- c[0] = c[-1];
- c->ic_flags |= IEEE80211_CHAN_HT20;
- /* XXX NARROW =>'s 1/2 and 1/4 width? */
-#endif
+ if (sc->sc_flags & IWN_FLAG_HAS_11N) {
+ /* add HT20, HT40 added separately */
+ c = &ic->ic_channels[ic->ic_nchans++];
+ c[0] = c[-1];
+ c->ic_flags |= IEEE80211_CHAN_HT20;
+ }
}
}
-#if 0 /* HT */
static void
iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
{
@@ -1909,55 +1904,59 @@ iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
struct ieee80211_channel *c, *cent, *extc;
- int i;
+ uint8_t chan;
+ int i, nflags;
+
+ if (!(sc->sc_flags & IWN_FLAG_HAS_11N))
+ return;
for (i = 0; i < band->nchan; i++) {
- if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
- !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
+ if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
DPRINTF(sc, IWN_DEBUG_RESET,
"skip chan %d flags 0x%x maxpwr %d\n",
band->chan[i], channels[i].flags,
channels[i].maxpwr);
continue;
}
+ chan = band->chan[i];
+ nflags = iwn_eeprom_channel_flags(&channels[i]);
+
/*
* Each entry defines an HT40 channel pair; find the
* center channel, then the extension channel above.
*/
- cent = ieee80211_find_channel_byieee(ic, band->chan[i],
- band->flags & ~IEEE80211_CHAN_HT);
+ cent = ieee80211_find_channel_byieee(ic, chan,
+ (n == 5 ? IEEE80211_CHAN_G : IEEE80211_CHAN_A));
if (cent == NULL) { /* XXX shouldn't happen */
device_printf(sc->sc_dev,
- "%s: no entry for channel %d\n",
- __func__, band->chan[i]);
+ "%s: no entry for channel %d\n", __func__, chan);
continue;
}
extc = ieee80211_find_channel(ic, cent->ic_freq+20,
- band->flags & ~IEEE80211_CHAN_HT);
+ (n == 5 ? IEEE80211_CHAN_G : IEEE80211_CHAN_A));
if (extc == NULL) {
DPRINTF(sc, IWN_DEBUG_RESET,
- "skip chan %d, extension channel not found\n",
- band->chan[i]);
+ "%s: skip chan %d, extension channel not found\n",
+ __func__, chan);
continue;
}
DPRINTF(sc, IWN_DEBUG_RESET,
"add ht40 chan %d flags 0x%x maxpwr %d\n",
- band->chan[i], channels[i].flags, channels[i].maxpwr);
+ chan, channels[i].flags, channels[i].maxpwr);
c = &ic->ic_channels[ic->ic_nchans++];
c[0] = cent[0];
c->ic_extieee = extc->ic_ieee;
c->ic_flags &= ~IEEE80211_CHAN_HT;
- c->ic_flags |= IEEE80211_CHAN_HT40U;
+ c->ic_flags |= IEEE80211_CHAN_HT40U | nflags;
c = &ic->ic_channels[ic->ic_nchans++];
c[0] = extc[0];
c->ic_extieee = cent->ic_ieee;
c->ic_flags &= ~IEEE80211_CHAN_HT;
- c->ic_flags |= IEEE80211_CHAN_HT40D;
+ c->ic_flags |= IEEE80211_CHAN_HT40D | nflags;
}
}
-#endif
static void
iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
@@ -1970,25 +1969,34 @@ iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
if (n < 5)
iwn_read_eeprom_band(sc, n);
-#if 0 /* HT */
else
iwn_read_eeprom_ht40(sc, n);
-#endif
ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
}
static struct iwn_eeprom_chan *
iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
{
- int i, j;
+ int band, chan, i, j;
- for (j = 0; j < 7; j++) {
- for (i = 0; i < iwn_bands[j].nchan; i++) {
- if (iwn_bands[j].chan[i] == c->ic_ieee)
- return &sc->eeprom_channels[j][i];
+ if (IEEE80211_IS_CHAN_HT40(c)) {
+ band = IEEE80211_IS_CHAN_5GHZ(c) ? 6 : 5;
+ if (IEEE80211_IS_CHAN_HT40D(c))
+ chan = c->ic_extieee;
+ else
+ chan = c->ic_ieee;
+ for (i = 0; i < iwn_bands[band].nchan; i++) {
+ if (iwn_bands[band].chan[i] == chan)
+ return &sc->eeprom_channels[band][i];
+ }
+ } else {
+ for (j = 0; j < 5; j++) {
+ for (i = 0; i < iwn_bands[j].nchan; i++) {
+ if (iwn_bands[j].chan[i] == c->ic_ieee)
+ return &sc->eeprom_channels[j][i];
+ }
}
}
-
return NULL;
}
OpenPOWER on IntegriCloud