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