~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/net/ethernet/brocade/bna/bfa_ioc.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Linux network driver for Brocade Converged Network Adapter.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License (GPL) Version 2 as
 
6
 * published by the Free Software Foundation
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
 * General Public License for more details.
 
12
 */
 
13
/*
 
14
 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
 
15
 * All rights reserved
 
16
 * www.brocade.com
 
17
 */
 
18
 
 
19
#include "bfa_ioc.h"
 
20
#include "bfi_reg.h"
 
21
#include "bfa_defs.h"
 
22
 
 
23
/**
 
24
 * IOC local definitions
 
25
 */
 
26
 
 
27
/**
 
28
 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
 
29
 */
 
30
 
 
31
#define bfa_ioc_firmware_lock(__ioc)                    \
 
32
                        ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
 
33
#define bfa_ioc_firmware_unlock(__ioc)                  \
 
34
                        ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
 
35
#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
 
36
#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
 
37
#define bfa_ioc_notify_fail(__ioc)                      \
 
38
                        ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
 
39
#define bfa_ioc_sync_start(__ioc)               \
 
40
                        ((__ioc)->ioc_hwif->ioc_sync_start(__ioc))
 
41
#define bfa_ioc_sync_join(__ioc)                        \
 
42
                        ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
 
43
#define bfa_ioc_sync_leave(__ioc)                       \
 
44
                        ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
 
45
#define bfa_ioc_sync_ack(__ioc)                         \
 
46
                        ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
 
47
#define bfa_ioc_sync_complete(__ioc)                    \
 
48
                        ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
 
49
 
 
50
#define bfa_ioc_mbox_cmd_pending(__ioc)         \
 
51
                        (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
 
52
                        readl((__ioc)->ioc_regs.hfn_mbox_cmd))
 
53
 
 
54
static bool bfa_nw_auto_recover = true;
 
55
 
 
56
/*
 
57
 * forward declarations
 
58
 */
 
59
static void bfa_ioc_hw_sem_init(struct bfa_ioc *ioc);
 
60
static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
 
61
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
 
62
static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
 
63
static void bfa_ioc_poll_fwinit(struct bfa_ioc *ioc);
 
64
static void bfa_ioc_send_enable(struct bfa_ioc *ioc);
 
65
static void bfa_ioc_send_disable(struct bfa_ioc *ioc);
 
66
static void bfa_ioc_send_getattr(struct bfa_ioc *ioc);
 
67
static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc);
 
68
static void bfa_ioc_hb_stop(struct bfa_ioc *ioc);
 
69
static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
 
70
static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
 
71
static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc);
 
72
static void bfa_ioc_recover(struct bfa_ioc *ioc);
 
73
static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
 
74
static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
 
75
static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
 
76
static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
 
77
static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
 
78
static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc);
 
79
static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
 
80
static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
 
81
static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc);
 
82
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
 
83
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
 
84
                         u32 boot_param);
 
85
static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
 
86
static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
 
87
                                                char *serial_num);
 
88
static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc,
 
89
                                                char *fw_ver);
 
90
static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc,
 
91
                                                char *chip_rev);
 
92
static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc,
 
93
                                                char *optrom_ver);
 
94
static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc,
 
95
                                                char *manufacturer);
 
96
static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model);
 
97
static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc);
 
98
 
 
99
/**
 
100
 * IOC state machine definitions/declarations
 
101
 */
 
102
enum ioc_event {
 
103
        IOC_E_RESET             = 1,    /*!< IOC reset request          */
 
104
        IOC_E_ENABLE            = 2,    /*!< IOC enable request         */
 
105
        IOC_E_DISABLE           = 3,    /*!< IOC disable request        */
 
106
        IOC_E_DETACH            = 4,    /*!< driver detach cleanup      */
 
107
        IOC_E_ENABLED           = 5,    /*!< f/w enabled                */
 
108
        IOC_E_FWRSP_GETATTR     = 6,    /*!< IOC get attribute response */
 
109
        IOC_E_DISABLED          = 7,    /*!< f/w disabled               */
 
110
        IOC_E_PFFAILED          = 8,    /*!< failure notice by iocpf sm */
 
111
        IOC_E_HBFAIL            = 9,    /*!< heartbeat failure          */
 
112
        IOC_E_HWERROR           = 10,   /*!< hardware error interrupt   */
 
113
        IOC_E_TIMEOUT           = 11,   /*!< timeout                    */
 
114
        IOC_E_HWFAILED          = 12,   /*!< PCI mapping failure notice */
 
115
};
 
116
 
 
117
bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
 
118
bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event);
 
119
bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event);
 
120
bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event);
 
121
bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event);
 
122
bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event);
 
123
bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event);
 
124
bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
 
125
bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
 
126
bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event);
 
127
 
 
128
static struct bfa_sm_table ioc_sm_table[] = {
 
129
        {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
 
130
        {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
 
131
        {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
 
132
        {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
 
133
        {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
 
134
        {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
 
135
        {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
 
136
        {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
 
137
        {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
 
138
        {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
 
139
};
 
140
 
 
141
/*
 
142
 * Forward declareations for iocpf state machine
 
143
 */
 
144
static void bfa_iocpf_enable(struct bfa_ioc *ioc);
 
145
static void bfa_iocpf_disable(struct bfa_ioc *ioc);
 
146
static void bfa_iocpf_fail(struct bfa_ioc *ioc);
 
147
static void bfa_iocpf_initfail(struct bfa_ioc *ioc);
 
148
static void bfa_iocpf_getattrfail(struct bfa_ioc *ioc);
 
149
static void bfa_iocpf_stop(struct bfa_ioc *ioc);
 
150
 
 
151
/**
 
152
 * IOCPF state machine events
 
153
 */
 
154
enum iocpf_event {
 
155
        IOCPF_E_ENABLE          = 1,    /*!< IOCPF enable request       */
 
156
        IOCPF_E_DISABLE         = 2,    /*!< IOCPF disable request      */
 
157
        IOCPF_E_STOP            = 3,    /*!< stop on driver detach      */
 
158
        IOCPF_E_FWREADY         = 4,    /*!< f/w initialization done    */
 
159
        IOCPF_E_FWRSP_ENABLE    = 5,    /*!< enable f/w response        */
 
160
        IOCPF_E_FWRSP_DISABLE   = 6,    /*!< disable f/w response       */
 
161
        IOCPF_E_FAIL            = 7,    /*!< failure notice by ioc sm   */
 
162
        IOCPF_E_INITFAIL        = 8,    /*!< init fail notice by ioc sm */
 
163
        IOCPF_E_GETATTRFAIL     = 9,    /*!< init fail notice by ioc sm */
 
164
        IOCPF_E_SEMLOCKED       = 10,   /*!< h/w semaphore is locked    */
 
165
        IOCPF_E_TIMEOUT         = 11,   /*!< f/w response timeout       */
 
166
        IOCPF_E_SEM_ERROR       = 12,   /*!< h/w sem mapping error      */
 
167
};
 
168
 
 
169
/**
 
170
 * IOCPF states
 
171
 */
 
172
enum bfa_iocpf_state {
 
173
        BFA_IOCPF_RESET         = 1,    /*!< IOC is in reset state */
 
174
        BFA_IOCPF_SEMWAIT       = 2,    /*!< Waiting for IOC h/w semaphore */
 
175
        BFA_IOCPF_HWINIT        = 3,    /*!< IOC h/w is being initialized */
 
176
        BFA_IOCPF_READY         = 4,    /*!< IOCPF is initialized */
 
177
        BFA_IOCPF_INITFAIL      = 5,    /*!< IOCPF failed */
 
178
        BFA_IOCPF_FAIL          = 6,    /*!< IOCPF failed */
 
179
        BFA_IOCPF_DISABLING     = 7,    /*!< IOCPF is being disabled */
 
180
        BFA_IOCPF_DISABLED      = 8,    /*!< IOCPF is disabled */
 
181
        BFA_IOCPF_FWMISMATCH    = 9,    /*!< IOC f/w different from drivers */
 
182
};
 
183
 
 
184
bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf, enum iocpf_event);
 
185
bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf, enum iocpf_event);
 
186
bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf, enum iocpf_event);
 
187
bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf, enum iocpf_event);
 
188
bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf, enum iocpf_event);
 
189
bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf, enum iocpf_event);
 
190
bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf, enum iocpf_event);
 
191
bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf,
 
192
                                                enum iocpf_event);
 
193
bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf, enum iocpf_event);
 
194
bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf, enum iocpf_event);
 
195
bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf, enum iocpf_event);
 
196
bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf, enum iocpf_event);
 
197
bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf,
 
198
                                                enum iocpf_event);
 
199
bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event);
 
