// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright(c) 2015 - 2018 Intel Corporation. */ #include <linux/spinlock.h> #include "hfi.h" #include "mad.h" #include "qp.h" #include "verbs_txreq.h" #include "trace.h" static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id) { … } /* * * This should be called with the QP r_lock held. * * The s_lock will be acquired around the hfi1_migrate_qp() call. */ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet) { … } /** * hfi1_make_grh - construct a GRH header * @ibp: a pointer to the IB port * @hdr: a pointer to the GRH header being constructed * @grh: the global route address to send to * @hwords: size of header after grh being sent in dwords * @nwords: the number of 32 bit words of data being sent * * Return the size of the header in 32 bit words. */ u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr, const struct ib_global_route *grh, u32 hwords, u32 nwords) { … } #define BTH2_OFFSET … /** * build_ahg - create ahg in s_ahg * @qp: a pointer to QP * @npsn: the next PSN for the request/response * * This routine handles the AHG by allocating an ahg entry and causing the * copy of the first middle. * * Subsequent middles use the copied entry, editing the * PSN with 1 or 2 edits. */ static inline void build_ahg(struct rvt_qp *qp, u32 npsn) { … } static inline void hfi1_make_ruc_bth(struct rvt_qp *qp, struct ib_other_headers *ohdr, u32 bth0, u32 bth1, u32 bth2) { … } /** * hfi1_make_ruc_header_16B - build a 16B header * @qp: the queue pair * @ohdr: a pointer to the destination header memory * @bth0: bth0 passed in from the RC/UC builder * @bth1: bth1 passed in from the RC/UC builder * @bth2: bth2 passed in from the RC/UC builder * @middle: non zero implies indicates ahg "could" be used * @ps: the current packet state * * This routine may disarm ahg under these situations: * - packet needs a GRH * - BECN needed * - migration state not IB_MIG_MIGRATED */ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, struct ib_other_headers *ohdr, u32 bth0, u32 bth1, u32 bth2, int middle, struct hfi1_pkt_state *ps) { … } /** * hfi1_make_ruc_header_9B - build a 9B header * @qp: the queue pair * @ohdr: a pointer to the destination header memory * @bth0: bth0 passed in from the RC/UC builder * @bth1: bth1 passed in from the RC/UC builder * @bth2: bth2 passed in from the RC/UC builder * @middle: non zero implies indicates ahg "could" be used * @ps: the current packet state * * This routine may disarm ahg under these situations: * - packet needs a GRH * - BECN needed * - migration state not IB_MIG_MIGRATED */ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, struct ib_other_headers *ohdr, u32 bth0, u32 bth1, u32 bth2, int middle, struct hfi1_pkt_state *ps) { … } hfi1_make_ruc_hdr; /* We support only two types - 9B and 16B for now */ static const hfi1_make_ruc_hdr hfi1_ruc_header_tbl[2] = …; void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr, u32 bth0, u32 bth1, u32 bth2, int middle, struct hfi1_pkt_state *ps) { … } /* when sending, force a reschedule every one of these periods */ #define SEND_RESCHED_TIMEOUT … /** * hfi1_schedule_send_yield - test for a yield required for QP * send engine * @qp: a pointer to QP * @ps: a pointer to a structure with commonly lookup values for * the send engine progress * @tid: true if it is the tid leg * * This routine checks if the time slice for the QP has expired * for RC QPs, if so an additional work entry is queued. At this * point, other QPs have an opportunity to be scheduled. It * returns true if a yield is required, otherwise, false * is returned. */ bool hfi1_schedule_send_yield(struct rvt_qp *qp, struct hfi1_pkt_state *ps, bool tid) { … } void hfi1_do_send_from_rvt(struct rvt_qp *qp) { … } void _hfi1_do_send(struct work_struct *work) { … } /** * hfi1_do_send - perform a send on a QP * @qp: a pointer to the QP * @in_thread: true if in a workqueue thread * * Process entries in the send work queue until credit or queue is * exhausted. Only allow one CPU to send a packet per QP. * Otherwise, two threads could send packets out of order. */ void hfi1_do_send(struct rvt_qp *qp, bool in_thread) { … }