iPXE
mcdi.h
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Driver for Solarflare network controllers and boards
00003  *
00004  * Written by Martin Habets <mhabets@solarflare.com>
00005  *
00006  * Copyright 2012-2017 Solarflare Communications Inc.
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or any later version.
00012  *
00013  * You can also choose to distribute this program under the terms of
00014  * the Unmodified Binary Distribution Licence (as given in the file
00015  * COPYING.UBDL), provided that you have satisfied its requirements.
00016  */
00017 #ifndef SFC_MCDI_H
00018 #define SFC_MCDI_H
00019 
00020 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00021 
00022 #ifndef DIV_ROUND_UP
00023 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
00024 #endif
00025 
00026 #define MCDI_SEQ_MASK 0xf
00027 
00028 /* We expect that 16- and 32-bit fields in MCDI requests and responses
00029  * are appropriately aligned, but 64-bit fields are only
00030  * 32-bit-aligned.  Also, on Siena we must copy to the MC shared
00031  * memory strictly 32 bits at a time, so add any necessary padding.
00032  */
00033 #define MCDI_DECLARE_BUF(_name, _len)                                   \
00034         efx_dword_t _name[DIV_ROUND_UP(_len, 4)]
00035 #define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len)                        \
00036         MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8))
00037 #define _MCDI_PTR(_buf, _offset)                                        \
00038         ((u8 *)(_buf) + (_offset))
00039 #define MCDI_PTR(_buf, _field)                                          \
00040         _MCDI_PTR(_buf, MC_CMD_ ## _field ## _OFST)
00041 #define _MCDI_CHECK_ALIGN(_ofst, _align)                                \
00042         ((_ofst) + BUILD_BUG_ON_ZERO((_ofst) & (_align - 1)))
00043 #define _MCDI_DWORD(_buf, _field)                                       \
00044         ((_buf) + (_MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _OFST, 4) >> 2))
00045 
00046 #define MCDI_WORD(_buf, _field)                                         \
00047         ((u16)BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) +       \
00048          le16_to_cpu(*(__force const __le16 *)MCDI_PTR(_buf, _field)))
00049 #define MCDI_SET_DWORD(_buf, _field, _value)                            \
00050         EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value)
00051 #define MCDI_DWORD(_buf, _field)                                        \
00052         EFX_DWORD_FIELD(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0)
00053 #define MCDI_POPULATE_DWORD_1(_buf, _field, _name1, _value1)            \
00054         EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field),                \
00055                              MC_CMD_ ## _name1, _value1)
00056 #define MCDI_POPULATE_DWORD_2(_buf, _field, _name1, _value1,            \
00057                               _name2, _value2)                          \
00058         EFX_POPULATE_DWORD_2(*_MCDI_DWORD(_buf, _field),                \
00059                              MC_CMD_ ## _name1, _value1,                \
00060                              MC_CMD_ ## _name2, _value2)
00061 #define MCDI_POPULATE_DWORD_3(_buf, _field, _name1, _value1,            \
00062                               _name2, _value2, _name3, _value3)         \
00063         EFX_POPULATE_DWORD_3(*_MCDI_DWORD(_buf, _field),                \
00064                              MC_CMD_ ## _name1, _value1,                \
00065                              MC_CMD_ ## _name2, _value2,                \
00066                              MC_CMD_ ## _name3, _value3)
00067 #define MCDI_POPULATE_DWORD_4(_buf, _field, _name1, _value1,            \
00068                               _name2, _value2, _name3, _value3,         \
00069                               _name4, _value4)                          \
00070         EFX_POPULATE_DWORD_4(*_MCDI_DWORD(_buf, _field),                \
00071                              MC_CMD_ ## _name1, _value1,                \
00072                              MC_CMD_ ## _name2, _value2,                \
00073                              MC_CMD_ ## _name3, _value3,                \
00074                              MC_CMD_ ## _name4, _value4)
00075 #define MCDI_POPULATE_DWORD_5(_buf, _field, _name1, _value1,            \
00076                               _name2, _value2, _name3, _value3,         \
00077                               _name4, _value4, _name5, _value5)         \
00078         EFX_POPULATE_DWORD_5(*_MCDI_DWORD(_buf, _field),                \
00079                              MC_CMD_ ## _name1, _value1,                \
00080                              MC_CMD_ ## _name2, _value2,                \
00081                              MC_CMD_ ## _name3, _value3,                \
00082                              MC_CMD_ ## _name4, _value4,                \
00083                              MC_CMD_ ## _name5, _value5)
00084 #define MCDI_POPULATE_DWORD_6(_buf, _field, _name1, _value1,            \
00085                               _name2, _value2, _name3, _value3,         \
00086                               _name4, _value4, _name5, _value5,         \
00087                               _name6, _value6)                          \
00088         EFX_POPULATE_DWORD_6(*_MCDI_DWORD(_buf, _field),                \
00089                              MC_CMD_ ## _name1, _value1,                \
00090                              MC_CMD_ ## _name2, _value2,                \
00091                              MC_CMD_ ## _name3, _value3,                \
00092                              MC_CMD_ ## _name4, _value4,                \
00093                              MC_CMD_ ## _name5, _value5,                \
00094                              MC_CMD_ ## _name6, _value6)
00095 #define MCDI_POPULATE_DWORD_7(_buf, _field, _name1, _value1,            \
00096                               _name2, _value2, _name3, _value3,         \
00097                               _name4, _value4, _name5, _value5,         \
00098                               _name6, _value6, _name7, _value7)         \
00099         EFX_POPULATE_DWORD_7(*_MCDI_DWORD(_buf, _field),                \
00100                              MC_CMD_ ## _name1, _value1,                \
00101                              MC_CMD_ ## _name2, _value2,                \
00102                              MC_CMD_ ## _name3, _value3,                \
00103                              MC_CMD_ ## _name4, _value4,                \
00104                              MC_CMD_ ## _name5, _value5,                \
00105                              MC_CMD_ ## _name6, _value6,                \
00106                              MC_CMD_ ## _name7, _value7)
00107 #define MCDI_SET_QWORD(_buf, _field, _value)                            \
00108         do {                                                            \
00109                 EFX_POPULATE_DWORD_1(_MCDI_DWORD(_buf, _field)[0],      \
00110                                      EFX_DWORD_0, (u32)(_value));       \
00111                 EFX_POPULATE_DWORD_1(_MCDI_DWORD(_buf, _field)[1],      \
00112                                      EFX_DWORD_0, (u64)(_value) >> 32); \
00113         } while (0)
00114 #define MCDI_QWORD(_buf, _field)                                        \
00115         (EFX_DWORD_FIELD(_MCDI_DWORD(_buf, _field)[0], EFX_DWORD_0) |   \
00116         (u64)EFX_DWORD_FIELD(_MCDI_DWORD(_buf, _field)[1], EFX_DWORD_0) << 32)
00117 #define MCDI_FIELD(_ptr, _type, _field)                                 \
00118         EFX_EXTRACT_DWORD(                                              \
00119                 *(efx_dword_t *)                                        \
00120                 _MCDI_PTR(_ptr, MC_CMD_ ## _type ## _ ## _field ## _OFST & ~3),\
00121                 MC_CMD_ ## _type ## _ ## _field ## _LBN & 0x1f, \
00122                 (MC_CMD_ ## _type ## _ ## _field ## _LBN & 0x1f) +      \
00123                 MC_CMD_ ## _type ## _ ## _field ## _WIDTH - 1)
00124 
00125 #define _MCDI_ARRAY_PTR(_buf, _field, _index, _align)                   \
00126         (_MCDI_PTR(_buf, _MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _OFST, _align))\
00127          + (_index) * _MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _LEN, _align))
00128 #define MCDI_DECLARE_STRUCT_PTR(_name)                                  \
00129         efx_dword_t *_name
00130 #define MCDI_ARRAY_STRUCT_PTR(_buf, _field, _index)                     \
00131         ((efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
00132 #define MCDI_VAR_ARRAY_LEN(_len, _field)                                \
00133         min_t(size_t, MC_CMD_ ## _field ## _MAXNUM,                     \
00134               ((_len) - MC_CMD_ ## _field ## _OFST) / MC_CMD_ ## _field ## _LEN)
00135 #define MCDI_ARRAY_WORD(_buf, _field, _index)                           \
00136         (BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) +            \
00137          le16_to_cpu(*(__force const __le16 *)                          \
00138                      _MCDI_ARRAY_PTR(_buf, _field, _index, 2)))
00139 #define _MCDI_ARRAY_DWORD(_buf, _field, _index)                         \
00140         (BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 4) +            \
00141          (efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
00142 #define MCDI_SET_ARRAY_DWORD(_buf, _field, _index, _value)              \
00143         EFX_SET_DWORD_FIELD(*_MCDI_ARRAY_DWORD(_buf, _field, _index),   \
00144                             EFX_DWORD_0, _value)
00145 #define MCDI_ARRAY_DWORD(_buf, _field, _index)                          \
00146         EFX_DWORD_FIELD(*_MCDI_ARRAY_DWORD(_buf, _field, _index), EFX_DWORD_0)
00147 #define _MCDI_ARRAY_QWORD(_buf, _field, _index)                         \
00148         (BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 8) +            \
00149          (efx_dword_t *)_MCDI_ARRAY_PTR(_buf, _field, _index, 4))
00150 #define MCDI_SET_ARRAY_QWORD(_buf, _field, _index, _value)              \
00151         do {                                                            \
00152                 EFX_SET_DWORD_FIELD(_MCDI_ARRAY_QWORD(_buf, _field, _index)[0],\
00153                                     EFX_DWORD_0, (u32)(_value));        \
00154                 EFX_SET_DWORD_FIELD(_MCDI_ARRAY_QWORD(_buf, _field, _index)[1],\
00155                                     EFX_DWORD_0, (u64)(_value) >> 32);  \
00156         } while (0)
00157 #define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2)         \
00158         MCDI_FIELD(MCDI_ARRAY_STRUCT_PTR(_buf, _field1, _index),        \
00159                    _type ## _TYPEDEF, _field2)
00160 
00161 #define MCDI_EVENT_FIELD(_ev, _field)                   \
00162         EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
00163 
00164 #endif