{
struct greybus_host_device *hd = connection->hd;
struct gb_protocol *protocol = connection->protocol;
+ struct gb_interface *intf;
int ret;
if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
return 0;
+ intf = connection->bundle->intf;
ret = gb_svc_connection_create(hd->svc,
hd->endo->ap_intf_id,
connection->hd_cport_id,
- connection->bundle->intf->interface_id,
- connection->intf_cport_id);
+ intf->interface_id,
+ connection->intf_cport_id,
+ intf->boot_over_unipro);
if (ret) {
dev_err(&connection->dev,
"failed to create svc connection: %d\n", ret);
#define DME_ATTR_SELECTOR_INDEX 0
#define DME_ATTR_T_TST_SRC_INCREMENT 0x4083
+/* Return value from TST_SRC_INCREMENT */
+#define DME_TSI_SPI_BOOT_STARTED 0x02
+#define DME_TSI_TRUSTED_SPI_BOOT_FINISHED 0x03
+#define DME_TSI_UNTRUSTED_SPI_BOOT_FINISHED 0x04
+#define DME_TSI_UNIPRO_BOOT_STARTED 0x06
+#define DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED 0x09
+
struct gb_svc_route_create_request {
__u8 intf1_id;
__u8 dev1_id;
struct gb_module *module;
struct greybus_host_device *hd;
+
+ /* The interface needs to boot over unipro */
+ bool boot_over_unipro;
};
#define to_gb_interface(d) container_of(d, struct gb_interface, dev)
return -ENODEV;
}
+ /*
+ * Check if the module needs to boot from unipro.
+ * For ES2: We need to check lowest 8 bits of 'value'.
+ * For ES3: We need to check highest 8 bits out of 32 of 'value'.
+ *
+ * FIXME: Add code to find if we are on ES2 or ES3 to have separate
+ * checks.
+ */
+ if (value == DME_TSI_UNIPRO_BOOT_STARTED ||
+ value == DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED)
+ intf->boot_over_unipro = true;
+
return gb_svc_dme_peer_set(hd->svc, intf->interface_id,
DME_ATTR_T_TST_SRC_INCREMENT,
DME_ATTR_SELECTOR_INDEX, 0);
int gb_svc_connection_create(struct gb_svc *svc,
u8 intf1_id, u16 cport1_id,
- u8 intf2_id, u16 cport2_id)
+ u8 intf2_id, u16 cport2_id,
+ bool boot_over_unipro)
{
struct gb_svc_conn_create_request request;
* for now.
*/
request.tc = 0;
- request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_E2EFC;
+
+ /*
+ * We need to skip setting E2EFC and other flags to the connection
+ * create request, for all cports, on an interface that need to boot
+ * over unipro, i.e. interfaces required to download firmware.
+ */
+ if (boot_over_unipro)
+ request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_CSD_N;
+ else
+ request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_E2EFC;
return gb_operation_sync(svc->connection, GB_SVC_TYPE_CONN_CREATE,
&request, sizeof(request), NULL, 0);
int gb_svc_intf_reset(struct gb_svc *svc, u8 intf_id);
int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
- u8 intf2_id, u16 cport2_id);
+ u8 intf2_id, u16 cport2_id, bool boot_over_unipro);
void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
u8 intf2_id, u16 cport2_id);
int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,