200
 
 
201
static struct bfa_sm_table iocpf_sm_table[] = {
 
202
        {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
 
203
        {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
 
204
        {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
 
205
        {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
 
206
        {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
 
207
        {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
 
208
        {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
 
209
        {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
 
210
        {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
 
211
        {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
 
212
        {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
 
213
        {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
 
214
        {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
 
215
        {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
 
216
};
 
217
 
 
218
/**
 
219
 * IOC State Machine
 
220
 */
 
221
 
 
222
/**
 
223
 * Beginning state. IOC uninit state.
 
224
 */
 
225
static void
 
226
bfa_ioc_sm_uninit_entry(struct bfa_ioc *ioc)
 
227
{
 
228
}
 
229
 
 
230
/**
 
231
 * IOC is in uninit state.
 
232
 */
 
233
static void
 
234
bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event)
 
235
{
 
236
        switch (event) {
 
237
        case IOC_E_RESET:
 
238
                bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
 
239
                break;
 
240
 
 
241
        default:
 
242
                bfa_sm_fault(event);
 
243
        }
 
244
}
 
245
 
 
246
/**
 
247
 * Reset entry actions -- initialize state machine
 
248
 */
 
249
static void
 
250
bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc)
 
251
{
 
252
        bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
 
253
}
 
254
 
 
255
/**
 
256
 * IOC is in reset state.
 
257
 */
 
258
static void
 
259
bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
 
260
{
 
261
        switch (event) {
 
262
        case IOC_E_ENABLE:
 
263
                bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
 
264
                break;
 
265
 
 
266
        case IOC_E_DISABLE:
 
267
                bfa_ioc_disable_comp(ioc);
 
268
                break;
 
269
 
 
270
        case IOC_E_DETACH:
 
271
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
272
                break;
 
273
 
 
274
        default:
 
275
                bfa_sm_fault(event);
 
276
        }
 
277
}
 
278
 
 
279
static void
 
280
bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc)
 
281
{
 
282
        bfa_iocpf_enable(ioc);
 
283
}
 
284
 
 
285
/**
 
286
 * Host IOC function is being enabled, awaiting response from firmware.
 
287
 * Semaphore is acquired.
 
288
 */
 
289
static void
 
290
bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
 
291
{
 
292
        switch (event) {
 
293
        case IOC_E_ENABLED:
 
294
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
 
295
                break;
 
296
 
 
297
        case IOC_E_PFFAILED:
 
298
                /* !!! fall through !!! */
 
299
        case IOC_E_HWERROR:
 
300
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
301
                bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
302
                if (event != IOC_E_PFFAILED)
 
303
                        bfa_iocpf_initfail(ioc);
 
304
                break;
 
305
 
 
306
        case IOC_E_HWFAILED:
 
307
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
308
                bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
 
309
                break;
 
310
 
 
311
        case IOC_E_DISABLE:
 
312
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
 
313
                break;
 
314
 
 
315
        case IOC_E_DETACH:
 
316
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
317
                bfa_iocpf_stop(ioc);
 
318
                break;
 
319
 
 
320
        case IOC_E_ENABLE:
 
321
                break;
 
322
 
 
323
        default:
 
324
                bfa_sm_fault(event);
 
325
        }
 
326
}
 
327
 
 
328
/**
 
329
 * Semaphore should be acquired for version check.
 
330
 */
 
331
static void
 
332
bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc)
 
333
{
 
334
        mod_timer(&ioc->ioc_timer, jiffies +
 
335
                msecs_to_jiffies(BFA_IOC_TOV));
 
336
        bfa_ioc_send_getattr(ioc);
 
337
}
 
338
 
 
339
/**
 
340
 * IOC configuration in progress. Timer is active.
 
341
 */
 
342
static void
 
343
bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
 
344
{
 
345
        switch (event) {
 
346
        case IOC_E_FWRSP_GETATTR:
 
347
                del_timer(&ioc->ioc_timer);
 
348
                bfa_ioc_check_attr_wwns(ioc);
 
349
                bfa_ioc_hb_monitor(ioc);
 
350
                bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
 
351
                break;
 
352
 
 
353
        case IOC_E_PFFAILED:
 
354
        case IOC_E_HWERROR:
 
355
                del_timer(&ioc->ioc_timer);
 
356
                /* fall through */
 
357
        case IOC_E_TIMEOUT:
 
358
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
359
                bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
360
                if (event != IOC_E_PFFAILED)
 
361
                        bfa_iocpf_getattrfail(ioc);
 
362
                break;
 
363
 
 
364
        case IOC_E_DISABLE:
 
365
                del_timer(&ioc->ioc_timer);
 
366
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
 
367
                break;
 
368
 
 
369
        case IOC_E_ENABLE:
 
370
                break;
 
371
 
 
372
        default:
 
373
                bfa_sm_fault(event);
 
374
        }
 
375
}
 
376
 
 
377
static void
 
378
bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
 
379
{
 
380
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
 
381
        bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
 
382
}
 
383
 
 
384
static void
 
385
bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
 
386
{
 
387
        switch (event) {
 
388
        case IOC_E_ENABLE:
 
389
                break;
 
390
 
 
391
        case IOC_E_DISABLE:
 
392
                bfa_ioc_hb_stop(ioc);
 
393
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
 
394
                break;
 
395
 
 
396
        case IOC_E_PFFAILED:
 
397
        case IOC_E_HWERROR:
 
398
                bfa_ioc_hb_stop(ioc);
 
399
                /* !!! fall through !!! */
 
400
        case IOC_E_HBFAIL:
 
401
                if (ioc->iocpf.auto_recover)
 
402
                        bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
 
403
                else
 
404
                        bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
405
 
 
406
                bfa_ioc_fail_notify(ioc);
 
407
 
 
408
                if (event != IOC_E_PFFAILED)
 
409
                        bfa_iocpf_fail(ioc);
 
410
                break;
 
411
 
 
412
        default:
 
413
                bfa_sm_fault(event);
 
414
        }
 
415
}
 
416
 
 
417
static void
 
418
bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc)
 
419
{
 
420
        bfa_iocpf_disable(ioc);
 
421
}
 
422
 
 
423
/**
 
424
 * IOC is being disabled
 
425
 */
 
426
static void
 
427
bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
 
428
{
 
429
        switch (event) {
 
430
        case IOC_E_DISABLED:
 
431
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
 
432
                break;
 
433
 
 
434
        case IOC_E_HWERROR:
 
435
                /*
 
436
                 * No state change.  Will move to disabled state
 
437
                 * after iocpf sm completes failure processing and
 
438
                 * moves to disabled state.
 
439
                 */
 
440
                bfa_iocpf_fail(ioc);
 
441
                break;
 
442
 
 
443
        case IOC_E_HWFAILED:
 
444
                bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
 
445
                bfa_ioc_disable_comp(ioc);
 
446
                break;
 
447
 
 
448
        default:
 
449
                bfa_sm_fault(event);
 
450
        }
 
451
}
 
452
 
 
453
/**
 
454
 * IOC disable completion entry.
 
455
 */
 
456
static void
 
457
bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc)
 
458
{
 
459
        bfa_ioc_disable_comp(ioc);
 
460
}
 
461
 
 
462
static void
 
463
bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
 
464
{
 
465
        switch (event) {
 
466
        case IOC_E_ENABLE:
 
467
                bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
 
468
                break;
 
469
 
 
470
        case IOC_E_DISABLE:
 
471
                ioc->cbfn->disable_cbfn(ioc->bfa);
 
472
                break;
 
473
 
 
474
        case IOC_E_DETACH:
 
475
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
476
                bfa_iocpf_stop(ioc);
 
477
                break;
 
478
 
 
479
        default:
 
480
                bfa_sm_fault(event);
 
481
        }
 
482
}
 
483
 
 
484
static void
 
485
bfa_ioc_sm_fail_retry_entry(struct bfa_ioc *ioc)
 
486
{
 
487
}
 
488
 
 
489
/**
 
490
 * Hardware initialization retry.
 
491
 */
 
492
static void
 
493
bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
 
494
{
 
495
        switch (event) {
 
496
        case IOC_E_ENABLED:
 
497
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
 
498
                break;
 
499
 
 
500
        case IOC_E_PFFAILED:
 
501
        case IOC_E_HWERROR:
 
502
                /**
 
503
                 * Initialization retry failed.
 
504
                 */
 
505
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
506
                bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
507
                if (event != IOC_E_PFFAILED)
 
508
                        bfa_iocpf_initfail(ioc);
 
509
                break;
 
510
 
 
511
        case IOC_E_HWFAILED:
 
512
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
513
                bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
 
514
                break;
 
515
 
 
516
        case IOC_E_ENABLE:
 
517
                break;
 
518
 
 
519
        case IOC_E_DISABLE:
 
520
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
 
521
                break;
 
522
 
 
523
        case IOC_E_DETACH:
 
524
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
525
                bfa_iocpf_stop(ioc);
 
526
                break;
 
527
 
 
528
        default:
 
529
                bfa_sm_fault(event);
 
530
        }
 
531
}
 
532
 
 
533
static void
 
534
bfa_ioc_sm_fail_entry(struct bfa_ioc *ioc)
 
535
{
 
536
}
 
537
 
 
538
/**
 
539
 * IOC failure.
 
540
 */
 
541
static void
 
542
bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
 
543
{
 
544
        switch (event) {
 
545
        case IOC_E_ENABLE:
 
546
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
547
                break;
 
548
 
 
549
        case IOC_E_DISABLE:
 
550
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
 
551
                break;
 
552
 
 
553
        case IOC_E_DETACH:
 
554
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
555
                bfa_iocpf_stop(ioc);
 
556
                break;
 
557
 
 
558
        case IOC_E_HWERROR:
 
559
                /* HB failure notification, ignore. */
 
560
                break;
 
561
 
 
562
        default:
 
563
                bfa_sm_fault(event);
 
564
        }
 
565
}
 
566
 
 
567
static void
 
568
bfa_ioc_sm_hwfail_entry(struct bfa_ioc *ioc)
 
569
{
 
570
}
 
571
 
 
572
/**
 
573
 * IOC failure.
 
574
 */
 
575
static void
 
576
bfa_ioc_sm_hwfail(struct bfa_ioc *ioc, enum ioc_event event)
 
577
{
 
578
        switch (event) {
 
579
 
 
580
        case IOC_E_ENABLE:
 
581
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
582
                break;
 
583
 
 
584
        case IOC_E_DISABLE:
 
585
                ioc->cbfn->disable_cbfn(ioc->bfa);
 
586
                break;
 
587
 
 
588
        case IOC_E_DETACH:
 
589
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
590
                break;
 
591
 
 
592
        default:
 
593
                bfa_sm_fault(event);
 
594
        }
 
595
}
 
596
 
 
597
/**
 
598
 * IOCPF State Machine
 
599
 */
 
600
 
 
601
/**
 
602
 * Reset entry actions -- initialize state machine
 
603
 */
 
604
static void
 
605
bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf)
 
606
{
 
607
        iocpf->fw_mismatch_notified = false;
 
608
        iocpf->auto_recover = bfa_nw_auto_recover;
 
609
}
 
610
 
 
611
/**
 
612
 * Beginning state. IOC is in reset state.
 
613
 */
 
614
static void
 
615
bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
616
{
 
617
        switch (event) {
 
618
        case IOCPF_E_ENABLE:
 
619
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
 
620
                break;
 
621
 
 
622
        case IOCPF_E_STOP:
 
623
                break;
 
624
 
 
625
        default:
 
626
                bfa_sm_fault(event);
 
627
        }
 
628
}
 
629
 
 
630
/**
 
631
 * Semaphore should be acquired for version check.
 
632
 */
 
633
static void
 
634
bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf)
 
635
{
 
636
        bfa_ioc_hw_sem_init(iocpf->ioc);
 
637
        bfa_ioc_hw_sem_get(iocpf->ioc);
 
638
}
 
639
 
 
640
/**
 
641
 * Awaiting h/w semaphore to continue with version check.
 
642
 */
 
643
static void
 
644
bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
645
{
 
646
        struct bfa_ioc *ioc = iocpf->ioc;
 
647
 
 
648
        switch (event) {
 
649
        case IOCPF_E_SEMLOCKED:
 
650
                if (bfa_ioc_firmware_lock(ioc)) {
 
651
                        if (bfa_ioc_sync_start(ioc)) {
 
652
                                bfa_ioc_sync_join(ioc);
 
653
                                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
 
654
                        } else {
 
655
                                bfa_ioc_firmware_unlock(ioc);
 
656
                                bfa_nw_ioc_hw_sem_release(ioc);
 
657
                                mod_timer(&ioc->sem_timer, jiffies +
 
658
                                        msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
 
659
                        }
 
660
                } else {
 
661
                        bfa_nw_ioc_hw_sem_release(ioc);
 
662
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
 
663
                }
 
664
                break;
 
665
 
 
666
        case IOCPF_E_SEM_ERROR:
 
667
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
668
                bfa_ioc_pf_hwfailed(ioc);
 
669
                break;
 
670
 
 
671
        case IOCPF_E_DISABLE:
 
672
                bfa_ioc_hw_sem_get_cancel(ioc);
 
673
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
674
                bfa_ioc_pf_disabled(ioc);
 
675
                break;
 
676
 
 
677
        case IOCPF_E_STOP:
 
678
                bfa_ioc_hw_sem_get_cancel(ioc);
 
679
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
680
                break;
 
681
 
 
682
        default:
 
683
                bfa_sm_fault(event);
 
684
        }
 
685
}
 
686
 
 
687
/**
 
688
 * Notify enable completion callback
 
689
 */
 
690
static void
 
691
bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
 
692
{
 
693
        /* Call only the first time sm enters fwmismatch state. */
 
694
        if (iocpf->fw_mismatch_notified == false)
 
695
                bfa_ioc_pf_fwmismatch(iocpf->ioc);
 
696
 
 
697
        iocpf->fw_mismatch_notified = true;
 
698
        mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
 
699
                msecs_to_jiffies(BFA_IOC_TOV));
 
700
}
 
701
 
 
702
/**
 
703
 * Awaiting firmware version match.
 
704
 */
 
705
static void
 
706
bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
707
{
 
708
        struct bfa_ioc *ioc = iocpf->ioc;
 
709
 
 
710
        switch (event) {
 
711
        case IOCPF_E_TIMEOUT:
 
712
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
 
713
                break;
 
714
 
 
715
        case IOCPF_E_DISABLE:
 
716
                del_timer(&ioc->iocpf_timer);
 
717
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
718
                bfa_ioc_pf_disabled(ioc);
 
719
                break;
 
720
 
 
721
        case IOCPF_E_STOP:
 
722
                del_timer(&ioc->iocpf_timer);
 
723
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
724
                break;
 
725
 
 
726
        default:
 
727
                bfa_sm_fault(event);
 
728
        }
 
729
}
 
730
 
 
731
/**
 
732
 * Request for semaphore.
 
733
 */
 
734
static void
 
735
bfa_iocpf_sm_semwait_entry(struct bfa_iocpf *iocpf)
 
736
{
 
737
        bfa_ioc_hw_sem_get(iocpf->ioc);
 
738
}
 
739
 
 
740
/**
 
741
 * Awaiting semaphore for h/w initialzation.
 
742
 */
 
743
static void
 
744
bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
745
{
 
746
        struct bfa_ioc *ioc = iocpf->ioc;
 
747
 
 
748
        switch (event) {
 
749
        case IOCPF_E_SEMLOCKED:
 
750
                if (bfa_ioc_sync_complete(ioc)) {
 
751
                        bfa_ioc_sync_join(ioc);
 
752
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
 
753
                } else {
 
754
                        bfa_nw_ioc_hw_sem_release(ioc);
 
755
                        mod_timer(&ioc->sem_timer, jiffies +
 
756
                                msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
 
757
                }
 
758
                break;
 
759
 
 
760
        case IOCPF_E_SEM_ERROR:
 
761
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
762
                bfa_ioc_pf_hwfailed(ioc);
 
763
                break;
 
764
 
 
765
        case IOCPF_E_DISABLE:
 
766
                bfa_ioc_hw_sem_get_cancel(ioc);
 
767
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 
768
                break;
 
769
 
 
770
        default:
 
771
                bfa_sm_fault(event);
 
772
        }
 
773
}
 
774
 
 
775
static void
 
776
bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf)
 
777
{
 
778
        iocpf->poll_time = 0;
 
779
        bfa_ioc_reset(iocpf->ioc, false);
 
780
}
 
781
 
 
782
/**
 
783
 * Hardware is being initialized. Interrupts are enabled.
 
784
 * Holding hardware semaphore lock.
 
785
 */
 
786
static void
 
787
bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
788
{
 
789
        struct bfa_ioc *ioc = iocpf->ioc;
 
790
 
 
791
        switch (event) {
 
792
        case IOCPF_E_FWREADY:
 
793
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
 
794
                break;
 
795
 
 
796
        case IOCPF_E_TIMEOUT:
 
797
                bfa_nw_ioc_hw_sem_release(ioc);
 
798
                        bfa_ioc_pf_failed(ioc);
 
799
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
 
800
                break;
 
801
 
 
802
        case IOCPF_E_DISABLE:
 
803
                del_timer(&ioc->iocpf_timer);
 
804
                bfa_ioc_sync_leave(ioc);
 
805
                bfa_nw_ioc_hw_sem_release(ioc);
 
806
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
 
807
                break;
 
808
 
 
809
        default:
 
810
                bfa_sm_fault(event);
 
811
        }
 
812
}
 
813
 
 
814
static void
 
815
bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
 
816
{
 
817
        mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
 
818
                msecs_to_jiffies(BFA_IOC_TOV));
 
819
        /**
 
820
         * Enable Interrupts before sending fw IOC ENABLE cmd.
 
821
         */
 
822
        iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
 
823
        bfa_ioc_send_enable(iocpf->ioc);
 
824
}
 
825
 
 
826
/**
 
827
 * Host IOC function is being enabled, awaiting response from firmware.
 
828
 * Semaphore is acquired.
 
829
 */
 
830
static void
 
831
bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
832
{
 
833
        struct bfa_ioc *ioc = iocpf->ioc;
 
834
 
 
835
        switch (event) {
 
836
        case IOCPF_E_FWRSP_ENABLE:
 
837
                del_timer(&ioc->iocpf_timer);
 
838
                bfa_nw_ioc_hw_sem_release(ioc);
 
839
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
 
840
                break;
 
841
 
 
842
        case IOCPF_E_INITFAIL:
 
843
                del_timer(&ioc->iocpf_timer);
 
844
                /*
 
845
                 * !!! fall through !!!
 
846
                 */
 
847
        case IOCPF_E_TIMEOUT:
 
848
                bfa_nw_ioc_hw_sem_release(ioc);
 
849
                if (event == IOCPF_E_TIMEOUT)
 
850
                        bfa_ioc_pf_failed(ioc);
 
851
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
 
852
                break;
 
853
 
 
854
        case IOCPF_E_DISABLE:
 
855
                del_timer(&ioc->iocpf_timer);
 
856
                bfa_nw_ioc_hw_sem_release(ioc);
 
857
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
 
858
                break;
 
859
 
 
860
        default:
 
861
                bfa_sm_fault(event);
 
862
        }
 
863
}
 
864
 
 
865
static void
 
866
bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
 
867
{
 
868
        bfa_ioc_pf_enabled(iocpf->ioc);
 
869
}
 
870
 
 
871
static void
 
872
bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
873
{
 
874
        switch (event) {
 
875
        case IOCPF_E_DISABLE:
 
876
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
 
877
                break;
 
878
 
 
879
        case IOCPF_E_GETATTRFAIL:
 
880
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
 
881
                break;
 
882
 
 
883
        case IOCPF_E_FAIL:
 
884
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
 
885
                break;
 
886
 
 
887
        default:
 
888
                bfa_sm_fault(event);
 
889
        }
 
890
}
 
891
 
 
892
static void
 
893
bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf)
 
894
{
 
895
        mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
 
896
                msecs_to_jiffies(BFA_IOC_TOV));
 
897
        bfa_ioc_send_disable(iocpf->ioc);
 
898
}
 
899
 
 
900
/**
 
901
 * IOC is being disabled
 
902
 */
 
903
static void
 
904
bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
905
{
 
906
        struct bfa_ioc *ioc = iocpf->ioc;
 
907
 
 
908
        switch (event) {
 
909
        case IOCPF_E_FWRSP_DISABLE:
 
910
                del_timer(&ioc->iocpf_timer);
 
911
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 
912
                break;
 
913
 
 
914
        case IOCPF_E_FAIL:
 
915
                del_timer(&ioc->iocpf_timer);
 
916
                /*
 
917
                 * !!! fall through !!!
 
918
                 */
 
919
 
 
920
        case IOCPF_E_TIMEOUT:
 
921
                writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
 
922
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 
923
                break;
 
924
 
 
925
        case IOCPF_E_FWRSP_ENABLE:
 
926
                break;
 
927
 
 
928
        default:
 
929
                bfa_sm_fault(event);
 
930
        }
 
931
}
 
932
 
 
933
static void
 
934
bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf *iocpf)
 
935
{
 
936
        bfa_ioc_hw_sem_get(iocpf->ioc);
 
937
}
 
938
 
 
939
/**
 
940
 * IOC hb ack request is being removed.
 
941
 */
 
942
static void
 
943
bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
944
{
 
945
        struct bfa_ioc *ioc = iocpf->ioc;
 
946
 
 
947
        switch (event) {
 
948
        case IOCPF_E_SEMLOCKED:
 
949
                bfa_ioc_sync_leave(ioc);
 
950
                bfa_nw_ioc_hw_sem_release(ioc);
 
951
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
 
952
                break;
 
953
 
 
954
        case IOCPF_E_SEM_ERROR:
 
955
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
956
                bfa_ioc_pf_hwfailed(ioc);
 
957
                break;
 
958
 
 
959
        case IOCPF_E_FAIL:
 
960
                break;
 
961
 
 
962
        default:
 
963
                bfa_sm_fault(event);
 
964
        }
 
965
}
 
966
 
 
967
/**
 
968
 * IOC disable completion entry.
 
969
 */
 
970
static void
 
971
bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf)
 
972
{
 
973
        bfa_ioc_mbox_flush(iocpf->ioc);
 
974
        bfa_ioc_pf_disabled(iocpf->ioc);
 
975
}
 
976
 
 
977
static void
 
978
bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
979
{
 
980
        struct bfa_ioc *ioc = iocpf->ioc;
 
981
 
 
982
        switch (event) {
 
983
        case IOCPF_E_ENABLE:
 
984
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
 
985
                break;
 
986
 
 
987
        case IOCPF_E_STOP:
 
988
                bfa_ioc_firmware_unlock(ioc);
 
989
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
990
                break;
 
991
 
 
992
        default:
 
993
                bfa_sm_fault(event);
 
994
        }
 
995
}
 
996
 
 
997
static void
 
998
bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf *iocpf)
 
