~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/net/ethernet/sfc/mcdi.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 * Driver for Solarflare Solarstorm network controllers and boards
 
3
 * Copyright 2008-2011 Solarflare Communications Inc.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License version 2 as published
 
7
 * by the Free Software Foundation, incorporated herein by reference.
 
8
 */
 
9
 
 
10
#include <linux/delay.h>
 
11
#include "net_driver.h"
 
12
#include "nic.h"
 
13
#include "io.h"
 
14
#include "regs.h"
 
15
#include "mcdi_pcol.h"
 
16
#include "phy.h"
 
17
 
 
18
/**************************************************************************
 
19
 *
 
20
 * Management-Controller-to-Driver Interface
 
21
 *
 
22
 **************************************************************************
 
23
 */
 
24
 
 
25
/* Software-defined structure to the shared-memory */
 
26
#define CMD_NOTIFY_PORT0 0
 
27
#define CMD_NOTIFY_PORT1 4
 
28
#define CMD_PDU_PORT0    0x008
 
29
#define CMD_PDU_PORT1    0x108
 
30
#define REBOOT_FLAG_PORT0 0x3f8
 
31
#define REBOOT_FLAG_PORT1 0x3fc
 
32
 
 
33
#define MCDI_RPC_TIMEOUT       10 /*seconds */
 
34
 
 
35
#define MCDI_PDU(efx)                                                   \
 
36
        (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0)
 
37
#define MCDI_DOORBELL(efx)                                              \
 
38
        (efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0)
 
39
#define MCDI_REBOOT_FLAG(efx)                                           \
 
40
        (efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0)
 
41
 
 
42
#define SEQ_MASK                                                        \
 
43
        EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ))
 
44
 
 
45
static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
 
46
{
 
47
        struct siena_nic_data *nic_data;
 
48
        EFX_BUG_ON_PARANOID(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
 
49
        nic_data = efx->nic_data;
 
50
        return &nic_data->mcdi;
 
51
}
 
52
 
 
53
void efx_mcdi_init(struct efx_nic *efx)
 
54
{
 
55
        struct efx_mcdi_iface *mcdi;
 
56
 
 
57
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
 
58
                return;
 
59
 
 
60
        mcdi = efx_mcdi(efx);
 
61
        init_waitqueue_head(&mcdi->wq);
 
62
        spin_lock_init(&mcdi->iface_lock);
 
63
        atomic_set(&mcdi->state, MCDI_STATE_QUIESCENT);
 
64
        mcdi->mode = MCDI_MODE_POLL;
 
65
 
 
66
        (void) efx_mcdi_poll_reboot(efx);
 
67
}
 
68
 
 
69
static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
 
70
                            const u8 *inbuf, size_t inlen)
 
71
{
 
72
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
73
        unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
 
74
        unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
 
75
        unsigned int i;
 
76
        efx_dword_t hdr;
 
77
        u32 xflags, seqno;
 
78
 
 
79
        BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
 
80
        BUG_ON(inlen & 3 || inlen >= 0x100);
 
81
 
 
82
        seqno = mcdi->seqno & SEQ_MASK;
 
83
        xflags = 0;
 
84
        if (mcdi->mode == MCDI_MODE_EVENTS)
 
85
                xflags |= MCDI_HEADER_XFLAGS_EVREQ;
 
86
 
 
87
        EFX_POPULATE_DWORD_6(hdr,
 
88
                             MCDI_HEADER_RESPONSE, 0,
 
89
                             MCDI_HEADER_RESYNC, 1,
 
90
                             MCDI_HEADER_CODE, cmd,
 
91
                             MCDI_HEADER_DATALEN, inlen,
 
92
                             MCDI_HEADER_SEQ, seqno,
 
93
                             MCDI_HEADER_XFLAGS, xflags);
 
94
 
 
95
        efx_writed(efx, &hdr, pdu);
 
96
 
 
97
        for (i = 0; i < inlen; i += 4)
 
98
                _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i);
 
99
 
 
100
        /* Ensure the payload is written out before the header */
 
101
        wmb();
 
102
 
 
103
        /* ring the doorbell with a distinctive value */
 
104
        _efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
 
105
}
 
106
 
 
107
static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
 
108
{
 
109
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
110
        unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
 
111
        int i;
 
112
 
 
113
        BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
 
114
        BUG_ON(outlen & 3 || outlen >= 0x100);
 
115
 
 
116
        for (i = 0; i < outlen; i += 4)
 
117
                *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
 
118
}
 
119
 
 
120
static int efx_mcdi_poll(struct efx_nic *efx)
 
121
{
 
122
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
123
        unsigned int time, finish;
 
124
        unsigned int respseq, respcmd, error;
 
125
        unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
 
126
        unsigned int rc, spins;
 
127
        efx_dword_t reg;
 
128
 
 
129
        /* Check for a reboot atomically with respect to efx_mcdi_copyout() */
 
130
        rc = -efx_mcdi_poll_reboot(efx);
 
131
        if (rc)
 
132
                goto out;
 
133
 
 
134
        /* Poll for completion. Poll quickly (once a us) for the 1st jiffy,
 
135
         * because generally mcdi responses are fast. After that, back off
 
136
         * and poll once a jiffy (approximately)
 
137
         */
 
138
        spins = TICK_USEC;
 
139
        finish = get_seconds() + MCDI_RPC_TIMEOUT;
 
140
 
 
141
        while (1) {
 
142
                if (spins != 0) {
 
143
                        --spins;
 
144
                        udelay(1);
 
145
                } else {
 
146
                        schedule_timeout_uninterruptible(1);
 
147
                }
 
148
 
 
149
                time = get_seconds();
 
150
 
 
151
                rmb();
 
152
                efx_readd(efx, &reg, pdu);
 
153
 
 
154
                /* All 1's indicates that shared memory is in reset (and is
 
155
                 * not a valid header). Wait for it to come out reset before
 
156
                 * completing the command */
 
157
                if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) != 0xffffffff &&
 
158
                    EFX_DWORD_FIELD(reg, MCDI_HEADER_RESPONSE))
 
