mirror of
https://github.com/proski/madwifi
synced 2024-11-22 06:21:47 +03:00
Merge some changes from -dfs:r3800:3803
Replace ath_hal_puttxbuf by ath_hw_puttxbuf git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3804 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
49943c6614
commit
bc6b795455
130
ath/if_ath.c
130
ath/if_ath.c
@ -1593,6 +1593,35 @@ static inline void ath_override_intmit_if_disabled(struct ath_softc *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline HAL_BOOL ath_hw_puttxbuf(struct ath_softc *sc, u_int qnum,
|
||||||
|
u_int32_t txdp, const char *msg)
|
||||||
|
{
|
||||||
|
HAL_BOOL result;
|
||||||
|
u_int32_t txdp_2;
|
||||||
|
|
||||||
|
result = ath_hal_puttxbuf(sc->sc_ah, qnum, txdp);
|
||||||
|
if (!result) {
|
||||||
|
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
||||||
|
"TXQ%d: BUG failed to set TXDP:%08x\n",
|
||||||
|
qnum, txdp);
|
||||||
|
ath_txq_check(sc, &sc->sc_txq[qnum], msg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
txdp_2 = ath_hal_gettxbuf(sc->sc_ah, qnum);
|
||||||
|
if (txdp_2 != txdp) {
|
||||||
|
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
||||||
|
"TXQ%d: BUG failed to set TXDP:%08x (is %08x)\n",
|
||||||
|
qnum, txdp, txdp_2);
|
||||||
|
ath_txq_check(sc, &sc->sc_txq[qnum], msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If channel change is sucessfull, sc->sc_curchan is updated with the new
|
||||||
|
* channel */
|
||||||
|
|
||||||
static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
||||||
HAL_CHANNEL *channel, HAL_BOOL bChannelChange,
|
HAL_CHANNEL *channel, HAL_BOOL bChannelChange,
|
||||||
HAL_STATUS *status)
|
HAL_STATUS *status)
|
||||||
@ -1601,6 +1630,7 @@ static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
|||||||
unsigned long __axq_lockflags[HAL_NUM_TX_QUEUES];
|
unsigned long __axq_lockflags[HAL_NUM_TX_QUEUES];
|
||||||
struct ath_txq * txq;
|
struct ath_txq * txq;
|
||||||
int i;
|
int i;
|
||||||
|
u_int8_t old_privFlags = sc->sc_curchan.privFlags;
|
||||||
|
|
||||||
/* ath_hal_reset() resets all TXDP pointers, so we need to
|
/* ath_hal_reset() resets all TXDP pointers, so we need to
|
||||||
* lock all TXQ to avoid race condition with
|
* lock all TXQ to avoid race condition with
|
||||||
@ -1614,6 +1644,7 @@ static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = ath_hal_reset(sc->sc_ah, sc->sc_opmode, channel, bChannelChange, status);
|
ret = ath_hal_reset(sc->sc_ah, sc->sc_opmode, channel, bChannelChange, status);
|
||||||
|
|
||||||
/* Restore all TXDP pointers, if appropriate, and unlock in
|
/* Restore all TXDP pointers, if appropriate, and unlock in
|
||||||
* the reverse order we locked */
|
* the reverse order we locked */
|
||||||
for (i = HAL_NUM_TX_QUEUES - 1; i >= 0; i--) {
|
for (i = HAL_NUM_TX_QUEUES - 1; i >= 0; i--) {
|
||||||
@ -1633,33 +1664,47 @@ static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
|||||||
txq->axq_qnum, txdp);
|
txq->axq_qnum, txdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bf = STAILQ_FIRST(&txq->axq_q);
|
/* We restore TXDP to the first "In Progress" TX
|
||||||
if (bf != NULL) {
|
* descriptor. We skip "Done" TX descriptors in
|
||||||
|
* order to avoid sending duplicate packets */
|
||||||
|
STAILQ_FOREACH(bf, &txq->axq_q, bf_list) {
|
||||||
|
if (ath_hal_txprocdesc(sc->sc_ah,
|
||||||
|
bf->bf_desc,
|
||||||
|
&bf->bf_dsstatus.ds_txstat) ==
|
||||||
|
HAL_EINPROGRESS) {
|
||||||
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
||||||
"TXQ%d: restoring "
|
"TXQ%d: restoring"
|
||||||
"TXDP:%08llx\n",
|
" TXDP:%08llx\n",
|
||||||
txq->axq_qnum,
|
txq->axq_qnum,
|
||||||
(u_int64_t)bf->bf_daddr);
|
(u_int64_t)bf->bf_daddr);
|
||||||
ath_hal_puttxbuf(sc->sc_ah, txq->axq_qnum,
|
ath_hw_puttxbuf(sc, txq->axq_qnum,
|
||||||
bf->bf_daddr);
|
bf->bf_daddr,
|
||||||
txdp = ath_hal_gettxbuf(sc->sc_ah,
|
__func__);
|
||||||
|
ath_hal_txstart(sc->sc_ah,
|
||||||
txq->axq_qnum);
|
txq->axq_qnum);
|
||||||
if (txdp != bf->bf_daddr) {
|
|
||||||
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
|
||||||
"TXQ%d: BUG failed to "
|
|
||||||
"restore TXDP:%08llx "
|
|
||||||
"(is %08x)\n",
|
|
||||||
txq->axq_qnum,
|
|
||||||
(u_int64_t)bf->bf_daddr,
|
|
||||||
txdp);
|
|
||||||
}
|
}
|
||||||
ath_hal_txstart(sc->sc_ah, txq->axq_qnum);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&txq->axq_lock,
|
spin_unlock_irqrestore(&txq->axq_lock,
|
||||||
__axq_lockflags[i]);
|
__axq_lockflags[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On failure, we return immediately */
|
||||||
|
if (!ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Do the same as in ath_getchannels() */
|
||||||
|
ath_radar_correct_dfs_flags(sc, channel);
|
||||||
|
|
||||||
|
/* Restore CHANNEL_DFS_CLEAR and CHANNEL_INTERFERENCE flags */
|
||||||
|
#define CHANNEL_DFS_FLAGS (CHANNEL_DFS_CLEAR|CHANNEL_INTERFERENCE)
|
||||||
|
channel->privFlags = (channel->privFlags & ~CHANNEL_DFS_FLAGS) |
|
||||||
|
(old_privFlags & CHANNEL_DFS_FLAGS);
|
||||||
|
|
||||||
|
/* On success, we update sc->sc_curchan which can be needed by other
|
||||||
|
* functions below , like ath_radar_update() at least */
|
||||||
|
sc->sc_curchan = *channel;
|
||||||
|
|
||||||
#ifdef ATH_CAP_TPC
|
#ifdef ATH_CAP_TPC
|
||||||
if (sc->sc_hastpc && (hal_tpc != ath_hal_gettpc(sc->sc_ah))) {
|
if (sc->sc_hastpc && (hal_tpc != ath_hal_gettpc(sc->sc_ah))) {
|
||||||
EPRINTF(sc, "TPC HAL capability out of sync. Got %d!\n",
|
EPRINTF(sc, "TPC HAL capability out of sync. Got %d!\n",
|
||||||
@ -1687,8 +1732,11 @@ static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Channel Availability Check is running, or a channel has already found to be
|
/* Returns true if we can transmit any frames : this is not the case if :
|
||||||
* unavailable. */
|
* - we are on a DFS channel
|
||||||
|
* - 802.11h is enabled
|
||||||
|
* - Channel Availability Check is not done or a radar has been detected
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
ath_chan_unavail(struct ath_softc *sc)
|
ath_chan_unavail(struct ath_softc *sc)
|
||||||
{
|
{
|
||||||
@ -2115,9 +2163,10 @@ ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t
|
|||||||
/* Below leaves an_uapsd_q NULL. */
|
/* Below leaves an_uapsd_q NULL. */
|
||||||
STAILQ_CONCAT(&uapsd_xmit_q->axq_q,
|
STAILQ_CONCAT(&uapsd_xmit_q->axq_q,
|
||||||
&an->an_uapsd_q);
|
&an->an_uapsd_q);
|
||||||
ath_hal_puttxbuf(sc->sc_ah,
|
ath_hw_puttxbuf(sc,
|
||||||
uapsd_xmit_q->axq_qnum,
|
uapsd_xmit_q->axq_qnum,
|
||||||
(STAILQ_FIRST(&uapsd_xmit_q->axq_q))->bf_daddr);
|
(STAILQ_FIRST(&uapsd_xmit_q->axq_q))->bf_daddr,
|
||||||
|
__func__);
|
||||||
|
|
||||||
ath_hal_txstart(sc->sc_ah,
|
ath_hal_txstart(sc->sc_ah,
|
||||||
uapsd_xmit_q->axq_qnum);
|
uapsd_xmit_q->axq_qnum);
|
||||||
@ -2915,20 +2964,7 @@ ath_tx_txqaddbuf(struct ath_softc *sc, struct ieee80211_node *ni,
|
|||||||
} else {
|
} else {
|
||||||
ATH_TXQ_LINK_DESC(txq, bf);
|
ATH_TXQ_LINK_DESC(txq, bf);
|
||||||
if (!STAILQ_FIRST(&txq->axq_q)) {
|
if (!STAILQ_FIRST(&txq->axq_q)) {
|
||||||
u_int32_t txdp;
|
ath_hw_puttxbuf(sc, txq->axq_qnum, bf->bf_daddr, __func__);
|
||||||
|
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
|
||||||
DPRINTF(sc, ATH_DEBUG_XMIT, "TXDP[%u] = %08llx (%p)\n",
|
|
||||||
txq->axq_qnum, (u_int64_t)bf->bf_daddr,
|
|
||||||
bf->bf_desc);
|
|
||||||
txdp = ath_hal_gettxbuf(ah, txq->axq_qnum);
|
|
||||||
if (txdp != bf->bf_daddr) {
|
|
||||||
DPRINTF(sc, ATH_DEBUG_WATCHDOG,
|
|
||||||
"TXQ%d: BUG TXDP:%08x instead "
|
|
||||||
"of %08llx\n",
|
|
||||||
txq->axq_qnum, txdp,
|
|
||||||
(u_int64_t)bf->bf_daddr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
|
ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
|
||||||
|
|
||||||
@ -5056,8 +5092,9 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap, int *needmar
|
|||||||
/* Append the private VAP mcast list to the cabq. */
|
/* Append the private VAP mcast list to the cabq. */
|
||||||
ATH_TXQ_MOVE_Q(&avp->av_mcastq, cabq);
|
ATH_TXQ_MOVE_Q(&avp->av_mcastq, cabq);
|
||||||
if (!STAILQ_FIRST(&cabq->axq_q))
|
if (!STAILQ_FIRST(&cabq->axq_q))
|
||||||
ath_hal_puttxbuf(ah, cabq->axq_qnum,
|
ath_hw_puttxbuf(sc, cabq->axq_qnum,
|
||||||
bfmcast->bf_daddr);
|
bfmcast->bf_daddr,
|
||||||
|
__func__);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||||
@ -5250,9 +5287,9 @@ ath_beacon_send(struct ath_softc *sc, int *needmark, uint64_t hw_tsf)
|
|||||||
}
|
}
|
||||||
/* NB: cabq traffic should already be queued and primed */
|
/* NB: cabq traffic should already be queued and primed */
|
||||||
DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
|
DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
|
||||||
"Invoking ath_hal_puttxbuf with sc_bhalq: %d bfaddr: %x\n",
|
"Invoking ath_hw_puttxbuf with sc_bhalq: %d bfaddr: %x\n",
|
||||||
sc->sc_bhalq, bfaddr);
|
sc->sc_bhalq, bfaddr);
|
||||||
ath_hal_puttxbuf(ah, sc->sc_bhalq, bfaddr);
|
ath_hw_puttxbuf(sc, sc->sc_bhalq, bfaddr, __func__);
|
||||||
|
|
||||||
DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
|
DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
|
||||||
"Invoking ath_hal_txstart with sc_bhalq: %d\n",
|
"Invoking ath_hal_txstart with sc_bhalq: %d\n",
|
||||||
@ -5927,8 +5964,8 @@ ath_node_move_data(const struct ieee80211_node *ni)
|
|||||||
else
|
else
|
||||||
bf = STAILQ_FIRST(&txq->axq_q);
|
bf = STAILQ_FIRST(&txq->axq_q);
|
||||||
if (bf) {
|
if (bf) {
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum,
|
ath_hw_puttxbuf(sc, txq->axq_qnum,
|
||||||
bf->bf_daddr);
|
bf->bf_daddr, __func__);
|
||||||
ath_hal_txstart(ah, txq->axq_qnum);
|
ath_hal_txstart(ah, txq->axq_qnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6055,7 +6092,7 @@ ath_node_move_data(const struct ieee80211_node *ni)
|
|||||||
bf = STAILQ_FIRST(&txq->axq_q);
|
bf = STAILQ_FIRST(&txq->axq_q);
|
||||||
|
|
||||||
if (bf) {
|
if (bf) {
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
ath_hw_puttxbuf(sc, txq->axq_qnum, bf->bf_daddr, __func__);
|
||||||
ath_hal_txstart(ah, txq->axq_qnum);
|
ath_hal_txstart(ah, txq->axq_qnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6093,7 +6130,7 @@ ath_node_move_data(const struct ieee80211_node *ni)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bf) {
|
if (bf) {
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
ath_hw_puttxbuf(sc, txq->axq_qnum, bf->bf_daddr, __func__);
|
||||||
ath_hal_txstart(ah, txq->axq_qnum);
|
ath_hal_txstart(ah, txq->axq_qnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7004,7 +7041,7 @@ static void ath_grppoll_start(struct ieee80211vap *vap, int pollcount)
|
|||||||
/* make it circular */
|
/* make it circular */
|
||||||
bf->bf_desc->ds_link = ath_ds_link_swap(head->bf_daddr);
|
bf->bf_desc->ds_link = ath_ds_link_swap(head->bf_daddr);
|
||||||
/* start the queue */
|
/* start the queue */
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum, head->bf_daddr);
|
ath_hw_puttxbuf(sc, txq->axq_qnum, head->bf_daddr, __func__);
|
||||||
ath_hal_txstart(ah, txq->axq_qnum);
|
ath_hal_txstart(ah, txq->axq_qnum);
|
||||||
sc->sc_xrgrppoll = 1;
|
sc->sc_xrgrppoll = 1;
|
||||||
#undef USE_SHPREAMBLE
|
#undef USE_SHPREAMBLE
|
||||||
@ -8328,6 +8365,11 @@ ath_tx_tasklet(TQUEUE_ARG data)
|
|||||||
struct ath_softc *sc = dev->priv;
|
struct ath_softc *sc = dev->priv;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
|
||||||
|
if (!ath_txq_check(sc, &sc->sc_txq[i], __func__))
|
||||||
|
ath_txq_dump(sc, &sc->sc_txq[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Process each active queue. This includes sc_cabq, sc_xrtq and
|
/* Process each active queue. This includes sc_cabq, sc_xrtq and
|
||||||
* sc_uapsdq */
|
* sc_uapsdq */
|
||||||
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
|
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
|
||||||
@ -8680,8 +8722,6 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->sc_curchan = hchan;
|
|
||||||
|
|
||||||
/* Change channels and update the h/w rate map
|
/* Change channels and update the h/w rate map
|
||||||
* if we're switching; e.g. 11a to 11b/g. */
|
* if we're switching; e.g. 11a to 11b/g. */
|
||||||
ath_chan_change(sc, chan);
|
ath_chan_change(sc, chan);
|
||||||
|
@ -683,6 +683,14 @@ struct ath_softc {
|
|||||||
unsigned int sc_xrgrppoll:1; /* xr group polls are active */
|
unsigned int sc_xrgrppoll:1; /* xr group polls are active */
|
||||||
unsigned int sc_syncbeacon:1; /* sync/resync beacon timers */
|
unsigned int sc_syncbeacon:1; /* sync/resync beacon timers */
|
||||||
unsigned int sc_hasclrkey:1; /* CLR key supported */
|
unsigned int sc_hasclrkey:1; /* CLR key supported */
|
||||||
|
/* sc_stagbeacons : If set and several VAPs need to send beacons,
|
||||||
|
* this flag means that beacons transmission is evenly distributed
|
||||||
|
* over time. If unset, it means that beacons for all VAPs are sent
|
||||||
|
* at the same time. For instance, with a common beacon interval of
|
||||||
|
* 100 TU and 2 VAPs, 1 beacon is sent every 50 TU (staggered mode)
|
||||||
|
* or 2 beacons are sent every 100 TU (bursted mode) depending on
|
||||||
|
* this flag
|
||||||
|
*/
|
||||||
unsigned int sc_stagbeacons:1; /* use staggered beacons */
|
unsigned int sc_stagbeacons:1; /* use staggered beacons */
|
||||||
unsigned int sc_dfswait:1; /* waiting on channel for radar detect */
|
unsigned int sc_dfswait:1; /* waiting on channel for radar detect */
|
||||||
unsigned int sc_ackrate:1; /* send acks at high bitrate */
|
unsigned int sc_ackrate:1; /* send acks at high bitrate */
|
||||||
|
Loading…
Reference in New Issue
Block a user