Deleted Added
full compact
siena_mcdi.c (293937) siena_mcdi.c (293939)
1/*-
2 * Copyright (c) 2012-2015 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,

--- 15 unchanged lines hidden (view full) ---

24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2012-2015 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,

--- 15 unchanged lines hidden (view full) ---

24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/siena_mcdi.c 293937 2016-01-14 14:25:49Z arybchik $");
32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/siena_mcdi.c 293939 2016-01-14 14:28:30Z arybchik $");
33
34#include "efsys.h"
35#include "efx.h"
36#include "efx_impl.h"
37
38#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI
39
40#define SIENA_MCDI_PDU(_emip) \

--- 15 unchanged lines hidden (view full) ---

56 void
57siena_mcdi_request_copyin(
58 __in efx_nic_t *enp,
59 __in efx_mcdi_req_t *emrp,
60 __in unsigned int seq,
61 __in boolean_t ev_cpl,
62 __in boolean_t new_epoch)
63{
33
34#include "efsys.h"
35#include "efx.h"
36#include "efx_impl.h"
37
38#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI
39
40#define SIENA_MCDI_PDU(_emip) \

--- 15 unchanged lines hidden (view full) ---

56 void
57siena_mcdi_request_copyin(
58 __in efx_nic_t *enp,
59 __in efx_mcdi_req_t *emrp,
60 __in unsigned int seq,
61 __in boolean_t ev_cpl,
62 __in boolean_t new_epoch)
63{
64#if EFSYS_OPT_MCDI_LOGGING
65 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
66#endif
64 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
67 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
68 efx_dword_t hdr;
65 efx_dword_t dword;
66 unsigned int xflags;
67 unsigned int pdur;
68 unsigned int dbr;
69 unsigned int pos;
70
71 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
72 _NOTE(ARGUNUSED(new_epoch))
73
74 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
75 pdur = SIENA_MCDI_PDU(emip);
76 dbr = SIENA_MCDI_DOORBELL(emip);
77
78 xflags = 0;
79 if (ev_cpl)
80 xflags |= MCDI_HEADER_XFLAGS_EVREQ;
81
82 /* Construct the header in shared memory */
69 efx_dword_t dword;
70 unsigned int xflags;
71 unsigned int pdur;
72 unsigned int dbr;
73 unsigned int pos;
74
75 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
76 _NOTE(ARGUNUSED(new_epoch))
77
78 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
79 pdur = SIENA_MCDI_PDU(emip);
80 dbr = SIENA_MCDI_DOORBELL(emip);
81
82 xflags = 0;
83 if (ev_cpl)
84 xflags |= MCDI_HEADER_XFLAGS_EVREQ;
85
86 /* Construct the header in shared memory */
83 EFX_POPULATE_DWORD_6(dword,
87 EFX_POPULATE_DWORD_6(hdr,
84 MCDI_HEADER_CODE, emrp->emr_cmd,
85 MCDI_HEADER_RESYNC, 1,
86 MCDI_HEADER_DATALEN, emrp->emr_in_length,
87 MCDI_HEADER_SEQ, seq,
88 MCDI_HEADER_RESPONSE, 0,
89 MCDI_HEADER_XFLAGS, xflags);
88 MCDI_HEADER_CODE, emrp->emr_cmd,
89 MCDI_HEADER_RESYNC, 1,
90 MCDI_HEADER_DATALEN, emrp->emr_in_length,
91 MCDI_HEADER_SEQ, seq,
92 MCDI_HEADER_RESPONSE, 0,
93 MCDI_HEADER_XFLAGS, xflags);
90 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
94 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_TRUE);
91
95
96#if EFSYS_OPT_MCDI_LOGGING
97 if (emtp->emt_logger != NULL) {
98 emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
99 &hdr, sizeof (hdr),
100 emrp->emr_in_buf, emrp->emr_in_length);
101 }
102#endif /* EFSYS_OPT_MCDI_LOGGING */
103
104 /* Construct the payload */
92 for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
93 memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
94 MIN(sizeof (dword), emrp->emr_in_length - pos));
95 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
96 pdur + 1 + (pos >> 2), &dword, B_FALSE);
97 }
98
99 /* Ring the doorbell */
100 EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
101 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
102}
103
104 void
105siena_mcdi_request_copyout(
106 __in efx_nic_t *enp,
107 __in efx_mcdi_req_t *emrp)
108{
105 for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
106 memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
107 MIN(sizeof (dword), emrp->emr_in_length - pos));
108 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
109 pdur + 1 + (pos >> 2), &dword, B_FALSE);
110 }
111
112 /* Ring the doorbell */
113 EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
114 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
115}
116
117 void
118siena_mcdi_request_copyout(
119 __in efx_nic_t *enp,
120 __in efx_mcdi_req_t *emrp)
121{
122#if EFSYS_OPT_MCDI_LOGGING
123 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
124 efx_dword_t hdr;
125#endif
109 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
110 unsigned int pos;
111 unsigned int pdur;
112 efx_dword_t data;
113
114 pdur = SIENA_MCDI_PDU(emip);
115
116 /* Copy payload out if caller supplied buffer */
117 if (emrp->emr_out_buf != NULL) {
118 size_t bytes = MIN(emrp->emr_out_length_used,
119 emrp->emr_out_length);
120 for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
121 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
122 pdur + 1 + (pos >> 2), &data, B_FALSE);
123 memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
124 MIN(sizeof (data), bytes - pos));
125 }
126 }
126 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
127 unsigned int pos;
128 unsigned int pdur;
129 efx_dword_t data;
130
131 pdur = SIENA_MCDI_PDU(emip);
132
133 /* Copy payload out if caller supplied buffer */
134 if (emrp->emr_out_buf != NULL) {
135 size_t bytes = MIN(emrp->emr_out_length_used,
136 emrp->emr_out_length);
137 for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
138 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
139 pdur + 1 + (pos >> 2), &data, B_FALSE);
140 memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
141 MIN(sizeof (data), bytes - pos));
142 }
143 }
144
145#if EFSYS_OPT_MCDI_LOGGING
146 if (emtp->emt_logger != NULL) {
147 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE);
148
149 emtp->emt_logger(emtp->emt_context,
150 EFX_LOG_MCDI_RESPONSE,
151 &hdr, sizeof (hdr),
152 emrp->emr_out_buf, emrp->emr_out_length_used);
153 }
154#endif /* EFSYS_OPT_MCDI_LOGGING */
127}
128
129 efx_rc_t
130siena_mcdi_poll_reboot(
131 __in efx_nic_t *enp)
132{
133#ifndef EFX_GRACEFUL_MC_REBOOT
134 /*

--- 27 unchanged lines hidden (view full) ---

162 return (EIO);
163#endif
164}
165
166 __checkReturn boolean_t
167siena_mcdi_request_poll(
168 __in efx_nic_t *enp)
169{
155}
156
157 efx_rc_t
158siena_mcdi_poll_reboot(
159 __in efx_nic_t *enp)
160{
161#ifndef EFX_GRACEFUL_MC_REBOOT
162 /*

--- 27 unchanged lines hidden (view full) ---

190 return (EIO);
191#endif
192}
193
194 __checkReturn boolean_t
195siena_mcdi_request_poll(
196 __in efx_nic_t *enp)
197{
198#if EFSYS_OPT_MCDI_LOGGING
199 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
200#endif
170 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
171 efx_mcdi_req_t *emrp;
201 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
202 efx_mcdi_req_t *emrp;
172 efx_dword_t dword;
203 efx_dword_t hdr;
173 unsigned int pdur;
174 unsigned int seq;
175 unsigned int length;
176 int state;
177 efx_rc_t rc;
178
179 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
180

--- 13 unchanged lines hidden (view full) ---

194 goto fail1;
195 }
196 }
197
198 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
199 pdur = SIENA_MCDI_PDU(emip);
200
201 /* Read the command header */
204 unsigned int pdur;
205 unsigned int seq;
206 unsigned int length;
207 int state;
208 efx_rc_t rc;
209
210 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
211

--- 13 unchanged lines hidden (view full) ---

225 goto fail1;
226 }
227 }
228
229 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
230 pdur = SIENA_MCDI_PDU(emip);
231
232 /* Read the command header */
202 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
203 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
233 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE);
234 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) == 0) {
204 EFSYS_UNLOCK(enp->en_eslp, state);
205 return (B_FALSE);
206 }
207
208 /* Request complete */
209 emip->emi_pending_req = NULL;
210 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
211
212 /* Check for synchronous reboot */
235 EFSYS_UNLOCK(enp->en_eslp, state);
236 return (B_FALSE);
237 }
238
239 /* Request complete */
240 emip->emi_pending_req = NULL;
241 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
242
243 /* Check for synchronous reboot */
213 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
214 EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
244 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR) != 0 &&
245 EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN) == 0) {
215 /* Consume status word */
216 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
217 siena_mcdi_poll_reboot(enp);
218 EFSYS_UNLOCK(enp->en_eslp, state);
219 rc = EIO;
220 goto fail2;
221 }
222
223 EFSYS_UNLOCK(enp->en_eslp, state);
224
225 /* Check that the returned data is consistent */
246 /* Consume status word */
247 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
248 siena_mcdi_poll_reboot(enp);
249 EFSYS_UNLOCK(enp->en_eslp, state);
250 rc = EIO;
251 goto fail2;
252 }
253
254 EFSYS_UNLOCK(enp->en_eslp, state);
255
256 /* Check that the returned data is consistent */
226 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
227 EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
257 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) != emrp->emr_cmd ||
258 EFX_DWORD_FIELD(hdr, MCDI_HEADER_SEQ) != seq) {
228 /* Response is for a different request */
229 rc = EIO;
230 goto fail3;
231 }
232
259 /* Response is for a different request */
260 rc = EIO;
261 goto fail3;
262 }
263
233 length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
234 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
264 length = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN);
265 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) {
235 efx_dword_t errdword;
236 int errcode;
237
238 EFSYS_ASSERT3U(length, ==, 4);
239 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
240 pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
241 &errdword, B_FALSE);
242 errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
266 efx_dword_t errdword;
267 int errcode;
268
269 EFSYS_ASSERT3U(length, ==, 4);
270 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
271 pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
272 &errdword, B_FALSE);
273 errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
274
275#if EFSYS_OPT_MCDI_LOGGING
276 if (emtp->emt_logger != NULL) {
277 emtp->emt_logger(emtp->emt_context,
278 EFX_LOG_MCDI_RESPONSE,
279 &hdr, sizeof (hdr),
280 &errdword, sizeof (errdword));
281 }
282#endif /* EFSYS_OPT_MCDI_LOGGING */
283
243 rc = efx_mcdi_request_errcode(errcode);
244 if (!emrp->emr_quiet) {
245 EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
246 int, errcode);
247 }
248 goto fail4;
249
250 } else {

--- 116 unchanged lines hidden ---
284 rc = efx_mcdi_request_errcode(errcode);
285 if (!emrp->emr_quiet) {
286 EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
287 int, errcode);
288 }
289 goto fail4;
290
291 } else {

--- 116 unchanged lines hidden ---