999
{
 
1000
        bfa_ioc_hw_sem_get(iocpf->ioc);
 
1001
}
 
1002
 
 
1003
/**
 
1004
 * Hardware initialization failed.
 
1005
 */
 
1006
static void
 
1007
bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
1008
{
 
1009
        struct bfa_ioc *ioc = iocpf->ioc;
 
1010
 
 
1011
        switch (event) {
 
1012
        case IOCPF_E_SEMLOCKED:
 
1013
                bfa_ioc_notify_fail(ioc);
 
1014
                bfa_ioc_sync_leave(ioc);
 
1015
                writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
 
1016
                bfa_nw_ioc_hw_sem_release(ioc);
 
1017
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
 
1018
                break;
 
1019
 
 
1020
        case IOCPF_E_SEM_ERROR:
 
1021
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
1022
                bfa_ioc_pf_hwfailed(ioc);
 
1023
                break;
 
1024
 
 
1025
        case IOCPF_E_DISABLE:
 
1026
                bfa_ioc_hw_sem_get_cancel(ioc);
 
1027
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 
1028
                break;
 
1029
 
 
1030
        case IOCPF_E_STOP:
 
1031
                bfa_ioc_hw_sem_get_cancel(ioc);
 
1032
                bfa_ioc_firmware_unlock(ioc);
 
1033
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
1034
                break;
 
1035
 
 
1036
        case IOCPF_E_FAIL:
 
1037
                break;
 
1038
 
 
1039
        default:
 
1040
                bfa_sm_fault(event);
 
1041
        }
 
1042
}
 
