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);
138 case BFA_FCS_PORT_SM_OFFLINE:
142 bfa_sm_fault(port->fcs, event);
147 bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
148 enum bfa_fcs_port_event event)
150 struct bfa_fcs_rport_s *rport;
151 struct list_head *qe, *qen;
153 bfa_trc(port->fcs, port->port_cfg.pwwn);
154 bfa_trc(port->fcs, event);
157 case BFA_FCS_PORT_SM_OFFLINE:
158 bfa_sm_set_state(port, bfa_fcs_port_sm_offline);
159 bfa_fcs_port_offline_actions(port);
162 case BFA_FCS_PORT_SM_DELETE:
164 __port_action[port->fabric->fab_type].offline(port);
166 if (port->num_rports == 0) {
167 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
168 bfa_fcs_port_deleted(port);
170 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
171 list_for_each_safe(qe, qen, &port->rport_q) {
172 rport = (struct bfa_fcs_rport_s *)qe;
173 bfa_fcs_rport_delete(rport);
178 case BFA_FCS_PORT_SM_DELRPORT:
182 bfa_sm_fault(port->fcs, event);
187 bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
188 enum bfa_fcs_port_event event)
190 struct bfa_fcs_rport_s *rport;
191 struct list_head *qe, *qen;
193 bfa_trc(port->fcs, port->port_cfg.pwwn);
194 bfa_trc(port->fcs, event);
197 case BFA_FCS_PORT_SM_ONLINE:
198 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
199 bfa_fcs_port_online_actions(port);
202 case BFA_FCS_PORT_SM_DELETE:
203 if (port->num_rports == 0) {
204 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
205 bfa_fcs_port_deleted(port);
207 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
208 list_for_each_safe(qe, qen, &port->rport_q) {
209 rport = (struct bfa_fcs_rport_s *)qe;
210 bfa_fcs_rport_delete(rport);
215 case BFA_FCS_PORT_SM_DELRPORT:
216 case BFA_FCS_PORT_SM_OFFLINE:
220 bfa_sm_fault(port->fcs, event);
225 bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
226 enum bfa_fcs_port_event event)
228 bfa_trc(port->fcs, port->port_cfg.pwwn);
229 bfa_trc(port->fcs, event);
232 case BFA_FCS_PORT_SM_DELRPORT:
233 if (port->num_rports == 0) {
234 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
235 bfa_fcs_port_deleted(port);
240 bfa_sm_fault(port->fcs, event);
251 * Send AEN notification
254 bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
255 enum bfa_lport_aen_event event)
257 union bfa_aen_data_u aen_data;
258 struct bfa_log_mod_s *logmod = port->fcs->logm;
259 enum bfa_port_role role = port->port_cfg.roles;
260 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
261 char lpwwn_ptr[BFA_STRING_32];
262 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
263 { "Initiator", "Target", "IPFC" };
265 wwn2str(lpwwn_ptr, lpwwn);
267 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
269 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
272 aen_data.lport.vf_id = port->fabric->vf_id;
273 aen_data.lport.roles = role;
274 aen_data.lport.ppwwn =
275 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
276 aen_data.lport.lpwwn = lpwwn;
283 bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
284 u8 reason_code, u8 reason_code_expl)
287 struct bfa_fcxp_s *fcxp;
288 struct bfa_rport_s *bfa_rport = NULL;
291 bfa_trc(port->fcs, rx_fchs->s_id);
293 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
297 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
298 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
299 reason_code, reason_code_expl);
301 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
302 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
307 * Process incoming plogi from a remote port.
310 bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
311 struct fc_logi_s *plogi)
313 struct bfa_fcs_rport_s *rport;
315 bfa_trc(port->fcs, rx_fchs->d_id);
316 bfa_trc(port->fcs, rx_fchs->s_id);
319 * If min cfg mode is enabled, drop any incoming PLOGIs
321 if (__fcs_min_cfg(port->fcs)) {
322 bfa_trc(port->fcs, rx_fchs->s_id);
326 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
327 bfa_trc(port->fcs, rx_fchs->s_id);
331 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
332 FC_LS_RJT_RSN_PROTOCOL_ERROR,
333 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
338 * Direct Attach P2P mode : verify address assigned by the r-port.
340 if ((!bfa_fcs_fabric_is_switched(port->fabric))
343 ((void *)&bfa_fcs_port_get_pwwn(port), (void *)&plogi->port_name,
344 sizeof(wwn_t)) < 0)) {
345 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
347 * Address assigned to us cannot be a WKA
349 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
350 FC_LS_RJT_RSN_PROTOCOL_ERROR,
351 FC_LS_RJT_EXP_INVALID_NPORT_ID);
354 port->pid = rx_fchs->d_id;
358 * First, check if we know the device by pwwn.
360 rport = bfa_fcs_port_get_rport_by_pwwn(port, plogi->port_name);
363 * Direct Attach P2P mode: handle address assigned by the rport.
365 if ((!bfa_fcs_fabric_is_switched(port->fabric))
368 ((void *)&bfa_fcs_port_get_pwwn(port),
369 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
370 port->pid = rx_fchs->d_id;
371 rport->pid = rx_fchs->s_id;
373 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
378 * Next, lookup rport by PID.
380 rport = bfa_fcs_port_get_rport_by_pid(port, rx_fchs->s_id);
383 * Inbound PLOGI from a new device.
385 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
390 * Rport is known only by PID.
394 * This is a different device with the same pid. Old device
395 * disappeared. Send implicit LOGO to old device.
397 bfa_assert(rport->pwwn != plogi->port_name);
398 bfa_fcs_rport_logo_imp(rport);
401 * Inbound PLOGI from a new device (with old PID).
403 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
408 * PLOGI crossing each other.
410 bfa_assert(rport->pwwn == WWN_NULL);
411 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
415 * Process incoming ECHO.
416 * Since it does not require a login, it is processed here.
419 bfa_fcs_port_echo(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
420 struct fc_echo_s *echo, u16 rx_len)
423 struct bfa_fcxp_s *fcxp;
424 struct bfa_rport_s *bfa_rport = NULL;
427 bfa_trc(port->fcs, rx_fchs->s_id);
428 bfa_trc(port->fcs, rx_fchs->d_id);
429 bfa_trc(port->fcs, rx_len);
431 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
435 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
436 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
439 * Copy the payload (if any) from the echo frame
441 pyld_len = rx_len - sizeof(struct fchs_s);
442 bfa_trc(port->fcs, pyld_len);
445 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
446 sizeof(struct fc_echo_s), (echo + 1),
447 (pyld_len - sizeof(struct fc_echo_s)));
449 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
450 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
455 * Process incoming RNID.
456 * Since it does not require a login, it is processed here.
459 bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
460 struct fc_rnid_cmd_s *rnid, u16 rx_len)
462 struct fc_rnid_common_id_data_s common_id_data;
463 struct fc_rnid_general_topology_data_s gen_topo_data;
465 struct bfa_fcxp_s *fcxp;
466 struct bfa_rport_s *bfa_rport = NULL;
470 bfa_trc(port->fcs, rx_fchs->s_id);
471 bfa_trc(port->fcs, rx_fchs->d_id);
472 bfa_trc(port->fcs, rx_len);
474 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
479 * Check Node Indentification Data Format
480 * We only support General Topology Discovery Format.
481 * For any other requested Data Formats, we return Common Node Id Data
482 * only, as per FC-LS.
484 bfa_trc(port->fcs, rnid->node_id_data_format);
485 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
486 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
488 * Get General topology data for this port
490 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
492 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
496 * Copy the Node Id Info
498 common_id_data.port_name = bfa_fcs_port_get_pwwn(port);
499 common_id_data.node_name = bfa_fcs_port_get_nwwn(port);
501 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
502 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
503 data_format, &common_id_data, &gen_topo_data);
505 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
506 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
513 * Fill out General Topolpgy Discovery Data for RNID ELS.
516 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
517 struct fc_rnid_general_topology_data_s *gen_topo_data)
520 bfa_os_memset(gen_topo_data, 0,
521 sizeof(struct fc_rnid_general_topology_data_s));
523 gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST);
524 gen_topo_data->phy_port_num = 0; /* @todo */
525 gen_topo_data->num_attached_nodes = bfa_os_htonl(1);
529 bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port)
531 bfa_trc(port->fcs, port->fabric->oper_type);
533 __port_action[port->fabric->fab_type].init(port);
534 __port_action[port->fabric->fab_type].online(port);
536 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_ONLINE);
537 bfa_fcb_port_online(port->fcs->bfad, port->port_cfg.roles,
538 port->fabric->vf_drv, (port->vport == NULL) ?
539 NULL : port->vport->vport_drv);
543 bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port)
545 struct list_head *qe, *qen;
546 struct bfa_fcs_rport_s *rport;
548 bfa_trc(port->fcs, port->fabric->oper_type);
550 __port_action[port->fabric->fab_type].offline(port);
552 if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
553 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
555 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
556 bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
557 port->fabric->vf_drv,
558 (port->vport == NULL) ? NULL : port->vport->vport_drv);
560 list_for_each_safe(qe, qen, &port->rport_q) {
561 rport = (struct bfa_fcs_rport_s *)qe;
562 bfa_fcs_rport_offline(rport);
567 bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port)
573 bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port)
579 bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port)
585 bfa_fcs_port_deleted(struct bfa_fcs_port_s *port)
587 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DELETE);
590 * Base port will be deleted by the OS driver
593 bfa_fcb_port_delete(port->fcs->bfad, port->port_cfg.roles,
594 port->fabric->vf_drv,
595 port->vport ? port->vport->vport_drv : NULL);
596 bfa_fcs_vport_delete_comp(port->vport);
598 bfa_fcs_fabric_port_delete_comp(port->fabric);
605 * fcs_lport_api BFA FCS port API
608 * Module initialization
611 bfa_fcs_port_modinit(struct bfa_fcs_s *fcs)
620 bfa_fcs_port_modexit(struct bfa_fcs_s *fcs)
622 bfa_fcs_modexit_comp(fcs);
626 * Unsolicited frame receive handling.
629 bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
632 u32 pid = fchs->s_id;
633 struct bfa_fcs_rport_s *rport = NULL;
634 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
636 bfa_stats(lport, uf_recvs);
638 if (!bfa_fcs_port_is_online(lport)) {
639 bfa_stats(lport, uf_recv_drops);
644 * First, handle ELSs that donot require a login.
649 if ((fchs->type == FC_TYPE_ELS) &&
650 (els_cmd->els_code == FC_ELS_PLOGI)) {
651 bfa_fcs_port_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
656 * Handle ECHO separately.
658 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
659 bfa_fcs_port_echo(lport, fchs,
660 (struct fc_echo_s *) els_cmd, len);
665 * Handle RNID separately.
667 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
668 bfa_fcs_port_rnid(lport, fchs,
669 (struct fc_rnid_cmd_s *) els_cmd, len);
674 * look for a matching remote port ID
676 rport = bfa_fcs_port_get_rport_by_pid(lport, pid);
678 bfa_trc(rport->fcs, fchs->s_id);
679 bfa_trc(rport->fcs, fchs->d_id);
680 bfa_trc(rport->fcs, fchs->type);
682 bfa_fcs_rport_uf_recv(rport, fchs, len);
687 * Only handles ELS frames for now.
689 if (fchs->type != FC_TYPE_ELS) {
690 bfa_trc(lport->fcs, fchs->type);
695 bfa_trc(lport->fcs, els_cmd->els_code);
696 if (els_cmd->els_code == FC_ELS_RSCN) {
697 bfa_fcs_port_scn_process_rscn(lport, fchs, len);
701 if (els_cmd->els_code == FC_ELS_LOGO) {
703 * @todo Handle LOGO frames received.
705 bfa_trc(lport->fcs, els_cmd->els_code);
709 if (els_cmd->els_code == FC_ELS_PRLI) {
711 * @todo Handle PRLI frames received.
713 bfa_trc(lport->fcs, els_cmd->els_code);
718 * Unhandled ELS frames. Send a LS_RJT.
720 bfa_fcs_port_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
721 FC_LS_RJT_EXP_NO_ADDL_INFO);
726 * PID based Lookup for a R-Port in the Port R-Port Queue
728 struct bfa_fcs_rport_s *
729 bfa_fcs_port_get_rport_by_pid(struct bfa_fcs_port_s *port, u32 pid)
731 struct bfa_fcs_rport_s *rport;
732 struct list_head *qe;
734 list_for_each(qe, &port->rport_q) {
735 rport = (struct bfa_fcs_rport_s *)qe;
736 if (rport->pid == pid)
740 bfa_trc(port->fcs, pid);
745 * PWWN based Lookup for a R-Port in the Port R-Port Queue
747 struct bfa_fcs_rport_s *
748 bfa_fcs_port_get_rport_by_pwwn(struct bfa_fcs_port_s *port, wwn_t pwwn)
750 struct bfa_fcs_rport_s *rport;
751 struct list_head *qe;
753 list_for_each(qe, &port->rport_q) {
754 rport = (struct bfa_fcs_rport_s *)qe;
755 if (wwn_is_equal(rport->pwwn, pwwn))
759 bfa_trc(port->fcs, pwwn);
764 * NWWN based Lookup for a R-Port in the Port R-Port Queue
766 struct bfa_fcs_rport_s *
767 bfa_fcs_port_get_rport_by_nwwn(struct bfa_fcs_port_s *port, wwn_t nwwn)
769 struct bfa_fcs_rport_s *rport;
770 struct list_head *qe;
772 list_for_each(qe, &port->rport_q) {
773 rport = (struct bfa_fcs_rport_s *)qe;
774 if (wwn_is_equal(rport->nwwn, nwwn))
778 bfa_trc(port->fcs, nwwn);
783 * Called by rport module when new rports are discovered.
786 bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
787 struct bfa_fcs_rport_s *rport)
789 list_add_tail(&rport->qe, &port->rport_q);
794 * Called by rport module to when rports are deleted.
797 bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
798 struct bfa_fcs_rport_s *rport)
800 bfa_assert(bfa_q_is_on_q(&port->rport_q, rport));
801 list_del(&rport->qe);
804 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
808 * Called by fabric for base port when fabric login is complete.
809 * Called by vport for virtual ports when FDISC is complete.
812 bfa_fcs_port_online(struct bfa_fcs_port_s *port)
814 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
818 * Called by fabric for base port when fabric goes offline.
819 * Called by vport for virtual ports when virtual port becomes offline.
822 bfa_fcs_port_offline(struct bfa_fcs_port_s *port)
824 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
828 * Called by fabric to delete base lport and associated resources.
830 * Called by vport to delete lport and associated resources. Should call
831 * bfa_fcs_vport_delete_comp() for vports on completion.
834 bfa_fcs_port_delete(struct bfa_fcs_port_s *port)
836 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
840 * Called by fabric in private loop topology to process LIP event.
843 bfa_fcs_port_lip(struct bfa_fcs_port_s *port)
848 * Return TRUE if port is online, else return FALSE
851 bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
853 return bfa_sm_cmp_state(port, bfa_fcs_port_sm_online);
857 * Attach time initialization of logical ports.
860 bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
861 uint16_t vf_id, struct bfa_fcs_vport_s *vport)
864 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
865 lport->vport = vport;
866 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
867 bfa_lps_get_tag(lport->fabric->lps);
869 INIT_LIST_HEAD(&lport->rport_q);
870 lport->num_rports = 0;
874 * Logical port initialization of base or virtual port.
875 * Called by fabric for base port or by vport for virtual ports.
879 bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
880 struct bfa_port_cfg_s *port_cfg)
882 struct bfa_fcs_vport_s *vport = lport->vport;
884 bfa_os_assign(lport->port_cfg, *port_cfg);
886 lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
887 lport->port_cfg.roles,
888 lport->fabric->vf_drv,
889 vport ? vport->vport_drv : NULL);
891 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
893 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
894 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
902 bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
903 struct bfa_port_attr_s *port_attr)
905 if (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online))
906 port_attr->pid = port->pid;
910 port_attr->port_cfg = port->port_cfg;
913 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
914 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
915 port_attr->authfail =
916 bfa_fcs_fabric_is_auth_failed(port->fabric);
917 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
918 memcpy(port_attr->fabric_ip_addr,
919 bfa_fcs_port_get_fabric_ipaddr(port),
920 BFA_FCS_FABRIC_IPADDR_SZ);
922 if (port->vport != NULL) {
923 port_attr->port_type = BFA_PPORT_TYPE_VPORT;
924 port_attr->fpma_mac =
925 bfa_lps_get_lp_mac(port->vport->lps);
927 port_attr->fpma_mac =
928 bfa_lps_get_lp_mac(port->fabric->lps);
931 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
932 port_attr->state = BFA_PORT_UNINIT;