aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/infiniband/linda.c32
-rw-r--r--src/drivers/infiniband/linda.h3
2 files changed, 35 insertions, 0 deletions
diff --git a/src/drivers/infiniband/linda.c b/src/drivers/infiniband/linda.c
index 7893e063..b9a7ba58 100644
--- a/src/drivers/infiniband/linda.c
+++ b/src/drivers/infiniband/linda.c
@@ -239,6 +239,32 @@ static void linda_link_state_changed ( struct ib_device *ibdev ) {
}
/**
+ * Wait for link state change to take effect
+ *
+ * @v linda Linda device
+ * @v new_link_state Expected link state
+ * @ret rc Return status code
+ */
+static int linda_link_state_check ( struct linda *linda,
+ unsigned int new_link_state ) {
+ struct QIB_7220_IBCStatus ibcstatus;
+ unsigned int link_state;
+ unsigned int i;
+
+ for ( i = 0 ; i < LINDA_LINK_STATE_MAX_WAIT_US ; i++ ) {
+ linda_readq ( linda, &ibcstatus, QIB_7220_IBCStatus_offset );
+ link_state = BIT_GET ( &ibcstatus, LinkState );
+ if ( link_state == new_link_state )
+ return 0;
+ udelay ( 1 );
+ }
+
+ DBGC ( linda, "Linda %p timed out waiting for link state %s\n",
+ linda, linda_link_state_text ( link_state ) );
+ return -ETIMEDOUT;
+}
+
+/**
* Set port information
*
* @v ibdev Infiniband device
@@ -260,6 +286,12 @@ static int linda_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) {
linda_readq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
BIT_SET ( &ibcctrl, LinkCmd, link_state );
linda_writeq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
+
+ /* Wait for link state change to take effect. Ignore
+ * errors; the current link state will be returned via
+ * the GetResponse MAD.
+ */
+ linda_link_state_check ( linda, link_state );
}
/* Detect and report link state change */
diff --git a/src/drivers/infiniband/linda.h b/src/drivers/infiniband/linda.h
index 66eea28e..3068421b 100644
--- a/src/drivers/infiniband/linda.h
+++ b/src/drivers/infiniband/linda.h
@@ -270,4 +270,7 @@ enum linda_link_state {
LINDA_LINK_STATE_ACT_DEFER = 4,
};
+/** Maximum time to wait for link state changes, in us */
+#define LINDA_LINK_STATE_MAX_WAIT_US 20
+
#endif /* _LINDA_H */