t4_sge.c (309558) | t4_sge.c (309560) |
---|---|
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: stable/11/sys/dev/cxgbe/t4_sge.c 309558 2016-12-05 19:34:52Z jhb $"); | 29__FBSDID("$FreeBSD: stable/11/sys/dev/cxgbe/t4_sge.c 309560 2016-12-05 20:43:25Z jhb $"); |
30 31#include "opt_inet.h" 32#include "opt_inet6.h" 33 34#include <sys/types.h> 35#include <sys/eventhandler.h> 36#include <sys/mbuf.h> 37#include <sys/socket.h> --- 186 unchanged lines hidden (view full) --- 224 225static inline void get_pkt_gl(struct mbuf *, struct sglist *); 226static inline u_int txpkt_len16(u_int, u_int); 227static inline u_int txpkt_vm_len16(u_int, u_int); 228static inline u_int txpkts0_len16(u_int); 229static inline u_int txpkts1_len16(void); 230static u_int write_txpkt_wr(struct sge_txq *, struct fw_eth_tx_pkt_wr *, 231 struct mbuf *, u_int); | 30 31#include "opt_inet.h" 32#include "opt_inet6.h" 33 34#include <sys/types.h> 35#include <sys/eventhandler.h> 36#include <sys/mbuf.h> 37#include <sys/socket.h> --- 186 unchanged lines hidden (view full) --- 224 225static inline void get_pkt_gl(struct mbuf *, struct sglist *); 226static inline u_int txpkt_len16(u_int, u_int); 227static inline u_int txpkt_vm_len16(u_int, u_int); 228static inline u_int txpkts0_len16(u_int); 229static inline u_int txpkts1_len16(void); 230static u_int write_txpkt_wr(struct sge_txq *, struct fw_eth_tx_pkt_wr *, 231 struct mbuf *, u_int); |
232static u_int write_txpkt_vm_wr(struct sge_txq *, struct fw_eth_tx_pkt_vm_wr *, 233 struct mbuf *, u_int); | 232static u_int write_txpkt_vm_wr(struct adapter *, struct sge_txq *, 233 struct fw_eth_tx_pkt_vm_wr *, struct mbuf *, u_int); |
234static int try_txpkts(struct mbuf *, struct mbuf *, struct txpkts *, u_int); 235static int add_to_txpkts(struct mbuf *, struct txpkts *, u_int); 236static u_int write_txpkts_wr(struct sge_txq *, struct fw_eth_tx_pkts_wr *, 237 struct mbuf *, const struct txpkts *, u_int); 238static void write_gl_to_txd(struct sge_txq *, struct mbuf *, caddr_t *, int); 239static inline void copy_to_txd(struct sge_eq *, caddr_t, caddr_t *, int); 240static inline void ring_eq_db(struct adapter *, struct sge_eq *, u_int); 241static inline uint16_t read_hw_cidx(struct sge_eq *); --- 186 unchanged lines hidden (view full) --- 428 429 return (refs - rels); 430} 431 432static inline void 433setup_pad_and_pack_boundaries(struct adapter *sc) 434{ 435 uint32_t v, m; | 234static int try_txpkts(struct mbuf *, struct mbuf *, struct txpkts *, u_int); 235static int add_to_txpkts(struct mbuf *, struct txpkts *, u_int); 236static u_int write_txpkts_wr(struct sge_txq *, struct fw_eth_tx_pkts_wr *, 237 struct mbuf *, const struct txpkts *, u_int); 238static void write_gl_to_txd(struct sge_txq *, struct mbuf *, caddr_t *, int); 239static inline void copy_to_txd(struct sge_eq *, caddr_t, caddr_t *, int); 240static inline void ring_eq_db(struct adapter *, struct sge_eq *, u_int); 241static inline uint16_t read_hw_cidx(struct sge_eq *); --- 186 unchanged lines hidden (view full) --- 428 429 return (refs - rels); 430} 431 432static inline void 433setup_pad_and_pack_boundaries(struct adapter *sc) 434{ 435 uint32_t v, m; |
436 int pad, pack; | 436 int pad, pack, pad_shift; |
437 | 437 |
438 pad_shift = chip_id(sc) > CHELSIO_T5 ? X_T6_INGPADBOUNDARY_SHIFT : 439 X_INGPADBOUNDARY_SHIFT; |
|
438 pad = fl_pad; | 440 pad = fl_pad; |
439 if (fl_pad < 32 || fl_pad > 4096 || !powerof2(fl_pad)) { | 441 if (fl_pad < (1 << pad_shift) || 442 fl_pad > (1 << (pad_shift + M_INGPADBOUNDARY)) || 443 !powerof2(fl_pad)) { |
440 /* 441 * If there is any chance that we might use buffer packing and 442 * the chip is a T4, then pick 64 as the pad/pack boundary. Set | 444 /* 445 * If there is any chance that we might use buffer packing and 446 * the chip is a T4, then pick 64 as the pad/pack boundary. Set |
443 * it to 32 in all other cases. | 447 * it to the minimum allowed in all other cases. |
444 */ | 448 */ |
445 pad = is_t4(sc) && buffer_packing ? 64 : 32; | 449 pad = is_t4(sc) && buffer_packing ? 64 : 1 << pad_shift; |
446 447 /* 448 * For fl_pad = 0 we'll still write a reasonable value to the 449 * register but all the freelists will opt out of padding. 450 * We'll complain here only if the user tried to set it to a 451 * value greater than 0 that was invalid. 452 */ 453 if (fl_pad > 0) { 454 device_printf(sc->dev, "Invalid hw.cxgbe.fl_pad value" 455 " (%d), using %d instead.\n", fl_pad, pad); 456 } 457 } 458 m = V_INGPADBOUNDARY(M_INGPADBOUNDARY); | 450 451 /* 452 * For fl_pad = 0 we'll still write a reasonable value to the 453 * register but all the freelists will opt out of padding. 454 * We'll complain here only if the user tried to set it to a 455 * value greater than 0 that was invalid. 456 */ 457 if (fl_pad > 0) { 458 device_printf(sc->dev, "Invalid hw.cxgbe.fl_pad value" 459 " (%d), using %d instead.\n", fl_pad, pad); 460 } 461 } 462 m = V_INGPADBOUNDARY(M_INGPADBOUNDARY); |
459 v = V_INGPADBOUNDARY(ilog2(pad) - 5); | 463 v = V_INGPADBOUNDARY(ilog2(pad) - pad_shift); |
460 t4_set_reg_field(sc, A_SGE_CONTROL, m, v); 461 462 if (is_t4(sc)) { 463 if (fl_pack != -1 && fl_pack != pad) { 464 /* Complain but carry on. */ 465 device_printf(sc->dev, "hw.cxgbe.fl_pack (%d) ignored," 466 " using %d instead.\n", fl_pack, pad); 467 } --- 1979 unchanged lines hidden (view full) --- 2447 if (__predict_false(next_cidx == r->size)) 2448 next_cidx = 0; 2449 2450 wr = (void *)&eq->desc[eq->pidx]; 2451 if (sc->flags & IS_VF) { 2452 total++; 2453 remaining--; 2454 ETHER_BPF_MTAP(ifp, m0); | 464 t4_set_reg_field(sc, A_SGE_CONTROL, m, v); 465 466 if (is_t4(sc)) { 467 if (fl_pack != -1 && fl_pack != pad) { 468 /* Complain but carry on. */ 469 device_printf(sc->dev, "hw.cxgbe.fl_pack (%d) ignored," 470 " using %d instead.\n", fl_pack, pad); 471 } --- 1979 unchanged lines hidden (view full) --- 2451 if (__predict_false(next_cidx == r->size)) 2452 next_cidx = 0; 2453 2454 wr = (void *)&eq->desc[eq->pidx]; 2455 if (sc->flags & IS_VF) { 2456 total++; 2457 remaining--; 2458 ETHER_BPF_MTAP(ifp, m0); |
2455 n = write_txpkt_vm_wr(txq, (void *)wr, m0, available); | 2459 n = write_txpkt_vm_wr(sc, txq, (void *)wr, m0, 2460 available); |
2456 } else if (remaining > 1 && 2457 try_txpkts(m0, r->items[next_cidx], &txp, available) == 0) { 2458 2459 /* pkts at cidx, next_cidx should both be in txp. */ 2460 MPASS(txp.npkt == 2); 2461 tail = r->items[next_cidx]; 2462 MPASS(tail->m_nextpkt == NULL); 2463 ETHER_BPF_MTAP(ifp, m0); --- 251 unchanged lines hidden (view full) --- 2715 0)); 2716 if (cong >= 0) { 2717 c.iqns_to_fl0congen |= 2718 htobe32(V_FW_IQ_CMD_FL0CNGCHMAP(cong) | 2719 F_FW_IQ_CMD_FL0CONGCIF | 2720 F_FW_IQ_CMD_FL0CONGEN); 2721 } 2722 c.fl0dcaen_to_fl0cidxfthresh = | 2461 } else if (remaining > 1 && 2462 try_txpkts(m0, r->items[next_cidx], &txp, available) == 0) { 2463 2464 /* pkts at cidx, next_cidx should both be in txp. */ 2465 MPASS(txp.npkt == 2); 2466 tail = r->items[next_cidx]; 2467 MPASS(tail->m_nextpkt == NULL); 2468 ETHER_BPF_MTAP(ifp, m0); --- 251 unchanged lines hidden (view full) --- 2720 0)); 2721 if (cong >= 0) { 2722 c.iqns_to_fl0congen |= 2723 htobe32(V_FW_IQ_CMD_FL0CNGCHMAP(cong) | 2724 F_FW_IQ_CMD_FL0CONGCIF | 2725 F_FW_IQ_CMD_FL0CONGEN); 2726 } 2727 c.fl0dcaen_to_fl0cidxfthresh = |
2723 htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_128B) | 2724 V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B)); | 2728 htobe16(V_FW_IQ_CMD_FL0FBMIN(chip_id(sc) <= CHELSIO_T5 ? 2729 X_FETCHBURSTMIN_128B : X_FETCHBURSTMIN_64B) | 2730 V_FW_IQ_CMD_FL0FBMAX(chip_id(sc) <= CHELSIO_T5 ? 2731 X_FETCHBURSTMAX_512B : X_FETCHBURSTMAX_256B)); |
2725 c.fl0size = htobe16(fl->qsize); 2726 c.fl0addr = htobe64(fl->ba); 2727 } 2728 2729 rc = -t4_wr_mbox(sc, sc->mbox, &c, sizeof(c), &c); 2730 if (rc != 0) { 2731 device_printf(sc->dev, 2732 "failed to create ingress queue: %d\n", rc); --- 46 unchanged lines hidden (view full) --- 2779 fl->dbval = V_QID(qid) | sc->chip_params->sge_fl_db; 2780 2781 FL_LOCK(fl); 2782 /* Enough to make sure the SGE doesn't think it's starved */ 2783 refill_fl(sc, fl, fl->lowat); 2784 FL_UNLOCK(fl); 2785 } 2786 | 2732 c.fl0size = htobe16(fl->qsize); 2733 c.fl0addr = htobe64(fl->ba); 2734 } 2735 2736 rc = -t4_wr_mbox(sc, sc->mbox, &c, sizeof(c), &c); 2737 if (rc != 0) { 2738 device_printf(sc->dev, 2739 "failed to create ingress queue: %d\n", rc); --- 46 unchanged lines hidden (view full) --- 2786 fl->dbval = V_QID(qid) | sc->chip_params->sge_fl_db; 2787 2788 FL_LOCK(fl); 2789 /* Enough to make sure the SGE doesn't think it's starved */ 2790 refill_fl(sc, fl, fl->lowat); 2791 FL_UNLOCK(fl); 2792 } 2793 |
2787 if (is_t5(sc) && !(sc->flags & IS_VF) && cong >= 0) { | 2794 if (chip_id(sc) >= CHELSIO_T5 && !(sc->flags & IS_VF) && cong >= 0) { |
2788 uint32_t param, val; 2789 2790 param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | 2791 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) | 2792 V_FW_PARAMS_PARAM_YZ(iq->cntxt_id); 2793 if (cong == 0) 2794 val = 1 << 19; 2795 else { --- 437 unchanged lines hidden (view full) --- 3233 if (rc) 3234 return (rc); 3235 3236 nm_txq->pidx = nm_txq->cidx = 0; 3237 nm_txq->sidx = na->num_tx_desc; 3238 nm_txq->nid = idx; 3239 nm_txq->iqidx = iqidx; 3240 nm_txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT) | | 2795 uint32_t param, val; 2796 2797 param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | 2798 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) | 2799 V_FW_PARAMS_PARAM_YZ(iq->cntxt_id); 2800 if (cong == 0) 2801 val = 1 << 19; 2802 else { --- 437 unchanged lines hidden (view full) --- 3240 if (rc) 3241 return (rc); 3242 3243 nm_txq->pidx = nm_txq->cidx = 0; 3244 nm_txq->sidx = na->num_tx_desc; 3245 nm_txq->nid = idx; 3246 nm_txq->iqidx = iqidx; 3247 nm_txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT) | |
3241 V_TXPKT_INTF(pi->tx_chan) | V_TXPKT_VF_VLD(1) | 3242 V_TXPKT_VF(vi->viid)); | 3248 V_TXPKT_INTF(pi->tx_chan) | V_TXPKT_PF(G_FW_VIID_PFN(vi->viid)) | 3249 V_TXPKT_VF(G_FW_VIID_VIN(vi->viid)) | 3250 V_TXPKT_VF_VLD(G_FW_VIID_VIVLD(vi->viid))); |
3243 3244 snprintf(name, sizeof(name), "%d", idx); 3245 oid = SYSCTL_ADD_NODE(&vi->ctx, children, OID_AUTO, name, CTLFLAG_RD, 3246 NULL, "netmap tx queue"); 3247 children = SYSCTL_CHILDREN(oid); 3248 3249 SYSCTL_ADD_UINT(&vi->ctx, children, OID_AUTO, "cntxt_id", CTLFLAG_RD, 3250 &nm_txq->cntxt_id, 0, "SGE context id of the queue"); --- 351 unchanged lines hidden (view full) --- 3602 TASK_INIT(&txq->tx_reclaim_task, 0, tx_reclaim, eq); 3603 txq->ifp = vi->ifp; 3604 txq->gl = sglist_alloc(TX_SGL_SEGS, M_WAITOK); 3605 if (sc->flags & IS_VF) 3606 txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT_XT) | 3607 V_TXPKT_INTF(pi->tx_chan)); 3608 else 3609 txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT) | | 3251 3252 snprintf(name, sizeof(name), "%d", idx); 3253 oid = SYSCTL_ADD_NODE(&vi->ctx, children, OID_AUTO, name, CTLFLAG_RD, 3254 NULL, "netmap tx queue"); 3255 children = SYSCTL_CHILDREN(oid); 3256 3257 SYSCTL_ADD_UINT(&vi->ctx, children, OID_AUTO, "cntxt_id", CTLFLAG_RD, 3258 &nm_txq->cntxt_id, 0, "SGE context id of the queue"); --- 351 unchanged lines hidden (view full) --- 3610 TASK_INIT(&txq->tx_reclaim_task, 0, tx_reclaim, eq); 3611 txq->ifp = vi->ifp; 3612 txq->gl = sglist_alloc(TX_SGL_SEGS, M_WAITOK); 3613 if (sc->flags & IS_VF) 3614 txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT_XT) | 3615 V_TXPKT_INTF(pi->tx_chan)); 3616 else 3617 txq->cpl_ctrl0 = htobe32(V_TXPKT_OPCODE(CPL_TX_PKT) | |
3610 V_TXPKT_INTF(pi->tx_chan) | V_TXPKT_VF_VLD(1) | 3611 V_TXPKT_VF(vi->viid)); | 3618 V_TXPKT_INTF(pi->tx_chan) | 3619 V_TXPKT_PF(G_FW_VIID_PFN(vi->viid)) | 3620 V_TXPKT_VF(G_FW_VIID_VIN(vi->viid)) | 3621 V_TXPKT_VF_VLD(G_FW_VIID_VIVLD(vi->viid))); |
3612 txq->tc_idx = -1; 3613 txq->sdesc = malloc(eq->sidx * sizeof(struct tx_sdesc), M_CXGBE, 3614 M_ZERO | M_WAITOK); 3615 3616 snprintf(name, sizeof(name), "%d", idx); 3617 oid = SYSCTL_ADD_NODE(&vi->ctx, children, OID_AUTO, name, CTLFLAG_RD, 3618 NULL, "tx queue"); 3619 children = SYSCTL_CHILDREN(oid); --- 408 unchanged lines hidden (view full) --- 4028/* 4029 * Write a VM txpkt WR for this packet to the hardware descriptors, update the 4030 * software descriptor, and advance the pidx. It is guaranteed that enough 4031 * descriptors are available. 4032 * 4033 * The return value is the # of hardware descriptors used. 4034 */ 4035static u_int | 3622 txq->tc_idx = -1; 3623 txq->sdesc = malloc(eq->sidx * sizeof(struct tx_sdesc), M_CXGBE, 3624 M_ZERO | M_WAITOK); 3625 3626 snprintf(name, sizeof(name), "%d", idx); 3627 oid = SYSCTL_ADD_NODE(&vi->ctx, children, OID_AUTO, name, CTLFLAG_RD, 3628 NULL, "tx queue"); 3629 children = SYSCTL_CHILDREN(oid); --- 408 unchanged lines hidden (view full) --- 4038/* 4039 * Write a VM txpkt WR for this packet to the hardware descriptors, update the 4040 * software descriptor, and advance the pidx. It is guaranteed that enough 4041 * descriptors are available. 4042 * 4043 * The return value is the # of hardware descriptors used. 4044 */ 4045static u_int |
4036write_txpkt_vm_wr(struct sge_txq *txq, struct fw_eth_tx_pkt_vm_wr *wr, 4037 struct mbuf *m0, u_int available) | 4046write_txpkt_vm_wr(struct adapter *sc, struct sge_txq *txq, 4047 struct fw_eth_tx_pkt_vm_wr *wr, struct mbuf *m0, u_int available) |
4038{ 4039 struct sge_eq *eq = &txq->eq; 4040 struct tx_sdesc *txsd; 4041 struct cpl_tx_pkt_core *cpl; 4042 uint32_t ctrl; /* used in many unrelated places */ 4043 uint64_t ctrl1; 4044 int csum_type, len16, ndesc, pktlen, nsegs; 4045 caddr_t dst; --- 99 unchanged lines hidden (view full) --- 4145 ctrl1 = 0; 4146 if (needs_l3_csum(m0) == 0) 4147 ctrl1 |= F_TXPKT_IPCSUM_DIS; 4148 if (csum_type >= 0) { 4149 KASSERT(m0->m_pkthdr.l2hlen > 0 && m0->m_pkthdr.l3hlen > 0, 4150 ("%s: mbuf %p needs checksum offload but missing header lengths", 4151 __func__, m0)); 4152 | 4048{ 4049 struct sge_eq *eq = &txq->eq; 4050 struct tx_sdesc *txsd; 4051 struct cpl_tx_pkt_core *cpl; 4052 uint32_t ctrl; /* used in many unrelated places */ 4053 uint64_t ctrl1; 4054 int csum_type, len16, ndesc, pktlen, nsegs; 4055 caddr_t dst; --- 99 unchanged lines hidden (view full) --- 4155 ctrl1 = 0; 4156 if (needs_l3_csum(m0) == 0) 4157 ctrl1 |= F_TXPKT_IPCSUM_DIS; 4158 if (csum_type >= 0) { 4159 KASSERT(m0->m_pkthdr.l2hlen > 0 && m0->m_pkthdr.l3hlen > 0, 4160 ("%s: mbuf %p needs checksum offload but missing header lengths", 4161 __func__, m0)); 4162 |
4153 /* XXX: T6 */ 4154 ctrl1 |= V_TXPKT_ETHHDR_LEN(m0->m_pkthdr.l2hlen - 4155 ETHER_HDR_LEN); | 4163 if (chip_id(sc) <= CHELSIO_T5) { 4164 ctrl1 |= V_TXPKT_ETHHDR_LEN(m0->m_pkthdr.l2hlen - 4165 ETHER_HDR_LEN); 4166 } else { 4167 ctrl1 |= V_T6_TXPKT_ETHHDR_LEN(m0->m_pkthdr.l2hlen - 4168 ETHER_HDR_LEN); 4169 } |
4156 ctrl1 |= V_TXPKT_IPHDR_LEN(m0->m_pkthdr.l3hlen); 4157 ctrl1 |= V_TXPKT_CSUM_TYPE(csum_type); 4158 } else 4159 ctrl1 |= F_TXPKT_L4CSUM_DIS; 4160 if (m0->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP | 4161 CSUM_UDP_IPV6 | CSUM_TCP_IPV6 | CSUM_TSO)) 4162 txq->txcsum++; /* some hardware assistance provided */ 4163 --- 1041 unchanged lines hidden --- | 4170 ctrl1 |= V_TXPKT_IPHDR_LEN(m0->m_pkthdr.l3hlen); 4171 ctrl1 |= V_TXPKT_CSUM_TYPE(csum_type); 4172 } else 4173 ctrl1 |= F_TXPKT_L4CSUM_DIS; 4174 if (m0->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP | 4175 CSUM_UDP_IPV6 | CSUM_TCP_IPV6 | CSUM_TSO)) 4176 txq->txcsum++; /* some hardware assistance provided */ 4177 --- 1041 unchanged lines hidden --- |