Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ath/if_ath_tx.c
Show First 20 Lines • Show All 1,045 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
ath_tx_calc_protection(struct ath_softc *sc, struct ath_buf *bf) | ath_tx_calc_protection(struct ath_softc *sc, struct ath_buf *bf) | ||||
{ | { | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
uint8_t rix; | uint8_t rix; | ||||
uint16_t flags; | uint16_t flags; | ||||
int shortPreamble; | int shortPreamble; | ||||
const HAL_RATE_TABLE *rt = sc->sc_currates; | const HAL_RATE_TABLE *rt = sc->sc_currates; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
flags = bf->bf_state.bfs_txflags; | flags = bf->bf_state.bfs_txflags; | ||||
rix = bf->bf_state.bfs_rc[0].rix; | rix = bf->bf_state.bfs_rc[0].rix; | ||||
shortPreamble = bf->bf_state.bfs_shpream; | shortPreamble = bf->bf_state.bfs_shpream; | ||||
wh = mtod(bf->bf_m, struct ieee80211_frame *); | wh = mtod(bf->bf_m, struct ieee80211_frame *); | ||||
/* | /* | ||||
* If 802.11g protection is enabled, determine whether | * If 802.11g protection is enabled, determine whether | ||||
▲ Show 20 Lines • Show All 476 Lines • ▼ Show 20 Lines | |||||
* m0 may not be valid. | * m0 may not be valid. | ||||
*/ | */ | ||||
static int | static int | ||||
ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni, | ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni, | ||||
struct ath_buf *bf, struct mbuf *m0, struct ath_txq *txq) | struct ath_buf *bf, struct mbuf *m0, struct ath_txq *txq) | ||||
{ | { | ||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
struct ath_hal *ah = sc->sc_ah; | struct ath_hal *ah = sc->sc_ah; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; | const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; | ||||
int error, iswep, ismcast, isfrag, ismrr; | int error, iswep, ismcast, isfrag, ismrr; | ||||
int keyix, hdrlen, pktlen, try0 = 0; | int keyix, hdrlen, pktlen, try0 = 0; | ||||
u_int8_t rix = 0, txrate = 0; | u_int8_t rix = 0, txrate = 0; | ||||
struct ath_desc *ds; | struct ath_desc *ds; | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
u_int subtype, flags; | u_int subtype, flags; | ||||
HAL_PKT_TYPE atype; | HAL_PKT_TYPE atype; | ||||
▲ Show 20 Lines • Show All 511 Lines • ▼ Show 20 Lines | done: | ||||
return 0; | return 0; | ||||
} | } | ||||
static int | static int | ||||
ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, | ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, | ||||
struct ath_buf *bf, struct mbuf *m0, | struct ath_buf *bf, struct mbuf *m0, | ||||
const struct ieee80211_bpf_params *params) | const struct ieee80211_bpf_params *params) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct ath_hal *ah = sc->sc_ah; | struct ath_hal *ah = sc->sc_ah; | ||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
int error, ismcast, ismrr; | int error, ismcast, ismrr; | ||||
int keyix, hdrlen, pktlen, try0, txantenna; | int keyix, hdrlen, pktlen, try0, txantenna; | ||||
u_int8_t rix, txrate; | u_int8_t rix, txrate; | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
u_int flags; | u_int flags; | ||||
HAL_PKT_TYPE atype; | HAL_PKT_TYPE atype; | ||||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* This can be called by net80211. | * This can be called by net80211. | ||||
*/ | */ | ||||
int | int | ||||
ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, | ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, | ||||
const struct ieee80211_bpf_params *params) | const struct ieee80211_bpf_params *params) | ||||
{ | { | ||||
struct ieee80211com *ic = ni->ni_ic; | struct ieee80211com *ic = ni->ni_ic; | ||||
struct ifnet *ifp = ic->ic_ifp; | struct ath_softc *sc = ic->ic_softc; | ||||
struct ath_softc *sc = ifp->if_softc; | |||||
struct ath_buf *bf; | struct ath_buf *bf; | ||||
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); | struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); | ||||
int error = 0; | int error = 0; | ||||
ATH_PCU_LOCK(sc); | ATH_PCU_LOCK(sc); | ||||
if (sc->sc_inreset_cnt > 0) { | if (sc->sc_inreset_cnt > 0) { | ||||
DPRINTF(sc, ATH_DEBUG_XMIT, | DPRINTF(sc, ATH_DEBUG_XMIT, | ||||
"%s: sc_inreset_cnt > 0; bailing\n", __func__); | "%s: sc_inreset_cnt > 0; bailing\n", __func__); | ||||
error = EIO; | error = EIO; | ||||
ATH_PCU_UNLOCK(sc); | ATH_PCU_UNLOCK(sc); | ||||
goto badbad; | goto badbad; | ||||
} | } | ||||
sc->sc_txstart_cnt++; | sc->sc_txstart_cnt++; | ||||
ATH_PCU_UNLOCK(sc); | ATH_PCU_UNLOCK(sc); | ||||
/* Wake the hardware up already */ | /* Wake the hardware up already */ | ||||
ATH_LOCK(sc); | ATH_LOCK(sc); | ||||
ath_power_set_power_state(sc, HAL_PM_AWAKE); | ath_power_set_power_state(sc, HAL_PM_AWAKE); | ||||
ATH_UNLOCK(sc); | ATH_UNLOCK(sc); | ||||
ATH_TX_LOCK(sc); | ATH_TX_LOCK(sc); | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) { | if (!sc->sc_running || sc->sc_invalid) { | ||||
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__, | DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, r/i: %d/%d", | ||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ? | __func__, sc->sc_running, sc->sc_invalid); | ||||
"!running" : "invalid"); | |||||
m_freem(m); | m_freem(m); | ||||
error = ENETDOWN; | error = ENETDOWN; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* | /* | ||||
* Enforce how deep the multicast queue can grow. | * Enforce how deep the multicast queue can grow. | ||||
* | * | ||||
Show All 40 Lines | if (params == NULL) { | ||||
* sending the frame. | * sending the frame. | ||||
*/ | */ | ||||
if (ath_tx_raw_start(sc, ni, bf, m, params)) { | if (ath_tx_raw_start(sc, ni, bf, m, params)) { | ||||
error = EIO; /* XXX */ | error = EIO; /* XXX */ | ||||
goto bad2; | goto bad2; | ||||
} | } | ||||
} | } | ||||
sc->sc_wd_timer = 5; | sc->sc_wd_timer = 5; | ||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |||||
sc->sc_stats.ast_tx_raw++; | sc->sc_stats.ast_tx_raw++; | ||||
/* | /* | ||||
* Update the TIM - if there's anything queued to the | * Update the TIM - if there's anything queued to the | ||||
* software queue and power save is enabled, we should | * software queue and power save is enabled, we should | ||||
* set the TIM. | * set the TIM. | ||||
*/ | */ | ||||
ath_tx_update_tim(sc, ni, 1); | ath_tx_update_tim(sc, ni, 1); | ||||
Show All 32 Lines | bad: | ||||
/* Put the hardware back to sleep if required */ | /* Put the hardware back to sleep if required */ | ||||
ATH_LOCK(sc); | ATH_LOCK(sc); | ||||
ath_power_restore_power_state(sc); | ath_power_restore_power_state(sc); | ||||
ATH_UNLOCK(sc); | ATH_UNLOCK(sc); | ||||
badbad: | badbad: | ||||
ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p", | ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p", | ||||
m, params); | m, params); | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); | ||||
sc->sc_stats.ast_tx_raw_fail++; | sc->sc_stats.ast_tx_raw_fail++; | ||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
return error; | return error; | ||||
} | } | ||||
/* Some helper functions */ | /* Some helper functions */ | ||||
▲ Show 20 Lines • Show All 3,241 Lines • ▼ Show 20 Lines | |||||
* whilst waiting for the response. | * whilst waiting for the response. | ||||
* | * | ||||
* XXX there's no timeout handler we can override? | * XXX there's no timeout handler we can override? | ||||
*/ | */ | ||||
int | int | ||||
ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ||||
int dialogtoken, int baparamset, int batimeout) | int dialogtoken, int baparamset, int batimeout) | ||||
{ | { | ||||
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; | struct ath_softc *sc = ni->ni_ic->ic_softc; | ||||
int tid = tap->txa_tid; | int tid = tap->txa_tid; | ||||
struct ath_node *an = ATH_NODE(ni); | struct ath_node *an = ATH_NODE(ni); | ||||
struct ath_tid *atid = &an->an_tid[tid]; | struct ath_tid *atid = &an->an_tid[tid]; | ||||
/* | /* | ||||
* XXX danger Will Robinson! | * XXX danger Will Robinson! | ||||
* | * | ||||
* Although the taskqueue may be running and scheduling some more | * Although the taskqueue may be running and scheduling some more | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
* addba request should be tagged as aggregate and queued as non-aggregate | * addba request should be tagged as aggregate and queued as non-aggregate | ||||
* frames; thus updating the BAW. For now though, I'll just slide the | * frames; thus updating the BAW. For now though, I'll just slide the | ||||
* window. | * window. | ||||
*/ | */ | ||||
int | int | ||||
ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ||||
int status, int code, int batimeout) | int status, int code, int batimeout) | ||||
{ | { | ||||
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; | struct ath_softc *sc = ni->ni_ic->ic_softc; | ||||
int tid = tap->txa_tid; | int tid = tap->txa_tid; | ||||
struct ath_node *an = ATH_NODE(ni); | struct ath_node *an = ATH_NODE(ni); | ||||
struct ath_tid *atid = &an->an_tid[tid]; | struct ath_tid *atid = &an->an_tid[tid]; | ||||
int r; | int r; | ||||
DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, | DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, | ||||
"%s: %6D: called; status=%d, code=%d, batimeout=%d\n", __func__, | "%s: %6D: called; status=%d, code=%d, batimeout=%d\n", __func__, | ||||
ni->ni_macaddr, | ni->ni_macaddr, | ||||
Show All 30 Lines | |||||
* Stop ADDBA on a queue. | * Stop ADDBA on a queue. | ||||
* | * | ||||
* This can be called whilst BAR TX is currently active on the queue, | * This can be called whilst BAR TX is currently active on the queue, | ||||
* so make sure this is unblocked before continuing. | * so make sure this is unblocked before continuing. | ||||
*/ | */ | ||||
void | void | ||||
ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) | ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) | ||||
{ | { | ||||
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; | struct ath_softc *sc = ni->ni_ic->ic_softc; | ||||
int tid = tap->txa_tid; | int tid = tap->txa_tid; | ||||
struct ath_node *an = ATH_NODE(ni); | struct ath_node *an = ATH_NODE(ni); | ||||
struct ath_tid *atid = &an->an_tid[tid]; | struct ath_tid *atid = &an->an_tid[tid]; | ||||
ath_bufhead bf_cq; | ath_bufhead bf_cq; | ||||
struct ath_buf *bf; | struct ath_buf *bf; | ||||
DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: %6D: called\n", | DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: %6D: called\n", | ||||
__func__, | __func__, | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* XXX This uses a hard-coded max BAR count value; the whole | * XXX This uses a hard-coded max BAR count value; the whole | ||||
* XXX BAR TX success or failure should be better handled! | * XXX BAR TX success or failure should be better handled! | ||||
*/ | */ | ||||
void | void | ||||
ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, | ||||
int status) | int status) | ||||
{ | { | ||||
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; | struct ath_softc *sc = ni->ni_ic->ic_softc; | ||||
int tid = tap->txa_tid; | int tid = tap->txa_tid; | ||||
struct ath_node *an = ATH_NODE(ni); | struct ath_node *an = ATH_NODE(ni); | ||||
struct ath_tid *atid = &an->an_tid[tid]; | struct ath_tid *atid = &an->an_tid[tid]; | ||||
int attempts = tap->txa_attempts; | int attempts = tap->txa_attempts; | ||||
int old_txa_start; | int old_txa_start; | ||||
DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, | DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, | ||||
"%s: %6D: called; txa_tid=%d, atid->tid=%d, status=%d, attempts=%d, txa_start=%d, txa_seqpending=%d\n", | "%s: %6D: called; txa_tid=%d, atid->tid=%d, status=%d, attempts=%d, txa_start=%d, txa_seqpending=%d\n", | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* This is called whenever the pending ADDBA request times out. | * This is called whenever the pending ADDBA request times out. | ||||
* Unpause and reschedule the TID. | * Unpause and reschedule the TID. | ||||
*/ | */ | ||||
void | void | ||||
ath_addba_response_timeout(struct ieee80211_node *ni, | ath_addba_response_timeout(struct ieee80211_node *ni, | ||||
struct ieee80211_tx_ampdu *tap) | struct ieee80211_tx_ampdu *tap) | ||||
{ | { | ||||
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; | struct ath_softc *sc = ni->ni_ic->ic_softc; | ||||
int tid = tap->txa_tid; | int tid = tap->txa_tid; | ||||
struct ath_node *an = ATH_NODE(ni); | struct ath_node *an = ATH_NODE(ni); | ||||
struct ath_tid *atid = &an->an_tid[tid]; | struct ath_tid *atid = &an->an_tid[tid]; | ||||
DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, | DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, | ||||
"%s: %6D: TID=%d, called; resuming\n", | "%s: %6D: TID=%d, called; resuming\n", | ||||
__func__, | __func__, | ||||
ni->ni_macaddr, | ni->ni_macaddr, | ||||
▲ Show 20 Lines • Show All 155 Lines • Show Last 20 Lines |