2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
20 #include "bfa_fcbuild.h"
23 BFA_TRC_FILE(FCS, PORT);
25 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
26 struct fchs_s *rx_fchs, u8 reason_code,
28 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
29 struct fchs_s *rx_fchs, struct fc_logi_s *plogi);
30 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port);
31 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port);
32 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port);
33 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port);
34 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port);
35 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port);
36 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port,
37 struct fchs_s *rx_fchs,
38 struct fc_echo_s *echo, u16 len);
39 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port,
40 struct fchs_s *rx_fchs,
41 struct fc_rnid_cmd_s *rnid, u16 len);
42 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
43 struct fc_rnid_general_topology_data_s *gen_topo_data);
45 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port);
46 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port);
47 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port);
49 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
50 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
51 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
54 void (*init) (struct bfa_fcs_lport_s *port);
55 void (*online) (struct bfa_fcs_lport_s *port);
56 void (*offline) (struct bfa_fcs_lport_s *port);
59 bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online,
60 bfa_fcs_lport_unknown_offline}, {
61 bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
62 bfa_fcs_lport_fab_offline}, {
63 bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
64 bfa_fcs_lport_n2n_offline},
68 * fcs_port_sm FCS logical port state machine
71 enum bfa_fcs_lport_event {
72 BFA_FCS_PORT_SM_CREATE = 1,
73 BFA_FCS_PORT_SM_ONLINE = 2,
74 BFA_FCS_PORT_SM_OFFLINE = 3,
75 BFA_FCS_PORT_SM_DELETE = 4,
76 BFA_FCS_PORT_SM_DELRPORT = 5,
77 BFA_FCS_PORT_SM_STOP = 6,
80 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port,
81 enum bfa_fcs_lport_event event);
82 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
83 enum bfa_fcs_lport_event event);
84 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port,
85 enum bfa_fcs_lport_event event);
86 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port,
87 enum bfa_fcs_lport_event event);
88 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port,
89 enum bfa_fcs_lport_event event);
90 static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
91 enum bfa_fcs_lport_event event);
94 bfa_fcs_lport_sm_uninit(
95 struct bfa_fcs_lport_s *port,
96 enum bfa_fcs_lport_event event)
98 bfa_trc(port->fcs, port->port_cfg.pwwn);
99 bfa_trc(port->fcs, event);
102 case BFA_FCS_PORT_SM_CREATE:
103 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
107 bfa_sm_fault(port->fcs, event);
112 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
113 enum bfa_fcs_lport_event event)
115 bfa_trc(port->fcs, port->port_cfg.pwwn);
116 bfa_trc(port->fcs, event);
119 case BFA_FCS_PORT_SM_ONLINE:
120 bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
121 bfa_fcs_lport_online_actions(port);
124 case BFA_FCS_PORT_SM_DELETE:
125 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
126 bfa_fcs_lport_deleted(port);
129 case BFA_FCS_PORT_SM_STOP:
130 /* If vport - send completion call back */
132 bfa_fcs_vport_stop_comp(port->vport);
135 case BFA_FCS_PORT_SM_OFFLINE:
139 bfa_sm_fault(port->fcs, event);
144 bfa_fcs_lport_sm_online(
145 struct bfa_fcs_lport_s *port,
146 enum bfa_fcs_lport_event event)
148 struct bfa_fcs_rport_s *rport;
149 struct list_head *qe, *qen;
151 bfa_trc(port->fcs, port->port_cfg.pwwn);
152 bfa_trc(port->fcs, event);
155 case BFA_FCS_PORT_SM_OFFLINE:
156 bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
157 bfa_fcs_lport_offline_actions(port);
160 case BFA_FCS_PORT_SM_STOP:
161 __port_action[port->fabric->fab_type].offline(port);
163 if (port->num_rports == 0) {
164 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
165 /* If vport - send completion call back */
167 bfa_fcs_vport_stop_comp(port->vport);
169 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
170 list_for_each_safe(qe, qen, &port->rport_q) {
171 rport = (struct bfa_fcs_rport_s *) qe;
172 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
177 case BFA_FCS_PORT_SM_DELETE:
179 __port_action[port->fabric->fab_type].offline(port);
181 if (port->num_rports == 0) {
182 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
183 bfa_fcs_lport_deleted(port);
185 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
186 list_for_each_safe(qe, qen, &port->rport_q) {
187 rport = (struct bfa_fcs_rport_s *) qe;
188 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
193 case BFA_FCS_PORT_SM_DELRPORT:
197 bfa_sm_fault(port->fcs, event);
202 bfa_fcs_lport_sm_offline(
203 struct bfa_fcs_lport_s *port,
204 enum bfa_fcs_lport_event event)
206 struct bfa_fcs_rport_s *rport;
207 struct list_head *qe, *qen;
209 bfa_trc(port->fcs, port->port_cfg.pwwn);
210 bfa_trc(port->fcs, event);
213 case BFA_FCS_PORT_SM_ONLINE:
214 bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
215 bfa_fcs_lport_online_actions(port);
218 case BFA_FCS_PORT_SM_STOP:
219 if (port->num_rports == 0) {
220 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
221 /* If vport - send completion call back */
223 bfa_fcs_vport_stop_comp(port->vport);
225 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
226 list_for_each_safe(qe, qen, &port->rport_q) {
227 rport = (struct bfa_fcs_rport_s *) qe;
228 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
233 case BFA_FCS_PORT_SM_DELETE:
234 if (port->num_rports == 0) {
235 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
236 bfa_fcs_lport_deleted(port);
238 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
239 list_for_each_safe(qe, qen, &port->rport_q) {
240 rport = (struct bfa_fcs_rport_s *) qe;
241 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
246 case BFA_FCS_PORT_SM_DELRPORT:
247 case BFA_FCS_PORT_SM_OFFLINE:
251 bfa_sm_fault(port->fcs, event);
256 bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
257 enum bfa_fcs_lport_event event)
259 bfa_trc(port->fcs, port->port_cfg.pwwn);
260 bfa_trc(port->fcs, event);
263 case BFA_FCS_PORT_SM_DELRPORT:
264 if (port->num_rports == 0) {
265 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
266 /* If vport - send completion call back */
268 bfa_fcs_vport_stop_comp(port->vport);
273 bfa_sm_fault(port->fcs, event);
278 bfa_fcs_lport_sm_deleting(
279 struct bfa_fcs_lport_s *port,
280 enum bfa_fcs_lport_event event)
282 bfa_trc(port->fcs, port->port_cfg.pwwn);
283 bfa_trc(port->fcs, event);
286 case BFA_FCS_PORT_SM_DELRPORT:
287 if (port->num_rports == 0) {
288 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
289 bfa_fcs_lport_deleted(port);
294 bfa_sm_fault(port->fcs, event);
306 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
307 u8 reason_code, u8 reason_code_expl)
310 struct bfa_fcxp_s *fcxp;
311 struct bfa_rport_s *bfa_rport = NULL;
314 bfa_trc(port->fcs, rx_fchs->d_id);
315 bfa_trc(port->fcs, rx_fchs->s_id);
317 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
321 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
322 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
323 rx_fchs->ox_id, reason_code, reason_code_expl);
325 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
326 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
334 bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
335 struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
338 struct bfa_fcxp_s *fcxp;
339 struct bfa_rport_s *bfa_rport = NULL;
341 struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
342 struct ct_hdr_s *ct_hdr;
344 bfa_trc(port->fcs, rx_fchs->d_id);
345 bfa_trc(port->fcs, rx_fchs->s_id);
347 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
351 ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
352 ct_hdr->gs_type = rx_cthdr->gs_type;
353 ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
355 len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
356 bfa_fcs_lport_get_fcid(port),
357 rx_fchs->ox_id, reason_code, reason_code_expl);
359 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
360 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
365 * Process incoming plogi from a remote port.
368 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
369 struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
371 struct bfa_fcs_rport_s *rport;
373 bfa_trc(port->fcs, rx_fchs->d_id);
374 bfa_trc(port->fcs, rx_fchs->s_id);
377 * If min cfg mode is enabled, drop any incoming PLOGIs
379 if (__fcs_min_cfg(port->fcs)) {
380 bfa_trc(port->fcs, rx_fchs->s_id);
384 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
385 bfa_trc(port->fcs, rx_fchs->s_id);
389 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
390 FC_LS_RJT_RSN_PROTOCOL_ERROR,
391 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
396 * Direct Attach P2P mode : verify address assigned by the r-port.
398 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
399 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
400 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
401 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
402 /* Address assigned to us cannot be a WKA */
403 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
404 FC_LS_RJT_RSN_PROTOCOL_ERROR,
405 FC_LS_RJT_EXP_INVALID_NPORT_ID);
408 port->pid = rx_fchs->d_id;
409 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
413 * First, check if we know the device by pwwn.
415 rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
418 * Direct Attach P2P mode : handle address assigned by r-port.
420 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
421 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
422 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
423 port->pid = rx_fchs->d_id;
424 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
425 rport->pid = rx_fchs->s_id;
427 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
432 * Next, lookup rport by PID.
434 rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
437 * Inbound PLOGI from a new device.
439 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
444 * Rport is known only by PID.
448 * This is a different device with the same pid. Old device
449 * disappeared. Send implicit LOGO to old device.
451 WARN_ON(rport->pwwn == plogi->port_name);
452 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
455 * Inbound PLOGI from a new device (with old PID).
457 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
462 * PLOGI crossing each other.
464 WARN_ON(rport->pwwn != WWN_NULL);
465 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
469 * Process incoming ECHO.
470 * Since it does not require a login, it is processed here.
473 bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
474 struct fc_echo_s *echo, u16 rx_len)
477 struct bfa_fcxp_s *fcxp;
478 struct bfa_rport_s *bfa_rport = NULL;
481 bfa_trc(port->fcs, rx_fchs->s_id);
482 bfa_trc(port->fcs, rx_fchs->d_id);
484 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
488 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
489 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
493 * Copy the payload (if any) from the echo frame
495 pyld_len = rx_len - sizeof(struct fchs_s);
496 bfa_trc(port->fcs, rx_len);
497 bfa_trc(port->fcs, pyld_len);
500 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
501 sizeof(struct fc_echo_s), (echo + 1),
502 (pyld_len - sizeof(struct fc_echo_s)));
504 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
505 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
510 * Process incoming RNID.
511 * Since it does not require a login, it is processed here.
514 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
515 struct fc_rnid_cmd_s *rnid, u16 rx_len)
517 struct fc_rnid_common_id_data_s common_id_data;
518 struct fc_rnid_general_topology_data_s gen_topo_data;
520 struct bfa_fcxp_s *fcxp;
521 struct bfa_rport_s *bfa_rport = NULL;
525 bfa_trc(port->fcs, rx_fchs->s_id);
526 bfa_trc(port->fcs, rx_fchs->d_id);
527 bfa_trc(port->fcs, rx_len);
529 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
534 * Check Node Indentification Data Format
535 * We only support General Topology Discovery Format.
536 * For any other requested Data Formats, we return Common Node Id Data
537 * only, as per FC-LS.
539 bfa_trc(port->fcs, rnid->node_id_data_format);
540 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
541 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
543 * Get General topology data for this port
545 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
547 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
551 * Copy the Node Id Info
553 common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
554 common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
556 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
557 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
558 rx_fchs->ox_id, data_format, &common_id_data,
561 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
562 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
567 * Fill out General Topolpgy Discovery Data for RNID ELS.
570 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
571 struct fc_rnid_general_topology_data_s *gen_topo_data)
573 memset(gen_topo_data, 0,
574 sizeof(struct fc_rnid_general_topology_data_s));
576 gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
577 gen_topo_data->phy_port_num = 0; /* @todo */
578 gen_topo_data->num_attached_nodes = cpu_to_be32(1);
582 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
584 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
585 char lpwwn_buf[BFA_STRING_32];
587 bfa_trc(port->fcs, port->fabric->oper_type);
589 __port_action[port->fabric->fab_type].init(port);
590 __port_action[port->fabric->fab_type].online(port);
592 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
593 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
594 "Logical port online: WWN = %s Role = %s\n",
595 lpwwn_buf, "Initiator");
597 bfad->bfad_flags |= BFAD_PORT_ONLINE;
601 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
603 struct list_head *qe, *qen;
604 struct bfa_fcs_rport_s *rport;
605 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
606 char lpwwn_buf[BFA_STRING_32];
608 bfa_trc(port->fcs, port->fabric->oper_type);
610 __port_action[port->fabric->fab_type].offline(port);
612 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
613 if (bfa_sm_cmp_state(port->fabric,
614 bfa_fcs_fabric_sm_online) == BFA_TRUE)
615 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
616 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
617 lpwwn_buf, "Initiator");
619 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
620 "Logical port taken offline: WWN = %s Role = %s\n",
621 lpwwn_buf, "Initiator");
623 list_for_each_safe(qe, qen, &port->rport_q) {
624 rport = (struct bfa_fcs_rport_s *) qe;
625 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
630 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
636 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
642 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
648 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
651 struct bfa_fcxp_s *fcxp;
654 bfa_trc(port->fcs, rx_fchs->d_id);
655 bfa_trc(port->fcs, rx_fchs->s_id);
657 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
661 len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
662 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
666 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
670 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
672 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
673 char lpwwn_buf[BFA_STRING_32];
675 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
676 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
677 "Logical port deleted: WWN = %s Role = %s\n",
678 lpwwn_buf, "Initiator");
680 /* Base port will be deleted by the OS driver */
682 bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles,
683 port->fabric->vf_drv,
684 port->vport ? port->vport->vport_drv : NULL);
685 bfa_fcs_vport_delete_comp(port->vport);
687 bfa_wc_down(&port->fabric->wc);
693 * Unsolicited frame receive handling.
696 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
697 struct fchs_s *fchs, u16 len)
699 u32 pid = fchs->s_id;
700 struct bfa_fcs_rport_s *rport = NULL;
701 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
703 bfa_stats(lport, uf_recvs);
704 bfa_trc(lport->fcs, fchs->type);
706 if (!bfa_fcs_lport_is_online(lport)) {
707 bfa_stats(lport, uf_recv_drops);
712 * First, handle ELSs that donot require a login.
717 if ((fchs->type == FC_TYPE_ELS) &&
718 (els_cmd->els_code == FC_ELS_PLOGI)) {
719 bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
724 * Handle ECHO separately.
726 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
727 bfa_fcs_lport_echo(lport, fchs,
728 (struct fc_echo_s *)els_cmd, len);
733 * Handle RNID separately.
735 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
736 bfa_fcs_lport_rnid(lport, fchs,
737 (struct fc_rnid_cmd_s *) els_cmd, len);
741 if (fchs->type == FC_TYPE_BLS) {
742 if ((fchs->routing == FC_RTG_BASIC_LINK) &&
743 (fchs->cat_info == FC_CAT_ABTS))
744 bfa_fcs_lport_abts_acc(lport, fchs);
748 if (fchs->type == FC_TYPE_SERVICES) {
750 * Unhandled FC-GS frames. Send a FC-CT Reject
752 bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
753 CT_NS_EXP_NOADDITIONAL);
758 * look for a matching remote port ID
760 rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
762 bfa_trc(rport->fcs, fchs->s_id);
763 bfa_trc(rport->fcs, fchs->d_id);
764 bfa_trc(rport->fcs, fchs->type);
766 bfa_fcs_rport_uf_recv(rport, fchs, len);
771 * Only handles ELS frames for now.
773 if (fchs->type != FC_TYPE_ELS) {
774 bfa_trc(lport->fcs, fchs->s_id);
775 bfa_trc(lport->fcs, fchs->d_id);
776 /* ignore type FC_TYPE_FC_FSS */
777 if (fchs->type != FC_TYPE_FC_FSS)
778 bfa_sm_fault(lport->fcs, fchs->type);
782 bfa_trc(lport->fcs, els_cmd->els_code);
783 if (els_cmd->els_code == FC_ELS_RSCN) {
784 bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
788 if (els_cmd->els_code == FC_ELS_LOGO) {
790 * @todo Handle LOGO frames received.
795 if (els_cmd->els_code == FC_ELS_PRLI) {
797 * @todo Handle PRLI frames received.
803 * Unhandled ELS frames. Send a LS_RJT.
805 bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
806 FC_LS_RJT_EXP_NO_ADDL_INFO);
811 * PID based Lookup for a R-Port in the Port R-Port Queue
813 struct bfa_fcs_rport_s *
814 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
816 struct bfa_fcs_rport_s *rport;
817 struct list_head *qe;
819 list_for_each(qe, &port->rport_q) {
820 rport = (struct bfa_fcs_rport_s *) qe;
821 if (rport->pid == pid)
825 bfa_trc(port->fcs, pid);
830 * PWWN based Lookup for a R-Port in the Port R-Port Queue
832 struct bfa_fcs_rport_s *
833 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
835 struct bfa_fcs_rport_s *rport;
836 struct list_head *qe;
838 list_for_each(qe, &port->rport_q) {
839 rport = (struct bfa_fcs_rport_s *) qe;
840 if (wwn_is_equal(rport->pwwn, pwwn))
844 bfa_trc(port->fcs, pwwn);
849 * NWWN based Lookup for a R-Port in the Port R-Port Queue
851 struct bfa_fcs_rport_s *
852 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
854 struct bfa_fcs_rport_s *rport;
855 struct list_head *qe;
857 list_for_each(qe, &port->rport_q) {
858 rport = (struct bfa_fcs_rport_s *) qe;
859 if (wwn_is_equal(rport->nwwn, nwwn))
863 bfa_trc(port->fcs, nwwn);
868 * Called by rport module when new rports are discovered.
871 bfa_fcs_lport_add_rport(
872 struct bfa_fcs_lport_s *port,
873 struct bfa_fcs_rport_s *rport)
875 list_add_tail(&rport->qe, &port->rport_q);
880 * Called by rport module to when rports are deleted.
883 bfa_fcs_lport_del_rport(
884 struct bfa_fcs_lport_s *port,
885 struct bfa_fcs_rport_s *rport)
887 WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
888 list_del(&rport->qe);
891 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
895 * Called by fabric for base port when fabric login is complete.
896 * Called by vport for virtual ports when FDISC is complete.
899 bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
901 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
905 * Called by fabric for base port when fabric goes offline.
906 * Called by vport for virtual ports when virtual port becomes offline.
909 bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
911 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
915 * Called by fabric to delete base lport and associated resources.
917 * Called by vport to delete lport and associated resources. Should call
918 * bfa_fcs_vport_delete_comp() for vports on completion.
921 bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
923 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
927 * Return TRUE if port is online, else return FALSE
930 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
932 return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
936 * Attach time initialization of logical ports.
939 bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
940 u16 vf_id, struct bfa_fcs_vport_s *vport)
943 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
944 lport->vport = vport;
945 lport->lp_tag = (vport) ? vport->lps->bfa_tag :
946 lport->fabric->lps->bfa_tag;
948 INIT_LIST_HEAD(&lport->rport_q);
949 lport->num_rports = 0;
953 * Logical port initialization of base or virtual port.
954 * Called by fabric for base port or by vport for virtual ports.
958 bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
959 struct bfa_lport_cfg_s *port_cfg)
961 struct bfa_fcs_vport_s *vport = lport->vport;
962 struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
963 char lpwwn_buf[BFA_STRING_32];
965 lport->port_cfg = *port_cfg;
967 lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
968 lport->port_cfg.roles,
969 lport->fabric->vf_drv,
970 vport ? vport->vport_drv : NULL);
972 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
973 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
974 "New logical port created: WWN = %s Role = %s\n",
975 lpwwn_buf, "Initiator");
977 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
978 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
986 bfa_fcs_lport_get_attr(
987 struct bfa_fcs_lport_s *port,
988 struct bfa_lport_attr_s *port_attr)
990 if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
991 port_attr->pid = port->pid;
995 port_attr->port_cfg = port->port_cfg;
998 port_attr->port_type = port->fabric->oper_type;
999 port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1000 bfa_fcs_fabric_sm_loopback);
1001 port_attr->authfail =
1002 bfa_sm_cmp_state(port->fabric,
1003 bfa_fcs_fabric_sm_auth_failed);
1004 port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port);
1005 memcpy(port_attr->fabric_ip_addr,
1006 bfa_fcs_lport_get_fabric_ipaddr(port),
1007 BFA_FCS_FABRIC_IPADDR_SZ);
1009 if (port->vport != NULL) {
1010 port_attr->port_type = BFA_PORT_TYPE_VPORT;
1011 port_attr->fpma_mac =
1012 port->vport->lps->lp_mac;
1014 port_attr->fpma_mac =
1015 port->fabric->lps->lp_mac;
1018 port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1019 port_attr->state = BFA_LPORT_UNINIT;
1024 * bfa_fcs_lport_fab port fab functions
1028 * Called by port to initialize fabric services of the base port.
1031 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1033 bfa_fcs_lport_ns_init(port);
1034 bfa_fcs_lport_scn_init(port);
1035 bfa_fcs_lport_ms_init(port);
1039 * Called by port to notify transition to online state.
1042 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1044 bfa_fcs_lport_ns_online(port);
1045 bfa_fcs_lport_scn_online(port);
1049 * Called by port to notify transition to offline state.
1052 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1054 bfa_fcs_lport_ns_offline(port);
1055 bfa_fcs_lport_scn_offline(port);
1056 bfa_fcs_lport_ms_offline(port);
1060 * bfa_fcs_lport_n2n functions
1064 * Called by fcs/port to initialize N2N topology.
1067 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1072 * Called by fcs/port to notify transition to online state.
1075 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1077 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1078 struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1079 struct bfa_fcs_rport_s *rport;
1081 bfa_trc(port->fcs, pcfg->pwwn);
1084 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1085 * and assign an Address. if not, we need to wait for its PLOGI.
1087 * If our PWWN is < than that of the remote port, it will send a PLOGI
1088 * with the PIDs assigned. The rport state machine take care of this
1092 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1093 sizeof(wwn_t)) > 0) {
1094 port->pid = N2N_LOCAL_PID;
1095 bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
1097 * First, check if we know the device by pwwn.
1099 rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1100 n2n_port->rem_port_wwn);
1102 bfa_trc(port->fcs, rport->pid);
1103 bfa_trc(port->fcs, rport->pwwn);
1104 rport->pid = N2N_REMOTE_PID;
1105 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1110 * In n2n there can be only one rport. Delete the old one
1111 * whose pid should be zero, because it is offline.
1113 if (port->num_rports > 0) {
1114 rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1115 WARN_ON(rport == NULL);
1117 bfa_trc(port->fcs, rport->pwwn);
1118 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1121 bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1126 * Called by fcs/port to notify transition to offline state.
1129 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1131 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1133 bfa_trc(port->fcs, port->pid);
1135 n2n_port->rem_port_wwn = 0;
1136 n2n_port->reply_oxid = 0;
1139 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1142 * forward declarations
1144 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1145 struct bfa_fcxp_s *fcxp_alloced);
1146 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1147 struct bfa_fcxp_s *fcxp_alloced);
1148 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1149 struct bfa_fcxp_s *fcxp_alloced);
1150 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1151 struct bfa_fcxp_s *fcxp,
1153 bfa_status_t req_status,
1156 struct fchs_s *rsp_fchs);
1157 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1158 struct bfa_fcxp_s *fcxp,
1160 bfa_status_t req_status,
1163 struct fchs_s *rsp_fchs);
1164 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1165 struct bfa_fcxp_s *fcxp,
1167 bfa_status_t req_status,
1170 struct fchs_s *rsp_fchs);
1171 static void bfa_fcs_lport_fdmi_timeout(void *arg);
1172 static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1174 static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1176 static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1178 static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1180 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1181 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1182 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1183 struct bfa_fcs_fdmi_port_attr_s *port_attr);
1184 u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed);
1187 * fcs_fdmi_sm FCS FDMI state machine
1191 * FDMI State Machine events
1193 enum port_fdmi_event {
1194 FDMISM_EVENT_PORT_ONLINE = 1,
1195 FDMISM_EVENT_PORT_OFFLINE = 2,
1196 FDMISM_EVENT_RSP_OK = 4,
1197 FDMISM_EVENT_RSP_ERROR = 5,
1198 FDMISM_EVENT_TIMEOUT = 6,
1199 FDMISM_EVENT_RHBA_SENT = 7,
1200 FDMISM_EVENT_RPRT_SENT = 8,
1201 FDMISM_EVENT_RPA_SENT = 9,
1204 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1205 enum port_fdmi_event event);
1206 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1207 struct bfa_fcs_lport_fdmi_s *fdmi,
1208 enum port_fdmi_event event);
1209 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1210 enum port_fdmi_event event);
1211 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1212 struct bfa_fcs_lport_fdmi_s *fdmi,
1213 enum port_fdmi_event event);
1214 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1215 struct bfa_fcs_lport_fdmi_s *fdmi,
1216 enum port_fdmi_event event);
1217 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1218 enum port_fdmi_event event);
1219 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1220 struct bfa_fcs_lport_fdmi_s *fdmi,
1221 enum port_fdmi_event event);
1222 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1223 struct bfa_fcs_lport_fdmi_s *fdmi,
1224 enum port_fdmi_event event);
1225 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1226 enum port_fdmi_event event);
1227 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1228 struct bfa_fcs_lport_fdmi_s *fdmi,
1229 enum port_fdmi_event event);
1230 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1231 enum port_fdmi_event event);
1232 static void bfa_fcs_lport_fdmi_sm_disabled(
1233 struct bfa_fcs_lport_fdmi_s *fdmi,
1234 enum port_fdmi_event event);
1236 * Start in offline state - awaiting MS to send start.
1239 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1240 enum port_fdmi_event event)
1242 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1244 bfa_trc(port->fcs, port->port_cfg.pwwn);
1245 bfa_trc(port->fcs, event);
1247 fdmi->retry_cnt = 0;
1250 case FDMISM_EVENT_PORT_ONLINE:
1253 * For Vports, register a new port.
1255 bfa_sm_set_state(fdmi,
1256 bfa_fcs_lport_fdmi_sm_sending_rprt);
1257 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1260 * For a base port, we should first register the HBA
1261 * attribute. The HBA attribute also contains the base
1262 * port registration.
1264 bfa_sm_set_state(fdmi,
1265 bfa_fcs_lport_fdmi_sm_sending_rhba);
1266 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1270 case FDMISM_EVENT_PORT_OFFLINE:
1274 bfa_sm_fault(port->fcs, event);
1279 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1280 enum port_fdmi_event event)
1282 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1284 bfa_trc(port->fcs, port->port_cfg.pwwn);
1285 bfa_trc(port->fcs, event);
1288 case FDMISM_EVENT_RHBA_SENT:
1289 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1292 case FDMISM_EVENT_PORT_OFFLINE:
1293 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1294 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1299 bfa_sm_fault(port->fcs, event);
1304 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1305 enum port_fdmi_event event)
1307 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1309 bfa_trc(port->fcs, port->port_cfg.pwwn);
1310 bfa_trc(port->fcs, event);
1313 case FDMISM_EVENT_RSP_ERROR:
1315 * if max retries have not been reached, start timer for a
1318 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1319 bfa_sm_set_state(fdmi,
1320 bfa_fcs_lport_fdmi_sm_rhba_retry);
1321 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1323 bfa_fcs_lport_fdmi_timeout, fdmi,
1324 BFA_FCS_RETRY_TIMEOUT);
1327 * set state to offline
1329 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1333 case FDMISM_EVENT_RSP_OK:
1335 * Initiate Register Port Attributes
1337 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1338 fdmi->retry_cnt = 0;
1339 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1342 case FDMISM_EVENT_PORT_OFFLINE:
1343 bfa_fcxp_discard(fdmi->fcxp);
1344 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1348 bfa_sm_fault(port->fcs, event);
1353 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1354 enum port_fdmi_event event)
1356 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1358 bfa_trc(port->fcs, port->port_cfg.pwwn);
1359 bfa_trc(port->fcs, event);
1362 case FDMISM_EVENT_TIMEOUT:
1364 * Retry Timer Expired. Re-send
1366 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1367 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1370 case FDMISM_EVENT_PORT_OFFLINE:
1371 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1372 bfa_timer_stop(&fdmi->timer);
1376 bfa_sm_fault(port->fcs, event);
1381 * RPRT : Register Port
1384 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1385 enum port_fdmi_event event)
1387 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1389 bfa_trc(port->fcs, port->port_cfg.pwwn);
1390 bfa_trc(port->fcs, event);
1393 case FDMISM_EVENT_RPRT_SENT:
1394 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1397 case FDMISM_EVENT_PORT_OFFLINE:
1398 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1399 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1404 bfa_sm_fault(port->fcs, event);
1409 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1410 enum port_fdmi_event event)
1412 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1414 bfa_trc(port->fcs, port->port_cfg.pwwn);
1415 bfa_trc(port->fcs, event);
1418 case FDMISM_EVENT_RSP_ERROR:
1420 * if max retries have not been reached, start timer for a
1423 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1424 bfa_sm_set_state(fdmi,
1425 bfa_fcs_lport_fdmi_sm_rprt_retry);
1426 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1428 bfa_fcs_lport_fdmi_timeout, fdmi,
1429 BFA_FCS_RETRY_TIMEOUT);
1433 * set state to offline
1435 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1436 fdmi->retry_cnt = 0;
1440 case FDMISM_EVENT_RSP_OK:
1441 fdmi->retry_cnt = 0;
1442 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1445 case FDMISM_EVENT_PORT_OFFLINE:
1446 bfa_fcxp_discard(fdmi->fcxp);
1447 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1451 bfa_sm_fault(port->fcs, event);
1456 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1457 enum port_fdmi_event event)
1459 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1461 bfa_trc(port->fcs, port->port_cfg.pwwn);
1462 bfa_trc(port->fcs, event);
1465 case FDMISM_EVENT_TIMEOUT:
1467 * Retry Timer Expired. Re-send
1469 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1470 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1473 case FDMISM_EVENT_PORT_OFFLINE:
1474 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1475 bfa_timer_stop(&fdmi->timer);
1479 bfa_sm_fault(port->fcs, event);
1484 * Register Port Attributes
1487 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1488 enum port_fdmi_event event)
1490 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1492 bfa_trc(port->fcs, port->port_cfg.pwwn);
1493 bfa_trc(port->fcs, event);
1496 case FDMISM_EVENT_RPA_SENT:
1497 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1500 case FDMISM_EVENT_PORT_OFFLINE:
1501 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1502 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1507 bfa_sm_fault(port->fcs, event);
1512 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1513 enum port_fdmi_event event)
1515 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1517 bfa_trc(port->fcs, port->port_cfg.pwwn);
1518 bfa_trc(port->fcs, event);
1521 case FDMISM_EVENT_RSP_ERROR:
1523 * if max retries have not been reached, start timer for a
1526 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1527 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1528 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1530 bfa_fcs_lport_fdmi_timeout, fdmi,
1531 BFA_FCS_RETRY_TIMEOUT);
1534 * set state to offline
1536 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1537 fdmi->retry_cnt = 0;
1541 case FDMISM_EVENT_RSP_OK:
1542 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1543 fdmi->retry_cnt = 0;
1546 case FDMISM_EVENT_PORT_OFFLINE:
1547 bfa_fcxp_discard(fdmi->fcxp);
1548 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1552 bfa_sm_fault(port->fcs, event);
1557 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1558 enum port_fdmi_event event)
1560 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1562 bfa_trc(port->fcs, port->port_cfg.pwwn);
1563 bfa_trc(port->fcs, event);
1566 case FDMISM_EVENT_TIMEOUT:
1568 * Retry Timer Expired. Re-send
1570 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1571 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1574 case FDMISM_EVENT_PORT_OFFLINE:
1575 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1576 bfa_timer_stop(&fdmi->timer);
1580 bfa_sm_fault(port->fcs, event);
1585 bfa_fcs_lport_fdmi_sm_online(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_PORT_OFFLINE:
1595 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1599 bfa_sm_fault(port->fcs, event);
1603 * FDMI is disabled state.
1606 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1607 enum port_fdmi_event event)
1609 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1611 bfa_trc(port->fcs, port->port_cfg.pwwn);
1612 bfa_trc(port->fcs, event);
1614 /* No op State. It can only be enabled at Driver Init. */
1618 * RHBA : Register HBA Attributes.
1621 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1623 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1624 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1627 struct bfa_fcxp_s *fcxp;
1630 bfa_trc(port->fcs, port->port_cfg.pwwn);
1632 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1634 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1635 bfa_fcs_lport_fdmi_send_rhba, fdmi);
1640 pyld = bfa_fcxp_get_reqbuf(fcxp);
1641 memset(pyld, 0, FC_MAX_PDUSZ);
1643 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1647 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1648 (u8 *) ((struct ct_hdr_s *) pyld
1651 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1652 FC_CLASS_3, (len + attr_len), &fchs,
1653 bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1654 FC_MAX_PDUSZ, FC_FCCT_TOV);
1656 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1660 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1662 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1663 struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1664 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1665 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1666 struct fdmi_attr_s *attr;
1672 * get hba attributes
1674 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1676 rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1677 rhba->port_list.num_ports = cpu_to_be32(1);
1678 rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1680 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1683 len += sizeof(rhba->hba_attr_blk.attr_count);
1686 * fill out the invididual entries of the HBA attrib Block
1688 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1693 attr = (struct fdmi_attr_s *) curr_ptr;
1694 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
1695 templen = sizeof(wwn_t);
1696 memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
1697 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1700 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1706 attr = (struct fdmi_attr_s *) curr_ptr;
1707 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
1708 templen = (u16) strlen(fcs_hba_attr->manufacturer);
1709 memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
1710 templen = fc_roundup(templen, sizeof(u32));
1711 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1714 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1720 attr = (struct fdmi_attr_s *) curr_ptr;
1721 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
1722 templen = (u16) strlen(fcs_hba_attr->serial_num);
1723 memcpy(attr->value, fcs_hba_attr->serial_num, templen);
1724 templen = fc_roundup(templen, sizeof(u32));
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_MODEL);
1736 templen = (u16) strlen(fcs_hba_attr->model);
1737 memcpy(attr->value, fcs_hba_attr->model, 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_MODEL_DESC);
1750 templen = (u16) strlen(fcs_hba_attr->model_desc);
1751 memcpy(attr->value, fcs_hba_attr->model_desc, 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 if (fcs_hba_attr->hw_version[0] != '\0') {
1763 attr = (struct fdmi_attr_s *) curr_ptr;
1764 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
1765 templen = (u16) strlen(fcs_hba_attr->hw_version);
1766 memcpy(attr->value, fcs_hba_attr->hw_version, templen);
1767 templen = fc_roundup(templen, sizeof(u32));
1768 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1771 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1778 attr = (struct fdmi_attr_s *) curr_ptr;
1779 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
1780 templen = (u16) strlen(fcs_hba_attr->driver_version);
1781 memcpy(attr->value, fcs_hba_attr->driver_version, templen);
1782 templen = fc_roundup(templen, sizeof(u32));
1783 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1786 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1790 * Option Rom Version
1792 if (fcs_hba_attr->option_rom_ver[0] != '\0') {
1793 attr = (struct fdmi_attr_s *) curr_ptr;
1794 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
1795 templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
1796 memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
1797 templen = fc_roundup(templen, sizeof(u32));
1798 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1801 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1806 * f/w Version = driver version
1808 attr = (struct fdmi_attr_s *) curr_ptr;
1809 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
1810 templen = (u16) strlen(fcs_hba_attr->driver_version);
1811 memcpy(attr->value, fcs_hba_attr->driver_version, templen);
1812 templen = fc_roundup(templen, sizeof(u32));
1813 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1816 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1822 if (fcs_hba_attr->os_name[0] != '\0') {
1823 attr = (struct fdmi_attr_s *) curr_ptr;
1824 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
1825 templen = (u16) strlen(fcs_hba_attr->os_name);
1826 memcpy(attr->value, fcs_hba_attr->os_name, templen);
1827 templen = fc_roundup(templen, sizeof(u32));
1828 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1831 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1838 attr = (struct fdmi_attr_s *) curr_ptr;
1839 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
1840 templen = sizeof(fcs_hba_attr->max_ct_pyld);
1841 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
1844 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1848 * Update size of payload
1850 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
1852 rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
1857 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1858 void *cbarg, bfa_status_t req_status,
1859 u32 rsp_len, u32 resid_len,
1860 struct fchs_s *rsp_fchs)
1862 struct bfa_fcs_lport_fdmi_s *fdmi =
1863 (struct bfa_fcs_lport_fdmi_s *) cbarg;
1864 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1865 struct ct_hdr_s *cthdr = NULL;
1867 bfa_trc(port->fcs, port->port_cfg.pwwn);
1872 if (req_status != BFA_STATUS_OK) {
1873 bfa_trc(port->fcs, req_status);
1874 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1878 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1879 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1881 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1882 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1886 bfa_trc(port->fcs, cthdr->reason_code);
1887 bfa_trc(port->fcs, cthdr->exp_code);
1888 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1892 * RPRT : Register Port
1895 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1897 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1898 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1901 struct bfa_fcxp_s *fcxp;
1904 bfa_trc(port->fcs, port->port_cfg.pwwn);
1906 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1908 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1909 bfa_fcs_lport_fdmi_send_rprt, fdmi);
1914 pyld = bfa_fcxp_get_reqbuf(fcxp);
1915 memset(pyld, 0, FC_MAX_PDUSZ);
1917 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1921 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
1922 (u8 *) ((struct ct_hdr_s *) pyld
1925 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1926 FC_CLASS_3, len + attr_len, &fchs,
1927 bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
1928 FC_MAX_PDUSZ, FC_FCCT_TOV);
1930 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
1934 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
1937 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
1940 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
1941 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
1942 struct fdmi_attr_s *attr;
1949 * get port attributes
1951 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
1953 len = sizeof(port_attrib->attr_count);
1956 * fill out the invididual entries
1958 curr_ptr = (u8 *) &port_attrib->port_attr;
1963 attr = (struct fdmi_attr_s *) curr_ptr;
1964 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
1965 templen = sizeof(fcs_port_attr.supp_fc4_types);
1966 memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
1967 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1971 cpu_to_be16(templen + sizeof(attr->type) +
1977 attr = (struct fdmi_attr_s *) curr_ptr;
1978 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
1979 templen = sizeof(fcs_port_attr.supp_speed);
1980 memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
1981 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1985 cpu_to_be16(templen + sizeof(attr->type) +
1989 * current Port Speed
1991 attr = (struct fdmi_attr_s *) curr_ptr;
1992 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
1993 templen = sizeof(fcs_port_attr.curr_speed);
1994 memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
1995 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1998 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2004 attr = (struct fdmi_attr_s *) curr_ptr;
2005 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
2006 templen = sizeof(fcs_port_attr.max_frm_size);
2007 memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
2008 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2011 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2017 if (fcs_port_attr.os_device_name[0] != '\0') {
2018 attr = (struct fdmi_attr_s *) curr_ptr;
2019 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
2020 templen = (u16) strlen(fcs_port_attr.os_device_name);
2021 memcpy(attr->value, fcs_port_attr.os_device_name, templen);
2022 templen = fc_roundup(templen, sizeof(u32));
2023 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2026 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2032 if (fcs_port_attr.host_name[0] != '\0') {
2033 attr = (struct fdmi_attr_s *) curr_ptr;
2034 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
2035 templen = (u16) strlen(fcs_port_attr.host_name);
2036 memcpy(attr->value, fcs_port_attr.host_name, templen);
2037 templen = fc_roundup(templen, sizeof(u32));
2038 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2041 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2046 * Update size of payload
2048 port_attrib->attr_count = cpu_to_be32(count);
2049 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2054 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2056 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2057 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2060 rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2061 rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2063 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2064 (u8 *) &rprt->port_attr_blk);
2066 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2072 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2073 void *cbarg, bfa_status_t req_status,
2074 u32 rsp_len, u32 resid_len,
2075 struct fchs_s *rsp_fchs)
2077 struct bfa_fcs_lport_fdmi_s *fdmi =
2078 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2079 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2080 struct ct_hdr_s *cthdr = NULL;
2082 bfa_trc(port->fcs, port->port_cfg.pwwn);
2087 if (req_status != BFA_STATUS_OK) {
2088 bfa_trc(port->fcs, req_status);
2089 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2093 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2094 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2096 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2097 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2101 bfa_trc(port->fcs, cthdr->reason_code);
2102 bfa_trc(port->fcs, cthdr->exp_code);
2103 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2107 * RPA : Register Port Attributes.
2110 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2112 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2113 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2116 struct bfa_fcxp_s *fcxp;
2119 bfa_trc(port->fcs, port->port_cfg.pwwn);
2121 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2123 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2124 bfa_fcs_lport_fdmi_send_rpa, fdmi);
2129 pyld = bfa_fcxp_get_reqbuf(fcxp);
2130 memset(pyld, 0, FC_MAX_PDUSZ);
2132 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2135 attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
2136 (u8 *) ((struct ct_hdr_s *) pyld + 1));
2138 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2139 FC_CLASS_3, len + attr_len, &fchs,
2140 bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2141 FC_MAX_PDUSZ, FC_FCCT_TOV);
2143 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2147 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2149 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2150 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2153 rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2155 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2156 (u8 *) &rpa->port_attr_blk);
2158 len += sizeof(rpa->port_name);
2164 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2165 void *cbarg, bfa_status_t req_status, u32 rsp_len,
2166 u32 resid_len, struct fchs_s *rsp_fchs)
2168 struct bfa_fcs_lport_fdmi_s *fdmi =
2169 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2170 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2171 struct ct_hdr_s *cthdr = NULL;
2173 bfa_trc(port->fcs, port->port_cfg.pwwn);
2178 if (req_status != BFA_STATUS_OK) {
2179 bfa_trc(port->fcs, req_status);
2180 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2184 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2185 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2187 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2188 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2192 bfa_trc(port->fcs, cthdr->reason_code);
2193 bfa_trc(port->fcs, cthdr->exp_code);
2194 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2198 bfa_fcs_lport_fdmi_timeout(void *arg)
2200 struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2202 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2206 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2207 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2209 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2210 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2212 memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2214 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2215 hba_attr->manufacturer);
2216 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2217 hba_attr->serial_num);
2218 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2220 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2221 hba_attr->model_desc);
2222 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2223 hba_attr->hw_version);
2224 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2225 hba_attr->option_rom_ver);
2226 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2227 hba_attr->fw_version);
2229 strncpy(hba_attr->driver_version, (char *)driver_info->version,
2230 sizeof(hba_attr->driver_version));
2232 strncpy(hba_attr->os_name, driver_info->host_os_name,
2233 sizeof(hba_attr->os_name));
2236 * If there is a patch level, append it
2237 * to the os name along with a separator
2239 if (driver_info->host_os_patch[0] != '\0') {
2240 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2241 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
2242 strncat(hba_attr->os_name, driver_info->host_os_patch,
2243 sizeof(driver_info->host_os_patch));
2246 hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
2250 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2251 struct bfa_fcs_fdmi_port_attr_s *port_attr)
2253 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2254 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2255 struct bfa_port_attr_s pport_attr;
2257 memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2260 * get pport attributes from hal
2262 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2265 * get FC4 type Bitmask
2267 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2272 switch (pport_attr.speed_supported) {
2273 case BFA_PORT_SPEED_16GBPS:
2274 port_attr->supp_speed =
2275 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G);
2278 case BFA_PORT_SPEED_10GBPS:
2279 port_attr->supp_speed =
2280 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G);
2283 case BFA_PORT_SPEED_8GBPS:
2284 port_attr->supp_speed =
2285 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G);
2288 case BFA_PORT_SPEED_4GBPS:
2289 port_attr->supp_speed =
2290 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G);
2294 bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2300 port_attr->curr_speed = cpu_to_be32(
2301 bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2306 port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
2311 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2312 sizeof(port_attr->os_device_name));
2317 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2318 sizeof(port_attr->host_name));
2323 * Convert BFA speed to FDMI format.
2326 bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed)
2330 switch (pport_speed) {
2331 case BFA_PORT_SPEED_1GBPS:
2332 case BFA_PORT_SPEED_2GBPS:
2336 case BFA_PORT_SPEED_4GBPS:
2337 ret = FDMI_TRANS_SPEED_4G;
2340 case BFA_PORT_SPEED_8GBPS:
2341 ret = FDMI_TRANS_SPEED_8G;
2344 case BFA_PORT_SPEED_10GBPS:
2345 ret = FDMI_TRANS_SPEED_10G;
2348 case BFA_PORT_SPEED_16GBPS:
2349 ret = FDMI_TRANS_SPEED_16G;
2353 ret = FDMI_TRANS_SPEED_UNKNOWN;
2359 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2361 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2364 if (ms->port->fcs->fdmi_enabled)
2365 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2367 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2371 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2373 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2376 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2380 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2382 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2385 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2388 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2391 * forward declarations
2393 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2394 struct bfa_fcxp_s *fcxp_alloced);
2395 static void bfa_fcs_lport_ms_timeout(void *arg);
2396 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2397 struct bfa_fcxp_s *fcxp,
2399 bfa_status_t req_status,
2402 struct fchs_s *rsp_fchs);
2404 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2405 struct bfa_fcxp_s *fcxp_alloced);
2406 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2407 struct bfa_fcxp_s *fcxp,
2409 bfa_status_t req_status,
2412 struct fchs_s *rsp_fchs);
2413 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2414 struct bfa_fcxp_s *fcxp_alloced);
2415 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2416 struct bfa_fcxp_s *fcxp,
2418 bfa_status_t req_status,
2421 struct fchs_s *rsp_fchs);
2423 * fcs_ms_sm FCS MS state machine
2427 * MS State Machine events
2429 enum port_ms_event {
2430 MSSM_EVENT_PORT_ONLINE = 1,
2431 MSSM_EVENT_PORT_OFFLINE = 2,
2432 MSSM_EVENT_RSP_OK = 3,
2433 MSSM_EVENT_RSP_ERROR = 4,
2434 MSSM_EVENT_TIMEOUT = 5,
2435 MSSM_EVENT_FCXP_SENT = 6,
2436 MSSM_EVENT_PORT_FABRIC_RSCN = 7
2439 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2440 enum port_ms_event event);
2441 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2442 enum port_ms_event event);
2443 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2444 enum port_ms_event event);
2445 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2446 enum port_ms_event event);
2447 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2448 enum port_ms_event event);
2449 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2450 enum port_ms_event event);
2451 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2452 enum port_ms_event event);
2453 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2454 enum port_ms_event event);
2455 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2456 enum port_ms_event event);
2457 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2458 enum port_ms_event event);
2459 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2460 enum port_ms_event event);
2462 * Start in offline state - awaiting NS to send start.
2465 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2466 enum port_ms_event event)
2468 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2469 bfa_trc(ms->port->fcs, event);
2472 case MSSM_EVENT_PORT_ONLINE:
2473 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2474 bfa_fcs_lport_ms_send_plogi(ms, NULL);
2477 case MSSM_EVENT_PORT_OFFLINE:
2481 bfa_sm_fault(ms->port->fcs, event);
2486 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2487 enum port_ms_event event)
2489 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2490 bfa_trc(ms->port->fcs, event);
2493 case MSSM_EVENT_FCXP_SENT:
2494 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2497 case MSSM_EVENT_PORT_OFFLINE:
2498 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2499 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2504 bfa_sm_fault(ms->port->fcs, event);
2509 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2510 enum port_ms_event event)
2512 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2513 bfa_trc(ms->port->fcs, event);
2516 case MSSM_EVENT_RSP_ERROR:
2518 * Start timer for a delayed retry
2520 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2521 ms->port->stats.ms_retries++;
2522 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2523 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2524 BFA_FCS_RETRY_TIMEOUT);
2527 case MSSM_EVENT_RSP_OK:
2529 * since plogi is done, now invoke MS related sub-modules
2531 bfa_fcs_lport_fdmi_online(ms);
2534 * if this is a Vport, go to online state.
2536 if (ms->port->vport) {
2537 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2542 * For a base port we need to get the
2543 * switch's IP address.
2545 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2546 bfa_fcs_lport_ms_send_gmal(ms, NULL);
2549 case MSSM_EVENT_PORT_OFFLINE:
2550 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2551 bfa_fcxp_discard(ms->fcxp);
2555 bfa_sm_fault(ms->port->fcs, event);
2560 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2561 enum port_ms_event event)
2563 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2564 bfa_trc(ms->port->fcs, event);
2567 case MSSM_EVENT_TIMEOUT:
2569 * Retry Timer Expired. Re-send
2571 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2572 bfa_fcs_lport_ms_send_plogi(ms, NULL);
2575 case MSSM_EVENT_PORT_OFFLINE:
2576 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2577 bfa_timer_stop(&ms->timer);
2581 bfa_sm_fault(ms->port->fcs, event);
2586 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2587 enum port_ms_event event)
2589 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2590 bfa_trc(ms->port->fcs, event);
2593 case MSSM_EVENT_PORT_OFFLINE:
2594 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2597 case MSSM_EVENT_PORT_FABRIC_RSCN:
2598 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2600 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2604 bfa_sm_fault(ms->port->fcs, event);
2609 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2610 enum port_ms_event event)
2612 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2613 bfa_trc(ms->port->fcs, event);
2616 case MSSM_EVENT_FCXP_SENT:
2617 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
2620 case MSSM_EVENT_PORT_OFFLINE:
2621 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2622 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2627 bfa_sm_fault(ms->port->fcs, event);
2632 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2633 enum port_ms_event event)
2635 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2636 bfa_trc(ms->port->fcs, event);
2639 case MSSM_EVENT_RSP_ERROR:
2641 * Start timer for a delayed retry
2643 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2644 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
2645 ms->port->stats.ms_retries++;
2646 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2647 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2648 BFA_FCS_RETRY_TIMEOUT);
2650 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2651 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2656 case MSSM_EVENT_RSP_OK:
2657 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2658 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2661 case MSSM_EVENT_PORT_OFFLINE:
2662 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2663 bfa_fcxp_discard(ms->fcxp);
2667 bfa_sm_fault(ms->port->fcs, event);
2672 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2673 enum port_ms_event event)
2675 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2676 bfa_trc(ms->port->fcs, event);
2679 case MSSM_EVENT_TIMEOUT:
2681 * Retry Timer Expired. Re-send
2683 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2684 bfa_fcs_lport_ms_send_gmal(ms, NULL);
2687 case MSSM_EVENT_PORT_OFFLINE:
2688 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2689 bfa_timer_stop(&ms->timer);
2693 bfa_sm_fault(ms->port->fcs, event);
2697 * ms_pvt MS local functions
2701 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2703 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2704 bfa_fcs_lport_t *port = ms->port;
2707 struct bfa_fcxp_s *fcxp;
2709 bfa_trc(port->fcs, port->pid);
2711 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2713 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2714 bfa_fcs_lport_ms_send_gmal, ms);
2719 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2720 bfa_fcs_lport_get_fcid(port),
2721 port->fabric->lps->pr_nwwn);
2723 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2724 FC_CLASS_3, len, &fchs,
2725 bfa_fcs_lport_ms_gmal_response, (void *)ms,
2726 FC_MAX_PDUSZ, FC_FCCT_TOV);
2728 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2732 bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2733 void *cbarg, bfa_status_t req_status,
2734 u32 rsp_len, u32 resid_len,
2735 struct fchs_s *rsp_fchs)
2737 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2738 bfa_fcs_lport_t *port = ms->port;
2739 struct ct_hdr_s *cthdr = NULL;
2740 struct fcgs_gmal_resp_s *gmal_resp;
2741 struct fcgs_gmal_entry_s *gmal_entry;
2745 bfa_trc(port->fcs, req_status);
2746 bfa_trc(port->fcs, port->port_cfg.pwwn);
2751 if (req_status != BFA_STATUS_OK) {
2752 bfa_trc(port->fcs, req_status);
2753 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2757 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2758 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2760 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2761 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
2763 num_entries = be32_to_cpu(gmal_resp->ms_len);
2764 if (num_entries == 0) {
2765 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2769 * The response could contain multiple Entries.
2770 * Entries for SNMP interface, etc.
2771 * We look for the entry with a telnet prefix.
2772 * First "http://" entry refers to IP addr
2775 gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
2776 while (num_entries > 0) {
2777 if (strncmp(gmal_entry->prefix,
2778 CT_GMAL_RESP_PREFIX_HTTP,
2779 sizeof(gmal_entry->prefix)) == 0) {
2782 * if the IP address is terminating with a '/',
2784 * Byte 0 consists of the length of the string.
2786 rsp_str = &(gmal_entry->prefix[0]);
2787 if (rsp_str[gmal_entry->len-1] == '/')
2788 rsp_str[gmal_entry->len-1] = 0;
2790 /* copy IP Address to fabric */
2791 strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
2792 gmal_entry->ip_addr,
2793 BFA_FCS_FABRIC_IPADDR_SZ);
2801 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2805 bfa_trc(port->fcs, cthdr->reason_code);
2806 bfa_trc(port->fcs, cthdr->exp_code);
2807 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2811 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2812 enum port_ms_event event)
2814 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2815 bfa_trc(ms->port->fcs, event);
2818 case MSSM_EVENT_FCXP_SENT:
2819 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
2822 case MSSM_EVENT_PORT_OFFLINE:
2823 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2824 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2829 bfa_sm_fault(ms->port->fcs, event);
2834 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2835 enum port_ms_event event)
2837 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2838 bfa_trc(ms->port->fcs, event);
2841 case MSSM_EVENT_RSP_ERROR:
2843 * Start timer for a delayed retry
2845 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2846 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
2847 ms->port->stats.ms_retries++;
2848 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2849 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2850 BFA_FCS_RETRY_TIMEOUT);
2852 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2857 case MSSM_EVENT_RSP_OK:
2858 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2861 case MSSM_EVENT_PORT_OFFLINE:
2862 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2863 bfa_fcxp_discard(ms->fcxp);
2867 bfa_sm_fault(ms->port->fcs, event);
2872 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2873 enum port_ms_event event)
2875 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2876 bfa_trc(ms->port->fcs, event);
2879 case MSSM_EVENT_TIMEOUT:
2881 * Retry Timer Expired. Re-send
2883 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2884 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2887 case MSSM_EVENT_PORT_OFFLINE:
2888 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2889 bfa_timer_stop(&ms->timer);
2893 bfa_sm_fault(ms->port->fcs, event);
2897 * ms_pvt MS local functions
2901 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2903 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2904 bfa_fcs_lport_t *port = ms->port;
2907 struct bfa_fcxp_s *fcxp;
2909 bfa_trc(port->fcs, port->pid);
2911 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2913 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2914 bfa_fcs_lport_ms_send_gfn, ms);
2919 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2920 bfa_fcs_lport_get_fcid(port),
2921 port->fabric->lps->pr_nwwn);
2923 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2924 FC_CLASS_3, len, &fchs,
2925 bfa_fcs_lport_ms_gfn_response, (void *)ms,
2926 FC_MAX_PDUSZ, FC_FCCT_TOV);
2928 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2932 bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2933 void *cbarg, bfa_status_t req_status, u32 rsp_len,
2934 u32 resid_len, struct fchs_s *rsp_fchs)
2936 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2937 bfa_fcs_lport_t *port = ms->port;
2938 struct ct_hdr_s *cthdr = NULL;
2941 bfa_trc(port->fcs, req_status);
2942 bfa_trc(port->fcs, port->port_cfg.pwwn);
2947 if (req_status != BFA_STATUS_OK) {
2948 bfa_trc(port->fcs, req_status);
2949 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2953 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2954 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2956 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2957 gfn_resp = (wwn_t *)(cthdr + 1);
2958 /* check if it has actually changed */
2959 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
2960 gfn_resp, sizeof(wwn_t)) != 0)) {
2961 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
2963 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2967 bfa_trc(port->fcs, cthdr->reason_code);
2968 bfa_trc(port->fcs, cthdr->exp_code);
2969 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2973 * ms_pvt MS local functions
2977 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2979 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2980 struct bfa_fcs_lport_s *port = ms->port;
2983 struct bfa_fcxp_s *fcxp;
2985 bfa_trc(port->fcs, port->pid);
2987 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2989 port->stats.ms_plogi_alloc_wait++;
2990 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2991 bfa_fcs_lport_ms_send_plogi, ms);
2996 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2997 bfa_hton3b(FC_MGMT_SERVER),
2998 bfa_fcs_lport_get_fcid(port), 0,
2999 port->port_cfg.pwwn, port->port_cfg.nwwn,
3000 bfa_fcport_get_maxfrsize(port->fcs->bfa),
3001 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3003 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3004 FC_CLASS_3, len, &fchs,
3005 bfa_fcs_lport_ms_plogi_response, (void *)ms,
3006 FC_MAX_PDUSZ, FC_ELS_TOV);
3008 port->stats.ms_plogi_sent++;
3009 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3013 bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3014 void *cbarg, bfa_status_t req_status,
3015 u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3017 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3018 struct bfa_fcs_lport_s *port = ms->port;
3019 struct fc_els_cmd_s *els_cmd;
3020 struct fc_ls_rjt_s *ls_rjt;
3022 bfa_trc(port->fcs, req_status);
3023 bfa_trc(port->fcs, port->port_cfg.pwwn);
3028 if (req_status != BFA_STATUS_OK) {
3029 port->stats.ms_plogi_rsp_err++;
3030 bfa_trc(port->fcs, req_status);
3031 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3035 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3037 switch (els_cmd->els_code) {
3040 if (rsp_len < sizeof(struct fc_logi_s)) {
3041 bfa_trc(port->fcs, rsp_len);
3042 port->stats.ms_plogi_acc_err++;
3043 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3046 port->stats.ms_plogi_accepts++;
3047 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3051 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3053 bfa_trc(port->fcs, ls_rjt->reason_code);
3054 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3056 port->stats.ms_rejects++;
3057 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3061 port->stats.ms_plogi_unknown_rsp++;
3062 bfa_trc(port->fcs, els_cmd->els_code);
3063 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3068 bfa_fcs_lport_ms_timeout(void *arg)
3070 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3072 ms->port->stats.ms_timeouts++;
3073 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
3078 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
3080 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3083 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3086 * Invoke init routines of sub modules.
3088 bfa_fcs_lport_fdmi_init(ms);
3092 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
3094 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3097 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
3098 bfa_fcs_lport_fdmi_offline(ms);
3102 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
3104 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3107 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3110 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3112 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3114 /* todo. Handle this only when in Online state */
3115 if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3116 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3120 * @page ns_sm_info VPORT NS State Machine
3122 * @section ns_sm_interactions VPORT NS State Machine Interactions
3124 * @section ns_sm VPORT NS State Machine
3129 * forward declarations
3131 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3132 struct bfa_fcxp_s *fcxp_alloced);
3133 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3134 struct bfa_fcxp_s *fcxp_alloced);
3135 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3136 struct bfa_fcxp_s *fcxp_alloced);
3137 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3138 struct bfa_fcxp_s *fcxp_alloced);
3139 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3140 struct bfa_fcxp_s *fcxp_alloced);
3141 static void bfa_fcs_lport_ns_timeout(void *arg);
3142 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3143 struct bfa_fcxp_s *fcxp,
3145 bfa_status_t req_status,
3148 struct fchs_s *rsp_fchs);
3149 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3150 struct bfa_fcxp_s *fcxp,
3152 bfa_status_t req_status,
3155 struct fchs_s *rsp_fchs);
3156 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3157 struct bfa_fcxp_s *fcxp,
3159 bfa_status_t req_status,
3162 struct fchs_s *rsp_fchs);
3163 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3164 struct bfa_fcxp_s *fcxp,
3166 bfa_status_t req_status,
3169 struct fchs_s *rsp_fchs);
3170 static void bfa_fcs_lport_ns_gid_ft_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_process_gidft_pids(
3178 struct bfa_fcs_lport_s *port,
3179 u32 *pid_buf, u32 n_pids);
3181 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
3183 * fcs_ns_sm FCS nameserver interface state machine
3187 * VPort NS State Machine events
3189 enum vport_ns_event {
3190 NSSM_EVENT_PORT_ONLINE = 1,
3191 NSSM_EVENT_PORT_OFFLINE = 2,
3192 NSSM_EVENT_PLOGI_SENT = 3,
3193 NSSM_EVENT_RSP_OK = 4,
3194 NSSM_EVENT_RSP_ERROR = 5,
3195 NSSM_EVENT_TIMEOUT = 6,
3196 NSSM_EVENT_NS_QUERY = 7,
3197 NSSM_EVENT_RSPNID_SENT = 8,
3198 NSSM_EVENT_RFTID_SENT = 9,
3199 NSSM_EVENT_RFFID_SENT = 10,
3200 NSSM_EVENT_GIDFT_SENT = 11,
3203 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3204 enum vport_ns_event event);
3205 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3206 enum vport_ns_event event);
3207 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3208 enum vport_ns_event event);
3209 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3210 enum vport_ns_event event);
3211 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3212 struct bfa_fcs_lport_ns_s *ns,
3213 enum vport_ns_event event);
3214 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3215 enum vport_ns_event event);
3216 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3217 enum vport_ns_event event);
3218 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3219 struct bfa_fcs_lport_ns_s *ns,
3220 enum vport_ns_event event);
3221 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3222 enum vport_ns_event event);
3223 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3224 enum vport_ns_event event);
3225 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3226 struct bfa_fcs_lport_ns_s *ns,
3227 enum vport_ns_event event);
3228 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3229 enum vport_ns_event event);
3230 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3231 enum vport_ns_event event);
3232 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3233 struct bfa_fcs_lport_ns_s *ns,
3234 enum vport_ns_event event);
3235 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3236 enum vport_ns_event event);
3237 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3238 enum vport_ns_event event);
3239 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3240 enum vport_ns_event event);
3242 * Start in offline state - awaiting linkup
3245 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3246 enum vport_ns_event event)
3248 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3249 bfa_trc(ns->port->fcs, event);
3252 case NSSM_EVENT_PORT_ONLINE:
3253 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3254 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3257 case NSSM_EVENT_PORT_OFFLINE:
3261 bfa_sm_fault(ns->port->fcs, event);
3266 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3267 enum vport_ns_event event)
3269 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3270 bfa_trc(ns->port->fcs, event);
3273 case NSSM_EVENT_PLOGI_SENT:
3274 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3277 case NSSM_EVENT_PORT_OFFLINE:
3278 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3279 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3284 bfa_sm_fault(ns->port->fcs, event);
3289 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3290 enum vport_ns_event event)
3292 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3293 bfa_trc(ns->port->fcs, event);
3296 case NSSM_EVENT_RSP_ERROR:
3298 * Start timer for a delayed retry
3300 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3301 ns->port->stats.ns_retries++;
3302 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3303 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3304 BFA_FCS_RETRY_TIMEOUT);
3307 case NSSM_EVENT_RSP_OK:
3308 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3309 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3312 case NSSM_EVENT_PORT_OFFLINE:
3313 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3314 bfa_fcxp_discard(ns->fcxp);
3318 bfa_sm_fault(ns->port->fcs, event);
3323 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3324 enum vport_ns_event event)
3326 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3327 bfa_trc(ns->port->fcs, event);
3330 case NSSM_EVENT_TIMEOUT:
3332 * Retry Timer Expired. Re-send
3334 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3335 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3338 case NSSM_EVENT_PORT_OFFLINE:
3339 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3340 bfa_timer_stop(&ns->timer);
3344 bfa_sm_fault(ns->port->fcs, event);
3349 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3350 enum vport_ns_event event)
3352 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3353 bfa_trc(ns->port->fcs, event);
3356 case NSSM_EVENT_RSPNID_SENT:
3357 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3360 case NSSM_EVENT_PORT_OFFLINE:
3361 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3362 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3367 bfa_sm_fault(ns->port->fcs, event);
3372 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3373 enum vport_ns_event event)
3375 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3376 bfa_trc(ns->port->fcs, event);
3379 case NSSM_EVENT_RSP_ERROR:
3381 * Start timer for a delayed retry
3383 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
3384 ns->port->stats.ns_retries++;
3385 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3386 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3387 BFA_FCS_RETRY_TIMEOUT);
3390 case NSSM_EVENT_RSP_OK:
3391 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3392 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3395 case NSSM_EVENT_PORT_OFFLINE:
3396 bfa_fcxp_discard(ns->fcxp);
3397 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3401 bfa_sm_fault(ns->port->fcs, event);
3406 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3407 enum vport_ns_event event)
3409 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3410 bfa_trc(ns->port->fcs, event);
3413 case NSSM_EVENT_TIMEOUT:
3415 * Retry Timer Expired. Re-send
3417 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3418 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3421 case NSSM_EVENT_PORT_OFFLINE:
3422 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3423 bfa_timer_stop(&ns->timer);
3427 bfa_sm_fault(ns->port->fcs, event);
3432 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
3433 enum vport_ns_event event)
3435 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3436 bfa_trc(ns->port->fcs, event);
3439 case NSSM_EVENT_RFTID_SENT:
3440 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
3443 case NSSM_EVENT_PORT_OFFLINE:
3444 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3445 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3450 bfa_sm_fault(ns->port->fcs, event);
3455 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3456 enum vport_ns_event event)
3458 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3459 bfa_trc(ns->port->fcs, event);
3462 case NSSM_EVENT_RSP_OK:
3463 /* Now move to register FC4 Features */
3464 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3465 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3468 case NSSM_EVENT_RSP_ERROR:
3470 * Start timer for a delayed retry
3472 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
3473 ns->port->stats.ns_retries++;
3474 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3475 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3476 BFA_FCS_RETRY_TIMEOUT);
3479 case NSSM_EVENT_PORT_OFFLINE:
3480 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3481 bfa_fcxp_discard(ns->fcxp);
3485 bfa_sm_fault(ns->port->fcs, event);
3490 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3491 enum vport_ns_event event)
3493 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3494 bfa_trc(ns->port->fcs, event);
3497 case NSSM_EVENT_TIMEOUT:
3498 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3499 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3502 case NSSM_EVENT_PORT_OFFLINE:
3503 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3504 bfa_timer_stop(&ns->timer);
3508 bfa_sm_fault(ns->port->fcs, event);
3513 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
3514 enum vport_ns_event event)
3516 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3517 bfa_trc(ns->port->fcs, event);
3520 case NSSM_EVENT_RFFID_SENT:
3521 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
3524 case NSSM_EVENT_PORT_OFFLINE:
3525 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3526 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3531 bfa_sm_fault(ns->port->fcs, event);
3536 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3537 enum vport_ns_event event)
3539 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3540 bfa_trc(ns->port->fcs, event);
3543 case NSSM_EVENT_RSP_OK:
3546 * If min cfg mode is enabled, we donot initiate rport
3547 * discovery with the fabric. Instead, we will retrieve the
3548 * boot targets from HAL/FW.
3550 if (__fcs_min_cfg(ns->port->fcs)) {
3551 bfa_fcs_lport_ns_boot_target_disc(ns->port);
3552 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3557 * If the port role is Initiator Mode issue NS query.
3558 * If it is Target Mode, skip this and go to online.
3560 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3561 bfa_sm_set_state(ns,
3562 bfa_fcs_lport_ns_sm_sending_gid_ft);
3563 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3566 * kick off mgmt srvr state machine
3568 bfa_fcs_lport_ms_online(ns->port);
3571 case NSSM_EVENT_RSP_ERROR:
3573 * Start timer for a delayed retry
3575 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
3576 ns->port->stats.ns_retries++;
3577 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3578 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3579 BFA_FCS_RETRY_TIMEOUT);
3582 case NSSM_EVENT_PORT_OFFLINE:
3583 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3584 bfa_fcxp_discard(ns->fcxp);
3588 bfa_sm_fault(ns->port->fcs, event);
3593 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3594 enum vport_ns_event event)
3596 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3597 bfa_trc(ns->port->fcs, event);
3600 case NSSM_EVENT_TIMEOUT:
3601 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3602 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3605 case NSSM_EVENT_PORT_OFFLINE:
3606 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3607 bfa_timer_stop(&ns->timer);
3611 bfa_sm_fault(ns->port->fcs, event);
3615 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3616 enum vport_ns_event event)
3618 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3619 bfa_trc(ns->port->fcs, event);
3622 case NSSM_EVENT_GIDFT_SENT:
3623 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
3626 case NSSM_EVENT_PORT_OFFLINE:
3627 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3628 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3633 bfa_sm_fault(ns->port->fcs, event);
3638 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3639 enum vport_ns_event event)
3641 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3642 bfa_trc(ns->port->fcs, event);
3645 case NSSM_EVENT_RSP_OK:
3646 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3649 case NSSM_EVENT_RSP_ERROR:
3651 * TBD: for certain reject codes, we don't need to retry
3654 * Start timer for a delayed retry
3656 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
3657 ns->port->stats.ns_retries++;
3658 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3659 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3660 BFA_FCS_RETRY_TIMEOUT);
3663 case NSSM_EVENT_PORT_OFFLINE:
3664 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3665 bfa_fcxp_discard(ns->fcxp);
3668 case NSSM_EVENT_NS_QUERY:
3672 bfa_sm_fault(ns->port->fcs, event);
3677 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3678 enum vport_ns_event event)
3680 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3681 bfa_trc(ns->port->fcs, event);
3684 case NSSM_EVENT_TIMEOUT:
3685 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
3686 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3689 case NSSM_EVENT_PORT_OFFLINE:
3690 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3691 bfa_timer_stop(&ns->timer);
3695 bfa_sm_fault(ns->port->fcs, event);
3700 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3701 enum vport_ns_event event)
3703 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3704 bfa_trc(ns->port->fcs, event);
3707 case NSSM_EVENT_PORT_OFFLINE:
3708 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3711 case NSSM_EVENT_NS_QUERY:
3713 * If the port role is Initiator Mode issue NS query.
3714 * If it is Target Mode, skip this and go to online.
3716 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3717 bfa_sm_set_state(ns,
3718 bfa_fcs_lport_ns_sm_sending_gid_ft);
3719 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3724 bfa_sm_fault(ns->port->fcs, event);
3731 * ns_pvt Nameserver local functions
3735 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3737 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3738 struct bfa_fcs_lport_s *port = ns->port;
3741 struct bfa_fcxp_s *fcxp;
3743 bfa_trc(port->fcs, port->pid);
3745 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3747 port->stats.ns_plogi_alloc_wait++;
3748 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3749 bfa_fcs_lport_ns_send_plogi, ns);
3754 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3755 bfa_hton3b(FC_NAME_SERVER),
3756 bfa_fcs_lport_get_fcid(port), 0,
3757 port->port_cfg.pwwn, port->port_cfg.nwwn,
3758 bfa_fcport_get_maxfrsize(port->fcs->bfa),
3759 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3761 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3762 FC_CLASS_3, len, &fchs,
3763 bfa_fcs_lport_ns_plogi_response, (void *)ns,
3764 FC_MAX_PDUSZ, FC_ELS_TOV);
3765 port->stats.ns_plogi_sent++;
3767 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
3771 bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3772 void *cbarg, bfa_status_t req_status, u32 rsp_len,
3773 u32 resid_len, struct fchs_s *rsp_fchs)
3775 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3776 struct bfa_fcs_lport_s *port = ns->port;
3777 /* struct fc_logi_s *plogi_resp; */
3778 struct fc_els_cmd_s *els_cmd;
3779 struct fc_ls_rjt_s *ls_rjt;
3781 bfa_trc(port->fcs, req_status);
3782 bfa_trc(port->fcs, port->port_cfg.pwwn);
3787 if (req_status != BFA_STATUS_OK) {
3788 bfa_trc(port->fcs, req_status);
3789 port->stats.ns_plogi_rsp_err++;
3790 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3794 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3796 switch (els_cmd->els_code) {
3799 if (rsp_len < sizeof(struct fc_logi_s)) {
3800 bfa_trc(port->fcs, rsp_len);
3801 port->stats.ns_plogi_acc_err++;
3802 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3805 port->stats.ns_plogi_accepts++;
3806 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3810 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3812 bfa_trc(port->fcs, ls_rjt->reason_code);
3813 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3815 port->stats.ns_rejects++;
3817 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3821 port->stats.ns_plogi_unknown_rsp++;
3822 bfa_trc(port->fcs, els_cmd->els_code);
3823 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3828 * Register the symbolic port name.
3831 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3833 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3834 struct bfa_fcs_lport_s *port = ns->port;
3837 struct bfa_fcxp_s *fcxp;
3839 u8 *psymbl = &symbl[0];
3841 memset(symbl, 0, sizeof(symbl));
3843 bfa_trc(port->fcs, port->port_cfg.pwwn);
3845 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3847 port->stats.ns_rspnid_alloc_wait++;
3848 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3849 bfa_fcs_lport_ns_send_rspn_id, ns);
3855 * for V-Port, form a Port Symbolic Name
3859 * For Vports, we append the vport's port symbolic name
3860 * to that of the base port.
3863 strncpy((char *)psymbl,
3865 (bfa_fcs_lport_get_psym_name
3866 (bfa_fcs_get_base_port(port->fcs))),
3868 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3871 /* Ensure we have a null terminating string. */
3872 ((char *)psymbl)[strlen((char *) &
3873 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3875 strncat((char *)psymbl,
3876 (char *) &(bfa_fcs_lport_get_psym_name(port)),
3877 strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
3879 psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
3882 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3883 bfa_fcs_lport_get_fcid(port), 0, psymbl);
3885 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3886 FC_CLASS_3, len, &fchs,
3887 bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
3888 FC_MAX_PDUSZ, FC_FCCT_TOV);
3890 port->stats.ns_rspnid_sent++;
3892 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
3896 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3897 void *cbarg, bfa_status_t req_status,
3898 u32 rsp_len, u32 resid_len,
3899 struct fchs_s *rsp_fchs)
3901 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3902 struct bfa_fcs_lport_s *port = ns->port;
3903 struct ct_hdr_s *cthdr = NULL;
3905 bfa_trc(port->fcs, port->port_cfg.pwwn);
3910 if (req_status != BFA_STATUS_OK) {
3911 bfa_trc(port->fcs, req_status);
3912 port->stats.ns_rspnid_rsp_err++;
3913 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3917 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3918 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3920 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3921 port->stats.ns_rspnid_accepts++;
3922 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3926 port->stats.ns_rspnid_rejects++;
3927 bfa_trc(port->fcs, cthdr->reason_code);
3928 bfa_trc(port->fcs, cthdr->exp_code);
3929 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3933 * Register FC4-Types
3936 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3938 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3939 struct bfa_fcs_lport_s *port = ns->port;
3942 struct bfa_fcxp_s *fcxp;
3944 bfa_trc(port->fcs, port->port_cfg.pwwn);
3946 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3948 port->stats.ns_rftid_alloc_wait++;
3949 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3950 bfa_fcs_lport_ns_send_rft_id, ns);
3955 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3956 bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
3958 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3959 FC_CLASS_3, len, &fchs,
3960 bfa_fcs_lport_ns_rft_id_response, (void *)ns,
3961 FC_MAX_PDUSZ, FC_FCCT_TOV);
3963 port->stats.ns_rftid_sent++;
3964 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
3968 bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3969 void *cbarg, bfa_status_t req_status,
3970 u32 rsp_len, u32 resid_len,
3971 struct fchs_s *rsp_fchs)
3973 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3974 struct bfa_fcs_lport_s *port = ns->port;
3975 struct ct_hdr_s *cthdr = NULL;
3977 bfa_trc(port->fcs, port->port_cfg.pwwn);
3982 if (req_status != BFA_STATUS_OK) {
3983 bfa_trc(port->fcs, req_status);
3984 port->stats.ns_rftid_rsp_err++;
3985 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3989 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3990 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3992 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3993 port->stats.ns_rftid_accepts++;
3994 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3998 port->stats.ns_rftid_rejects++;
3999 bfa_trc(port->fcs, cthdr->reason_code);
4000 bfa_trc(port->fcs, cthdr->exp_code);
4001 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4005 * Register FC4-Features : Should be done after RFT_ID
4008 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4010 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4011 struct bfa_fcs_lport_s *port = ns->port;
4014 struct bfa_fcxp_s *fcxp;
4017 bfa_trc(port->fcs, port->port_cfg.pwwn);
4019 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4021 port->stats.ns_rffid_alloc_wait++;
4022 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4023 bfa_fcs_lport_ns_send_rff_id, ns);
4028 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
4029 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
4031 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4032 bfa_fcs_lport_get_fcid(port), 0,
4033 FC_TYPE_FCP, fc4_ftrs);
4035 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4036 FC_CLASS_3, len, &fchs,
4037 bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4038 FC_MAX_PDUSZ, FC_FCCT_TOV);
4040 port->stats.ns_rffid_sent++;
4041 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
4045 bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4046 void *cbarg, bfa_status_t req_status,
4047 u32 rsp_len, u32 resid_len,
4048 struct fchs_s *rsp_fchs)
4050 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4051 struct bfa_fcs_lport_s *port = ns->port;
4052 struct ct_hdr_s *cthdr = NULL;
4054 bfa_trc(port->fcs, port->port_cfg.pwwn);
4059 if (req_status != BFA_STATUS_OK) {
4060 bfa_trc(port->fcs, req_status);
4061 port->stats.ns_rffid_rsp_err++;
4062 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4066 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4067 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4069 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4070 port->stats.ns_rffid_accepts++;
4071 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4075 port->stats.ns_rffid_rejects++;
4076 bfa_trc(port->fcs, cthdr->reason_code);
4077 bfa_trc(port->fcs, cthdr->exp_code);
4079 if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4080 /* if this command is not supported, we don't retry */
4081 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4083 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4086 * Query Fabric for FC4-Types Devices.
4088 * TBD : Need to use a local (FCS private) response buffer, since the response
4089 * can be larger than 2K.
4092 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4094 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4095 struct bfa_fcs_lport_s *port = ns->port;
4098 struct bfa_fcxp_s *fcxp;
4100 bfa_trc(port->fcs, port->pid);
4102 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4104 port->stats.ns_gidft_alloc_wait++;
4105 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4106 bfa_fcs_lport_ns_send_gid_ft, ns);
4112 * This query is only initiated for FCP initiator mode.
4114 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4115 ns->port->pid, FC_TYPE_FCP);
4117 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4118 FC_CLASS_3, len, &fchs,
4119 bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4120 bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4122 port->stats.ns_gidft_sent++;
4124 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4128 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4129 void *cbarg, bfa_status_t req_status,
4130 u32 rsp_len, u32 resid_len,
4131 struct fchs_s *rsp_fchs)
4133 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4134 struct bfa_fcs_lport_s *port = ns->port;
4135 struct ct_hdr_s *cthdr = NULL;
4138 bfa_trc(port->fcs, port->port_cfg.pwwn);
4143 if (req_status != BFA_STATUS_OK) {
4144 bfa_trc(port->fcs, req_status);
4145 port->stats.ns_gidft_rsp_err++;
4146 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4150 if (resid_len != 0) {
4152 * TBD : we will need to allocate a larger buffer & retry the
4155 bfa_trc(port->fcs, rsp_len);
4156 bfa_trc(port->fcs, resid_len);
4160 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4161 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4163 switch (cthdr->cmd_rsp_code) {
4167 port->stats.ns_gidft_accepts++;
4168 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4169 bfa_trc(port->fcs, n_pids);
4170 bfa_fcs_lport_ns_process_gidft_pids(port,
4171 (u32 *) (cthdr + 1),
4173 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4179 * Check the reason code & explanation.
4180 * There may not have been any FC4 devices in the fabric
4182 port->stats.ns_gidft_rejects++;
4183 bfa_trc(port->fcs, cthdr->reason_code);
4184 bfa_trc(port->fcs, cthdr->exp_code);
4186 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4187 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4189 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4192 * for all other errors, retry
4194 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4199 port->stats.ns_gidft_unknown_rsp++;
4200 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4201 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4206 * This routine will be called by bfa_timer on timer timeouts.
4208 * param[in] port - pointer to bfa_fcs_lport_t.
4213 * Special Considerations:
4218 bfa_fcs_lport_ns_timeout(void *arg)
4220 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
4222 ns->port->stats.ns_timeouts++;
4223 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
4227 * Process the PID list in GID_FT response
4230 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
4233 struct fcgs_gidft_resp_s *gidft_entry;
4234 struct bfa_fcs_rport_s *rport;
4237 for (ii = 0; ii < n_pids; ii++) {
4238 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
4240 if (gidft_entry->pid == port->pid)
4244 * Check if this rport already exists
4246 rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
4247 if (rport == NULL) {
4249 * this is a new device. create rport
4251 rport = bfa_fcs_rport_create(port, gidft_entry->pid);
4254 * this rport already exists
4256 bfa_fcs_rport_scn(rport);
4259 bfa_trc(port->fcs, gidft_entry->pid);
4262 * if the last entry bit is set, bail out.
4264 if (gidft_entry->last)
4270 * fcs_ns_public FCS nameserver public interfaces
4274 * Functions called by port/fab.
4275 * These will send relevant Events to the ns state machine.
4278 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
4280 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4283 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4287 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
4289 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4292 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
4296 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
4298 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4301 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
4305 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
4307 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4309 bfa_trc(port->fcs, port->pid);
4310 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
4314 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
4317 struct bfa_fcs_rport_s *rport;
4319 wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
4322 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
4324 for (ii = 0 ; ii < nwwns; ++ii) {
4325 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
4334 #define FC_QOS_RSCN_EVENT 0x0c
4335 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
4338 * forward declarations
4340 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
4341 struct bfa_fcxp_s *fcxp_alloced);
4342 static void bfa_fcs_lport_scn_scr_response(void *fcsarg,
4343 struct bfa_fcxp_s *fcxp,
4345 bfa_status_t req_status,
4348 struct fchs_s *rsp_fchs);
4349 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4350 struct fchs_s *rx_fchs);
4351 static void bfa_fcs_lport_scn_timeout(void *arg);
4354 * fcs_scm_sm FCS SCN state machine
4358 * VPort SCN State Machine events
4360 enum port_scn_event {
4361 SCNSM_EVENT_PORT_ONLINE = 1,
4362 SCNSM_EVENT_PORT_OFFLINE = 2,
4363 SCNSM_EVENT_RSP_OK = 3,
4364 SCNSM_EVENT_RSP_ERROR = 4,
4365 SCNSM_EVENT_TIMEOUT = 5,
4366 SCNSM_EVENT_SCR_SENT = 6,
4369 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4370 enum port_scn_event event);
4371 static void bfa_fcs_lport_scn_sm_sending_scr(
4372 struct bfa_fcs_lport_scn_s *scn,
4373 enum port_scn_event event);
4374 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4375 enum port_scn_event event);
4376 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4377 enum port_scn_event event);
4378 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4379 enum port_scn_event event);
4382 * Starting state - awaiting link up.
4385 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4386 enum port_scn_event event)
4389 case SCNSM_EVENT_PORT_ONLINE:
4390 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4391 bfa_fcs_lport_scn_send_scr(scn, NULL);
4394 case SCNSM_EVENT_PORT_OFFLINE:
4398 bfa_sm_fault(scn->port->fcs, event);
4403 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
4404 enum port_scn_event event)
4407 case SCNSM_EVENT_SCR_SENT:
4408 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
4411 case SCNSM_EVENT_PORT_OFFLINE:
4412 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4413 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
4417 bfa_sm_fault(scn->port->fcs, event);
4422 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4423 enum port_scn_event event)
4425 struct bfa_fcs_lport_s *port = scn->port;
4428 case SCNSM_EVENT_RSP_OK:
4429 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
4432 case SCNSM_EVENT_RSP_ERROR:
4433 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
4434 bfa_timer_start(port->fcs->bfa, &scn->timer,
4435 bfa_fcs_lport_scn_timeout, scn,
4436 BFA_FCS_RETRY_TIMEOUT);
4439 case SCNSM_EVENT_PORT_OFFLINE:
4440 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4441 bfa_fcxp_discard(scn->fcxp);
4445 bfa_sm_fault(port->fcs, event);
4450 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4451 enum port_scn_event event)
4454 case SCNSM_EVENT_TIMEOUT:
4455 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4456 bfa_fcs_lport_scn_send_scr(scn, NULL);
4459 case SCNSM_EVENT_PORT_OFFLINE:
4460 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4461 bfa_timer_stop(&scn->timer);
4465 bfa_sm_fault(scn->port->fcs, event);
4470 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4471 enum port_scn_event event)
4474 case SCNSM_EVENT_PORT_OFFLINE:
4475 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4479 bfa_sm_fault(scn->port->fcs, event);
4486 * fcs_scn_private FCS SCN private functions
4490 * This routine will be called to send a SCR command.
4493 bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4495 struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
4496 struct bfa_fcs_lport_s *port = scn->port;
4499 struct bfa_fcxp_s *fcxp;
4501 bfa_trc(port->fcs, port->pid);
4502 bfa_trc(port->fcs, port->port_cfg.pwwn);
4504 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4506 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
4507 bfa_fcs_lport_scn_send_scr, scn);
4512 /* Handle VU registrations for Base port only */
4513 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
4514 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4515 port->fabric->lps->brcd_switch,
4518 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4523 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4524 FC_CLASS_3, len, &fchs,
4525 bfa_fcs_lport_scn_scr_response,
4526 (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
4528 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
4532 bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4533 void *cbarg, bfa_status_t req_status, u32 rsp_len,
4534 u32 resid_len, struct fchs_s *rsp_fchs)
4536 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
4537 struct bfa_fcs_lport_s *port = scn->port;
4538 struct fc_els_cmd_s *els_cmd;
4539 struct fc_ls_rjt_s *ls_rjt;
4541 bfa_trc(port->fcs, port->port_cfg.pwwn);
4546 if (req_status != BFA_STATUS_OK) {
4547 bfa_trc(port->fcs, req_status);
4548 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4552 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4554 switch (els_cmd->els_code) {
4557 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
4562 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4564 bfa_trc(port->fcs, ls_rjt->reason_code);
4565 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4567 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4571 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4579 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4580 struct fchs_s *rx_fchs)
4583 struct bfa_fcxp_s *fcxp;
4584 struct bfa_rport_s *bfa_rport = NULL;
4587 bfa_trc(port->fcs, rx_fchs->s_id);
4589 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
4593 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4594 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
4597 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
4598 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
4603 * This routine will be called by bfa_timer on timer timeouts.
4605 * param[in] vport - pointer to bfa_fcs_lport_t.
4606 * param[out] vport_status - pointer to return vport status in
4611 * Special Considerations:
4616 bfa_fcs_lport_scn_timeout(void *arg)
4618 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
4620 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
4626 * fcs_scn_public FCS state change notification public interfaces
4630 * Functions called by port/fab
4633 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
4635 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4638 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4642 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
4644 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4647 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
4651 bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
4653 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4656 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
4660 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
4662 struct bfa_fcs_rport_s *rport;
4664 bfa_trc(port->fcs, rpid);
4667 * If this is an unknown device, then it just came online.
4668 * Otherwise let rport handle the RSCN event.
4670 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
4671 if (rport == NULL) {
4673 * If min cfg mode is enabled, we donot need to
4674 * discover any new rports.
4676 if (!__fcs_min_cfg(port->fcs))
4677 rport = bfa_fcs_rport_create(port, rpid);
4679 bfa_fcs_rport_scn(rport);
4683 * rscn format based PID comparison
4685 #define __fc_pid_match(__c0, __c1, __fmt) \
4686 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
4687 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
4688 ((__c0)[0] == (__c1)[0])) || \
4689 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
4690 ((__c0)[0] == (__c1)[0]) && \
4691 ((__c0)[1] == (__c1)[1])))
4694 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
4695 enum fc_rscn_format format,
4698 struct bfa_fcs_rport_s *rport;
4699 struct list_head *qe, *qe_next;
4702 bfa_trc(port->fcs, format);
4703 bfa_trc(port->fcs, rscn_pid);
4705 c0 = (u8 *) &rscn_pid;
4707 list_for_each_safe(qe, qe_next, &port->rport_q) {
4708 rport = (struct bfa_fcs_rport_s *) qe;
4709 c1 = (u8 *) &rport->pid;
4710 if (__fc_pid_match(c0, c1, format))
4711 bfa_fcs_rport_scn(rport);
4717 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
4718 struct fchs_s *fchs, u32 len)
4720 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
4723 bfa_boolean_t nsquery = BFA_FALSE, found;
4727 (be16_to_cpu(rscn->payldlen) -
4728 sizeof(u32)) / sizeof(rscn->event[0]);
4730 bfa_trc(port->fcs, num_entries);
4732 port->stats.num_rscn++;
4734 bfa_fcs_lport_scn_send_ls_acc(port, fchs);
4736 for (i = 0; i < num_entries; i++) {
4737 rscn_pid = rscn->event[i].portid;
4739 bfa_trc(port->fcs, rscn->event[i].format);
4740 bfa_trc(port->fcs, rscn_pid);
4742 /* check for duplicate entries in the list */
4744 for (j = 0; j < i; j++) {
4745 if (rscn->event[j].portid == rscn_pid) {
4751 /* if found in down the list, pid has been already processed */
4753 bfa_trc(port->fcs, rscn_pid);
4757 switch (rscn->event[i].format) {
4758 case FC_RSCN_FORMAT_PORTID:
4759 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
4761 * Ignore this event.
4762 * f/w would have processed it
4764 bfa_trc(port->fcs, rscn_pid);
4766 port->stats.num_portid_rscn++;
4767 bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
4771 case FC_RSCN_FORMAT_FABRIC:
4772 if (rscn->event[i].qualifier ==
4773 FC_FABRIC_NAME_RSCN_EVENT) {
4774 bfa_fcs_lport_ms_fabric_rscn(port);
4777 /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4779 case FC_RSCN_FORMAT_AREA:
4780 case FC_RSCN_FORMAT_DOMAIN:
4782 bfa_fcs_lport_scn_multiport_rscn(port,
4783 rscn->event[i].format,
4795 * If any of area, domain or fabric RSCN is received, do a fresh
4796 * discovery to find new devices.
4799 bfa_fcs_lport_ns_query(port);
4806 * fcs_port_api BFA FCS port API
4808 struct bfa_fcs_lport_s *
4809 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
4811 return &fcs->fabric.bport;
4815 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
4816 int nrports, bfa_boolean_t bwwn)
4818 struct list_head *qh, *qe;
4819 struct bfa_fcs_rport_s *rport = NULL;
4821 struct bfa_fcs_s *fcs;
4823 if (port == NULL || nrports == 0)
4827 bfa_trc(fcs, (u32) nrports);
4830 qh = &port->rport_q;
4831 qe = bfa_q_first(qh);
4833 while ((qe != qh) && (i < nrports)) {
4834 rport = (struct bfa_fcs_rport_s *) qe;
4835 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4836 qe = bfa_q_next(qe);
4837 bfa_trc(fcs, (u32) rport->pwwn);
4838 bfa_trc(fcs, rport->pid);
4844 if (!memcmp(&wwn, &rport->pwwn, 8))
4852 qe = bfa_q_next(qe);
4863 bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
4864 wwn_t rport_wwns[], int *nrports)
4866 struct list_head *qh, *qe;
4867 struct bfa_fcs_rport_s *rport = NULL;
4869 struct bfa_fcs_s *fcs;
4871 if (port == NULL || rport_wwns == NULL || *nrports == 0)
4875 bfa_trc(fcs, (u32) *nrports);
4878 qh = &port->rport_q;
4879 qe = bfa_q_first(qh);
4881 while ((qe != qh) && (i < *nrports)) {
4882 rport = (struct bfa_fcs_rport_s *) qe;
4883 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4884 qe = bfa_q_next(qe);
4885 bfa_trc(fcs, (u32) rport->pwwn);
4886 bfa_trc(fcs, rport->pid);
4891 rport_wwns[i] = rport->pwwn;
4894 qe = bfa_q_next(qe);
4902 * Iterate's through all the rport's in the given port to
4903 * determine the maximum operating speed.
4905 * !!!! To be used in TRL Functionality only !!!!
4908 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
4910 struct list_head *qh, *qe;
4911 struct bfa_fcs_rport_s *rport = NULL;
4912 struct bfa_fcs_s *fcs;
4913 bfa_port_speed_t max_speed = 0;
4914 struct bfa_port_attr_s port_attr;
4915 bfa_port_speed_t port_speed, rport_speed;
4916 bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
4924 /* Get Physical port's current speed */
4925 bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
4926 port_speed = port_attr.speed;
4927 bfa_trc(fcs, port_speed);
4929 qh = &port->rport_q;
4930 qe = bfa_q_first(qh);
4933 rport = (struct bfa_fcs_rport_s *) qe;
4934 if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
4935 (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
4936 (rport->scsi_function != BFA_RPORT_TARGET)) {
4937 qe = bfa_q_next(qe);
4941 rport_speed = rport->rpf.rpsc_speed;
4942 if ((trl_enabled) && (rport_speed ==
4943 BFA_PORT_SPEED_UNKNOWN)) {
4944 /* Use default ratelim speed setting */
4946 bfa_fcport_get_ratelim_speed(port->fcs->bfa);
4949 if (rport_speed > max_speed)
4950 max_speed = rport_speed;
4952 qe = bfa_q_next(qe);
4955 if (max_speed > port_speed)
4956 max_speed = port_speed;
4958 bfa_trc(fcs, max_speed);
4962 struct bfa_fcs_lport_s *
4963 bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
4965 struct bfa_fcs_vport_s *vport;
4968 WARN_ON(fcs == NULL);
4970 vf = bfa_fcs_vf_lookup(fcs, vf_id);
4972 bfa_trc(fcs, vf_id);
4976 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
4979 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
4981 return &vport->lport;
4987 * API corresponding to NPIV_VPORT_GETINFO.
4990 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
4991 struct bfa_lport_info_s *port_info)
4994 bfa_trc(port->fcs, port->fabric->fabric_name);
4996 if (port->vport == NULL) {
4998 * This is a Physical port
5000 port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5003 * @todo : need to fix the state & reason
5005 port_info->port_state = 0;
5006 port_info->offline_reason = 0;
5008 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5009 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5011 port_info->max_vports_supp =
5012 bfa_lps_get_max_vport(port->fcs->bfa);
5013 port_info->num_vports_inuse =
5014 port->fabric->num_vports;
5015 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
5016 port_info->num_rports_inuse = port->num_rports;
5019 * This is a virtual port
5021 port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5024 * @todo : need to fix the state & reason
5026 port_info->port_state = 0;
5027 port_info->offline_reason = 0;
5029 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5030 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5035 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
5036 struct bfa_lport_stats_s *port_stats)
5038 *port_stats = fcs_port->stats;
5042 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5044 memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5048 * FCS virtual port state machine
5051 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
5052 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
5053 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
5054 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
5055 #define __vport_fcid(__vp) ((__vp)->lport.pid)
5056 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
5057 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
5059 #define BFA_FCS_VPORT_MAX_RETRIES 5
5061 * Forward declarations
5063 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5064 static void bfa_fcs_vport_timeout(void *vport_arg);
5065 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5066 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5069 * fcs_vport_sm FCS virtual port state machine
5073 * VPort State Machine events
5075 enum bfa_fcs_vport_event {
5076 BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */
5077 BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */
5078 BFA_FCS_VPORT_SM_START = 3, /* vport start request */
5079 BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */
5080 BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */
5081 BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */
5082 BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */
5083 BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */
5084 BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */
5085 BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */
5086 BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */
5087 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/
5088 BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */
5089 BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */
5092 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5093 enum bfa_fcs_vport_event event);
5094 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5095 enum bfa_fcs_vport_event event);
5096 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5097 enum bfa_fcs_vport_event event);
5098 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5099 enum bfa_fcs_vport_event event);
5100 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5101 enum bfa_fcs_vport_event event);
5102 static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5103 enum bfa_fcs_vport_event event);
5104 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5105 enum bfa_fcs_vport_event event);
5106 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5107 enum bfa_fcs_vport_event event);
5108 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5109 enum bfa_fcs_vport_event event);
5110 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5111 enum bfa_fcs_vport_event event);
5112 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5113 enum bfa_fcs_vport_event event);
5114 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5115 enum bfa_fcs_vport_event event);
5116 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5117 enum bfa_fcs_vport_event event);
5119 static struct bfa_sm_table_s vport_sm_table[] = {
5120 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
5121 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
5122 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
5123 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
5124 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
5125 {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
5126 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
5127 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
5128 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
5129 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
5130 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
5137 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5138 enum bfa_fcs_vport_event event)
5140 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5141 bfa_trc(__vport_fcs(vport), event);
5144 case BFA_FCS_VPORT_SM_CREATE:
5145 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5146 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
5150 bfa_sm_fault(__vport_fcs(vport), event);
5155 * Created state - a start event is required to start up the state machine.
5158 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5159 enum bfa_fcs_vport_event event)
5161 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5162 bfa_trc(__vport_fcs(vport), event);
5165 case BFA_FCS_VPORT_SM_START:
5166 if (bfa_sm_cmp_state(__vport_fabric(vport),
5167 bfa_fcs_fabric_sm_online)
5168 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
5169 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5170 bfa_fcs_vport_do_fdisc(vport);
5173 * Fabric is offline or not NPIV capable, stay in
5176 vport->vport_stats.fab_no_npiv++;
5177 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5181 case BFA_FCS_VPORT_SM_DELETE:
5182 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5183 bfa_fcs_lport_delete(&vport->lport);
5186 case BFA_FCS_VPORT_SM_ONLINE:
5187 case BFA_FCS_VPORT_SM_OFFLINE:
5189 * Ignore ONLINE/OFFLINE events from fabric
5190 * till vport is started.
5195 bfa_sm_fault(__vport_fcs(vport), event);
5200 * Offline state - awaiting ONLINE event from fabric SM.
5203 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5204 enum bfa_fcs_vport_event event)
5206 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5207 bfa_trc(__vport_fcs(vport), event);
5210 case BFA_FCS_VPORT_SM_DELETE:
5211 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5212 bfa_fcs_lport_delete(&vport->lport);
5215 case BFA_FCS_VPORT_SM_ONLINE:
5216 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5217 vport->fdisc_retries = 0;
5218 bfa_fcs_vport_do_fdisc(vport);
5221 case BFA_FCS_VPORT_SM_STOP:
5222 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5223 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5226 case BFA_FCS_VPORT_SM_OFFLINE:
5228 * This can happen if the vport couldn't be initialzied
5229 * due the fact that the npiv was not enabled on the switch.
5230 * In that case we will put the vport in offline state.
5231 * However, the link can go down and cause the this event to
5232 * be sent when we are already offline. Ignore it.
5237 bfa_sm_fault(__vport_fcs(vport), event);
5243 * FDISC is sent and awaiting reply from fabric.
5246 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5247 enum bfa_fcs_vport_event event)
5249 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5250 bfa_trc(__vport_fcs(vport), event);
5253 case BFA_FCS_VPORT_SM_DELETE:
5254 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
5257 case BFA_FCS_VPORT_SM_OFFLINE:
5258 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5259 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5262 case BFA_FCS_VPORT_SM_RSP_OK:
5263 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
5264 bfa_fcs_lport_online(&vport->lport);
5267 case BFA_FCS_VPORT_SM_RSP_ERROR:
5268 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
5269 bfa_timer_start(__vport_bfa(vport), &vport->timer,
5270 bfa_fcs_vport_timeout, vport,
5271 BFA_FCS_RETRY_TIMEOUT);
5274 case BFA_FCS_VPORT_SM_RSP_FAILED:
5275 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5278 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5279 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
5283 bfa_sm_fault(__vport_fcs(vport), event);
5288 * FDISC attempt failed - a timer is active to retry FDISC.
5291 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5292 enum bfa_fcs_vport_event event)
5294 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5295 bfa_trc(__vport_fcs(vport), event);
5298 case BFA_FCS_VPORT_SM_DELETE:
5299 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5300 bfa_timer_stop(&vport->timer);
5301 bfa_fcs_lport_delete(&vport->lport);
5304 case BFA_FCS_VPORT_SM_OFFLINE:
5305 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5306 bfa_timer_stop(&vport->timer);
5309 case BFA_FCS_VPORT_SM_TIMEOUT:
5310 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5311 vport->vport_stats.fdisc_retries++;
5312 vport->fdisc_retries++;
5313 bfa_fcs_vport_do_fdisc(vport);
5317 bfa_sm_fault(__vport_fcs(vport), event);
5322 * FDISC is in progress and we got a vport delete request -
5323 * this is a wait state while we wait for fdisc response and
5324 * we will transition to the appropriate state - on rsp status.
5327 bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5328 enum bfa_fcs_vport_event event)
5330 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5331 bfa_trc(__vport_fcs(vport), event);
5334 case BFA_FCS_VPORT_SM_RSP_OK:
5335 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5336 bfa_fcs_lport_delete(&vport->lport);
5339 case BFA_FCS_VPORT_SM_DELETE:
5342 case BFA_FCS_VPORT_SM_OFFLINE:
5343 case BFA_FCS_VPORT_SM_RSP_ERROR:
5344 case BFA_FCS_VPORT_SM_RSP_FAILED:
5345 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5346 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5347 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5348 bfa_fcs_lport_delete(&vport->lport);
5352 bfa_sm_fault(__vport_fcs(vport), event);
5357 * Vport is online (FDISC is complete).
5360 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5361 enum bfa_fcs_vport_event event)
5363 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5364 bfa_trc(__vport_fcs(vport), event);
5367 case BFA_FCS_VPORT_SM_DELETE:
5368 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5369 bfa_fcs_lport_delete(&vport->lport);
5372 case BFA_FCS_VPORT_SM_STOP:
5373 bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
5374 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5377 case BFA_FCS_VPORT_SM_OFFLINE:
5378 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5379 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5380 bfa_fcs_lport_offline(&vport->lport);
5384 bfa_sm_fault(__vport_fcs(vport), event);
5389 * Vport is being stopped - awaiting lport stop completion to send
5393 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5394 enum bfa_fcs_vport_event event)
5396 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5397 bfa_trc(__vport_fcs(vport), event);
5400 case BFA_FCS_VPORT_SM_STOPCOMP:
5401 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
5402 bfa_fcs_vport_do_logo(vport);
5405 case BFA_FCS_VPORT_SM_OFFLINE:
5406 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5410 bfa_sm_fault(__vport_fcs(vport), event);
5415 * Vport is being deleted - awaiting lport delete completion to send
5419 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5420 enum bfa_fcs_vport_event event)
5422 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5423 bfa_trc(__vport_fcs(vport), event);
5426 case BFA_FCS_VPORT_SM_DELETE:
5429 case BFA_FCS_VPORT_SM_DELCOMP:
5430 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
5431 bfa_fcs_vport_do_logo(vport);
5434 case BFA_FCS_VPORT_SM_OFFLINE:
5435 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5439 bfa_sm_fault(__vport_fcs(vport), event);
5445 * This state will be set when the Vport Creation fails due
5446 * to errors like Dup WWN. In this state only operation allowed
5447 * is a Vport Delete.
5450 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5451 enum bfa_fcs_vport_event event)
5453 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5454 bfa_trc(__vport_fcs(vport), event);
5457 case BFA_FCS_VPORT_SM_DELETE:
5458 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5459 bfa_fcs_lport_delete(&vport->lport);
5463 bfa_trc(__vport_fcs(vport), event);
5468 * Lport cleanup is in progress since vport is being deleted. Fabric is
5469 * offline, so no LOGO is needed to complete vport deletion.
5472 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5473 enum bfa_fcs_vport_event event)
5475 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5476 bfa_trc(__vport_fcs(vport), event);
5479 case BFA_FCS_VPORT_SM_DELCOMP:
5480 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5481 bfa_fcs_vport_free(vport);
5484 case BFA_FCS_VPORT_SM_STOPCOMP:
5485 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5488 case BFA_FCS_VPORT_SM_DELETE:
5492 bfa_sm_fault(__vport_fcs(vport), event);
5497 * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
5501 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5502 enum bfa_fcs_vport_event event)
5504 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5505 bfa_trc(__vport_fcs(vport), event);
5508 case BFA_FCS_VPORT_SM_OFFLINE:
5509 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5511 * !!! fall through !!!
5514 case BFA_FCS_VPORT_SM_RSP_OK:
5515 case BFA_FCS_VPORT_SM_RSP_ERROR:
5516 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5520 bfa_sm_fault(__vport_fcs(vport), event);
5525 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5529 bfa_fcs_vport_sm_logo(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_uninit);
5545 bfa_fcs_vport_free(vport);
5548 case BFA_FCS_VPORT_SM_DELETE:
5552 bfa_sm_fault(__vport_fcs(vport), event);
5559 * fcs_vport_private FCS virtual port private functions
5562 * This routine will be called to send a FDISC command.
5565 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
5567 bfa_lps_fdisc(vport->lps, vport,
5568 bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
5569 __vport_pwwn(vport), __vport_nwwn(vport));
5570 vport->vport_stats.fdisc_sent++;
5574 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5576 u8 lsrjt_rsn = vport->lps->lsrjt_rsn;
5577 u8 lsrjt_expl = vport->lps->lsrjt_expl;
5579 bfa_trc(__vport_fcs(vport), lsrjt_rsn);
5580 bfa_trc(__vport_fcs(vport), lsrjt_expl);
5582 /* For certain reason codes, we don't want to retry. */
5583 switch (vport->lps->lsrjt_expl) {
5584 case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
5585 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
5586 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5587 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5589 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
5592 case FC_LS_RJT_EXP_INSUFF_RES:
5594 * This means max logins per port/switch setting on the
5595 * switch was exceeded.
5597 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5598 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5600 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
5604 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5609 * Called to send a logout to the fabric. Used when a V-Port is
5613 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
5615 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5617 vport->vport_stats.logo_sent++;
5618 bfa_lps_fdisclogo(vport->lps);
5623 * This routine will be called by bfa_timer on timer timeouts.
5625 * param[in] vport - pointer to bfa_fcs_vport_t.
5626 * param[out] vport_status - pointer to return vport status in
5631 * Special Considerations:
5636 bfa_fcs_vport_timeout(void *vport_arg)
5638 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
5640 vport->vport_stats.fdisc_timeouts++;
5641 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
5645 bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
5647 struct bfad_vport_s *vport_drv =
5648 (struct bfad_vport_s *)vport->vport_drv;
5650 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
5652 if (vport_drv->comp_del)
5653 complete(vport_drv->comp_del);
5655 bfa_lps_delete(vport->lps);
5661 * fcs_vport_public FCS virtual port public interfaces
5665 * Online notification from fabric SM.
5668 bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
5670 vport->vport_stats.fab_online++;
5671 if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
5672 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
5674 vport->vport_stats.fab_no_npiv++;
5678 * Offline notification from fabric SM.
5681 bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
5683 vport->vport_stats.fab_offline++;
5684 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
5688 * Cleanup notification from fabric SM on link timer expiry.
5691 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
5693 vport->vport_stats.fab_cleanup++;
5696 * delete notification from fabric SM. To be invoked from within FCS.
5699 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
5701 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5705 * Stop completion callback from associated lport
5708 bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
5710 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
5714 * Delete completion callback from associated lport
5717 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
5719 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
5725 * fcs_vport_api Virtual port API
5729 * Use this function to instantiate a new FCS vport object. This
5730 * function will not trigger any HW initialization process (which will be
5731 * done in vport_start() call)
5733 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5734 * needs to be allocated by the driver.
5735 * param[in] fcs - FCS instance
5736 * param[in] vport_cfg - vport configuration
5737 * param[in] vf_id - VF_ID if vport is created within a VF.
5738 * FC_VF_ID_NULL to specify base fabric.
5739 * param[in] vport_drv - Opaque handle back to the driver's vport
5742 * retval BFA_STATUS_OK - on success.
5743 * retval BFA_STATUS_FAILED - on failure.
5746 bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5747 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5748 struct bfad_vport_s *vport_drv)
5750 if (vport_cfg->pwwn == 0)
5751 return BFA_STATUS_INVALID_WWN;
5753 if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
5754 return BFA_STATUS_VPORT_WWN_BP;
5756 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
5757 return BFA_STATUS_VPORT_EXISTS;
5759 if (fcs->fabric.num_vports ==
5760 bfa_lps_get_max_vport(fcs->bfa))
5761 return BFA_STATUS_VPORT_MAX;
5763 vport->lps = bfa_lps_alloc(fcs->bfa);
5765 return BFA_STATUS_VPORT_MAX;
5767 vport->vport_drv = vport_drv;
5768 vport_cfg->preboot_vp = BFA_FALSE;
5770 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5771 bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
5772 bfa_fcs_lport_init(&vport->lport, vport_cfg);
5773 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
5775 return BFA_STATUS_OK;
5779 * Use this function to instantiate a new FCS PBC vport object. This
5780 * function will not trigger any HW initialization process (which will be
5781 * done in vport_start() call)
5783 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5784 * needs to be allocated by the driver.
5785 * param[in] fcs - FCS instance
5786 * param[in] vport_cfg - vport configuration
5787 * param[in] vf_id - VF_ID if vport is created within a VF.
5788 * FC_VF_ID_NULL to specify base fabric.
5789 * param[in] vport_drv - Opaque handle back to the driver's vport
5792 * retval BFA_STATUS_OK - on success.
5793 * retval BFA_STATUS_FAILED - on failure.
5796 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5797 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5798 struct bfad_vport_s *vport_drv)
5802 rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
5803 vport->lport.port_cfg.preboot_vp = BFA_TRUE;
5809 * Use this function to findout if this is a pbc vport or not.
5811 * @param[in] vport - pointer to bfa_fcs_vport_t.
5816 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
5819 if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
5827 * Use this function initialize the vport.
5829 * @param[in] vport - pointer to bfa_fcs_vport_t.
5834 bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
5836 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
5838 return BFA_STATUS_OK;
5842 * Use this function quiese the vport object. This function will return
5843 * immediately, when the vport is actually stopped, the
5844 * bfa_drv_vport_stop_cb() will be called.
5846 * param[in] vport - pointer to bfa_fcs_vport_t.
5851 bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
5853 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
5855 return BFA_STATUS_OK;
5859 * Use this function to delete a vport object. Fabric object should
5860 * be stopped before this function call.
5862 * !!!!!!! Donot invoke this from within FCS !!!!!!!
5864 * param[in] vport - pointer to bfa_fcs_vport_t.
5869 bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
5872 if (vport->lport.port_cfg.preboot_vp)
5873 return BFA_STATUS_PBC;
5875 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5877 return BFA_STATUS_OK;
5881 * Use this function to get vport's current status info.
5883 * param[in] vport pointer to bfa_fcs_vport_t.
5884 * param[out] attr pointer to return vport attributes
5889 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
5890 struct bfa_vport_attr_s *attr)
5892 if (vport == NULL || attr == NULL)
5895 memset(attr, 0, sizeof(struct bfa_vport_attr_s));
5897 bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
5898 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
5903 * Lookup a virtual port. Excludes base port from lookup.
5905 struct bfa_fcs_vport_s *
5906 bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
5908 struct bfa_fcs_vport_s *vport;
5909 struct bfa_fcs_fabric_s *fabric;
5911 bfa_trc(fcs, vf_id);
5912 bfa_trc(fcs, vpwwn);
5914 fabric = bfa_fcs_vf_lookup(fcs, vf_id);
5916 bfa_trc(fcs, vf_id);
5920 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
5928 bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
5930 struct bfa_fcs_vport_s *vport = uarg;
5932 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5933 bfa_trc(__vport_fcs(vport), status);
5938 * Initialize the V-Port fields
5940 __vport_fcid(vport) = vport->lps->lp_pid;
5941 vport->vport_stats.fdisc_accepts++;
5942 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
5945 case BFA_STATUS_INVALID_MAC:
5947 vport->vport_stats.fdisc_acc_bad++;
5948 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5952 case BFA_STATUS_EPROTOCOL:
5953 switch (vport->lps->ext_status) {
5954 case BFA_EPROTO_BAD_ACCEPT:
5955 vport->vport_stats.fdisc_acc_bad++;
5958 case BFA_EPROTO_UNKNOWN_RSP:
5959 vport->vport_stats.fdisc_unknown_rsp++;
5966 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5969 case BFA_STATUS_FABRIC_RJT:
5970 vport->vport_stats.fdisc_rejects++;
5971 bfa_fcs_vport_fdisc_rejected(vport);
5975 vport->vport_stats.fdisc_rsp_err++;
5976 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5984 bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
5986 struct bfa_fcs_vport_s *vport = uarg;
5987 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
5991 * Received clear virtual link
5994 bfa_cb_lps_cvl_event(void *bfad, void *uarg)
5996 struct bfa_fcs_vport_s *vport = uarg;
5998 /* Send an Offline followed by an ONLINE */
5999 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6000 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);