Browse Source

[linda] Wait up to 20us for link state to update

Some subnet managers expect the GetResponse from a SetPortInfo MAD to
contain the new link state.  The transition is not immediate, so we
often end up returning the previous link state.  This can cause the SM
to fail to activate the port.

Fix by waiting for up to 20us for the link state transition to take
effect.
tags/v1.0.0-rc1
Michael Brown 15 years ago
parent
commit
7467cf5f09
2 changed files with 35 additions and 0 deletions
  1. 32
    0
      src/drivers/infiniband/linda.c
  2. 3
    0
      src/drivers/infiniband/linda.h

+ 32
- 0
src/drivers/infiniband/linda.c View File

238
 	ib_link_state_changed ( ibdev );
238
 	ib_link_state_changed ( ibdev );
239
 }
239
 }
240
 
240
 
241
+/**
242
+ * Wait for link state change to take effect
243
+ *
244
+ * @v linda		Linda device
245
+ * @v new_link_state	Expected link state
246
+ * @ret rc		Return status code
247
+ */
248
+static int linda_link_state_check ( struct linda *linda,
249
+				    unsigned int new_link_state ) {
250
+	struct QIB_7220_IBCStatus ibcstatus;
251
+	unsigned int link_state;
252
+	unsigned int i;
253
+
254
+	for ( i = 0 ; i < LINDA_LINK_STATE_MAX_WAIT_US ; i++ ) {
255
+		linda_readq ( linda, &ibcstatus, QIB_7220_IBCStatus_offset );
256
+		link_state = BIT_GET ( &ibcstatus, LinkState );
257
+		if ( link_state == new_link_state )
258
+			return 0;
259
+		udelay ( 1 );
260
+	}
261
+
262
+	DBGC ( linda, "Linda %p timed out waiting for link state %s\n",
263
+	       linda, linda_link_state_text ( link_state ) );
264
+	return -ETIMEDOUT;
265
+}
266
+
241
 /**
267
 /**
242
  * Set port information
268
  * Set port information
243
  *
269
  *
260
 		linda_readq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
286
 		linda_readq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
261
 		BIT_SET ( &ibcctrl, LinkCmd, link_state );
287
 		BIT_SET ( &ibcctrl, LinkCmd, link_state );
262
 		linda_writeq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
288
 		linda_writeq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
289
+
290
+		/* Wait for link state change to take effect.  Ignore
291
+		 * errors; the current link state will be returned via
292
+		 * the GetResponse MAD.
293
+		 */
294
+		linda_link_state_check ( linda, link_state );
263
 	}
295
 	}
264
 
296
 
265
 	/* Detect and report link state change */
297
 	/* Detect and report link state change */

+ 3
- 0
src/drivers/infiniband/linda.h View File

270
 	LINDA_LINK_STATE_ACT_DEFER = 4,
270
 	LINDA_LINK_STATE_ACT_DEFER = 4,
271
 };
271
 };
272
 
272
 
273
+/** Maximum time to wait for link state changes, in us */
274
+#define LINDA_LINK_STATE_MAX_WAIT_US 20
275
+
273
 #endif /* _LINDA_H */
276
 #endif /* _LINDA_H */

Loading…
Cancel
Save