Example #1
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_start_authentication
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_start_authentication(void)
{
	int status = HDCP_OK;

	hdcp.hdcp_state = HDCP_AUTHENTICATION_START;

	printk(KERN_INFO "HDCP: authentication start\n");

	/* Step 1 part 1 (until R0 calc delay) */
	status = hdcp_lib_step1_start();

	if (status == -HDCP_AKSV_ERROR) {
		hdcp_wq_authentication_failure();
	} else if (status == -HDCP_CANCELLED_AUTH) {
		DBG("Authentication step 1 cancelled.");
		return;
	} else if (status != HDCP_OK) {
		hdcp_wq_authentication_failure();
	} else {
		hdcp.hdcp_state = HDCP_WAIT_R0_DELAY;
		hdcp.auth_state = HDCP_STATE_AUTH_1ST_STEP;
		hdcp.pending_wq_event = hdcp_submit_work(HDCP_R0_EXP_EVENT,
							 HDCP_R0_DELAY);
	}
}
Example #2
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_step2_authentication
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_step2_authentication(void)
{
	int status = HDCP_OK;

	/* KSV list timeout is running and should be canceled */
	hdcp_cancel_work(&hdcp.pending_wq_event);

	status = hdcp_lib_step2();

	if (status == -HDCP_CANCELLED_AUTH) {
		DBG("Authentication step 2 cancelled.");
		return;
	} else if (status < 0)
		hdcp_wq_authentication_failure();
	else {
		printk(KERN_INFO "HDCP: (Repeater) authentication step 2 "
				 "successful\n");

		hdcp.hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
		hdcp.auth_state = HDCP_STATE_AUTH_3RD_STEP;

		/* Restore retry counter */
		if (hdcp.en_ctrl->nb_retry == 0)
			hdcp.retry_cnt = HDCP_INFINITE_REAUTH;
		else
			hdcp.retry_cnt = hdcp.en_ctrl->nb_retry;
	}
}
Example #3
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_check_bksv
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_check_bksv(void)
{
	int status = HDCP_OK;

	DBG("Check BKSV start");
	
	status = rk30_hdcp_check_bksv(hdcp);

	if (status != HDCP_OK) {
		printk(KERN_INFO "HDCP: Check BKSV failed");
		hdcp->retry_cnt = 0;
		hdcp_wq_authentication_failure();
	}
	else {
		DBG("HDCP: Check BKSV successful");

		hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;

		/* Restore retry counter */
		if(hdcp->retry_times == 0)
			hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
		else
			hdcp->retry_cnt = hdcp->retry_times;
	}
}
Example #4
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_start_authentication
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_start_authentication(void)
{
	int status = HDCP_OK;

	hdcp->hdcp_state = HDCP_AUTHENTICATION_START;

	DBG("HDCP: authentication start");

	status = rk30_hdcp_start_authentication(hdcp);

	if (status != HDCP_OK) {
		DBG("HDCP: authentication failed");
		hdcp_wq_authentication_failure();
	} else {
		hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;
	}
}
Example #5
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_check_r0
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_check_r0(void)
{
	int status = hdcp_lib_step1_r0_check();

	if (status == -HDCP_CANCELLED_AUTH) {
		DBG("Authentication step 1/R0 cancelled.");
		return;
	} else if (status < 0)
		hdcp_wq_authentication_failure();
	else {
		if (hdcp_lib_check_repeater_bit_in_tx()) {
			/* Repeater */
			printk(KERN_INFO "HDCP: authentication step 1 "
					 "successful - Repeater\n");

			hdcp.hdcp_state = HDCP_WAIT_KSV_LIST;
			hdcp.auth_state = HDCP_STATE_AUTH_2ND_STEP;

			hdcp.pending_wq_event =
				hdcp_submit_work(HDCP_KSV_TIMEOUT_EVENT,
						 HDCP_KSV_TIMEOUT_DELAY);
		} else {
			/* Receiver */
			printk(KERN_INFO "HDCP: authentication step 1 "
					 "successful - Receiver\n");

			hdcp.hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
			hdcp.auth_state = HDCP_STATE_AUTH_3RD_STEP;

			/* Restore retry counter */
			if (hdcp.en_ctrl->nb_retry == 0)
				hdcp.retry_cnt = HDCP_INFINITE_REAUTH;
			else
				hdcp.retry_cnt = hdcp.en_ctrl->nb_retry;
		}
	}
}
Example #6
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_work_queue
 *-----------------------------------------------------------------------------
 */
