Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thunderbolt: Add support for Intel Titan Ridge

Intel Titan Ridge is the next Thunderbolt 3 controller. The ICM firmware
message format in Titan Ridge differs from Falcon Ridge and Alpine Ridge
somewhat because it is using route strings addressing devices. In
addition to that the DMA port of 4-channel (two port) controller is in
different port number than the previous controllers. There are some
other minor differences as well.

This patch add support for Intel Titan Ridge and the new ICM firmware
message format.

Signed-off-by: Radion Mirchevsky <radion.mirchevsky@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

authored by

Radion Mirchevsky and committed by
Mika Westerberg
4bac471d 6fc14e1a

+545 -14
+12 -14
drivers/thunderbolt/dma_port.c
··· 170 170 171 171 static int dma_find_port(struct tb_switch *sw) 172 172 { 173 - int port, ret; 174 - u32 type; 173 + static const int ports[] = { 3, 5, 7 }; 174 + int i; 175 175 176 176 /* 177 - * The DMA (NHI) port is either 3 or 5 depending on the 178 - * controller. Try both starting from 5 which is more common. 177 + * The DMA (NHI) port is either 3, 5 or 7 depending on the 178 + * controller. Try all of them. 179 179 */ 180 - port = 5; 181 - ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1, 182 - DMA_PORT_TIMEOUT); 183 - if (!ret && (type & 0xffffff) == TB_TYPE_NHI) 184 - return port; 180 + for (i = 0; i < ARRAY_SIZE(ports); i++) { 181 + u32 type; 182 + int ret; 185 183 186 - port = 3; 187 - ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1, 188 - DMA_PORT_TIMEOUT); 189 - if (!ret && (type & 0xffffff) == TB_TYPE_NHI) 190 - return port; 184 + ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), ports[i], 185 + 2, 1, DMA_PORT_TIMEOUT); 186 + if (!ret && (type & 0xffffff) == TB_TYPE_NHI) 187 + return ports[i]; 188 + } 191 189 192 190 return -ENODEV; 193 191 }
+382
drivers/thunderbolt/icm.c
··· 118 118 return (u64)route_hi << 32 | route_lo; 119 119 } 120 120 121 + static inline u64 get_parent_route(u64 route) 122 + { 123 + int depth = tb_route_length(route); 124 + return depth ? route & ~(0xffULL << (depth - 1) * TB_ROUTE_SHIFT) : 0; 125 + } 126 + 121 127 static bool icm_match(const struct tb_cfg_request *req, 122 128 const struct ctl_pkg *pkg) 123 129 { ··· 749 743 * cannot find it here. 750 744 */ 751 745 xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid); 746 + if (xd) { 747 + remove_xdomain(xd); 748 + tb_xdomain_put(xd); 749 + } 750 + } 751 + 752 + static int 753 + icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level, 754 + size_t *nboot_acl) 755 + { 756 + struct icm_tr_pkg_driver_ready_response reply; 757 + struct icm_pkg_driver_ready request = { 758 + .hdr.code = ICM_DRIVER_READY, 759 + }; 760 + int ret; 761 + 762 + memset(&reply, 0, sizeof(reply)); 763 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 764 + 1, 20000); 765 + if (ret) 766 + return ret; 767 + 768 + if (security_level) 769 + *security_level = reply.info & ICM_TR_INFO_SLEVEL_MASK; 770 + if (nboot_acl) 771 + *nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK) >> 772 + ICM_TR_INFO_BOOT_ACL_SHIFT; 773 + return 0; 774 + } 775 + 776 + static int icm_tr_approve_switch(struct tb *tb, struct tb_switch *sw) 777 + { 778 + struct icm_tr_pkg_approve_device request; 779 + struct icm_tr_pkg_approve_device reply; 780 + int ret; 781 + 782 + memset(&request, 0, sizeof(request)); 783 + memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid)); 784 + request.hdr.code = ICM_APPROVE_DEVICE; 785 + request.route_lo = sw->config.route_lo; 786 + request.route_hi = sw->config.route_hi; 787 + request.connection_id = sw->connection_id; 788 + 789 + memset(&reply, 0, sizeof(reply)); 790 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 791 + 1, ICM_APPROVE_TIMEOUT); 792 + if (ret) 793 + return ret; 794 + 795 + if (reply.hdr.flags & ICM_FLAGS_ERROR) { 796 + tb_warn(tb, "PCIe tunnel creation failed\n"); 797 + return -EIO; 798 + } 799 + 800 + return 0; 801 + } 802 + 803 + static int icm_tr_add_switch_key(struct tb *tb, struct tb_switch *sw) 804 + { 805 + struct icm_tr_pkg_add_device_key_response reply; 806 + struct icm_tr_pkg_add_device_key request; 807 + int ret; 808 + 809 + memset(&request, 0, sizeof(request)); 810 + memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid)); 811 + request.hdr.code = ICM_ADD_DEVICE_KEY; 812 + request.route_lo = sw->config.route_lo; 813 + request.route_hi = sw->config.route_hi; 814 + request.connection_id = sw->connection_id; 815 + memcpy(request.key, sw->key, TB_SWITCH_KEY_SIZE); 816 + 817 + memset(&reply, 0, sizeof(reply)); 818 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 819 + 1, ICM_TIMEOUT); 820 + if (ret) 821 + return ret; 822 + 823 + if (reply.hdr.flags & ICM_FLAGS_ERROR) { 824 + tb_warn(tb, "Adding key to switch failed\n"); 825 + return -EIO; 826 + } 827 + 828 + return 0; 829 + } 830 + 831 + static int icm_tr_challenge_switch_key(struct tb *tb, struct tb_switch *sw, 832 + const u8 *challenge, u8 *response) 833 + { 834 + struct icm_tr_pkg_challenge_device_response reply; 835 + struct icm_tr_pkg_challenge_device request; 836 + int ret; 837 + 838 + memset(&request, 0, sizeof(request)); 839 + memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid)); 840 + request.hdr.code = ICM_CHALLENGE_DEVICE; 841 + request.route_lo = sw->config.route_lo; 842 + request.route_hi = sw->config.route_hi; 843 + request.connection_id = sw->connection_id; 844 + memcpy(request.challenge, challenge, TB_SWITCH_KEY_SIZE); 845 + 846 + memset(&reply, 0, sizeof(reply)); 847 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 848 + 1, ICM_TIMEOUT); 849 + if (ret) 850 + return ret; 851 + 852 + if (reply.hdr.flags & ICM_FLAGS_ERROR) 853 + return -EKEYREJECTED; 854 + if (reply.hdr.flags & ICM_FLAGS_NO_KEY) 855 + return -ENOKEY; 856 + 857 + memcpy(response, reply.response, TB_SWITCH_KEY_SIZE); 858 + 859 + return 0; 860 + } 861 + 862 + static int icm_tr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd) 863 + { 864 + struct icm_tr_pkg_approve_xdomain_response reply; 865 + struct icm_tr_pkg_approve_xdomain request; 866 + int ret; 867 + 868 + memset(&request, 0, sizeof(request)); 869 + request.hdr.code = ICM_APPROVE_XDOMAIN; 870 + request.route_hi = upper_32_bits(xd->route); 871 + request.route_lo = lower_32_bits(xd->route); 872 + request.transmit_path = xd->transmit_path; 873 + request.transmit_ring = xd->transmit_ring; 874 + request.receive_path = xd->receive_path; 875 + request.receive_ring = xd->receive_ring; 876 + memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd->remote_uuid)); 877 + 878 + memset(&reply, 0, sizeof(reply)); 879 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 880 + 1, ICM_TIMEOUT); 881 + if (ret) 882 + return ret; 883 + 884 + if (reply.hdr.flags & ICM_FLAGS_ERROR) 885 + return -EIO; 886 + 887 + return 0; 888 + } 889 + 890 + static int icm_tr_xdomain_tear_down(struct tb *tb, struct tb_xdomain *xd, 891 + int stage) 892 + { 893 + struct icm_tr_pkg_disconnect_xdomain_response reply; 894 + struct icm_tr_pkg_disconnect_xdomain request; 895 + int ret; 896 + 897 + memset(&request, 0, sizeof(request)); 898 + request.hdr.code = ICM_DISCONNECT_XDOMAIN; 899 + request.stage = stage; 900 + request.route_hi = upper_32_bits(xd->route); 901 + request.route_lo = lower_32_bits(xd->route); 902 + memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd->remote_uuid)); 903 + 904 + memset(&reply, 0, sizeof(reply)); 905 + ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), 906 + 1, ICM_TIMEOUT); 907 + if (ret) 908 + return ret; 909 + 910 + if (reply.hdr.flags & ICM_FLAGS_ERROR) 911 + return -EIO; 912 + 913 + return 0; 914 + } 915 + 916 + static int icm_tr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd) 917 + { 918 + int ret; 919 + 920 + ret = icm_tr_xdomain_tear_down(tb, xd, 1); 921 + if (ret) 922 + return ret; 923 + 924 + usleep_range(10, 50); 925 + return icm_tr_xdomain_tear_down(tb, xd, 2); 926 + } 927 + 928 + static void 929 + icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) 930 + { 931 + const struct icm_tr_event_device_connected *pkg = 932 + (const struct icm_tr_event_device_connected *)hdr; 933 + enum tb_security_level security_level; 934 + struct tb_switch *sw, *parent_sw; 935 + struct tb_xdomain *xd; 936 + bool authorized, boot; 937 + u64 route; 938 + 939 + /* 940 + * Currently we don't use the QoS information coming with the 941 + * device connected message so simply just ignore that extra 942 + * packet for now. 943 + */ 944 + if (pkg->hdr.packet_id) 945 + return; 946 + 947 + /* 948 + * After NVM upgrade adding root switch device fails because we 949 + * initiated reset. During that time ICM might still send device 950 + * connected message which we ignore here. 951 + */ 952 + if (!tb->root_switch) 953 + return; 954 + 955 + route = get_route(pkg->route_hi, pkg->route_lo); 956 + authorized = pkg->link_info & ICM_LINK_INFO_APPROVED; 957 + security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >> 958 + ICM_FLAGS_SLEVEL_SHIFT; 959 + boot = pkg->link_info & ICM_LINK_INFO_BOOT; 960 + 961 + if (pkg->link_info & ICM_LINK_INFO_REJECTED) { 962 + tb_info(tb, "switch at %llx was rejected by ICM firmware because topology limit exceeded\n", 963 + route); 964 + return; 965 + } 966 + 967 + sw = tb_switch_find_by_uuid(tb, &pkg->ep_uuid); 968 + if (sw) { 969 + /* Update the switch if it is still in the same place */ 970 + if (tb_route(sw) == route && !!sw->authorized == authorized) { 971 + parent_sw = tb_to_switch(sw->dev.parent); 972 + update_switch(parent_sw, sw, route, pkg->connection_id, 973 + 0, 0, 0, boot); 974 + tb_switch_put(sw); 975 + return; 976 + } 977 + 978 + remove_switch(sw); 979 + tb_switch_put(sw); 980 + } 981 + 982 + /* Another switch with the same address */ 983 + sw = tb_switch_find_by_route(tb, route); 984 + if (sw) { 985 + remove_switch(sw); 986 + tb_switch_put(sw); 987 + } 988 + 989 + /* XDomain connection with the same address */ 990 + xd = tb_xdomain_find_by_route(tb, route); 991 + if (xd) { 992 + remove_xdomain(xd); 993 + tb_xdomain_put(xd); 994 + } 995 + 996 + parent_sw = tb_switch_find_by_route(tb, get_parent_route(route)); 997 + if (!parent_sw) { 998 + tb_err(tb, "failed to find parent switch for %llx\n", route); 999 + return; 1000 + } 1001 + 1002 + add_switch(parent_sw, route, &pkg->ep_uuid, pkg->connection_id, 1003 + 0, 0, 0, security_level, authorized, boot); 1004 + 1005 + tb_switch_put(parent_sw); 1006 + } 1007 + 1008 + static void 1009 + icm_tr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) 1010 + { 1011 + const struct icm_tr_event_device_disconnected *pkg = 1012 + (const struct icm_tr_event_device_disconnected *)hdr; 1013 + struct tb_switch *sw; 1014 + u64 route; 1015 + 1016 + route = get_route(pkg->route_hi, pkg->route_lo); 1017 + 1018 + sw = tb_switch_find_by_route(tb, route); 1019 + if (!sw) { 1020 + tb_warn(tb, "no switch exists at %llx, ignoring\n", route); 1021 + return; 1022 + } 1023 + 1024 + remove_switch(sw); 1025 + tb_switch_put(sw); 1026 + } 1027 + 1028 + static void 1029 + icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) 1030 + { 1031 + const struct icm_tr_event_xdomain_connected *pkg = 1032 + (const struct icm_tr_event_xdomain_connected *)hdr; 1033 + struct tb_xdomain *xd; 1034 + struct tb_switch *sw; 1035 + u64 route; 1036 + 1037 + if (!tb->root_switch) 1038 + return; 1039 + 1040 + route = get_route(pkg->local_route_hi, pkg->local_route_lo); 1041 + 1042 + xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid); 1043 + if (xd) { 1044 + if (xd->route == route) { 1045 + update_xdomain(xd, route, 0); 1046 + tb_xdomain_put(xd); 1047 + return; 1048 + } 1049 + 1050 + remove_xdomain(xd); 1051 + tb_xdomain_put(xd); 1052 + } 1053 + 1054 + /* An existing xdomain with the same address */ 1055 + xd = tb_xdomain_find_by_route(tb, route); 1056 + if (xd) { 1057 + remove_xdomain(xd); 1058 + tb_xdomain_put(xd); 1059 + } 1060 + 1061 + /* 1062 + * If the user disconnected a switch during suspend and 1063 + * connected another host to the same port, remove the switch 1064 + * first. 1065 + */ 1066 + sw = get_switch_at_route(tb->root_switch, route); 1067 + if (sw) 1068 + remove_switch(sw); 1069 + 1070 + sw = tb_switch_find_by_route(tb, get_parent_route(route)); 1071 + if (!sw) { 1072 + tb_warn(tb, "no switch exists at %llx, ignoring\n", route); 1073 + return; 1074 + } 1075 + 1076 + add_xdomain(sw, route, &pkg->local_uuid, &pkg->remote_uuid, 0, 0); 1077 + tb_switch_put(sw); 1078 + } 1079 + 1080 + static void 1081 + icm_tr_xdomain_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) 1082 + { 1083 + const struct icm_tr_event_xdomain_disconnected *pkg = 1084 + (const struct icm_tr_event_xdomain_disconnected *)hdr; 1085 + struct tb_xdomain *xd; 1086 + u64 route; 1087 + 1088 + route = get_route(pkg->route_hi, pkg->route_lo); 1089 + 1090 + xd = tb_xdomain_find_by_route(tb, route); 752 1091 if (xd) { 753 1092 remove_xdomain(xd); 754 1093 tb_xdomain_put(xd); ··· 1823 1472 .disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths, 1824 1473 }; 1825 1474 1475 + /* Titan Ridge */ 1476 + static const struct tb_cm_ops icm_tr_ops = { 1477 + .driver_ready = icm_driver_ready, 1478 + .start = icm_start, 1479 + .stop = icm_stop, 1480 + .suspend = icm_suspend, 1481 + .complete = icm_complete, 1482 + .handle_event = icm_handle_event, 1483 + .get_boot_acl = icm_ar_get_boot_acl, 1484 + .set_boot_acl = icm_ar_set_boot_acl, 1485 + .approve_switch = icm_tr_approve_switch, 1486 + .add_switch_key = icm_tr_add_switch_key, 1487 + .challenge_switch_key = icm_tr_challenge_switch_key, 1488 + .disconnect_pcie_paths = icm_disconnect_pcie_paths, 1489 + .approve_xdomain_paths = icm_tr_approve_xdomain_paths, 1490 + .disconnect_xdomain_paths = icm_tr_disconnect_xdomain_paths, 1491 + }; 1492 + 1826 1493 struct tb *icm_probe(struct tb_nhi *nhi) 1827 1494 { 1828 1495 struct icm *icm; ··· 1882 1513 icm->xdomain_connected = icm_fr_xdomain_connected; 1883 1514 icm->xdomain_disconnected = icm_fr_xdomain_disconnected; 1884 1515 tb->cm_ops = &icm_ar_ops; 1516 + break; 1517 + 1518 + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI: 1519 + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI: 1520 + icm->max_boot_acl = ICM_AR_PREBOOT_ACL_ENTRIES; 1521 + icm->is_supported = icm_ar_is_supported; 1522 + icm->get_mode = icm_ar_get_mode; 1523 + icm->driver_ready = icm_tr_driver_ready; 1524 + icm->device_connected = icm_tr_device_connected; 1525 + icm->device_disconnected = icm_tr_device_disconnected; 1526 + icm->xdomain_connected = icm_tr_xdomain_connected; 1527 + icm->xdomain_disconnected = icm_tr_xdomain_disconnected; 1528 + tb->cm_ops = &icm_tr_ops; 1885 1529 break; 1886 1530 } 1887 1531
+2
drivers/thunderbolt/nhi.c
··· 1111 1111 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI) }, 1112 1112 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI) }, 1113 1113 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI) }, 1114 + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI) }, 1115 + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI) }, 1114 1116 1115 1117 { 0,} 1116 1118 };
+5
drivers/thunderbolt/nhi.h
··· 45 45 #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_USBONLY_NHI 0x15dc 46 46 #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_USBONLY_NHI 0x15dd 47 47 #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI 0x15de 48 + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE 0x15e7 49 + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI 0x15e8 50 + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE 0x15ea 51 + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI 0x15eb 52 + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef 48 53 49 54 #endif
+3
drivers/thunderbolt/switch.c
··· 1051 1051 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE: 1052 1052 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE: 1053 1053 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE: 1054 + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE: 1055 + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE: 1056 + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE: 1054 1057 return 3; 1055 1058 1056 1059 default:
+141
drivers/thunderbolt/tb_msgs.h
··· 102 102 ICM_ADD_DEVICE_KEY = 0x6, 103 103 ICM_GET_ROUTE = 0xa, 104 104 ICM_APPROVE_XDOMAIN = 0x10, 105 + ICM_DISCONNECT_XDOMAIN = 0x11, 105 106 ICM_PREBOOT_ACL = 0x18, 106 107 }; 107 108 ··· 320 319 struct icm_ar_pkg_preboot_acl_response { 321 320 struct icm_pkg_header hdr; 322 321 struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES]; 322 + }; 323 + 324 + /* Titan Ridge messages */ 325 + 326 + struct icm_tr_pkg_driver_ready_response { 327 + struct icm_pkg_header hdr; 328 + u16 reserved1; 329 + u16 info; 330 + u32 nvm_version; 331 + u16 device_id; 332 + u16 reserved2; 333 + }; 334 + 335 + #define ICM_TR_INFO_SLEVEL_MASK GENMASK(2, 0) 336 + #define ICM_TR_INFO_BOOT_ACL_SHIFT 7 337 + #define ICM_TR_INFO_BOOT_ACL_MASK GENMASK(12, 7) 338 + 339 + struct icm_tr_event_device_connected { 340 + struct icm_pkg_header hdr; 341 + uuid_t ep_uuid; 342 + u32 route_hi; 343 + u32 route_lo; 344 + u8 connection_id; 345 + u8 reserved; 346 + u16 link_info; 347 + u32 ep_name[55]; 348 + }; 349 + 350 + struct icm_tr_event_device_disconnected { 351 + struct icm_pkg_header hdr; 352 + u32 route_hi; 353 + u32 route_lo; 354 + }; 355 + 356 + struct icm_tr_event_xdomain_connected { 357 + struct icm_pkg_header hdr; 358 + u16 reserved; 359 + u16 link_info; 360 + uuid_t remote_uuid; 361 + uuid_t local_uuid; 362 + u32 local_route_hi; 363 + u32 local_route_lo; 364 + u32 remote_route_hi; 365 + u32 remote_route_lo; 366 + }; 367 + 368 + struct icm_tr_event_xdomain_disconnected { 369 + struct icm_pkg_header hdr; 370 + u32 route_hi; 371 + u32 route_lo; 372 + uuid_t remote_uuid; 373 + }; 374 + 375 + struct icm_tr_pkg_approve_device { 376 + struct icm_pkg_header hdr; 377 + uuid_t ep_uuid; 378 + u32 route_hi; 379 + u32 route_lo; 380 + u8 connection_id; 381 + u8 reserved1[3]; 382 + }; 383 + 384 + struct icm_tr_pkg_add_device_key { 385 + struct icm_pkg_header hdr; 386 + uuid_t ep_uuid; 387 + u32 route_hi; 388 + u32 route_lo; 389 + u8 connection_id; 390 + u8 reserved[3]; 391 + u32 key[8]; 392 + }; 393 + 394 + struct icm_tr_pkg_challenge_device { 395 + struct icm_pkg_header hdr; 396 + uuid_t ep_uuid; 397 + u32 route_hi; 398 + u32 route_lo; 399 + u8 connection_id; 400 + u8 reserved[3]; 401 + u32 challenge[8]; 402 + }; 403 + 404 + struct icm_tr_pkg_approve_xdomain { 405 + struct icm_pkg_header hdr; 406 + u32 route_hi; 407 + u32 route_lo; 408 + uuid_t remote_uuid; 409 + u16 transmit_path; 410 + u16 transmit_ring; 411 + u16 receive_path; 412 + u16 receive_ring; 413 + }; 414 + 415 + struct icm_tr_pkg_disconnect_xdomain { 416 + struct icm_pkg_header hdr; 417 + u8 stage; 418 + u8 reserved[3]; 419 + u32 route_hi; 420 + u32 route_lo; 421 + uuid_t remote_uuid; 422 + }; 423 + 424 + struct icm_tr_pkg_challenge_device_response { 425 + struct icm_pkg_header hdr; 426 + uuid_t ep_uuid; 427 + u32 route_hi; 428 + u32 route_lo; 429 + u8 connection_id; 430 + u8 reserved[3]; 431 + u32 challenge[8]; 432 + u32 response[8]; 433 + }; 434 + 435 + struct icm_tr_pkg_add_device_key_response { 436 + struct icm_pkg_header hdr; 437 + uuid_t ep_uuid; 438 + u32 route_hi; 439 + u32 route_lo; 440 + u8 connection_id; 441 + u8 reserved[3]; 442 + }; 443 + 444 + struct icm_tr_pkg_approve_xdomain_response { 445 + struct icm_pkg_header hdr; 446 + u32 route_hi; 447 + u32 route_lo; 448 + uuid_t remote_uuid; 449 + u16 transmit_path; 450 + u16 transmit_ring; 451 + u16 receive_path; 452 + u16 receive_ring; 453 + }; 454 + 455 + struct icm_tr_pkg_disconnect_xdomain_response { 456 + struct icm_pkg_header hdr; 457 + u8 stage; 458 + u8 reserved[3]; 459 + u32 route_hi; 460 + u32 route_lo; 461 + uuid_t remote_uuid; 323 462 }; 324 463 325 464 /* XDomain messages */