.. | .. |
---|
1447 | 1447 | static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, |
---|
1448 | 1448 | const u32 *data, int cnt) |
---|
1449 | 1449 | { |
---|
| 1450 | + u32 vdo_hdr = port->vdo_data[0]; |
---|
| 1451 | + |
---|
1450 | 1452 | WARN_ON(!mutex_is_locked(&port->lock)); |
---|
1451 | 1453 | |
---|
1452 | | - /* Make sure we are not still processing a previous VDM packet */ |
---|
1453 | | - WARN_ON(port->vdm_state > VDM_STATE_DONE); |
---|
| 1454 | + /* If is sending discover_identity, handle received message first */ |
---|
| 1455 | + if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMD(vdo_hdr) == CMD_DISCOVER_IDENT) { |
---|
| 1456 | + port->send_discover = true; |
---|
| 1457 | + mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS); |
---|
| 1458 | + } else { |
---|
| 1459 | + /* Make sure we are not still processing a previous VDM packet */ |
---|
| 1460 | + WARN_ON(port->vdm_state > VDM_STATE_DONE); |
---|
| 1461 | + } |
---|
1454 | 1462 | |
---|
1455 | 1463 | port->vdo_count = cnt + 1; |
---|
1456 | 1464 | port->vdo_data[0] = header; |
---|
.. | .. |
---|
1540 | 1548 | * 0x0000 in the last VDO, so we need to break the Discover SVIDs |
---|
1541 | 1549 | * request and return false here. |
---|
1542 | 1550 | */ |
---|
1543 | | - return cnt == 7 ? true : false; |
---|
| 1551 | + return cnt == 7; |
---|
1544 | 1552 | abort: |
---|
1545 | 1553 | tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX); |
---|
1546 | 1554 | return false; |
---|
.. | .. |
---|
1724 | 1732 | rlen = 1; |
---|
1725 | 1733 | } else if (port->data_role == TYPEC_HOST) { |
---|
1726 | 1734 | tcpm_register_partner_altmodes(port); |
---|
| 1735 | + } else { |
---|
| 1736 | + /* Do dr_swap for ufp if the port supports drd */ |
---|
| 1737 | + if (port->typec_caps.data == TYPEC_PORT_DRD && |
---|
| 1738 | + !IS_ERR_OR_NULL(port->port_altmode[0])) { |
---|
| 1739 | + port->vdm_sm_running = false; |
---|
| 1740 | + port->upcoming_state = DR_SWAP_SEND; |
---|
| 1741 | + tcpm_ams_start(port, DATA_ROLE_SWAP); |
---|
| 1742 | + } |
---|
1727 | 1743 | } |
---|
1728 | 1744 | break; |
---|
1729 | 1745 | case CMD_ENTER_MODE: |
---|
.. | .. |
---|
1755 | 1771 | tcpm_ams_finish(port); |
---|
1756 | 1772 | switch (cmd) { |
---|
1757 | 1773 | case CMD_DISCOVER_IDENT: |
---|
| 1774 | + /* Do dr_swap for ufp if the port supports drd */ |
---|
| 1775 | + if (port->typec_caps.data == TYPEC_PORT_DRD && |
---|
| 1776 | + port->data_role == TYPEC_DEVICE && |
---|
| 1777 | + !IS_ERR_OR_NULL(port->port_altmode[0])) { |
---|
| 1778 | + port->vdm_sm_running = false; |
---|
| 1779 | + port->upcoming_state = DR_SWAP_SEND; |
---|
| 1780 | + tcpm_ams_start(port, DATA_ROLE_SWAP); |
---|
| 1781 | + break; |
---|
| 1782 | + } |
---|
| 1783 | + fallthrough; |
---|
1758 | 1784 | case CMD_DISCOVER_SVID: |
---|
1759 | 1785 | case CMD_DISCOVER_MODES: |
---|
1760 | 1786 | case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15): |
---|
.. | .. |
---|
1883 | 1909 | } |
---|
1884 | 1910 | break; |
---|
1885 | 1911 | case ADEV_ATTENTION: |
---|
1886 | | - typec_altmode_attention(adev, p[1]); |
---|
| 1912 | + if (typec_altmode_attention(adev, p[1])) |
---|
| 1913 | + tcpm_log(port, "typec_altmode_attention no port partner altmode"); |
---|
1887 | 1914 | break; |
---|
1888 | 1915 | } |
---|
1889 | 1916 | } |
---|
.. | .. |
---|
1976 | 2003 | switch (PD_VDO_CMD(vdo_hdr)) { |
---|
1977 | 2004 | case CMD_DISCOVER_IDENT: |
---|
1978 | 2005 | res = tcpm_ams_start(port, DISCOVER_IDENTITY); |
---|
1979 | | - if (res == 0) |
---|
| 2006 | + if (res == 0) { |
---|
1980 | 2007 | port->send_discover = false; |
---|
1981 | | - else if (res == -EAGAIN) |
---|
| 2008 | + } else if (res == -EAGAIN) { |
---|
| 2009 | + port->vdo_data[0] = 0; |
---|
1982 | 2010 | mod_send_discover_delayed_work(port, |
---|
1983 | 2011 | SEND_DISCOVER_RETRY_MS); |
---|
| 2012 | + } |
---|
1984 | 2013 | break; |
---|
1985 | 2014 | case CMD_DISCOVER_SVID: |
---|
1986 | 2015 | res = tcpm_ams_start(port, DISCOVER_SVIDS); |
---|
.. | .. |
---|
2063 | 2092 | unsigned long timeout; |
---|
2064 | 2093 | |
---|
2065 | 2094 | port->vdm_retries = 0; |
---|
| 2095 | + port->vdo_data[0] = 0; |
---|
2066 | 2096 | port->vdm_state = VDM_STATE_BUSY; |
---|
2067 | 2097 | timeout = vdm_ready_timeout(vdo_hdr); |
---|
2068 | 2098 | mod_vdm_delayed_work(port, timeout); |
---|