1043
 
 
1044
static void
 
1045
bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf)
 
1046
{
 
1047
}
 
1048
 
 
1049
/**
 
1050
 * Hardware initialization failed.
 
1051
 */
 
1052
static void
 
1053
bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
1054
{
 
1055
        struct bfa_ioc *ioc = iocpf->ioc;
 
1056
 
 
1057
        switch (event) {
 
1058
        case IOCPF_E_DISABLE:
 
1059
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
 
1060
                break;
 
1061
 
 
1062
        case IOCPF_E_STOP:
 
1063
                bfa_ioc_firmware_unlock(ioc);
 
1064
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
 
1065
                break;
 
1066
 
 
1067
        default:
 
1068
                bfa_sm_fault(event);
 
1069
        }
 
1070
}
 
1071
 
 
1072
static void
 
1073
bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf)
 
1074
{
 
1075
        /**
 
1076
         * Mark IOC as failed in hardware and stop firmware.
 
1077
         */
 
1078
        bfa_ioc_lpu_stop(iocpf->ioc);
 
1079
 
 
1080
        /**
 
1081
         * Flush any queued up mailbox requests.
 
1082
         */
 
1083
        bfa_ioc_mbox_flush(iocpf->ioc);
 
1084
        bfa_ioc_hw_sem_get(iocpf->ioc);
 
1085
}
 
1086
 
 
1087
/**
 
1088
 * IOC is in failed state.
 
1089
 */
 
1090
static void
 
1091
bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
1092
{
 
1093
        struct bfa_ioc *ioc = iocpf->ioc;
 
1094
 
 
1095
        switch (event) {
 
1096
        case IOCPF_E_SEMLOCKED:
 
1097
                bfa_ioc_sync_ack(ioc);
 
1098
                bfa_ioc_notify_fail(ioc);
 
1099
                if (!iocpf->auto_recover) {
 
1100
                        bfa_ioc_sync_leave(ioc);
 
1101
                        writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
 
1102
                        bfa_nw_ioc_hw_sem_release(ioc);
 
1103
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
1104
                } else {
 
1105
                        if (bfa_ioc_sync_complete(ioc))
 
1106
                                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
 
1107
                        else {
 
1108
                                bfa_nw_ioc_hw_sem_release(ioc);
 
1109
                                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
 
1110
                        }
 
1111
                }
 
1112
                break;
 
1113
 
 
1114
        case IOCPF_E_SEM_ERROR:
 
1115
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 
1116
                bfa_ioc_pf_hwfailed(ioc);
 
1117
                break;
 
1118
 
 
1119
        case IOCPF_E_DISABLE:
 
1120
                bfa_ioc_hw_sem_get_cancel(ioc);
 
1121
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 
1122
                break;
 
1123
 
 
1124
        case IOCPF_E_FAIL:
 
1125
                break;
 
1126
 
 
1127
        default:
 
1128
                bfa_sm_fault(event);
 
1129
        }
 
1130
}
 
1131
 
 
1132
static void
 
1133
bfa_iocpf_sm_fail_entry(struct bfa_iocpf *iocpf)
 
1134
{
 
1135
}
 
1136
 
 
1137
/**
 
1138
 * @brief
 
1139
 * IOC is in failed state.
 
1140
 */
 
1141
static void
 
1142
bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
1143
{
 
1144
        switch (event) {
 
1145
        case IOCPF_E_DISABLE:
 
1146
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
 
1147
                break;
 
1148
 
 
1149
        default:
 
1150
                bfa_sm_fault(event);
 
1151
        }
 
1152
}
 
1153
 
 
1154
/**
 
1155
 * BFA IOC private functions
 
1156
 */
 
1157
 
 
1158
/**
 
1159
 * Notify common modules registered for notification.
 
1160
 */
 
1161
static void
 
1162
bfa_ioc_event_notify(struct bfa_ioc *ioc, enum bfa_ioc_event event)
 
1163
{
 
1164
        struct bfa_ioc_notify *notify;
 
1165
        struct list_head                        *qe;
 
1166
 
 
1167
        list_for_each(qe, &ioc->notify_q) {
 
1168
                notify = (struct bfa_ioc_notify *)qe;
 
1169
                notify->cbfn(notify->cbarg, event);
 
1170
        }
 
1171
}
 
1172
 
 
1173
static void
 
1174
bfa_ioc_disable_comp(struct bfa_ioc *ioc)
 
1175
{
 
1176
        ioc->cbfn->disable_cbfn(ioc->bfa);
 
1177
        bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
 
1178
}
 
1179
 
 
1180
bool
 
1181
bfa_nw_ioc_sem_get(void __iomem *sem_reg)
 
1182
{
 
1183
        u32 r32;
 
1184
        int cnt = 0;
 
1185
#define BFA_SEM_SPINCNT 3000
 
1186
 
 
1187
        r32 = readl(sem_reg);
 
1188
 
 
1189
        while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
 
1190
                cnt++;
 
1191
                udelay(2);
 
1192
                r32 = readl(sem_reg);
 
1193
        }
 
1194
 
 
1195
        if (!(r32 & 1))
 
1196
                return true;
 
1197
 
 
1198
        return false;
 
1199
}
 
1200
 
 
1201
void
 
1202
bfa_nw_ioc_sem_release(void __iomem *sem_reg)
 
1203
{
 
1204
        readl(sem_reg);
 
1205
        writel(1, sem_reg);
 
1206
}
 
1207
 
 
1208
static void
 
1209
bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
 
1210
{
 
1211
        struct bfi_ioc_image_hdr fwhdr;
 
1212
        u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
 
1213
 
 
1214
        if (fwstate == BFI_IOC_UNINIT)
 
1215
                return;
 
1216
 
 
1217
        bfa_nw_ioc_fwver_get(ioc, &fwhdr);
 
1218
 
 
1219
        if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
 
1220
                return;
 
1221
 
 
1222
        writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
 
1223
 
 
1224
        /*
 
1225
         * Try to lock and then unlock the semaphore.
 
1226
         */
 
1227
        readl(ioc->ioc_regs.ioc_sem_reg);
 
1228
        writel(1, ioc->ioc_regs.ioc_sem_reg);
 
1229
}
 
1230
 
 
1231
static void
 
1232
bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
 
1233
{
 
1234
        u32     r32;
 
1235
 
 
1236
        /**
 
1237
         * First read to the semaphore register will return 0, subsequent reads
 
1238
         * will return 1. Semaphore is released by writing 1 to the register
 
1239
         */
 
1240
        r32 = readl(ioc->ioc_regs.ioc_sem_reg);
 
1241
        if (r32 == ~0) {
 
1242
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
 
1243
                return;
 
1244
        }
 
1245
        if (!(r32 & 1)) {
 
1246
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
 
1247
                return;
 
1248
        }
 
1249
 
 
1250
        mod_timer(&ioc->sem_timer, jiffies +
 
1251
                msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
 
1252
}
 
1253
 
 
1254
void
 
1255
bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc)
 
1256
{
 
1257
        writel(1, ioc->ioc_regs.ioc_sem_reg);
 
1258
}
 
1259
 
 
1260
static void
 
1261
bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc)
 
1262
{
 
1263
        del_timer(&ioc->sem_timer);
 
1264
}
 
1265
 
 
1266
/**
 
1267
 * @brief
 
1268
 * Initialize LPU local memory (aka secondary memory / SRAM)
 
1269
 */
 
1270
static void
 
1271
bfa_ioc_lmem_init(struct bfa_ioc *ioc)
 
1272
{
 
1273
        u32     pss_ctl;
 
1274
        int             i;
 
1275
#define PSS_LMEM_INIT_TIME  10000
 
1276
 
 
1277
        pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
 
1278
        pss_ctl &= ~__PSS_LMEM_RESET;
 
1279
        pss_ctl |= __PSS_LMEM_INIT_EN;
 
1280
 
 
1281
        /*
 
1282
         * i2c workaround 12.5khz clock
 
1283
         */
 
1284
        pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
 
1285
        writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 
1286
 
 
1287
        /**
 
1288
         * wait for memory initialization to be complete
 
1289
         */
 
1290
        i = 0;
 
1291
        do {
 
1292
                pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
 
1293
                i++;
 
1294
        } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
 
1295
 
 
1296
        /**
 
1297
         * If memory initialization is not successful, IOC timeout will catch
 
1298
         * such failures.
 
1299
         */
 
1300
        BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
 
1301
 
 
1302
        pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
 
1303
        writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 
1304
}
 
