1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017 Netronome Systems, Inc. */
3 
4 #include <linux/kernel.h>
5 #include <linux/slab.h>
6 
7 #include "nfp.h"
8 #include "nfp_nsp.h"
9 
10 struct nsp_identify {
11 	u8 version[40];
12 	u8 flags;
13 	u8 br_primary;
14 	u8 br_secondary;
15 	u8 br_nsp;
16 	__le16 primary;
17 	__le16 secondary;
18 	__le16 nsp;
19 	u8 reserved[6];
20 	__le64 sensor_mask;
21 };
22 
23 struct nfp_nsp_identify *__nfp_nsp_identify(struct nfp_nsp *nsp)
24 {
25 	struct nfp_nsp_identify *nspi = NULL;
26 	struct nsp_identify *ni;
27 	int ret;
28 
29 	if (nfp_nsp_get_abi_ver_minor(nsp) < 15)
30 		return NULL;
31 
32 	ni = kzalloc(sizeof(*ni), GFP_KERNEL);
33 	if (!ni)
34 		return NULL;
35 
36 	ret = nfp_nsp_read_identify(nsp, ni, sizeof(*ni));
37 	if (ret < 0) {
38 		nfp_err(nfp_nsp_cpp(nsp), "reading bsp version failed %d\n",
39 			ret);
40 		goto exit_free;
41 	}
42 
43 	nspi = kzalloc(sizeof(*nspi), GFP_KERNEL);
44 	if (!nspi)
45 		goto exit_free;
46 
47 	memcpy(nspi->version, ni->version, sizeof(nspi->version));
48 	nspi->version[sizeof(nspi->version) - 1] = '\0';
49 	nspi->flags = ni->flags;
50 	nspi->br_primary = ni->br_primary;
51 	nspi->br_secondary = ni->br_secondary;
52 	nspi->br_nsp = ni->br_nsp;
53 	nspi->primary = le16_to_cpu(ni->primary);
54 	nspi->secondary = le16_to_cpu(ni->secondary);
55 	nspi->nsp = le16_to_cpu(ni->nsp);
56 	nspi->sensor_mask = le64_to_cpu(ni->sensor_mask);
57 
58 exit_free:
59 	kfree(ni);
60 	return nspi;
61 }
62 
63 struct nfp_sensors {
64 	__le32 chip_temp;
65 	__le32 assembly_power;
66 	__le32 assembly_12v_power;
67 	__le32 assembly_3v3_power;
68 };
69 
70 int nfp_hwmon_read_sensor(struct nfp_cpp *cpp, enum nfp_nsp_sensor_id id,
71 			  long *val)
72 {
73 	struct nfp_sensors s;
74 	struct nfp_nsp *nsp;
75 	int ret;
76 
77 	nsp = nfp_nsp_open(cpp);
78 	if (IS_ERR(nsp))
79 		return PTR_ERR(nsp);
80 
81 	ret = nfp_nsp_read_sensors(nsp, BIT(id), &s, sizeof(s));
82 	nfp_nsp_close(nsp);
83 
84 	if (ret < 0)
85 		return ret;
86 
87 	switch (id) {
88 	case NFP_SENSOR_CHIP_TEMPERATURE:
89 		*val = le32_to_cpu(s.chip_temp);
90 		break;
91 	case NFP_SENSOR_ASSEMBLY_POWER:
92 		*val = le32_to_cpu(s.assembly_power);
93 		break;
94 	case NFP_SENSOR_ASSEMBLY_12V_POWER:
95 		*val = le32_to_cpu(s.assembly_12v_power);
96 		break;
97 	case NFP_SENSOR_ASSEMBLY_3V3_POWER:
98 		*val = le32_to_cpu(s.assembly_3v3_power);
99 		break;
100 	default:
101 		return -EINVAL;
102 	}
103 	return 0;
104 }
105