Ejemplo n.º 1
0
static inline uint64_t
select_ddp_flags(struct socket *so, int flags, int db_idx)
{
    uint64_t ddp_flags = V_TF_DDP_INDICATE_OUT(0);
    int waitall = flags & MSG_WAITALL;
    int nb = so->so_state & SS_NBIO || flags & (MSG_DONTWAIT | MSG_NBIO);

    KASSERT(db_idx == 0 || db_idx == 1,
            ("%s: bad DDP buffer index %d", __func__, db_idx));

    if (db_idx == 0) {
        ddp_flags |= V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_ACTIVE_BUF(0);
        if (waitall)
            ddp_flags |= V_TF_DDP_PUSH_DISABLE_0(1);
        else if (nb)
            ddp_flags |= V_TF_DDP_BUF0_FLUSH(1);
        else
            ddp_flags |= V_TF_DDP_BUF0_FLUSH(0);
    } else {
        ddp_flags |= V_TF_DDP_BUF1_VALID(1) | V_TF_DDP_ACTIVE_BUF(1);
        if (waitall)
            ddp_flags |= V_TF_DDP_PUSH_DISABLE_1(1);
        else if (nb)
            ddp_flags |= V_TF_DDP_BUF1_FLUSH(1);
        else
            ddp_flags |= V_TF_DDP_BUF1_FLUSH(0);
    }

    return (ddp_flags);
}
Ejemplo n.º 2
0
void
enable_ddp(struct adapter *sc, struct toepcb *toep)
{

	KASSERT((toep->ddp_flags & (DDP_ON | DDP_OK | DDP_SC_REQ)) == DDP_OK,
	    ("%s: toep %p has bad ddp_flags 0x%x",
	    __func__, toep, toep->ddp_flags));

	CTR3(KTR_CXGBE, "%s: tid %u (time %u)",
	    __func__, toep->tid, time_uptime);

	toep->ddp_flags |= DDP_SC_REQ;
	t4_set_tcb_field(sc, toep, 1, W_TCB_RX_DDP_FLAGS,
	    V_TF_DDP_OFF(1) | V_TF_DDP_INDICATE_OUT(1) |
	    V_TF_DDP_BUF0_INDICATE(1) | V_TF_DDP_BUF1_INDICATE(1) |
	    V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_BUF1_VALID(1),
	    V_TF_DDP_BUF0_INDICATE(1) | V_TF_DDP_BUF1_INDICATE(1));
	t4_set_tcb_field(sc, toep, 1, W_TCB_T_FLAGS,
	    V_TF_RCV_COALESCE_ENABLE(1), 0);
}
Ejemplo n.º 3
0
static struct wrqe *
mk_update_tcb_for_ddp(struct adapter *sc, struct toepcb *toep, int db_idx,
                      int offset, uint64_t ddp_flags)
{
    struct ddp_buffer *db = toep->db[db_idx];
    struct wrqe *wr;
    struct work_request_hdr *wrh;
    struct ulp_txpkt *ulpmc;
    int len;

    KASSERT(db_idx == 0 || db_idx == 1,
            ("%s: bad DDP buffer index %d", __func__, db_idx));

    /*
     * We'll send a compound work request that has 3 SET_TCB_FIELDs and an
     * RX_DATA_ACK (with RX_MODULATE to speed up delivery).
     *
     * The work request header is 16B and always ends at a 16B boundary.
     * The ULPTX master commands that follow must all end at 16B boundaries
     * too so we round up the size to 16.
     */
    len = sizeof(*wrh) + 3 * roundup2(LEN__SET_TCB_FIELD_ULP, 16) +
          roundup2(LEN__RX_DATA_ACK_ULP, 16);

    wr = alloc_wrqe(len, toep->ctrlq);
    if (wr == NULL)
        return (NULL);
    wrh = wrtod(wr);
    INIT_ULPTX_WRH(wrh, len, 1, 0);	/* atomic */
    ulpmc = (struct ulp_txpkt *)(wrh + 1);

    /* Write the buffer's tag */
    ulpmc = mk_set_tcb_field_ulp(ulpmc, toep,
                                 W_TCB_RX_DDP_BUF0_TAG + db_idx,
                                 V_TCB_RX_DDP_BUF0_TAG(M_TCB_RX_DDP_BUF0_TAG),
                                 V_TCB_RX_DDP_BUF0_TAG(db->tag));

    /* Update the current offset in the DDP buffer and its total length */
    if (db_idx == 0)
        ulpmc = mk_set_tcb_field_ulp(ulpmc, toep,
                                     W_TCB_RX_DDP_BUF0_OFFSET,
                                     V_TCB_RX_DDP_BUF0_OFFSET(M_TCB_RX_DDP_BUF0_OFFSET) |
                                     V_TCB_RX_DDP_BUF0_LEN(M_TCB_RX_DDP_BUF0_LEN),
                                     V_TCB_RX_DDP_BUF0_OFFSET(offset) |
                                     V_TCB_RX_DDP_BUF0_LEN(db->len));
    else
        ulpmc = mk_set_tcb_field_ulp(ulpmc, toep,
                                     W_TCB_RX_DDP_BUF1_OFFSET,
                                     V_TCB_RX_DDP_BUF1_OFFSET(M_TCB_RX_DDP_BUF1_OFFSET) |
                                     V_TCB_RX_DDP_BUF1_LEN((u64)M_TCB_RX_DDP_BUF1_LEN << 32),
                                     V_TCB_RX_DDP_BUF1_OFFSET(offset) |
                                     V_TCB_RX_DDP_BUF1_LEN((u64)db->len << 32));

    /* Update DDP flags */
    ulpmc = mk_set_tcb_field_ulp(ulpmc, toep, W_TCB_RX_DDP_FLAGS,
                                 V_TF_DDP_BUF0_FLUSH(1) | V_TF_DDP_BUF1_FLUSH(1) |
                                 V_TF_DDP_PUSH_DISABLE_0(1) | V_TF_DDP_PUSH_DISABLE_1(1) |
                                 V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_BUF1_VALID(1) |
                                 V_TF_DDP_ACTIVE_BUF(1) | V_TF_DDP_INDICATE_OUT(1), ddp_flags);

    /* Gratuitous RX_DATA_ACK with RX_MODULATE set to speed up delivery. */
    ulpmc = mk_rx_data_ack_ulp(ulpmc, toep);

    return (wr);
}