static int usb4_native_switch_op()

in usb4.c [53:106]


static int usb4_native_switch_op(struct tb_switch *sw, u16 opcode,
				 u32 *metadata, u8 *status,
				 const void *tx_data, size_t tx_dwords,
				 void *rx_data, size_t rx_dwords)
{
	u32 val;
	int ret;

	if (metadata) {
		ret = tb_sw_write(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
		if (ret)
			return ret;
	}
	if (tx_dwords) {
		ret = tb_sw_write(sw, tx_data, TB_CFG_SWITCH, ROUTER_CS_9,
				  tx_dwords);
		if (ret)
			return ret;
	}

	val = opcode | ROUTER_CS_26_OV;
	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
	if (ret)
		return ret;

	ret = tb_switch_wait_for_bit(sw, ROUTER_CS_26, ROUTER_CS_26_OV, 0, 500);
	if (ret)
		return ret;

	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
	if (ret)
		return ret;

	if (val & ROUTER_CS_26_ONS)
		return -EOPNOTSUPP;

	if (status)
		*status = (val & ROUTER_CS_26_STATUS_MASK) >>
			ROUTER_CS_26_STATUS_SHIFT;

	if (metadata) {
		ret = tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
		if (ret)
			return ret;
	}
	if (rx_dwords) {
		ret = tb_sw_read(sw, rx_data, TB_CFG_SWITCH, ROUTER_CS_9,
				 rx_dwords);
		if (ret)
			return ret;
	}

	return 0;
}