1305
 
 
1306
static void
 
1307
bfa_ioc_lpu_start(struct bfa_ioc *ioc)
 
1308
{
 
1309
        u32     pss_ctl;
 
1310
 
 
1311
        /**
 
1312
         * Take processor out of reset.
 
1313
         */
 
1314
        pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
 
1315
        pss_ctl &= ~__PSS_LPU0_RESET;
 
1316
 
 
1317
        writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 
1318
}
 
1319
 
 
1320
static void
 
1321
bfa_ioc_lpu_stop(struct bfa_ioc *ioc)
 
1322
{
 
1323
        u32     pss_ctl;
 
1324
 
 
1325
        /**
 
1326
         * Put processors in reset.
 
1327
         */
 
1328
        pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
 
1329
        pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
 
1330
 
 
1331
        writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 
1332
}
 
1333
 
 
1334
/**
 
1335
 * Get driver and firmware versions.
 
1336
 */
 
1337
void
 
1338
bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
 
1339
{
 
1340
        u32     pgnum;
 
1341
        u32     loff = 0;
 
1342
        int             i;
 
1343
        u32     *fwsig = (u32 *) fwhdr;
 
1344
 
 
1345
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
 
1346
        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
1347
 
 
1348
        for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32));
 
1349
             i++) {
 
1350
                fwsig[i] =
 
1351
                        swab32(readl((loff) + (ioc->ioc_regs.smem_page_start)));
 
1352
                loff += sizeof(u32);
 
1353
        }
 
1354
}
 
1355
 
 
1356
/**
 
1357
 * Returns TRUE if same.
 
1358
 */
 
1359
bool
 
1360
bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
 
1361
{
 
1362
        struct bfi_ioc_image_hdr *drv_fwhdr;
 
1363
        int i;
 
1364
 
 
1365
        drv_fwhdr = (struct bfi_ioc_image_hdr *)
 
1366
                bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
 
1367
 
 
1368
        for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
 
1369
                if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i])
 
1370
                        return false;
 
1371
        }
 
1372
 
 
1373
        return true;
 
1374
}
 
1375
 
 
1376
/**
 
1377
 * Return true if current running version is valid. Firmware signature and
 
1378
 * execution context (driver/bios) must match.
 
1379
 */
 
1380
static bool
 
1381
bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env)
 
1382
{
 
1383
        struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr;
 
1384
 
 
1385
        bfa_nw_ioc_fwver_get(ioc, &fwhdr);
 
1386
        drv_fwhdr = (struct bfi_ioc_image_hdr *)
 
1387
                bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
 
1388
 
 
1389
        if (fwhdr.signature != drv_fwhdr->signature)
 
1390
                return false;
 
1391
 
 
1392
        if (swab32(fwhdr.bootenv) != boot_env)
 
1393
                return false;
 
1394
 
 
1395
        return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr);
 
1396
}
 
1397
 
 
1398
/**
 
1399
 * Conditionally flush any pending message from firmware at start.
 
1400
 */
 
1401
static void
 
1402
bfa_ioc_msgflush(struct bfa_ioc *ioc)
 
1403
{
 
1404
        u32     r32;
 
1405
 
 
1406
        r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
 
1407
        if (r32)
 
1408
                writel(1, ioc->ioc_regs.lpu_mbox_cmd);
 
1409
}
 
1410
 
 
1411
/**
 
1412
 * @img ioc_init_logic.jpg
 
1413
 */
 
1414
static void
 
1415
bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
 
1416
{
 
1417
        enum bfi_ioc_state ioc_fwstate;
 
1418
        bool fwvalid;
 
1419
        u32 boot_env;
 
1420
 
 
1421
        ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
 
1422
 
 
1423
        if (force)
 
1424
                ioc_fwstate = BFI_IOC_UNINIT;
 
1425
 
 
1426
        boot_env = BFI_FWBOOT_ENV_OS;
 
1427
 
 
1428
        /**
 
1429
         * check if firmware is valid
 
1430
         */
 
1431
        fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
 
1432
                false : bfa_ioc_fwver_valid(ioc, boot_env);
 
1433
 
 
1434
        if (!fwvalid) {
 
1435
                bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
 
1436
                bfa_ioc_poll_fwinit(ioc);
 
1437
                return;
 
1438
        }
 
1439
 
 
1440
        /**
 
1441
         * If hardware initialization is in progress (initialized by other IOC),
 
1442
         * just wait for an initialization completion interrupt.
 
1443
         */
 
1444
        if (ioc_fwstate == BFI_IOC_INITING) {
 
1445
                bfa_ioc_poll_fwinit(ioc);
 
1446
                return;
 
1447
        }
 
1448
 
 
1449
        /**
 
1450
         * If IOC function is disabled and firmware version is same,
 
1451
         * just re-enable IOC.
 
1452
         */
 
1453
        if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
 
1454
                /**
 
1455
                 * When using MSI-X any pending firmware ready event should
 
1456
                 * be flushed. Otherwise MSI-X interrupts are not delivered.
 
1457
                 */
 
1458
                bfa_ioc_msgflush(ioc);
 
1459
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
 
1460
                return;
 
1461
        }
 
1462
 
 
1463
        /**
 
1464
         * Initialize the h/w for any other states.
 
1465
         */
 
1466
        bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
 
1467
        bfa_ioc_poll_fwinit(ioc);
 
1468
}
 
1469
 
 
1470
void
 
1471
bfa_nw_ioc_timeout(void *ioc_arg)
 
1472
{
 
1473
        struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
 
1474
 
 
1475
        bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
 
1476
}
 
1477
 
 
1478
static void
 
1479
bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len)
 
1480
{
 
1481
        u32 *msgp = (u32 *) ioc_msg;
 
1482
        u32 i;
 
1483
 
 
1484
        BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX));
 
1485
 
 
1486
        /*
 
1487
         * first write msg to mailbox registers
 
1488
         */
 
1489
        for (i = 0; i < len / sizeof(u32); i++)
 
1490
                writel(cpu_to_le32(msgp[i]),
 
1491
                              ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
 
1492
 
 
1493
        for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
 
1494
                writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
 
1495
 
 
1496
        /*
 
1497
         * write 1 to mailbox CMD to trigger LPU event
 
1498
         */
 
1499
        writel(1, ioc->ioc_regs.hfn_mbox_cmd);
 
1500
        (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
 
1501
}
 
1502
 
 
1503
static void
 
1504
bfa_ioc_send_enable(struct bfa_ioc *ioc)
 
1505
{
 
1506
        struct bfi_ioc_ctrl_req enable_req;
 
1507
        struct timeval tv;
 
1508
 
 
1509
        bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
 
1510
                    bfa_ioc_portid(ioc));
 
1511
        enable_req.clscode = htons(ioc->clscode);
 
1512
        do_gettimeofday(&tv);
 
1513
        enable_req.tv_sec = ntohl(tv.tv_sec);
 
1514
        bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
 
1515
}
 
1516
 
 
1517
static void
 
1518
bfa_ioc_send_disable(struct bfa_ioc *ioc)
 
1519
{
 
1520
        struct bfi_ioc_ctrl_req disable_req;
 
1521
 
 
1522
        bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
 
1523
                    bfa_ioc_portid(ioc));
 
1524
        bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req));
 
1525
}
 
1526
 
 
1527
static void
 
1528
bfa_ioc_send_getattr(struct bfa_ioc *ioc)
 
1529
{
 
1530
        struct bfi_ioc_getattr_req attr_req;
 
1531
 
 
1532
        bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
 
1533
                    bfa_ioc_portid(ioc));
 
1534
        bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
 
1535
        bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
 
1536
}
 
1537
 
 
1538
void
 
1539
bfa_nw_ioc_hb_check(void *cbarg)
 
1540
{
 
1541
        struct bfa_ioc *ioc = cbarg;
 
1542
        u32     hb_count;
 
1543
 
 
1544
        hb_count = readl(ioc->ioc_regs.heartbeat);
 
1545
        if (ioc->hb_count == hb_count) {
 
1546
                bfa_ioc_recover(ioc);
 
1547
                return;
 
1548
        } else {
 
1549
                ioc->hb_count = hb_count;
 
1550
        }
 
1551
 
 
1552
        bfa_ioc_mbox_poll(ioc);
 
1553
        mod_timer(&ioc->hb_timer, jiffies +
 
1554
                msecs_to_jiffies(BFA_IOC_HB_TOV));
 
1555
}
 
1556
 
 
1557
static void
 
1558
bfa_ioc_hb_monitor(struct bfa_ioc *ioc)
 
1559
{
 
1560
        ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
 
1561
        mod_timer(&ioc->hb_timer, jiffies +
 
1562
                msecs_to_jiffies(BFA_IOC_HB_TOV));
 
1563
}
 
1564
 
 
1565
static void
 
1566
bfa_ioc_hb_stop(struct bfa_ioc *ioc)
 
1567
{
 
1568
        del_timer(&ioc->hb_timer);
 
1569
}
 
1570
 
 
1571
/**
 
1572
 * @brief
 
1573
 *      Initiate a full firmware download.
 
1574
 */
 
1575
static void
 
1576
bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
 
1577
                    u32 boot_env)
 
1578
{
 
1579
        u32 *fwimg;
 
1580
        u32 pgnum;
 
1581
        u32 loff = 0;
 
1582
        u32 chunkno = 0;
 
1583
        u32 i;
 
1584
        u32 asicmode;
 
1585
 
 
1586
        /**
 
1587
         * Initialize LMEM first before code download
 
1588
         */
 
1589
        bfa_ioc_lmem_init(ioc);
 
1590
 
 
1591
        fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
 
1592
 
 
1593
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
 
1594
 
 
1595
        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
1596
 
 
1597
        for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) {
 
1598
                if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
 
1599
                        chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
 
1600
                        fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
 
1601
                                        BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
 
1602
                }
 
