IB/hfi1: Setup common IB fields in hfi1_packet struct
authorDon Hiatt <don.hiatt@intel.com>
Fri, 12 May 2017 16:20:20 +0000 (09:20 -0700)
committerDoug Ledford <dledford@redhat.com>
Tue, 27 Jun 2017 20:56:33 +0000 (16:56 -0400)
We move many common IB fields into the hfi1_packet structure and
set them up in a single function. This allows us to set the fields
in a single place and not deal with them throughout the driver.

Reviewed-by: Brian Welty <brian.welty@intel.com>
Reviewed-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Don Hiatt <don.hiatt@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/chip.h
drivers/infiniband/hw/hfi1/common.h
drivers/infiniband/hw/hfi1/driver.c
drivers/infiniband/hw/hfi1/hfi.h
drivers/infiniband/hw/hfi1/rc.c
drivers/infiniband/hw/hfi1/ruc.c
drivers/infiniband/hw/hfi1/uc.c
drivers/infiniband/hw/hfi1/ud.c
drivers/infiniband/hw/hfi1/verbs.c
drivers/infiniband/hw/hfi1/verbs.h

index 2ba00b89df6a046bba536cfe889c373d9063ced0..5dbee3c1bd453f0d15f14a459b31ef3b9ae5a138 100644 (file)
@@ -9810,15 +9810,6 @@ void hfi1_clear_tids(struct hfi1_ctxtdata *rcd)
                hfi1_put_tid(dd, i, PT_INVALID, 0, 0);
 }
 
