svn commit: r221636 - head/sys/dev/iwn

Bernhard Schmidt bschmidt at FreeBSD.org
Sun May 8 10:31:23 UTC 2011


Author: bschmidt
Date: Sun May  8 10:31:22 2011
New Revision: 221636
URL: http://svn.freebsd.org/changeset/base/221636

Log:
  Hook HT channel setup.

Modified:
  head/sys/dev/iwn/if_iwn.c

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Sun May  8 10:21:42 2011	(r221635)
+++ head/sys/dev/iwn/if_iwn.c	Sun May  8 10:31:22 2011	(r221636)
@@ -154,9 +154,7 @@ static void	iwn4965_print_power_group(st
 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 *s
 		    "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 *s
 	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_soft
 
 	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;
 }
 


More information about the svn-src-all mailing list