- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / scsi / bfa / bfa_ioc.c
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License (GPL) Version 2 as
10  * published by the Free Software Foundation
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  */
17
18 #include <bfa.h>
19 #include <bfa_ioc.h>
20 #include <bfa_fwimg_priv.h>
21 #include <bfa_trcmod_priv.h>
22 #include <cs/bfa_debug.h>
23 #include <bfi/bfi_ioc.h>
24 #include <bfi/bfi_ctreg.h>
25 #include <aen/bfa_aen_ioc.h>
26 #include <aen/bfa_aen.h>
27 #include <log/bfa_log_hal.h>
28 #include <defs/bfa_defs_pci.h>
29
30 BFA_TRC_FILE(HAL, IOC);
31
32 /**
33  * IOC local definitions
34  */
35 #define BFA_IOC_TOV             2000    /* msecs */
36 #define BFA_IOC_HB_TOV          1000    /* msecs */
37 #define BFA_IOC_HB_FAIL_MAX     4
38 #define BFA_IOC_HWINIT_MAX      2
39 #define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
40 #define BFA_IOC_TOV_RECOVER     (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
41                                 + BFA_IOC_TOV)
42
43 #define bfa_ioc_timer_start(__ioc)                                      \
44         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
45                         bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
46 #define bfa_ioc_timer_stop(__ioc)   bfa_timer_stop(&(__ioc)->ioc_timer)
47
48 #define BFA_DBG_FWTRC_ENTS      (BFI_IOC_TRC_ENTS)
49 #define BFA_DBG_FWTRC_LEN                                       \
50         (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) +        \
51          (sizeof(struct bfa_trc_mod_s) -                        \
52           BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
53 #define BFA_DBG_FWTRC_OFF(_fn)  (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
54 #define bfa_ioc_stats(_ioc, _stats)     ((_ioc)->stats._stats++)
55
56 #define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
57 #define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
58 #define BFA_FLASH_CHUNK_ADDR(chunkno)   (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
59 bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
60
61 /*
62  * forward declarations
63  */
64 static void     bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
65                                  enum bfa_ioc_aen_event event);
66 static void     bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
67 static void     bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
68 static void     bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
69 static void     bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
70 static void     bfa_ioc_timeout(void *ioc);
71 static void     bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
72 static void     bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
73 static void     bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
74 static void     bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
75 static void     bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
76 static void     bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
77 static void     bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
78 static void     bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
79 static void     bfa_ioc_recover(struct bfa_ioc_s *ioc);
80 static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
81 static void     bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
82 static void     bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
83 static void     bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
84
85 /**
86  *  bfa_ioc_sm
87  */
88
89 /**
90  * IOC state machine events
91  */
92 enum ioc_event {
93         IOC_E_ENABLE = 1,       /*  IOC enable request */
94         IOC_E_DISABLE = 2,      /*  IOC disable request */
95         IOC_E_TIMEOUT = 3,      /*  f/w response timeout */
96         IOC_E_FWREADY = 4,      /*  f/w initialization done */
97         IOC_E_FWRSP_GETATTR = 5,        /*  IOC get attribute response */
98         IOC_E_FWRSP_ENABLE = 6, /*  enable f/w response */
99         IOC_E_FWRSP_DISABLE = 7,        /*  disable f/w response */
100         IOC_E_HBFAIL = 8,       /*  heartbeat failure */
101         IOC_E_HWERROR = 9,      /*  hardware error interrupt */
102         IOC_E_SEMLOCKED = 10,   /*  h/w semaphore is locked */
103         IOC_E_DETACH = 11,      /*  driver detach cleanup */
104 };
105
106 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
107 bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc_s, enum ioc_event);
108 bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc_s, enum ioc_event);
109 bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc_s, enum ioc_event);
110 bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc_s, enum ioc_event);
111 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
112 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
113 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
114 bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
115 bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc_s, enum ioc_event);
116 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
117 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
118
119 static struct bfa_sm_table_s ioc_sm_table[] = {
120         {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
121         {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
122         {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
123         {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
124         {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
125         {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
126         {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
127         {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
128         {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
129         {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
130         {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
131         {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
132 };
133
134 /**
135  * Reset entry actions -- initialize state machine
136  */
137 static void
138 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
139 {
140         ioc->retry_count = 0;
141         ioc->auto_recover = bfa_auto_recover;
142 }
143
144 /**
145  * Beginning state. IOC is in reset state.
146  */
147 static void
148 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
149 {
150         bfa_trc(ioc, event);
151
152         switch (event) {
153         case IOC_E_ENABLE:
154                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
155                 break;
156
157         case IOC_E_DISABLE:
158                 bfa_ioc_disable_comp(ioc);
159                 break;
160
161         case IOC_E_DETACH:
162                 break;
163
164         default:
165                 bfa_sm_fault(ioc, event);
166         }
167 }
168
169 /**
170  * Semaphore should be acquired for version check.
171  */
172 static void
173 bfa_ioc_sm_fwcheck_entry(struct bfa_ioc_s *ioc)
174 {
175         bfa_ioc_hw_sem_get(ioc);
176 }
177
178 /**
179  * Awaiting h/w semaphore to continue with version check.
180  */
181 static void
182 bfa_ioc_sm_fwcheck(struct bfa_ioc_s *ioc, enum ioc_event event)
183 {
184         bfa_trc(ioc, event);
185
186         switch (event) {
187         case IOC_E_SEMLOCKED:
188                 if (bfa_ioc_firmware_lock(ioc)) {
189                         ioc->retry_count = 0;
190                         bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
191                 } else {
192                         bfa_ioc_hw_sem_release(ioc);
193                         bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
194                 }
195                 break;
196
197         case IOC_E_DISABLE:
198                 bfa_ioc_disable_comp(ioc);
199                 /*
200                  * fall through
201                  */
202
203         case IOC_E_DETACH:
204                 bfa_ioc_hw_sem_get_cancel(ioc);
205                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
206                 break;
207
208         case IOC_E_FWREADY:
209                 break;
210
211         default:
212                 bfa_sm_fault(ioc, event);
213         }
214 }
215
216 /**
217  * Notify enable completion callback and generate mismatch AEN.
218  */
219 static void
220 bfa_ioc_sm_mismatch_entry(struct bfa_ioc_s *ioc)
221 {
222         /**
223          * Provide enable completion callback and AEN notification only once.
224          */
225         if (ioc->retry_count == 0) {
226                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
227                 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
228         }
229         ioc->retry_count++;
230         bfa_ioc_timer_start(ioc);
231 }
232
233 /**
234  * Awaiting firmware version match.
235  */
236 static void
237 bfa_ioc_sm_mismatch(struct bfa_ioc_s *ioc, enum ioc_event event)
238 {
239         bfa_trc(ioc, event);
240
241         switch (event) {
242         case IOC_E_TIMEOUT:
243                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
244                 break;
245
246         case IOC_E_DISABLE:
247                 bfa_ioc_disable_comp(ioc);
248                 /*
249                  * fall through
250                  */
251
252         case IOC_E_DETACH:
253                 bfa_ioc_timer_stop(ioc);
254                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
255                 break;
256
257         case IOC_E_FWREADY:
258                 break;
259
260         default:
261                 bfa_sm_fault(ioc, event);
262         }
263 }
264
265 /**
266  * Request for semaphore.
267  */
268 static void
269 bfa_ioc_sm_semwait_entry(struct bfa_ioc_s *ioc)
270 {
271         bfa_ioc_hw_sem_get(ioc);
272 }
273
274 /**
275  * Awaiting semaphore for h/w initialzation.
276  */
277 static void
278 bfa_ioc_sm_semwait(struct bfa_ioc_s *ioc, enum ioc_event event)
279 {
280         bfa_trc(ioc, event);
281
282         switch (event) {
283         case IOC_E_SEMLOCKED:
284                 ioc->retry_count = 0;
285                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
286                 break;
287
288         case IOC_E_DISABLE:
289                 bfa_ioc_hw_sem_get_cancel(ioc);
290                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
291                 break;
292
293         default:
294                 bfa_sm_fault(ioc, event);
295         }
296 }
297
298
299 static void
300 bfa_ioc_sm_hwinit_entry(struct bfa_ioc_s *ioc)
301 {
302         bfa_ioc_timer_start(ioc);
303         bfa_ioc_reset(ioc, BFA_FALSE);
304 }
305
306 /**
307  * Hardware is being initialized. Interrupts are enabled.
308  * Holding hardware semaphore lock.
309  */
310 static void
311 bfa_ioc_sm_hwinit(struct bfa_ioc_s *ioc, enum ioc_event event)
312 {
313         bfa_trc(ioc, event);
314
315         switch (event) {
316         case IOC_E_FWREADY:
317                 bfa_ioc_timer_stop(ioc);
318                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
319                 break;
320
321         case IOC_E_HWERROR:
322                 bfa_ioc_timer_stop(ioc);
323                 /*
324                  * fall through
325                  */
326
327         case IOC_E_TIMEOUT:
328                 ioc->retry_count++;
329                 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
330                         bfa_ioc_timer_start(ioc);
331                         bfa_ioc_reset(ioc, BFA_TRUE);
332                         break;
333                 }
334
335                 bfa_ioc_hw_sem_release(ioc);
336                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
337                 break;
338
339         case IOC_E_DISABLE:
340                 bfa_ioc_hw_sem_release(ioc);
341                 bfa_ioc_timer_stop(ioc);
342                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
343                 break;
344
345         default:
346                 bfa_sm_fault(ioc, event);
347         }
348 }
349
350
351 static void
352 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
353 {
354         bfa_ioc_timer_start(ioc);
355         bfa_ioc_send_enable(ioc);
356 }
357
358 /**
359  * Host IOC function is being enabled, awaiting response from firmware.
360  * Semaphore is acquired.
361  */
362 static void
363 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
364 {
365         bfa_trc(ioc, event);
366
367         switch (event) {
368         case IOC_E_FWRSP_ENABLE:
369                 bfa_ioc_timer_stop(ioc);
370                 bfa_ioc_hw_sem_release(ioc);
371                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
372                 break;
373
374         case IOC_E_HWERROR:
375                 bfa_ioc_timer_stop(ioc);
376                 /*
377                  * fall through
378                  */
379
380         case IOC_E_TIMEOUT:
381                 ioc->retry_count++;
382                 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
383                         bfa_reg_write(ioc->ioc_regs.ioc_fwstate,
384                                       BFI_IOC_UNINIT);
385                         bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
386                         break;
387                 }
388
389                 bfa_ioc_hw_sem_release(ioc);
390                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
391                 break;
392
393         case IOC_E_DISABLE:
394                 bfa_ioc_timer_stop(ioc);
395                 bfa_ioc_hw_sem_release(ioc);
396                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
397                 break;
398
399         case IOC_E_FWREADY:
400                 bfa_ioc_send_enable(ioc);
401                 break;
402
403         default:
404                 bfa_sm_fault(ioc, event);
405         }
406 }
407
408
409 static void
410 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
411 {
412         bfa_ioc_timer_start(ioc);
413         bfa_ioc_send_getattr(ioc);
414 }
415
416 /**
417  * IOC configuration in progress. Timer is active.
418  */
419 static void
420 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
421 {
422         bfa_trc(ioc, event);
423
424         switch (event) {
425         case IOC_E_FWRSP_GETATTR:
426                 bfa_ioc_timer_stop(ioc);
427                 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
428                 break;
429
430         case IOC_E_HWERROR:
431                 bfa_ioc_timer_stop(ioc);
432                 /*
433                  * fall through
434                  */
435
436         case IOC_E_TIMEOUT:
437                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
438                 break;
439
440         case IOC_E_DISABLE:
441                 bfa_ioc_timer_stop(ioc);
442                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
443                 break;
444
445         default:
446                 bfa_sm_fault(ioc, event);
447         }
448 }
449
450
451 static void
452 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
453 {
454         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
455         bfa_ioc_hb_monitor(ioc);
456         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
457 }
458
459 static void
460 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
461 {
462         bfa_trc(ioc, event);
463
464         switch (event) {
465         case IOC_E_ENABLE:
466                 break;
467
468         case IOC_E_DISABLE:
469                 bfa_ioc_hb_stop(ioc);
470                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
471                 break;
472
473         case IOC_E_HWERROR:
474         case IOC_E_FWREADY:
475                 /**
476                  * Hard error or IOC recovery by other function.
477                  * Treat it same as heartbeat failure.
478                  */
479                 bfa_ioc_hb_stop(ioc);
480                 /*
481                  * !!! fall through !!!
482                  */
483
484         case IOC_E_HBFAIL:
485                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
486                 break;
487
488         default:
489                 bfa_sm_fault(ioc, event);
490         }
491 }
492
493
494 static void
495 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
496 {
497         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
498         bfa_ioc_timer_start(ioc);
499         bfa_ioc_send_disable(ioc);
500 }
501
502 /**
503  * IOC is being disabled
504  */
505 static void
506 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
507 {
508         bfa_trc(ioc, event);
509
510         switch (event) {
511         case IOC_E_HWERROR:
512         case IOC_E_FWRSP_DISABLE:
513                 bfa_ioc_timer_stop(ioc);
514                 /*
515                  * !!! fall through !!!
516                  */
517
518         case IOC_E_TIMEOUT:
519                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
520                 break;
521
522         default:
523                 bfa_sm_fault(ioc, event);
524         }
525 }
526
527 /**
528  * IOC disable completion entry.
529  */
530 static void
531 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
532 {
533         bfa_ioc_disable_comp(ioc);
534 }
535
536 static void
537 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
538 {
539         bfa_trc(ioc, event);
540
541         switch (event) {
542         case IOC_E_ENABLE:
543                 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
544                 break;
545
546         case IOC_E_DISABLE:
547                 ioc->cbfn->disable_cbfn(ioc->bfa);
548                 break;
549
550         case IOC_E_FWREADY:
551                 break;
552
553         case IOC_E_DETACH:
554                 bfa_ioc_firmware_unlock(ioc);
555                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
556                 break;
557
558         default:
559                 bfa_sm_fault(ioc, event);
560         }
561 }
562
563
564 static void
565 bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
566 {
567         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
568         bfa_ioc_timer_start(ioc);
569 }
570
571 /**
572  * Hardware initialization failed.
573  */
574 static void
575 bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
576 {
577         bfa_trc(ioc, event);
578
579         switch (event) {
580         case IOC_E_DISABLE:
581                 bfa_ioc_timer_stop(ioc);
582                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
583                 break;
584
585         case IOC_E_DETACH:
586                 bfa_ioc_timer_stop(ioc);
587                 bfa_ioc_firmware_unlock(ioc);
588                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
589                 break;
590
591         case IOC_E_TIMEOUT:
592                 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
593                 break;
594
595         default:
596                 bfa_sm_fault(ioc, event);
597         }
598 }
599
600
601 static void
602 bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
603 {
604         struct list_head *qe;
605         struct bfa_ioc_hbfail_notify_s *notify;
606
607         /**
608          * Mark IOC as failed in hardware and stop firmware.
609          */
610         bfa_ioc_lpu_stop(ioc);
611         bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
612
613         if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
614                 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
615                 /*
616                  * Wait for halt to take effect
617                  */
618                 bfa_reg_read(ioc->ioc_regs.ll_halt);
619         }
620
621         /**
622          * Notify driver and common modules registered for notification.
623          */
624         ioc->cbfn->hbfail_cbfn(ioc->bfa);
625         list_for_each(qe, &ioc->hb_notify_q) {
626                 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
627                 notify->cbfn(notify->cbarg);
628         }
629
630         /**
631          * Flush any queued up mailbox requests.
632          */
633         bfa_ioc_mbox_hbfail(ioc);
634         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
635
636         /**
637          * Trigger auto-recovery after a delay.
638          */
639         if (ioc->auto_recover) {
640                 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer,
641                                 bfa_ioc_timeout, ioc, BFA_IOC_TOV_RECOVER);
642         }
643 }
644
645 /**
646  * IOC heartbeat failure.
647  */
648 static void
649 bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
650 {
651         bfa_trc(ioc, event);
652
653         switch (event) {
654
655         case IOC_E_ENABLE:
656                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
657                 break;
658
659         case IOC_E_DISABLE:
660                 if (ioc->auto_recover)
661                         bfa_ioc_timer_stop(ioc);
662                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
663                 break;
664
665         case IOC_E_TIMEOUT:
666                 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
667                 break;
668
669         case IOC_E_FWREADY:
670                 /**
671                  * Recovery is already initiated by other function.
672                  */
673                 break;
674
675         default:
676                 bfa_sm_fault(ioc, event);
677         }
678 }
679
680
681
682 /**
683  *  bfa_ioc_pvt BFA IOC private functions
684  */
685
686 static void
687 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
688 {
689         struct list_head *qe;
690         struct bfa_ioc_hbfail_notify_s *notify;
691
692         ioc->cbfn->disable_cbfn(ioc->bfa);
693
694         /**
695          * Notify common modules registered for notification.
696          */
697         list_for_each(qe, &ioc->hb_notify_q) {
698                 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
699                 notify->cbfn(notify->cbarg);
700         }
701 }
702
703 static void
704 bfa_ioc_sem_timeout(void *ioc_arg)
705 {
706         struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
707
708         bfa_ioc_hw_sem_get(ioc);
709 }
710
711 static void
712 bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
713 {
714         u32        r32;
715         int             cnt = 0;
716 #define BFA_SEM_SPINCNT 1000
717
718         do {
719                 r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
720                 cnt++;
721                 if (cnt > BFA_SEM_SPINCNT)
722                         break;
723         } while (r32 != 0);
724         bfa_assert(cnt < BFA_SEM_SPINCNT);
725 }
726
727 static void
728 bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
729 {
730         bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
731 }
732
733 static void
734 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
735 {
736         u32        r32;
737
738         /**
739          * First read to the semaphore register will return 0, subsequent reads
740          * will return 1. Semaphore is released by writing 0 to the register
741          */
742         r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
743         if (r32 == 0) {
744                 bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
745                 return;
746         }
747
748         bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
749                         ioc, BFA_IOC_TOV);
750 }
751
752 static void
753 bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
754 {
755         bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
756 }
757
758 static void
759 bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
760 {
761         bfa_timer_stop(&ioc->sem_timer);
762 }
763
764 /**
765  * Initialize LPU local memory (aka secondary memory / SRAM)
766  */
767 static void
768 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
769 {
770         u32        pss_ctl;
771         int             i;
772 #define PSS_LMEM_INIT_TIME  10000
773
774         pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
775         pss_ctl &= ~__PSS_LMEM_RESET;
776         pss_ctl |= __PSS_LMEM_INIT_EN;
777         pss_ctl |= __PSS_I2C_CLK_DIV(3UL); /* i2c workaround 12.5khz clock */
778         bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
779
780         /**
781          * wait for memory initialization to be complete
782          */
783         i = 0;
784         do {
785                 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
786                 i++;
787         } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
788
789         /**
790          * If memory initialization is not successful, IOC timeout will catch
791          * such failures.
792          */
793         bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
794         bfa_trc(ioc, pss_ctl);
795
796         pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
797         bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
798 }
799
800 static void
801 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
802 {
803         u32        pss_ctl;
804
805         /**
806          * Take processor out of reset.
807          */
808         pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
809         pss_ctl &= ~__PSS_LPU0_RESET;
810
811         bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
812 }
813
814 static void
815 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
816 {
817         u32        pss_ctl;
818
819         /**
820          * Put processors in reset.
821          */
822         pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
823         pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
824
825         bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
826 }
827
828 /**
829  * Get driver and firmware versions.
830  */
831 static void
832 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
833 {
834         u32        pgnum, pgoff;
835         u32        loff = 0;
836         int             i;
837         u32       *fwsig = (u32 *) fwhdr;
838
839         pgnum = bfa_ioc_smem_pgnum(ioc, loff);
840         pgoff = bfa_ioc_smem_pgoff(ioc, loff);
841         bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
842
843         for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
844              i++) {
845                 fwsig[i] = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
846                 loff += sizeof(u32);
847         }
848 }
849
850 static u32 *
851 bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
852 {
853         if (ioc->ctdev)
854                 return bfi_image_ct_get_chunk(off);
855         return bfi_image_cb_get_chunk(off);
856 }
857
858 static          u32
859 bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
860 {
861 return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
862 }
863
864 /**
865  * Returns TRUE if same.
866  */
867 static          bfa_boolean_t
868 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
869 {
870         struct bfi_ioc_image_hdr_s *drv_fwhdr;
871         int             i;
872
873         drv_fwhdr =
874                 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
875
876         for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
877                 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
878                         bfa_trc(ioc, i);
879                         bfa_trc(ioc, fwhdr->md5sum[i]);
880                         bfa_trc(ioc, drv_fwhdr->md5sum[i]);
881                         return BFA_FALSE;
882                 }
883         }
884
885         bfa_trc(ioc, fwhdr->md5sum[0]);
886         return BFA_TRUE;
887 }
888
889 /**
890  * Return true if current running version is valid. Firmware signature and
891  * execution context (driver/bios) must match.
892  */
893 static          bfa_boolean_t
894 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
895 {
896         struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
897
898         /**
899          * If bios/efi boot (flash based) -- return true
900          */
901         if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
902                 return BFA_TRUE;
903
904         bfa_ioc_fwver_get(ioc, &fwhdr);
905         drv_fwhdr =
906                 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
907
908         if (fwhdr.signature != drv_fwhdr->signature) {
909                 bfa_trc(ioc, fwhdr.signature);
910                 bfa_trc(ioc, drv_fwhdr->signature);
911                 return BFA_FALSE;
912         }
913
914         if (fwhdr.exec != drv_fwhdr->exec) {
915                 bfa_trc(ioc, fwhdr.exec);
916                 bfa_trc(ioc, drv_fwhdr->exec);
917                 return BFA_FALSE;
918         }
919
920         return bfa_ioc_fwver_cmp(ioc, &fwhdr);
921 }
922
923 /**
924  * Return true if firmware of current driver matches the running firmware.
925  */
926 static          bfa_boolean_t
927 bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
928 {
929         enum bfi_ioc_state ioc_fwstate;
930         u32        usecnt;
931         struct bfi_ioc_image_hdr_s fwhdr;
932
933         /**
934          * Firmware match check is relevant only for CNA.
935          */
936         if (!ioc->cna)
937                 return BFA_TRUE;
938
939         /**
940          * If bios boot (flash based) -- do not increment usage count
941          */
942         if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
943                 return BFA_TRUE;
944
945         bfa_ioc_usage_sem_get(ioc);
946         usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
947
948         /**
949          * If usage count is 0, always return TRUE.
950          */
951         if (usecnt == 0) {
952                 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
953                 bfa_ioc_usage_sem_release(ioc);
954                 bfa_trc(ioc, usecnt);
955                 return BFA_TRUE;
956         }
957
958         ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
959         bfa_trc(ioc, ioc_fwstate);
960
961         /**
962          * Use count cannot be non-zero and chip in uninitialized state.
963          */
964         bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
965
966         /**
967          * Check if another driver with a different firmware is active
968          */
969         bfa_ioc_fwver_get(ioc, &fwhdr);
970         if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
971                 bfa_ioc_usage_sem_release(ioc);
972                 bfa_trc(ioc, usecnt);
973                 return BFA_FALSE;
974         }
975
976         /**
977          * Same firmware version. Increment the reference count.
978          */
979         usecnt++;
980         bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
981         bfa_ioc_usage_sem_release(ioc);
982         bfa_trc(ioc, usecnt);
983         return BFA_TRUE;
984 }
985
986 static void
987 bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
988 {
989         u32        usecnt;
990
991         /**
992          * Firmware lock is relevant only for CNA.
993          * If bios boot (flash based) -- do not decrement usage count
994          */
995         if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
996                 return;
997
998         /**
999          * decrement usage count
1000          */
1001         bfa_ioc_usage_sem_get(ioc);
1002         usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
1003         bfa_assert(usecnt > 0);
1004
1005         usecnt--;
1006         bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
1007         bfa_trc(ioc, usecnt);
1008
1009         bfa_ioc_usage_sem_release(ioc);
1010 }
1011
1012 /**
1013  * Conditionally flush any pending message from firmware at start.
1014  */
1015 static void
1016 bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1017 {
1018         u32        r32;
1019
1020         r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1021         if (r32)
1022                 bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1023 }
1024
1025
1026 static void
1027 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1028 {
1029         enum bfi_ioc_state ioc_fwstate;
1030         bfa_boolean_t   fwvalid;
1031
1032         ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
1033
1034         if (force)
1035                 ioc_fwstate = BFI_IOC_UNINIT;
1036
1037         bfa_trc(ioc, ioc_fwstate);
1038
1039         /**
1040          * check if firmware is valid
1041          */
1042         fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1043                         BFA_FALSE : bfa_ioc_fwver_valid(ioc);
1044
1045         if (!fwvalid) {
1046                 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1047                 return;
1048         }
1049
1050         /**
1051          * If hardware initialization is in progress (initialized by other IOC),
1052          * just wait for an initialization completion interrupt.
1053          */
1054         if (ioc_fwstate == BFI_IOC_INITING) {
1055                 bfa_trc(ioc, ioc_fwstate);
1056                 ioc->cbfn->reset_cbfn(ioc->bfa);
1057                 return;
1058         }
1059
1060         /**
1061          * If IOC function is disabled and firmware version is same,
1062          * just re-enable IOC.
1063          */
1064         if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1065                 bfa_trc(ioc, ioc_fwstate);
1066
1067                 /**
1068                  * When using MSI-X any pending firmware ready event should
1069                  * be flushed. Otherwise MSI-X interrupts are not delivered.
1070                  */
1071                 bfa_ioc_msgflush(ioc);
1072                 ioc->cbfn->reset_cbfn(ioc->bfa);
1073                 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1074                 return;
1075         }
1076
1077         /**
1078          * Initialize the h/w for any other states.
1079          */
1080         bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1081 }
1082
1083 static void
1084 bfa_ioc_timeout(void *ioc_arg)
1085 {
1086         struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
1087
1088         bfa_trc(ioc, 0);
1089         bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1090 }
1091
1092 void
1093 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1094 {
1095         u32       *msgp = (u32 *) ioc_msg;
1096         u32        i;
1097
1098         bfa_trc(ioc, msgp[0]);
1099         bfa_trc(ioc, len);
1100
1101         bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
1102
1103         /*
1104          * first write msg to mailbox registers
1105          */
1106         for (i = 0; i < len / sizeof(u32); i++)
1107                 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32),
1108                               bfa_os_wtole(msgp[i]));
1109
1110         for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1111                 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0);
1112
1113         /*
1114          * write 1 to mailbox CMD to trigger LPU event
1115          */
1116         bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1);
1117         (void)bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1118 }
1119
1120 static void
1121 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1122 {
1123         struct bfi_ioc_ctrl_req_s enable_req;
1124
1125         bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1126                     bfa_ioc_portid(ioc));
1127         enable_req.ioc_class = ioc->ioc_mc;
1128         bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1129 }
1130
1131 static void
1132 bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1133 {
1134         struct bfi_ioc_ctrl_req_s disable_req;
1135
1136         bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1137                     bfa_ioc_portid(ioc));
1138         bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1139 }
1140
1141 static void
1142 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1143 {
1144         struct bfi_ioc_getattr_req_s attr_req;
1145
1146         bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1147                     bfa_ioc_portid(ioc));
1148         bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1149         bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1150 }
1151
1152 static void
1153 bfa_ioc_hb_check(void *cbarg)
1154 {
1155         struct bfa_ioc_s *ioc = cbarg;
1156         u32        hb_count;
1157
1158         hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1159         if (ioc->hb_count == hb_count) {
1160                 ioc->hb_fail++;
1161         } else {
1162                 ioc->hb_count = hb_count;
1163                 ioc->hb_fail = 0;
1164         }
1165
1166         if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
1167                 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
1168                 ioc->hb_fail = 0;
1169                 bfa_ioc_recover(ioc);
1170                 return;
1171         }
1172
1173         bfa_ioc_mbox_poll(ioc);
1174         bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1175                         BFA_IOC_HB_TOV);
1176 }
1177
1178 static void
1179 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1180 {
1181         ioc->hb_fail = 0;
1182         ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1183         bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1184                         BFA_IOC_HB_TOV);
1185 }
1186
1187 static void
1188 bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
1189 {
1190         bfa_timer_stop(&ioc->ioc_timer);
1191 }
1192
1193 /**
1194  * Host to LPU mailbox message addresses
1195  */
1196 static struct {
1197         u32        hfn_mbox, lpu_mbox, hfn_pgn;
1198 } iocreg_fnreg[] = {
1199         {
1200         HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
1201         HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
1202         HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
1203         HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
1204 };
1205
1206 /**
1207  * Host <-> LPU mailbox command/status registers - port 0
1208  */
1209 static struct {
1210         u32        hfn, lpu;
1211 } iocreg_mbcmd_p0[] = {
1212         {
1213         HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
1214         HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
1215         HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
1216         HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
1217 };
1218
1219 /**
1220  * Host <-> LPU mailbox command/status registers - port 1
1221  */
1222 static struct {
1223         u32        hfn, lpu;
1224 } iocreg_mbcmd_p1[] = {
1225         {
1226         HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
1227         HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
1228         HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
1229         HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
1230 };
1231
1232 /**
1233  * Shared IRQ handling in INTX mode
1234  */
1235 static struct {
1236         u32        isr, msk;
1237 } iocreg_shirq_next[] = {
1238         {
1239         HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
1240         HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
1241         HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
1242 HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
1243
1244 static void
1245 bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
1246 {
1247         bfa_os_addr_t   rb;
1248         int             pcifn = bfa_ioc_pcifn(ioc);
1249
1250         rb = bfa_ioc_bar0(ioc);
1251
1252         ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
1253         ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
1254         ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
1255
1256         if (ioc->port_id == 0) {
1257                 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
1258                 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
1259                 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
1260                 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
1261                 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
1262         } else {
1263                 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
1264                 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
1265                 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
1266                 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
1267                 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
1268         }
1269
1270         /**
1271          * Shared IRQ handling in INTX mode
1272          */
1273         ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
1274         ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
1275
1276         /*
1277          * PSS control registers
1278          */
1279         ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
1280         ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
1281         ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
1282
1283         /*
1284          * IOC semaphore registers and serialization
1285          */
1286         ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
1287         ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
1288         ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
1289
1290         /**
1291          * sram memory access
1292          */
1293         ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
1294         ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
1295         if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
1296                 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
1297 }
1298
1299 /**
1300  *      Initiate a full firmware download.
1301  */
1302 static void
1303 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1304                     u32 boot_param)
1305 {
1306         u32       *fwimg;
1307         u32        pgnum, pgoff;
1308         u32        loff = 0;
1309         u32        chunkno = 0;
1310         u32        i;
1311
1312         /**
1313          * Initialize LMEM first before code download
1314          */
1315         bfa_ioc_lmem_init(ioc);
1316
1317         /**
1318          * Flash based firmware boot
1319          */
1320         bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc));
1321         if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
1322                 boot_type = BFI_BOOT_TYPE_FLASH;
1323         fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
1324         fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
1325         fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
1326                 bfa_os_swap32(boot_param);
1327
1328         pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1329         pgoff = bfa_ioc_smem_pgoff(ioc, loff);
1330
1331         bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1332
1333         for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
1334
1335                 if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
1336                         chunkno = BFA_FLASH_CHUNK_NO(i);
1337                         fwimg = bfa_ioc_fwimg_get_chunk(ioc,
1338                                         BFA_FLASH_CHUNK_ADDR(chunkno));
1339                 }
1340
1341                 /**
1342                  * write smem
1343                  */
1344                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1345                               fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
1346
1347                 loff += sizeof(u32);
1348
1349                 /**
1350                  * handle page offset wrap around
1351                  */
1352                 loff = PSS_SMEM_PGOFF(loff);
1353                 if (loff == 0) {
1354                         pgnum++;
1355                         bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1356                 }
1357         }
1358
1359         bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
1360                       bfa_ioc_smem_pgnum(ioc, 0));
1361 }
1362
1363 static void
1364 bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1365 {
1366         bfa_ioc_hwinit(ioc, force);
1367 }
1368
1369 /**
1370  * Update BFA configuration from firmware configuration.
1371  */
1372 static void
1373 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1374 {
1375         struct bfi_ioc_attr_s *attr = ioc->attr;
1376
1377         attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
1378         attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
1379
1380         bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1381 }
1382
1383 /**
1384  * Attach time initialization of mbox logic.
1385  */
1386 static void
1387 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1388 {
1389         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1390         int             mc;
1391
1392         INIT_LIST_HEAD(&mod->cmd_q);
1393         for (mc = 0; mc < BFI_MC_MAX; mc++) {
1394                 mod->mbhdlr[mc].cbfn = NULL;
1395                 mod->mbhdlr[mc].cbarg = ioc->bfa;
1396         }
1397 }
1398
1399 /**
1400  * Mbox poll timer -- restarts any pending mailbox requests.
1401  */
1402 static void
1403 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1404 {
1405         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1406         struct bfa_mbox_cmd_s *cmd;
1407         u32        stat;
1408
1409         /**
1410          * If no command pending, do nothing
1411          */
1412         if (list_empty(&mod->cmd_q))
1413                 return;
1414
1415         /**
1416          * If previous command is not yet fetched by firmware, do nothing
1417          */
1418         stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1419         if (stat)
1420                 return;
1421
1422         /**
1423          * Enqueue command to firmware.
1424          */
1425         bfa_q_deq(&mod->cmd_q, &cmd);
1426         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1427 }
1428
1429 /**
1430  * Cleanup any pending requests.
1431  */
1432 static void
1433 bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1434 {
1435         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1436         struct bfa_mbox_cmd_s *cmd;
1437
1438         while (!list_empty(&mod->cmd_q))
1439                 bfa_q_deq(&mod->cmd_q, &cmd);
1440 }
1441
1442 /**
1443  * Initialize IOC to port mapping.
1444  */
1445
1446 #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
1447 static void
1448 bfa_ioc_map_port(struct bfa_ioc_s *ioc)
1449 {
1450         bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
1451         u32        r32;
1452
1453         /**
1454          * For crossbow, port id is same as pci function.
1455          */
1456         if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
1457                 ioc->port_id = bfa_ioc_pcifn(ioc);
1458                 return;
1459         }
1460
1461         /**
1462          * For catapult, base port id on personality register and IOC type
1463          */
1464         r32 = bfa_reg_read(rb + FNC_PERS_REG);
1465         r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
1466         ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
1467
1468         bfa_trc(ioc, bfa_ioc_pcifn(ioc));
1469         bfa_trc(ioc, ioc->port_id);
1470 }
1471
1472
1473
1474 /**
1475  *  bfa_ioc_public
1476  */
1477
1478 /**
1479 * Set interrupt mode for a function: INTX or MSIX
1480  */
1481 void
1482 bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
1483 {
1484         bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
1485         u32        r32, mode;
1486
1487         r32 = bfa_reg_read(rb + FNC_PERS_REG);
1488         bfa_trc(ioc, r32);
1489
1490         mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
1491                 __F0_INTX_STATUS;
1492
1493         /**
1494          * If already in desired mode, do not change anything
1495          */
1496         if (!msix && mode)
1497                 return;
1498
1499         if (msix)
1500                 mode = __F0_INTX_STATUS_MSIX;
1501         else
1502                 mode = __F0_INTX_STATUS_INTA;
1503
1504         r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1505         r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1506         bfa_trc(ioc, r32);
1507
1508         bfa_reg_write(rb + FNC_PERS_REG, r32);
1509 }
1510
1511 bfa_status_t
1512 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1513 {
1514         bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
1515         u32        pll_sclk, pll_fclk, r32;
1516
1517         if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1518                 pll_sclk =
1519                         __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1520                         __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
1521                         __APP_PLL_312_JITLMT0_1(3U) |
1522                         __APP_PLL_312_CNTLMT0_1(1U);
1523                 pll_fclk =
1524                         __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1525                         __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
1526                         __APP_PLL_425_JITLMT0_1(3U) |
1527                         __APP_PLL_425_CNTLMT0_1(1U);
1528
1529                 /**
1530                  *      For catapult, choose operational mode FC/FCoE
1531                  */
1532                 if (ioc->fcmode) {
1533                         bfa_reg_write((rb + OP_MODE), 0);
1534                         bfa_reg_write((rb + ETH_MAC_SER_REG),
1535                                       __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
1536                                       | __APP_EMS_CHANNEL_SEL);
1537                 } else {
1538                         ioc->pllinit = BFA_TRUE;
1539                         bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
1540                         bfa_reg_write((rb + ETH_MAC_SER_REG),
1541                                       __APP_EMS_REFCKBUFEN1);
1542                 }
1543         } else {
1544                 pll_sclk =
1545                         __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1546                         __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
1547                         __APP_PLL_312_CNTLMT0_1(3U);
1548                 pll_fclk =
1549                         __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1550                         __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
1551                         __APP_PLL_425_JITLMT0_1(3U) |
1552                         __APP_PLL_425_CNTLMT0_1(3U);
1553         }
1554
1555         bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
1556         bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
1557
1558         bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1559         bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1560         bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1561         bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1562         bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1563         bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1564
1565         bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1566                       __APP_PLL_312_LOGIC_SOFT_RESET);
1567         bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1568                       __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
1569         bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1570                       __APP_PLL_425_LOGIC_SOFT_RESET);
1571         bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1572                       __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
1573         bfa_os_udelay(2);
1574         bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1575                       __APP_PLL_312_LOGIC_SOFT_RESET);
1576         bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1577                       __APP_PLL_425_LOGIC_SOFT_RESET);
1578
1579         bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1580                       pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
1581         bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1582                       pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
1583
1584         /**
1585          * Wait for PLLs to lock.
1586          */
1587         bfa_os_udelay(2000);
1588         bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1589         bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1590
1591         bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
1592         bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
1593
1594         if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1595                 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
1596                 bfa_os_udelay(1000);
1597                 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
1598                 bfa_trc(ioc, r32);
1599         }
1600
1601         return BFA_STATUS_OK;
1602 }
1603
1604 /**
1605  * Interface used by diag module to do firmware boot with memory test
1606  * as the entry vector.
1607  */
1608 void
1609 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
1610 {
1611         bfa_os_addr_t   rb;
1612
1613         bfa_ioc_stats(ioc, ioc_boots);
1614
1615         if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
1616                 return;
1617
1618         /**
1619          * Initialize IOC state of all functions on a chip reset.
1620          */
1621         rb = ioc->pcidev.pci_bar_kva;
1622         if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
1623                 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST);
1624                 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST);
1625         } else {
1626                 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING);
1627                 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
1628         }
1629
1630         bfa_ioc_download_fw(ioc, boot_type, boot_param);
1631
1632         /**
1633          * Enable interrupts just before starting LPU
1634          */
1635         ioc->cbfn->reset_cbfn(ioc->bfa);
1636         bfa_ioc_lpu_start(ioc);
1637 }
1638
1639 /**
1640  * Enable/disable IOC failure auto recovery.
1641  */
1642 void
1643 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
1644 {
1645         bfa_auto_recover = BFA_FALSE;
1646 }
1647
1648
1649 bfa_boolean_t
1650 bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
1651 {
1652         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
1653 }
1654
1655 void
1656 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
1657 {
1658         u32       *msgp = mbmsg;
1659         u32        r32;
1660         int             i;
1661
1662         /**
1663          * read the MBOX msg
1664          */
1665         for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
1666              i++) {
1667                 r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox +
1668                                    i * sizeof(u32));
1669                 msgp[i] = bfa_os_htonl(r32);
1670         }
1671
1672         /**
1673          * turn off mailbox interrupt by clearing mailbox status
1674          */
1675         bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1676         bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1677 }
1678
1679 void
1680 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
1681 {
1682         union bfi_ioc_i2h_msg_u *msg;
1683
1684         msg = (union bfi_ioc_i2h_msg_u *)m;
1685
1686         bfa_ioc_stats(ioc, ioc_isrs);
1687
1688         switch (msg->mh.msg_id) {
1689         case BFI_IOC_I2H_HBEAT:
1690                 break;
1691
1692         case BFI_IOC_I2H_READY_EVENT:
1693                 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1694                 break;
1695
1696         case BFI_IOC_I2H_ENABLE_REPLY:
1697                 bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
1698                 break;
1699
1700         case BFI_IOC_I2H_DISABLE_REPLY:
1701                 bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
1702                 break;
1703
1704         case BFI_IOC_I2H_GETATTR_REPLY:
1705                 bfa_ioc_getattr_reply(ioc);
1706                 break;
1707
1708         default:
1709                 bfa_trc(ioc, msg->mh.msg_id);
1710                 bfa_assert(0);
1711         }
1712 }
1713
1714 /**
1715  * IOC attach time initialization and setup.
1716  *
1717  * @param[in]   ioc     memory for IOC
1718  * @param[in]   bfa     driver instance structure
1719  * @param[in]   trcmod  kernel trace module
1720  * @param[in]   aen     kernel aen event module
1721  * @param[in]   logm    kernel logging module
1722  */
1723 void
1724 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
1725                struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod,
1726                struct bfa_aen_s *aen, struct bfa_log_mod_s *logm)
1727 {
1728         ioc->bfa = bfa;
1729         ioc->cbfn = cbfn;
1730         ioc->timer_mod = timer_mod;
1731         ioc->trcmod = trcmod;
1732         ioc->aen = aen;
1733         ioc->logm = logm;
1734         ioc->fcmode = BFA_FALSE;
1735         ioc->pllinit = BFA_FALSE;
1736         ioc->dbg_fwsave_once = BFA_TRUE;
1737
1738         bfa_ioc_mbox_attach(ioc);
1739         INIT_LIST_HEAD(&ioc->hb_notify_q);
1740
1741         bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
1742 }
1743
1744 /**
1745  * Driver detach time IOC cleanup.
1746  */
1747 void
1748 bfa_ioc_detach(struct bfa_ioc_s *ioc)
1749 {
1750         bfa_fsm_send_event(ioc, IOC_E_DETACH);
1751 }
1752
1753 /**
1754  * Setup IOC PCI properties.
1755  *
1756  * @param[in]   pcidev  PCI device information for this IOC
1757  */
1758 void
1759 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1760                  enum bfi_mclass mc)
1761 {
1762         ioc->ioc_mc = mc;
1763         ioc->pcidev = *pcidev;
1764         ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
1765         ioc->cna = ioc->ctdev && !ioc->fcmode;
1766
1767         bfa_ioc_map_port(ioc);
1768         bfa_ioc_reg_init(ioc);
1769 }
1770
1771 /**
1772  * Initialize IOC dma memory
1773  *
1774  * @param[in]   dm_kva  kernel virtual address of IOC dma memory
1775  * @param[in]   dm_pa   physical address of IOC dma memory
1776  */
1777 void
1778 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
1779 {
1780         /**
1781          * dma memory for firmware attribute
1782          */
1783         ioc->attr_dma.kva = dm_kva;
1784         ioc->attr_dma.pa = dm_pa;
1785         ioc->attr = (struct bfi_ioc_attr_s *)dm_kva;
1786 }
1787
1788 /**
1789  * Return size of dma memory required.
1790  */
1791 u32
1792 bfa_ioc_meminfo(void)
1793 {
1794         return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
1795 }
1796
1797 void
1798 bfa_ioc_enable(struct bfa_ioc_s *ioc)
1799 {
1800         bfa_ioc_stats(ioc, ioc_enables);
1801         ioc->dbg_fwsave_once = BFA_TRUE;
1802
1803         bfa_fsm_send_event(ioc, IOC_E_ENABLE);
1804 }
1805
1806 void
1807 bfa_ioc_disable(struct bfa_ioc_s *ioc)
1808 {
1809         bfa_ioc_stats(ioc, ioc_disables);
1810         bfa_fsm_send_event(ioc, IOC_E_DISABLE);
1811 }
1812
1813 /**
1814  * Returns memory required for saving firmware trace in case of crash.
1815  * Driver must call this interface to allocate memory required for
1816  * automatic saving of firmware trace. Driver should call
1817  * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
1818  * trace memory.
1819  */
1820 int
1821 bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
1822 {
1823 return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
1824 }
1825
1826 /**
1827  * Initialize memory for saving firmware trace. Driver must initialize
1828  * trace memory before call bfa_ioc_enable().
1829  */
1830 void
1831 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
1832 {
1833         bfa_assert(ioc->auto_recover);
1834         ioc->dbg_fwsave = dbg_fwsave;
1835         ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
1836 }
1837
1838 u32
1839 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
1840 {
1841         return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
1842 }
1843
1844 u32
1845 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
1846 {
1847         return PSS_SMEM_PGOFF(fmaddr);
1848 }
1849
1850 /**
1851  * Register mailbox message handler functions
1852  *
1853  * @param[in]   ioc             IOC instance
1854  * @param[in]   mcfuncs         message class handler functions
1855  */
1856 void
1857 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
1858 {
1859         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1860         int             mc;
1861
1862         for (mc = 0; mc < BFI_MC_MAX; mc++)
1863                 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
1864 }
1865
1866 /**
1867  * Register mailbox message handler function, to be called by common modules
1868  */
1869 void
1870 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
1871                     bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
1872 {
1873         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1874
1875         mod->mbhdlr[mc].cbfn = cbfn;
1876         mod->mbhdlr[mc].cbarg = cbarg;
1877 }
1878
1879 /**
1880  * Queue a mailbox command request to firmware. Waits if mailbox is busy.
1881  * Responsibility of caller to serialize
1882  *
1883  * @param[in]   ioc     IOC instance
1884  * @param[i]    cmd     Mailbox command
1885  */
1886 void
1887 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
1888 {
1889         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1890         u32        stat;
1891
1892         /**
1893          * If a previous command is pending, queue new command
1894          */
1895         if (!list_empty(&mod->cmd_q)) {
1896                 list_add_tail(&cmd->qe, &mod->cmd_q);
1897                 return;
1898         }
1899
1900         /**
1901          * If mailbox is busy, queue command for poll timer
1902          */
1903         stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1904         if (stat) {
1905                 list_add_tail(&cmd->qe, &mod->cmd_q);
1906                 return;
1907         }
1908
1909         /**
1910          * mailbox is free -- queue command to firmware
1911          */
1912         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1913 }
1914
1915 /**
1916  * Handle mailbox interrupts
1917  */
1918 void
1919 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
1920 {
1921         struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1922         struct bfi_mbmsg_s m;
1923         int             mc;
1924
1925         bfa_ioc_msgget(ioc, &m);
1926
1927         /**
1928          * Treat IOC message class as special.
1929          */
1930         mc = m.mh.msg_class;
1931         if (mc == BFI_MC_IOC) {
1932                 bfa_ioc_isr(ioc, &m);
1933                 return;
1934         }
1935
1936         if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
1937                 return;
1938
1939         mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
1940 }
1941
1942 void
1943 bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
1944 {
1945         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
1946 }
1947
1948 #ifndef BFA_BIOS_BUILD
1949
1950 /**
1951  * return true if IOC is disabled
1952  */
1953 bfa_boolean_t
1954 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
1955 {
1956         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
1957                 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
1958 }
1959
1960 /**
1961  * return true if IOC firmware is different.
1962  */
1963 bfa_boolean_t
1964 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
1965 {
1966         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
1967                 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
1968                 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch);
1969 }
1970
1971 #define bfa_ioc_state_disabled(__sm)            \
1972         (((__sm) == BFI_IOC_UNINIT) ||          \
1973          ((__sm) == BFI_IOC_INITING) ||         \
1974          ((__sm) == BFI_IOC_HWINIT) ||          \
1975          ((__sm) == BFI_IOC_DISABLED) ||        \
1976          ((__sm) == BFI_IOC_HBFAIL) ||          \
1977          ((__sm) == BFI_IOC_CFG_DISABLED))
1978
1979 /**
1980  * Check if adapter is disabled -- both IOCs should be in a disabled
1981  * state.
1982  */
1983 bfa_boolean_t
1984 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
1985 {
1986         u32        ioc_state;
1987         bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
1988
1989         if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
1990                 return BFA_FALSE;
1991
1992         ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG);
1993         if (!bfa_ioc_state_disabled(ioc_state))
1994                 return BFA_FALSE;
1995
1996         ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG);
1997         if (!bfa_ioc_state_disabled(ioc_state))
1998                 return BFA_FALSE;
1999
2000         return BFA_TRUE;
2001 }
2002
2003 /**
2004  * Add to IOC heartbeat failure notification queue. To be used by common
2005  * modules such as
2006  */
2007 void
2008 bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
2009                         struct bfa_ioc_hbfail_notify_s *notify)
2010 {
2011         list_add_tail(&notify->qe, &ioc->hb_notify_q);
2012 }
2013
2014 #define BFA_MFG_NAME "Brocade"
2015 void
2016 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2017                          struct bfa_adapter_attr_s *ad_attr)
2018 {
2019         struct bfi_ioc_attr_s *ioc_attr;
2020         char            model[BFA_ADAPTER_MODEL_NAME_LEN];
2021
2022         ioc_attr = ioc->attr;
2023         bfa_os_memcpy((void *)&ad_attr->serial_num,
2024                       (void *)ioc_attr->brcd_serialnum,
2025                       BFA_ADAPTER_SERIAL_NUM_LEN);
2026
2027         bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
2028         bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
2029                       BFA_VERSION_LEN);
2030         bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
2031                       BFA_ADAPTER_MFG_NAME_LEN);
2032         bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2033                       sizeof(struct bfa_mfg_vpd_s));
2034
2035         ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
2036         ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2037
2038         /**
2039          * model name
2040          */
2041         if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
2042                 strcpy(model, "BR-10?0");
2043                 model[5] = '0' + ad_attr->nports;
2044         } else {
2045                 strcpy(model, "Brocade-??5");
2046                 model[8] =
2047                         '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2048                 model[9] = '0' + ad_attr->nports;
2049         }
2050
2051         if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2052                 ad_attr->prototype = 1;
2053         else
2054                 ad_attr->prototype = 0;
2055
2056         bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
2057         bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
2058                       BFA_ADAPTER_MODEL_NAME_LEN);
2059
2060         ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
2061         ad_attr->mac = bfa_ioc_get_mac(ioc);
2062
2063         ad_attr->pcie_gen = ioc_attr->pcie_gen;
2064         ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2065         ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2066         ad_attr->asic_rev = ioc_attr->asic_rev;
2067         ad_attr->hw_ver[0] = 'R';
2068         ad_attr->hw_ver[1] = 'e';
2069         ad_attr->hw_ver[2] = 'v';
2070         ad_attr->hw_ver[3] = '-';
2071         ad_attr->hw_ver[4] = ioc_attr->asic_rev;
2072         ad_attr->hw_ver[5] = '\0';
2073
2074         ad_attr->cna_capable = ioc->cna;
2075 }
2076
2077 void
2078 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2079 {
2080         bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2081
2082         ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2083         ioc_attr->port_id = ioc->port_id;
2084
2085         if (!ioc->ctdev)
2086                 ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
2087         else if (ioc->ioc_mc == BFI_MC_IOCFC)
2088                 ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
2089         else if (ioc->ioc_mc == BFI_MC_LL)
2090                 ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
2091
2092         bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2093
2094         ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
2095         ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
2096         ioc_attr->pci_attr.chip_rev[0] = 'R';
2097         ioc_attr->pci_attr.chip_rev[1] = 'e';
2098         ioc_attr->pci_attr.chip_rev[2] = 'v';
2099         ioc_attr->pci_attr.chip_rev[3] = '-';
2100         ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
2101         ioc_attr->pci_attr.chip_rev[5] = '\0';
2102 }
2103
2104 /**
2105  *  hal_wwn_public
2106  */
2107 wwn_t
2108 bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
2109 {
2110         union {
2111                 wwn_t           wwn;
2112                 u8         byte[sizeof(wwn_t)];
2113         }
2114         w;
2115
2116         w.wwn = ioc->attr->mfg_wwn;
2117
2118         if (bfa_ioc_portid(ioc) == 1)
2119                 w.byte[7]++;
2120
2121         return w.wwn;
2122 }
2123
2124 wwn_t
2125 bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
2126 {
2127         union {
2128                 wwn_t           wwn;
2129                 u8         byte[sizeof(wwn_t)];
2130         }
2131         w;
2132
2133         w.wwn = ioc->attr->mfg_wwn;
2134
2135         if (bfa_ioc_portid(ioc) == 1)
2136                 w.byte[7]++;
2137
2138         w.byte[0] = 0x20;
2139
2140         return w.wwn;
2141 }
2142
2143 wwn_t
2144 bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
2145 {
2146         union {
2147                 wwn_t           wwn;
2148                 u8         byte[sizeof(wwn_t)];
2149         }
2150         w              , w5;
2151
2152         bfa_trc(ioc, inst);
2153
2154         w.wwn = ioc->attr->mfg_wwn;
2155         w5.byte[0] = 0x50 | w.byte[2] >> 4;
2156         w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
2157         w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
2158         w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
2159         w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
2160         w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
2161         w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
2162         w5.byte[7] = (inst & 0xff);
2163
2164         return w5.wwn;
2165 }
2166
2167 u64
2168 bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
2169 {
2170         return ioc->attr->mfg_wwn;
2171 }
2172
2173 mac_t
2174 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2175 {
2176         mac_t           mac;
2177
2178         mac = ioc->attr->mfg_mac;
2179         mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2180
2181         return mac;
2182 }
2183
2184 void
2185 bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
2186 {
2187         ioc->fcmode = BFA_TRUE;
2188         ioc->port_id = bfa_ioc_pcifn(ioc);
2189 }
2190
2191 bfa_boolean_t
2192 bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2193 {
2194         return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
2195 }
2196
2197 /**
2198  * Return true if interrupt should be claimed.
2199  */
2200 bfa_boolean_t
2201 bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
2202 {
2203         u32        isr, msk;
2204
2205         /**
2206          * Always claim if not catapult.
2207          */
2208         if (!ioc->ctdev)
2209                 return BFA_TRUE;
2210
2211         /**
2212          * FALSE if next device is claiming interrupt.
2213          * TRUE if next device is not interrupting or not present.
2214          */
2215         msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
2216         isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
2217         return !(isr & ~msk);
2218 }
2219
2220 /**
2221  * Send AEN notification
2222  */
2223 static void
2224 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2225 {
2226         union bfa_aen_data_u aen_data;
2227         struct bfa_log_mod_s *logmod = ioc->logm;
2228         s32         inst_num = 0;
2229         struct bfa_ioc_attr_s ioc_attr;
2230
2231         switch (event) {
2232         case BFA_IOC_AEN_HBGOOD:
2233                 bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
2234                 break;
2235         case BFA_IOC_AEN_HBFAIL:
2236                 bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
2237                 break;
2238         case BFA_IOC_AEN_ENABLE:
2239                 bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
2240                 break;
2241         case BFA_IOC_AEN_DISABLE:
2242                 bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
2243                 break;
2244         case BFA_IOC_AEN_FWMISMATCH:
2245                 bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
2246                 break;
2247         default:
2248                 break;
2249         }
2250
2251         memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
2252         memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
2253         bfa_ioc_get_attr(ioc, &ioc_attr);
2254         switch (ioc_attr.ioc_type) {
2255         case BFA_IOC_TYPE_FC:
2256                 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2257                 break;
2258         case BFA_IOC_TYPE_FCoE:
2259                 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2260                 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2261                 break;
2262         case BFA_IOC_TYPE_LL:
2263                 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2264                 break;
2265         default:
2266                 bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
2267                 break;
2268         }
2269         aen_data.ioc.ioc_type = ioc_attr.ioc_type;
2270 }
2271
2272 /**
2273  * Retrieve saved firmware trace from a prior IOC failure.
2274  */
2275 bfa_status_t
2276 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2277 {
2278         int             tlen;
2279
2280         if (ioc->dbg_fwsave_len == 0)
2281                 return BFA_STATUS_ENOFSAVE;
2282
2283         tlen = *trclen;
2284         if (tlen > ioc->dbg_fwsave_len)
2285                 tlen = ioc->dbg_fwsave_len;
2286
2287         bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen);
2288         *trclen = tlen;
2289         return BFA_STATUS_OK;
2290 }
2291
2292 /**
2293  * Retrieve saved firmware trace from a prior IOC failure.
2294  */
2295 bfa_status_t
2296 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2297 {
2298         u32        pgnum;
2299         u32        loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2300         int             i, tlen;
2301         u32       *tbuf = trcdata, r32;
2302
2303         bfa_trc(ioc, *trclen);
2304
2305         pgnum = bfa_ioc_smem_pgnum(ioc, loff);
2306         loff = bfa_ioc_smem_pgoff(ioc, loff);
2307         bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2308
2309         tlen = *trclen;
2310         if (tlen > BFA_DBG_FWTRC_LEN)
2311                 tlen = BFA_DBG_FWTRC_LEN;
2312         tlen /= sizeof(u32);
2313
2314         bfa_trc(ioc, tlen);
2315
2316         for (i = 0; i < tlen; i++) {
2317                 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2318                 tbuf[i] = bfa_os_ntohl(r32);
2319                 loff += sizeof(u32);
2320
2321                 /**
2322                  * handle page offset wrap around
2323                  */
2324                 loff = PSS_SMEM_PGOFF(loff);
2325                 if (loff == 0) {
2326                         pgnum++;
2327                         bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2328                 }
2329         }
2330         bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
2331                       bfa_ioc_smem_pgnum(ioc, 0));
2332         bfa_trc(ioc, pgnum);
2333
2334         *trclen = tlen * sizeof(u32);
2335         return BFA_STATUS_OK;
2336 }
2337
2338 /**
2339  * Save firmware trace if configured.
2340  */
2341 static void
2342 bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
2343 {
2344         int             tlen;
2345
2346         if (ioc->dbg_fwsave_len) {
2347                 tlen = ioc->dbg_fwsave_len;
2348                 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
2349         }
2350 }
2351
2352 /**
2353  * Firmware failure detected. Start recovery actions.
2354  */
2355 static void
2356 bfa_ioc_recover(struct bfa_ioc_s *ioc)
2357 {
2358         if (ioc->dbg_fwsave_once) {
2359                 ioc->dbg_fwsave_once = BFA_FALSE;
2360                 bfa_ioc_debug_save(ioc);
2361         }
2362
2363         bfa_ioc_stats(ioc, ioc_hbfails);
2364         bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2365 }
2366
2367 #else
2368
2369 static void
2370 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2371 {
2372 }
2373
2374 static void
2375 bfa_ioc_recover(struct bfa_ioc_s *ioc)
2376 {
2377         bfa_assert(0);
2378 }
2379
2380 #endif
2381
2382