summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2019-11-18 18:32:35 -0800
committerCommit Bot <commit-bot@chromium.org>2019-11-21 23:20:03 +0000
commit14e356b73ee9c40170c8c0042dd452ba83b5ead9 (patch)
tree8a115b2c0ea3cc5e31528d963a304ae04f3b4bec
parent073a512059c475b75f2e5b55ffa807c2f1762b6b (diff)
downloadchrome-ec-14e356b73ee9c40170c8c0042dd452ba83b5ead9.tar.gz
TCPMv1: Improve jitter based collision avoidance
For the holdoff timer, we were using the system timestamp as a source of adding jitter. However, it seems that there are certain cases that can cause a periodic collision with the jitter only varying by ~1-2ms. This leads to many repeated collisions until the jitter slides just out of the collision window. This commit changes the jitter calculation to use more of the bits that are changing to reduce the number of collisions. BUG=b:144676183, chromium:925618 BRANCH=hatch,atlas,nocturne,grunt,octopus,rammus,kukui TEST=Flash kohaku, plug some peripherals known for collisions, verify that if a collision is encountered, it's only encountered once (no cycles). TEST=Add debugging prints for the jitter, verify that the jitter is varied and appears non-deterministic. Change-Id: I6c27880551dd35b78993f7130d1ce4eb81aa10ef Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1922751 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Auto-Submit: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--common/usb_pd_protocol.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 2b3d5704aa..61850a98c2 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -1857,13 +1857,12 @@ static void handle_ctrl_request(int port, uint16_t head,
/*
* Give the source some time to send any messages before
* we start our interrogation. Add some jitter of up to
- * 100ms, taken from the current system time, to prevent
- * multiple collisions.
+ * ~192ms to prevent multiple collisions.
*/
if (pd[port].task_state == PD_STATE_SNK_TRANSITION)
pd[port].ready_state_holdoff_timer =
get_time().val + SNK_READY_HOLD_OFF_US
- + (get_time().le.lo % (100 * MSEC));
+ + (get_time().le.lo & 0xf) * 12 * MSEC;
set_state(port, PD_STATE_SNK_READY);
pd_set_input_current_limit(port, pd[port].curr_limit,
@@ -3620,19 +3619,18 @@ void pd_task(void *u)
/*
* Give the sink some time to send any messages
* before we may send messages of our own. Add
- * some jitter of up to 100ms, taken from the
- * current system time, to prevent multiple
- * collisions. This delay also allows the sink
- * device to request power role swap and allow
- * the the accept message to be sent prior to
- * CMD_DISCOVER_IDENT being sent in the
+ * some jitter of up to ~192ms, to prevent
+ * multiple collisions. This delay also allows
+ * the sink device to request power role swap
+ * and allow the the accept message to be sent
+ * prior to CMD_DISCOVER_IDENT being sent in the
* SRC_READY state.
*/
pd[port].ready_state_holdoff_timer =
get_time().val + SRC_READY_HOLD_OFF_US
- + (get_time().le.lo % (100 * MSEC));
+ + (get_time().le.lo & 0xf) * 12 * MSEC;
- /* it'a time to ping regularly the sink */
+ /* it's time to ping regularly the sink */
set_state(port, PD_STATE_SRC_READY);
} else {
/* The sink did not ack, cut the power... */