diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c index 0b6b6222bd..c062d6868a 100644 --- a/drivers/mmc/rpmb.c +++ b/drivers/mmc/rpmb.c @@ -40,12 +40,6 @@ #define RPMB_ERR_CNT_EXPIRED 0x80 #define RPMB_ERR_MSK 0x7 -/* Sizes of RPMB data frame */ -#define RPMB_SZ_STUFF 196 -#define RPMB_SZ_MAC 32 -#define RPMB_SZ_DATA 256 -#define RPMB_SZ_NONCE 16 - #define SHA256_BLOCK_SIZE 64 /* Error messages */ @@ -60,20 +54,6 @@ static const char * const rpmb_err_msg[] = { "Authentication key not yet programmed", }; - -/* Structure of RPMB data frame. */ -struct s_rpmb { - unsigned char stuff[RPMB_SZ_STUFF]; - unsigned char mac[RPMB_SZ_MAC]; - unsigned char data[RPMB_SZ_DATA]; - unsigned char nonce[RPMB_SZ_NONCE]; - unsigned int write_counter; - unsigned short address; - unsigned short block_count; - unsigned short result; - unsigned short request; -}; - static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount, bool is_rel_write) { @@ -87,7 +67,7 @@ static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount, return mmc_send_cmd(mmc, &cmd, NULL); } -static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, +int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, unsigned int count, bool is_rel_write) { struct mmc_cmd cmd = {0}; @@ -107,7 +87,7 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, cmd.resp_type = MMC_RSP_R1b; data.src = (const char *)s; - data.blocks = 1; + data.blocks = count; data.blocksize = MMC_MAX_BLOCK_LEN; data.flags = MMC_DATA_WRITE; @@ -120,14 +100,14 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, } return 0; } -static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, - unsigned short expected) +int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, + unsigned int count, unsigned short expected) { struct mmc_cmd cmd = {0}; struct mmc_data data; int ret; - ret = mmc_set_blockcount(mmc, 1, false); + ret = mmc_set_blockcount(mmc, count, false); if (ret) { #ifdef CONFIG_MMC_RPMB_TRACE printf("%s:mmc_set_blockcount-> %d\n", __func__, ret); @@ -139,7 +119,7 @@ static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, cmd.resp_type = MMC_RSP_R1; data.dest = (char *)s; - data.blocks = 1; + data.blocks = count; data.blocksize = MMC_MAX_BLOCK_LEN; data.flags = MMC_DATA_READ; @@ -151,7 +131,7 @@ static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, return -1; } /* Check the response and the status */ - if (be16_to_cpu(s->request) != expected) { + if (expected && be16_to_cpu(s->request) != expected) { #ifdef CONFIG_MMC_RPMB_TRACE printf("%s:response= %x\n", __func__, be16_to_cpu(s->request)); @@ -178,7 +158,7 @@ static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected) return -1; /* Read the result */ - return mmc_rpmb_response(mmc, rpmb_frame, expected); + return mmc_rpmb_response(mmc, rpmb_frame, 1, expected); } static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len, unsigned char *output) @@ -236,7 +216,7 @@ int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter) return -1; /* Read the result */ - ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER); + ret = mmc_rpmb_response(mmc, rpmb_frame, 1, RPMB_RESP_WCOUNTER); if (ret) return ret; @@ -272,7 +252,7 @@ int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk, break; /* Read the result */ - if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA)) + if (mmc_rpmb_response(mmc, rpmb_frame, 1, RPMB_RESP_READ_DATA)) break; /* Check the HMAC if key is provided */ diff --git a/include/mmc.h b/include/mmc.h index 9ec452cd7d..1b3b380ea8 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -767,12 +767,34 @@ int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode); /* Function to modify the RST_n_FUNCTION field of EXT_CSD */ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable); /* Functions to read / write the RPMB partition */ +/* Sizes of RPMB data frame */ +#define RPMB_SZ_STUFF 196 +#define RPMB_SZ_MAC 32 +#define RPMB_SZ_DATA 256 +#define RPMB_SZ_NONCE 16 + +/* Structure of RPMB data frame. */ +struct s_rpmb { + unsigned char stuff[RPMB_SZ_STUFF]; + unsigned char mac[RPMB_SZ_MAC]; + unsigned char data[RPMB_SZ_DATA]; + unsigned char nonce[RPMB_SZ_NONCE]; + unsigned long write_counter; + unsigned short address; + unsigned short block_count; + unsigned short result; + unsigned short request; +}; int mmc_rpmb_set_key(struct mmc *mmc, void *key); int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *counter); int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk, unsigned short cnt, unsigned char *key); int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk, unsigned short cnt, unsigned char *key); +int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, + unsigned int count, bool is_rel_write); +int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, + unsigned int count, unsigned short expected); #ifdef CONFIG_CMD_BKOPS_ENABLE int mmc_set_bkops_enable(struct mmc *mmc); #endif