|
@@ -50,8 +50,6 @@
|
|
|
#include "qp.h"
|
|
|
#include "trace.h"
|
|
|
|
|
|
-#define SC_CTXT_PACKET_EGRESS_TIMEOUT 350 /* in chip cycles */
|
|
|
-
|
|
|
#define SC(name) SEND_CTXT_##name
|
|
|
/*
|
|
|
* Send Context functions
|
|
@@ -961,15 +959,40 @@ void sc_disable(struct send_context *sc)
|
|
|
}
|
|
|
|
|
|
/* return SendEgressCtxtStatus.PacketOccupancy */
|
|
|
-#define packet_occupancy(r) \
|
|
|
- (((r) & SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_PACKET_OCCUPANCY_SMASK)\
|
|
|
- >> SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_PACKET_OCCUPANCY_SHIFT)
|
|
|
+static u64 packet_occupancy(u64 reg)
|
|
|
+{
|
|
|
+ return (reg &
|
|
|
+ SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_PACKET_OCCUPANCY_SMASK)
|
|
|
+ >> SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_PACKET_OCCUPANCY_SHIFT;
|
|
|
+}
|
|
|
|
|
|
/* is egress halted on the context? */
|
|
|
-#define egress_halted(r) \
|
|
|
- ((r) & SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_HALT_STATUS_SMASK)
|
|
|
+static bool egress_halted(u64 reg)
|
|
|
+{
|
|
|
+ return !!(reg & SEND_EGRESS_CTXT_STATUS_CTXT_EGRESS_HALT_STATUS_SMASK);
|
|
|
+}
|
|
|
|
|
|
-/* wait for packet egress, optionally pause for credit return */
|
|
|
+/* is the send context halted? */
|
|
|
+static bool is_sc_halted(struct hfi1_devdata *dd, u32 hw_context)
|
|
|
+{
|
|
|
+ return !!(read_kctxt_csr(dd, hw_context, SC(STATUS)) &
|
|
|
+ SC(STATUS_CTXT_HALTED_SMASK));
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * sc_wait_for_packet_egress
|
|
|
+ * @sc: valid send context
|
|
|
+ * @pause: wait for credit return
|
|
|
+ *
|
|
|
+ * Wait for packet egress, optionally pause for credit return
|
|
|
+ *
|
|
|
+ * Egress halt and Context halt are not necessarily the same thing, so
|
|
|
+ * check for both.
|
|
|
+ *
|
|
|
+ * NOTE: The context halt bit may not be set immediately. Because of this,
|
|
|
+ * it is necessary to check the SW SFC_HALTED bit (set in the IRQ) and the HW
|
|
|
+ * context bit to determine if the context is halted.
|
|
|
+ */
|
|
|
static void sc_wait_for_packet_egress(struct send_context *sc, int pause)
|
|
|
{
|
|
|
struct hfi1_devdata *dd = sc->dd;
|
|
@@ -981,8 +1004,9 @@ static void sc_wait_for_packet_egress(struct send_context *sc, int pause)
|
|
|
reg_prev = reg;
|
|
|
reg = read_csr(dd, sc->hw_context * 8 +
|
|
|
SEND_EGRESS_CTXT_STATUS);
|
|
|
- /* done if egress is stopped */
|
|
|
- if (egress_halted(reg))
|
|
|
+ /* done if any halt bits, SW or HW are set */
|
|
|
+ if (sc->flags & SCF_HALTED ||
|
|
|
+ is_sc_halted(dd, sc->hw_context) || egress_halted(reg))
|
|
|
break;
|
|
|
reg = packet_occupancy(reg);
|
|
|
if (reg == 0)
|