Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src/sys/dev/pci Only map channels from epprom - from FreeBSD.
details: https://anonhg.NetBSD.org/src-all/rev/7ce53837fbd8
branches: trunk
changeset: 376435:7ce53837fbd8
user: Nathanial Sloss <nat%netbsd.org@localhost>
date: Sun Jun 18 15:05:48 2023 +1000
description:
Only map channels from epprom - from FreeBSD.
diffstat:
sys/dev/pci/if_iwn.c | 167 +++++++++++++++++++++++++++++++++++++++++------
sys/dev/pci/if_iwnvar.h | 1 +
2 files changed, 147 insertions(+), 21 deletions(-)
diffs (206 lines):
diff -r 8a30b93978eb -r 7ce53837fbd8 sys/dev/pci/if_iwn.c
--- a/sys/dev/pci/if_iwn.c Fri Apr 28 22:38:34 2023 +1000
+++ b/sys/dev/pci/if_iwn.c Sun Jun 18 15:05:48 2023 +1000
@@ -268,6 +268,11 @@ static int iwn_raw_xmit(struct ieee80211
static void iwn4965_print_power_group(struct iwn_softc *, int);
#endif
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, int, int *,
+ struct ieee80211_channel[]);
+static void iwn_read_eeprom_ht40(struct iwn_softc *, int, int, int *,
+ struct ieee80211_channel[]);
static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
static void iwn_newassoc(struct ieee80211_node *, int);
@@ -463,26 +468,13 @@ iwn_get_radiocaps(struct ieee80211com *i
int maxchans, int *nchans, struct ieee80211_channel chans[])
{
struct iwn_softc *sc = ic->ic_softc;
- uint8_t bands[IEEE80211_MODE_BYTES];
-
- /*
- * NNN Should be able to do something based on chip if
- * a chip has more bands .... eg. N ... but for the future.
- */
-
- memset(bands, 0, sizeof(bands));
- if (sc->sc_flags & IWN_FLAG_HAS_5GHZ)
- setbit(bands, IEEE80211_MODE_11A);
- setbit(bands, IEEE80211_MODE_11B);
- setbit(bands, IEEE80211_MODE_11G);
-#ifndef IEEE80211_NO_HT
- setbit(bands, IEEE80211_MODE_11NG);
- if (sc->sc_flags & IWN_FLAG_HAS_5GHZ)
- setbit(bands, IEEE80211_MODE_11NA);
-#endif
- /* XXX is it still safe to use NULL here as ic channels are populated
- when firmware is read */
- ieee80211_init_channels(ic, NULL, bands);
+ int i;
+
+ /* Parse the list of authorized channels. */
+ for (i = 0; i < 5 && *nchans < maxchans; i++)
+ iwn_read_eeprom_band(sc, i, maxchans, nchans, chans);
+ for (i = 5; i < IWN_NBANDS - 1 && *nchans < maxchans; i++)
+ iwn_read_eeprom_ht40(sc, i, maxchans, nchans, chans);
}
static void
@@ -2074,12 +2066,145 @@ iwn5000_read_eeprom(struct iwn_softc *sc
}
}
+/*
+ * Translate EEPROM flags to net80211.
+ */
+static uint32_t
+iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel)
+{
+ uint32_t nflags;
+
+ nflags = 0;
+ if ((channel->flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
+ nflags |= IEEE80211_CHAN_PASSIVE;
+ if ((channel->flags & IWN_EEPROM_CHAN_IBSS) == 0)
+ nflags |= IEEE80211_CHAN_NOADHOC;
+ if (channel->flags & IWN_EEPROM_CHAN_RADAR) {
+ nflags |= IEEE80211_CHAN_DFS;
+ /* XXX apparently IBSS may still be marked */
+ nflags |= IEEE80211_CHAN_NOADHOC;
+ }
+
+ return nflags;
+}
+
+static void
+iwn_read_eeprom_band(struct iwn_softc *sc, int n, int maxchans, int *nchans,
+ struct ieee80211_channel chans[])
+{
+ struct iwn_eeprom_chan *channels = &sc->eeprom_channels[n];
+ const struct iwn_chan_band *band = &iwn_bands[n];
+ uint8_t bands[IEEE80211_MODE_BYTES];
+ uint8_t chan;
+ int i, error, nflags;
+
+ DPRINTF((sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__));
+
+ memset(bands, 0, sizeof(bands));
+ if (n == 0) {
+ setbit(bands, IEEE80211_MODE_11B);
+ setbit(bands, IEEE80211_MODE_11G);
+ if (sc->sc_flags & IWN_FLAG_HAS_11N)
+ setbit(bands, IEEE80211_MODE_11NG);
+ } else {
+ setbit(bands, IEEE80211_MODE_11A);
+ if (sc->sc_flags & IWN_FLAG_HAS_11N)
+ setbit(bands, IEEE80211_MODE_11NA);
+ }
+
+ for (i = 0; i < band->nchan; i++) {
+ 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]);
+ error = ieee80211_add_channel(chans, maxchans, nchans,
+ chan, 0, channels[i].maxpwr, nflags, bands);
+ if (error != 0)
+ break;
+
+ /* Save maximum allowed TX power for this channel. */
+ /* XXX wrong */
+ sc->maxpwr[chan] = channels[i].maxpwr;
+
+ DPRINTF((sc, IWN_DEBUG_RESET,
+ "add chan %d flags 0x%x maxpwr %d\n", chan,
+ channels[i].flags, channels[i].maxpwr));
+ }
+
+ DPRINTF((sc, IWN_DEBUG_TRACE, "->%s end\n", __func__));
+
+}
+
+void
+iwn_read_eeprom_ht40(struct iwn_softc *sc, int n, int maxchans, int *nchans,
+ struct ieee80211_channel chans[])
+{
+ struct iwn_eeprom_chan *channels = &sc->eeprom_channels[n];
+ const struct iwn_chan_band *band = &iwn_bands[n];
+ uint8_t chan;
+ int i, error, nflags;
+
+ DPRINTF((sc, IWN_DEBUG_TRACE, "->%s start\n", __func__));
+
+ if (!(sc->sc_flags & IWN_FLAG_HAS_11N)) {
+ DPRINTF((sc, IWN_DEBUG_TRACE, "->%s end no 11n\n", __func__));
+ return;
+ }
+
+ for (i = 0; i < band->nchan; i++) {
+ 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]);
+ nflags |= (n == 5 ? IEEE80211_CHAN_G : IEEE80211_CHAN_A);
+ error = ieee80211_add_channel_ht40(chans, maxchans, nchans,
+ chan, channels[i].maxpwr, nflags);
+ switch (error) {
+ case EINVAL:
+ device_printf(sc->sc_dev,
+ "%s: no entry for channel %d\n", __func__, chan);
+ continue;
+ case ENOENT:
+ DPRINTF((sc, IWN_DEBUG_RESET,
+ "%s: skip chan %d, extension channel not found\n",
+ __func__, chan));
+ continue;
+ case ENOBUFS:
+ device_printf(sc->sc_dev,
+ "%s: channel table is full!\n", __func__);
+ break;
+ case 0:
+ DPRINTF((sc, IWN_DEBUG_RESET,
+ "add ht40 chan %d flags 0x%x maxpwr %d\n",
+ chan, channels[i].flags, channels[i].maxpwr));
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+ }
+
+ DPRINTF((sc, IWN_DEBUG_TRACE, "->%s end\n", __func__));
+
+}
+
static void
iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
{
struct ieee80211com *ic = &sc->sc_ic;
+ struct iwn_eeprom_chan *channels = &sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
- struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
uint8_t chan;
int i;
diff -r 8a30b93978eb -r 7ce53837fbd8 sys/dev/pci/if_iwnvar.h
--- a/sys/dev/pci/if_iwnvar.h Fri Apr 28 22:38:34 2023 +1000
+++ b/sys/dev/pci/if_iwnvar.h Sun Jun 18 15:05:48 2023 +1000
@@ -342,5 +342,6 @@ struct iwn_softc {
kcondvar_t t_event;
int sc_beacon_wait; /* defer/skip sending */
+ struct iwn_eeprom_chan eeprom_channels[IWN_MAX_CHAN_PER_BAND];
};
Home |
Main Index |
Thread Index |
Old Index