159
                        break;
 
160
 
 
161
                if (time >= finish)
 
162
                        return -ETIMEDOUT;
 
163
        }
 
164
 
 
165
        mcdi->resplen = EFX_DWORD_FIELD(reg, MCDI_HEADER_DATALEN);
 
166
        respseq = EFX_DWORD_FIELD(reg, MCDI_HEADER_SEQ);
 
167
        respcmd = EFX_DWORD_FIELD(reg, MCDI_HEADER_CODE);
 
168
        error = EFX_DWORD_FIELD(reg, MCDI_HEADER_ERROR);
 
169
 
 
170
        if (error && mcdi->resplen == 0) {
 
171
                netif_err(efx, hw, efx->net_dev, "MC rebooted\n");
 
172
                rc = EIO;
 
173
        } else if ((respseq ^ mcdi->seqno) & SEQ_MASK) {
 
174
                netif_err(efx, hw, efx->net_dev,
 
175
                          "MC response mismatch tx seq 0x%x rx seq 0x%x\n",
 
176
                          respseq, mcdi->seqno);
 
177
                rc = EIO;
 
178
        } else if (error) {
 
179
                efx_readd(efx, &reg, pdu + 4);
 
180
                switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) {
 
181
#define TRANSLATE_ERROR(name)                                   \
 
182
                case MC_CMD_ERR_ ## name:                       \
 
183
                        rc = name;                              \
 
184
                        break
 
185
                        TRANSLATE_ERROR(ENOENT);
 
186
                        TRANSLATE_ERROR(EINTR);
 
187
                        TRANSLATE_ERROR(EACCES);
 
188
                        TRANSLATE_ERROR(EBUSY);
 
189
                        TRANSLATE_ERROR(EINVAL);
 
190
                        TRANSLATE_ERROR(EDEADLK);
 
191
                        TRANSLATE_ERROR(ENOSYS);
 
192
                        TRANSLATE_ERROR(ETIME);
 
193
#undef TRANSLATE_ERROR
 
194
                default:
 
195
                        rc = EIO;
 
196
                        break;
 
197
                }
 
198
        } else
 
199
                rc = 0;
 
200
 
 
201
out:
 
202
        mcdi->resprc = rc;
 
203
        if (rc)
 
204
                mcdi->resplen = 0;
 
205
 
 
206
        /* Return rc=0 like wait_event_timeout() */
 
207
        return 0;
 
208
}
 
209
 
 
210
/* Test and clear MC-rebooted flag for this port/function */
 
211
int efx_mcdi_poll_reboot(struct efx_nic *efx)
 
212
{
 
213
        unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx);
 
214
        efx_dword_t reg;
 
215
        uint32_t value;
 
216
 
 
217
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
 
218
                return false;
 
219
 
 
220
        efx_readd(efx, &reg, addr);
 
221
        value = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
 
222
 
 
223
        if (value == 0)
 
224
                return 0;
 
225
 
 
226
        EFX_ZERO_DWORD(reg);
 
227
        efx_writed(efx, &reg, addr);
 
228
 
 
229
        if (value == MC_STATUS_DWORD_ASSERT)
 
230
                return -EINTR;
 
231
        else
 
232
                return -EIO;
 
233
}
 
234
 
 
235
static void efx_mcdi_acquire(struct efx_mcdi_iface *mcdi)
 
236
{
 
237
        /* Wait until the interface becomes QUIESCENT and we win the race
 
238
         * to mark it RUNNING. */
 
239
        wait_event(mcdi->wq,
 
240
                   atomic_cmpxchg(&mcdi->state,
 
241
                                  MCDI_STATE_QUIESCENT,
 
242
                                  MCDI_STATE_RUNNING)
 
243
                   == MCDI_STATE_QUIESCENT);
 
244
}
 
245
 
 
246
static int efx_mcdi_await_completion(struct efx_nic *efx)
 
247
{
 
248
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
249
 
 
250
        if (wait_event_timeout(
 
251
                    mcdi->wq,
 
252
                    atomic_read(&mcdi->state) == MCDI_STATE_COMPLETED,
 
253
                    msecs_to_jiffies(MCDI_RPC_TIMEOUT * 1000)) == 0)
 
254
                return -ETIMEDOUT;
 
255
 
 
256
        /* Check if efx_mcdi_set_mode() switched us back to polled completions.
 
257
         * In which case, poll for completions directly. If efx_mcdi_ev_cpl()
 
258
         * completed the request first, then we'll just end up completing the
 
259
         * request again, which is safe.
 
260
         *
 
261
         * We need an smp_rmb() to synchronise with efx_mcdi_mode_poll(), which
 
262
         * wait_event_timeout() implicitly provides.
 
263
         */
 
264
        if (mcdi->mode == MCDI_MODE_POLL)
 
265
                return efx_mcdi_poll(efx);
 
266
 
 
267
        return 0;
 
268
}
 
269
 
 
270
static bool efx_mcdi_complete(struct efx_mcdi_iface *mcdi)
 
271
{
 
272
        /* If the interface is RUNNING, then move to COMPLETED and wake any
 
273
         * waiters. If the interface isn't in RUNNING then we've received a
 
274
         * duplicate completion after we've already transitioned back to
 
275
         * QUIESCENT. [A subsequent invocation would increment seqno, so would
 
276
         * have failed the seqno check].
 
277
         */
 
278
        if (atomic_cmpxchg(&mcdi->state,
 
279
                           MCDI_STATE_RUNNING,
 
280
                           MCDI_STATE_COMPLETED) == MCDI_STATE_RUNNING) {
 
281
                wake_up(&mcdi->wq);
 
282
                return true;
 
283
        }
 
284
 
 
285
        return false;
 
286
}
 
287
 
 
288
static void efx_mcdi_release(struct efx_mcdi_iface *mcdi)
 
