2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
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
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.
20 #include "bfa_fcbuild.h"
23 BFA_TRC_FILE(FCS
, PORT
);
25 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s
*port
,
26 struct fchs_s
*rx_fchs
, u8 reason_code
,
28 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s
*port
,
29 struct fchs_s
*rx_fchs
, struct fc_logi_s
*plogi
);
30 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s
*port
);
31 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s
*port
);
32 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s
*port
);
33 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s
*port
);
34 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s
*port
);
35 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s
*port
);
36 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s
*port
,
37 struct fchs_s
*rx_fchs
,
38 struct fc_echo_s
*echo
, u16 len
);
39 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s
*port
,
40 struct fchs_s
*rx_fchs
,
41 struct fc_rnid_cmd_s
*rnid
, u16 len
);
42 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s
*port
,
43 struct fc_rnid_general_topology_data_s
*gen_topo_data
);
45 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s
*port
);
46 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s
*port
);
47 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s
*port
);
49 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s
*port
);
50 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s
*port
);
51 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s
*port
);
54 void (*init
) (struct bfa_fcs_lport_s
*port
);
55 void (*online
) (struct bfa_fcs_lport_s
*port
);
56 void (*offline
) (struct bfa_fcs_lport_s
*port
);
59 bfa_fcs_lport_unknown_init
, bfa_fcs_lport_unknown_online
,
60 bfa_fcs_lport_unknown_offline
}, {
61 bfa_fcs_lport_fab_init
, bfa_fcs_lport_fab_online
,
62 bfa_fcs_lport_fab_offline
}, {
63 bfa_fcs_lport_n2n_init
, bfa_fcs_lport_n2n_online
,
64 bfa_fcs_lport_n2n_offline
},
68 * fcs_port_sm FCS logical port state machine
71 enum bfa_fcs_lport_event
{
72 BFA_FCS_PORT_SM_CREATE
= 1,
73 BFA_FCS_PORT_SM_ONLINE
= 2,
74 BFA_FCS_PORT_SM_OFFLINE
= 3,
75 BFA_FCS_PORT_SM_DELETE
= 4,
76 BFA_FCS_PORT_SM_DELRPORT
= 5,
79 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s
*port
,
80 enum bfa_fcs_lport_event event
);
81 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s
*port
,
82 enum bfa_fcs_lport_event event
);
83 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s
*port
,
84 enum bfa_fcs_lport_event event
);
85 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s
*port
,
86 enum bfa_fcs_lport_event event
);
87 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s
*port
,
88 enum bfa_fcs_lport_event event
);
91 bfa_fcs_lport_sm_uninit(
92 struct bfa_fcs_lport_s
*port
,
93 enum bfa_fcs_lport_event event
)
95 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
96 bfa_trc(port
->fcs
, event
);
99 case BFA_FCS_PORT_SM_CREATE
:
100 bfa_sm_set_state(port
, bfa_fcs_lport_sm_init
);
104 bfa_sm_fault(port
->fcs
, event
);
109 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s
*port
,
110 enum bfa_fcs_lport_event event
)
112 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
113 bfa_trc(port
->fcs
, event
);
116 case BFA_FCS_PORT_SM_ONLINE
:
117 bfa_sm_set_state(port
, bfa_fcs_lport_sm_online
);
118 bfa_fcs_lport_online_actions(port
);
121 case BFA_FCS_PORT_SM_DELETE
:
122 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
123 bfa_fcs_lport_deleted(port
);
126 case BFA_FCS_PORT_SM_OFFLINE
:
130 bfa_sm_fault(port
->fcs
, event
);
135 bfa_fcs_lport_sm_online(
136 struct bfa_fcs_lport_s
*port
,
137 enum bfa_fcs_lport_event event
)
139 struct bfa_fcs_rport_s
*rport
;
140 struct list_head
*qe
, *qen
;
142 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
143 bfa_trc(port
->fcs
, event
);
146 case BFA_FCS_PORT_SM_OFFLINE
:
147 bfa_sm_set_state(port
, bfa_fcs_lport_sm_offline
);
148 bfa_fcs_lport_offline_actions(port
);
151 case BFA_FCS_PORT_SM_DELETE
:
153 __port_action
[port
->fabric
->fab_type
].offline(port
);
155 if (port
->num_rports
== 0) {
156 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
157 bfa_fcs_lport_deleted(port
);
159 bfa_sm_set_state(port
, bfa_fcs_lport_sm_deleting
);
160 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
161 rport
= (struct bfa_fcs_rport_s
*) qe
;
162 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
167 case BFA_FCS_PORT_SM_DELRPORT
:
171 bfa_sm_fault(port
->fcs
, event
);
176 bfa_fcs_lport_sm_offline(
177 struct bfa_fcs_lport_s
*port
,
178 enum bfa_fcs_lport_event event
)
180 struct bfa_fcs_rport_s
*rport
;
181 struct list_head
*qe
, *qen
;
183 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
184 bfa_trc(port
->fcs
, event
);
187 case BFA_FCS_PORT_SM_ONLINE
:
188 bfa_sm_set_state(port
, bfa_fcs_lport_sm_online
);
189 bfa_fcs_lport_online_actions(port
);
192 case BFA_FCS_PORT_SM_DELETE
:
193 if (port
->num_rports
== 0) {
194 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
195 bfa_fcs_lport_deleted(port
);
197 bfa_sm_set_state(port
, bfa_fcs_lport_sm_deleting
);
198 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
199 rport
= (struct bfa_fcs_rport_s
*) qe
;
200 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
205 case BFA_FCS_PORT_SM_DELRPORT
:
206 case BFA_FCS_PORT_SM_OFFLINE
:
210 bfa_sm_fault(port
->fcs
, event
);
215 bfa_fcs_lport_sm_deleting(
216 struct bfa_fcs_lport_s
*port
,
217 enum bfa_fcs_lport_event event
)
219 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
220 bfa_trc(port
->fcs
, event
);
223 case BFA_FCS_PORT_SM_DELRPORT
:
224 if (port
->num_rports
== 0) {
225 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
226 bfa_fcs_lport_deleted(port
);
231 bfa_sm_fault(port
->fcs
, event
);
243 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
244 u8 reason_code
, u8 reason_code_expl
)
247 struct bfa_fcxp_s
*fcxp
;
248 struct bfa_rport_s
*bfa_rport
= NULL
;
251 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
252 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
254 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
258 len
= fc_ls_rjt_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
259 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
260 rx_fchs
->ox_id
, reason_code
, reason_code_expl
);
262 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
263 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
268 * Process incoming plogi from a remote port.
271 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s
*port
,
272 struct fchs_s
*rx_fchs
, struct fc_logi_s
*plogi
)
274 struct bfa_fcs_rport_s
*rport
;
276 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
277 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
280 * If min cfg mode is enabled, drop any incoming PLOGIs
282 if (__fcs_min_cfg(port
->fcs
)) {
283 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
287 if (fc_plogi_parse(rx_fchs
) != FC_PARSE_OK
) {
288 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
292 bfa_fcs_lport_send_ls_rjt(port
, rx_fchs
,
293 FC_LS_RJT_RSN_PROTOCOL_ERROR
,
294 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS
);
299 * Direct Attach P2P mode : verify address assigned by the r-port.
301 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
302 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port
),
303 (void *)&plogi
->port_name
, sizeof(wwn_t
)) < 0)) {
304 if (BFA_FCS_PID_IS_WKA(rx_fchs
->d_id
)) {
305 /* Address assigned to us cannot be a WKA */
306 bfa_fcs_lport_send_ls_rjt(port
, rx_fchs
,
307 FC_LS_RJT_RSN_PROTOCOL_ERROR
,
308 FC_LS_RJT_EXP_INVALID_NPORT_ID
);
311 port
->pid
= rx_fchs
->d_id
;
312 bfa_lps_set_n2n_pid(port
->fabric
->lps
, rx_fchs
->d_id
);
316 * First, check if we know the device by pwwn.
318 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
, plogi
->port_name
);
321 * Direct Attach P2P mode : handle address assigned by r-port.
323 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
324 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port
),
325 (void *)&plogi
->port_name
, sizeof(wwn_t
)) < 0)) {
326 port
->pid
= rx_fchs
->d_id
;
327 bfa_lps_set_n2n_pid(port
->fabric
->lps
, rx_fchs
->d_id
);
328 rport
->pid
= rx_fchs
->s_id
;
330 bfa_fcs_rport_plogi(rport
, rx_fchs
, plogi
);
335 * Next, lookup rport by PID.
337 rport
= bfa_fcs_lport_get_rport_by_pid(port
, rx_fchs
->s_id
);
340 * Inbound PLOGI from a new device.
342 bfa_fcs_rport_plogi_create(port
, rx_fchs
, plogi
);
347 * Rport is known only by PID.
351 * This is a different device with the same pid. Old device
352 * disappeared. Send implicit LOGO to old device.
354 WARN_ON(rport
->pwwn
== plogi
->port_name
);
355 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_IMP
);
358 * Inbound PLOGI from a new device (with old PID).
360 bfa_fcs_rport_plogi_create(port
, rx_fchs
, plogi
);
365 * PLOGI crossing each other.
367 WARN_ON(rport
->pwwn
!= WWN_NULL
);
368 bfa_fcs_rport_plogi(rport
, rx_fchs
, plogi
);
372 * Process incoming ECHO.
373 * Since it does not require a login, it is processed here.
376 bfa_fcs_lport_echo(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
377 struct fc_echo_s
*echo
, u16 rx_len
)
380 struct bfa_fcxp_s
*fcxp
;
381 struct bfa_rport_s
*bfa_rport
= NULL
;
384 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
385 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
387 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
391 len
= fc_ls_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
392 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
396 * Copy the payload (if any) from the echo frame
398 pyld_len
= rx_len
- sizeof(struct fchs_s
);
399 bfa_trc(port
->fcs
, rx_len
);
400 bfa_trc(port
->fcs
, pyld_len
);
403 memcpy(((u8
*) bfa_fcxp_get_reqbuf(fcxp
)) +
404 sizeof(struct fc_echo_s
), (echo
+ 1),
405 (pyld_len
- sizeof(struct fc_echo_s
)));
407 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
408 BFA_FALSE
, FC_CLASS_3
, pyld_len
, &fchs
, NULL
, NULL
,
413 * Process incoming RNID.
414 * Since it does not require a login, it is processed here.
417 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
418 struct fc_rnid_cmd_s
*rnid
, u16 rx_len
)
420 struct fc_rnid_common_id_data_s common_id_data
;
421 struct fc_rnid_general_topology_data_s gen_topo_data
;
423 struct bfa_fcxp_s
*fcxp
;
424 struct bfa_rport_s
*bfa_rport
= NULL
;
428 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
429 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
430 bfa_trc(port
->fcs
, rx_len
);
432 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
437 * Check Node Indentification Data Format
438 * We only support General Topology Discovery Format.
439 * For any other requested Data Formats, we return Common Node Id Data
440 * only, as per FC-LS.
442 bfa_trc(port
->fcs
, rnid
->node_id_data_format
);
443 if (rnid
->node_id_data_format
== RNID_NODEID_DATA_FORMAT_DISCOVERY
) {
444 data_format
= RNID_NODEID_DATA_FORMAT_DISCOVERY
;
446 * Get General topology data for this port
448 bfa_fs_port_get_gen_topo_data(port
, &gen_topo_data
);
450 data_format
= RNID_NODEID_DATA_FORMAT_COMMON
;
454 * Copy the Node Id Info
456 common_id_data
.port_name
= bfa_fcs_lport_get_pwwn(port
);
457 common_id_data
.node_name
= bfa_fcs_lport_get_nwwn(port
);
459 len
= fc_rnid_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
460 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
461 rx_fchs
->ox_id
, data_format
, &common_id_data
,
464 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
465 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
470 * Fill out General Topolpgy Discovery Data for RNID ELS.
473 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s
*port
,
474 struct fc_rnid_general_topology_data_s
*gen_topo_data
)
476 memset(gen_topo_data
, 0,
477 sizeof(struct fc_rnid_general_topology_data_s
));
479 gen_topo_data
->asso_type
= cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST
);
480 gen_topo_data
->phy_port_num
= 0; /* @todo */
481 gen_topo_data
->num_attached_nodes
= cpu_to_be32(1);
485 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s
*port
)
487 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
488 char lpwwn_buf
[BFA_STRING_32
];
490 bfa_trc(port
->fcs
, port
->fabric
->oper_type
);
492 __port_action
[port
->fabric
->fab_type
].init(port
);
493 __port_action
[port
->fabric
->fab_type
].online(port
);
495 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
496 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
497 "Logical port online: WWN = %s Role = %s\n",
498 lpwwn_buf
, "Initiator");
500 bfad
->bfad_flags
|= BFAD_PORT_ONLINE
;
504 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s
*port
)
506 struct list_head
*qe
, *qen
;
507 struct bfa_fcs_rport_s
*rport
;
508 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
509 char lpwwn_buf
[BFA_STRING_32
];
511 bfa_trc(port
->fcs
, port
->fabric
->oper_type
);
513 __port_action
[port
->fabric
->fab_type
].offline(port
);
515 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
516 if (bfa_sm_cmp_state(port
->fabric
,
517 bfa_fcs_fabric_sm_online
) == BFA_TRUE
)
518 BFA_LOG(KERN_ERR
, bfad
, bfa_log_level
,
519 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
520 lpwwn_buf
, "Initiator");
522 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
523 "Logical port taken offline: WWN = %s Role = %s\n",
524 lpwwn_buf
, "Initiator");
526 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
527 rport
= (struct bfa_fcs_rport_s
*) qe
;
528 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_IMP
);
533 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s
*port
)
539 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s
*port
)
545 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s
*port
)
551 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
)
554 struct bfa_fcxp_s
*fcxp
;
557 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
558 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
560 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
564 len
= fc_ba_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
565 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
568 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
569 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
573 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s
*port
)
575 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
576 char lpwwn_buf
[BFA_STRING_32
];
578 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
579 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
580 "Logical port deleted: WWN = %s Role = %s\n",
581 lpwwn_buf
, "Initiator");
583 /* Base port will be deleted by the OS driver */
585 bfa_fcb_lport_delete(port
->fcs
->bfad
, port
->port_cfg
.roles
,
586 port
->fabric
->vf_drv
,
587 port
->vport
? port
->vport
->vport_drv
: NULL
);
588 bfa_fcs_vport_delete_comp(port
->vport
);
590 bfa_wc_down(&port
->fabric
->wc
);
596 * Unsolicited frame receive handling.
599 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s
*lport
,
600 struct fchs_s
*fchs
, u16 len
)
602 u32 pid
= fchs
->s_id
;
603 struct bfa_fcs_rport_s
*rport
= NULL
;
604 struct fc_els_cmd_s
*els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
606 bfa_stats(lport
, uf_recvs
);
607 bfa_trc(lport
->fcs
, fchs
->type
);
609 if (!bfa_fcs_lport_is_online(lport
)) {
610 bfa_stats(lport
, uf_recv_drops
);
615 * First, handle ELSs that donot require a login.
620 if ((fchs
->type
== FC_TYPE_ELS
) &&
621 (els_cmd
->els_code
== FC_ELS_PLOGI
)) {
622 bfa_fcs_lport_plogi(lport
, fchs
, (struct fc_logi_s
*) els_cmd
);
627 * Handle ECHO separately.
629 if ((fchs
->type
== FC_TYPE_ELS
) && (els_cmd
->els_code
== FC_ELS_ECHO
)) {
630 bfa_fcs_lport_echo(lport
, fchs
,
631 (struct fc_echo_s
*)els_cmd
, len
);
636 * Handle RNID separately.
638 if ((fchs
->type
== FC_TYPE_ELS
) && (els_cmd
->els_code
== FC_ELS_RNID
)) {
639 bfa_fcs_lport_rnid(lport
, fchs
,
640 (struct fc_rnid_cmd_s
*) els_cmd
, len
);
644 if (fchs
->type
== FC_TYPE_BLS
) {
645 if ((fchs
->routing
== FC_RTG_BASIC_LINK
) &&
646 (fchs
->cat_info
== FC_CAT_ABTS
))
647 bfa_fcs_lport_abts_acc(lport
, fchs
);
651 * look for a matching remote port ID
653 rport
= bfa_fcs_lport_get_rport_by_pid(lport
, pid
);
655 bfa_trc(rport
->fcs
, fchs
->s_id
);
656 bfa_trc(rport
->fcs
, fchs
->d_id
);
657 bfa_trc(rport
->fcs
, fchs
->type
);
659 bfa_fcs_rport_uf_recv(rport
, fchs
, len
);
664 * Only handles ELS frames for now.
666 if (fchs
->type
!= FC_TYPE_ELS
) {
667 bfa_trc(lport
->fcs
, fchs
->s_id
);
668 bfa_trc(lport
->fcs
, fchs
->d_id
);
669 /* ignore type FC_TYPE_FC_FSS */
670 if (fchs
->type
!= FC_TYPE_FC_FSS
)
671 bfa_sm_fault(lport
->fcs
, fchs
->type
);
675 bfa_trc(lport
->fcs
, els_cmd
->els_code
);
676 if (els_cmd
->els_code
== FC_ELS_RSCN
) {
677 bfa_fcs_lport_scn_process_rscn(lport
, fchs
, len
);
681 if (els_cmd
->els_code
== FC_ELS_LOGO
) {
683 * @todo Handle LOGO frames received.
688 if (els_cmd
->els_code
== FC_ELS_PRLI
) {
690 * @todo Handle PRLI frames received.
696 * Unhandled ELS frames. Send a LS_RJT.
698 bfa_fcs_lport_send_ls_rjt(lport
, fchs
, FC_LS_RJT_RSN_CMD_NOT_SUPP
,
699 FC_LS_RJT_EXP_NO_ADDL_INFO
);
704 * PID based Lookup for a R-Port in the Port R-Port Queue
706 struct bfa_fcs_rport_s
*
707 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s
*port
, u32 pid
)
709 struct bfa_fcs_rport_s
*rport
;
710 struct list_head
*qe
;
712 list_for_each(qe
, &port
->rport_q
) {
713 rport
= (struct bfa_fcs_rport_s
*) qe
;
714 if (rport
->pid
== pid
)
718 bfa_trc(port
->fcs
, pid
);
723 * PWWN based Lookup for a R-Port in the Port R-Port Queue
725 struct bfa_fcs_rport_s
*
726 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s
*port
, wwn_t pwwn
)
728 struct bfa_fcs_rport_s
*rport
;
729 struct list_head
*qe
;
731 list_for_each(qe
, &port
->rport_q
) {
732 rport
= (struct bfa_fcs_rport_s
*) qe
;
733 if (wwn_is_equal(rport
->pwwn
, pwwn
))
737 bfa_trc(port
->fcs
, pwwn
);
742 * NWWN based Lookup for a R-Port in the Port R-Port Queue
744 struct bfa_fcs_rport_s
*
745 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s
*port
, wwn_t nwwn
)
747 struct bfa_fcs_rport_s
*rport
;
748 struct list_head
*qe
;
750 list_for_each(qe
, &port
->rport_q
) {
751 rport
= (struct bfa_fcs_rport_s
*) qe
;
752 if (wwn_is_equal(rport
->nwwn
, nwwn
))
756 bfa_trc(port
->fcs
, nwwn
);
761 * Called by rport module when new rports are discovered.
764 bfa_fcs_lport_add_rport(
765 struct bfa_fcs_lport_s
*port
,
766 struct bfa_fcs_rport_s
*rport
)
768 list_add_tail(&rport
->qe
, &port
->rport_q
);
773 * Called by rport module to when rports are deleted.
776 bfa_fcs_lport_del_rport(
777 struct bfa_fcs_lport_s
*port
,
778 struct bfa_fcs_rport_s
*rport
)
780 WARN_ON(!bfa_q_is_on_q(&port
->rport_q
, rport
));
781 list_del(&rport
->qe
);
784 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_DELRPORT
);
788 * Called by fabric for base port when fabric login is complete.
789 * Called by vport for virtual ports when FDISC is complete.
792 bfa_fcs_lport_online(struct bfa_fcs_lport_s
*port
)
794 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_ONLINE
);
798 * Called by fabric for base port when fabric goes offline.
799 * Called by vport for virtual ports when virtual port becomes offline.
802 bfa_fcs_lport_offline(struct bfa_fcs_lport_s
*port
)
804 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_OFFLINE
);
808 * Called by fabric to delete base lport and associated resources.
810 * Called by vport to delete lport and associated resources. Should call
811 * bfa_fcs_vport_delete_comp() for vports on completion.
814 bfa_fcs_lport_delete(struct bfa_fcs_lport_s
*port
)
816 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_DELETE
);
820 * Return TRUE if port is online, else return FALSE
823 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s
*port
)
825 return bfa_sm_cmp_state(port
, bfa_fcs_lport_sm_online
);
829 * Attach time initialization of logical ports.
832 bfa_fcs_lport_attach(struct bfa_fcs_lport_s
*lport
, struct bfa_fcs_s
*fcs
,
833 u16 vf_id
, struct bfa_fcs_vport_s
*vport
)
836 lport
->fabric
= bfa_fcs_vf_lookup(fcs
, vf_id
);
837 lport
->vport
= vport
;
838 lport
->lp_tag
= (vport
) ? vport
->lps
->lp_tag
:
839 lport
->fabric
->lps
->lp_tag
;
841 INIT_LIST_HEAD(&lport
->rport_q
);
842 lport
->num_rports
= 0;
846 * Logical port initialization of base or virtual port.
847 * Called by fabric for base port or by vport for virtual ports.
851 bfa_fcs_lport_init(struct bfa_fcs_lport_s
*lport
,
852 struct bfa_lport_cfg_s
*port_cfg
)
854 struct bfa_fcs_vport_s
*vport
= lport
->vport
;
855 struct bfad_s
*bfad
= (struct bfad_s
*)lport
->fcs
->bfad
;
856 char lpwwn_buf
[BFA_STRING_32
];
858 lport
->port_cfg
= *port_cfg
;
860 lport
->bfad_port
= bfa_fcb_lport_new(lport
->fcs
->bfad
, lport
,
861 lport
->port_cfg
.roles
,
862 lport
->fabric
->vf_drv
,
863 vport
? vport
->vport_drv
: NULL
);
865 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(lport
));
866 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
867 "New logical port created: WWN = %s Role = %s\n",
868 lpwwn_buf
, "Initiator");
870 bfa_sm_set_state(lport
, bfa_fcs_lport_sm_uninit
);
871 bfa_sm_send_event(lport
, BFA_FCS_PORT_SM_CREATE
);
879 bfa_fcs_lport_get_attr(
880 struct bfa_fcs_lport_s
*port
,
881 struct bfa_lport_attr_s
*port_attr
)
883 if (bfa_sm_cmp_state(port
, bfa_fcs_lport_sm_online
))
884 port_attr
->pid
= port
->pid
;
888 port_attr
->port_cfg
= port
->port_cfg
;
891 port_attr
->port_type
= port
->fabric
->oper_type
;
892 port_attr
->loopback
= bfa_sm_cmp_state(port
->fabric
,
893 bfa_fcs_fabric_sm_loopback
);
894 port_attr
->authfail
=
895 bfa_sm_cmp_state(port
->fabric
,
896 bfa_fcs_fabric_sm_auth_failed
);
897 port_attr
->fabric_name
= bfa_fcs_lport_get_fabric_name(port
);
898 memcpy(port_attr
->fabric_ip_addr
,
899 bfa_fcs_lport_get_fabric_ipaddr(port
),
900 BFA_FCS_FABRIC_IPADDR_SZ
);
902 if (port
->vport
!= NULL
) {
903 port_attr
->port_type
= BFA_PORT_TYPE_VPORT
;
904 port_attr
->fpma_mac
=
905 port
->vport
->lps
->lp_mac
;
907 port_attr
->fpma_mac
=
908 port
->fabric
->lps
->lp_mac
;
911 port_attr
->port_type
= BFA_PORT_TYPE_UNKNOWN
;
912 port_attr
->state
= BFA_LPORT_UNINIT
;
917 * bfa_fcs_lport_fab port fab functions
921 * Called by port to initialize fabric services of the base port.
924 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s
*port
)
926 bfa_fcs_lport_ns_init(port
);
927 bfa_fcs_lport_scn_init(port
);
928 bfa_fcs_lport_ms_init(port
);
932 * Called by port to notify transition to online state.
935 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s
*port
)
937 bfa_fcs_lport_ns_online(port
);
938 bfa_fcs_lport_scn_online(port
);
942 * Called by port to notify transition to offline state.
945 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s
*port
)
947 bfa_fcs_lport_ns_offline(port
);
948 bfa_fcs_lport_scn_offline(port
);
949 bfa_fcs_lport_ms_offline(port
);
953 * bfa_fcs_lport_n2n functions
957 * Called by fcs/port to initialize N2N topology.
960 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s
*port
)
965 * Called by fcs/port to notify transition to online state.
968 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s
*port
)
970 struct bfa_fcs_lport_n2n_s
*n2n_port
= &port
->port_topo
.pn2n
;
971 struct bfa_lport_cfg_s
*pcfg
= &port
->port_cfg
;
972 struct bfa_fcs_rport_s
*rport
;
974 bfa_trc(port
->fcs
, pcfg
->pwwn
);
977 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
978 * and assign an Address. if not, we need to wait for its PLOGI.
980 * If our PWWN is < than that of the remote port, it will send a PLOGI
981 * with the PIDs assigned. The rport state machine take care of this
985 ((void *)&pcfg
->pwwn
, (void *)&n2n_port
->rem_port_wwn
,
986 sizeof(wwn_t
)) > 0) {
987 port
->pid
= N2N_LOCAL_PID
;
988 bfa_lps_set_n2n_pid(port
->fabric
->lps
, N2N_LOCAL_PID
);
990 * First, check if we know the device by pwwn.
992 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
,
993 n2n_port
->rem_port_wwn
);
995 bfa_trc(port
->fcs
, rport
->pid
);
996 bfa_trc(port
->fcs
, rport
->pwwn
);
997 rport
->pid
= N2N_REMOTE_PID
;
998 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_SEND
);
1003 * In n2n there can be only one rport. Delete the old one
1004 * whose pid should be zero, because it is offline.
1006 if (port
->num_rports
> 0) {
1007 rport
= bfa_fcs_lport_get_rport_by_pid(port
, 0);
1008 WARN_ON(rport
== NULL
);
1010 bfa_trc(port
->fcs
, rport
->pwwn
);
1011 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
1014 bfa_fcs_rport_create(port
, N2N_REMOTE_PID
);
1019 * Called by fcs/port to notify transition to offline state.
1022 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s
*port
)
1024 struct bfa_fcs_lport_n2n_s
*n2n_port
= &port
->port_topo
.pn2n
;
1026 bfa_trc(port
->fcs
, port
->pid
);
1028 n2n_port
->rem_port_wwn
= 0;
1029 n2n_port
->reply_oxid
= 0;
1032 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1035 * forward declarations
1037 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg
,
1038 struct bfa_fcxp_s
*fcxp_alloced
);
1039 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg
,
1040 struct bfa_fcxp_s
*fcxp_alloced
);
1041 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg
,
1042 struct bfa_fcxp_s
*fcxp_alloced
);
1043 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg
,
1044 struct bfa_fcxp_s
*fcxp
,
1046 bfa_status_t req_status
,
1049 struct fchs_s
*rsp_fchs
);
1050 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg
,
1051 struct bfa_fcxp_s
*fcxp
,
1053 bfa_status_t req_status
,
1056 struct fchs_s
*rsp_fchs
);
1057 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg
,
1058 struct bfa_fcxp_s
*fcxp
,
1060 bfa_status_t req_status
,
1063 struct fchs_s
*rsp_fchs
);
1064 static void bfa_fcs_lport_fdmi_timeout(void *arg
);
1065 static u16
bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1067 static u16
bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1069 static u16
bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1071 static u16
bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s
*
1073 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1074 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
);
1075 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1076 struct bfa_fcs_fdmi_port_attr_s
*port_attr
);
1078 * fcs_fdmi_sm FCS FDMI state machine
1082 * FDMI State Machine events
1084 enum port_fdmi_event
{
1085 FDMISM_EVENT_PORT_ONLINE
= 1,
1086 FDMISM_EVENT_PORT_OFFLINE
= 2,
1087 FDMISM_EVENT_RSP_OK
= 4,
1088 FDMISM_EVENT_RSP_ERROR
= 5,
1089 FDMISM_EVENT_TIMEOUT
= 6,
1090 FDMISM_EVENT_RHBA_SENT
= 7,
1091 FDMISM_EVENT_RPRT_SENT
= 8,
1092 FDMISM_EVENT_RPA_SENT
= 9,
1095 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1096 enum port_fdmi_event event
);
1097 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1098 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1099 enum port_fdmi_event event
);
1100 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1101 enum port_fdmi_event event
);
1102 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1103 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1104 enum port_fdmi_event event
);
1105 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1106 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1107 enum port_fdmi_event event
);
1108 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1109 enum port_fdmi_event event
);
1110 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1111 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1112 enum port_fdmi_event event
);
1113 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1114 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1115 enum port_fdmi_event event
);
1116 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1117 enum port_fdmi_event event
);
1118 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1119 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1120 enum port_fdmi_event event
);
1121 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1122 enum port_fdmi_event event
);
1123 static void bfa_fcs_lport_fdmi_sm_disabled(
1124 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1125 enum port_fdmi_event event
);
1127 * Start in offline state - awaiting MS to send start.
1130 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1131 enum port_fdmi_event event
)
1133 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1135 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1136 bfa_trc(port
->fcs
, event
);
1138 fdmi
->retry_cnt
= 0;
1141 case FDMISM_EVENT_PORT_ONLINE
:
1144 * For Vports, register a new port.
1146 bfa_sm_set_state(fdmi
,
1147 bfa_fcs_lport_fdmi_sm_sending_rprt
);
1148 bfa_fcs_lport_fdmi_send_rprt(fdmi
, NULL
);
1151 * For a base port, we should first register the HBA
1152 * atribute. The HBA attribute also contains the base
1153 * port registration.
1155 bfa_sm_set_state(fdmi
,
1156 bfa_fcs_lport_fdmi_sm_sending_rhba
);
1157 bfa_fcs_lport_fdmi_send_rhba(fdmi
, NULL
);
1161 case FDMISM_EVENT_PORT_OFFLINE
:
1165 bfa_sm_fault(port
->fcs
, event
);
1170 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1171 enum port_fdmi_event event
)
1173 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1175 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1176 bfa_trc(port
->fcs
, event
);
1179 case FDMISM_EVENT_RHBA_SENT
:
1180 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rhba
);
1183 case FDMISM_EVENT_PORT_OFFLINE
:
1184 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1185 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1190 bfa_sm_fault(port
->fcs
, event
);
1195 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1196 enum port_fdmi_event event
)
1198 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1200 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1201 bfa_trc(port
->fcs
, event
);
1204 case FDMISM_EVENT_RSP_ERROR
:
1206 * if max retries have not been reached, start timer for a
1209 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1210 bfa_sm_set_state(fdmi
,
1211 bfa_fcs_lport_fdmi_sm_rhba_retry
);
1212 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1214 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1215 BFA_FCS_RETRY_TIMEOUT
);
1218 * set state to offline
1220 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1224 case FDMISM_EVENT_RSP_OK
:
1226 * Initiate Register Port Attributes
1228 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rpa
);
1229 fdmi
->retry_cnt
= 0;
1230 bfa_fcs_lport_fdmi_send_rpa(fdmi
, NULL
);
1233 case FDMISM_EVENT_PORT_OFFLINE
:
1234 bfa_fcxp_discard(fdmi
->fcxp
);
1235 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1239 bfa_sm_fault(port
->fcs
, event
);
1244 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1245 enum port_fdmi_event event
)
1247 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1249 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1250 bfa_trc(port
->fcs
, event
);
1253 case FDMISM_EVENT_TIMEOUT
:
1255 * Retry Timer Expired. Re-send
1257 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rhba
);
1258 bfa_fcs_lport_fdmi_send_rhba(fdmi
, NULL
);
1261 case FDMISM_EVENT_PORT_OFFLINE
:
1262 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1263 bfa_timer_stop(&fdmi
->timer
);
1267 bfa_sm_fault(port
->fcs
, event
);
1272 * RPRT : Register Port
1275 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1276 enum port_fdmi_event event
)
1278 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1280 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1281 bfa_trc(port
->fcs
, event
);
1284 case FDMISM_EVENT_RPRT_SENT
:
1285 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rprt
);
1288 case FDMISM_EVENT_PORT_OFFLINE
:
1289 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1290 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1295 bfa_sm_fault(port
->fcs
, event
);
1300 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1301 enum port_fdmi_event event
)
1303 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1305 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1306 bfa_trc(port
->fcs
, event
);
1309 case FDMISM_EVENT_RSP_ERROR
:
1311 * if max retries have not been reached, start timer for a
1314 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1315 bfa_sm_set_state(fdmi
,
1316 bfa_fcs_lport_fdmi_sm_rprt_retry
);
1317 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1319 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1320 BFA_FCS_RETRY_TIMEOUT
);
1324 * set state to offline
1326 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1327 fdmi
->retry_cnt
= 0;
1331 case FDMISM_EVENT_RSP_OK
:
1332 fdmi
->retry_cnt
= 0;
1333 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_online
);
1336 case FDMISM_EVENT_PORT_OFFLINE
:
1337 bfa_fcxp_discard(fdmi
->fcxp
);
1338 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1342 bfa_sm_fault(port
->fcs
, event
);
1347 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1348 enum port_fdmi_event event
)
1350 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1352 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1353 bfa_trc(port
->fcs
, event
);
1356 case FDMISM_EVENT_TIMEOUT
:
1358 * Retry Timer Expired. Re-send
1360 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rprt
);
1361 bfa_fcs_lport_fdmi_send_rprt(fdmi
, NULL
);
1364 case FDMISM_EVENT_PORT_OFFLINE
:
1365 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1366 bfa_timer_stop(&fdmi
->timer
);
1370 bfa_sm_fault(port
->fcs
, event
);
1375 * Register Port Attributes
1378 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1379 enum port_fdmi_event event
)
1381 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1383 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1384 bfa_trc(port
->fcs
, event
);
1387 case FDMISM_EVENT_RPA_SENT
:
1388 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rpa
);
1391 case FDMISM_EVENT_PORT_OFFLINE
:
1392 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1393 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1398 bfa_sm_fault(port
->fcs
, event
);
1403 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1404 enum port_fdmi_event event
)
1406 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1408 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1409 bfa_trc(port
->fcs
, event
);
1412 case FDMISM_EVENT_RSP_ERROR
:
1414 * if max retries have not been reached, start timer for a
1417 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1418 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rpa_retry
);
1419 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1421 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1422 BFA_FCS_RETRY_TIMEOUT
);
1425 * set state to offline
1427 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1428 fdmi
->retry_cnt
= 0;
1432 case FDMISM_EVENT_RSP_OK
:
1433 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_online
);
1434 fdmi
->retry_cnt
= 0;
1437 case FDMISM_EVENT_PORT_OFFLINE
:
1438 bfa_fcxp_discard(fdmi
->fcxp
);
1439 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1443 bfa_sm_fault(port
->fcs
, event
);
1448 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1449 enum port_fdmi_event event
)
1451 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1453 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1454 bfa_trc(port
->fcs
, event
);
1457 case FDMISM_EVENT_TIMEOUT
:
1459 * Retry Timer Expired. Re-send
1461 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rpa
);
1462 bfa_fcs_lport_fdmi_send_rpa(fdmi
, NULL
);
1465 case FDMISM_EVENT_PORT_OFFLINE
:
1466 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1467 bfa_timer_stop(&fdmi
->timer
);
1471 bfa_sm_fault(port
->fcs
, event
);
1476 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1477 enum port_fdmi_event event
)
1479 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1481 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1482 bfa_trc(port
->fcs
, event
);
1485 case FDMISM_EVENT_PORT_OFFLINE
:
1486 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1490 bfa_sm_fault(port
->fcs
, event
);
1494 * FDMI is disabled state.
1497 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1498 enum port_fdmi_event event
)
1500 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1502 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1503 bfa_trc(port
->fcs
, event
);
1505 /* No op State. It can only be enabled at Driver Init. */
1509 * RHBA : Register HBA Attributes.
1512 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1514 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
1515 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1518 struct bfa_fcxp_s
*fcxp
;
1521 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1523 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1525 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1526 bfa_fcs_lport_fdmi_send_rhba
, fdmi
);
1531 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1532 memset(pyld
, 0, FC_MAX_PDUSZ
);
1534 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
1538 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi
,
1539 (u8
*) ((struct ct_hdr_s
*) pyld
1542 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1543 FC_CLASS_3
, (len
+ attr_len
), &fchs
,
1544 bfa_fcs_lport_fdmi_rhba_response
, (void *)fdmi
,
1545 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
1547 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RHBA_SENT
);
1551 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
1553 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1554 struct bfa_fcs_fdmi_hba_attr_s hba_attr
;
1555 struct bfa_fcs_fdmi_hba_attr_s
*fcs_hba_attr
= &hba_attr
;
1556 struct fdmi_rhba_s
*rhba
= (struct fdmi_rhba_s
*) pyld
;
1557 struct fdmi_attr_s
*attr
;
1563 * get hba attributes
1565 bfa_fcs_fdmi_get_hbaattr(fdmi
, fcs_hba_attr
);
1567 rhba
->hba_id
= bfa_fcs_lport_get_pwwn(port
);
1568 rhba
->port_list
.num_ports
= cpu_to_be32(1);
1569 rhba
->port_list
.port_entry
= bfa_fcs_lport_get_pwwn(port
);
1571 len
= sizeof(rhba
->hba_id
) + sizeof(rhba
->port_list
);
1574 len
+= sizeof(rhba
->hba_attr_blk
.attr_count
);
1577 * fill out the invididual entries of the HBA attrib Block
1579 curr_ptr
= (u8
*) &rhba
->hba_attr_blk
.hba_attr
;
1584 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1585 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME
);
1586 templen
= sizeof(wwn_t
);
1587 memcpy(attr
->value
, &bfa_fcs_lport_get_nwwn(port
), templen
);
1588 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1591 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1597 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1598 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER
);
1599 templen
= (u16
) strlen(fcs_hba_attr
->manufacturer
);
1600 memcpy(attr
->value
, fcs_hba_attr
->manufacturer
, templen
);
1601 templen
= fc_roundup(templen
, sizeof(u32
));
1602 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1605 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1611 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1612 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM
);
1613 templen
= (u16
) strlen(fcs_hba_attr
->serial_num
);
1614 memcpy(attr
->value
, fcs_hba_attr
->serial_num
, templen
);
1615 templen
= fc_roundup(templen
, sizeof(u32
));
1616 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1619 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1625 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1626 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MODEL
);
1627 templen
= (u16
) strlen(fcs_hba_attr
->model
);
1628 memcpy(attr
->value
, fcs_hba_attr
->model
, templen
);
1629 templen
= fc_roundup(templen
, sizeof(u32
));
1630 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1633 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1639 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1640 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC
);
1641 templen
= (u16
) strlen(fcs_hba_attr
->model_desc
);
1642 memcpy(attr
->value
, fcs_hba_attr
->model_desc
, templen
);
1643 templen
= fc_roundup(templen
, sizeof(u32
));
1644 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1647 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1653 if (fcs_hba_attr
->hw_version
[0] != '\0') {
1654 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1655 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION
);
1656 templen
= (u16
) strlen(fcs_hba_attr
->hw_version
);
1657 memcpy(attr
->value
, fcs_hba_attr
->hw_version
, templen
);
1658 templen
= fc_roundup(templen
, sizeof(u32
));
1659 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1662 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1669 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1670 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION
);
1671 templen
= (u16
) strlen(fcs_hba_attr
->driver_version
);
1672 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, templen
);
1673 templen
= fc_roundup(templen
, sizeof(u32
));
1674 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1677 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1681 * Option Rom Version
1683 if (fcs_hba_attr
->option_rom_ver
[0] != '\0') {
1684 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1685 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION
);
1686 templen
= (u16
) strlen(fcs_hba_attr
->option_rom_ver
);
1687 memcpy(attr
->value
, fcs_hba_attr
->option_rom_ver
, templen
);
1688 templen
= fc_roundup(templen
, sizeof(u32
));
1689 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1692 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1697 * f/w Version = driver version
1699 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1700 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION
);
1701 templen
= (u16
) strlen(fcs_hba_attr
->driver_version
);
1702 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, templen
);
1703 templen
= fc_roundup(templen
, sizeof(u32
));
1704 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1707 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1713 if (fcs_hba_attr
->os_name
[0] != '\0') {
1714 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1715 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME
);
1716 templen
= (u16
) strlen(fcs_hba_attr
->os_name
);
1717 memcpy(attr
->value
, fcs_hba_attr
->os_name
, templen
);
1718 templen
= fc_roundup(templen
, sizeof(u32
));
1719 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1722 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1729 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1730 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT
);
1731 templen
= sizeof(fcs_hba_attr
->max_ct_pyld
);
1732 memcpy(attr
->value
, &fcs_hba_attr
->max_ct_pyld
, templen
);
1735 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1739 * Update size of payload
1741 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
1743 rhba
->hba_attr_blk
.attr_count
= cpu_to_be32(count
);
1748 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1749 void *cbarg
, bfa_status_t req_status
,
1750 u32 rsp_len
, u32 resid_len
,
1751 struct fchs_s
*rsp_fchs
)
1753 struct bfa_fcs_lport_fdmi_s
*fdmi
=
1754 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
1755 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1756 struct ct_hdr_s
*cthdr
= NULL
;
1758 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1763 if (req_status
!= BFA_STATUS_OK
) {
1764 bfa_trc(port
->fcs
, req_status
);
1765 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1769 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1770 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
1772 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1773 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1777 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1778 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1779 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1783 * RPRT : Register Port
1786 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1788 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
1789 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1792 struct bfa_fcxp_s
*fcxp
;
1795 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1797 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1799 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1800 bfa_fcs_lport_fdmi_send_rprt
, fdmi
);
1805 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1806 memset(pyld
, 0, FC_MAX_PDUSZ
);
1808 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
1812 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi
,
1813 (u8
*) ((struct ct_hdr_s
*) pyld
1816 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1817 FC_CLASS_3
, len
+ attr_len
, &fchs
,
1818 bfa_fcs_lport_fdmi_rprt_response
, (void *)fdmi
,
1819 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
1821 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPRT_SENT
);
1825 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
1828 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1831 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr
;
1832 struct fdmi_port_attr_s
*port_attrib
= (struct fdmi_port_attr_s
*) pyld
;
1833 struct fdmi_attr_s
*attr
;
1840 * get port attributes
1842 bfa_fcs_fdmi_get_portattr(fdmi
, &fcs_port_attr
);
1844 len
= sizeof(port_attrib
->attr_count
);
1847 * fill out the invididual entries
1849 curr_ptr
= (u8
*) &port_attrib
->port_attr
;
1854 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1855 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES
);
1856 templen
= sizeof(fcs_port_attr
.supp_fc4_types
);
1857 memcpy(attr
->value
, fcs_port_attr
.supp_fc4_types
, templen
);
1858 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1862 cpu_to_be16(templen
+ sizeof(attr
->type
) +
1868 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1869 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED
);
1870 templen
= sizeof(fcs_port_attr
.supp_speed
);
1871 memcpy(attr
->value
, &fcs_port_attr
.supp_speed
, templen
);
1872 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1876 cpu_to_be16(templen
+ sizeof(attr
->type
) +
1880 * current Port Speed
1882 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1883 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED
);
1884 templen
= sizeof(fcs_port_attr
.curr_speed
);
1885 memcpy(attr
->value
, &fcs_port_attr
.curr_speed
, templen
);
1886 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1889 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1895 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1896 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE
);
1897 templen
= sizeof(fcs_port_attr
.max_frm_size
);
1898 memcpy(attr
->value
, &fcs_port_attr
.max_frm_size
, templen
);
1899 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1902 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1908 if (fcs_port_attr
.os_device_name
[0] != '\0') {
1909 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1910 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME
);
1911 templen
= (u16
) strlen(fcs_port_attr
.os_device_name
);
1912 memcpy(attr
->value
, fcs_port_attr
.os_device_name
, templen
);
1913 templen
= fc_roundup(templen
, sizeof(u32
));
1914 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1917 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1923 if (fcs_port_attr
.host_name
[0] != '\0') {
1924 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1925 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME
);
1926 templen
= (u16
) strlen(fcs_port_attr
.host_name
);
1927 memcpy(attr
->value
, fcs_port_attr
.host_name
, templen
);
1928 templen
= fc_roundup(templen
, sizeof(u32
));
1929 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1932 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1937 * Update size of payload
1939 port_attrib
->attr_count
= cpu_to_be32(count
);
1940 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
1945 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
1947 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1948 struct fdmi_rprt_s
*rprt
= (struct fdmi_rprt_s
*) pyld
;
1951 rprt
->hba_id
= bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port
->fcs
));
1952 rprt
->port_name
= bfa_fcs_lport_get_pwwn(port
);
1954 len
= bfa_fcs_lport_fdmi_build_portattr_block(fdmi
,
1955 (u8
*) &rprt
->port_attr_blk
);
1957 len
+= sizeof(rprt
->hba_id
) + sizeof(rprt
->port_name
);
1963 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1964 void *cbarg
, bfa_status_t req_status
,
1965 u32 rsp_len
, u32 resid_len
,
1966 struct fchs_s
*rsp_fchs
)
1968 struct bfa_fcs_lport_fdmi_s
*fdmi
=
1969 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
1970 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1971 struct ct_hdr_s
*cthdr
= NULL
;
1973 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1978 if (req_status
!= BFA_STATUS_OK
) {
1979 bfa_trc(port
->fcs
, req_status
);
1980 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1984 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1985 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
1987 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1988 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1992 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1993 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1994 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1998 * RPA : Register Port Attributes.
2001 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2003 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
2004 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2007 struct bfa_fcxp_s
*fcxp
;
2010 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2012 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2014 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
2015 bfa_fcs_lport_fdmi_send_rpa
, fdmi
);
2020 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
2021 memset(pyld
, 0, FC_MAX_PDUSZ
);
2023 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
2026 attr_len
= bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi
,
2027 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
2029 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2030 FC_CLASS_3
, len
+ attr_len
, &fchs
,
2031 bfa_fcs_lport_fdmi_rpa_response
, (void *)fdmi
,
2032 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2034 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPA_SENT
);
2038 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
2040 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2041 struct fdmi_rpa_s
*rpa
= (struct fdmi_rpa_s
*) pyld
;
2044 rpa
->port_name
= bfa_fcs_lport_get_pwwn(port
);
2046 len
= bfa_fcs_lport_fdmi_build_portattr_block(fdmi
,
2047 (u8
*) &rpa
->port_attr_blk
);
2049 len
+= sizeof(rpa
->port_name
);
2055 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2056 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
2057 u32 resid_len
, struct fchs_s
*rsp_fchs
)
2059 struct bfa_fcs_lport_fdmi_s
*fdmi
=
2060 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
2061 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2062 struct ct_hdr_s
*cthdr
= NULL
;
2064 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2069 if (req_status
!= BFA_STATUS_OK
) {
2070 bfa_trc(port
->fcs
, req_status
);
2071 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2075 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2076 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2078 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2079 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
2083 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2084 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2085 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2089 bfa_fcs_lport_fdmi_timeout(void *arg
)
2091 struct bfa_fcs_lport_fdmi_s
*fdmi
= (struct bfa_fcs_lport_fdmi_s
*) arg
;
2093 bfa_sm_send_event(fdmi
, FDMISM_EVENT_TIMEOUT
);
2097 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
2098 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
)
2100 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2101 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
2103 memset(hba_attr
, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s
));
2105 bfa_ioc_get_adapter_manufacturer(&port
->fcs
->bfa
->ioc
,
2106 hba_attr
->manufacturer
);
2107 bfa_ioc_get_adapter_serial_num(&port
->fcs
->bfa
->ioc
,
2108 hba_attr
->serial_num
);
2109 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
,
2111 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
,
2112 hba_attr
->model_desc
);
2113 bfa_ioc_get_pci_chip_rev(&port
->fcs
->bfa
->ioc
,
2114 hba_attr
->hw_version
);
2115 bfa_ioc_get_adapter_optrom_ver(&port
->fcs
->bfa
->ioc
,
2116 hba_attr
->option_rom_ver
);
2117 bfa_ioc_get_adapter_fw_ver(&port
->fcs
->bfa
->ioc
,
2118 hba_attr
->fw_version
);
2120 strncpy(hba_attr
->driver_version
, (char *)driver_info
->version
,
2121 sizeof(hba_attr
->driver_version
));
2123 strncpy(hba_attr
->os_name
, driver_info
->host_os_name
,
2124 sizeof(hba_attr
->os_name
));
2127 * If there is a patch level, append it
2128 * to the os name along with a separator
2130 if (driver_info
->host_os_patch
[0] != '\0') {
2131 strncat(hba_attr
->os_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
2132 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
2133 strncat(hba_attr
->os_name
, driver_info
->host_os_patch
,
2134 sizeof(driver_info
->host_os_patch
));
2137 hba_attr
->max_ct_pyld
= cpu_to_be32(FC_MAX_PDUSZ
);
2141 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
2142 struct bfa_fcs_fdmi_port_attr_s
*port_attr
)
2144 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2145 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
2146 struct bfa_port_attr_s pport_attr
;
2148 memset(port_attr
, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s
));
2151 * get pport attributes from hal
2153 bfa_fcport_get_attr(port
->fcs
->bfa
, &pport_attr
);
2156 * get FC4 type Bitmask
2158 fc_get_fc4type_bitmask(FC_TYPE_FCP
, port_attr
->supp_fc4_types
);
2163 port_attr
->supp_speed
= cpu_to_be32(BFA_FCS_FDMI_SUPORTED_SPEEDS
);
2168 port_attr
->curr_speed
= cpu_to_be32(pport_attr
.speed
);
2173 port_attr
->max_frm_size
= cpu_to_be32(FC_MAX_PDUSZ
);
2178 strncpy(port_attr
->os_device_name
, (char *)driver_info
->os_device_name
,
2179 sizeof(port_attr
->os_device_name
));
2184 strncpy(port_attr
->host_name
, (char *)driver_info
->host_machine_name
,
2185 sizeof(port_attr
->host_name
));
2191 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s
*ms
)
2193 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2196 if (ms
->port
->fcs
->fdmi_enabled
)
2197 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
2199 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_disabled
);
2203 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s
*ms
)
2205 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2208 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_OFFLINE
);
2212 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s
*ms
)
2214 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2217 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_ONLINE
);
2220 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2223 * forward declarations
2225 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg
,
2226 struct bfa_fcxp_s
*fcxp_alloced
);
2227 static void bfa_fcs_lport_ms_timeout(void *arg
);
2228 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg
,
2229 struct bfa_fcxp_s
*fcxp
,
2231 bfa_status_t req_status
,
2234 struct fchs_s
*rsp_fchs
);
2236 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg
,
2237 struct bfa_fcxp_s
*fcxp_alloced
);
2238 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg
,
2239 struct bfa_fcxp_s
*fcxp
,
2241 bfa_status_t req_status
,
2244 struct fchs_s
*rsp_fchs
);
2245 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg
,
2246 struct bfa_fcxp_s
*fcxp_alloced
);
2247 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg
,
2248 struct bfa_fcxp_s
*fcxp
,
2250 bfa_status_t req_status
,
2253 struct fchs_s
*rsp_fchs
);
2255 * fcs_ms_sm FCS MS state machine
2259 * MS State Machine events
2261 enum port_ms_event
{
2262 MSSM_EVENT_PORT_ONLINE
= 1,
2263 MSSM_EVENT_PORT_OFFLINE
= 2,
2264 MSSM_EVENT_RSP_OK
= 3,
2265 MSSM_EVENT_RSP_ERROR
= 4,
2266 MSSM_EVENT_TIMEOUT
= 5,
2267 MSSM_EVENT_FCXP_SENT
= 6,
2268 MSSM_EVENT_PORT_FABRIC_RSCN
= 7
2271 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s
*ms
,
2272 enum port_ms_event event
);
2273 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s
*ms
,
2274 enum port_ms_event event
);
2275 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s
*ms
,
2276 enum port_ms_event event
);
2277 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s
*ms
,
2278 enum port_ms_event event
);
2279 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s
*ms
,
2280 enum port_ms_event event
);
2281 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s
*ms
,
2282 enum port_ms_event event
);
2283 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s
*ms
,
2284 enum port_ms_event event
);
2285 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s
*ms
,
2286 enum port_ms_event event
);
2287 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s
*ms
,
2288 enum port_ms_event event
);
2289 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s
*ms
,
2290 enum port_ms_event event
);
2291 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s
*ms
,
2292 enum port_ms_event event
);
2294 * Start in offline state - awaiting NS to send start.
2297 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s
*ms
,
2298 enum port_ms_event event
)
2300 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2301 bfa_trc(ms
->port
->fcs
, event
);
2304 case MSSM_EVENT_PORT_ONLINE
:
2305 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_sending
);
2306 bfa_fcs_lport_ms_send_plogi(ms
, NULL
);
2309 case MSSM_EVENT_PORT_OFFLINE
:
2313 bfa_sm_fault(ms
->port
->fcs
, event
);
2318 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s
*ms
,
2319 enum port_ms_event event
)
2321 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2322 bfa_trc(ms
->port
->fcs
, event
);
2325 case MSSM_EVENT_FCXP_SENT
:
2326 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi
);
2329 case MSSM_EVENT_PORT_OFFLINE
:
2330 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2331 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2336 bfa_sm_fault(ms
->port
->fcs
, event
);
2341 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s
*ms
,
2342 enum port_ms_event event
)
2344 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2345 bfa_trc(ms
->port
->fcs
, event
);
2348 case MSSM_EVENT_RSP_ERROR
:
2350 * Start timer for a delayed retry
2352 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_retry
);
2353 ms
->port
->stats
.ms_retries
++;
2354 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2355 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2356 BFA_FCS_RETRY_TIMEOUT
);
2359 case MSSM_EVENT_RSP_OK
:
2361 * since plogi is done, now invoke MS related sub-modules
2363 bfa_fcs_lport_fdmi_online(ms
);
2366 * if this is a Vport, go to online state.
2368 if (ms
->port
->vport
) {
2369 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2374 * For a base port we need to get the
2375 * switch's IP address.
2377 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_sending
);
2378 bfa_fcs_lport_ms_send_gmal(ms
, NULL
);
2381 case MSSM_EVENT_PORT_OFFLINE
:
2382 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2383 bfa_fcxp_discard(ms
->fcxp
);
2387 bfa_sm_fault(ms
->port
->fcs
, event
);
2392 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s
*ms
,
2393 enum port_ms_event event
)
2395 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2396 bfa_trc(ms
->port
->fcs
, event
);
2399 case MSSM_EVENT_TIMEOUT
:
2401 * Retry Timer Expired. Re-send
2403 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_sending
);
2404 bfa_fcs_lport_ms_send_plogi(ms
, NULL
);
2407 case MSSM_EVENT_PORT_OFFLINE
:
2408 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2409 bfa_timer_stop(&ms
->timer
);
2413 bfa_sm_fault(ms
->port
->fcs
, event
);
2418 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s
*ms
,
2419 enum port_ms_event event
)
2421 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2422 bfa_trc(ms
->port
->fcs
, event
);
2425 case MSSM_EVENT_PORT_OFFLINE
:
2426 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2429 case MSSM_EVENT_PORT_FABRIC_RSCN
:
2430 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2432 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2436 bfa_sm_fault(ms
->port
->fcs
, event
);
2441 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s
*ms
,
2442 enum port_ms_event event
)
2444 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2445 bfa_trc(ms
->port
->fcs
, event
);
2448 case MSSM_EVENT_FCXP_SENT
:
2449 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal
);
2452 case MSSM_EVENT_PORT_OFFLINE
:
2453 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2454 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2459 bfa_sm_fault(ms
->port
->fcs
, event
);
2464 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s
*ms
,
2465 enum port_ms_event event
)
2467 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2468 bfa_trc(ms
->port
->fcs
, event
);
2471 case MSSM_EVENT_RSP_ERROR
:
2473 * Start timer for a delayed retry
2475 if (ms
->retry_cnt
++ < BFA_FCS_MS_CMD_MAX_RETRIES
) {
2476 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_retry
);
2477 ms
->port
->stats
.ms_retries
++;
2478 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2479 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2480 BFA_FCS_RETRY_TIMEOUT
);
2482 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2483 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2488 case MSSM_EVENT_RSP_OK
:
2489 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2490 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2493 case MSSM_EVENT_PORT_OFFLINE
:
2494 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2495 bfa_fcxp_discard(ms
->fcxp
);
2499 bfa_sm_fault(ms
->port
->fcs
, event
);
2504 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s
*ms
,
2505 enum port_ms_event event
)
2507 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2508 bfa_trc(ms
->port
->fcs
, event
);
2511 case MSSM_EVENT_TIMEOUT
:
2513 * Retry Timer Expired. Re-send
2515 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_sending
);
2516 bfa_fcs_lport_ms_send_gmal(ms
, NULL
);
2519 case MSSM_EVENT_PORT_OFFLINE
:
2520 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2521 bfa_timer_stop(&ms
->timer
);
2525 bfa_sm_fault(ms
->port
->fcs
, event
);
2529 * ms_pvt MS local functions
2533 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2535 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
2536 bfa_fcs_lport_t
*port
= ms
->port
;
2539 struct bfa_fcxp_s
*fcxp
;
2541 bfa_trc(port
->fcs
, port
->pid
);
2543 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2545 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
2546 bfa_fcs_lport_ms_send_gmal
, ms
);
2551 len
= fc_gmal_req_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2552 bfa_fcs_lport_get_fcid(port
),
2553 port
->fabric
->lps
->pr_nwwn
);
2555 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2556 FC_CLASS_3
, len
, &fchs
,
2557 bfa_fcs_lport_ms_gmal_response
, (void *)ms
,
2558 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2560 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
2564 bfa_fcs_lport_ms_gmal_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2565 void *cbarg
, bfa_status_t req_status
,
2566 u32 rsp_len
, u32 resid_len
,
2567 struct fchs_s
*rsp_fchs
)
2569 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
2570 bfa_fcs_lport_t
*port
= ms
->port
;
2571 struct ct_hdr_s
*cthdr
= NULL
;
2572 struct fcgs_gmal_resp_s
*gmal_resp
;
2573 struct fcgs_gmal_entry_s
*gmal_entry
;
2577 bfa_trc(port
->fcs
, req_status
);
2578 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2583 if (req_status
!= BFA_STATUS_OK
) {
2584 bfa_trc(port
->fcs
, req_status
);
2585 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2589 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2590 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2592 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2593 gmal_resp
= (struct fcgs_gmal_resp_s
*)(cthdr
+ 1);
2595 num_entries
= be32_to_cpu(gmal_resp
->ms_len
);
2596 if (num_entries
== 0) {
2597 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2601 * The response could contain multiple Entries.
2602 * Entries for SNMP interface, etc.
2603 * We look for the entry with a telnet prefix.
2604 * First "http://" entry refers to IP addr
2607 gmal_entry
= (struct fcgs_gmal_entry_s
*)gmal_resp
->ms_ma
;
2608 while (num_entries
> 0) {
2609 if (strncmp(gmal_entry
->prefix
,
2610 CT_GMAL_RESP_PREFIX_HTTP
,
2611 sizeof(gmal_entry
->prefix
)) == 0) {
2614 * if the IP address is terminating with a '/',
2616 * Byte 0 consists of the length of the string.
2618 rsp_str
= &(gmal_entry
->prefix
[0]);
2619 if (rsp_str
[gmal_entry
->len
-1] == '/')
2620 rsp_str
[gmal_entry
->len
-1] = 0;
2622 /* copy IP Address to fabric */
2623 strncpy(bfa_fcs_lport_get_fabric_ipaddr(port
),
2624 gmal_entry
->ip_addr
,
2625 BFA_FCS_FABRIC_IPADDR_SZ
);
2633 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
2637 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2638 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2639 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2643 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s
*ms
,
2644 enum port_ms_event event
)
2646 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2647 bfa_trc(ms
->port
->fcs
, event
);
2650 case MSSM_EVENT_FCXP_SENT
:
2651 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn
);
2654 case MSSM_EVENT_PORT_OFFLINE
:
2655 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2656 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2661 bfa_sm_fault(ms
->port
->fcs
, event
);
2666 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s
*ms
,
2667 enum port_ms_event event
)
2669 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2670 bfa_trc(ms
->port
->fcs
, event
);
2673 case MSSM_EVENT_RSP_ERROR
:
2675 * Start timer for a delayed retry
2677 if (ms
->retry_cnt
++ < BFA_FCS_MS_CMD_MAX_RETRIES
) {
2678 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_retry
);
2679 ms
->port
->stats
.ms_retries
++;
2680 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2681 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2682 BFA_FCS_RETRY_TIMEOUT
);
2684 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2689 case MSSM_EVENT_RSP_OK
:
2690 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2693 case MSSM_EVENT_PORT_OFFLINE
:
2694 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2695 bfa_fcxp_discard(ms
->fcxp
);
2699 bfa_sm_fault(ms
->port
->fcs
, event
);
2704 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s
*ms
,
2705 enum port_ms_event event
)
2707 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2708 bfa_trc(ms
->port
->fcs
, event
);
2711 case MSSM_EVENT_TIMEOUT
:
2713 * Retry Timer Expired. Re-send
2715 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2716 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2719 case MSSM_EVENT_PORT_OFFLINE
:
2720 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2721 bfa_timer_stop(&ms
->timer
);
2725 bfa_sm_fault(ms
->port
->fcs
, event
);
2729 * ms_pvt MS local functions
2733 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2735 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
2736 bfa_fcs_lport_t
*port
= ms
->port
;
2739 struct bfa_fcxp_s
*fcxp
;
2741 bfa_trc(port
->fcs
, port
->pid
);
2743 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2745 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
2746 bfa_fcs_lport_ms_send_gfn
, ms
);
2751 len
= fc_gfn_req_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2752 bfa_fcs_lport_get_fcid(port
),
2753 port
->fabric
->lps
->pr_nwwn
);
2755 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2756 FC_CLASS_3
, len
, &fchs
,
2757 bfa_fcs_lport_ms_gfn_response
, (void *)ms
,
2758 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2760 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
2764 bfa_fcs_lport_ms_gfn_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2765 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
2766 u32 resid_len
, struct fchs_s
*rsp_fchs
)
2768 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
2769 bfa_fcs_lport_t
*port
= ms
->port
;
2770 struct ct_hdr_s
*cthdr
= NULL
;
2773 bfa_trc(port
->fcs
, req_status
);
2774 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2779 if (req_status
!= BFA_STATUS_OK
) {
2780 bfa_trc(port
->fcs
, req_status
);
2781 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2785 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2786 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2788 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2789 gfn_resp
= (wwn_t
*)(cthdr
+ 1);
2790 /* check if it has actually changed */
2791 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port
),
2792 gfn_resp
, sizeof(wwn_t
)) != 0)) {
2793 bfa_fcs_fabric_set_fabric_name(port
->fabric
, *gfn_resp
);
2795 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
2799 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2800 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2801 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2805 * ms_pvt MS local functions
2809 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2811 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
2812 struct bfa_fcs_lport_s
*port
= ms
->port
;
2815 struct bfa_fcxp_s
*fcxp
;
2817 bfa_trc(port
->fcs
, port
->pid
);
2819 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2821 port
->stats
.ms_plogi_alloc_wait
++;
2822 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
2823 bfa_fcs_lport_ms_send_plogi
, ms
);
2828 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2829 bfa_hton3b(FC_MGMT_SERVER
),
2830 bfa_fcs_lport_get_fcid(port
), 0,
2831 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
2832 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
));
2834 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2835 FC_CLASS_3
, len
, &fchs
,
2836 bfa_fcs_lport_ms_plogi_response
, (void *)ms
,
2837 FC_MAX_PDUSZ
, FC_ELS_TOV
);
2839 port
->stats
.ms_plogi_sent
++;
2840 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
2844 bfa_fcs_lport_ms_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2845 void *cbarg
, bfa_status_t req_status
,
2846 u32 rsp_len
, u32 resid_len
, struct fchs_s
*rsp_fchs
)
2848 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
2849 struct bfa_fcs_lport_s
*port
= ms
->port
;
2850 struct fc_els_cmd_s
*els_cmd
;
2851 struct fc_ls_rjt_s
*ls_rjt
;
2853 bfa_trc(port
->fcs
, req_status
);
2854 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2859 if (req_status
!= BFA_STATUS_OK
) {
2860 port
->stats
.ms_plogi_rsp_err
++;
2861 bfa_trc(port
->fcs
, req_status
);
2862 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2866 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2868 switch (els_cmd
->els_code
) {
2871 if (rsp_len
< sizeof(struct fc_logi_s
)) {
2872 bfa_trc(port
->fcs
, rsp_len
);
2873 port
->stats
.ms_plogi_acc_err
++;
2874 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2877 port
->stats
.ms_plogi_accepts
++;
2878 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
2882 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2884 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
2885 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
2887 port
->stats
.ms_rejects
++;
2888 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2892 port
->stats
.ms_plogi_unknown_rsp
++;
2893 bfa_trc(port
->fcs
, els_cmd
->els_code
);
2894 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2899 bfa_fcs_lport_ms_timeout(void *arg
)
2901 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) arg
;
2903 ms
->port
->stats
.ms_timeouts
++;
2904 bfa_sm_send_event(ms
, MSSM_EVENT_TIMEOUT
);
2909 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s
*port
)
2911 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
2914 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2917 * Invoke init routines of sub modules.
2919 bfa_fcs_lport_fdmi_init(ms
);
2923 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s
*port
)
2925 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
2928 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_OFFLINE
);
2929 bfa_fcs_lport_fdmi_offline(ms
);
2933 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s
*port
)
2935 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
2938 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_ONLINE
);
2941 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s
*port
)
2943 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
2945 /* todo. Handle this only when in Online state */
2946 if (bfa_sm_cmp_state(ms
, bfa_fcs_lport_ms_sm_online
))
2947 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_FABRIC_RSCN
);
2951 * @page ns_sm_info VPORT NS State Machine
2953 * @section ns_sm_interactions VPORT NS State Machine Interactions
2955 * @section ns_sm VPORT NS State Machine
2960 * forward declarations
2962 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg
,
2963 struct bfa_fcxp_s
*fcxp_alloced
);
2964 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg
,
2965 struct bfa_fcxp_s
*fcxp_alloced
);
2966 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg
,
2967 struct bfa_fcxp_s
*fcxp_alloced
);
2968 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg
,
2969 struct bfa_fcxp_s
*fcxp_alloced
);
2970 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg
,
2971 struct bfa_fcxp_s
*fcxp_alloced
);
2972 static void bfa_fcs_lport_ns_timeout(void *arg
);
2973 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg
,
2974 struct bfa_fcxp_s
*fcxp
,
2976 bfa_status_t req_status
,
2979 struct fchs_s
*rsp_fchs
);
2980 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg
,
2981 struct bfa_fcxp_s
*fcxp
,
2983 bfa_status_t req_status
,
2986 struct fchs_s
*rsp_fchs
);
2987 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg
,
2988 struct bfa_fcxp_s
*fcxp
,
2990 bfa_status_t req_status
,
2993 struct fchs_s
*rsp_fchs
);
2994 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg
,
2995 struct bfa_fcxp_s
*fcxp
,
2997 bfa_status_t req_status
,
3000 struct fchs_s
*rsp_fchs
);
3001 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg
,
3002 struct bfa_fcxp_s
*fcxp
,
3004 bfa_status_t req_status
,
3007 struct fchs_s
*rsp_fchs
);
3008 static void bfa_fcs_lport_ns_process_gidft_pids(
3009 struct bfa_fcs_lport_s
*port
,
3010 u32
*pid_buf
, u32 n_pids
);
3012 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t
*port
);
3014 * fcs_ns_sm FCS nameserver interface state machine
3018 * VPort NS State Machine events
3020 enum vport_ns_event
{
3021 NSSM_EVENT_PORT_ONLINE
= 1,
3022 NSSM_EVENT_PORT_OFFLINE
= 2,
3023 NSSM_EVENT_PLOGI_SENT
= 3,
3024 NSSM_EVENT_RSP_OK
= 4,
3025 NSSM_EVENT_RSP_ERROR
= 5,
3026 NSSM_EVENT_TIMEOUT
= 6,
3027 NSSM_EVENT_NS_QUERY
= 7,
3028 NSSM_EVENT_RSPNID_SENT
= 8,
3029 NSSM_EVENT_RFTID_SENT
= 9,
3030 NSSM_EVENT_RFFID_SENT
= 10,
3031 NSSM_EVENT_GIDFT_SENT
= 11,
3034 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s
*ns
,
3035 enum vport_ns_event event
);
3036 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s
*ns
,
3037 enum vport_ns_event event
);
3038 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s
*ns
,
3039 enum vport_ns_event event
);
3040 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s
*ns
,
3041 enum vport_ns_event event
);
3042 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3043 struct bfa_fcs_lport_ns_s
*ns
,
3044 enum vport_ns_event event
);
3045 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3046 enum vport_ns_event event
);
3047 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3048 enum vport_ns_event event
);
3049 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3050 struct bfa_fcs_lport_ns_s
*ns
,
3051 enum vport_ns_event event
);
3052 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3053 enum vport_ns_event event
);
3054 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3055 enum vport_ns_event event
);
3056 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3057 struct bfa_fcs_lport_ns_s
*ns
,
3058 enum vport_ns_event event
);
3059 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3060 enum vport_ns_event event
);
3061 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3062 enum vport_ns_event event
);
3063 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3064 struct bfa_fcs_lport_ns_s
*ns
,
3065 enum vport_ns_event event
);
3066 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3067 enum vport_ns_event event
);
3068 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s
*ns
,
3069 enum vport_ns_event event
);
3070 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s
*ns
,
3071 enum vport_ns_event event
);
3073 * Start in offline state - awaiting linkup
3076 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s
*ns
,
3077 enum vport_ns_event event
)
3079 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3080 bfa_trc(ns
->port
->fcs
, event
);
3083 case NSSM_EVENT_PORT_ONLINE
:
3084 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_sending
);
3085 bfa_fcs_lport_ns_send_plogi(ns
, NULL
);
3088 case NSSM_EVENT_PORT_OFFLINE
:
3092 bfa_sm_fault(ns
->port
->fcs
, event
);
3097 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s
*ns
,
3098 enum vport_ns_event event
)
3100 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3101 bfa_trc(ns
->port
->fcs
, event
);
3104 case NSSM_EVENT_PLOGI_SENT
:
3105 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi
);
3108 case NSSM_EVENT_PORT_OFFLINE
:
3109 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3110 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3115 bfa_sm_fault(ns
->port
->fcs
, event
);
3120 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s
*ns
,
3121 enum vport_ns_event event
)
3123 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3124 bfa_trc(ns
->port
->fcs
, event
);
3127 case NSSM_EVENT_RSP_ERROR
:
3129 * Start timer for a delayed retry
3131 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_retry
);
3132 ns
->port
->stats
.ns_retries
++;
3133 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3134 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3135 BFA_FCS_RETRY_TIMEOUT
);
3138 case NSSM_EVENT_RSP_OK
:
3139 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rspn_id
);
3140 bfa_fcs_lport_ns_send_rspn_id(ns
, NULL
);
3143 case NSSM_EVENT_PORT_OFFLINE
:
3144 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3145 bfa_fcxp_discard(ns
->fcxp
);
3149 bfa_sm_fault(ns
->port
->fcs
, event
);
3154 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s
*ns
,
3155 enum vport_ns_event event
)
3157 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3158 bfa_trc(ns
->port
->fcs
, event
);
3161 case NSSM_EVENT_TIMEOUT
:
3163 * Retry Timer Expired. Re-send
3165 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_sending
);
3166 bfa_fcs_lport_ns_send_plogi(ns
, NULL
);
3169 case NSSM_EVENT_PORT_OFFLINE
:
3170 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3171 bfa_timer_stop(&ns
->timer
);
3175 bfa_sm_fault(ns
->port
->fcs
, event
);
3180 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3181 enum vport_ns_event event
)
3183 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3184 bfa_trc(ns
->port
->fcs
, event
);
3187 case NSSM_EVENT_RSPNID_SENT
:
3188 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rspn_id
);
3191 case NSSM_EVENT_PORT_OFFLINE
:
3192 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3193 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3198 bfa_sm_fault(ns
->port
->fcs
, event
);
3203 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3204 enum vport_ns_event event
)
3206 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3207 bfa_trc(ns
->port
->fcs
, event
);
3210 case NSSM_EVENT_RSP_ERROR
:
3212 * Start timer for a delayed retry
3214 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rspn_id_retry
);
3215 ns
->port
->stats
.ns_retries
++;
3216 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3217 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3218 BFA_FCS_RETRY_TIMEOUT
);
3221 case NSSM_EVENT_RSP_OK
:
3222 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rft_id
);
3223 bfa_fcs_lport_ns_send_rft_id(ns
, NULL
);
3226 case NSSM_EVENT_PORT_OFFLINE
:
3227 bfa_fcxp_discard(ns
->fcxp
);
3228 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3232 bfa_sm_fault(ns
->port
->fcs
, event
);
3237 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3238 enum vport_ns_event event
)
3240 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3241 bfa_trc(ns
->port
->fcs
, event
);
3244 case NSSM_EVENT_TIMEOUT
:
3246 * Retry Timer Expired. Re-send
3248 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rspn_id
);
3249 bfa_fcs_lport_ns_send_rspn_id(ns
, NULL
);
3252 case NSSM_EVENT_PORT_OFFLINE
:
3253 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3254 bfa_timer_stop(&ns
->timer
);
3258 bfa_sm_fault(ns
->port
->fcs
, event
);
3263 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3264 enum vport_ns_event event
)
3266 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3267 bfa_trc(ns
->port
->fcs
, event
);
3270 case NSSM_EVENT_RFTID_SENT
:
3271 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rft_id
);
3274 case NSSM_EVENT_PORT_OFFLINE
:
3275 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3276 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3281 bfa_sm_fault(ns
->port
->fcs
, event
);
3286 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3287 enum vport_ns_event event
)
3289 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3290 bfa_trc(ns
->port
->fcs
, event
);
3293 case NSSM_EVENT_RSP_OK
:
3294 /* Now move to register FC4 Features */
3295 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rff_id
);
3296 bfa_fcs_lport_ns_send_rff_id(ns
, NULL
);
3299 case NSSM_EVENT_RSP_ERROR
:
3301 * Start timer for a delayed retry
3303 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rft_id_retry
);
3304 ns
->port
->stats
.ns_retries
++;
3305 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3306 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3307 BFA_FCS_RETRY_TIMEOUT
);
3310 case NSSM_EVENT_PORT_OFFLINE
:
3311 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3312 bfa_fcxp_discard(ns
->fcxp
);
3316 bfa_sm_fault(ns
->port
->fcs
, event
);
3321 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3322 enum vport_ns_event event
)
3324 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3325 bfa_trc(ns
->port
->fcs
, event
);
3328 case NSSM_EVENT_TIMEOUT
:
3329 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rft_id
);
3330 bfa_fcs_lport_ns_send_rft_id(ns
, NULL
);
3333 case NSSM_EVENT_PORT_OFFLINE
:
3334 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3335 bfa_timer_stop(&ns
->timer
);
3339 bfa_sm_fault(ns
->port
->fcs
, event
);
3344 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3345 enum vport_ns_event event
)
3347 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3348 bfa_trc(ns
->port
->fcs
, event
);
3351 case NSSM_EVENT_RFFID_SENT
:
3352 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rff_id
);
3355 case NSSM_EVENT_PORT_OFFLINE
:
3356 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3357 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3362 bfa_sm_fault(ns
->port
->fcs
, event
);
3367 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3368 enum vport_ns_event event
)
3370 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3371 bfa_trc(ns
->port
->fcs
, event
);
3374 case NSSM_EVENT_RSP_OK
:
3377 * If min cfg mode is enabled, we donot initiate rport
3378 * discovery with the fabric. Instead, we will retrieve the
3379 * boot targets from HAL/FW.
3381 if (__fcs_min_cfg(ns
->port
->fcs
)) {
3382 bfa_fcs_lport_ns_boot_target_disc(ns
->port
);
3383 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_online
);
3388 * If the port role is Initiator Mode issue NS query.
3389 * If it is Target Mode, skip this and go to online.
3391 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
3392 bfa_sm_set_state(ns
,
3393 bfa_fcs_lport_ns_sm_sending_gid_ft
);
3394 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3397 * kick off mgmt srvr state machine
3399 bfa_fcs_lport_ms_online(ns
->port
);
3402 case NSSM_EVENT_RSP_ERROR
:
3404 * Start timer for a delayed retry
3406 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rff_id_retry
);
3407 ns
->port
->stats
.ns_retries
++;
3408 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3409 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3410 BFA_FCS_RETRY_TIMEOUT
);
3413 case NSSM_EVENT_PORT_OFFLINE
:
3414 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3415 bfa_fcxp_discard(ns
->fcxp
);
3419 bfa_sm_fault(ns
->port
->fcs
, event
);
3424 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3425 enum vport_ns_event event
)
3427 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3428 bfa_trc(ns
->port
->fcs
, event
);
3431 case NSSM_EVENT_TIMEOUT
:
3432 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rff_id
);
3433 bfa_fcs_lport_ns_send_rff_id(ns
, NULL
);
3436 case NSSM_EVENT_PORT_OFFLINE
:
3437 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3438 bfa_timer_stop(&ns
->timer
);
3442 bfa_sm_fault(ns
->port
->fcs
, event
);
3446 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3447 enum vport_ns_event event
)
3449 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3450 bfa_trc(ns
->port
->fcs
, event
);
3453 case NSSM_EVENT_GIDFT_SENT
:
3454 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_gid_ft
);
3457 case NSSM_EVENT_PORT_OFFLINE
:
3458 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3459 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3464 bfa_sm_fault(ns
->port
->fcs
, event
);
3469 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3470 enum vport_ns_event event
)
3472 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3473 bfa_trc(ns
->port
->fcs
, event
);
3476 case NSSM_EVENT_RSP_OK
:
3477 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_online
);
3480 case NSSM_EVENT_RSP_ERROR
:
3482 * TBD: for certain reject codes, we don't need to retry
3485 * Start timer for a delayed retry
3487 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_gid_ft_retry
);
3488 ns
->port
->stats
.ns_retries
++;
3489 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3490 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3491 BFA_FCS_RETRY_TIMEOUT
);
3494 case NSSM_EVENT_PORT_OFFLINE
:
3495 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3496 bfa_fcxp_discard(ns
->fcxp
);
3499 case NSSM_EVENT_NS_QUERY
:
3503 bfa_sm_fault(ns
->port
->fcs
, event
);
3508 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s
*ns
,
3509 enum vport_ns_event event
)
3511 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3512 bfa_trc(ns
->port
->fcs
, event
);
3515 case NSSM_EVENT_TIMEOUT
:
3516 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_gid_ft
);
3517 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3520 case NSSM_EVENT_PORT_OFFLINE
:
3521 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3522 bfa_timer_stop(&ns
->timer
);
3526 bfa_sm_fault(ns
->port
->fcs
, event
);
3531 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s
*ns
,
3532 enum vport_ns_event event
)
3534 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3535 bfa_trc(ns
->port
->fcs
, event
);
3538 case NSSM_EVENT_PORT_OFFLINE
:
3539 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3542 case NSSM_EVENT_NS_QUERY
:
3544 * If the port role is Initiator Mode issue NS query.
3545 * If it is Target Mode, skip this and go to online.
3547 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
3548 bfa_sm_set_state(ns
,
3549 bfa_fcs_lport_ns_sm_sending_gid_ft
);
3550 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3555 bfa_sm_fault(ns
->port
->fcs
, event
);
3562 * ns_pvt Nameserver local functions
3566 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3568 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3569 struct bfa_fcs_lport_s
*port
= ns
->port
;
3572 struct bfa_fcxp_s
*fcxp
;
3574 bfa_trc(port
->fcs
, port
->pid
);
3576 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3578 port
->stats
.ns_plogi_alloc_wait
++;
3579 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3580 bfa_fcs_lport_ns_send_plogi
, ns
);
3585 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3586 bfa_hton3b(FC_NAME_SERVER
),
3587 bfa_fcs_lport_get_fcid(port
), 0,
3588 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
3589 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
));
3591 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3592 FC_CLASS_3
, len
, &fchs
,
3593 bfa_fcs_lport_ns_plogi_response
, (void *)ns
,
3594 FC_MAX_PDUSZ
, FC_ELS_TOV
);
3595 port
->stats
.ns_plogi_sent
++;
3597 bfa_sm_send_event(ns
, NSSM_EVENT_PLOGI_SENT
);
3601 bfa_fcs_lport_ns_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3602 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
3603 u32 resid_len
, struct fchs_s
*rsp_fchs
)
3605 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3606 struct bfa_fcs_lport_s
*port
= ns
->port
;
3607 /* struct fc_logi_s *plogi_resp; */
3608 struct fc_els_cmd_s
*els_cmd
;
3609 struct fc_ls_rjt_s
*ls_rjt
;
3611 bfa_trc(port
->fcs
, req_status
);
3612 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3617 if (req_status
!= BFA_STATUS_OK
) {
3618 bfa_trc(port
->fcs
, req_status
);
3619 port
->stats
.ns_plogi_rsp_err
++;
3620 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3624 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3626 switch (els_cmd
->els_code
) {
3629 if (rsp_len
< sizeof(struct fc_logi_s
)) {
3630 bfa_trc(port
->fcs
, rsp_len
);
3631 port
->stats
.ns_plogi_acc_err
++;
3632 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3635 port
->stats
.ns_plogi_accepts
++;
3636 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3640 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3642 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
3643 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
3645 port
->stats
.ns_rejects
++;
3647 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3651 port
->stats
.ns_plogi_unknown_rsp
++;
3652 bfa_trc(port
->fcs
, els_cmd
->els_code
);
3653 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3658 * Register the symbolic port name.
3661 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3663 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3664 struct bfa_fcs_lport_s
*port
= ns
->port
;
3667 struct bfa_fcxp_s
*fcxp
;
3669 u8
*psymbl
= &symbl
[0];
3671 memset(symbl
, 0, sizeof(symbl
));
3673 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3675 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3677 port
->stats
.ns_rspnid_alloc_wait
++;
3678 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3679 bfa_fcs_lport_ns_send_rspn_id
, ns
);
3685 * for V-Port, form a Port Symbolic Name
3689 * For Vports, we append the vport's port symbolic name
3690 * to that of the base port.
3693 strncpy((char *)psymbl
,
3695 (bfa_fcs_lport_get_psym_name
3696 (bfa_fcs_get_base_port(port
->fcs
))),
3698 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3701 /* Ensure we have a null terminating string. */
3702 ((char *)psymbl
)[strlen((char *) &
3703 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3705 strncat((char *)psymbl
,
3706 (char *) &(bfa_fcs_lport_get_psym_name(port
)),
3707 strlen((char *) &bfa_fcs_lport_get_psym_name(port
)));
3709 psymbl
= (u8
*) &(bfa_fcs_lport_get_psym_name(port
));
3712 len
= fc_rspnid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3713 bfa_fcs_lport_get_fcid(port
), 0, psymbl
);
3715 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3716 FC_CLASS_3
, len
, &fchs
,
3717 bfa_fcs_lport_ns_rspn_id_response
, (void *)ns
,
3718 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
3720 port
->stats
.ns_rspnid_sent
++;
3722 bfa_sm_send_event(ns
, NSSM_EVENT_RSPNID_SENT
);
3726 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3727 void *cbarg
, bfa_status_t req_status
,
3728 u32 rsp_len
, u32 resid_len
,
3729 struct fchs_s
*rsp_fchs
)
3731 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3732 struct bfa_fcs_lport_s
*port
= ns
->port
;
3733 struct ct_hdr_s
*cthdr
= NULL
;
3735 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3740 if (req_status
!= BFA_STATUS_OK
) {
3741 bfa_trc(port
->fcs
, req_status
);
3742 port
->stats
.ns_rspnid_rsp_err
++;
3743 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3747 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3748 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
3750 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
3751 port
->stats
.ns_rspnid_accepts
++;
3752 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3756 port
->stats
.ns_rspnid_rejects
++;
3757 bfa_trc(port
->fcs
, cthdr
->reason_code
);
3758 bfa_trc(port
->fcs
, cthdr
->exp_code
);
3759 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3763 * Register FC4-Types
3766 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3768 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3769 struct bfa_fcs_lport_s
*port
= ns
->port
;
3772 struct bfa_fcxp_s
*fcxp
;
3774 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3776 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3778 port
->stats
.ns_rftid_alloc_wait
++;
3779 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3780 bfa_fcs_lport_ns_send_rft_id
, ns
);
3785 len
= fc_rftid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3786 bfa_fcs_lport_get_fcid(port
), 0, port
->port_cfg
.roles
);
3788 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3789 FC_CLASS_3
, len
, &fchs
,
3790 bfa_fcs_lport_ns_rft_id_response
, (void *)ns
,
3791 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
3793 port
->stats
.ns_rftid_sent
++;
3794 bfa_sm_send_event(ns
, NSSM_EVENT_RFTID_SENT
);
3798 bfa_fcs_lport_ns_rft_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3799 void *cbarg
, bfa_status_t req_status
,
3800 u32 rsp_len
, u32 resid_len
,
3801 struct fchs_s
*rsp_fchs
)
3803 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3804 struct bfa_fcs_lport_s
*port
= ns
->port
;
3805 struct ct_hdr_s
*cthdr
= NULL
;
3807 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3812 if (req_status
!= BFA_STATUS_OK
) {
3813 bfa_trc(port
->fcs
, req_status
);
3814 port
->stats
.ns_rftid_rsp_err
++;
3815 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3819 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3820 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
3822 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
3823 port
->stats
.ns_rftid_accepts
++;
3824 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3828 port
->stats
.ns_rftid_rejects
++;
3829 bfa_trc(port
->fcs
, cthdr
->reason_code
);
3830 bfa_trc(port
->fcs
, cthdr
->exp_code
);
3831 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3835 * Register FC4-Features : Should be done after RFT_ID
3838 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3840 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3841 struct bfa_fcs_lport_s
*port
= ns
->port
;
3844 struct bfa_fcxp_s
*fcxp
;
3847 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3849 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3851 port
->stats
.ns_rffid_alloc_wait
++;
3852 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3853 bfa_fcs_lport_ns_send_rff_id
, ns
);
3858 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
))
3859 fc4_ftrs
= FC_GS_FCP_FC4_FEATURE_INITIATOR
;
3861 len
= fc_rffid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3862 bfa_fcs_lport_get_fcid(port
), 0,
3863 FC_TYPE_FCP
, fc4_ftrs
);
3865 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3866 FC_CLASS_3
, len
, &fchs
,
3867 bfa_fcs_lport_ns_rff_id_response
, (void *)ns
,
3868 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
3870 port
->stats
.ns_rffid_sent
++;
3871 bfa_sm_send_event(ns
, NSSM_EVENT_RFFID_SENT
);
3875 bfa_fcs_lport_ns_rff_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3876 void *cbarg
, bfa_status_t req_status
,
3877 u32 rsp_len
, u32 resid_len
,
3878 struct fchs_s
*rsp_fchs
)
3880 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3881 struct bfa_fcs_lport_s
*port
= ns
->port
;
3882 struct ct_hdr_s
*cthdr
= NULL
;
3884 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3889 if (req_status
!= BFA_STATUS_OK
) {
3890 bfa_trc(port
->fcs
, req_status
);
3891 port
->stats
.ns_rffid_rsp_err
++;
3892 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3896 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3897 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
3899 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
3900 port
->stats
.ns_rffid_accepts
++;
3901 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3905 port
->stats
.ns_rffid_rejects
++;
3906 bfa_trc(port
->fcs
, cthdr
->reason_code
);
3907 bfa_trc(port
->fcs
, cthdr
->exp_code
);
3909 if (cthdr
->reason_code
== CT_RSN_NOT_SUPP
) {
3910 /* if this command is not supported, we don't retry */
3911 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3913 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3916 * Query Fabric for FC4-Types Devices.
3918 * TBD : Need to use a local (FCS private) response buffer, since the response
3919 * can be larger than 2K.
3922 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3924 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3925 struct bfa_fcs_lport_s
*port
= ns
->port
;
3928 struct bfa_fcxp_s
*fcxp
;
3930 bfa_trc(port
->fcs
, port
->pid
);
3932 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3934 port
->stats
.ns_gidft_alloc_wait
++;
3935 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3936 bfa_fcs_lport_ns_send_gid_ft
, ns
);
3942 * This query is only initiated for FCP initiator mode.
3944 len
= fc_gid_ft_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3945 ns
->port
->pid
, FC_TYPE_FCP
);
3947 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3948 FC_CLASS_3
, len
, &fchs
,
3949 bfa_fcs_lport_ns_gid_ft_response
, (void *)ns
,
3950 bfa_fcxp_get_maxrsp(port
->fcs
->bfa
), FC_FCCT_TOV
);
3952 port
->stats
.ns_gidft_sent
++;
3954 bfa_sm_send_event(ns
, NSSM_EVENT_GIDFT_SENT
);
3958 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3959 void *cbarg
, bfa_status_t req_status
,
3960 u32 rsp_len
, u32 resid_len
,
3961 struct fchs_s
*rsp_fchs
)
3963 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3964 struct bfa_fcs_lport_s
*port
= ns
->port
;
3965 struct ct_hdr_s
*cthdr
= NULL
;
3968 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3973 if (req_status
!= BFA_STATUS_OK
) {
3974 bfa_trc(port
->fcs
, req_status
);
3975 port
->stats
.ns_gidft_rsp_err
++;
3976 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3980 if (resid_len
!= 0) {
3982 * TBD : we will need to allocate a larger buffer & retry the
3985 bfa_trc(port
->fcs
, rsp_len
);
3986 bfa_trc(port
->fcs
, resid_len
);
3990 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3991 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
3993 switch (cthdr
->cmd_rsp_code
) {
3997 port
->stats
.ns_gidft_accepts
++;
3998 n_pids
= (fc_get_ctresp_pyld_len(rsp_len
) / sizeof(u32
));
3999 bfa_trc(port
->fcs
, n_pids
);
4000 bfa_fcs_lport_ns_process_gidft_pids(port
,
4001 (u32
*) (cthdr
+ 1),
4003 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4009 * Check the reason code & explanation.
4010 * There may not have been any FC4 devices in the fabric
4012 port
->stats
.ns_gidft_rejects
++;
4013 bfa_trc(port
->fcs
, cthdr
->reason_code
);
4014 bfa_trc(port
->fcs
, cthdr
->exp_code
);
4016 if ((cthdr
->reason_code
== CT_RSN_UNABLE_TO_PERF
)
4017 && (cthdr
->exp_code
== CT_NS_EXP_FT_NOT_REG
)) {
4019 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4022 * for all other errors, retry
4024 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4029 port
->stats
.ns_gidft_unknown_rsp
++;
4030 bfa_trc(port
->fcs
, cthdr
->cmd_rsp_code
);
4031 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4036 * This routine will be called by bfa_timer on timer timeouts.
4038 * param[in] port - pointer to bfa_fcs_lport_t.
4043 * Special Considerations:
4048 bfa_fcs_lport_ns_timeout(void *arg
)
4050 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) arg
;
4052 ns
->port
->stats
.ns_timeouts
++;
4053 bfa_sm_send_event(ns
, NSSM_EVENT_TIMEOUT
);
4057 * Process the PID list in GID_FT response
4060 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s
*port
, u32
*pid_buf
,
4063 struct fcgs_gidft_resp_s
*gidft_entry
;
4064 struct bfa_fcs_rport_s
*rport
;
4067 for (ii
= 0; ii
< n_pids
; ii
++) {
4068 gidft_entry
= (struct fcgs_gidft_resp_s
*) &pid_buf
[ii
];
4070 if (gidft_entry
->pid
== port
->pid
)
4074 * Check if this rport already exists
4076 rport
= bfa_fcs_lport_get_rport_by_pid(port
, gidft_entry
->pid
);
4077 if (rport
== NULL
) {
4079 * this is a new device. create rport
4081 rport
= bfa_fcs_rport_create(port
, gidft_entry
->pid
);
4084 * this rport already exists
4086 bfa_fcs_rport_scn(rport
);
4089 bfa_trc(port
->fcs
, gidft_entry
->pid
);
4092 * if the last entry bit is set, bail out.
4094 if (gidft_entry
->last
)
4100 * fcs_ns_public FCS nameserver public interfaces
4104 * Functions called by port/fab.
4105 * These will send relevant Events to the ns state machine.
4108 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s
*port
)
4110 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4113 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
4117 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s
*port
)
4119 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4122 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_OFFLINE
);
4126 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s
*port
)
4128 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4131 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_ONLINE
);
4135 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s
*port
)
4137 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4139 bfa_trc(port
->fcs
, port
->pid
);
4140 bfa_sm_send_event(ns
, NSSM_EVENT_NS_QUERY
);
4144 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t
*port
)
4147 struct bfa_fcs_rport_s
*rport
;
4149 wwn_t wwns
[BFA_PREBOOT_BOOTLUN_MAX
];
4152 bfa_iocfc_get_bootwwns(port
->fcs
->bfa
, &nwwns
, wwns
);
4154 for (ii
= 0 ; ii
< nwwns
; ++ii
) {
4155 rport
= bfa_fcs_rport_create_by_wwn(port
, wwns
[ii
]);
4164 #define FC_QOS_RSCN_EVENT 0x0c
4165 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
4168 * forward declarations
4170 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg
,
4171 struct bfa_fcxp_s
*fcxp_alloced
);
4172 static void bfa_fcs_lport_scn_scr_response(void *fcsarg
,
4173 struct bfa_fcxp_s
*fcxp
,
4175 bfa_status_t req_status
,
4178 struct fchs_s
*rsp_fchs
);
4179 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s
*port
,
4180 struct fchs_s
*rx_fchs
);
4181 static void bfa_fcs_lport_scn_timeout(void *arg
);
4184 * fcs_scm_sm FCS SCN state machine
4188 * VPort SCN State Machine events
4190 enum port_scn_event
{
4191 SCNSM_EVENT_PORT_ONLINE
= 1,
4192 SCNSM_EVENT_PORT_OFFLINE
= 2,
4193 SCNSM_EVENT_RSP_OK
= 3,
4194 SCNSM_EVENT_RSP_ERROR
= 4,
4195 SCNSM_EVENT_TIMEOUT
= 5,
4196 SCNSM_EVENT_SCR_SENT
= 6,
4199 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s
*scn
,
4200 enum port_scn_event event
);
4201 static void bfa_fcs_lport_scn_sm_sending_scr(
4202 struct bfa_fcs_lport_scn_s
*scn
,
4203 enum port_scn_event event
);
4204 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s
*scn
,
4205 enum port_scn_event event
);
4206 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s
*scn
,
4207 enum port_scn_event event
);
4208 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s
*scn
,
4209 enum port_scn_event event
);
4212 * Starting state - awaiting link up.
4215 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s
*scn
,
4216 enum port_scn_event event
)
4219 case SCNSM_EVENT_PORT_ONLINE
:
4220 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_sending_scr
);
4221 bfa_fcs_lport_scn_send_scr(scn
, NULL
);
4224 case SCNSM_EVENT_PORT_OFFLINE
:
4228 bfa_sm_fault(scn
->port
->fcs
, event
);
4233 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s
*scn
,
4234 enum port_scn_event event
)
4237 case SCNSM_EVENT_SCR_SENT
:
4238 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_scr
);
4241 case SCNSM_EVENT_PORT_OFFLINE
:
4242 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4243 bfa_fcxp_walloc_cancel(scn
->port
->fcs
->bfa
, &scn
->fcxp_wqe
);
4247 bfa_sm_fault(scn
->port
->fcs
, event
);
4252 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s
*scn
,
4253 enum port_scn_event event
)
4255 struct bfa_fcs_lport_s
*port
= scn
->port
;
4258 case SCNSM_EVENT_RSP_OK
:
4259 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_online
);
4262 case SCNSM_EVENT_RSP_ERROR
:
4263 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_scr_retry
);
4264 bfa_timer_start(port
->fcs
->bfa
, &scn
->timer
,
4265 bfa_fcs_lport_scn_timeout
, scn
,
4266 BFA_FCS_RETRY_TIMEOUT
);
4269 case SCNSM_EVENT_PORT_OFFLINE
:
4270 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4271 bfa_fcxp_discard(scn
->fcxp
);
4275 bfa_sm_fault(port
->fcs
, event
);
4280 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s
*scn
,
4281 enum port_scn_event event
)
4284 case SCNSM_EVENT_TIMEOUT
:
4285 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_sending_scr
);
4286 bfa_fcs_lport_scn_send_scr(scn
, NULL
);
4289 case SCNSM_EVENT_PORT_OFFLINE
:
4290 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4291 bfa_timer_stop(&scn
->timer
);
4295 bfa_sm_fault(scn
->port
->fcs
, event
);
4300 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s
*scn
,
4301 enum port_scn_event event
)
4304 case SCNSM_EVENT_PORT_OFFLINE
:
4305 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4309 bfa_sm_fault(scn
->port
->fcs
, event
);
4316 * fcs_scn_private FCS SCN private functions
4320 * This routine will be called to send a SCR command.
4323 bfa_fcs_lport_scn_send_scr(void *scn_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
4325 struct bfa_fcs_lport_scn_s
*scn
= scn_cbarg
;
4326 struct bfa_fcs_lport_s
*port
= scn
->port
;
4329 struct bfa_fcxp_s
*fcxp
;
4331 bfa_trc(port
->fcs
, port
->pid
);
4332 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4334 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
4336 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &scn
->fcxp_wqe
,
4337 bfa_fcs_lport_scn_send_scr
, scn
);
4342 /* Handle VU registrations for Base port only */
4343 if ((!port
->vport
) && bfa_ioc_get_fcmode(&port
->fcs
->bfa
->ioc
)) {
4344 len
= fc_scr_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4345 port
->fabric
->lps
->brcd_switch
,
4348 len
= fc_scr_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4353 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
4354 FC_CLASS_3
, len
, &fchs
,
4355 bfa_fcs_lport_scn_scr_response
,
4356 (void *)scn
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
4358 bfa_sm_send_event(scn
, SCNSM_EVENT_SCR_SENT
);
4362 bfa_fcs_lport_scn_scr_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
4363 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
4364 u32 resid_len
, struct fchs_s
*rsp_fchs
)
4366 struct bfa_fcs_lport_scn_s
*scn
= (struct bfa_fcs_lport_scn_s
*) cbarg
;
4367 struct bfa_fcs_lport_s
*port
= scn
->port
;
4368 struct fc_els_cmd_s
*els_cmd
;
4369 struct fc_ls_rjt_s
*ls_rjt
;
4371 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4376 if (req_status
!= BFA_STATUS_OK
) {
4377 bfa_trc(port
->fcs
, req_status
);
4378 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4382 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4384 switch (els_cmd
->els_code
) {
4387 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_OK
);
4392 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4394 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
4395 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
4397 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4401 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4409 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s
*port
,
4410 struct fchs_s
*rx_fchs
)
4413 struct bfa_fcxp_s
*fcxp
;
4414 struct bfa_rport_s
*bfa_rport
= NULL
;
4417 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
4419 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
4423 len
= fc_ls_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4424 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
4427 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
4428 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
4433 * This routine will be called by bfa_timer on timer timeouts.
4435 * param[in] vport - pointer to bfa_fcs_lport_t.
4436 * param[out] vport_status - pointer to return vport status in
4441 * Special Considerations:
4446 bfa_fcs_lport_scn_timeout(void *arg
)
4448 struct bfa_fcs_lport_scn_s
*scn
= (struct bfa_fcs_lport_scn_s
*) arg
;
4450 bfa_sm_send_event(scn
, SCNSM_EVENT_TIMEOUT
);
4456 * fcs_scn_public FCS state change notification public interfaces
4460 * Functions called by port/fab
4463 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s
*port
)
4465 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4468 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4472 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s
*port
)
4474 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4477 bfa_sm_send_event(scn
, SCNSM_EVENT_PORT_OFFLINE
);
4481 bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s
*port
)
4483 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4486 bfa_sm_send_event(scn
, SCNSM_EVENT_PORT_ONLINE
);
4490 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s
*port
, u32 rpid
)
4492 struct bfa_fcs_rport_s
*rport
;
4494 bfa_trc(port
->fcs
, rpid
);
4497 * If this is an unknown device, then it just came online.
4498 * Otherwise let rport handle the RSCN event.
4500 rport
= bfa_fcs_lport_get_rport_by_pid(port
, rpid
);
4501 if (rport
== NULL
) {
4503 * If min cfg mode is enabled, we donot need to
4504 * discover any new rports.
4506 if (!__fcs_min_cfg(port
->fcs
))
4507 rport
= bfa_fcs_rport_create(port
, rpid
);
4509 bfa_fcs_rport_scn(rport
);
4513 * rscn format based PID comparison
4515 #define __fc_pid_match(__c0, __c1, __fmt) \
4516 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
4517 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
4518 ((__c0)[0] == (__c1)[0])) || \
4519 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
4520 ((__c0)[0] == (__c1)[0]) && \
4521 ((__c0)[1] == (__c1)[1])))
4524 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s
*port
,
4525 enum fc_rscn_format format
,
4528 struct bfa_fcs_rport_s
*rport
;
4529 struct list_head
*qe
, *qe_next
;
4532 bfa_trc(port
->fcs
, format
);
4533 bfa_trc(port
->fcs
, rscn_pid
);
4535 c0
= (u8
*) &rscn_pid
;
4537 list_for_each_safe(qe
, qe_next
, &port
->rport_q
) {
4538 rport
= (struct bfa_fcs_rport_s
*) qe
;
4539 c1
= (u8
*) &rport
->pid
;
4540 if (__fc_pid_match(c0
, c1
, format
))
4541 bfa_fcs_rport_scn(rport
);
4547 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s
*port
,
4548 struct fchs_s
*fchs
, u32 len
)
4550 struct fc_rscn_pl_s
*rscn
= (struct fc_rscn_pl_s
*) (fchs
+ 1);
4553 bfa_boolean_t nsquery
= BFA_FALSE
, found
;
4557 (be16_to_cpu(rscn
->payldlen
) -
4558 sizeof(u32
)) / sizeof(rscn
->event
[0]);
4560 bfa_trc(port
->fcs
, num_entries
);
4562 port
->stats
.num_rscn
++;
4564 bfa_fcs_lport_scn_send_ls_acc(port
, fchs
);
4566 for (i
= 0; i
< num_entries
; i
++) {
4567 rscn_pid
= rscn
->event
[i
].portid
;
4569 bfa_trc(port
->fcs
, rscn
->event
[i
].format
);
4570 bfa_trc(port
->fcs
, rscn_pid
);
4572 /* check for duplicate entries in the list */
4574 for (j
= 0; j
< i
; j
++) {
4575 if (rscn
->event
[j
].portid
== rscn_pid
) {
4581 /* if found in down the list, pid has been already processed */
4583 bfa_trc(port
->fcs
, rscn_pid
);
4587 switch (rscn
->event
[i
].format
) {
4588 case FC_RSCN_FORMAT_PORTID
:
4589 if (rscn
->event
[i
].qualifier
== FC_QOS_RSCN_EVENT
) {
4591 * Ignore this event.
4592 * f/w would have processed it
4594 bfa_trc(port
->fcs
, rscn_pid
);
4596 port
->stats
.num_portid_rscn
++;
4597 bfa_fcs_lport_scn_portid_rscn(port
, rscn_pid
);
4601 case FC_RSCN_FORMAT_FABRIC
:
4602 if (rscn
->event
[i
].qualifier
==
4603 FC_FABRIC_NAME_RSCN_EVENT
) {
4604 bfa_fcs_lport_ms_fabric_rscn(port
);
4607 /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4609 case FC_RSCN_FORMAT_AREA
:
4610 case FC_RSCN_FORMAT_DOMAIN
:
4612 bfa_fcs_lport_scn_multiport_rscn(port
,
4613 rscn
->event
[i
].format
,
4625 * If any of area, domain or fabric RSCN is received, do a fresh
4626 * discovery to find new devices.
4629 bfa_fcs_lport_ns_query(port
);
4636 * fcs_port_api BFA FCS port API
4638 struct bfa_fcs_lport_s
*
4639 bfa_fcs_get_base_port(struct bfa_fcs_s
*fcs
)
4641 return &fcs
->fabric
.bport
;
4645 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s
*port
, wwn_t wwn
, int index
,
4646 int nrports
, bfa_boolean_t bwwn
)
4648 struct list_head
*qh
, *qe
;
4649 struct bfa_fcs_rport_s
*rport
= NULL
;
4651 struct bfa_fcs_s
*fcs
;
4653 if (port
== NULL
|| nrports
== 0)
4657 bfa_trc(fcs
, (u32
) nrports
);
4660 qh
= &port
->rport_q
;
4661 qe
= bfa_q_first(qh
);
4663 while ((qe
!= qh
) && (i
< nrports
)) {
4664 rport
= (struct bfa_fcs_rport_s
*) qe
;
4665 if (bfa_ntoh3b(rport
->pid
) > 0xFFF000) {
4666 qe
= bfa_q_next(qe
);
4667 bfa_trc(fcs
, (u32
) rport
->pwwn
);
4668 bfa_trc(fcs
, rport
->pid
);
4674 if (!memcmp(&wwn
, &rport
->pwwn
, 8))
4682 qe
= bfa_q_next(qe
);
4693 bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s
*port
,
4694 wwn_t rport_wwns
[], int *nrports
)
4696 struct list_head
*qh
, *qe
;
4697 struct bfa_fcs_rport_s
*rport
= NULL
;
4699 struct bfa_fcs_s
*fcs
;
4701 if (port
== NULL
|| rport_wwns
== NULL
|| *nrports
== 0)
4705 bfa_trc(fcs
, (u32
) *nrports
);
4708 qh
= &port
->rport_q
;
4709 qe
= bfa_q_first(qh
);
4711 while ((qe
!= qh
) && (i
< *nrports
)) {
4712 rport
= (struct bfa_fcs_rport_s
*) qe
;
4713 if (bfa_ntoh3b(rport
->pid
) > 0xFFF000) {
4714 qe
= bfa_q_next(qe
);
4715 bfa_trc(fcs
, (u32
) rport
->pwwn
);
4716 bfa_trc(fcs
, rport
->pid
);
4721 rport_wwns
[i
] = rport
->pwwn
;
4724 qe
= bfa_q_next(qe
);
4732 * Iterate's through all the rport's in the given port to
4733 * determine the maximum operating speed.
4735 * !!!! To be used in TRL Functionality only !!!!
4738 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t
*port
)
4740 struct list_head
*qh
, *qe
;
4741 struct bfa_fcs_rport_s
*rport
= NULL
;
4742 struct bfa_fcs_s
*fcs
;
4743 bfa_port_speed_t max_speed
= 0;
4744 struct bfa_port_attr_s port_attr
;
4745 bfa_port_speed_t port_speed
, rport_speed
;
4746 bfa_boolean_t trl_enabled
= bfa_fcport_is_ratelim(port
->fcs
->bfa
);
4754 /* Get Physical port's current speed */
4755 bfa_fcport_get_attr(port
->fcs
->bfa
, &port_attr
);
4756 port_speed
= port_attr
.speed
;
4757 bfa_trc(fcs
, port_speed
);
4759 qh
= &port
->rport_q
;
4760 qe
= bfa_q_first(qh
);
4763 rport
= (struct bfa_fcs_rport_s
*) qe
;
4764 if ((bfa_ntoh3b(rport
->pid
) > 0xFFF000) ||
4765 (bfa_fcs_rport_get_state(rport
) ==
4766 BFA_RPORT_OFFLINE
)) {
4767 qe
= bfa_q_next(qe
);
4771 rport_speed
= rport
->rpf
.rpsc_speed
;
4772 if ((trl_enabled
) && (rport_speed
==
4773 BFA_PORT_SPEED_UNKNOWN
)) {
4774 /* Use default ratelim speed setting */
4776 bfa_fcport_get_ratelim_speed(port
->fcs
->bfa
);
4779 if ((rport_speed
== BFA_PORT_SPEED_8GBPS
) ||
4780 (rport_speed
> port_speed
)) {
4781 max_speed
= rport_speed
;
4783 } else if (rport_speed
> max_speed
) {
4784 max_speed
= rport_speed
;
4787 qe
= bfa_q_next(qe
);
4790 bfa_trc(fcs
, max_speed
);
4794 struct bfa_fcs_lport_s
*
4795 bfa_fcs_lookup_port(struct bfa_fcs_s
*fcs
, u16 vf_id
, wwn_t lpwwn
)
4797 struct bfa_fcs_vport_s
*vport
;
4800 WARN_ON(fcs
== NULL
);
4802 vf
= bfa_fcs_vf_lookup(fcs
, vf_id
);
4804 bfa_trc(fcs
, vf_id
);
4808 if (!lpwwn
|| (vf
->bport
.port_cfg
.pwwn
== lpwwn
))
4811 vport
= bfa_fcs_fabric_vport_lookup(vf
, lpwwn
);
4813 return &vport
->lport
;
4819 * API corresponding to NPIV_VPORT_GETINFO.
4822 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s
*port
,
4823 struct bfa_lport_info_s
*port_info
)
4826 bfa_trc(port
->fcs
, port
->fabric
->fabric_name
);
4828 if (port
->vport
== NULL
) {
4830 * This is a Physical port
4832 port_info
->port_type
= BFA_LPORT_TYPE_PHYSICAL
;
4835 * @todo : need to fix the state & reason
4837 port_info
->port_state
= 0;
4838 port_info
->offline_reason
= 0;
4840 port_info
->port_wwn
= bfa_fcs_lport_get_pwwn(port
);
4841 port_info
->node_wwn
= bfa_fcs_lport_get_nwwn(port
);
4843 port_info
->max_vports_supp
=
4844 bfa_lps_get_max_vport(port
->fcs
->bfa
);
4845 port_info
->num_vports_inuse
=
4846 port
->fabric
->num_vports
;
4847 port_info
->max_rports_supp
= BFA_FCS_MAX_RPORTS_SUPP
;
4848 port_info
->num_rports_inuse
= port
->num_rports
;
4851 * This is a virtual port
4853 port_info
->port_type
= BFA_LPORT_TYPE_VIRTUAL
;
4856 * @todo : need to fix the state & reason
4858 port_info
->port_state
= 0;
4859 port_info
->offline_reason
= 0;
4861 port_info
->port_wwn
= bfa_fcs_lport_get_pwwn(port
);
4862 port_info
->node_wwn
= bfa_fcs_lport_get_nwwn(port
);
4867 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s
*fcs_port
,
4868 struct bfa_lport_stats_s
*port_stats
)
4870 *port_stats
= fcs_port
->stats
;
4874 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s
*fcs_port
)
4876 memset(&fcs_port
->stats
, 0, sizeof(struct bfa_lport_stats_s
));
4880 * FCS virtual port state machine
4883 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
4884 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
4885 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
4886 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
4887 #define __vport_fcid(__vp) ((__vp)->lport.pid)
4888 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
4889 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
4891 #define BFA_FCS_VPORT_MAX_RETRIES 5
4893 * Forward declarations
4895 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s
*vport
);
4896 static void bfa_fcs_vport_timeout(void *vport_arg
);
4897 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s
*vport
);
4898 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s
*vport
);
4901 * fcs_vport_sm FCS virtual port state machine
4905 * VPort State Machine events
4907 enum bfa_fcs_vport_event
{
4908 BFA_FCS_VPORT_SM_CREATE
= 1, /* vport create event */
4909 BFA_FCS_VPORT_SM_DELETE
= 2, /* vport delete event */
4910 BFA_FCS_VPORT_SM_START
= 3, /* vport start request */
4911 BFA_FCS_VPORT_SM_STOP
= 4, /* stop: unsupported */
4912 BFA_FCS_VPORT_SM_ONLINE
= 5, /* fabric online */
4913 BFA_FCS_VPORT_SM_OFFLINE
= 6, /* fabric offline event */
4914 BFA_FCS_VPORT_SM_FRMSENT
= 7, /* fdisc/logo sent events */
4915 BFA_FCS_VPORT_SM_RSP_OK
= 8, /* good response */
4916 BFA_FCS_VPORT_SM_RSP_ERROR
= 9, /* error/bad response */
4917 BFA_FCS_VPORT_SM_TIMEOUT
= 10, /* delay timer event */
4918 BFA_FCS_VPORT_SM_DELCOMP
= 11, /* lport delete completion */
4919 BFA_FCS_VPORT_SM_RSP_DUP_WWN
= 12, /* Dup wnn error*/
4920 BFA_FCS_VPORT_SM_RSP_FAILED
= 13, /* non-retryable failure */
4923 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s
*vport
,
4924 enum bfa_fcs_vport_event event
);
4925 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s
*vport
,
4926 enum bfa_fcs_vport_event event
);
4927 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s
*vport
,
4928 enum bfa_fcs_vport_event event
);
4929 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s
*vport
,
4930 enum bfa_fcs_vport_event event
);
4931 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s
*vport
,
4932 enum bfa_fcs_vport_event event
);
4933 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s
*vport
,
4934 enum bfa_fcs_vport_event event
);
4935 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s
*vport
,
4936 enum bfa_fcs_vport_event event
);
4937 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s
*vport
,
4938 enum bfa_fcs_vport_event event
);
4939 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s
*vport
,
4940 enum bfa_fcs_vport_event event
);
4941 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s
*vport
,
4942 enum bfa_fcs_vport_event event
);
4944 static struct bfa_sm_table_s vport_sm_table
[] = {
4945 {BFA_SM(bfa_fcs_vport_sm_uninit
), BFA_FCS_VPORT_UNINIT
},
4946 {BFA_SM(bfa_fcs_vport_sm_created
), BFA_FCS_VPORT_CREATED
},
4947 {BFA_SM(bfa_fcs_vport_sm_offline
), BFA_FCS_VPORT_OFFLINE
},
4948 {BFA_SM(bfa_fcs_vport_sm_fdisc
), BFA_FCS_VPORT_FDISC
},
4949 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry
), BFA_FCS_VPORT_FDISC_RETRY
},
4950 {BFA_SM(bfa_fcs_vport_sm_online
), BFA_FCS_VPORT_ONLINE
},
4951 {BFA_SM(bfa_fcs_vport_sm_deleting
), BFA_FCS_VPORT_DELETING
},
4952 {BFA_SM(bfa_fcs_vport_sm_cleanup
), BFA_FCS_VPORT_CLEANUP
},
4953 {BFA_SM(bfa_fcs_vport_sm_logo
), BFA_FCS_VPORT_LOGO
},
4954 {BFA_SM(bfa_fcs_vport_sm_error
), BFA_FCS_VPORT_ERROR
}
4961 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s
*vport
,
4962 enum bfa_fcs_vport_event event
)
4964 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
4965 bfa_trc(__vport_fcs(vport
), event
);
4968 case BFA_FCS_VPORT_SM_CREATE
:
4969 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_created
);
4970 bfa_fcs_fabric_addvport(__vport_fabric(vport
), vport
);
4974 bfa_sm_fault(__vport_fcs(vport
), event
);
4979 * Created state - a start event is required to start up the state machine.
4982 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s
*vport
,
4983 enum bfa_fcs_vport_event event
)
4985 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
4986 bfa_trc(__vport_fcs(vport
), event
);
4989 case BFA_FCS_VPORT_SM_START
:
4990 if (bfa_sm_cmp_state(__vport_fabric(vport
),
4991 bfa_fcs_fabric_sm_online
)
4992 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport
))) {
4993 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
4994 bfa_fcs_vport_do_fdisc(vport
);
4997 * Fabric is offline or not NPIV capable, stay in
5000 vport
->vport_stats
.fab_no_npiv
++;
5001 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5005 case BFA_FCS_VPORT_SM_DELETE
:
5006 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5007 bfa_fcs_lport_delete(&vport
->lport
);
5010 case BFA_FCS_VPORT_SM_ONLINE
:
5011 case BFA_FCS_VPORT_SM_OFFLINE
:
5013 * Ignore ONLINE/OFFLINE events from fabric
5014 * till vport is started.
5019 bfa_sm_fault(__vport_fcs(vport
), event
);
5024 * Offline state - awaiting ONLINE event from fabric SM.
5027 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s
*vport
,
5028 enum bfa_fcs_vport_event event
)
5030 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5031 bfa_trc(__vport_fcs(vport
), event
);
5034 case BFA_FCS_VPORT_SM_DELETE
:
5035 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5036 bfa_fcs_lport_delete(&vport
->lport
);
5039 case BFA_FCS_VPORT_SM_ONLINE
:
5040 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
5041 vport
->fdisc_retries
= 0;
5042 bfa_fcs_vport_do_fdisc(vport
);
5045 case BFA_FCS_VPORT_SM_OFFLINE
:
5047 * This can happen if the vport couldn't be initialzied
5048 * due the fact that the npiv was not enabled on the switch.
5049 * In that case we will put the vport in offline state.
5050 * However, the link can go down and cause the this event to
5051 * be sent when we are already offline. Ignore it.
5056 bfa_sm_fault(__vport_fcs(vport
), event
);
5062 * FDISC is sent and awaiting reply from fabric.
5065 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s
*vport
,
5066 enum bfa_fcs_vport_event event
)
5068 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5069 bfa_trc(__vport_fcs(vport
), event
);
5072 case BFA_FCS_VPORT_SM_DELETE
:
5073 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5074 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5075 bfa_fcs_lport_delete(&vport
->lport
);
5078 case BFA_FCS_VPORT_SM_OFFLINE
:
5079 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5080 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5083 case BFA_FCS_VPORT_SM_RSP_OK
:
5084 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_online
);
5085 bfa_fcs_lport_online(&vport
->lport
);
5088 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5089 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc_retry
);
5090 bfa_timer_start(__vport_bfa(vport
), &vport
->timer
,
5091 bfa_fcs_vport_timeout
, vport
,
5092 BFA_FCS_RETRY_TIMEOUT
);
5095 case BFA_FCS_VPORT_SM_RSP_FAILED
:
5096 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5099 case BFA_FCS_VPORT_SM_RSP_DUP_WWN
:
5100 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_error
);
5104 bfa_sm_fault(__vport_fcs(vport
), event
);
5109 * FDISC attempt failed - a timer is active to retry FDISC.
5112 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s
*vport
,
5113 enum bfa_fcs_vport_event event
)
5115 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5116 bfa_trc(__vport_fcs(vport
), event
);
5119 case BFA_FCS_VPORT_SM_DELETE
:
5120 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5121 bfa_timer_stop(&vport
->timer
);
5122 bfa_fcs_lport_delete(&vport
->lport
);
5125 case BFA_FCS_VPORT_SM_OFFLINE
:
5126 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5127 bfa_timer_stop(&vport
->timer
);
5130 case BFA_FCS_VPORT_SM_TIMEOUT
:
5131 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
5132 vport
->vport_stats
.fdisc_retries
++;
5133 vport
->fdisc_retries
++;
5134 bfa_fcs_vport_do_fdisc(vport
);
5138 bfa_sm_fault(__vport_fcs(vport
), event
);
5143 * Vport is online (FDISC is complete).
5146 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s
*vport
,
5147 enum bfa_fcs_vport_event event
)
5149 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5150 bfa_trc(__vport_fcs(vport
), event
);
5153 case BFA_FCS_VPORT_SM_DELETE
:
5154 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_deleting
);
5155 bfa_fcs_lport_delete(&vport
->lport
);
5158 case BFA_FCS_VPORT_SM_OFFLINE
:
5159 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5160 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5161 bfa_fcs_lport_offline(&vport
->lport
);
5165 bfa_sm_fault(__vport_fcs(vport
), event
);
5170 * Vport is being deleted - awaiting lport delete completion to send
5174 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s
*vport
,
5175 enum bfa_fcs_vport_event event
)
5177 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5178 bfa_trc(__vport_fcs(vport
), event
);
5181 case BFA_FCS_VPORT_SM_DELETE
:
5184 case BFA_FCS_VPORT_SM_DELCOMP
:
5185 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_logo
);
5186 bfa_fcs_vport_do_logo(vport
);
5189 case BFA_FCS_VPORT_SM_OFFLINE
:
5190 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5194 bfa_sm_fault(__vport_fcs(vport
), event
);
5200 * This state will be set when the Vport Creation fails due
5201 * to errors like Dup WWN. In this state only operation allowed
5202 * is a Vport Delete.
5205 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s
*vport
,
5206 enum bfa_fcs_vport_event event
)
5208 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5209 bfa_trc(__vport_fcs(vport
), event
);
5212 case BFA_FCS_VPORT_SM_DELETE
:
5213 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5214 bfa_fcs_lport_delete(&vport
->lport
);
5218 bfa_trc(__vport_fcs(vport
), event
);
5223 * Lport cleanup is in progress since vport is being deleted. Fabric is
5224 * offline, so no LOGO is needed to complete vport deletion.
5227 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s
*vport
,
5228 enum bfa_fcs_vport_event event
)
5230 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5231 bfa_trc(__vport_fcs(vport
), event
);
5234 case BFA_FCS_VPORT_SM_DELCOMP
:
5235 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5236 bfa_fcs_vport_free(vport
);
5239 case BFA_FCS_VPORT_SM_DELETE
:
5243 bfa_sm_fault(__vport_fcs(vport
), event
);
5248 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5252 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s
*vport
,
5253 enum bfa_fcs_vport_event event
)
5255 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5256 bfa_trc(__vport_fcs(vport
), event
);
5259 case BFA_FCS_VPORT_SM_OFFLINE
:
5260 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5262 * !!! fall through !!!
5265 case BFA_FCS_VPORT_SM_RSP_OK
:
5266 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5267 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5268 bfa_fcs_vport_free(vport
);
5271 case BFA_FCS_VPORT_SM_DELETE
:
5275 bfa_sm_fault(__vport_fcs(vport
), event
);
5282 * fcs_vport_private FCS virtual port private functions
5285 * This routine will be called to send a FDISC command.
5288 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s
*vport
)
5290 bfa_lps_fdisc(vport
->lps
, vport
,
5291 bfa_fcport_get_maxfrsize(__vport_bfa(vport
)),
5292 __vport_pwwn(vport
), __vport_nwwn(vport
));
5293 vport
->vport_stats
.fdisc_sent
++;
5297 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s
*vport
)
5299 u8 lsrjt_rsn
= vport
->lps
->lsrjt_rsn
;
5300 u8 lsrjt_expl
= vport
->lps
->lsrjt_expl
;
5302 bfa_trc(__vport_fcs(vport
), lsrjt_rsn
);
5303 bfa_trc(__vport_fcs(vport
), lsrjt_expl
);
5305 /* For certain reason codes, we don't want to retry. */
5306 switch (vport
->lps
->lsrjt_expl
) {
5307 case FC_LS_RJT_EXP_INV_PORT_NAME
: /* by brocade */
5308 case FC_LS_RJT_EXP_INVALID_NPORT_ID
: /* by Cisco */
5309 if (vport
->fdisc_retries
< BFA_FCS_VPORT_MAX_RETRIES
)
5310 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5312 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_DUP_WWN
);
5315 case FC_LS_RJT_EXP_INSUFF_RES
:
5317 * This means max logins per port/switch setting on the
5318 * switch was exceeded.
5320 if (vport
->fdisc_retries
< BFA_FCS_VPORT_MAX_RETRIES
)
5321 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5323 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_FAILED
);
5327 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5332 * Called to send a logout to the fabric. Used when a V-Port is
5336 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s
*vport
)
5338 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5340 vport
->vport_stats
.logo_sent
++;
5341 bfa_lps_fdisclogo(vport
->lps
);
5346 * This routine will be called by bfa_timer on timer timeouts.
5348 * param[in] vport - pointer to bfa_fcs_vport_t.
5349 * param[out] vport_status - pointer to return vport status in
5354 * Special Considerations:
5359 bfa_fcs_vport_timeout(void *vport_arg
)
5361 struct bfa_fcs_vport_s
*vport
= (struct bfa_fcs_vport_s
*) vport_arg
;
5363 vport
->vport_stats
.fdisc_timeouts
++;
5364 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_TIMEOUT
);
5368 bfa_fcs_vport_free(struct bfa_fcs_vport_s
*vport
)
5370 struct bfad_vport_s
*vport_drv
=
5371 (struct bfad_vport_s
*)vport
->vport_drv
;
5373 bfa_fcs_fabric_delvport(__vport_fabric(vport
), vport
);
5375 if (vport_drv
->comp_del
)
5376 complete(vport_drv
->comp_del
);
5378 bfa_lps_delete(vport
->lps
);
5384 * fcs_vport_public FCS virtual port public interfaces
5388 * Online notification from fabric SM.
5391 bfa_fcs_vport_online(struct bfa_fcs_vport_s
*vport
)
5393 vport
->vport_stats
.fab_online
++;
5394 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_ONLINE
);
5398 * Offline notification from fabric SM.
5401 bfa_fcs_vport_offline(struct bfa_fcs_vport_s
*vport
)
5403 vport
->vport_stats
.fab_offline
++;
5404 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_OFFLINE
);
5408 * Cleanup notification from fabric SM on link timer expiry.
5411 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s
*vport
)
5413 vport
->vport_stats
.fab_cleanup
++;
5416 * delete notification from fabric SM. To be invoked from within FCS.
5419 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s
*vport
)
5421 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELETE
);
5425 * Delete completion callback from associated lport
5428 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s
*vport
)
5430 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELCOMP
);
5436 * fcs_vport_api Virtual port API
5440 * Use this function to instantiate a new FCS vport object. This
5441 * function will not trigger any HW initialization process (which will be
5442 * done in vport_start() call)
5444 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5445 * needs to be allocated by the driver.
5446 * param[in] fcs - FCS instance
5447 * param[in] vport_cfg - vport configuration
5448 * param[in] vf_id - VF_ID if vport is created within a VF.
5449 * FC_VF_ID_NULL to specify base fabric.
5450 * param[in] vport_drv - Opaque handle back to the driver's vport
5453 * retval BFA_STATUS_OK - on success.
5454 * retval BFA_STATUS_FAILED - on failure.
5457 bfa_fcs_vport_create(struct bfa_fcs_vport_s
*vport
, struct bfa_fcs_s
*fcs
,
5458 u16 vf_id
, struct bfa_lport_cfg_s
*vport_cfg
,
5459 struct bfad_vport_s
*vport_drv
)
5461 if (vport_cfg
->pwwn
== 0)
5462 return BFA_STATUS_INVALID_WWN
;
5464 if (bfa_fcs_lport_get_pwwn(&fcs
->fabric
.bport
) == vport_cfg
->pwwn
)
5465 return BFA_STATUS_VPORT_WWN_BP
;
5467 if (bfa_fcs_vport_lookup(fcs
, vf_id
, vport_cfg
->pwwn
) != NULL
)
5468 return BFA_STATUS_VPORT_EXISTS
;
5470 if (fcs
->fabric
.num_vports
==
5471 bfa_lps_get_max_vport(fcs
->bfa
))
5472 return BFA_STATUS_VPORT_MAX
;
5474 vport
->lps
= bfa_lps_alloc(fcs
->bfa
);
5476 return BFA_STATUS_VPORT_MAX
;
5478 vport
->vport_drv
= vport_drv
;
5479 vport_cfg
->preboot_vp
= BFA_FALSE
;
5481 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5482 bfa_fcs_lport_attach(&vport
->lport
, fcs
, vf_id
, vport
);
5483 bfa_fcs_lport_init(&vport
->lport
, vport_cfg
);
5484 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_CREATE
);
5486 return BFA_STATUS_OK
;
5490 * Use this function to instantiate a new FCS PBC vport object. This
5491 * function will not trigger any HW initialization process (which will be
5492 * done in vport_start() call)
5494 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5495 * needs to be allocated by the driver.
5496 * param[in] fcs - FCS instance
5497 * param[in] vport_cfg - vport configuration
5498 * param[in] vf_id - VF_ID if vport is created within a VF.
5499 * FC_VF_ID_NULL to specify base fabric.
5500 * param[in] vport_drv - Opaque handle back to the driver's vport
5503 * retval BFA_STATUS_OK - on success.
5504 * retval BFA_STATUS_FAILED - on failure.
5507 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s
*vport
, struct bfa_fcs_s
*fcs
,
5508 u16 vf_id
, struct bfa_lport_cfg_s
*vport_cfg
,
5509 struct bfad_vport_s
*vport_drv
)
5513 rc
= bfa_fcs_vport_create(vport
, fcs
, vf_id
, vport_cfg
, vport_drv
);
5514 vport
->lport
.port_cfg
.preboot_vp
= BFA_TRUE
;
5520 * Use this function to findout if this is a pbc vport or not.
5522 * @param[in] vport - pointer to bfa_fcs_vport_t.
5527 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s
*vport
)
5530 if (vport
&& (vport
->lport
.port_cfg
.preboot_vp
== BFA_TRUE
))
5538 * Use this function initialize the vport.
5540 * @param[in] vport - pointer to bfa_fcs_vport_t.
5545 bfa_fcs_vport_start(struct bfa_fcs_vport_s
*vport
)
5547 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_START
);
5549 return BFA_STATUS_OK
;
5553 * Use this function quiese the vport object. This function will return
5554 * immediately, when the vport is actually stopped, the
5555 * bfa_drv_vport_stop_cb() will be called.
5557 * param[in] vport - pointer to bfa_fcs_vport_t.
5562 bfa_fcs_vport_stop(struct bfa_fcs_vport_s
*vport
)
5564 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_STOP
);
5566 return BFA_STATUS_OK
;
5570 * Use this function to delete a vport object. Fabric object should
5571 * be stopped before this function call.
5573 * !!!!!!! Donot invoke this from within FCS !!!!!!!
5575 * param[in] vport - pointer to bfa_fcs_vport_t.
5580 bfa_fcs_vport_delete(struct bfa_fcs_vport_s
*vport
)
5583 if (vport
->lport
.port_cfg
.preboot_vp
)
5584 return BFA_STATUS_PBC
;
5586 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELETE
);
5588 return BFA_STATUS_OK
;
5592 * Use this function to get vport's current status info.
5594 * param[in] vport pointer to bfa_fcs_vport_t.
5595 * param[out] attr pointer to return vport attributes
5600 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s
*vport
,
5601 struct bfa_vport_attr_s
*attr
)
5603 if (vport
== NULL
|| attr
== NULL
)
5606 memset(attr
, 0, sizeof(struct bfa_vport_attr_s
));
5608 bfa_fcs_lport_get_attr(&vport
->lport
, &attr
->port_attr
);
5609 attr
->vport_state
= bfa_sm_to_state(vport_sm_table
, vport
->sm
);
5614 * Lookup a virtual port. Excludes base port from lookup.
5616 struct bfa_fcs_vport_s
*
5617 bfa_fcs_vport_lookup(struct bfa_fcs_s
*fcs
, u16 vf_id
, wwn_t vpwwn
)
5619 struct bfa_fcs_vport_s
*vport
;
5620 struct bfa_fcs_fabric_s
*fabric
;
5622 bfa_trc(fcs
, vf_id
);
5623 bfa_trc(fcs
, vpwwn
);
5625 fabric
= bfa_fcs_vf_lookup(fcs
, vf_id
);
5627 bfa_trc(fcs
, vf_id
);
5631 vport
= bfa_fcs_fabric_vport_lookup(fabric
, vpwwn
);
5639 bfa_cb_lps_fdisc_comp(void *bfad
, void *uarg
, bfa_status_t status
)
5641 struct bfa_fcs_vport_s
*vport
= uarg
;
5643 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5644 bfa_trc(__vport_fcs(vport
), status
);
5649 * Initialize the V-Port fields
5651 __vport_fcid(vport
) = vport
->lps
->lp_pid
;
5652 vport
->vport_stats
.fdisc_accepts
++;
5653 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_OK
);
5656 case BFA_STATUS_INVALID_MAC
:
5658 vport
->vport_stats
.fdisc_acc_bad
++;
5659 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5663 case BFA_STATUS_EPROTOCOL
:
5664 switch (vport
->lps
->ext_status
) {
5665 case BFA_EPROTO_BAD_ACCEPT
:
5666 vport
->vport_stats
.fdisc_acc_bad
++;
5669 case BFA_EPROTO_UNKNOWN_RSP
:
5670 vport
->vport_stats
.fdisc_unknown_rsp
++;
5677 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5680 case BFA_STATUS_FABRIC_RJT
:
5681 vport
->vport_stats
.fdisc_rejects
++;
5682 bfa_fcs_vport_fdisc_rejected(vport
);
5686 vport
->vport_stats
.fdisc_rsp_err
++;
5687 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5695 bfa_cb_lps_fdisclogo_comp(void *bfad
, void *uarg
)
5697 struct bfa_fcs_vport_s
*vport
= uarg
;
5698 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_OK
);
5702 * Received clear virtual link
5705 bfa_cb_lps_cvl_event(void *bfad
, void *uarg
)
5707 struct bfa_fcs_vport_s
*vport
= uarg
;
5709 /* Send an Offline followed by an ONLINE */
5710 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_OFFLINE
);
5711 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_ONLINE
);