Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/usb/wlan/if_urtw.c
Show First 20 Lines • Show All 476 Lines • ▼ Show 20 Lines | |||||
static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = { | static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = { | ||||
0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, | 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, | ||||
0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, | 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, | ||||
0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, | 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, | ||||
0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 | 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 | ||||
}; | }; | ||||
static struct urtw_pair urtw_ratetable[] = { | |||||
{ 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 }, | |||||
{ 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 }, | |||||
{ 96, 10 }, { 108, 11 } | |||||
}; | |||||
#if 0 | #if 0 | ||||
static const uint8_t urtw_8187b_reg_table[][3] = { | static const uint8_t urtw_8187b_reg_table[][3] = { | ||||
{ 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 }, | { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 }, | ||||
{ 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 }, | { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 }, | ||||
{ 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 }, | { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 }, | ||||
{ 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 }, | { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 }, | ||||
{ 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 }, | { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 }, | ||||
{ 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, | { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | static int urtw_tx_start(struct urtw_softc *, | ||||
struct ieee80211_node *, struct mbuf *, | struct ieee80211_node *, struct mbuf *, | ||||
struct urtw_data *, int); | struct urtw_data *, int); | ||||
static int urtw_newstate(struct ieee80211vap *, | static int urtw_newstate(struct ieee80211vap *, | ||||
enum ieee80211_state, int); | enum ieee80211_state, int); | ||||
static void urtw_led_ch(void *); | static void urtw_led_ch(void *); | ||||
static void urtw_ledtask(void *, int); | static void urtw_ledtask(void *, int); | ||||
static void urtw_watchdog(void *); | static void urtw_watchdog(void *); | ||||
static void urtw_set_multi(void *); | static void urtw_set_multi(void *); | ||||
static int urtw_isbmode(uint16_t); | static uint16_t urtw_rtl2rate_idx(uint8_t); | ||||
static uint16_t urtw_rtl2rate(uint32_t); | |||||
static usb_error_t urtw_set_rate(struct urtw_softc *); | static usb_error_t urtw_set_rate(struct urtw_softc *); | ||||
static usb_error_t urtw_update_msr(struct urtw_softc *); | static usb_error_t urtw_update_msr(struct urtw_softc *); | ||||
static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *); | static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *); | ||||
static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *); | static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *); | ||||
static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *); | static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *); | ||||
static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t); | static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t); | ||||
static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t); | static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t); | ||||
static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t); | static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t); | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *); | static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *); | ||||
static usb_error_t urtw_do_request(struct urtw_softc *, | static usb_error_t urtw_do_request(struct urtw_softc *, | ||||
struct usb_device_request *, void *); | struct usb_device_request *, void *); | ||||
static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int); | static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int); | ||||
static usb_error_t urtw_led_off(struct urtw_softc *, int); | static usb_error_t urtw_led_off(struct urtw_softc *, int); | ||||
static void urtw_abort_xfers(struct urtw_softc *); | static void urtw_abort_xfers(struct urtw_softc *); | ||||
static struct urtw_data * | static struct urtw_data * | ||||
urtw_getbuf(struct urtw_softc *sc); | urtw_getbuf(struct urtw_softc *sc); | ||||
static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t, | static int urtw_compute_txtime(uint16_t, | ||||
uint8_t); | const struct ieee80211_rate_t *, uint8_t); | ||||
static void urtw_updateslot(struct ieee80211com *); | static void urtw_updateslot(struct ieee80211com *); | ||||
static void urtw_updateslottask(void *, int); | static void urtw_updateslottask(void *, int); | ||||
static void urtw_sysctl_node(struct urtw_softc *); | static void urtw_sysctl_node(struct urtw_softc *); | ||||
static int | static int | ||||
urtw_match(device_t dev) | urtw_match(device_t dev) | ||||
{ | { | ||||
struct usb_attach_arg *uaa = device_get_ivars(dev); | struct usb_attach_arg *uaa = device_get_ivars(dev); | ||||
▲ Show 20 Lines • Show All 862 Lines • ▼ Show 20 Lines | urtw_update_mcast(struct ieee80211com *ic) | ||||
/* XXX do nothing? */ | /* XXX do nothing? */ | ||||
} | } | ||||
static int | static int | ||||
urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, | urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, | ||||
struct urtw_data *data, int prior) | struct urtw_data *data, int prior) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate, *ctl_rate; | |||||
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); | struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); | ||||
struct ieee80211_key *k; | struct ieee80211_key *k; | ||||
const struct ieee80211_txparam *tp = ni->ni_txparms; | const struct ieee80211_txparam_vht *tp = ni->ni_txparms; | ||||
struct ieee80211com *ic = &sc->sc_ic; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = { | struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = { | ||||
sc->sc_xfer[URTW_8187B_BULK_TX_BE], | sc->sc_xfer[URTW_8187B_BULK_TX_BE], | ||||
sc->sc_xfer[URTW_8187B_BULK_TX_BK], | sc->sc_xfer[URTW_8187B_BULK_TX_BK], | ||||
sc->sc_xfer[URTW_8187B_BULK_TX_VI], | sc->sc_xfer[URTW_8187B_BULK_TX_VI], | ||||
sc->sc_xfer[URTW_8187B_BULK_TX_VO] | sc->sc_xfer[URTW_8187B_BULK_TX_VO] | ||||
}; | }; | ||||
struct usb_xfer *xfer; | struct usb_xfer *xfer; | ||||
int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate, type, | int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, type, | ||||
pkttime = 0, txdur = 0, isshort = 0, xferlen, ismcast; | pkttime = 0, txdur = 0, isshort = 0, xferlen, ismcast; | ||||
uint16_t acktime, rtstime, ctstime; | uint16_t acktime, rtstime, ctstime, rate_idx; | ||||
uint32_t flags; | uint32_t flags; | ||||
usb_error_t error; | usb_error_t error; | ||||
URTW_ASSERT_LOCKED(sc); | URTW_ASSERT_LOCKED(sc); | ||||
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ||||
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; | type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; | ||||
Show All 23 Lines | if (ieee80211_radiotap_active_vap(vap)) { | ||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); | tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); | ||||
ieee80211_radiotap_tx(vap, m0); | ieee80211_radiotap_tx(vap, m0); | ||||
} | } | ||||
if (type == IEEE80211_FC0_TYPE_MGT || | if (type == IEEE80211_FC0_TYPE_MGT || | ||||
type == IEEE80211_FC0_TYPE_CTL || | type == IEEE80211_FC0_TYPE_CTL || | ||||
(m0->m_flags & M_EAPOL) != 0) { | (m0->m_flags & M_EAPOL) != 0) { | ||||
rate = tp->mgmtrate; | rate_idx = tp->mgmtrate; | ||||
} else { | } else { | ||||
/* for data frames */ | /* for data frames */ | ||||
if (ismcast) | if (ismcast) | ||||
rate = tp->mcastrate; | rate_idx = tp->mcastrate; | ||||
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) | else if (tp->ucastrate != IEEE80211_RATE_NONEXISTENT) | ||||
rate = tp->ucastrate; | rate_idx = tp->ucastrate; | ||||
else | else | ||||
rate = urtw_rtl2rate(sc->sc_currate); | rate_idx = urtw_rtl2rate_idx(sc->sc_currate); | ||||
} | } | ||||
ctl_rate = ieee80211_get_rate(IEEE80211_RATE_INDEX_CCK1); | |||||
rate = ieee80211_get_rate(rate_idx); | |||||
sc->sc_stats.txrates[sc->sc_currate]++; | sc->sc_stats.txrates[sc->sc_currate]++; | ||||
if (ismcast) | if (ismcast) | ||||
txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | ||||
IEEE80211_CRC_LEN, rate, 0, 0); | IEEE80211_CRC_LEN, rate, 0); | ||||
else { | else { | ||||
acktime = urtw_compute_txtime(14, 2,0, 0); | acktime = urtw_compute_txtime(14, ctl_rate, 0); | ||||
if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) { | if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) { | ||||
rtsenable = 1; | rtsenable = 1; | ||||
ctsenable = 0; | ctsenable = 0; | ||||
rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0); | rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, | ||||
ctstime = urtw_compute_txtime(14, 2, 0, 0); | ctl_rate, 0); | ||||
ctstime = urtw_compute_txtime(14, ctl_rate, 0); | |||||
pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | ||||
IEEE80211_CRC_LEN, rate, 0, isshort); | IEEE80211_CRC_LEN, rate, isshort); | ||||
rtsdur = ctstime + pkttime + acktime + | rtsdur = ctstime + pkttime + acktime + | ||||
3 * URTW_ASIFS_TIME; | 3 * URTW_ASIFS_TIME; | ||||
txdur = rtstime + rtsdur; | txdur = rtstime + rtsdur; | ||||
} else { | } else { | ||||
rtsenable = ctsenable = rtsdur = 0; | rtsenable = ctsenable = rtsdur = 0; | ||||
pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | pkttime = urtw_compute_txtime(m0->m_pkthdr.len + | ||||
IEEE80211_CRC_LEN, rate, 0, isshort); | IEEE80211_CRC_LEN, rate, isshort); | ||||
txdur = pkttime + URTW_ASIFS_TIME + acktime; | txdur = pkttime + URTW_ASIFS_TIME + acktime; | ||||
} | } | ||||
if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) | if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) | ||||
dur = urtw_compute_txtime(m0->m_pkthdr.len + | dur = urtw_compute_txtime(m0->m_pkthdr.len + | ||||
IEEE80211_CRC_LEN, rate, 0, isshort) + | IEEE80211_CRC_LEN, rate, isshort) + | ||||
3 * URTW_ASIFS_TIME + | 3 * URTW_ASIFS_TIME + | ||||
2 * acktime; | 2 * acktime; | ||||
else | else | ||||
dur = URTW_ASIFS_TIME + acktime; | dur = URTW_ASIFS_TIME + acktime; | ||||
} | } | ||||
USETW(wh->i_dur, dur); | USETW(wh->i_dur, dur); | ||||
xferlen = m0->m_pkthdr.len; | xferlen = m0->m_pkthdr.len; | ||||
xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3); | xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3); | ||||
if ((0 == xferlen % 64) || (0 == xferlen % 512)) | if ((0 == xferlen % 64) || (0 == xferlen % 512)) | ||||
xferlen += 1; | xferlen += 1; | ||||
memset(data->buf, 0, URTW_TX_MAXSIZE); | memset(data->buf, 0, URTW_TX_MAXSIZE); | ||||
flags = m0->m_pkthdr.len & 0xfff; | flags = m0->m_pkthdr.len & 0xfff; | ||||
flags |= URTW_TX_FLAG_NO_ENC; | flags |= URTW_TX_FLAG_NO_ENC; | ||||
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && | if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && | ||||
(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) && | (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) && | ||||
(sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) && | (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) && | ||||
(sc->sc_currate != 0)) | rate->type == IEEE80211_T_CCK && rate->props.cck.short_preamble) | ||||
flags |= URTW_TX_FLAG_SPLCP; | flags |= URTW_TX_FLAG_SPLCP; | ||||
if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) | if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) | ||||
flags |= URTW_TX_FLAG_MOREFRAG; | flags |= URTW_TX_FLAG_MOREFRAG; | ||||
flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT; | flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT; | ||||
if (sc->sc_flags & URTW_RTL8187B) { | if (sc->sc_flags & URTW_RTL8187B) { | ||||
struct urtw_8187b_txhdr *tx; | struct urtw_8187b_txhdr *tx; | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | if (sc->sc_txtimer > 0) { | ||||
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); | callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
urtw_set_multi(void *arg) | urtw_set_multi(void *arg) | ||||
{ | { | ||||
/* XXX don't know how to set a device. Lack of docs. */ | /* XXX don't know how to set a device. Lack of docs. */ | ||||
/* XXX probably the same as in rtwn(4) - need to test */ | |||||
} | } | ||||
static usb_error_t | static usb_error_t | ||||
urtw_set_rate(struct urtw_softc *sc) | urtw_set_rate(struct urtw_softc *sc) | ||||
{ | { | ||||
int i, basic_rate, min_rr_rate, max_rr_rate; | int i, basic_rate, min_rr_rate, max_rr_rate; | ||||
uint16_t data; | uint16_t data; | ||||
usb_error_t error; | usb_error_t error; | ||||
Show All 13 Lines | for (i = 0; i <= basic_rate; i++) | ||||
data |= (1 << i); | data |= (1 << i); | ||||
urtw_write16_m(sc, URTW_BRSR, data); | urtw_write16_m(sc, URTW_BRSR, data); | ||||
fail: | fail: | ||||
return (error); | return (error); | ||||
} | } | ||||
static uint16_t | static uint16_t | ||||
urtw_rtl2rate(uint32_t rate) | urtw_rtl2rate_idx(uint8_t ridx) | ||||
{ | { | ||||
unsigned int i; | static const uint16_t ridx2rate_idx[] = { | ||||
IEEE80211_RATE_INDEX_CCK1, IEEE80211_RATE_INDEX_CCK2, | |||||
IEEE80211_RATE_INDEX_CCK5, IEEE80211_RATE_INDEX_CCK11, | |||||
IEEE80211_RATE_INDEX_OFDM6, IEEE80211_RATE_INDEX_OFDM9, | |||||
IEEE80211_RATE_INDEX_OFDM12, IEEE80211_RATE_INDEX_OFDM18, | |||||
IEEE80211_RATE_INDEX_OFDM24, IEEE80211_RATE_INDEX_OFDM36, | |||||
IEEE80211_RATE_INDEX_OFDM48, IEEE80211_RATE_INDEX_OFDM54 | |||||
}; | |||||
for (i = 0; i < nitems(urtw_ratetable); i++) { | if (ridx < nitems(ridx2rate_idx)) | ||||
if (rate == urtw_ratetable[i].val) | return (ridx2rate_idx[ridx]); | ||||
return urtw_ratetable[i].reg; | |||||
} | |||||
return (0); | return (IEEE80211_RATE_INDEX_CCK1); | ||||
} | } | ||||
static usb_error_t | static usb_error_t | ||||
urtw_update_msr(struct urtw_softc *sc) | urtw_update_msr(struct urtw_softc *sc) | ||||
{ | { | ||||
struct ieee80211com *ic = &sc->sc_ic; | struct ieee80211com *ic = &sc->sc_ic; | ||||
uint8_t data; | uint8_t data; | ||||
usb_error_t error; | usb_error_t error; | ||||
▲ Show 20 Lines • Show All 2,033 Lines • ▼ Show 20 Lines | if (ieee80211_radiotap_active(ic)) { | ||||
/* XXX Are variables correct? */ | /* XXX Are variables correct? */ | ||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); | tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); | ||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); | tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); | ||||
tap->wr_dbm_antsignal = (int8_t)rssi; | tap->wr_dbm_antsignal = (int8_t)rssi; | ||||
} | } | ||||
wh = mtod(m, struct ieee80211_frame *); | wh = mtod(m, struct ieee80211_frame *); | ||||
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) | if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) | ||||
sc->sc_currate = (rate > 0) ? rate : sc->sc_currate; | if (rate > 0) | ||||
sc->sc_currate = rate; | |||||
*rssi_p = rssi; | *rssi_p = rssi; | ||||
*nf_p = noise; /* XXX correct? */ | *nf_p = noise; /* XXX correct? */ | ||||
return (m); | return (m); | ||||
} | } | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | urtw_getbuf(struct urtw_softc *sc) | ||||
URTW_ASSERT_LOCKED(sc); | URTW_ASSERT_LOCKED(sc); | ||||
bf = _urtw_getbuf(sc); | bf = _urtw_getbuf(sc); | ||||
if (bf == NULL) | if (bf == NULL) | ||||
DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__); | DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__); | ||||
return (bf); | return (bf); | ||||
} | } | ||||
static int | |||||
urtw_isbmode(uint16_t rate) | |||||
{ | |||||
return ((rate <= 22 && rate != 12 && rate != 18) || | |||||
rate == 44) ? (1) : (0); | |||||
} | |||||
static uint16_t | static uint16_t | ||||
urtw_rate2dbps(uint16_t rate) | urtw_rate2dbps(uint16_t rate) | ||||
{ | { | ||||
switch(rate) { | switch(rate) { | ||||
case 12: | case 12: | ||||
case 18: | case 18: | ||||
case 24: | case 24: | ||||
case 36: | case 36: | ||||
case 48: | case 48: | ||||
case 72: | case 72: | ||||
case 96: | case 96: | ||||
case 108: | case 108: | ||||
return (rate * 2); | return (rate * 2); | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
return (24); | return (24); | ||||
} | } | ||||
#define CCK_PREAMBLE_BITS 144 | |||||
#define CCK_PLCP_BITS 48 | |||||
static int | static int | ||||
urtw_compute_txtime(uint16_t framelen, uint16_t rate, | urtw_compute_txtime(uint16_t framelen, const struct ieee80211_rate_t *rate, | ||||
uint8_t ismgt, uint8_t isshort) | uint8_t isshort) | ||||
{ | { | ||||
uint16_t ceiling, frametime, n_dbps; | uint16_t ceiling, frametime, n_dbps; | ||||
if (urtw_isbmode(rate)) { | if (rate->type == IEEE80211_T_CCK) { | ||||
if (ismgt || !isshort || rate == 2) | frametime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; | ||||
frametime = (uint16_t)(144 + 48 + | if (isshort && rate->props.cck.short_preamble) | ||||
(framelen * 8 / (rate / 2))); | frametime >>= 1; | ||||
else | |||||
frametime = (uint16_t)(72 + 24 + | frametime += framelen * 8 / (rate->value / 2); | ||||
(framelen * 8 / (rate / 2))); | if ((framelen * 8 % (rate->value / 2)) != 0) | ||||
if ((framelen * 8 % (rate / 2)) != 0) | |||||
frametime++; | frametime++; | ||||
} else { | } else { | ||||
n_dbps = urtw_rate2dbps(rate); | n_dbps = urtw_rate2dbps(rate->value); | ||||
ceiling = (16 + 8 * framelen + 6) / n_dbps | ceiling = (16 + 8 * framelen + 6) / n_dbps | ||||
+ (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0); | + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0); | ||||
frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6); | frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6); | ||||
} | } | ||||
return (frametime); | return (frametime); | ||||
} | } | ||||
#undef CCK_PREAMBLE_BITS | |||||
#undef CCK_PLCP_BITS | |||||
/* | /* | ||||
* Callback from the 802.11 layer to update the | * Callback from the 802.11 layer to update the | ||||
* slot time based on the current setting. | * slot time based on the current setting. | ||||
*/ | */ | ||||
static void | static void | ||||
urtw_updateslot(struct ieee80211com *ic) | urtw_updateslot(struct ieee80211com *ic) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines |