diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2004-10-27 21:19:44 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2004-10-27 21:19:44 +0000 |
commit | 94e2deb912cbe3d78816af3867547a51a269024d (patch) | |
tree | 2f1eb01c5b158b55bb2cc89254310325e5e6184f /sys/dev | |
parent | ee398faf027faa4650aef33c6f4c8e4efbd81391 (diff) |
Add ipw_media_status() to report the current Tx rate properly.
This was imported from iwi.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_ipw.c | 58 | ||||
-rw-r--r-- | sys/dev/pci/if_ipwreg.h | 8 |
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; |