Commit 9ef23f05 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld Committed by Oded Gabbay
Browse files

accel/habanalabs: add helper to extract the FW major/minor



the helper is extract_u32_until_given_char and can later be used to
also get the major/minor of the sw version.

Signed-off-by: default avatarDafna Hirschfeld <dhirschfeld@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent f9b60242
Loading
Loading
Loading
Loading
+45 −24
Original line number Diff line number Diff line
@@ -71,38 +71,59 @@ static char *extract_fw_ver_from_str(const char *fw_str)
	return NULL;
}

static int hl_get_preboot_major_minor(struct hl_device *hdev, char *preboot_ver)
/**
 * extract_u32_until_given_char() - given a string of the format "<u32><char>*", extract the u32.
 * @str: the given string
 * @ver_num: the pointer to the extracted u32 to be returned to the caller.
 * @given_char: the given char at the end of the u32 in the string
 *
 * Return: Upon success, return a pointer to the given_char in the string. Upon failure, return NULL
 */
static char *extract_u32_until_given_char(char *str, u32 *ver_num, char given_char)
{
	char major[8], minor[8], *first_dot, *second_dot;
	int rc;
	char num_str[8] = {}, *ch;

	first_dot = strnstr(preboot_ver, ".", 10);
	if (first_dot) {
		strscpy(major, preboot_ver, first_dot - preboot_ver + 1);
		rc = kstrtou32(major, 10, &hdev->fw_major_version);
	} else {
		rc = -EINVAL;
	ch = strchrnul(str, given_char);
	if (*ch == '\0' || ch == str || ch - str >= sizeof(num_str))
		return NULL;

	memcpy(num_str, str, ch - str);
	if (kstrtou32(num_str, 10, ver_num))
		return NULL;
	return ch;
}

	if (rc) {
		dev_err(hdev->dev, "Error %d parsing preboot major version\n", rc);
		return rc;
/**
 * hl_get_preboot_major_minor() - extract the FW's version major, minor from the version string.
 * @hdev: pointer to the hl_device
 * @preboot_ver: the FW's version string
 *
 * preboot_ver is expected to be the format of <major>.<minor>.<sub minor>*, e.g: 42.0.1-sec-3
 * The extracted version is set in the hdev fields: fw_inner_{major/minor}_ver.
 *
 * Return: 0 on success, negative error code for failure.
 */
static int hl_get_preboot_major_minor(struct hl_device *hdev, char *preboot_ver)
{
	preboot_ver = extract_u32_until_given_char(preboot_ver, &hdev->fw_major_version, '.');
	if (!preboot_ver) {
		dev_err(hdev->dev, "Error parsing preboot major version\n");
		goto err_zero_ver;
	}

	/* skip the first dot */
	first_dot++;
	preboot_ver++;

	second_dot = strnstr(first_dot, ".", 10);
	if (second_dot) {
		strscpy(minor, first_dot, second_dot - first_dot + 1);
		rc = kstrtou32(minor, 10, &hdev->fw_minor_version);
	} else {
		rc = -EINVAL;
	preboot_ver = extract_u32_until_given_char(preboot_ver, &hdev->fw_minor_version, '.');
	if (!preboot_ver) {
		dev_err(hdev->dev, "Error parsing preboot minor version\n");
		goto err_zero_ver;
	}
	return 0;

	if (rc)
		dev_err(hdev->dev, "Error %d parsing preboot minor version\n", rc);
	return rc;
err_zero_ver:
	hdev->fw_major_version = 0;
	hdev->fw_minor_version = 0;
	return -EINVAL;
}

static int hl_request_fw(struct hl_device *hdev,