Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include <linux/delay.h>
0027 
0028 #include "hdcp.h"
0029 
0030 static inline enum mod_hdcp_status check_receiver_id_list_ready(struct mod_hdcp *hdcp)
0031 {
0032     uint8_t is_ready = 0;
0033 
0034     if (is_dp_hdcp(hdcp))
0035         is_ready = HDCP_2_2_DP_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus_dp) ? 1 : 0;
0036     else
0037         is_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus[1]) &&
0038                 (HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0039                         hdcp->auth.msg.hdcp2.rxstatus[0])) ? 1 : 0;
0040     return is_ready ? MOD_HDCP_STATUS_SUCCESS :
0041             MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
0042 }
0043 
0044 static inline enum mod_hdcp_status check_hdcp2_capable(struct mod_hdcp *hdcp)
0045 {
0046     enum mod_hdcp_status status;
0047 
0048     if (is_dp_hdcp(hdcp))
0049         status = (hdcp->auth.msg.hdcp2.rxcaps_dp[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) &&
0050                 HDCP_2_2_DP_HDCP_CAPABLE(hdcp->auth.msg.hdcp2.rxcaps_dp[2]) ?
0051                 MOD_HDCP_STATUS_SUCCESS :
0052                 MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
0053     else
0054         status = (hdcp->auth.msg.hdcp2.hdcp2version_hdmi & HDCP_2_2_HDMI_SUPPORT_MASK) ?
0055                 MOD_HDCP_STATUS_SUCCESS :
0056                 MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
0057     return status;
0058 }
0059 
0060 static inline enum mod_hdcp_status check_reauthentication_request(
0061         struct mod_hdcp *hdcp)
0062 {
0063     uint8_t ret = 0;
0064 
0065     if (is_dp_hdcp(hdcp))
0066         ret = HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
0067                 MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
0068                 MOD_HDCP_STATUS_SUCCESS;
0069     else
0070         ret = HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus[1]) ?
0071                 MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
0072                 MOD_HDCP_STATUS_SUCCESS;
0073     return ret;
0074 }
0075 
0076 static inline enum mod_hdcp_status check_link_integrity_failure_dp(
0077         struct mod_hdcp *hdcp)
0078 {
0079     return HDCP_2_2_DP_RXSTATUS_LINK_FAILED(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
0080             MOD_HDCP_STATUS_HDCP2_REAUTH_LINK_INTEGRITY_FAILURE :
0081             MOD_HDCP_STATUS_SUCCESS;
0082 }
0083 
0084 static enum mod_hdcp_status check_ake_cert_available(struct mod_hdcp *hdcp)
0085 {
0086     enum mod_hdcp_status status;
0087     uint16_t size;
0088 
0089     if (is_dp_hdcp(hdcp)) {
0090         status = MOD_HDCP_STATUS_SUCCESS;
0091     } else {
0092         status = mod_hdcp_read_rxstatus(hdcp);
0093         if (status == MOD_HDCP_STATUS_SUCCESS) {
0094             size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0095                    hdcp->auth.msg.hdcp2.rxstatus[0];
0096             status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_cert)) ?
0097                     MOD_HDCP_STATUS_SUCCESS :
0098                     MOD_HDCP_STATUS_HDCP2_AKE_CERT_PENDING;
0099         }
0100     }
0101     return status;
0102 }
0103 
0104 static enum mod_hdcp_status check_h_prime_available(struct mod_hdcp *hdcp)
0105 {
0106     enum mod_hdcp_status status;
0107     uint8_t size;
0108 
0109     status = mod_hdcp_read_rxstatus(hdcp);
0110     if (status != MOD_HDCP_STATUS_SUCCESS)
0111         goto out;
0112 
0113     if (is_dp_hdcp(hdcp)) {
0114         status = HDCP_2_2_DP_RXSTATUS_H_PRIME(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
0115                 MOD_HDCP_STATUS_SUCCESS :
0116                 MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
0117     } else {
0118         size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0119                hdcp->auth.msg.hdcp2.rxstatus[0];
0120         status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)) ?
0121                 MOD_HDCP_STATUS_SUCCESS :
0122                 MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
0123     }
0124 out:
0125     return status;
0126 }
0127 
0128 static enum mod_hdcp_status check_pairing_info_available(struct mod_hdcp *hdcp)
0129 {
0130     enum mod_hdcp_status status;
0131     uint8_t size;
0132 
0133     status = mod_hdcp_read_rxstatus(hdcp);
0134     if (status != MOD_HDCP_STATUS_SUCCESS)
0135         goto out;
0136 
0137     if (is_dp_hdcp(hdcp)) {
0138         status = HDCP_2_2_DP_RXSTATUS_PAIRING(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
0139                 MOD_HDCP_STATUS_SUCCESS :
0140                 MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
0141     } else {
0142         size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0143                hdcp->auth.msg.hdcp2.rxstatus[0];
0144         status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)) ?
0145                 MOD_HDCP_STATUS_SUCCESS :
0146                 MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
0147     }
0148 out:
0149     return status;
0150 }
0151 
0152 static enum mod_hdcp_status poll_l_prime_available(struct mod_hdcp *hdcp)
0153 {
0154     enum mod_hdcp_status status;
0155     uint8_t size;
0156     uint16_t max_wait = 20; // units of ms
0157     uint16_t num_polls = 5;
0158     uint16_t wait_time = max_wait / num_polls;
0159 
0160     if (is_dp_hdcp(hdcp))
0161         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0162     else
0163         for (; num_polls; num_polls--) {
0164             msleep(wait_time);
0165 
0166             status = mod_hdcp_read_rxstatus(hdcp);
0167             if (status != MOD_HDCP_STATUS_SUCCESS)
0168                 break;
0169 
0170             size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0171                    hdcp->auth.msg.hdcp2.rxstatus[0];
0172             status = (size == sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)) ?
0173                     MOD_HDCP_STATUS_SUCCESS :
0174                     MOD_HDCP_STATUS_HDCP2_L_PRIME_PENDING;
0175             if (status == MOD_HDCP_STATUS_SUCCESS)
0176                 break;
0177         }
0178     return status;
0179 }
0180 
0181 static enum mod_hdcp_status check_stream_ready_available(struct mod_hdcp *hdcp)
0182 {
0183     enum mod_hdcp_status status;
0184     uint8_t size;
0185 
0186     if (is_dp_hdcp(hdcp)) {
0187         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0188     } else {
0189         status = mod_hdcp_read_rxstatus(hdcp);
0190         if (status != MOD_HDCP_STATUS_SUCCESS)
0191             goto out;
0192         size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0193                hdcp->auth.msg.hdcp2.rxstatus[0];
0194         status = (size == sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)) ?
0195                 MOD_HDCP_STATUS_SUCCESS :
0196                 MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING;
0197     }
0198 out:
0199     return status;
0200 }
0201 
0202 static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
0203 {
0204     return HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
0205             (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
0206 }
0207 
0208 static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
0209 {
0210     /* Avoid device count == 0 to do authentication */
0211     if (0 == get_device_count(hdcp)) {
0212         return MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE;
0213     }
0214 
0215     /* Some MST display may choose to report the internal panel as an HDCP RX.   */
0216     /* To update this condition with 1(because the immediate repeater's internal */
0217     /* panel is possibly not included in DEVICE_COUNT) + get_device_count(hdcp). */
0218     /* Device count must be greater than or equal to tracked hdcp displays.      */
0219     return ((1 + get_device_count(hdcp)) < get_active_display_count(hdcp)) ?
0220             MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE :
0221             MOD_HDCP_STATUS_SUCCESS;
0222 }
0223 
0224 static uint8_t process_rxstatus(struct mod_hdcp *hdcp,
0225         struct mod_hdcp_event_context *event_ctx,
0226         struct mod_hdcp_transition_input_hdcp2 *input,
0227         enum mod_hdcp_status *status)
0228 {
0229     if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxstatus,
0230             &input->rxstatus_read, status,
0231             hdcp, "rxstatus_read"))
0232         goto out;
0233     if (!mod_hdcp_execute_and_set(check_reauthentication_request,
0234             &input->reauth_request_check, status,
0235             hdcp, "reauth_request_check"))
0236         goto out;
0237     if (is_dp_hdcp(hdcp)) {
0238         if (!mod_hdcp_execute_and_set(check_link_integrity_failure_dp,
0239                 &input->link_integrity_check_dp, status,
0240                 hdcp, "link_integrity_check_dp"))
0241             goto out;
0242     }
0243     if (hdcp->connection.is_repeater)
0244         if (check_receiver_id_list_ready(hdcp) ==
0245                 MOD_HDCP_STATUS_SUCCESS) {
0246             HDCP_INPUT_PASS_TRACE(hdcp, "rx_id_list_ready");
0247             event_ctx->rx_id_list_ready = 1;
0248             if (is_dp_hdcp(hdcp))
0249                 hdcp->auth.msg.hdcp2.rx_id_list_size =
0250                         sizeof(hdcp->auth.msg.hdcp2.rx_id_list);
0251             else
0252                 hdcp->auth.msg.hdcp2.rx_id_list_size =
0253                     HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
0254                     hdcp->auth.msg.hdcp2.rxstatus[0];
0255         }
0256 out:
0257     return (*status == MOD_HDCP_STATUS_SUCCESS);
0258 }
0259 
0260 static enum mod_hdcp_status known_hdcp2_capable_rx(struct mod_hdcp *hdcp,
0261         struct mod_hdcp_event_context *event_ctx,
0262         struct mod_hdcp_transition_input_hdcp2 *input)
0263 {
0264     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0265 
0266     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0267         event_ctx->unexpected_event = 1;
0268         goto out;
0269     }
0270 
0271     if (!mod_hdcp_execute_and_set(mod_hdcp_read_hdcp2version,
0272             &input->hdcp2version_read, &status,
0273             hdcp, "hdcp2version_read"))
0274         goto out;
0275     if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
0276             &input->hdcp2_capable_check, &status,
0277             hdcp, "hdcp2_capable"))
0278         goto out;
0279 out:
0280     return status;
0281 }
0282 
0283 static enum mod_hdcp_status send_ake_init(struct mod_hdcp *hdcp,
0284         struct mod_hdcp_event_context *event_ctx,
0285         struct mod_hdcp_transition_input_hdcp2 *input)
0286 {
0287     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0288 
0289     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0290         event_ctx->unexpected_event = 1;
0291         goto out;
0292     }
0293 
0294     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_create_session,
0295             &input->create_session, &status,
0296             hdcp, "create_session"))
0297         goto out;
0298     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_ake_init,
0299             &input->ake_init_prepare, &status,
0300             hdcp, "ake_init_prepare"))
0301         goto out;
0302     if (!mod_hdcp_execute_and_set(mod_hdcp_write_ake_init,
0303             &input->ake_init_write, &status,
0304             hdcp, "ake_init_write"))
0305         goto out;
0306 out:
0307     return status;
0308 }
0309 
0310 static enum mod_hdcp_status validate_ake_cert(struct mod_hdcp *hdcp,
0311         struct mod_hdcp_event_context *event_ctx,
0312         struct mod_hdcp_transition_input_hdcp2 *input)
0313 {
0314     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0315 
0316 
0317     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0318             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0319         event_ctx->unexpected_event = 1;
0320         goto out;
0321     }
0322 
0323     if (is_hdmi_dvi_sl_hdcp(hdcp))
0324         if (!mod_hdcp_execute_and_set(check_ake_cert_available,
0325                 &input->ake_cert_available, &status,
0326                 hdcp, "ake_cert_available"))
0327             goto out;
0328     if (!mod_hdcp_execute_and_set(mod_hdcp_read_ake_cert,
0329             &input->ake_cert_read, &status,
0330             hdcp, "ake_cert_read"))
0331         goto out;
0332     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_ake_cert,
0333             &input->ake_cert_validation, &status,
0334             hdcp, "ake_cert_validation"))
0335         goto out;
0336 out:
0337     return status;
0338 }
0339 
0340 static enum mod_hdcp_status send_no_stored_km(struct mod_hdcp *hdcp,
0341         struct mod_hdcp_event_context *event_ctx,
0342         struct mod_hdcp_transition_input_hdcp2 *input)
0343 {
0344     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0345 
0346     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0347         event_ctx->unexpected_event = 1;
0348         goto out;
0349     }
0350 
0351     if (!mod_hdcp_execute_and_set(mod_hdcp_write_no_stored_km,
0352             &input->no_stored_km_write, &status,
0353             hdcp, "no_stored_km_write"))
0354         goto out;
0355 out:
0356     return status;
0357 }
0358 
0359 static enum mod_hdcp_status read_h_prime(struct mod_hdcp *hdcp,
0360         struct mod_hdcp_event_context *event_ctx,
0361         struct mod_hdcp_transition_input_hdcp2 *input)
0362 {
0363     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0364 
0365     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0366             event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
0367             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0368         event_ctx->unexpected_event = 1;
0369         goto out;
0370     }
0371 
0372     if (!mod_hdcp_execute_and_set(check_h_prime_available,
0373             &input->h_prime_available, &status,
0374             hdcp, "h_prime_available"))
0375         goto out;
0376 
0377     if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
0378             &input->h_prime_read, &status,
0379             hdcp, "h_prime_read"))
0380         goto out;
0381 out:
0382     return status;
0383 }
0384 
0385 static enum mod_hdcp_status read_pairing_info_and_validate_h_prime(
0386         struct mod_hdcp *hdcp,
0387         struct mod_hdcp_event_context *event_ctx,
0388         struct mod_hdcp_transition_input_hdcp2 *input)
0389 {
0390     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0391 
0392     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0393             event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
0394             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0395         event_ctx->unexpected_event = 1;
0396         goto out;
0397     }
0398 
0399     if (!mod_hdcp_execute_and_set(check_pairing_info_available,
0400             &input->pairing_available, &status,
0401             hdcp, "pairing_available"))
0402         goto out;
0403     if (!mod_hdcp_execute_and_set(mod_hdcp_read_pairing_info,
0404             &input->pairing_info_read, &status,
0405             hdcp, "pairing_info_read"))
0406         goto out;
0407     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
0408             &input->h_prime_validation, &status,
0409             hdcp, "h_prime_validation"))
0410         goto out;
0411 out:
0412     return status;
0413 }
0414 
0415 static enum mod_hdcp_status send_stored_km(struct mod_hdcp *hdcp,
0416         struct mod_hdcp_event_context *event_ctx,
0417         struct mod_hdcp_transition_input_hdcp2 *input)
0418 {
0419     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0420 
0421     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0422         event_ctx->unexpected_event = 1;
0423         goto out;
0424     }
0425 
0426     if (!mod_hdcp_execute_and_set(mod_hdcp_write_stored_km,
0427             &input->stored_km_write, &status,
0428             hdcp, "stored_km_write"))
0429         goto out;
0430 out:
0431     return status;
0432 }
0433 
0434 static enum mod_hdcp_status validate_h_prime(struct mod_hdcp *hdcp,
0435         struct mod_hdcp_event_context *event_ctx,
0436         struct mod_hdcp_transition_input_hdcp2 *input)
0437 {
0438     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0439 
0440     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0441             event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
0442             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0443         event_ctx->unexpected_event = 1;
0444         goto out;
0445     }
0446 
0447     if (!mod_hdcp_execute_and_set(check_h_prime_available,
0448             &input->h_prime_available, &status,
0449             hdcp, "h_prime_available"))
0450         goto out;
0451     if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
0452             &input->h_prime_read, &status,
0453             hdcp, "h_prime_read"))
0454         goto out;
0455     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
0456             &input->h_prime_validation, &status,
0457             hdcp, "h_prime_validation"))
0458         goto out;
0459 out:
0460     return status;
0461 }
0462 
0463 static enum mod_hdcp_status locality_check(struct mod_hdcp *hdcp,
0464         struct mod_hdcp_event_context *event_ctx,
0465         struct mod_hdcp_transition_input_hdcp2 *input)
0466 {
0467     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0468 
0469     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0470         event_ctx->unexpected_event = 1;
0471         goto out;
0472     }
0473 
0474     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_lc_init,
0475             &input->lc_init_prepare, &status,
0476             hdcp, "lc_init_prepare"))
0477         goto out;
0478     if (!mod_hdcp_execute_and_set(mod_hdcp_write_lc_init,
0479             &input->lc_init_write, &status,
0480              hdcp, "lc_init_write"))
0481         goto out;
0482     if (is_dp_hdcp(hdcp))
0483         msleep(16);
0484     else
0485         if (!mod_hdcp_execute_and_set(poll_l_prime_available,
0486                 &input->l_prime_available_poll, &status,
0487                 hdcp, "l_prime_available_poll"))
0488             goto out;
0489     if (!mod_hdcp_execute_and_set(mod_hdcp_read_l_prime,
0490             &input->l_prime_read, &status,
0491             hdcp, "l_prime_read"))
0492         goto out;
0493     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_l_prime,
0494             &input->l_prime_validation, &status,
0495             hdcp, "l_prime_validation"))
0496         goto out;
0497 out:
0498     return status;
0499 }
0500 
0501 static enum mod_hdcp_status exchange_ks_and_test_for_repeater(struct mod_hdcp *hdcp,
0502         struct mod_hdcp_event_context *event_ctx,
0503         struct mod_hdcp_transition_input_hdcp2 *input)
0504 {
0505     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0506 
0507     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0508         event_ctx->unexpected_event = 1;
0509         goto out;
0510     }
0511 
0512     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_eks,
0513             &input->eks_prepare, &status,
0514             hdcp, "eks_prepare"))
0515         goto out;
0516     if (!mod_hdcp_execute_and_set(mod_hdcp_write_eks,
0517             &input->eks_write, &status,
0518             hdcp, "eks_write"))
0519         goto out;
0520 out:
0521     return status;
0522 }
0523 
0524 static enum mod_hdcp_status enable_encryption(struct mod_hdcp *hdcp,
0525         struct mod_hdcp_event_context *event_ctx,
0526         struct mod_hdcp_transition_input_hdcp2 *input)
0527 {
0528     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0529 
0530     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0531             event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
0532         event_ctx->unexpected_event = 1;
0533         goto out;
0534     }
0535     if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
0536         process_rxstatus(hdcp, event_ctx, input, &status);
0537         goto out;
0538     }
0539 
0540     if (is_hdmi_dvi_sl_hdcp(hdcp)) {
0541         if (!process_rxstatus(hdcp, event_ctx, input, &status))
0542             goto out;
0543         if (event_ctx->rx_id_list_ready)
0544             goto out;
0545     }
0546     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_enable_encryption,
0547             &input->enable_encryption, &status,
0548             hdcp, "enable_encryption"))
0549         goto out;
0550     if (is_dp_mst_hdcp(hdcp)) {
0551         if (!mod_hdcp_execute_and_set(
0552                 mod_hdcp_hdcp2_enable_dp_stream_encryption,
0553                 &input->stream_encryption_dp, &status,
0554                 hdcp, "stream_encryption_dp"))
0555             goto out;
0556     }
0557 out:
0558     return status;
0559 }
0560 
0561 static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp,
0562         struct mod_hdcp_event_context *event_ctx,
0563         struct mod_hdcp_transition_input_hdcp2 *input)
0564 {
0565     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0566 
0567     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0568             event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
0569         event_ctx->unexpected_event = 1;
0570         goto out;
0571     }
0572 
0573     process_rxstatus(hdcp, event_ctx, input, &status);
0574 out:
0575     return status;
0576 }
0577 
0578 static enum mod_hdcp_status wait_for_rx_id_list(struct mod_hdcp *hdcp,
0579         struct mod_hdcp_event_context *event_ctx,
0580         struct mod_hdcp_transition_input_hdcp2 *input)
0581 {
0582     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0583 
0584     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0585             event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
0586             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0587         event_ctx->unexpected_event = 1;
0588         goto out;
0589     }
0590 
0591     if (!process_rxstatus(hdcp, event_ctx, input, &status))
0592         goto out;
0593     if (!event_ctx->rx_id_list_ready) {
0594         status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
0595         goto out;
0596     }
0597 out:
0598     return status;
0599 }
0600 
0601 static enum mod_hdcp_status verify_rx_id_list_and_send_ack(struct mod_hdcp *hdcp,
0602         struct mod_hdcp_event_context *event_ctx,
0603         struct mod_hdcp_transition_input_hdcp2 *input)
0604 {
0605     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0606 
0607     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0608             event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
0609         event_ctx->unexpected_event = 1;
0610         goto out;
0611     }
0612     if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
0613         process_rxstatus(hdcp, event_ctx, input, &status);
0614         goto out;
0615     }
0616 
0617     if (!mod_hdcp_execute_and_set(mod_hdcp_read_rx_id_list,
0618             &input->rx_id_list_read,
0619             &status, hdcp, "receiver_id_list_read"))
0620         goto out;
0621     if (!mod_hdcp_execute_and_set(check_device_count,
0622             &input->device_count_check,
0623             &status, hdcp, "device_count_check"))
0624         goto out;
0625     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_rx_id_list,
0626             &input->rx_id_list_validation,
0627             &status, hdcp, "rx_id_list_validation"))
0628         goto out;
0629     if (!mod_hdcp_execute_and_set(mod_hdcp_write_repeater_auth_ack,
0630             &input->repeater_auth_ack_write,
0631             &status, hdcp, "repeater_auth_ack_write"))
0632         goto out;
0633 out:
0634     return status;
0635 }
0636 
0637 static enum mod_hdcp_status send_stream_management(struct mod_hdcp *hdcp,
0638         struct mod_hdcp_event_context *event_ctx,
0639         struct mod_hdcp_transition_input_hdcp2 *input)
0640 {
0641     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0642 
0643     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0644             event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
0645         event_ctx->unexpected_event = 1;
0646         goto out;
0647     }
0648     if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
0649         process_rxstatus(hdcp, event_ctx, input, &status);
0650         goto out;
0651     }
0652 
0653     if (is_hdmi_dvi_sl_hdcp(hdcp)) {
0654         if (!process_rxstatus(hdcp, event_ctx, input, &status))
0655             goto out;
0656         if (event_ctx->rx_id_list_ready)
0657             goto out;
0658     }
0659     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_stream_management,
0660             &input->prepare_stream_manage,
0661             &status, hdcp, "prepare_stream_manage"))
0662         goto out;
0663 
0664     if (!mod_hdcp_execute_and_set(mod_hdcp_write_stream_manage,
0665             &input->stream_manage_write,
0666             &status, hdcp, "stream_manage_write"))
0667         goto out;
0668 out:
0669     return status;
0670 }
0671 
0672 static enum mod_hdcp_status validate_stream_ready(struct mod_hdcp *hdcp,
0673         struct mod_hdcp_event_context *event_ctx,
0674         struct mod_hdcp_transition_input_hdcp2 *input)
0675 {
0676     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0677 
0678     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0679             event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
0680             event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
0681         event_ctx->unexpected_event = 1;
0682         goto out;
0683     }
0684     if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
0685         process_rxstatus(hdcp, event_ctx, input, &status);
0686         goto out;
0687     }
0688 
0689     if (is_hdmi_dvi_sl_hdcp(hdcp)) {
0690         if (!process_rxstatus(hdcp, event_ctx, input, &status))
0691             goto out;
0692         if (event_ctx->rx_id_list_ready) {
0693             goto out;
0694         }
0695     }
0696     if (is_hdmi_dvi_sl_hdcp(hdcp))
0697         if (!mod_hdcp_execute_and_set(check_stream_ready_available,
0698                 &input->stream_ready_available,
0699                 &status, hdcp, "stream_ready_available"))
0700             goto out;
0701     if (!mod_hdcp_execute_and_set(mod_hdcp_read_stream_ready,
0702             &input->stream_ready_read,
0703             &status, hdcp, "stream_ready_read"))
0704         goto out;
0705     if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_stream_ready,
0706             &input->stream_ready_validation,
0707             &status, hdcp, "stream_ready_validation"))
0708         goto out;
0709 
0710 out:
0711     return status;
0712 }
0713 
0714 static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp,
0715         struct mod_hdcp_event_context *event_ctx,
0716         struct mod_hdcp_transition_input_hdcp2 *input)
0717 {
0718     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0719 
0720     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
0721         event_ctx->unexpected_event = 1;
0722         goto out;
0723     }
0724 
0725     if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxcaps,
0726             &input->rx_caps_read_dp,
0727             &status, hdcp, "rx_caps_read_dp"))
0728         goto out;
0729     if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
0730             &input->hdcp2_capable_check, &status,
0731             hdcp, "hdcp2_capable_check"))
0732         goto out;
0733 out:
0734     return status;
0735 }
0736 
0737 static enum mod_hdcp_status send_content_stream_type_dp(struct mod_hdcp *hdcp,
0738         struct mod_hdcp_event_context *event_ctx,
0739         struct mod_hdcp_transition_input_hdcp2 *input)
0740 {
0741     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0742 
0743     if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
0744             event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
0745         event_ctx->unexpected_event = 1;
0746         goto out;
0747     }
0748 
0749     if (!process_rxstatus(hdcp, event_ctx, input, &status))
0750         goto out;
0751     if (!mod_hdcp_execute_and_set(mod_hdcp_write_content_type,
0752             &input->content_stream_type_write, &status,
0753             hdcp, "content_stream_type_write"))
0754         goto out;
0755 out:
0756     return status;
0757 }
0758 
0759 enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp,
0760     struct mod_hdcp_event_context *event_ctx,
0761     struct mod_hdcp_transition_input_hdcp2 *input)
0762 {
0763     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0764 
0765     switch (current_state(hdcp)) {
0766     case H2_A0_KNOWN_HDCP2_CAPABLE_RX:
0767         status = known_hdcp2_capable_rx(hdcp, event_ctx, input);
0768         break;
0769     case H2_A1_SEND_AKE_INIT:
0770         status = send_ake_init(hdcp, event_ctx, input);
0771         break;
0772     case H2_A1_VALIDATE_AKE_CERT:
0773         status = validate_ake_cert(hdcp, event_ctx, input);
0774         break;
0775     case H2_A1_SEND_NO_STORED_KM:
0776         status = send_no_stored_km(hdcp, event_ctx, input);
0777         break;
0778     case H2_A1_READ_H_PRIME:
0779         status = read_h_prime(hdcp, event_ctx, input);
0780         break;
0781     case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
0782         status = read_pairing_info_and_validate_h_prime(hdcp,
0783                 event_ctx, input);
0784         break;
0785     case H2_A1_SEND_STORED_KM:
0786         status = send_stored_km(hdcp, event_ctx, input);
0787         break;
0788     case H2_A1_VALIDATE_H_PRIME:
0789         status = validate_h_prime(hdcp, event_ctx, input);
0790         break;
0791     case H2_A2_LOCALITY_CHECK:
0792         status = locality_check(hdcp, event_ctx, input);
0793         break;
0794     case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
0795         status = exchange_ks_and_test_for_repeater(hdcp, event_ctx, input);
0796         break;
0797     case H2_ENABLE_ENCRYPTION:
0798         status = enable_encryption(hdcp, event_ctx, input);
0799         break;
0800     case H2_A5_AUTHENTICATED:
0801         status = authenticated(hdcp, event_ctx, input);
0802         break;
0803     case H2_A6_WAIT_FOR_RX_ID_LIST:
0804         status = wait_for_rx_id_list(hdcp, event_ctx, input);
0805         break;
0806     case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
0807         status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
0808         break;
0809     case H2_A9_SEND_STREAM_MANAGEMENT:
0810         status = send_stream_management(hdcp, event_ctx, input);
0811         break;
0812     case H2_A9_VALIDATE_STREAM_READY:
0813         status = validate_stream_ready(hdcp, event_ctx, input);
0814         break;
0815     default:
0816         status = MOD_HDCP_STATUS_INVALID_STATE;
0817         break;
0818     }
0819 
0820     return status;
0821 }
0822 
0823 enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp,
0824     struct mod_hdcp_event_context *event_ctx,
0825     struct mod_hdcp_transition_input_hdcp2 *input)
0826 {
0827     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0828 
0829     switch (current_state(hdcp)) {
0830     case D2_A0_DETERMINE_RX_HDCP_CAPABLE:
0831         status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input);
0832         break;
0833     case D2_A1_SEND_AKE_INIT:
0834         status = send_ake_init(hdcp, event_ctx, input);
0835         break;
0836     case D2_A1_VALIDATE_AKE_CERT:
0837         status = validate_ake_cert(hdcp, event_ctx, input);
0838         break;
0839     case D2_A1_SEND_NO_STORED_KM:
0840         status = send_no_stored_km(hdcp, event_ctx, input);
0841         break;
0842     case D2_A1_READ_H_PRIME:
0843         status = read_h_prime(hdcp, event_ctx, input);
0844         break;
0845     case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
0846         status = read_pairing_info_and_validate_h_prime(hdcp,
0847                 event_ctx, input);
0848         break;
0849     case D2_A1_SEND_STORED_KM:
0850         status = send_stored_km(hdcp, event_ctx, input);
0851         break;
0852     case D2_A1_VALIDATE_H_PRIME:
0853         status = validate_h_prime(hdcp, event_ctx, input);
0854         break;
0855     case D2_A2_LOCALITY_CHECK:
0856         status = locality_check(hdcp, event_ctx, input);
0857         break;
0858     case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
0859         status = exchange_ks_and_test_for_repeater(hdcp,
0860                 event_ctx, input);
0861         break;
0862     case D2_SEND_CONTENT_STREAM_TYPE:
0863         status = send_content_stream_type_dp(hdcp, event_ctx, input);
0864         break;
0865     case D2_ENABLE_ENCRYPTION:
0866         status = enable_encryption(hdcp, event_ctx, input);
0867         break;
0868     case D2_A5_AUTHENTICATED:
0869         status = authenticated(hdcp, event_ctx, input);
0870         break;
0871     case D2_A6_WAIT_FOR_RX_ID_LIST:
0872         status = wait_for_rx_id_list(hdcp, event_ctx, input);
0873         break;
0874     case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
0875         status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
0876         break;
0877     case D2_A9_SEND_STREAM_MANAGEMENT:
0878         status = send_stream_management(hdcp, event_ctx, input);
0879         break;
0880     case D2_A9_VALIDATE_STREAM_READY:
0881         status = validate_stream_ready(hdcp, event_ctx, input);
0882         break;
0883     default:
0884         status = MOD_HDCP_STATUS_INVALID_STATE;
0885         break;
0886     }
0887 
0888     return status;
0889 }