t4_sge.c (220897) | t4_sge.c (220905) |
---|---|
1/*- 2 * Copyright (c) 2011 Chelsio Communications, Inc. 3 * All rights reserved. 4 * Written by: Navdeep Parhar <np@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2011 Chelsio Communications, Inc. 3 * All rights reserved. 4 * Written by: Navdeep Parhar <np@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_sge.c 220897 2011-04-20 18:04:34Z np $"); | 29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_sge.c 220905 2011-04-20 23:20:00Z np $"); |
30 31#include "opt_inet.h" 32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/socket.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> --- 71 unchanged lines hidden (view full) --- 109static int alloc_ctrlq(struct adapter *, struct sge_ctrlq *, int); 110static int free_ctrlq(struct adapter *, struct sge_ctrlq *); 111static int alloc_txq(struct port_info *, struct sge_txq *, int); 112static int free_txq(struct port_info *, struct sge_txq *); 113static void oneseg_dma_callback(void *, bus_dma_segment_t *, int, int); 114static inline bool is_new_response(const struct sge_iq *, struct rsp_ctrl **); 115static inline void iq_next(struct sge_iq *); 116static inline void ring_fl_db(struct adapter *, struct sge_fl *); | 30 31#include "opt_inet.h" 32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/socket.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> --- 71 unchanged lines hidden (view full) --- 109static int alloc_ctrlq(struct adapter *, struct sge_ctrlq *, int); 110static int free_ctrlq(struct adapter *, struct sge_ctrlq *); 111static int alloc_txq(struct port_info *, struct sge_txq *, int); 112static int free_txq(struct port_info *, struct sge_txq *); 113static void oneseg_dma_callback(void *, bus_dma_segment_t *, int, int); 114static inline bool is_new_response(const struct sge_iq *, struct rsp_ctrl **); 115static inline void iq_next(struct sge_iq *); 116static inline void ring_fl_db(struct adapter *, struct sge_fl *); |
117static void refill_fl(struct sge_fl *, int); | 117static void refill_fl(struct adapter *, struct sge_fl *, int, int); |
118static int alloc_fl_sdesc(struct sge_fl *); 119static void free_fl_sdesc(struct sge_fl *); 120static int alloc_tx_maps(struct sge_txq *); 121static void free_tx_maps(struct sge_txq *); 122static void set_fl_tag_idx(struct sge_fl *, int); 123 124static int get_pkt_sgl(struct sge_txq *, struct mbuf **, struct sgl *, int); 125static int free_pkt_sgl(struct sge_txq *, struct sgl *); --- 632 unchanged lines hidden (view full) --- 758 /* queued for LRO */ 759 } else 760#endif 761 ifp->if_input(ifp, m0); 762 763 FL_LOCK(fl); 764 fl->needed += i; 765 if (fl->needed >= 32) | 118static int alloc_fl_sdesc(struct sge_fl *); 119static void free_fl_sdesc(struct sge_fl *); 120static int alloc_tx_maps(struct sge_txq *); 121static void free_tx_maps(struct sge_txq *); 122static void set_fl_tag_idx(struct sge_fl *, int); 123 124static int get_pkt_sgl(struct sge_txq *, struct mbuf **, struct sgl *, int); 125static int free_pkt_sgl(struct sge_txq *, struct sgl *); --- 632 unchanged lines hidden (view full) --- 758 /* queued for LRO */ 759 } else 760#endif 761 ifp->if_input(ifp, m0); 762 763 FL_LOCK(fl); 764 fl->needed += i; 765 if (fl->needed >= 32) |
766 refill_fl(fl, 64); 767 if (fl->pending >= 32) 768 ring_fl_db(sc, fl); | 766 refill_fl(sc, fl, 64, 32); |
769 FL_UNLOCK(fl); 770 771nextdesc: ndescs++; 772 iq_next(iq); 773 774 if (ndescs > 32) { 775 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), 776 V_CIDXINC(ndescs) | --- 11 unchanged lines hidden (view full) --- 788 } 789#endif 790 791 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) | 792 V_INGRESSQID((u32)iq->cntxt_id) | V_SEINTARM(iq->intr_next)); 793 794 FL_LOCK(fl); 795 if (fl->needed >= 32) | 767 FL_UNLOCK(fl); 768 769nextdesc: ndescs++; 770 iq_next(iq); 771 772 if (ndescs > 32) { 773 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), 774 V_CIDXINC(ndescs) | --- 11 unchanged lines hidden (view full) --- 786 } 787#endif 788 789 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) | 790 V_INGRESSQID((u32)iq->cntxt_id) | V_SEINTARM(iq->intr_next)); 791 792 FL_LOCK(fl); 793 if (fl->needed >= 32) |
796 refill_fl(fl, 128); 797 if (fl->pending >= 8) 798 ring_fl_db(sc, fl); | 794 refill_fl(sc, fl, 128, 8); |
799 FL_UNLOCK(fl); 800} 801 802int 803t4_mgmt_tx(struct adapter *sc, struct mbuf *m) 804{ 805 return ctrl_tx(sc, &sc->sge.ctrlq[0], m); 806} --- 367 unchanged lines hidden (view full) --- 1174 rc = alloc_fl_sdesc(fl); 1175 FL_UNLOCK(fl); 1176 if (rc != 0) { 1177 device_printf(sc->dev, 1178 "failed to setup fl software descriptors: %d\n", 1179 rc); 1180 return (rc); 1181 } | 795 FL_UNLOCK(fl); 796} 797 798int 799t4_mgmt_tx(struct adapter *sc, struct mbuf *m) 800{ 801 return ctrl_tx(sc, &sc->sge.ctrlq[0], m); 802} --- 367 unchanged lines hidden (view full) --- 1170 rc = alloc_fl_sdesc(fl); 1171 FL_UNLOCK(fl); 1172 if (rc != 0) { 1173 device_printf(sc->dev, 1174 "failed to setup fl software descriptors: %d\n", 1175 rc); 1176 return (rc); 1177 } |
1182 fl->needed = fl->cap - 1; /* one less to avoid cidx = pidx */ | 1178 fl->needed = fl->cap; |
1183 1184 c.iqns_to_fl0congen = 1185 htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE)); 1186 c.fl0dcaen_to_fl0cidxfthresh = 1187 htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_64B) | 1188 V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B)); 1189 c.fl0size = htobe16(fl->qsize); 1190 c.fl0addr = htobe64(fl->ba); --- 26 unchanged lines hidden (view full) --- 1217 1218 cntxt_id = fl->cntxt_id - sc->sge.eq_start; 1219 KASSERT(cntxt_id < sc->sge.neq, 1220 ("%s: fl->cntxt_id (%d) more than the max (%d)", __func__, 1221 cntxt_id, sc->sge.neq - 1)); 1222 sc->sge.eqmap[cntxt_id] = (void *)fl; 1223 1224 FL_LOCK(fl); | 1179 1180 c.iqns_to_fl0congen = 1181 htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE)); 1182 c.fl0dcaen_to_fl0cidxfthresh = 1183 htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_64B) | 1184 V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B)); 1185 c.fl0size = htobe16(fl->qsize); 1186 c.fl0addr = htobe64(fl->ba); --- 26 unchanged lines hidden (view full) --- 1213 1214 cntxt_id = fl->cntxt_id - sc->sge.eq_start; 1215 KASSERT(cntxt_id < sc->sge.neq, 1216 ("%s: fl->cntxt_id (%d) more than the max (%d)", __func__, 1217 cntxt_id, sc->sge.neq - 1)); 1218 sc->sge.eqmap[cntxt_id] = (void *)fl; 1219 1220 FL_LOCK(fl); |
1225 refill_fl(fl, -1); 1226 if (fl->pending >= 8) 1227 ring_fl_db(sc, fl); | 1221 refill_fl(sc, fl, -1, 8); |
1228 FL_UNLOCK(fl); 1229 } 1230 1231 /* Enable IQ interrupts */ 1232 atomic_store_rel_32(&iq->state, IQS_IDLE); 1233 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(iq->intr_params) | 1234 V_INGRESSQID(iq->cntxt_id)); 1235 --- 451 unchanged lines hidden (view full) --- 1687 iq->cdesc = (void *) ((uintptr_t)iq->cdesc + iq->esize); 1688 if (__predict_false(++iq->cidx == iq->qsize - 1)) { 1689 iq->cidx = 0; 1690 iq->gen ^= 1; 1691 iq->cdesc = iq->desc; 1692 } 1693} 1694 | 1222 FL_UNLOCK(fl); 1223 } 1224 1225 /* Enable IQ interrupts */ 1226 atomic_store_rel_32(&iq->state, IQS_IDLE); 1227 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(iq->intr_params) | 1228 V_INGRESSQID(iq->cntxt_id)); 1229 --- 451 unchanged lines hidden (view full) --- 1681 iq->cdesc = (void *) ((uintptr_t)iq->cdesc + iq->esize); 1682 if (__predict_false(++iq->cidx == iq->qsize - 1)) { 1683 iq->cidx = 0; 1684 iq->gen ^= 1; 1685 iq->cdesc = iq->desc; 1686 } 1687} 1688 |
1689#define FL_HW_IDX(x) ((x) >> 3) |
|
1695static inline void 1696ring_fl_db(struct adapter *sc, struct sge_fl *fl) 1697{ 1698 int ndesc = fl->pending / 8; 1699 | 1690static inline void 1691ring_fl_db(struct adapter *sc, struct sge_fl *fl) 1692{ 1693 int ndesc = fl->pending / 8; 1694 |
1700 /* Caller responsible for ensuring there's something useful to do */ 1701 KASSERT(ndesc > 0, ("%s called with no useful work to do.", __func__)); | 1695 if (FL_HW_IDX(fl->pidx) == FL_HW_IDX(fl->cidx)) 1696 ndesc--; /* hold back one credit */ |
1702 | 1697 |
1698 if (ndesc <= 0) 1699 return; /* nothing to do */ 1700 |
|
1703 wmb(); 1704 1705 t4_write_reg(sc, MYPF_REG(A_SGE_PF_KDOORBELL), F_DBPRIO | 1706 V_QID(fl->cntxt_id) | V_PIDX(ndesc)); | 1701 wmb(); 1702 1703 t4_write_reg(sc, MYPF_REG(A_SGE_PF_KDOORBELL), F_DBPRIO | 1704 V_QID(fl->cntxt_id) | V_PIDX(ndesc)); |
1707 1708 fl->pending &= 7; | 1705 fl->pending -= ndesc * 8; |
1709} 1710 | 1706} 1707 |
1708/* 1709 * Fill up the freelist by upto nbufs and ring its doorbell if the number of 1710 * buffers ready to be handed to the hardware >= dbthresh. 1711 */ |
|
1711static void | 1712static void |
1712refill_fl(struct sge_fl *fl, int nbufs) | 1713refill_fl(struct adapter *sc, struct sge_fl *fl, int nbufs, int dbthresh) |
1713{ 1714 __be64 *d = &fl->desc[fl->pidx]; 1715 struct fl_sdesc *sd = &fl->sdesc[fl->pidx]; 1716 bus_dma_tag_t tag; 1717 bus_addr_t pa; 1718 caddr_t cl; 1719 int rc; 1720 --- 74 unchanged lines hidden (view full) --- 1795 fl->needed--; 1796 sd++; 1797 if (++fl->pidx == fl->cap) { 1798 fl->pidx = 0; 1799 sd = fl->sdesc; 1800 d = fl->desc; 1801 } 1802 } | 1714{ 1715 __be64 *d = &fl->desc[fl->pidx]; 1716 struct fl_sdesc *sd = &fl->sdesc[fl->pidx]; 1717 bus_dma_tag_t tag; 1718 bus_addr_t pa; 1719 caddr_t cl; 1720 int rc; 1721 --- 74 unchanged lines hidden (view full) --- 1796 fl->needed--; 1797 sd++; 1798 if (++fl->pidx == fl->cap) { 1799 fl->pidx = 0; 1800 sd = fl->sdesc; 1801 d = fl->desc; 1802 } 1803 } |
1804 1805 if (fl->pending >= dbthresh) 1806 ring_fl_db(sc, fl); |
|
1803} 1804 1805static int 1806alloc_fl_sdesc(struct sge_fl *fl) 1807{ 1808 struct fl_sdesc *sd; 1809 bus_dma_tag_t tag; 1810 int i, rc; --- 902 unchanged lines hidden --- | 1807} 1808 1809static int 1810alloc_fl_sdesc(struct sge_fl *fl) 1811{ 1812 struct fl_sdesc *sd; 1813 bus_dma_tag_t tag; 1814 int i, rc; --- 902 unchanged lines hidden --- |