diff options
Diffstat (limited to 'sys/dev/cxgbe/tom/t4_tls.c')
| -rw-r--r-- | sys/dev/cxgbe/tom/t4_tls.c | 357 | 
1 files changed, 246 insertions, 111 deletions
| diff --git a/sys/dev/cxgbe/tom/t4_tls.c b/sys/dev/cxgbe/tom/t4_tls.c index 27c16b9988ae..bbcc1c88c3db 100644 --- a/sys/dev/cxgbe/tom/t4_tls.c +++ b/sys/dev/cxgbe/tom/t4_tls.c @@ -61,11 +61,21 @@  static void  t4_set_tls_tcb_field(struct toepcb *toep, uint16_t word, uint64_t mask, -    uint64_t val) +    uint64_t val, int reply, int cookie)  {  	struct adapter *sc = td_adapter(toep->td); +	struct mbuf *m; + +	m = alloc_raw_wr_mbuf(sizeof(struct cpl_set_tcb_field)); +	if (m == NULL) { +		/* XXX */ +		panic("%s: out of memory", __func__); +	} -	t4_set_tcb_field(sc, &toep->ofld_txq->wrq, toep, word, mask, val, 0, 0); +	write_set_tcb_field(sc, mtod(m, void *), toep, word, mask, val, reply, +	    cookie); + +	t4_raw_wr_tx(sc, toep, m);  }  /* TLS and DTLS common routines */ @@ -88,10 +98,9 @@ tls_tx_key(struct toepcb *toep)  static void  t4_set_rx_quiesce(struct toepcb *toep)  { -	struct adapter *sc = td_adapter(toep->td); -	t4_set_tcb_field(sc, &toep->ofld_txq->wrq, toep, W_TCB_T_FLAGS, -	    V_TF_RX_QUIESCE(1), V_TF_RX_QUIESCE(1), 1, CPL_COOKIE_TOM); +	t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1), +	    V_TF_RX_QUIESCE(1), 1, CPL_COOKIE_TOM);  }  /* Clear TF_RX_QUIESCE to re-enable receive. */ @@ -99,7 +108,7 @@ static void  t4_clear_rx_quiesce(struct toepcb *toep)  { -	t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1), 0); +	t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1), 0, 0, 0);  }  /* TLS/DTLS content type  for CPL SFO */ @@ -145,16 +154,15 @@ get_tp_plen_max(struct ktls_session *tls)  	return (tls->params.max_frame_len <= 8192 ? plen : FC_TP_PLEN_MAX);  } -/* Send request to get the key-id */ +/* Send request to save the key in on-card memory. */  static int  tls_program_key_id(struct toepcb *toep, struct ktls_session *tls,      int direction)  {  	struct tls_ofld_info *tls_ofld = &toep->tls;  	struct adapter *sc = td_adapter(toep->td); -	struct ofld_tx_sdesc *txsd;  	int keyid; -	struct wrqe *wr; +	struct mbuf *m;  	struct tls_key_req *kwr;  	struct tls_keyctx *kctx; @@ -173,12 +181,12 @@ tls_program_key_id(struct toepcb *toep, struct ktls_session *tls,  		return (ENOSPC);  	} -	wr = alloc_wrqe(TLS_KEY_WR_SZ, &toep->ofld_txq->wrq); -	if (wr == NULL) { +	m = alloc_raw_wr_mbuf(TLS_KEY_WR_SZ); +	if (m == NULL) {  		t4_free_tls_keyid(sc, keyid);  		return (ENOMEM);  	} -	kwr = wrtod(wr); +	kwr = mtod(m, struct tls_key_req *);  	memset(kwr, 0, TLS_KEY_WR_SZ);  	t4_write_tlskey_wr(tls, direction, toep->tid, F_FW_WR_COMPL, keyid, @@ -190,15 +198,7 @@ tls_program_key_id(struct toepcb *toep, struct ktls_session *tls,  		tls_ofld->rx_key_addr = keyid;  	t4_tls_key_ctx(tls, direction, kctx); -	txsd = &toep->txsd[toep->txsd_pidx]; -	txsd->tx_credits = DIV_ROUND_UP(TLS_KEY_WR_SZ, 16); -	txsd->plen = 0; -	toep->tx_credits -= txsd->tx_credits; -	if (__predict_false(++toep->txsd_pidx == toep->txsd_total)) -		toep->txsd_pidx = 0; -	toep->txsd_avail--; - -	t4_wrq_tx(sc, wr); +	t4_raw_wr_tx(sc, toep, m);  	return (0);  } @@ -207,7 +207,7 @@ int  tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  {  	struct adapter *sc = td_adapter(toep->td); -	int error, explicit_iv_size, mac_first; +	int error, iv_size, mac_first;  	if (!can_tls_offload(sc))  		return (EINVAL); @@ -228,6 +228,21 @@ tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  		}  	} +	/* TLS 1.1 through TLS 1.3 are currently supported. */ +	if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || +	    tls->params.tls_vminor < TLS_MINOR_VER_ONE || +	    tls->params.tls_vminor > TLS_MINOR_VER_THREE) { +		return (EPROTONOSUPPORT); +	} + +	/* TLS 1.3 is only supported on T7+. */ +	if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) { +		if (is_t6(sc)) { +			return (EPROTONOSUPPORT); +		} +	} + +	/* Sanity check values in *tls. */  	switch (tls->params.cipher_algorithm) {  	case CRYPTO_AES_CBC:  		/* XXX: Explicitly ignore any provided IV. */ @@ -247,13 +262,10 @@ tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  		default:  			return (EPROTONOSUPPORT);  		} -		explicit_iv_size = AES_BLOCK_LEN; +		iv_size = AES_BLOCK_LEN;  		mac_first = 1;  		break;  	case CRYPTO_AES_NIST_GCM_16: -		if (tls->params.iv_len != SALT_SIZE) { -			return (EINVAL); -		}  		switch (tls->params.cipher_key_len) {  		case 128 / 8:  		case 192 / 8: @@ -262,20 +274,19 @@ tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  		default:  			return (EINVAL);  		} -		explicit_iv_size = 8; + +		/* +		 * The IV size for TLS 1.2 is the explicit IV in the +		 * record header.  For TLS 1.3 it is the size of the +		 * sequence number. +		 */ +		iv_size = 8;  		mac_first = 0;  		break;  	default:  		return (EPROTONOSUPPORT);  	} -	/* Only TLS 1.1 and TLS 1.2 are currently supported. */ -	if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || -	    tls->params.tls_vminor < TLS_MINOR_VER_ONE || -	    tls->params.tls_vminor > TLS_MINOR_VER_TWO) { -		return (EPROTONOSUPPORT); -	} -  	/* Bail if we already have a key. */  	if (direction == KTLS_TX) {  		if (toep->tls.tx_key_addr != -1) @@ -289,6 +300,7 @@ tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  	if (error)  		return (error); +	toep->tls.tls13 = tls->params.tls_vminor == TLS_MINOR_VER_THREE;  	if (direction == KTLS_TX) {  		toep->tls.scmd0.seqno_numivs =  			(V_SCMD_SEQ_NO_CTRL(3) | @@ -298,14 +310,14 @@ tls_alloc_ktls(struct toepcb *toep, struct ktls_session *tls, int direction)  			 V_SCMD_CIPH_MODE(t4_tls_cipher_mode(tls)) |  			 V_SCMD_AUTH_MODE(t4_tls_auth_mode(tls)) |  			 V_SCMD_HMAC_CTRL(t4_tls_hmac_ctrl(tls)) | -			 V_SCMD_IV_SIZE(explicit_iv_size / 2)); +			 V_SCMD_IV_SIZE(iv_size / 2));  		toep->tls.scmd0.ivgen_hdrlen =  			(V_SCMD_IV_GEN_CTRL(1) |  			 V_SCMD_KEY_CTX_INLINE(0) |  			 V_SCMD_TLS_FRAG_ENABLE(1)); -		toep->tls.iv_len = explicit_iv_size; +		toep->tls.iv_len = iv_size;  		toep->tls.frag_size = tls->params.max_frame_len;  		toep->tls.fcplenmax = get_tp_plen_max(tls);  		toep->tls.expn_per_ulp = tls->params.tls_hlen + @@ -352,7 +364,8 @@ tls_uninit_toep(struct toepcb *toep)  static void  write_tlstx_wr(struct fw_tlstx_data_wr *txwr, struct toepcb *toep, -    unsigned int plen, unsigned int expn, uint8_t credits, int shove) +    unsigned int plen, unsigned int expn, uint8_t credits, int shove, +    int num_ivs)  {  	struct tls_ofld_info *tls_ofld = &toep->tls;  	unsigned int len = plen + expn; @@ -365,7 +378,7 @@ write_tlstx_wr(struct fw_tlstx_data_wr *txwr, struct toepcb *toep,  	txwr->plen = htobe32(len);  	txwr->lsodisable_to_flags = htobe32(V_TX_ULP_MODE(ULP_MODE_TLS) |  	    V_TX_URG(0) | /* F_T6_TX_FORCE | */ V_TX_SHOVE(shove)); -	txwr->ctxloc_to_exp = htobe32(V_FW_TLSTX_DATA_WR_NUMIVS(1) | +	txwr->ctxloc_to_exp = htobe32(V_FW_TLSTX_DATA_WR_NUMIVS(num_ivs) |  	    V_FW_TLSTX_DATA_WR_EXP(expn) |  	    V_FW_TLSTX_DATA_WR_CTXLOC(TLS_SFO_WR_CONTEXTLOC_DDR) |  	    V_FW_TLSTX_DATA_WR_IVDSGL(0) | @@ -381,20 +394,20 @@ write_tlstx_wr(struct fw_tlstx_data_wr *txwr, struct toepcb *toep,  static void  write_tlstx_cpl(struct cpl_tx_tls_sfo *cpl, struct toepcb *toep, -    struct tls_hdr *tls_hdr, unsigned int plen, uint64_t seqno) +    struct tls_hdr *tls_hdr, unsigned int plen, uint8_t rec_type, +    uint64_t seqno)  {  	struct tls_ofld_info *tls_ofld = &toep->tls;  	int data_type, seglen;  	seglen = plen; -	data_type = tls_content_type(tls_hdr->type); +	data_type = tls_content_type(rec_type);  	cpl->op_to_seg_len = htobe32(V_CPL_TX_TLS_SFO_OPCODE(CPL_TX_TLS_SFO) |  	    V_CPL_TX_TLS_SFO_DATA_TYPE(data_type) |  	    V_CPL_TX_TLS_SFO_CPL_LEN(2) | V_CPL_TX_TLS_SFO_SEG_LEN(seglen));  	cpl->pld_len = htobe32(plen);  	if (data_type == CPL_TX_TLS_SFO_TYPE_CUSTOM) -		cpl->type_protover = htobe32( -		    V_CPL_TX_TLS_SFO_TYPE(tls_hdr->type)); +		cpl->type_protover = htobe32(V_CPL_TX_TLS_SFO_TYPE(rec_type));  	cpl->seqno_numivs = htobe32(tls_ofld->scmd0.seqno_numivs |  	    V_SCMD_NUM_IVS(1));  	cpl->ivgen_hdrlen = htobe32(tls_ofld->scmd0.ivgen_hdrlen); @@ -494,9 +507,11 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  	struct tcpcb *tp = intotcpcb(inp);  	struct socket *so = inp->inp_socket;  	struct sockbuf *sb = &so->so_snd; +	struct mbufq *pduq = &toep->ulp_pduq;  	int tls_size, tx_credits, shove, sowwakeup;  	struct ofld_tx_sdesc *txsd;  	char *buf; +	bool tls13;  	INP_WLOCK_ASSERT(inp);  	KASSERT(toep->flags & TPF_FLOWC_WR_SENT, @@ -532,10 +547,23 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  		return;  	} +	tls13 = toep->tls.tls13;  	txsd = &toep->txsd[toep->txsd_pidx];  	for (;;) {  		tx_credits = min(toep->tx_credits, MAX_OFLD_TX_CREDITS); +		if (__predict_false((m = mbufq_first(pduq)) != NULL)) { +			if (!t4_push_raw_wr(sc, toep, m)) { +				toep->flags |= TPF_TX_SUSPENDED; +				return; +			} + +			(void)mbufq_dequeue(pduq); + +			txsd = &toep->txsd[toep->txsd_pidx]; +			continue; +		} +  		SOCKBUF_LOCK(sb);  		sowwakeup = drop;  		if (drop) { @@ -586,9 +614,11 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  		    sizeof(struct cpl_tx_tls_sfo) +  		    sizeof(struct ulptx_idata) + sizeof(struct ulptx_sc_memrd); -		/* Explicit IVs for AES-CBC and AES-GCM are <= 16. */ -		MPASS(toep->tls.iv_len <= AES_BLOCK_LEN); -		wr_len += AES_BLOCK_LEN; +		if (!tls13) { +			/* Explicit IVs for AES-CBC and AES-GCM are <= 16. */ +			MPASS(toep->tls.iv_len <= AES_BLOCK_LEN); +			wr_len += AES_BLOCK_LEN; +		}  		/* Account for SGL in work request length. */  		nsegs = count_ext_pgs_segs(m); @@ -658,8 +688,10 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  		expn_size = m->m_epg_hdrlen +  		    m->m_epg_trllen;  		tls_size = m->m_len - expn_size; -		write_tlstx_wr(txwr, toep, tls_size, expn_size, credits, shove); -		write_tlstx_cpl(cpl, toep, thdr, tls_size, m->m_epg_seqno); +		write_tlstx_wr(txwr, toep, tls_size, expn_size, credits, shove, +		    tls13 ? 0 : 1); +		write_tlstx_cpl(cpl, toep, thdr, tls_size, +		    tls13 ? m->m_epg_record_type : thdr->type, m->m_epg_seqno);  		idata = (struct ulptx_idata *)(cpl + 1);  		idata->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_NOOP)); @@ -670,10 +702,12 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  		    V_ULPTX_LEN16(toep->tls.tx_key_info_size >> 4));  		memrd->addr = htobe32(toep->tls.tx_key_addr >> 5); -		/* Copy IV. */  		buf = (char *)(memrd + 1); -		memcpy(buf, thdr + 1, toep->tls.iv_len); -		buf += AES_BLOCK_LEN; +		if (!tls13) { +			/* Copy IV. */ +			memcpy(buf, thdr + 1, toep->tls.iv_len); +			buf += AES_BLOCK_LEN; +		}  		write_ktlstx_sgl(buf, m, nsegs); @@ -694,6 +728,8 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int drop)  			toep->flags |= TPF_TX_SUSPENDED;  		KASSERT(toep->txsd_avail > 0, ("%s: no txsd", __func__)); +		KASSERT(m->m_len <= MAX_OFLD_TX_SDESC_PLEN, +		    ("%s: plen %u too large", __func__, m->m_len));  		txsd->plen = m->m_len;  		txsd->tx_credits = credits;  		txsd++; @@ -793,8 +829,8 @@ do_rx_tls_cmp(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)  	struct sockbuf *sb;  	struct mbuf *tls_data;  	struct tls_get_record *tgr; -	struct mbuf *control; -	int pdu_length, trailer_len; +	struct mbuf *control, *n; +	int pdu_length, resid, trailer_len;  #if defined(KTR) || defined(INVARIANTS)  	int len;  #endif @@ -842,7 +878,9 @@ do_rx_tls_cmp(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)  	/*  	 * The payload of this CPL is the TLS header followed by -	 * additional fields. +	 * additional fields.  For TLS 1.3 the type field holds the +	 * inner record type and the length field has been updated to +	 * strip the inner record type, padding, and MAC.  	 */  	KASSERT(m->m_len >= sizeof(*tls_hdr_pkt),  	    ("%s: payload too small", __func__)); @@ -854,7 +892,14 @@ do_rx_tls_cmp(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)  		    ("%s: sequence mismatch", __func__));  	} -	/* Report decryption errors as EBADMSG. */ +	/* +	 * Report decryption errors as EBADMSG. +	 * +	 * XXX: To support rekeying for TLS 1.3 this will eventually +	 * have to be updated to recrypt the data with the old key and +	 * then decrypt with the new key.  Punt for now as KTLS +	 * doesn't yet support rekeying. +	 */  	if ((tls_hdr_pkt->res_to_mac_error & M_TLSRX_HDR_PKT_ERROR) != 0) {  		CTR4(KTR_CXGBE, "%s: tid %u TLS error %#x ddp_vld %#x",  		    __func__, toep->tid, tls_hdr_pkt->res_to_mac_error, @@ -872,6 +917,33 @@ do_rx_tls_cmp(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)  		return (0);  	} +	/* For TLS 1.3 trim the header and trailer. */ +	if (toep->tls.tls13) { +		KASSERT(tls_data != NULL, ("%s: TLS 1.3 record without data", +		    __func__)); +		MPASS(tls_data->m_pkthdr.len == pdu_length); +		m_adj(tls_data, sizeof(struct tls_record_layer)); +		if (tls_data->m_pkthdr.len > be16toh(tls_hdr_pkt->length)) +			tls_data->m_pkthdr.len = be16toh(tls_hdr_pkt->length); +		resid = tls_data->m_pkthdr.len; +		if (resid == 0) { +			m_freem(tls_data); +			tls_data = NULL; +		} else { +			for (n = tls_data;; n = n->m_next) { +				if (n->m_len < resid) { +					resid -= n->m_len; +					continue; +				} + +				n->m_len = resid; +				m_freem(n->m_next); +				n->m_next = NULL; +				break; +			} +		} +	} +  	/* Handle data received after the socket is closed. */  	sb = &so->so_rcv;  	SOCKBUF_LOCK(sb); @@ -1076,33 +1148,60 @@ out:  }  /* - * Send a work request setting multiple TCB fields to enable - * ULP_MODE_TLS. + * Send a work request setting one or more TCB fields to partially or + * fully enable ULP_MODE_TLS. + * + * - If resid == 0, the socket buffer ends at a record boundary + *   (either empty or contains one or more complete records).  Switch + *   to ULP_MODE_TLS (if not already) and enable TLS decryption. + * + * - If resid != 0, the socket buffer contains a partial record.  In + *   this case, switch to ULP_MODE_TLS partially and configure the TCB + *   to pass along the remaining resid bytes undecrypted.  Once they + *   arrive, this is called again with resid == 0 and enables TLS + *   decryption.   */  static void -tls_update_tcb(struct adapter *sc, struct toepcb *toep, uint64_t seqno) +tls_update_tcb(struct adapter *sc, struct toepcb *toep, uint64_t seqno, +    size_t resid)  { -	struct wrqe *wr; +	struct mbuf *m;  	struct work_request_hdr *wrh;  	struct ulp_txpkt *ulpmc;  	int fields, key_offset, len; -	KASSERT(ulp_mode(toep) == ULP_MODE_NONE, -	    ("%s: tid %d already ULP_MODE_TLS", __func__, toep->tid)); +	/* +	 * If we are already in ULP_MODE_TLS, then we should now be at +	 * a record boundary and ready to finish enabling TLS RX. +	 */ +	KASSERT(resid == 0 || ulp_mode(toep) == ULP_MODE_NONE, +	    ("%s: tid %d needs %zu more data but already ULP_MODE_TLS", +	    __func__, toep->tid, resid));  	fields = 0; +	if (ulp_mode(toep) == ULP_MODE_NONE) { +		/* 2 writes for the overlay region */ +		fields += 2; +	} -	/* 2 writes for the overlay region */ -	fields += 2; +	if (resid == 0) { +		/* W_TCB_TLS_SEQ */ +		fields++; -	/* W_TCB_TLS_SEQ */ -	fields++; +		/* W_TCB_ULP_RAW */ +		fields++; +	} else { +		/* W_TCB_PDU_LEN */ +		fields++; -	/* W_TCB_ULP_RAW */ -	fields++; +		/* W_TCB_ULP_RAW */ +		fields++; +	} -	/* W_TCB_ULP_TYPE */ -	fields ++; +	if (ulp_mode(toep) == ULP_MODE_NONE) { +		/* W_TCB_ULP_TYPE */ +		fields ++; +	}  	/* W_TCB_T_FLAGS */  	fields++; @@ -1111,59 +1210,94 @@ tls_update_tcb(struct adapter *sc, struct toepcb *toep, uint64_t seqno)  	KASSERT(len <= SGE_MAX_WR_LEN,  	    ("%s: WR with %d TCB field updates too large", __func__, fields)); -	wr = alloc_wrqe(len, toep->ctrlq); -	if (wr == NULL) { +	m = alloc_raw_wr_mbuf(len); +	if (m == NULL) {  		/* XXX */  		panic("%s: out of memory", __func__);  	} -	wrh = wrtod(wr); -	INIT_ULPTX_WRH(wrh, len, 1, 0);	/* atomic */ +	wrh = mtod(m, struct work_request_hdr *); +	INIT_ULPTX_WRH(wrh, len, 1, toep->tid);	/* atomic */  	ulpmc = (struct ulp_txpkt *)(wrh + 1); -	/* -	 * Clear the TLS overlay region: 1023:832. -	 * -	 * Words 26/27 are always set to zero.  Words 28/29 -	 * contain seqno and are set when enabling TLS -	 * decryption.  Word 30 is zero and Word 31 contains -	 * the keyid. -	 */ -	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, 26, -	    0xffffffffffffffff, 0); +	if (ulp_mode(toep) == ULP_MODE_NONE) { +		/* +		 * Clear the TLS overlay region: 1023:832. +		 * +		 * Words 26/27 are always set to zero.  Words 28/29 +		 * contain seqno and are set when enabling TLS +		 * decryption.  Word 30 is zero and Word 31 contains +		 * the keyid. +		 */ +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, 26, +		    0xffffffffffffffff, 0); -	/* -	 * RX key tags are an index into the key portion of MA -	 * memory stored as an offset from the base address in -	 * units of 64 bytes. -	 */ -	key_offset = toep->tls.rx_key_addr - sc->vres.key.start; -	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, 30, -	    0xffffffffffffffff, -	    (uint64_t)V_TCB_RX_TLS_KEY_TAG(key_offset / 64) << 32); - -	CTR3(KTR_CXGBE, "%s: tid %d enable TLS seqno %lu", __func__, -	    toep->tid, seqno); -	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, W_TCB_TLS_SEQ, -	    V_TCB_TLS_SEQ(M_TCB_TLS_SEQ), V_TCB_TLS_SEQ(seqno)); -	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, W_TCB_ULP_RAW, -	    V_TCB_ULP_RAW(M_TCB_ULP_RAW), -	    V_TCB_ULP_RAW((V_TF_TLS_KEY_SIZE(3) | V_TF_TLS_CONTROL(1) | -	    V_TF_TLS_ACTIVE(1) | V_TF_TLS_ENABLE(1)))); - -	toep->flags &= ~TPF_TLS_STARTING; -	toep->flags |= TPF_TLS_RECEIVE; - -	/* Set the ULP mode to ULP_MODE_TLS. */ -	toep->params.ulp_mode = ULP_MODE_TLS; -	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, W_TCB_ULP_TYPE, -	    V_TCB_ULP_TYPE(M_TCB_ULP_TYPE), V_TCB_ULP_TYPE(ULP_MODE_TLS)); +		/* +		 * RX key tags are an index into the key portion of MA +		 * memory stored as an offset from the base address in +		 * units of 64 bytes. +		 */ +		key_offset = toep->tls.rx_key_addr - sc->vres.key.start; +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, 30, +		    0xffffffffffffffff, +		    (uint64_t)V_TCB_RX_TLS_KEY_TAG(key_offset / 64) << 32); +	} + +	if (resid == 0) { +		/* +		 * The socket buffer is empty or only contains +		 * complete TLS records: Set the sequence number and +		 * enable TLS decryption. +		 */ +		CTR3(KTR_CXGBE, "%s: tid %d enable TLS seqno %lu", __func__, +		    toep->tid, seqno); +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, +		    W_TCB_RX_TLS_SEQ, V_TCB_RX_TLS_SEQ(M_TCB_RX_TLS_SEQ), +		    V_TCB_RX_TLS_SEQ(seqno)); +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, +		    W_TCB_ULP_RAW, V_TCB_ULP_RAW(M_TCB_ULP_RAW), +		    V_TCB_ULP_RAW((V_TF_TLS_KEY_SIZE(3) | V_TF_TLS_CONTROL(1) | +		    V_TF_TLS_ACTIVE(1) | V_TF_TLS_ENABLE(1)))); + +		toep->flags &= ~TPF_TLS_STARTING; +		toep->flags |= TPF_TLS_RECEIVE; +	} else { +		/* +		 * The socket buffer ends with a partial record with a +		 * full header and needs at least 6 bytes. +		 * +		 * Set PDU length.  This is treating the 'resid' bytes +		 * as a TLS PDU, so the first 5 bytes are a fake +		 * header and the rest are the PDU length. +		 */ +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, +		    W_TCB_PDU_LEN, V_TCB_PDU_LEN(M_TCB_PDU_LEN), +		    V_TCB_PDU_LEN(resid - sizeof(struct tls_hdr))); +		CTR3(KTR_CXGBE, "%s: tid %d setting PDU_LEN to %zu", +		    __func__, toep->tid, resid - sizeof(struct tls_hdr)); + +		/* Clear all bits in ULP_RAW except for ENABLE. */ +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, +		    W_TCB_ULP_RAW, V_TCB_ULP_RAW(M_TCB_ULP_RAW), +		    V_TCB_ULP_RAW(V_TF_TLS_ENABLE(1))); + +		/* Wait for 'resid' bytes to be delivered as CPL_RX_DATA. */ +		toep->tls.rx_resid = resid; +	} + +	if (ulp_mode(toep) == ULP_MODE_NONE) { +		/* Set the ULP mode to ULP_MODE_TLS. */ +		toep->params.ulp_mode = ULP_MODE_TLS; +		ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, +		    W_TCB_ULP_TYPE, V_TCB_ULP_TYPE(M_TCB_ULP_TYPE), +		    V_TCB_ULP_TYPE(ULP_MODE_TLS)); +	}  	/* Clear TF_RX_QUIESCE. */  	ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, W_TCB_T_FLAGS,  	    V_TF_RX_QUIESCE(1), 0); -	t4_wrq_tx(sc, wr); +	t4_raw_wr_tx(sc, toep, m);  }  /* @@ -1190,7 +1324,8 @@ tls_check_rx_sockbuf(struct adapter *sc, struct toepcb *toep,  	 * size of a TLS record, re-enable receive and pause again once  	 * we get more data to try again.  	 */ -	if (!have_header || resid != 0) { +	if (!have_header || (resid != 0 && (resid < sizeof(struct tls_hdr) || +	    is_t6(sc)))) {  		CTR(KTR_CXGBE, "%s: tid %d waiting for more data", __func__,  		    toep->tid);  		toep->flags &= ~TPF_TLS_RX_QUIESCED; @@ -1198,7 +1333,7 @@ tls_check_rx_sockbuf(struct adapter *sc, struct toepcb *toep,  		return;  	} -	tls_update_tcb(sc, toep, seqno); +	tls_update_tcb(sc, toep, seqno, resid);  }  void | 
