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 */