289
{
 
290
        atomic_set(&mcdi->state, MCDI_STATE_QUIESCENT);
 
291
        wake_up(&mcdi->wq);
 
292
}
 
293
 
 
294
static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno,
 
295
                            unsigned int datalen, unsigned int errno)
 
296
{
 
297
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
298
        bool wake = false;
 
299
 
 
300
        spin_lock(&mcdi->iface_lock);
 
301
 
 
302
        if ((seqno ^ mcdi->seqno) & SEQ_MASK) {
 
303
                if (mcdi->credits)
 
304
                        /* The request has been cancelled */
 
305
                        --mcdi->credits;
 
306
                else
 
307
                        netif_err(efx, hw, efx->net_dev,
 
308
                                  "MC response mismatch tx seq 0x%x rx "
 
309
                                  "seq 0x%x\n", seqno, mcdi->seqno);
 
310
        } else {
 
311
                mcdi->resprc = errno;
 
312
                mcdi->resplen = datalen;
 
313
 
 
314
                wake = true;
 
315
        }
 
316
 
 
317
        spin_unlock(&mcdi->iface_lock);
 
318
 
 
319
        if (wake)
 
320
                efx_mcdi_complete(mcdi);
 
321
}
 
322
 
 
323
/* Issue the given command by writing the data into the shared memory PDU,
 
324
 * ring the doorbell and wait for completion. Copyout the result. */
 
325
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
 
326
                 const u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen,
 
327
                 size_t *outlen_actual)
 
328
{
 
329
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
330
        int rc;
 
331
        BUG_ON(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
 
332
 
 
333
        efx_mcdi_acquire(mcdi);
 
334
 
 
335
        /* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
 
336
        spin_lock_bh(&mcdi->iface_lock);
 
337
        ++mcdi->seqno;
 
338
        spin_unlock_bh(&mcdi->iface_lock);
 
339
 
 
340
        efx_mcdi_copyin(efx, cmd, inbuf, inlen);
 
341
 
 
342
        if (mcdi->mode == MCDI_MODE_POLL)
 
343
                rc = efx_mcdi_poll(efx);
 
344
        else
 
345
                rc = efx_mcdi_await_completion(efx);
 
346
 
 
347
        if (rc != 0) {
 
348
                /* Close the race with efx_mcdi_ev_cpl() executing just too late
 
349
                 * and completing a request we've just cancelled, by ensuring
 
350
                 * that the seqno check therein fails.
 
351
                 */
 
352
                spin_lock_bh(&mcdi->iface_lock);
 
353
                ++mcdi->seqno;
 
354
                ++mcdi->credits;
 
355
                spin_unlock_bh(&mcdi->iface_lock);
 
356
 
 
357
                netif_err(efx, hw, efx->net_dev,
 
358
                          "MC command 0x%x inlen %d mode %d timed out\n",
 
359
                          cmd, (int)inlen, mcdi->mode);
 
360
        } else {
 
361
                size_t resplen;
 
362
 
 
363
                /* At the very least we need a memory barrier here to ensure
 
364
                 * we pick up changes from efx_mcdi_ev_cpl(). Protect against
 
365
                 * a spurious efx_mcdi_ev_cpl() running concurrently by
 
366
                 * acquiring the iface_lock. */
 
367
                spin_lock_bh(&mcdi->iface_lock);
 
368
                rc = -mcdi->resprc;
 
369
                resplen = mcdi->resplen;
 
370
                spin_unlock_bh(&mcdi->iface_lock);
 
371
 
 
372
                if (rc == 0) {
 
373
                        efx_mcdi_copyout(efx, outbuf,
 
374
                                         min(outlen, mcdi->resplen + 3) & ~0x3);
 
375
                        if (outlen_actual != NULL)
 
376
                                *outlen_actual = resplen;
 
377
                } else if (cmd == MC_CMD_REBOOT && rc == -EIO)
 
378
                        ; /* Don't reset if MC_CMD_REBOOT returns EIO */
 
379
                else if (rc == -EIO || rc == -EINTR) {
 
380
                        netif_err(efx, hw, efx->net_dev, "MC fatal error %d\n",
 
381
                                  -rc);
 
382
                        efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
 
383
                } else
 
384
                        netif_dbg(efx, hw, efx->net_dev,
 
385
                                  "MC command 0x%x inlen %d failed rc=%d\n",
 
386
                                  cmd, (int)inlen, -rc);
 
387
        }
 
388
 
 
389
        efx_mcdi_release(mcdi);
 
390
        return rc;
 
391
}
 
392
 
 
393
void efx_mcdi_mode_poll(struct efx_nic *efx)
 
394
{
 
395
        struct efx_mcdi_iface *mcdi;
 
396
 
 
397
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
 
398
                return;
 
399
 
 
400
        mcdi = efx_mcdi(efx);
 
401
        if (mcdi->mode == MCDI_MODE_POLL)
 
402
                return;
 
403
 
 
404
        /* We can switch from event completion to polled completion, because
 
405
         * mcdi requests are always completed in shared memory. We do this by
 
406
         * switching the mode to POLL'd then completing the request.
 
407
         * efx_mcdi_await_completion() will then call efx_mcdi_poll().
 
408
         *
 
409
         * We need an smp_wmb() to synchronise with efx_mcdi_await_completion(),
 
410
         * which efx_mcdi_complete() provides for us.
 
411
         */
 
412
        mcdi->mode = MCDI_MODE_POLL;
 
413
 
 
414
        efx_mcdi_complete(mcdi);
 
415
}
 
416
 
 
417
void efx_mcdi_mode_event(struct efx_nic *efx)
 