1603
 
 
1604
                /**
 
1605
                 * write smem
 
1606
                 */
 
1607
                writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])),
 
1608
                              ((ioc->ioc_regs.smem_page_start) + (loff)));
 
1609
 
 
1610
                loff += sizeof(u32);
 
1611
 
 
1612
                /**
 
1613
                 * handle page offset wrap around
 
1614
                 */
 
1615
                loff = PSS_SMEM_PGOFF(loff);
 
1616
                if (loff == 0) {
 
1617
                        pgnum++;
 
1618
                        writel(pgnum,
 
1619
                                      ioc->ioc_regs.host_page_num_fn);
 
1620
                }
 
1621
        }
 
1622
 
 
1623
        writel(bfa_ioc_smem_pgnum(ioc, 0),
 
1624
                      ioc->ioc_regs.host_page_num_fn);
 
1625
 
 
1626
        /*
 
1627
         * Set boot type, env and device mode at the end.
 
1628
        */
 
1629
        asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
 
1630
                                        ioc->port0_mode, ioc->port1_mode);
 
1631
        writel(asicmode, ((ioc->ioc_regs.smem_page_start)
 
1632
                        + BFI_FWBOOT_DEVMODE_OFF));
 
1633
        writel(boot_type, ((ioc->ioc_regs.smem_page_start)
 
1634
                        + (BFI_FWBOOT_TYPE_OFF)));
 
1635
        writel(boot_env, ((ioc->ioc_regs.smem_page_start)
 
1636
                        + (BFI_FWBOOT_ENV_OFF)));
 
1637
}
 
1638
 
 
1639
static void
 
1640
bfa_ioc_reset(struct bfa_ioc *ioc, bool force)
 
1641
{
 
1642
        bfa_ioc_hwinit(ioc, force);
 
1643
}
 
1644
 
 
1645
/**
 
1646
 * BFA ioc enable reply by firmware
 
1647
 */
 
1648
static void
 
1649
bfa_ioc_enable_reply(struct bfa_ioc *ioc, enum bfa_mode port_mode,
 
1650
                        u8 cap_bm)
 
1651
{
 
1652
        struct bfa_iocpf *iocpf = &ioc->iocpf;
 
1653
 
 
1654
        ioc->port_mode = ioc->port_mode_cfg = port_mode;
 
1655
        ioc->ad_cap_bm = cap_bm;
 
1656
        bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
 
1657
}
 
1658
 
 
1659
/**
 
1660
 * @brief
 
1661
 * Update BFA configuration from firmware configuration.
 
1662
 */
 
1663
static void
 
1664
bfa_ioc_getattr_reply(struct bfa_ioc *ioc)
 
1665
{
 
1666
        struct bfi_ioc_attr *attr = ioc->attr;
 
1667
 
 
1668
        attr->adapter_prop  = ntohl(attr->adapter_prop);
 
1669
        attr->card_type     = ntohl(attr->card_type);
 
1670
        attr->maxfrsize     = ntohs(attr->maxfrsize);
 
1671
 
 
1672
        bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
 
1673
}
 
1674
 
 
1675
/**
 
1676
 * Attach time initialization of mbox logic.
 
1677
 */
 
1678
static void
 
1679
bfa_ioc_mbox_attach(struct bfa_ioc *ioc)
 
1680
{
 
1681
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
1682
        int     mc;
 
1683
 
 
1684
        INIT_LIST_HEAD(&mod->cmd_q);
 
1685
        for (mc = 0; mc < BFI_MC_MAX; mc++) {
 
1686
                mod->mbhdlr[mc].cbfn = NULL;
 
1687
                mod->mbhdlr[mc].cbarg = ioc->bfa;
 
1688
        }
 
1689
}
 
1690
 
 
1691
/**
 
1692
 * Mbox poll timer -- restarts any pending mailbox requests.
 
1693
 */
 
1694
static void
 
1695
bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
 
1696
{
 
1697
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
1698
        struct bfa_mbox_cmd *cmd;
 
1699
        bfa_mbox_cmd_cbfn_t cbfn;
 
1700
        void *cbarg;
 
1701
        u32 stat;
 
1702
 
 
1703
        /**
 
1704
         * If no command pending, do nothing
 
1705
         */
 
1706
        if (list_empty(&mod->cmd_q))
 
1707
                return;
 
1708
 
 
1709
        /**
 
1710
         * If previous command is not yet fetched by firmware, do nothing
 
1711
         */
 
1712
        stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
 
1713
        if (stat)
 
1714
                return;
 
1715
 
 
1716
        /**
 
1717
         * Enqueue command to firmware.
 
1718
         */
 
1719
        bfa_q_deq(&mod->cmd_q, &cmd);
 
1720
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
 
1721
 
 
1722
        /**
 
1723
         * Give a callback to the client, indicating that the command is sent
 
1724
         */
 
1725
        if (cmd->cbfn) {
 
1726
                cbfn = cmd->cbfn;
 
1727
                cbarg = cmd->cbarg;
 
1728
                cmd->cbfn = NULL;
 
1729
                cbfn(cbarg);
 
1730
        }
 
1731
}
 
1732
 
 
1733
/**
 
1734
 * Cleanup any pending requests.
 
1735
 */
 
1736
static void
 
1737
bfa_ioc_mbox_flush(struct bfa_ioc *ioc)
 
1738
{
 
1739
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
1740
        struct bfa_mbox_cmd *cmd;
 
1741
 
 
1742
        while (!list_empty(&mod->cmd_q))
 
1743
                bfa_q_deq(&mod->cmd_q, &cmd);
 
1744
}
 
1745
 
 
1746
static void
 
1747
bfa_ioc_fail_notify(struct bfa_ioc *ioc)
 
1748
{
 
1749
        /**
 
1750
         * Notify driver and common modules registered for notification.
 
1751
         */
 
1752
        ioc->cbfn->hbfail_cbfn(ioc->bfa);
 
1753
        bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
 
1754
}
 
1755
 
 
1756
/**
 
1757
 * IOCPF to IOC interface
 
1758
 */
 
1759
static void
 
1760
bfa_ioc_pf_enabled(struct bfa_ioc *ioc)
 
1761
{
 
1762
        bfa_fsm_send_event(ioc, IOC_E_ENABLED);
 
1763
}
 
1764
 
 
1765
static void
 
1766
bfa_ioc_pf_disabled(struct bfa_ioc *ioc)
 
1767
{
 
1768
        bfa_fsm_send_event(ioc, IOC_E_DISABLED);
 
1769
}
 
1770
 
 
1771
static void
 
1772
bfa_ioc_pf_failed(struct bfa_ioc *ioc)
 
1773
{
 
1774
        bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
 
1775
}
 
1776
 
 
1777
static void
 
1778
bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc)
 
1779
{
 
1780
        bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
 
1781
}
 
1782
 
 
1783
static void
 
1784
bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc)
 
1785
{
 
1786
        /**
 
1787
         * Provide enable completion callback and AEN notification.
 
1788
         */
 
1789
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 
1790
}
 
1791
 
 
1792
/**
 
1793
 * IOC public
 
1794
 */
 
1795
static enum bfa_status
 
1796
bfa_ioc_pll_init(struct bfa_ioc *ioc)
 
1797
{
 
1798
        /*
 
1799
         *  Hold semaphore so that nobody can access the chip during init.
 
1800
         */
 
1801
        bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
 
1802
 
 
1803
        bfa_ioc_pll_init_asic(ioc);
 
1804
 
 
1805
        ioc->pllinit = true;
 
1806
        /*
 
1807
         *  release semaphore.
 
1808
         */
 
1809
        bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
 
1810
 
 
1811
        return BFA_STATUS_OK;
 
1812
}
 
1813
 
 
1814
/**
 
1815
 * Interface used by diag module to do firmware boot with memory test
 
1816
 * as the entry vector.
 
1817
 */
 
1818
static void
 
1819
bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
 
1820
                u32 boot_env)
 
1821
{
 
1822
        bfa_ioc_stats(ioc, ioc_boots);
 
1823
 
 
1824
        if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
 
1825
                return;
 
1826
 
 
1827
        /**
 
1828
         * Initialize IOC state of all functions on a chip reset.
 
1829
         */
 
1830
        if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
 
1831
                writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate);
 
1832
                writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate);
 
1833
        } else {
 
1834
                writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate);
 
1835
                writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate);
 
1836
        }
 
1837
 
 
1838
        bfa_ioc_msgflush(ioc);
 
1839
        bfa_ioc_download_fw(ioc, boot_type, boot_env);
 
1840
        bfa_ioc_lpu_start(ioc);
 
1841
}
 
1842
 
 
1843
/**
 
1844
 * Enable/disable IOC failure auto recovery.
 
1845
 */
 
1846
void
 
1847
bfa_nw_ioc_auto_recover(bool auto_recover)
 
1848
{
 
1849
        bfa_nw_auto_recover = auto_recover;
 
1850
}
 
1851
 
 
1852
static bool
 
1853
bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg)
 
1854
{
 
1855
        u32     *msgp = mbmsg;
 
1856
        u32     r32;
 
1857
        int             i;
 
1858
 
 
1859
        r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
 
1860
        if ((r32 & 1) == 0)
 
1861
                return false;
 
1862
 
 
1863
        /**
 
1864
         * read the MBOX msg
 
1865
         */
 
1866
        for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
 
1867
             i++) {
 
1868
                r32 = readl(ioc->ioc_regs.lpu_mbox +
 
1869
                                   i * sizeof(u32));
 
1870
                msgp[i] = htonl(r32);
 
1871
        }
 
1872
 
 
1873
        /**
 
1874
         * turn off mailbox interrupt by clearing mailbox status
 
1875
         */
 
1876
        writel(1, ioc->ioc_regs.lpu_mbox_cmd);
 
1877
        readl(ioc->ioc_regs.lpu_mbox_cmd);
 
1878
 
 
1879
        return true;
 
1880
}
 
1881
 
 
1882
static void
 
1883
bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
 
