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 "max6647.h"
32 #include "max6647_impl.h"
33
34 #if EFSYS_OPT_MON_MAX6647
35
36 __checkReturn int
37 max6647_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 if ((rc = falcon_i2c_check(enp, devid)) != 0)
45 goto fail1;
46
47 /* Reset the chip */
48 EFX_POPULATE_BYTE_2(byte, MASK, 1, NRUN, 1);
49 if ((rc = falcon_i2c_write(enp, devid, WCA_REG, (caddr_t)&byte,
50 1)) != 0)
51 goto fail2;
52
53 EFSYS_SPIN(10);
54
55 EFX_POPULATE_BYTE_2(byte, MASK, 1, NRUN, 0);
56 if ((rc = falcon_i2c_write(enp, devid, WCA_REG, (caddr_t)&byte,
57 1)) != 0)
58 goto fail3;
59
60 /* Check the company identifier and revision */
61 if ((rc = falcon_i2c_read(enp, devid, MFID_REG, (caddr_t)&byte,
62 1)) != 0)
63 goto fail2;
64
65 if (EFX_BYTE_FIELD(byte, EFX_BYTE_0) != MFID_DECODE) {
66 rc = ENODEV;
67 goto fail3;
68 }
69
70 if ((rc = falcon_i2c_read(enp, devid, REVID_REG, (caddr_t)&byte,
71 1)) != 0)
72 goto fail4;
73
74 if (EFX_BYTE_FIELD(byte, EFX_BYTE_0) != REVID_DECODE) {
75 rc = ENODEV;
76 goto fail5;
77 }
78
79 return (0);
80
81 fail5:
82 EFSYS_PROBE(fail5);
83 fail4:
84 EFSYS_PROBE(fail4);
85 fail3:
86 EFSYS_PROBE(fail3);
87 fail2:
88 EFSYS_PROBE(fail2);
89 fail1:
90 EFSYS_PROBE1(fail1, int, rc);
91
92 return (rc);
93 }
94
95 __checkReturn int
96 max6647_reconfigure(
97 __in efx_nic_t *enp)
98 {
99 uint8_t devid = enp->en_u.falcon.enu_mon_devid;
100 efx_byte_t byte;
101 int rc;
102
103 /* Clear any latched status */
104 if ((rc = falcon_i2c_read(enp, devid, RSL_REG, (caddr_t)&byte,
105 1)) != 0)
106 goto fail1;
107
108 /* Override the default alert limit */
109 EFX_POPULATE_BYTE_1(byte, EFX_BYTE_0, 90);
110 if ((rc = falcon_i2c_write(enp, devid, WLHO_REG, (caddr_t)&byte,
111 1)) != 0)
112 goto fail2;
113
114 /* Read it back and verify */
115 if ((rc = falcon_i2c_read(enp, devid, RLHN_REG, (caddr_t)&byte,
116 1)) != 0)
117 goto fail3;
118
119 if (EFX_BYTE_FIELD(byte, EFX_BYTE_0) != 90) {
120 rc = EFAULT;
121 goto fail4;
122 }
123
124 /* Enable the alert signal */
125 EFX_POPULATE_BYTE_2(byte, MASK, 0, NRUN, 0);
126 if ((rc = falcon_i2c_write(enp, devid, WCA_REG, (caddr_t)&byte,
127 1)) != 0)
128 goto fail5;
129
130 return (0);
131
132 fail5:
133 EFSYS_PROBE(fail5);
134 fail4:
135 EFSYS_PROBE(fail4);
136 fail3:
137 EFSYS_PROBE(fail3);
138 fail2:
139 EFSYS_PROBE(fail2);
140 fail1:
141 EFSYS_PROBE1(fail1, int, rc);
142
143 return (rc);
144 }
145
146 #if EFSYS_OPT_MON_STATS
147
148 #define MAX6647_STAT_SET(_enp, _value, _id, _rc) \
149 do { \
150 uint8_t devid = enp->en_u.falcon.enu_mon_devid; \
151 efx_byte_t byte; \
152 \
153 if (((_rc) = falcon_i2c_read((_enp), devid, \
154 _id ## _REG, (caddr_t)&byte, 1)) == 0) { \
155 (_value)->emsv_value = \
156 (uint16_t)EFX_BYTE_FIELD(byte, \
157 EFX_BYTE_0); \
158 (_value)->emsv_state = 0; \
159 } \
160 _NOTE(CONSTANTCONDITION) \
161 } while (B_FALSE)
162
163 __checkReturn int
164 max6647_stats_update(
165 __in efx_nic_t *enp,
166 __in efsys_mem_t *esmp,
167 __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
168 {
169 int rc;
170
171 _NOTE(ARGUNUSED(esmp))
172
173 MAX6647_STAT_SET(enp, values + EFX_MON_STAT_INT_TEMP, RLTS, rc);
174 if (rc != 0)
175 goto fail1;
176
177 MAX6647_STAT_SET(enp, values + EFX_MON_STAT_EXT_TEMP, RRTE, rc);
178 if (rc != 0)
179 goto fail2;
180
181 return (0);
182
183 fail2:
184 EFSYS_PROBE(fail2);
185 fail1:
186 EFSYS_PROBE1(fail1, int, rc);
187
188 return (rc);
189 }
190 #endif /* EFSYS_OPT_MON_STATS */
191
192 #endif /* EFSYS_OPT_MON_MAX6647 */