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