summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2006-09-23 13:29:59 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2006-09-23 13:29:59 +0000
commit620f8a907567eff0d52e59cbdea2d935e6776cf9 (patch)
tree1ff5966c34e3366d48a025687f9b09b69d9fed9e /sys/dev/ic
parent85f0edddd511a71d56b3b452ce7a34462421a03c (diff)
Update media state correctly.
ok claudio@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/pgt.c119
1 files changed, 97 insertions, 22 deletions
diff --git a/sys/dev/ic/pgt.c b/sys/dev/ic/pgt.c
index 8b50624bb87..eacc7d4e9fd 100644
--- a/sys/dev/ic/pgt.c
+++ b/sys/dev/ic/pgt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pgt.c,v 1.12 2006/09/19 17:38:39 brad Exp $ */
+/* $OpenBSD: pgt.c,v 1.13 2006/09/23 13:29:58 mglocker Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -111,22 +111,13 @@
* http://www.prism54.org/.
*/
-/*
- * hack to get it compiled (from FreeBSD)
- */
-#define IEEE80211_IOC_MLME 21
-#define IEEE80211_IOC_AUTHMODE 7
-#define IEEE80211_POWERSAVE_ON 1
-#define IEEE80211_POWERSAVE_OFF 0
-#define IEEE80211_MLME_UNAUTHORIZE 5
-#define IEEE80211_MLME_AUTHORIZE 4
-
#define SCAN_TIMEOUT 5 /* 5 seconds */
struct cfdriver pgt_cd = {
NULL, "pgt", DV_IFNET
};
+void pgt_media_status(struct ifnet *ifp, struct ifmediareq *imr);
int pgt_media_change(struct ifnet *ifp);
void pgt_write_memory_barrier(struct pgt_softc *);
uint32_t pgt_read_4(struct pgt_softc *, uint16_t);
@@ -1970,6 +1961,12 @@ pgt_net_attach(struct pgt_softc *sc)
IFQ_SET_MAXLEN(&ifp->if_snd, PGT_QUEUE_FULL_THRESHOLD);
IFQ_SET_READY(&ifp->if_snd);
+ /*
+ * Set channels
+ *
+ * Prism hardware likes to report supported frequencies that are
+ * not actually available for the country of origin.
+ */
j = sizeof(*freqs) + (IEEE80211_CHAN_MAX + 1) * sizeof(uint16_t);
freqs = malloc(j, M_DEVBUF, M_WAITOK);
error = pgt_oid_get(sc, PGT_OID_SUPPORTED_FREQUENCIES, freqs, j);
@@ -1977,20 +1974,18 @@ pgt_net_attach(struct pgt_softc *sc)
free(freqs, M_DEVBUF);
return (error);
}
- /*
- * Prism hardware likes to report supported frequencies that are
- * not actually available for the country of origin.
- */
- j = letoh16(freqs->pof_count);
- for (i = 0; i < j; i++) {
+
+ for (i = 0, j = letoh16(freqs->pof_count); i < j; i++) {
chan = ieee80211_mhz2ieee(letoh16(freqs->pof_freqlist_mhz[i]),
0);
+
if (chan > IEEE80211_CHAN_MAX) {
printf("%s: reported bogus channel (%uMHz)\n",
sc->sc_dev.dv_xname, chan);
free(freqs, M_DEVBUF);
return (EIO);
}
+
if (letoh16(freqs->pof_freqlist_mhz[i]) < 5000) {
if (!(phymode & htole32(PGT_OID_PHY_2400MHZ)))
continue;
@@ -2007,16 +2002,26 @@ pgt_net_attach(struct pgt_softc *sc)
continue;
ic->ic_channels[chan].ic_flags |= IEEE80211_CHAN_A;
}
+
ic->ic_channels[chan].ic_freq =
letoh16(freqs->pof_freqlist_mhz[i]);
+
if (firstchan == -1)
firstchan = chan;
+
+ DPRINTF(("%s: set channel %d to freq %uMHz\n",
+ sc->sc_dev.dv_xname, chan,
+ letoh16(freqs->pof_freqlist_mhz[i])));
}
free(freqs, M_DEVBUF);
if (firstchan == -1) {
printf("%s: no channels found\n", sc->sc_dev.dv_xname);
return (EIO);
}
+
+ /*
+ * Set rates
+ */
bzero(rates, sizeof(rates));
error = pgt_oid_get(sc, PGT_OID_SUPPORTED_RATES, rates, sizeof(rates));
if (error)
@@ -2056,7 +2061,7 @@ pgt_net_attach(struct pgt_softc *sc)
if_attach(ifp);
ieee80211_ifattach(ifp);
- /* Set up post-attach/pre-lateattach vector functions */
+ /* setup post-attach/pre-lateattach vector functions */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = pgt_newstate;
ic->ic_node_alloc = pgt_ieee80211_node_alloc;
@@ -2066,7 +2071,7 @@ pgt_net_attach(struct pgt_softc *sc)
ic->ic_send_mgmt = pgt_ieee80211_send_mgmt;
/* let net80211 handle switching around the media + resetting */
- ieee80211_media_init(ifp, pgt_media_change, ieee80211_media_status);
+ ieee80211_media_init(ifp, pgt_media_change, pgt_media_status);
#if NBPFILTER > 0
bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
@@ -2100,6 +2105,66 @@ pgt_media_change(struct ifnet *ifp)
}
void
+pgt_media_status(struct ifnet *ifp, struct ifmediareq *imr)
+{
+ struct pgt_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t rate;
+ int s;
+
+ imr->ifm_status = 0;
+ imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
+
+ if (!(ifp->if_flags & IFF_UP))
+ return;
+
+ s = splnet();
+
+ if (ic->ic_fixed_rate != -1) {
+ rate = ic->ic_sup_rates[ic->ic_curmode].
+ rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
+ } else {
+ if (pgt_oid_get(sc, PGT_OID_LINK_STATE, &rate, sizeof(rate)))
+ return;
+ rate = letoh32(rate);
+ if (rate == 0)
+ return;
+ if (sc->sc_debug & SC_DEBUG_LINK) {
+ DPRINTF(("%s: %s: link rate %u\n",
+ sc->sc_dev.dv_xname, __func__, rate));
+ }
+ }
+
+ imr->ifm_status = IFM_AVALID;
+ imr->ifm_active = IFM_IEEE80211;
+ if (ic->ic_state == IEEE80211_S_RUN)
+ imr->ifm_status |= IFM_ACTIVE;
+
+ imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
+
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_STA:
+ break;
+ case IEEE80211_M_IBSS:
+ imr->ifm_active |= IFM_IEEE80211_ADHOC;
+ break;
+ case IEEE80211_M_AHDEMO:
+ imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
+ break;
+ case IEEE80211_M_HOSTAP:
+ imr->ifm_active |= IFM_IEEE80211_HOSTAP;
+ break;
+ case IEEE80211_M_MONITOR:
+ imr->ifm_active |= IFM_IEEE80211_MONITOR;
+ break;
+ default:
+ break;
+ }
+
+ splx(s);
+}
+
+void
pgt_start(struct ifnet *ifp)
{
struct pgt_softc *sc;
@@ -2933,18 +2998,22 @@ badopmode:
bsstype = PGT_BSS_TYPE_NONE;
}
+ DPRINTF(("%s: current mode is ", sc->sc_dev.dv_xname));
switch (ic->ic_curmode) {
case IEEE80211_MODE_11A:
profile = PGT_PROFILE_A_ONLY;
preamble = PGT_OID_PREAMBLE_MODE_DYNAMIC;
+ DPRINTF(("IEEE80211_MODE_11A\n"));
break;
case IEEE80211_MODE_11B:
profile = PGT_PROFILE_B_ONLY;
preamble = PGT_OID_PREAMBLE_MODE_LONG;
+ DPRINTF(("IEEE80211_MODE_11B\n"));
break;
case IEEE80211_MODE_11G:
profile = PGT_PROFILE_G_ONLY;
preamble = PGT_OID_PREAMBLE_MODE_SHORT;
+ DPRINTF(("IEEE80211_MODE_11G\n"));
break;
case IEEE80211_MODE_FH:
/* FALLTHROUGH */
@@ -2953,6 +3022,7 @@ badopmode:
case IEEE80211_MODE_AUTO:
profile = PGT_PROFILE_MIXED_G_WIFI;
preamble = PGT_OID_PREAMBLE_MODE_DYNAMIC;
+ DPRINTF(("IEEE80211_MODE_AUTO\n"));
break;
default:
panic("unknown mode %d\n", ic->ic_curmode);
@@ -3006,9 +3076,14 @@ badopmode:
} else
channel = htole32(ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
- for (i = 0; i < ic->ic_sup_rates[ic->ic_curmode].rs_nrates; i++)
+ DPRINTF(("%s: set rates", sc->sc_dev.dv_xname));
+ for (i = 0; i < ic->ic_sup_rates[ic->ic_curmode].rs_nrates; i++) {
availrates[i] = ic->ic_sup_rates[ic->ic_curmode].rs_rates[i];
+ DPRINTF((" %d", availrates[i]));
+ }
+ DPRINTF(("\n"));
availrates[i++] = 0;
+
essid.pos_length = min(ic->ic_des_esslen, sizeof(essid.pos_ssid));
memcpy(&essid.pos_ssid, ic->ic_des_essid, essid.pos_length);
@@ -3241,8 +3316,8 @@ pgt_update_sw_from_hw(struct pgt_softc *sc, struct pgt_async_trap *pa,
break;
ls = letoh32(*mtod(args, uint32_t *));
if (sc->sc_debug & (SC_DEBUG_TRAP | SC_DEBUG_LINK))
- DPRINTF(("%s: link: %u\n",
- sc->sc_dev.dv_xname, ls));
+ DPRINTF(("%s: %s: link rate %u\n",
+ sc->sc_dev.dv_xname, __func__, ls));
if (ls)
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
else