diff options
author | damien <damien@FreeBSD.org> | 2005-08-21 09:52:18 +0000 |
---|---|---|
committer | damien <damien@FreeBSD.org> | 2005-08-21 09:52:18 +0000 |
commit | ea310447377cd39830eaf591ec9114aef91400b0 (patch) | |
tree | c0badf7b4107a39e2f34c5454216385c700b9d2b /sys | |
parent | 42418979749a47afb8872241d640870728dcce45 (diff) | |
download | FreeBSD-src-ea310447377cd39830eaf591ec9114aef91400b0.zip FreeBSD-src-ea310447377cd39830eaf591ec9114aef91400b0.tar.gz |
Enhanced WME (802.11e) support.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/iwi/if_iwi.c | 64 | ||||
-rw-r--r-- | sys/dev/iwi/if_iwireg.h | 6 |
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 |