static void hdcp_work_queue(struct work_struct *work)
{
	struct hdcp_delayed_work *hdcp_w =
		container_of(work, struct hdcp_delayed_work, work.work);
	int event = hdcp_w->event;

	mutex_lock(&hdcp.lock);

	hdcp_request_dss();

	DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d auth=%d evt= %x %d"
	    " hdcp_ctrl=%02x",
		jiffies_to_msecs(jiffies),
		hdcp.hdmi_state,
		hdcp.hdcp_state,
		hdcp.auth_state,
		(event & 0xFF00) >> 8,
		event & 0xFF,
		RD_REG_32(hdcp.hdmi_wp_base_addr + HDMI_IP_CORE_SYSTEM,
			  HDMI_IP_CORE_SYSTEM__HDCP_CTRL));

	/* Clear pending_wq_event
	 * In case a delayed work is scheduled from the state machine
	 * "pending_wq_event" is used to memorize pointer on the event to be
	 * able to cancel any pending work in case HDCP is disabled
	 */
	if (event & HDCP_WORKQUEUE_SRC)
		hdcp.pending_wq_event = 0;

	/* First handle HDMI state */
	if (event == HDCP_START_FRAME_EVENT) {
		hdcp.pending_start = 0;
		hdcp.hdmi_state = HDMI_STARTED;
	}
	/**********************/
	/* HDCP state machine */
	/**********************/
	switch (hdcp.hdcp_state) {

	/* State */
	/*********/
	case HDCP_DISABLED:
		/* HDCP enable control or re-authentication event */
		if (event == HDCP_ENABLE_CTL) {
			if (hdcp.en_ctrl->nb_retry == 0)
				hdcp.retry_cnt = HDCP_INFINITE_REAUTH;
			else
				hdcp.retry_cnt = hdcp.en_ctrl->nb_retry;

			if (hdcp.hdmi_state == HDMI_STARTED)
				hdcp_wq_start_authentication();
			else
				hdcp.hdcp_state = HDCP_ENABLE_PENDING;
		}

		break;

	/* State */
	/*********/
	case HDCP_ENABLE_PENDING:
		/* HDMI start frame event */
		if (event == HDCP_START_FRAME_EVENT)
			hdcp_wq_start_authentication();

		break;

	/* State */
	/*********/
	case HDCP_AUTHENTICATION_START:
		/* Re-authentication */
		if (event == HDCP_AUTH_REATT_EVENT)
			hdcp_wq_start_authentication();

		break;

	/* State */
	/*********/
	case HDCP_WAIT_R0_DELAY:
		/* R0 timer elapsed */
		if (event == HDCP_R0_EXP_EVENT)
			hdcp_wq_check_r0();

		break;

	/* State */
	/*********/
	case HDCP_WAIT_KSV_LIST:
		/* Ri failure */
		if (event == HDCP_RI_FAIL_EVENT) {
			printk(KERN_INFO "HDCP: Ri check failure\n");

			hdcp_wq_authentication_failure();
		}
		/* KSV list ready event */
		else if (event == HDCP_KSV_LIST_RDY_EVENT)
			hdcp_wq_step2_authentication();
		/* Timeout */
		else if (event == HDCP_KSV_TIMEOUT_EVENT) {
			printk(KERN_INFO "HDCP: BCAPS polling timeout\n");
			hdcp_wq_authentication_failure();
		}
		break;

	/* State */
	/*********/
	case HDCP_LINK_INTEGRITY_CHECK:
		/* Ri failure */
		if (event == HDCP_RI_FAIL_EVENT) {
			printk(KERN_INFO "HDCP: Ri check failure\n");
			hdcp_wq_authentication_failure();
		}
		break;

	default:
		printk(KERN_WARNING "HDCP: error - unknow HDCP state\n");
		break;
	}

	kfree(hdcp_w);
	hdcp_w = 0;
	if (event == HDCP_START_FRAME_EVENT)
		hdcp.pending_start = 0;
	if (event == HDCP_KSV_LIST_RDY_EVENT ||
	    event == HDCP_R0_EXP_EVENT) {
		hdcp.pending_wq_event = 0;
	}

	DBG("hdcp_work_queue() - END - %u hdmi=%d hdcp=%d auth=%d evt=%x %d ",
		jiffies_to_msecs(jiffies),
		hdcp.hdmi_state,
		hdcp.hdcp_state,
		hdcp.auth_state,
		(event & 0xFF00) >> 8,
		event & 0xFF);

	hdcp_release_dss();
	mutex_unlock(&hdcp.lock);
}
Example #7
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_work_queue
 *-----------------------------------------------------------------------------
 */