-struct ib_header *hfi1_get_msgheader(
-       struct hfi1_devdata *dd, __le32 *rhf_addr)
-{
-       u32 offset = rhf_hdrq_offset(rhf_to_cpu(rhf_addr));
-
-       return (struct ib_header *)
-               (rhf_addr - dd->rhf_offset + offset);
-}
-
 static const char * const ib_cfg_name_strings[] = {
        "HFI1_IB_CFG_LIDLMC",
        "HFI1_IB_CFG_LWID_DG_ENB",
index cbe455d9ab8b65547849011b6e2e2ffd937ee0bb..0b4f418ba0ac4b120cbb5680f851ca7a5e63282a 100644 (file)
@@ -1347,8 +1347,6 @@ enum {
 u64 get_all_cpu_total(u64 __percpu *cntr);
 void hfi1_start_cleanup(struct hfi1_devdata *dd);
 void hfi1_clear_tids(struct hfi1_ctxtdata *rcd);
-struct ib_header *hfi1_get_msgheader(
-                               struct hfi1_devdata *dd, __le32 *rhf_addr);
 void hfi1_init_ctxt(struct send_context *sc);
 void hfi1_put_tid(struct hfi1_devdata *dd, u32 index,
                  u32 type, unsigned long pa, u16 order);
index 995d62c7f9a7d6f2d1c7c2a7b86f8044837e95fe..ba9ab971ced942352fd2ab27bba9ae97c275e81f 100644 (file)
@@ -325,6 +325,7 @@ struct diag_pkt {
 #define HFI1_LRH_BTH 0x0002      /* 1. word of IB LRH - next header: BTH */
 
 /* misc. */
+#define SC15_PACKET 0xF
 #define SIZE_OF_CRC 1
 
 #define LIM_MGMT_P_KEY       0x7FFF
index 0583479f2576ae67c57c651088a1a0fc720d27fb..2a1022e374a581c1eb8b0be874da024780524e35 100644 (file)
@@ -224,6 +224,20 @@ static inline void *get_egrbuf(const struct hfi1_ctxtdata *rcd, u64 rhf,
                        (offset * RCV_BUF_BLOCK_SIZE));
 }
 
+static inline void *hfi1_get_header(struct hfi1_devdata *dd,
+                                   __le32 *rhf_addr)
+{
+       u32 offset = rhf_hdrq_offset(rhf_to_cpu(rhf_addr));
+
+       return (void *)(rhf_addr - dd->rhf_offset + offset);
+}
+
+static inline struct ib_header *hfi1_get_msgheader(struct hfi1_devdata *dd,
+                                                  __le32 *rhf_addr)
+{
+       return (struct ib_header *)hfi1_get_header(dd, rhf_addr);
+}
+
 /*
  * Validate and encode the a given RcvArray Buffer size.
  * The function will check whether the given size falls within
@@ -249,7 +263,8 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
 {
        struct ib_header *rhdr = packet->hdr;
        u32 rte = rhf_rcv_type_err(packet->rhf);
-       int lnh = ib_get_lnh(rhdr);
+       u8 lnh = ib_get_lnh(rhdr);
+       bool has_grh = false;
        struct hfi1_ibport *ibp = rcd_to_iport(rcd);
        struct hfi1_devdata *dd = ppd->dd;
        struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
@@ -257,37 +272,42 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
        if (packet->rhf & (RHF_VCRC_ERR | RHF_ICRC_ERR))
                return;
 
+       if (lnh == HFI1_LRH_BTH) {
+               packet->ohdr = &rhdr->u.oth;
+       } else if (lnh == HFI1_LRH_GRH) {
+               has_grh = true;
+               packet->ohdr = &rhdr->u.l.oth;
+               packet->grh = &rhdr->u.l.grh;
+       } else {
+               goto drop;
+       }
+
        if (packet->rhf & RHF_TID_ERR) {
                /* For TIDERR and RC QPs preemptively schedule a NAK */
-               struct ib_other_headers *ohdr = NULL;
                u32 tlen = rhf_pkt_len(packet->rhf); /* in bytes */
-               u16 lid  = ib_get_dlid(rhdr);
+               u32 dlid = ib_get_dlid(rhdr);
                u32 qp_num;
-               u32 rcv_flags = 0;
+               u32 mlid_base = be16_to_cpu(IB_MULTICAST_LID_BASE);
 
                /* Sanity check packet */
                if (tlen < 24)
                        goto drop;
 
                /* Check for GRH */
-               if (lnh == HFI1_LRH_BTH) {
-                       ohdr = &rhdr->u.oth;
-               } else if (lnh == HFI1_LRH_GRH) {
+               if (has_grh) {
                        u32 vtf;
+                       struct ib_grh *grh = packet->grh;
 
-                       ohdr = &rhdr->u.l.oth;
-                       if (rhdr->u.l.grh.next_hdr != IB_GRH_NEXT_HDR)
+                       if (grh->next_hdr != IB_GRH_NEXT_HDR)
                                goto drop;
-                       vtf = be32_to_cpu(rhdr->u.l.grh.version_tclass_flow);
+                       vtf = be32_to_cpu(grh->version_tclass_flow);
                        if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
                                goto drop;
-                       rcv_flags |= HFI1_HAS_GRH;
-               } else {
-                       goto drop;
                }
+
                /* Get the destination QP number. */
-               qp_num = ib_bth_get_qpn(ohdr);
-               if (lid < be16_to_cpu(IB_MULTICAST_LID_BASE)) {
+               qp_num = ib_bth_get_qpn(packet->ohdr);
+               if (dlid < mlid_base) {
                        struct rvt_qp *qp;
                        unsigned long flags;
 
@@ -312,11 +332,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
 
                        switch (qp->ibqp.qp_type) {
                        case IB_QPT_RC:
-                               hfi1_rc_hdrerr(
-                                       rcd,
-                                       rhdr,
-                                       rcv_flags,
-                                       qp);
+                               hfi1_rc_hdrerr(rcd, packet, qp);
                                break;
                        default:
                                /* For now don't handle any other QP types */
@@ -332,9 +348,8 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
        switch (rte) {
        case RHF_RTE_ERROR_OP_CODE_ERR:
        {
-               u32 opcode;
                void *ebuf = NULL;
-               __be32 *bth = NULL;
+               u8 opcode;
 
                if (rhf_use_egr_bfr(packet->rhf))
                        ebuf = packet->ebuf;
@@ -342,16 +357,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
                if (!ebuf)
                        goto drop; /* this should never happen */
 
-               if (lnh == HFI1_LRH_BTH)
-                       bth = (__be32 *)ebuf;
-               else if (lnh == HFI1_LRH_GRH)
-                       bth = (__be32 *)((char *)ebuf + sizeof(struct ib_grh));
-               else
-                       goto drop;
-
-               opcode = be32_to_cpu(bth[0]) >> 24;
-               opcode &= 0xff;
-
+               opcode = ib_bth_get_opcode(packet->ohdr);
                if (opcode == IB_OPCODE_CNP) {
                        /*
                         * Only in pre-B0 h/w is the CNP_OPCODE handled
@@ -365,7 +371,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
                        sc5 = hfi1_9B_get_sc5(rhdr, packet->rhf);
                        sl = ibp->sc_to_sl[sc5];
 
-                       lqpn = be32_to_cpu(bth[1]) & RVT_QPN_MASK;
+                       lqpn = ib_bth_get_qpn(packet->ohdr);
                        rcu_read_lock();
                        qp = rvt_lookup_qpn(rdi, &ibp->rvp, lqpn);
                        if (!qp) {
@@ -415,7 +421,6 @@ static inline void init_packet(struct hfi1_ctxtdata *rcd,
        packet->rhf = rhf_to_cpu(packet->rhf_addr);
        packet->rhqoff = rcd->head;
        packet->numpkt = 0;
-       packet->rcv_flags = 0;
 }
 
 void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
@@ -424,15 +429,12 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
        struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
        struct ib_header *hdr = pkt->hdr;
        struct ib_other_headers *ohdr = pkt->ohdr;
-       struct ib_grh *grh = NULL;
+       struct ib_grh *grh = pkt->grh;
        u32 rqpn = 0, bth1;
        u16 rlid, dlid = ib_get_dlid(hdr);
        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:
        case IB_QPT_GSI:
@@ -591,9 +593,10 @@ static void __prescan_rxq(struct hfi1_packet *packet)
 
                if (lnh == HFI1_LRH_BTH) {
                        packet->ohdr = &hdr->u.oth;
+                       packet->grh = NULL;
                } else if (lnh == HFI1_LRH_GRH) {
                        packet->ohdr = &hdr->u.l.oth;
-                       packet->rcv_flags |= HFI1_HAS_GRH;
+                       packet->grh = &hdr->u.l.grh;
                } else {
                        goto next; /* just in case */
                }
@@ -698,10 +701,9 @@ static inline int process_rcv_packet(struct hfi1_packet *packet, int thread)
 {
        int ret;
 
-       packet->hdr = hfi1_get_msgheader(packet->rcd->dd,
-                                        packet->rhf_addr);
-       packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
        packet->etype = rhf_rcv_type(packet->rhf);
+
+       packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
        /* total length */
        packet->tlen = rhf_pkt_len(packet->rhf); /* in bytes */
        /* retrieve eager buffer details */
@@ -759,7 +761,7 @@ static inline void process_rcv_update(int last, struct hfi1_packet *packet)
                               packet->etail, 0, 0);
                packet->updegr = 0;
        }
-       packet->rcv_flags = 0;
+       packet->grh = NULL;
 }
 
 static inline void finish_packet(struct hfi1_packet *packet)
@@ -896,12 +898,15 @@ static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd,
                                      struct hfi1_devdata *dd)
 {
        struct work_struct *lsaw = &rcd->ppd->linkstate_active_work;
-       struct ib_header *hdr = hfi1_get_msgheader(packet->rcd->dd,
-                                                  packet->rhf_addr);
        u8 etype = rhf_rcv_type(packet->rhf);
+       u8 sc = SC15_PACKET;
 
-       if (etype == RHF_RCV_TYPE_IB &&
-           hfi1_9B_get_sc5(hdr, packet->rhf) != 0xf) {
+       if (etype == RHF_RCV_TYPE_IB) {
+               struct ib_header *hdr = hfi1_get_msgheader(packet->rcd->dd,
+                                                          packet->rhf_addr);
+               sc = hfi1_9B_get_sc5(hdr, packet->rhf);
+       }
+       if (sc != SC15_PACKET) {
                int hwstate = read_logical_state(dd);
 
                if (hwstate != LSTATE_ACTIVE) {
@@ -1321,6 +1326,58 @@ bail:
        return ret;
 }
 
+static inline void hfi1_setup_ib_header(struct hfi1_packet *packet)
+{
+       packet->hdr = (struct hfi1_ib_message_header *)
+                       hfi1_get_msgheader(packet->rcd->dd,
+                                          packet->rhf_addr);
+       packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
+}
+
+static int hfi1_setup_9B_packet(struct hfi1_packet *packet)
+{
+       struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
+       struct ib_header *hdr;
+       u8 lnh;
+
+       hfi1_setup_ib_header(packet);
+       hdr = packet->hdr;
+
+       lnh = ib_get_lnh(hdr);
+       if (lnh == HFI1_LRH_BTH) {
+               packet->ohdr = &hdr->u.oth;
+               packet->grh = NULL;
+       } else if (lnh == HFI1_LRH_GRH) {
+               u32 vtf;
+
+               packet->ohdr = &hdr->u.l.oth;
+               packet->grh = &hdr->u.l.grh;
+               if (packet->grh->next_hdr != IB_GRH_NEXT_HDR)
+                       goto drop;
+               vtf = be32_to_cpu(packet->grh->version_tclass_flow);
+               if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
+                       goto drop;
+       } else {
+               goto drop;
+       }
+
+       /* Query commonly used fields from packet header */
+       packet->opcode = ib_bth_get_opcode(packet->ohdr);
+       packet->slid = ib_get_slid(hdr);
+       packet->dlid = ib_get_dlid(hdr);
+       packet->sl = ib_get_sl(hdr);
+       packet->sc = hfi1_9B_get_sc5(hdr, packet->rhf);
+       packet->pad = ib_bth_get_pad(packet->ohdr);
+       packet->extra_byte = 0;
+       packet->fecn = ib_bth_get_fecn(packet->ohdr);
+       packet->becn = ib_bth_get_becn(packet->ohdr);
+
+       return 0;
+drop:
+       ibp->rvp.n_pkt_drops++;
+       return -EINVAL;
+}
+
 void handle_eflags(struct hfi1_packet *packet)
 {
        struct hfi1_ctxtdata *rcd = packet->rcd;
@@ -1351,6 +1408,9 @@ int process_receive_ib(struct hfi1_packet *packet)
        if (unlikely(hfi1_dbg_fault_packet(packet)))
                return RHF_RCV_CONTINUE;
 
+       if (hfi1_setup_9B_packet(packet))
+               return RHF_RCV_CONTINUE;
+
        trace_hfi1_rcvhdr(packet->rcd->ppd->dd,
                          packet->rcd->ctxt,
                          rhf_err_flags(packet->rhf),
@@ -1422,6 +1482,7 @@ int process_receive_error(struct hfi1_packet *packet)
                 rhf_rcv_type_err(packet->rhf) == 3))
                return RHF_RCV_CONTINUE;
 
+       hfi1_setup_ib_header(packet);
        handle_eflags(packet);
 
        if (unlikely(rhf_err_flags(packet->rhf)))
@@ -1435,6 +1496,8 @@ int kdeth_process_expected(struct hfi1_packet *packet)
 {
        if (unlikely(hfi1_dbg_fault_packet(packet)))
                return RHF_RCV_CONTINUE;
+
+       hfi1_setup_ib_header(packet);
        if (unlikely(rhf_err_flags(packet->rhf)))
                handle_eflags(packet);
 
@@ -1445,6 +1508,7 @@ int kdeth_process_expected(struct hfi1_packet *packet)
 
 int kdeth_process_eager(struct hfi1_packet *packet)
 {
+       hfi1_setup_ib_header(packet);
        if (unlikely(rhf_err_flags(packet->rhf)))
                handle_eflags(packet);
        if (unlikely(hfi1_dbg_fault_packet(packet)))
index 3b76631cbcbd56358990da318d5cccdfe479d6e8..9c6c7344846158c1e6df80c866329f9e09e7aade 100644 (file)
@@ -356,17 +356,26 @@ struct hfi1_packet {
        __le32 *rhf_addr;
        struct rvt_qp *qp;
        struct ib_other_headers *ohdr;
+       struct ib_grh *grh;
        u64 rhf;
        u32 maxcnt;
        u32 rhqoff;
+       u32 dlid;
+       u32 slid;
        u16 tlen;
        s16 etail;
        u8 hlen;
        u8 numpkt;
        u8 rsize;
        u8 updegr;
-       u8 rcv_flags;
        u8 etype;
+       u8 extra_byte;
+       u8 pad;
+       u8 sc;
+       u8 sl;
+       u8 opcode;
+       bool becn;
+       bool fecn;
 };
 
 struct rvt_sge_state;
@@ -2086,4 +2095,14 @@ int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp);
 
 #define DD_DEV_ENTRY(dd)       __string(dev, dev_name(&(dd)->pcidev->dev))
 #define DD_DEV_ASSIGN(dd)      __assign_str(dev, dev_name(&(dd)->pcidev->dev))
+
+/*
+ * hfi1_check_mcast- Check if the given lid is
+ * in the IB multicast range.
+ */
+static inline bool hfi1_check_mcast(u16 lid)
+{
+       return ((lid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
+               (lid != be16_to_cpu(IB_LID_PERMISSIVE)));
+}
 #endif                          /* _HFI1_KERNEL_H */
index b443c1e0154357c664032fcd7940588c23edfa94..baa67bf0772b297667d5caf7f31873133c073d19 100644 (file)
@@ -1916,17 +1916,16 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
 void hfi1_rc_rcv(struct hfi1_packet *packet)
 {
        struct hfi1_ctxtdata *rcd = packet->rcd;
-       struct ib_header *hdr = packet->hdr;
-       u32 rcv_flags = packet->rcv_flags;
        void *data = packet->ebuf;
        u32 tlen = packet->tlen;
        struct rvt_qp *qp = packet->qp;
        struct hfi1_ibport *ibp = rcd_to_iport(rcd);
        struct ib_other_headers *ohdr = packet->ohdr;
-       u32 bth0, opcode;
+       u32 bth0;
+       u32 opcode = packet->opcode;
        u32 hdrsize = packet->hlen;
        u32 psn;
-       u32 pad;
+       u32 pad = packet->pad;
        struct ib_wc wc;
        u32 pmtu = qp->pmtu;
        int diff;
@@ -1938,14 +1937,13 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
        u32 rkey;
 
        lockdep_assert_held(&qp->r_lock);
+
        bth0 = be32_to_cpu(ohdr->bth[0]);
-       if (hfi1_ruc_check_hdr(ibp, hdr, rcv_flags & HFI1_HAS_GRH, qp, bth0))
+       if (hfi1_ruc_check_hdr(ibp, packet))
                return;
 
        is_fecn = process_ecn(qp, packet, false);
-
        psn = ib_bth_get_psn(ohdr);
-       opcode = ib_bth_get_opcode(ohdr);
 
        /*
         * Process responses (ACKs) before anything else.  Note that the
@@ -2075,8 +2073,6 @@ no_immediate_data:
                wc.wc_flags = 0;
                wc.ex.imm_data = 0;
 send_last:
-               /* Get the number of bytes the message was padded by. */
-               pad = ib_bth_get_pad(ohdr);
                /* Check for invalid length. */
                /* LAST len should be >= 1 */
                if (unlikely(tlen < (hdrsize + pad + 4)))
@@ -2369,28 +2365,19 @@ send_ack:
 
 void hfi1_rc_hdrerr(
        struct hfi1_ctxtdata *rcd,
-       struct ib_header *hdr,
-       u32 rcv_flags,
+       struct hfi1_packet *packet,
        struct rvt_qp *qp)
 {
-       int has_grh = rcv_flags & HFI1_HAS_GRH;
-       struct ib_other_headers *ohdr;
        struct hfi1_ibport *ibp = rcd_to_iport(rcd);
        int diff;
        u32 opcode;
-       u32 psn, bth0;
-
-       /* Check for GRH */
-       ohdr = &hdr->u.oth;
-       if (has_grh)
-               ohdr = &hdr->u.l.oth;
+       u32 psn;
 
-       bth0 = be32_to_cpu(ohdr->bth[0]);
-       if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0))
+       if (hfi1_ruc_check_hdr(ibp, packet))
                return;
 
-       psn = ib_bth_get_psn(ohdr);
-       opcode = ib_bth_get_opcode(ohdr);
+       psn = ib_bth_get_psn(packet->ohdr);
+       opcode = ib_bth_get_opcode(packet->ohdr);
 
        /* Only deal with RDMA Writes for now */
        if (opcode < IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST) {
index 3a17daba28a935535904ed3596e9745a9f6c763b..9cc9c7be9dd4bea7b4d3ca8db7a4ab264d42d736 100644 (file)
@@ -214,100 +214,95 @@ static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
  *
  * The s_lock will be acquired around the hfi1_migrate_qp() call.
  */
-int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct ib_header *hdr,
-                      int has_grh, struct rvt_qp *qp, u32 bth0)
+int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet)
 {
        __be64 guid;
        unsigned long flags;
+       struct rvt_qp *qp = packet->qp;
        u8 sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&qp->remote_ah_attr)];
-
-       if (qp->s_mig_state == IB_MIG_ARMED && (bth0 & IB_BTH_MIG_REQ)) {
-               if (!has_grh) {
+       u32 dlid = packet->dlid;
+       u32 slid = packet->slid;
+       u32 sl = packet->sl;
+       int migrated;
+       u32 bth0, bth1;
+
+       bth0 = be32_to_cpu(packet->ohdr->bth[0]);
+       bth1 = be32_to_cpu(packet->ohdr->bth[1]);
+       migrated = bth0 & IB_BTH_MIG_REQ;
+
+       if (qp->s_mig_state == IB_MIG_ARMED && migrated) {
+               if (!packet->grh) {
                        if (rdma_ah_get_ah_flags(&qp->alt_ah_attr) &
                            IB_AH_GRH)
-                               goto err;
+                               return 1;
                } else {
                        const struct ib_global_route *grh;
 
                        if (!(rdma_ah_get_ah_flags(&qp->alt_ah_attr) &
                              IB_AH_GRH))
-                               goto err;
+                               return 1;
                        grh = rdma_ah_read_grh(&qp->alt_ah_attr);
                        guid = get_sguid(ibp, grh->sgid_index);
-                       if (!gid_ok(&hdr->u.l.grh.dgid, ibp->rvp.gid_prefix,
+                       if (!gid_ok(&packet->grh->dgid, ibp->rvp.gid_prefix,
                                    guid))
-                               goto err;
+                               return 1;
                        if (!gid_ok(
-                               &hdr->u.l.grh.sgid,
+                               &packet->grh->sgid,
                                grh->dgid.global.subnet_prefix,
                                grh->dgid.global.interface_id))
-                               goto err;
+                               return 1;
                }
-               if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5,
-                                           ib_get_slid(hdr)))) {
-                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
-                                      (u16)bth0,
-                                      ib_get_sl(hdr),
-                                      0, qp->ibqp.qp_num,
-                                      ib_get_slid(hdr),
-                                      ib_get_dlid(hdr));
-                       goto err;
+               if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0,
+                                           sc5, slid))) {
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, (u16)bth0, sl,
+                                      0, qp->ibqp.qp_num, slid, dlid);
+                       return 1;
                }
                /* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
-               if (ib_get_slid(hdr) !=
-                       rdma_ah_get_dlid(&qp->alt_ah_attr) ||
+               if (slid != rdma_ah_get_dlid(&qp->alt_ah_attr) ||
                    ppd_from_ibp(ibp)->port !=
                        rdma_ah_get_port_num(&qp->alt_ah_attr))
-                       goto err;
+                       return 1;
                spin_lock_irqsave(&qp->s_lock, flags);
                hfi1_migrate_qp(qp);
                spin_unlock_irqrestore(&qp->s_lock, flags);
        } else {
-               if (!has_grh) {
+               if (!packet->grh) {
                        if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) &
                                                 IB_AH_GRH)
-                               goto err;
+                               return 1;
                } else {
                        const struct ib_global_route *grh;
 
                        if (!(rdma_ah_get_ah_flags(&qp->remote_ah_attr) &
                                                   IB_AH_GRH))
-                               goto err;
+                               return 1;
                        grh = rdma_ah_read_grh(&qp->remote_ah_attr);
                        guid = get_sguid(ibp, grh->sgid_index);
-                       if (!gid_ok(&hdr->u.l.grh.dgid, ibp->rvp.gid_prefix,
+                       if (!gid_ok(&packet->grh->dgid, ibp->rvp.gid_prefix,
                                    guid))
-                               goto err;
+                               return 1;
                        if (!gid_ok(
-                            &hdr->u.l.grh.sgid,
+                            &packet->grh->sgid,
                             grh->dgid.global.subnet_prefix,
                             grh->dgid.global.interface_id))
-                               goto err;
+                               return 1;
                }
-               if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5,
-                                           ib_get_slid(hdr)))) {
-                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
-                                      (u16)bth0,
-                                      ib_get_sl(hdr),
-                                      0, qp->ibqp.qp_num,
-                                      ib_get_slid(hdr),
-                                      ib_get_dlid(hdr));
-                       goto err;
+               if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0,
+                                           sc5, slid))) {
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, (u16)bth0, sl,
+                                      0, qp->ibqp.qp_num, slid, dlid);
+                       return 1;
                }
                /* Validate the SLID. See Ch. 9.6.1.5 */
-               if (ib_get_slid(hdr) !=
-                       rdma_ah_get_dlid(&qp->remote_ah_attr) ||
+               if ((slid != rdma_ah_get_dlid(&qp->remote_ah_attr)) ||
                    ppd_from_ibp(ibp)->port != qp->port_num)
-                       goto err;
-               if (qp->s_mig_state == IB_MIG_REARM &&
-                   !(bth0 & IB_BTH_MIG_REQ))
+                       return 1;
+               if (qp->s_mig_state == IB_MIG_REARM && !migrated)
                        qp->s_mig_state = IB_MIG_ARMED;
        }
 
        return 0;
-
-err:
-       return 1;
 }
 
 /**
index 2a5650f8aee00c63bc322d1bf53618b12861c988..76c2451a53d7b72ef7ef3963049da388c0444348 100644 (file)
@@ -297,31 +297,25 @@ bail_no_tx:
 void hfi1_uc_rcv(struct hfi1_packet *packet)
 {
        struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
-       struct ib_header *hdr = packet->hdr;
-       u32 rcv_flags = packet->rcv_flags;
        void *data = packet->ebuf;
        u32 tlen = packet->tlen;
        struct rvt_qp *qp = packet->qp;
        struct ib_other_headers *ohdr = packet->ohdr;
-       u32 bth0, opcode;
+       u32 opcode = packet->opcode;
        u32 hdrsize = packet->hlen;
        u32 psn;
-       u32 pad;
+       u32 pad = packet->pad;
        struct ib_wc wc;
        u32 pmtu = qp->pmtu;
        struct ib_reth *reth;
-       int has_grh = rcv_flags & HFI1_HAS_GRH;
        int ret;
 
-       bth0 = be32_to_cpu(ohdr->bth[0]);
-       if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0))
+       if (hfi1_ruc_check_hdr(ibp, packet))
                return;
 
        process_ecn(qp, packet, true);
 
        psn = ib_bth_get_psn(ohdr);
-       opcode = ib_bth_get_opcode(ohdr);
-
        /* Compare the PSN verses the expected PSN. */
        if (unlikely(cmp_psn(psn, qp->r_psn) != 0)) {
                /*
@@ -432,8 +426,6 @@ no_immediate_data:
                wc.ex.imm_data = 0;
                wc.wc_flags = 0;
 send_last:
-               /* Get the number of bytes the message was padded by. */
-               pad = ib_bth_get_pad(ohdr);
                /* Check for invalid length. */
                /* LAST len should be >= 1 */
                if (unlikely(tlen < (hdrsize + pad + 4)))
@@ -527,8 +519,6 @@ rdma_first:
 rdma_last_imm:
                wc.wc_flags = IB_WC_WITH_IMM;
 
-               /* Get the number of bytes the message was padded by. */
-               pad = ib_bth_get_pad(ohdr);
                /* Check for invalid length. */
                /* LAST len should be >= 1 */
                if (unlikely(tlen < (hdrsize + pad + 4)))
index 49fe179ad3ae200acc8f63d373937d22fc8a65bb..c995aa58c36a2425a34656bf3e6b2fb0e8f93c47 100644 (file)
@@ -668,36 +668,31 @@ static int opa_smp_check(struct hfi1_ibport *ibp, u16 pkey, u8 sc5,
 void hfi1_ud_rcv(struct hfi1_packet *packet)
 {
        struct ib_other_headers *ohdr = packet->ohdr;
-       int opcode;
        u32 hdrsize = packet->hlen;
        struct ib_wc wc;
        u32 qkey;
        u32 src_qp;
-       u16 dlid, pkey;
+       u16 pkey;
        int mgmt_pkey_idx = -1;
        struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
        struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
        struct ib_header *hdr = packet->hdr;
-       u32 rcv_flags = packet->rcv_flags;
        void *data = packet->ebuf;
        u32 tlen = packet->tlen;
        struct rvt_qp *qp = packet->qp;
-       bool has_grh = rcv_flags & HFI1_HAS_GRH;
        u8 sc5 = hfi1_9B_get_sc5(hdr, packet->rhf);
        u32 bth1;
-       u8 sl_from_sc, sl;
-       u16 slid;
-       u8 extra_bytes;
+       u8 sl_from_sc;
+       u8 extra_bytes = packet->pad;
+       u8 opcode = packet->opcode;
+       u8 sl = packet->sl;
+       u32 dlid = packet->dlid;
+       u32 slid = packet->slid;
 
+       bth1 = be32_to_cpu(ohdr->bth[1]);
        qkey = ib_get_qkey(ohdr);
        src_qp = ib_get_sqpn(ohdr);
-       dlid = ib_get_dlid(hdr);
-       bth1 = be32_to_cpu(ohdr->bth[1]);
-       slid = ib_get_slid(hdr);
        pkey = ib_bth_get_pkey(ohdr);
-       opcode = ib_bth_get_opcode(ohdr);
-       sl = ib_get_sl(hdr);
-       extra_bytes = ib_bth_get_pad(ohdr);
        extra_bytes += (SIZE_OF_CRC << 2);
        sl_from_sc = ibp->sc_to_sl[sc5];
 
@@ -811,7 +806,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
                qp->r_flags |= RVT_R_REUSE_SGE;
                goto drop;
        }
-       if (has_grh) {
+       if (packet->grh) {
                hfi1_copy_sge(&qp->r_sge, &hdr->u.l.grh,
                              sizeof(struct ib_grh), true, false);
                wc.wc_flags |= IB_WC_GRH;
index 5f4be35f31b6dc68ea70275e693babba2ff0ea21..af54d3f4696aa2cc70ec29e67c3a1116e88c709c 100644 (file)
@@ -508,13 +508,14 @@ again:
 /*
  * Make sure the QP is ready and able to accept the given opcode.
  */
-static inline opcode_handler qp_ok(int opcode, struct hfi1_packet *packet)
+static inline opcode_handler qp_ok(struct hfi1_packet *packet)
 {
        if (!(ib_rvt_state_ops[packet->qp->state] & RVT_PROCESS_RECV_OK))
                return NULL;
-       if (((opcode & RVT_OPCODE_QP_MASK) == packet->qp->allowed_ops) ||
-           (opcode == IB_OPCODE_CNP))
-               return opcode_handler_tbl[opcode];
+       if (((packet->opcode & RVT_OPCODE_QP_MASK) ==
+            packet->qp->allowed_ops) ||
+           (packet->opcode == IB_OPCODE_CNP))
+               return opcode_handler_tbl[packet->opcode];
 
        return NULL;
 }
@@ -548,68 +549,34 @@ static u64 hfi1_fault_tx(struct rvt_qp *qp, u8 opcode, u64 pbc)
        return pbc;
 }
 
-/**
- * hfi1_ib_rcv - process an incoming packet
- * @packet: data packet information
- *
- * This is called to process an incoming packet at interrupt level.
- *
- * Tlen is the length of the header + data + CRC in bytes.
- */
-void hfi1_ib_rcv(struct hfi1_packet *packet)
+static inline void hfi1_handle_packet(struct hfi1_packet *packet,
+                                     bool is_mcast)
 {
+       u32 qp_num;
        struct hfi1_ctxtdata *rcd = packet->rcd;
-       struct ib_header *hdr = packet->hdr;
-       u32 tlen = packet->tlen;
        struct hfi1_pportdata *ppd = rcd->ppd;
        struct hfi1_ibport *ibp = rcd_to_iport(rcd);
        struct rvt_dev_info *rdi = &ppd->dd->verbs_dev.rdi;
        opcode_handler packet_handler;
        unsigned long flags;
-       u32 qp_num;
-       int lnh;
-       u8 opcode;
-       u16 lid;
-
-       /* Check for GRH */
-       lnh = ib_get_lnh(hdr);
-       if (lnh == HFI1_LRH_BTH) {
-               packet->ohdr = &hdr->u.oth;
-       } else if (lnh == HFI1_LRH_GRH) {
-               u32 vtf;
-
-               packet->ohdr = &hdr->u.l.oth;
-               if (hdr->u.l.grh.next_hdr != IB_GRH_NEXT_HDR)
-                       goto drop;
-               vtf = be32_to_cpu(hdr->u.l.grh.version_tclass_flow);
-               if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
-                       goto drop;
-               packet->rcv_flags |= HFI1_HAS_GRH;
-       } else {
-               goto drop;
-       }
 
-       trace_input_ibhdr(rcd->dd, packet, !!(packet->rhf & RHF_DC_INFO_SMASK));
-       opcode = ib_bth_get_opcode(packet->ohdr);
-       inc_opstats(tlen, &rcd->opstats->stats[opcode]);
+       inc_opstats(packet->tlen, &rcd->opstats->stats[packet->opcode]);
 
-       /* Get the destination QP number. */
-       qp_num = ib_bth_get_qpn(packet->ohdr);
-       lid = ib_get_dlid(hdr);
-       if (unlikely((lid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
-                    (lid != be16_to_cpu(IB_LID_PERMISSIVE)))) {
+       if (unlikely(is_mcast)) {
                struct rvt_mcast *mcast;
                struct rvt_mcast_qp *p;
 
-               if (lnh != HFI1_LRH_GRH)
+               if (!packet->grh)
                        goto drop;
-               mcast = rvt_mcast_find(&ibp->rvp, &hdr->u.l.grh.dgid, lid);
+               mcast = rvt_mcast_find(&ibp->rvp,
+                                      &packet->grh->dgid,
+                                      packet->dlid);
                if (!mcast)
                        goto drop;
                list_for_each_entry_rcu(p, &mcast->qp_list, list) {
                        packet->qp = p->qp;
                        spin_lock_irqsave(&packet->qp->r_lock, flags);
-                       packet_handler = qp_ok(opcode, packet);
+                       packet_handler = qp_ok(packet);
                        if (likely(packet_handler))
                                packet_handler(packet);
                        else
@@ -623,19 +590,21 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)
                if (atomic_dec_return(&mcast->refcount) <= 1)
                        wake_up(&mcast->wait);
        } else {
+               /* Get the destination QP number. */
+               qp_num = ib_bth_get_qpn(packet->ohdr);
                rcu_read_lock();
                packet->qp = rvt_lookup_qpn(rdi, &ibp->rvp, qp_num);
                if (!packet->qp) {
                        rcu_read_unlock();
                        goto drop;
                }
-               if (unlikely(hfi1_dbg_fault_opcode(packet->qp, opcode,
+               if (unlikely(hfi1_dbg_fault_opcode(packet->qp, packet->opcode,
                                                   true))) {
                        rcu_read_unlock();
                        goto drop;
                }
                spin_lock_irqsave(&packet->qp->r_lock, flags);
-               packet_handler = qp_ok(opcode, packet);
+               packet_handler = qp_ok(packet);
                if (likely(packet_handler))
                        packet_handler(packet);
                else
@@ -644,11 +613,29 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)
                rcu_read_unlock();
        }
        return;
-
 drop:
        ibp->rvp.n_pkt_drops++;
 }
 
+/**
+ * hfi1_ib_rcv - process an incoming packet
+ * @packet: data packet information
+ *
+ * This is called to process an incoming packet at interrupt level.
+ */
+void hfi1_ib_rcv(struct hfi1_packet *packet)
+{
+       struct hfi1_ctxtdata *rcd = packet->rcd;
+       bool is_mcast = false;
+
+       if (unlikely(hfi1_check_mcast(packet->dlid)))
+               is_mcast = true;
+
+       trace_input_ibhdr(rcd->dd, packet,
+                         !!(packet->rhf & RHF_DC_INFO_SMASK));
+       hfi1_handle_packet(packet, is_mcast);
+}
+
 /*
  * This is called from a timer to check for QPs
  * which need kernel memory in order to send a packet.
index cd635d0c1d3b32eb8fbd3a0303e03f532eca4a09..17b38cd5f654576b9e32e6d92ca465175074cc03 100644 (file)
@@ -307,8 +307,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet);
 
 void hfi1_rc_hdrerr(
        struct hfi1_ctxtdata *rcd,
-       struct ib_header *hdr,
-       u32 rcv_flags,
+       struct hfi1_packet *packet,
        struct rvt_qp *qp);
 
 u8 ah_to_sc(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr);
@@ -346,8 +345,7 @@ static inline u8 get_opcode(struct ib_header *h)
                return be32_to_cpu(h->u.l.oth.bth[0]) >> 24;
 }
 
-int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct ib_header *hdr,
-                      int has_grh, struct rvt_qp *qp, u32 bth0);
+int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet);
 
 u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,
                  const struct ib_global_route *grh, u32 hwords, u32 nwords);