1/*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: stable/11/sys/dev/bwn/if_bwn.c 342138 2018-12-15 20:07:32Z markj $"); |
32 33/* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37#include "opt_bwn.h" 38#include "opt_wlan.h" 39 --- 151 unchanged lines hidden (view full) --- 191 const struct bwn_txstatus *); 192static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 193static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 194static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 195 uint16_t); 196static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 197 uint32_t); 198static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, |
199 struct mbuf **); |
200static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 201static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 202 struct bwn_pio_txqueue *, uint32_t, const void *, int); 203static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 204 uint16_t, uint32_t); 205static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 206 struct bwn_pio_txqueue *, uint16_t, const void *, int); 207static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, --- 48 unchanged lines hidden (view full) --- 256 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 257 int); 258static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 259 bus_size_t, int); 260static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 261static void bwn_dma_handle_txeof(struct bwn_mac *, 262 const struct bwn_txstatus *); 263static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, |
264 struct mbuf **); |
265static int bwn_dma_getslot(struct bwn_dma_ring *); 266static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 267 uint8_t); 268static int bwn_dma_attach(struct bwn_mac *); 269static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 270 int, int, int); 271static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 272 const struct bwn_txstatus *, uint16_t, int *); --- 659 unchanged lines hidden (view full) --- 932 BWN_ASSERT_LOCKED(sc); 933 934 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 935 m_freem(m); 936 return (ENXIO); 937 } 938 939 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? |
940 bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m); |
941 if (error) { 942 m_freem(m); 943 return (error); 944 } 945 return (0); 946} 947 948static int |
949bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, 950 struct mbuf **mp) |
951{ 952 struct bwn_pio_txpkt *tp; |
953 struct bwn_pio_txqueue *tq; |
954 struct bwn_softc *sc = mac->mac_sc; 955 struct bwn_txhdr txhdr; |
956 struct mbuf *m, *m_new; |
957 uint32_t ctl32; 958 int error; 959 uint16_t ctl16; 960 961 BWN_ASSERT_LOCKED(sc); 962 963 /* XXX TODO send packets after DTIM */ 964 |
965 m = *mp; 966 tq = bwn_pio_select(mac, M_WME_GETAC(m)); |
967 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 968 tp = TAILQ_FIRST(&tq->tq_pktlist); 969 tp->tp_ni = ni; 970 tp->tp_m = m; 971 972 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 973 if (error) { 974 device_printf(sc->sc_dev, "tx fail\n"); 975 return (error); 976 } 977 978 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 979 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 980 tq->tq_free--; 981 982 if (siba_get_revid(sc->sc_dev) >= 8) { 983 /* 984 * XXX please removes m_defrag(9) 985 */ |
986 m_new = m_defrag(*mp, M_NOWAIT); |
987 if (m_new == NULL) { 988 device_printf(sc->sc_dev, 989 "%s: can't defrag TX buffer\n", 990 __func__); 991 return (ENOBUFS); 992 } |
993 *mp = m_new; |
994 if (m_new->m_next != NULL) 995 device_printf(sc->sc_dev, 996 "TODO: fragmented packets for PIO\n"); 997 tp->tp_m = m_new; 998 999 /* send HEADER */ 1000 ctl32 = bwn_pio_write_multi_4(mac, tq, 1001 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | --- 34 unchanged lines hidden (view full) --- 1036 case 3: 1037 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1038 } 1039 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1040 return (NULL); 1041} 1042 1043static int |
1044bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, 1045 struct mbuf **mp) |
1046{ 1047#define BWN_GET_TXHDRCACHE(slot) \ 1048 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1049 struct bwn_dma *dma = &mac->mac_method.dma; |
1050 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(*mp)); |
1051 struct bwn_dmadesc_generic *desc; 1052 struct bwn_dmadesc_meta *mt; 1053 struct bwn_softc *sc = mac->mac_sc; |
1054 struct mbuf *m; |
1055 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1056 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1057 1058 BWN_ASSERT_LOCKED(sc); 1059 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1060 1061 /* XXX send after DTIM */ 1062 |
1063 m = *mp; |
1064 slot = bwn_dma_getslot(dr); 1065 dr->getdesc(dr, slot, &desc, &mt); 1066 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1067 ("%s:%d: fail", __func__, __LINE__)); 1068 1069 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1070 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1071 BWN_DMA_COOKIE(dr, slot)); --- 32 unchanged lines hidden (view full) --- 1104 1105 m_new = m_defrag(m, M_NOWAIT); 1106 if (m_new == NULL) { 1107 device_printf(sc->sc_dev, 1108 "%s: can't defrag TX buffer\n", 1109 __func__); 1110 error = ENOBUFS; 1111 goto fail; |
1112 } |
1113 *mp = m = m_new; |
1114 1115 mt->mt_m = m; 1116 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1117 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1118 if (error) { 1119 device_printf(sc->sc_dev, 1120 "%s: can't load TX buffer (2) %d\n", 1121 __func__, error); --- 6371 unchanged lines hidden --- |