418
{
 
419
        struct efx_mcdi_iface *mcdi;
 
420
 
 
421
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
 
422
                return;
 
423
 
 
424
        mcdi = efx_mcdi(efx);
 
425
 
 
426
        if (mcdi->mode == MCDI_MODE_EVENTS)
 
427
                return;
 
428
 
 
429
        /* We can't switch from polled to event completion in the middle of a
 
430
         * request, because the completion method is specified in the request.
 
431
         * So acquire the interface to serialise the requestors. We don't need
 
432
         * to acquire the iface_lock to change the mode here, but we do need a
 
433
         * write memory barrier ensure that efx_mcdi_rpc() sees it, which
 
434
         * efx_mcdi_acquire() provides.
 
435
         */
 
436
        efx_mcdi_acquire(mcdi);
 
437
        mcdi->mode = MCDI_MODE_EVENTS;
 
438
        efx_mcdi_release(mcdi);
 
439
}
 
440
 
 
441
static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
 
442
{
 
443
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
 
444
 
 
445
        /* If there is an outstanding MCDI request, it has been terminated
 
446
         * either by a BADASSERT or REBOOT event. If the mcdi interface is
 
447
         * in polled mode, then do nothing because the MC reboot handler will
 
448
         * set the header correctly. However, if the mcdi interface is waiting
 
449
         * for a CMDDONE event it won't receive it [and since all MCDI events
 
450
         * are sent to the same queue, we can't be racing with
 
451
         * efx_mcdi_ev_cpl()]
 
452
         *
 
453
         * There's a race here with efx_mcdi_rpc(), because we might receive
 
454
         * a REBOOT event *before* the request has been copied out. In polled
 
455
         * mode (during startup) this is irrelevant, because efx_mcdi_complete()
 
456
         * is ignored. In event mode, this condition is just an edge-case of
 
457
         * receiving a REBOOT event after posting the MCDI request. Did the mc
 
458
         * reboot before or after the copyout? The best we can do always is
 
459
         * just return failure.
 
460
         */
 
461
        spin_lock(&mcdi->iface_lock);
 
462
        if (efx_mcdi_complete(mcdi)) {
 
463
                if (mcdi->mode == MCDI_MODE_EVENTS) {
 
464
                        mcdi->resprc = rc;
 
465
                        mcdi->resplen = 0;
 
466
                        ++mcdi->credits;
 
467
                }
 
468
        } else
 
469
                /* Nobody was waiting for an MCDI request, so trigger a reset */
 
470
                efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
 
471
 
 
472
        spin_unlock(&mcdi->iface_lock);
 
473
}
 
474
 
 
475
static unsigned int efx_mcdi_event_link_speed[] = {
 
476
        [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
 
477
        [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
 
478
        [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
 
479
};
 
480
 
 
481
 
 
482
static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
 
483
{
 
484
        u32 flags, fcntl, speed, lpa;
 
485
 
 
486
        speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
 
487
        EFX_BUG_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
 
488
        speed = efx_mcdi_event_link_speed[speed];
 
489
 
 
490
        flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
 
491
        fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
 
492
        lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
 
493
 
 
494
        /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
 
495
         * which is only run after flushing the event queues. Therefore, it
 
496
         * is safe to modify the link state outside of the mac_lock here.
 
497
         */
 
498
        efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
 
499
 
 
500
        efx_mcdi_phy_check_fcntl(efx, lpa);
 
501
 
 
502
        efx_link_status_changed(efx);
 
503
}
 
504
 
 
505
static const char *sensor_names[] = {
 
506
        [MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor",
 
507
        [MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor",
 
508
        [MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling",
 
509
        [MC_CMD_SENSOR_PHY0_TEMP] = "PHY 0 temp. sensor",
 
510
        [MC_CMD_SENSOR_PHY0_COOLING] = "PHY 0 cooling",
 
511
        [MC_CMD_SENSOR_PHY1_TEMP] = "PHY 1 temp. sensor",
 
512
        [MC_CMD_SENSOR_PHY1_COOLING] = "PHY 1 cooling",
 
513
        [MC_CMD_SENSOR_IN_1V0] = "1.0V supply sensor",
 
514
        [MC_CMD_SENSOR_IN_1V2] = "1.2V supply sensor",
 
515
        [MC_CMD_SENSOR_IN_1V8] = "1.8V supply sensor",
 
516
        [MC_CMD_SENSOR_IN_2V5] = "2.5V supply sensor",
 
517
        [MC_CMD_SENSOR_IN_3V3] = "3.3V supply sensor",
 
518
        [MC_CMD_SENSOR_IN_12V0] = "12V supply sensor"
 
519
};
 
520
 
 
521
static const char *sensor_status_names[] = {
 
522
        [MC_CMD_SENSOR_STATE_OK] = "OK",
 
523
        [MC_CMD_SENSOR_STATE_WARNING] = "Warning",
 
524
        [MC_CMD_SENSOR_STATE_FATAL] = "Fatal",
 
525
        [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure",
 
526
};
 
527
 
 
528
static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
 
529
{
 
530
        unsigned int monitor, state, value;
 
531
        const char *name, *state_txt;
 
532
        monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR);
 
533
        state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE);
 
534
        value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE);
 
535
        /* Deal gracefully with the board having more drivers than we
 
536
         * know about, but do not expect new sensor states. */
 
537
        name = (monitor >= ARRAY_SIZE(sensor_names))
 
538
                                    ? "No sensor name available" :
 
539
                                    sensor_names[monitor];
 
540
        EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names));
 
541
        state_txt = sensor_status_names[state];
 
542
 
 
543
        netif_err(efx, hw, efx->net_dev,
 
544
                  "Sensor %d (%s) reports condition '%s' for raw value %d\n",
 
545
                  monitor, name, state_txt, value);
 
546
}
 
547
 
 
548
/* Called from  falcon_process_eventq for MCDI events */
 
549
void efx_mcdi_process_event(struct efx_channel *channel,
 
550
                            efx_qword_t *event)
 
551
{
 
552
        struct efx_nic *efx = channel->efx;
 
553
        int code = EFX_QWORD_FIELD(*event, MCDI_EVENT_CODE);
 
554
        u32 data = EFX_QWORD_FIELD(*event, MCDI_EVENT_DATA);
 
555
 
 
556
        switch (code) {
 
557
        case MCDI_EVENT_CODE_BADSSERT:
 
558
                netif_err(efx, hw, efx->net_dev,
 
559
                          "MC watchdog or assertion failure at 0x%x\n", data);
 
560
                efx_mcdi_ev_death(efx, EINTR);
 
561
                break;
 
562
 
 
563
        case MCDI_EVENT_CODE_PMNOTICE:
 
564
                netif_info(efx, wol, efx->net_dev, "MCDI PM event.\n");
 
565
                break;
 
566
 
 
567
        case MCDI_EVENT_CODE_CMDDONE:
 
568
                efx_mcdi_ev_cpl(efx,
 
569
                                MCDI_EVENT_FIELD(*event, CMDDONE_SEQ),
 
570
                                MCDI_EVENT_FIELD(*event, CMDDONE_DATALEN),
 
571
                                MCDI_EVENT_FIELD(*event, CMDDONE_ERRNO));
 
572
                break;
 
573
 
 
574
        case MCDI_EVENT_CODE_LINKCHANGE:
 
575
                efx_mcdi_process_link_change(efx, event);
 
576
                break;
 
577
        case MCDI_EVENT_CODE_SENSOREVT:
 
578
                efx_mcdi_sensor_event(efx, event);
 
579
                break;
 
580
        case MCDI_EVENT_CODE_SCHEDERR:
 
581
                netif_info(efx, hw, efx->net_dev,
 
582
                           "MC Scheduler error address=0x%x\n", data);
 
583
                break;
 
584
        case MCDI_EVENT_CODE_REBOOT:
 
585
                netif_info(efx, hw, efx->net_dev, "MC Reboot\n");
 
586
                efx_mcdi_ev_death(efx, EIO);
 
587
                break;
 
588
        case MCDI_EVENT_CODE_MAC_STATS_DMA:
 
589
                /* MAC stats are gather lazily.  We can ignore this. */
 
590
                break;
 
591
 
 
592
        default:
 
593
                netif_err(efx, hw, efx->net_dev, "Unknown MCDI event 0x%x\n",
 
594
                          code);
 
595
        }
 
596
}
 
597
 
 
598
/**************************************************************************
 
599
 *
 
600
 * Specific request functions
 
601
 *
 
602
 **************************************************************************
 
603
 */
 
604
 
 
605
void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
 
606
{
 
607
        u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)];
 
608
        size_t outlength;
 
609
        const __le16 *ver_words;
 
610
        int rc;
 
611
 
 
612
        BUILD_BUG_ON(MC_CMD_GET_VERSION_IN_LEN != 0);
 
613
 
 
614
        rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, NULL, 0,
 
615
                          outbuf, sizeof(outbuf), &outlength);
 
