FreeBSD/sys/dev/cxgbe/iw_cxgbe/cm.c
/*
 * process_mpa_request - process streaming mode MPA request
 *
 * Returns:
 *
 * 0 upon success indicating a connect request was delivered to the ULP
 * or the mpa request is incomplete but valid so far.
 *
 * 1 if a failure requires the caller to close the connection.
 *
 * 2 if a failure requires the caller to abort the connection.
 */
process streaming mode MPA request
Returns.

0 upon success indicating a connect request was delivered to the ULP
or the mpa request is incomplete but valid so far.

1 if a failure requires the caller to close the connection.

2 if a failure requires the caller to abort the connection.
process streaming mode MPA request Returns . 0 upon success indicating a connect request was delivered to the ULP or the mpa request is incomplete but valid so far . 1 if a failure requires the caller to close the connection . 2 if a failure requires the caller to abort the connection .
static int
process_mpa_request(struct c4iw_ep *ep)
{
	struct mpa_message *mpa;
	u16 plen;
	int flags = MSG_DONTWAIT;
	int rc;
	struct iovec iov;
	struct uio uio;
	enum c4iw_ep_state state = state_read(&ep->com);
	CTR3(KTR_IW_CXGBE, "%s: ep %p, state %s", __func__, ep, states[state]);
	if (state != MPA_REQ_WAIT)
		return 0;
	iov.iov_base = &ep->mpa_pkt[ep->mpa_pkt_len];
	iov.iov_len = sizeof(ep->mpa_pkt) - ep->mpa_pkt_len;
	uio.uio_iov = &iov;
	uio.uio_iovcnt = 1;
	uio.uio_offset = 0;
	uio.uio_resid = sizeof(ep->mpa_pkt) - ep->mpa_pkt_len;
	uio.uio_segflg = UIO_SYSSPACE;
	uio.uio_rw = UIO_READ;
	uio.uio_td = NULL; 
	rc = soreceive(ep->com.so, NULL, &uio, NULL, NULL, &flags);
	if (rc == EAGAIN)
		return 0;
	else if (rc)
		goto err_stop_timer;
	KASSERT(uio.uio_offset > 0, ("%s: sorecieve on so %p read no data",
	    __func__, ep->com.so));
	ep->mpa_pkt_len += uio.uio_offset;
	if (ep->mpa_pkt_len < sizeof(*mpa))
		return 0;
	mpa = (struct mpa_message *) ep->mpa_pkt;
	if (mpa->revision > mpa_rev) {
		log(LOG_ERR, "%s: MPA version mismatch. Local = %d,"
		    " Received = %d\n", __func__, mpa_rev, mpa->revision);
		goto err_stop_timer;
	}
	if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key)))
		goto err_stop_timer;
	plen = ntohs(mpa->private_data_size);
	if (plen > MPA_MAX_PRIVATE_DATA)
		goto err_stop_timer;
	if (ep->mpa_pkt_len > (sizeof(*mpa) + plen))
		goto err_stop_timer;
	ep->plen = (u8) plen;
	if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
		return 0;
	ep->mpa_attr.initiator = 0;
	ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
	ep->mpa_attr.recv_marker_enabled = markers_enabled;
	ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
	ep->mpa_attr.version = mpa->revision;
	if (mpa->revision == 1)
		ep->tried_with_mpa_v1 = 1;
	ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
	if (mpa->revision == 2) {
		ep->mpa_attr.enhanced_rdma_conn =
		    mpa->flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0;
		if (ep->mpa_attr.enhanced_rdma_conn) {
			struct mpa_v2_conn_params *mpa_v2_params;
			u16 ird, ord;
			mpa_v2_params = (void *)&ep->mpa_pkt[sizeof(*mpa)];
			ird = ntohs(mpa_v2_params->ird);
			ord = ntohs(mpa_v2_params->ord);
			ep->ird = ird & MPA_V2_IRD_ORD_MASK;
			ep->ord = ord & MPA_V2_IRD_ORD_MASK;
			if (ird & MPA_V2_PEER2PEER_MODEL && peer2peer) {
				if (ord & MPA_V2_RDMA_WRITE_RTR) {
					ep->mpa_attr.p2p_type =
					    FW_RI_INIT_P2PTYPE_RDMA_WRITE;
				} else if (ord & MPA_V2_RDMA_READ_RTR) {
					ep->mpa_attr.p2p_type =
					    FW_RI_INIT_P2PTYPE_READ_REQ;
				}
			}
		}
	} else if (mpa->revision == 1 && peer2peer)
		ep->mpa_attr.p2p_type = p2p_type;
	if (set_tcpinfo(ep))
		goto err_stop_timer;
	CTR5(KTR_IW_CXGBE, "%s: crc_enabled = %d, recv_marker_enabled = %d, "
	    "xmit_marker_enabled = %d, version = %d", __func__,
	    ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,
	    ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version);
	state_set(&ep->com, MPA_REQ_RCVD);
	STOP_EP_TIMER(ep);
	mutex_lock(&ep->parent_ep->com.mutex);
	if (ep->parent_ep->com.state != DEAD) {
		if (connect_request_upcall(ep))
			goto err_unlock_parent;
	} else
		goto err_unlock_parent;
	mutex_unlock(&ep->parent_ep->com.mutex);
	return 0;
