brintos

brintos / linux-shallow public Read only

0
0
Text · 21.7 KiB · c5f6c11 Raw
678 lines · c
1/*2 * Copyright 2018 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "hdcp.h"27 28enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp,29		struct mod_hdcp_event_context *event_ctx,30		struct mod_hdcp_transition_input_hdcp2 *input,31		struct mod_hdcp_output *output)32{33	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;34	struct mod_hdcp_connection *conn = &hdcp->connection;35	struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;36 37	switch (current_state(hdcp)) {38	case H2_A0_KNOWN_HDCP2_CAPABLE_RX:39		if (input->hdcp2version_read != PASS ||40				input->hdcp2_capable_check != PASS) {41			adjust->hdcp2.disable = 1;42			callback_in_ms(0, output);43			set_state_id(hdcp, output, HDCP_INITIALIZED);44		} else {45			callback_in_ms(0, output);46			set_state_id(hdcp, output, H2_A1_SEND_AKE_INIT);47		}48		break;49	case H2_A1_SEND_AKE_INIT:50		if (input->create_session != PASS ||51				input->ake_init_prepare != PASS) {52			/* out of sync with psp state */53			adjust->hdcp2.disable = 1;54			fail_and_restart_in_ms(0, &status, output);55			break;56		} else if (input->ake_init_write != PASS) {57			fail_and_restart_in_ms(0, &status, output);58			break;59		}60		set_watchdog_in_ms(hdcp, 100, output);61		callback_in_ms(0, output);62		set_state_id(hdcp, output, H2_A1_VALIDATE_AKE_CERT);63		break;64	case H2_A1_VALIDATE_AKE_CERT:65		if (input->ake_cert_available != PASS) {66			if (event_ctx->event ==67					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {68				/* 1A-08: consider ake timeout a failure */69				/* some hdmi receivers are not ready for HDCP70				 * immediately after video becomes active,71				 * delay 1s before retry on first HDCP message72				 * timeout.73				 */74				fail_and_restart_in_ms(1000, &status, output);75			} else {76				/* continue ake cert polling*/77				callback_in_ms(10, output);78				increment_stay_counter(hdcp);79			}80			break;81		} else if (input->ake_cert_read != PASS ||82				input->ake_cert_validation != PASS) {83			/*84			 * 1A-09: consider invalid ake cert a failure85			 * 1A-10: consider receiver id listed in SRM a failure86			 */87			fail_and_restart_in_ms(0, &status, output);88			break;89		}90		if (conn->is_km_stored &&91				!adjust->hdcp2.force_no_stored_km) {92			callback_in_ms(0, output);93			set_state_id(hdcp, output, H2_A1_SEND_STORED_KM);94		} else {95			callback_in_ms(0, output);96			set_state_id(hdcp, output, H2_A1_SEND_NO_STORED_KM);97		}98		break;99	case H2_A1_SEND_NO_STORED_KM:100		if (input->no_stored_km_write != PASS) {101			fail_and_restart_in_ms(0, &status, output);102			break;103		}104		if (adjust->hdcp2.increase_h_prime_timeout)105			set_watchdog_in_ms(hdcp, 2000, output);106		else107			set_watchdog_in_ms(hdcp, 1000, output);108		callback_in_ms(0, output);109		set_state_id(hdcp, output, H2_A1_READ_H_PRIME);110		break;111	case H2_A1_READ_H_PRIME:112		if (input->h_prime_available != PASS) {113			if (event_ctx->event ==114					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {115				/* 1A-11-3: consider h' timeout a failure */116				fail_and_restart_in_ms(1000, &status, output);117			} else {118				/* continue h' polling */119				callback_in_ms(100, output);120				increment_stay_counter(hdcp);121			}122			break;123		} else if (input->h_prime_read != PASS) {124			fail_and_restart_in_ms(0, &status, output);125			break;126		}127		set_watchdog_in_ms(hdcp, 200, output);128		callback_in_ms(0, output);129		set_state_id(hdcp, output, H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME);130		break;131	case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:132		if (input->pairing_available != PASS) {133			if (event_ctx->event ==134					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {135				/* 1A-12: consider pairing info timeout136				 * a failure137				 */138				fail_and_restart_in_ms(0, &status, output);139			} else {140				/* continue pairing info polling */141				callback_in_ms(20, output);142				increment_stay_counter(hdcp);143			}144			break;145		} else if (input->pairing_info_read != PASS ||146				input->h_prime_validation != PASS) {147			/* 1A-11-1: consider invalid h' a failure */148			fail_and_restart_in_ms(0, &status, output);149			break;150		}151		callback_in_ms(0, output);152		set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK);153		break;154	case H2_A1_SEND_STORED_KM:155		if (input->stored_km_write != PASS) {156			fail_and_restart_in_ms(0, &status, output);157			break;158		}159		set_watchdog_in_ms(hdcp, 200, output);160		callback_in_ms(0, output);161		set_state_id(hdcp, output, H2_A1_VALIDATE_H_PRIME);162		break;163	case H2_A1_VALIDATE_H_PRIME:164		if (input->h_prime_available != PASS) {165			if (event_ctx->event ==166					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {167				/* 1A-11-2: consider h' timeout a failure */168				fail_and_restart_in_ms(1000, &status, output);169			} else {170				/* continue h' polling */171				callback_in_ms(20, output);172				increment_stay_counter(hdcp);173			}174			break;175		} else if (input->h_prime_read != PASS) {176			fail_and_restart_in_ms(0, &status, output);177			break;178		} else if (input->h_prime_validation != PASS) {179			/* 1A-11-1: consider invalid h' a failure */180			adjust->hdcp2.force_no_stored_km = 1;181			fail_and_restart_in_ms(0, &status, output);182			break;183		}184		callback_in_ms(0, output);185		set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK);186		break;187	case H2_A2_LOCALITY_CHECK:188		if (hdcp->state.stay_count > 10 ||189				input->lc_init_prepare != PASS ||190				input->lc_init_write != PASS ||191				input->l_prime_available_poll != PASS ||192				input->l_prime_read != PASS) {193			/*194			 * 1A-05: consider disconnection after LC init a failure195			 * 1A-13-1: consider invalid l' a failure196			 * 1A-13-2: consider l' timeout a failure197			 */198			fail_and_restart_in_ms(0, &status, output);199			break;200		} else if (input->l_prime_validation != PASS) {201			callback_in_ms(0, output);202			increment_stay_counter(hdcp);203			break;204		}205		callback_in_ms(0, output);206		set_state_id(hdcp, output, H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER);207		break;208	case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER:209		if (input->eks_prepare != PASS ||210				input->eks_write != PASS) {211			fail_and_restart_in_ms(0, &status, output);212			break;213		}214		if (conn->is_repeater) {215			set_watchdog_in_ms(hdcp, 3000, output);216			callback_in_ms(0, output);217			set_state_id(hdcp, output, H2_A6_WAIT_FOR_RX_ID_LIST);218		} else {219			/* some CTS equipment requires a delay GREATER than220			 * 200 ms, so delay 210 ms instead of 200 ms221			 */222			callback_in_ms(210, output);223			set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION);224		}225		break;226	case H2_ENABLE_ENCRYPTION:227		if (input->rxstatus_read != PASS ||228				input->reauth_request_check != PASS) {229			/*230			 * 1A-07: restart hdcp on REAUTH_REQ231			 * 1B-08: restart hdcp on REAUTH_REQ232			 */233			fail_and_restart_in_ms(0, &status, output);234			break;235		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {236			callback_in_ms(0, output);237			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);238			break;239		} else if (input->enable_encryption != PASS) {240			fail_and_restart_in_ms(0, &status, output);241			break;242		}243		callback_in_ms(0, output);244		set_state_id(hdcp, output, H2_A5_AUTHENTICATED);245		set_auth_complete(hdcp, output);246		break;247	case H2_A5_AUTHENTICATED:248		if (input->rxstatus_read == FAIL ||249				input->reauth_request_check == FAIL) {250			fail_and_restart_in_ms(0, &status, output);251			break;252		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {253			callback_in_ms(0, output);254			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);255			break;256		}257		callback_in_ms(500, output);258		increment_stay_counter(hdcp);259		break;260	case H2_A6_WAIT_FOR_RX_ID_LIST:261		if (input->rxstatus_read != PASS ||262				input->reauth_request_check != PASS) {263			fail_and_restart_in_ms(0, &status, output);264			break;265		} else if (!event_ctx->rx_id_list_ready) {266			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {267				/* 1B-02: consider rx id list timeout a failure */268				/* some CTS equipment's actual timeout269				 * measurement is slightly greater than 3000 ms.270				 * Delay 100 ms to ensure it is fully timeout271				 * before re-authentication.272				 */273				fail_and_restart_in_ms(100, &status, output);274			} else {275				callback_in_ms(300, output);276				increment_stay_counter(hdcp);277			}278			break;279		}280		callback_in_ms(0, output);281		set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);282		break;283	case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:284		if (input->rxstatus_read != PASS ||285				input->reauth_request_check != PASS ||286				input->rx_id_list_read != PASS ||287				input->device_count_check != PASS ||288				input->rx_id_list_validation != PASS ||289				input->repeater_auth_ack_write != PASS) {290			/* 1B-03: consider invalid v' a failure291			 * 1B-04: consider MAX_DEVS_EXCEEDED a failure292			 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure293			 * 1B-06: consider invalid seq_num_V a failure294			 * 1B-09: consider seq_num_V rollover a failure295			 */296			fail_and_restart_in_ms(0, &status, output);297			break;298		}299		callback_in_ms(0, output);300		set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);301		break;302	case H2_A9_SEND_STREAM_MANAGEMENT:303		if (input->rxstatus_read != PASS ||304				input->reauth_request_check != PASS) {305			fail_and_restart_in_ms(0, &status, output);306			break;307		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {308			callback_in_ms(0, output);309			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);310			break;311		} else if (input->prepare_stream_manage != PASS ||312				input->stream_manage_write != PASS) {313			fail_and_restart_in_ms(0, &status, output);314			break;315		}316		set_watchdog_in_ms(hdcp, 100, output);317		callback_in_ms(0, output);318		set_state_id(hdcp, output, H2_A9_VALIDATE_STREAM_READY);319		break;320	case H2_A9_VALIDATE_STREAM_READY:321		if (input->rxstatus_read != PASS ||322				input->reauth_request_check != PASS) {323			fail_and_restart_in_ms(0, &status, output);324			break;325		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {326			callback_in_ms(0, output);327			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);328			break;329		} else if (input->stream_ready_available != PASS) {330			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {331				/* 1B-10-2: restart content stream management on332				 * stream ready timeout333				 */334				hdcp->auth.count.stream_management_retry_count++;335				callback_in_ms(0, output);336				set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);337			} else {338				callback_in_ms(10, output);339				increment_stay_counter(hdcp);340			}341			break;342		} else if (input->stream_ready_read != PASS ||343				input->stream_ready_validation != PASS) {344			/*345			 * 1B-10-1: restart content stream management346			 * on invalid M'347			 */348			if (hdcp->auth.count.stream_management_retry_count > 10) {349				fail_and_restart_in_ms(0, &status, output);350			} else {351				hdcp->auth.count.stream_management_retry_count++;352				callback_in_ms(0, output);353				set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);354			}355			break;356		}357		callback_in_ms(200, output);358		set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION);359		break;360	default:361		status = MOD_HDCP_STATUS_INVALID_STATE;362		fail_and_restart_in_ms(0, &status, output);363		break;364	}365 366	return status;367}368 369enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,370		struct mod_hdcp_event_context *event_ctx,371		struct mod_hdcp_transition_input_hdcp2 *input,372		struct mod_hdcp_output *output)373{374	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;375	struct mod_hdcp_connection *conn = &hdcp->connection;376	struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;377 378	switch (current_state(hdcp)) {379	case D2_A0_DETERMINE_RX_HDCP_CAPABLE:380		if (input->rx_caps_read_dp != PASS ||381				input->hdcp2_capable_check != PASS) {382			adjust->hdcp2.disable = 1;383			callback_in_ms(0, output);384			set_state_id(hdcp, output, HDCP_INITIALIZED);385		} else {386			callback_in_ms(0, output);387			set_state_id(hdcp, output, D2_A1_SEND_AKE_INIT);388		}389		break;390	case D2_A1_SEND_AKE_INIT:391		if (input->create_session != PASS ||392				input->ake_init_prepare != PASS) {393			/* out of sync with psp state */394			adjust->hdcp2.disable = 1;395			fail_and_restart_in_ms(0, &status, output);396			break;397		} else if (input->ake_init_write != PASS) {398			/* possibly display not ready */399			fail_and_restart_in_ms(0, &status, output);400			break;401		}402		callback_in_ms(100, output);403		set_state_id(hdcp, output, D2_A1_VALIDATE_AKE_CERT);404		break;405	case D2_A1_VALIDATE_AKE_CERT:406		if (input->ake_cert_read != PASS ||407				input->ake_cert_validation != PASS) {408			/*409			 * 1A-08: consider invalid ake cert a failure410			 * 1A-09: consider receiver id listed in SRM a failure411			 */412			fail_and_restart_in_ms(0, &status, output);413			break;414		}415		if (conn->is_km_stored &&416				!adjust->hdcp2.force_no_stored_km) {417			callback_in_ms(0, output);418			set_state_id(hdcp, output, D2_A1_SEND_STORED_KM);419		} else {420			callback_in_ms(0, output);421			set_state_id(hdcp, output, D2_A1_SEND_NO_STORED_KM);422		}423		break;424	case D2_A1_SEND_NO_STORED_KM:425		if (input->no_stored_km_write != PASS) {426			fail_and_restart_in_ms(0, &status, output);427			break;428		}429		if (adjust->hdcp2.increase_h_prime_timeout)430			set_watchdog_in_ms(hdcp, 2000, output);431		else432			set_watchdog_in_ms(hdcp, 1000, output);433		set_state_id(hdcp, output, D2_A1_READ_H_PRIME);434		break;435	case D2_A1_READ_H_PRIME:436		if (input->h_prime_available != PASS) {437			if (event_ctx->event ==438					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)439				/* 1A-10-3: consider h' timeout a failure */440				fail_and_restart_in_ms(1000, &status, output);441			else442				increment_stay_counter(hdcp);443			break;444		} else if (input->h_prime_read != PASS) {445			fail_and_restart_in_ms(0, &status, output);446			break;447		}448		set_watchdog_in_ms(hdcp, 200, output);449		set_state_id(hdcp, output, D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME);450		break;451	case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:452		if (input->pairing_available != PASS) {453			if (event_ctx->event ==454					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)455				/*456				 * 1A-11: consider pairing info timeout457				 * a failure458				 */459				fail_and_restart_in_ms(0, &status, output);460			else461				increment_stay_counter(hdcp);462			break;463		} else if (input->pairing_info_read != PASS ||464				input->h_prime_validation != PASS) {465			/* 1A-10-1: consider invalid h' a failure */466			fail_and_restart_in_ms(0, &status, output);467			break;468		}469		callback_in_ms(0, output);470		set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK);471		break;472	case D2_A1_SEND_STORED_KM:473		if (input->stored_km_write != PASS) {474			fail_and_restart_in_ms(0, &status, output);475			break;476		}477		set_watchdog_in_ms(hdcp, 200, output);478		set_state_id(hdcp, output, D2_A1_VALIDATE_H_PRIME);479		break;480	case D2_A1_VALIDATE_H_PRIME:481		if (input->h_prime_available != PASS) {482			if (event_ctx->event ==483					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)484				/* 1A-10-2: consider h' timeout a failure */485				fail_and_restart_in_ms(1000, &status, output);486			else487				increment_stay_counter(hdcp);488			break;489		} else if (input->h_prime_read != PASS) {490			fail_and_restart_in_ms(0, &status, output);491			break;492		} else if (input->h_prime_validation != PASS) {493			/* 1A-10-1: consider invalid h' a failure */494			adjust->hdcp2.force_no_stored_km = 1;495			fail_and_restart_in_ms(0, &status, output);496			break;497		}498		callback_in_ms(0, output);499		set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK);500		break;501	case D2_A2_LOCALITY_CHECK:502		if (hdcp->state.stay_count > 10 ||503				input->lc_init_prepare != PASS ||504				input->lc_init_write != PASS ||505				input->l_prime_read != PASS) {506			/* 1A-12: consider invalid l' a failure */507			fail_and_restart_in_ms(0, &status, output);508			break;509		} else if (input->l_prime_validation != PASS) {510			callback_in_ms(0, output);511			increment_stay_counter(hdcp);512			break;513		}514		callback_in_ms(0, output);515		set_state_id(hdcp, output, D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER);516		break;517	case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER:518		if (input->eks_prepare != PASS ||519				input->eks_write != PASS) {520			fail_and_restart_in_ms(0, &status, output);521			break;522		}523		if (conn->is_repeater) {524			set_watchdog_in_ms(hdcp, 3000, output);525			set_state_id(hdcp, output, D2_A6_WAIT_FOR_RX_ID_LIST);526		} else {527			callback_in_ms(1, output);528			set_state_id(hdcp, output, D2_SEND_CONTENT_STREAM_TYPE);529		}530		break;531	case D2_SEND_CONTENT_STREAM_TYPE:532		if (input->rxstatus_read != PASS ||533				input->reauth_request_check != PASS ||534				input->link_integrity_check_dp != PASS ||535				input->content_stream_type_write != PASS) {536			fail_and_restart_in_ms(0, &status, output);537			break;538		}539		callback_in_ms(210, output);540		set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION);541		break;542	case D2_ENABLE_ENCRYPTION:543		if (input->rxstatus_read != PASS ||544				input->reauth_request_check != PASS ||545				input->link_integrity_check_dp != PASS) {546			/*547			 * 1A-07: restart hdcp on REAUTH_REQ548			 * 1B-08: restart hdcp on REAUTH_REQ549			 */550			fail_and_restart_in_ms(0, &status, output);551			break;552		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {553			callback_in_ms(0, output);554			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);555			break;556		} else if (input->enable_encryption != PASS ||557				(is_dp_mst_hdcp(hdcp) && input->stream_encryption_dp != PASS)) {558			fail_and_restart_in_ms(0, &status, output);559			break;560		}561		set_state_id(hdcp, output, D2_A5_AUTHENTICATED);562		set_auth_complete(hdcp, output);563		break;564	case D2_A5_AUTHENTICATED:565		if (input->rxstatus_read == FAIL ||566				input->reauth_request_check == FAIL) {567			fail_and_restart_in_ms(100, &status, output);568			break;569		} else if (input->link_integrity_check_dp == FAIL) {570			if (hdcp->connection.hdcp2_retry_count >= 1)571				adjust->hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;572			fail_and_restart_in_ms(0, &status, output);573			break;574		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {575			callback_in_ms(0, output);576			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);577			break;578		}579		increment_stay_counter(hdcp);580		break;581	case D2_A6_WAIT_FOR_RX_ID_LIST:582		if (input->rxstatus_read != PASS ||583				input->reauth_request_check != PASS ||584				input->link_integrity_check_dp != PASS) {585			fail_and_restart_in_ms(0, &status, output);586			break;587		} else if (!event_ctx->rx_id_list_ready) {588			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)589				/* 1B-02: consider rx id list timeout a failure */590				fail_and_restart_in_ms(0, &status, output);591			else592				increment_stay_counter(hdcp);593			break;594		}595		callback_in_ms(0, output);596		set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);597		break;598	case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:599		if (input->rxstatus_read != PASS ||600				input->reauth_request_check != PASS ||601				input->link_integrity_check_dp != PASS ||602				input->rx_id_list_read != PASS ||603				input->device_count_check != PASS ||604				input->rx_id_list_validation != PASS ||605				input->repeater_auth_ack_write != PASS) {606			/*607			 * 1B-03: consider invalid v' a failure608			 * 1B-04: consider MAX_DEVS_EXCEEDED a failure609			 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure610			 * 1B-06: consider invalid seq_num_V a failure611			 * 1B-09: consider seq_num_V rollover a failure612			 */613			fail_and_restart_in_ms(0, &status, output);614			break;615		}616		callback_in_ms(0, output);617		set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT);618		break;619	case D2_A9_SEND_STREAM_MANAGEMENT:620		if (input->rxstatus_read != PASS ||621				input->reauth_request_check != PASS ||622				input->link_integrity_check_dp != PASS) {623			fail_and_restart_in_ms(0, &status, output);624			break;625		} else if (event_ctx->rx_id_list_ready) {626			callback_in_ms(0, output);627			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);628			break;629		} else if (input->prepare_stream_manage != PASS ||630				input->stream_manage_write != PASS) {631			if (event_ctx->event == MOD_HDCP_EVENT_CALLBACK)632				fail_and_restart_in_ms(0, &status, output);633			else634				increment_stay_counter(hdcp);635			break;636		}637		callback_in_ms(100, output);638		set_state_id(hdcp, output, D2_A9_VALIDATE_STREAM_READY);639		break;640	case D2_A9_VALIDATE_STREAM_READY:641		if (input->rxstatus_read != PASS ||642				input->reauth_request_check != PASS ||643				input->link_integrity_check_dp != PASS) {644			fail_and_restart_in_ms(0, &status, output);645			break;646		} else if (event_ctx->rx_id_list_ready) {647			callback_in_ms(0, output);648			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);649			break;650		} else if (input->stream_ready_read != PASS ||651				input->stream_ready_validation != PASS) {652			/*653			 * 1B-10-1: restart content stream management654			 * on invalid M'655			 * 1B-10-2: consider stream ready timeout a failure656			 */657			if (hdcp->auth.count.stream_management_retry_count > 10) {658				fail_and_restart_in_ms(0, &status, output);659			} else if (event_ctx->event == MOD_HDCP_EVENT_CALLBACK) {660				hdcp->auth.count.stream_management_retry_count++;661				callback_in_ms(0, output);662				set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT);663			} else {664				increment_stay_counter(hdcp);665			}666			break;667		}668		callback_in_ms(200, output);669		set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION);670		break;671	default:672		status = MOD_HDCP_STATUS_INVALID_STATE;673		fail_and_restart_in_ms(0, &status, output);674		break;675	}676	return status;677}678