616
        if (rc)
 
617
                goto fail;
 
618
 
 
619
        if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) {
 
620
                rc = -EIO;
 
621
                goto fail;
 
622
        }
 
623
 
 
624
        ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION);
 
625
        snprintf(buf, len, "%u.%u.%u.%u",
 
626
                 le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]),
 
627
                 le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3]));
 
628
        return;
 
629
 
 
630
fail:
 
631
        netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
632
        buf[0] = 0;
 
633
}
 
634
 
 
635
int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
 
636
                        bool *was_attached)
 
637
{
 
638
        u8 inbuf[MC_CMD_DRV_ATTACH_IN_LEN];
 
639
        u8 outbuf[MC_CMD_DRV_ATTACH_OUT_LEN];
 
640
        size_t outlen;
 
641
        int rc;
 
642
 
 
643
        MCDI_SET_DWORD(inbuf, DRV_ATTACH_IN_NEW_STATE,
 
644
                       driver_operating ? 1 : 0);
 
645
        MCDI_SET_DWORD(inbuf, DRV_ATTACH_IN_UPDATE, 1);
 
646
 
 
647
        rc = efx_mcdi_rpc(efx, MC_CMD_DRV_ATTACH, inbuf, sizeof(inbuf),
 
648
                          outbuf, sizeof(outbuf), &outlen);
 
649
        if (rc)
 
650
                goto fail;
 
651
        if (outlen < MC_CMD_DRV_ATTACH_OUT_LEN) {
 
652
                rc = -EIO;
 
653
                goto fail;
 
654
        }
 
655
 
 
656
        if (was_attached != NULL)
 
657
                *was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE);
 
658
        return 0;
 
659
 
 
660
fail:
 
661
        netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
662
        return rc;
 
663
}
 
664
 
 
665
int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
 
666
                           u16 *fw_subtype_list)
 
667
{
 
668
        uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN];
 
669
        size_t outlen;
 
670
        int port_num = efx_port_num(efx);
 
671
        int offset;
 
672
        int rc;
 
673
 
 
674
        BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0);
 
675
 
 
676
        rc = efx_mcdi_rpc(efx, MC_CMD_GET_BOARD_CFG, NULL, 0,
 
677
                          outbuf, sizeof(outbuf), &outlen);
 
678
        if (rc)
 
679
                goto fail;
 
680
 
 
681
        if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LEN) {
 
682
                rc = -EIO;
 
683
                goto fail;
 
684
        }
 
685
 
 
686
        offset = (port_num)
 
687
                ? MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST
 
688
                : MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
 
689
        if (mac_address)
 
690
                memcpy(mac_address, outbuf + offset, ETH_ALEN);
 
691
        if (fw_subtype_list)
 
692
                memcpy(fw_subtype_list,
 
693
                       outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST,
 
694
                       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN);
 
695
 
 
696
        return 0;
 
697
 
 
698
fail:
 
699
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d len=%d\n",
 
700
                  __func__, rc, (int)outlen);
 
701
 
 
702
        return rc;
 
703
}
 
704
 
 
705
int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq)
 
