Commit 9039746c authored by Don Hiatt's avatar Don Hiatt Committed by Doug Ledford

IB/hfi1: Setup common IB fields in hfi1_packet struct

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