err_unlock_parent:
	mutex_unlock(&ep->parent_ep->com.mutex);
	goto err_out;
err_stop_timer:
	STOP_EP_TIMER(ep);
err_out:
	return 2;
}
static int process_mpa_request ( struct c4iw_ep * ep ) { struct mpa_message * mpa ; u16 plen ; int flags = MSG_DONTWAIT ; int rc ; struct iovec iov ; struct uio uio ; enum c4iw_ep_state state = state_read ( & ep -> com ) ; CTR3 ( KTR_IW_CXGBE , " " , __func__ , ep , states [ state ] ) ; if ( state != MPA_REQ_WAIT ) return 0 ; iov . iov_base = & ep -> mpa_pkt [ ep -> mpa_pkt_len ] ; iov . iov_len = sizeof ( ep -> mpa_pkt ) - ep -> mpa_pkt_len ; uio . uio_iov = & iov ; uio . uio_iovcnt = 1 ; uio . uio_offset = 0 ; uio . uio_resid = sizeof ( ep -> mpa_pkt ) - ep -> mpa_pkt_len ; uio . uio_segflg = UIO_SYSSPACE ; uio . uio_rw = UIO_READ ; uio . uio_td = NULL ; rc = soreceive ( ep -> com . so , NULL , & uio , NULL , NULL , & flags ) ; if ( rc == EAGAIN ) return 0 ; else if ( rc ) goto err_stop_timer ; KASSERT ( uio . uio_offset > 0 , ( " " , __func__ , ep -> com . so ) ) ; ep -> mpa_pkt_len += uio . uio_offset ; if ( ep -> mpa_pkt_len < sizeof ( * mpa ) ) return 0 ; mpa = ( struct mpa_message * ) ep -> mpa_pkt ; if ( mpa -> revision > mpa_rev ) { log ( LOG_ERR , " " " \n " , __func__ , mpa_rev , mpa -> revision ) ; goto err_stop_timer ; } if ( memcmp ( mpa -> key , MPA_KEY_REQ , sizeof ( mpa -> key ) ) ) goto err_stop_timer ; plen = ntohs ( mpa -> private_data_size ) ; if ( plen > MPA_MAX_PRIVATE_DATA ) goto err_stop_timer ; if ( ep -> mpa_pkt_len > ( sizeof ( * mpa ) + plen ) ) goto err_stop_timer ; ep -> plen = ( u8 ) plen ; if ( ep -> mpa_pkt_len < ( sizeof ( * mpa ) + plen ) ) return 0 ; ep -> mpa_attr . initiator = 0 ; ep -> mpa_attr . crc_enabled = ( mpa -> flags & MPA_CRC ) | crc_enabled ? 1 : 0 ; ep -> mpa_attr . recv_marker_enabled = markers_enabled ; ep -> mpa_attr . xmit_marker_enabled = mpa -> flags & MPA_MARKERS ? 1 : 0 ; ep -> mpa_attr . version = mpa -> revision ; if ( mpa -> revision == 1 ) ep -> tried_with_mpa_v1 = 1 ; ep -> mpa_attr . p2p_type = FW_RI_INIT_P2PTYPE_DISABLED ; if ( mpa -> revision == 2 ) { ep -> mpa_attr . enhanced_rdma_conn = mpa -> flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0 ; if ( ep -> mpa_attr . enhanced_rdma_conn ) { struct mpa_v2_conn_params * mpa_v2_params ; u16 ird , ord ; mpa_v2_params = ( void * ) & ep -> mpa_pkt [ sizeof ( * mpa ) ] ; ird = ntohs ( mpa_v2_params -> ird ) ; ord = ntohs ( mpa_v2_params -> ord ) ; ep -> ird = ird & MPA_V2_IRD_ORD_MASK ; ep -> ord = ord & MPA_V2_IRD_ORD_MASK ; if ( ird & MPA_V2_PEER2PEER_MODEL && peer2peer ) { if ( ord & MPA_V2_RDMA_WRITE_RTR ) { ep -> mpa_attr . p2p_type = FW_RI_INIT_P2PTYPE_RDMA_WRITE ; } else if ( ord & MPA_V2_RDMA_READ_RTR ) { ep -> mpa_attr . p2p_type = FW_RI_INIT_P2PTYPE_READ_REQ ; } } } } else if ( mpa -> revision == 1 && peer2peer ) ep -> mpa_attr . p2p_type = p2p_type ; if ( set_tcpinfo ( ep ) ) goto err_stop_timer ; CTR5 ( KTR_IW_CXGBE , " " " " , __func__ , ep -> mpa_attr . crc_enabled , ep -> mpa_attr . recv_marker_enabled , ep -> mpa_attr . xmit_marker_enabled , ep -> mpa_attr . version ) ; state_set ( & ep -> com , MPA_REQ_RCVD ) ; STOP_EP_TIMER ( ep ) ; mutex_lock ( & ep -> parent_ep -> com . mutex ) ; if ( ep -> parent_ep -> com . state != DEAD ) { if ( connect_request_upcall ( ep ) ) goto err_unlock_parent ; } else goto err_unlock_parent ; mutex_unlock ( & ep -> parent_ep -> com . mutex ) ; return 0 ; err_unlock_parent : mutex_unlock ( & ep -> parent_ep -> com . mutex ) ; goto err_out ; err_stop_timer : STOP_EP_TIMER ( ep ) ; err_out : return 2 ; }
process_mpa_request - process streaming mode MPA request
 Returns:
process_mpa_request - process streaming mode MPA request Returns :
/* uio.uio_td = ep->com.thread; */ /*
	 * If we get more than the supported amount of private data then we must
	 * fail this connection.  XXX: check so_rcv->sb_cc, or peek with another
	 * soreceive, or increase the size of mpa_pkt by 1 and abort if the last
	 * byte is filled by the soreceive above.
	 */ /* Don't even have the MPA message.  Wait for more data to arrive. */ /*
	 * Validate MPA Header.
	 */ /*
	 * Fail if there's too much private data.
	 */ /*
	 * If plen does not account for pkt size
	 */ /*
	 * If we don't have all the pdata yet, then bail.
	 */ /*
	 * If we get here we have accumulated the entire mpa
	 * start reply message including private data.
	 */ /* drive upcall */