706
{
 
707
        u8 inbuf[MC_CMD_LOG_CTRL_IN_LEN];
 
708
        u32 dest = 0;
 
709
        int rc;
 
710
 
 
711
        if (uart)
 
712
                dest |= MC_CMD_LOG_CTRL_IN_LOG_DEST_UART;
 
713
        if (evq)
 
714
                dest |= MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ;
 
715
 
 
716
        MCDI_SET_DWORD(inbuf, LOG_CTRL_IN_LOG_DEST, dest);
 
717
        MCDI_SET_DWORD(inbuf, LOG_CTRL_IN_LOG_DEST_EVQ, dest_evq);
 
718
 
 
719
        BUILD_BUG_ON(MC_CMD_LOG_CTRL_OUT_LEN != 0);
 
720
 
 
721
        rc = efx_mcdi_rpc(efx, MC_CMD_LOG_CTRL, inbuf, sizeof(inbuf),
 
722
                          NULL, 0, NULL);
 
723
        if (rc)
 
724
                goto fail;
 
725
 
 
726
        return 0;
 
727
 
 
728
fail:
 
729
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
730
        return rc;
 
731
}
 
732
 
 
733
int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out)
 
734
{
 
735
        u8 outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN];
 
736
        size_t outlen;
 
737
        int rc;
 
738
 
 
739
        BUILD_BUG_ON(MC_CMD_NVRAM_TYPES_IN_LEN != 0);
 
740
 
 
741
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_TYPES, NULL, 0,
 
742
                          outbuf, sizeof(outbuf), &outlen);
 
743
        if (rc)
 
744
                goto fail;
 
745
        if (outlen < MC_CMD_NVRAM_TYPES_OUT_LEN) {
 
746
                rc = -EIO;
 
747
                goto fail;
 
748
        }
 
749
 
 
750
        *nvram_types_out = MCDI_DWORD(outbuf, NVRAM_TYPES_OUT_TYPES);
 
751
        return 0;
 
752
 
 
753
fail:
 
754
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
 
755
                  __func__, rc);
 
756
        return rc;
 
757
}
 
758
 
 
759
int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
 
760
                        size_t *size_out, size_t *erase_size_out,
 
761
                        bool *protected_out)
 
762
{
 
763
        u8 inbuf[MC_CMD_NVRAM_INFO_IN_LEN];
 
764
        u8 outbuf[MC_CMD_NVRAM_INFO_OUT_LEN];
 
765
        size_t outlen;
 
766
        int rc;
 
767
 
 
768
        MCDI_SET_DWORD(inbuf, NVRAM_INFO_IN_TYPE, type);
 
769
 
 
770
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_INFO, inbuf, sizeof(inbuf),
 
771
                          outbuf, sizeof(outbuf), &outlen);
 
772
        if (rc)
 
773
                goto fail;
 
774
        if (outlen < MC_CMD_NVRAM_INFO_OUT_LEN) {
 
775
                rc = -EIO;
 
776
                goto fail;
 
777
        }
 
778
 
 
779
        *size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE);
 
780
        *erase_size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE);
 
781
        *protected_out = !!(MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) &
 
782
                                (1 << MC_CMD_NVRAM_PROTECTED_LBN));
 
783
        return 0;
 
784
 
 
785
fail:
 
786
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
787
        return rc;
 
788
}
 
789
 
 
790
int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
 
791
{
 
792
        u8 inbuf[MC_CMD_NVRAM_UPDATE_START_IN_LEN];
 
793
        int rc;
 
794
 
 
795
        MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
 
796
 
 
797
        BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
 
798
 
 
799
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
 
800
                          NULL, 0, NULL);
 
801
        if (rc)
 
802
                goto fail;
 
803
 
 
804
        return 0;
 
805
 
 
806
fail:
 
807
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
808
        return rc;
 
809
}
 
810
 
 
811
int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
 
812
                        loff_t offset, u8 *buffer, size_t length)
 
813
{
 
814
        u8 inbuf[MC_CMD_NVRAM_READ_IN_LEN];
 
815
        u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
 
816
        size_t outlen;
 
817
        int rc;
 
818
 
 
819
        MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
 
820
        MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
 
821
        MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
 
822
 
 
823
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
 
824
                          outbuf, sizeof(outbuf), &outlen);
 
825
        if (rc)
 
826
                goto fail;
 
827
 
 
828
        memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
 
829
        return 0;
 
830
 
 
831
fail:
 
832
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
833
        return rc;
 
834
}
 
835
 
 
836
int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
 
837
                           loff_t offset, const u8 *buffer, size_t length)
 
838
{
 
839
        u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
 
840
        int rc;
 
841
 
 
842
        MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
 
843
        MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
 
844
        MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
 
845
        memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
 
846
 
 
847
        BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
 
848
 
 
849
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
 
850
                          ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
 
851
                          NULL, 0, NULL);
 
852
        if (rc)
 
853
                goto fail;
 
854
 
 
855
        return 0;
 
856
 
 
857
fail:
 
858
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
859
        return rc;
 
860
}
 
861
 
 
862
int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
 
863
                         loff_t offset, size_t length)
 
864
{
 
865
        u8 inbuf[MC_CMD_NVRAM_ERASE_IN_LEN];
 
866
        int rc;
 
867
 
 
868
        MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
 
869
        MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
 
870
        MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
 
871
 
 
872
        BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
 
873
 
 
874
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
 
875
                          NULL, 0, NULL);
 
876
        if (rc)
 
877
                goto fail;
 
878
 
 
879
        return 0;
 
880
 
 
881
fail:
 
882
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
883
        return rc;
 
884
}
 
885
 
 
886
int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
 
887
{
 
888
        u8 inbuf[MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN];
 
889
        int rc;
 
890
 
 
891
        MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
 
892
 
 
893
        BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
 
894
 
 
895
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
 
896
                          NULL, 0, NULL);
 
897
        if (rc)
 
898
                goto fail;
 
899
 
 
900
        return 0;
 
901
 
 
902
fail:
 
903
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
904
        return rc;
 
