|
@@ -450,14 +450,20 @@ static inline void init_packet(struct hfi1_ctxtdata *rcd,
|
|
|
packet->rcv_flags = 0;
|
|
|
}
|
|
|
|
|
|
-static void process_ecn(struct rvt_qp *qp, struct hfi1_ib_header *hdr,
|
|
|
- struct hfi1_other_headers *ohdr,
|
|
|
- u64 rhf, u32 bth1, struct ib_grh *grh)
|
|
|
+void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
|
|
|
+ bool do_cnp)
|
|
|
{
|
|
|
struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
|
|
|
- u32 rqpn = 0;
|
|
|
- u16 rlid;
|
|
|
- u8 sc5, svc_type;
|
|
|
+ struct hfi1_ib_header *hdr = pkt->hdr;
|
|
|
+ struct hfi1_other_headers *ohdr = pkt->ohdr;
|
|
|
+ struct ib_grh *grh = NULL;
|
|
|
+ u32 rqpn = 0, bth1;
|
|
|
+ u16 rlid, dlid = be16_to_cpu(hdr->lrh[1]);
|
|
|
+ u8 sc, svc_type;
|
|
|
+ bool is_mcast = false;
|
|
|
+
|
|
|
+ if (pkt->rcv_flags & HFI1_HAS_GRH)
|
|
|
+ grh = &hdr->u.l.grh;
|
|
|
|
|
|
switch (qp->ibqp.qp_type) {
|
|
|
case IB_QPT_SMI:
|
|
@@ -466,6 +472,8 @@ static void process_ecn(struct rvt_qp *qp, struct hfi1_ib_header *hdr,
|
|
|
rlid = be16_to_cpu(hdr->lrh[3]);
|
|
|
rqpn = be32_to_cpu(ohdr->u.ud.deth[1]) & RVT_QPN_MASK;
|
|
|
svc_type = IB_CC_SVCTYPE_UD;
|
|
|
+ is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
|
|
|
+ (dlid != be16_to_cpu(IB_LID_PERMISSIVE));
|
|
|
break;
|
|
|
case IB_QPT_UC:
|
|
|
rlid = qp->remote_ah_attr.dlid;
|
|
@@ -481,24 +489,23 @@ static void process_ecn(struct rvt_qp *qp, struct hfi1_ib_header *hdr,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
|
|
|
- if (rhf_dc_info(rhf))
|
|
|
- sc5 |= 0x10;
|
|
|
+ sc = hdr2sc((struct hfi1_message_header *)hdr, pkt->rhf);
|
|
|
|
|
|
- if (bth1 & HFI1_FECN_SMASK) {
|
|
|
+ bth1 = be32_to_cpu(ohdr->bth[1]);
|
|
|
+ if (do_cnp && (bth1 & HFI1_FECN_SMASK)) {
|
|
|
u16 pkey = (u16)be32_to_cpu(ohdr->bth[0]);
|
|
|
- u16 dlid = be16_to_cpu(hdr->lrh[1]);
|
|
|
|
|
|
- return_cnp(ibp, qp, rqpn, pkey, dlid, rlid, sc5, grh);
|
|
|
+ return_cnp(ibp, qp, rqpn, pkey, dlid, rlid, sc, grh);
|
|
|
}
|
|
|
|
|
|
- if (bth1 & HFI1_BECN_SMASK) {
|
|
|
+ if (!is_mcast && (bth1 & HFI1_BECN_SMASK)) {
|
|
|
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
|
|
|
u32 lqpn = bth1 & RVT_QPN_MASK;
|
|
|
- u8 sl = ibp->sc_to_sl[sc5];
|
|
|
+ u8 sl = ibp->sc_to_sl[sc];
|
|
|
|
|
|
process_becn(ppd, sl, rlid, lqpn, rqpn, svc_type);
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
struct ps_mdata {
|
|
@@ -596,7 +603,6 @@ static void __prescan_rxq(struct hfi1_packet *packet)
|
|
|
struct rvt_qp *qp;
|
|
|
struct hfi1_ib_header *hdr;
|
|
|
struct hfi1_other_headers *ohdr;
|
|
|
- struct ib_grh *grh = NULL;
|
|
|
struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
|
|
|
u64 rhf = rhf_to_cpu(rhf_addr);
|
|
|
u32 etype = rhf_rcv_type(rhf), qpn, bth1;
|
|
@@ -616,14 +622,13 @@ static void __prescan_rxq(struct hfi1_packet *packet)
|
|
|
hfi1_get_msgheader(dd, rhf_addr);
|
|
|
lnh = be16_to_cpu(hdr->lrh[0]) & 3;
|
|
|
|
|
|
- if (lnh == HFI1_LRH_BTH) {
|
|
|
+ if (lnh == HFI1_LRH_BTH)
|
|
|
ohdr = &hdr->u.oth;
|
|
|
- } else if (lnh == HFI1_LRH_GRH) {
|
|
|
+ else if (lnh == HFI1_LRH_GRH)
|
|
|
ohdr = &hdr->u.l.oth;
|
|
|
- grh = &hdr->u.l.grh;
|
|
|
- } else {
|
|
|
+ else
|
|
|
goto next; /* just in case */
|
|
|
- }
|
|
|
+
|
|
|
bth1 = be32_to_cpu(ohdr->bth[1]);
|
|
|
is_ecn = !!(bth1 & (HFI1_FECN_SMASK | HFI1_BECN_SMASK));
|
|
|
|
|
@@ -639,7 +644,7 @@ static void __prescan_rxq(struct hfi1_packet *packet)
|
|
|
goto next;
|
|
|
}
|
|
|
|
|
|
- process_ecn(qp, hdr, ohdr, rhf, bth1, grh);
|
|
|
+ process_ecn(qp, packet, true);
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
/* turn off BECN, FECN */
|