Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/cxgbei/icl_cxgbei.c
Show First 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | finalize_pdu(struct icl_cxgbei_conn *icc, struct icl_cxgbei_pdu *icp) | ||||
* Fix up the data segment mbuf first. | * Fix up the data segment mbuf first. | ||||
*/ | */ | ||||
m = ip->ip_data_mbuf; | m = ip->ip_data_mbuf; | ||||
ulp_submode = icc->ulp_submode; | ulp_submode = icc->ulp_submode; | ||||
if (m) { | if (m) { | ||||
last = m_last(m); | last = m_last(m); | ||||
/* | /* | ||||
* Round up the data segment to a 4B boundary. Pad with 0 if | * Round up the data segment to a 4B boundary. Pad with 0 if | ||||
* necessary. There will definitely be room in the mbuf. | * necessary. There will definitely be room in the mbuf. | ||||
*/ | */ | ||||
padding = roundup2(ip->ip_data_len, 4) - ip->ip_data_len; | padding = roundup2(ip->ip_data_len, 4) - ip->ip_data_len; | ||||
if (padding) { | if (padding) { | ||||
bzero(mtod(last, uint8_t *) + last->m_len, padding); | bzero(mtod(last, uint8_t *) + last->m_len, padding); | ||||
last->m_len += padding; | last->m_len += padding; | ||||
} | } | ||||
} else { | } else { | ||||
Show All 9 Lines | finalize_pdu(struct icl_cxgbei_conn *icc, struct icl_cxgbei_pdu *icp) | ||||
MPASS(m->m_pkthdr.len == sizeof(struct iscsi_bhs)); | MPASS(m->m_pkthdr.len == sizeof(struct iscsi_bhs)); | ||||
MPASS(m->m_len == sizeof(struct iscsi_bhs)); | MPASS(m->m_len == sizeof(struct iscsi_bhs)); | ||||
bhs = ip->ip_bhs; | bhs = ip->ip_bhs; | ||||
bhs->bhs_data_segment_len[2] = ip->ip_data_len; | bhs->bhs_data_segment_len[2] = ip->ip_data_len; | ||||
bhs->bhs_data_segment_len[1] = ip->ip_data_len >> 8; | bhs->bhs_data_segment_len[1] = ip->ip_data_len >> 8; | ||||
bhs->bhs_data_segment_len[0] = ip->ip_data_len >> 16; | bhs->bhs_data_segment_len[0] = ip->ip_data_len >> 16; | ||||
/* "Convert" PDU to mbuf chain. Do not use icp/ip after this. */ | /* "Convert" PDU to mbuf chain. Do not use icp/ip after this. */ | ||||
m->m_pkthdr.len = sizeof(struct iscsi_bhs) + ip->ip_data_len + padding; | m->m_pkthdr.len = sizeof(struct iscsi_bhs) + ip->ip_data_len + padding; | ||||
m->m_next = ip->ip_data_mbuf; | m->m_next = ip->ip_data_mbuf; | ||||
set_mbuf_ulp_submode(m, ulp_submode); | set_mbuf_ulp_submode(m, ulp_submode); | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
bzero(icp, sizeof(*icp)); | bzero(icp, sizeof(*icp)); | ||||
#endif | #endif | ||||
#ifdef DIAGNOSTIC | #ifdef DIAGNOSTIC | ||||
refcount_release(&icc->ic.ic_outstanding_pdus); | refcount_release(&icc->ic.ic_outstanding_pdus); | ||||
Show All 24 Lines | if (m == NULL) { | ||||
ip->ip_data_mbuf = m; | ip->ip_data_mbuf = m; | ||||
} | } | ||||
if (__predict_true(m_append(m, len, addr) != 0)) { | if (__predict_true(m_append(m, len, addr) != 0)) { | ||||
ip->ip_data_len += len; | ip->ip_data_len += len; | ||||
MPASS(ip->ip_data_len <= ic->ic_max_data_segment_length); | MPASS(ip->ip_data_len <= ic->ic_max_data_segment_length); | ||||
return (0); | return (0); | ||||
} else { | } else { | ||||
if (flags & M_WAITOK) { | if (flags & M_WAITOK) { | ||||
CXGBE_UNIMPLEMENTED("fail safe append"); | CXGBE_UNIMPLEMENTED("fail safe append"); | ||||
} | } | ||||
ip->ip_data_len = m_length(m, NULL); | ip->ip_data_len = m_length(m, NULL); | ||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | send_iscsi_flowc_wr(struct adapter *sc, struct toepcb *toep, int maxlen) | ||||
txsd->plen = 0; | txsd->plen = 0; | ||||
KASSERT(toep->tx_credits >= txsd->tx_credits && toep->txsd_avail > 0, | KASSERT(toep->tx_credits >= txsd->tx_credits && toep->txsd_avail > 0, | ||||
("%s: not enough credits (%d)", __func__, toep->tx_credits)); | ("%s: not enough credits (%d)", __func__, toep->tx_credits)); | ||||
toep->tx_credits -= txsd->tx_credits; | toep->tx_credits -= txsd->tx_credits; | ||||
if (__predict_false(++toep->txsd_pidx == toep->txsd_total)) | if (__predict_false(++toep->txsd_pidx == toep->txsd_total)) | ||||
toep->txsd_pidx = 0; | toep->txsd_pidx = 0; | ||||
toep->txsd_avail--; | toep->txsd_avail--; | ||||
t4_wrq_tx(sc, wr); | t4_wrq_tx(sc, wr); | ||||
} | } | ||||
static void | static void | ||||
set_ulp_mode_iscsi(struct adapter *sc, struct toepcb *toep, u_int ulp_submode) | set_ulp_mode_iscsi(struct adapter *sc, struct toepcb *toep, u_int ulp_submode) | ||||
{ | { | ||||
uint64_t val; | uint64_t val; | ||||
CTR3(KTR_CXGBE, "%s: tid %u, ULP_MODE_ISCSI, submode=%#x", | CTR3(KTR_CXGBE, "%s: tid %u, ULP_MODE_ISCSI, submode=%#x", | ||||
▲ Show 20 Lines • Show All 220 Lines • ▼ Show 20 Lines | icl_cxgbei_conn_task_setup(struct icl_conn *ic, struct icl_pdu *ip, | ||||
/* This is for the offload driver's state. Must not be set already. */ | /* This is for the offload driver's state. Must not be set already. */ | ||||
MPASS(arg != NULL); | MPASS(arg != NULL); | ||||
MPASS(*arg == NULL); | MPASS(*arg == NULL); | ||||
if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_IN || | if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_IN || | ||||
csio->dxfer_len < ci->ddp_threshold) { | csio->dxfer_len < ci->ddp_threshold) { | ||||
no_ddp: | no_ddp: | ||||
/* | /* | ||||
* No DDP for this I/O. Allocate an ITT (based on the one | * No DDP for this I/O. Allocate an ITT (based on the one | ||||
* passed in) that cannot be a valid hardware DDP tag in the | * passed in) that cannot be a valid hardware DDP tag in the | ||||
* iSCSI region. | * iSCSI region. | ||||
*/ | */ | ||||
itt = *ittp & M_PPOD_TAG; | itt = *ittp & M_PPOD_TAG; | ||||
itt = V_PPOD_TAG(itt) | pr->pr_invalid_bit; | itt = V_PPOD_TAG(itt) | pr->pr_invalid_bit; | ||||
*ittp = htobe32(itt); | *ittp = htobe32(itt); | ||||
MPASS(*arg == NULL); /* State is maintained for DDP only. */ | MPASS(*arg == NULL); /* State is maintained for DDP only. */ | ||||
if (rc != 0) | if (rc != 0) | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | cxgbei_limits(struct adapter *sc, void *arg) | ||||
end_synchronized_op(sc, LOCK_HELD); | end_synchronized_op(sc, LOCK_HELD); | ||||
} | } | ||||
static int | static int | ||||
icl_cxgbei_limits(struct icl_drv_limits *idl) | icl_cxgbei_limits(struct icl_drv_limits *idl) | ||||
{ | { | ||||
/* Maximum allowed by the RFC. cxgbei_limits will clip them. */ | /* Maximum allowed by the RFC. cxgbei_limits will clip them. */ | ||||
idl->idl_max_recv_data_segment_length = (1 << 24) - 1; | idl->idl_max_recv_data_segment_length = (1 << 24) - 1; | ||||
idl->idl_max_send_data_segment_length = (1 << 24) - 1; | idl->idl_max_send_data_segment_length = (1 << 24) - 1; | ||||
/* These are somewhat arbitrary. */ | /* These are somewhat arbitrary. */ | ||||
idl->idl_max_burst_length = 2 * 1024 * 1024; | idl->idl_max_burst_length = 2 * 1024 * 1024; | ||||
idl->idl_first_burst_length = 8192; | idl->idl_first_burst_length = 8192; | ||||
t4_iterate(cxgbei_limits, idl); | t4_iterate(cxgbei_limits, idl); | ||||
Show All 38 Lines |