905
}
 
906
 
 
907
static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
 
908
{
 
909
        u8 inbuf[MC_CMD_NVRAM_TEST_IN_LEN];
 
910
        u8 outbuf[MC_CMD_NVRAM_TEST_OUT_LEN];
 
911
        int rc;
 
912
 
 
913
        MCDI_SET_DWORD(inbuf, NVRAM_TEST_IN_TYPE, type);
 
914
 
 
915
        rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_TEST, inbuf, sizeof(inbuf),
 
916
                          outbuf, sizeof(outbuf), NULL);
 
917
        if (rc)
 
918
                return rc;
 
919
 
 
920
        switch (MCDI_DWORD(outbuf, NVRAM_TEST_OUT_RESULT)) {
 
921
        case MC_CMD_NVRAM_TEST_PASS:
 
922
        case MC_CMD_NVRAM_TEST_NOTSUPP:
 
923
                return 0;
 
924
        default:
 
925
                return -EIO;
 
926
        }
 
927
}
 
928
 
 
929
int efx_mcdi_nvram_test_all(struct efx_nic *efx)
 
930
{
 
931
        u32 nvram_types;
 
932
        unsigned int type;
 
933
        int rc;
 
934
 
 
935
        rc = efx_mcdi_nvram_types(efx, &nvram_types);
 
936
        if (rc)
 
937
                goto fail1;
 
938
 
 
939
        type = 0;
 
940
        while (nvram_types != 0) {
 
941
                if (nvram_types & 1) {
 
942
                        rc = efx_mcdi_nvram_test(efx, type);
 
943
                        if (rc)
 
944
                                goto fail2;
 
945
                }
 
946
                type++;
 
947
                nvram_types >>= 1;
 
948
        }
 
949
 
 
950
        return 0;
 
951
 
 
952
fail2:
 
953
        netif_err(efx, hw, efx->net_dev, "%s: failed type=%u\n",
 
954
                  __func__, type);
 
955
fail1:
 
956
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
957
        return rc;
 
958
}
 
959
 
 
960
static int efx_mcdi_read_assertion(struct efx_nic *efx)
 
961
{
 
962
        u8 inbuf[MC_CMD_GET_ASSERTS_IN_LEN];
 
963
        u8 outbuf[MC_CMD_GET_ASSERTS_OUT_LEN];
 
964
        unsigned int flags, index, ofst;
 
965
        const char *reason;
 
966
        size_t outlen;
 
967
        int retry;
 
968
        int rc;
 
969
 
 
970
        /* Attempt to read any stored assertion state before we reboot
 
971
         * the mcfw out of the assertion handler. Retry twice, once
 
972
         * because a boot-time assertion might cause this command to fail
 
973
         * with EINTR. And once again because GET_ASSERTS can race with
 
974
         * MC_CMD_REBOOT running on the other port. */
 
975
        retry = 2;
 
976
        do {
 
977
                MCDI_SET_DWORD(inbuf, GET_ASSERTS_IN_CLEAR, 1);
 
978
                rc = efx_mcdi_rpc(efx, MC_CMD_GET_ASSERTS,
 
979
                                  inbuf, MC_CMD_GET_ASSERTS_IN_LEN,
 
980
                                  outbuf, sizeof(outbuf), &outlen);
 
981
        } while ((rc == -EINTR || rc == -EIO) && retry-- > 0);
 
982
 
 
983
        if (rc)
 
984
                return rc;
 
985
        if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN)
 
986
                return -EIO;
 
987
 
 
988
        /* Print out any recorded assertion state */
 
989
        flags = MCDI_DWORD(outbuf, GET_ASSERTS_OUT_GLOBAL_FLAGS);
 
990
        if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
 
991
                return 0;
 
992
 
 
993
        reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
 
994
                ? "system-level assertion"
 
995
                : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
 
996
                ? "thread-level assertion"
 
997
                : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
 
998
                ? "watchdog reset"
 
999
                : "unknown assertion";
 
1000
        netif_err(efx, hw, efx->net_dev,
 
1001
                  "MCPU %s at PC = 0x%.8x in thread 0x%.8x\n", reason,
 
1002
                  MCDI_DWORD(outbuf, GET_ASSERTS_OUT_SAVED_PC_OFFS),
 
1003
                  MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
 
1004
 
 
1005
        /* Print out the registers */
 
1006
        ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
 
1007
        for (index = 1; index < 32; index++) {
 
1008
                netif_err(efx, hw, efx->net_dev, "R%.2d (?): 0x%.8x\n", index,
 
1009
                        MCDI_DWORD2(outbuf, ofst));
 
1010
                ofst += sizeof(efx_dword_t);
 
1011
        }
 
1012
 
 
1013
        return 0;
 
1014
}
 
1015
 
 
1016
static void efx_mcdi_exit_assertion(struct efx_nic *efx)
 
1017
{
 
1018
        u8 inbuf[MC_CMD_REBOOT_IN_LEN];
 
1019
 
 
1020
        /* Atomically reboot the mcfw out of the assertion handler */
 
1021
        BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
 
1022
        MCDI_SET_DWORD(inbuf, REBOOT_IN_FLAGS,
 
1023
                       MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
 
1024
        efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf, MC_CMD_REBOOT_IN_LEN,
 
1025
                     NULL, 0, NULL);
 
1026
}
 
1027
 
 
1028
int efx_mcdi_handle_assertion(struct efx_nic *efx)
 
1029
{
 
1030
        int rc;
 
1031
 
 
1032
        rc = efx_mcdi_read_assertion(efx);
 
1033
        if (rc)
 
1034
                return rc;
 
1035
 
 
1036
        efx_mcdi_exit_assertion(efx);
 
1037
 
 
1038
        return 0;
 
1039
}
 
