1 /*-
   2  * Copyright 2009 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 #ifndef _SYS_EFX_MCDI_H
  27 #define _SYS_EFX_MCDI_H
  28 
  29 #include "efx.h"
  30 #include "efx_regs.h"
  31 #include "efx_regs_mcdi.h"
  32 
  33 #ifdef  __cplusplus
  34 extern "C" {
  35 #endif
  36 
  37 /* Number of retries attempted for init code */
  38 #define EFX_MCDI_REQ_RETRY_INIT 2
  39 
  40 struct efx_mcdi_req_s {
  41         /* Inputs: Command #, input buffer and length */
  42         unsigned int    emr_cmd;
  43         uint8_t         *emr_in_buf;
  44         size_t          emr_in_length;
  45         /* Outputs: retcode, buffer, length, and length used*/
  46         int             emr_rc;
  47         uint8_t         *emr_out_buf;
  48         size_t          emr_out_length;
  49         size_t          emr_out_length_used;
  50 };
  51 
  52 typedef struct efx_mcdi_iface_s {
  53         const efx_mcdi_transport_t *emi_mtp;
  54         unsigned int            emi_port;
  55         unsigned int            emi_seq;
  56         efx_mcdi_req_t          *emi_pending_req;
  57         boolean_t               emi_ev_cpl;
  58         int                     emi_aborted;
  59         uint32_t                emi_poll_cnt;
  60 } efx_mcdi_iface_t;
  61 
  62 extern                  void
  63 efx_mcdi_execute(
  64         __in            efx_nic_t *enp,
  65         __in            efx_mcdi_req_t *emrp);
  66 
  67 extern                  void
  68 efx_mcdi_ev_cpl(
  69         __in            efx_nic_t *enp,
  70         __in            unsigned int seq,
  71         __in            unsigned int outlen,
  72         __in            int errcode);
  73 
  74 extern                  void
  75 efx_mcdi_ev_death(
  76         __in            efx_nic_t *enp,
  77         __in            int rc);
  78 
  79 typedef enum efx_mcdi_boot_e {
  80         EFX_MCDI_BOOT_PRIMARY,
  81         EFX_MCDI_BOOT_SECONDARY,
  82         EFX_MCDI_BOOT_ROM,
  83 } efx_mcdi_boot_t;
  84 
  85 extern  __checkReturn           int
  86 efx_mcdi_version(
  87         __in                    efx_nic_t *enp,
  88         __out_ecount_opt(4)     uint16_t versionp[4],
  89         __out_opt               uint32_t *buildp,
  90         __out_opt               efx_mcdi_boot_t *statusp);
  91 
  92 #define MCDI_IN(_emr, _type, _ofst)                                     \
  93         ((_type *)((_emr).emr_in_buf + (_ofst)))
  94 
  95 #define MCDI_IN2(_emr, _type, _ofst)                                    \
  96         MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST)
  97 
  98 #define MCDI_IN_SET_BYTE(_emr, _ofst, _value)                           \
  99         EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst),         \
 100                 EFX_BYTE_0, _value)
 101 
 102 #define MCDI_IN_SET_DWORD(_emr, _ofst, _value)                          \
 103         EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 104                 EFX_DWORD_0, _value)
 105 
 106 #define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1)         \
 107         EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 108                 MC_CMD_ ## _field1, _value1)
 109 
 110 #define MCDI_IN_POPULATE_DWORD_2(_emr, _ofst, _field1, _value1,         \
 111                 _field2, _value2)                                       \
 112         EFX_POPULATE_DWORD_2(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 113                 MC_CMD_ ## _field1, _value1,                            \
 114                 MC_CMD_ ## _field2, _value2)
 115 
 116 #define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1,         \
 117                 _field2, _value2, _field3, _value3)                     \
 118         EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 119                 MC_CMD_ ## _field1, _value1,                            \
 120                 MC_CMD_ ## _field2, _value2,                            \
 121                 MC_CMD_ ## _field3, _value3)
 122 
 123 #define MCDI_IN_POPULATE_DWORD_4(_emr, _ofst, _field1, _value1,         \
 124                 _field2, _value2, _field3, _value3, _field4, _value4)   \
 125         EFX_POPULATE_DWORD_4(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 126                 MC_CMD_ ## _field1, _value1,                            \
 127                 MC_CMD_ ## _field2, _value2,                            \
 128                 MC_CMD_ ## _field3, _value3,                            \
 129                 MC_CMD_ ## _field4, _value4)
 130 
 131 #define MCDI_IN_POPULATE_DWORD_5(_emr, _ofst, _field1, _value1,         \
 132                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 133                 _field5, _value5)                                       \
 134         EFX_POPULATE_DWORD_5(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 135                 MC_CMD_ ## _field1, _value1,                            \
 136                 MC_CMD_ ## _field2, _value2,                            \
 137                 MC_CMD_ ## _field3, _value3,                            \
 138                 MC_CMD_ ## _field4, _value4,                            \
 139                 MC_CMD_ ## _field5, _value5)
 140 
 141 #define MCDI_IN_POPULATE_DWORD_6(_emr, _ofst, _field1, _value1,         \
 142                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 143                 _field5, _value5, _field6, _value6)                     \
 144         EFX_POPULATE_DWORD_6(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 145                 MC_CMD_ ## _field1, _value1,                            \
 146                 MC_CMD_ ## _field2, _value2,                            \
 147                 MC_CMD_ ## _field3, _value3,                            \
 148                 MC_CMD_ ## _field4, _value4,                            \
 149                 MC_CMD_ ## _field5, _value5,                            \
 150                 MC_CMD_ ## _field6, _value6)
 151 
 152 #define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1,         \
 153                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 154                 _field5, _value5, _field6, _value6, _field7, _value7)   \
 155         EFX_POPULATE_DWORD_7(MCDI_IN2(_emr, efx_dword_t, _ofst),        \
 156                 MC_CMD_ ## _field1, _value1,                            \
 157                 MC_CMD_ ## _field2, _value2,                            \
 158                 MC_CMD_ ## _field3, _value3,                            \
 159                 MC_CMD_ ## _field4, _value4,                            \
 160                 MC_CMD_ ## _field5, _value5,                            \
 161                 MC_CMD_ ## _field6, _value6,                            \
 162                 MC_CMD_ ## _field7, _value7)
 163 
 164 #define MCDI_IN_POPULATE_DWORD_8(_emr, _ofst, _field1, _value1,         \
 165                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 166                 _field5, _value5, _field6, _value6, _field7, _value7,   \
 167                 _field8, _value8)                                       \
 168         EFX_POPULATE_DWORD_8(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 169                 MC_CMD_ ## _field1, _value1,                            \
 170                 MC_CMD_ ## _field2, _value2,                            \
 171                 MC_CMD_ ## _field3, _value3,                            \
 172                 MC_CMD_ ## _field4, _value4,                            \
 173                 MC_CMD_ ## _field5, _value5,                            \
 174                 MC_CMD_ ## _field6, _value6,                            \
 175                 MC_CMD_ ## _field7, _value7,                            \
 176                 MC_CMD_ ## _field8, _value8)
 177 
 178 #define MCDI_IN_POPULATE_DWORD_9(_emr, _ofst, _field1, _value1,         \
 179                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 180                 _field5, _value5, _field6, _value6, _field7, _value7,   \
 181                 _field8, _value8, _field9, _value9)                     \
 182         EFX_POPULATE_DWORD_9(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
 183                 MC_CMD_ ## _field1, _value1,                            \
 184                 MC_CMD_ ## _field2, _value2,                            \
 185                 MC_CMD_ ## _field3, _value3,                            \
 186                 MC_CMD_ ## _field4, _value4,                            \
 187                 MC_CMD_ ## _field5, _value5,                            \
 188                 MC_CMD_ ## _field6, _value6,                            \
 189                 MC_CMD_ ## _field7, _value7,                            \
 190                 MC_CMD_ ## _field8, _value8,                            \
 191                 MC_CMD_ ## _field9, _value9)
 192 
 193 #define MCDI_IN_POPULATE_DWORD_10(_emr, _ofst, _field1, _value1,        \
 194                 _field2, _value2, _field3, _value3, _field4, _value4,   \
 195                 _field5, _value5, _field6, _value6, _field7, _value7,   \
 196                 _field8, _value8, _field9, _value9, _field10, _value10) \
 197         EFX_POPULATE_DWORD_10(*MCDI_IN2(_emr, efx_dword_t, _ofst),      \
 198                 MC_CMD_ ## _field1, _value1,                            \
 199                 MC_CMD_ ## _field2, _value2,                            \
 200                 MC_CMD_ ## _field3, _value3,                            \
 201                 MC_CMD_ ## _field4, _value4,                            \
 202                 MC_CMD_ ## _field5, _value5,                            \
 203                 MC_CMD_ ## _field6, _value6,                            \
 204                 MC_CMD_ ## _field7, _value7,                            \
 205                 MC_CMD_ ## _field8, _value8,                            \
 206                 MC_CMD_ ## _field9, _value9,                            \
 207                 MC_CMD_ ## _field10, _value10)
 208 
 209 #define MCDI_OUT(_emr, _type, _ofst)                                    \
 210         ((_type *)((_emr).emr_out_buf + (_ofst)))
 211 
 212 #define MCDI_OUT2(_emr, _type, _ofst)                                   \
 213         MCDI_OUT(_emr, _type, MC_CMD_ ## _ofst ## _OFST)
 214 
 215 #define MCDI_OUT_BYTE(_emr, _ofst)                                      \
 216         EFX_BYTE_FIELD(*MCDI_OUT2(_emr, efx_byte_t, _ofst),             \
 217                     EFX_BYTE_0)
 218 
 219 #define MCDI_OUT_WORD(_emr, _ofst)                                      \
 220         EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst),             \
 221                     EFX_WORD_0)
 222 
 223 #define MCDI_OUT_DWORD(_emr, _ofst)                                     \
 224         EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst),           \
 225                         EFX_DWORD_0)
 226 
 227 #define MCDI_OUT_DWORD_FIELD(_emr, _ofst, _field)                       \
 228         EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst),           \
 229                         MC_CMD_ ## _field)
 230 
 231 #define MCDI_EV_FIELD(_eqp, _field)                                     \
 232         EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field)
 233 
 234 #define MCDI_CMD_DWORD_FIELD(_edp, _field)                              \
 235         EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
 236 
 237 #ifdef  __cplusplus
 238 }
 239 #endif
 240 
 241 #endif  /* _SYS_EFX_MCDI_H */