Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/bwn/if_bwn.c
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | static void bwn_pio_handle_txeof(struct bwn_mac *, | ||||
const struct bwn_txstatus *); | const struct bwn_txstatus *); | ||||
static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); | static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); | ||||
static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); | static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); | ||||
static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, | static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, | ||||
uint16_t); | uint16_t); | ||||
static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, | static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, | ||||
uint32_t); | uint32_t); | ||||
static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, | static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, | ||||
struct mbuf *); | struct mbuf **); | ||||
static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); | static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); | ||||
static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, | static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, | ||||
struct bwn_pio_txqueue *, uint32_t, const void *, int); | struct bwn_pio_txqueue *, uint32_t, const void *, int); | ||||
static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, | static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, | ||||
uint16_t, uint32_t); | uint16_t, uint32_t); | ||||
static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, | static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, | ||||
struct bwn_pio_txqueue *, uint16_t, const void *, int); | struct bwn_pio_txqueue *, uint16_t, const void *, int); | ||||
static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, | static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, | static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, | ||||
bus_size_t, int); | bus_size_t, int); | ||||
static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); | static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); | ||||
static void bwn_ratectl_tx_complete(const struct ieee80211_node *, | static void bwn_ratectl_tx_complete(const struct ieee80211_node *, | ||||
const struct bwn_txstatus *); | const struct bwn_txstatus *); | ||||
static void bwn_dma_handle_txeof(struct bwn_mac *, | static void bwn_dma_handle_txeof(struct bwn_mac *, | ||||
const struct bwn_txstatus *); | const struct bwn_txstatus *); | ||||
static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, | static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, | ||||
struct mbuf *); | struct mbuf **); | ||||
static int bwn_dma_getslot(struct bwn_dma_ring *); | static int bwn_dma_getslot(struct bwn_dma_ring *); | ||||
static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, | static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, | ||||
uint8_t); | uint8_t); | ||||
static int bwn_dma_attach(struct bwn_mac *); | static int bwn_dma_attach(struct bwn_mac *); | ||||
static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, | static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, | ||||
int, int); | int, int); | ||||
static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, | static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, | ||||
const struct bwn_txstatus *, uint16_t, int *); | const struct bwn_txstatus *, uint16_t, int *); | ||||
▲ Show 20 Lines • Show All 778 Lines • ▼ Show 20 Lines | bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) | ||||
BWN_ASSERT_LOCKED(sc); | BWN_ASSERT_LOCKED(sc); | ||||
if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { | if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { | ||||
m_freem(m); | m_freem(m); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? | error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? | ||||
bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); | bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m); | ||||
if (error) { | if (error) { | ||||
m_freem(m); | m_freem(m); | ||||
return (error); | return (error); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) | bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, | ||||
struct mbuf **mp) | |||||
{ | { | ||||
struct bwn_pio_txpkt *tp; | struct bwn_pio_txpkt *tp; | ||||
struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); | struct bwn_pio_txqueue *tq; | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_txhdr txhdr; | struct bwn_txhdr txhdr; | ||||
struct mbuf *m_new; | struct mbuf *m, *m_new; | ||||
uint32_t ctl32; | uint32_t ctl32; | ||||
int error; | int error; | ||||
uint16_t ctl16; | uint16_t ctl16; | ||||
BWN_ASSERT_LOCKED(sc); | BWN_ASSERT_LOCKED(sc); | ||||
/* XXX TODO send packets after DTIM */ | /* XXX TODO send packets after DTIM */ | ||||
m = *mp; | |||||
tq = bwn_pio_select(mac, M_WME_GETAC(m)); | |||||
KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); | KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); | ||||
tp = TAILQ_FIRST(&tq->tq_pktlist); | tp = TAILQ_FIRST(&tq->tq_pktlist); | ||||
tp->tp_ni = ni; | tp->tp_ni = ni; | ||||
tp->tp_m = m; | tp->tp_m = m; | ||||
error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); | error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); | ||||
if (error) { | if (error) { | ||||
device_printf(sc->sc_dev, "tx fail\n"); | device_printf(sc->sc_dev, "tx fail\n"); | ||||
return (error); | return (error); | ||||
} | } | ||||
TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); | TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); | ||||
tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); | tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); | ||||
tq->tq_free--; | tq->tq_free--; | ||||
if (bhnd_get_hwrev(sc->sc_dev) >= 8) { | if (bhnd_get_hwrev(sc->sc_dev) >= 8) { | ||||
/* | /* | ||||
* XXX please removes m_defrag(9) | * XXX please removes m_defrag(9) | ||||
*/ | */ | ||||
m_new = m_defrag(m, M_NOWAIT); | m_new = m_defrag(*mp, M_NOWAIT); | ||||
if (m_new == NULL) { | if (m_new == NULL) { | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"%s: can't defrag TX buffer\n", | "%s: can't defrag TX buffer\n", | ||||
__func__); | __func__); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
*mp = m_new; | |||||
if (m_new->m_next != NULL) | if (m_new->m_next != NULL) | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"TODO: fragmented packets for PIO\n"); | "TODO: fragmented packets for PIO\n"); | ||||
tp->tp_m = m_new; | tp->tp_m = m_new; | ||||
/* send HEADER */ | /* send HEADER */ | ||||
ctl32 = bwn_pio_write_multi_4(mac, tq, | ctl32 = bwn_pio_write_multi_4(mac, tq, | ||||
(BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | | (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | | ||||
Show All 34 Lines | bwn_pio_select(struct bwn_mac *mac, uint8_t prio) | ||||
case 3: | case 3: | ||||
return (&mac->mac_method.pio.wme[WME_AC_VO]); | return (&mac->mac_method.pio.wme[WME_AC_VO]); | ||||
} | } | ||||
KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); | KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
static int | static int | ||||
bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) | bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, | ||||
struct mbuf **mp) | |||||
{ | { | ||||
#define BWN_GET_TXHDRCACHE(slot) \ | #define BWN_GET_TXHDRCACHE(slot) \ | ||||
&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) | &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) | ||||
struct bwn_dma *dma = &mac->mac_method.dma; | struct bwn_dma *dma = &mac->mac_method.dma; | ||||
struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); | struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(*mp)); | ||||
struct bwn_dmadesc_generic *desc; | struct bwn_dmadesc_generic *desc; | ||||
struct bwn_dmadesc_meta *mt; | struct bwn_dmadesc_meta *mt; | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct mbuf *m; | |||||
uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; | uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; | ||||
int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; | int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; | ||||
BWN_ASSERT_LOCKED(sc); | BWN_ASSERT_LOCKED(sc); | ||||
KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); | KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); | ||||
/* XXX send after DTIM */ | /* XXX send after DTIM */ | ||||
m = *mp; | |||||
slot = bwn_dma_getslot(dr); | slot = bwn_dma_getslot(dr); | ||||
dr->getdesc(dr, slot, &desc, &mt); | dr->getdesc(dr, slot, &desc, &mt); | ||||
KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, | KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, | ||||
("%s:%d: fail", __func__, __LINE__)); | ("%s:%d: fail", __func__, __LINE__)); | ||||
error = bwn_set_txhdr(dr->dr_mac, ni, m, | error = bwn_set_txhdr(dr->dr_mac, ni, m, | ||||
(struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), | (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), | ||||
BWN_DMA_COOKIE(dr, slot)); | BWN_DMA_COOKIE(dr, slot)); | ||||
Show All 32 Lines | if (error) { /* error == EFBIG */ | ||||
m_new = m_defrag(m, M_NOWAIT); | m_new = m_defrag(m, M_NOWAIT); | ||||
if (m_new == NULL) { | if (m_new == NULL) { | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"%s: can't defrag TX buffer\n", | "%s: can't defrag TX buffer\n", | ||||
__func__); | __func__); | ||||
error = ENOBUFS; | error = ENOBUFS; | ||||
goto fail; | goto fail; | ||||
} else { | |||||
m = m_new; | |||||
} | } | ||||
*mp = m = m_new; | |||||
mt->mt_m = m; | mt->mt_m = m; | ||||
error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, | error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, | ||||
m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); | m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); | ||||
if (error) { | if (error) { | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"%s: can't load TX buffer (2) %d\n", | "%s: can't load TX buffer (2) %d\n", | ||||
__func__, error); | __func__, error); | ||||
▲ Show 20 Lines • Show All 6,507 Lines • Show Last 20 Lines |