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.
21 #include "bfa_fcbuild.h"
24 BFA_TRC_FILE(FCS
, PORT
);
26 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s
*port
,
27 struct fchs_s
*rx_fchs
, u8 reason_code
,
29 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s
*port
,
30 struct fchs_s
*rx_fchs
, struct fc_logi_s
*plogi
);
31 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s
*port
);
32 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s
*port
);
33 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s
*port
);
34 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s
*port
);
35 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s
*port
);
36 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s
*port
);
37 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s
*port
,
38 struct fchs_s
*rx_fchs
,
39 struct fc_echo_s
*echo
, u16 len
);
40 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s
*port
,
41 struct fchs_s
*rx_fchs
,
42 struct fc_rnid_cmd_s
*rnid
, u16 len
);
43 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s
*port
,
44 struct fc_rnid_general_topology_data_s
*gen_topo_data
);
46 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s
*port
);
47 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s
*port
);
48 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s
*port
);
50 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s
*port
);
51 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s
*port
);
52 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s
*port
);
55 void (*init
) (struct bfa_fcs_lport_s
*port
);
56 void (*online
) (struct bfa_fcs_lport_s
*port
);
57 void (*offline
) (struct bfa_fcs_lport_s
*port
);
60 bfa_fcs_lport_unknown_init
, bfa_fcs_lport_unknown_online
,
61 bfa_fcs_lport_unknown_offline
}, {
62 bfa_fcs_lport_fab_init
, bfa_fcs_lport_fab_online
,
63 bfa_fcs_lport_fab_offline
}, {
64 bfa_fcs_lport_n2n_init
, bfa_fcs_lport_n2n_online
,
65 bfa_fcs_lport_n2n_offline
},
69 * fcs_port_sm FCS logical port state machine
72 enum bfa_fcs_lport_event
{
73 BFA_FCS_PORT_SM_CREATE
= 1,
74 BFA_FCS_PORT_SM_ONLINE
= 2,
75 BFA_FCS_PORT_SM_OFFLINE
= 3,
76 BFA_FCS_PORT_SM_DELETE
= 4,
77 BFA_FCS_PORT_SM_DELRPORT
= 5,
78 BFA_FCS_PORT_SM_STOP
= 6,
81 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s
*port
,
82 enum bfa_fcs_lport_event event
);
83 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s
*port
,
84 enum bfa_fcs_lport_event event
);
85 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s
*port
,
86 enum bfa_fcs_lport_event event
);
87 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s
*port
,
88 enum bfa_fcs_lport_event event
);
89 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s
*port
,
90 enum bfa_fcs_lport_event event
);
91 static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s
*port
,
92 enum bfa_fcs_lport_event event
);
95 bfa_fcs_lport_sm_uninit(
96 struct bfa_fcs_lport_s
*port
,
97 enum bfa_fcs_lport_event event
)
99 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
100 bfa_trc(port
->fcs
, event
);
103 case BFA_FCS_PORT_SM_CREATE
:
104 bfa_sm_set_state(port
, bfa_fcs_lport_sm_init
);
108 bfa_sm_fault(port
->fcs
, event
);
113 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s
*port
,
114 enum bfa_fcs_lport_event event
)
116 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
117 bfa_trc(port
->fcs
, event
);
120 case BFA_FCS_PORT_SM_ONLINE
:
121 bfa_sm_set_state(port
, bfa_fcs_lport_sm_online
);
122 bfa_fcs_lport_online_actions(port
);
125 case BFA_FCS_PORT_SM_DELETE
:
126 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
127 bfa_fcs_lport_deleted(port
);
130 case BFA_FCS_PORT_SM_STOP
:
131 /* If vport - send completion call back */
133 bfa_fcs_vport_stop_comp(port
->vport
);
136 case BFA_FCS_PORT_SM_OFFLINE
:
140 bfa_sm_fault(port
->fcs
, event
);
145 bfa_fcs_lport_sm_online(
146 struct bfa_fcs_lport_s
*port
,
147 enum bfa_fcs_lport_event event
)
149 struct bfa_fcs_rport_s
*rport
;
150 struct list_head
*qe
, *qen
;
152 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
153 bfa_trc(port
->fcs
, event
);
156 case BFA_FCS_PORT_SM_OFFLINE
:
157 bfa_sm_set_state(port
, bfa_fcs_lport_sm_offline
);
158 bfa_fcs_lport_offline_actions(port
);
161 case BFA_FCS_PORT_SM_STOP
:
162 __port_action
[port
->fabric
->fab_type
].offline(port
);
164 if (port
->num_rports
== 0) {
165 bfa_sm_set_state(port
, bfa_fcs_lport_sm_init
);
166 /* If vport - send completion call back */
168 bfa_fcs_vport_stop_comp(port
->vport
);
170 bfa_sm_set_state(port
, bfa_fcs_lport_sm_stopping
);
171 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
172 rport
= (struct bfa_fcs_rport_s
*) qe
;
173 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
178 case BFA_FCS_PORT_SM_DELETE
:
180 __port_action
[port
->fabric
->fab_type
].offline(port
);
182 if (port
->num_rports
== 0) {
183 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
184 bfa_fcs_lport_deleted(port
);
186 bfa_sm_set_state(port
, bfa_fcs_lport_sm_deleting
);
187 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
188 rport
= (struct bfa_fcs_rport_s
*) qe
;
189 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
194 case BFA_FCS_PORT_SM_DELRPORT
:
198 bfa_sm_fault(port
->fcs
, event
);
203 bfa_fcs_lport_sm_offline(
204 struct bfa_fcs_lport_s
*port
,
205 enum bfa_fcs_lport_event event
)
207 struct bfa_fcs_rport_s
*rport
;
208 struct list_head
*qe
, *qen
;
210 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
211 bfa_trc(port
->fcs
, event
);
214 case BFA_FCS_PORT_SM_ONLINE
:
215 bfa_sm_set_state(port
, bfa_fcs_lport_sm_online
);
216 bfa_fcs_lport_online_actions(port
);
219 case BFA_FCS_PORT_SM_STOP
:
220 if (port
->num_rports
== 0) {
221 bfa_sm_set_state(port
, bfa_fcs_lport_sm_init
);
222 /* If vport - send completion call back */
224 bfa_fcs_vport_stop_comp(port
->vport
);
226 bfa_sm_set_state(port
, bfa_fcs_lport_sm_stopping
);
227 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
228 rport
= (struct bfa_fcs_rport_s
*) qe
;
229 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
234 case BFA_FCS_PORT_SM_DELETE
:
235 if (port
->num_rports
== 0) {
236 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
237 bfa_fcs_lport_deleted(port
);
239 bfa_sm_set_state(port
, bfa_fcs_lport_sm_deleting
);
240 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
241 rport
= (struct bfa_fcs_rport_s
*) qe
;
242 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
247 case BFA_FCS_PORT_SM_DELRPORT
:
248 case BFA_FCS_PORT_SM_OFFLINE
:
252 bfa_sm_fault(port
->fcs
, event
);
257 bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s
*port
,
258 enum bfa_fcs_lport_event event
)
260 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
261 bfa_trc(port
->fcs
, event
);
264 case BFA_FCS_PORT_SM_DELRPORT
:
265 if (port
->num_rports
== 0) {
266 bfa_sm_set_state(port
, bfa_fcs_lport_sm_init
);
267 /* If vport - send completion call back */
269 bfa_fcs_vport_stop_comp(port
->vport
);
274 bfa_sm_fault(port
->fcs
, event
);
279 bfa_fcs_lport_sm_deleting(
280 struct bfa_fcs_lport_s
*port
,
281 enum bfa_fcs_lport_event event
)
283 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
284 bfa_trc(port
->fcs
, event
);
287 case BFA_FCS_PORT_SM_DELRPORT
:
288 if (port
->num_rports
== 0) {
289 bfa_sm_set_state(port
, bfa_fcs_lport_sm_uninit
);
290 bfa_fcs_lport_deleted(port
);
295 bfa_sm_fault(port
->fcs
, event
);
304 * Send AEN notification
307 bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s
*port
,
308 enum bfa_lport_aen_event event
)
310 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fabric
->fcs
->bfad
;
311 struct bfa_aen_entry_s
*aen_entry
;
313 bfad_get_aen_entry(bfad
, aen_entry
);
317 aen_entry
->aen_data
.lport
.vf_id
= port
->fabric
->vf_id
;
318 aen_entry
->aen_data
.lport
.roles
= port
->port_cfg
.roles
;
319 aen_entry
->aen_data
.lport
.ppwwn
= bfa_fcs_lport_get_pwwn(
320 bfa_fcs_get_base_port(port
->fcs
));
321 aen_entry
->aen_data
.lport
.lpwwn
= bfa_fcs_lport_get_pwwn(port
);
323 /* Send the AEN notification */
324 bfad_im_post_vendor_event(aen_entry
, bfad
, ++port
->fcs
->fcs_aen_seq
,
325 BFA_AEN_CAT_LPORT
, event
);
332 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
333 u8 reason_code
, u8 reason_code_expl
)
336 struct bfa_fcxp_s
*fcxp
;
337 struct bfa_rport_s
*bfa_rport
= NULL
;
340 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
341 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
343 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
347 len
= fc_ls_rjt_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
348 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
349 rx_fchs
->ox_id
, reason_code
, reason_code_expl
);
351 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
352 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
360 bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s
*port
,
361 struct fchs_s
*rx_fchs
, u8 reason_code
, u8 reason_code_expl
)
364 struct bfa_fcxp_s
*fcxp
;
365 struct bfa_rport_s
*bfa_rport
= NULL
;
367 struct ct_hdr_s
*rx_cthdr
= (struct ct_hdr_s
*)(rx_fchs
+ 1);
368 struct ct_hdr_s
*ct_hdr
;
370 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
371 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
373 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
377 ct_hdr
= bfa_fcxp_get_reqbuf(fcxp
);
378 ct_hdr
->gs_type
= rx_cthdr
->gs_type
;
379 ct_hdr
->gs_sub_type
= rx_cthdr
->gs_sub_type
;
381 len
= fc_gs_rjt_build(&fchs
, ct_hdr
, rx_fchs
->s_id
,
382 bfa_fcs_lport_get_fcid(port
),
383 rx_fchs
->ox_id
, reason_code
, reason_code_expl
);
385 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
386 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
391 * Process incoming plogi from a remote port.
394 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s
*port
,
395 struct fchs_s
*rx_fchs
, struct fc_logi_s
*plogi
)
397 struct bfa_fcs_rport_s
*rport
;
399 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
400 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
403 * If min cfg mode is enabled, drop any incoming PLOGIs
405 if (__fcs_min_cfg(port
->fcs
)) {
406 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
410 if (fc_plogi_parse(rx_fchs
) != FC_PARSE_OK
) {
411 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
415 bfa_fcs_lport_send_ls_rjt(port
, rx_fchs
,
416 FC_LS_RJT_RSN_PROTOCOL_ERROR
,
417 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS
);
422 * Direct Attach P2P mode : verify address assigned by the r-port.
424 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
425 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port
),
426 (void *)&plogi
->port_name
, sizeof(wwn_t
)) < 0)) {
427 if (BFA_FCS_PID_IS_WKA(rx_fchs
->d_id
)) {
428 /* Address assigned to us cannot be a WKA */
429 bfa_fcs_lport_send_ls_rjt(port
, rx_fchs
,
430 FC_LS_RJT_RSN_PROTOCOL_ERROR
,
431 FC_LS_RJT_EXP_INVALID_NPORT_ID
);
434 port
->pid
= rx_fchs
->d_id
;
435 bfa_lps_set_n2n_pid(port
->fabric
->lps
, rx_fchs
->d_id
);
439 * First, check if we know the device by pwwn.
441 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
, plogi
->port_name
);
444 * Direct Attach P2P mode : handle address assigned by r-port.
446 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
447 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port
),
448 (void *)&plogi
->port_name
, sizeof(wwn_t
)) < 0)) {
449 port
->pid
= rx_fchs
->d_id
;
450 bfa_lps_set_n2n_pid(port
->fabric
->lps
, rx_fchs
->d_id
);
451 rport
->pid
= rx_fchs
->s_id
;
453 bfa_fcs_rport_plogi(rport
, rx_fchs
, plogi
);
458 * Next, lookup rport by PID.
460 rport
= bfa_fcs_lport_get_rport_by_pid(port
, rx_fchs
->s_id
);
463 * Inbound PLOGI from a new device.
465 bfa_fcs_rport_plogi_create(port
, rx_fchs
, plogi
);
470 * Rport is known only by PID.
474 * This is a different device with the same pid. Old device
475 * disappeared. Send implicit LOGO to old device.
477 WARN_ON(rport
->pwwn
== plogi
->port_name
);
478 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_IMP
);
481 * Inbound PLOGI from a new device (with old PID).
483 bfa_fcs_rport_plogi_create(port
, rx_fchs
, plogi
);
488 * PLOGI crossing each other.
490 WARN_ON(rport
->pwwn
!= WWN_NULL
);
491 bfa_fcs_rport_plogi(rport
, rx_fchs
, plogi
);
495 * Process incoming ECHO.
496 * Since it does not require a login, it is processed here.
499 bfa_fcs_lport_echo(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
500 struct fc_echo_s
*echo
, u16 rx_len
)
503 struct bfa_fcxp_s
*fcxp
;
504 struct bfa_rport_s
*bfa_rport
= NULL
;
507 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
508 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
510 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
514 len
= fc_ls_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
515 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
519 * Copy the payload (if any) from the echo frame
521 pyld_len
= rx_len
- sizeof(struct fchs_s
);
522 bfa_trc(port
->fcs
, rx_len
);
523 bfa_trc(port
->fcs
, pyld_len
);
526 memcpy(((u8
*) bfa_fcxp_get_reqbuf(fcxp
)) +
527 sizeof(struct fc_echo_s
), (echo
+ 1),
528 (pyld_len
- sizeof(struct fc_echo_s
)));
530 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
531 BFA_FALSE
, FC_CLASS_3
, pyld_len
, &fchs
, NULL
, NULL
,
536 * Process incoming RNID.
537 * Since it does not require a login, it is processed here.
540 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
,
541 struct fc_rnid_cmd_s
*rnid
, u16 rx_len
)
543 struct fc_rnid_common_id_data_s common_id_data
;
544 struct fc_rnid_general_topology_data_s gen_topo_data
;
546 struct bfa_fcxp_s
*fcxp
;
547 struct bfa_rport_s
*bfa_rport
= NULL
;
551 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
552 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
553 bfa_trc(port
->fcs
, rx_len
);
555 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
560 * Check Node Indentification Data Format
561 * We only support General Topology Discovery Format.
562 * For any other requested Data Formats, we return Common Node Id Data
563 * only, as per FC-LS.
565 bfa_trc(port
->fcs
, rnid
->node_id_data_format
);
566 if (rnid
->node_id_data_format
== RNID_NODEID_DATA_FORMAT_DISCOVERY
) {
567 data_format
= RNID_NODEID_DATA_FORMAT_DISCOVERY
;
569 * Get General topology data for this port
571 bfa_fs_port_get_gen_topo_data(port
, &gen_topo_data
);
573 data_format
= RNID_NODEID_DATA_FORMAT_COMMON
;
577 * Copy the Node Id Info
579 common_id_data
.port_name
= bfa_fcs_lport_get_pwwn(port
);
580 common_id_data
.node_name
= bfa_fcs_lport_get_nwwn(port
);
582 len
= fc_rnid_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
583 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
584 rx_fchs
->ox_id
, data_format
, &common_id_data
,
587 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
588 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
593 * Fill out General Topolpgy Discovery Data for RNID ELS.
596 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s
*port
,
597 struct fc_rnid_general_topology_data_s
*gen_topo_data
)
599 memset(gen_topo_data
, 0,
600 sizeof(struct fc_rnid_general_topology_data_s
));
602 gen_topo_data
->asso_type
= cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST
);
603 gen_topo_data
->phy_port_num
= 0; /* @todo */
604 gen_topo_data
->num_attached_nodes
= cpu_to_be32(1);
608 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s
*port
)
610 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
611 char lpwwn_buf
[BFA_STRING_32
];
613 bfa_trc(port
->fcs
, port
->fabric
->oper_type
);
615 __port_action
[port
->fabric
->fab_type
].init(port
);
616 __port_action
[port
->fabric
->fab_type
].online(port
);
618 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
619 BFA_LOG(KERN_WARNING
, bfad
, bfa_log_level
,
620 "Logical port online: WWN = %s Role = %s\n",
621 lpwwn_buf
, "Initiator");
622 bfa_fcs_lport_aen_post(port
, BFA_LPORT_AEN_ONLINE
);
624 bfad
->bfad_flags
|= BFAD_PORT_ONLINE
;
628 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s
*port
)
630 struct list_head
*qe
, *qen
;
631 struct bfa_fcs_rport_s
*rport
;
632 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
633 char lpwwn_buf
[BFA_STRING_32
];
635 bfa_trc(port
->fcs
, port
->fabric
->oper_type
);
637 __port_action
[port
->fabric
->fab_type
].offline(port
);
639 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
640 if (bfa_sm_cmp_state(port
->fabric
,
641 bfa_fcs_fabric_sm_online
) == BFA_TRUE
) {
642 BFA_LOG(KERN_WARNING
, bfad
, bfa_log_level
,
643 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
644 lpwwn_buf
, "Initiator");
645 bfa_fcs_lport_aen_post(port
, BFA_LPORT_AEN_DISCONNECT
);
647 BFA_LOG(KERN_WARNING
, bfad
, bfa_log_level
,
648 "Logical port taken offline: WWN = %s Role = %s\n",
649 lpwwn_buf
, "Initiator");
650 bfa_fcs_lport_aen_post(port
, BFA_LPORT_AEN_OFFLINE
);
653 list_for_each_safe(qe
, qen
, &port
->rport_q
) {
654 rport
= (struct bfa_fcs_rport_s
*) qe
;
655 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_IMP
);
660 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s
*port
)
666 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s
*port
)
672 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s
*port
)
678 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s
*port
, struct fchs_s
*rx_fchs
)
681 struct bfa_fcxp_s
*fcxp
;
684 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
685 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
687 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
691 len
= fc_ba_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
692 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
695 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
696 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
700 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s
*port
)
702 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
703 char lpwwn_buf
[BFA_STRING_32
];
705 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
706 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
707 "Logical port deleted: WWN = %s Role = %s\n",
708 lpwwn_buf
, "Initiator");
709 bfa_fcs_lport_aen_post(port
, BFA_LPORT_AEN_DELETE
);
711 /* Base port will be deleted by the OS driver */
713 bfa_fcs_vport_delete_comp(port
->vport
);
715 bfa_wc_down(&port
->fabric
->wc
);
720 * Unsolicited frame receive handling.
723 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s
*lport
,
724 struct fchs_s
*fchs
, u16 len
)
726 u32 pid
= fchs
->s_id
;
727 struct bfa_fcs_rport_s
*rport
= NULL
;
728 struct fc_els_cmd_s
*els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
730 bfa_stats(lport
, uf_recvs
);
731 bfa_trc(lport
->fcs
, fchs
->type
);
733 if (!bfa_fcs_lport_is_online(lport
)) {
734 bfa_stats(lport
, uf_recv_drops
);
739 * First, handle ELSs that donot require a login.
744 if ((fchs
->type
== FC_TYPE_ELS
) &&
745 (els_cmd
->els_code
== FC_ELS_PLOGI
)) {
746 bfa_fcs_lport_plogi(lport
, fchs
, (struct fc_logi_s
*) els_cmd
);
751 * Handle ECHO separately.
753 if ((fchs
->type
== FC_TYPE_ELS
) && (els_cmd
->els_code
== FC_ELS_ECHO
)) {
754 bfa_fcs_lport_echo(lport
, fchs
,
755 (struct fc_echo_s
*)els_cmd
, len
);
760 * Handle RNID separately.
762 if ((fchs
->type
== FC_TYPE_ELS
) && (els_cmd
->els_code
== FC_ELS_RNID
)) {
763 bfa_fcs_lport_rnid(lport
, fchs
,
764 (struct fc_rnid_cmd_s
*) els_cmd
, len
);
768 if (fchs
->type
== FC_TYPE_BLS
) {
769 if ((fchs
->routing
== FC_RTG_BASIC_LINK
) &&
770 (fchs
->cat_info
== FC_CAT_ABTS
))
771 bfa_fcs_lport_abts_acc(lport
, fchs
);
775 if (fchs
->type
== FC_TYPE_SERVICES
) {
777 * Unhandled FC-GS frames. Send a FC-CT Reject
779 bfa_fcs_lport_send_fcgs_rjt(lport
, fchs
, CT_RSN_NOT_SUPP
,
780 CT_NS_EXP_NOADDITIONAL
);
785 * look for a matching remote port ID
787 rport
= bfa_fcs_lport_get_rport_by_pid(lport
, pid
);
789 bfa_trc(rport
->fcs
, fchs
->s_id
);
790 bfa_trc(rport
->fcs
, fchs
->d_id
);
791 bfa_trc(rport
->fcs
, fchs
->type
);
793 bfa_fcs_rport_uf_recv(rport
, fchs
, len
);
798 * Only handles ELS frames for now.
800 if (fchs
->type
!= FC_TYPE_ELS
) {
801 bfa_trc(lport
->fcs
, fchs
->s_id
);
802 bfa_trc(lport
->fcs
, fchs
->d_id
);
803 /* ignore type FC_TYPE_FC_FSS */
804 if (fchs
->type
!= FC_TYPE_FC_FSS
)
805 bfa_sm_fault(lport
->fcs
, fchs
->type
);
809 bfa_trc(lport
->fcs
, els_cmd
->els_code
);
810 if (els_cmd
->els_code
== FC_ELS_RSCN
) {
811 bfa_fcs_lport_scn_process_rscn(lport
, fchs
, len
);
815 if (els_cmd
->els_code
== FC_ELS_LOGO
) {
817 * @todo Handle LOGO frames received.
822 if (els_cmd
->els_code
== FC_ELS_PRLI
) {
824 * @todo Handle PRLI frames received.
830 * Unhandled ELS frames. Send a LS_RJT.
832 bfa_fcs_lport_send_ls_rjt(lport
, fchs
, FC_LS_RJT_RSN_CMD_NOT_SUPP
,
833 FC_LS_RJT_EXP_NO_ADDL_INFO
);
838 * PID based Lookup for a R-Port in the Port R-Port Queue
840 struct bfa_fcs_rport_s
*
841 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s
*port
, u32 pid
)
843 struct bfa_fcs_rport_s
*rport
;
844 struct list_head
*qe
;
846 list_for_each(qe
, &port
->rport_q
) {
847 rport
= (struct bfa_fcs_rport_s
*) qe
;
848 if (rport
->pid
== pid
)
852 bfa_trc(port
->fcs
, pid
);
857 * PWWN based Lookup for a R-Port in the Port R-Port Queue
859 struct bfa_fcs_rport_s
*
860 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s
*port
, wwn_t pwwn
)
862 struct bfa_fcs_rport_s
*rport
;
863 struct list_head
*qe
;
865 list_for_each(qe
, &port
->rport_q
) {
866 rport
= (struct bfa_fcs_rport_s
*) qe
;
867 if (wwn_is_equal(rport
->pwwn
, pwwn
))
871 bfa_trc(port
->fcs
, pwwn
);
876 * NWWN based Lookup for a R-Port in the Port R-Port Queue
878 struct bfa_fcs_rport_s
*
879 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s
*port
, wwn_t nwwn
)
881 struct bfa_fcs_rport_s
*rport
;
882 struct list_head
*qe
;
884 list_for_each(qe
, &port
->rport_q
) {
885 rport
= (struct bfa_fcs_rport_s
*) qe
;
886 if (wwn_is_equal(rport
->nwwn
, nwwn
))
890 bfa_trc(port
->fcs
, nwwn
);
895 * Called by rport module when new rports are discovered.
898 bfa_fcs_lport_add_rport(
899 struct bfa_fcs_lport_s
*port
,
900 struct bfa_fcs_rport_s
*rport
)
902 list_add_tail(&rport
->qe
, &port
->rport_q
);
907 * Called by rport module to when rports are deleted.
910 bfa_fcs_lport_del_rport(
911 struct bfa_fcs_lport_s
*port
,
912 struct bfa_fcs_rport_s
*rport
)
914 WARN_ON(!bfa_q_is_on_q(&port
->rport_q
, rport
));
915 list_del(&rport
->qe
);
918 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_DELRPORT
);
922 * Called by fabric for base port when fabric login is complete.
923 * Called by vport for virtual ports when FDISC is complete.
926 bfa_fcs_lport_online(struct bfa_fcs_lport_s
*port
)
928 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_ONLINE
);
932 * Called by fabric for base port when fabric goes offline.
933 * Called by vport for virtual ports when virtual port becomes offline.
936 bfa_fcs_lport_offline(struct bfa_fcs_lport_s
*port
)
938 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_OFFLINE
);
942 * Called by fabric to delete base lport and associated resources.
944 * Called by vport to delete lport and associated resources. Should call
945 * bfa_fcs_vport_delete_comp() for vports on completion.
948 bfa_fcs_lport_delete(struct bfa_fcs_lport_s
*port
)
950 bfa_sm_send_event(port
, BFA_FCS_PORT_SM_DELETE
);
954 * Return TRUE if port is online, else return FALSE
957 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s
*port
)
959 return bfa_sm_cmp_state(port
, bfa_fcs_lport_sm_online
);
963 * Attach time initialization of logical ports.
966 bfa_fcs_lport_attach(struct bfa_fcs_lport_s
*lport
, struct bfa_fcs_s
*fcs
,
967 u16 vf_id
, struct bfa_fcs_vport_s
*vport
)
970 lport
->fabric
= bfa_fcs_vf_lookup(fcs
, vf_id
);
971 lport
->vport
= vport
;
972 lport
->lp_tag
= (vport
) ? vport
->lps
->bfa_tag
:
973 lport
->fabric
->lps
->bfa_tag
;
975 INIT_LIST_HEAD(&lport
->rport_q
);
976 lport
->num_rports
= 0;
980 * Logical port initialization of base or virtual port.
981 * Called by fabric for base port or by vport for virtual ports.
985 bfa_fcs_lport_init(struct bfa_fcs_lport_s
*lport
,
986 struct bfa_lport_cfg_s
*port_cfg
)
988 struct bfa_fcs_vport_s
*vport
= lport
->vport
;
989 struct bfad_s
*bfad
= (struct bfad_s
*)lport
->fcs
->bfad
;
990 char lpwwn_buf
[BFA_STRING_32
];
992 lport
->port_cfg
= *port_cfg
;
994 lport
->bfad_port
= bfa_fcb_lport_new(lport
->fcs
->bfad
, lport
,
995 lport
->port_cfg
.roles
,
996 lport
->fabric
->vf_drv
,
997 vport
? vport
->vport_drv
: NULL
);
999 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(lport
));
1000 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
1001 "New logical port created: WWN = %s Role = %s\n",
1002 lpwwn_buf
, "Initiator");
1003 bfa_fcs_lport_aen_post(lport
, BFA_LPORT_AEN_NEW
);
1005 bfa_sm_set_state(lport
, bfa_fcs_lport_sm_uninit
);
1006 bfa_sm_send_event(lport
, BFA_FCS_PORT_SM_CREATE
);
1014 bfa_fcs_lport_get_attr(
1015 struct bfa_fcs_lport_s
*port
,
1016 struct bfa_lport_attr_s
*port_attr
)
1018 if (bfa_sm_cmp_state(port
, bfa_fcs_lport_sm_online
))
1019 port_attr
->pid
= port
->pid
;
1023 port_attr
->port_cfg
= port
->port_cfg
;
1026 port_attr
->port_type
= port
->fabric
->oper_type
;
1027 port_attr
->loopback
= bfa_sm_cmp_state(port
->fabric
,
1028 bfa_fcs_fabric_sm_loopback
);
1029 port_attr
->authfail
=
1030 bfa_sm_cmp_state(port
->fabric
,
1031 bfa_fcs_fabric_sm_auth_failed
);
1032 port_attr
->fabric_name
= bfa_fcs_lport_get_fabric_name(port
);
1033 memcpy(port_attr
->fabric_ip_addr
,
1034 bfa_fcs_lport_get_fabric_ipaddr(port
),
1035 BFA_FCS_FABRIC_IPADDR_SZ
);
1037 if (port
->vport
!= NULL
) {
1038 port_attr
->port_type
= BFA_PORT_TYPE_VPORT
;
1039 port_attr
->fpma_mac
=
1040 port
->vport
->lps
->lp_mac
;
1042 port_attr
->fpma_mac
=
1043 port
->fabric
->lps
->lp_mac
;
1046 port_attr
->port_type
= BFA_PORT_TYPE_UNKNOWN
;
1047 port_attr
->state
= BFA_LPORT_UNINIT
;
1052 * bfa_fcs_lport_fab port fab functions
1056 * Called by port to initialize fabric services of the base port.
1059 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s
*port
)
1061 bfa_fcs_lport_ns_init(port
);
1062 bfa_fcs_lport_scn_init(port
);
1063 bfa_fcs_lport_ms_init(port
);
1067 * Called by port to notify transition to online state.
1070 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s
*port
)
1072 bfa_fcs_lport_ns_online(port
);
1073 bfa_fcs_lport_scn_online(port
);
1077 * Called by port to notify transition to offline state.
1080 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s
*port
)
1082 bfa_fcs_lport_ns_offline(port
);
1083 bfa_fcs_lport_scn_offline(port
);
1084 bfa_fcs_lport_ms_offline(port
);
1088 * bfa_fcs_lport_n2n functions
1092 * Called by fcs/port to initialize N2N topology.
1095 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s
*port
)
1100 * Called by fcs/port to notify transition to online state.
1103 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s
*port
)
1105 struct bfa_fcs_lport_n2n_s
*n2n_port
= &port
->port_topo
.pn2n
;
1106 struct bfa_lport_cfg_s
*pcfg
= &port
->port_cfg
;
1107 struct bfa_fcs_rport_s
*rport
;
1109 bfa_trc(port
->fcs
, pcfg
->pwwn
);
1112 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1113 * and assign an Address. if not, we need to wait for its PLOGI.
1115 * If our PWWN is < than that of the remote port, it will send a PLOGI
1116 * with the PIDs assigned. The rport state machine take care of this
1120 ((void *)&pcfg
->pwwn
, (void *)&n2n_port
->rem_port_wwn
,
1121 sizeof(wwn_t
)) > 0) {
1122 port
->pid
= N2N_LOCAL_PID
;
1123 bfa_lps_set_n2n_pid(port
->fabric
->lps
, N2N_LOCAL_PID
);
1125 * First, check if we know the device by pwwn.
1127 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
,
1128 n2n_port
->rem_port_wwn
);
1130 bfa_trc(port
->fcs
, rport
->pid
);
1131 bfa_trc(port
->fcs
, rport
->pwwn
);
1132 rport
->pid
= N2N_REMOTE_PID
;
1133 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_SEND
);
1138 * In n2n there can be only one rport. Delete the old one
1139 * whose pid should be zero, because it is offline.
1141 if (port
->num_rports
> 0) {
1142 rport
= bfa_fcs_lport_get_rport_by_pid(port
, 0);
1143 WARN_ON(rport
== NULL
);
1145 bfa_trc(port
->fcs
, rport
->pwwn
);
1146 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
1149 bfa_fcs_rport_create(port
, N2N_REMOTE_PID
);
1154 * Called by fcs/port to notify transition to offline state.
1157 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s
*port
)
1159 struct bfa_fcs_lport_n2n_s
*n2n_port
= &port
->port_topo
.pn2n
;
1161 bfa_trc(port
->fcs
, port
->pid
);
1163 n2n_port
->rem_port_wwn
= 0;
1164 n2n_port
->reply_oxid
= 0;
1167 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1170 * forward declarations
1172 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg
,
1173 struct bfa_fcxp_s
*fcxp_alloced
);
1174 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg
,
1175 struct bfa_fcxp_s
*fcxp_alloced
);
1176 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg
,
1177 struct bfa_fcxp_s
*fcxp_alloced
);
1178 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg
,
1179 struct bfa_fcxp_s
*fcxp
,
1181 bfa_status_t req_status
,
1184 struct fchs_s
*rsp_fchs
);
1185 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg
,
1186 struct bfa_fcxp_s
*fcxp
,
1188 bfa_status_t req_status
,
1191 struct fchs_s
*rsp_fchs
);
1192 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg
,
1193 struct bfa_fcxp_s
*fcxp
,
1195 bfa_status_t req_status
,
1198 struct fchs_s
*rsp_fchs
);
1199 static void bfa_fcs_lport_fdmi_timeout(void *arg
);
1200 static u16
bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1202 static u16
bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1204 static u16
bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1206 static u16
bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s
*
1208 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1209 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
);
1210 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1211 struct bfa_fcs_fdmi_port_attr_s
*port_attr
);
1212 u32
bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed
);
1215 * fcs_fdmi_sm FCS FDMI state machine
1219 * FDMI State Machine events
1221 enum port_fdmi_event
{
1222 FDMISM_EVENT_PORT_ONLINE
= 1,
1223 FDMISM_EVENT_PORT_OFFLINE
= 2,
1224 FDMISM_EVENT_RSP_OK
= 4,
1225 FDMISM_EVENT_RSP_ERROR
= 5,
1226 FDMISM_EVENT_TIMEOUT
= 6,
1227 FDMISM_EVENT_RHBA_SENT
= 7,
1228 FDMISM_EVENT_RPRT_SENT
= 8,
1229 FDMISM_EVENT_RPA_SENT
= 9,
1232 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1233 enum port_fdmi_event event
);
1234 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1235 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1236 enum port_fdmi_event event
);
1237 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1238 enum port_fdmi_event event
);
1239 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1240 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1241 enum port_fdmi_event event
);
1242 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1243 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1244 enum port_fdmi_event event
);
1245 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1246 enum port_fdmi_event event
);
1247 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1248 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1249 enum port_fdmi_event event
);
1250 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1251 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1252 enum port_fdmi_event event
);
1253 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1254 enum port_fdmi_event event
);
1255 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1256 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1257 enum port_fdmi_event event
);
1258 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1259 enum port_fdmi_event event
);
1260 static void bfa_fcs_lport_fdmi_sm_disabled(
1261 struct bfa_fcs_lport_fdmi_s
*fdmi
,
1262 enum port_fdmi_event event
);
1264 * Start in offline state - awaiting MS to send start.
1267 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1268 enum port_fdmi_event event
)
1270 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1272 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1273 bfa_trc(port
->fcs
, event
);
1275 fdmi
->retry_cnt
= 0;
1278 case FDMISM_EVENT_PORT_ONLINE
:
1281 * For Vports, register a new port.
1283 bfa_sm_set_state(fdmi
,
1284 bfa_fcs_lport_fdmi_sm_sending_rprt
);
1285 bfa_fcs_lport_fdmi_send_rprt(fdmi
, NULL
);
1288 * For a base port, we should first register the HBA
1289 * attribute. The HBA attribute also contains the base
1290 * port registration.
1292 bfa_sm_set_state(fdmi
,
1293 bfa_fcs_lport_fdmi_sm_sending_rhba
);
1294 bfa_fcs_lport_fdmi_send_rhba(fdmi
, NULL
);
1298 case FDMISM_EVENT_PORT_OFFLINE
:
1302 bfa_sm_fault(port
->fcs
, event
);
1307 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1308 enum port_fdmi_event event
)
1310 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1312 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1313 bfa_trc(port
->fcs
, event
);
1316 case FDMISM_EVENT_RHBA_SENT
:
1317 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rhba
);
1320 case FDMISM_EVENT_PORT_OFFLINE
:
1321 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1322 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1327 bfa_sm_fault(port
->fcs
, event
);
1332 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1333 enum port_fdmi_event event
)
1335 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1337 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1338 bfa_trc(port
->fcs
, event
);
1341 case FDMISM_EVENT_RSP_ERROR
:
1343 * if max retries have not been reached, start timer for a
1346 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1347 bfa_sm_set_state(fdmi
,
1348 bfa_fcs_lport_fdmi_sm_rhba_retry
);
1349 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1351 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1352 BFA_FCS_RETRY_TIMEOUT
);
1355 * set state to offline
1357 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1361 case FDMISM_EVENT_RSP_OK
:
1363 * Initiate Register Port Attributes
1365 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rpa
);
1366 fdmi
->retry_cnt
= 0;
1367 bfa_fcs_lport_fdmi_send_rpa(fdmi
, NULL
);
1370 case FDMISM_EVENT_PORT_OFFLINE
:
1371 bfa_fcxp_discard(fdmi
->fcxp
);
1372 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1376 bfa_sm_fault(port
->fcs
, event
);
1381 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1382 enum port_fdmi_event event
)
1384 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1386 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1387 bfa_trc(port
->fcs
, event
);
1390 case FDMISM_EVENT_TIMEOUT
:
1392 * Retry Timer Expired. Re-send
1394 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rhba
);
1395 bfa_fcs_lport_fdmi_send_rhba(fdmi
, NULL
);
1398 case FDMISM_EVENT_PORT_OFFLINE
:
1399 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1400 bfa_timer_stop(&fdmi
->timer
);
1404 bfa_sm_fault(port
->fcs
, event
);
1409 * RPRT : Register Port
1412 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1413 enum port_fdmi_event event
)
1415 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1417 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1418 bfa_trc(port
->fcs
, event
);
1421 case FDMISM_EVENT_RPRT_SENT
:
1422 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rprt
);
1425 case FDMISM_EVENT_PORT_OFFLINE
:
1426 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1427 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1432 bfa_sm_fault(port
->fcs
, event
);
1437 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1438 enum port_fdmi_event event
)
1440 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1442 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1443 bfa_trc(port
->fcs
, event
);
1446 case FDMISM_EVENT_RSP_ERROR
:
1448 * if max retries have not been reached, start timer for a
1451 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1452 bfa_sm_set_state(fdmi
,
1453 bfa_fcs_lport_fdmi_sm_rprt_retry
);
1454 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1456 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1457 BFA_FCS_RETRY_TIMEOUT
);
1461 * set state to offline
1463 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1464 fdmi
->retry_cnt
= 0;
1468 case FDMISM_EVENT_RSP_OK
:
1469 fdmi
->retry_cnt
= 0;
1470 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_online
);
1473 case FDMISM_EVENT_PORT_OFFLINE
:
1474 bfa_fcxp_discard(fdmi
->fcxp
);
1475 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1479 bfa_sm_fault(port
->fcs
, event
);
1484 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1485 enum port_fdmi_event event
)
1487 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1489 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1490 bfa_trc(port
->fcs
, event
);
1493 case FDMISM_EVENT_TIMEOUT
:
1495 * Retry Timer Expired. Re-send
1497 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rprt
);
1498 bfa_fcs_lport_fdmi_send_rprt(fdmi
, NULL
);
1501 case FDMISM_EVENT_PORT_OFFLINE
:
1502 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1503 bfa_timer_stop(&fdmi
->timer
);
1507 bfa_sm_fault(port
->fcs
, event
);
1512 * Register Port Attributes
1515 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1516 enum port_fdmi_event event
)
1518 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1520 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1521 bfa_trc(port
->fcs
, event
);
1524 case FDMISM_EVENT_RPA_SENT
:
1525 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rpa
);
1528 case FDMISM_EVENT_PORT_OFFLINE
:
1529 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1530 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
1535 bfa_sm_fault(port
->fcs
, event
);
1540 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1541 enum port_fdmi_event event
)
1543 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1545 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1546 bfa_trc(port
->fcs
, event
);
1549 case FDMISM_EVENT_RSP_ERROR
:
1551 * if max retries have not been reached, start timer for a
1554 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
1555 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_rpa_retry
);
1556 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
1558 bfa_fcs_lport_fdmi_timeout
, fdmi
,
1559 BFA_FCS_RETRY_TIMEOUT
);
1562 * set state to offline
1564 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1565 fdmi
->retry_cnt
= 0;
1569 case FDMISM_EVENT_RSP_OK
:
1570 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_online
);
1571 fdmi
->retry_cnt
= 0;
1574 case FDMISM_EVENT_PORT_OFFLINE
:
1575 bfa_fcxp_discard(fdmi
->fcxp
);
1576 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1580 bfa_sm_fault(port
->fcs
, event
);
1585 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1586 enum port_fdmi_event event
)
1588 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1590 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1591 bfa_trc(port
->fcs
, event
);
1594 case FDMISM_EVENT_TIMEOUT
:
1596 * Retry Timer Expired. Re-send
1598 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_sending_rpa
);
1599 bfa_fcs_lport_fdmi_send_rpa(fdmi
, NULL
);
1602 case FDMISM_EVENT_PORT_OFFLINE
:
1603 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1604 bfa_timer_stop(&fdmi
->timer
);
1608 bfa_sm_fault(port
->fcs
, event
);
1613 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1614 enum port_fdmi_event event
)
1616 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1618 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1619 bfa_trc(port
->fcs
, event
);
1622 case FDMISM_EVENT_PORT_OFFLINE
:
1623 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
1627 bfa_sm_fault(port
->fcs
, event
);
1631 * FDMI is disabled state.
1634 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1635 enum port_fdmi_event event
)
1637 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1639 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1640 bfa_trc(port
->fcs
, event
);
1642 /* No op State. It can only be enabled at Driver Init. */
1646 * RHBA : Register HBA Attributes.
1649 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1651 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
1652 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1655 struct bfa_fcxp_s
*fcxp
;
1658 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1660 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1662 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1663 bfa_fcs_lport_fdmi_send_rhba
, fdmi
);
1668 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1669 memset(pyld
, 0, FC_MAX_PDUSZ
);
1671 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
1675 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi
,
1676 (u8
*) ((struct ct_hdr_s
*) pyld
1679 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1680 FC_CLASS_3
, (len
+ attr_len
), &fchs
,
1681 bfa_fcs_lport_fdmi_rhba_response
, (void *)fdmi
,
1682 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
1684 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RHBA_SENT
);
1688 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
1690 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1691 struct bfa_fcs_fdmi_hba_attr_s hba_attr
;
1692 struct bfa_fcs_fdmi_hba_attr_s
*fcs_hba_attr
= &hba_attr
;
1693 struct fdmi_rhba_s
*rhba
= (struct fdmi_rhba_s
*) pyld
;
1694 struct fdmi_attr_s
*attr
;
1700 * get hba attributes
1702 bfa_fcs_fdmi_get_hbaattr(fdmi
, fcs_hba_attr
);
1704 rhba
->hba_id
= bfa_fcs_lport_get_pwwn(port
);
1705 rhba
->port_list
.num_ports
= cpu_to_be32(1);
1706 rhba
->port_list
.port_entry
= bfa_fcs_lport_get_pwwn(port
);
1708 len
= sizeof(rhba
->hba_id
) + sizeof(rhba
->port_list
);
1711 len
+= sizeof(rhba
->hba_attr_blk
.attr_count
);
1714 * fill out the invididual entries of the HBA attrib Block
1716 curr_ptr
= (u8
*) &rhba
->hba_attr_blk
.hba_attr
;
1721 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1722 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME
);
1723 templen
= sizeof(wwn_t
);
1724 memcpy(attr
->value
, &bfa_fcs_lport_get_nwwn(port
), templen
);
1725 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1728 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1734 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1735 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER
);
1736 templen
= (u16
) strlen(fcs_hba_attr
->manufacturer
);
1737 memcpy(attr
->value
, fcs_hba_attr
->manufacturer
, templen
);
1738 templen
= fc_roundup(templen
, sizeof(u32
));
1739 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1742 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1748 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1749 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM
);
1750 templen
= (u16
) strlen(fcs_hba_attr
->serial_num
);
1751 memcpy(attr
->value
, fcs_hba_attr
->serial_num
, templen
);
1752 templen
= fc_roundup(templen
, sizeof(u32
));
1753 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1756 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1762 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1763 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MODEL
);
1764 templen
= (u16
) strlen(fcs_hba_attr
->model
);
1765 memcpy(attr
->value
, fcs_hba_attr
->model
, templen
);
1766 templen
= fc_roundup(templen
, sizeof(u32
));
1767 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1770 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1776 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1777 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC
);
1778 templen
= (u16
) strlen(fcs_hba_attr
->model_desc
);
1779 memcpy(attr
->value
, fcs_hba_attr
->model_desc
, templen
);
1780 templen
= fc_roundup(templen
, sizeof(u32
));
1781 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1784 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1790 if (fcs_hba_attr
->hw_version
[0] != '\0') {
1791 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1792 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION
);
1793 templen
= (u16
) strlen(fcs_hba_attr
->hw_version
);
1794 memcpy(attr
->value
, fcs_hba_attr
->hw_version
, templen
);
1795 templen
= fc_roundup(templen
, sizeof(u32
));
1796 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1799 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1806 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1807 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION
);
1808 templen
= (u16
) strlen(fcs_hba_attr
->driver_version
);
1809 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, templen
);
1810 templen
= fc_roundup(templen
, sizeof(u32
));
1811 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1814 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1818 * Option Rom Version
1820 if (fcs_hba_attr
->option_rom_ver
[0] != '\0') {
1821 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1822 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION
);
1823 templen
= (u16
) strlen(fcs_hba_attr
->option_rom_ver
);
1824 memcpy(attr
->value
, fcs_hba_attr
->option_rom_ver
, templen
);
1825 templen
= fc_roundup(templen
, sizeof(u32
));
1826 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1829 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1834 * f/w Version = driver version
1836 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1837 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION
);
1838 templen
= (u16
) strlen(fcs_hba_attr
->driver_version
);
1839 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, templen
);
1840 templen
= fc_roundup(templen
, sizeof(u32
));
1841 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1844 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1850 if (fcs_hba_attr
->os_name
[0] != '\0') {
1851 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1852 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME
);
1853 templen
= (u16
) strlen(fcs_hba_attr
->os_name
);
1854 memcpy(attr
->value
, fcs_hba_attr
->os_name
, templen
);
1855 templen
= fc_roundup(templen
, sizeof(u32
));
1856 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1859 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1866 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1867 attr
->type
= cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT
);
1868 templen
= sizeof(fcs_hba_attr
->max_ct_pyld
);
1869 memcpy(attr
->value
, &fcs_hba_attr
->max_ct_pyld
, templen
);
1872 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
1876 * Update size of payload
1878 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
1880 rhba
->hba_attr_blk
.attr_count
= cpu_to_be32(count
);
1885 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1886 void *cbarg
, bfa_status_t req_status
,
1887 u32 rsp_len
, u32 resid_len
,
1888 struct fchs_s
*rsp_fchs
)
1890 struct bfa_fcs_lport_fdmi_s
*fdmi
=
1891 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
1892 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1893 struct ct_hdr_s
*cthdr
= NULL
;
1895 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1900 if (req_status
!= BFA_STATUS_OK
) {
1901 bfa_trc(port
->fcs
, req_status
);
1902 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1906 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1907 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
1909 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1910 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1914 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1915 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1916 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1920 * RPRT : Register Port
1923 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1925 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
1926 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
1929 struct bfa_fcxp_s
*fcxp
;
1932 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1934 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1936 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1937 bfa_fcs_lport_fdmi_send_rprt
, fdmi
);
1942 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1943 memset(pyld
, 0, FC_MAX_PDUSZ
);
1945 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
1949 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi
,
1950 (u8
*) ((struct ct_hdr_s
*) pyld
1953 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1954 FC_CLASS_3
, len
+ attr_len
, &fchs
,
1955 bfa_fcs_lport_fdmi_rprt_response
, (void *)fdmi
,
1956 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
1958 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPRT_SENT
);
1962 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
1965 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s
*fdmi
,
1968 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr
;
1969 struct fdmi_port_attr_s
*port_attrib
= (struct fdmi_port_attr_s
*) pyld
;
1970 struct fdmi_attr_s
*attr
;
1977 * get port attributes
1979 bfa_fcs_fdmi_get_portattr(fdmi
, &fcs_port_attr
);
1981 len
= sizeof(port_attrib
->attr_count
);
1984 * fill out the invididual entries
1986 curr_ptr
= (u8
*) &port_attrib
->port_attr
;
1991 attr
= (struct fdmi_attr_s
*) curr_ptr
;
1992 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES
);
1993 templen
= sizeof(fcs_port_attr
.supp_fc4_types
);
1994 memcpy(attr
->value
, fcs_port_attr
.supp_fc4_types
, templen
);
1995 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
1999 cpu_to_be16(templen
+ sizeof(attr
->type
) +
2005 attr
= (struct fdmi_attr_s
*) curr_ptr
;
2006 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED
);
2007 templen
= sizeof(fcs_port_attr
.supp_speed
);
2008 memcpy(attr
->value
, &fcs_port_attr
.supp_speed
, templen
);
2009 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
2013 cpu_to_be16(templen
+ sizeof(attr
->type
) +
2017 * current Port Speed
2019 attr
= (struct fdmi_attr_s
*) curr_ptr
;
2020 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED
);
2021 templen
= sizeof(fcs_port_attr
.curr_speed
);
2022 memcpy(attr
->value
, &fcs_port_attr
.curr_speed
, templen
);
2023 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
2026 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
2032 attr
= (struct fdmi_attr_s
*) curr_ptr
;
2033 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE
);
2034 templen
= sizeof(fcs_port_attr
.max_frm_size
);
2035 memcpy(attr
->value
, &fcs_port_attr
.max_frm_size
, templen
);
2036 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
2039 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
2045 if (fcs_port_attr
.os_device_name
[0] != '\0') {
2046 attr
= (struct fdmi_attr_s
*) curr_ptr
;
2047 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME
);
2048 templen
= (u16
) strlen(fcs_port_attr
.os_device_name
);
2049 memcpy(attr
->value
, fcs_port_attr
.os_device_name
, templen
);
2050 templen
= fc_roundup(templen
, sizeof(u32
));
2051 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
2054 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
2060 if (fcs_port_attr
.host_name
[0] != '\0') {
2061 attr
= (struct fdmi_attr_s
*) curr_ptr
;
2062 attr
->type
= cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME
);
2063 templen
= (u16
) strlen(fcs_port_attr
.host_name
);
2064 memcpy(attr
->value
, fcs_port_attr
.host_name
, templen
);
2065 templen
= fc_roundup(templen
, sizeof(u32
));
2066 curr_ptr
+= sizeof(attr
->type
) + sizeof(templen
) + templen
;
2069 attr
->len
= cpu_to_be16(templen
+ sizeof(attr
->type
) +
2074 * Update size of payload
2076 port_attrib
->attr_count
= cpu_to_be32(count
);
2077 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
2082 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
2084 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2085 struct fdmi_rprt_s
*rprt
= (struct fdmi_rprt_s
*) pyld
;
2088 rprt
->hba_id
= bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port
->fcs
));
2089 rprt
->port_name
= bfa_fcs_lport_get_pwwn(port
);
2091 len
= bfa_fcs_lport_fdmi_build_portattr_block(fdmi
,
2092 (u8
*) &rprt
->port_attr_blk
);
2094 len
+= sizeof(rprt
->hba_id
) + sizeof(rprt
->port_name
);
2100 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2101 void *cbarg
, bfa_status_t req_status
,
2102 u32 rsp_len
, u32 resid_len
,
2103 struct fchs_s
*rsp_fchs
)
2105 struct bfa_fcs_lport_fdmi_s
*fdmi
=
2106 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
2107 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2108 struct ct_hdr_s
*cthdr
= NULL
;
2110 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2115 if (req_status
!= BFA_STATUS_OK
) {
2116 bfa_trc(port
->fcs
, req_status
);
2117 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2121 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2122 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2124 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2125 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
2129 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2130 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2131 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2135 * RPA : Register Port Attributes.
2138 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2140 struct bfa_fcs_lport_fdmi_s
*fdmi
= fdmi_cbarg
;
2141 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2144 struct bfa_fcxp_s
*fcxp
;
2147 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2149 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2151 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
2152 bfa_fcs_lport_fdmi_send_rpa
, fdmi
);
2157 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
2158 memset(pyld
, 0, FC_MAX_PDUSZ
);
2160 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_lport_get_fcid(port
),
2163 attr_len
= bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi
,
2164 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
2166 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2167 FC_CLASS_3
, len
+ attr_len
, &fchs
,
2168 bfa_fcs_lport_fdmi_rpa_response
, (void *)fdmi
,
2169 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2171 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPA_SENT
);
2175 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s
*fdmi
, u8
*pyld
)
2177 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2178 struct fdmi_rpa_s
*rpa
= (struct fdmi_rpa_s
*) pyld
;
2181 rpa
->port_name
= bfa_fcs_lport_get_pwwn(port
);
2183 len
= bfa_fcs_lport_fdmi_build_portattr_block(fdmi
,
2184 (u8
*) &rpa
->port_attr_blk
);
2186 len
+= sizeof(rpa
->port_name
);
2192 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2193 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
2194 u32 resid_len
, struct fchs_s
*rsp_fchs
)
2196 struct bfa_fcs_lport_fdmi_s
*fdmi
=
2197 (struct bfa_fcs_lport_fdmi_s
*) cbarg
;
2198 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2199 struct ct_hdr_s
*cthdr
= NULL
;
2201 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2206 if (req_status
!= BFA_STATUS_OK
) {
2207 bfa_trc(port
->fcs
, req_status
);
2208 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2212 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2213 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2215 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2216 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
2220 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2221 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2222 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
2226 bfa_fcs_lport_fdmi_timeout(void *arg
)
2228 struct bfa_fcs_lport_fdmi_s
*fdmi
= (struct bfa_fcs_lport_fdmi_s
*) arg
;
2230 bfa_sm_send_event(fdmi
, FDMISM_EVENT_TIMEOUT
);
2234 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
2235 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
)
2237 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2238 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
2240 memset(hba_attr
, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s
));
2242 bfa_ioc_get_adapter_manufacturer(&port
->fcs
->bfa
->ioc
,
2243 hba_attr
->manufacturer
);
2244 bfa_ioc_get_adapter_serial_num(&port
->fcs
->bfa
->ioc
,
2245 hba_attr
->serial_num
);
2246 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
,
2248 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
,
2249 hba_attr
->model_desc
);
2250 bfa_ioc_get_pci_chip_rev(&port
->fcs
->bfa
->ioc
,
2251 hba_attr
->hw_version
);
2252 bfa_ioc_get_adapter_optrom_ver(&port
->fcs
->bfa
->ioc
,
2253 hba_attr
->option_rom_ver
);
2254 bfa_ioc_get_adapter_fw_ver(&port
->fcs
->bfa
->ioc
,
2255 hba_attr
->fw_version
);
2257 strncpy(hba_attr
->driver_version
, (char *)driver_info
->version
,
2258 sizeof(hba_attr
->driver_version
));
2260 strncpy(hba_attr
->os_name
, driver_info
->host_os_name
,
2261 sizeof(hba_attr
->os_name
));
2264 * If there is a patch level, append it
2265 * to the os name along with a separator
2267 if (driver_info
->host_os_patch
[0] != '\0') {
2268 strncat(hba_attr
->os_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
2269 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
2270 strncat(hba_attr
->os_name
, driver_info
->host_os_patch
,
2271 sizeof(driver_info
->host_os_patch
));
2274 hba_attr
->max_ct_pyld
= cpu_to_be32(FC_MAX_PDUSZ
);
2278 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s
*fdmi
,
2279 struct bfa_fcs_fdmi_port_attr_s
*port_attr
)
2281 struct bfa_fcs_lport_s
*port
= fdmi
->ms
->port
;
2282 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
2283 struct bfa_port_attr_s pport_attr
;
2285 memset(port_attr
, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s
));
2288 * get pport attributes from hal
2290 bfa_fcport_get_attr(port
->fcs
->bfa
, &pport_attr
);
2293 * get FC4 type Bitmask
2295 fc_get_fc4type_bitmask(FC_TYPE_FCP
, port_attr
->supp_fc4_types
);
2300 switch (pport_attr
.speed_supported
) {
2301 case BFA_PORT_SPEED_16GBPS
:
2302 port_attr
->supp_speed
=
2303 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G
);
2306 case BFA_PORT_SPEED_10GBPS
:
2307 port_attr
->supp_speed
=
2308 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G
);
2311 case BFA_PORT_SPEED_8GBPS
:
2312 port_attr
->supp_speed
=
2313 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G
);
2316 case BFA_PORT_SPEED_4GBPS
:
2317 port_attr
->supp_speed
=
2318 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G
);
2322 bfa_sm_fault(port
->fcs
, pport_attr
.speed_supported
);
2328 port_attr
->curr_speed
= cpu_to_be32(
2329 bfa_fcs_fdmi_convert_speed(pport_attr
.speed
));
2334 port_attr
->max_frm_size
= cpu_to_be32(FC_MAX_PDUSZ
);
2339 strncpy(port_attr
->os_device_name
, (char *)driver_info
->os_device_name
,
2340 sizeof(port_attr
->os_device_name
));
2345 strncpy(port_attr
->host_name
, (char *)driver_info
->host_machine_name
,
2346 sizeof(port_attr
->host_name
));
2351 * Convert BFA speed to FDMI format.
2354 bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed
)
2358 switch (pport_speed
) {
2359 case BFA_PORT_SPEED_1GBPS
:
2360 case BFA_PORT_SPEED_2GBPS
:
2364 case BFA_PORT_SPEED_4GBPS
:
2365 ret
= FDMI_TRANS_SPEED_4G
;
2368 case BFA_PORT_SPEED_8GBPS
:
2369 ret
= FDMI_TRANS_SPEED_8G
;
2372 case BFA_PORT_SPEED_10GBPS
:
2373 ret
= FDMI_TRANS_SPEED_10G
;
2376 case BFA_PORT_SPEED_16GBPS
:
2377 ret
= FDMI_TRANS_SPEED_16G
;
2381 ret
= FDMI_TRANS_SPEED_UNKNOWN
;
2387 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s
*ms
)
2389 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2392 if (ms
->port
->fcs
->fdmi_enabled
)
2393 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_offline
);
2395 bfa_sm_set_state(fdmi
, bfa_fcs_lport_fdmi_sm_disabled
);
2399 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s
*ms
)
2401 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2404 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_OFFLINE
);
2408 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s
*ms
)
2410 struct bfa_fcs_lport_fdmi_s
*fdmi
= &ms
->fdmi
;
2413 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_ONLINE
);
2416 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2419 * forward declarations
2421 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg
,
2422 struct bfa_fcxp_s
*fcxp_alloced
);
2423 static void bfa_fcs_lport_ms_timeout(void *arg
);
2424 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg
,
2425 struct bfa_fcxp_s
*fcxp
,
2427 bfa_status_t req_status
,
2430 struct fchs_s
*rsp_fchs
);
2432 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg
,
2433 struct bfa_fcxp_s
*fcxp_alloced
);
2434 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg
,
2435 struct bfa_fcxp_s
*fcxp
,
2437 bfa_status_t req_status
,
2440 struct fchs_s
*rsp_fchs
);
2441 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg
,
2442 struct bfa_fcxp_s
*fcxp_alloced
);
2443 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg
,
2444 struct bfa_fcxp_s
*fcxp
,
2446 bfa_status_t req_status
,
2449 struct fchs_s
*rsp_fchs
);
2451 * fcs_ms_sm FCS MS state machine
2455 * MS State Machine events
2457 enum port_ms_event
{
2458 MSSM_EVENT_PORT_ONLINE
= 1,
2459 MSSM_EVENT_PORT_OFFLINE
= 2,
2460 MSSM_EVENT_RSP_OK
= 3,
2461 MSSM_EVENT_RSP_ERROR
= 4,
2462 MSSM_EVENT_TIMEOUT
= 5,
2463 MSSM_EVENT_FCXP_SENT
= 6,
2464 MSSM_EVENT_PORT_FABRIC_RSCN
= 7
2467 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s
*ms
,
2468 enum port_ms_event event
);
2469 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s
*ms
,
2470 enum port_ms_event event
);
2471 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s
*ms
,
2472 enum port_ms_event event
);
2473 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s
*ms
,
2474 enum port_ms_event event
);
2475 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s
*ms
,
2476 enum port_ms_event event
);
2477 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s
*ms
,
2478 enum port_ms_event event
);
2479 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s
*ms
,
2480 enum port_ms_event event
);
2481 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s
*ms
,
2482 enum port_ms_event event
);
2483 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s
*ms
,
2484 enum port_ms_event event
);
2485 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s
*ms
,
2486 enum port_ms_event event
);
2487 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s
*ms
,
2488 enum port_ms_event event
);
2490 * Start in offline state - awaiting NS to send start.
2493 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s
*ms
,
2494 enum port_ms_event event
)
2496 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2497 bfa_trc(ms
->port
->fcs
, event
);
2500 case MSSM_EVENT_PORT_ONLINE
:
2501 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_sending
);
2502 bfa_fcs_lport_ms_send_plogi(ms
, NULL
);
2505 case MSSM_EVENT_PORT_OFFLINE
:
2509 bfa_sm_fault(ms
->port
->fcs
, event
);
2514 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s
*ms
,
2515 enum port_ms_event event
)
2517 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2518 bfa_trc(ms
->port
->fcs
, event
);
2521 case MSSM_EVENT_FCXP_SENT
:
2522 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi
);
2525 case MSSM_EVENT_PORT_OFFLINE
:
2526 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2527 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2532 bfa_sm_fault(ms
->port
->fcs
, event
);
2537 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s
*ms
,
2538 enum port_ms_event event
)
2540 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2541 bfa_trc(ms
->port
->fcs
, event
);
2544 case MSSM_EVENT_RSP_ERROR
:
2546 * Start timer for a delayed retry
2548 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_retry
);
2549 ms
->port
->stats
.ms_retries
++;
2550 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2551 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2552 BFA_FCS_RETRY_TIMEOUT
);
2555 case MSSM_EVENT_RSP_OK
:
2557 * since plogi is done, now invoke MS related sub-modules
2559 bfa_fcs_lport_fdmi_online(ms
);
2562 * if this is a Vport, go to online state.
2564 if (ms
->port
->vport
) {
2565 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2570 * For a base port we need to get the
2571 * switch's IP address.
2573 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_sending
);
2574 bfa_fcs_lport_ms_send_gmal(ms
, NULL
);
2577 case MSSM_EVENT_PORT_OFFLINE
:
2578 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2579 bfa_fcxp_discard(ms
->fcxp
);
2583 bfa_sm_fault(ms
->port
->fcs
, event
);
2588 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s
*ms
,
2589 enum port_ms_event event
)
2591 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2592 bfa_trc(ms
->port
->fcs
, event
);
2595 case MSSM_EVENT_TIMEOUT
:
2597 * Retry Timer Expired. Re-send
2599 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_plogi_sending
);
2600 bfa_fcs_lport_ms_send_plogi(ms
, NULL
);
2603 case MSSM_EVENT_PORT_OFFLINE
:
2604 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2605 bfa_timer_stop(&ms
->timer
);
2609 bfa_sm_fault(ms
->port
->fcs
, event
);
2614 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s
*ms
,
2615 enum port_ms_event event
)
2617 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2618 bfa_trc(ms
->port
->fcs
, event
);
2621 case MSSM_EVENT_PORT_OFFLINE
:
2622 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2625 case MSSM_EVENT_PORT_FABRIC_RSCN
:
2626 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2628 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2632 bfa_sm_fault(ms
->port
->fcs
, event
);
2637 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s
*ms
,
2638 enum port_ms_event event
)
2640 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2641 bfa_trc(ms
->port
->fcs
, event
);
2644 case MSSM_EVENT_FCXP_SENT
:
2645 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal
);
2648 case MSSM_EVENT_PORT_OFFLINE
:
2649 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2650 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2655 bfa_sm_fault(ms
->port
->fcs
, event
);
2660 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s
*ms
,
2661 enum port_ms_event event
)
2663 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2664 bfa_trc(ms
->port
->fcs
, event
);
2667 case MSSM_EVENT_RSP_ERROR
:
2669 * Start timer for a delayed retry
2671 if (ms
->retry_cnt
++ < BFA_FCS_MS_CMD_MAX_RETRIES
) {
2672 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_retry
);
2673 ms
->port
->stats
.ms_retries
++;
2674 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2675 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2676 BFA_FCS_RETRY_TIMEOUT
);
2678 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2679 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2684 case MSSM_EVENT_RSP_OK
:
2685 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2686 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2689 case MSSM_EVENT_PORT_OFFLINE
:
2690 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2691 bfa_fcxp_discard(ms
->fcxp
);
2695 bfa_sm_fault(ms
->port
->fcs
, event
);
2700 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s
*ms
,
2701 enum port_ms_event event
)
2703 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2704 bfa_trc(ms
->port
->fcs
, event
);
2707 case MSSM_EVENT_TIMEOUT
:
2709 * Retry Timer Expired. Re-send
2711 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gmal_sending
);
2712 bfa_fcs_lport_ms_send_gmal(ms
, NULL
);
2715 case MSSM_EVENT_PORT_OFFLINE
:
2716 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2717 bfa_timer_stop(&ms
->timer
);
2721 bfa_sm_fault(ms
->port
->fcs
, event
);
2725 * ms_pvt MS local functions
2729 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2731 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
2732 bfa_fcs_lport_t
*port
= ms
->port
;
2735 struct bfa_fcxp_s
*fcxp
;
2737 bfa_trc(port
->fcs
, port
->pid
);
2739 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2741 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
2742 bfa_fcs_lport_ms_send_gmal
, ms
);
2747 len
= fc_gmal_req_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2748 bfa_fcs_lport_get_fcid(port
),
2749 port
->fabric
->lps
->pr_nwwn
);
2751 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2752 FC_CLASS_3
, len
, &fchs
,
2753 bfa_fcs_lport_ms_gmal_response
, (void *)ms
,
2754 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2756 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
2760 bfa_fcs_lport_ms_gmal_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2761 void *cbarg
, bfa_status_t req_status
,
2762 u32 rsp_len
, u32 resid_len
,
2763 struct fchs_s
*rsp_fchs
)
2765 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
2766 bfa_fcs_lport_t
*port
= ms
->port
;
2767 struct ct_hdr_s
*cthdr
= NULL
;
2768 struct fcgs_gmal_resp_s
*gmal_resp
;
2769 struct fcgs_gmal_entry_s
*gmal_entry
;
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 gmal_resp
= (struct fcgs_gmal_resp_s
*)(cthdr
+ 1);
2791 num_entries
= be32_to_cpu(gmal_resp
->ms_len
);
2792 if (num_entries
== 0) {
2793 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2797 * The response could contain multiple Entries.
2798 * Entries for SNMP interface, etc.
2799 * We look for the entry with a telnet prefix.
2800 * First "http://" entry refers to IP addr
2803 gmal_entry
= (struct fcgs_gmal_entry_s
*)gmal_resp
->ms_ma
;
2804 while (num_entries
> 0) {
2805 if (strncmp(gmal_entry
->prefix
,
2806 CT_GMAL_RESP_PREFIX_HTTP
,
2807 sizeof(gmal_entry
->prefix
)) == 0) {
2810 * if the IP address is terminating with a '/',
2812 * Byte 0 consists of the length of the string.
2814 rsp_str
= &(gmal_entry
->prefix
[0]);
2815 if (rsp_str
[gmal_entry
->len
-1] == '/')
2816 rsp_str
[gmal_entry
->len
-1] = 0;
2818 /* copy IP Address to fabric */
2819 strncpy(bfa_fcs_lport_get_fabric_ipaddr(port
),
2820 gmal_entry
->ip_addr
,
2821 BFA_FCS_FABRIC_IPADDR_SZ
);
2829 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
2833 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2834 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2835 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2839 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s
*ms
,
2840 enum port_ms_event event
)
2842 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2843 bfa_trc(ms
->port
->fcs
, event
);
2846 case MSSM_EVENT_FCXP_SENT
:
2847 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn
);
2850 case MSSM_EVENT_PORT_OFFLINE
:
2851 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2852 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2857 bfa_sm_fault(ms
->port
->fcs
, event
);
2862 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s
*ms
,
2863 enum port_ms_event event
)
2865 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2866 bfa_trc(ms
->port
->fcs
, event
);
2869 case MSSM_EVENT_RSP_ERROR
:
2871 * Start timer for a delayed retry
2873 if (ms
->retry_cnt
++ < BFA_FCS_MS_CMD_MAX_RETRIES
) {
2874 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_retry
);
2875 ms
->port
->stats
.ms_retries
++;
2876 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms
->port
),
2877 &ms
->timer
, bfa_fcs_lport_ms_timeout
, ms
,
2878 BFA_FCS_RETRY_TIMEOUT
);
2880 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2885 case MSSM_EVENT_RSP_OK
:
2886 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_online
);
2889 case MSSM_EVENT_PORT_OFFLINE
:
2890 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2891 bfa_fcxp_discard(ms
->fcxp
);
2895 bfa_sm_fault(ms
->port
->fcs
, event
);
2900 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s
*ms
,
2901 enum port_ms_event event
)
2903 bfa_trc(ms
->port
->fcs
, ms
->port
->port_cfg
.pwwn
);
2904 bfa_trc(ms
->port
->fcs
, event
);
2907 case MSSM_EVENT_TIMEOUT
:
2909 * Retry Timer Expired. Re-send
2911 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_gfn_sending
);
2912 bfa_fcs_lport_ms_send_gfn(ms
, NULL
);
2915 case MSSM_EVENT_PORT_OFFLINE
:
2916 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
2917 bfa_timer_stop(&ms
->timer
);
2921 bfa_sm_fault(ms
->port
->fcs
, event
);
2925 * ms_pvt MS local functions
2929 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2931 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
2932 bfa_fcs_lport_t
*port
= ms
->port
;
2935 struct bfa_fcxp_s
*fcxp
;
2937 bfa_trc(port
->fcs
, port
->pid
);
2939 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2941 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
2942 bfa_fcs_lport_ms_send_gfn
, ms
);
2947 len
= fc_gfn_req_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2948 bfa_fcs_lport_get_fcid(port
),
2949 port
->fabric
->lps
->pr_nwwn
);
2951 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2952 FC_CLASS_3
, len
, &fchs
,
2953 bfa_fcs_lport_ms_gfn_response
, (void *)ms
,
2954 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
2956 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
2960 bfa_fcs_lport_ms_gfn_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
2961 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
2962 u32 resid_len
, struct fchs_s
*rsp_fchs
)
2964 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
2965 bfa_fcs_lport_t
*port
= ms
->port
;
2966 struct ct_hdr_s
*cthdr
= NULL
;
2969 bfa_trc(port
->fcs
, req_status
);
2970 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
2975 if (req_status
!= BFA_STATUS_OK
) {
2976 bfa_trc(port
->fcs
, req_status
);
2977 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
2981 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2982 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2984 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2985 gfn_resp
= (wwn_t
*)(cthdr
+ 1);
2986 /* check if it has actually changed */
2987 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port
),
2988 gfn_resp
, sizeof(wwn_t
)) != 0)) {
2989 bfa_fcs_fabric_set_fabric_name(port
->fabric
, *gfn_resp
);
2991 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
2995 bfa_trc(port
->fcs
, cthdr
->reason_code
);
2996 bfa_trc(port
->fcs
, cthdr
->exp_code
);
2997 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
3001 * ms_pvt MS local functions
3005 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3007 struct bfa_fcs_lport_ms_s
*ms
= ms_cbarg
;
3008 struct bfa_fcs_lport_s
*port
= ms
->port
;
3011 struct bfa_fcxp_s
*fcxp
;
3013 bfa_trc(port
->fcs
, port
->pid
);
3015 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3017 port
->stats
.ms_plogi_alloc_wait
++;
3018 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ms
->fcxp_wqe
,
3019 bfa_fcs_lport_ms_send_plogi
, ms
);
3024 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3025 bfa_hton3b(FC_MGMT_SERVER
),
3026 bfa_fcs_lport_get_fcid(port
), 0,
3027 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
3028 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
),
3029 bfa_fcport_get_rx_bbcredit(port
->fcs
->bfa
));
3031 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3032 FC_CLASS_3
, len
, &fchs
,
3033 bfa_fcs_lport_ms_plogi_response
, (void *)ms
,
3034 FC_MAX_PDUSZ
, FC_ELS_TOV
);
3036 port
->stats
.ms_plogi_sent
++;
3037 bfa_sm_send_event(ms
, MSSM_EVENT_FCXP_SENT
);
3041 bfa_fcs_lport_ms_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3042 void *cbarg
, bfa_status_t req_status
,
3043 u32 rsp_len
, u32 resid_len
, struct fchs_s
*rsp_fchs
)
3045 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) cbarg
;
3046 struct bfa_fcs_lport_s
*port
= ms
->port
;
3047 struct fc_els_cmd_s
*els_cmd
;
3048 struct fc_ls_rjt_s
*ls_rjt
;
3050 bfa_trc(port
->fcs
, req_status
);
3051 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3056 if (req_status
!= BFA_STATUS_OK
) {
3057 port
->stats
.ms_plogi_rsp_err
++;
3058 bfa_trc(port
->fcs
, req_status
);
3059 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
3063 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3065 switch (els_cmd
->els_code
) {
3068 if (rsp_len
< sizeof(struct fc_logi_s
)) {
3069 bfa_trc(port
->fcs
, rsp_len
);
3070 port
->stats
.ms_plogi_acc_err
++;
3071 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
3074 port
->stats
.ms_plogi_accepts
++;
3075 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_OK
);
3079 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3081 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
3082 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
3084 port
->stats
.ms_rejects
++;
3085 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
3089 port
->stats
.ms_plogi_unknown_rsp
++;
3090 bfa_trc(port
->fcs
, els_cmd
->els_code
);
3091 bfa_sm_send_event(ms
, MSSM_EVENT_RSP_ERROR
);
3096 bfa_fcs_lport_ms_timeout(void *arg
)
3098 struct bfa_fcs_lport_ms_s
*ms
= (struct bfa_fcs_lport_ms_s
*) arg
;
3100 ms
->port
->stats
.ms_timeouts
++;
3101 bfa_sm_send_event(ms
, MSSM_EVENT_TIMEOUT
);
3106 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s
*port
)
3108 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
3111 bfa_sm_set_state(ms
, bfa_fcs_lport_ms_sm_offline
);
3114 * Invoke init routines of sub modules.
3116 bfa_fcs_lport_fdmi_init(ms
);
3120 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s
*port
)
3122 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
3125 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_OFFLINE
);
3126 bfa_fcs_lport_fdmi_offline(ms
);
3130 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s
*port
)
3132 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
3135 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_ONLINE
);
3138 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s
*port
)
3140 struct bfa_fcs_lport_ms_s
*ms
= BFA_FCS_GET_MS_FROM_PORT(port
);
3142 /* todo. Handle this only when in Online state */
3143 if (bfa_sm_cmp_state(ms
, bfa_fcs_lport_ms_sm_online
))
3144 bfa_sm_send_event(ms
, MSSM_EVENT_PORT_FABRIC_RSCN
);
3148 * @page ns_sm_info VPORT NS State Machine
3150 * @section ns_sm_interactions VPORT NS State Machine Interactions
3152 * @section ns_sm VPORT NS State Machine
3157 * forward declarations
3159 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg
,
3160 struct bfa_fcxp_s
*fcxp_alloced
);
3161 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg
,
3162 struct bfa_fcxp_s
*fcxp_alloced
);
3163 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg
,
3164 struct bfa_fcxp_s
*fcxp_alloced
);
3165 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg
,
3166 struct bfa_fcxp_s
*fcxp_alloced
);
3167 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg
,
3168 struct bfa_fcxp_s
*fcxp_alloced
);
3169 static void bfa_fcs_lport_ns_timeout(void *arg
);
3170 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg
,
3171 struct bfa_fcxp_s
*fcxp
,
3173 bfa_status_t req_status
,
3176 struct fchs_s
*rsp_fchs
);
3177 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg
,
3178 struct bfa_fcxp_s
*fcxp
,
3180 bfa_status_t req_status
,
3183 struct fchs_s
*rsp_fchs
);
3184 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg
,
3185 struct bfa_fcxp_s
*fcxp
,
3187 bfa_status_t req_status
,
3190 struct fchs_s
*rsp_fchs
);
3191 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg
,
3192 struct bfa_fcxp_s
*fcxp
,
3194 bfa_status_t req_status
,
3197 struct fchs_s
*rsp_fchs
);
3198 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg
,
3199 struct bfa_fcxp_s
*fcxp
,
3201 bfa_status_t req_status
,
3204 struct fchs_s
*rsp_fchs
);
3205 static void bfa_fcs_lport_ns_process_gidft_pids(
3206 struct bfa_fcs_lport_s
*port
,
3207 u32
*pid_buf
, u32 n_pids
);
3209 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t
*port
);
3211 * fcs_ns_sm FCS nameserver interface state machine
3215 * VPort NS State Machine events
3217 enum vport_ns_event
{
3218 NSSM_EVENT_PORT_ONLINE
= 1,
3219 NSSM_EVENT_PORT_OFFLINE
= 2,
3220 NSSM_EVENT_PLOGI_SENT
= 3,
3221 NSSM_EVENT_RSP_OK
= 4,
3222 NSSM_EVENT_RSP_ERROR
= 5,
3223 NSSM_EVENT_TIMEOUT
= 6,
3224 NSSM_EVENT_NS_QUERY
= 7,
3225 NSSM_EVENT_RSPNID_SENT
= 8,
3226 NSSM_EVENT_RFTID_SENT
= 9,
3227 NSSM_EVENT_RFFID_SENT
= 10,
3228 NSSM_EVENT_GIDFT_SENT
= 11,
3231 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s
*ns
,
3232 enum vport_ns_event event
);
3233 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s
*ns
,
3234 enum vport_ns_event event
);
3235 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s
*ns
,
3236 enum vport_ns_event event
);
3237 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s
*ns
,
3238 enum vport_ns_event event
);
3239 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3240 struct bfa_fcs_lport_ns_s
*ns
,
3241 enum vport_ns_event event
);
3242 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3243 enum vport_ns_event event
);
3244 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3245 enum vport_ns_event event
);
3246 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3247 struct bfa_fcs_lport_ns_s
*ns
,
3248 enum vport_ns_event event
);
3249 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3250 enum vport_ns_event event
);
3251 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3252 enum vport_ns_event event
);
3253 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3254 struct bfa_fcs_lport_ns_s
*ns
,
3255 enum vport_ns_event event
);
3256 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3257 enum vport_ns_event event
);
3258 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3259 enum vport_ns_event event
);
3260 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3261 struct bfa_fcs_lport_ns_s
*ns
,
3262 enum vport_ns_event event
);
3263 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3264 enum vport_ns_event event
);
3265 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s
*ns
,
3266 enum vport_ns_event event
);
3267 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s
*ns
,
3268 enum vport_ns_event event
);
3270 * Start in offline state - awaiting linkup
3273 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s
*ns
,
3274 enum vport_ns_event event
)
3276 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3277 bfa_trc(ns
->port
->fcs
, event
);
3280 case NSSM_EVENT_PORT_ONLINE
:
3281 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_sending
);
3282 bfa_fcs_lport_ns_send_plogi(ns
, NULL
);
3285 case NSSM_EVENT_PORT_OFFLINE
:
3289 bfa_sm_fault(ns
->port
->fcs
, event
);
3294 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s
*ns
,
3295 enum vport_ns_event event
)
3297 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3298 bfa_trc(ns
->port
->fcs
, event
);
3301 case NSSM_EVENT_PLOGI_SENT
:
3302 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi
);
3305 case NSSM_EVENT_PORT_OFFLINE
:
3306 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3307 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3312 bfa_sm_fault(ns
->port
->fcs
, event
);
3317 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s
*ns
,
3318 enum vport_ns_event event
)
3320 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3321 bfa_trc(ns
->port
->fcs
, event
);
3324 case NSSM_EVENT_RSP_ERROR
:
3326 * Start timer for a delayed retry
3328 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_retry
);
3329 ns
->port
->stats
.ns_retries
++;
3330 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3331 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3332 BFA_FCS_RETRY_TIMEOUT
);
3335 case NSSM_EVENT_RSP_OK
:
3336 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rspn_id
);
3337 bfa_fcs_lport_ns_send_rspn_id(ns
, NULL
);
3340 case NSSM_EVENT_PORT_OFFLINE
:
3341 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3342 bfa_fcxp_discard(ns
->fcxp
);
3346 bfa_sm_fault(ns
->port
->fcs
, event
);
3351 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s
*ns
,
3352 enum vport_ns_event event
)
3354 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3355 bfa_trc(ns
->port
->fcs
, event
);
3358 case NSSM_EVENT_TIMEOUT
:
3360 * Retry Timer Expired. Re-send
3362 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_plogi_sending
);
3363 bfa_fcs_lport_ns_send_plogi(ns
, NULL
);
3366 case NSSM_EVENT_PORT_OFFLINE
:
3367 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3368 bfa_timer_stop(&ns
->timer
);
3372 bfa_sm_fault(ns
->port
->fcs
, event
);
3377 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3378 enum vport_ns_event event
)
3380 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3381 bfa_trc(ns
->port
->fcs
, event
);
3384 case NSSM_EVENT_RSPNID_SENT
:
3385 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rspn_id
);
3388 case NSSM_EVENT_PORT_OFFLINE
:
3389 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3390 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3395 bfa_sm_fault(ns
->port
->fcs
, event
);
3400 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s
*ns
,
3401 enum vport_ns_event event
)
3403 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3404 bfa_trc(ns
->port
->fcs
, event
);
3407 case NSSM_EVENT_RSP_ERROR
:
3409 * Start timer for a delayed retry
3411 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rspn_id_retry
);
3412 ns
->port
->stats
.ns_retries
++;
3413 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3414 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3415 BFA_FCS_RETRY_TIMEOUT
);
3418 case NSSM_EVENT_RSP_OK
:
3419 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rft_id
);
3420 bfa_fcs_lport_ns_send_rft_id(ns
, NULL
);
3423 case NSSM_EVENT_PORT_OFFLINE
:
3424 bfa_fcxp_discard(ns
->fcxp
);
3425 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3429 bfa_sm_fault(ns
->port
->fcs
, event
);
3434 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3435 enum vport_ns_event event
)
3437 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3438 bfa_trc(ns
->port
->fcs
, event
);
3441 case NSSM_EVENT_TIMEOUT
:
3443 * Retry Timer Expired. Re-send
3445 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rspn_id
);
3446 bfa_fcs_lport_ns_send_rspn_id(ns
, NULL
);
3449 case NSSM_EVENT_PORT_OFFLINE
:
3450 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3451 bfa_timer_stop(&ns
->timer
);
3455 bfa_sm_fault(ns
->port
->fcs
, event
);
3460 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3461 enum vport_ns_event event
)
3463 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3464 bfa_trc(ns
->port
->fcs
, event
);
3467 case NSSM_EVENT_RFTID_SENT
:
3468 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rft_id
);
3471 case NSSM_EVENT_PORT_OFFLINE
:
3472 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3473 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3478 bfa_sm_fault(ns
->port
->fcs
, event
);
3483 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s
*ns
,
3484 enum vport_ns_event event
)
3486 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3487 bfa_trc(ns
->port
->fcs
, event
);
3490 case NSSM_EVENT_RSP_OK
:
3491 /* Now move to register FC4 Features */
3492 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rff_id
);
3493 bfa_fcs_lport_ns_send_rff_id(ns
, NULL
);
3496 case NSSM_EVENT_RSP_ERROR
:
3498 * Start timer for a delayed retry
3500 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rft_id_retry
);
3501 ns
->port
->stats
.ns_retries
++;
3502 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3503 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3504 BFA_FCS_RETRY_TIMEOUT
);
3507 case NSSM_EVENT_PORT_OFFLINE
:
3508 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3509 bfa_fcxp_discard(ns
->fcxp
);
3513 bfa_sm_fault(ns
->port
->fcs
, event
);
3518 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3519 enum vport_ns_event event
)
3521 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3522 bfa_trc(ns
->port
->fcs
, event
);
3525 case NSSM_EVENT_TIMEOUT
:
3526 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rft_id
);
3527 bfa_fcs_lport_ns_send_rft_id(ns
, NULL
);
3530 case NSSM_EVENT_PORT_OFFLINE
:
3531 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3532 bfa_timer_stop(&ns
->timer
);
3536 bfa_sm_fault(ns
->port
->fcs
, event
);
3541 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3542 enum vport_ns_event event
)
3544 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3545 bfa_trc(ns
->port
->fcs
, event
);
3548 case NSSM_EVENT_RFFID_SENT
:
3549 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rff_id
);
3552 case NSSM_EVENT_PORT_OFFLINE
:
3553 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3554 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3559 bfa_sm_fault(ns
->port
->fcs
, event
);
3564 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s
*ns
,
3565 enum vport_ns_event event
)
3567 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3568 bfa_trc(ns
->port
->fcs
, event
);
3571 case NSSM_EVENT_RSP_OK
:
3574 * If min cfg mode is enabled, we donot initiate rport
3575 * discovery with the fabric. Instead, we will retrieve the
3576 * boot targets from HAL/FW.
3578 if (__fcs_min_cfg(ns
->port
->fcs
)) {
3579 bfa_fcs_lport_ns_boot_target_disc(ns
->port
);
3580 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_online
);
3585 * If the port role is Initiator Mode issue NS query.
3586 * If it is Target Mode, skip this and go to online.
3588 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
3589 bfa_sm_set_state(ns
,
3590 bfa_fcs_lport_ns_sm_sending_gid_ft
);
3591 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3594 * kick off mgmt srvr state machine
3596 bfa_fcs_lport_ms_online(ns
->port
);
3599 case NSSM_EVENT_RSP_ERROR
:
3601 * Start timer for a delayed retry
3603 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_rff_id_retry
);
3604 ns
->port
->stats
.ns_retries
++;
3605 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3606 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3607 BFA_FCS_RETRY_TIMEOUT
);
3610 case NSSM_EVENT_PORT_OFFLINE
:
3611 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3612 bfa_fcxp_discard(ns
->fcxp
);
3616 bfa_sm_fault(ns
->port
->fcs
, event
);
3621 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s
*ns
,
3622 enum vport_ns_event event
)
3624 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3625 bfa_trc(ns
->port
->fcs
, event
);
3628 case NSSM_EVENT_TIMEOUT
:
3629 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_rff_id
);
3630 bfa_fcs_lport_ns_send_rff_id(ns
, NULL
);
3633 case NSSM_EVENT_PORT_OFFLINE
:
3634 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3635 bfa_timer_stop(&ns
->timer
);
3639 bfa_sm_fault(ns
->port
->fcs
, event
);
3643 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3644 enum vport_ns_event event
)
3646 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3647 bfa_trc(ns
->port
->fcs
, event
);
3650 case NSSM_EVENT_GIDFT_SENT
:
3651 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_gid_ft
);
3654 case NSSM_EVENT_PORT_OFFLINE
:
3655 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3656 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3661 bfa_sm_fault(ns
->port
->fcs
, event
);
3666 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s
*ns
,
3667 enum vport_ns_event event
)
3669 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3670 bfa_trc(ns
->port
->fcs
, event
);
3673 case NSSM_EVENT_RSP_OK
:
3674 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_online
);
3677 case NSSM_EVENT_RSP_ERROR
:
3679 * TBD: for certain reject codes, we don't need to retry
3682 * Start timer for a delayed retry
3684 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_gid_ft_retry
);
3685 ns
->port
->stats
.ns_retries
++;
3686 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
3687 &ns
->timer
, bfa_fcs_lport_ns_timeout
, ns
,
3688 BFA_FCS_RETRY_TIMEOUT
);
3691 case NSSM_EVENT_PORT_OFFLINE
:
3692 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3693 bfa_fcxp_discard(ns
->fcxp
);
3696 case NSSM_EVENT_NS_QUERY
:
3700 bfa_sm_fault(ns
->port
->fcs
, event
);
3705 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s
*ns
,
3706 enum vport_ns_event event
)
3708 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3709 bfa_trc(ns
->port
->fcs
, event
);
3712 case NSSM_EVENT_TIMEOUT
:
3713 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_sending_gid_ft
);
3714 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3717 case NSSM_EVENT_PORT_OFFLINE
:
3718 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3719 bfa_timer_stop(&ns
->timer
);
3723 bfa_sm_fault(ns
->port
->fcs
, event
);
3728 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s
*ns
,
3729 enum vport_ns_event event
)
3731 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
3732 bfa_trc(ns
->port
->fcs
, event
);
3735 case NSSM_EVENT_PORT_OFFLINE
:
3736 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
3739 case NSSM_EVENT_NS_QUERY
:
3741 * If the port role is Initiator Mode issue NS query.
3742 * If it is Target Mode, skip this and go to online.
3744 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
3745 bfa_sm_set_state(ns
,
3746 bfa_fcs_lport_ns_sm_sending_gid_ft
);
3747 bfa_fcs_lport_ns_send_gid_ft(ns
, NULL
);
3752 bfa_sm_fault(ns
->port
->fcs
, event
);
3759 * ns_pvt Nameserver local functions
3763 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3765 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3766 struct bfa_fcs_lport_s
*port
= ns
->port
;
3769 struct bfa_fcxp_s
*fcxp
;
3771 bfa_trc(port
->fcs
, port
->pid
);
3773 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3775 port
->stats
.ns_plogi_alloc_wait
++;
3776 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3777 bfa_fcs_lport_ns_send_plogi
, ns
);
3782 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3783 bfa_hton3b(FC_NAME_SERVER
),
3784 bfa_fcs_lport_get_fcid(port
), 0,
3785 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
3786 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
),
3787 bfa_fcport_get_rx_bbcredit(port
->fcs
->bfa
));
3789 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3790 FC_CLASS_3
, len
, &fchs
,
3791 bfa_fcs_lport_ns_plogi_response
, (void *)ns
,
3792 FC_MAX_PDUSZ
, FC_ELS_TOV
);
3793 port
->stats
.ns_plogi_sent
++;
3795 bfa_sm_send_event(ns
, NSSM_EVENT_PLOGI_SENT
);
3799 bfa_fcs_lport_ns_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3800 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
3801 u32 resid_len
, 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 fc_logi_s *plogi_resp; */
3806 struct fc_els_cmd_s
*els_cmd
;
3807 struct fc_ls_rjt_s
*ls_rjt
;
3809 bfa_trc(port
->fcs
, req_status
);
3810 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3815 if (req_status
!= BFA_STATUS_OK
) {
3816 bfa_trc(port
->fcs
, req_status
);
3817 port
->stats
.ns_plogi_rsp_err
++;
3818 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3822 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3824 switch (els_cmd
->els_code
) {
3827 if (rsp_len
< sizeof(struct fc_logi_s
)) {
3828 bfa_trc(port
->fcs
, rsp_len
);
3829 port
->stats
.ns_plogi_acc_err
++;
3830 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3833 port
->stats
.ns_plogi_accepts
++;
3834 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3838 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3840 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
3841 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
3843 port
->stats
.ns_rejects
++;
3845 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3849 port
->stats
.ns_plogi_unknown_rsp
++;
3850 bfa_trc(port
->fcs
, els_cmd
->els_code
);
3851 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3856 * Register the symbolic port name.
3859 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3861 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3862 struct bfa_fcs_lport_s
*port
= ns
->port
;
3865 struct bfa_fcxp_s
*fcxp
;
3867 u8
*psymbl
= &symbl
[0];
3869 memset(symbl
, 0, sizeof(symbl
));
3871 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3873 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3875 port
->stats
.ns_rspnid_alloc_wait
++;
3876 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3877 bfa_fcs_lport_ns_send_rspn_id
, ns
);
3883 * for V-Port, form a Port Symbolic Name
3887 * For Vports, we append the vport's port symbolic name
3888 * to that of the base port.
3891 strncpy((char *)psymbl
,
3893 (bfa_fcs_lport_get_psym_name
3894 (bfa_fcs_get_base_port(port
->fcs
))),
3896 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3899 /* Ensure we have a null terminating string. */
3900 ((char *)psymbl
)[strlen((char *) &
3901 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3903 strncat((char *)psymbl
,
3904 (char *) &(bfa_fcs_lport_get_psym_name(port
)),
3905 strlen((char *) &bfa_fcs_lport_get_psym_name(port
)));
3907 psymbl
= (u8
*) &(bfa_fcs_lport_get_psym_name(port
));
3910 len
= fc_rspnid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3911 bfa_fcs_lport_get_fcid(port
), 0, psymbl
);
3913 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3914 FC_CLASS_3
, len
, &fchs
,
3915 bfa_fcs_lport_ns_rspn_id_response
, (void *)ns
,
3916 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
3918 port
->stats
.ns_rspnid_sent
++;
3920 bfa_sm_send_event(ns
, NSSM_EVENT_RSPNID_SENT
);
3924 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3925 void *cbarg
, bfa_status_t req_status
,
3926 u32 rsp_len
, u32 resid_len
,
3927 struct fchs_s
*rsp_fchs
)
3929 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
3930 struct bfa_fcs_lport_s
*port
= ns
->port
;
3931 struct ct_hdr_s
*cthdr
= NULL
;
3933 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3938 if (req_status
!= BFA_STATUS_OK
) {
3939 bfa_trc(port
->fcs
, req_status
);
3940 port
->stats
.ns_rspnid_rsp_err
++;
3941 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3945 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3946 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
3948 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
3949 port
->stats
.ns_rspnid_accepts
++;
3950 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
3954 port
->stats
.ns_rspnid_rejects
++;
3955 bfa_trc(port
->fcs
, cthdr
->reason_code
);
3956 bfa_trc(port
->fcs
, cthdr
->exp_code
);
3957 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
3961 * Register FC4-Types
3964 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
3966 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
3967 struct bfa_fcs_lport_s
*port
= ns
->port
;
3970 struct bfa_fcxp_s
*fcxp
;
3972 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
3974 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
3976 port
->stats
.ns_rftid_alloc_wait
++;
3977 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
3978 bfa_fcs_lport_ns_send_rft_id
, ns
);
3983 len
= fc_rftid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
3984 bfa_fcs_lport_get_fcid(port
), 0, port
->port_cfg
.roles
);
3986 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
3987 FC_CLASS_3
, len
, &fchs
,
3988 bfa_fcs_lport_ns_rft_id_response
, (void *)ns
,
3989 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
3991 port
->stats
.ns_rftid_sent
++;
3992 bfa_sm_send_event(ns
, NSSM_EVENT_RFTID_SENT
);
3996 bfa_fcs_lport_ns_rft_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
3997 void *cbarg
, bfa_status_t req_status
,
3998 u32 rsp_len
, u32 resid_len
,
3999 struct fchs_s
*rsp_fchs
)
4001 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
4002 struct bfa_fcs_lport_s
*port
= ns
->port
;
4003 struct ct_hdr_s
*cthdr
= NULL
;
4005 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4010 if (req_status
!= BFA_STATUS_OK
) {
4011 bfa_trc(port
->fcs
, req_status
);
4012 port
->stats
.ns_rftid_rsp_err
++;
4013 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4017 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4018 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
4020 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
4021 port
->stats
.ns_rftid_accepts
++;
4022 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4026 port
->stats
.ns_rftid_rejects
++;
4027 bfa_trc(port
->fcs
, cthdr
->reason_code
);
4028 bfa_trc(port
->fcs
, cthdr
->exp_code
);
4029 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4033 * Register FC4-Features : Should be done after RFT_ID
4036 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
4038 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
4039 struct bfa_fcs_lport_s
*port
= ns
->port
;
4042 struct bfa_fcxp_s
*fcxp
;
4045 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4047 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
4049 port
->stats
.ns_rffid_alloc_wait
++;
4050 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
4051 bfa_fcs_lport_ns_send_rff_id
, ns
);
4056 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
))
4057 fc4_ftrs
= FC_GS_FCP_FC4_FEATURE_INITIATOR
;
4059 len
= fc_rffid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4060 bfa_fcs_lport_get_fcid(port
), 0,
4061 FC_TYPE_FCP
, fc4_ftrs
);
4063 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
4064 FC_CLASS_3
, len
, &fchs
,
4065 bfa_fcs_lport_ns_rff_id_response
, (void *)ns
,
4066 FC_MAX_PDUSZ
, FC_FCCT_TOV
);
4068 port
->stats
.ns_rffid_sent
++;
4069 bfa_sm_send_event(ns
, NSSM_EVENT_RFFID_SENT
);
4073 bfa_fcs_lport_ns_rff_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
4074 void *cbarg
, bfa_status_t req_status
,
4075 u32 rsp_len
, u32 resid_len
,
4076 struct fchs_s
*rsp_fchs
)
4078 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
4079 struct bfa_fcs_lport_s
*port
= ns
->port
;
4080 struct ct_hdr_s
*cthdr
= NULL
;
4082 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4087 if (req_status
!= BFA_STATUS_OK
) {
4088 bfa_trc(port
->fcs
, req_status
);
4089 port
->stats
.ns_rffid_rsp_err
++;
4090 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4094 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4095 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
4097 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
4098 port
->stats
.ns_rffid_accepts
++;
4099 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4103 port
->stats
.ns_rffid_rejects
++;
4104 bfa_trc(port
->fcs
, cthdr
->reason_code
);
4105 bfa_trc(port
->fcs
, cthdr
->exp_code
);
4107 if (cthdr
->reason_code
== CT_RSN_NOT_SUPP
) {
4108 /* if this command is not supported, we don't retry */
4109 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4111 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4114 * Query Fabric for FC4-Types Devices.
4116 * TBD : Need to use a local (FCS private) response buffer, since the response
4117 * can be larger than 2K.
4120 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
4122 struct bfa_fcs_lport_ns_s
*ns
= ns_cbarg
;
4123 struct bfa_fcs_lport_s
*port
= ns
->port
;
4126 struct bfa_fcxp_s
*fcxp
;
4128 bfa_trc(port
->fcs
, port
->pid
);
4130 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
4132 port
->stats
.ns_gidft_alloc_wait
++;
4133 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
4134 bfa_fcs_lport_ns_send_gid_ft
, ns
);
4140 * This query is only initiated for FCP initiator mode.
4142 len
= fc_gid_ft_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4143 ns
->port
->pid
, FC_TYPE_FCP
);
4145 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
4146 FC_CLASS_3
, len
, &fchs
,
4147 bfa_fcs_lport_ns_gid_ft_response
, (void *)ns
,
4148 bfa_fcxp_get_maxrsp(port
->fcs
->bfa
), FC_FCCT_TOV
);
4150 port
->stats
.ns_gidft_sent
++;
4152 bfa_sm_send_event(ns
, NSSM_EVENT_GIDFT_SENT
);
4156 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
4157 void *cbarg
, bfa_status_t req_status
,
4158 u32 rsp_len
, u32 resid_len
,
4159 struct fchs_s
*rsp_fchs
)
4161 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) cbarg
;
4162 struct bfa_fcs_lport_s
*port
= ns
->port
;
4163 struct ct_hdr_s
*cthdr
= NULL
;
4166 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4171 if (req_status
!= BFA_STATUS_OK
) {
4172 bfa_trc(port
->fcs
, req_status
);
4173 port
->stats
.ns_gidft_rsp_err
++;
4174 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4178 if (resid_len
!= 0) {
4180 * TBD : we will need to allocate a larger buffer & retry the
4183 bfa_trc(port
->fcs
, rsp_len
);
4184 bfa_trc(port
->fcs
, resid_len
);
4188 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4189 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
4191 switch (cthdr
->cmd_rsp_code
) {
4195 port
->stats
.ns_gidft_accepts
++;
4196 n_pids
= (fc_get_ctresp_pyld_len(rsp_len
) / sizeof(u32
));
4197 bfa_trc(port
->fcs
, n_pids
);
4198 bfa_fcs_lport_ns_process_gidft_pids(port
,
4199 (u32
*) (cthdr
+ 1),
4201 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4207 * Check the reason code & explanation.
4208 * There may not have been any FC4 devices in the fabric
4210 port
->stats
.ns_gidft_rejects
++;
4211 bfa_trc(port
->fcs
, cthdr
->reason_code
);
4212 bfa_trc(port
->fcs
, cthdr
->exp_code
);
4214 if ((cthdr
->reason_code
== CT_RSN_UNABLE_TO_PERF
)
4215 && (cthdr
->exp_code
== CT_NS_EXP_FT_NOT_REG
)) {
4217 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
4220 * for all other errors, retry
4222 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4227 port
->stats
.ns_gidft_unknown_rsp
++;
4228 bfa_trc(port
->fcs
, cthdr
->cmd_rsp_code
);
4229 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
4234 * This routine will be called by bfa_timer on timer timeouts.
4236 * param[in] port - pointer to bfa_fcs_lport_t.
4241 * Special Considerations:
4246 bfa_fcs_lport_ns_timeout(void *arg
)
4248 struct bfa_fcs_lport_ns_s
*ns
= (struct bfa_fcs_lport_ns_s
*) arg
;
4250 ns
->port
->stats
.ns_timeouts
++;
4251 bfa_sm_send_event(ns
, NSSM_EVENT_TIMEOUT
);
4255 * Process the PID list in GID_FT response
4258 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s
*port
, u32
*pid_buf
,
4261 struct fcgs_gidft_resp_s
*gidft_entry
;
4262 struct bfa_fcs_rport_s
*rport
;
4265 for (ii
= 0; ii
< n_pids
; ii
++) {
4266 gidft_entry
= (struct fcgs_gidft_resp_s
*) &pid_buf
[ii
];
4268 if (gidft_entry
->pid
== port
->pid
)
4272 * Check if this rport already exists
4274 rport
= bfa_fcs_lport_get_rport_by_pid(port
, gidft_entry
->pid
);
4275 if (rport
== NULL
) {
4277 * this is a new device. create rport
4279 rport
= bfa_fcs_rport_create(port
, gidft_entry
->pid
);
4282 * this rport already exists
4284 bfa_fcs_rport_scn(rport
);
4287 bfa_trc(port
->fcs
, gidft_entry
->pid
);
4290 * if the last entry bit is set, bail out.
4292 if (gidft_entry
->last
)
4298 * fcs_ns_public FCS nameserver public interfaces
4302 * Functions called by port/fab.
4303 * These will send relevant Events to the ns state machine.
4306 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s
*port
)
4308 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4311 bfa_sm_set_state(ns
, bfa_fcs_lport_ns_sm_offline
);
4315 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s
*port
)
4317 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4320 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_OFFLINE
);
4324 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s
*port
)
4326 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4329 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_ONLINE
);
4333 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s
*port
)
4335 struct bfa_fcs_lport_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
4337 bfa_trc(port
->fcs
, port
->pid
);
4338 bfa_sm_send_event(ns
, NSSM_EVENT_NS_QUERY
);
4342 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t
*port
)
4345 struct bfa_fcs_rport_s
*rport
;
4347 wwn_t wwns
[BFA_PREBOOT_BOOTLUN_MAX
];
4350 bfa_iocfc_get_bootwwns(port
->fcs
->bfa
, &nwwns
, wwns
);
4352 for (ii
= 0 ; ii
< nwwns
; ++ii
) {
4353 rport
= bfa_fcs_rport_create_by_wwn(port
, wwns
[ii
]);
4362 #define FC_QOS_RSCN_EVENT 0x0c
4363 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
4366 * forward declarations
4368 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg
,
4369 struct bfa_fcxp_s
*fcxp_alloced
);
4370 static void bfa_fcs_lport_scn_scr_response(void *fcsarg
,
4371 struct bfa_fcxp_s
*fcxp
,
4373 bfa_status_t req_status
,
4376 struct fchs_s
*rsp_fchs
);
4377 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s
*port
,
4378 struct fchs_s
*rx_fchs
);
4379 static void bfa_fcs_lport_scn_timeout(void *arg
);
4382 * fcs_scm_sm FCS SCN state machine
4386 * VPort SCN State Machine events
4388 enum port_scn_event
{
4389 SCNSM_EVENT_PORT_ONLINE
= 1,
4390 SCNSM_EVENT_PORT_OFFLINE
= 2,
4391 SCNSM_EVENT_RSP_OK
= 3,
4392 SCNSM_EVENT_RSP_ERROR
= 4,
4393 SCNSM_EVENT_TIMEOUT
= 5,
4394 SCNSM_EVENT_SCR_SENT
= 6,
4397 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s
*scn
,
4398 enum port_scn_event event
);
4399 static void bfa_fcs_lport_scn_sm_sending_scr(
4400 struct bfa_fcs_lport_scn_s
*scn
,
4401 enum port_scn_event event
);
4402 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s
*scn
,
4403 enum port_scn_event event
);
4404 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s
*scn
,
4405 enum port_scn_event event
);
4406 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s
*scn
,
4407 enum port_scn_event event
);
4410 * Starting state - awaiting link up.
4413 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s
*scn
,
4414 enum port_scn_event event
)
4417 case SCNSM_EVENT_PORT_ONLINE
:
4418 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_sending_scr
);
4419 bfa_fcs_lport_scn_send_scr(scn
, NULL
);
4422 case SCNSM_EVENT_PORT_OFFLINE
:
4426 bfa_sm_fault(scn
->port
->fcs
, event
);
4431 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s
*scn
,
4432 enum port_scn_event event
)
4435 case SCNSM_EVENT_SCR_SENT
:
4436 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_scr
);
4439 case SCNSM_EVENT_PORT_OFFLINE
:
4440 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4441 bfa_fcxp_walloc_cancel(scn
->port
->fcs
->bfa
, &scn
->fcxp_wqe
);
4445 bfa_sm_fault(scn
->port
->fcs
, event
);
4450 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s
*scn
,
4451 enum port_scn_event event
)
4453 struct bfa_fcs_lport_s
*port
= scn
->port
;
4456 case SCNSM_EVENT_RSP_OK
:
4457 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_online
);
4460 case SCNSM_EVENT_RSP_ERROR
:
4461 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_scr_retry
);
4462 bfa_timer_start(port
->fcs
->bfa
, &scn
->timer
,
4463 bfa_fcs_lport_scn_timeout
, scn
,
4464 BFA_FCS_RETRY_TIMEOUT
);
4467 case SCNSM_EVENT_PORT_OFFLINE
:
4468 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4469 bfa_fcxp_discard(scn
->fcxp
);
4473 bfa_sm_fault(port
->fcs
, event
);
4478 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s
*scn
,
4479 enum port_scn_event event
)
4482 case SCNSM_EVENT_TIMEOUT
:
4483 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_sending_scr
);
4484 bfa_fcs_lport_scn_send_scr(scn
, NULL
);
4487 case SCNSM_EVENT_PORT_OFFLINE
:
4488 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4489 bfa_timer_stop(&scn
->timer
);
4493 bfa_sm_fault(scn
->port
->fcs
, event
);
4498 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s
*scn
,
4499 enum port_scn_event event
)
4502 case SCNSM_EVENT_PORT_OFFLINE
:
4503 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4507 bfa_sm_fault(scn
->port
->fcs
, event
);
4514 * fcs_scn_private FCS SCN private functions
4518 * This routine will be called to send a SCR command.
4521 bfa_fcs_lport_scn_send_scr(void *scn_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
4523 struct bfa_fcs_lport_scn_s
*scn
= scn_cbarg
;
4524 struct bfa_fcs_lport_s
*port
= scn
->port
;
4527 struct bfa_fcxp_s
*fcxp
;
4529 bfa_trc(port
->fcs
, port
->pid
);
4530 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4532 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
4534 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &scn
->fcxp_wqe
,
4535 bfa_fcs_lport_scn_send_scr
, scn
);
4540 /* Handle VU registrations for Base port only */
4541 if ((!port
->vport
) && bfa_ioc_get_fcmode(&port
->fcs
->bfa
->ioc
)) {
4542 len
= fc_scr_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4543 port
->fabric
->lps
->brcd_switch
,
4546 len
= fc_scr_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4551 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
4552 FC_CLASS_3
, len
, &fchs
,
4553 bfa_fcs_lport_scn_scr_response
,
4554 (void *)scn
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
4556 bfa_sm_send_event(scn
, SCNSM_EVENT_SCR_SENT
);
4560 bfa_fcs_lport_scn_scr_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
4561 void *cbarg
, bfa_status_t req_status
, u32 rsp_len
,
4562 u32 resid_len
, struct fchs_s
*rsp_fchs
)
4564 struct bfa_fcs_lport_scn_s
*scn
= (struct bfa_fcs_lport_scn_s
*) cbarg
;
4565 struct bfa_fcs_lport_s
*port
= scn
->port
;
4566 struct fc_els_cmd_s
*els_cmd
;
4567 struct fc_ls_rjt_s
*ls_rjt
;
4569 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
4574 if (req_status
!= BFA_STATUS_OK
) {
4575 bfa_trc(port
->fcs
, req_status
);
4576 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4580 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4582 switch (els_cmd
->els_code
) {
4585 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_OK
);
4590 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
4592 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
4593 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
4595 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4599 bfa_sm_send_event(scn
, SCNSM_EVENT_RSP_ERROR
);
4607 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s
*port
,
4608 struct fchs_s
*rx_fchs
)
4611 struct bfa_fcxp_s
*fcxp
;
4612 struct bfa_rport_s
*bfa_rport
= NULL
;
4615 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
4617 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
4621 len
= fc_ls_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
4622 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
4625 bfa_fcxp_send(fcxp
, bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
4626 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
4631 * This routine will be called by bfa_timer on timer timeouts.
4633 * param[in] vport - pointer to bfa_fcs_lport_t.
4634 * param[out] vport_status - pointer to return vport status in
4639 * Special Considerations:
4644 bfa_fcs_lport_scn_timeout(void *arg
)
4646 struct bfa_fcs_lport_scn_s
*scn
= (struct bfa_fcs_lport_scn_s
*) arg
;
4648 bfa_sm_send_event(scn
, SCNSM_EVENT_TIMEOUT
);
4654 * fcs_scn_public FCS state change notification public interfaces
4658 * Functions called by port/fab
4661 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s
*port
)
4663 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4666 bfa_sm_set_state(scn
, bfa_fcs_lport_scn_sm_offline
);
4670 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s
*port
)
4672 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4675 bfa_sm_send_event(scn
, SCNSM_EVENT_PORT_OFFLINE
);
4679 bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s
*port
)
4681 struct bfa_fcs_lport_scn_s
*scn
= BFA_FCS_GET_SCN_FROM_PORT(port
);
4684 bfa_sm_send_event(scn
, SCNSM_EVENT_PORT_ONLINE
);
4688 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s
*port
, u32 rpid
)
4690 struct bfa_fcs_rport_s
*rport
;
4692 bfa_trc(port
->fcs
, rpid
);
4695 * If this is an unknown device, then it just came online.
4696 * Otherwise let rport handle the RSCN event.
4698 rport
= bfa_fcs_lport_get_rport_by_pid(port
, rpid
);
4699 if (rport
== NULL
) {
4701 * If min cfg mode is enabled, we donot need to
4702 * discover any new rports.
4704 if (!__fcs_min_cfg(port
->fcs
))
4705 rport
= bfa_fcs_rport_create(port
, rpid
);
4707 bfa_fcs_rport_scn(rport
);
4711 * rscn format based PID comparison
4713 #define __fc_pid_match(__c0, __c1, __fmt) \
4714 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
4715 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
4716 ((__c0)[0] == (__c1)[0])) || \
4717 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
4718 ((__c0)[0] == (__c1)[0]) && \
4719 ((__c0)[1] == (__c1)[1])))
4722 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s
*port
,
4723 enum fc_rscn_format format
,
4726 struct bfa_fcs_rport_s
*rport
;
4727 struct list_head
*qe
, *qe_next
;
4730 bfa_trc(port
->fcs
, format
);
4731 bfa_trc(port
->fcs
, rscn_pid
);
4733 c0
= (u8
*) &rscn_pid
;
4735 list_for_each_safe(qe
, qe_next
, &port
->rport_q
) {
4736 rport
= (struct bfa_fcs_rport_s
*) qe
;
4737 c1
= (u8
*) &rport
->pid
;
4738 if (__fc_pid_match(c0
, c1
, format
))
4739 bfa_fcs_rport_scn(rport
);
4745 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s
*port
,
4746 struct fchs_s
*fchs
, u32 len
)
4748 struct fc_rscn_pl_s
*rscn
= (struct fc_rscn_pl_s
*) (fchs
+ 1);
4751 bfa_boolean_t nsquery
= BFA_FALSE
, found
;
4755 (be16_to_cpu(rscn
->payldlen
) -
4756 sizeof(u32
)) / sizeof(rscn
->event
[0]);
4758 bfa_trc(port
->fcs
, num_entries
);
4760 port
->stats
.num_rscn
++;
4762 bfa_fcs_lport_scn_send_ls_acc(port
, fchs
);
4764 for (i
= 0; i
< num_entries
; i
++) {
4765 rscn_pid
= rscn
->event
[i
].portid
;
4767 bfa_trc(port
->fcs
, rscn
->event
[i
].format
);
4768 bfa_trc(port
->fcs
, rscn_pid
);
4770 /* check for duplicate entries in the list */
4772 for (j
= 0; j
< i
; j
++) {
4773 if (rscn
->event
[j
].portid
== rscn_pid
) {
4779 /* if found in down the list, pid has been already processed */
4781 bfa_trc(port
->fcs
, rscn_pid
);
4785 switch (rscn
->event
[i
].format
) {
4786 case FC_RSCN_FORMAT_PORTID
:
4787 if (rscn
->event
[i
].qualifier
== FC_QOS_RSCN_EVENT
) {
4789 * Ignore this event.
4790 * f/w would have processed it
4792 bfa_trc(port
->fcs
, rscn_pid
);
4794 port
->stats
.num_portid_rscn
++;
4795 bfa_fcs_lport_scn_portid_rscn(port
, rscn_pid
);
4799 case FC_RSCN_FORMAT_FABRIC
:
4800 if (rscn
->event
[i
].qualifier
==
4801 FC_FABRIC_NAME_RSCN_EVENT
) {
4802 bfa_fcs_lport_ms_fabric_rscn(port
);
4805 /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4807 case FC_RSCN_FORMAT_AREA
:
4808 case FC_RSCN_FORMAT_DOMAIN
:
4810 bfa_fcs_lport_scn_multiport_rscn(port
,
4811 rscn
->event
[i
].format
,
4823 * If any of area, domain or fabric RSCN is received, do a fresh
4824 * discovery to find new devices.
4827 bfa_fcs_lport_ns_query(port
);
4834 * fcs_port_api BFA FCS port API
4836 struct bfa_fcs_lport_s
*
4837 bfa_fcs_get_base_port(struct bfa_fcs_s
*fcs
)
4839 return &fcs
->fabric
.bport
;
4843 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s
*port
, wwn_t wwn
, int index
,
4844 int nrports
, bfa_boolean_t bwwn
)
4846 struct list_head
*qh
, *qe
;
4847 struct bfa_fcs_rport_s
*rport
= NULL
;
4849 struct bfa_fcs_s
*fcs
;
4851 if (port
== NULL
|| nrports
== 0)
4855 bfa_trc(fcs
, (u32
) nrports
);
4858 qh
= &port
->rport_q
;
4859 qe
= bfa_q_first(qh
);
4861 while ((qe
!= qh
) && (i
< nrports
)) {
4862 rport
= (struct bfa_fcs_rport_s
*) qe
;
4863 if (bfa_ntoh3b(rport
->pid
) > 0xFFF000) {
4864 qe
= bfa_q_next(qe
);
4865 bfa_trc(fcs
, (u32
) rport
->pwwn
);
4866 bfa_trc(fcs
, rport
->pid
);
4872 if (!memcmp(&wwn
, &rport
->pwwn
, 8))
4880 qe
= bfa_q_next(qe
);
4891 bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s
*port
,
4892 wwn_t rport_wwns
[], int *nrports
)
4894 struct list_head
*qh
, *qe
;
4895 struct bfa_fcs_rport_s
*rport
= NULL
;
4897 struct bfa_fcs_s
*fcs
;
4899 if (port
== NULL
|| rport_wwns
== NULL
|| *nrports
== 0)
4903 bfa_trc(fcs
, (u32
) *nrports
);
4906 qh
= &port
->rport_q
;
4907 qe
= bfa_q_first(qh
);
4909 while ((qe
!= qh
) && (i
< *nrports
)) {
4910 rport
= (struct bfa_fcs_rport_s
*) qe
;
4911 if (bfa_ntoh3b(rport
->pid
) > 0xFFF000) {
4912 qe
= bfa_q_next(qe
);
4913 bfa_trc(fcs
, (u32
) rport
->pwwn
);
4914 bfa_trc(fcs
, rport
->pid
);
4919 rport_wwns
[i
] = rport
->pwwn
;
4922 qe
= bfa_q_next(qe
);
4930 * Iterate's through all the rport's in the given port to
4931 * determine the maximum operating speed.
4933 * !!!! To be used in TRL Functionality only !!!!
4936 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t
*port
)
4938 struct list_head
*qh
, *qe
;
4939 struct bfa_fcs_rport_s
*rport
= NULL
;
4940 struct bfa_fcs_s
*fcs
;
4941 bfa_port_speed_t max_speed
= 0;
4942 struct bfa_port_attr_s port_attr
;
4943 bfa_port_speed_t port_speed
, rport_speed
;
4944 bfa_boolean_t trl_enabled
= bfa_fcport_is_ratelim(port
->fcs
->bfa
);
4952 /* Get Physical port's current speed */
4953 bfa_fcport_get_attr(port
->fcs
->bfa
, &port_attr
);
4954 port_speed
= port_attr
.speed
;
4955 bfa_trc(fcs
, port_speed
);
4957 qh
= &port
->rport_q
;
4958 qe
= bfa_q_first(qh
);
4961 rport
= (struct bfa_fcs_rport_s
*) qe
;
4962 if ((bfa_ntoh3b(rport
->pid
) > 0xFFF000) ||
4963 (bfa_fcs_rport_get_state(rport
) == BFA_RPORT_OFFLINE
) ||
4964 (rport
->scsi_function
!= BFA_RPORT_TARGET
)) {
4965 qe
= bfa_q_next(qe
);
4969 rport_speed
= rport
->rpf
.rpsc_speed
;
4970 if ((trl_enabled
) && (rport_speed
==
4971 BFA_PORT_SPEED_UNKNOWN
)) {
4972 /* Use default ratelim speed setting */
4974 bfa_fcport_get_ratelim_speed(port
->fcs
->bfa
);
4977 if (rport_speed
> max_speed
)
4978 max_speed
= rport_speed
;
4980 qe
= bfa_q_next(qe
);
4983 if (max_speed
> port_speed
)
4984 max_speed
= port_speed
;
4986 bfa_trc(fcs
, max_speed
);
4990 struct bfa_fcs_lport_s
*
4991 bfa_fcs_lookup_port(struct bfa_fcs_s
*fcs
, u16 vf_id
, wwn_t lpwwn
)
4993 struct bfa_fcs_vport_s
*vport
;
4996 WARN_ON(fcs
== NULL
);
4998 vf
= bfa_fcs_vf_lookup(fcs
, vf_id
);
5000 bfa_trc(fcs
, vf_id
);
5004 if (!lpwwn
|| (vf
->bport
.port_cfg
.pwwn
== lpwwn
))
5007 vport
= bfa_fcs_fabric_vport_lookup(vf
, lpwwn
);
5009 return &vport
->lport
;
5015 * API corresponding to NPIV_VPORT_GETINFO.
5018 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s
*port
,
5019 struct bfa_lport_info_s
*port_info
)
5022 bfa_trc(port
->fcs
, port
->fabric
->fabric_name
);
5024 if (port
->vport
== NULL
) {
5026 * This is a Physical port
5028 port_info
->port_type
= BFA_LPORT_TYPE_PHYSICAL
;
5031 * @todo : need to fix the state & reason
5033 port_info
->port_state
= 0;
5034 port_info
->offline_reason
= 0;
5036 port_info
->port_wwn
= bfa_fcs_lport_get_pwwn(port
);
5037 port_info
->node_wwn
= bfa_fcs_lport_get_nwwn(port
);
5039 port_info
->max_vports_supp
=
5040 bfa_lps_get_max_vport(port
->fcs
->bfa
);
5041 port_info
->num_vports_inuse
=
5042 port
->fabric
->num_vports
;
5043 port_info
->max_rports_supp
= BFA_FCS_MAX_RPORTS_SUPP
;
5044 port_info
->num_rports_inuse
= port
->num_rports
;
5047 * This is a virtual port
5049 port_info
->port_type
= BFA_LPORT_TYPE_VIRTUAL
;
5052 * @todo : need to fix the state & reason
5054 port_info
->port_state
= 0;
5055 port_info
->offline_reason
= 0;
5057 port_info
->port_wwn
= bfa_fcs_lport_get_pwwn(port
);
5058 port_info
->node_wwn
= bfa_fcs_lport_get_nwwn(port
);
5063 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s
*fcs_port
,
5064 struct bfa_lport_stats_s
*port_stats
)
5066 *port_stats
= fcs_port
->stats
;
5070 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s
*fcs_port
)
5072 memset(&fcs_port
->stats
, 0, sizeof(struct bfa_lport_stats_s
));
5076 * FCS virtual port state machine
5079 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
5080 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
5081 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
5082 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
5083 #define __vport_fcid(__vp) ((__vp)->lport.pid)
5084 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
5085 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
5087 #define BFA_FCS_VPORT_MAX_RETRIES 5
5089 * Forward declarations
5091 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s
*vport
);
5092 static void bfa_fcs_vport_timeout(void *vport_arg
);
5093 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s
*vport
);
5094 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s
*vport
);
5097 * fcs_vport_sm FCS virtual port state machine
5101 * VPort State Machine events
5103 enum bfa_fcs_vport_event
{
5104 BFA_FCS_VPORT_SM_CREATE
= 1, /* vport create event */
5105 BFA_FCS_VPORT_SM_DELETE
= 2, /* vport delete event */
5106 BFA_FCS_VPORT_SM_START
= 3, /* vport start request */
5107 BFA_FCS_VPORT_SM_STOP
= 4, /* stop: unsupported */
5108 BFA_FCS_VPORT_SM_ONLINE
= 5, /* fabric online */
5109 BFA_FCS_VPORT_SM_OFFLINE
= 6, /* fabric offline event */
5110 BFA_FCS_VPORT_SM_FRMSENT
= 7, /* fdisc/logo sent events */
5111 BFA_FCS_VPORT_SM_RSP_OK
= 8, /* good response */
5112 BFA_FCS_VPORT_SM_RSP_ERROR
= 9, /* error/bad response */
5113 BFA_FCS_VPORT_SM_TIMEOUT
= 10, /* delay timer event */
5114 BFA_FCS_VPORT_SM_DELCOMP
= 11, /* lport delete completion */
5115 BFA_FCS_VPORT_SM_RSP_DUP_WWN
= 12, /* Dup wnn error*/
5116 BFA_FCS_VPORT_SM_RSP_FAILED
= 13, /* non-retryable failure */
5117 BFA_FCS_VPORT_SM_STOPCOMP
= 14, /* vport delete completion */
5120 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s
*vport
,
5121 enum bfa_fcs_vport_event event
);
5122 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s
*vport
,
5123 enum bfa_fcs_vport_event event
);
5124 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s
*vport
,
5125 enum bfa_fcs_vport_event event
);
5126 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s
*vport
,
5127 enum bfa_fcs_vport_event event
);
5128 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s
*vport
,
5129 enum bfa_fcs_vport_event event
);
5130 static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s
*vport
,
5131 enum bfa_fcs_vport_event event
);
5132 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s
*vport
,
5133 enum bfa_fcs_vport_event event
);
5134 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s
*vport
,
5135 enum bfa_fcs_vport_event event
);
5136 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s
*vport
,
5137 enum bfa_fcs_vport_event event
);
5138 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s
*vport
,
5139 enum bfa_fcs_vport_event event
);
5140 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s
*vport
,
5141 enum bfa_fcs_vport_event event
);
5142 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s
*vport
,
5143 enum bfa_fcs_vport_event event
);
5144 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s
*vport
,
5145 enum bfa_fcs_vport_event event
);
5147 static struct bfa_sm_table_s vport_sm_table
[] = {
5148 {BFA_SM(bfa_fcs_vport_sm_uninit
), BFA_FCS_VPORT_UNINIT
},
5149 {BFA_SM(bfa_fcs_vport_sm_created
), BFA_FCS_VPORT_CREATED
},
5150 {BFA_SM(bfa_fcs_vport_sm_offline
), BFA_FCS_VPORT_OFFLINE
},
5151 {BFA_SM(bfa_fcs_vport_sm_fdisc
), BFA_FCS_VPORT_FDISC
},
5152 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry
), BFA_FCS_VPORT_FDISC_RETRY
},
5153 {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait
), BFA_FCS_VPORT_FDISC_RSP_WAIT
},
5154 {BFA_SM(bfa_fcs_vport_sm_online
), BFA_FCS_VPORT_ONLINE
},
5155 {BFA_SM(bfa_fcs_vport_sm_deleting
), BFA_FCS_VPORT_DELETING
},
5156 {BFA_SM(bfa_fcs_vport_sm_cleanup
), BFA_FCS_VPORT_CLEANUP
},
5157 {BFA_SM(bfa_fcs_vport_sm_logo
), BFA_FCS_VPORT_LOGO
},
5158 {BFA_SM(bfa_fcs_vport_sm_error
), BFA_FCS_VPORT_ERROR
}
5165 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s
*vport
,
5166 enum bfa_fcs_vport_event event
)
5168 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5169 bfa_trc(__vport_fcs(vport
), event
);
5172 case BFA_FCS_VPORT_SM_CREATE
:
5173 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_created
);
5174 bfa_fcs_fabric_addvport(__vport_fabric(vport
), vport
);
5178 bfa_sm_fault(__vport_fcs(vport
), event
);
5183 * Created state - a start event is required to start up the state machine.
5186 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s
*vport
,
5187 enum bfa_fcs_vport_event event
)
5189 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5190 bfa_trc(__vport_fcs(vport
), event
);
5193 case BFA_FCS_VPORT_SM_START
:
5194 if (bfa_sm_cmp_state(__vport_fabric(vport
),
5195 bfa_fcs_fabric_sm_online
)
5196 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport
))) {
5197 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
5198 bfa_fcs_vport_do_fdisc(vport
);
5201 * Fabric is offline or not NPIV capable, stay in
5204 vport
->vport_stats
.fab_no_npiv
++;
5205 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5209 case BFA_FCS_VPORT_SM_DELETE
:
5210 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5211 bfa_fcs_lport_delete(&vport
->lport
);
5214 case BFA_FCS_VPORT_SM_ONLINE
:
5215 case BFA_FCS_VPORT_SM_OFFLINE
:
5217 * Ignore ONLINE/OFFLINE events from fabric
5218 * till vport is started.
5223 bfa_sm_fault(__vport_fcs(vport
), event
);
5228 * Offline state - awaiting ONLINE event from fabric SM.
5231 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s
*vport
,
5232 enum bfa_fcs_vport_event event
)
5234 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5235 bfa_trc(__vport_fcs(vport
), event
);
5238 case BFA_FCS_VPORT_SM_DELETE
:
5239 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5240 bfa_fcs_lport_delete(&vport
->lport
);
5243 case BFA_FCS_VPORT_SM_ONLINE
:
5244 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
5245 vport
->fdisc_retries
= 0;
5246 bfa_fcs_vport_do_fdisc(vport
);
5249 case BFA_FCS_VPORT_SM_STOP
:
5250 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5251 bfa_sm_send_event(&vport
->lport
, BFA_FCS_PORT_SM_STOP
);
5254 case BFA_FCS_VPORT_SM_OFFLINE
:
5256 * This can happen if the vport couldn't be initialzied
5257 * due the fact that the npiv was not enabled on the switch.
5258 * In that case we will put the vport in offline state.
5259 * However, the link can go down and cause the this event to
5260 * be sent when we are already offline. Ignore it.
5265 bfa_sm_fault(__vport_fcs(vport
), event
);
5271 * FDISC is sent and awaiting reply from fabric.
5274 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s
*vport
,
5275 enum bfa_fcs_vport_event event
)
5277 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5278 bfa_trc(__vport_fcs(vport
), event
);
5281 case BFA_FCS_VPORT_SM_DELETE
:
5282 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc_rsp_wait
);
5285 case BFA_FCS_VPORT_SM_OFFLINE
:
5286 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5287 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5290 case BFA_FCS_VPORT_SM_RSP_OK
:
5291 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_online
);
5292 bfa_fcs_lport_online(&vport
->lport
);
5295 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5296 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc_retry
);
5297 bfa_timer_start(__vport_bfa(vport
), &vport
->timer
,
5298 bfa_fcs_vport_timeout
, vport
,
5299 BFA_FCS_RETRY_TIMEOUT
);
5302 case BFA_FCS_VPORT_SM_RSP_FAILED
:
5303 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5306 case BFA_FCS_VPORT_SM_RSP_DUP_WWN
:
5307 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_error
);
5311 bfa_sm_fault(__vport_fcs(vport
), event
);
5316 * FDISC attempt failed - a timer is active to retry FDISC.
5319 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s
*vport
,
5320 enum bfa_fcs_vport_event event
)
5322 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5323 bfa_trc(__vport_fcs(vport
), event
);
5326 case BFA_FCS_VPORT_SM_DELETE
:
5327 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5328 bfa_timer_stop(&vport
->timer
);
5329 bfa_fcs_lport_delete(&vport
->lport
);
5332 case BFA_FCS_VPORT_SM_OFFLINE
:
5333 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5334 bfa_timer_stop(&vport
->timer
);
5337 case BFA_FCS_VPORT_SM_TIMEOUT
:
5338 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_fdisc
);
5339 vport
->vport_stats
.fdisc_retries
++;
5340 vport
->fdisc_retries
++;
5341 bfa_fcs_vport_do_fdisc(vport
);
5345 bfa_sm_fault(__vport_fcs(vport
), event
);
5350 * FDISC is in progress and we got a vport delete request -
5351 * this is a wait state while we wait for fdisc response and
5352 * we will transition to the appropriate state - on rsp status.
5355 bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s
*vport
,
5356 enum bfa_fcs_vport_event event
)
5358 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5359 bfa_trc(__vport_fcs(vport
), event
);
5362 case BFA_FCS_VPORT_SM_RSP_OK
:
5363 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_deleting
);
5364 bfa_fcs_lport_delete(&vport
->lport
);
5367 case BFA_FCS_VPORT_SM_DELETE
:
5370 case BFA_FCS_VPORT_SM_OFFLINE
:
5371 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5372 case BFA_FCS_VPORT_SM_RSP_FAILED
:
5373 case BFA_FCS_VPORT_SM_RSP_DUP_WWN
:
5374 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5375 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5376 bfa_fcs_lport_delete(&vport
->lport
);
5380 bfa_sm_fault(__vport_fcs(vport
), event
);
5385 * Vport is online (FDISC is complete).
5388 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s
*vport
,
5389 enum bfa_fcs_vport_event event
)
5391 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5392 bfa_trc(__vport_fcs(vport
), event
);
5395 case BFA_FCS_VPORT_SM_DELETE
:
5396 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_deleting
);
5397 bfa_fcs_lport_delete(&vport
->lport
);
5400 case BFA_FCS_VPORT_SM_STOP
:
5401 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_stopping
);
5402 bfa_sm_send_event(&vport
->lport
, BFA_FCS_PORT_SM_STOP
);
5405 case BFA_FCS_VPORT_SM_OFFLINE
:
5406 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_offline
);
5407 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5408 bfa_fcs_lport_offline(&vport
->lport
);
5412 bfa_sm_fault(__vport_fcs(vport
), event
);
5417 * Vport is being stopped - awaiting lport stop completion to send
5421 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s
*vport
,
5422 enum bfa_fcs_vport_event event
)
5424 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5425 bfa_trc(__vport_fcs(vport
), event
);
5428 case BFA_FCS_VPORT_SM_STOPCOMP
:
5429 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_logo_for_stop
);
5430 bfa_fcs_vport_do_logo(vport
);
5433 case BFA_FCS_VPORT_SM_OFFLINE
:
5434 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5438 bfa_sm_fault(__vport_fcs(vport
), event
);
5443 * Vport is being deleted - awaiting lport delete completion to send
5447 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s
*vport
,
5448 enum bfa_fcs_vport_event event
)
5450 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5451 bfa_trc(__vport_fcs(vport
), event
);
5454 case BFA_FCS_VPORT_SM_DELETE
:
5457 case BFA_FCS_VPORT_SM_DELCOMP
:
5458 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_logo
);
5459 bfa_fcs_vport_do_logo(vport
);
5462 case BFA_FCS_VPORT_SM_OFFLINE
:
5463 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5467 bfa_sm_fault(__vport_fcs(vport
), event
);
5473 * This state will be set when the Vport Creation fails due
5474 * to errors like Dup WWN. In this state only operation allowed
5475 * is a Vport Delete.
5478 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s
*vport
,
5479 enum bfa_fcs_vport_event event
)
5481 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5482 bfa_trc(__vport_fcs(vport
), event
);
5485 case BFA_FCS_VPORT_SM_DELETE
:
5486 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_cleanup
);
5487 bfa_fcs_lport_delete(&vport
->lport
);
5491 bfa_trc(__vport_fcs(vport
), event
);
5496 * Lport cleanup is in progress since vport is being deleted. Fabric is
5497 * offline, so no LOGO is needed to complete vport deletion.
5500 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s
*vport
,
5501 enum bfa_fcs_vport_event event
)
5503 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5504 bfa_trc(__vport_fcs(vport
), event
);
5507 case BFA_FCS_VPORT_SM_DELCOMP
:
5508 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5509 bfa_fcs_vport_free(vport
);
5512 case BFA_FCS_VPORT_SM_STOPCOMP
:
5513 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_created
);
5516 case BFA_FCS_VPORT_SM_DELETE
:
5520 bfa_sm_fault(__vport_fcs(vport
), event
);
5525 * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
5529 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s
*vport
,
5530 enum bfa_fcs_vport_event event
)
5532 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5533 bfa_trc(__vport_fcs(vport
), event
);
5536 case BFA_FCS_VPORT_SM_OFFLINE
:
5537 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5539 * !!! fall through !!!
5542 case BFA_FCS_VPORT_SM_RSP_OK
:
5543 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5544 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_created
);
5548 bfa_sm_fault(__vport_fcs(vport
), event
);
5553 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5557 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s
*vport
,
5558 enum bfa_fcs_vport_event event
)
5560 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5561 bfa_trc(__vport_fcs(vport
), event
);
5564 case BFA_FCS_VPORT_SM_OFFLINE
:
5565 bfa_sm_send_event(vport
->lps
, BFA_LPS_SM_OFFLINE
);
5567 * !!! fall through !!!
5570 case BFA_FCS_VPORT_SM_RSP_OK
:
5571 case BFA_FCS_VPORT_SM_RSP_ERROR
:
5572 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5573 bfa_fcs_vport_free(vport
);
5576 case BFA_FCS_VPORT_SM_DELETE
:
5580 bfa_sm_fault(__vport_fcs(vport
), event
);
5587 * fcs_vport_private FCS virtual port private functions
5590 * Send AEN notification
5593 bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s
*port
,
5594 enum bfa_lport_aen_event event
)
5596 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fabric
->fcs
->bfad
;
5597 struct bfa_aen_entry_s
*aen_entry
;
5599 bfad_get_aen_entry(bfad
, aen_entry
);
5603 aen_entry
->aen_data
.lport
.vf_id
= port
->fabric
->vf_id
;
5604 aen_entry
->aen_data
.lport
.roles
= port
->port_cfg
.roles
;
5605 aen_entry
->aen_data
.lport
.ppwwn
= bfa_fcs_lport_get_pwwn(
5606 bfa_fcs_get_base_port(port
->fcs
));
5607 aen_entry
->aen_data
.lport
.lpwwn
= bfa_fcs_lport_get_pwwn(port
);
5609 /* Send the AEN notification */
5610 bfad_im_post_vendor_event(aen_entry
, bfad
, ++port
->fcs
->fcs_aen_seq
,
5611 BFA_AEN_CAT_LPORT
, event
);
5615 * This routine will be called to send a FDISC command.
5618 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s
*vport
)
5620 bfa_lps_fdisc(vport
->lps
, vport
,
5621 bfa_fcport_get_maxfrsize(__vport_bfa(vport
)),
5622 __vport_pwwn(vport
), __vport_nwwn(vport
));
5623 vport
->vport_stats
.fdisc_sent
++;
5627 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s
*vport
)
5629 u8 lsrjt_rsn
= vport
->lps
->lsrjt_rsn
;
5630 u8 lsrjt_expl
= vport
->lps
->lsrjt_expl
;
5632 bfa_trc(__vport_fcs(vport
), lsrjt_rsn
);
5633 bfa_trc(__vport_fcs(vport
), lsrjt_expl
);
5635 /* For certain reason codes, we don't want to retry. */
5636 switch (vport
->lps
->lsrjt_expl
) {
5637 case FC_LS_RJT_EXP_INV_PORT_NAME
: /* by brocade */
5638 case FC_LS_RJT_EXP_INVALID_NPORT_ID
: /* by Cisco */
5639 if (vport
->fdisc_retries
< BFA_FCS_VPORT_MAX_RETRIES
)
5640 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5642 bfa_fcs_vport_aen_post(&vport
->lport
,
5643 BFA_LPORT_AEN_NPIV_DUP_WWN
);
5644 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_DUP_WWN
);
5648 case FC_LS_RJT_EXP_INSUFF_RES
:
5650 * This means max logins per port/switch setting on the
5651 * switch was exceeded.
5653 if (vport
->fdisc_retries
< BFA_FCS_VPORT_MAX_RETRIES
)
5654 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5656 bfa_fcs_vport_aen_post(&vport
->lport
,
5657 BFA_LPORT_AEN_NPIV_FABRIC_MAX
);
5658 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_FAILED
);
5663 if (vport
->fdisc_retries
== 0)
5664 bfa_fcs_vport_aen_post(&vport
->lport
,
5665 BFA_LPORT_AEN_NPIV_UNKNOWN
);
5666 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
5671 * Called to send a logout to the fabric. Used when a V-Port is
5675 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s
*vport
)
5677 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
5679 vport
->vport_stats
.logo_sent
++;
5680 bfa_lps_fdisclogo(vport
->lps
);
5685 * This routine will be called by bfa_timer on timer timeouts.
5687 * param[in] vport - pointer to bfa_fcs_vport_t.
5688 * param[out] vport_status - pointer to return vport status in
5693 * Special Considerations:
5698 bfa_fcs_vport_timeout(void *vport_arg
)
5700 struct bfa_fcs_vport_s
*vport
= (struct bfa_fcs_vport_s
*) vport_arg
;
5702 vport
->vport_stats
.fdisc_timeouts
++;
5703 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_TIMEOUT
);
5707 bfa_fcs_vport_free(struct bfa_fcs_vport_s
*vport
)
5709 struct bfad_vport_s
*vport_drv
=
5710 (struct bfad_vport_s
*)vport
->vport_drv
;
5712 bfa_fcs_fabric_delvport(__vport_fabric(vport
), vport
);
5713 bfa_lps_delete(vport
->lps
);
5715 if (vport_drv
->comp_del
) {
5716 complete(vport_drv
->comp_del
);
5721 * We queue the vport delete work to the IM work_q from here.
5722 * The memory for the bfad_vport_s is freed from the FC function
5723 * template vport_delete entry point.
5726 bfad_im_port_delete(vport_drv
->drv_port
.bfad
,
5727 &vport_drv
->drv_port
);
5731 * fcs_vport_public FCS virtual port public interfaces
5735 * Online notification from fabric SM.
5738 bfa_fcs_vport_online(struct bfa_fcs_vport_s
*vport
)
5740 vport
->vport_stats
.fab_online
++;
5741 if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport
)))
5742 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_ONLINE
);
5744 vport
->vport_stats
.fab_no_npiv
++;
5748 * Offline notification from fabric SM.
5751 bfa_fcs_vport_offline(struct bfa_fcs_vport_s
*vport
)
5753 vport
->vport_stats
.fab_offline
++;
5754 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_OFFLINE
);
5758 * Cleanup notification from fabric SM on link timer expiry.
5761 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s
*vport
)
5763 vport
->vport_stats
.fab_cleanup
++;
5766 * delete notification from fabric SM. To be invoked from within FCS.
5769 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s
*vport
)
5771 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELETE
);
5775 * Stop completion callback from associated lport
5778 bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s
*vport
)
5780 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_STOPCOMP
);
5784 * Delete completion callback from associated lport
5787 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s
*vport
)
5789 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELCOMP
);
5795 * fcs_vport_api Virtual port API
5799 * Use this function to instantiate a new FCS vport object. This
5800 * function will not trigger any HW initialization process (which will be
5801 * done in vport_start() call)
5803 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5804 * needs to be allocated by the driver.
5805 * param[in] fcs - FCS instance
5806 * param[in] vport_cfg - vport configuration
5807 * param[in] vf_id - VF_ID if vport is created within a VF.
5808 * FC_VF_ID_NULL to specify base fabric.
5809 * param[in] vport_drv - Opaque handle back to the driver's vport
5812 * retval BFA_STATUS_OK - on success.
5813 * retval BFA_STATUS_FAILED - on failure.
5816 bfa_fcs_vport_create(struct bfa_fcs_vport_s
*vport
, struct bfa_fcs_s
*fcs
,
5817 u16 vf_id
, struct bfa_lport_cfg_s
*vport_cfg
,
5818 struct bfad_vport_s
*vport_drv
)
5820 if (vport_cfg
->pwwn
== 0)
5821 return BFA_STATUS_INVALID_WWN
;
5823 if (bfa_fcs_lport_get_pwwn(&fcs
->fabric
.bport
) == vport_cfg
->pwwn
)
5824 return BFA_STATUS_VPORT_WWN_BP
;
5826 if (bfa_fcs_vport_lookup(fcs
, vf_id
, vport_cfg
->pwwn
) != NULL
)
5827 return BFA_STATUS_VPORT_EXISTS
;
5829 if (fcs
->fabric
.num_vports
==
5830 bfa_lps_get_max_vport(fcs
->bfa
))
5831 return BFA_STATUS_VPORT_MAX
;
5833 vport
->lps
= bfa_lps_alloc(fcs
->bfa
);
5835 return BFA_STATUS_VPORT_MAX
;
5837 vport
->vport_drv
= vport_drv
;
5838 vport_cfg
->preboot_vp
= BFA_FALSE
;
5840 bfa_sm_set_state(vport
, bfa_fcs_vport_sm_uninit
);
5841 bfa_fcs_lport_attach(&vport
->lport
, fcs
, vf_id
, vport
);
5842 bfa_fcs_lport_init(&vport
->lport
, vport_cfg
);
5843 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_CREATE
);
5845 return BFA_STATUS_OK
;
5849 * Use this function to instantiate a new FCS PBC vport object. This
5850 * function will not trigger any HW initialization process (which will be
5851 * done in vport_start() call)
5853 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5854 * needs to be allocated by the driver.
5855 * param[in] fcs - FCS instance
5856 * param[in] vport_cfg - vport configuration
5857 * param[in] vf_id - VF_ID if vport is created within a VF.
5858 * FC_VF_ID_NULL to specify base fabric.
5859 * param[in] vport_drv - Opaque handle back to the driver's vport
5862 * retval BFA_STATUS_OK - on success.
5863 * retval BFA_STATUS_FAILED - on failure.
5866 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s
*vport
, struct bfa_fcs_s
*fcs
,
5867 u16 vf_id
, struct bfa_lport_cfg_s
*vport_cfg
,
5868 struct bfad_vport_s
*vport_drv
)
5872 rc
= bfa_fcs_vport_create(vport
, fcs
, vf_id
, vport_cfg
, vport_drv
);
5873 vport
->lport
.port_cfg
.preboot_vp
= BFA_TRUE
;
5879 * Use this function to findout if this is a pbc vport or not.
5881 * @param[in] vport - pointer to bfa_fcs_vport_t.
5886 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s
*vport
)
5889 if (vport
&& (vport
->lport
.port_cfg
.preboot_vp
== BFA_TRUE
))
5897 * Use this function initialize the vport.
5899 * @param[in] vport - pointer to bfa_fcs_vport_t.
5904 bfa_fcs_vport_start(struct bfa_fcs_vport_s
*vport
)
5906 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_START
);
5908 return BFA_STATUS_OK
;
5912 * Use this function quiese the vport object. This function will return
5913 * immediately, when the vport is actually stopped, the
5914 * bfa_drv_vport_stop_cb() will be called.
5916 * param[in] vport - pointer to bfa_fcs_vport_t.
5921 bfa_fcs_vport_stop(struct bfa_fcs_vport_s
*vport
)
5923 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_STOP
);
5925 return BFA_STATUS_OK
;
5929 * Use this function to delete a vport object. Fabric object should
5930 * be stopped before this function call.
5932 * !!!!!!! Donot invoke this from within FCS !!!!!!!
5934 * param[in] vport - pointer to bfa_fcs_vport_t.
5939 bfa_fcs_vport_delete(struct bfa_fcs_vport_s
*vport
)
5942 if (vport
->lport
.port_cfg
.preboot_vp
)
5943 return BFA_STATUS_PBC
;
5945 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_DELETE
);
5947 return BFA_STATUS_OK
;
5951 * Use this function to get vport's current status info.
5953 * param[in] vport pointer to bfa_fcs_vport_t.
5954 * param[out] attr pointer to return vport attributes
5959 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s
*vport
,
5960 struct bfa_vport_attr_s
*attr
)
5962 if (vport
== NULL
|| attr
== NULL
)
5965 memset(attr
, 0, sizeof(struct bfa_vport_attr_s
));
5967 bfa_fcs_lport_get_attr(&vport
->lport
, &attr
->port_attr
);
5968 attr
->vport_state
= bfa_sm_to_state(vport_sm_table
, vport
->sm
);
5973 * Lookup a virtual port. Excludes base port from lookup.
5975 struct bfa_fcs_vport_s
*
5976 bfa_fcs_vport_lookup(struct bfa_fcs_s
*fcs
, u16 vf_id
, wwn_t vpwwn
)
5978 struct bfa_fcs_vport_s
*vport
;
5979 struct bfa_fcs_fabric_s
*fabric
;
5981 bfa_trc(fcs
, vf_id
);
5982 bfa_trc(fcs
, vpwwn
);
5984 fabric
= bfa_fcs_vf_lookup(fcs
, vf_id
);
5986 bfa_trc(fcs
, vf_id
);
5990 vport
= bfa_fcs_fabric_vport_lookup(fabric
, vpwwn
);
5998 bfa_cb_lps_fdisc_comp(void *bfad
, void *uarg
, bfa_status_t status
)
6000 struct bfa_fcs_vport_s
*vport
= uarg
;
6002 bfa_trc(__vport_fcs(vport
), __vport_pwwn(vport
));
6003 bfa_trc(__vport_fcs(vport
), status
);
6008 * Initialize the V-Port fields
6010 __vport_fcid(vport
) = vport
->lps
->lp_pid
;
6011 vport
->vport_stats
.fdisc_accepts
++;
6012 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_OK
);
6015 case BFA_STATUS_INVALID_MAC
:
6017 vport
->vport_stats
.fdisc_acc_bad
++;
6018 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
6022 case BFA_STATUS_EPROTOCOL
:
6023 switch (vport
->lps
->ext_status
) {
6024 case BFA_EPROTO_BAD_ACCEPT
:
6025 vport
->vport_stats
.fdisc_acc_bad
++;
6028 case BFA_EPROTO_UNKNOWN_RSP
:
6029 vport
->vport_stats
.fdisc_unknown_rsp
++;
6036 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
6039 case BFA_STATUS_FABRIC_RJT
:
6040 vport
->vport_stats
.fdisc_rejects
++;
6041 bfa_fcs_vport_fdisc_rejected(vport
);
6045 vport
->vport_stats
.fdisc_rsp_err
++;
6046 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_ERROR
);
6054 bfa_cb_lps_fdisclogo_comp(void *bfad
, void *uarg
)
6056 struct bfa_fcs_vport_s
*vport
= uarg
;
6057 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_RSP_OK
);
6061 * Received clear virtual link
6064 bfa_cb_lps_cvl_event(void *bfad
, void *uarg
)
6066 struct bfa_fcs_vport_s
*vport
= uarg
;
6068 /* Send an Offline followed by an ONLINE */
6069 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_OFFLINE
);
6070 bfa_sm_send_event(vport
, BFA_FCS_VPORT_SM_ONLINE
);