Merge tag 'perf-tools-fixes-for-v5.14-2021-07-18' of git://git.kernel.org/pub/scm...
[linux-block.git] / drivers / firmware / turris-mox-rwtm.c
index 62f0d1a5dd3242404a7748e644de572ae05fdc0d..c2d34dc8ba462828a428ee26899193c40b8c8889 100644 (file)
@@ -147,11 +147,14 @@ MOX_ATTR_RO(pubkey, "%s\n", pubkey);
 
 static int mox_get_status(enum mbox_cmd cmd, u32 retval)
 {
-       if (MBOX_STS_CMD(retval) != cmd ||
-           MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS)
+       if (MBOX_STS_CMD(retval) != cmd)
                return -EIO;
        else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL)
                return -(int)MBOX_STS_VALUE(retval);
+       else if (MBOX_STS_ERROR(retval) == MBOX_STS_BADCMD)
+               return -ENOSYS;
+       else if (MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS)
+               return -EIO;
        else
                return MBOX_STS_VALUE(retval);
 }
@@ -201,11 +204,14 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
                return ret;
 
        ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval);
-       if (ret < 0 && ret != -ENODATA) {
-               return ret;
-       } else if (ret == -ENODATA) {
+       if (ret == -ENODATA) {
                dev_warn(rwtm->dev,
                         "Board does not have manufacturing information burned!\n");
+       } else if (ret == -ENOSYS) {
+               dev_notice(rwtm->dev,
+                          "Firmware does not support the BOARD_INFO command\n");
+       } else if (ret < 0) {
+               return ret;
        } else {
                rwtm->serial_number = reply->status[1];
                rwtm->serial_number <<= 32;
@@ -234,10 +240,13 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
                return ret;
 
        ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval);
-       if (ret < 0 && ret != -ENODATA) {
-               return ret;
-       } else if (ret == -ENODATA) {
+       if (ret == -ENODATA) {
                dev_warn(rwtm->dev, "Board has no public key burned!\n");
+       } else if (ret == -ENOSYS) {
+               dev_notice(rwtm->dev,
+                          "Firmware does not support the ECDSA_PUB_KEY command\n");
+       } else if (ret < 0) {
+               return ret;
        } else {
                u32 *s = reply->status;
 
@@ -251,6 +260,27 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
        return 0;
 }
 
+static int check_get_random_support(struct mox_rwtm *rwtm)
+{
+       struct armada_37xx_rwtm_tx_msg msg;
+       int ret;
+
+       msg.command = MBOX_CMD_GET_RANDOM;
+       msg.args[0] = 1;
+       msg.args[1] = rwtm->buf_phys;
+       msg.args[2] = 4;
+
+       ret = mbox_send_message(rwtm->mbox, &msg);
+       if (ret < 0)
+               return ret;
+
+       ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
+       if (ret < 0)
+               return ret;
+
+       return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
+}
+
 static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
        struct mox_rwtm *rwtm = (struct mox_rwtm *) rng->priv;
@@ -488,6 +518,13 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev)
        if (ret < 0)
                dev_warn(dev, "Cannot read board information: %i\n", ret);
 
+       ret = check_get_random_support(rwtm);
+       if (ret < 0) {
+               dev_notice(dev,
+                          "Firmware does not support the GET_RANDOM command\n");
+               goto free_channel;
+       }
+
        rwtm->hwrng.name = DRIVER_NAME "_hwrng";
        rwtm->hwrng.read = mox_hwrng_read;
        rwtm->hwrng.priv = (unsigned long) rwtm;
@@ -505,6 +542,8 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev)
                goto free_channel;
        }
 
+       dev_info(dev, "HWRNG successfully registered\n");
+
        return 0;
 
 free_channel:
@@ -530,6 +569,7 @@ static int turris_mox_rwtm_remove(struct platform_device *pdev)
 
 static const struct of_device_id turris_mox_rwtm_match[] = {
        { .compatible = "cznic,turris-mox-rwtm", },
+       { .compatible = "marvell,armada-3700-rwtm-firmware", },
        { },
 };