static void hdcp_work_queue(struct work_struct *work)
{
	struct hdcp_delayed_work *hdcp_w =
		container_of(work, struct hdcp_delayed_work, work.work);
	int event = hdcp_w->event;

	mutex_lock(&hdcp->lock);
	
	DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d",
		jiffies_to_msecs(jiffies),
		hdcp->hdmi_state,
		hdcp->hdcp_state,
		(event & 0xFF00) >> 8,
		event & 0xFF);
	
	if(event == HDCP_STOP_FRAME_EVENT) {
		hdcp->hdmi_state = HDMI_STOPPED;
	}
	
	if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) {
		hdcp_wq_disable(event);
	}
	
	if (event & HDCP_WORKQUEUE_SRC)
		hdcp->pending_wq_event = 0;
	
	/* First handle HDMI state */
	if (event == HDCP_START_FRAME_EVENT) {
		hdcp->pending_start = 0;
		hdcp->hdmi_state = HDMI_STARTED;
	}
	
	/**********************/
	/* HDCP state machine */
	/**********************/
	switch (hdcp->hdcp_state) {
		case HDCP_DISABLED:
			/* HDCP enable control or re-authentication event */
			if (event == HDCP_ENABLE_CTL) {
				if(hdcp->retry_times == 0)
					hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
				else
					hdcp->retry_cnt = hdcp->retry_times;
				if (hdcp->hdmi_state == HDMI_STARTED)
					hdcp_wq_start_authentication();
				else
					hdcp->hdcp_state = HDCP_ENABLE_PENDING;
			}
			break;
		
		case HDCP_ENABLE_PENDING:
			/* HDMI start frame event */
			if (event == HDCP_START_FRAME_EVENT)
				hdcp_wq_start_authentication();

			break;
		
		case HDCP_AUTHENTICATION_START:
			/* Re-authentication */
			if (event == HDCP_AUTH_REATT_EVENT)
				hdcp_wq_start_authentication();
	
			break;
		
		case HDCP_WAIT_KSV_LIST:
			/* KSV failure */
			if (event == HDCP_FAIL_EVENT) {
				printk(KERN_INFO "HDCP: KSV switch failure\n");
	
				hdcp_wq_authentication_failure();
			}
			/* KSV list ready event */
			else if (event == HDCP_KSV_LIST_RDY_EVENT)
				hdcp_wq_check_bksv();
			break;
		
		case HDCP_LINK_INTEGRITY_CHECK:
			/* Ri failure */
			if (event == HDCP_FAIL_EVENT) {
				printk(KERN_INFO "HDCP: Ri check failure\n");
				hdcp_wq_authentication_failure();
			}
			else if(event == HDCP_AUTH_PASS_EVENT)
				hdcp_wq_authentication_sucess();
			break;
	
		default:
			printk(KERN_WARNING "HDCP: error - unknow HDCP state\n");
			break;
	}
	
	kfree(hdcp_w);
	if(event == HDCP_STOP_FRAME_EVENT)
		complete(&hdcp->complete);
		
	mutex_unlock(&hdcp->lock);
}