summaryrefslogtreecommitdiffstats
path: root/sys/dev/iwi
diff options
context:
space:
mode:
authordamien <damien@FreeBSD.org>2005-08-21 09:52:18 +0000
committerdamien <damien@FreeBSD.org>2005-08-21 09:52:18 +0000
commitea310447377cd39830eaf591ec9114aef91400b0 (patch)
treec0badf7b4107a39e2f34c5454216385c700b9d2b /sys/dev/iwi
parent42418979749a47afb8872241d640870728dcce45 (diff)
downloadFreeBSD-src-ea310447377cd39830eaf591ec9114aef91400b0.zip
FreeBSD-src-ea310447377cd39830eaf591ec9114aef91400b0.tar.gz
Enhanced WME (802.11e) support.
Diffstat (limited to 'sys/dev/iwi')
-rw-r--r--sys/dev/iwi/if_iwi.c64
-rw-r--r--sys/dev/iwi/if_iwireg.h6
2 files changed, 65 insertions, 5 deletions
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index 0eb7b7c..ad33e11 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -953,12 +953,72 @@ iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
return 0;
}
+/*
+ * WME parameters coming from IEEE 802.11e specification. These values are
+ * already declared in ieee80211_proto.c, but they are static so they can't
+ * be reused here.
+ */
+static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {
+ { 0, 3, 5, 7, 0 }, /* WME_AC_BE */
+ { 0, 3, 5, 10, 0 }, /* WME_AC_BK */
+ { 0, 2, 4, 5, 188 }, /* WME_AC_VI */
+ { 0, 2, 3, 4, 102 } /* WME_AC_VO */
+};
+
+static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = {
+ { 0, 3, 4, 6, 0 }, /* WME_AC_BE */
+ { 0, 3, 4, 10, 0 }, /* WME_AC_BK */
+ { 0, 2, 3, 4, 94 }, /* WME_AC_VI */
+ { 0, 2, 2, 3, 47 } /* WME_AC_VO */
+};
+
static int
iwi_wme_update(struct ieee80211com *ic)
{
- /* XXX: we should send a IWI_CMD_SET_WME_PARAMS command here */
+#define IWI_EXP2(v) htole16((1 << (v)) - 1)
+#define IWI_USEC(v) htole16(IEEE80211_TXOP_TO_US(v))
+ struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_wme_params wme[3];
+ const struct wmeParams *wmep;
+ int ac;
- return 0;
+ /*
+ * We shall not override firmware default WME values if WME is not
+ * actually enabled.
+ */
+ if (!(ic->ic_flags & IEEE80211_F_WME))
+ return 0;
+
+ for (ac = 0; ac < WME_NUM_AC; ac++) {
+ /* set WME values for current operating mode */
+ wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
+ wme[0].aifsn[ac] = wmep->wmep_aifsn;
+ wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[0].acm[ac] = wmep->wmep_acm;
+
+ /* set WME values for CCK modulation */
+ wmep = &iwi_wme_cck_params[ac];
+ wme[1].aifsn[ac] = wmep->wmep_aifsn;
+ wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[1].acm[ac] = wmep->wmep_acm;
+
+ /* set WME values for OFDM modulation */
+ wmep = &iwi_wme_ofdm_params[ac];
+ wme[2].aifsn[ac] = wmep->wmep_aifsn;
+ wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[2].acm[ac] = wmep->wmep_acm;
+ }
+
+ DPRINTF(("Setting WME parameters\n"));
+ return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
+#undef IWI_USEC
+#undef IWI_EXP2
}
/*
diff --git a/sys/dev/iwi/if_iwireg.h b/sys/dev/iwi/if_iwireg.h
index f86e2b5..8c5e21c 100644
--- a/sys/dev/iwi/if_iwireg.h
+++ b/sys/dev/iwi/if_iwireg.h
@@ -378,11 +378,11 @@ struct iwi_wep_key {
/* structure for command IWI_CMD_SET_WME_PARAMS */
struct iwi_wme_params {
- uint16_t logcwmin[WME_NUM_AC];
- uint16_t logcwmax[WME_NUM_AC];
+ uint16_t cwmin[WME_NUM_AC];
+ uint16_t cwmax[WME_NUM_AC];
uint8_t aifsn[WME_NUM_AC];
uint8_t acm[WME_NUM_AC];
- uint16_t txopLimit[WME_NUM_AC];
+ uint16_t burst[WME_NUM_AC];
} __packed;
#define IWI_MEM_EEPROM_CTL 0x00300040
OpenPOWER on IntegriCloud