1884
{
 
1885
        union bfi_ioc_i2h_msg_u *msg;
 
1886
        struct bfa_iocpf *iocpf = &ioc->iocpf;
 
1887
 
 
1888
        msg = (union bfi_ioc_i2h_msg_u *) m;
 
1889
 
 
1890
        bfa_ioc_stats(ioc, ioc_isrs);
 
1891
 
 
1892
        switch (msg->mh.msg_id) {
 
1893
        case BFI_IOC_I2H_HBEAT:
 
1894
                break;
 
1895
 
 
1896
        case BFI_IOC_I2H_ENABLE_REPLY:
 
1897
                bfa_ioc_enable_reply(ioc,
 
1898
                        (enum bfa_mode)msg->fw_event.port_mode,
 
1899
                        msg->fw_event.cap_bm);
 
1900
                break;
 
1901
 
 
1902
        case BFI_IOC_I2H_DISABLE_REPLY:
 
1903
                bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
 
1904
                break;
 
1905
 
 
1906
        case BFI_IOC_I2H_GETATTR_REPLY:
 
1907
                bfa_ioc_getattr_reply(ioc);
 
1908
                break;
 
1909
 
 
1910
        default:
 
1911
                BUG_ON(1);
 
1912
        }
 
1913
}
 
1914
 
 
1915
/**
 
1916
 * IOC attach time initialization and setup.
 
1917
 *
 
1918
 * @param[in]   ioc     memory for IOC
 
1919
 * @param[in]   bfa     driver instance structure
 
1920
 */
 
1921
void
 
1922
bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
 
1923
{
 
1924
        ioc->bfa        = bfa;
 
1925
        ioc->cbfn       = cbfn;
 
1926
        ioc->fcmode     = false;
 
1927
        ioc->pllinit    = false;
 
1928
        ioc->dbg_fwsave_once = true;
 
1929
        ioc->iocpf.ioc  = ioc;
 
1930
 
 
1931
        bfa_ioc_mbox_attach(ioc);
 
1932
        INIT_LIST_HEAD(&ioc->notify_q);
 
1933
 
 
1934
        bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
 
1935
        bfa_fsm_send_event(ioc, IOC_E_RESET);
 
1936
}
 
1937
 
 
1938
/**
 
1939
 * Driver detach time IOC cleanup.
 
1940
 */
 
1941
void
 
1942
bfa_nw_ioc_detach(struct bfa_ioc *ioc)
 
1943
{
 
1944
        bfa_fsm_send_event(ioc, IOC_E_DETACH);
 
1945
 
 
1946
        /* Done with detach, empty the notify_q. */
 
1947
        INIT_LIST_HEAD(&ioc->notify_q);
 
1948
}
 
1949
 
 
1950
/**
 
1951
 * Setup IOC PCI properties.
 
1952
 *
 
1953
 * @param[in]   pcidev  PCI device information for this IOC
 
1954
 */
 
1955
void
 
1956
bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
 
1957
                 enum bfi_pcifn_class clscode)
 
1958
{
 
1959
        ioc->clscode    = clscode;
 
1960
        ioc->pcidev     = *pcidev;
 
1961
 
 
1962
        /**
 
1963
         * Initialize IOC and device personality
 
1964
         */
 
1965
        ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC;
 
1966
        ioc->asic_mode  = BFI_ASIC_MODE_FC;
 
1967
 
 
1968
        switch (pcidev->device_id) {
 
1969
        case PCI_DEVICE_ID_BROCADE_CT:
 
1970
                ioc->asic_gen = BFI_ASIC_GEN_CT;
 
1971
                ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
 
1972
                ioc->asic_mode  = BFI_ASIC_MODE_ETH;
 
1973
                ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
 
1974
                ioc->ad_cap_bm = BFA_CM_CNA;
 
1975
                break;
 
1976
 
 
1977
        case BFA_PCI_DEVICE_ID_CT2:
 
1978
                ioc->asic_gen = BFI_ASIC_GEN_CT2;
 
1979
                if (clscode == BFI_PCIFN_CLASS_FC &&
 
1980
                        pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
 
1981
                        ioc->asic_mode  = BFI_ASIC_MODE_FC16;
 
1982
                        ioc->fcmode = true;
 
1983
                        ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
 
1984
                        ioc->ad_cap_bm = BFA_CM_HBA;
 
1985
                } else {
 
1986
                        ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
 
1987
                        ioc->asic_mode  = BFI_ASIC_MODE_ETH;
 
1988
                        if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
 
1989
                                ioc->port_mode =
 
1990
                                ioc->port_mode_cfg = BFA_MODE_CNA;
 
1991
                                ioc->ad_cap_bm = BFA_CM_CNA;
 
1992
                        } else {
 
1993
                                ioc->port_mode =
 
1994
                                ioc->port_mode_cfg = BFA_MODE_NIC;
 
1995
                                ioc->ad_cap_bm = BFA_CM_NIC;
 
1996
                        }
 
1997
                }
 
1998
                break;
 
1999
 
 
2000
        default:
 
2001
                BUG_ON(1);
 
2002
        }
 
2003
 
 
2004
        /**
 
2005
         * Set asic specific interfaces.
 
2006
         */
 
2007
        if (ioc->asic_gen == BFI_ASIC_GEN_CT)
 
2008
                bfa_nw_ioc_set_ct_hwif(ioc);
 
2009
        else {
 
2010
                WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2);
 
2011
                bfa_nw_ioc_set_ct2_hwif(ioc);
 
2012
                bfa_nw_ioc_ct2_poweron(ioc);
 
2013
        }
 
2014
 
 
2015
        bfa_ioc_map_port(ioc);
 
2016
        bfa_ioc_reg_init(ioc);
 
2017
}
 
2018
 
 
2019
/**
 
2020
 * Initialize IOC dma memory
 
2021
 *
 
2022
 * @param[in]   dm_kva  kernel virtual address of IOC dma memory
 
2023
 * @param[in]   dm_pa   physical address of IOC dma memory
 
2024
 */
 
2025
void
 
2026
bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc,  u8 *dm_kva, u64 dm_pa)
 
2027
{
 
2028
        /**
 
2029
         * dma memory for firmware attribute
 
2030
         */
 
2031
        ioc->attr_dma.kva = dm_kva;
 
2032
        ioc->attr_dma.pa = dm_pa;
 
2033
        ioc->attr = (struct bfi_ioc_attr *) dm_kva;
 
2034
}
 
2035
 
 
2036
/**
 
2037
 * Return size of dma memory required.
 
2038
 */
 
2039
u32
 
2040
bfa_nw_ioc_meminfo(void)
 
2041
{
 
2042
        return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ);
 
2043
}
 
2044
 
 
2045
void
 
2046
bfa_nw_ioc_enable(struct bfa_ioc *ioc)
 
2047
{
 
2048
        bfa_ioc_stats(ioc, ioc_enables);
 
2049
        ioc->dbg_fwsave_once = true;
 
2050
 
 
2051
        bfa_fsm_send_event(ioc, IOC_E_ENABLE);
 
2052
}
 
2053
 
 
2054
void
 
2055
bfa_nw_ioc_disable(struct bfa_ioc *ioc)
 
2056
{
 
2057
        bfa_ioc_stats(ioc, ioc_disables);
 
2058
        bfa_fsm_send_event(ioc, IOC_E_DISABLE);
 
2059
}
 
2060
 
 
2061
static u32
 
2062
bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr)
 
2063
{
 
2064
        return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
 
2065
}
 
2066
 
 
2067
/**
 
2068
 * Register mailbox message handler function, to be called by common modules
 
2069
 */
 
2070
void
 
2071
bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
 
2072
                    bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
 
2073
{
 
2074
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
2075
 
 
2076
        mod->mbhdlr[mc].cbfn    = cbfn;
 
2077
        mod->mbhdlr[mc].cbarg = cbarg;
 
2078
}
 
2079
 
 
2080
/**
 
2081
 * Queue a mailbox command request to firmware. Waits if mailbox is busy.
 
2082
 * Responsibility of caller to serialize
 
2083
 *
 
2084
 * @param[in]   ioc     IOC instance
 
2085
 * @param[i]    cmd     Mailbox command
 
2086
 */
 
2087
bool
 
2088
bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd,
 
2089
                        bfa_mbox_cmd_cbfn_t cbfn, void *cbarg)
 
2090
{
 
2091
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
2092
        u32                     stat;
 
2093
 
 
2094
        cmd->cbfn = cbfn;
 
2095
        cmd->cbarg = cbarg;
 
2096
 
 
2097
        /**
 
2098
         * If a previous command is pending, queue new command
 
2099
         */
 
2100
        if (!list_empty(&mod->cmd_q)) {
 
2101
                list_add_tail(&cmd->qe, &mod->cmd_q);
 
2102
                return true;
 
2103
        }
 
2104
 
 
2105
        /**
 
2106
         * If mailbox is busy, queue command for poll timer
 
2107
         */
 
2108
        stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
 
2109
        if (stat) {
 
2110
                list_add_tail(&cmd->qe, &mod->cmd_q);
 
2111
                return true;
 
2112
        }
 
2113
 
 
2114
        /**
 
2115
         * mailbox is free -- queue command to firmware
 
2116
         */
 
2117
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
 
2118
 
 
2119
        return false;
 
2120
}
 
2121
 
 
2122
/**
 
2123
 * Handle mailbox interrupts
 
2124
 */
 
2125
void
 
2126
bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
 
2127
{
 
2128
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
 
2129
        struct bfi_mbmsg m;
 
2130
        int                             mc;
 
2131
 
 
2132
        if (bfa_ioc_msgget(ioc, &m)) {
 
2133
                /**
 
2134
                 * Treat IOC message class as special.
 
2135
                 */
 
2136
                mc = m.mh.msg_class;
 
2137
                if (mc == BFI_MC_IOC) {
 
2138
                        bfa_ioc_isr(ioc, &m);
 
2139
                        return;
 
2140
                }
 
2141
 
 
2142
                if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
 
2143
                        return;
 
2144
 
 
2145
                mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
 
2146
        }
 
2147
 
 
2148
        bfa_ioc_lpu_read_stat(ioc);
 
2149
 
 
2150
        /**
 
2151
         * Try to send pending mailbox commands
 
2152
         */
 
2153
        bfa_ioc_mbox_poll(ioc);
 
2154
}
 
2155
 
 
2156
void
 
2157
bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
 
2158
{
 
2159
        bfa_ioc_stats(ioc, ioc_hbfails);
 
2160
        bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
 
2161
        bfa_fsm_send_event(ioc, IOC_E_HWERROR);
 
2162
}
 
2163
 
 
2164
/**
 
2165
 * return true if IOC is disabled
 
2166
 */
 
