summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2004-10-27 21:19:44 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2004-10-27 21:19:44 +0000
commit94e2deb912cbe3d78816af3867547a51a269024d (patch)
tree2f1eb01c5b158b55bb2cc89254310325e5e6184f /sys
parentee398faf027faa4650aef33c6f4c8e4efbd81391 (diff)
Add ipw_media_status() to report the current Tx rate properly.
This was imported from iwi.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_ipw.c58
-rw-r--r--sys/dev/pci/if_ipwreg.h8
2 files changed, 63 insertions, 3 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index 6f81084c5e7..daaddb77c3b 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,4 +1,4 @@
-/* $Id: if_ipw.c,v 1.9 2004/10/27 21:19:01 damien Exp $ */
+/* $Id: if_ipw.c,v 1.10 2004/10/27 21:19:43 damien Exp $ */
/*-
* Copyright (c) 2004
@@ -80,6 +80,7 @@ int ipw_match(struct device *, void *, void *);
void ipw_attach(struct device *, struct device *, void *);
int ipw_detach(struct device *, int);
int ipw_media_change(struct ifnet *);
+void ipw_media_status(struct ifnet *, struct ifmediareq *);
int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int);
void ipw_command_intr(struct ipw_softc *, struct ipw_soft_buf *);
void ipw_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
@@ -252,7 +253,7 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = ipw_newstate;
- ieee80211_media_init(ifp, ipw_media_change, ieee80211_media_status);
+ ieee80211_media_init(ifp, ipw_media_change, ipw_media_status);
#if NBPFILTER > 0
bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
@@ -307,6 +308,59 @@ ipw_media_change(struct ifnet *ifp)
return 0;
}
+void
+ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
+{
+ struct ipw_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+#define N(a) (sizeof (a) / sizeof (a[0]))
+ static const struct {
+ u_int32_t val;
+ int rate;
+ } rates[] = {
+ { IPW_RATE_DS1, 2 },
+ { IPW_RATE_DS2, 4 },
+ { IPW_RATE_DS5, 11 },
+ { IPW_RATE_DS11, 22 },
+ };
+ u_int32_t val;
+ int rate, i;
+
+ imr->ifm_status = IFM_AVALID;
+ imr->ifm_active = IFM_IEEE80211;
+ if (ic->ic_state == IEEE80211_S_RUN)
+ imr->ifm_status |= IFM_ACTIVE;
+
+ /* read current transmission rate from adapter */
+ val = ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE);
+ val &= 0xf;
+
+ /* convert rate to 802.11 rate */
+ for (i = 0; i < N(rates) && rates[i].val != val; i++);
+ rate = (i < N(rates)) ? rates[i].rate : 0;
+
+ imr->ifm_active |= IFM_IEEE80211_11B;
+ imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B);
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_STA:
+ break;
+
+ case IEEE80211_M_IBSS:
+ imr->ifm_active |= IFM_IEEE80211_ADHOC;
+ break;
+
+ case IEEE80211_M_MONITOR:
+ imr->ifm_active |= IFM_IEEE80211_MONITOR;
+ break;
+
+ case IEEE80211_M_AHDEMO:
+ case IEEE80211_M_HOSTAP:
+ /* should not get there */
+ break;
+ }
+#undef N
+}
+
int
ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
{
diff --git a/sys/dev/pci/if_ipwreg.h b/sys/dev/pci/if_ipwreg.h
index e1aff17964c..7d82b2c3926 100644
--- a/sys/dev/pci/if_ipwreg.h
+++ b/sys/dev/pci/if_ipwreg.h
@@ -1,4 +1,4 @@
-/* $Id: if_ipwreg.h,v 1.3 2004/10/27 21:16:45 damien Exp $ */
+/* $Id: if_ipwreg.h,v 1.4 2004/10/27 21:19:43 damien Exp $ */
/*-
* Copyright (c) 2004
@@ -106,6 +106,12 @@
#define IPW_INFO_CURRENT_SSID 48
#define IPW_INFO_CURRENT_BSSID 112
+/* supported rates */
+#define IPW_RATE_DS1 1
+#define IPW_RATE_DS2 2
+#define IPW_RATE_DS5 4
+#define IPW_RATE_DS11 8
+
/* firmware binary image header */
struct ipw_fw_hdr {
u_int32_t version;