]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/scsi/bfa/bfa_fcport.c
[SCSI] qla2xxx: Update version number to 8.03.04-k0.
[karo-tx-linux.git] / drivers / scsi / bfa / bfa_fcport.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_svc.h>
20 #include <bfi/bfi_pport.h>
21 #include <bfi/bfi_pbc.h>
22 #include <cs/bfa_debug.h>
23 #include <aen/bfa_aen.h>
24 #include <cs/bfa_plog.h>
25 #include <aen/bfa_aen_port.h>
26
27 BFA_TRC_FILE(HAL, FCPORT);
28 BFA_MODULE(fcport);
29
30 /*
31  * The port is considered disabled if corresponding physical port or IOC are
32  * disabled explicitly
33  */
34 #define BFA_PORT_IS_DISABLED(bfa) \
35         ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
36         (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
37
38 /*
39  * forward declarations
40  */
41 static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
42 static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
43 static void     bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
44 static void     bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
45 static void     bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
46 static void     __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
47 static void     bfa_fcport_callback(struct bfa_fcport_s *fcport,
48                                 enum bfa_pport_linkstate event);
49 static void     bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
50                                 enum bfa_pport_linkstate event);
51 static void     __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
52 static void     bfa_fcport_stats_get_timeout(void *cbarg);
53 static void     bfa_fcport_stats_clr_timeout(void *cbarg);
54
55 /**
56  *  bfa_pport_private
57  */
58
59 /**
60  * BFA port state machine events
61  */
62 enum bfa_fcport_sm_event {
63         BFA_FCPORT_SM_START = 1,        /*  start port state machine */
64         BFA_FCPORT_SM_STOP = 2, /*  stop port state machine */
65         BFA_FCPORT_SM_ENABLE = 3,       /*  enable port */
66         BFA_FCPORT_SM_DISABLE = 4,      /*  disable port state machine */
67         BFA_FCPORT_SM_FWRSP = 5,        /*  firmware enable/disable rsp */
68         BFA_FCPORT_SM_LINKUP = 6,       /*  firmware linkup event */
69         BFA_FCPORT_SM_LINKDOWN = 7,     /*  firmware linkup down */
70         BFA_FCPORT_SM_QRESUME = 8,      /*  CQ space available */
71         BFA_FCPORT_SM_HWFAIL = 9,       /*  IOC h/w failure */
72 };
73
74 /**
75  * BFA port link notification state machine events
76  */
77
78 enum bfa_fcport_ln_sm_event {
79         BFA_FCPORT_LN_SM_LINKUP         = 1,    /*  linkup event */
80         BFA_FCPORT_LN_SM_LINKDOWN       = 2,    /*  linkdown event */
81         BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification */
82 };
83
84 static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
85                                         enum bfa_fcport_sm_event event);
86 static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
87                                                 enum bfa_fcport_sm_event event);
88 static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
89                                                 enum bfa_fcport_sm_event event);
90 static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
91                                                 enum bfa_fcport_sm_event event);
92 static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
93                                                 enum bfa_fcport_sm_event event);
94 static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
95                                                 enum bfa_fcport_sm_event event);
96 static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
97                                                 enum bfa_fcport_sm_event event);
98 static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
99                                                 enum bfa_fcport_sm_event event);
100 static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
101                                          enum bfa_fcport_sm_event event);
102 static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
103                                          enum bfa_fcport_sm_event event);
104 static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
105                                          enum bfa_fcport_sm_event event);
106
107 static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
108                                          enum bfa_fcport_ln_sm_event event);
109 static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
110                                          enum bfa_fcport_ln_sm_event event);
111 static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
112                                          enum bfa_fcport_ln_sm_event event);
113 static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
114                                          enum bfa_fcport_ln_sm_event event);
115 static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
116                                          enum bfa_fcport_ln_sm_event event);
117 static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
118                                          enum bfa_fcport_ln_sm_event event);
119 static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
120                                          enum bfa_fcport_ln_sm_event event);
121
122 static struct bfa_sm_table_s hal_pport_sm_table[] = {
123         {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
124         {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
125         {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
126         {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
127         {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
128         {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
129         {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
130         {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
131         {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
132         {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
133         {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
134 };
135
136 static void
137 bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
138 {
139         union bfa_aen_data_u aen_data;
140         struct bfa_log_mod_s *logmod = fcport->bfa->logm;
141         wwn_t           pwwn = fcport->pwwn;
142         char            pwwn_ptr[BFA_STRING_32];
143
144         memset(&aen_data, 0, sizeof(aen_data));
145         wwn2str(pwwn_ptr, pwwn);
146         bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
147
148         aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
149         aen_data.port.pwwn = pwwn;
150 }
151
152 static void
153 bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
154                         enum bfa_fcport_sm_event event)
155 {
156         bfa_trc(fcport->bfa, event);
157
158         switch (event) {
159         case BFA_FCPORT_SM_START:
160                 /**
161                  * Start event after IOC is configured and BFA is started.
162                  */
163                 if (bfa_fcport_send_enable(fcport))
164                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
165                 else
166                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
167                 break;
168
169         case BFA_FCPORT_SM_ENABLE:
170                 /**
171                  * Port is persistently configured to be in enabled state. Do
172                  * not change state. Port enabling is done when START event is
173                  * received.
174                  */
175                 break;
176
177         case BFA_FCPORT_SM_DISABLE:
178                 /**
179                  * If a port is persistently configured to be disabled, the
180                  * first event will a port disable request.
181                  */
182                 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
183                 break;
184
185         case BFA_FCPORT_SM_HWFAIL:
186                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
187                 break;
188
189         default:
190                 bfa_sm_fault(fcport->bfa, event);
191         }
192 }
193
194 static void
195 bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
196                             enum bfa_fcport_sm_event event)
197 {
198         bfa_trc(fcport->bfa, event);
199
200         switch (event) {
201         case BFA_FCPORT_SM_QRESUME:
202                 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
203                 bfa_fcport_send_enable(fcport);
204                 break;
205
206         case BFA_FCPORT_SM_STOP:
207                 bfa_reqq_wcancel(&fcport->reqq_wait);
208                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
209                 break;
210
211         case BFA_FCPORT_SM_ENABLE:
212                 /**
213                  * Already enable is in progress.
214                  */
215                 break;
216
217         case BFA_FCPORT_SM_DISABLE:
218                 /**
219                  * Just send disable request to firmware when room becomes
220                  * available in request queue.
221                  */
222                 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
223                 bfa_reqq_wcancel(&fcport->reqq_wait);
224                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
225                              BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
226                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
227                 break;
228
229         case BFA_FCPORT_SM_LINKUP:
230         case BFA_FCPORT_SM_LINKDOWN:
231                 /**
232                  * Possible to get link events when doing back-to-back
233                  * enable/disables.
234                  */
235                 break;
236
237         case BFA_FCPORT_SM_HWFAIL:
238                 bfa_reqq_wcancel(&fcport->reqq_wait);
239                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
240                 break;
241
242         default:
243                 bfa_sm_fault(fcport->bfa, event);
244         }
245 }
246
247 static void
248 bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
249                 enum bfa_fcport_sm_event event)
250 {
251         bfa_trc(fcport->bfa, event);
252
253         switch (event) {
254         case BFA_FCPORT_SM_FWRSP:
255         case BFA_FCPORT_SM_LINKDOWN:
256                 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
257                 break;
258
259         case BFA_FCPORT_SM_LINKUP:
260                 bfa_fcport_update_linkinfo(fcport);
261                 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
262
263                 bfa_assert(fcport->event_cbfn);
264                 bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
265                 break;
266
267         case BFA_FCPORT_SM_ENABLE:
268                 /**
269                  * Already being enabled.
270                  */
271                 break;
272
273         case BFA_FCPORT_SM_DISABLE:
274                 if (bfa_fcport_send_disable(fcport))
275                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
276                 else
277                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
278
279                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
280                              BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
281                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
282                 break;
283
284         case BFA_FCPORT_SM_STOP:
285                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
286                 break;
287
288         case BFA_FCPORT_SM_HWFAIL:
289                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
290                 break;
291
292         default:
293                 bfa_sm_fault(fcport->bfa, event);
294         }
295 }
296
297 static void
298 bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
299                         enum bfa_fcport_sm_event event)
300 {
301         struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
302         bfa_trc(fcport->bfa, event);
303
304         switch (event) {
305         case BFA_FCPORT_SM_LINKUP:
306                 bfa_fcport_update_linkinfo(fcport);
307                 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
308                 bfa_assert(fcport->event_cbfn);
309                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
310                              BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311
312                 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
313
314                         bfa_trc(fcport->bfa,
315                                 pevent->link_state.vc_fcf.fcf.fipenabled);
316                         bfa_trc(fcport->bfa,
317                                 pevent->link_state.vc_fcf.fcf.fipfailed);
318
319                         if (pevent->link_state.vc_fcf.fcf.fipfailed)
320                                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
321                                         BFA_PL_EID_FIP_FCF_DISC, 0,
322                                         "FIP FCF Discovery Failed");
323                         else
324                                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
325                                         BFA_PL_EID_FIP_FCF_DISC, 0,
326                                         "FIP FCF Discovered");
327                 }
328
329                 bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
330                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
331                 /**
332                  * If QoS is enabled and it is not online,
333                  * Send a separate event.
334                  */
335                 if ((fcport->cfg.qos_enabled)
336                     && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
337                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
338
339                 break;
340
341         case BFA_FCPORT_SM_LINKDOWN:
342                 /**
343                  * Possible to get link down event.
344                  */
345                 break;
346
347         case BFA_FCPORT_SM_ENABLE:
348                 /**
349                  * Already enabled.
350                  */
351                 break;
352
353         case BFA_FCPORT_SM_DISABLE:
354                 if (bfa_fcport_send_disable(fcport))
355                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
356                 else
357                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
358
359                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
360                              BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
361                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
362                 break;
363
364         case BFA_FCPORT_SM_STOP:
365                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
366                 break;
367
368         case BFA_FCPORT_SM_HWFAIL:
369                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
370                 break;
371
372         default:
373                 bfa_sm_fault(fcport->bfa, event);
374         }
375 }
376
377 static void
378 bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
379                         enum bfa_fcport_sm_event event)
380 {
381         bfa_trc(fcport->bfa, event);
382
383         switch (event) {
384         case BFA_FCPORT_SM_ENABLE:
385                 /**
386                  * Already enabled.
387                  */
388                 break;
389
390         case BFA_FCPORT_SM_DISABLE:
391                 if (bfa_fcport_send_disable(fcport))
392                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
393                 else
394                         bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
395
396                 bfa_fcport_reset_linkinfo(fcport);
397                 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
398                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
399                              BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
400                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
401                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
402                 break;
403
404         case BFA_FCPORT_SM_LINKDOWN:
405                 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
406                 bfa_fcport_reset_linkinfo(fcport);
407                 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
408                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
409                              BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
410                 if (BFA_PORT_IS_DISABLED(fcport->bfa))
411                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
412                 else
413                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
414                 break;
415
416         case BFA_FCPORT_SM_STOP:
417                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
418                 bfa_fcport_reset_linkinfo(fcport);
419                 if (BFA_PORT_IS_DISABLED(fcport->bfa))
420                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
421                 else
422                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
423                 break;
424
425         case BFA_FCPORT_SM_HWFAIL:
426                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
427                 bfa_fcport_reset_linkinfo(fcport);
428                 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
429                 if (BFA_PORT_IS_DISABLED(fcport->bfa))
430                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
431                 else
432                         bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
433                 break;
434
435         default:
436                 bfa_sm_fault(fcport->bfa, event);
437         }
438 }
439
440 static void
441 bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
442                              enum bfa_fcport_sm_event event)
443 {
444         bfa_trc(fcport->bfa, event);
445
446         switch (event) {
447         case BFA_FCPORT_SM_QRESUME:
448                 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
449                 bfa_fcport_send_disable(fcport);
450                 break;
451
452         case BFA_FCPORT_SM_STOP:
453                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
454                 bfa_reqq_wcancel(&fcport->reqq_wait);
455                 break;
456
457         case BFA_FCPORT_SM_DISABLE:
458                 /**
459                  * Already being disabled.
460                  */
461                 break;
462
463         case BFA_FCPORT_SM_LINKUP:
464         case BFA_FCPORT_SM_LINKDOWN:
465                 /**
466                  * Possible to get link events when doing back-to-back
467                  * enable/disables.
468                  */
469                 break;
470
471         case BFA_FCPORT_SM_HWFAIL:
472                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
473                 bfa_reqq_wcancel(&fcport->reqq_wait);
474                 break;
475
476         default:
477                 bfa_sm_fault(fcport->bfa, event);
478         }
479 }
480
481 static void
482 bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
483                         enum bfa_fcport_sm_event event)
484 {
485         bfa_trc(fcport->bfa, event);
486
487         switch (event) {
488         case BFA_FCPORT_SM_FWRSP:
489                 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
490                 break;
491
492         case BFA_FCPORT_SM_DISABLE:
493                 /**
494                  * Already being disabled.
495                  */
496                 break;
497
498         case BFA_FCPORT_SM_ENABLE:
499                 if (bfa_fcport_send_enable(fcport))
500                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
501                 else
502                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
503
504                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
505                              BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
506                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
507                 break;
508
509         case BFA_FCPORT_SM_STOP:
510                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
511                 break;
512
513         case BFA_FCPORT_SM_LINKUP:
514         case BFA_FCPORT_SM_LINKDOWN:
515                 /**
516                  * Possible to get link events when doing back-to-back
517                  * enable/disables.
518                  */
519                 break;
520
521         case BFA_FCPORT_SM_HWFAIL:
522                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
523                 break;
524
525         default:
526                 bfa_sm_fault(fcport->bfa, event);
527         }
528 }
529
530 static void
531 bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
532                         enum bfa_fcport_sm_event event)
533 {
534         bfa_trc(fcport->bfa, event);
535
536         switch (event) {
537         case BFA_FCPORT_SM_START:
538                 /**
539                  * Ignore start event for a port that is disabled.
540                  */
541                 break;
542
543         case BFA_FCPORT_SM_STOP:
544                 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
545                 break;
546
547         case BFA_FCPORT_SM_ENABLE:
548                 if (bfa_fcport_send_enable(fcport))
549                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
550                 else
551                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
552
553                 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
554                              BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
555                 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
556                 break;
557
558         case BFA_FCPORT_SM_DISABLE:
559                 /**
560                  * Already disabled.
561                  */
562                 break;
563
564         case BFA_FCPORT_SM_HWFAIL:
565                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
566                 break;
567
568         default:
569                 bfa_sm_fault(fcport->bfa, event);
570         }
571 }
572
573 static void
574 bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
575                         enum bfa_fcport_sm_event event)
576 {
577         bfa_trc(fcport->bfa, event);
578
579         switch (event) {
580         case BFA_FCPORT_SM_START:
581                 if (bfa_fcport_send_enable(fcport))
582                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
583                 else
584                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
585                 break;
586
587         default:
588                 /**
589                  * Ignore all other events.
590                  */
591                 ;
592         }
593 }
594
595 /**
596  * Port is enabled. IOC is down/failed.
597  */
598 static void
599 bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
600                         enum bfa_fcport_sm_event event)
601 {
602         bfa_trc(fcport->bfa, event);
603
604         switch (event) {
605         case BFA_FCPORT_SM_START:
606                 if (bfa_fcport_send_enable(fcport))
607                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
608                 else
609                         bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
610                 break;
611
612         default:
613                 /**
614                  * Ignore all events.
615                  */
616                 ;
617         }
618 }
619
620 /**
621  * Port is disabled. IOC is down/failed.
622  */
623 static void
624 bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
625                         enum bfa_fcport_sm_event event)
626 {
627         bfa_trc(fcport->bfa, event);
628
629         switch (event) {
630         case BFA_FCPORT_SM_START:
631                 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
632                 break;
633
634         case BFA_FCPORT_SM_ENABLE:
635                 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
636                 break;
637
638         default:
639                 /**
640                  * Ignore all events.
641                  */
642                 ;
643         }
644 }
645
646 /**
647  * Link state is down
648  */
649 static void
650 bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
651                 enum bfa_fcport_ln_sm_event event)
652 {
653         bfa_trc(ln->fcport->bfa, event);
654
655         switch (event) {
656         case BFA_FCPORT_LN_SM_LINKUP:
657                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
658                 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
659                 break;
660
661         default:
662                 bfa_sm_fault(ln->fcport->bfa, event);
663         }
664 }
665
666 /**
667  * Link state is waiting for down notification
668  */
669 static void
670 bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
671                 enum bfa_fcport_ln_sm_event event)
672 {
673         bfa_trc(ln->fcport->bfa, event);
674
675         switch (event) {
676         case BFA_FCPORT_LN_SM_LINKUP:
677                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
678                 break;
679
680         case BFA_FCPORT_LN_SM_NOTIFICATION:
681                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
682                 break;
683
684         default:
685                 bfa_sm_fault(ln->fcport->bfa, event);
686         }
687 }
688
689 /**
690  * Link state is waiting for down notification and there is a pending up
691  */
692 static void
693 bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
694                 enum bfa_fcport_ln_sm_event event)
695 {
696         bfa_trc(ln->fcport->bfa, event);
697
698         switch (event) {
699         case BFA_FCPORT_LN_SM_LINKDOWN:
700                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
701                 break;
702
703         case BFA_FCPORT_LN_SM_NOTIFICATION:
704                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
705                 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
706                 break;
707
708         default:
709                 bfa_sm_fault(ln->fcport->bfa, event);
710         }
711 }
712
713 /**
714  * Link state is up
715  */
716 static void
717 bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
718                 enum bfa_fcport_ln_sm_event event)
719 {
720         bfa_trc(ln->fcport->bfa, event);
721
722         switch (event) {
723         case BFA_FCPORT_LN_SM_LINKDOWN:
724                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
725                 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
726                 break;
727
728         default:
729                 bfa_sm_fault(ln->fcport->bfa, event);
730         }
731 }
732
733 /**
734  * Link state is waiting for up notification
735  */
736 static void
737 bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
738                 enum bfa_fcport_ln_sm_event event)
739 {
740         bfa_trc(ln->fcport->bfa, event);
741
742         switch (event) {
743         case BFA_FCPORT_LN_SM_LINKDOWN:
744                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
745                 break;
746
747         case BFA_FCPORT_LN_SM_NOTIFICATION:
748                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
749                 break;
750
751         default:
752                 bfa_sm_fault(ln->fcport->bfa, event);
753         }
754 }
755
756 /**
757  * Link state is waiting for up notification and there is a pending down
758  */
759 static void
760 bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
761                 enum bfa_fcport_ln_sm_event event)
762 {
763         bfa_trc(ln->fcport->bfa, event);
764
765         switch (event) {
766         case BFA_FCPORT_LN_SM_LINKUP:
767                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
768                 break;
769
770         case BFA_FCPORT_LN_SM_NOTIFICATION:
771                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
772                 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
773                 break;
774
775         default:
776                 bfa_sm_fault(ln->fcport->bfa, event);
777         }
778 }
779
780 /**
781  * Link state is waiting for up notification and there are pending down and up
782  */
783 static void
784 bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
785                         enum bfa_fcport_ln_sm_event event)
786 {
787         bfa_trc(ln->fcport->bfa, event);
788
789         switch (event) {
790         case BFA_FCPORT_LN_SM_LINKDOWN:
791                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
792                 break;
793
794         case BFA_FCPORT_LN_SM_NOTIFICATION:
795                 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
796                 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
797                 break;
798
799         default:
800                 bfa_sm_fault(ln->fcport->bfa, event);
801         }
802 }
803
804 /**
805  *  bfa_pport_private
806  */
807
808 static void
809 __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
810 {
811         struct bfa_fcport_ln_s *ln = cbarg;
812
813         if (complete)
814                 ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
815         else
816                 bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
817 }
818
819 static void
820 bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
821 {
822         if (fcport->bfa->fcs) {
823                 fcport->event_cbfn(fcport->event_cbarg, event);
824                 return;
825         }
826
827         switch (event) {
828         case BFA_PPORT_LINKUP:
829                 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
830                 break;
831         case BFA_PPORT_LINKDOWN:
832                 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
833                 break;
834         default:
835                 bfa_assert(0);
836         }
837 }
838
839 static void
840 bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
841 {
842         ln->ln_event = event;
843         bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
844 }
845
846 #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
847                                                         BFA_CACHELINE_SZ))
848
849 static void
850 bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
851                   u32 *dm_len)
852 {
853         *dm_len += FCPORT_STATS_DMA_SZ;
854 }
855
856 static void
857 bfa_fcport_qresume(void *cbarg)
858 {
859         struct bfa_fcport_s *fcport = cbarg;
860
861         bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
862 }
863
864 static void
865 bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
866 {
867         u8        *dm_kva;
868         u64        dm_pa;
869
870         dm_kva = bfa_meminfo_dma_virt(meminfo);
871         dm_pa = bfa_meminfo_dma_phys(meminfo);
872
873         fcport->stats_kva = dm_kva;
874         fcport->stats_pa = dm_pa;
875         fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
876
877         dm_kva += FCPORT_STATS_DMA_SZ;
878         dm_pa += FCPORT_STATS_DMA_SZ;
879
880         bfa_meminfo_dma_virt(meminfo) = dm_kva;
881         bfa_meminfo_dma_phys(meminfo) = dm_pa;
882 }
883
884 /**
885  * Memory initialization.
886  */
887 static void
888 bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
889                  struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
890 {
891         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
892         struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
893         struct bfa_fcport_ln_s *ln = &fcport->ln;
894         struct bfa_timeval_s tv;
895
896         bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
897         fcport->bfa = bfa;
898         ln->fcport = fcport;
899
900         bfa_fcport_mem_claim(fcport, meminfo);
901
902         bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
903         bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
904
905         /**
906          * initialize time stamp for stats reset
907          */
908         bfa_os_gettimeofday(&tv);
909         fcport->stats_reset_time = tv.tv_sec;
910
911         /**
912          * initialize and set default configuration
913          */
914         port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
915         port_cfg->speed = BFA_PPORT_SPEED_AUTO;
916         port_cfg->trunked = BFA_FALSE;
917         port_cfg->maxfrsize = 0;
918
919         port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
920
921         bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
922 }
923
924 static void
925 bfa_fcport_detach(struct bfa_s *bfa)
926 {
927 }
928
929 /**
930  * Called when IOC is ready.
931  */
932 static void
933 bfa_fcport_start(struct bfa_s *bfa)
934 {
935         bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
936 }
937
938 /**
939  * Called before IOC is stopped.
940  */
941 static void
942 bfa_fcport_stop(struct bfa_s *bfa)
943 {
944         bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
945 }
946
947 /**
948  * Called when IOC failure is detected.
949  */
950 static void
951 bfa_fcport_iocdisable(struct bfa_s *bfa)
952 {
953         bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
954 }
955
956 static void
957 bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
958 {
959         struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
960
961         fcport->speed = pevent->link_state.speed;
962         fcport->topology = pevent->link_state.topology;
963
964         if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
965                 fcport->myalpa = 0;
966
967         /*
968          * QoS Details
969          */
970         bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
971         bfa_os_assign(fcport->qos_vc_attr,
972                 pevent->link_state.vc_fcf.qos_vc_attr);
973
974
975         bfa_trc(fcport->bfa, fcport->speed);
976         bfa_trc(fcport->bfa, fcport->topology);
977 }
978
979 static void
980 bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
981 {
982         fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
983         fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
984 }
985
986 /**
987  * Send port enable message to firmware.
988  */
989 static          bfa_boolean_t
990 bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
991 {
992         struct bfi_fcport_enable_req_s *m;
993
994         /**
995          * Increment message tag before queue check, so that responses to old
996          * requests are discarded.
997          */
998         fcport->msgtag++;
999
1000         /**
1001          * check for room in queue to send request now
1002          */
1003         m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1004         if (!m) {
1005                 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1006                                                         &fcport->reqq_wait);
1007                 return BFA_FALSE;
1008         }
1009
1010         bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
1011                                 bfa_lpuid(fcport->bfa));
1012         m->nwwn = fcport->nwwn;
1013         m->pwwn = fcport->pwwn;
1014         m->port_cfg = fcport->cfg;
1015         m->msgtag = fcport->msgtag;
1016         m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
1017         bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
1018         bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
1019         bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
1020
1021         /**
1022          * queue I/O message to firmware
1023          */
1024         bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1025         return BFA_TRUE;
1026 }
1027
1028 /**
1029  * Send port disable message to firmware.
1030  */
1031 static          bfa_boolean_t
1032 bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
1033 {
1034         struct bfi_fcport_req_s *m;
1035
1036         /**
1037          * Increment message tag before queue check, so that responses to old
1038          * requests are discarded.
1039          */
1040         fcport->msgtag++;
1041
1042         /**
1043          * check for room in queue to send request now
1044          */
1045         m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1046         if (!m) {
1047                 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1048                                                         &fcport->reqq_wait);
1049                 return BFA_FALSE;
1050         }
1051
1052         bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
1053                         bfa_lpuid(fcport->bfa));
1054         m->msgtag = fcport->msgtag;
1055
1056         /**
1057          * queue I/O message to firmware
1058          */
1059         bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1060
1061         return BFA_TRUE;
1062 }
1063
1064 static void
1065 bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
1066 {
1067         fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
1068         fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
1069
1070         bfa_trc(fcport->bfa, fcport->pwwn);
1071         bfa_trc(fcport->bfa, fcport->nwwn);
1072 }
1073
1074 static void
1075 bfa_fcport_send_txcredit(void *port_cbarg)
1076 {
1077
1078         struct bfa_fcport_s *fcport = port_cbarg;
1079         struct bfi_fcport_set_svc_params_req_s *m;
1080
1081         /**
1082          * check for room in queue to send request now
1083          */
1084         m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1085         if (!m) {
1086                 bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
1087                 return;
1088         }
1089
1090         bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
1091                         bfa_lpuid(fcport->bfa));
1092         m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
1093
1094         /**
1095          * queue I/O message to firmware
1096          */
1097         bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1098 }
1099
1100 static void
1101 bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
1102         struct bfa_qos_stats_s *s)
1103 {
1104         u32     *dip = (u32 *) d;
1105         u32     *sip = (u32 *) s;
1106         int             i;
1107
1108         /* Now swap the 32 bit fields */
1109         for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
1110                 dip[i] = bfa_os_ntohl(sip[i]);
1111 }
1112
1113 static void
1114 bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
1115         struct bfa_fcoe_stats_s *s)
1116 {
1117         u32     *dip = (u32 *) d;
1118         u32     *sip = (u32 *) s;
1119         int             i;
1120
1121         for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
1122                 i = i + 2) {
1123 #ifdef __BIGENDIAN
1124                 dip[i] = bfa_os_ntohl(sip[i]);
1125                 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1126 #else
1127                 dip[i] = bfa_os_ntohl(sip[i + 1]);
1128                 dip[i + 1] = bfa_os_ntohl(sip[i]);
1129 #endif
1130         }
1131 }
1132
1133 static void
1134 __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
1135 {
1136         struct bfa_fcport_s *fcport = cbarg;
1137
1138         if (complete) {
1139                 if (fcport->stats_status == BFA_STATUS_OK) {
1140                         struct bfa_timeval_s tv;
1141
1142                         /* Swap FC QoS or FCoE stats */
1143                         if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
1144                                 bfa_fcport_qos_stats_swap(
1145                                         &fcport->stats_ret->fcqos,
1146                                         &fcport->stats->fcqos);
1147                         } else {
1148                                 bfa_fcport_fcoe_stats_swap(
1149                                         &fcport->stats_ret->fcoe,
1150                                         &fcport->stats->fcoe);
1151
1152                                 bfa_os_gettimeofday(&tv);
1153                                 fcport->stats_ret->fcoe.secs_reset =
1154                                         tv.tv_sec - fcport->stats_reset_time;
1155                         }
1156                 }
1157                 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1158         } else {
1159                 fcport->stats_busy = BFA_FALSE;
1160                 fcport->stats_status = BFA_STATUS_OK;
1161         }
1162 }
1163
1164 static void
1165 bfa_fcport_stats_get_timeout(void *cbarg)
1166 {
1167         struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1168
1169         bfa_trc(fcport->bfa, fcport->stats_qfull);
1170
1171         if (fcport->stats_qfull) {
1172                 bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1173                 fcport->stats_qfull = BFA_FALSE;
1174         }
1175
1176         fcport->stats_status = BFA_STATUS_ETIMER;
1177         bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
1178                 fcport);
1179 }
1180
1181 static void
1182 bfa_fcport_send_stats_get(void *cbarg)
1183 {
1184         struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1185         struct bfi_fcport_req_s *msg;
1186
1187         msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1188
1189         if (!msg) {
1190                 fcport->stats_qfull = BFA_TRUE;
1191                 bfa_reqq_winit(&fcport->stats_reqq_wait,
1192                                 bfa_fcport_send_stats_get, fcport);
1193                 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1194                                 &fcport->stats_reqq_wait);
1195                 return;
1196         }
1197         fcport->stats_qfull = BFA_FALSE;
1198
1199         bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1200         bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
1201                 bfa_lpuid(fcport->bfa));
1202         bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1203 }
1204
1205 static void
1206 __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
1207 {
1208         struct bfa_fcport_s *fcport = cbarg;
1209
1210         if (complete) {
1211                 struct bfa_timeval_s tv;
1212
1213                 /**
1214                  * re-initialize time stamp for stats reset
1215                  */
1216                 bfa_os_gettimeofday(&tv);
1217                 fcport->stats_reset_time = tv.tv_sec;
1218
1219                 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1220         } else {
1221                 fcport->stats_busy = BFA_FALSE;
1222                 fcport->stats_status = BFA_STATUS_OK;
1223         }
1224 }
1225
1226 static void
1227 bfa_fcport_stats_clr_timeout(void *cbarg)
1228 {
1229         struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1230
1231         bfa_trc(fcport->bfa, fcport->stats_qfull);
1232
1233         if (fcport->stats_qfull) {
1234                 bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1235                 fcport->stats_qfull = BFA_FALSE;
1236         }
1237
1238         fcport->stats_status = BFA_STATUS_ETIMER;
1239         bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1240                         __bfa_cb_fcport_stats_clr, fcport);
1241 }
1242
1243 static void
1244 bfa_fcport_send_stats_clear(void *cbarg)
1245 {
1246         struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1247         struct bfi_fcport_req_s *msg;
1248
1249         msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1250
1251         if (!msg) {
1252                 fcport->stats_qfull = BFA_TRUE;
1253                 bfa_reqq_winit(&fcport->stats_reqq_wait,
1254                                 bfa_fcport_send_stats_clear, fcport);
1255                 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1256                                 &fcport->stats_reqq_wait);
1257                 return;
1258         }
1259         fcport->stats_qfull = BFA_FALSE;
1260
1261         bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1262         bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
1263                         bfa_lpuid(fcport->bfa));
1264         bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1265 }
1266
1267 /**
1268  *  bfa_pport_public
1269  */
1270
1271 /**
1272  * Called to initialize port attributes
1273  */
1274 void
1275 bfa_fcport_init(struct bfa_s *bfa)
1276 {
1277         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1278
1279         /**
1280          * Initialize port attributes from IOC hardware data.
1281          */
1282         bfa_fcport_set_wwns(fcport);
1283         if (fcport->cfg.maxfrsize == 0)
1284                 fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
1285         fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
1286         fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
1287
1288         bfa_assert(fcport->cfg.maxfrsize);
1289         bfa_assert(fcport->cfg.rx_bbcredit);
1290         bfa_assert(fcport->speed_sup);
1291 }
1292
1293
1294 /**
1295  * Firmware message handler.
1296  */
1297 void
1298 bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
1299 {
1300         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1301         union bfi_fcport_i2h_msg_u i2hmsg;
1302
1303         i2hmsg.msg = msg;
1304         fcport->event_arg.i2hmsg = i2hmsg;
1305
1306         switch (msg->mhdr.msg_id) {
1307         case BFI_FCPORT_I2H_ENABLE_RSP:
1308                 if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
1309                         bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
1310                 break;
1311
1312         case BFI_FCPORT_I2H_DISABLE_RSP:
1313                 if (fcport->msgtag == i2hmsg.pdisable_rsp->msgtag)
1314                         bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
1315                 break;
1316
1317         case BFI_FCPORT_I2H_EVENT:
1318                 switch (i2hmsg.event->link_state.linkstate) {
1319                 case BFA_PPORT_LINKUP:
1320                         bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
1321                         break;
1322                 case BFA_PPORT_LINKDOWN:
1323                         bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
1324                         break;
1325                 case BFA_PPORT_TRUNK_LINKDOWN:
1326                         /** todo: event notification */
1327                         break;
1328                 }
1329                 break;
1330
1331         case BFI_FCPORT_I2H_STATS_GET_RSP:
1332                 /*
1333                  * check for timer pop before processing the rsp
1334                  */
1335                 if (fcport->stats_busy == BFA_FALSE ||
1336                         fcport->stats_status == BFA_STATUS_ETIMER)
1337                         break;
1338
1339                 bfa_timer_stop(&fcport->timer);
1340                 fcport->stats_status = i2hmsg.pstatsget_rsp->status;
1341                 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1342                                 __bfa_cb_fcport_stats_get, fcport);
1343                 break;
1344
1345         case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
1346                 /*
1347                  * check for timer pop before processing the rsp
1348                  */
1349                 if (fcport->stats_busy == BFA_FALSE ||
1350                         fcport->stats_status == BFA_STATUS_ETIMER)
1351                         break;
1352
1353                 bfa_timer_stop(&fcport->timer);
1354                 fcport->stats_status = BFA_STATUS_OK;
1355                 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1356                                 __bfa_cb_fcport_stats_clr, fcport);
1357                 break;
1358
1359         default:
1360                 bfa_assert(0);
1361         break;
1362         }
1363 }
1364
1365 /**
1366  *  bfa_pport_api
1367  */
1368
1369 /**
1370  * Registered callback for port events.
1371  */
1372 void
1373 bfa_fcport_event_register(struct bfa_s *bfa,
1374                          void (*cbfn) (void *cbarg, bfa_pport_event_t event),
1375                          void *cbarg)
1376 {
1377         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1378
1379         fcport->event_cbfn = cbfn;
1380         fcport->event_cbarg = cbarg;
1381 }
1382
1383 bfa_status_t
1384 bfa_fcport_enable(struct bfa_s *bfa)
1385 {
1386         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1387         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1388         struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1389
1390         /* if port is PBC disabled, return error */
1391         if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
1392                 bfa_trc(bfa, fcport->pwwn);
1393                 return BFA_STATUS_PBC;
1394         }
1395
1396         if (bfa_ioc_is_disabled(&bfa->ioc))
1397                 return BFA_STATUS_IOC_DISABLED;
1398
1399         if (fcport->diag_busy)
1400                 return BFA_STATUS_DIAG_BUSY;
1401         else if (bfa_sm_cmp_state
1402                  (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
1403                 return BFA_STATUS_DEVBUSY;
1404
1405         bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
1406         return BFA_STATUS_OK;
1407 }
1408
1409 bfa_status_t
1410 bfa_fcport_disable(struct bfa_s *bfa)
1411 {
1412         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1413         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1414         struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1415
1416         /* if port is PBC disabled, return error */
1417         if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
1418                 bfa_trc(bfa, fcport->pwwn);
1419                 return BFA_STATUS_PBC;
1420         }
1421
1422         bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
1423         return BFA_STATUS_OK;
1424 }
1425
1426 /**
1427  * Configure port speed.
1428  */
1429 bfa_status_t
1430 bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1431 {
1432         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1433
1434         bfa_trc(bfa, speed);
1435
1436         if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
1437                 bfa_trc(bfa, fcport->speed_sup);
1438                 return BFA_STATUS_UNSUPP_SPEED;
1439         }
1440
1441         fcport->cfg.speed = speed;
1442
1443         return BFA_STATUS_OK;
1444 }
1445
1446 /**
1447  * Get current speed.
1448  */
1449 enum bfa_pport_speed
1450 bfa_fcport_get_speed(struct bfa_s *bfa)
1451 {
1452         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1453
1454         return fcport->speed;
1455 }
1456
1457 /**
1458  * Configure port topology.
1459  */
1460 bfa_status_t
1461 bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1462 {
1463         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1464
1465         bfa_trc(bfa, topology);
1466         bfa_trc(bfa, fcport->cfg.topology);
1467
1468         switch (topology) {
1469         case BFA_PPORT_TOPOLOGY_P2P:
1470         case BFA_PPORT_TOPOLOGY_LOOP:
1471         case BFA_PPORT_TOPOLOGY_AUTO:
1472                 break;
1473
1474         default:
1475                 return BFA_STATUS_EINVAL;
1476         }
1477
1478         fcport->cfg.topology = topology;
1479         return BFA_STATUS_OK;
1480 }
1481
1482 /**
1483  * Get current topology.
1484  */
1485 enum bfa_pport_topology
1486 bfa_fcport_get_topology(struct bfa_s *bfa)
1487 {
1488         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1489
1490         return fcport->topology;
1491 }
1492
1493 bfa_status_t
1494 bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1495 {
1496         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1497
1498         bfa_trc(bfa, alpa);
1499         bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1500         bfa_trc(bfa, fcport->cfg.hardalpa);
1501
1502         fcport->cfg.cfg_hardalpa = BFA_TRUE;
1503         fcport->cfg.hardalpa = alpa;
1504
1505         return BFA_STATUS_OK;
1506 }
1507
1508 bfa_status_t
1509 bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
1510 {
1511         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1512
1513         bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1514         bfa_trc(bfa, fcport->cfg.hardalpa);
1515
1516         fcport->cfg.cfg_hardalpa = BFA_FALSE;
1517         return BFA_STATUS_OK;
1518 }
1519
1520 bfa_boolean_t
1521 bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1522 {
1523         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1524
1525         *alpa = fcport->cfg.hardalpa;
1526         return fcport->cfg.cfg_hardalpa;
1527 }
1528
1529 u8
1530 bfa_fcport_get_myalpa(struct bfa_s *bfa)
1531 {
1532         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1533
1534         return fcport->myalpa;
1535 }
1536
1537 bfa_status_t
1538 bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1539 {
1540         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1541
1542         bfa_trc(bfa, maxfrsize);
1543         bfa_trc(bfa, fcport->cfg.maxfrsize);
1544
1545         /*
1546          * with in range
1547          */
1548         if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
1549                 return BFA_STATUS_INVLD_DFSZ;
1550
1551         /*
1552          * power of 2, if not the max frame size of 2112
1553          */
1554         if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1555                 return BFA_STATUS_INVLD_DFSZ;
1556
1557         fcport->cfg.maxfrsize = maxfrsize;
1558         return BFA_STATUS_OK;
1559 }
1560
1561 u16
1562 bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
1563 {
1564         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1565
1566         return fcport->cfg.maxfrsize;
1567 }
1568
1569 u32
1570 bfa_fcport_mypid(struct bfa_s *bfa)
1571 {
1572         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1573
1574         return fcport->mypid;
1575 }
1576
1577 u8
1578 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
1579 {
1580         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1581
1582         return fcport->cfg.rx_bbcredit;
1583 }
1584
1585 void
1586 bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1587 {
1588         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1589
1590         fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
1591         bfa_fcport_send_txcredit(fcport);
1592 }
1593
1594 /**
1595  * Get port attributes.
1596  */
1597
1598 wwn_t
1599 bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1600 {
1601         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1602         if (node)
1603                 return fcport->nwwn;
1604         else
1605                 return fcport->pwwn;
1606 }
1607
1608 void
1609 bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1610 {
1611         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1612         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1613         struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1614
1615         bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1616
1617         attr->nwwn = fcport->nwwn;
1618         attr->pwwn = fcport->pwwn;
1619
1620         attr->factorypwwn =  bfa_ioc_get_mfg_pwwn(&bfa->ioc);
1621         attr->factorynwwn =  bfa_ioc_get_mfg_nwwn(&bfa->ioc);
1622
1623         bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
1624                       sizeof(struct bfa_pport_cfg_s));
1625         /*
1626          * speed attributes
1627          */
1628         attr->pport_cfg.speed = fcport->cfg.speed;
1629         attr->speed_supported = fcport->speed_sup;
1630         attr->speed = fcport->speed;
1631         attr->cos_supported = FC_CLASS_3;
1632
1633         /*
1634          * topology attributes
1635          */
1636         attr->pport_cfg.topology = fcport->cfg.topology;
1637         attr->topology = fcport->topology;
1638
1639         /*
1640          * beacon attributes
1641          */
1642         attr->beacon = fcport->beacon;
1643         attr->link_e2e_beacon = fcport->link_e2e_beacon;
1644         attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
1645
1646         attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1647         attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1648
1649         /* PBC Disabled State */
1650         if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED)
1651                 attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED;
1652         else {
1653                 attr->port_state = bfa_sm_to_state(
1654                                 hal_pport_sm_table, fcport->sm);
1655                 if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
1656                         attr->port_state = BFA_PPORT_ST_IOCDIS;
1657                 else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
1658                         attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1659         }
1660 }
1661
1662 #define BFA_FCPORT_STATS_TOV    1000
1663
1664 /**
1665  * Fetch port attributes (FCQoS or FCoE).
1666  */
1667 bfa_status_t
1668 bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1669                     bfa_cb_pport_t cbfn, void *cbarg)
1670 {
1671         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1672
1673         if (fcport->stats_busy) {
1674                 bfa_trc(bfa, fcport->stats_busy);
1675                 return BFA_STATUS_DEVBUSY;
1676         }
1677
1678         fcport->stats_busy  = BFA_TRUE;
1679         fcport->stats_ret   = stats;
1680         fcport->stats_cbfn  = cbfn;
1681         fcport->stats_cbarg = cbarg;
1682
1683         bfa_fcport_send_stats_get(fcport);
1684
1685         bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
1686                 fcport, BFA_FCPORT_STATS_TOV);
1687         return BFA_STATUS_OK;
1688 }
1689
1690 /**
1691  * Reset port statistics (FCQoS or FCoE).
1692  */
1693 bfa_status_t
1694 bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1695 {
1696         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1697
1698         if (fcport->stats_busy) {
1699                 bfa_trc(bfa, fcport->stats_busy);
1700                 return BFA_STATUS_DEVBUSY;
1701         }
1702
1703         fcport->stats_busy = BFA_TRUE;
1704         fcport->stats_cbfn = cbfn;
1705         fcport->stats_cbarg = cbarg;
1706
1707         bfa_fcport_send_stats_clear(fcport);
1708
1709         bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
1710                         fcport, BFA_FCPORT_STATS_TOV);
1711         return BFA_STATUS_OK;
1712 }
1713
1714 /**
1715  * Fetch FCQoS port statistics
1716  */
1717 bfa_status_t
1718 bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1719         bfa_cb_pport_t cbfn, void *cbarg)
1720 {
1721         /* Meaningful only for FC mode */
1722         bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1723
1724         return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1725 }
1726
1727 /**
1728  * Reset FCoE port statistics
1729  */
1730 bfa_status_t
1731 bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1732 {
1733         /* Meaningful only for FC mode */
1734         bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1735
1736         return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1737 }
1738
1739 /**
1740  * Fetch FCQoS port statistics
1741  */
1742 bfa_status_t
1743 bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1744         bfa_cb_pport_t cbfn, void *cbarg)
1745 {
1746         /* Meaningful only for FCoE mode */
1747         bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1748
1749         return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1750 }
1751
1752 /**
1753  * Reset FCoE port statistics
1754  */
1755 bfa_status_t
1756 bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1757 {
1758         /* Meaningful only for FCoE mode */
1759         bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1760
1761         return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1762 }
1763
1764 bfa_status_t
1765 bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1766 {
1767         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1768
1769         bfa_trc(bfa, bitmap);
1770         bfa_trc(bfa, fcport->cfg.trunked);
1771         bfa_trc(bfa, fcport->cfg.trunk_ports);
1772
1773         if (!bitmap || (bitmap & (bitmap - 1)))
1774                 return BFA_STATUS_EINVAL;
1775
1776         fcport->cfg.trunked = BFA_TRUE;
1777         fcport->cfg.trunk_ports = bitmap;
1778
1779         return BFA_STATUS_OK;
1780 }
1781
1782 void
1783 bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1784 {
1785         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1786
1787         qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
1788         qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
1789 }
1790
1791 void
1792 bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
1793                           struct bfa_qos_vc_attr_s *qos_vc_attr)
1794 {
1795         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1796         struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
1797         u32        i = 0;
1798
1799         qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
1800         qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
1801         qos_vc_attr->elp_opmode_flags =
1802                 bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
1803
1804         /*
1805          * Individual VC info
1806          */
1807         while (i < qos_vc_attr->total_vc_count) {
1808                 qos_vc_attr->vc_info[i].vc_credit =
1809                         bfa_vc_attr->vc_info[i].vc_credit;
1810                 qos_vc_attr->vc_info[i].borrow_credit =
1811                         bfa_vc_attr->vc_info[i].borrow_credit;
1812                 qos_vc_attr->vc_info[i].priority =
1813                         bfa_vc_attr->vc_info[i].priority;
1814                 ++i;
1815         }
1816 }
1817
1818 /**
1819  * Fetch port attributes.
1820  */
1821 bfa_status_t
1822 bfa_fcport_trunk_disable(struct bfa_s *bfa)
1823 {
1824         return BFA_STATUS_OK;
1825 }
1826
1827 bfa_boolean_t
1828 bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1829 {
1830         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1831
1832         *bitmap = fcport->cfg.trunk_ports;
1833         return fcport->cfg.trunked;
1834 }
1835
1836 bfa_boolean_t
1837 bfa_fcport_is_disabled(struct bfa_s *bfa)
1838 {
1839         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1840
1841         return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
1842                 BFA_PPORT_ST_DISABLED;
1843
1844 }
1845
1846 bfa_boolean_t
1847 bfa_fcport_is_ratelim(struct bfa_s *bfa)
1848 {
1849         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1850
1851         return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
1852
1853 }
1854
1855 void
1856 bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1857 {
1858         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1859         enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
1860
1861         bfa_trc(bfa, on_off);
1862         bfa_trc(bfa, fcport->cfg.qos_enabled);
1863
1864         bfa_trc(bfa, ioc_type);
1865
1866         if (ioc_type == BFA_IOC_TYPE_FC) {
1867                 fcport->cfg.qos_enabled = on_off;
1868                 /**
1869                  * Notify fcpim of the change in QoS state
1870                  */
1871                 bfa_fcpim_update_ioredirect(bfa);
1872         }
1873 }
1874
1875 void
1876 bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1877 {
1878         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1879
1880         bfa_trc(bfa, on_off);
1881         bfa_trc(bfa, fcport->cfg.ratelimit);
1882
1883         fcport->cfg.ratelimit = on_off;
1884         if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1885                 fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1886 }
1887
1888 /**
1889  * Configure default minimum ratelim speed
1890  */
1891 bfa_status_t
1892 bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1893 {
1894         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1895
1896         bfa_trc(bfa, speed);
1897
1898         /*
1899          * Auto and speeds greater than the supported speed, are invalid
1900          */
1901         if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
1902                 bfa_trc(bfa, fcport->speed_sup);
1903                 return BFA_STATUS_UNSUPP_SPEED;
1904         }
1905
1906         fcport->cfg.trl_def_speed = speed;
1907
1908         return BFA_STATUS_OK;
1909 }
1910
1911 /**
1912  * Get default minimum ratelim speed
1913  */
1914 enum bfa_pport_speed
1915 bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
1916 {
1917         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1918
1919         bfa_trc(bfa, fcport->cfg.trl_def_speed);
1920         return fcport->cfg.trl_def_speed;
1921
1922 }
1923
1924 void
1925 bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1926 {
1927         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1928
1929         bfa_trc(bfa, status);
1930         bfa_trc(bfa, fcport->diag_busy);
1931
1932         fcport->diag_busy = status;
1933 }
1934
1935 void
1936 bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1937                  bfa_boolean_t link_e2e_beacon)
1938 {
1939         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1940
1941         bfa_trc(bfa, beacon);
1942         bfa_trc(bfa, link_e2e_beacon);
1943         bfa_trc(bfa, fcport->beacon);
1944         bfa_trc(bfa, fcport->link_e2e_beacon);
1945
1946         fcport->beacon = beacon;
1947         fcport->link_e2e_beacon = link_e2e_beacon;
1948 }
1949
1950 bfa_boolean_t
1951 bfa_fcport_is_linkup(struct bfa_s *bfa)
1952 {
1953         return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
1954 }
1955
1956 bfa_boolean_t
1957 bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
1958 {
1959         struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1960
1961         return fcport->cfg.qos_enabled;
1962 }