1040
 
 
1041
void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 
1042
{
 
1043
        u8 inbuf[MC_CMD_SET_ID_LED_IN_LEN];
 
1044
        int rc;
 
1045
 
 
1046
        BUILD_BUG_ON(EFX_LED_OFF != MC_CMD_LED_OFF);
 
1047
        BUILD_BUG_ON(EFX_LED_ON != MC_CMD_LED_ON);
 
1048
        BUILD_BUG_ON(EFX_LED_DEFAULT != MC_CMD_LED_DEFAULT);
 
1049
 
 
1050
        BUILD_BUG_ON(MC_CMD_SET_ID_LED_OUT_LEN != 0);
 
1051
 
 
1052
        MCDI_SET_DWORD(inbuf, SET_ID_LED_IN_STATE, mode);
 
1053
 
 
1054
        rc = efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf),
 
1055
                          NULL, 0, NULL);
 
1056
        if (rc)
 
1057
                netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
 
1058
                          __func__, rc);
 
1059
}
 
1060
 
 
1061
int efx_mcdi_reset_port(struct efx_nic *efx)
 
1062
{
 
1063
        int rc = efx_mcdi_rpc(efx, MC_CMD_PORT_RESET, NULL, 0, NULL, 0, NULL);
 
1064
        if (rc)
 
1065
                netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
 
1066
                          __func__, rc);
 
1067
        return rc;
 
1068
}
 
1069
 
 
1070
int efx_mcdi_reset_mc(struct efx_nic *efx)
 
1071
{
 
1072
        u8 inbuf[MC_CMD_REBOOT_IN_LEN];
 
1073
        int rc;
 
1074
 
 
1075
        BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
 
1076
        MCDI_SET_DWORD(inbuf, REBOOT_IN_FLAGS, 0);
 
1077
        rc = efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf, sizeof(inbuf),
 
1078
                          NULL, 0, NULL);
 
1079
        /* White is black, and up is down */
 
1080
        if (rc == -EIO)
 
1081
                return 0;
 
1082
        if (rc == 0)
 
1083
                rc = -EIO;
 
1084
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
1085
        return rc;
 
1086
}
 
1087
 
 
1088
static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
 
1089
                                   const u8 *mac, int *id_out)
 
1090
{
 
1091
        u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN];
 
1092
        u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN];
 
1093
        size_t outlen;
 
1094
        int rc;
 
1095
 
 
1096
        MCDI_SET_DWORD(inbuf, WOL_FILTER_SET_IN_WOL_TYPE, type);
 
1097
        MCDI_SET_DWORD(inbuf, WOL_FILTER_SET_IN_FILTER_MODE,
 
1098
                       MC_CMD_FILTER_MODE_SIMPLE);
 
1099
        memcpy(MCDI_PTR(inbuf, WOL_FILTER_SET_IN_MAGIC_MAC), mac, ETH_ALEN);
 
1100
 
 
1101
        rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_SET, inbuf, sizeof(inbuf),
 
1102
                          outbuf, sizeof(outbuf), &outlen);
 
1103
        if (rc)
 
1104
                goto fail;
 
1105
 
 
1106
        if (outlen < MC_CMD_WOL_FILTER_SET_OUT_LEN) {
 
1107
                rc = -EIO;
 
1108
                goto fail;
 
1109
        }
 
1110
 
 
1111
        *id_out = (int)MCDI_DWORD(outbuf, WOL_FILTER_SET_OUT_FILTER_ID);
 
1112
 
 
1113
        return 0;
 
1114
 
 
1115
fail:
 
1116
        *id_out = -1;
 
1117
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
1118
        return rc;
 
1119
 
 
1120
}
 
1121
 
 
1122
 
 
1123
int
 
1124
efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,  const u8 *mac, int *id_out)
 
1125
{
 
1126
        return efx_mcdi_wol_filter_set(efx, MC_CMD_WOL_TYPE_MAGIC, mac, id_out);
 
1127
}
 
1128
 
 
1129
 
 
1130
int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out)
 
1131
{
 
1132
        u8 outbuf[MC_CMD_WOL_FILTER_GET_OUT_LEN];
 
1133
        size_t outlen;
 
1134
        int rc;
 
1135
 
 
1136
        rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_GET, NULL, 0,
 
1137
                          outbuf, sizeof(outbuf), &outlen);
 
1138
        if (rc)
 
1139
                goto fail;
 
1140
 
 
1141
        if (outlen < MC_CMD_WOL_FILTER_GET_OUT_LEN) {
 
1142
                rc = -EIO;
 
1143
                goto fail;
 
1144
        }
 
1145
 
 
1146
        *id_out = (int)MCDI_DWORD(outbuf, WOL_FILTER_GET_OUT_FILTER_ID);
 
1147
 
 
1148
        return 0;
 
1149
 
 
1150
fail:
 
1151
        *id_out = -1;
 
1152
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
1153
        return rc;
 
1154
}
 
1155
 
 
1156
 
 
1157
int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id)
 
1158
{
 
1159
        u8 inbuf[MC_CMD_WOL_FILTER_REMOVE_IN_LEN];
 
1160
        int rc;
 
1161
 
 
1162
        MCDI_SET_DWORD(inbuf, WOL_FILTER_REMOVE_IN_FILTER_ID, (u32)id);
 
1163
 
 
1164
        rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_REMOVE, inbuf, sizeof(inbuf),
 
1165
                          NULL, 0, NULL);
 
1166
        if (rc)
 
1167
                goto fail;
 
1168
 
 
1169
        return 0;
 
1170
 
 
1171
fail:
 
1172
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
1173
        return rc;
 
1174
}
 
1175
 
 
1176
 
 
1177
int efx_mcdi_wol_filter_reset(struct efx_nic *efx)
 
1178
{
 
1179
        int rc;
 
1180
 
 
1181
        rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_RESET, NULL, 0, NULL, 0, NULL);
 
1182
        if (rc)
 
1183
                goto fail;
 
1184
 
 
1185
        return 0;
 
1186
 
 
1187
fail:
 
1188
        netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
 
1189
        return rc;
 
1190
}
 
1191