1 /*
2 * Copyright 2007-2013 Solarflare Communications Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #include "efsys.h"
27 #include "efx.h"
28 #include "efx_types.h"
29 #include "efx_regs.h"
30 #include "efx_impl.h"
31 #include "lm87.h"
32 #include "lm87_impl.h"
33
34 #if EFSYS_OPT_MON_LM87
35
36 __checkReturn int
37 lm87_reset(
38 __in efx_nic_t *enp)
39 {
40 uint8_t devid = enp->en_u.falcon.enu_mon_devid;
41 efx_byte_t byte;
42 int rc;
43
44 /* Check we can communicate with the chip */
45 if ((rc = falcon_i2c_check(enp, devid)) != 0)
46 goto fail1;
47
48 /* Reset the chip */
49 EFX_POPULATE_BYTE_1(byte, INIT, 1);
50 if ((rc = falcon_i2c_write(enp, devid, CONFIG1_REG, (caddr_t)&byte,
51 1)) != 0)
52 goto fail2;
53
54 /* Check the company identifier and revision */
55 if ((rc = falcon_i2c_read(enp, devid, ID_REG, (caddr_t)&byte, 1)) != 0)
56 goto fail3;
57
58 if (EFX_BYTE_FIELD(byte, EFX_BYTE_0) != ID_DECODE) {
59 rc = ENODEV;
60 goto fail4;
61 }
62
63 if ((rc = falcon_i2c_read(enp, devid, REV_REG, (caddr_t)&byte, 1)) != 0)
64 goto fail5;
65
66 if (EFX_BYTE_FIELD(byte, EFX_BYTE_0) != REV_DECODE) {
67 rc = ENODEV;
68 goto fail6;
69 }
70
71 return (0);
72
73 fail6:
74 EFSYS_PROBE(fail6);
75 fail5:
76 EFSYS_PROBE(fail5);
77 fail4:
78 EFSYS_PROBE(fail4);
79 fail3:
80 EFSYS_PROBE(fail3);
81 fail2:
82 EFSYS_PROBE(fail2);
83 fail1:
84 EFSYS_PROBE1(fail1, int, rc);
85
86 return (rc);
87 }
88
89 __checkReturn int
90 lm87_reconfigure(
91 __in efx_nic_t *enp)
92 {
93 uint8_t devid = enp->en_u.falcon.enu_mon_devid;
94 efx_byte_t byte;
95 int rc;
96
97 /* Configure the channel mode to select AIN1/2 rather than FAN1/2 */
98 EFX_POPULATE_BYTE_2(byte, FAN1_AIN1, 1, FAN2_AIN2, 1);
99 if ((rc = falcon_i2c_write(enp, devid, CHANNEL_MODE_REG, (caddr_t)&byte,
100 1)) != 0)
101 goto fail1;
102
103 /* Mask out all interrupts */
104 EFX_SET_BYTE(byte);
105 if ((rc = falcon_i2c_write(enp, devid, INTERRUPT_MASK1_REG,
106 (caddr_t)&byte, 1)) != 0)
107 goto fail2;
108 if ((rc = falcon_i2c_write(enp, devid, INTERRUPT_MASK2_REG,
109 (caddr_t)&byte, 1)) != 0)
110 goto fail3;
111
112 /* Start monitoring */
113 EFX_POPULATE_BYTE_1(byte, START, 1);
114 if ((rc = falcon_i2c_write(enp, devid, CONFIG1_REG, (caddr_t)&byte,
115 1)) != 0)
116 goto fail4;
117
118 return (0);
119
120 fail4:
121 EFSYS_PROBE(fail4);
122 fail3:
123 EFSYS_PROBE(fail3);
124 fail2:
125 EFSYS_PROBE(fail2);
126 fail1:
127 EFSYS_PROBE1(fail1, int, rc);
128
129 return (rc);
130 }
131
132 #if EFSYS_OPT_MON_STATS
133
134 #define LM87_STAT_SET(_enp, _mask, _value, _id, _rc) \
135 do { \
136 uint8_t devid = enp->en_u.falcon.enu_mon_devid; \
137 efx_mon_stat_value_t *value = \
138 (_value) + EFX_MON_STAT_ ## _id; \
139 efx_byte_t byte; \
140 \
141 if (((_rc) = falcon_i2c_read((_enp), devid, \
142 VALUE_ ## _id ## _REG, (caddr_t)&byte, 1)) == 0) { \
143 uint8_t val = EFX_BYTE_FIELD(byte, EFX_BYTE_0); \
144 value->emsv_value = (uint16_t)val; \
145 value->emsv_state = 0; \
146 } \
147 \
148 (_mask) |= (1 << (EFX_MON_STAT_ ## _id)); \
149 _NOTE(CONSTANTCONDITION) \
150 } while (B_FALSE)
151
152 __checkReturn int
153 lm87_stats_update(
154 __in efx_nic_t *enp,
155 __in efsys_mem_t *esmp,
156 __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
157 {
158 uint32_t mask = 0;
159 int rc;
160
161 _NOTE(ARGUNUSED(esmp))
162
163 LM87_STAT_SET(enp, mask, values, 2_5V, rc);
164 if (rc != 0)
165 goto fail1;
166
167 LM87_STAT_SET(enp, mask, values, VCCP1, rc);
168 if (rc != 0)
169 goto fail2;
170
171 LM87_STAT_SET(enp, mask, values, VCC, rc);
172 if (rc != 0)
173 goto fail3;
174
175 LM87_STAT_SET(enp, mask, values, 5V, rc);
176 if (rc != 0)
177 goto fail4;
178
179 LM87_STAT_SET(enp, mask, values, 12V, rc);
180 if (rc != 0)
181 goto fail5;
182
183 LM87_STAT_SET(enp, mask, values, VCCP2, rc);
184 if (rc != 0)
185 goto fail6;
186
187 LM87_STAT_SET(enp, mask, values, EXT_TEMP, rc);
188 if (rc != 0)
189 goto fail7;
190
191 LM87_STAT_SET(enp, mask, values, INT_TEMP, rc);
192 if (rc != 0)
193 goto fail8;
194
195 LM87_STAT_SET(enp, mask, values, AIN1, rc);
196 if (rc != 0)
197 goto fail9;
198
199 LM87_STAT_SET(enp, mask, values, AIN2, rc);
200 if (rc != 0)
201 goto fail10;
202
203 EFSYS_ASSERT3U(mask, ==, LM87_STAT_MASK);
204
205 return (0);
206
207 fail10:
208 EFSYS_PROBE(fail10);
209 fail9:
210 EFSYS_PROBE(fail9);
211 fail8:
212 EFSYS_PROBE(fail8);
213 fail7:
214 EFSYS_PROBE(fail7);
215 fail6:
216 EFSYS_PROBE(fail6);
217 fail5:
218 EFSYS_PROBE(fail5);
219 fail4:
220 EFSYS_PROBE(fail4);
221 fail3:
222 EFSYS_PROBE(fail3);
223 fail2:
224 EFSYS_PROBE(fail2);
225 fail1:
226 EFSYS_PROBE1(fail1, int, rc);
227
228 return (rc);
229 }
230 #endif /* EFSYS_OPT_MON_STATS */
231
232 #endif /* EFSYS_OPT_MON_LM87 */