2167
bool
 
2168
bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc)
 
2169
{
 
2170
        return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
 
2171
                bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
 
2172
}
 
2173
 
 
2174
/**
 
2175
 * Add to IOC heartbeat failure notification queue. To be used by common
 
2176
 * modules such as cee, port, diag.
 
2177
 */
 
2178
void
 
2179
bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
 
2180
                        struct bfa_ioc_notify *notify)
 
2181
{
 
2182
        list_add_tail(&notify->qe, &ioc->notify_q);
 
2183
}
 
2184
 
 
2185
#define BFA_MFG_NAME "Brocade"
 
2186
static void
 
2187
bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc,
 
2188
                         struct bfa_adapter_attr *ad_attr)
 
2189
{
 
2190
        struct bfi_ioc_attr *ioc_attr;
 
2191
 
 
2192
        ioc_attr = ioc->attr;
 
2193
 
 
2194
        bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
 
2195
        bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
 
2196
        bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
 
2197
        bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
 
2198
        memcpy(&ad_attr->vpd, &ioc_attr->vpd,
 
2199
                      sizeof(struct bfa_mfg_vpd));
 
2200
 
 
2201
        ad_attr->nports = bfa_ioc_get_nports(ioc);
 
2202
        ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
 
2203
 
 
2204
        bfa_ioc_get_adapter_model(ioc, ad_attr->model);
 
2205
        /* For now, model descr uses same model string */
 
2206
        bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
 
2207
 
 
2208
        ad_attr->card_type = ioc_attr->card_type;
 
2209
        ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
 
2210
 
 
2211
        if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
 
2212
                ad_attr->prototype = 1;
 
2213
        else
 
2214
                ad_attr->prototype = 0;
 
2215
 
 
2216
        ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
 
2217
        ad_attr->mac  = bfa_nw_ioc_get_mac(ioc);
 
2218
 
 
2219
        ad_attr->pcie_gen = ioc_attr->pcie_gen;
 
2220
        ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
 
2221
        ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
 
2222
        ad_attr->asic_rev = ioc_attr->asic_rev;
 
2223
 
 
2224
        bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
 
2225
}
 
2226
 
 
2227
static enum bfa_ioc_type
 
2228
bfa_ioc_get_type(struct bfa_ioc *ioc)
 
2229
{
 
2230
        if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
 
2231
                return BFA_IOC_TYPE_LL;
 
2232
 
 
2233
        BUG_ON(!(ioc->clscode == BFI_PCIFN_CLASS_FC));
 
2234
 
 
2235
        return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
 
2236
                ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
 
2237
}
 
2238
 
 
2239
static void
 
2240
bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num)
 
2241
{
 
2242
        memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
 
2243
        memcpy(serial_num,
 
2244
                        (void *)ioc->attr->brcd_serialnum,
 
2245
                        BFA_ADAPTER_SERIAL_NUM_LEN);
 
2246
}
 
2247
 
 
2248
static void
 
2249
bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver)
 
2250
{
 
2251
        memset(fw_ver, 0, BFA_VERSION_LEN);
 
2252
        memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
 
2253
}
 
2254
 
 
2255
static void
 
2256
bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev)
 
2257
{
 
2258
        BUG_ON(!(chip_rev));
 
2259
 
 
2260
        memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
 
2261
 
 
2262
        chip_rev[0] = 'R';
 
2263
        chip_rev[1] = 'e';
 
2264
        chip_rev[2] = 'v';
 
2265
        chip_rev[3] = '-';
 
2266
        chip_rev[4] = ioc->attr->asic_rev;
 
2267
        chip_rev[5] = '\0';
 
2268
}
 
2269
 
 
2270
static void
 
2271
bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver)
 
2272
{
 
2273
        memset(optrom_ver, 0, BFA_VERSION_LEN);
 
2274
        memcpy(optrom_ver, ioc->attr->optrom_version,
 
2275
                      BFA_VERSION_LEN);
 
2276
}
 
2277
 
 
2278
static void
 
2279
bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer)
 
2280
{
 
2281
        memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
 
2282
        memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
 
2283
}
 
2284
 
 
2285
static void
 
2286
bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model)
 
2287
{
 
2288
        struct bfi_ioc_attr *ioc_attr;
 
2289
 
 
2290
        BUG_ON(!(model));
 
2291
        memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
 
2292
 
 
2293
        ioc_attr = ioc->attr;
 
2294
 
 
2295
        snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
 
2296
                BFA_MFG_NAME, ioc_attr->card_type);
 
2297
}
 
2298
 
 
2299
static enum bfa_ioc_state
 
2300
bfa_ioc_get_state(struct bfa_ioc *ioc)
 
2301
{
 
2302
        enum bfa_iocpf_state iocpf_st;
 
2303
        enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
 
2304
 
 
2305
        if (ioc_st == BFA_IOC_ENABLING ||
 
2306
                ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
 
2307
 
 
2308
                iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
 
2309
 
 
2310
                switch (iocpf_st) {
 
2311
                case BFA_IOCPF_SEMWAIT:
 
2312
                        ioc_st = BFA_IOC_SEMWAIT;
 
2313
                        break;
 
2314
 
 
2315
                case BFA_IOCPF_HWINIT:
 
2316
                        ioc_st = BFA_IOC_HWINIT;
 
2317
                        break;
 
2318
 
 
2319
                case BFA_IOCPF_FWMISMATCH:
 
2320
                        ioc_st = BFA_IOC_FWMISMATCH;
 
2321
                        break;
 
2322
 
 
2323
                case BFA_IOCPF_FAIL:
 
2324
                        ioc_st = BFA_IOC_FAIL;
 
2325
                        break;
 
2326
 
 
2327
                case BFA_IOCPF_INITFAIL:
 
2328
                        ioc_st = BFA_IOC_INITFAIL;
 
2329
                        break;
 
2330
 
 
2331
                default:
 
2332
                        break;
 
2333
                }
 
2334
        }
 
2335
        return ioc_st;
 
2336
}
 
2337
 
 
2338
void
 
2339
bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr)
 
2340
{
 
2341
        memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr));
 
2342
 
 
2343
        ioc_attr->state = bfa_ioc_get_state(ioc);
 
2344
        ioc_attr->port_id = ioc->port_id;
 
2345
        ioc_attr->port_mode = ioc->port_mode;
 
2346
 
 
2347
        ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
 
2348
        ioc_attr->cap_bm = ioc->ad_cap_bm;
 
2349
 
 
2350
        ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
 
2351
 
 
2352
        bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
2353
 
 
2354
        ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
 
2355
        ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
 
2356
        bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 
2357
}
 
2358
 
 
2359
/**
 
2360
 * WWN public
 
2361
 */
 
2362
static u64
 
2363
bfa_ioc_get_pwwn(struct bfa_ioc *ioc)
 
2364
{
 
2365
        return ioc->attr->pwwn;
 
2366
}
 
2367
 
 
2368
mac_t
 
2369
bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
 
2370
{
 
2371
        return ioc->attr->mac;
 
2372
}
 
2373
 
 
2374
/**
 
2375
 * Firmware failure detected. Start recovery actions.
 
2376
 */
 
2377
static void
 
2378
bfa_ioc_recover(struct bfa_ioc *ioc)
 
2379
{
 
2380
        pr_crit("Heart Beat of IOC has failed\n");
 
2381
        bfa_ioc_stats(ioc, ioc_hbfails);
 
2382
        bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
 
2383
        bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
 
2384
}
 
2385
 
 
2386
static void
 
2387
bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
 
2388
{
 
2389
        if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
 
2390
                return;
 
2391
}
 
2392
 
 
2393
/**
 
2394
 * @dg hal_iocpf_pvt BFA IOC PF private functions
 
2395
 * @{
 
2396
 */
 
2397
 
 
2398
static void
 
2399
bfa_iocpf_enable(struct bfa_ioc *ioc)
 
2400
{
 
2401
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
 
2402
}
 
2403
 
 
2404
static void
 
2405
bfa_iocpf_disable(struct bfa_ioc *ioc)
 
2406
{
 
2407
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
 
2408
}
 
2409
 
 
2410
static void
 
2411
bfa_iocpf_fail(struct bfa_ioc *ioc)
 
2412
{
 
2413
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
 
2414
}
 
2415
 
 
2416
static void
 
2417
bfa_iocpf_initfail(struct bfa_ioc *ioc)
 
2418
{
 
2419
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
 
2420
}
 
2421
 
 
2422
static void
 
2423
bfa_iocpf_getattrfail(struct bfa_ioc *ioc)
 
2424
{
 
2425
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
 
2426
}
 
2427
 
 
2428
static void
 
2429
bfa_iocpf_stop(struct bfa_ioc *ioc)
 
2430
{
 
2431
        bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
 
2432
}
 
2433
 
 
2434
void
 
2435
bfa_nw_iocpf_timeout(void *ioc_arg)
 
2436
{
 
2437
        struct bfa_ioc  *ioc = (struct bfa_ioc *) ioc_arg;
 
2438
        enum bfa_iocpf_state iocpf_st;
 
2439
 
 
2440
        iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
 
2441
 
 
2442
        if (iocpf_st == BFA_IOCPF_HWINIT)
 
2443
                bfa_ioc_poll_fwinit(ioc);
 
2444
        else
 
2445
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
 
2446
}
 
2447
 
 
2448
void
 
2449
bfa_nw_iocpf_sem_timeout(void *ioc_arg)
 
2450
{
 
2451
        struct bfa_ioc  *ioc = (struct bfa_ioc *) ioc_arg;
 
2452
 
 
2453
        bfa_ioc_hw_sem_get(ioc);
 
2454
}
 
2455
 
 
2456
static void
 
2457
bfa_ioc_poll_fwinit(struct bfa_ioc *ioc)
 
2458
{
 
2459
        u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
 
2460
 
 
2461
        if (fwstate == BFI_IOC_DISABLED) {
 
2462
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
 
2463
                return;
 
2464
        }
 
2465
 
 
2466
        if (ioc->iocpf.poll_time >= BFA_IOC_TOV) {
 
2467
                bfa_nw_iocpf_timeout(ioc);
 
2468
        } else {
 
2469
                ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
 
2470
                mod_timer(&ioc->iocpf_timer, jiffies +
 
2471
                        msecs_to_jiffies(BFA_IOC_POLL_TOV));
 
2472
        }
 
2473
}