diff options
author | Aseda Aboagye <aaboagye@google.com> | 2019-11-18 18:32:35 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-21 23:20:03 +0000 |
commit | 14e356b73ee9c40170c8c0042dd452ba83b5ead9 (patch) | |
tree | 8a115b2c0ea3cc5e31528d963a304ae04f3b4bec /common/usb_pd_protocol.c | |
parent | 073a512059c475b75f2e5b55ffa807c2f1762b6b (diff) | |
download | chrome-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>
Diffstat (limited to 'common/usb_pd_protocol.c')
-rw-r--r-- | common/usb_pd_protocol.c | 20 |
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... */ |