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,
331 * Process incoming plogi from a remote port.
334 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
335 struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
337 struct bfa_fcs_rport_s *rport;
339 bfa_trc(port->fcs, rx_fchs->d_id);
340 bfa_trc(port->fcs, rx_fchs->s_id);
343 * If min cfg mode is enabled, drop any incoming PLOGIs
345 if (__fcs_min_cfg(port->fcs)) {
346 bfa_trc(port->fcs, rx_fchs->s_id);
350 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
351 bfa_trc(port->fcs, rx_fchs->s_id);
355 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
356 FC_LS_RJT_RSN_PROTOCOL_ERROR,
357 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
362 * Direct Attach P2P mode : verify address assigned by the r-port.
364 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
365 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
366 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
367 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
368 /* Address assigned to us cannot be a WKA */
369 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
370 FC_LS_RJT_RSN_PROTOCOL_ERROR,
371 FC_LS_RJT_EXP_INVALID_NPORT_ID);
374 port->pid = rx_fchs->d_id;
375 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
379 * First, check if we know the device by pwwn.
381 rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
384 * Direct Attach P2P mode : handle address assigned by r-port.
386 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
387 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
388 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
389 port->pid = rx_fchs->d_id;
390 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
391 rport->pid = rx_fchs->s_id;
393 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
398 * Next, lookup rport by PID.
400 rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
403 * Inbound PLOGI from a new device.
405 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
410 * Rport is known only by PID.
414 * This is a different device with the same pid. Old device
415 * disappeared. Send implicit LOGO to old device.
417 WARN_ON(rport->pwwn == plogi->port_name);
418 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
421 * Inbound PLOGI from a new device (with old PID).
423 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
428 * PLOGI crossing each other.
430 WARN_ON(rport->pwwn != WWN_NULL);
431 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
435 * Process incoming ECHO.
436 * Since it does not require a login, it is processed here.
439 bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
440 struct fc_echo_s *echo, u16 rx_len)
443 struct bfa_fcxp_s *fcxp;
444 struct bfa_rport_s *bfa_rport = NULL;
447 bfa_trc(port->fcs, rx_fchs->s_id);
448 bfa_trc(port->fcs, rx_fchs->d_id);
450 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
454 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
455 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
459 * Copy the payload (if any) from the echo frame
461 pyld_len = rx_len - sizeof(struct fchs_s);
462 bfa_trc(port->fcs, rx_len);
463 bfa_trc(port->fcs, pyld_len);
466 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
467 sizeof(struct fc_echo_s), (echo + 1),
468 (pyld_len - sizeof(struct fc_echo_s)));
470 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
471 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
476 * Process incoming RNID.
477 * Since it does not require a login, it is processed here.
480 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
481 struct fc_rnid_cmd_s *rnid, u16 rx_len)
483 struct fc_rnid_common_id_data_s common_id_data;
484 struct fc_rnid_general_topology_data_s gen_topo_data;
486 struct bfa_fcxp_s *fcxp;
487 struct bfa_rport_s *bfa_rport = NULL;
491 bfa_trc(port->fcs, rx_fchs->s_id);
492 bfa_trc(port->fcs, rx_fchs->d_id);
493 bfa_trc(port->fcs, rx_len);
495 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
500 * Check Node Indentification Data Format
501 * We only support General Topology Discovery Format.
502 * For any other requested Data Formats, we return Common Node Id Data
503 * only, as per FC-LS.
505 bfa_trc(port->fcs, rnid->node_id_data_format);
506 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
507 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
509 * Get General topology data for this port
511 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
513 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
517 * Copy the Node Id Info
519 common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
520 common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
522 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
523 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
524 rx_fchs->ox_id, data_format, &common_id_data,
527 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
528 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
533 * Fill out General Topolpgy Discovery Data for RNID ELS.
536 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
537 struct fc_rnid_general_topology_data_s *gen_topo_data)
539 memset(gen_topo_data, 0,
540 sizeof(struct fc_rnid_general_topology_data_s));
542 gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
543 gen_topo_data->phy_port_num = 0; /* @todo */
544 gen_topo_data->num_attached_nodes = cpu_to_be32(1);
548 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
550 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
551 char lpwwn_buf[BFA_STRING_32];
553 bfa_trc(port->fcs, port->fabric->oper_type);
555 __port_action[port->fabric->fab_type].init(port);
556 __port_action[port->fabric->fab_type].online(port);
558 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
559 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
560 "Logical port online: WWN = %s Role = %s\n",
561 lpwwn_buf, "Initiator");
563 bfad->bfad_flags |= BFAD_PORT_ONLINE;
567 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
569 struct list_head *qe, *qen;
570 struct bfa_fcs_rport_s *rport;
571 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
572 char lpwwn_buf[BFA_STRING_32];
574 bfa_trc(port->fcs, port->fabric->oper_type);
576 __port_action[port->fabric->fab_type].offline(port);
578 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
579 if (bfa_sm_cmp_state(port->fabric,
580 bfa_fcs_fabric_sm_online) == BFA_TRUE)
581 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
582 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
583 lpwwn_buf, "Initiator");
585 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
586 "Logical port taken offline: WWN = %s Role = %s\n",
587 lpwwn_buf, "Initiator");
589 list_for_each_safe(qe, qen, &port->rport_q) {
590 rport = (struct bfa_fcs_rport_s *) qe;
591 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
596 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
602 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
608 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
614 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
617 struct bfa_fcxp_s *fcxp;
620 bfa_trc(port->fcs, rx_fchs->d_id);
621 bfa_trc(port->fcs, rx_fchs->s_id);
623 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
627 len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
628 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
631 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
632 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
636 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
638 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
639 char lpwwn_buf[BFA_STRING_32];
641 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
642 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
643 "Logical port deleted: WWN = %s Role = %s\n",
644 lpwwn_buf, "Initiator");
646 /* Base port will be deleted by the OS driver */
648 bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles,
649 port->fabric->vf_drv,
650 port->vport ? port->vport->vport_drv : NULL);
651 bfa_fcs_vport_delete_comp(port->vport);
653 bfa_wc_down(&port->fabric->wc);
659 * Unsolicited frame receive handling.
662 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
663 struct fchs_s *fchs, u16 len)
665 u32 pid = fchs->s_id;
666 struct bfa_fcs_rport_s *rport = NULL;
667 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
669 bfa_stats(lport, uf_recvs);
670 bfa_trc(lport->fcs, fchs->type);
672 if (!bfa_fcs_lport_is_online(lport)) {
673 bfa_stats(lport, uf_recv_drops);
678 * First, handle ELSs that donot require a login.
683 if ((fchs->type == FC_TYPE_ELS) &&
684 (els_cmd->els_code == FC_ELS_PLOGI)) {
685 bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
690 * Handle ECHO separately.
692 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
693 bfa_fcs_lport_echo(lport, fchs,
694 (struct fc_echo_s *)els_cmd, len);
699 * Handle RNID separately.
701 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
702 bfa_fcs_lport_rnid(lport, fchs,
703 (struct fc_rnid_cmd_s *) els_cmd, len);
707 if (fchs->type == FC_TYPE_BLS) {
708 if ((fchs->routing == FC_RTG_BASIC_LINK) &&
709 (fchs->cat_info == FC_CAT_ABTS))
710 bfa_fcs_lport_abts_acc(lport, fchs);
714 * look for a matching remote port ID
716 rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
718 bfa_trc(rport->fcs, fchs->s_id);
719 bfa_trc(rport->fcs, fchs->d_id);
720 bfa_trc(rport->fcs, fchs->type);
722 bfa_fcs_rport_uf_recv(rport, fchs, len);
727 * Only handles ELS frames for now.
729 if (fchs->type != FC_TYPE_ELS) {
730 bfa_trc(lport->fcs, fchs->s_id);
731 bfa_trc(lport->fcs, fchs->d_id);
732 /* ignore type FC_TYPE_FC_FSS */
733 if (fchs->type != FC_TYPE_FC_FSS)
734 bfa_sm_fault(lport->fcs, fchs->type);
738 bfa_trc(lport->fcs, els_cmd->els_code);
739 if (els_cmd->els_code == FC_ELS_RSCN) {
740 bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
744 if (els_cmd->els_code == FC_ELS_LOGO) {
746 * @todo Handle LOGO frames received.
751 if (els_cmd->els_code == FC_ELS_PRLI) {
753 * @todo Handle PRLI frames received.
759 * Unhandled ELS frames. Send a LS_RJT.
761 bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
762 FC_LS_RJT_EXP_NO_ADDL_INFO);
767 * PID based Lookup for a R-Port in the Port R-Port Queue
769 struct bfa_fcs_rport_s *
770 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
772 struct bfa_fcs_rport_s *rport;
773 struct list_head *qe;
775 list_for_each(qe, &port->rport_q) {
776 rport = (struct bfa_fcs_rport_s *) qe;
777 if (rport->pid == pid)
781 bfa_trc(port->fcs, pid);
786 * PWWN based Lookup for a R-Port in the Port R-Port Queue
788 struct bfa_fcs_rport_s *
789 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
791 struct bfa_fcs_rport_s *rport;
792 struct list_head *qe;
794 list_for_each(qe, &port->rport_q) {
795 rport = (struct bfa_fcs_rport_s *) qe;
796 if (wwn_is_equal(rport->pwwn, pwwn))
800 bfa_trc(port->fcs, pwwn);
805 * NWWN based Lookup for a R-Port in the Port R-Port Queue
807 struct bfa_fcs_rport_s *
808 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
810 struct bfa_fcs_rport_s *rport;
811 struct list_head *qe;
813 list_for_each(qe, &port->rport_q) {
814 rport = (struct bfa_fcs_rport_s *) qe;
815 if (wwn_is_equal(rport->nwwn, nwwn))
819 bfa_trc(port->fcs, nwwn);
824 * Called by rport module when new rports are discovered.
827 bfa_fcs_lport_add_rport(
828 struct bfa_fcs_lport_s *port,
829 struct bfa_fcs_rport_s *rport)
831 list_add_tail(&rport->qe, &port->rport_q);
836 * Called by rport module to when rports are deleted.
839 bfa_fcs_lport_del_rport(
840 struct bfa_fcs_lport_s *port,
841 struct bfa_fcs_rport_s *rport)
843 WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
844 list_del(&rport->qe);
847 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
851 * Called by fabric for base port when fabric login is complete.
852 * Called by vport for virtual ports when FDISC is complete.
855 bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
857 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
861 * Called by fabric for base port when fabric goes offline.
862 * Called by vport for virtual ports when virtual port becomes offline.
865 bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
867 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
871 * Called by fabric to delete base lport and associated resources.
873 * Called by vport to delete lport and associated resources. Should call
874 * bfa_fcs_vport_delete_comp() for vports on completion.
877 bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
879 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
883 * Return TRUE if port is online, else return FALSE
886 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
888 return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
892 * Attach time initialization of logical ports.
895 bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
896 u16 vf_id, struct bfa_fcs_vport_s *vport)
899 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
900 lport->vport = vport;
901 lport->lp_tag = (vport) ? vport->lps->bfa_tag :
902 lport->fabric->lps->bfa_tag;
904 INIT_LIST_HEAD(&lport->rport_q);
905 lport->num_rports = 0;
909 * Logical port initialization of base or virtual port.
910 * Called by fabric for base port or by vport for virtual ports.
914 bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
915 struct bfa_lport_cfg_s *port_cfg)
917 struct bfa_fcs_vport_s *vport = lport->vport;
918 struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
919 char lpwwn_buf[BFA_STRING_32];
921 lport->port_cfg = *port_cfg;
923 lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
924 lport->port_cfg.roles,
925 lport->fabric->vf_drv,
926 vport ? vport->vport_drv : NULL);
928 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
929 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
930 "New logical port created: WWN = %s Role = %s\n",
931 lpwwn_buf, "Initiator");
933 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
934 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
942 bfa_fcs_lport_get_attr(
943 struct bfa_fcs_lport_s *port,
944 struct bfa_lport_attr_s *port_attr)
946 if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
947 port_attr->pid = port->pid;
951 port_attr->port_cfg = port->port_cfg;
954 port_attr->port_type = port->fabric->oper_type;
955 port_attr->loopback = bfa_sm_cmp_state(port->fabric,
956 bfa_fcs_fabric_sm_loopback);
957 port_attr->authfail =
958 bfa_sm_cmp_state(port->fabric,
959 bfa_fcs_fabric_sm_auth_failed);
960 port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port);
961 memcpy(port_attr->fabric_ip_addr,
962 bfa_fcs_lport_get_fabric_ipaddr(port),
963 BFA_FCS_FABRIC_IPADDR_SZ);
965 if (port->vport != NULL) {
966 port_attr->port_type = BFA_PORT_TYPE_VPORT;
967 port_attr->fpma_mac =
968 port->vport->lps->lp_mac;
970 port_attr->fpma_mac =
971 port->fabric->lps->lp_mac;
974 port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
975 port_attr->state = BFA_LPORT_UNINIT;
980 * bfa_fcs_lport_fab port fab functions
984 * Called by port to initialize fabric services of the base port.
987 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
989 bfa_fcs_lport_ns_init(port);
990 bfa_fcs_lport_scn_init(port);
991 bfa_fcs_lport_ms_init(port);
995 * Called by port to notify transition to online state.
998 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1000 bfa_fcs_lport_ns_online(port);
1001 bfa_fcs_lport_scn_online(port);
1005 * Called by port to notify transition to offline state.
1008 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1010 bfa_fcs_lport_ns_offline(port);
1011 bfa_fcs_lport_scn_offline(port);
1012 bfa_fcs_lport_ms_offline(port);
1016 * bfa_fcs_lport_n2n functions
1020 * Called by fcs/port to initialize N2N topology.
1023 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1028 * Called by fcs/port to notify transition to online state.
1031 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1033 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1034 struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1035 struct bfa_fcs_rport_s *rport;
1037 bfa_trc(port->fcs, pcfg->pwwn);
1040 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1041 * and assign an Address. if not, we need to wait for its PLOGI.
1043 * If our PWWN is < than that of the remote port, it will send a PLOGI
1044 * with the PIDs assigned. The rport state machine take care of this
1048 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1049 sizeof(wwn_t)) > 0) {
1050 port->pid = N2N_LOCAL_PID;
1051 bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
1053 * First, check if we know the device by pwwn.
1055 rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1056 n2n_port->rem_port_wwn);
1058 bfa_trc(port->fcs, rport->pid);
1059 bfa_trc(port->fcs, rport->pwwn);
1060 rport->pid = N2N_REMOTE_PID;
1061 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1066 * In n2n there can be only one rport. Delete the old one
1067 * whose pid should be zero, because it is offline.
1069 if (port->num_rports > 0) {
1070 rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1071 WARN_ON(rport == NULL);
1073 bfa_trc(port->fcs, rport->pwwn);
1074 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1077 bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1082 * Called by fcs/port to notify transition to offline state.
1085 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1087 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1089 bfa_trc(port->fcs, port->pid);
1091 n2n_port->rem_port_wwn = 0;
1092 n2n_port->reply_oxid = 0;
1095 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1098 * forward declarations
1100 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1101 struct bfa_fcxp_s *fcxp_alloced);
1102 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1103 struct bfa_fcxp_s *fcxp_alloced);
1104 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1105 struct bfa_fcxp_s *fcxp_alloced);
1106 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1107 struct bfa_fcxp_s *fcxp,
1109 bfa_status_t req_status,
1112 struct fchs_s *rsp_fchs);
1113 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1114 struct bfa_fcxp_s *fcxp,
1116 bfa_status_t req_status,
1119 struct fchs_s *rsp_fchs);
1120 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1121 struct bfa_fcxp_s *fcxp,
1123 bfa_status_t req_status,
1126 struct fchs_s *rsp_fchs);
1127 static void bfa_fcs_lport_fdmi_timeout(void *arg);
1128 static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1130 static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1132 static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1134 static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1136 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1137 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1138 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1139 struct bfa_fcs_fdmi_port_attr_s *port_attr);
1141 * fcs_fdmi_sm FCS FDMI state machine
1145 * FDMI State Machine events
1147 enum port_fdmi_event {
1148 FDMISM_EVENT_PORT_ONLINE = 1,
1149 FDMISM_EVENT_PORT_OFFLINE = 2,
1150 FDMISM_EVENT_RSP_OK = 4,
1151 FDMISM_EVENT_RSP_ERROR = 5,
1152 FDMISM_EVENT_TIMEOUT = 6,
1153 FDMISM_EVENT_RHBA_SENT = 7,
1154 FDMISM_EVENT_RPRT_SENT = 8,
1155 FDMISM_EVENT_RPA_SENT = 9,
1158 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1159 enum port_fdmi_event event);
1160 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1161 struct bfa_fcs_lport_fdmi_s *fdmi,
1162 enum port_fdmi_event event);
1163 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1164 enum port_fdmi_event event);
1165 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1166 struct bfa_fcs_lport_fdmi_s *fdmi,
1167 enum port_fdmi_event event);
1168 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1169 struct bfa_fcs_lport_fdmi_s *fdmi,
1170 enum port_fdmi_event event);
1171 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1172 enum port_fdmi_event event);
1173 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1174 struct bfa_fcs_lport_fdmi_s *fdmi,
1175 enum port_fdmi_event event);
1176 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1177 struct bfa_fcs_lport_fdmi_s *fdmi,
1178 enum port_fdmi_event event);
1179 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1180 enum port_fdmi_event event);
1181 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1182 struct bfa_fcs_lport_fdmi_s *fdmi,
1183 enum port_fdmi_event event);
1184 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1185 enum port_fdmi_event event);
1186 static void bfa_fcs_lport_fdmi_sm_disabled(
1187 struct bfa_fcs_lport_fdmi_s *fdmi,
1188 enum port_fdmi_event event);
1190 * Start in offline state - awaiting MS to send start.
1193 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1194 enum port_fdmi_event event)
1196 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1198 bfa_trc(port->fcs, port->port_cfg.pwwn);
1199 bfa_trc(port->fcs, event);
1201 fdmi->retry_cnt = 0;
1204 case FDMISM_EVENT_PORT_ONLINE:
1207 * For Vports, register a new port.
1209 bfa_sm_set_state(fdmi,
1210 bfa_fcs_lport_fdmi_sm_sending_rprt);
1211 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1214 * For a base port, we should first register the HBA
1215 * attribute. The HBA attribute also contains the base
1216 * port registration.
1218 bfa_sm_set_state(fdmi,
1219 bfa_fcs_lport_fdmi_sm_sending_rhba);
1220 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1224 case FDMISM_EVENT_PORT_OFFLINE:
1228 bfa_sm_fault(port->fcs, event);
1233 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1234 enum port_fdmi_event event)
1236 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1238 bfa_trc(port->fcs, port->port_cfg.pwwn);
1239 bfa_trc(port->fcs, event);
1242 case FDMISM_EVENT_RHBA_SENT:
1243 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1246 case FDMISM_EVENT_PORT_OFFLINE:
1247 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1248 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1253 bfa_sm_fault(port->fcs, event);
1258 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1259 enum port_fdmi_event event)
1261 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1263 bfa_trc(port->fcs, port->port_cfg.pwwn);
1264 bfa_trc(port->fcs, event);
1267 case FDMISM_EVENT_RSP_ERROR:
1269 * if max retries have not been reached, start timer for a
1272 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1273 bfa_sm_set_state(fdmi,
1274 bfa_fcs_lport_fdmi_sm_rhba_retry);
1275 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1277 bfa_fcs_lport_fdmi_timeout, fdmi,
1278 BFA_FCS_RETRY_TIMEOUT);
1281 * set state to offline
1283 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1287 case FDMISM_EVENT_RSP_OK:
1289 * Initiate Register Port Attributes
1291 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1292 fdmi->retry_cnt = 0;
1293 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1296 case FDMISM_EVENT_PORT_OFFLINE:
1297 bfa_fcxp_discard(fdmi->fcxp);
1298 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1302 bfa_sm_fault(port->fcs, event);
1307 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1308 enum port_fdmi_event event)
1310 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1312 bfa_trc(port->fcs, port->port_cfg.pwwn);
1313 bfa_trc(port->fcs, event);
1316 case FDMISM_EVENT_TIMEOUT:
1318 * Retry Timer Expired. Re-send
1320 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1321 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1324 case FDMISM_EVENT_PORT_OFFLINE:
1325 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1326 bfa_timer_stop(&fdmi->timer);
1330 bfa_sm_fault(port->fcs, event);
1335 * RPRT : Register Port
1338 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1339 enum port_fdmi_event event)
1341 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1343 bfa_trc(port->fcs, port->port_cfg.pwwn);
1344 bfa_trc(port->fcs, event);
1347 case FDMISM_EVENT_RPRT_SENT:
1348 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1351 case FDMISM_EVENT_PORT_OFFLINE:
1352 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1353 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1358 bfa_sm_fault(port->fcs, event);
1363 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1364 enum port_fdmi_event event)
1366 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1368 bfa_trc(port->fcs, port->port_cfg.pwwn);
1369 bfa_trc(port->fcs, event);
1372 case FDMISM_EVENT_RSP_ERROR:
1374 * if max retries have not been reached, start timer for a
1377 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1378 bfa_sm_set_state(fdmi,
1379 bfa_fcs_lport_fdmi_sm_rprt_retry);
1380 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1382 bfa_fcs_lport_fdmi_timeout, fdmi,
1383 BFA_FCS_RETRY_TIMEOUT);
1387 * set state to offline
1389 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1390 fdmi->retry_cnt = 0;
1394 case FDMISM_EVENT_RSP_OK:
1395 fdmi->retry_cnt = 0;
1396 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1399 case FDMISM_EVENT_PORT_OFFLINE:
1400 bfa_fcxp_discard(fdmi->fcxp);
1401 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1405 bfa_sm_fault(port->fcs, event);
1410 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1411 enum port_fdmi_event event)
1413 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1415 bfa_trc(port->fcs, port->port_cfg.pwwn);
1416 bfa_trc(port->fcs, event);
1419 case FDMISM_EVENT_TIMEOUT:
1421 * Retry Timer Expired. Re-send
1423 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1424 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1427 case FDMISM_EVENT_PORT_OFFLINE:
1428 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1429 bfa_timer_stop(&fdmi->timer);
1433 bfa_sm_fault(port->fcs, event);
1438 * Register Port Attributes
1441 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1442 enum port_fdmi_event event)
1444 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1446 bfa_trc(port->fcs, port->port_cfg.pwwn);
1447 bfa_trc(port->fcs, event);
1450 case FDMISM_EVENT_RPA_SENT:
1451 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1454 case FDMISM_EVENT_PORT_OFFLINE:
1455 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1456 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1461 bfa_sm_fault(port->fcs, event);
1466 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1467 enum port_fdmi_event event)
1469 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1471 bfa_trc(port->fcs, port->port_cfg.pwwn);
1472 bfa_trc(port->fcs, event);
1475 case FDMISM_EVENT_RSP_ERROR:
1477 * if max retries have not been reached, start timer for a
1480 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1481 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1482 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1484 bfa_fcs_lport_fdmi_timeout, fdmi,
1485 BFA_FCS_RETRY_TIMEOUT);
1488 * set state to offline
1490 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1491 fdmi->retry_cnt = 0;
1495 case FDMISM_EVENT_RSP_OK:
1496 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1497 fdmi->retry_cnt = 0;
1500 case FDMISM_EVENT_PORT_OFFLINE:
1501 bfa_fcxp_discard(fdmi->fcxp);
1502 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1506 bfa_sm_fault(port->fcs, event);
1511 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1512 enum port_fdmi_event event)
1514 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1516 bfa_trc(port->fcs, port->port_cfg.pwwn);
1517 bfa_trc(port->fcs, event);
1520 case FDMISM_EVENT_TIMEOUT:
1522 * Retry Timer Expired. Re-send
1524 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1525 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1528 case FDMISM_EVENT_PORT_OFFLINE:
1529 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1530 bfa_timer_stop(&fdmi->timer);
1534 bfa_sm_fault(port->fcs, event);
1539 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1540 enum port_fdmi_event event)
1542 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1544 bfa_trc(port->fcs, port->port_cfg.pwwn);
1545 bfa_trc(port->fcs, event);
1548 case FDMISM_EVENT_PORT_OFFLINE:
1549 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1553 bfa_sm_fault(port->fcs, event);
1557 * FDMI is disabled state.
1560 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1561 enum port_fdmi_event event)
1563 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1565 bfa_trc(port->fcs, port->port_cfg.pwwn);
1566 bfa_trc(port->fcs, event);
1568 /* No op State. It can only be enabled at Driver Init. */
1572 * RHBA : Register HBA Attributes.
1575 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1577 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1578 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1581 struct bfa_fcxp_s *fcxp;
1584 bfa_trc(port->fcs, port->port_cfg.pwwn);
1586 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1588 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1589 bfa_fcs_lport_fdmi_send_rhba, fdmi);
1594 pyld = bfa_fcxp_get_reqbuf(fcxp);
1595 memset(pyld, 0, FC_MAX_PDUSZ);
1597 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1601 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1602 (u8 *) ((struct ct_hdr_s *) pyld
1605 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1606 FC_CLASS_3, (len + attr_len), &fchs,
1607 bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1608 FC_MAX_PDUSZ, FC_FCCT_TOV);
1610 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1614 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1616 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1617 struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1618 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1619 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1620 struct fdmi_attr_s *attr;
1626 * get hba attributes
1628 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1630 rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1631 rhba->port_list.num_ports = cpu_to_be32(1);
1632 rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1634 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1637 len += sizeof(rhba->hba_attr_blk.attr_count);
1640 * fill out the invididual entries of the HBA attrib Block
1642 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1647 attr = (struct fdmi_attr_s *) curr_ptr;
1648 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
1649 templen = sizeof(wwn_t);
1650 memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
1651 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1654 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1660 attr = (struct fdmi_attr_s *) curr_ptr;
1661 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
1662 templen = (u16) strlen(fcs_hba_attr->manufacturer);
1663 memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
1664 templen = fc_roundup(templen, sizeof(u32));
1665 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1668 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1674 attr = (struct fdmi_attr_s *) curr_ptr;
1675 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
1676 templen = (u16) strlen(fcs_hba_attr->serial_num);
1677 memcpy(attr->value, fcs_hba_attr->serial_num, templen);
1678 templen = fc_roundup(templen, sizeof(u32));
1679 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1682 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1688 attr = (struct fdmi_attr_s *) curr_ptr;
1689 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
1690 templen = (u16) strlen(fcs_hba_attr->model);
1691 memcpy(attr->value, fcs_hba_attr->model, templen);
1692 templen = fc_roundup(templen, sizeof(u32));
1693 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1696 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1702 attr = (struct fdmi_attr_s *) curr_ptr;
1703 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
1704 templen = (u16) strlen(fcs_hba_attr->model_desc);
1705 memcpy(attr->value, fcs_hba_attr->model_desc, templen);
1706 templen = fc_roundup(templen, sizeof(u32));
1707 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1710 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1716 if (fcs_hba_attr->hw_version[0] != '\0') {
1717 attr = (struct fdmi_attr_s *) curr_ptr;
1718 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
1719 templen = (u16) strlen(fcs_hba_attr->hw_version);
1720 memcpy(attr->value, fcs_hba_attr->hw_version, templen);
1721 templen = fc_roundup(templen, sizeof(u32));
1722 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1725 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1732 attr = (struct fdmi_attr_s *) curr_ptr;
1733 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
1734 templen = (u16) strlen(fcs_hba_attr->driver_version);
1735 memcpy(attr->value, fcs_hba_attr->driver_version, templen);
1736 templen = fc_roundup(templen, sizeof(u32));
1737 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1740 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1744 * Option Rom Version
1746 if (fcs_hba_attr->option_rom_ver[0] != '\0') {
1747 attr = (struct fdmi_attr_s *) curr_ptr;
1748 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
1749 templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
1750 memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
1751 templen = fc_roundup(templen, sizeof(u32));
1752 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1755 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1760 * f/w Version = driver version
1762 attr = (struct fdmi_attr_s *) curr_ptr;
1763 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
1764 templen = (u16) strlen(fcs_hba_attr->driver_version);
1765 memcpy(attr->value, fcs_hba_attr->driver_version, templen);
1766 templen = fc_roundup(templen, sizeof(u32));
1767 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1770 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1776 if (fcs_hba_attr->os_name[0] != '\0') {
1777 attr = (struct fdmi_attr_s *) curr_ptr;
1778 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
1779 templen = (u16) strlen(fcs_hba_attr->os_name);
1780 memcpy(attr->value, fcs_hba_attr->os_name, templen);
1781 templen = fc_roundup(templen, sizeof(u32));
1782 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1785 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1792 attr = (struct fdmi_attr_s *) curr_ptr;
1793 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
1794 templen = sizeof(fcs_hba_attr->max_ct_pyld);
1795 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
1798 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1802 * Update size of payload
1804 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
1806 rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
1811 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1812 void *cbarg, bfa_status_t req_status,
1813 u32 rsp_len, u32 resid_len,
1814 struct fchs_s *rsp_fchs)
1816 struct bfa_fcs_lport_fdmi_s *fdmi =
1817 (struct bfa_fcs_lport_fdmi_s *) cbarg;
1818 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1819 struct ct_hdr_s *cthdr = NULL;
1821 bfa_trc(port->fcs, port->port_cfg.pwwn);
1826 if (req_status != BFA_STATUS_OK) {
1827 bfa_trc(port->fcs, req_status);
1828 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1832 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1833 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1835 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1836 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1840 bfa_trc(port->fcs, cthdr->reason_code);
1841 bfa_trc(port->fcs, cthdr->exp_code);
1842 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1846 * RPRT : Register Port
1849 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1851 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1852 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1855 struct bfa_fcxp_s *fcxp;
1858 bfa_trc(port->fcs, port->port_cfg.pwwn);
1860 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1862 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1863 bfa_fcs_lport_fdmi_send_rprt, fdmi);
1868 pyld = bfa_fcxp_get_reqbuf(fcxp);
1869 memset(pyld, 0, FC_MAX_PDUSZ);
1871 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1875 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
1876 (u8 *) ((struct ct_hdr_s *) pyld
1879 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1880 FC_CLASS_3, len + attr_len, &fchs,
1881 bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
1882 FC_MAX_PDUSZ, FC_FCCT_TOV);
1884 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
1888 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
1891 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
1894 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
1895 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
1896 struct fdmi_attr_s *attr;
1903 * get port attributes
1905 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
1907 len = sizeof(port_attrib->attr_count);
1910 * fill out the invididual entries
1912 curr_ptr = (u8 *) &port_attrib->port_attr;
1917 attr = (struct fdmi_attr_s *) curr_ptr;
1918 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
1919 templen = sizeof(fcs_port_attr.supp_fc4_types);
1920 memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
1921 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1925 cpu_to_be16(templen + sizeof(attr->type) +
1931 attr = (struct fdmi_attr_s *) curr_ptr;
1932 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
1933 templen = sizeof(fcs_port_attr.supp_speed);
1934 memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
1935 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1939 cpu_to_be16(templen + sizeof(attr->type) +
1943 * current Port Speed
1945 attr = (struct fdmi_attr_s *) curr_ptr;
1946 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
1947 templen = sizeof(fcs_port_attr.curr_speed);
1948 memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
1949 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1952 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1958 attr = (struct fdmi_attr_s *) curr_ptr;
1959 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
1960 templen = sizeof(fcs_port_attr.max_frm_size);
1961 memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
1962 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1965 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1971 if (fcs_port_attr.os_device_name[0] != '\0') {
1972 attr = (struct fdmi_attr_s *) curr_ptr;
1973 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
1974 templen = (u16) strlen(fcs_port_attr.os_device_name);
1975 memcpy(attr->value, fcs_port_attr.os_device_name, templen);
1976 templen = fc_roundup(templen, sizeof(u32));
1977 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1980 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1986 if (fcs_port_attr.host_name[0] != '\0') {
1987 attr = (struct fdmi_attr_s *) curr_ptr;
1988 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
1989 templen = (u16) strlen(fcs_port_attr.host_name);
1990 memcpy(attr->value, fcs_port_attr.host_name, templen);
1991 templen = fc_roundup(templen, sizeof(u32));
1992 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1995 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2000 * Update size of payload
2002 port_attrib->attr_count = cpu_to_be32(count);
2003 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2008 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2010 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2011 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2014 rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2015 rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2017 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2018 (u8 *) &rprt->port_attr_blk);
2020 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2026 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2027 void *cbarg, bfa_status_t req_status,
2028 u32 rsp_len, u32 resid_len,
2029 struct fchs_s *rsp_fchs)
2031 struct bfa_fcs_lport_fdmi_s *fdmi =
2032 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2033 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2034 struct ct_hdr_s *cthdr = NULL;
2036 bfa_trc(port->fcs, port->port_cfg.pwwn);
2041 if (req_status != BFA_STATUS_OK) {
2042 bfa_trc(port->fcs, req_status);
2043 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2047 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2048 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2050 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2051 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2055 bfa_trc(port->fcs, cthdr->reason_code);
2056 bfa_trc(port->fcs, cthdr->exp_code);
2057 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2061 * RPA : Register Port Attributes.
2064 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2066 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2067 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2070 struct bfa_fcxp_s *fcxp;
2073 bfa_trc(port->fcs, port->port_cfg.pwwn);
2075 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2077 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2078 bfa_fcs_lport_fdmi_send_rpa, fdmi);
2083 pyld = bfa_fcxp_get_reqbuf(fcxp);
2084 memset(pyld, 0, FC_MAX_PDUSZ);
2086 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2089 attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
2090 (u8 *) ((struct ct_hdr_s *) pyld + 1));
2092 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2093 FC_CLASS_3, len + attr_len, &fchs,
2094 bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2095 FC_MAX_PDUSZ, FC_FCCT_TOV);
2097 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2101 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2103 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2104 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2107 rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2109 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2110 (u8 *) &rpa->port_attr_blk);
2112 len += sizeof(rpa->port_name);
2118 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2119 void *cbarg, bfa_status_t req_status, u32 rsp_len,
2120 u32 resid_len, struct fchs_s *rsp_fchs)
2122 struct bfa_fcs_lport_fdmi_s *fdmi =
2123 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2124 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2125 struct ct_hdr_s *cthdr = NULL;
2127 bfa_trc(port->fcs, port->port_cfg.pwwn);
2132 if (req_status != BFA_STATUS_OK) {
2133 bfa_trc(port->fcs, req_status);
2134 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2138 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2139 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2141 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2142 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2146 bfa_trc(port->fcs, cthdr->reason_code);
2147 bfa_trc(port->fcs, cthdr->exp_code);
2148 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2152 bfa_fcs_lport_fdmi_timeout(void *arg)
2154 struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2156 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2160 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2161 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2163 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2164 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2166 memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2168 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2169 hba_attr->manufacturer);
2170 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2171 hba_attr->serial_num);
2172 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2174 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2175 hba_attr->model_desc);
2176 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2177 hba_attr->hw_version);
2178 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2179 hba_attr->option_rom_ver);
2180 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2181 hba_attr->fw_version);
2183 strncpy(hba_attr->driver_version, (char *)driver_info->version,
2184 sizeof(hba_attr->driver_version));
2186 strncpy(hba_attr->os_name, driver_info->host_os_name,
2187 sizeof(hba_attr->os_name));
2190 * If there is a patch level, append it
2191 * to the os name along with a separator
2193 if (driver_info->host_os_patch[0] != '\0') {
2194 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2195 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
2196 strncat(hba_attr->os_name, driver_info->host_os_patch,
2197 sizeof(driver_info->host_os_patch));
2200 hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
2204 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2205 struct bfa_fcs_fdmi_port_attr_s *port_attr)
2207 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2208 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2209 struct bfa_port_attr_s pport_attr;
2211 memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2214 * get pport attributes from hal
2216 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2219 * get FC4 type Bitmask
2221 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2226 port_attr->supp_speed = cpu_to_be32(BFA_FCS_FDMI_SUPORTED_SPEEDS);
2231 port_attr->curr_speed = cpu_to_be32(pport_attr.speed);
2236 port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
2241 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2242 sizeof(port_attr->os_device_name));
2247 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2248 sizeof(port_attr->host_name));
2254 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2256 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2259 if (ms->port->fcs->fdmi_enabled)
2260 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2262 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2266 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2268 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2271 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2275 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2277 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2280 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2283 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2286 * forward declarations
2288 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2289 struct bfa_fcxp_s *fcxp_alloced);
2290 static void bfa_fcs_lport_ms_timeout(void *arg);
2291 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2292 struct bfa_fcxp_s *fcxp,
2294 bfa_status_t req_status,
2297 struct fchs_s *rsp_fchs);
2299 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2300 struct bfa_fcxp_s *fcxp_alloced);
2301 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2302 struct bfa_fcxp_s *fcxp,
2304 bfa_status_t req_status,
2307 struct fchs_s *rsp_fchs);
2308 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2309 struct bfa_fcxp_s *fcxp_alloced);
2310 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2311 struct bfa_fcxp_s *fcxp,
2313 bfa_status_t req_status,
2316 struct fchs_s *rsp_fchs);
2318 * fcs_ms_sm FCS MS state machine
2322 * MS State Machine events
2324 enum port_ms_event {
2325 MSSM_EVENT_PORT_ONLINE = 1,
2326 MSSM_EVENT_PORT_OFFLINE = 2,
2327 MSSM_EVENT_RSP_OK = 3,
2328 MSSM_EVENT_RSP_ERROR = 4,
2329 MSSM_EVENT_TIMEOUT = 5,
2330 MSSM_EVENT_FCXP_SENT = 6,
2331 MSSM_EVENT_PORT_FABRIC_RSCN = 7
2334 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2335 enum port_ms_event event);
2336 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2337 enum port_ms_event event);
2338 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2339 enum port_ms_event event);
2340 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2341 enum port_ms_event event);
2342 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2343 enum port_ms_event event);
2344 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2345 enum port_ms_event event);
2346 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2347 enum port_ms_event event);
2348 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2349 enum port_ms_event event);
2350 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2351 enum port_ms_event event);
2352 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2353 enum port_ms_event event);
2354 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2355 enum port_ms_event event);
2357 * Start in offline state - awaiting NS to send start.
2360 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2361 enum port_ms_event event)
2363 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2364 bfa_trc(ms->port->fcs, event);
2367 case MSSM_EVENT_PORT_ONLINE:
2368 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2369 bfa_fcs_lport_ms_send_plogi(ms, NULL);
2372 case MSSM_EVENT_PORT_OFFLINE:
2376 bfa_sm_fault(ms->port->fcs, event);
2381 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2382 enum port_ms_event event)
2384 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2385 bfa_trc(ms->port->fcs, event);
2388 case MSSM_EVENT_FCXP_SENT:
2389 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2392 case MSSM_EVENT_PORT_OFFLINE:
2393 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2394 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2399 bfa_sm_fault(ms->port->fcs, event);
2404 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2405 enum port_ms_event event)
2407 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2408 bfa_trc(ms->port->fcs, event);
2411 case MSSM_EVENT_RSP_ERROR:
2413 * Start timer for a delayed retry
2415 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2416 ms->port->stats.ms_retries++;
2417 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2418 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2419 BFA_FCS_RETRY_TIMEOUT);
2422 case MSSM_EVENT_RSP_OK:
2424 * since plogi is done, now invoke MS related sub-modules
2426 bfa_fcs_lport_fdmi_online(ms);
2429 * if this is a Vport, go to online state.
2431 if (ms->port->vport) {
2432 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2437 * For a base port we need to get the
2438 * switch's IP address.
2440 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2441 bfa_fcs_lport_ms_send_gmal(ms, NULL);
2444 case MSSM_EVENT_PORT_OFFLINE:
2445 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2446 bfa_fcxp_discard(ms->fcxp);
2450 bfa_sm_fault(ms->port->fcs, event);
2455 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2456 enum port_ms_event event)
2458 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2459 bfa_trc(ms->port->fcs, event);
2462 case MSSM_EVENT_TIMEOUT:
2464 * Retry Timer Expired. Re-send
2466 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2467 bfa_fcs_lport_ms_send_plogi(ms, NULL);
2470 case MSSM_EVENT_PORT_OFFLINE:
2471 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2472 bfa_timer_stop(&ms->timer);
2476 bfa_sm_fault(ms->port->fcs, event);
2481 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2482 enum port_ms_event event)
2484 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2485 bfa_trc(ms->port->fcs, event);
2488 case MSSM_EVENT_PORT_OFFLINE:
2489 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2492 case MSSM_EVENT_PORT_FABRIC_RSCN:
2493 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2495 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2499 bfa_sm_fault(ms->port->fcs, event);
2504 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2505 enum port_ms_event event)
2507 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2508 bfa_trc(ms->port->fcs, event);
2511 case MSSM_EVENT_FCXP_SENT:
2512 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
2515 case MSSM_EVENT_PORT_OFFLINE:
2516 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2517 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2522 bfa_sm_fault(ms->port->fcs, event);
2527 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2528 enum port_ms_event event)
2530 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2531 bfa_trc(ms->port->fcs, event);
2534 case MSSM_EVENT_RSP_ERROR:
2536 * Start timer for a delayed retry
2538 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2539 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
2540 ms->port->stats.ms_retries++;
2541 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2542 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2543 BFA_FCS_RETRY_TIMEOUT);
2545 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2546 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2551 case MSSM_EVENT_RSP_OK:
2552 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2553 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2556 case MSSM_EVENT_PORT_OFFLINE:
2557 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2558 bfa_fcxp_discard(ms->fcxp);
2562 bfa_sm_fault(ms->port->fcs, event);
2567 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2568 enum port_ms_event event)
2570 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2571 bfa_trc(ms->port->fcs, event);
2574 case MSSM_EVENT_TIMEOUT:
2576 * Retry Timer Expired. Re-send
2578 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2579 bfa_fcs_lport_ms_send_gmal(ms, NULL);
2582 case MSSM_EVENT_PORT_OFFLINE:
2583 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2584 bfa_timer_stop(&ms->timer);
2588 bfa_sm_fault(ms->port->fcs, event);
2592 * ms_pvt MS local functions
2596 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2598 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2599 bfa_fcs_lport_t *port = ms->port;
2602 struct bfa_fcxp_s *fcxp;
2604 bfa_trc(port->fcs, port->pid);
2606 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2608 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2609 bfa_fcs_lport_ms_send_gmal, ms);
2614 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2615 bfa_fcs_lport_get_fcid(port),
2616 port->fabric->lps->pr_nwwn);
2618 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2619 FC_CLASS_3, len, &fchs,
2620 bfa_fcs_lport_ms_gmal_response, (void *)ms,
2621 FC_MAX_PDUSZ, FC_FCCT_TOV);
2623 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2627 bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2628 void *cbarg, bfa_status_t req_status,
2629 u32 rsp_len, u32 resid_len,
2630 struct fchs_s *rsp_fchs)
2632 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2633 bfa_fcs_lport_t *port = ms->port;
2634 struct ct_hdr_s *cthdr = NULL;
2635 struct fcgs_gmal_resp_s *gmal_resp;
2636 struct fcgs_gmal_entry_s *gmal_entry;
2640 bfa_trc(port->fcs, req_status);
2641 bfa_trc(port->fcs, port->port_cfg.pwwn);
2646 if (req_status != BFA_STATUS_OK) {
2647 bfa_trc(port->fcs, req_status);
2648 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2652 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2653 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2655 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2656 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
2658 num_entries = be32_to_cpu(gmal_resp->ms_len);
2659 if (num_entries == 0) {
2660 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2664 * The response could contain multiple Entries.
2665 * Entries for SNMP interface, etc.
2666 * We look for the entry with a telnet prefix.
2667 * First "http://" entry refers to IP addr
2670 gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
2671 while (num_entries > 0) {
2672 if (strncmp(gmal_entry->prefix,
2673 CT_GMAL_RESP_PREFIX_HTTP,
2674 sizeof(gmal_entry->prefix)) == 0) {
2677 * if the IP address is terminating with a '/',
2679 * Byte 0 consists of the length of the string.
2681 rsp_str = &(gmal_entry->prefix[0]);
2682 if (rsp_str[gmal_entry->len-1] == '/')
2683 rsp_str[gmal_entry->len-1] = 0;
2685 /* copy IP Address to fabric */
2686 strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
2687 gmal_entry->ip_addr,
2688 BFA_FCS_FABRIC_IPADDR_SZ);
2696 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2700 bfa_trc(port->fcs, cthdr->reason_code);
2701 bfa_trc(port->fcs, cthdr->exp_code);
2702 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2706 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2707 enum port_ms_event event)
2709 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2710 bfa_trc(ms->port->fcs, event);
2713 case MSSM_EVENT_FCXP_SENT:
2714 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
2717 case MSSM_EVENT_PORT_OFFLINE:
2718 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2719 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2724 bfa_sm_fault(ms->port->fcs, event);
2729 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2730 enum port_ms_event event)
2732 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2733 bfa_trc(ms->port->fcs, event);
2736 case MSSM_EVENT_RSP_ERROR:
2738 * Start timer for a delayed retry
2740 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2741 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
2742 ms->port->stats.ms_retries++;
2743 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2744 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2745 BFA_FCS_RETRY_TIMEOUT);
2747 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2752 case MSSM_EVENT_RSP_OK:
2753 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2756 case MSSM_EVENT_PORT_OFFLINE:
2757 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2758 bfa_fcxp_discard(ms->fcxp);
2762 bfa_sm_fault(ms->port->fcs, event);
2767 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2768 enum port_ms_event event)
2770 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2771 bfa_trc(ms->port->fcs, event);
2774 case MSSM_EVENT_TIMEOUT:
2776 * Retry Timer Expired. Re-send
2778 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2779 bfa_fcs_lport_ms_send_gfn(ms, NULL);
2782 case MSSM_EVENT_PORT_OFFLINE:
2783 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2784 bfa_timer_stop(&ms->timer);
2788 bfa_sm_fault(ms->port->fcs, event);
2792 * ms_pvt MS local functions
2796 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2798 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2799 bfa_fcs_lport_t *port = ms->port;
2802 struct bfa_fcxp_s *fcxp;
2804 bfa_trc(port->fcs, port->pid);
2806 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2808 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2809 bfa_fcs_lport_ms_send_gfn, ms);
2814 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2815 bfa_fcs_lport_get_fcid(port),
2816 port->fabric->lps->pr_nwwn);
2818 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2819 FC_CLASS_3, len, &fchs,
2820 bfa_fcs_lport_ms_gfn_response, (void *)ms,
2821 FC_MAX_PDUSZ, FC_FCCT_TOV);
2823 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2827 bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2828 void *cbarg, bfa_status_t req_status, u32 rsp_len,
2829 u32 resid_len, struct fchs_s *rsp_fchs)
2831 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2832 bfa_fcs_lport_t *port = ms->port;
2833 struct ct_hdr_s *cthdr = NULL;
2836 bfa_trc(port->fcs, req_status);
2837 bfa_trc(port->fcs, port->port_cfg.pwwn);
2842 if (req_status != BFA_STATUS_OK) {
2843 bfa_trc(port->fcs, req_status);
2844 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2848 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2849 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2851 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2852 gfn_resp = (wwn_t *)(cthdr + 1);
2853 /* check if it has actually changed */
2854 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
2855 gfn_resp, sizeof(wwn_t)) != 0)) {
2856 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
2858 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2862 bfa_trc(port->fcs, cthdr->reason_code);
2863 bfa_trc(port->fcs, cthdr->exp_code);
2864 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2868 * ms_pvt MS local functions
2872 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2874 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2875 struct bfa_fcs_lport_s *port = ms->port;
2878 struct bfa_fcxp_s *fcxp;
2880 bfa_trc(port->fcs, port->pid);
2882 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2884 port->stats.ms_plogi_alloc_wait++;
2885 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2886 bfa_fcs_lport_ms_send_plogi, ms);
2891 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2892 bfa_hton3b(FC_MGMT_SERVER),
2893 bfa_fcs_lport_get_fcid(port), 0,
2894 port->port_cfg.pwwn, port->port_cfg.nwwn,
2895 bfa_fcport_get_maxfrsize(port->fcs->bfa),
2896 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
2898 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2899 FC_CLASS_3, len, &fchs,
2900 bfa_fcs_lport_ms_plogi_response, (void *)ms,
2901 FC_MAX_PDUSZ, FC_ELS_TOV);
2903 port->stats.ms_plogi_sent++;
2904 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2908 bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2909 void *cbarg, bfa_status_t req_status,
2910 u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
2912 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2913 struct bfa_fcs_lport_s *port = ms->port;
2914 struct fc_els_cmd_s *els_cmd;
2915 struct fc_ls_rjt_s *ls_rjt;
2917 bfa_trc(port->fcs, req_status);
2918 bfa_trc(port->fcs, port->port_cfg.pwwn);
2923 if (req_status != BFA_STATUS_OK) {
2924 port->stats.ms_plogi_rsp_err++;
2925 bfa_trc(port->fcs, req_status);
2926 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2930 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
2932 switch (els_cmd->els_code) {
2935 if (rsp_len < sizeof(struct fc_logi_s)) {
2936 bfa_trc(port->fcs, rsp_len);
2937 port->stats.ms_plogi_acc_err++;
2938 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2941 port->stats.ms_plogi_accepts++;
2942 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2946 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
2948 bfa_trc(port->fcs, ls_rjt->reason_code);
2949 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
2951 port->stats.ms_rejects++;
2952 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2956 port->stats.ms_plogi_unknown_rsp++;
2957 bfa_trc(port->fcs, els_cmd->els_code);
2958 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2963 bfa_fcs_lport_ms_timeout(void *arg)
2965 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
2967 ms->port->stats.ms_timeouts++;
2968 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
2973 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
2975 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
2978 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2981 * Invoke init routines of sub modules.
2983 bfa_fcs_lport_fdmi_init(ms);
2987 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
2989 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
2992 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
2993 bfa_fcs_lport_fdmi_offline(ms);
2997 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
2999 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3002 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3005 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3007 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3009 /* todo. Handle this only when in Online state */
3010 if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3011 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3015 * @page ns_sm_info VPORT NS State Machine
3017 * @section ns_sm_interactions VPORT NS State Machine Interactions
3019 * @section ns_sm VPORT NS State Machine
3024 * forward declarations
3026 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3027 struct bfa_fcxp_s *fcxp_alloced);
3028 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3029 struct bfa_fcxp_s *fcxp_alloced);
3030 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3031 struct bfa_fcxp_s *fcxp_alloced);
3032 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3033 struct bfa_fcxp_s *fcxp_alloced);
3034 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3035 struct bfa_fcxp_s *fcxp_alloced);
3036 static void bfa_fcs_lport_ns_timeout(void *arg);
3037 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3038 struct bfa_fcxp_s *fcxp,
3040 bfa_status_t req_status,
3043 struct fchs_s *rsp_fchs);
3044 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3045 struct bfa_fcxp_s *fcxp,
3047 bfa_status_t req_status,
3050 struct fchs_s *rsp_fchs);
3051 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3052 struct bfa_fcxp_s *fcxp,
3054 bfa_status_t req_status,
3057 struct fchs_s *rsp_fchs);
3058 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3059 struct bfa_fcxp_s *fcxp,
3061 bfa_status_t req_status,
3064 struct fchs_s *rsp_fchs);
3065 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3066 struct bfa_fcxp_s *fcxp,
3068 bfa_status_t req_status,
3071 struct fchs_s *rsp_fchs);
3072 static void bfa_fcs_lport_ns_process_gidft_pids(
3073 struct bfa_fcs_lport_s *port,
3074 u32 *pid_buf, u32 n_pids);
3076 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
3078 * fcs_ns_sm FCS nameserver interface state machine
3082 * VPort NS State Machine events
3084 enum vport_ns_event {
3085 NSSM_EVENT_PORT_ONLINE = 1,
3086 NSSM_EVENT_PORT_OFFLINE = 2,
3087 NSSM_EVENT_PLOGI_SENT = 3,
3088 NSSM_EVENT_RSP_OK = 4,
3089 NSSM_EVENT_RSP_ERROR = 5,
3090 NSSM_EVENT_TIMEOUT = 6,
3091 NSSM_EVENT_NS_QUERY = 7,
3092 NSSM_EVENT_RSPNID_SENT = 8,
3093 NSSM_EVENT_RFTID_SENT = 9,
3094 NSSM_EVENT_RFFID_SENT = 10,
3095 NSSM_EVENT_GIDFT_SENT = 11,
3098 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3099 enum vport_ns_event event);
3100 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3101 enum vport_ns_event event);
3102 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3103 enum vport_ns_event event);
3104 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3105 enum vport_ns_event event);
3106 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3107 struct bfa_fcs_lport_ns_s *ns,
3108 enum vport_ns_event event);
3109 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3110 enum vport_ns_event event);
3111 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3112 enum vport_ns_event event);
3113 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3114 struct bfa_fcs_lport_ns_s *ns,
3115 enum vport_ns_event event);
3116 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3117 enum vport_ns_event event);
3118 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3119 enum vport_ns_event event);
3120 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3121 struct bfa_fcs_lport_ns_s *ns,
3122 enum vport_ns_event event);
3123 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3124 enum vport_ns_event event);
3125 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3126 enum vport_ns_event event);
3127 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3128 struct bfa_fcs_lport_ns_s *ns,
3129 enum vport_ns_event event);
3130 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3131 enum vport_ns_event event);
3132 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3133 enum vport_ns_event event);
3134 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3135 enum vport_ns_event event);
3137 * Start in offline state - awaiting linkup
3140 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3141 enum vport_ns_event event)
3143 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3144 bfa_trc(ns->port->fcs, event);
3147 case NSSM_EVENT_PORT_ONLINE:
3148 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3149 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3152 case NSSM_EVENT_PORT_OFFLINE:
3156 bfa_sm_fault(ns->port->fcs, event);
3161 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3162 enum vport_ns_event event)
3164 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3165 bfa_trc(ns->port->fcs, event);
3168 case NSSM_EVENT_PLOGI_SENT:
3169 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3172 case NSSM_EVENT_PORT_OFFLINE:
3173 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3174 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3179 bfa_sm_fault(ns->port->fcs, event);
3184 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3185 enum vport_ns_event event)
3187 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3188 bfa_trc(ns->port->fcs, event);
3191 case NSSM_EVENT_RSP_ERROR:
3193 * Start timer for a delayed retry
3195 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3196 ns->port->stats.ns_retries++;
3197 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3198 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3199 BFA_FCS_RETRY_TIMEOUT);
3202 case NSSM_EVENT_RSP_OK:
3203 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3204 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3207 case NSSM_EVENT_PORT_OFFLINE:
3208 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3209 bfa_fcxp_discard(ns->fcxp);
3213 bfa_sm_fault(ns->port->fcs, event);
3218 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3219 enum vport_ns_event event)
3221 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3222 bfa_trc(ns->port->fcs, event);
3225 case NSSM_EVENT_TIMEOUT:
3227 * Retry Timer Expired. Re-send
3229 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3230 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3233 case NSSM_EVENT_PORT_OFFLINE:
3234 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3235 bfa_timer_stop(&ns->timer);
3239 bfa_sm_fault(ns->port->fcs, event);
3244 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3245 enum vport_ns_event event)
3247 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3248 bfa_trc(ns->port->fcs, event);
3251 case NSSM_EVENT_RSPNID_SENT:
3252 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3255 case NSSM_EVENT_PORT_OFFLINE:
3256 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3257 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3262 bfa_sm_fault(ns->port->fcs, event);
3267 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3268 enum vport_ns_event event)
3270 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3271 bfa_trc(ns->port->fcs, event);
3274 case NSSM_EVENT_RSP_ERROR:
3276 * Start timer for a delayed retry
3278 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
3279 ns->port->stats.ns_retries++;
3280 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3281 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3282 BFA_FCS_RETRY_TIMEOUT);
3285 case NSSM_EVENT_RSP_OK:
3286 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3287 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3290 case NSSM_EVENT_PORT_OFFLINE:
3291 bfa_fcxp_discard(ns->fcxp);
3292 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3296 bfa_sm_fault(ns->port->fcs, event);
3301 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3302 enum vport_ns_event event)
3304 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3305 bfa_trc(ns->port->fcs, event);
3308 case NSSM_EVENT_TIMEOUT:
3310 * Retry Timer Expired. Re-send
3312 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3313 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3316 case NSSM_EVENT_PORT_OFFLINE:
3317 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3318 bfa_timer_stop(&ns->timer);
3322 bfa_sm_fault(ns->port->fcs, event);
3327 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
3328 enum vport_ns_event event)
3330 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3331 bfa_trc(ns->port->fcs, event);
3334 case NSSM_EVENT_RFTID_SENT:
3335 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
3338 case NSSM_EVENT_PORT_OFFLINE:
3339 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3340 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3345 bfa_sm_fault(ns->port->fcs, event);
3350 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3351 enum vport_ns_event event)
3353 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3354 bfa_trc(ns->port->fcs, event);
3357 case NSSM_EVENT_RSP_OK:
3358 /* Now move to register FC4 Features */
3359 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3360 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3363 case NSSM_EVENT_RSP_ERROR:
3365 * Start timer for a delayed retry
3367 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
3368 ns->port->stats.ns_retries++;
3369 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3370 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3371 BFA_FCS_RETRY_TIMEOUT);
3374 case NSSM_EVENT_PORT_OFFLINE:
3375 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3376 bfa_fcxp_discard(ns->fcxp);
3380 bfa_sm_fault(ns->port->fcs, event);
3385 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3386 enum vport_ns_event event)
3388 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3389 bfa_trc(ns->port->fcs, event);
3392 case NSSM_EVENT_TIMEOUT:
3393 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3394 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3397 case NSSM_EVENT_PORT_OFFLINE:
3398 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3399 bfa_timer_stop(&ns->timer);
3403 bfa_sm_fault(ns->port->fcs, event);
3408 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
3409 enum vport_ns_event event)
3411 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3412 bfa_trc(ns->port->fcs, event);
3415 case NSSM_EVENT_RFFID_SENT:
3416 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
3419 case NSSM_EVENT_PORT_OFFLINE:
3420 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3421 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3426 bfa_sm_fault(ns->port->fcs, event);
3431 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3432 enum vport_ns_event event)
3434 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3435 bfa_trc(ns->port->fcs, event);
3438 case NSSM_EVENT_RSP_OK:
3441 * If min cfg mode is enabled, we donot initiate rport
3442 * discovery with the fabric. Instead, we will retrieve the
3443 * boot targets from HAL/FW.
3445 if (__fcs_min_cfg(ns->port->fcs)) {
3446 bfa_fcs_lport_ns_boot_target_disc(ns->port);
3447 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3452 * If the port role is Initiator Mode issue NS query.
3453 * If it is Target Mode, skip this and go to online.
3455 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3456 bfa_sm_set_state(ns,
3457 bfa_fcs_lport_ns_sm_sending_gid_ft);
3458 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3461 * kick off mgmt srvr state machine
3463 bfa_fcs_lport_ms_online(ns->port);
3466 case NSSM_EVENT_RSP_ERROR:
3468 * Start timer for a delayed retry
3470 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
3471 ns->port->stats.ns_retries++;
3472 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3473 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3474 BFA_FCS_RETRY_TIMEOUT);
3477 case NSSM_EVENT_PORT_OFFLINE:
3478 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3479 bfa_fcxp_discard(ns->fcxp);
3483 bfa_sm_fault(ns->port->fcs, event);
3488 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3489 enum vport_ns_event event)
3491 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3492 bfa_trc(ns->port->fcs, event);
3495 case NSSM_EVENT_TIMEOUT:
3496 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3497 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3500 case NSSM_EVENT_PORT_OFFLINE:
3501 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3502 bfa_timer_stop(&ns->timer);
3506 bfa_sm_fault(ns->port->fcs, event);
3510 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3511 enum vport_ns_event event)
3513 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3514 bfa_trc(ns->port->fcs, event);
3517 case NSSM_EVENT_GIDFT_SENT:
3518 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
3521 case NSSM_EVENT_PORT_OFFLINE:
3522 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3523 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3528 bfa_sm_fault(ns->port->fcs, event);
3533 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3534 enum vport_ns_event event)
3536 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3537 bfa_trc(ns->port->fcs, event);
3540 case NSSM_EVENT_RSP_OK:
3541 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3544 case NSSM_EVENT_RSP_ERROR:
3546 * TBD: for certain reject codes, we don't need to retry
3549 * Start timer for a delayed retry
3551 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
3552 ns->port->stats.ns_retries++;
3553 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3554 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3555 BFA_FCS_RETRY_TIMEOUT);
3558 case NSSM_EVENT_PORT_OFFLINE:
3559 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3560 bfa_fcxp_discard(ns->fcxp);
3563 case NSSM_EVENT_NS_QUERY:
3567 bfa_sm_fault(ns->port->fcs, event);
3572 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3573 enum vport_ns_event event)
3575 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3576 bfa_trc(ns->port->fcs, event);
3579 case NSSM_EVENT_TIMEOUT:
3580 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
3581 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3584 case NSSM_EVENT_PORT_OFFLINE:
3585 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3586 bfa_timer_stop(&ns->timer);
3590 bfa_sm_fault(ns->port->fcs, event);
3595 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3596 enum vport_ns_event event)
3598 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3599 bfa_trc(ns->port->fcs, event);
3602 case NSSM_EVENT_PORT_OFFLINE:
3603 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3606 case NSSM_EVENT_NS_QUERY:
3608 * If the port role is Initiator Mode issue NS query.
3609 * If it is Target Mode, skip this and go to online.
3611 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3612 bfa_sm_set_state(ns,
3613 bfa_fcs_lport_ns_sm_sending_gid_ft);
3614 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3619 bfa_sm_fault(ns->port->fcs, event);
3626 * ns_pvt Nameserver local functions
3630 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3632 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3633 struct bfa_fcs_lport_s *port = ns->port;
3636 struct bfa_fcxp_s *fcxp;
3638 bfa_trc(port->fcs, port->pid);
3640 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3642 port->stats.ns_plogi_alloc_wait++;
3643 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3644 bfa_fcs_lport_ns_send_plogi, ns);
3649 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3650 bfa_hton3b(FC_NAME_SERVER),
3651 bfa_fcs_lport_get_fcid(port), 0,
3652 port->port_cfg.pwwn, port->port_cfg.nwwn,
3653 bfa_fcport_get_maxfrsize(port->fcs->bfa),
3654 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3656 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3657 FC_CLASS_3, len, &fchs,
3658 bfa_fcs_lport_ns_plogi_response, (void *)ns,
3659 FC_MAX_PDUSZ, FC_ELS_TOV);
3660 port->stats.ns_plogi_sent++;
3662 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
3666 bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3667 void *cbarg, bfa_status_t req_status, u32 rsp_len,
3668 u32 resid_len, struct fchs_s *rsp_fchs)
3670 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3671 struct bfa_fcs_lport_s *port = ns->port;
3672 /* struct fc_logi_s *plogi_resp; */
3673 struct fc_els_cmd_s *els_cmd;
3674 struct fc_ls_rjt_s *ls_rjt;
3676 bfa_trc(port->fcs, req_status);
3677 bfa_trc(port->fcs, port->port_cfg.pwwn);
3682 if (req_status != BFA_STATUS_OK) {
3683 bfa_trc(port->fcs, req_status);
3684 port->stats.ns_plogi_rsp_err++;
3685 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3689 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3691 switch (els_cmd->els_code) {
3694 if (rsp_len < sizeof(struct fc_logi_s)) {
3695 bfa_trc(port->fcs, rsp_len);
3696 port->stats.ns_plogi_acc_err++;
3697 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3700 port->stats.ns_plogi_accepts++;
3701 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3705 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3707 bfa_trc(port->fcs, ls_rjt->reason_code);
3708 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3710 port->stats.ns_rejects++;
3712 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3716 port->stats.ns_plogi_unknown_rsp++;
3717 bfa_trc(port->fcs, els_cmd->els_code);
3718 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3723 * Register the symbolic port name.
3726 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3728 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3729 struct bfa_fcs_lport_s *port = ns->port;
3732 struct bfa_fcxp_s *fcxp;
3734 u8 *psymbl = &symbl[0];
3736 memset(symbl, 0, sizeof(symbl));
3738 bfa_trc(port->fcs, port->port_cfg.pwwn);
3740 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3742 port->stats.ns_rspnid_alloc_wait++;
3743 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3744 bfa_fcs_lport_ns_send_rspn_id, ns);
3750 * for V-Port, form a Port Symbolic Name
3754 * For Vports, we append the vport's port symbolic name
3755 * to that of the base port.
3758 strncpy((char *)psymbl,
3760 (bfa_fcs_lport_get_psym_name
3761 (bfa_fcs_get_base_port(port->fcs))),
3763 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3766 /* Ensure we have a null terminating string. */
3767 ((char *)psymbl)[strlen((char *) &
3768 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3770 strncat((char *)psymbl,
3771 (char *) &(bfa_fcs_lport_get_psym_name(port)),
3772 strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
3774 psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
3777 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3778 bfa_fcs_lport_get_fcid(port), 0, psymbl);
3780 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3781 FC_CLASS_3, len, &fchs,
3782 bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
3783 FC_MAX_PDUSZ, FC_FCCT_TOV);
3785 port->stats.ns_rspnid_sent++;
3787 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
3791 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3792 void *cbarg, bfa_status_t req_status,
3793 u32 rsp_len, u32 resid_len,
3794 struct fchs_s *rsp_fchs)
3796 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3797 struct bfa_fcs_lport_s *port = ns->port;
3798 struct ct_hdr_s *cthdr = NULL;
3800 bfa_trc(port->fcs, port->port_cfg.pwwn);
3805 if (req_status != BFA_STATUS_OK) {
3806 bfa_trc(port->fcs, req_status);
3807 port->stats.ns_rspnid_rsp_err++;
3808 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3812 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3813 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3815 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3816 port->stats.ns_rspnid_accepts++;
3817 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3821 port->stats.ns_rspnid_rejects++;
3822 bfa_trc(port->fcs, cthdr->reason_code);
3823 bfa_trc(port->fcs, cthdr->exp_code);
3824 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3828 * Register FC4-Types
3831 bfa_fcs_lport_ns_send_rft_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 bfa_trc(port->fcs, port->port_cfg.pwwn);
3841 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3843 port->stats.ns_rftid_alloc_wait++;
3844 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3845 bfa_fcs_lport_ns_send_rft_id, ns);
3850 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3851 bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
3853 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3854 FC_CLASS_3, len, &fchs,
3855 bfa_fcs_lport_ns_rft_id_response, (void *)ns,
3856 FC_MAX_PDUSZ, FC_FCCT_TOV);
3858 port->stats.ns_rftid_sent++;
3859 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
3863 bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3864 void *cbarg, bfa_status_t req_status,
3865 u32 rsp_len, u32 resid_len,
3866 struct fchs_s *rsp_fchs)
3868 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3869 struct bfa_fcs_lport_s *port = ns->port;
3870 struct ct_hdr_s *cthdr = NULL;
3872 bfa_trc(port->fcs, port->port_cfg.pwwn);
3877 if (req_status != BFA_STATUS_OK) {
3878 bfa_trc(port->fcs, req_status);
3879 port->stats.ns_rftid_rsp_err++;
3880 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3884 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3885 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3887 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3888 port->stats.ns_rftid_accepts++;
3889 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3893 port->stats.ns_rftid_rejects++;
3894 bfa_trc(port->fcs, cthdr->reason_code);
3895 bfa_trc(port->fcs, cthdr->exp_code);
3896 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3900 * Register FC4-Features : Should be done after RFT_ID
3903 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3905 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3906 struct bfa_fcs_lport_s *port = ns->port;
3909 struct bfa_fcxp_s *fcxp;
3912 bfa_trc(port->fcs, port->port_cfg.pwwn);
3914 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3916 port->stats.ns_rffid_alloc_wait++;
3917 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3918 bfa_fcs_lport_ns_send_rff_id, ns);
3923 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
3924 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
3926 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3927 bfa_fcs_lport_get_fcid(port), 0,
3928 FC_TYPE_FCP, fc4_ftrs);
3930 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3931 FC_CLASS_3, len, &fchs,
3932 bfa_fcs_lport_ns_rff_id_response, (void *)ns,
3933 FC_MAX_PDUSZ, FC_FCCT_TOV);
3935 port->stats.ns_rffid_sent++;
3936 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
3940 bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3941 void *cbarg, bfa_status_t req_status,
3942 u32 rsp_len, u32 resid_len,
3943 struct fchs_s *rsp_fchs)
3945 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3946 struct bfa_fcs_lport_s *port = ns->port;
3947 struct ct_hdr_s *cthdr = NULL;
3949 bfa_trc(port->fcs, port->port_cfg.pwwn);
3954 if (req_status != BFA_STATUS_OK) {
3955 bfa_trc(port->fcs, req_status);
3956 port->stats.ns_rffid_rsp_err++;
3957 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3961 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3962 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3964 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3965 port->stats.ns_rffid_accepts++;
3966 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3970 port->stats.ns_rffid_rejects++;
3971 bfa_trc(port->fcs, cthdr->reason_code);
3972 bfa_trc(port->fcs, cthdr->exp_code);
3974 if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
3975 /* if this command is not supported, we don't retry */
3976 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3978 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3981 * Query Fabric for FC4-Types Devices.
3983 * TBD : Need to use a local (FCS private) response buffer, since the response
3984 * can be larger than 2K.
3987 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3989 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3990 struct bfa_fcs_lport_s *port = ns->port;
3993 struct bfa_fcxp_s *fcxp;
3995 bfa_trc(port->fcs, port->pid);
3997 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3999 port->stats.ns_gidft_alloc_wait++;
4000 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4001 bfa_fcs_lport_ns_send_gid_ft, ns);
4007 * This query is only initiated for FCP initiator mode.
4009 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4010 ns->port->pid, FC_TYPE_FCP);
4012 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4013 FC_CLASS_3, len, &fchs,
4014 bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4015 bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4017 port->stats.ns_gidft_sent++;
4019 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4023 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4024 void *cbarg, bfa_status_t req_status,
4025 u32 rsp_len, u32 resid_len,
4026 struct fchs_s *rsp_fchs)
4028 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4029 struct bfa_fcs_lport_s *port = ns->port;
4030 struct ct_hdr_s *cthdr = NULL;
4033 bfa_trc(port->fcs, port->port_cfg.pwwn);
4038 if (req_status != BFA_STATUS_OK) {
4039 bfa_trc(port->fcs, req_status);
4040 port->stats.ns_gidft_rsp_err++;
4041 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4045 if (resid_len != 0) {
4047 * TBD : we will need to allocate a larger buffer & retry the
4050 bfa_trc(port->fcs, rsp_len);
4051 bfa_trc(port->fcs, resid_len);
4055 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4056 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4058 switch (cthdr->cmd_rsp_code) {
4062 port->stats.ns_gidft_accepts++;
4063 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4064 bfa_trc(port->fcs, n_pids);
4065 bfa_fcs_lport_ns_process_gidft_pids(port,
4066 (u32 *) (cthdr + 1),
4068 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4074 * Check the reason code & explanation.
4075 * There may not have been any FC4 devices in the fabric
4077 port->stats.ns_gidft_rejects++;
4078 bfa_trc(port->fcs, cthdr->reason_code);
4079 bfa_trc(port->fcs, cthdr->exp_code);
4081 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4082 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4084 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4087 * for all other errors, retry
4089 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4094 port->stats.ns_gidft_unknown_rsp++;
4095 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4096 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4101 * This routine will be called by bfa_timer on timer timeouts.
4103 * param[in] port - pointer to bfa_fcs_lport_t.
4108 * Special Considerations:
4113 bfa_fcs_lport_ns_timeout(void *arg)
4115 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
4117 ns->port->stats.ns_timeouts++;
4118 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
4122 * Process the PID list in GID_FT response
4125 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
4128 struct fcgs_gidft_resp_s *gidft_entry;
4129 struct bfa_fcs_rport_s *rport;
4132 for (ii = 0; ii < n_pids; ii++) {
4133 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
4135 if (gidft_entry->pid == port->pid)
4139 * Check if this rport already exists
4141 rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
4142 if (rport == NULL) {
4144 * this is a new device. create rport
4146 rport = bfa_fcs_rport_create(port, gidft_entry->pid);
4149 * this rport already exists
4151 bfa_fcs_rport_scn(rport);
4154 bfa_trc(port->fcs, gidft_entry->pid);
4157 * if the last entry bit is set, bail out.
4159 if (gidft_entry->last)
4165 * fcs_ns_public FCS nameserver public interfaces
4169 * Functions called by port/fab.
4170 * These will send relevant Events to the ns state machine.
4173 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
4175 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4178 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4182 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
4184 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4187 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
4191 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
4193 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4196 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
4200 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
4202 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4204 bfa_trc(port->fcs, port->pid);
4205 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
4209 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
4212 struct bfa_fcs_rport_s *rport;
4214 wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
4217 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
4219 for (ii = 0 ; ii < nwwns; ++ii) {
4220 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
4229 #define FC_QOS_RSCN_EVENT 0x0c
4230 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
4233 * forward declarations
4235 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
4236 struct bfa_fcxp_s *fcxp_alloced);
4237 static void bfa_fcs_lport_scn_scr_response(void *fcsarg,
4238 struct bfa_fcxp_s *fcxp,
4240 bfa_status_t req_status,
4243 struct fchs_s *rsp_fchs);
4244 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4245 struct fchs_s *rx_fchs);
4246 static void bfa_fcs_lport_scn_timeout(void *arg);
4249 * fcs_scm_sm FCS SCN state machine
4253 * VPort SCN State Machine events
4255 enum port_scn_event {
4256 SCNSM_EVENT_PORT_ONLINE = 1,
4257 SCNSM_EVENT_PORT_OFFLINE = 2,
4258 SCNSM_EVENT_RSP_OK = 3,
4259 SCNSM_EVENT_RSP_ERROR = 4,
4260 SCNSM_EVENT_TIMEOUT = 5,
4261 SCNSM_EVENT_SCR_SENT = 6,
4264 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4265 enum port_scn_event event);
4266 static void bfa_fcs_lport_scn_sm_sending_scr(
4267 struct bfa_fcs_lport_scn_s *scn,
4268 enum port_scn_event event);
4269 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4270 enum port_scn_event event);
4271 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4272 enum port_scn_event event);
4273 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4274 enum port_scn_event event);
4277 * Starting state - awaiting link up.
4280 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4281 enum port_scn_event event)
4284 case SCNSM_EVENT_PORT_ONLINE:
4285 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4286 bfa_fcs_lport_scn_send_scr(scn, NULL);
4289 case SCNSM_EVENT_PORT_OFFLINE:
4293 bfa_sm_fault(scn->port->fcs, event);
4298 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
4299 enum port_scn_event event)
4302 case SCNSM_EVENT_SCR_SENT:
4303 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
4306 case SCNSM_EVENT_PORT_OFFLINE:
4307 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4308 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
4312 bfa_sm_fault(scn->port->fcs, event);
4317 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4318 enum port_scn_event event)
4320 struct bfa_fcs_lport_s *port = scn->port;
4323 case SCNSM_EVENT_RSP_OK:
4324 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
4327 case SCNSM_EVENT_RSP_ERROR:
4328 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
4329 bfa_timer_start(port->fcs->bfa, &scn->timer,
4330 bfa_fcs_lport_scn_timeout, scn,
4331 BFA_FCS_RETRY_TIMEOUT);
4334 case SCNSM_EVENT_PORT_OFFLINE:
4335 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4336 bfa_fcxp_discard(scn->fcxp);
4340 bfa_sm_fault(port->fcs, event);
4345 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4346 enum port_scn_event event)
4349 case SCNSM_EVENT_TIMEOUT:
4350 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4351 bfa_fcs_lport_scn_send_scr(scn, NULL);
4354 case SCNSM_EVENT_PORT_OFFLINE:
4355 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4356 bfa_timer_stop(&scn->timer);
4360 bfa_sm_fault(scn->port->fcs, event);
4365 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4366 enum port_scn_event event)
4369 case SCNSM_EVENT_PORT_OFFLINE:
4370 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4374 bfa_sm_fault(scn->port->fcs, event);
4381 * fcs_scn_private FCS SCN private functions
4385 * This routine will be called to send a SCR command.
4388 bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4390 struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
4391 struct bfa_fcs_lport_s *port = scn->port;
4394 struct bfa_fcxp_s *fcxp;
4396 bfa_trc(port->fcs, port->pid);
4397 bfa_trc(port->fcs, port->port_cfg.pwwn);
4399 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4401 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
4402 bfa_fcs_lport_scn_send_scr, scn);
4407 /* Handle VU registrations for Base port only */
4408 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
4409 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4410 port->fabric->lps->brcd_switch,
4413 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4418 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4419 FC_CLASS_3, len, &fchs,
4420 bfa_fcs_lport_scn_scr_response,
4421 (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
4423 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
4427 bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4428 void *cbarg, bfa_status_t req_status, u32 rsp_len,
4429 u32 resid_len, struct fchs_s *rsp_fchs)
4431 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
4432 struct bfa_fcs_lport_s *port = scn->port;
4433 struct fc_els_cmd_s *els_cmd;
4434 struct fc_ls_rjt_s *ls_rjt;
4436 bfa_trc(port->fcs, port->port_cfg.pwwn);
4441 if (req_status != BFA_STATUS_OK) {
4442 bfa_trc(port->fcs, req_status);
4443 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4447 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4449 switch (els_cmd->els_code) {
4452 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
4457 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4459 bfa_trc(port->fcs, ls_rjt->reason_code);
4460 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4462 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4466 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4474 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4475 struct fchs_s *rx_fchs)
4478 struct bfa_fcxp_s *fcxp;
4479 struct bfa_rport_s *bfa_rport = NULL;
4482 bfa_trc(port->fcs, rx_fchs->s_id);
4484 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
4488 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4489 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
4492 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
4493 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
4498 * This routine will be called by bfa_timer on timer timeouts.
4500 * param[in] vport - pointer to bfa_fcs_lport_t.
4501 * param[out] vport_status - pointer to return vport status in
4506 * Special Considerations:
4511 bfa_fcs_lport_scn_timeout(void *arg)
4513 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
4515 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
4521 * fcs_scn_public FCS state change notification public interfaces
4525 * Functions called by port/fab
4528 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
4530 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4533 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4537 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
4539 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4542 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
4546 bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
4548 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4551 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
4555 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
4557 struct bfa_fcs_rport_s *rport;
4559 bfa_trc(port->fcs, rpid);
4562 * If this is an unknown device, then it just came online.
4563 * Otherwise let rport handle the RSCN event.
4565 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
4566 if (rport == NULL) {
4568 * If min cfg mode is enabled, we donot need to
4569 * discover any new rports.
4571 if (!__fcs_min_cfg(port->fcs))
4572 rport = bfa_fcs_rport_create(port, rpid);
4574 bfa_fcs_rport_scn(rport);
4578 * rscn format based PID comparison
4580 #define __fc_pid_match(__c0, __c1, __fmt) \
4581 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
4582 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
4583 ((__c0)[0] == (__c1)[0])) || \
4584 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
4585 ((__c0)[0] == (__c1)[0]) && \
4586 ((__c0)[1] == (__c1)[1])))
4589 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
4590 enum fc_rscn_format format,
4593 struct bfa_fcs_rport_s *rport;
4594 struct list_head *qe, *qe_next;
4597 bfa_trc(port->fcs, format);
4598 bfa_trc(port->fcs, rscn_pid);
4600 c0 = (u8 *) &rscn_pid;
4602 list_for_each_safe(qe, qe_next, &port->rport_q) {
4603 rport = (struct bfa_fcs_rport_s *) qe;
4604 c1 = (u8 *) &rport->pid;
4605 if (__fc_pid_match(c0, c1, format))
4606 bfa_fcs_rport_scn(rport);
4612 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
4613 struct fchs_s *fchs, u32 len)
4615 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
4618 bfa_boolean_t nsquery = BFA_FALSE, found;
4622 (be16_to_cpu(rscn->payldlen) -
4623 sizeof(u32)) / sizeof(rscn->event[0]);
4625 bfa_trc(port->fcs, num_entries);
4627 port->stats.num_rscn++;
4629 bfa_fcs_lport_scn_send_ls_acc(port, fchs);
4631 for (i = 0; i < num_entries; i++) {
4632 rscn_pid = rscn->event[i].portid;
4634 bfa_trc(port->fcs, rscn->event[i].format);
4635 bfa_trc(port->fcs, rscn_pid);
4637 /* check for duplicate entries in the list */
4639 for (j = 0; j < i; j++) {
4640 if (rscn->event[j].portid == rscn_pid) {
4646 /* if found in down the list, pid has been already processed */
4648 bfa_trc(port->fcs, rscn_pid);
4652 switch (rscn->event[i].format) {
4653 case FC_RSCN_FORMAT_PORTID:
4654 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
4656 * Ignore this event.
4657 * f/w would have processed it
4659 bfa_trc(port->fcs, rscn_pid);
4661 port->stats.num_portid_rscn++;
4662 bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
4666 case FC_RSCN_FORMAT_FABRIC:
4667 if (rscn->event[i].qualifier ==
4668 FC_FABRIC_NAME_RSCN_EVENT) {
4669 bfa_fcs_lport_ms_fabric_rscn(port);
4672 /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4674 case FC_RSCN_FORMAT_AREA:
4675 case FC_RSCN_FORMAT_DOMAIN:
4677 bfa_fcs_lport_scn_multiport_rscn(port,
4678 rscn->event[i].format,
4690 * If any of area, domain or fabric RSCN is received, do a fresh
4691 * discovery to find new devices.
4694 bfa_fcs_lport_ns_query(port);
4701 * fcs_port_api BFA FCS port API
4703 struct bfa_fcs_lport_s *
4704 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
4706 return &fcs->fabric.bport;
4710 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
4711 int nrports, bfa_boolean_t bwwn)
4713 struct list_head *qh, *qe;
4714 struct bfa_fcs_rport_s *rport = NULL;
4716 struct bfa_fcs_s *fcs;
4718 if (port == NULL || nrports == 0)
4722 bfa_trc(fcs, (u32) nrports);
4725 qh = &port->rport_q;
4726 qe = bfa_q_first(qh);
4728 while ((qe != qh) && (i < nrports)) {
4729 rport = (struct bfa_fcs_rport_s *) qe;
4730 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4731 qe = bfa_q_next(qe);
4732 bfa_trc(fcs, (u32) rport->pwwn);
4733 bfa_trc(fcs, rport->pid);
4739 if (!memcmp(&wwn, &rport->pwwn, 8))
4747 qe = bfa_q_next(qe);
4758 bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
4759 wwn_t rport_wwns[], int *nrports)
4761 struct list_head *qh, *qe;
4762 struct bfa_fcs_rport_s *rport = NULL;
4764 struct bfa_fcs_s *fcs;
4766 if (port == NULL || rport_wwns == NULL || *nrports == 0)
4770 bfa_trc(fcs, (u32) *nrports);
4773 qh = &port->rport_q;
4774 qe = bfa_q_first(qh);
4776 while ((qe != qh) && (i < *nrports)) {
4777 rport = (struct bfa_fcs_rport_s *) qe;
4778 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4779 qe = bfa_q_next(qe);
4780 bfa_trc(fcs, (u32) rport->pwwn);
4781 bfa_trc(fcs, rport->pid);
4786 rport_wwns[i] = rport->pwwn;
4789 qe = bfa_q_next(qe);
4797 * Iterate's through all the rport's in the given port to
4798 * determine the maximum operating speed.
4800 * !!!! To be used in TRL Functionality only !!!!
4803 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
4805 struct list_head *qh, *qe;
4806 struct bfa_fcs_rport_s *rport = NULL;
4807 struct bfa_fcs_s *fcs;
4808 bfa_port_speed_t max_speed = 0;
4809 struct bfa_port_attr_s port_attr;
4810 bfa_port_speed_t port_speed, rport_speed;
4811 bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
4819 /* Get Physical port's current speed */
4820 bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
4821 port_speed = port_attr.speed;
4822 bfa_trc(fcs, port_speed);
4824 qh = &port->rport_q;
4825 qe = bfa_q_first(qh);
4828 rport = (struct bfa_fcs_rport_s *) qe;
4829 if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
4830 (bfa_fcs_rport_get_state(rport) ==
4831 BFA_RPORT_OFFLINE)) {
4832 qe = bfa_q_next(qe);
4836 rport_speed = rport->rpf.rpsc_speed;
4837 if ((trl_enabled) && (rport_speed ==
4838 BFA_PORT_SPEED_UNKNOWN)) {
4839 /* Use default ratelim speed setting */
4841 bfa_fcport_get_ratelim_speed(port->fcs->bfa);
4844 if ((rport_speed == BFA_PORT_SPEED_8GBPS) ||
4845 (rport_speed > port_speed)) {
4846 max_speed = rport_speed;
4848 } else if (rport_speed > max_speed) {
4849 max_speed = rport_speed;
4852 qe = bfa_q_next(qe);
4855 bfa_trc(fcs, max_speed);
4859 struct bfa_fcs_lport_s *
4860 bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
4862 struct bfa_fcs_vport_s *vport;
4865 WARN_ON(fcs == NULL);
4867 vf = bfa_fcs_vf_lookup(fcs, vf_id);
4869 bfa_trc(fcs, vf_id);
4873 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
4876 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
4878 return &vport->lport;
4884 * API corresponding to NPIV_VPORT_GETINFO.
4887 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
4888 struct bfa_lport_info_s *port_info)
4891 bfa_trc(port->fcs, port->fabric->fabric_name);
4893 if (port->vport == NULL) {
4895 * This is a Physical port
4897 port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
4900 * @todo : need to fix the state & reason
4902 port_info->port_state = 0;
4903 port_info->offline_reason = 0;
4905 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
4906 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
4908 port_info->max_vports_supp =
4909 bfa_lps_get_max_vport(port->fcs->bfa);
4910 port_info->num_vports_inuse =
4911 port->fabric->num_vports;
4912 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
4913 port_info->num_rports_inuse = port->num_rports;
4916 * This is a virtual port
4918 port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
4921 * @todo : need to fix the state & reason
4923 port_info->port_state = 0;
4924 port_info->offline_reason = 0;
4926 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
4927 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
4932 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
4933 struct bfa_lport_stats_s *port_stats)
4935 *port_stats = fcs_port->stats;
4939 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
4941 memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
4945 * FCS virtual port state machine
4948 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
4949 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
4950 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
4951 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
4952 #define __vport_fcid(__vp) ((__vp)->lport.pid)
4953 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
4954 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
4956 #define BFA_FCS_VPORT_MAX_RETRIES 5
4958 * Forward declarations
4960 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
4961 static void bfa_fcs_vport_timeout(void *vport_arg);
4962 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
4963 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
4966 * fcs_vport_sm FCS virtual port state machine
4970 * VPort State Machine events
4972 enum bfa_fcs_vport_event {
4973 BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */
4974 BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */
4975 BFA_FCS_VPORT_SM_START = 3, /* vport start request */
4976 BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */
4977 BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */
4978 BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */
4979 BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */
4980 BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */
4981 BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */
4982 BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */
4983 BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */
4984 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/
4985 BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */
4986 BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */
4989 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
4990 enum bfa_fcs_vport_event event);
4991 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
4992 enum bfa_fcs_vport_event event);
4993 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
4994 enum bfa_fcs_vport_event event);
4995 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
4996 enum bfa_fcs_vport_event event);
4997 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
4998 enum bfa_fcs_vport_event event);
4999 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5000 enum bfa_fcs_vport_event event);
5001 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5002 enum bfa_fcs_vport_event event);
5003 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5004 enum bfa_fcs_vport_event event);
5005 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5006 enum bfa_fcs_vport_event event);
5007 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5008 enum bfa_fcs_vport_event event);
5009 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5010 enum bfa_fcs_vport_event event);
5011 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5012 enum bfa_fcs_vport_event event);
5014 static struct bfa_sm_table_s vport_sm_table[] = {
5015 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
5016 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
5017 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
5018 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
5019 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
5020 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
5021 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
5022 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
5023 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
5024 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
5031 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5032 enum bfa_fcs_vport_event event)
5034 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5035 bfa_trc(__vport_fcs(vport), event);
5038 case BFA_FCS_VPORT_SM_CREATE:
5039 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5040 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
5044 bfa_sm_fault(__vport_fcs(vport), event);
5049 * Created state - a start event is required to start up the state machine.
5052 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5053 enum bfa_fcs_vport_event event)
5055 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5056 bfa_trc(__vport_fcs(vport), event);
5059 case BFA_FCS_VPORT_SM_START:
5060 if (bfa_sm_cmp_state(__vport_fabric(vport),
5061 bfa_fcs_fabric_sm_online)
5062 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
5063 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5064 bfa_fcs_vport_do_fdisc(vport);
5067 * Fabric is offline or not NPIV capable, stay in
5070 vport->vport_stats.fab_no_npiv++;
5071 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5075 case BFA_FCS_VPORT_SM_DELETE:
5076 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5077 bfa_fcs_lport_delete(&vport->lport);
5080 case BFA_FCS_VPORT_SM_ONLINE:
5081 case BFA_FCS_VPORT_SM_OFFLINE:
5083 * Ignore ONLINE/OFFLINE events from fabric
5084 * till vport is started.
5089 bfa_sm_fault(__vport_fcs(vport), event);
5094 * Offline state - awaiting ONLINE event from fabric SM.
5097 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5098 enum bfa_fcs_vport_event event)
5100 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5101 bfa_trc(__vport_fcs(vport), event);
5104 case BFA_FCS_VPORT_SM_DELETE:
5105 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5106 bfa_fcs_lport_delete(&vport->lport);
5109 case BFA_FCS_VPORT_SM_ONLINE:
5110 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5111 vport->fdisc_retries = 0;
5112 bfa_fcs_vport_do_fdisc(vport);
5115 case BFA_FCS_VPORT_SM_STOP:
5116 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5117 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5120 case BFA_FCS_VPORT_SM_OFFLINE:
5122 * This can happen if the vport couldn't be initialzied
5123 * due the fact that the npiv was not enabled on the switch.
5124 * In that case we will put the vport in offline state.
5125 * However, the link can go down and cause the this event to
5126 * be sent when we are already offline. Ignore it.
5131 bfa_sm_fault(__vport_fcs(vport), event);
5137 * FDISC is sent and awaiting reply from fabric.
5140 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5141 enum bfa_fcs_vport_event event)
5143 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5144 bfa_trc(__vport_fcs(vport), event);
5147 case BFA_FCS_VPORT_SM_DELETE:
5148 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5149 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5150 bfa_fcs_lport_delete(&vport->lport);
5153 case BFA_FCS_VPORT_SM_OFFLINE:
5154 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5155 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5158 case BFA_FCS_VPORT_SM_RSP_OK:
5159 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
5160 bfa_fcs_lport_online(&vport->lport);
5163 case BFA_FCS_VPORT_SM_RSP_ERROR:
5164 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
5165 bfa_timer_start(__vport_bfa(vport), &vport->timer,
5166 bfa_fcs_vport_timeout, vport,
5167 BFA_FCS_RETRY_TIMEOUT);
5170 case BFA_FCS_VPORT_SM_RSP_FAILED:
5171 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5174 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5175 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
5179 bfa_sm_fault(__vport_fcs(vport), event);
5184 * FDISC attempt failed - a timer is active to retry FDISC.
5187 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5188 enum bfa_fcs_vport_event event)
5190 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5191 bfa_trc(__vport_fcs(vport), event);
5194 case BFA_FCS_VPORT_SM_DELETE:
5195 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5196 bfa_timer_stop(&vport->timer);
5197 bfa_fcs_lport_delete(&vport->lport);
5200 case BFA_FCS_VPORT_SM_OFFLINE:
5201 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5202 bfa_timer_stop(&vport->timer);
5205 case BFA_FCS_VPORT_SM_TIMEOUT:
5206 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5207 vport->vport_stats.fdisc_retries++;
5208 vport->fdisc_retries++;
5209 bfa_fcs_vport_do_fdisc(vport);
5213 bfa_sm_fault(__vport_fcs(vport), event);
5218 * Vport is online (FDISC is complete).
5221 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5222 enum bfa_fcs_vport_event event)
5224 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5225 bfa_trc(__vport_fcs(vport), event);
5228 case BFA_FCS_VPORT_SM_DELETE:
5229 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5230 bfa_fcs_lport_delete(&vport->lport);
5233 case BFA_FCS_VPORT_SM_STOP:
5234 bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
5235 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5238 case BFA_FCS_VPORT_SM_OFFLINE:
5239 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5240 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5241 bfa_fcs_lport_offline(&vport->lport);
5245 bfa_sm_fault(__vport_fcs(vport), event);
5250 * Vport is being stopped - awaiting lport stop completion to send
5254 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5255 enum bfa_fcs_vport_event event)
5257 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5258 bfa_trc(__vport_fcs(vport), event);
5261 case BFA_FCS_VPORT_SM_STOPCOMP:
5262 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
5263 bfa_fcs_vport_do_logo(vport);
5266 case BFA_FCS_VPORT_SM_OFFLINE:
5267 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5271 bfa_sm_fault(__vport_fcs(vport), event);
5276 * Vport is being deleted - awaiting lport delete completion to send
5280 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5281 enum bfa_fcs_vport_event event)
5283 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5284 bfa_trc(__vport_fcs(vport), event);
5287 case BFA_FCS_VPORT_SM_DELETE:
5290 case BFA_FCS_VPORT_SM_DELCOMP:
5291 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
5292 bfa_fcs_vport_do_logo(vport);
5295 case BFA_FCS_VPORT_SM_OFFLINE:
5296 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5300 bfa_sm_fault(__vport_fcs(vport), event);
5306 * This state will be set when the Vport Creation fails due
5307 * to errors like Dup WWN. In this state only operation allowed
5308 * is a Vport Delete.
5311 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5312 enum bfa_fcs_vport_event event)
5314 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5315 bfa_trc(__vport_fcs(vport), event);
5318 case BFA_FCS_VPORT_SM_DELETE:
5319 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5320 bfa_fcs_lport_delete(&vport->lport);
5324 bfa_trc(__vport_fcs(vport), event);
5329 * Lport cleanup is in progress since vport is being deleted. Fabric is
5330 * offline, so no LOGO is needed to complete vport deletion.
5333 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5334 enum bfa_fcs_vport_event event)
5336 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5337 bfa_trc(__vport_fcs(vport), event);
5340 case BFA_FCS_VPORT_SM_DELCOMP:
5341 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5342 bfa_fcs_vport_free(vport);
5345 case BFA_FCS_VPORT_SM_STOPCOMP:
5346 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5349 case BFA_FCS_VPORT_SM_DELETE:
5353 bfa_sm_fault(__vport_fcs(vport), event);
5358 * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
5362 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5363 enum bfa_fcs_vport_event event)
5365 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5366 bfa_trc(__vport_fcs(vport), event);
5369 case BFA_FCS_VPORT_SM_OFFLINE:
5370 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5372 * !!! fall through !!!
5375 case BFA_FCS_VPORT_SM_RSP_OK:
5376 case BFA_FCS_VPORT_SM_RSP_ERROR:
5377 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5381 bfa_sm_fault(__vport_fcs(vport), event);
5386 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5390 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5391 enum bfa_fcs_vport_event event)
5393 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5394 bfa_trc(__vport_fcs(vport), event);
5397 case BFA_FCS_VPORT_SM_OFFLINE:
5398 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5400 * !!! fall through !!!
5403 case BFA_FCS_VPORT_SM_RSP_OK:
5404 case BFA_FCS_VPORT_SM_RSP_ERROR:
5405 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5406 bfa_fcs_vport_free(vport);
5409 case BFA_FCS_VPORT_SM_DELETE:
5413 bfa_sm_fault(__vport_fcs(vport), event);
5420 * fcs_vport_private FCS virtual port private functions
5423 * This routine will be called to send a FDISC command.
5426 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
5428 bfa_lps_fdisc(vport->lps, vport,
5429 bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
5430 __vport_pwwn(vport), __vport_nwwn(vport));
5431 vport->vport_stats.fdisc_sent++;
5435 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5437 u8 lsrjt_rsn = vport->lps->lsrjt_rsn;
5438 u8 lsrjt_expl = vport->lps->lsrjt_expl;
5440 bfa_trc(__vport_fcs(vport), lsrjt_rsn);
5441 bfa_trc(__vport_fcs(vport), lsrjt_expl);
5443 /* For certain reason codes, we don't want to retry. */
5444 switch (vport->lps->lsrjt_expl) {
5445 case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
5446 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
5447 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5448 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5450 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
5453 case FC_LS_RJT_EXP_INSUFF_RES:
5455 * This means max logins per port/switch setting on the
5456 * switch was exceeded.
5458 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5459 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5461 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
5465 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5470 * Called to send a logout to the fabric. Used when a V-Port is
5474 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
5476 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5478 vport->vport_stats.logo_sent++;
5479 bfa_lps_fdisclogo(vport->lps);
5484 * This routine will be called by bfa_timer on timer timeouts.
5486 * param[in] vport - pointer to bfa_fcs_vport_t.
5487 * param[out] vport_status - pointer to return vport status in
5492 * Special Considerations:
5497 bfa_fcs_vport_timeout(void *vport_arg)
5499 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
5501 vport->vport_stats.fdisc_timeouts++;
5502 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
5506 bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
5508 struct bfad_vport_s *vport_drv =
5509 (struct bfad_vport_s *)vport->vport_drv;
5511 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
5513 if (vport_drv->comp_del)
5514 complete(vport_drv->comp_del);
5516 bfa_lps_delete(vport->lps);
5522 * fcs_vport_public FCS virtual port public interfaces
5526 * Online notification from fabric SM.
5529 bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
5531 vport->vport_stats.fab_online++;
5532 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
5536 * Offline notification from fabric SM.
5539 bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
5541 vport->vport_stats.fab_offline++;
5542 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
5546 * Cleanup notification from fabric SM on link timer expiry.
5549 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
5551 vport->vport_stats.fab_cleanup++;
5554 * delete notification from fabric SM. To be invoked from within FCS.
5557 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
5559 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5563 * Stop completion callback from associated lport
5566 bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
5568 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
5572 * Delete completion callback from associated lport
5575 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
5577 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
5583 * fcs_vport_api Virtual port API
5587 * Use this function to instantiate a new FCS vport object. This
5588 * function will not trigger any HW initialization process (which will be
5589 * done in vport_start() call)
5591 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5592 * needs to be allocated by the driver.
5593 * param[in] fcs - FCS instance
5594 * param[in] vport_cfg - vport configuration
5595 * param[in] vf_id - VF_ID if vport is created within a VF.
5596 * FC_VF_ID_NULL to specify base fabric.
5597 * param[in] vport_drv - Opaque handle back to the driver's vport
5600 * retval BFA_STATUS_OK - on success.
5601 * retval BFA_STATUS_FAILED - on failure.
5604 bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5605 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5606 struct bfad_vport_s *vport_drv)
5608 if (vport_cfg->pwwn == 0)
5609 return BFA_STATUS_INVALID_WWN;
5611 if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
5612 return BFA_STATUS_VPORT_WWN_BP;
5614 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
5615 return BFA_STATUS_VPORT_EXISTS;
5617 if (fcs->fabric.num_vports ==
5618 bfa_lps_get_max_vport(fcs->bfa))
5619 return BFA_STATUS_VPORT_MAX;
5621 vport->lps = bfa_lps_alloc(fcs->bfa);
5623 return BFA_STATUS_VPORT_MAX;
5625 vport->vport_drv = vport_drv;
5626 vport_cfg->preboot_vp = BFA_FALSE;
5628 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5629 bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
5630 bfa_fcs_lport_init(&vport->lport, vport_cfg);
5631 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
5633 return BFA_STATUS_OK;
5637 * Use this function to instantiate a new FCS PBC vport object. This
5638 * function will not trigger any HW initialization process (which will be
5639 * done in vport_start() call)
5641 * param[in] vport - pointer to bfa_fcs_vport_t. This space
5642 * needs to be allocated by the driver.
5643 * param[in] fcs - FCS instance
5644 * param[in] vport_cfg - vport configuration
5645 * param[in] vf_id - VF_ID if vport is created within a VF.
5646 * FC_VF_ID_NULL to specify base fabric.
5647 * param[in] vport_drv - Opaque handle back to the driver's vport
5650 * retval BFA_STATUS_OK - on success.
5651 * retval BFA_STATUS_FAILED - on failure.
5654 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5655 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5656 struct bfad_vport_s *vport_drv)
5660 rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
5661 vport->lport.port_cfg.preboot_vp = BFA_TRUE;
5667 * Use this function to findout if this is a pbc vport or not.
5669 * @param[in] vport - pointer to bfa_fcs_vport_t.
5674 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
5677 if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
5685 * Use this function initialize the vport.
5687 * @param[in] vport - pointer to bfa_fcs_vport_t.
5692 bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
5694 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
5696 return BFA_STATUS_OK;
5700 * Use this function quiese the vport object. This function will return
5701 * immediately, when the vport is actually stopped, the
5702 * bfa_drv_vport_stop_cb() will be called.
5704 * param[in] vport - pointer to bfa_fcs_vport_t.
5709 bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
5711 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
5713 return BFA_STATUS_OK;
5717 * Use this function to delete a vport object. Fabric object should
5718 * be stopped before this function call.
5720 * !!!!!!! Donot invoke this from within FCS !!!!!!!
5722 * param[in] vport - pointer to bfa_fcs_vport_t.
5727 bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
5730 if (vport->lport.port_cfg.preboot_vp)
5731 return BFA_STATUS_PBC;
5733 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5735 return BFA_STATUS_OK;
5739 * Use this function to get vport's current status info.
5741 * param[in] vport pointer to bfa_fcs_vport_t.
5742 * param[out] attr pointer to return vport attributes
5747 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
5748 struct bfa_vport_attr_s *attr)
5750 if (vport == NULL || attr == NULL)
5753 memset(attr, 0, sizeof(struct bfa_vport_attr_s));
5755 bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
5756 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
5761 * Lookup a virtual port. Excludes base port from lookup.
5763 struct bfa_fcs_vport_s *
5764 bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
5766 struct bfa_fcs_vport_s *vport;
5767 struct bfa_fcs_fabric_s *fabric;
5769 bfa_trc(fcs, vf_id);
5770 bfa_trc(fcs, vpwwn);
5772 fabric = bfa_fcs_vf_lookup(fcs, vf_id);
5774 bfa_trc(fcs, vf_id);
5778 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
5786 bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
5788 struct bfa_fcs_vport_s *vport = uarg;
5790 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5791 bfa_trc(__vport_fcs(vport), status);
5796 * Initialize the V-Port fields
5798 __vport_fcid(vport) = vport->lps->lp_pid;
5799 vport->vport_stats.fdisc_accepts++;
5800 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
5803 case BFA_STATUS_INVALID_MAC:
5805 vport->vport_stats.fdisc_acc_bad++;
5806 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5810 case BFA_STATUS_EPROTOCOL:
5811 switch (vport->lps->ext_status) {
5812 case BFA_EPROTO_BAD_ACCEPT:
5813 vport->vport_stats.fdisc_acc_bad++;
5816 case BFA_EPROTO_UNKNOWN_RSP:
5817 vport->vport_stats.fdisc_unknown_rsp++;
5824 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5827 case BFA_STATUS_FABRIC_RJT:
5828 vport->vport_stats.fdisc_rejects++;
5829 bfa_fcs_vport_fdisc_rejected(vport);
5833 vport->vport_stats.fdisc_rsp_err++;
5834 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5842 bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
5844 struct bfa_fcs_vport_s *vport = uarg;
5845 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
5849 * Received clear virtual link
5852 bfa_cb_lps_cvl_event(void *bfad, void *uarg)
5854 struct bfa_fcs_vport_s *vport = uarg;
5856 /* Send an Offline followed by an ONLINE */
5857 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
5858 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);