2 * Copyright (c) 2005-2009 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.
19 * bfa_fcs_port.c BFA FCS port
22 #include <fcs/bfa_fcs.h>
23 #include <fcs/bfa_fcs_lport.h>
24 #include <fcs/bfa_fcs_rport.h>
25 #include <fcb/bfa_fcb_port.h>
27 #include <log/bfa_log_fcs.h>
29 #include "fcs_lport.h"
30 #include "fcs_vport.h"
31 #include "fcs_rport.h"
33 #include "fcs_trcmod.h"
34 #include "lport_priv.h"
35 #include <aen/bfa_aen_lport.h>
37 BFA_TRC_FILE(FCS, PORT);
40 * Forward declarations
43 static void bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
44 enum bfa_lport_aen_event event);
45 static void bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port,
46 struct fchs_s *rx_fchs, u8 reason_code,
48 static void bfa_fcs_port_plogi(struct bfa_fcs_port_s *port,
49 struct fchs_s *rx_fchs,
50 struct fc_logi_s *plogi);
51 static void bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port);
52 static void bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port);
53 static void bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port);
54 static void bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port);
55 static void bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port);
56 static void bfa_fcs_port_deleted(struct bfa_fcs_port_s *port);
57 static void bfa_fcs_port_echo(struct bfa_fcs_port_s *port,
58 struct fchs_s *rx_fchs,
59 struct fc_echo_s *echo, u16 len);
60 static void bfa_fcs_port_rnid(struct bfa_fcs_port_s *port,
61 struct fchs_s *rx_fchs,
62 struct fc_rnid_cmd_s *rnid, u16 len);
63 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
64 struct fc_rnid_general_topology_data_s *gen_topo_data);
67 void (*init) (struct bfa_fcs_port_s *port);
68 void (*online) (struct bfa_fcs_port_s *port);
69 void (*offline) (struct bfa_fcs_port_s *port);
72 bfa_fcs_port_unknown_init, bfa_fcs_port_unknown_online,
73 bfa_fcs_port_unknown_offline}, {
74 bfa_fcs_port_fab_init, bfa_fcs_port_fab_online,
75 bfa_fcs_port_fab_offline}, {
76 bfa_fcs_port_loop_init, bfa_fcs_port_loop_online,
77 bfa_fcs_port_loop_offline}, {
78 bfa_fcs_port_n2n_init, bfa_fcs_port_n2n_online,
79 bfa_fcs_port_n2n_offline},};
82 * fcs_port_sm FCS logical port state machine
85 enum bfa_fcs_port_event {
86 BFA_FCS_PORT_SM_CREATE = 1,
87 BFA_FCS_PORT_SM_ONLINE = 2,
88 BFA_FCS_PORT_SM_OFFLINE = 3,
89 BFA_FCS_PORT_SM_DELETE = 4,
90 BFA_FCS_PORT_SM_DELRPORT = 5,
93 static void bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
94 enum bfa_fcs_port_event event);
95 static void bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port,
96 enum bfa_fcs_port_event event);
97 static void bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
98 enum bfa_fcs_port_event event);
99 static void bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
100 enum bfa_fcs_port_event event);
101 static void bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
102 enum bfa_fcs_port_event event);
105 bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
106 enum bfa_fcs_port_event event)
108 bfa_trc(port->fcs, port->port_cfg.pwwn);
109 bfa_trc(port->fcs, event);
112 case BFA_FCS_PORT_SM_CREATE:
113 bfa_sm_set_state(port, bfa_fcs_port_sm_init);
117 bfa_sm_fault(port->fcs, event);
122 bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
124 bfa_trc(port->fcs, port->port_cfg.pwwn);
125 bfa_trc(port->fcs, event);
128 case BFA_FCS_PORT_SM_ONLINE:
129 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
130 bfa_fcs_port_online_actions(port);
133 case BFA_FCS_PORT_SM_DELETE:
134 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
135 bfa_fcs_port_deleted(port);
139 bfa_sm_fault(port->fcs, event);
144 bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
145 enum bfa_fcs_port_event event)
147 struct bfa_fcs_rport_s *rport;
148 struct list_head *qe, *qen;
150 bfa_trc(port->fcs, port->port_cfg.pwwn);
151 bfa_trc(port->fcs, event);
154 case BFA_FCS_PORT_SM_OFFLINE:
155 bfa_sm_set_state(port, bfa_fcs_port_sm_offline);
156 bfa_fcs_port_offline_actions(port);
159 case BFA_FCS_PORT_SM_DELETE:
161 __port_action[port->fabric->fab_type].offline(port);
163 if (port->num_rports == 0) {
164 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
165 bfa_fcs_port_deleted(port);
167 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
168 list_for_each_safe(qe, qen, &port->rport_q) {
169 rport = (struct bfa_fcs_rport_s *)qe;
170 bfa_fcs_rport_delete(rport);
175 case BFA_FCS_PORT_SM_DELRPORT:
179 bfa_sm_fault(port->fcs, event);
184 bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
185 enum bfa_fcs_port_event event)
187 struct bfa_fcs_rport_s *rport;
188 struct list_head *qe, *qen;
190 bfa_trc(port->fcs, port->port_cfg.pwwn);
191 bfa_trc(port->fcs, event);
194 case BFA_FCS_PORT_SM_ONLINE:
195 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
196 bfa_fcs_port_online_actions(port);
199 case BFA_FCS_PORT_SM_DELETE:
200 if (port->num_rports == 0) {
201 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
202 bfa_fcs_port_deleted(port);
204 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
205 list_for_each_safe(qe, qen, &port->rport_q) {
206 rport = (struct bfa_fcs_rport_s *)qe;
207 bfa_fcs_rport_delete(rport);
212 case BFA_FCS_PORT_SM_DELRPORT:
213 case BFA_FCS_PORT_SM_OFFLINE:
217 bfa_sm_fault(port->fcs, event);
222 bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
223 enum bfa_fcs_port_event event)
225 bfa_trc(port->fcs, port->port_cfg.pwwn);
226 bfa_trc(port->fcs, event);
229 case BFA_FCS_PORT_SM_DELRPORT:
230 if (port->num_rports == 0) {
231 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
232 bfa_fcs_port_deleted(port);
237 bfa_sm_fault(port->fcs, event);
248 * Send AEN notification
251 bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
252 enum bfa_lport_aen_event event)
254 union bfa_aen_data_u aen_data;
255 struct bfa_log_mod_s *logmod = port->fcs->logm;
256 enum bfa_port_role role = port->port_cfg.roles;
257 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
258 char lpwwn_ptr[BFA_STRING_32];
259 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
260 { "Initiator", "Target", "IPFC" };
262 wwn2str(lpwwn_ptr, lpwwn);
264 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
266 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
269 aen_data.lport.vf_id = port->fabric->vf_id;
270 aen_data.lport.roles = role;
271 aen_data.lport.ppwwn =
272 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
273 aen_data.lport.lpwwn = lpwwn;
280 bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
281 u8 reason_code, u8 reason_code_expl)
284 struct bfa_fcxp_s *fcxp;
285 struct bfa_rport_s *bfa_rport = NULL;
288 bfa_trc(port->fcs, rx_fchs->s_id);
290 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
294 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
295 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
296 reason_code, reason_code_expl);
298 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
299 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
304 * Process incoming plogi from a remote port.
307 bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
308 struct fc_logi_s *plogi)
310 struct bfa_fcs_rport_s *rport;
312 bfa_trc(port->fcs, rx_fchs->d_id);
313 bfa_trc(port->fcs, rx_fchs->s_id);
316 * If min cfg mode is enabled, drop any incoming PLOGIs
318 if (__fcs_min_cfg(port->fcs)) {
319 bfa_trc(port->fcs, rx_fchs->s_id);
323 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
324 bfa_trc(port->fcs, rx_fchs->s_id);
328 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
329 FC_LS_RJT_RSN_PROTOCOL_ERROR,
330 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
335 * Direct Attach P2P mode : verify address assigned by the r-port.
337 if ((!bfa_fcs_fabric_is_switched(port->fabric))
340 ((void *)&bfa_fcs_port_get_pwwn(port), (void *)&plogi->port_name,
341 sizeof(wwn_t)) < 0)) {
342 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
344 * Address assigned to us cannot be a WKA
346 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
347 FC_LS_RJT_RSN_PROTOCOL_ERROR,
348 FC_LS_RJT_EXP_INVALID_NPORT_ID);
351 port->pid = rx_fchs->d_id;
355 * First, check if we know the device by pwwn.
357 rport = bfa_fcs_port_get_rport_by_pwwn(port, plogi->port_name);
360 * Direct Attach P2P mode: handle address assigned by the rport.
362 if ((!bfa_fcs_fabric_is_switched(port->fabric))
365 ((void *)&bfa_fcs_port_get_pwwn(port),
366 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
367 port->pid = rx_fchs->d_id;
368 rport->pid = rx_fchs->s_id;
370 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
375 * Next, lookup rport by PID.
377 rport = bfa_fcs_port_get_rport_by_pid(port, rx_fchs->s_id);
380 * Inbound PLOGI from a new device.
382 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
387 * Rport is known only by PID.
391 * This is a different device with the same pid. Old device
392 * disappeared. Send implicit LOGO to old device.
394 bfa_assert(rport->pwwn != plogi->port_name);
395 bfa_fcs_rport_logo_imp(rport);
398 * Inbound PLOGI from a new device (with old PID).
400 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
405 * PLOGI crossing each other.
407 bfa_assert(rport->pwwn == WWN_NULL);
408 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
412 * Process incoming ECHO.
413 * Since it does not require a login, it is processed here.
416 bfa_fcs_port_echo(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
417 struct fc_echo_s *echo, u16 rx_len)
420 struct bfa_fcxp_s *fcxp;
421 struct bfa_rport_s *bfa_rport = NULL;
424 bfa_trc(port->fcs, rx_fchs->s_id);
425 bfa_trc(port->fcs, rx_fchs->d_id);
426 bfa_trc(port->fcs, rx_len);
428 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
432 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
433 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
436 * Copy the payload (if any) from the echo frame
438 pyld_len = rx_len - sizeof(struct fchs_s);
439 bfa_trc(port->fcs, pyld_len);
442 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
443 sizeof(struct fc_echo_s), (echo + 1),
444 (pyld_len - sizeof(struct fc_echo_s)));
446 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
447 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
452 * Process incoming RNID.
453 * Since it does not require a login, it is processed here.
456 bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
457 struct fc_rnid_cmd_s *rnid, u16 rx_len)
459 struct fc_rnid_common_id_data_s common_id_data;
460 struct fc_rnid_general_topology_data_s gen_topo_data;
462 struct bfa_fcxp_s *fcxp;
463 struct bfa_rport_s *bfa_rport = NULL;
467 bfa_trc(port->fcs, rx_fchs->s_id);
468 bfa_trc(port->fcs, rx_fchs->d_id);
469 bfa_trc(port->fcs, rx_len);
471 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
476 * Check Node Indentification Data Format
477 * We only support General Topology Discovery Format.
478 * For any other requested Data Formats, we return Common Node Id Data
479 * only, as per FC-LS.
481 bfa_trc(port->fcs, rnid->node_id_data_format);
482 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
483 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
485 * Get General topology data for this port
487 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
489 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
493 * Copy the Node Id Info
495 common_id_data.port_name = bfa_fcs_port_get_pwwn(port);
496 common_id_data.node_name = bfa_fcs_port_get_nwwn(port);
498 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
499 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
500 data_format, &common_id_data, &gen_topo_data);
502 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
503 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
510 * Fill out General Topolpgy Discovery Data for RNID ELS.
513 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
514 struct fc_rnid_general_topology_data_s *gen_topo_data)
517 bfa_os_memset(gen_topo_data, 0,
518 sizeof(struct fc_rnid_general_topology_data_s));
520 gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST);
521 gen_topo_data->phy_port_num = 0; /* @todo */
522 gen_topo_data->num_attached_nodes = bfa_os_htonl(1);
526 bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port)
528 bfa_trc(port->fcs, port->fabric->oper_type);
530 __port_action[port->fabric->fab_type].init(port);
531 __port_action[port->fabric->fab_type].online(port);
533 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_ONLINE);
534 bfa_fcb_port_online(port->fcs->bfad, port->port_cfg.roles,
535 port->fabric->vf_drv, (port->vport == NULL) ?
536 NULL : port->vport->vport_drv);
540 bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port)
542 struct list_head *qe, *qen;
543 struct bfa_fcs_rport_s *rport;
545 bfa_trc(port->fcs, port->fabric->oper_type);
547 __port_action[port->fabric->fab_type].offline(port);
549 if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
550 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
552 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
553 bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
554 port->fabric->vf_drv,
555 (port->vport == NULL) ? NULL : port->vport->vport_drv);
557 list_for_each_safe(qe, qen, &port->rport_q) {
558 rport = (struct bfa_fcs_rport_s *)qe;
559 bfa_fcs_rport_offline(rport);
564 bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port)
570 bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port)
576 bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port)
582 bfa_fcs_port_deleted(struct bfa_fcs_port_s *port)
584 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DELETE);
587 * Base port will be deleted by the OS driver
590 bfa_fcb_port_delete(port->fcs->bfad, port->port_cfg.roles,
591 port->fabric->vf_drv,
592 port->vport ? port->vport->vport_drv : NULL);
593 bfa_fcs_vport_delete_comp(port->vport);
595 bfa_fcs_fabric_port_delete_comp(port->fabric);
602 * fcs_lport_api BFA FCS port API
605 * Module initialization
608 bfa_fcs_port_modinit(struct bfa_fcs_s *fcs)
617 bfa_fcs_port_modexit(struct bfa_fcs_s *fcs)
619 bfa_fcs_modexit_comp(fcs);
623 * Unsolicited frame receive handling.
626 bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
629 u32 pid = fchs->s_id;
630 struct bfa_fcs_rport_s *rport = NULL;
631 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
633 bfa_stats(lport, uf_recvs);
635 if (!bfa_fcs_port_is_online(lport)) {
636 bfa_stats(lport, uf_recv_drops);
641 * First, handle ELSs that donot require a login.
646 if ((fchs->type == FC_TYPE_ELS) &&
647 (els_cmd->els_code == FC_ELS_PLOGI)) {
648 bfa_fcs_port_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
653 * Handle ECHO separately.
655 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
656 bfa_fcs_port_echo(lport, fchs,
657 (struct fc_echo_s *) els_cmd, len);
662 * Handle RNID separately.
664 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
665 bfa_fcs_port_rnid(lport, fchs,
666 (struct fc_rnid_cmd_s *) els_cmd, len);
671 * look for a matching remote port ID
673 rport = bfa_fcs_port_get_rport_by_pid(lport, pid);
675 bfa_trc(rport->fcs, fchs->s_id);
676 bfa_trc(rport->fcs, fchs->d_id);
677 bfa_trc(rport->fcs, fchs->type);
679 bfa_fcs_rport_uf_recv(rport, fchs, len);
684 * Only handles ELS frames for now.
686 if (fchs->type != FC_TYPE_ELS) {
687 bfa_trc(lport->fcs, fchs->type);
692 bfa_trc(lport->fcs, els_cmd->els_code);
693 if (els_cmd->els_code == FC_ELS_RSCN) {
694 bfa_fcs_port_scn_process_rscn(lport, fchs, len);
698 if (els_cmd->els_code == FC_ELS_LOGO) {
700 * @todo Handle LOGO frames received.
702 bfa_trc(lport->fcs, els_cmd->els_code);
706 if (els_cmd->els_code == FC_ELS_PRLI) {
708 * @todo Handle PRLI frames received.
710 bfa_trc(lport->fcs, els_cmd->els_code);
715 * Unhandled ELS frames. Send a LS_RJT.
717 bfa_fcs_port_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
718 FC_LS_RJT_EXP_NO_ADDL_INFO);
723 * PID based Lookup for a R-Port in the Port R-Port Queue
725 struct bfa_fcs_rport_s *
726 bfa_fcs_port_get_rport_by_pid(struct bfa_fcs_port_s *port, u32 pid)
728 struct bfa_fcs_rport_s *rport;
729 struct list_head *qe;
731 list_for_each(qe, &port->rport_q) {
732 rport = (struct bfa_fcs_rport_s *)qe;
733 if (rport->pid == pid)
737 bfa_trc(port->fcs, pid);
742 * PWWN based Lookup for a R-Port in the Port R-Port Queue
744 struct bfa_fcs_rport_s *
745 bfa_fcs_port_get_rport_by_pwwn(struct bfa_fcs_port_s *port, wwn_t pwwn)
747 struct bfa_fcs_rport_s *rport;
748 struct list_head *qe;
750 list_for_each(qe, &port->rport_q) {
751 rport = (struct bfa_fcs_rport_s *)qe;
752 if (wwn_is_equal(rport->pwwn, pwwn))
756 bfa_trc(port->fcs, pwwn);
761 * NWWN based Lookup for a R-Port in the Port R-Port Queue
763 struct bfa_fcs_rport_s *
764 bfa_fcs_port_get_rport_by_nwwn(struct bfa_fcs_port_s *port, wwn_t nwwn)
766 struct bfa_fcs_rport_s *rport;
767 struct list_head *qe;
769 list_for_each(qe, &port->rport_q) {
770 rport = (struct bfa_fcs_rport_s *)qe;
771 if (wwn_is_equal(rport->nwwn, nwwn))
775 bfa_trc(port->fcs, nwwn);
780 * Called by rport module when new rports are discovered.
783 bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
784 struct bfa_fcs_rport_s *rport)
786 list_add_tail(&rport->qe, &port->rport_q);
791 * Called by rport module to when rports are deleted.
794 bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
795 struct bfa_fcs_rport_s *rport)
797 bfa_assert(bfa_q_is_on_q(&port->rport_q, rport));
798 list_del(&rport->qe);
801 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
805 * Called by fabric for base port when fabric login is complete.
806 * Called by vport for virtual ports when FDISC is complete.
809 bfa_fcs_port_online(struct bfa_fcs_port_s *port)
811 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
815 * Called by fabric for base port when fabric goes offline.
816 * Called by vport for virtual ports when virtual port becomes offline.
819 bfa_fcs_port_offline(struct bfa_fcs_port_s *port)
821 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
825 * Called by fabric to delete base lport and associated resources.
827 * Called by vport to delete lport and associated resources. Should call
828 * bfa_fcs_vport_delete_comp() for vports on completion.
831 bfa_fcs_port_delete(struct bfa_fcs_port_s *port)
833 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
837 * Called by fabric in private loop topology to process LIP event.
840 bfa_fcs_port_lip(struct bfa_fcs_port_s *port)
845 * Return TRUE if port is online, else return FALSE
848 bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
850 return bfa_sm_cmp_state(port, bfa_fcs_port_sm_online);
854 * Attach time initialization of logical ports.
857 bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
858 uint16_t vf_id, struct bfa_fcs_vport_s *vport)
861 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
862 lport->vport = vport;
863 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
864 bfa_lps_get_tag(lport->fabric->lps);
866 INIT_LIST_HEAD(&lport->rport_q);
867 lport->num_rports = 0;
871 * Logical port initialization of base or virtual port.
872 * Called by fabric for base port or by vport for virtual ports.
876 bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
877 struct bfa_port_cfg_s *port_cfg)
879 struct bfa_fcs_vport_s *vport = lport->vport;
881 bfa_os_assign(lport->port_cfg, *port_cfg);
883 lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
884 lport->port_cfg.roles,
885 lport->fabric->vf_drv,
886 vport ? vport->vport_drv : NULL);
888 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
890 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
891 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
899 bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
900 struct bfa_port_attr_s *port_attr)
902 if (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online))
903 port_attr->pid = port->pid;
907 port_attr->port_cfg = port->port_cfg;
910 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
911 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
912 port_attr->authfail =
913 bfa_fcs_fabric_is_auth_failed(port->fabric);
914 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
915 memcpy(port_attr->fabric_ip_addr,
916 bfa_fcs_port_get_fabric_ipaddr(port),
917 BFA_FCS_FABRIC_IPADDR_SZ);
919 if (port->vport != NULL) {
920 port_attr->port_type = BFA_PPORT_TYPE_VPORT;
921 port_attr->fpma_mac =
922 bfa_lps_get_lp_mac(port->vport->lps);
924 port_attr->fpma_mac =
925 bfa_lps_get_lp_mac(port->fabric->lps);
928 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
929 port_attr->state = BFA_PORT_UNINIT;