Changeset View
Changeset View
Standalone View
Standalone View
sys/net80211/ieee80211_freebsd.c
Show First 20 Lines • Show All 556 Lines • ▼ Show 20 Lines | mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, | ||||
NULL); | NULL); | ||||
if (mtag == NULL) | if (mtag == NULL) | ||||
return (-1); | return (-1); | ||||
rx = (struct ieee80211_rx_params *)(mtag + 1); | rx = (struct ieee80211_rx_params *)(mtag + 1); | ||||
memcpy(rxs, &rx->params, sizeof(*rxs)); | memcpy(rxs, &rx->params, sizeof(*rxs)); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | |||||
ieee80211_tx_watchdog_attach(struct ieee80211com *ic) | |||||
{ | |||||
if (ic->ic_flags_ext & IEEE80211_FEXT_WATCHDOG) { | |||||
IEEE80211_WT_LOCK_INIT(ic, ic->ic_name); | |||||
callout_init_mtx(&ic->ic_tx_watchdog, | |||||
IEEE80211_WT_LOCK_OBJ(ic), 0); | |||||
} | |||||
} | |||||
static void | |||||
ieee80211_tx_watchdog(void *arg) | |||||
{ | |||||
struct ieee80211com *ic = arg; | |||||
if (ic->ic_tx_timer > 0) { | |||||
if (--ic->ic_tx_timer == 0) { | |||||
ic_printf(ic, "device timeout\n"); | |||||
counter_u64_add(ic->ic_oerrors, ic->ic_tx_queued); | |||||
ic->ic_tx_queued = 0; | |||||
ieee80211_restart_all(ic); | |||||
return; | |||||
} | |||||
callout_reset(&ic->ic_tx_watchdog, hz, ieee80211_tx_watchdog, | |||||
ic); | |||||
} | |||||
} | |||||
void | |||||
ieee80211_tx_watchdog_refresh(struct ieee80211com *ic, int nframes, int update) | |||||
{ | |||||
if (ic->ic_flags_ext & IEEE80211_FEXT_WATCHDOG) { | |||||
IEEE80211_WT_LOCK(ic); | |||||
if (ic->ic_tx_queued + nframes < 0) | |||||
ic->ic_tx_queued = -nframes; | |||||
if (ic->ic_tx_queued == 0) { | |||||
ic->ic_tx_timer = IEEE80211_WATCHDOG_TIMEOUT; | |||||
callout_reset(&ic->ic_tx_watchdog, hz, | |||||
ieee80211_tx_watchdog, ic); | |||||
} | |||||
ic->ic_tx_queued += nframes; | |||||
if (ic->ic_tx_queued == 0) | |||||
ic->ic_tx_timer = 0; | |||||
else if (update != 0) | |||||
ic->ic_tx_timer = IEEE80211_WATCHDOG_TIMEOUT; | |||||
IEEE80211_WT_UNLOCK(ic); | |||||
} | |||||
} | |||||
void | |||||
ieee80211_tx_watchdog_stop(struct ieee80211com *ic) | |||||
{ | |||||
if (ic->ic_flags_ext & IEEE80211_FEXT_WATCHDOG) { | |||||
IEEE80211_WT_LOCK(ic); | |||||
callout_stop(&ic->ic_tx_watchdog); | |||||
ic->ic_tx_timer = 0; | |||||
ic->ic_tx_queued = 0; | |||||
IEEE80211_WT_UNLOCK(ic); | |||||
} | |||||
} | |||||
void | |||||
ieee80211_tx_watchdog_detach(struct ieee80211com *ic) | |||||
{ | |||||
if (ic->ic_flags_ext & IEEE80211_FEXT_WATCHDOG) { | |||||
callout_drain(&ic->ic_tx_watchdog); | |||||
IEEE80211_WT_LOCK_DESTROY(ic); | |||||
} | |||||
} | |||||
/* | /* | ||||
* Transmit a frame to the parent interface. | * Transmit a frame to the parent interface. | ||||
*/ | */ | ||||
int | int | ||||
ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) | ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) | ||||
{ | { | ||||
int error; | int error, nframes; | ||||
struct mbuf *mnext; | |||||
nframes = 1; | |||||
for (mnext = m->m_nextpkt; mnext != NULL; mnext = mnext->m_nextpkt) | |||||
nframes++; | |||||
/* | /* | ||||
* Assert the IC TX lock is held - this enforces the | * Assert the IC TX lock is held - this enforces the | ||||
* processing -> queuing order is maintained | * processing -> queuing order is maintained | ||||
*/ | */ | ||||
IEEE80211_TX_LOCK_ASSERT(ic); | IEEE80211_TX_LOCK_ASSERT(ic); | ||||
ieee80211_tx_watchdog_refresh(ic, nframes, 0); | |||||
error = ic->ic_transmit(ic, m); | error = ic->ic_transmit(ic, m); | ||||
if (error) { | if (error) { | ||||
struct ieee80211_node *ni; | struct ieee80211_node *ni; | ||||
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; | ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; | ||||
/* XXX number of fragments */ | if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, nframes); | ||||
if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); | ieee80211_tx_watchdog_refresh(ic, -nframes, 0); | ||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
ieee80211_free_mbuf(m); | ieee80211_free_mbuf(m); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Transmit a frame to the VAP interface. | * Transmit a frame to the VAP interface. | ||||
▲ Show 20 Lines • Show All 357 Lines • Show Last 20 Lines |